打印

本人初学PIC单片机,写了一个数码管动态扫描的小程序。

[复制链接]
3878|16
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
PS:RA3端口的秒显正常显示,但是数码管显示有问题,百思不得其解,望各位大侠帮助!注:附件是仿真图

#include<pic.h> 
#include<math.h>
#include<stdio.h>

__CONFIG(0xe0f1); //芯片配置字,看门狗关,上电延时开,掉电检测关,低压编程关,加密,4M晶体HS振荡

#define data164 RA4
#define clk164 RA5

#define uchar unsigned char
#define uint unsigned int

#define _nop_() asm("nop")

#define LED RA3

uchar count_10ms=0;
uchar const bit_tab[]={0x80,0x40,0x20,0x01,0x08,0x04,0x02,0x01,0};//位选表,用来选择哪一只数码管进行显示
uchar const seg_data[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};//段选表,共阴数码显示码值
uchar disbuf[6]; //定义显示缓冲单元


/******函数定义**************/
void sendbyte1(char byte);
void sendbyte2(char byte);
void conv(int tmp_s,int humi_s);
void display();

/********端口设置函数********/
void port_init( )
{
TRISA=0x07;
TRISB=0x06;
TRISC =0x00; //端口C输出,位选
ADCON1=0x06; //定义RA为IO端口
ANSEL=0x00;
ANSELH=0x00;
}

/*****************显示函数***********************/
void sendbyte1(char byte)
{
unsigned char c;
for(c=0;c<8;c++)
{
if(byte&0x80)
data164=1;
else data164=0;
clk164=0;
_nop_();
clk164=1;
byte<<=1;
}
}

void sendbyte2(char byte)
{
unsigned char c;
for(c=0;c<16;c++)
{
if(byte&0x80)
data164=1;
else data164=0;
clk164=0;
_nop_();
clk164=1;
byte<<=1;
}
}

void conv(int tmp_s,int humi_s)
{
disbuf[0]=tmp_s/100;
disbuf[1]=tmp_s%100/10;
disbuf[2]=tmp_s%10;
disbuf[3]=humi_s/100;
disbuf[4]=humi_s%100/10;
disbuf[5]=humi_s%10;
}

void display()
{
static uchar count=0;
PORTC=bit_tab[8];
switch(count)
{
case 0:sendbyte1(seg_data[disbuf[0]]); PORTC=bit_tab[4];break;
case 1:sendbyte1(seg_data[disbuf[1]]); PORTC=bit_tab[5];break;
case 2:sendbyte1(seg_data[disbuf[2]]); PORTC=bit_tab[6];break;
case 3:sendbyte2(seg_data[disbuf[3]]); PORTC=bit_tab[4];break;
case 4:sendbyte2(seg_data[disbuf[4]]); PORTC=bit_tab[5];break;
case 5:sendbyte2(seg_data[disbuf[5]]); PORTC=bit_tab[6];break;
}
count++;
if(count==6) count=0;
}

/*********定时器0/定时器1初始化函数********/
void timer_init()
{
GIE=1; //开总中断
PEIE=1; //开外围功能模块中断
T0CS=0; //定时器0对内部时钟计数
PSA=0; //分频器分配给TRM0
PS0=1;
PS1=1;
PS2=1; //定时器0分频比为1:256
T0IE=1; //允许TMR0溢出中断
TMR0=248; //TMR0赋初值,定时2ms
T1CKPS0=1;T1CKPS1=1; //定时器1分频比为1:8
TMR1CS=0; //定时器1设置为定时功能
TMR1IE=1; //使能定时器1中断
TMR1ON=1; //启动定时器1
TMR1H=0xfb; //置计数值高位,定时时间为10ms
TMR1L=0x1e; //置计数值低位
}

/********中断服务程序********/
void interrupt ISR(void)
{
if (TMR0IF==1)
{
TMR0IF=0; //清TMR1溢出中断标志位
TMR0=248; //TMR0赋初值,定时2ms
display(); //调显示函数
}
if (TMR1IF==1)
{
TMR1IF=0; //清TMR1溢出中断标志位
TMR1H=0xfb; //重置计数值,定时时间为10ms
TMR1L=0x1e; //重置计数值
count_10ms++; //10ms计数器加1
if(count_10ms>=100)
{
LED=~LED;
count_10ms = 0; //计数100次后恰好为1s,此时10ms计数器清零
}
}
}


/*************************主函数****************************/
void main( )
{
port_init();
LED=1;
timer_init(); //调定时器T0、T1初始化函数
while(1)
{
conv(123,456); //调走时转换函数
}
}
沙发
yewuyi| | 2012-9-5 11:55 | 只看该作者
if (TMR0IF==1)
if (TMR1IF==1)
这两行有问题,在PIC中判断中断源必须和中断容许位一起判断才行。

例如:if(TMR0IE&&TMR0IF){}

使用特权

评论回复
板凳
xppx1987|  楼主 | 2012-9-5 12:28 | 只看该作者
2# yewuyi 还有一个问题是74HC164级联显示两个数码管的问题,一个164发送数据我知道怎么处理如:
  • void sendbyte1(char byte)
  • {
  • unsigned char c;
  • for(c=0;c<8;c++)
  • {
  • if(byte&0x80)
  • data164=1;
  • else data164=0;
  • clk164=0;
  • _nop_();
  • clk164=1;
  • byte<<=1;
  • }
  • }
,但是多个一起是怎么处理发送数据的呐?不知道我源程序中那样写对不对?请指教?

使用特权

评论回复
地板
yewuyi| | 2012-9-5 13:46 | 只看该作者
2# yewuyi  还有一个问题是74HC164级联显示两个数码管的问题,一个164发送数据我知道怎么处理如: void sendbyte1(char byte) { unsigned char c; for(c=0;c
xppx1987 发表于 2012-9-5 12:28


1个发送8次移位,两个发送16次移位

使用特权

评论回复
5
NE5532| | 2012-9-5 20:16 | 只看该作者
if (TMR0IF==1)
if (TMR1IF==1)
这两行有问题,在PIC中判断中断源必须和中断容许位一起判断才行。

例如:if(TMR0IE&&TMR0IF){}
yewuyi 发表于 2012-9-5 11:55


终于抓到斑竹一个小尾巴,PIC16里面只有Timer0才需要这样,Timer1是可以STOP的。

使用特权

评论回复
6
yewuyi| | 2012-9-6 08:58 | 只看该作者
终于抓到斑竹一个小尾巴,PIC16里面只有Timer0才需要这样,Timer1是可以STOP的。
NE5532 发表于 2012-9-5 20:16



你讲讲,俺还真没发现哪里说错了呢。

使用特权

评论回复
7
NE5532| | 2012-9-6 10:01 | 只看该作者
Timer1可以STOP的,STOP了就不会产生IF标志了。

使用特权

评论回复
8
xppx1987|  楼主 | 2012-9-6 11:06 | 只看该作者
4# yewuyi 版主老师,好像不需要这样,程序最后验证通过了,最后发现了问题是RA4脚直接连74ls164的数据端,而RA4输出时必须接一个上拉电阻才可以输出高电平。

使用特权

评论回复
9
xppx1987|  楼主 | 2012-9-6 11:08 | 只看该作者
7# NE5532 小弟也不是很清楚需不需要这样,不过最后程序验证通过了,定时扫描功能也实现了,是RA4端口接164端口的问题

使用特权

评论回复
10
yewuyi| | 2012-9-6 15:06 | 只看该作者
Timer1可以STOP的,STOP了就不会产生IF标志了。
NE5532 发表于 2012-9-6 10:01


他那个代码里面T1一直没有被关闭

使用特权

评论回复
11
NE5532| | 2012-9-6 15:15 | 只看该作者
;P但是你回帖说的是“在PIC中”而不是在他的代码中哈。

使用特权

评论回复
12
ocon| | 2012-9-6 15:50 | 只看该作者
各种小辫各种牛角~:lol

使用特权

评论回复
13
NE5532| | 2012-9-6 16:13 | 只看该作者
这个不算牛角吧,T0就必须这样判断了。我就在上面遭过的。

使用特权

评论回复
14
yewuyi| | 2012-9-6 16:34 | 只看该作者
;P但是你回帖说的是“在PIC中”而不是在他的代码中哈。
NE5532 发表于 2012-9-6 15:15


:L ,口误口误。。。

使用特权

评论回复
15
xppx1987|  楼主 | 2012-9-6 16:59 | 只看该作者
14# yewuyi 但是奇怪的是程序最后通过了,我没有按版主老师这样修改,只是将74ls164的数据端从RA4改到其他IO口就行,定时功能也实现了啊?不解?

使用特权

评论回复
16
yewuyi| | 2012-9-6 17:48 | 只看该作者
14# yewuyi  但是奇怪的是程序最后通过了,我没有按版主老师这样修改,只是将74ls164的数据端从RA4改到其他IO口就行,定时功能也实现了啊?不解?
xppx1987 发表于 2012-9-6 16:59


不这么写可能会出错,但未必会一定出错,如果你有足够的分析能力保证不出错,你也可以不判断容许位,但何必写这么一个提心吊胆的代码呢?

使用特权

评论回复
17
xppx1987|  楼主 | 2012-11-15 08:49 | 只看该作者
搞定!

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

5

主题

153

帖子

2

粉丝