标题:
51单片机实现2位一体数码管的99-1显示的代码和仿真 显示很闪?
[打印本页]
作者:
风格回家看了
时间:
2022-3-7 14:37
标题:
51单片机实现2位一体数码管的99-1显示的代码和仿真 显示很闪?
51单片机实现2位一体数码管的99-1显示的代码和仿真,按键可以暂停和继续开始
可以重复实现99到1的倒计时
按键按一下为暂停,再按一次继续倒计
仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)
51hei.gif
(160.18 KB, 下载次数: 44)
下载附件
2022-3-7 18:03 上传
单片机源程序如下:
#include "reg52.h"
#include <stdio.h>
typedef unsigned int u16;
typedef unsigned char u8;
sbit key = P3^4;
sbit LS0 = P3^0;
sbit LS1= P3^1;
unsigned char led_mod[] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
void display(u8 num);
void delay_ms(u16 num);
void main()
{
u8 c;
u8 m,n,a;
c=99;
while(1)
{
display(c);
delay_ms(300);
c=c-1;
if(key==0)
{
a=1;
while(a)
{
display(c);
delay_ms(300);
if(key==0)
{
a=0;
}
}
}
if(c<=0)
{
c=99;
}
}
}
void display(u8 num)
{
u8 m, n,j;
m = num/10;
n = num%10;
for(j=0;j<2;j++)
{
switch(j)
{
case(0):
LS0=0;LS1=1;
P2=led_mod[m];
break;
case(1):
LS0=1;LS1=0;
P2=led_mod[n];
break;
}
delay_ms(25);
P2=0x00;
}
}
void delay_ms(u16 num)
{
u16 x, y;
for(x = num; x > 0; x--)
for(y = 110; y > 0; y--);
}
复制代码
Keil代码与Proteus仿真下载:
电子设计.7z
(61.44 KB, 下载次数: 9)
2022-3-7 18:13 上传
点击文件名下载附件
作者:
LPB2021
时间:
2022-3-7 21:34
建议你程序规范一些,u8 c最好初始化的时候直接定于0或者其他数据要不然编译器有时会给你随便搞一个数值。
作者:
dazhige
时间:
2022-3-8 00:20
闪烁是“视觉暂留”没有控制好啊,delay_ms(300);delay_ms(25);都是问题
作者:
yzwzfyz
时间:
2022-3-8 15:39
何时不用DELAY了,就好了。
初学者,只会用最低级的DELAY延时,不知道教课书上有没有教过DELAY的危害是什么。谁害了初学者。
你想想看,当你DELAY 0.3秒时,在这0.3秒里,两个LED是显示的是什么?一个有字一个无字?
作者:
2936566371
时间:
2022-3-8 16:19
延迟弄长一点看看
作者:
wulin
时间:
2022-3-8 16:45
楼主仔细对比一下,会有收获。
#include "reg52.h"
#include <stdio.h>
typedef unsigned int u16;
typedef unsigned char u8;
sbit key = P3^4;
sbit LS0 = P3^0;
sbit LS1 = P3^1;
unsigned char led_mod[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
void display(u8 num);
void delay_ms(u16 num);
void main()
{
u16 count;
u8 c=0,a=0;
bit n=0,m=0;
while(1)
{
if(key==0)
{
if(++a>=10 && n==0)
{
n=1;
if(c!=0)m=~m;
else
{
c=99;
m=1;
}
}
}
else
{
a=0;
n=0;
}
if(m==1)
{
if(++count>=1000)
{
count=0;
if(c>0)c--;
else m=0;
}
}
display(c);
delay_ms(1);
}
}
void display(u8 num)
{
static bit i=0;
P2=0x00;
if(i==0)
{
LS0=0;LS1=1;
P2=led_mod[num/10];
i=1;
}
else
{
LS0=1;LS1=0;
P2=led_mod[num%10];
i=0;
}
}
void delay_ms(u16 num)
{
u16 x, y;
for(x=num;x>0;x--)
for(y=110;y>0;y--);
}
复制代码
作者:
名字不是重点
时间:
2022-3-8 16:45
本帖最后由 名字不是重点 于 2022-3-8 17:00 编辑
动态扫描显示,就是利用人眼的“视觉暂留”效果,来实现整幅画面的“稳定”显示。
人眼的“视觉暂留”一般在100ms-400ms,如要8个数码管动态扫显,必需保证至少每100ms(扫描间隔Ts)要输出一帧的显示数据。假如传输一帧数据花费的时间为2ms(Tf),一帧包含8个数码管,所以每个数码管的维持时间(Th)约为0.25ms,这时数码管显示看上去很暗,就要把Th加大。而且每个数码管的Th必需相同,这样才不会显得亮度不均(硬件参数正确的情况下)。而Ts太大了,就会出现数码管闪烁的现象,也不能太小,否则会影响其它任务的时效性。这就牵涉到任务时间片的调度,
在祼奔系统中,常规的做法是把扫显任务做成一个函数,在其它任务片中按需调用。比如按键扫描,插入扫显,替代“去抖动延时”,等等。而RTOS之类的系统另说。
作者:
2936566371
时间:
2022-3-8 21:33
应该是延时中断的问题
作者:
名字不是重点
时间:
2022-3-8 22:09
void display(u8 num)这个函数有点废。。
总共就2个数码管,又是if ,又是switchr ...
void display(u8 num)
{
u8 m, n;
m = num/10;
n = num%10;
LS0=0;LS1=1;
P2=led_mod[m];
delay_ms(25);
LS0=1;LS1=0;
P2=led_mod[n];
delay_ms(25);
P2=0x00;
}
这样不更快吗?
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1