基于51单片机通过点击移位按键移位修改LCD1602字符型液晶显示器显示时分秒个位十位数值的计时项目工程

Posted 吃不了就兜着走

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了基于51单片机通过点击移位按键移位修改LCD1602字符型液晶显示器显示时分秒个位十位数值的计时项目工程相关的知识,希望对你有一定的参考价值。

  1 #include<reg52.h>//单片机头文件
  2 #define uchar unsigned char//宏定义,用uchar表示unsigned char,叫无符号字符型数据类型,取值范围为:0到255。
  3 #define uint unsigned int//宏定义,用uint表示unsigned int,叫无符号整数型数据类型,取值范围为:0到65535。
  4 sbit RS=P0^7;//位定义LCD1602字符型液晶显示器的数据/命令选择引脚                 
  5 sbit RW=P0^6;//位定义LCD1602字符型液晶显示器的读写引脚                        
  6 sbit EN=P0^5; //位定义LCD1602字符型液晶显示器的使能引脚
  7 sbit S1=P3^5;//移位按键S1 
  8 sbit S2=P3^4;//增加按键S2 
  9 sbit S3=P3^3;//减少按键S3 
 10 sbit S4=P3^2;//启停按键S4
 11 uchar count,S1num,S4num;//count为定时器0中断次数变量,S1num为移位按键S1按键按下次数变量,S4num为启停按键S4按下次数变量。
 12 uchar shi,fen,miao;//未做时间修改的计时时钟、分钟、秒钟变量
 13 uchar secondge,secondshi; //秒钟个位、十位的变量
 14 uchar minutange,minutanshi;//分钟个位、十位的变量
 15 uchar hourge,hourshi;//时钟个位、十位的变量
 16 uchar table0[]="2019-11-11";//LCD1602第一行初始显示
 17 uchar table1[]="00:00:00";//LCD1602第二行初始显示
 18   void Delay(uint z)//延时程序
 19 {
 20    uint x,y;
 21    for(x=z;x>0;x--)
 22     for(y=110;y>0;y--);
 23  }
 24   void WriteCommand(uchar command)//LCD1602字符型液晶显示器写指令函数
 25 {
 26    RS=0;//LCD1602字符型液晶显示器指令寄存器低电平
 27    RW=0;//LCD1602字符型液晶显示器写指令操作低电平
 28    P2=command;//LCD1602字符型液晶显示器写指令函数写指令到单片机P2组端口,再输送到LCD1602字符型液晶显示器指令寄存器中执行。
 29    Delay(5);//实际单片机演示,可以去掉延时。Proteus 仿真,需要保留延时。
 30    EN=1;//LCD1602字符型液晶显示器使能端高电平  
 31    Delay(5);//实际单片机演示,可以去掉延时。Proteus 仿真,需要保留延时。
 32    EN=0;//LCD1602字符型液晶显示器使能端低电平
 33  }
 34   void WriteData(uchar information)//LCD1602字符型液晶显示器写数据函数
 35 {  
 36    RS=1;//LCD1602字符型液晶显示器数据寄存器高电平
 37    RW=0;//LCD1602字符型液晶显示器写数据操作低电平
 38    P2=information;//LCD1602字符型液晶显示器写数据函数写数据到单片机P2组端口,再输送到LCD1602字符型液晶显示器上显示。
 39    Delay(5);//实际单片机演示,可以去掉延时。Proteus 仿真,需要保留延时。
 40    EN=1;//LCD1602字符型液晶显示器使能端高电平 
 41    Delay(5);//实际单片机演示,可以去掉延时。Proteus 仿真,需要保留延时。
 42    EN=0;//LCD1602字符型液晶显示器使能端低电平
 43  }
 44   void LCD1602Init()//LCD1602初始化函数
 45 {
 46    WriteCommand(0x38);//设置LCD1602字符型液晶显示器16x2显示,5*7或5*8点阵,8位数据并口,简称显模。
 47    WriteCommand(0x08);//设置LCD1602字符型液晶显示器显示开,简称亮屏。
 48    WriteCommand(0x01);//设置清除LCD1602字符型液晶显示器屏上所有内容,并让光标复位到LCD1602字符型液晶显示器屏左上角,简称清屏。
 49    WriteCommand(0x06);//设置开光标(或字符)地址指针自增1,光标右移动一个字符位,整屏显示不移动。
 50    WriteCommand(0x0c);//设置开LCD1602字符型液晶显示器显示,关光标,关光标(字符)闪烁。
 51  }
 52   void Timer0Init()//定时器0初始化函数
 53 {
 54    TMOD=0x01;//设定定时器0工作模式为模式1
 55    TH0=(65536-50000)/256;//TH0装初值
 56    TL0=(65536-50000)%256;//TL0装初值
 57    EA=1;//开启定时器总中断
 58    ET0=1;//开启定时器0中断开关
 59    TR0=1;//启动定时器0
 60  }
 61   void LCD1602Display()//LCD1602字符型液晶显示器显示函数
 62 {
 63    uchar j;//j表示数组元素个数变量
 64    WriteCommand(0x80+0x00);//LCD1602字符型液晶显示器第一行第一个位置显示
 65    for(j=0;j<10;j++)//有10个字符,要循环10次。
 66   {
 67     WriteData(table0[j]);//显示字符串
 68     Delay(5);
 69    }
 70    WriteCommand(0x80+0x40);//LCD1602字符型液晶显示器第二行第一个位置显示
 71    for(j=0;j<8;j++)//有8个字符,要循环8次。
 72   { 
 73     WriteData(table1[j]);//显示字符串
 74     Delay(5);
 75    }
 76  }
 77   void LCD1602DisplayTime(uchar address,uchar num)//LCD1602显示时间两位数分解函数
 78 {
 79    uchar shi,ge;//十位、个位的变量
 80    shi=num/10;//十位数
 81    ge=num%10;//个位数
 82    WriteCommand(0x80+0x40+address);//LCD1602字符型液晶显示器第二行某个显示位
 83    WriteData(0x30+shi);//0x30表示字符库的数字0,整个代码表示十位可显示0到9的数字。
 84    WriteData(0x30+ge);//0x30表示字符库的数字0,整个代码表示个位可显示0到9的数字。
 85  }
 86   void LCD1602DisplayGeDigitResolve(uchar address,uchar num)//LCD1602字符型液晶显示器显示修改时间个位数分解函数
 87 {
 88    uchar ge;//个位的变量
 89    ge=num%10;//个位数
 90    WriteCommand(0x80+0x40+address);//LCD1602字符型液晶显示器第二行某个显示位
 91    WriteData(0x30+ge);//0x30表示字符库的数字0,整个代码表示个位可显示0到9的数字。
 92  }
 93   void LCD1602DisplayShiDigitResolve(uchar address,uchar num)//LCD1602字符型液晶显示器修改时间十位数分解函数
 94 {
 95    uchar shi;//十位变量
 96    shi=num%10;//十位数
 97    WriteCommand(0x80+0x40+address);//LCD1602字符型液晶显示器第二行某个显示位
 98    WriteData(0x30+shi);//0x30表示字符库的数字0,整个代码表示十位可显示0到9的数字。
 99  }
100   void KeyScan()//按键扫描函数
101 {
102    if(S1==0)//判断移位按键S1是否按下                                           
103   {
104     Delay(5);
105     if(S1==0)//再次判断移位按键S1是否按下
106    {        
107      S1num++;//移位按键S1按键次数变量先赋值再自加
108      while(!S1);//等待移位按键S1弹起
109      switch(S1num)
110     {
111       case 1:
112              TR0=0;//关定时器0
113              S4num=0;//启停按键S4按下次数清零
114              secondge=miao%10;//关掉定时器0定时后,把秒钟计时时间数值取余赋给秒钟个位显示位。 
115              secondshi=miao/10;//关掉定时器0定时后,把秒钟计时时间数值取除赋给秒钟十位显示位。
116              WriteCommand(0x80+0x40+0x07);//LCD1602字符型液晶显示器第二行第8个位置的显示位
117              WriteCommand(0x0f);//开LCD1602字符型液晶显示器显示,开光标,开光标(或字符)闪烁。
118              break;
119       case 2:
120              secondshi=secondshi;//关掉定时器0定时后,把秒钟计时时间数值取除后得到的值再赋给秒钟十位显示位。
121              WriteCommand(0x80+0x40+0x06);//LCD1602字符型液晶显示器第二行第7个位置的显示位
122              WriteCommand(0x0f);//开LCD1602字符型液晶显示器显示,开光标,开光标(或字符)闪烁。
123              break;
124       case 3:
125              minutange=fen%10;//关掉定时器0定时后,把分钟计时时间数值取余赋给分钟个位显示位。
126              minutanshi=fen/10;//关掉定时器0定时后,把分钟计时时间数值取除赋给分钟十位显示位。
127              WriteCommand(0x80+0x40+0x04);//LCD1602字符型液晶显示器第二行第5个位置的显示位
128              WriteCommand(0x0f);//开LCD1602字符型液晶显示器显示,开光标,开光标(或字符)闪烁。
129              break;
130       case 4:
131              minutanshi=minutanshi;//关掉定时器0定时后,把分钟计时时间数值取除后得到的值再赋给分钟十位显示位。
132              WriteCommand(0x80+0x40+0x03);//LCD1602字符型液晶显示器第二行第4个位置的显示位
133              WriteCommand(0x0f);//开LCD1602字符型液晶显示器显示,开光标,开光标(或字符)闪烁。
134              break;
135       case 5:
136              hourge=shi%10;//关掉定时器0定时后,把时钟计时时间数值取余赋给时钟个位显示位。
137              hourshi=shi/10;//关掉定时器0定时后,把时钟计时时间数值取除赋给时钟十位显示位。
138              WriteCommand(0x80+0x40+0x01);//LCD1602字符型液晶显示器第二行第2个位置的显示位
139              WriteCommand(0x0f);//开LCD1602字符型液晶显示器显示,开光标,开光标(或字符)闪烁。
140              break;
141       case 6:
142              hourshi=hourshi;//关掉定时器0定时后,把时钟计时时间数值取除后得到的值再赋给时钟十位显示位。
143              WriteCommand(0x80+0x40+0x00);//LCD1602字符型液晶显示器第二行第1个位置的显示位
144              WriteCommand(0x0f);//开LCD1602字符型液晶显示器显示,开光标,开光标(或字符)闪烁。
145              break;
146       case 7:
147              WriteCommand(0x80+0x40+0x07);//LCD1602字符型液晶显示器第二行第8个位置的显示位
148              WriteCommand(0x0c);//开LCD1602字符型液晶显示器显示,开光标,开光标(或字符)闪烁。
149              TR0=1;//打开定时器0
150              S1num=0;//移位按键S1按键按下次数清零
151              break;
152      default:
153              S1num=0;//移位按键S1按键按下次数清零
154              break;
155     }
156   }
157 }
158    if(S1num!=0)//判断移位按键S1按键按下次数变量是否为0
159   {
160     if(S2==0)//判断增加按键S2是否按下
161    {
162      if(S2==0)//判断增加按键S2是否按下
163     {
164       Delay(5);
165       if(S2==0)//再次判断增加按键S2是否按下
166      {
167        while(!S2);//等待增加按键S2弹起
168        switch(S1num)//移位按键S1按键按下次数变量选择位
169       {
170         case 1://移位按键S1按键第一次按下
171                secondge++;//秒钟个位数先赋值再加加
172                if(secondge==10)//判断秒钟个位数设定值是否达到10
173                secondge=0;//秒钟个位数归零
174                LCD1602DisplayGeDigitResolve(0x07,secondge);//LCD1602字符型液晶显示器第二行第8个位置的秒钟个位显示位的显示数
175                WriteCommand(0x80+0x40+0x07);//写入LCD1602字符型液晶显示器第二行第8个位置的秒钟个位显示位
176                miao=secondshi*10+secondge;//移位修改秒钟个位显示位的数值后,需要通过秒钟十位显示位的数值加上秒钟个位显示位的数值之和赋给秒钟变量,才能在修改秒钟个位或十位显示位的数值后重新计时。(原因:秒钟个位或十位显示位的数值是在秒钟的数值上分解得来,当秒钟个位或十位显示位的数值发生变化后,秒钟的数值也要变化,否则不能在原基础上修改后重新计时,只能返回原基础上计时。)
177                break;
178         case 2://移位按键S1按键第二次按下
179                secondshi++;//秒钟十位数先赋值再加加
180                if(secondshi==6)//判断秒钟十位数设定值是否达到6
181                secondshi=0;//秒钟十位数归零
182                LCD1602DisplayShiDigitResolve(0x06,secondshi);//LCD1602字符型液晶显示器第二行第7个位置的秒钟十位显示位的显示数
183                WriteCommand(0x80+0x40+0x06);//写入LCD1602字符型液晶显示器第二行第7个位置的秒钟十位显示位
184                miao=secondshi*10+secondge;//移位修改秒钟十位显示位的数值后,需要通过秒钟十位显示位的数值加上秒钟个位显示位的数值之和赋给秒钟变量,才能在修改秒钟个位或十位显示位的数值后重新计时。(原因:秒钟个位或十位显示位的数值是在秒钟的数值上分解得来,当秒钟个位或十位显示位的数值发生变化后,秒钟的数值也要变化,否则不能在原基础上修改后重新计时,只能返回原基础上计时。)
185                break;
186         case 3://移位按键S1按键第三次按下
187                minutange++;//分钟个位数先赋值再加加
188                if(minutange==10)//判断分钟个位数设定值是否达到10
189                minutange=0;//分钟个位数归零
190                LCD1602DisplayGeDigitResolve(0x04,minutange);//LCD1602字符型液晶显示器第二行第5个位置的分钟个位显示位的显示数
191                WriteCommand(0x80+0x40+0x04);//写入LCD1602字符型液晶显示器第二行第5个位置的分钟个位显示位
192                fen=minutanshi*10+minutange;//移位修改分钟个位显示位的数值后,需要通过分钟十位显示位的数值加上分钟个位显示位的数值之和赋给分钟变量,才能在修改分钟个位或十位显示位的数值后重新计时。(原因:分钟个位或十位显示位的数值是在分钟的数值上分解得来,当分钟个位或十位显示位的数值发生变化后,分钟的数值也要变化,否则不能在原基础上修改后重新计时,只能返回原基础上计时。)
193                break;
194         case 4://移位按键S1按键第四次按下
195                minutanshi++;//分钟十位数先赋值再加加
196                if(minutanshi==6)//判断分钟十位数设定值是否达到6
197                minutanshi=0;//分钟十位数归零
198                LCD1602DisplayShiDigitResolve(0x03,minutanshi);//LCD1602字符型液晶显示器第二行第4个位置的分钟十位显示位的显示数
199                WriteCommand(0x80+0x40+0x03);//写入LCD1602字符型液晶显示器第二行第7个位置的分钟十位显示位
200                fen=minutanshi*10+minutange;//移位修改分钟十位显示位的数值后,需要通过分钟十位显示位的数值加上分钟个位显示位的数值之和赋给分钟变量,才能在修改分钟个位或十位显示位的数值后重新计时。(原因:分钟个位或十位显示位的数值是在分钟的数值上分解得来,当分钟个位或十位显示位的数值发生变化后,分钟的数值也要变化,否则不能在原基础上修改后重新计时,只能返回原基础上计时。)
201                break;
202         case 5://移位按键S1按键第五次按下
203                hourge++;//时钟个位数先赋值再加加
204                if(hourge==4)//判断时钟个位数设定值是否达到4
205                hourge=0;//时钟个位数归零
206                LCD1602DisplayGeDigitResolve(0x01,hourge);//LCD1602字符型液晶显示器第二行第2个位置的时钟个位显示位的显示数
207                WriteCommand(0x80+0x40+0x01);//写入LCD1602字符型液晶显示器第二行第2个位置的时钟个位显示位
208                shi=hourshi*10+hourge;//移位修改时钟个位显示位的数值后,需要通过时钟十位显示位的数值加上时钟个位显示位的数值之和赋给时钟变量,才能在修改时钟个位或十位显示位的数值后重新计时。(原因:时钟个位或十位显示位的数值是在时钟的数值上分解得来,当时钟个位或十位显示位的数值发生变化后,时钟的数值也要变化,否则不能在原基础上修改后重新计时,只能返回原基础上计时。)
209                break;
210         case 6://移位按键S1按键第六次按下
211                hourshi++;//时钟十位数先赋值再加加
212                if(hourshi==3)//判断时钟十位数设定值是否达到3
213                hourshi=0;//时钟十位数归零
214                LCD1602DisplayShiDigitResolve(0x00,hourshi);//LCD1602字符型液晶显示器第二行第1个位置的时钟十位显示位的显示数
215                WriteCommand(0x80+0x40+0x00);//写入LCD1602第二行第1个位置的时钟十位显示位
216                shi=hourshi*10+hourge;//移位修改时钟十位显示位的数值后,需要通过时钟十位显示位的数值加上时钟个位显示位的数值之和赋给时钟变量,才能在修改时钟个位或十位显示位的数值后重新计时。(原因:时钟个位或十位显示位的数值是在时钟的数值上分解得来,当时钟个位或十位显示位的数值发生变化后,时钟的数值也要变化,否则不能在原基础上修改后重新计时,只能返回原基础上计时。)
217                break;
218        default:
219                S1num=0;//移位按键S1按键按下次数清零
220                break; 
221       }
222      }
223     }
224     if(S3==0)//判断减少按键S3是否按下
225    {
226      Delay(5);
227      if(S3==0)//再次判断减少按键S3是否按下
228     {
229       while(!S3);//等待减少按键S3弹起
230       switch(S1num)//移位按键S1按键按下次数变量选择位
231      {
232        case 1://移位按键S1按键第一次按下
233               secondge--;//秒钟个位数先赋值再减减
234               if(secondge==-1)//判断秒钟个位数设定值是否达到-1
235               secondge=9;//秒钟个位数归9
236               LCD1602DisplayGeDigitResolve(0x07,secondge);//LCD1602字符型液晶显示器第二行第8个位置的秒钟个位显示位的显示数
237               WriteCommand(0x80+0x40+0x07);//写入LCD1602字符型液晶显示器第二行第8个位置的秒钟个位显示位
238               miao=secondshi*10+secondge;//移位修改秒钟个位显示位的数值后,需要通过秒钟十位显示位的数值加上秒钟个位显示位的数值之和赋给秒钟变量,才能在修改秒钟个位或十位显示位的数值后重新计时。(原因:秒钟个位或十位显示位的数值是在秒钟的数值上分解得来,当秒钟个位或十位显示位的数值发生变化后,秒钟的数值也要变化,否则不能在原基础上修改后重新计时,只能返回原基础上计时。)
239               break;
240        case 2://移位按键S1按键第二次按下
241               secondshi--;//秒钟十位数先赋值再减减
242               if(secondshi==-1)//判断秒钟十位数设定值是否达到-1
243               secondshi=5;//秒钟十位数归5
244               LCD1602DisplayShiDigitResolve(0x06,secondshi);//LCD1602字符型液晶显示器第二行第7个位置的秒钟十位显示位的显示数
245               WriteCommand(0x80+0x40+0x06);//写入LCD1602字符型液晶显示器第二行第7个位置的秒钟十位显示位
246               miao=secondshi*10+secondge;//移位修改秒钟十位显示位的数值后,需要通过秒钟十位显示位的数值加上秒钟个位显示位的数值之和赋给秒钟变量,才能在修改秒钟个位或十位显示位的数值后重新计时。(原因:秒钟个位或十位显示位的数值是在秒钟的数值上分解得来,当秒钟个位或十位显示位的数值发生变化后,秒钟的数值也要变化,否则不能在原基础上修改后重新计时,只能返回原基础上计时。)
247               break;
248        case 3://移位按键S1按键第三次按下
249               minutange--;//分钟个位数先赋值再减减
250               if(minutange==-1)//判断分钟个位数设定值是否达到-1
251               minutange=9;//分钟个位数归9
252               LCD1602DisplayGeDigitResolve(0x04,minutange);//LCD1602字符型液晶显示器第二行第5个位置的分钟个位显示位的显示数
253               Wr

以上是关于基于51单片机通过点击移位按键移位修改LCD1602字符型液晶显示器显示时分秒个位十位数值的计时项目工程的主要内容,如果未能解决你的问题,请参考以下文章

51单片机 按键控制LED灯移位亮灭

基于51单片机定时器计数+2片74HC595联级+8位数码管时钟+按键修改时间

基于51单片机+DS1302万年历+LCD1602显示+按键播报时间+温控风扇+按键控灯

基于51单片机+DS1302万年历+LCD1602显示+按键播报时间+温控风扇+按键控灯

基于51单片机定时器计数+74HC595移位寄存器+8位数码管时钟

单片机 怎么用位移的方法实现乘除法