c51单片机0-9红绿灯倒计时用共阳八位数码管,且利用定时计数器实现精确秒
时间: 2023-06-14 08:05:15 浏览: 175
实现步骤如下:
1. 定义数码管端口及位选端口,并初始化为输出状态。
2. 定义倒计时所需的全局变量,包括计时器计数值、秒数、分数等。
3. 配置定时器,并开启定时器中断。定时器中断时间为1s,即计数器计满65536次后触发中断。
4. 在定时器中断服务函数中,每次中断时将计数器清零,同时将秒数减1,并更新数码管的显示值。
5. 在主函数中,先初始化数码管和定时器,并开启总中断开关,然后进入一个无限循环,等待中断服务函数的触发。
6. 在数码管显示函数中,将秒数转换为BCD码,并按照共阳数码管的驱动方式输出到数码管上。
下面是完整的代码示例:
```C
#include <reg51.h>
#define uchar unsigned char
#define uint unsigned int
// 数码管位选端口和段选端口
sbit dig_P1_7 = P1^7; // 数码管位选端口
sbit seg_P2_0 = P2^0; // 数码管段选端口
sbit seg_P2_1 = P2^1;
sbit seg_P2_2 = P2^2;
sbit seg_P2_3 = P2^3;
sbit seg_P2_4 = P2^4;
sbit seg_P2_5 = P2^5;
sbit seg_P2_6 = P2^6;
// 定时器计数值
uint timer_count = 0;
// 秒数、分数、计时标志位
uchar seconds = 60;
uchar minutes = 5;
uchar timer_flag = 0;
// 数码管显示函数
void display(uchar sec)
{
uchar bcd_sec = 0;
bcd_sec = ((sec / 10) << 4) + (sec % 10); // 将秒数转换为BCD码
dig_P1_7 = 1; // 显示百位
seg_P2_0 = 0;
seg_P2_1 = 0;
seg_P2_2 = 0;
seg_P2_3 = 1;
seg_P2_4 = 1;
seg_P2_5 = 1;
seg_P2_6 = 1;
P0 = bcd_sec / 100;
delay(5);
dig_P1_7 = 1; // 显示十位
seg_P2_0 = 1;
seg_P2_1 = 0;
seg_P2_2 = 0;
seg_P2_3 = 0;
seg_P2_4 = 1;
seg_P2_5 = 1;
seg_P2_6 = 0;
P0 = (bcd_sec % 100) / 10;
delay(5);
dig_P1_7 = 1; // 显示个位
seg_P2_0 = 1;
seg_P2_1 = 0;
seg_P2_2 = 0;
seg_P2_3 = 1;
seg_P2_4 = 1;
seg_P2_5 = 0;
seg_P2_6 = 1;
P0 = bcd_sec % 10;
delay(5);
}
// 定时器中断服务函数
void timer_isr() interrupt 1
{
TH0 = 0xFC; // 定时器初值,每隔1s触发中断
TL0 = 0x18;
timer_count++; // 计数器计数
if (timer_count >= 65536) // 计数器计满
{
timer_count = 0;
seconds--;
if (seconds == 0) // 秒数为0时,将分钟数减1
{
seconds = 60;
minutes--;
if (minutes == 0) // 倒计时结束
{
timer_flag = 1;
}
}
}
display(seconds); // 更新数码管显示值
}
// 延时函数
void delay(uint n)
{
uint i, j;
for (i = 0; i < n; i++)
for (j = 0; j < 125; j++);
}
// 主函数
void main()
{
TMOD = 0x01; // 定时器0工作模式1
TH0 = 0xFC; // 定时器初值,每隔1s触发中断
TL0 = 0x18;
ET0 = 1; // 允许定时器0中断
EA = 1; // 开启总中断开关
TR0 = 1; // 开启定时器0
P0 = 0xFF; // 数码管初始值
P1 = 0x00; // 数码管位选端口初始值
P2 = 0xFF; // 数码管段选端口初始值
while (1)
{
if (timer_flag) // 倒计时结束
{
P0 = 0xFF; // 关闭数码管显示
while (1); // 进入死循环
}
}
}
```
阅读全文