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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

基于stc89c52电子钟综合设计

發布時間:2024/1/1 编程问答 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 基于stc89c52电子钟综合设计 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

?? 1、基本功能:

?實現時間自動顯示和音響報時

① 按實時時間顯示時分秒

② 每隔60秒自動短響一聲????????

③ 按日期顯示-日?????????????

④ 每隔60連續響多聲,幾點響幾聲

⑤ 可設置每天4次鬧鐘功能

⑥ 設有調整日期、時間和止鬧按鈕

⑦ 有按秒閃動的雙LED

⑧? 鬧鈴需急促響多聲????????????

⑨ 日期與時間輪流顯示

51單片機_外部中斷 與 定時/計數器中斷

外部中斷其實隸屬于按鍵處理,外部中斷最著名的當屬IT0了,若IT0賦值為0,這個按鈕其實是低電平觸發;若IT0賦值為1,這個按鈕其實是下邊沿觸發。

(1條消息) 51單片機外部中斷 與 定時/計數器中斷踏過山河,踏過海的博客-CSDN博客_51單片機定時器中斷計數

定時器其實就是倒計時,而定時器T0和T1分別對應的引腳是P3.4和P3.5。

(插播一條廣告:EA代表總閘,不管是外部中斷,還是定時器中斷要開啟,首先都要EA開閘,外部中斷或定時器中斷也開閘才能運行.)

設計4次鬧鐘思路:(這里運用比較簡單方式 數組)

設置一次 然后按下k2 表示設置成功 刷新 success1

設置第二次 繼續按下k2 表示設置成功 刷新 success2

設置成功把數據存放到數組中。 判斷數組成員的hour min 是否相等 相等的話就響應

代碼實現

?

下面是代碼演示:此項目主要也是基于定時器實現時間的計時,利用按鈕調節模式切換 設置鬧鐘 調節時間等功能?

?

main函數:

#include <REGX52.H> #include "sys.h" #include "mode.h" #include "beep.h" #include "LCD1602.h" #include "key.h" #include <stdio.h>uchar mod;uchar naomin=0;uchar naohour=2;uchar naosec=0;//鬧鐘的時分秒uchar sec=59,min=59,hour=5,day,month,countmin,counthour,n; uchar day=2; uchar month=9; uint year=2022; uint i,j; int cont_res_flag = 0; extern u8 stop_clock_flag;void main() {Timer1Init();Int0Init();Int1Init();LCD_Init();LCD_ShowString(1,1," / / ");LCD_ShowString(2,1," : : ");while(1){Mode();key_control();} }void Int0() interrupt 0 //外部中斷 按鍵操作 關閉開啟鬧鐘響 {delay(10);//消抖if(K3==0){Buzzer_Time(100);stop_clock_flag = ~stop_clock_flag;}}void Int1() interrupt 2 {delay(15);if(K4==0){if(mod==1){LCD_ShowString(1,1," / / ");LCD_ShowString(2,1," : : ");delay(10);mod=0;delay(10);}else{LCD_ShowString(2,1," : : ");delay(10);mod=1;}} }int k = 0; void Timer1() interrupt 3 {int j= 0;TH1=0xd8;TL1=0xf0;i++;k++;if(i==100)//1秒{sec++; i=0; j++; Led2_on();Led1_on();}if(j==10){j=0;Led1_on();}if(sec==60){min++; sec=0; n=0; countmin++;Buzzer_Time(50);}if(min==60){hour++; min=0; counthour++;cont_res_flag = 1;for( ; j <hour+1; j++){Buzzer_Time(100);delay(60);}}if(hour==24) {day++; hour=0;}if(day==30){month++; day=1;}if(month==12){year++; month=1;}if(k == 70){k = 0;if(hour == bufhour[0] && min == bufmin[0] && stop_clock_flag == 1){Buzzer_Time(100);}if(hour == bufhour[1] && min == bufmin[1] && stop_clock_flag == 1){Buzzer_Time(100);}if(hour == bufhour[2] && min == bufmin[2] && stop_clock_flag == 1){Buzzer_Time(100);}if(hour == bufhour[3] && min == bufmin[3] && stop_clock_flag == 1){Buzzer_Time(100);} } }

sys.c

#include <REG52.H>sbit LED1=P2^0; sbit LED2=P2^1; //sbit LED3=P2^2; //sbit LED4=P2^3;void delay(unsigned int xms) //@12.000MHz {while(xms){unsigned char i, j;i = 2;j = 239;do{while (--j);} while (--i);xms--;} }void time0_init(void) {TMOD|=0X01;//選擇為定時器0模式,工作方式1TH0=0XFC; //給定時器賦初值,定時1msTL0=0X18; ET0=1;//打開定時器0中斷允許EA=1;//打開總中斷TR0=1;//打開定時器 }void Timer1Init() {TMOD=0x10;TH1=0xd8;TL1=0xf0; //10msET1=1;EA=1;TR1=1; }void Int0Init() {EX0=1;IT0=1;EA=1; }void Int1Init() {EX1=1;IT1=1;EA=1; }void Led1_on() {LED1=~LED1;delay(20);LED1=~LED1; }void Led2_on() {LED2=~LED2;delay(20);LED2=~LED2; }//void Led3_on() //{ // LED3=~LED3; // delay(20); // LED3=~LED3; //}//void Led4_on() //{ // LED4=~LED4; // delay(20); // LED4=~LED4; //}

sys.h

#ifndef __SYS_H__ #define __SYS_H__#include <REGX52.H>typedef unsigned char uchar; typedef unsigned int uint;sbit K1=P3^0; sbit K2=P3^1; sbit K3=P3^2; sbit K4=P3^3;//蜂鳴器端口: sbit Buzzer=P1^5;extern uchar sec,min,hour,day,month,countmin,counthour,mod,naomin,naohour,n,naosec; extern uint year;void Led1_on(); void Led2_on(); void Led3_on(); void Led4_on(); void Timer1Init(); void Int0Init(); void Int1Init(); void delay(unsigned int xms); void time0_init(void);#endif

beep.c

#include <REGX52.H> #include <INTRINS.H> #include "sys.h"/*** @brief 蜂鳴器私有延時函數,延時500us* @param 無* @retval 無*/ void Buzzer_Delay500us() //@12.000MHz {unsigned char i;_nop_();i = 247;while (--i); }/*** @brief 蜂鳴器發聲* @param ms 發聲的時長,范圍:0~32767* @retval 無*/ void Buzzer_Time(unsigned int ms) {unsigned int i;for(i=0;i<ms*2;i++){Buzzer=!Buzzer;Buzzer_Delay500us();} }

beep.h

#ifndef __BEEP_H_ #define __BEEP_H_void Buzzer_Time(unsigned int ms);#endif

lcd1602.c

#include <REGX52.H>//引腳配置: sbit LCD_RS=P2^6; sbit LCD_RW=P2^5; sbit LCD_EN=P2^7; #define LCD_DataPort P0//函數定義: /*** @brief LCD1602延時函數,12MHz調用可延時1ms* @param 無* @retval 無*/ void LCD_Delay() {unsigned char i, j;i = 2;j = 239;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 Char 要顯示的字符* @retval 無*/ void LCD_ShowChar(unsigned char Line,unsigned char Column,char Char) {LCD_SetCursor(Line,Column);LCD_WriteData(Char); }/*** @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');} }/*** @brief 在LCD1602指定位置開始以有符號十進制顯示所給數字* @param Line 起始行位置,范圍:1~2* @param Column 起始列位置,范圍:1~16* @param Number 要顯示的數字,范圍:-32768~32767* @param Length 要顯示數字的長度,范圍:1~5* @retval 無*/ void LCD_ShowSignedNum(unsigned char Line,unsigned char Column,int Number,unsigned char Length) {unsigned char i;unsigned int Number1;LCD_SetCursor(Line,Column);if(Number>=0){LCD_WriteData('+');Number1=Number;}else{LCD_WriteData('-');Number1=-Number;}for(i=Length;i>0;i--){LCD_WriteData(Number1/LCD_Pow(10,i-1)%10+'0');} }/*** @brief 在LCD1602指定位置開始以十六進制顯示所給數字* @param Line 起始行位置,范圍:1~2* @param Column 起始列位置,范圍:1~16* @param Number 要顯示的數字,范圍:0~0xFFFF* @param Length 要顯示數字的長度,范圍:1~4* @retval 無*/ void LCD_ShowHexNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length) {unsigned char i,SingleNumber;LCD_SetCursor(Line,Column);for(i=Length;i>0;i--){SingleNumber=Number/LCD_Pow(16,i-1)%16;if(SingleNumber<10){LCD_WriteData(SingleNumber+'0');}else{LCD_WriteData(SingleNumber-10+'A');}} }/*** @brief 在LCD1602指定位置開始以二進制顯示所給數字* @param Line 起始行位置,范圍:1~2* @param Column 起始列位置,范圍:1~16* @param Number 要顯示的數字,范圍:0~1111 1111 1111 1111* @param Length 要顯示數字的長度,范圍:1~16* @retval 無*/ void LCD_ShowBinNum(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(2,i-1)%2+'0');} } #ifndef __LCD1602_H__ #define __LCD1602_H__//用戶調用函數: void LCD_Init(); void LCD_ShowChar(unsigned char Line,unsigned char Column,char Char); 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); void LCD_ShowSignedNum(unsigned char Line,unsigned char Column,int Number,unsigned char Length); void LCD_ShowHexNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length); void LCD_ShowBinNum(unsigned char Line,unsigned char Column,unsigned int Number,unsigned char Length);#endif

mode.c? ?

#include "sys.h" #include "LCD1602.h" #include "key.h" #include "beep.h" #include "stdio.h"u8 reduce_plus_flag = 1;//默認加u8 stop_clock_flag = 1;//默認1 開鬧鐘 0停鬧鐘uchar set_time = 0; uchar bufhour[4] ; uchar bufmin[4] ;void naozhongjishu() {} void key_control() {u8 key_code;if(K1==0){delay(50);if(K1==0){if(set_time > 3){set_time = 0;}Buzzer_Time(100);LCD_ShowString(1,1," set success!");LCD_ShowString(2,1," ");delay(80);bufhour[set_time] = naohour;bufmin[set_time] = naomin;set_time++;if(mod==1){LCD_ShowString(1,1," / / ");LCD_ShowString(2,1," : : ");delay(10);mod=0;delay(10);}else{LCD_ShowString(2,1," : : ");delay(10);mod=1;} }}key_code = key_matrix_ranks_scan();if(key_code == 1){if( reduce_plus_flag == 0)reduce_plus_flag =1;else{reduce_plus_flag =0;}} //1.修改日期 if(key_code == 2 && reduce_plus_flag == 1) //年份加{year++;;}else if(key_code == 3 && reduce_plus_flag == 1) //月份加{month++;}else if(key_code == 4 && reduce_plus_flag == 1) //日 加{day++;}if(key_code == 2 && reduce_plus_flag == 0) //年份減{year--;}else if(key_code == 3 && reduce_plus_flag == 0) //月份減{month--;}else if(key_code == 4 && reduce_plus_flag == 0) //日 減{day--;} //2.修改時間if(key_code == 6 && reduce_plus_flag == 1) //時加{if(mod==0){hour++;}else{naohour++;}}else if(key_code == 7 && reduce_plus_flag == 1) //分加{if(mod==0){min++;}else{naomin++;}}else if(key_code == 8 && reduce_plus_flag == 1) //秒 加{if(mod==0){sec++;}else{naosec++;}}if(key_code == 6 && reduce_plus_flag == 0) //時減{if(mod==0){hour--;}else{naohour--;}}else if(key_code == 7 && reduce_plus_flag == 0) //分減{if(mod==0){min--;}else{naomin--;}}else if(key_code == 8 && reduce_plus_flag == 0) //秒 減{if(mod==0){sec--;}else{naosec--;}}//3.判斷時間格式if(sec==60){min++; sec=0; n=0; countmin++;}if(min==60){hour++; min=0; counthour++;}if(hour==24) {day++; hour=0;}if(day==30){month++; day=1;}if(month==12){year++; month=1;}if(naosec==60){naomin++;naosec=0;} if(naomin==60){naohour++;naomin=0;}if(naohour==24){naohour=0;} }void Mode() {if(mod==0){LCD_ShowNum(2,7,sec,2);LCD_ShowNum(2,4,min,2);LCD_ShowNum(2,1,hour,2);LCD_ShowNum(1,9,day,2);LCD_ShowNum(1,6,month,2); LCD_ShowNum(1,1,year,4);}else{LCD_ShowString(1,1,"clock: ");LCD_ShowNum(2,7,naosec,2);LCD_ShowNum(2,4,naomin,2);LCD_ShowNum(2,1,naohour,2);} }void zhinao() {n=100; }

mode.h

#ifndef __MODE_H_ #define __MODE_H_void naozhongjishu(); void key_control(); void Mode(); void zhinao();extern int set_time ; extern uchar bufhour[4] ; extern uchar bufmin[4] ;//uchar bufhour[4] ; //uchar bufmin[4] ;#endif

key.c? (矩陣按鍵掃描)

#include "reg52.h" #include "key.h"/******************************************************************************* * 函 數 名 : delay_10us * 函數功能 : 延時函數,ten_us=1時,大約延時10us * 輸 入 : ten_us * 輸 出 : 無 *******************************************************************************/ void delay_10us(u16 ten_us) {while(ten_us--); }/******************************************************************************* * 函 數 名 : key_matrix_ranks_scan * 函數功能 : 使用行列式掃描方法,檢測矩陣按鍵是否按下,按下則返回對應鍵值 * 輸 入 : 無 * 輸 出 : key_value:1-16,對應S1-S16鍵,0:按鍵未按下 *******************************************************************************/ u8 key_matrix_ranks_scan(void) {u8 key_value=0;KEY_MATRIX_PORT=0xf7;//給第一列賦值0,其余全為1if(KEY_MATRIX_PORT!=0xf7)//判斷第一列按鍵是否按下{delay_10us(1000);//消抖switch(KEY_MATRIX_PORT)//保存第一列按鍵按下后的鍵值 {case 0x77: key_value=1;break;case 0xb7: key_value=5;break;case 0xd7: key_value=9;break;case 0xe7: key_value=13;break;}}while(KEY_MATRIX_PORT!=0xf7);//等待按鍵松開 KEY_MATRIX_PORT=0xfb;//給第二列賦值0,其余全為1if(KEY_MATRIX_PORT!=0xfb)//判斷第二列按鍵是否按下{delay_10us(1000);//消抖switch(KEY_MATRIX_PORT)//保存第二列按鍵按下后的鍵值 {case 0x7b: key_value=2;break;case 0xbb: key_value=6;break;case 0xdb: key_value=10;break;case 0xeb: key_value=14;break;}}while(KEY_MATRIX_PORT!=0xfb);//等待按鍵松開 KEY_MATRIX_PORT=0xfd;//給第三列賦值0,其余全為1if(KEY_MATRIX_PORT!=0xfd)//判斷第三列按鍵是否按下{delay_10us(1000);//消抖switch(KEY_MATRIX_PORT)//保存第三列按鍵按下后的鍵值 {case 0x7d: key_value=3;break;case 0xbd: key_value=7;break;case 0xdd: key_value=11;break;case 0xed: key_value=15;break;}}while(KEY_MATRIX_PORT!=0xfd);//等待按鍵松開 KEY_MATRIX_PORT=0xfe;//給第四列賦值0,其余全為1if(KEY_MATRIX_PORT!=0xfe)//判斷第四列按鍵是否按下{delay_10us(1000);//消抖switch(KEY_MATRIX_PORT)//保存第四列按鍵按下后的鍵值 {case 0x7e: key_value=4;break;case 0xbe: key_value=8;break;case 0xde: key_value=12;break;case 0xee: key_value=16;break;}}while(KEY_MATRIX_PORT!=0xfe);//等待按鍵松開return key_value; }

key.h

#ifndef __KEY_H__ #define __KEY_H__ typedef unsigned int u16; //對系統默認數據類型進行重定義 typedef unsigned char u8; #define KEY_MATRIX_PORT P1 //使用宏定義矩陣按鍵控制口 u8 key_matrix_ranks_scan(void); #endif

總結

以上是生活随笔為你收集整理的基于stc89c52电子钟综合设计的全部內容,希望文章能夠幫你解決所遇到的問題。

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