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

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

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

显示:欢迎来到百色学院

 代码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) {//初始化LCD1602 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)
{//选择要显示的字字符串,参数一代表行,参数二代表列,参数三要传一个字符串进来,或者字符型的指针 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; } } } }
时间显示效果图

 单纯的在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) {//初始化LCD1602
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)
{//选择要显示的字字符串,参数一代表行,参数二代表列,参数三要传一个字符串进来,或者字符型的指针 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; } } } }

按键更改时间 效果图

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

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

独立按键电路连接图

 代码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) {//初始化lcd1602 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)
{//选择要显示的字字符串,参数一代表行,参数二代表列,参数三要传一个字符串进来,或者字符型的指针 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.000MHz TMOD &= 0xF0; //设置定时器模式 TMOD |= 0x01;
//设置定时器模式 TL0 = 0xB0; //设置定时初值 TH0 = 0x3C; //设置定时初值 TF0 = 0; //清除TF0标志 TR0 = 1;
//定时器0开始计时 ET0=1; //打开定时器T0中断小开关 EA=1; //打开总开关 } void Timer1Init(void)
{//定时器1初始化函数,定时:50毫秒 晶振为:12.000MHz TMOD &= 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; } } } }

秒表计时 效果图

使用说明: 

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

在时钟模式下:

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

k1无
k2秒表 暂停/起动
k3秒表清零
心得:要进行给LCD 首先要看明白LCD的数据手册,要显示内容,就得有显示的函数,在这之前还得有写命令和写数据的函数,写命令和写数据要看懂时序图才能码代码。

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

技术
下载桌面版
GitHub
Gitee
SourceForge
百度网盘(提取码:draw)
云服务器优惠
华为云优惠券
腾讯云优惠券
阿里云优惠券
Vultr优惠券
站点信息
问题反馈
邮箱:[email protected]
吐槽一下
QQ群:766591547
关注微信