yidehui 发表于 2012-1-28 14:35:40

使用HC595时,mega16数码管显示出现奇怪的问题,请帮我思考下。

#include <iom16v.h>
#include <macros.h>
#define uchar unsigned char
#define uint unsigned int
#pragma data:code
flash uchar table[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92, 0x82,0xf8,0x80,0x90};

void delay(uchar ms)          //延时函数
{
       uchar i;
       while(ms--)
       for(i=0;i<12;i++);
}
void HC_595out(uchar data)
{       
       PORTB&=~(1<<4);   //等待数据传输,595存储寄存器数据不变
       SPDR=data;             //传输数据
       while(!(SPSR&(1<<SPIF)))
       PORTB|=(1<<4);       //595移位寄存器的数据进入数据存储寄存器,并在数码管上显示
}
void show(uint num)
{
       uchar temp;
      if(num>9)
       {
                    PORTD=0XBF;
                  temp=num/10;
                  HC_595out(table);               
                  delay(5);
                  PORTD=0X7F;
                  temp=num%10;
                  HC_595out(table);
                  delay(5);
       }
       else
       {
       PORTD=0X7F;
       temp=num;
       HC_595out(table);
       delay(5);
       }
}
void main()
{
       uint i=71;
       DDRB=0XFF;PORTB=0XF0;
       DDRD=0Xff;PORTD=0X0F;   //输出低电平,启用数码管
       DDRB|=(1<<5)|(1<<7);      //数据放入SPI寄存器中
       SPCR=(1<<SPE)|(1<<MSTR)|(1<<SPR1)|(1<<SPR0);   //等待数据传输完毕
       while(1)
       show(i);
}
主函数里,我用i等于0到9时数码管都可以正常显示,而等于两位数的时候也即是上述的程序,数码管却都显示两个7,这到底错在哪里?难道是HC_595out( )函数不支持短时间内显示不同的数?
关键是void show()部分,因为我i等于1到9是数码管都可以正常显示出1到9,所以其他部分应该没问题,而i等于两位数却出问题,这是怎么回事,要如何改正(我是用的是mega16)?
ps:   SPI控制寄存器介绍
SPIE SPE DORD MSTR CPOL CPHA SPR1 SPR0
SPIE:中断使能
SPE :SPI使能
DORD:数据次序 1为LSB首先发送,0为MSB首先发送
MSTR:主从选择 1为主,0为从MSTR置位时选择主机模式,否则为从机.如果MSTR为"1",
      SS配置为输入,且被拉低,则MSTR 被清零,寄存器SPSR 的SPIF 置位.用户必须重新
          设置MSTR 进入主机模式。
CPOL: 时钟极性见ATMEGA16L(中文)P130
CPHA: 时钟相位
SPR1, SPR0: SPI 时钟速率选择1 与0SPR1 和SPR0 对从机没有影响。

yidehui 发表于 2012-1-29 10:45:15

尽管是简单的问题,大家帮忙回下帖啦,拜托!./emotion/em019.gif

yidehui 发表于 2012-2-8 21:01:35

自己含泪顶自己

sf49ers 发表于 2012-2-8 22:55:58

有仿真器吗,看看tmep=num/10和temp=num%10后temp是否正确?

weiwei4 发表于 2012-2-9 00:28:09

大概看了下,发现个问题,就是每发一个数据,然后就显示下,这就使得当程序中i=71时,应该显示1的位置,分时显示了1和7,也就是说1和7重叠了,看到的结果当然是77啦

millwood0 发表于 2012-2-9 05:58:43

"PORTB|=(1<<4);       //595移位寄存器的数据进入数据存储寄存器,并在数码管上显示 "

that type of coding style is simply terrible.

yidehui 发表于 2012-2-9 11:59:39

回复【4楼】weiwei4
-----------------------------------------------------------------------

怎么会分时呢?显示1和7的前面,我都用了port端口高低电平进行限制, HC_595out()显示是没错的,怎么会分时,这与595寄存器有关吗?

yidehui 发表于 2012-2-9 12:05:40

回复【3楼】sf49ers
-----------------------------------------------------------------------

但是num不改变,temp数值是不会受到影响

millwood0 发表于 2012-2-11 04:14:16

"while(!(SPSR&(1<<SPIF)))
PORTB|=(1<<4);       //595移位寄存器的数据进入数据存储寄存器,并在数码管上显示 "

that's a nice piece of code, :)

yidehui 发表于 2012-2-14 10:25:46

回复【8楼】millwood0
-----------------------------------------------------------------------

什么意思啊,这个应该不影响吧,这个端口高低电平是用来控制数据是否进入数据寄存器的

nieyingjie 发表于 2012-2-14 13:40:23

回复【9楼】yidehui
-----------------------------------------------------------------------
你在函数HC_595out()中写了下面这两条语句
while(!(SPSR&(1<<SPIF)))
PORTB|=(1<<4);       //595移位寄存器的数据进入数据存储寄存器,并在数码管上显示

其实”while(!(SPSR&(1<<SPIF)))“ 这条语句后面应该要有分号。
另外,你的编程风格有待加强,像“PORTB|=(1<<4);”这样的语句应该用宏定义来做会更直观。
像if、while、for这样的语句带{},该有的不要图省略,必须加{}。

machao 发表于 2012-2-16 18:56:21

1.先上个硬件电路
2.参考我的教材,把多位数码管动态扫描显示的方法搞清楚。拜托。
页: [1]
查看完整版本: 使用HC595时,mega16数码管显示出现奇怪的问题,请帮我思考下。