当前位置: 首页 > news >正文

10【模块学习】LCD1602(二):6路温度显示+实时时钟

项目:6路温度显示+实时时钟

  • 1、6路温度显示
    • ①TempMenu.c文件的代码
    • ②TempMenu.h文件的代码
    • ③main.c文件的代码
    • ④Timer.c文件的代码
    • ⑤Delay.c文件的代码
    • ⑥Key.c文件的代码
  • 2、实时时钟显示
    • ①BeiJingTime.c文件的代码
    • ②BeiJingTime.h文件的代码
    • ③main.c文件的代码如下
    • ④Timer.c文件的代码

1、6路温度显示

在这里插入图片描述

项目描述:
①单片机启动时,LCD1602显示启动界面 “TEMP MENU”
②显示1s后,自动跳转到显示温度数据。一次显示界面显示2路温度数据
③LCD1602显示温度分为自动模式和手动模式,在自动模式下:每隔1s跳转显示。
④使用按键KEY2切换自动模式和手动模式,切换时显示为“Automa”表示切换为自动模式,显示为“Manual”表示手动模式
⑤在手动模式下:按键KEY1用于切换温度显示
⑥按键KEY4用于切换为设置不同通道温度阈值模式,进入设置模式后,按键KEY1为增加温度阈值,KEY2为减小温度阈值,KEY3确定阈值并且退出设置模式

项目演示:

QQ2025415-112215

①TempMenu.c文件的代码

#include "TempMenu.h"/* 定义6路 CH1~CH6 温度缓存区 */
float Temp[] = {15.23, 21.55, 25.41, 22.77, 27.14, 22.34};/* 定义CH1~CH6通道温度阈值 */		
unsigned char ThreTemp[] = {11, 12, 13, 14, 15, 16};unsigned char Waring_CHNum = 0;/*** 温度菜单开机显示*/
void Temp_StartMenu(void)
{LCD_ShowString(1,1,"    TEMP MENU     ");LCD_ShowString(2,1,"      V1.0        ");
}/*** 显示℃字符函数*/
void SHOW_C(unsigned char Hang, unsigned char Lie)
{LCD_ShowChar(Hang, Lie, 0xdf);LCD_ShowChar(Hang, Lie + 1, 0x43);
}/*** 显示CH1 CH2通道的温度*/
void SHOW_CH1_CH2(void)
{/* 显示CH1通道的温度 */LCD_ShowString(1,1,"CH1:");LCD_ShowFloat(1,5,Temp[0],2,2);SHOW_C(1,11);LCD_ShowString(1,14,"    ");//清除上一次显示的残留字符/* 显示CH2通道的温度 */LCD_ShowString(2,1,"CH2:");LCD_ShowFloat(2,5,Temp[1],2,2);SHOW_C(2,11);LCD_ShowString(2,13,"    ");
}/*** 显示CH3 CH4通道的温度*/
void SHOW_CH3_CH4(void)
{/* 显示CH3通道的温度 */LCD_ShowString(1,1,"CH3:");LCD_ShowFloat(1,5,Temp[2],2,2);SHOW_C(1,11);/* 显示CH4通道的温度 */LCD_ShowString(2,1,"CH4:");LCD_ShowFloat(2,5,Temp[3],2,2);SHOW_C(2,11);
}/*** 显示CH5 CH6通道的温度*/
void SHOW_CH5_CH6(void)
{/* 显示CH5通道的温度 */LCD_ShowString(1,1,"CH5:");LCD_ShowFloat(1,5,Temp[4],2,2);SHOW_C(1,11);/* 显示CH6通道的温度 */LCD_ShowString(2,1,"CH6:");LCD_ShowFloat(2,5,Temp[5],2,2);SHOW_C(2,11);
}/*** 显示设置CH1通道阈值界面*/
void SHOW_SetCH1Temp(void)
{LCD_ShowString(1,1,"     SETING     ");/* 显示被设置CH1通道的温度 */LCD_ShowString(2,1,"CH1:");LCD_ShowFloat(2,5,ThreTemp[0],2,2);SHOW_C(2,11);LCD_ShowString(2,13,"    ");
}/*** 显示设置CH2通道阈值界面*/
void SHOW_SetCH2Temp(void)
{LCD_ShowString(1,1,"     SETING     ");/* 显示被设置CH2通道的温度 */LCD_ShowString(2,1,"CH2:");LCD_ShowFloat(2,5,ThreTemp[1],2,2);SHOW_C(2,11);LCD_ShowString(2,13,"    ");
}/*** 显示设置CH3通道阈值界面*/
void SHOW_SetCH3Temp(void)
{LCD_ShowString(1,1,"     SETING     ");/* 显示被设置CH3通道的温度 */LCD_ShowString(2,1,"CH3:");LCD_ShowFloat(2,5,ThreTemp[2],2,2);SHOW_C(2,11);LCD_ShowString(2,13,"    ");
}/*** 显示设置CH4通道阈值界面*/
void SHOW_SetCH4Temp(void)
{LCD_ShowString(1,1,"     SETING     ");/* 显示被设置CH4通道的温度 */LCD_ShowString(2,1,"CH4:");LCD_ShowFloat(2,5,ThreTemp[3],2,2);SHOW_C(2,11);LCD_ShowString(2,13,"    ");
}/*** 显示设置CH5通道阈值界面*/
void SHOW_SetCH5Temp(void)
{LCD_ShowString(1,1,"     SETING     ");/* 显示被设置CH5通道的温度 */LCD_ShowString(2,1,"CH5:");LCD_ShowFloat(2,5,ThreTemp[4],2,2);SHOW_C(2,11);LCD_ShowString(2,13,"    ");
}/*** 显示设置CH6通道阈值界面*/
void SHOW_SetCH6Temp(void)
{LCD_ShowString(1,1,"     SETING     ");/* 显示被设置CH6通道的温度 */LCD_ShowString(2,1,"CH6:");LCD_ShowFloat(2,5,ThreTemp[5],2,2);SHOW_C(2,11);LCD_ShowString(2,13,"    ");
}/*** 显示报警界面*/
void SHOW_Waring(void)
{LCD_ShowString(1,1,"      WARING     ");/* 显示被设置CH6通道的温度 */LCD_ShowString(2,1,"WaR CH Num:");LCD_ShowNum(2, 12, Waring_CHNum,2);
}

②TempMenu.h文件的代码

#ifndef __TempMen_H
#define __TempMen_H
#include "LCD1602.h"void Temp_StartMenu(void);
void SHOW_C(unsigned char Hang, unsigned char Lie);
void SHOW_CH1_CH2(void);
void SHOW_CH3_CH4(void);
void SHOW_CH5_CH6(void);void SHOW_SetCH1Temp(void);
void SHOW_SetCH2Temp(void);
void SHOW_SetCH3Temp(void);
void SHOW_SetCH4Temp(void);
void SHOW_SetCH5Temp(void);
void SHOW_SetCH6Temp(void);void SHOW_Waring(void);#endif

③main.c文件的代码

#include "LCD1602.h"
#include "TempMenu.h"
#include "Key.h"
#include "Delay.h"
#include "Timer.h"extern char ThreTemp[];			//CH1~CH6通道温度阈值
static char SET_Channel = 0;	//设置模式下通道切换变量
static char Seting_Flag = 0;	//进入设置模式标志位
char Menu_Status = 0;			//状态变量
bit Mode = 0;					//0表示自动模式,1表示手动模式void KEY_ChangeMenu(void);
void SHOW_CHange(void);void main(void)
{LCD_Init();	Time0_Intrrupt_Init();Temp_StartMenu();		//开机显示1sDelay_s(1);LCD_WriteCommand(0x01);	//清屏while(1){KEY_ChangeMenu();SHOW_CHange();}
}/*** 按键切换菜单函数*/
void KEY_ChangeMenu(void)
{switch(Key_Scanf()){case 1:									//按键1按下if(!Seting_Flag)					//没有进入设置模式{Menu_Status++;					//按下KEY1改变Menu_Statusif(Menu_Status >= 4)Menu_Status = 0;}else								//在设置模式下{switch(SET_Channel)				//按下KEY1增加温度阈值{case 1:ThreTemp[0]++;break;	//增加CH1的温度阈值case 2:ThreTemp[1]++;break;	//增加CH2的温度阈值case 3:ThreTemp[2]++;break;	//增加CH3的温度阈值case 4:ThreTemp[3]++;break;	//增加CH4的温度阈值case 5:ThreTemp[4]++;break;	//增加CH5的温度阈值case 6:ThreTemp[5]++;break;	//增加CH6的温度阈值default:break;}}break;case 2:									//按键2按下if(!Seting_Flag)					//没有进入设置模式{Mode = !Mode;					//切换模式if(Mode == 0)					//表示自动模式{LCD_ShowString(1,1,"     Automa     ");LCD_ShowString(2,1,"     Automa     ");}else							//手动模式{LCD_ShowString(1,1,"     Manual      ");LCD_ShowString(2,1,"     Manual      ");}Delay_s(1);}else								//在设置模式下{switch(SET_Channel)				//按下KEY1减小温度阈值{case 1:ThreTemp[0]--;break;	//减小CH1的温度阈值case 2:ThreTemp[1]--;break;	//减小CH2的温度阈值case 3:ThreTemp[2]--;break;	//减小CH3的温度阈值case 4:ThreTemp[3]--;break;	//减小CH4的温度阈值case 5:ThreTemp[4]--;break;	//减小CH5的温度阈值case 6:ThreTemp[5]--;break;	//减小CH6的温度阈值default:break;}}break;case 3:									//按键3按下,切换到初始界面if(!Seting_Flag)					//没有进入设置模式{Menu_Status = 0;				//复位显示}else								//在设置模式下{Seting_Flag = 0;				//退出设置模式Mode = 0;						//退出手动模式LCD_ShowString(1,1,"     SET OK        ");LCD_ShowString(2,1,"     SET OK        ");Delay_s(1);}break;case 4:									//按键4按下,切换到设置界面Seting_Flag = 1;					//进入设置模式Mode = 1;							//进入手动模式,关闭定时器改变Menu_StatusMenu_Status = 4;					SET_Channel++;						//切换设置通道if(SET_Channel == 7){SET_Channel = 1;}break;default:break;}
}/*** 在不同的Menu_Status下的显示不同的界面*/
void SHOW_CHange(void)
{switch(Menu_Status){case 0:SHOW_CH1_CH2();break;	//显示CH1-CH2通道的温度case 1:SHOW_CH3_CH4();break;	//显示CH3-CH4通道的温度case 2:SHOW_CH5_CH6();break;	//显示CH5-CH6通道的温度case 3:SHOW_Waring(); break;	//显示报警界面case 4:							//显示设置温度阈值界面switch(SET_Channel){case 1:SHOW_SetCH1Temp();break;	//显示设置CH1通道的界面case 2:SHOW_SetCH2Temp();break;	//显示设置CH2通道的界面case 3:SHOW_SetCH3Temp();break;	//显示设置CH3通道的界面case 4:SHOW_SetCH4Temp();break;	//显示设置CH4通道的界面case 5:SHOW_SetCH5Temp();break;	//显示设置CH5通道的界面case 6:SHOW_SetCH6Temp();break;	//显示设置CH6通道的界面}break;default:break;}
}

④Timer.c文件的代码

#include "Timer.h"/*** 定时器T0的初始化*/
void Time0_Intrrupt_Init(void)
{/* 设置T0的计数器为16,且时钟来源为晶振 TMOD = xxxx 0001 */TMOD &= 0xF0;			//将低4位置0TMOD |= 0x01;			//最低位置1/* 设置定时计数器的初始值,定时1ms */TH0 = ((65535 - (1000 - 1)) >> 8);TL0 = (65535 - (1000 - 1)) & 0x00FF;/* 启动T0 */TF0 = 0;				//清除标志位TR0 = 1;				//启动定时器0/* 开启中断 */PT0 = 1;				//优先级较高ET0 = 1;				//使能定时器溢出中断EA = 1;					//开启总开关
}/********中断服务函数*******/
/*** T0的中断服务函数(每隔1ms对TimeCount加1)*/
static unsigned long TimeCount = 0;
static unsigned char StatusFlag = 0;
static unsigned long GetTimeCon = 0;
extern char Menu_Status;
extern bit Mode;
void Time0_Rountine(void) interrupt 1
{//这里不用清除标志位,硬件会自动清除/* 设置定时计数器的初始值,定时1ms */TH0 = ((65535 - (1000 - 1)) >> 8);TL0 = (65535 - (1000 - 1)) & 0x00FF;TimeCount++;/* 每隔2s改变一次Menu_Status */switch(StatusFlag){case 0:GetTimeCon = TimeCount;StatusFlag = 1;case 1:if(TimeCount - GetTimeCon == 2000){GetTimeCon = TimeCount;if(!Mode)				//自动模式下{Menu_Status++;if(Menu_Status >= 4){Menu_Status = 0;}}}break;}
}/*** 对外暴露TimeCount的值*/
unsigned long Get_TimeCount(void)
{return TimeCount;
}

⑤Delay.c文件的代码

#include "Delay.h"
#include "Timer.h"/*** 使用T0构造延时函数ms*/
void Delay_ms(unsigned int nms)
{unsigned long time = Get_TimeCount();//获取此时的TimeCount值while((Get_TimeCount() - time) < nms);
}/*** 使用T0构造延时函数s*/
void Delay_s(unsigned char s)
{while(s--){Delay_ms(1000);}
}

⑥Key.c文件的代码

#include "Key.h"
#include "Delay.h"/*** 按键检测函数(按下按下,引脚输入低电平)* Position:需要检测那个按键* 返回值:不同的按键按下,返回值不同*/
unsigned char Key_Scanf(void)
{	unsigned char Key_Number = 0;if(!GPIO3_0 || !GPIO3_1 || !GPIO3_2|| !GPIO3_3){Delay_ms(10);//延时消抖if(!GPIO3_0)Key_Number = 1;if(!GPIO3_1)Key_Number = 2;if(!GPIO3_2)Key_Number = 3;if(!GPIO3_3)Key_Number = 4;while(!GPIO3_0 || !GPIO3_1 || !GPIO3_2|| !GPIO3_3);//按键松手,跳出此循环Delay_ms(10);//延时消抖}return Key_Number;//返回键值
}

2、实时时钟显示

项目描述:
①单片机启动时,LCD1602显示启动界面 “BeiJing Time”
②按键KEY4用于切换为设置时钟秒/分/时模式,进入设置模式后,按键KEY1为增加时钟,KEY1为减小时钟,KEY3确定时钟并且退出设置模式

项目演示:

QQ2025415-115636

①BeiJingTime.c文件的代码

#include "BeijingTime.h"/* 定义存储时分秒的缓存区 */
char Current_Time[] = {10, 10 ,10};//时分秒/*** 北京时间开机显示界面*/
void Beijing_Start(void)
{LCD_ShowString(1,1,"  BeiJing Time     ");LCD_ShowString(2,1,"      V1.0        ");
}/*** 显示当前时间*/
void SHOW_Current_Time(void)
{LCD_ShowString(1,1,"  Current Time     ");LCD_ShowNum(2, 5, Current_Time[0],2);LCD_ShowChar(2,7,':');LCD_ShowNum(2, 8, Current_Time[1],2);LCD_ShowChar(2,10,':');LCD_ShowNum(2, 11, Current_Time[2],2);
}/*** 显示设置小时*/
void Set_Hour(void)
{LCD_ShowString(1,1,"   SET Hour     ");LCD_ShowNum(2, 5, Current_Time[0],2);LCD_ShowChar(2,7,':');LCD_ShowNum(2, 8, Current_Time[1],2);LCD_ShowChar(2,10,':');LCD_ShowNum(2, 11, Current_Time[2],2);
}/*** 显示设置分钟*/
void Set_Min(void)
{LCD_ShowString(1,1,"   SET Min     ");LCD_ShowNum(2, 5, Current_Time[0],2);LCD_ShowChar(2,7,':');LCD_ShowNum(2, 8, Current_Time[1],2);LCD_ShowChar(2,10,':');LCD_ShowNum(2, 11, Current_Time[2],2);
}/*** 显示设置秒*/
void Set_Second(void)
{LCD_ShowString(1,1,"   SET Second     ");LCD_ShowNum(2, 5, Current_Time[0],2);LCD_ShowChar(2,7,':');LCD_ShowNum(2, 8, Current_Time[1],2);LCD_ShowChar(2,10,':');LCD_ShowNum(2, 11, Current_Time[2],2);
}

②BeiJingTime.h文件的代码

#ifndef __BeijingTime_H
#define __BeijingTime_H
#include "LCD1602.h"void Beijing_Start(void);
void SHOW_Current_Time(void);
void Set_Hour(void);
void Set_Min(void);
void Set_Second(void);#endif

③main.c文件的代码如下

#include "LCD1602.h"
#include "BeijingTime.h"
#include "Key.h"
#include "Delay.h"
#include "Timer.h"extern char Current_Time[];
static unsigned char SET = 0;
unsigned char Seting_Flag = 0;	//进入设置模式标志位void KEY_ChangeStatues(void);
void SHOW_TIME(void);void main(void)
{LCD_Init();	Time0_Intrrupt_Init();Beijing_Start();		//开机显示1sDelay_s(1);LCD_WriteCommand(0x01);	//清屏while(1){KEY_ChangeStatues();SHOW_TIME();}
}/*** KEY4改变状态*/
void KEY_ChangeStatues(void)
{switch(Key_Scanf()){case 1:if(Seting_Flag)							//在设置模式下{switch(SET){case 1:Current_Time[2]++;		//KEY1按键按下增加秒if(Current_Time[2] > 60)Current_Time[2] = 0;break;case 2:Current_Time[1]++;		//KEY1按键按下增加分if(Current_Time[1] > 60)Current_Time[1] = 0;break;case 3:Current_Time[0]++;		//KEY1按键按下增加时if(Current_Time[0] > 24)Current_Time[0] = 0;break;default:break;}}break;case 2:if(Seting_Flag)							//在设置模式下{switch(SET){case 1:Current_Time[2]--;		//KEY2按键按下减少秒if(Current_Time[2] < 0)Current_Time[2] = 59;break;case 2:	Current_Time[1]++;		//KEY2按键按下减少分if(Current_Time[1] < 0)Current_Time[1] = 59;break;case 3:Current_Time[0]++;		//KEY2按键按下减少时if(Current_Time[0] < 24)Current_Time[0] = 0;break;default:break;}}break;case 3:										//按键KEY3按键按下if(Seting_Flag)							//在设置模式下{LCD_ShowString(1,1,"     SET OK     ");LCD_ShowString(2,1,"     SET OK     ");Delay_s(1);LCD_WriteCommand(0x01);				//清屏Seting_Flag = 0;					//退出设置模式}break;case 4:										//按键KEY4按键按下Seting_Flag = 1;						//进入设置模式SET++;if(SET >= 4){SET = 1;}break;}
}void SHOW_TIME(void)
{if(Seting_Flag){switch(SET){case 1:Set_Second();break;case 2:Set_Min();break;case 3:Set_Hour();break;}}else{SHOW_Current_Time();//显示当前时间}
}

④Timer.c文件的代码

#include "Timer.h"/*** 定时器T0的初始化*/
void Time0_Intrrupt_Init(void)
{/* 设置T0的计数器为16,且时钟来源为晶振 TMOD = xxxx 0001 */TMOD &= 0xF0;			//将低4位置0TMOD |= 0x01;			//最低位置1/* 设置定时计数器的初始值,定时1ms */TH0 = ((65535 - (1000 - 1)) >> 8);TL0 = (65535 - (1000 - 1)) & 0x00FF;/* 启动T0 */TF0 = 0;				//清除标志位TR0 = 1;				//启动定时器0/* 开启中断 */PT0 = 1;				//优先级较高ET0 = 1;				//使能定时器溢出中断EA = 1;					//开启总开关
}/********中断服务函数*******/
/*** T0的中断服务函数(每隔1ms对TimeCount加1)*/
static unsigned long TimeCount = 0;
static unsigned char StatusFlag = 0;
static unsigned long GetTimeCon  = 0;
extern unsigned char Seting_Flag;
extern char Current_Time[];
void Time0_Rountine(void) interrupt 1
{//这里不用清除标志位,硬件会自动清除/* 设置定时计数器的初始值,定时1ms */TH0 = ((65535 - (1000 - 1)) >> 8);TL0 = (65535 - (1000 - 1)) & 0x00FF;TimeCount++;/* 每隔1s秒变量增加1 */switch(StatusFlag){case 0:GetTimeCon = TimeCount;StatusFlag = 1;case 1:if(TimeCount - GetTimeCon == 1000){GetTimeCon = TimeCount;if(!Seting_Flag)				//没有进入设置模式{Current_Time[2]++;			//每隔1s秒变量增加if(Current_Time[2] >= 60){Current_Time[2] = 0;	Current_Time[1]++;		//每隔60s分变量增加if(Current_Time[1] >= 60){Current_Time[1] = 0;Current_Time[0]++;	//每隔60min时变量增加if(Current_Time[0] >= 24){Current_Time[0] = 0;}}}}}break;}
}/*** 对外暴露TimeCount的值*/
unsigned long Get_TimeCount(void)
{return TimeCount;
}

相关文章:

  • pytorch实现逻辑回归
  • 提高RS-485总线稳定性办法
  • 黑马商城项目(一)MybatisPlus
  • 基于PySide6的YOLOv8/11目标检测GUI界面——智能安全帽检测系统
  • ScrollView(滚动视图)详解和按钮点击事件
  • 【Leetcode-Hot100】最小覆盖子串
  • 【链表】链表类型题目常用技巧及例题
  • Resilience4j与Spring Cloud Gateway整合指南:构建弹性的API网关
  • Stable Diffusion 图像生成 GUI 应用:图像缩放等五个优化——SD界面学习记录
  • yml文件上传并映射到实体类
  • Service生命周期
  • 微图4在《宁夏清水湾小流域治理》工程项目中的应用案例
  • Arrays.asList()的对象不能调用add/remove/clear方法
  • 力扣-hot100(最长连续序列 - Hash)
  • C++高级2 智能指针
  • CodeBuddy 焕新升级: 软件开发智能体 Craft 重磅发布
  • Function Calling 与 RAG的关系
  • [第十六届蓝桥杯 JavaB 组] 真题 + 经验分享
  • MySQL 数据库备份和恢复全指南
  • 多线程(三)
  • 男粉丝咬伤女主播嘴后写的条子引争议:赔偿“十万元”还是“十5元”?
  • 建行深圳市分行原副行长李华峰一审被判15年
  • 大学2025丨本科专业大调整,教育专家:化解就业难背后供需错配
  • 日媒:日本公明党党首将访华,并携带石破茂亲笔信
  • 大气科学家、北京大学副教授李成才逝世,终年56岁
  • GDP增长6.0%,一季度浙江经济数据出炉