请教各位大神,为什么我这个程序按键后按键控制数码管显示示的数字一闪而过,我想它一开始就显示数字,按键后再改变

8位数码管显示程序延时问题 - 光电及显示 -
中国电子技术论坛 -
最好最受欢迎电子论坛!
后使用快捷导航没有帐号?
Hot [学院]
8位数码管显示程序延时问题
17:24:35  
#include&reg52.h&
sbit CH1=P2^2;//段锁存
sbit CH2=P2^3;//位锁存
unsigned char code duanma[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
unsigned char code weima[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};
void delay();
for(i=0;i&8;i++)
P0=duanma;
for(n=0;n&2700;n++);
我这是一个8位数码管显示程序,在for循环里 我没加延时的时候,8位数码管亮了 但是显示的数字不清晰。我加了延时程序后8位数码管只有第一位显示了0,其他都不亮。这该怎么办,我的目的是让八位数码管清晰的显示0到7.
18:54:50  
你的程序中delay函数无效:
1 在main中定义delay?
2 你定义delay的地方函数名及括号后面带分号,所以后面一对花括号内地语句不是作为函数体,而是作为main函数内的语句;
所以,你的delay不知是在啥地方实现的,也许编译器会将你的delay调用编译成一个‘空’调用,然后你的循环外有一个for循环的延时,所以造成每循环一遍进行一次for循环延时,就会出现只有一位亮,其余位一闪而过的情况。
22:18:52  
PCB在线计价下单
板子大小:
板子数量:
PCB 在线计价
你的程序中delay函数无效:
1 在main中定义delay?
2 你定义delay的地方函数名及括号后面带分号,所以后面 ...
不怎么看得懂啊。&&直接说说该怎么改啊?
助理工程师
22:16:26  
新手前来学习一下
等待验证会员
12:25:06  
本帖最后由 luyao19 于
12:32 编辑
我有类似的问题,附上我的程序,本人新手,麻烦请各位指点迷津。
#include&reg52.h&
#include&intrins.h&
#define uint unsigned int
#define uchar unsigned char
sbit digiSegLa = P2^6; //段锁存
sbit digiBitLa = P2^7;&&//位锁存
uchar code digitron[] = {0x3f,0x06,0x5b,0x4f,
& && && && && && && && && && && &&&0x66,0x6d,0x7d,0x07,
& && && && && && && && && && && &&&0x7f,0x6f,0x77,0x7c,
& && && && && && && && && && && &&&0x39,0x5e,0x79,0x71};
void nbit_digitron(uchar num, uchar index);&&//在index位数码管处显示数字num
void delay(uint z);
void main()
& && &&&while(1){
& && && && && & nbit_digitron(1,1);
& && && && && & nbit_digitron(2,2);
& && && && && & nbit_digitron(3,3);
& && && && && & nbit_digitron(4,4);
& && && && && & nbit_digitron(5,5);
& && && && && & nbit_digitron(6,6);
void nbit_digitron(uchar num, uchar index){
& && &&&P0 = digitron[num];
& && &&&digiSegLa = 1;
& && &&&digiSegLa = 0;
& && &&&P0 = _crol_(0xfe, index-1);
& && &&&digiBitLa = 1;
& && &&&digiBitLa = 0;
& && &&&delay(4); //延时,这里有问题!!!!!!!
& && && && && && && &//若不加延时,则显示数字错误;
& && && && && && && &//若所加的延时太短,则显示数字不清晰;
& && && && && && && &//若所加延时太长,则数码管扫描有明显的跳跃感;
void delay(uint z)
& && &&&uint x,y;
& && &&&for(x=z;x&0;x--)
& && && && && & for(y=110;y&0;y--);& && &&&
调了很久,找不到问题在哪里,好纠结。。
13:06:00  
我有类似的问题,附上我的程序,本人新手,麻烦请各位指点迷津。
在P0赋值前,先执行关断操作。试试
17:32:13  
原厂LED显示驱动IC,可以提供原厂技术支持,沈生
23:55:34  
不怎么看得懂啊。&&直接说说该怎么改啊?
for(n=0;n&2700;n++);
工程师职场
Powered by请教各位大神,为什么我这个程序按键后数码管显示的数字一闪而过,我想它一开始就显示数字,按键后再改变-百谷歌为何我的数码管第一位只是一闪而过而不是固定显示0呢? - 单片机/MCU论坛 -
中国电子技术论坛 -
最好最受欢迎电子论坛!
后使用快捷导航没有帐号?
为何我的数码管第一位只是一闪而过而不是固定显示0呢?
20:07:26  
#include&reg52.h&
unsigned char temp,shi,ge,
sbit dula=P2^6;
sbit wela=P2^7;
unsigned char code table[]={0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71};
void delay(unsigned int z);
void display(unsigned char shi,unsigned char ge);
void init();
void main()
& & & & init();//初始化子程序
& & & & while(1)
& & & & & & & & if(aa==20)
& & & & & & & & {
& & & & & & & & & & & & aa=0;
& & & & & & & & & & & & if(temp==99)
& & & & & & & & & & & & {
& & & & & & & & & & & & & & & & temp=0;
& & & & & & & & & & & & };
& & & & & & & & & & & &
& & & & & & & & & & & & shi=temp/10;& && && && && && && && && && && &&&
& & & & & & & & & & & & ge=temp%10;
& & & & & & & & & & & & temp++;
& & & & & & & & & & & & display(shi,ge);
& & & & & & & & & & & &
& & & & & & & & };
void delay(unsigned int z)
& & & & unsigned int x,y;
& & & & for(x=z;x&0;x--)
& & & & & & & & for(y=50;y&0;y--)
& & & & & & & & {
& & & & & & & &
& & & & & & & & };
& & & & };
void display(unsigned char shi,unsigned char ge)
& & & & & & & &
& & & & & & & & dula=1;
& & & & & & & & P0=table[shi];
& & & & & & & & dula=0;
& & & & & & & & wela=1;
& & & & & & & & P0=0
& & & & & & & & wela=0;
& & & & & & & & delay(5);
//送完十位送个位
& & & & & & & &
& & & & & & & & dula=1;
& & & & & & & & P0=table[ge];
& & & & & & & & dula=0;
& & & & & & & & wela=1;
& & & & & & & & P0=0
& & & & & & & & wela=0;
& & & & & & & & delay(5);
void init()
& & & & temp=0;
& & & & TMOD=0x01;
& & & & TH0=()/256;
& & & & TL0=()%256;
& & & & EA=1;
& & & & ET0=1;
& & & & TR0=1;
void timer0() interrupt 1
& & & & TH0=()/256;
& & & & TL0=()%256;
& & & & aa++;
20:37:57  
本帖最后由 me860 于
20:41 编辑
& && && && && & dula=1; & && && && & //你是用的片选么,你这是想往同一个地址送的俩个不同的数么
& && && && && & P0=table[shi];
& && && && && & dula=0;& && && && &
& && && && && & wela=1;
& && && && && & P0=0
& && && && && & wela=0;
& && && && && & delay(5);
//送完十位送个位
& && && && && &
& && && && && & dula=1;& && && &
& && && && && & P0=table[ge];
& && && && && & dula=0;
& && && && && & wela=1;& && &
& && && && && & P0=0
& && && && && & wela=0;
& && && && && & delay(5);
20:44:20  
PCB在线计价下单
板子大小:
板子数量:
PCB 在线计价
dula=1;& && && && &&&//你是用的片选么,你这是想往同一个地址送的俩个不同的数么
& && & ...
是两次送两位数进去~~
21:23:57  
送到同一个数码管么?
21:27:10  
本帖最后由 me860 于
21:49 编辑
你是想送到同一个数码管啊,那你的十位显示就会一闪而过,你的个位会有个0.5s多点的延时
当a =20进入 void display ()
void display(unsigned char shi,unsigned char ge)&&
& && && && && &
& && && && && & dula=1;
& && && && && & P0=table[shi];
& && && && && & dula=0;
& && && && && & wela=1;
& && && && && & P0=0& && && &&&
& && && && && & wela=0;
& && && && && & delay(5);& && && && && && && && && && && && && && & //十位显示delay(5) 时间后准备显示个位
//送完十位送个位
& && && && && &
& && && && && & dula=1;
& && && && && & P0=table[ge];
& && && && && & dula=0;
& && && && && & wela=1;
& && && && && & P0=0
& && && && && & wela=0;
& && && && && & delay(5);& && && && && && && && && && && && && && &//十位数子显示被个位刷新(十位显示的时间为 delay(5)多一点),
& && && && && && && && && && && && && && && && && && && && && && && && &//个位在这显示delay(5) 时间,跳出,
& && && && && && && && && && && && && && && && && && && && && && && && &//再等a= 20进入,个位显示时间为 a加到20所用的时间+delay(5)
22:31:14  
贴个电路上来看看!~!~!~!~!
00:09:53  
在段选与位选间加一个消隐&&P0=0xff
18:16:55  
void main()
& && &&&init();//初始化子程序
& && &&&while(1)
& && && && && & if(aa==20)
& && && && && & {
& && && && && && && && &aa=0;
& && && && && && && && &if(temp==99)
& && && && && && && && &{
& && && && && && && && && && &&&temp=0;
& && && && && && && && &};
& && && && && && && && &
& && && && && && && && &shi=temp/10;& && && && && && && && && && && &&&
& && && && && && && && &ge=temp%10;
& && && && && && && && &temp++;
& && && && && && && &&&
& && && && && && && && &
& && && && && & }
& & & & & & & & & & & & & & & && &display(shi,ge);
主程序这样写就可以了
18:31:50  
8楼说的没错,讲display()写在if(aa==20)跳出大括号的地方就行了!
12:57:30  
void main()
& && &&&init();//初始化子程序
大神,请问为什么把display(shi,ge)移到if语句外面就行了呢?
09:05:33  
延时,让LED亮的时间长一点(应该是这样,忘了当时怎么弄得了)
09:09:09  
刚刚看了下你的程序,你把显示部分写到IF里面了,只有IF满足条件的时候才会显示一下,这样不对,移到外面的话是每个循环显示一次
Powered by数码管显示有残影,困扰几天了还没有解决|我爱单片机 - 数码之家
查看完整版本: [--
赞助商链接
数码管显示有残影,困扰几天了还没有解决单独把显示部分独立出来还是这样[attachment=4514447]再发个视频硬件电路结构[attachment=4514448]测试程序#include &REG52.H&#include &intrins.h&#define&&&&&&&&uint unsigned int#define&&&&&&&&uchar unsigned char#define&&NOP&&_nop_&&&&&&&&()&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& #define&&NOP3&&_nop_(); _nop_(); _nop_()#define&&Duan P2sfr T2MOD&&= 0xC9;sfr&&P4&&= 0xe8;uchar code Num[]={ 0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,};//uchar code Num[]={1,2,4,8,16,32,64,128,};uchar a,b,c,d;char Hour,Schar Min=10;bit Shan1,Shan2;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&//闪烁标志&&&&&&&& 1Hz/2Hzsbit SMG1= P1^6;&&&&&&&&&&&&&&&&&&//时十位sbit SMG2= P1^7;&&&&&&&&&&&&&&&&&&//时个位sbit SMG3= P3^6;&&&&&&&&&&&&&&&&&&//分十位sbit SMG4= P3^7;&&&&&&&&&&&&&&&&&&//分个位sbit DP&&= P4^0;&&&&&&&&&&&&&&&&&&//小数点sbit Maohao=P1^2;&&&&&&&&&&&&&&&&&&//冒号void Delay(uint x)&&//延时子函数&&&&&&&&&& 50us{&&&&&&uint i,j;&&&&&&for(i=x;i&0;i--)&&&& //yanshi x10us&&&&&& for(j=15;j&0;j--);&&}void Xianshi()&&&&&&&&&& /*显示扫描*/{&&&&&&&&&&&&&&&&&&&&&&&&Duan=Num[Sec/10];&&&&&&&&&&&&&&&& //段码&&&&&&&&&&&&&&&&&&&&&&&& SMG1=1;&&&&&&&&&&&&&&&&&&&&&&&&&&//位开&&&&&&&&&&&&&&&&&&&&&&&&Delay(12);&&&&&&&&&&&&&&&& &&&&&&&&&&&&&&&&&&&&&&&&SMG1=0;&&&&&&&&&&&&&&&&&&&&&&&&&&//位关&&&&&&&&&&&&&&&&&&&&&&&&Duan=0;&&&&&&&&&&&&&&&&&&&&&&&&Delay(20);&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&Duan=Num[Sec%10];&&&&&&&&&&&&&&&&&&&&&&&&SMG2=1;&&&&&&&&&&&&&&&&&& &&&&&&&&&&&&&&&&&&&&&&&&DP=Shan1;&&&&&&&&&&&&&&&&&&&&&&&&Delay(12);&&&&&&&&&&&&&&&&&&&&&&&&SMG2=0;&&&&&&&&&&&&&&&&&&&&&&&&Duan=0;&&&&&&&&&&&&&&&&&&&&&&&&DP=0;&&&&&&&&&&&&&&&&&&&&&&&&Delay(20);&&&&&&&&&&&&&&&&&&&&&&&&Duan=Num[Min/10];&&&&&&&&&&&&&&&&&&&&&&&& SMG3=1;&&&&&&&&&&&&&&&&&& &&&&&&&&&&&&&&&&&&&&&&&&Delay(12);&&&&&&&&&&&&&&&&&&&&&&&&SMG3=0;&&&&&&&&&&&&&&&&&&&&&&&&Duan=0;&&&&&&&&&&&&&&&&&&&&&&&&Delay(20);&&&&&&&&&&&&&&&&&&&&&&&&Duan=Num[Min%10];&&&&&&&&&&&&&&&&&&&&&&&&SMG4=1;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&Delay(12);&&&&&&&&&&&&&&&&&&&&&&&&SMG4=0;&&&&&&&&&&&&&&&&&&&&&&&&Duan=0;&&&&&&&&&&&&&&&&&&&&&&&&Delay(20);}void main(){&&&&&&&&TMOD = 0x01;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&//设置定时器0模式1&&&&&&&&TH0=0xE0;&&&&&&&&TL0=0x00;&&&&&&&&&&&&&&&&//设置定时0初值&&&&&&&&2ms@24.576M/6T&&&&&&&&TR0=1;&&&&&&&&&&&&&&&&ET0=1;&&&&&&&&&&&&&&&&&&&&&&&&//定时器0开始计时&&&&&&&&EA=1; &&&&&&&&SMG1=SMG2=SMG3=SMG4=DP=0;&&&&&&&&while(1)&&&&&&&&{&&&&&&&&&&&&&&&&Xianshi();&&&&&&&&}}void Tim0(void) interrupt 1 using 3&&&&&&&&//定时器中0{&&&&&&&&TH0=0xf5; TL0=0x95;&&&&&&&&&&&&&&&&//2ms@16M&&&&&&&&a++;&&&&&&&&if(a&124)&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& //0.25s&&&&&&&&{&&&&&&&&&& b++; &&&&&&&&&&&&&&&&Shan2=!Shan2; &&&&&&&&&&&&&&&&a=0; &&&&&&&&&&&&&&&&if(b&1)&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&//0.5s&&&&&&&&&&&&&&&&{ &&&&&&&&&&&&&&&&&&c++;&&&&&&&&&&&&&&&&&&b=0; &&&&&&&&&&&&&&&&&&Shan1=!Shan1; &&&&&&&&&&&&&&&&&&if(c&1)&&&&&&&&&&&&&&&&&&{&&&&&&&&&&&&&&&&&&&&&&&&&& Sec++;&&&&&&&&&&&&&&&&&&&&&&&&c=0;&&&&&&&&&&&&&&&&&&&&&&&&if(Sec&59)&&&&&&&&&&&&&&&&&&&&&&&&{&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& Min++;&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& Sec=0;&&&&&&&&&&&&&&&&&&&&&&&&}&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& &&&&&&&&&&&&&&&&&&}&&&&&&&&&&&&&&&&}&&&&&&&&}}复制代码
赞助商链接
先关段,延时20,再关位,应该会好的。应为延时太短,三极管和数码管会有电流存在,还来不及放完
赞助商链接
我提2点1、不知道LED数码管型号,12V驱动而限流电阻221是否太小了,LED太亮导致残影2、个人非常反对在主循环体内使用delay函数,因为在显示子程序内是靠delay延时来显示内容,而这时候很可能产生中断使显示数据改变,从而造成残影。
数码管是3寸的,内部是6串结构中断不会影响程序数据的,调用中断程序、子程序前都要把当前程序压入堆栈的
降低电压试试看,前些天我就遇到这种问题了,把电压降低后解决问题
把限流电阻换大一点应该能解决,不过太大了就会变暗了
8050去掉上拉或改成下拉。8550加12V上拉。
只用驱动,不接控制,直接检测给信号来判断下。修板子时有遇到过换驱动集成块后显示残影的问题,集成块不合格造成,换个厂做的就好了。
:8050去掉上拉或改成下拉。8550加12V上拉。 ( 00:17) Q2\Q3\Q4的基极没有上拉电阻,关断的时候由于载流子存储还会导通一段时间。加适当的上拉电阻吧。
:数码管是3寸的,内部是6串结构中断不会影响程序数据的,调用中断程序、子程序前都要把当前程序压入堆栈的 ( 00:01) 1、可能我没表述清楚,我坚持认为是代码问题,你延时函数是多少时间?整个主循环就只有1个显示函数,那么循环1次用时多少?在循环的过程中产生中断的话,中断里面又刚好秒进位。2、整个代码非常低劣(恕我直言),大量delay不说,在主循环里对duan数据有2次除法2次取模,单片机本身数学运算就弱还耗费大量的周期来处理这些运算,效率会很低,实时性变差。我写LED显示的思路是开辟几个字节RAM当做显示缓存,显示子程序只负责直接把显示数据送到LED,并不做任何运算,而在每次秒进位时才运算一次显示数据送进缓存,这样效率提高很多。本人也属初学,请指正
:1、可能我没表述清楚,我坚持认为是代码问题,你延时函数是多少时间?整个主循环就只有1个显示函数,那么循环1次用时多少?在循环的过程中产生中断的话,中断里面又刚好秒进位。2、整个代码非常低劣(恕我直言),大量delay不说,在主循环里对duan数据有2次除法2次取模,单片机 .. ( 00:47) 1.在扫描过程中中断触发会引发显示错乱,比如当前时间是11分59秒,当显示59秒之后产生中断,那么这一次实际显示的数字就是12 59,不过因为一次扫描的时间相当短暂,有一次错乱不会有什么人类可察觉的问题。2.程序确实写得不够精简,只在中断时计算显示数据可以大大减少开销。我不是很熟悉51,看注释两次中断之间有2ms,足够完成所有计算了,不会出现这次没算完下次中断又来的情况。一次除法用时也不会太长,印象中也就几个周期,短于delay(1)。不过算起来delay(1)大概是几十个周期,显示函数执行一次不超过1k个周期,中断我不是很了解先忽略,那么扫描频率会在1k-2kHz之间,相当高了。我之前做过一个扫描数码管驱动电路,驱动频率仅200Hz左右,但三极管不加上拉电阻时用示波器可以观察到LED上的电压已经不是方波而是锯齿波了。
6楼是正解!!!!!!!!!!!该死的字数
:降低电压试试看,前些天我就遇到这种问题了,把电压降低后解决问题 ( 00:12) 与电压无关。电压只是影响亮度,降电压是治标不治本
:8050去掉上拉或改成下拉。8550加12V上拉。 ( 00:17) 8050必须有上拉,下拉则无需,因为单片机输出是弱上拉的开漏结构,高电平驱动能力很弱。8550加上拉倒可以试试
:1、可能我没表述清楚,我坚持认为是代码问题,你延时函数是多少时间?整个主循环就只有1个显示函数,那么循环1次用时多少?在循环的过程中产生中断的话,中断里面又刚好秒进位。2、整个代码非常低劣(恕我直言),大量delay不说,在主循环里对duan数据有2次除法2次取模,单片机本身数学运算就弱还耗费大量的周期来处理这些运算,效率会很低,实时性变差。我写LED显示的思路是开辟几个字节RAM当做显示缓存,显示子程序只负责直接把显示数据送到LED,并不做任何运算,而在每次秒进位时才运算一次显示数据送进缓存,这样效率提高很多。本人也属初学,请指正....... 1,单片机是单任务运行的,一次只能处理一条指令,就算再循环过程产生中断改变数据也不会产生残影。相应中断程序前单片机要先执行完当前指令,然后把当前执行的函数压入堆栈保护起来,然后再调用中断函数。2,/10运算反汇编后仅3条指令,微不足道,这只是个测试程序,实际上用的是RTC时钟芯片,要是每次进位运算要做大量的if判断,还不如直接运算。
1,中断中数据改变不会影响当时执行程序的数据,直到下一个循环才会改变。2,也没必要一味追求高效,单片机资源够用就行,实际上是过剩状态,提高执行效率也没有多大意义
1,中断中数据改变不会影响当时执行程序的数据,直到下一个循环才会改变。2,也没必要一味追求高效,单片机资源够用就行,实际上是过剩状态,提高执行效率也没有多大意义
显示模块现在为什么不用一个TM1637呢?我们公司现在都很多在用了~
可能还是程序上的问题void Xianshi()&&&&&&&&&& /*显示扫描*/{&&&&&&&&&&&&&&&&&&&&&&&&Duan=Num[Sec/10];&&&&&&&&&&&&&&&& //段码&&&&&&&&&&&&&&&&&&&&&&&& SMG1=1;&&&&&&&&&&&&&&&&&&&&&&&&&&//位开&&&&&&&&&&&&&&&&&&&&&&&&Delay(20);&&&&&&&&&&&&&&&& &&&&&&&&&&&&&&&&&&&&&&&&SMG1=0;&&&&&&&&&&&&&&&&&&&&&&&&&&//位关&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&Duan=Num[Sec%10];&&&&&&&&&&&&&&&&&&&&&&&&SMG2=1;&&&&&&&&&&&&&&&&&& &&&&&&&&&&&&&&&&&&&&&&&&DP=Shan1;&&&&&&&&&&&&&&&&&&&&&&&&Delay(20);&&&&&&&&&&&&&&&&&&&&&&&&SMG2=0;&&&&&&&&&&&&&&&&&&&&&&&&Duan=Num[Min/10];&&&&&&&&&&&&&&&&&&&&&&&&SMG3=1;&&&&&&&&&&&&&&&&&& &&&&&&&&&&&&&&&&&&&&&&&&Delay(20);&&&&&&&&&&&&&&&&&&&&&&&&SMG3=0;&&&&&&&&&&&&&&&&&&&&&&&&Duan=Num[Min%10];&&&&&&&&&&&&&&&&&&&&&&&&SMG4=0;&&&&&&&&&&&&&&&&&&&&&&&&Delay(20);&&&&&&&&&&&&&&&&&&&&&&&&SMG4=0;}后面没有必要加多个 Delay(20);的呢从显示来看出是位没有完全关闭,下一个数有上一个的残影,但Duan=0;都加上了问题……
2个不同延时是为了调整亮度,为何有问题实在是搞不懂
:2个不同延时是为了调整亮度,为何有问题实在是搞不懂 ( 09:20) 用示波器看看相关电路的波形吧。
1、2、3、4总共4个灯。显示2之前先把1关了,再开2.
已经是这样做了
整个扫描过程延时量超过定时器2ms中断,造成在扫描过程中会被定时器中断干扰,形成乱码或者残影。最好的LED动态扫描是放在定时器中断里,定时刷新显示端口,整个过程无需延时函数,比如你有4个显示位,那么利用2ms的中断,循环一次只要8ms,甚至还可以加一个消隐,就是5*2==10ms,整个扫描过程还是100HZ,眼睛看不到闪烁的,这样做的好处是开可以调整显示占空比,调节亮度。例如&&uchar t0_void Tim0(void) interrupt 1 using 3&&&&&&&&//定时器中0{&&TH0=0xf5; TL0=0x95;&&&&&&&&&&&&&&&&//2ms@16M //LED动态扫描&&t0_cnt++;if(t0_cnt&4)t0_cnt=0;//将4增大可以降低LED亮度,但是太大后会降低扫描频率,除非提高定时器时间switch(t0_cnt)&&{&&csse 0:SMG4=0;&&&&&&&& Duan=Num[Sec/10];&&&&&&&&&&&&&&&& //段码&&&&&&&& SMG1=1;&&&&&&&&&&&&&&&&&&&&&&&&&&//位开&&&&&&&&&&case 1:SMG1=0;&&&&&&&& Duan=Num[Sec%10]+0x80*//假设你的数码管DP接在P2.7上,当做秒点&&&&&&&& SMG2=1; &&&&&&&&&&&&&&case 2:SMG2=0;&&&&&&&& Duan=Num[Min/10];&&&&&&&& SMG3=1;&&&&&&&&&&&& &&case 3:SMG3=0;&&&&&&&& Duan=Num[Min%10];&&&&&&&& SMG4=1;&&&&&&&&&& &&csse 4:SMG4=0;&&&&&&&& &&default:&&}&&&&&&&&&&&&&& && //这里写你其他的定时函数}
呵呵,不要乱说,定时器并不影响扫描,
我补充了例程,你先试试再说
呵呵,没法调整亮度的,扫描空闲一位也是浪费,我的亮度范围非常大,夜间才可见的最暗的微亮,到白天能正常看的亮度,相差几十倍,这种思路是行不通的
别着急嘛,慢慢来,我以前也为这个问题困扰过,支持你。
试一下这个电路, [attachment=4517792]
虽然还搞不清问题出在哪里,不过可以肯定与主程序扫描还是定时器扫描无关,两者只是方式不同。
扫描显示还是用定时中断,用延时占用单片机资源。参考代码://-------------------------------------------------------------------//Timer1Int:定时中断子程序,2ms//-------------------------------------------------------------------void Timer1Int(void) interrupt 3{&&&&&&&&TH1=0xE3;&&&&&&&&&&&&&&&&&&&&&& //延时时间2ms&&&&TL1=0x32;&&&&Snum++;&&&&if(Snum==1)&&&&&&&&&&&&&&&&&&&&&&&&//输出个位数字&&&& {&&&&&&&&COM2=1;&&&&&&&&COM3=1;&&&&&&&&P2=LED[Show[2]];&&&&&&&&COM1=0;&&&&&& }&&&&if(Snum==2)&&&&&&&&&&&&&&&&&&&&&&&&//输出十位数字&&&& {&&&&&&&&COM1=1;&&&&&&&&COM3=1;&&&&&&&&P2=LED[Show[1]];&&&&&&&&&&&&&&&&COM2=0;&&&&}&&&&if(Snum&2)&&&&&&&&&&&&&&&&&&&&&&&&//输出百位数字&&&& {&&&&&&&&Snum=0;&&&&&&&&&&&&&&&&&&&&&&&&//超时清零&&&&&&&&COM1=1;&&&&&&&&COM2=1;&&&&&&&&P2=LED[Show[0]];&&&&&&&&//显示温度符号&&&&&&&&COM3=0;&&&&}}共阳,位低电平有效,先关,显示段,再开位显示。
数码管显示不都是需要有消隐的吗?我以前的残影是通过在送下次数据前关前一次位选搞定的。没有细看程序。。只是一些自己的经历说下。。。
楼上的显示函数很好。。楼主可以借鉴。。我现在写的程序里超过1ms的延时都是用定时实现的。。delay只在初始化有用过。。。
:虽然还搞不清问题出在哪里,不过可以肯定与主程序扫描还是定时器扫描无关,两者只是方式不同。 ( 19:45) 我敢说绝对有关系,不要太固执己见,上面用朋友都给出了例子,照这思路改下程序就个把钟头的事。今天我仔细思考过这问题的,但是要画个流程图才好解释清楚
:呵呵,不要乱说,定时器并不影响扫描, 我玩计算机电子电路仿真的,很多时候要把自己的大脑模拟成CPU来考虑问题,而人觉得没问题的地方往往就是出错的地方,我画了张图来表述[attachment=4518668]你的主循环其实也就是一个显示扫描循环,就用图片左边的黑箭头表示你把自己当做CPU来走流程当SMG1显示完成时,刚好发生中断导致sec变量加1,那么这时候显示是不是就出问题了???
:我玩计算机电子电路仿真的,很多时候要把自己的大脑模拟成CPU来考虑问题,而人觉得没问题的地方往往就是出错的地方,我画了张图来表述[图片]你的主循环其实也就是一个显示扫描循环,就用图片左边的黑箭头表示....... ( 22:21) 这确实是个问题,但是该现象出现的周期为1秒,人眼基本不会观察到。从楼主的照片和视频可以看到,拖影是一直存在,而不是1秒出现一次。并且可以观察到小数点也有拖影现象。所以中断使变量前后不一致不是导致拖影的根本原因。
:我玩计算机电子电路仿真的,很多时候要把自己的大脑模拟成CPU来考虑问题,而人觉得没问题的地方往往就是出错的地方,我画了张图来表述[图片]你的主循环其实也就是一个显示扫描循环,就用图片左边的黑箭头表示....... ( 22:21) 绝对没有这个问题,1/100秒一闪而过人眼是觉察不到的
:我玩计算机电子电路仿真的,很多时候要把自己的大脑模拟成CPU来考虑问题,而人觉得没问题的地方往往就是出错的地方,我画了张图来表述[图片]你的主循环其实也就是一个显示扫描循环,就用图片左边的黑箭头表示....... ( 22:21) 补充一点,图片和视频都是RTC芯片获得的时间而不是中的产生的
:绝对没有这个问题,1/100秒一闪而过人眼是觉察不到的 ( 22:59) 你也觉得不是软件问题,那你有尝试更改硬件电路了吗?
我想问下benli,你程序中是先关位,再关段。有没有照我说的先关段,再关位,之后的效果怎样?
又想了下,这样也不会致使鬼影,数据变成40了,这一位会直接显示0。这和正常的数据变化的过程是看上去一样的,扫描一遍也就是1/100s的时间,人眼根本觉察不到,看起来就和39变为40一样,不会产生鬼影,
改过。应当不是软件的问题。已经从硬件上进行处理了,在每个段对地加了个电阻,现在已经基本上看不到鬼影了,只剩下小数点没处理好
刚用4位数码管做测试,定时器中断方式驱动,25HZ闪得很厉害,30HZ明显好转,35HZ基本看不到闪,40HZ完全看不到闪,100HZ再快,残影越来越明显,原因是写段数据时不关位驱动。不知道楼主的是不是写段时没有关位驱动,并且扫描速度较快。
没消隐发送下一个内容之前,把数码管全部关闭。数码管扫描显示都得这样啊,就像按键消抖,写按键扫描必须消抖…
试一下全亮 然后 全灭 看看没问题的话 就是代码问题目测是延迟
查看完整版本: [--
Powered by
Time 0.111577 second(s),query:5 Gzip enabled

我要回帖

更多关于 单片机数码管按键加一 的文章

 

随机推荐