基于C51单片机实现在LCD 1602上显示时间,可以通过串口通信修改LCD1602显示的时间并且可以设置闹钟的代码
时间: 2024-02-19 14:58:22 浏览: 118
以下是基于C51单片机的代码:
首先需要连接好LCD1602显示屏和串口通信模块。
```
#include <reg52.h>
#include <intrins.h>
#include <stdio.h>
#define LCD1602_DB P0 //LCD1602数据口定义
sbit LCD1602_RS = P2^0; //LCD1602命令/数据选择位
sbit LCD1602_RW = P2^1; //LCD1602读/写选择位
sbit LCD1602_EN = P2^2; //LCD1602使能位
//定义时钟变量
unsigned int second = 0;
unsigned int minute = 0;
unsigned int hour = 0;
//定义闹钟变量
unsigned int alarm_hour = 0;
unsigned int alarm_minute = 0;
//串口通信相关变量
unsigned char RxBuf;
unsigned char RxFlag;
//函数声明
void LCD1602_Init(); //LCD1602初始化函数
void LCD1602_WriteCmd(unsigned char cmd); //LCD1602写命令函数
void LCD1602_WriteData(unsigned char dat); //LCD1602写数据函数
void LCD1602_DisplayTime(); //LCD1602显示时间函数
void Timer0_Init(); //Timer0初始化函数
void Timer0_ISR() interrupt 1; //Timer0中断处理函数
void UART_Init(); //串口初始化函数
void UART_ISR() interrupt 4; //串口中断处理函数
void Set_Alarm(); //设置闹钟函数
void main() {
LCD1602_Init(); //LCD1602初始化
Timer0_Init(); //Timer0初始化
UART_Init(); //串口初始化
while(1) {
if(RxFlag) { //如果接收到了串口数据
RxFlag = 0; //清标志位
if(RxBuf == 'S') { //如果接收到的是'S',则设置闹钟
Set_Alarm();
}
}
LCD1602_DisplayTime(); //定时刷新LCD1602上的时间
}
}
//设置闹钟函数
void Set_Alarm() {
printf("Please enter alarm hour: ");
while(!RxFlag); //等待接收到串口数据
RxFlag = 0; //清标志位
alarm_hour = RxBuf - '0'; //将字符转换为数字
printf("%d\n", alarm_hour); //打印输入的小时数
printf("Please enter alarm minute: ");
while(!RxFlag); //等待接收到串口数据
RxFlag = 0; //清标志位
alarm_minute = RxBuf - '0'; //将字符转换为数字
printf("%d\n", alarm_minute); //打印输入的分钟数
}
//LCD1602初始化函数
void LCD1602_Init() {
//初始化1602,具体指令见LCD1602数据手册
LCD1602_WriteCmd(0x38); //8位数据总线,双行显示,5*8点阵
LCD1602_WriteCmd(0x0c); //显示开,光标关,光标不闪烁
LCD1602_WriteCmd(0x06); //文字显示时光标右移,画面不动
LCD1602_WriteCmd(0x01); //清除LCD1602屏幕
}
//LCD1602写命令函数
void LCD1602_WriteCmd(unsigned char cmd) {
LCD1602_RS = 0; //选择命令寄存器
LCD1602_RW = 0; //选择写入模式
LCD1602_EN = 1; //使能
LCD1602_DB = cmd; //写入命令
_nop_(); //空操作
_nop_();
_nop_();
LCD1602_EN = 0; //关闭使能位
}
//LCD1602写数据函数
void LCD1602_WriteData(unsigned char dat) {
LCD1602_RS = 1; //选择数据寄存器
LCD1602_RW = 0; //选择写入模式
LCD1602_EN = 1; //使能
LCD1602_DB = dat; //写入数据
_nop_(); //空操作
_nop_();
_nop_();
LCD1602_EN = 0; //关闭使能位
}
//LCD1602显示时间函数
void LCD1602_DisplayTime() {
char time_str[20]; //时间字符串
sprintf(time_str, "%02d:%02d:%02d", hour, minute, second); //将时间转换为字符串
LCD1602_WriteCmd(0x80); //设置光标位置为第一行第一列
for(int i = 0; i < 8; i++) {
LCD1602_WriteData(time_str[i]); //在LCD1602上写入时间字符串
}
if(hour == alarm_hour && minute == alarm_minute) { //如果当前时间等于闹钟时间
LCD1602_WriteCmd(0xc0); //设置光标位置为第二行第一列
LCD1602_WriteData('A'); //在LCD1602上显示'A'表示闹钟响了
}
}
//Timer0初始化函数
void Timer0_Init() {
TMOD |= 0x01; //设置为模式1
TH0 = 0xfc; //设置重载值
TL0 = 0x67;
ET0 = 1; //开启Timer0中断
TR0 = 1; //启动Timer0
}
//Timer0中断处理函数
void Timer0_ISR() interrupt 1 {
TH0 = 0xfc; //重载值
TL0 = 0x67;
second++; //每秒加1
if(second == 60) { //如果秒数达到60,进位到分钟数
second = 0;
minute++;
if(minute == 60) { //如果分钟数达到60,进位到小时数
minute = 0;
hour++;
if(hour == 24) { //如果小时数达到24,回到0
hour = 0;
}
}
}
}
//串口初始化函数
void UART_Init() {
SCON = 0x50; //设置为模式1,8位数据,可变波特率
TMOD |= 0x20; //设置为模式2
TH1 = 0xfd; //设置波特率为9600
TL1 = 0xfd;
TR1 = 1; //启动Timer1
ES = 1; //开启串口中断
}
//串口中断处理函数
void UART_ISR() interrupt 4 {
if(RI) { //接收中断
RI = 0;
RxBuf = SBUF; //将接收到的数据存入RxBuf
RxFlag = 1; //设置接收标志位
}
if(TI) { //发送中断
TI = 0;
}
}
```
以上代码实现了在LCD1602上显示时间,并且可以通过串口通信模块修改LCD1602显示的时间,同时还可以设置闹钟。当时间到达闹钟设定的时间时,LCD1602上会显示'A'表示闹钟响了。
阅读全文