51单片机定时器秒计数时钟二+Proteus仿真

51单片机定时器秒计数时钟二+Proteus仿真


  • Proteus

采用蓝桥杯单片机Proteus模板仿真
在这里插入图片描述

实例代码

功能说明:电子钟,从左到右,1、2位为秒,3、4位为分,5、6位为时,7、8位为天

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
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
#include<reg52.h>

typedef unsigned char u8;
typedef unsigned int u16;

u8 LedChar[] ={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}; //共阳极数码管从0到9的真值
u8 LedBuff[] = {0xFF, 0xFF, 0xFF,0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; //数码管显示缓冲区,初值0xFF确保启动时都不亮
u8 flags = 1; //1秒定时标志

void TimeInit(); //定时器中断初始化函数
void HC138(u8 channel); //138译码器通道选择函数
void ShowSMG\_Bit(u8 date,u8 pos); //数码管显示函数

int main()
{
u8 sec = 0, minutes = 0, hours = 0, days = 0; //定义记录秒,分,时,天的变量
TimeInit(); //定时器中断初始化
while(1)
{
if(flags == 1) //判断1秒定时标志
{
flags = 0; //标志位清零
sec++; //秒加1
if(sec == 60) //判断秒变量到达60秒
{
sec = 0; //清0零
minutes++; //分钟位加1
}
if(minutes == 60) //判断达到60分
{
minutes = 0; //清零
hours++; //小时位加1
}
if(hours == 24) //判断达到24小时
{
hours = 0; //清零
days++; //天数加1
}
LedBuff[0]= LedChar[sec%10]; //秒的低位
LedBuff[1]= LedChar[sec/10%10]; //秒的高位
LedBuff[2]= LedChar[minutes%10]; //分钟的低位
LedBuff[3]= LedChar[minutes/10%10]; //分钟的高位
LedBuff[4]= LedChar[hours%10]; //小时的低位
LedBuff[5]= LedChar[hours/10%10]; //小时的高位
LedBuff[6]= LedChar[days%10]; //天数的低位
LedBuff[7]= LedChar[days/10%10]; //天数的高位
}
}
}

void TimeInit()
{
EA = 1; //打开中断总开关
ET0 = 1; //打开T0中断开关
TMOD = 0x01; //设置定时器工作在模式1
TH0=(65536-5000)/256; //高四位寄存器的值;//5000us=5ms
TL0=(65536-5000)%256; //低四位寄存器的值;
TR0 = 1; //允许定时器T0工作
}

void HC138(u8 channel)
{
switch(channel)
{
case 4:
P2 = (P2&0x1f)|0x80; //选择Y4对应模块(LED小灯) ,运算结果为P2高三位为100
break;
case 5:
P2 = (P2&0x1f)|0xa0; //选择Y5对应模块(蜂鸣器),运算结果为P2高三位为101
break;
case 6:
P2 = (P2&0x1f)|0xc0; //选择Y6对应模块(数码管的位选),运算结果为P2高三位为110
break;
case 7:
P2 = (P2&0x1f)|0xe0; //选择Y7对应模块(数码管的段选),运算结果为P2高三位为111
break;
}
}

void ShowSMG\_Bit(u8 date,u8 pos)
{
HC138(6); //Y6模块工作,数码管进行位选
P0 = 0x01<<pos; //数码管的位选传到P0口
HC138(7); //Y7模块工作,数码管进行段选
P0 = date; //当前数码管要显示数值对应的真值传到P0口
}

void InterruptTimer0() interrupt 1
{
static u8 i = 0; //动态扫描的索引
static u16 cnt = 0; //用来记录中断次数,设置的中断定时为1ms,中断200次即一秒钟

TH0=(65536-5000)/256; //高四位寄存器的值;//5000us=5ms
TL0=(65536-5000)%256; //低四位寄存器的值;
cnt++; //中断次数计数值加1
if(cnt>=200) //中断次数达到200次即为1秒
{
cnt = 0; //清零,重新记录中断次数
flags = 1; //设置1秒定时标志位1
}

P0 = 0xff; //消隐
switch(i) //根据动态索引i的值进行位选,依次点亮八个数码管
{
case 0 : i++; ShowSMG\_Bit(LedBuff[0],7); break; //最右边一位数码管(com8)对应P0^7口
case 1 : i++; ShowSMG\_Bit(LedBuff[1],6); break;
case 2 : i++; ShowSMG\_Bit(LedBuff[2],5); break;
case 3 : i++; ShowSMG\_Bit(LedBuff[3],4); break;
case 4 : i++; ShowSMG\_Bit(LedBuff[4],3); break;
case 5 : i++; ShowSMG\_Bit(LedBuff[5],2); break;
case 6 : i++; ShowSMG\_Bit(LedBuff[6],1); break;
case 7 : i=0; ShowSMG\_Bit(LedBuff[7],0); break;
default:break;
}
}


仿真资源和程序源码

1
2
3
链接:https://pan.baidu.com/s/1Tos88Rp\_22T7xJkzqrQbsg 
提取码:x2s1