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)
{//初始化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;               }}}
}

时间显示效果图

单纯的在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;               }}}
}

按键更改时间 效果图

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

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)
{//初始化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;               }}}
}

秒表计时 效果图

使用说明:

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

在时钟模式下:

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

在秒表模式下:

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

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

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

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

  1. 51单片机LCD1602显示电子时钟 带按键设置和星期显示

    当时看书看到lcd那章,就想利用定时器做一个电子时钟,当时也不知道有时钟模块的,以为都是定时器定时产生的时间,也是一个main文件从头到尾的版本,注释倒不少,不要说什么模块化编程和代码优化,想到什么就 ...

  2. Proteus8仿真:51单片机LCD1602显示

    51单片机LCD1602显示 元器件 原理图部分 代码 main.c 工程文件 元器件 元器件 名称 排阻 RESPACK-8 51单片机 AT89C51 LCD1602 LM016L 按键 BUTT ...

  3. 基于51单片机LCD1602显示

    基于51单片机LCD1602显示 要在1602上显示字符,要大概明白1602液晶显示屏工作原理. 一般的液晶显示器(Liquid Crystal Display, LCD) 的主要原理是以电流刺激液晶 ...

  4. 【优秀课设】51单片机LCD1602显示的温度控制系统设计 包括时间显示 校时、设置最值温度报警功能

    1.将DS18B20温度传感器的温度读出来,并在LCD1602上显示出来. 2.在LCD上分别切换显示,软件设计时钟(时.分.秒),和当前温度值,和温度上下控制值.并可以通过按键进行修改设置,温度高于 ...

  5. 简单易懂的51单片机LCD1602显示protues仿真程序

    时序图  仿真效果  #include"AT89X51.h" typedef unsigned char u8; typedef unsigned int u16;#define ...

  6. 51单片机利用8266获取网络时间

    51单片机利用8266获取网络时间 我现在是成都一所不出名的二本院校大三学生,第一次来到CSDN,趁有时间,把我之前做的项目,其中一个模块拿出来和大家分享,我也是小白,希望提出宝贵意见.OK,废话不多 ...

  7. 使用51单片机+lcd1602转接板-iic接口进行显示

    使用51单片机+lcd1602转接板-iic接口进行显示 某宝上有卖lcd1602与iic芯片pcf8574的整合,虽然lcd1602能直接用51单片机使用,不过经过整合之后只需要对SCL和SDA两个 ...

  8. 【Proteus仿真】51单片机+LCD1602驱动显示模板程序

    [Proteus仿真]51单片机+LCD1602驱动显示模板程序 Proteus仿真 范例工程架构 LCD1602相关驱动显示函数 //函数或者变量声明 extern void LCD1602_del ...

  9. 基于51单片机LCD1602温度显示(DS18B20测温)

    基于51单片机DS18B20测温 要在1602上显示温度先要了解1602是如何显示的.详情可以参考我之前的文章基于51单片机1602显示 DS18B20是美国DALLAS半导体公司推出的第一片支持&q ...

最新文章

  1. java多线程-死锁的一些问题
  2. JS的prototype和__proto__
  3. pyhton3 rsa长加密/解密
  4. BFE Ingress Controller正式发布!
  5. 企鹅java游戏下载安装_企鹅企鹅生活安卓版游戏下载|企鹅企鹅生活手游下载v1.6.1-乐游网安卓下载...
  6. 二叉树结构 codevs 1029 遍历问题
  7. python 微信bot_我如何创建Python Bot自动登录到强制门户
  8. python pip安装第三方库老是报错_#python pip 安装dlib一直失败?#python安装dlib错误...
  9. SpringBoot前端Ajax以JSON格式获取后台数据
  10. 2013年C++A:神奇的算式
  11. 相机java程序_以编程方式在Android上用相机拍照
  12. 搭建springmvc项目遇到的问题
  13. Excel 公式复制同步到其他单元格
  14. jmeter性能测试并监控服务器
  15. 搭建类京东网站服务器
  16. MybatisPlus查询条件和排序高级封装
  17. CPU核心、进程、线程
  18. 【响应式】foundation栅格布局的“尝鲜”与“填坑”
  19. 问:用宏定义一年有多少秒(忽略闰年)
  20. Java switch和break用法

热门文章

  1. 项目0:泰坦尼克生还者预测
  2. idea设置中文字体不倾斜
  3. Centos之数据库基础
  4. 线性回归从零开始实现
  5. 数字信息化是计算机处理信息的基础,档案信息化、数字化、网络化及三者的关系...
  6. 评分法模型开发-WOE值计算
  7. 项目经理面试经验宝典
  8. 聚醚砜染料吸附膜纳米纤维膜
  9. 华为AppCube通过中国信通院“低代码开发平台通用能力要求”评估
  10. 浅析闪存盘(Flash Drive)内部架构与应用考虑