本项目介绍如何使用51单片机设计并制作一个实用的电子时钟。通过编程和硬件组装,实现时间显示、校准等功能,适用于学习嵌入式系统开发的基础实践。
准确延时与数码管显示实现!应用于电子钟
```c
#include
// 函数声明
void long_delay(void); // 长延迟函数定义
void short_delay(void); // 短延迟函数定义
void delay10ms(unsigned char time); // 延时10MS的函数定义
void write7279(unsigned char cmd, unsigned char data);// 向HD7279写入数据的函数定义
unsigned char read7279(unsigned char command);// 从HD7279读取数据的函数定义
void send_byte(unsigned char byte); // 发送一个字节的函数定义
unsigned char receive_byte(void); // 接收一个字节的函数定义
void init_timer(); /* 定时器T0初始化 */
void conv(); /* 时、分、秒单元及走时单元转换 */
void dirve(); /* 时间显示程序 */
void time_adj(); /* 时间调整设置 */
// 全局变量声明
unsigned char digit[6]; // 数码管段位数组
unsigned char j; // 循环计数器
unsigned int tmr; // 定时器计数值
unsigned long wait_cnter;
unsigned char hour = 0, min = 0, sec = 0; /* 初始化时、分、秒为零 */
unsigned char deda = 0; /* 初始5ms计数单元清零 */
bit sign; // 设置标志位
// 定义引脚
sbit cs=P1^5;
sbit clk=P1^4;
sbit dat=P1^3;
sbit set=P3^7;
// HD7279A 指令定义
#define CMD_RESET 0xA4
#define CMD_TEST 0xBF
#define DECODE0 0x80
#define DECODE1 0xC8
#define CMD_READ 0x15
#define UNDECODE 0x90
#define RTL_CYCLE 0xA3
#define RTR_CYCLE 0xA2
#define RTL_UNCYL 0xA1
#define RTR_UNCYL 0xA0
#define ACTCTL 0x98
#define SEGON 0xE0
#define SEGOFF 0xC0
#define BLINKCTL 0x88
// 主函数定义
void main(void)
{
for(tmr = 0; tmr < 0x2000; tmr++); // 上电延时
send_byte(CMD_RESET); // 复位HD7279A
send_byte(CMD_TEST); // 测试指令发送
for(j = 0; j < 3; j++) delay10ms(100);
init_timer(); /* 定时器T0初始化 */
while (1)
{
if(set == 0) time_adj();
conv(); // 转换时间
dirve(); // 显示当前的时间
}
}
// 初始化定时器T0函数定义
void init_timer()
{
TMOD = 0x01;
TH0 = -(4800 / 256);
TL0 = -(4800 % 256);
IE = 0x82; // 开启定时器中断和外部中断
TR0 = 1; // 启动计数器T0
}
// 定时器T0的5ms定时中断服务子函数定义
void zd(void) interrupt 1
{
TH0 = -(4800 / 256);
TL0 = -(4800 % 256);
deda++;
}
// 时间转换程序定义
void conv()
{
if(deda >= 200)
{
sec++;
deda = 0;
}
if(sec == 60) { min++; sec=0; }
if(min == 60) { hour++; min=0; }
if(hour==24){hour=0;}
}
// 显示时间程序定义
void dirve()
{
digit[0] = sec % 10;
write7279(DECODE0, digit[0]);
digit[1] = 0x80 | (sec / 10);
write7279(DECODE0 + 1, digit[1]);
digit[2] = 0x80 | (min % 10);
write7279(DECODE0 + 2, digit[2]);
digit[3] = 0x80 | (min / 10);
write7279(DECODE0 + 3