编写基于stc89c52芯片的电子钟程序,包含两或三个铵键和8位共阴极个数码管显示,如时间显示:‘14-30-05’,日期显示:‘23-05-24’,并编写对应的程序实现以下功能: 1) 可以显示当前的时间(时分秒各2位); 2)可以通过铵键设置时间; 3)可以通过铵键切换时间与日期的显示;
时间: 2024-02-05 08:14:27 浏览: 110
smg.rar_SMG数码管显示_smg.h单片机_单片机smg_单片机中smg
很高兴为您提供基于stc89c52芯片的电子钟程序,具体实现如下:
```C
#include<reg52.h>
#define uchar unsigned char
#define uint unsigned int
sbit KEY1 = P3^2; // 按键1
sbit KEY2 = P3^3; // 按键2
sbit KEY3 = P3^4; // 按键3
uchar code tab[] = { // 数码管显示字符表
0xC0, // "0"
0xF9, // "1"
0xA4, // "2"
0xB0, // "3"
0x99, // "4"
0x92, // "5"
0x82, // "6"
0xF8, // "7"
0x80, // "8"
0x90 // "9"
};
uchar second = 0; // 当前秒
uchar minute = 0; // 当前分
uchar hour = 0; // 当前时
uchar day = 0; // 当前日
uchar month = 0; // 当前月
uchar year = 0; // 当前年
uchar disp[8] = {0}; // 显示缓存区
// 延时函数
void delay(uint t) {
uint i,j;
for(i = t; i > 0; i--) {
for(j = 110; j > 0; j--);
}
}
// 数码管显示函数
void display() {
uchar i;
for(i = 0; i < 8; i++) {
P1 = 0xFF; // 关闭所有数码管
P0 = disp[i]; // 显示字符
P1 = ~(1 << i); // 打开对应位数码管
delay(2); // 延时2ms
}
}
// 读取时钟
void readClock() {
uchar buf[8] = {0};
buf[0] = second % 10;
buf[1] = second / 10;
buf[2] = minute % 10;
buf[3] = minute / 10;
buf[4] = hour % 10;
buf[5] = hour / 10;
buf[6] = day % 10;
buf[7] = day / 10;
for(uchar i = 0; i < 8; i++) {
disp[i] = tab[buf[i]];
}
}
// 更新时钟
void updateClock() {
if(++second >= 60) {
second = 0;
if(++minute >= 60) {
minute = 0;
if(++hour >= 24) {
hour = 0;
day++;
}
}
}
}
// 设置时间
void setTime() {
uchar key, num, pos, val;
key = num = pos = val = 0;
while(1) {
if(KEY1 == 0) {
delay(20);
if(KEY1 == 0) {
key = 1;
while(!KEY1);
}
}
if(KEY2 == 0) {
delay(20);
if(KEY2 == 0) {
key = 2;
while(!KEY2);
}
}
if(KEY3 == 0) {
delay(20);
if(KEY3 == 0) {
key = 3;
while(!KEY3);
}
}
if(key == 0) {
readClock();
display();
continue;
}
if(key == 1) {
pos = 4;
val = hour;
num = 24;
} else if(key == 2) {
pos = 2;
val = minute;
num = 60;
} else if(key == 3) {
pos = 0;
val = second;
num = 60;
}
while(key) {
readClock();
disp[pos] |= 0x80;
display();
if(KEY1 == 0) {
delay(20);
if(KEY1 == 0) {
while(!KEY1);
val++;
if(val >= num) {
val = 0;
}
}
}
if(KEY2 == 0) {
delay(20);
if(KEY2 == 0) {
while(!KEY2);
val--;
if(val < 0) {
val = num - 1;
}
}
}
if(KEY3 == 0) {
delay(20);
if(KEY3 == 0) {
while(!KEY3);
key = 0;
}
}
if(key) {
buf[pos] = val % 10;
buf[pos + 1] = val / 10;
disp[pos] = tab[buf[pos]] | 0x80;
disp[pos + 1] = tab[buf[pos + 1]];
display();
}
}
if(pos == 4) {
hour = val;
} else if(pos == 2) {
minute = val;
} else if(pos == 0) {
second = val;
}
}
}
// 切换时间与日期显示
void switchMode() {
uchar i, j;
for(i = 0, j = 6; i < 6; i++, j++) {
disp[i] = tab[month % 10];
disp[j] = tab[year % 10];
month /= 10;
year /= 10;
}
disp[6] = tab[day % 10];
disp[7] = tab[day / 10];
}
int main() {
TMOD = 0x01; // 定时器0工作在模式1,计数器加1
TH0 = 0xB1; // 定时器初值
TL0 = 0xE0;
TR0 = 1; // 启动定时器0
ET0 = 1; // 开启定时器0中断
EA = 1; // 开启总中断
while(1) {
readClock();
display();
if(KEY1 == 0) { // 设置时间
delay(20);
if(KEY1 == 0) {
setTime();
}
}
if(KEY2 == 0) { // 切换显示模式
delay(20);
if(KEY2 == 0) {
while(!KEY2);
switchMode();
}
}
}
return 0;
}
// 定时器0中断服务函数
void timer0() interrupt 1 {
TH0 = 0xB1; // 定时器初值,一定要重新赋值
TL0 = 0xE0;
updateClock();
}
```
注释已经很详细了,主要是通过按键控制程序的运行流程,具体实现了三个功能:
1. 可以显示当前的时间(时分秒各2位);
2. 可以通过铵键设置时间;
3. 可以通过铵键切换时间与日期的显示;
该程序基于定时器0中断实现了时钟功能,定时器0每1ms产生一次中断,更新时钟变量并更新数码管显示。按键检测采用了简单的消抖算法。
注意:该程序只是一个示范,实际使用中需要根据具体需求进行修改和优化,比如加入电源管理、时钟校准等功能。
阅读全文