51单片机lcd1602电子时钟代码和仿真图
时间: 2023-09-28 07:07:20 浏览: 257
以下是51单片机LCD1602电子时钟的代码和仿真图:
代码:
```
#include <reg52.h>
// 定义LCD控制引脚
sbit RS = P2^0; // 指令/数据选择
sbit RW = P2^1; // 读/写选择
sbit EN = P2^2; // 使能信号
// 定义DS1302控制引脚
sbit SCLK = P3^3; // 时钟线
sbit RST = P3^4; // 复位线
sbit IO = P3^5; // 数据线
// 定义按键输入引脚
sbit KEY1 = P1^0; // 设置时间
sbit KEY2 = P1^1; // 调整时间
// 全局变量
unsigned char second, minute, hour; // 时间变量
// 函数声明
void init(); // 初始化函数
void lcd_init(); // 初始化LCD
void lcd_write_cmd(unsigned char cmd); // 写命令到LCD
void lcd_write_data(unsigned char dat); // 写数据到LCD
void lcd_show_time(); // 显示时间到LCD
void ds1302_write_byte(unsigned char dat); // 写一个字节到DS1302
unsigned char ds1302_read_byte(); // 读一个字节从DS1302
void ds1302_write(unsigned char addr, unsigned char dat); // 写一个字节到DS1302指定地址
unsigned char ds1302_read(unsigned char addr); // 读一个字节从DS1302指定地址
void ds1302_init(); // 初始化DS1302
void ds1302_set_time(); // 设置时间
void ds1302_get_time(); // 读取时间
void delay(unsigned int i); // 延时函数
void main() {
init(); // 初始化
while (1) {
ds1302_get_time(); // 读取时间
lcd_show_time(); // 显示时间
}
}
// 初始化函数
void init() {
lcd_init(); // 初始化LCD
ds1302_init(); // 初始化DS1302
}
// 初始化LCD
void lcd_init() {
lcd_write_cmd(0x38); // 设置16*2显示,5*7点阵,8位数据接口
lcd_write_cmd(0x0c); // 显示开,光标关,光标闪烁关
lcd_write_cmd(0x06); // 光标右移,整屏不移
lcd_write_cmd(0x01); // 清屏,光标复位
}
// 写命令到LCD
void lcd_write_cmd(unsigned char cmd) {
RS = 0; // 选择命令
RW = 0; // 写数据
P0 = cmd; // 数据线输出
EN = 1; // 使能信号
EN = 0; // 取消使能信号
}
// 写数据到LCD
void lcd_write_data(unsigned char dat) {
RS = 1; // 选择数据
RW = 0; // 写数据
P0 = dat; // 数据线输出
EN = 1; // 使能信号
EN = 0; // 取消使能信号
}
// 显示时间到LCD
void lcd_show_time() {
lcd_write_cmd(0x80); // 光标移到第一行第一列
lcd_write_data(hour/10+'0'); // 显示小时的十位数
lcd_write_data(hour%10+'0'); // 显示小时的个位数
lcd_write_data(':'); // 显示冒号
lcd_write_data(minute/10+'0'); // 显示分钟的十位数
lcd_write_data(minute%10+'0'); // 显示分钟的个位数
lcd_write_data(':'); // 显示冒号
lcd_write_data(second/10+'0'); // 显示秒钟的十位数
lcd_write_data(second%10+'0'); // 显示秒钟的个位数
}
// 写一个字节到DS1302
void ds1302_write_byte(unsigned char dat) {
unsigned char i;
for (i=0; i<8; i++) {
IO = dat & 0x01; // 取最低位
SCLK = 0; // 时钟线下降沿
SCLK = 1; // 时钟线上升沿
dat >>= 1; // 右移一位
}
}
// 读一个字节从DS1302
unsigned char ds1302_read_byte() {
unsigned char i, dat = 0;
for (i=0; i<8; i++) {
dat >>= 1; // 右移一位
if (IO) dat |= 0x80; // 如果数据线为高电平,则最高位为1
SCLK = 0; // 时钟线下降沿
SCLK = 1; // 时钟线上升沿
}
return dat;
}
// 写一个字节到DS1302指定地址
void ds1302_write(unsigned char addr, unsigned char dat) {
RST = 0; // 复位线低电平
SCLK = 0; // 时钟线低电平
RST = 1; // 复位线高电平
ds1302_write_byte(addr); // 写地址
ds1302_write_byte(dat); // 写数据
RST = 0; // 复位线低电平
}
// 读一个字节从DS1302指定地址
unsigned char ds1302_read(unsigned char addr) {
unsigned char dat;
RST = 0; // 复位线低电平
SCLK = 0; // 时钟线低电平
RST = 1; // 复位线高电平
ds1302_write_byte(addr); // 写地址
dat = ds1302_read_byte(); // 读数据
RST = 0; // 复位线低电平
return dat;
}
// 初始化DS1302
void ds1302_init() {
unsigned char i;
ds1302_write(0x8e, 0x00); // 关闭写保护
ds1302_write(0x80, 0x00); // 秒钟清零
ds1302_write(0x82, 0x00); // 分钟清零
ds1302_write(0x84, 0x00); // 小时清零
ds1302_write(0x8e, 0x80); // 开启写保护
}
// 设置时间
void ds1302_set_time() {
unsigned char i;
while (1) {
if (!KEY1) { // 如果按下设置时间键
delay(10); // 延时10ms
if (!KEY1) { // 如果仍然按下
hour++; // 小时加1
if (hour>=24) hour = 0; // 如果小时数超过23,则小时数清零
ds1302_write(0x8e, 0x00); // 关闭写保护
ds1302_write(0x84, hour); // 设置小时数
ds1302_write(0x8e, 0x80); // 开启写保护
while (!KEY1); // 等待松开按键
}
}
if (!KEY2) { // 如果按下调整时间键
delay(10);
if (!KEY2) {
minute++; // 分钟加1
if (minute>=60) minute = 0; // 如果分钟数超过59,则分钟数清零
ds1302_write(0x8e, 0x00);
ds1302_write(0x82, minute); // 设置分钟数
ds1302_write(0x8e, 0x80);
while (!KEY2);
}
}
ds1302_get_time(); // 读取时间
lcd_show_time(); // 显示时间
}
}
// 读取时间
void ds1302_get_time() {
second = ds1302_read(0x81); // 读秒钟数
minute = ds1302_read(0x83); // 读分钟数
hour = ds1302_read(0x85); // 读小时数
}
// 延时函数
void delay(unsigned int i) {
unsigned int j;
for (j=0; j<i; j++);
}
```
仿真图:
![51单片机LCD1602电子时钟仿真图](https://img-blog.csdn.net/20180130203456723)
阅读全文