【Proteus仿真】6位数码管计时器(0-10^5)

【Proteus仿真】6位数码管计时器(0-105)


  • Proteus仿真
    在这里插入图片描述

仿真难点,如何控制数字显示时不闪屏问题

数码管第一位显示的是100毫秒递增+1的模式,2-6位是每秒计数,

程序源码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
/\*6位数码管计时器\*/
#include <reg52.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
uchar Count;
sbit Dot = P0^7;

uchar code DSY_CODE[]=
{
0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f
};

uchar Digits_of_6DSY[]={0,0,0,0,0,0};

void DelayMS(uint x)
{
uchar i;
while(--x)
{
for(i=0;i<120;i++);//120
}
}


void main()
{
uchar i,j;
P0 = 0x00;
P2 = 0xff;
Count =0;
TMOD = 0x01;
TH0 = (65535-50000)/256;
TL0 = (65535-50000)%256;
IE = 0x82;
TR0 = 1;
while(1)
{
j = 0x7f;
for(i=6;i>0;i--)
{
P0 =0x00;//消隐
P2 =0xff;
j=\_crol\_(j,1);
P2 = j;
P0 = DSY_CODE[Digits_of_6DSY[i-1]];
if(i==2){
P0 |= 0x80; //加小数点
}
DelayMS(2);
}
}
}

void Time0() interrupt 1
{
uchar i;
TH0 = (65535-50000)/256;//50ms定时初值
TL0 = (65535-50000)%256;
if(++Count !=2) return;
Count = 0;
Digits_of_6DSY[0]++;//0.1s位累加
for(i=0;i<=5;i++)//进位处理
{
if(Digits_of_6DSY[i] == 10)
{
Digits_of_6DSY[i] = 0;
if(i < 5) Digits_of_6DSY[i+1]++; //如果0~4位则分别向高一位进位
}
else break;//若某低位没有进位,则循环提前结束
}
}

有问题的程序代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
/\*6位数码管计时器\*/
#include <reg52.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
uchar Count;
sbit Dot = P0^7;
uchar code DSY_CODE[]=
{
0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f
};

uchar Digits_of_6DSY[]={0,0,0,0,0,0};

void DelayMS(uint x)
{
uchar i;
while(--x)
{
for(i=0;i<120;i++);
}
}

void main()
{
uchar i,j;
P0 = 0x00;
P3 = 0xff;
Count =0;
TMOD = 0x01;
TH0 = (65535-50000)/256;
TL0 = (65535-50000)%256;
IE = 0x82;
TR0 = 1;
while(1)
{
j = 0x7f;
//前面高位,后面低位,循环中 i!=-1 亦可写成 i!=0xff
for(i=5;i!=-1;i--)
{
j=\_crol\_(j,1);
P3 = j;
P0 = DSY_CODE[Digits_of_6DSY[i]];
if(i==1) P0 |= 0x80;
DelayMS(2);
}
}
}

void Time0() interrupt 1
{
uchar i;
TH0 = (65535-50000)/256;
TL0 = (65535-50000)%256;
if(++Count !=2) return;
Count = 0;
Digits_of_6DSY[0]++;
for(i=0;i<=5;i++)
{
if(Digits_of_6DSY[i] == 10)
{
Digits_of_6DSY[i] = 0;
if(i != 5) Digits_of_6DSY[i+1]++;
}
else break;
}
}

问题点总结和分析

问题代码的运行出现闪屏,原因:代码中有些语句可能在Keil以往低版本编译的Hex文件仿真时运行可能没有问题,在Keil5.37版本编译后,就出现闪屏。
  1. 编译机制和语法上可能有差异。
  2. 数码管扫描显示的话,需要注意消隐处理。数码管显示的效果呈现的是视觉效果,是根据人视觉响应和停留的时间对应关系。如果将每一帧数据单独拿出来看的话,是间隔的。
  3. 闪屏问题点已经找出,可以参考上面提供的两段代码对比分析
程序代码在书写表达时,尽量通俗易懂,言简意赅是最上层的修为。不要弄一些生僻,或标新立异的写法,写代码要明白一点,是给自己阅读的,所以写法一定要规范,不要求很高,起码自己能一眼就可以看懂。

仿真资源和程序源码

仿真基于proteus8.9SP2

1
2
3
链接:https://pan.baidu.com/s/1AcBl8w6aA71U5QYfPZK1vA 
提取码:gi35


其实一个人的时候真的很自由,无拘无束,随心所欲。只是一个人久了,都不知道自己到底要的是什么了,不是没有人追,也不是不想爱。只是不习惯去过两个人的生活,或许还是因为没有遇到那个可以让我心动的人。 也许,我的固执,注定了我要单身很久很久。