【51单片机】LCD1602显示字符串,时间、时间+按键校准、秒表计时的功能代码。

news/2024/11/7 14:33:27/

LCD1602显示字符和时间是最基本的实验,在综合前面所学知识并结合c语言程序设计,就可以通过独立按键,来对时间进行校准,计时等功能、或者通过矩阵键盘的按键进行输入,进而让LCD屏上显示的出我们想要的内容和效果。应实验要求,写了4个代码。

本实验采用的是12.000MHz晶振的51开发板.

8bf54d691c4a4ca080c60b810f1a66e8.png

LCD1602电路连线图

 代码1:(在LCD上显示“ Welcome to Baise University”->  (欢迎来到百色学院)  )

#include <REGX52.H>
typedef unsigned char uchar;
sbit LCD_RS=P2^6;
sbit LCD_RW=P2^5;
sbit LCD_E=P2^7;char count=0,hour=23,minute=59,second=55;void Delay(unsigned int xms)
{//延时函数uchar i, j;while(xms--){i = 2;j = 239;do{while (--j);} while (--i);}
}
void LCD_WriteCmd(uchar Command)
{//写命令函数LCD_RS=0;LCD_RW=0;P0=Command;LCD_E=1;Delay(1);LCD_E=0;Delay(1);
}
void LCD_WriteData(uchar Data)
{//写数据函数LCD_RS=1;LCD_RW=0;P0=Data;LCD_E=1;Delay(1);LCD_E=0;Delay(1);
}void LCD_Init(void)
{//初始化LCD_WriteCmd(0x38);LCD_WriteCmd(0x0C);LCD_WriteCmd(0x06);LCD_WriteCmd(0x01);
}
void LCD_SetCursor(uchar Line,uchar Column)
{//设置显示的行数和列数LCD_WriteCmd(Line==1?0x80+(Column-1):0xC0+(Column-1));
}void LCD_ShowString(uchar Line,uchar Column,char *String)
{//在指定的行数和列数显示对应的字符串uchar i;LCD_SetCursor(Line,Column);for(i=0;String[i]!='\0';i++)LCD_WriteData(String[i]);	
}void main(){ LCD_Init();LCD_ShowString(1,1,"Welcome to Baise");		LCD_ShowString(2,1,"University!");		while(1);
}

bb0aaa7f46e340d6925107bb42042b9a.jpeg

显示:欢迎来到百色学院

 代码2:(LCD显示时间)

#include <REGX52.H>
typedef unsigned char uchar;
sbit LCD_RS=P2^6;
sbit LCD_RW=P2^5;
sbit LCD_E=P2^7;
char hour=23,minute=59,second=55;//时间变量:时、分、秒
uchar T0_flag=0;
void Delay(unsigned int xms)
{//延时函数unsigned char i, j;while(xms--){i = 2;j = 239;do{while (--j);} while (--i);}
}
void LCD_WriteCmd(uchar Command)
{//写命令函数LCD_RS=0;LCD_RW=0;P0=Command;LCD_E=1;Delay(1);LCD_E=0;Delay(1);
}
void LCD_WriteData(uchar Data)
{//写数据函数LCD_RS=1;LCD_RW=0;P0=Data;LCD_E=1;Delay(1);LCD_E=0;Delay(1);
}void LCD_Init(void)
{//初始化LCD1602LCD_WriteCmd(0x38);LCD_WriteCmd(0x0C);LCD_WriteCmd(0x06);LCD_WriteCmd(0x01);
}
void LCD_SetCursor(uchar Line,uchar Column)
{//选择显示的行和列:参数一代表行,参数二代表列LCD_WriteCmd(Line==1?0x80+(Column-1):0xC0+(Column-1));
}void LCD_ShowString(uchar Line,uchar Column,char *String)
{//选择要显示的字字符串,参数一代表行,参数二代表列,参数三要传一个字符串进来,或者字符型的指针unsigned char i;LCD_SetCursor(Line,Column);for(i=0;String[i]!='\0';i++)LCD_WriteData(String[i]);
}
void LCD_ShowTime(char h,char m,char s)
{//在lcd1602上面显示时间 ,用定时器1 LCD_ShowString(1,7,"Time");LCD_SetCursor(2,5);   LCD_WriteData(h/10+0x30);LCD_WriteData(h%10+0x30);LCD_WriteData(0x3a);LCD_WriteData(m/10+0x30);LCD_WriteData(m%10+0x30);LCD_WriteData(0x3a);LCD_WriteData(s/10+0x30);LCD_WriteData(s%10+0x30);             
}void Timer0Init()		//50毫秒@12.000MHz
{TMOD &= 0xF0;		//设置定时器模式TMOD |= 0x01;		//设置定时器模式TL0 = 0xB0;		    //设置定时初值TH0 = 0x3C;		    //设置定时初值TF0 = 0;		    //清除TF0标志TR0 = 1;		    //定时器0开始计时ET0=1;              //打开小开关EA=1;               //打开总开关   
}void main(){Timer0Init();LCD_Init();					while(1)LCD_ShowTime(hour,minute,second);      
}void interrupt_T0()interrupt 1
{//定时器0中断函数TL0 = 0xB0;		TH0 = 0x3C;		T0_flag++;if(T0_flag==20){T0_flag=0;     second++;if(second==60){second=0;minute++;if(minute==60){minute=0;hour++;if(hour==24)hour=0;               }}}
}
1627250ab80f4642a9c1e5ba8fb8cd6f.jpeg

时间显示效果图

 单纯的在LCD1602上面显示可变时间

注:如果觉得时间不准,很可能是晶振不同的问题,这里我的晶振时12MHZ的,如果晶振频率时11.0592MHZ的就要把代码中初始化和中断里面的TL1 = 0xB0;和TH1 = 0x3C;     改成TL1 ==0x00;   TH1 = 0x4C;

代码3:(显示时间+按键扫描)

#include <REGX52.H>
typedef unsigned char uchar;
sbit LCD_RS=P2^6;
sbit LCD_RW=P2^5;
sbit LCD_E=P2^7;char T0_flag=0,hour=23,minute=59,second=55;void Delay(unsigned int xms)
{//延时函数unsigned char i, j;while(xms--){i = 2;j = 239;do{while (--j);} while (--i);}
}
void LCD_WriteCmd(uchar Command)
{//写命令函数LCD_RS=0;LCD_RW=0;P0=Command;LCD_E=1;Delay(1);LCD_E=0;Delay(1);
}
void LCD_WriteData(uchar Data)
{//写数据函数LCD_RS=1;LCD_RW=0;P0=Data;LCD_E=1;Delay(1);LCD_E=0;Delay(1);
}void LCD_Init(void)
{//初始化LCD1602LCD_WriteCmd(0x38);LCD_WriteCmd(0x0C);LCD_WriteCmd(0x06);LCD_WriteCmd(0x01);
}
void LCD_SetCursor(uchar Line,uchar Column)
{//选择显示的行和列:参数一代表行,参数二代表列LCD_WriteCmd(Line==1?0x80+(Column-1):0xC0+(Column-1));
}void LCD_ShowString(uchar Line,uchar Column,char *String)
{//选择要显示的字字符串,参数一代表行,参数二代表列,参数三要传一个字符串进来,或者字符型的指针unsigned char i;LCD_SetCursor(Line,Column);for(i=0;String[i]!='\0';i++)LCD_WriteData(String[i]);}
void LCD_ShowTime(char h,char m,char s)
{//在lcd1602上面显示时间 ,用定时器1            LCD_SetCursor(2,5);   LCD_WriteData(h/10+0x30);LCD_WriteData(h%10+0x30);LCD_WriteData(0x3a);LCD_WriteData(m/10+0x30);LCD_WriteData(m%10+0x30);LCD_WriteData(0x3a);LCD_WriteData(s/10+0x30);LCD_WriteData(s%10+0x30);            
}void key_scan(){static uchar flag=0;if(P3_1==0){Delay(20);while(P3_1==0);Delay(20);TR0=0;//关闭中断请求flag++;if(flag==4){flag=0;TR0=1;LCD_WriteCmd(0x01);}}if(flag!=0){LCD_ShowString(1,2,"Change Time");switch(flag){case 1:if(P3_0==0){ Delay(20);while(P3_0==0);Delay(20);hour++; if(hour>23) hour=0;}break;case 2:if(P3_0==0){ Delay(20);while(P3_0==0);Delay(20);minute++; if(minute>59) minute=0;}break;case 3:if(P3_0==0){ Delay(20);while(P3_0==0);Delay(20);second++; if(second>59) second=0;}break;default:break;}switch(flag){case 1:if(P3_2==0){ Delay(20);while(P3_2==0);Delay(20);hour--; if(hour<0) hour=23;}break;case 2:if(P3_2==0){ Delay(20);while(P3_2==0);Delay(20);minute--; if(minute<0) minute=59;}break;case 3:if(P3_2==0){ Delay(20);while(P3_2==0);Delay(20);second--; if(second<0) second=59;}break;default:break;}}else{LCD_ShowString(1,7,"Time");}
}
void Timer0Init()		//50毫秒@12.000MHz
{TMOD &= 0xF0;		//设置定时器模式TMOD |= 0x01;		//设置定时器模式TL0 = 0xB0;		    //设置定时初值TH0 = 0x3C;		    //设置定时初值TF0 = 0;		    //清除TF0标志TR0 = 1;		    //定时器0开始计时ET0=1;              //打开小开关EA=1;               //打开总开关   
}void main(){Timer0Init();LCD_Init();					while(1){key_scan();LCD_ShowTime(hour,minute,second);  }
}void interrupt_T0()interrupt 1
{//定时器0中断函数TL0 = 0xB0;		TH0 = 0x3C;		T0_flag++;if(T0_flag==20){T0_flag=0;     second++;if(second==60){second=0;minute++;if(minute==60){minute=0;hour++;if(hour==24)hour=0;               }}}
}

67a45bf6f3a5414db6ac5802da99f60b.jpeg

按键更改时间 效果图

功能:通过独立按键进行时间的校准。

k1按一次暂停时钟运行,进入更改时档位,第二次进入更改分档位,第三次进入更改秒档位,第四次启动时钟
k2时/分/秒  数值加一
k3时/分/秒  数值减一

独立按键电路如下:

f5dacf41f5924a8592be6860bbdb4f89.png

独立按键电路连接图

 代码4:(显示时间+按键扫描+秒表计时)

#include <REGX52.H>
typedef unsigned char uchar;
sbit LCD_RS=P2^6;
sbit LCD_RW=P2^5;
sbit LCD_E=P2^7;
char hour=23,minute=59,second=55;//时钟变量
char S=0,M=0,H=0;//秒表变量
uchar mode=0,T0_flag=0,T1_flag=0;void Delay(unsigned int xms)
{//延时函数uchar i, j;while(xms--){i = 2;j = 239;do{while (--j);} while (--i);}
}
void LCD_WriteCmd(uchar Command)
{//写命令函数LCD_RS=0;LCD_RW=0;P0=Command;LCD_E=1;Delay(1);LCD_E=0;Delay(1);
}
void LCD_WriteData(uchar Data)
{//写数据函数LCD_RS=1;LCD_RW=0;P0=Data;LCD_E=1;Delay(1);LCD_E=0;Delay(1);
}void LCD_Init(void)
{//初始化lcd1602LCD_WriteCmd(0x38);LCD_WriteCmd(0x0C);LCD_WriteCmd(0x06);LCD_WriteCmd(0x01);
}
void LCD_SetCursor(uchar Line,uchar Column)
{//选择显示的行和列:参数一代表行,参数二代表列LCD_WriteCmd(Line==1?0x80+(Column-1):0xC0+(Column-1));
}void LCD_ShowString(uchar Line,uchar Column,char *String)
{//选择要显示的字字符串,参数一代表行,参数二代表列,参数三要传一个字符串进来,或者字符型的指针unsigned char i;LCD_SetCursor(Line,Column);for(i=0;String[i]!='\0';i++)LCD_WriteData(String[i]);}
void LCD_ShowTime(char h,char m,char s)
{ //在lcd1602上面显示时间 ,用定时器1     LCD_SetCursor(2,5);   LCD_WriteData(h/10+0x30);LCD_WriteData(h%10+0x30);LCD_WriteData(0x3a);LCD_WriteData(m/10+0x30);LCD_WriteData(m%10+0x30);LCD_WriteData(0x3a);LCD_WriteData(s/10+0x30);LCD_WriteData(s%10+0x30);             
}void LCD_ShowStopwatch()
{//在lcd1602上面显示秒表 ,用定时器2     ,       LCD_SetCursor(2,5);   LCD_WriteData(H/10+0x30);LCD_WriteData(H%10+0x30);LCD_WriteData(0x3a);LCD_WriteData(M/10+0x30);LCD_WriteData(M%10+0x30);LCD_WriteData(0x3a);LCD_WriteData(S/10+0x30);LCD_WriteData(S%10+0x30);           
}void key_scan()
{//按键扫描,进行模式和档位的更改 static uchar flag=0;if(P3_1==0){   //档位选择Delay(20);while(P3_1==0);Delay(20);TR0=0;//关闭T0中断请求flag++;if(flag==4){flag=0;LCD_WriteCmd(0x01);//清屏TR0=1;}}if(P3_3==0){//模式切换按键Delay(20);while(P3_3==0);Delay(20);LCD_WriteCmd(0x01);mode++; if(mode==2)//模式切换成时钟模式 mode=0;       }if(mode==0){    //时钟模式  if(flag!=0){LCD_ShowString(1,2,"Change Time");switch(flag){case 1:if(P3_0==0){ Delay(20);while(P3_0==0);Delay(20);hour++; if(hour>23) hour=0;}break;case 2:if(P3_0==0){ Delay(20);while(P3_0==0);Delay(20);minute++; if(minute>59) minute=0;}break;case 3:if(P3_0==0){ Delay(20);while(P3_0==0);Delay(20);second++; if(second>59) second=0;}break;default:break;}switch(flag){case 1:if(P3_2==0){ Delay(20);while(P3_2==0);Delay(20);hour--; if(hour<0) hour=23;}break;case 2:if(P3_2==0){ Delay(20);while(P3_2==0);Delay(20);minute--; if(minute<0) minute=59;}break;case 3:if(P3_2==0){ Delay (20);while(P3_2==0);Delay(20);second--; if(second<0) second=59;}break;default:break;}}else{LCD_ShowString(1,7,"Time");}}else {//秒表模式LCD_ShowString(1,4,"Stopwatch");if(P3_2==0){ Delay(20);while(P3_2==0);Delay(20);S=0,H=0,M=0;}/*秒表清零*/if(P3_0==0){ Delay(20);while(P3_0==0);Delay(20);TR1=~TR1;}/*秒表 暂停/启动*/}
}
void Timer0Init()
{//定时器0初始化函数,定时:50毫秒  晶振为:12.000MHzTMOD &= 0xF0;		//设置定时器模式TMOD |= 0x01;		//设置定时器模式TL0 = 0xB0;		    //设置定时初值TH0 = 0x3C;		    //设置定时初值TF0 = 0;		    //清除TF0标志TR0 = 1;		    //定时器0开始计时ET0=1;              //打开定时器T0中断小开关EA=1;               //打开总开关   
}void Timer1Init(void)		
{//定时器1初始化函数,定时:50毫秒  晶振为:12.000MHzTMOD &= 0x0F;		//设置定时器模式TMOD |= 0x10;		//设置定时器模式	TL1 = 0xB0;		//设置定时初值TH1 = 0x3C;		//设置定时初值TF1 = 0;		//清除TF1标志	ET1=1;          //打开定时器T1中断小开关EA=1;           //打开总开关     
}
void main()
{Timer0Init();Timer1Init();LCD_Init();					    while(1){key_scan();switch(mode){case 0:LCD_ShowTime(hour,minute,second);break; case 1:LCD_ShowStopwatch();break;     }  }
}void interrupt_T0()interrupt 1
{//定时器0中断函数TL0 = 0xB0;		    //重新设置定时初值TH0 = 0x3C;		    //重新设置定时初值T0_flag++;if(T0_flag==20){T0_flag=0;     second++;if(second==60){second=0;minute++;if(minute==60){minute=0;hour++;if(hour==24)hour=0;               }}}
}void interrupt_T1() interrupt 3
{//定时器1中断函数 TL1 = 0xB0;		//重新设置定时初值TH1 = 0x3C;		//重新设置定时初值T1_flag++;if(T1_flag==20){T1_flag=0;     S++;if(S==60){S=0;M++;if(M==60){M=0;H++;if(H==24)H=0;               }}}
}

da6e6366532b47d1b0f7d1767984a21f.jpeg

秒表计时 效果图

使用说明: 

独立按键
k4模式切换(时钟/秒表)


在时钟模式下:

k1按一次暂停时钟运行,进入更改时档位,第二次进入更改分档位,第三次进入更改秒档位,第四次启动时钟
k2时/分/秒  数值加一
k3时/分/秒  数值减一

在秒表模式下:

k1
k2秒表 暂停/起动
k3秒表清零

心得:要进行给LCD 首先要看明白LCD的数据手册,要显示内容,就得有显示的函数,在这之前还得有写命令和写数据的函数,写命令和写数据要看懂时序图才能码代码。

熬夜肝出来的东西,做一下学习笔记。 


http://www.ppmy.cn/news/615618.html

相关文章

KST-51单片机:c语言编程实现数码管动态显示秒表的倒计时

/*60S倒计时*/ /*个位每1S变一次&#xff0c;从0&#xff5e;9*/ /*十位,个位为0的下一秒十位发生变化*/#include<reg52.h>sbit ADDR0P1^0; sbit ADDR1P1^1; sbit ADDR2P1^2; sbit ADDR3P1^3; sbit ENLEDP1^4;unsigned char code LedChar[] { 0xC0,0xF9,0xA4,0xB0,0x99,0…

stm32倒计时秒表proteus_单片机课程设计倒计时秒表教程文件

精品文档 精品文档 一、设计目的 此次设计是我们更进一步了解基本电路的设计流程&#xff0c;提高自己的设计理念&#xff0c; 丰富自己的理论知识&#xff0c;巩固所学知识&#xff0c;使自己的动手动脑能力有更进一步提高&#xff0c; 为自己今后的学习和工作打好基础&#x…

android手机时钟、闹钟、计时器、秒表app源码

简 介 此多功能闹钟界面采用TabHost框架&#xff0c;头部包含分别用LinearLayout水平布局显示四个标签闹钟&#xff0c;时钟&#xff0c;计时器和秒表&#xff0c;FrameLayout框架内部采用LinearLayout垂直布局。功能事件的基本实现分别有AlarmView类&#xff0c;AlarmReceiver…

60秒倒计时器 秒表 c语言程序,用单片机设计一个两位LED显示的秒表,按下计时键时,进行60s倒计时显示...

满意答案 w86586tk3y 2017.09.25 采纳率&#xff1a;57% 等级&#xff1a;8 已帮助&#xff1a;214人 #include sbit P3_5 P3^5; unsigned char code dispcode[]{0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8, 0x80,0x90,0x88,0x83,0xC6,0xA1,0x86,0x8E,0x00}; unsigned char …

verilog秒表计时器

本设计是使用verilog实现秒表计时器。 秒表指示的时间由nexys4 DDR开发板的8个数码管显示,从左到右数码管的前两个显示小时(范围0-24),第3-4个数码管显示分(范围0-59,计数到60,向小时位进1),第5-6个数码管显示秒(范围0-59,计数到60向分位进1),第7-8个数码管显示毫…

前端文件上传的几种交互造轮子

背景 前端文件上传本来是一个常规交互操作&#xff0c;没什么特殊性可言&#xff0c;但是最近在做文件上传&#xff0c;需要实现截图粘贴上传&#xff0c;去找了下有没有什么好用的组件&#xff0c;网上提供的方法有&#xff0c;但是没找完整的组件来支持 cv 上传&#xff0c;…

基于STM32的多功能秒表

基于STM32的多功能秒表 当上电运行后&#xff0c;按下KEY1,秒表开始正计时&#xff0c;再次按下KEY1秒表停止计时&#xff0c;按下KEY2秒表清零&#xff0c;按下KEY3&#xff0c;手动调节秒表时间递增&#xff0c;按下KEY4手动调节秒表时间递减&#xff0c;按下KEY5秒表倒计时…

stm32倒计时秒表proteus_倒计时秒表 单片机

目录 一、设计目的 ........................................................................................................ 1 二、设计任务及要求 ............................................................................................ 2 三、总体方案设计 …