【Proteus仿真】6位数码管秒计数器(0-999999S)

【Proteus仿真】6位数码管秒计数器(0-999999S)


  • 🎬 Proteus VSM仿真演示
    在这里插入图片描述
  • 📺例程二演示:
    在这里插入图片描述

📝例程一:VSM Studio代码

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
74
75
76
77
78
79
/\* Main.c file generated by New Project wizard
\*0-999999秒表
\* Created: 周四 6月 14 2022
\* Processor: AT89C52
\* Compiler: Keil for 8051
\*/

#include <reg52.h>
#define FOSC 12000000uL
//#define T50MS 15536 //50ms timer calculation method in 12T mode
#define T50MS (65536-FOSC\*50/12/1000) //1ms\*50 timer calculation method in 12T mode

sbit ADDR0 = P1^0;
sbit ADDR1 = P1^1;
sbit ADDR2 = P1^2;
sbit ADDR3 = P1^3;
sbit ENLED = P1^4;
sbit led = P1^5;
unsigned char code LedChar[] = { //数码管显示字符转换表
0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8,
0x80, 0x90, 0x88, 0x83, 0xC6, 0xA1, 0x86, 0x8E
};
unsigned char LedBuff[6] = { //数码管显示缓冲区,初值 0xFF 确保启动时都不亮
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
};
unsigned int cnt = 0; //记录 T0 中断次数
unsigned long sec = 0; //记录经过的秒数
void tm0\_isr() interrupt 1
{
TL0 = T50MS; //reload timer0 low byte
TH0 = T50MS >> 8; //reload timer0 high byte
if (cnt-- == 0) //1ms \* 1000 -> 1s
{
cnt = 20; //reset counter
sec++; //秒计数自加 1
led = ! led; //work LED flash
//以下代码将 sec 按十进制位从低到高依次提取并转为数码管显示字符
LedBuff[0] = LedChar[sec/100000];
LedBuff[1] = LedChar[sec%100000/10000];
LedBuff[2] = LedChar[sec%100000%10000/1000];
LedBuff[3] = LedChar[sec%100000%10000%1000/100];
LedBuff[4] = LedChar[sec%100000%10000%1000%100/10];
LedBuff[5] = LedChar[sec%100000%10000%1000%100%10];
}
}
//延时函数
void delay(int xms)
{
unsigned int i,j;
for(i=xms;i>0;i--)
for(j=110;j>0;j--);
}
void main(){
unsigned char i = 0; //动态扫描的索引
ENLED = 0; //使能 U3,选择控制数码管
ADDR3 = 1; //因为需要动态改变 ADDR0-2 的值,所以不需要再初始化了

TMOD = 0x01; //设置 T0 为模式 1
TL0 = T50MS; //initial timer0 low byte
TH0 = T50MS >> 8;
TR0 = 1; //timer0 start running
ET0 = 1; //enable timer0 interrupt
EA = 1; //open global interrupt switch

while (1){
//以下代码完成数码管动态扫描刷新
switch (i){
case 0: ENLED=1;ADDR2=0; ADDR1=0; ADDR0=0; i++; P0=LedBuff[0]; delay(5);ENLED=0;break;
case 1: ENLED=1;ADDR2=0; ADDR1=0; ADDR0=1; i++; P0=LedBuff[1]; delay(5);ENLED=0;break;
case 2: ENLED=1;ADDR2=0; ADDR1=1; ADDR0=0; i++; P0=LedBuff[2]; delay(5);ENLED=0;break;
case 3: ENLED=1;ADDR2=0; ADDR1=1; ADDR0=1; i++; P0=LedBuff[3]; delay(5);ENLED=0;break;
case 4: ENLED=1;ADDR2=1; ADDR1=0; ADDR0=0; i++; P0=LedBuff[4]; delay(5);ENLED=0;break;
case 5: ENLED=1;ADDR2=1; ADDR1=0; ADDR0=1; i=0; P0=LedBuff[5]; delay(5);ENLED=0;break;
default: break;
}
P0=0xFF;//消隐
}
}


📚例程一仿真资源

  • 🔖 本示例基于Proteus8.12平台,保留Keil工程。

在这里插入图片描述

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

📓例程二

  • 📋将数码管的一个位用于毫秒计数显示。
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
#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
};//共阴数码管断码:0 - 9

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;
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;
}
}

🍁例程二资源文件

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


江城子 宋 苏轼
十年生死两茫茫,不思量,自难忘。千里孤坟,无处话凄凉。纵使相逢应不识,尘满面,鬓如霜。
夜来幽梦忽还乡,小轩窗,正梳妆。相顾无言,惟有泪千行。料得年年肠断处,明月夜,短松冈。