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;
}