设计一个时钟/秒表计时器的代码,要求:1、用51单片机完成设计,制作电子时钟可以显示时、分、秒。2、用6位LED数码管显示时、分、秒,以24h(小时)计时方式显示;3、通过按键进行时钟/秒表功能的转换,时钟计时每1s进行加1操作,秒表计时每10ms进行加1操作。4、按键实现计时启动、暂停及清零功能。5、具有倒计时功能,可以预设时间倒计时
时间: 2023-07-10 15:38:16 浏览: 67
以下是一个简单的时钟/秒表计时器的代码,使用51单片机,6位LED数码管显示时、分、秒,可以进行时钟/秒表功能转换,计时启动、暂停及清零功能,以及倒计时功能:
```
#include <reg51.h>
#define uint unsigned int
#define uchar unsigned char
sbit key1 = P3^1; // 按键1
sbit key2 = P3^2; // 按键2
sbit key3 = P3^3; // 按键3
uchar code table[] = { // 数码管显示字符对应的编码表
0x3f, // 0
0x06, // 1
0x5b, // 2
0x4f, // 3
0x66, // 4
0x6d, // 5
0x7d, // 6
0x07, // 7
0x7f, // 8
0x6f // 9
};
uchar hour = 0; // 小时
uchar minute = 0; // 分钟
uchar second = 0; // 秒钟
uchar count = 0; // 计数器
uchar mode = 1; // 模式:1=时钟,2=秒表,3=倒计时
uchar pause = 0; // 暂停标志:0=未暂停,1=已暂停
uchar reset = 0; // 清零标志:0=未清零,1=已清零
uchar set_hour = 0; // 倒计时设定小时数
uchar set_minute = 0; // 倒计时设定分钟数
uchar set_second = 0; // 倒计时设定秒钟数
void delay(uchar n) // 延时函数
{
uint i, j;
for (i = 0; i < n; i++)
for (j = 0; j < 1000; j++);
}
void display() // 数码管显示函数
{
uchar shiwei, gewei;
shiwei = hour / 10; // 小时的十位数
gewei = hour % 10; // 小时的个位数
P2 = 0xfe; // 选择第1位数码管,即最高位
P0 = table[shiwei]; // 显示小时的十位数
delay(1); // 延时1ms
P2 = 0xfd; // 选择第2位数码管
P0 = table[gewei]; // 显示小时的个位数
delay(1);
shiwei = minute / 10; // 分钟的十位数
gewei = minute % 10; // 分钟的个位数
P2 = 0xfb; // 选择第3位数码管
P0 = table[shiwei]; // 显示分钟的十位数
delay(1);
P2 = 0xf7; // 选择第4位数码管
P0 = table[gewei]; // 显示分钟的个位数
delay(1);
shiwei = second / 10; // 秒钟的十位数
gewei = second % 10; // 秒钟的个位数
P2 = 0xef; // 选择第5位数码管
P0 = table[shiwei]; // 显示秒钟的十位数
delay(1);
P2 = 0xdf; // 选择第6位数码管,即最低位
P0 = table[gewei]; // 显示秒钟的个位数
delay(1);
}
void timer() interrupt 1 // 定时器中断处理函数
{
TH0 = (65536 - 1000) / 256; // 重新设置定时器的初始值
TL0 = (65536 - 1000) % 256;
count++; // 计数器加1
if (mode == 1) // 时钟模式
{
if (count == 1000) // 每1s加1
{
count = 0;
second++;
if (second == 60)
{
second = 0;
minute++;
if (minute == 60)
{
minute = 0;
hour++;
if (hour == 24)
{
hour = 0;
}
}
}
}
}
else if (mode == 2) // 秒表模式
{
if (count == 10) // 每10ms加1
{
count = 0;
second++;
if (second == 60)
{
second = 0;
minute++;
if (minute == 60)
{
minute = 0;
hour++;
if (hour == 24)
{
hour = 0;
}
}
}
}
}
else if (mode == 3) // 倒计时模式
{
if (pause == 0 && reset == 0) // 未暂停且未清零
{
if (count == 1000) // 每1s减1
{
count = 0;
if (set_second > 0)
{
set_second--;
}
else if (set_second == 0 && set_minute > 0)
{
set_minute--;
set_second = 59;
}
else if (set_second == 0 && set_minute == 0 && set_hour > 0)
{
set_hour--;
set_minute = 59;
set_second = 59;
}
}
}
}
}
void main()
{
TMOD = 0x01; // 定时器0工作在模式1(16位自动重装载)
TH0 = (65536 - 1000) / 256; // 定时器0的初始值
TL0 = (65536 - 1000) % 256;
EA = 1; // 开启中断总开关
ET0 = 1; // 开启定时器0中断
TR0 = 1; // 启动定时器0
while (1)
{
display(); // 显示当前时间或倒计时剩余时间
if (key1 == 0) // 按键1
{
delay(10);
if (key1 == 0)
{
mode++; // 切换模式:1->2->3->1...
if (mode > 3)
{
mode = 1;
}
while (key1 == 0); // 等待按键松开
}
}
if (key2 == 0) // 按键2
{
delay(10);
if (key2 == 0)
{
if (pause == 0) // 未暂停
{
pause = 1; // 暂停
}
else
{
pause = 0; // 取消暂停
}
while (key2 == 0); // 等待按键松开
}
}
if (key3 == 0) // 按键3
{
delay(10);
if (key3 == 0)
{
if (reset == 0) // 未清零
{
reset = 1; // 清零
if (mode == 3) // 倒计时模式
{
set_hour = 0;
set_minute = 0;
set_second = 0;
}
}
else
{
reset = 0; // 取消清零
}
while (key3 == 0); // 等待按键松开
}
}
if (mode == 3 && reset == 0) // 倒计时模式且未清零
{
shiwei = set_hour / 10; // 设定小时的十位数
gewei = set_hour % 10; // 设定小时的个位数
P2 = 0xfe; // 选择第1位数码管,即最高位
P0 = table[shiwei]; // 显示设定小时的十位数
delay(1); // 延时1ms
P2 = 0xfd; // 选择第2位数码管
P0 = table[gewei]; // 显示设定小时的个位数
delay(1);
shiwei = set_minute / 10; // 设定分钟的十位数
gewei = set_minute % 10; // 设定分钟的个位数
P2 = 0xfb; // 选择第3位数码管
P0 = table[shiwei]; // 显示设定分钟的十位数
delay(1);
P2 = 0xf7; // 选择第4位数码管
P0 = table[gewei]; // 显示设定分钟的个位数
delay(1);
shiwei = set_second / 10; // 设定秒钟的十位数
gewei = set_second % 10; // 设定秒钟的个位数
P2 = 0xef; // 选择第5位数码管
P0 = table[shiwei]; // 显示设定秒钟的十位数
delay(1);
P2 = 0xdf; // 选择第6位数码管,即最低位
P0 = table[gewei]; // 显示设定秒钟的个位数
delay(1);
}
if (pause == 1) // 暂停
{
P2 = 0xff; // 关闭所有数码管
}
if (reset == 1) // 清零
{
hour = 0;
minute = 0;
second = 0;
count = 0;
pause = 0;
}
}
}
```