51单片机数码管显示时间代码详解
以下是一个基于51单片机的数码管显示时间的代码示例,具体细节可以根据具体的硬件和需求进行调整和修改。
#include <reg51.h>
#define uchar unsigned char
#define uint unsigned int
uchar code table[] = { // 数码管显示表
0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f,
0x77, 0x7c, 0x39, 0x5e, 0x79, 0x71
};
sbit DIO = P2^0; // 74HC595 数据线
sbit RCLK = P2^1; // 74HC595 锁存线
sbit SCLK = P2^2; // 74HC595 时钟线
uchar hour, minute, second; // 时间变量
void delay(uint t) { // 延时函数
uint i, j;
for (i = t; i > 0; i--) {
for (j = 110; j > 0; j--);
}
}
void writeByte(uchar dat) { // 向74HC595写入一个字节
uchar i;
for (i = 0; i < 8; i++) {
DIO = dat >> 7; // 取最高位
dat <<= 1; // 移位
SCLK = 0; // 拉低时钟线
SCLK = 1; // 拉高时钟线
}
}
void initShiftReg(void) { // 初始化74HC595
DIO = 0;
SCLK = 0;
RCLK = 0;
}
void display(uchar hour, uchar minute, uchar second) { // 在数码管上显示时间
uchar i, j;
uchar code pos[] = { // 数码管位选表
0xfe, 0xfd, 0xfb, 0xf7, 0xef, 0xdf
};
uchar data[] = { // 数码管数据表
table[hour / 10], table[hour % 10],
table[minute / 10], table[minute % 10],
table[second / 10], table[second % 10]
};
for (i = 0; i < 6; i++) {
RCLK = 0;
writeByte(pos[i]); // 选择数码管
writeByte(data[i]); // 设置数码管数据
RCLK = 1; // 锁存数据
delay(1); // 延时一段时间,使数字更清晰
RCLK = 0; // 清零锁存线
for (j = 0; j < 6; j++) {
P0 = 0xff; // 关闭所有数码管
}
P0 = 0x01 << i; // 打开当前数码管
delay(1); // 延时一段时间,使数字更清晰
}
}
void main(void) {
TMOD = 0x01; // 定时器0工作在模式1
TH0 = 0xfc; // 定时器0初值
TL0 = 0x18;
TR0 = 1; // 启动定时器0
ET0 = 1; // 允许定时器0中断
EA = 1; // 允许总中断
initShiftReg();
while (1) {
display(hour, minute, second);
}
}
void timer0_isr(void) interrupt 1 { // 定时器0中断服务程序
TH0 = 0xfc; // 重新设置定时器0初值
TL0 = 0x18;
second++; // 秒数加1
if (second == 60) { // 如果秒数达到60,进位到分钟
second = 0;
minute++;
if (minute == 60) { // 如果分钟达到60,进位到小时
minute = 0;
hour++;
if (hour == 24) { // 如果小时达到24,归零
hour = 0;
}
}
}
}
该代码使用74HC595芯片驱动数码管显示时间,通过定时器0实现时间的计时和中断服务程序的调用,通过位选和数据线分别向74HC595写入数码管位选和数据,实现时间的在数码管上的显示。其中,需要注意的是,由于74HC595芯片的输出是低电平有效的,因此在写入数据时需要取反。
原文地址: https://www.cveoy.top/t/topic/l3aK 著作权归作者所有。请勿转载和采集!