C52LED电子时钟设计
时间: 2024-01-09 12:05:02 浏览: 100
以下是C52 LED电子时钟设计的相关信息:
1. 该电子时钟采用STC89C52单片机和LED点阵显示,能够显示当前的月、日、时、分、秒,24小时制。
2. 月、日、时、分、秒均可以单独设置,设置时该项目闪烁。
3. 外接3个按键,一个用于选择需要设置的项目,一个增加、一个减少。
4. 该电子时钟基于定时器实现时间的计时,利用按钮调节模式切换,设置闹钟,调节时间等功能。
以下是C52 LED电子时钟设计的代码演示:
```c
#include <reg52.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
uchar code table[] = {0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f}; // 数码管显示0~9的编码
uchar sec = 0, min = 0, hour = 0, day = 1, month = 1, year = 20; // 定义秒、分、时、日、月、年
uchar alarm_hour = 0, alarm_min = 0; // 定义闹钟的小时和分钟
uchar mode = 0; // 定义模式,0为时间模式,1为设置模式,2为闹钟模式
uchar set_pos = 0; // 定义设置的位置,0为设置小时,1为设置分钟,2为设置月份,3为设置日期,4为设置年份
uchar key_value = 0; // 定义按键值,0为没有按键按下,1为K1按下,2为K2按下,3为K3按下
sbit LSA = P2^2; // 数码管LSA引脚
sbit LSB = P2^3; // 数码管LSB引脚
sbit LSC = P2^4; // 数码管LSC引脚
sbit SDA = P3^4; // IIC总线数据线
sbit SCL = P3^5; // IIC总线时钟线
void delay(uint i) // 延时函数
{
while(i--);
}
void write_byte(uchar dat) // 向IIC总线写入一个字节
{
uchar i;
for(i = 0; i < 8; i++)
{
SDA = dat >> 7; // 先发送高位
dat <<= 1;
SCL = 1;
_nop_();
_nop_();
SCL = 0;
}
SDA = 1; // 释放数据线
}
uchar read_byte() // 从IIC总线读取一个字节
{
uchar i, dat = 0;
SDA = 1; // 先释放数据线
for(i = 0; i < 8; i++)
{
dat <<= 1;
SCL = 1;
_nop_();
_nop_();
dat |= SDA; // 读取数据线上的数据
SCL = 0;
}
return dat;
}
void iic_start() // IIC总线起始信号
{
SDA = 1;
SCL = 1;
_nop_();
_nop_();
SDA = 0;
_nop_();
_nop_();
SCL = 0;
}
void iic_stop() // IIC总线停止信号
{
SDA = 0;
SCL = 1;
_nop_();
_nop_();
SDA = 1;
_nop_();
_nop_();
}
void ds1307_write(uchar addr, uchar dat) // 向DS1307写入一个字节
{
iic_start();
write_byte(0xd0); // 发送写地址
write_byte(addr); // 发送寄存器地址
write_byte(dat); // 发送数据
iic_stop();
}
uchar ds1307_read(uchar addr) // 从DS1307读取一个字节
{
uchar dat;
iic_start();
write_byte(0xd0); // 发送写地址
write_byte(addr); // 发送寄存器地址
iic_start();
write_byte(0xd1); // 发送读地址
dat = read_byte(); // 读取数据
iic_stop();
return dat;
}
void init_ds1307() // 初始化DS1307
{
ds1307_write(0x00, 0x00); // 秒清零
ds1307_write(0x01, 0x00); // 分钟清零
ds1307_write(0x02, 0x00); // 小时清零
ds1307_write(0x03, 0x01); // 星期一
ds1307_write(0x04, 0x01); // 1号
ds1307_write(0x05, 0x01); // 1月
ds1307_write(0x06, 0x21); // 2021年
}
void display_time() // 显示时间
{
uchar i;
uchar dis_buf[8] = {0}; // 显示缓存
dis_buf[0] = table[hour / 10];
dis_buf[1] = table[hour % 10];
dis_buf[2] = 0x40;
dis_buf[3] = table[min / 10];
dis_buf[4] = table[min % 10];
dis_buf[5] = 0x40;
dis_buf[6] = table[sec / 10];
dis_buf[7] = table[sec % 10];
for(i = 0; i < 8; i++)
{
switch(i)
{
case(0): LSA = 0; LSB = 0; LSC = 0; break;
case(1): LSA = 1; LSB = 0; LSC = 0; break;
case(2): LSA = 0; LSB = 1; LSC = 0; break;
case(3): LSA = 1; LSB = 1; LSC = 0; break;
case(4): LSA = 0; LSB = 0; LSC = 1; break;
case(5): LSA = 1; LSB = 0; LSC = 1; break;
case(6): LSA = 0; LSB = 1; LSC = 1; break;
case(7): LSA = 1; LSB = 1; LSC = 1; break;
}
P0 = dis_buf[i];
delay(100);
P0 = 0x00;
}
}
void key_scan() // 按键扫描
{
if(K1 == 0) // K1按下
{
delay(1000);
if(K1 == 0)
{
key_value = 1;
while(!K1);
}
}
else if(K2 == 0) // K2按下
{
delay(1000);
if(K2 == 0)
{
key_value = 2;
while(!K2);
}
}
else if(K3 == 0) // K3按下
{
delay(1000);
if(K3 == 0)
{
key_value = 3;
while(!K3);
}
}
}
void set_time() // 设置时间
{
switch(set_pos)
{
case(0): // 设置小时
if(key_value == 1) // K1按下
{
hour++;
if(hour > 23) hour = 0;
}
else if(key_value == 2) // K2按下
{
hour--;
if(hour > 23) hour = 23;
}
break;
case(1): // 设置分钟
if(key_value == 1) // K1按下
{
min++;
if(min > 59) min = 0;
}
else if(key_value == 2) // K2按下
{
min--;
if(min > 59) min = 59;
}
break;
case(2): // 设置月份
if(key_value == 1) // K1按下
{
month++;
if(month > 12) month = 1;
}
else if(key_value == 2) // K2按下
{
month--;
if(month > 12) month = 12;
}
break;
case(3): // 设置日期
if(key_value == 1) // K1按下
{
day++;
if(day > 31) day = 1;
}
else if(key_value == 2) // K2按下
{
day--;
if(day > 31) day = 31;
}
break;
case(4): // 设置年份
if(key_value == 1) // K1按下
{
year++;
if(year > 99) year = 0;
}
else if(key_value == 2) // K2按下
{
year--;
if(year > 99) year = 99;
}
break;
}
}
void set_alarm() // 设置闹钟
{
if(key_value == 1) // K1按下
{
alarm_hour++;
if(alarm_hour > 23) alarm_hour = 0;
}
else if(key_value == 2) // K2按下
{
alarm_min++;
if(alarm_min > 59) alarm_min = 0;
}
}
void main()
{
init_ds1307(); // 初始化DS1307
while(1)
{
key_scan(); // 按键扫描
if(mode == 0) // 时间模式
{
sec = ds1307_read(0x00); // 读取秒
min = ds1307_read(0x01); // 读取分
hour = ds1307_read(0x02); // 读取时
display_time(); // 显示时间
if(key_value == 1) // K1按下,进入设置模式
{
mode = 1;
set_pos = 0;
key_value = 0;
}
else if(key_value == 2) // K2按下,进入闹钟模式
{
mode = 2;
key_value = 0;
}
if(alarm_hour == hour && alarm_min == min) // 判断是否到达闹钟时间
{
P1 = 0xff; // 发出警报
}
else
{
P1 = 0x00;
}
}
else if(mode == 1) // 设置模式
{
set_time(); // 设置时间
display_time(); // 显示时间
if(key_value == 1) // K1按下,切换到下一个设置位置
{
set_pos++;
if(set_pos > 4) // 所有设置位置都设置完毕,退出设置模式
{
mode = 0;
ds1307_write(0x00, sec); // 写入秒
ds1307_write(0x01, min); // 写入分
ds1307_write(0x02, hour); // 写入时
ds1307_write(0x03, 0x01); // 星期一
ds1307_write(0x04, day); // 写入日
ds1307_write(0x05, month); // 写入月
ds1307_write(0x06, year); // 写入年
}
key_value = 0;
}
else if(key_value == 2) // K2按下,退出设置模式
{
mode = 0;
key_value = 0;
}
}
else if(mode == 2) // 闹钟模式
{
set_alarm(); // 设置闹钟
P0 = table[alarm_hour / 10];
delay(100);
P0 = table[alarm_hour % 10];
delay(100);
P0 = 0x40;
delay(100);
P0 = table[alarm_min / 10];
delay(100);
P0 = table[alarm_min % 10];
delay(100);
P0 = 0x40;
delay(100);
if(key_value == 2) // K2按下,退出闹钟模式
{
mode = 0;
key_value = 0;
}
}
}
}
```
阅读全文