日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

51单片机定时器实现钟表(LCD1602显示)

發布時間:2023/12/10 编程问答 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 51单片机定时器实现钟表(LCD1602显示) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

文章目錄

  • 1、實現方法
  • 2、所有模塊函數
  • 3、定時器初始化函數(Timer0Init)
  • 4、LCD1602顯示函數(此顯示函數來自b站江科大自化協up主)
  • 5、主函數(main)

1、實現方法

通過定時器實現秒加,進而使時鐘跑起來,通過LCD1602進行顯示。

2、所有模塊函數

  • Timer0Init:定時器初始化函數。
  • LCD1602:LCD1602顯示函數。
  • main:主函數(包括中斷函數)。

3、定時器初始化函數(Timer0Init)

使用定時器T0計數,每20ms重裝一次,單片機晶振頻率11.0592MHz,對應重裝載值TH0=47104/256;TL0=47104%256;初始化代碼如下:

#include <STC89C5xRC.H> void Timer0Init() {TMOD=TMOD&0xf0;TMOD=TMOD|0x01;//配置定時器工作模式TF0=0; //計數器溢出標志位TR0=1; //允許定時器T0計數TH0=47104/256;TL0=47104%256;//計時20ms,11.0592MHzEA=1; //開總中斷ET0=1; //開定時器0中斷IPH=IPH&0xFD;//中斷優先級控制寄存器高,置零PT0HPT0=0; //中斷優先級控制寄存器低,置零PT0 }

當程序只用一個中斷時,IPH、PT0也可不配置,默認該中斷優先級為最低。

4、LCD1602顯示函數(此顯示函數來自b站江科大自化協up主)

#include <STC89C5xRC.H> #include <intrins.h>//延時函數_nop_()頭文件 //引腳配置: sbit LCD_RS=P2^6; sbit LCD_RW=P2^5; sbit LCD_EN=P2^7; #define LCD_DataPort P0//函數定義: /*** @brief LCD1602延時函數,11.0592MHz調用可延時1ms* @param 無* @retval 無*/ void LCD_Delay() {unsigned char i, j;_nop_();i = 2;j = 199;do{while (--j);} while (--i); }/*** @brief LCD1602寫命令* @param Command 要寫入的命令* @retval 無*/ void LCD_WriteCommand(unsigned char Command) {LCD_RS=0;LCD_RW=0;LCD_DataPort=Command;LCD_EN=1;LCD_Delay();LCD_EN=0;LCD_Delay(); }/*** @brief LCD1602寫數據* @param Data 要寫入的數據* @retval 無*/ void LCD_WriteData(unsigned char Data) {LCD_RS=1;LCD_RW=0;LCD_DataPort=Data;LCD_EN=1;LCD_Delay();LCD_EN=0;LCD_Delay(); }/*** @brief LCD1602設置光標位置* @param Line 行位置,范圍:1~2* @param Column 列位置,范圍:1~16* @retval 無*/ void LCD_SetCursor(unsigned char Line,unsigned char Column) {if(Line==1){LCD_WriteCommand(0x80|(Column-1));}else if(Line==2){LCD_WriteCommand(0x80|(Column-1+0x40));} }/*** @brief LCD1602初始化函數* @param 無* @retval 無*/ void LCD_Init() {LCD_WriteCommand(0x38);//八位數據接口,兩行顯示,5*7點陣LCD_WriteCommand(0x0c);//顯示開,光標關,閃爍關LCD_WriteCommand(0x06);//數據讀寫操作后,光標自動加一,畫面不動LCD_WriteCommand(0x01);//光標復位,清屏 }/*** @brief 在LCD1602指定位置開始顯示所給字符串* @param Line 起始行位置,范圍:1~2* @param Column 起始列位置,范圍:1~16* @param String 要顯示的字符串* @retval 無*/ void LCD_ShowString(unsigned char Line,unsigned char Column,char *String) {unsigned char i;LCD_SetCursor(Line,Column);for(i=0;String[i]!='\0';i++){LCD_WriteData(String[i]);} }/*** @brief 返回值=X的Y次方*/ int LCD_Pow(int X,int Y) {unsigned char i;int Result=1;for(i=0;i<Y;i++){Result*=X;}return Result; }/*** @brief 在LCD1602指定位置開始顯示所給數字* @param Line 起始行位置,范圍:1~2* @param Column 起始列位置,范圍:1~16* @param Number 要顯示的數字,范圍:0~65535* @param Length 要顯示數字的長度,范圍:1~5* @retval 無*/ void LCD_ShowNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length) {unsigned char i;LCD_SetCursor(Line,Column);for(i=Length;i>0;i--){LCD_WriteData(Number/LCD_Pow(10,i-1)%10+'0');} }

5、主函數(main)

主函數中需調用Timer0Init、LCD1602函數等,包含的頭文件如下:

#include <STC89C5xRC.H> #include "Timer0Init.h" //定時器初始化函數頭文件 #include "LCD1602.h" //LCD1602顯示函數頭文件 #include <string.h> //字符串比較函數頭文件
  • Timer0Init.h頭文件代碼如下:
#ifndef __TIMER0INIT_H__ #define __TIMER0INIT_H__void Timer0Init();#endif
  • LCD1602.h頭文件代碼如下:
#ifndef __LCD1602_H__ #define __LCD1602_H__void LCD_Init(); void LCD_ShowString(unsigned char Line,unsigned char Column,char *String); void LCD_ShowNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length);#endif
  • 字符串比較函數頭文件string.h

因在LCD1602上顯示漢字較為麻煩,而時鐘的年、月、日、時、分、秒,星期等漢字不便于顯示在LCD1602顯示屏上,若都不顯示或者年月日用“-”代替顯得較為隨意,不夠美觀。此處月份和星期采用英文縮寫顯示,將月份和星期分別初始化在數組中,而字符串比較函數就是判斷實時下的月份和星期。

char month[13][6]={" ","Jan.","Feb.","Mar.","Apr.","May.","Jun.","Jul.","Aug.","Sept.","Oct.","Nov.","Dec."}; idata char week[8][6]={" ","Mon.","Tues.","Wed.","Thur.","Fri.","Sat.","Sun."}; //單片機RAM前128字節不夠用,使用RAM前256字節,變量類型前(后)加idata
  • 初始化時間,變量定義與解釋如下:
unsigned int i=0,j=59,k=23,day=2,mon=5,year=2022,wek=1; //初始時間

其中i表示秒,j表示分,k表示時,day表示天,mon表示月,year表示年,wek表示星期。

  • 顯示效果如下圖所示:
  • main函數代碼如下:
#include <STC89C5xRC.H> #include "Timer0Init.h" //定時器初始化函數頭文件 #include "LCD1602.h" //LCD1602顯示函數頭文件 #include <string.h> //字符串比較函數頭文件 unsigned int i=56,j=59,k=23,day=2,mon=5,year=2022,wek=1; //初始時間 char month[13][6]={" ","Jan.","Feb.","Mar.","Apr.","May.","Jun.","Jul.","Aug.","Sept.","Oct.","Nov.","Dec."}; idata char week[8][6]={" ","Mon.","Tues.","Wed.","Thur.","Fri.","Sat.","Sun."}; //單片機RAM前128字節不夠用,使用RAM前256字節,變量類型前(后)加idatavoid main() {Timer0Init(); //定時器初始化LCD_Init(); //LCD1602初始化 LCD_ShowString(2,3,":"); //在屏幕第二行第三列顯示冒號 LCD_ShowString(2,6,":"); //在屏幕第二行第六列顯示冒號 LCD_ShowString(1,3,"th"); //在屏幕第一行第三列顯示th,代表日期的“號” while(1){LCD_ShowNum(2,7,i,2); //在屏幕的第二行第七列更新顯示秒LCD_ShowNum(2,4,j,2); //在屏幕的第二行第四列更新顯示分LCD_ShowNum(2,1,k,2); //在屏幕的第二行第一列更新顯示時LCD_ShowNum(1,1,day,2); //在屏幕的第一行第一列更新顯示天LCD_ShowString(1,6,month[mon]); //在屏幕的第一行第六列更新顯示月LCD_ShowNum(1,11,year,4); //在屏幕的第一行第十一列更新顯示年LCD_ShowString(2,11,week[wek]); //在屏幕的第二行第十一列更新顯示星期} }void Timer0_Rountine(void) interrupt 1 {static unsigned int cont;TH0=47104/256;TL0=47104%256; //定時器T0重裝載值,溢出率為20ms/次cont++;if(cont>=50) //判斷計時是否滿1s{cont=0;i++;if(i>=60) //判斷計時是否滿1min{i=0;j++;if(j>=60) //判斷計時是否滿1h{j=0;k++;if(k>=24) //判斷計時是否滿1天{k=0;day++;wek++;if(wek>7) //判斷計時是否滿1周{wek=1;}//判斷此時是否為4、6、9、11月if((strcmp(month[mon],"Apr.")==0)||(strcmp(month[mon],"Jun.")==0)||(strcmp(month[mon],"Sept.")==0)||(strcmp(month[mon],"Nov.")==0)){if(day>30){day=1;mon++;}}//判斷此時是否為1、3、5、7、8、10、12月else if((strcmp(month[mon],"Jan.")==0)||(strcmp(month[mon],"Mar.")==0)||(strcmp(month[mon],"May.")==0)||(strcmp(month[mon],"Jul.")==0)||(strcmp(month[mon],"Aug.")==0)||(strcmp(month[mon],"Oct.")==0)||(strcmp(month[mon],"Dec.")==0)){if(day>31){day=1;mon++;if(mon>12){mon=1;year++;}}}//若以上都不滿足,即為2月else {if(((year%4==0)&&(year%100!=0))||(year%400==0)) //判斷是否為閏年{if(day>29){day=1;mon++;}}else{if(day>28){day=1;mon++;}}}}}}} }

總結

以上是生活随笔為你收集整理的51单片机定时器实现钟表(LCD1602显示)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。