6位LED顯示單片機控制電子鐘/計數器

2020-12-21 電子產品世界
這是我們設計的單片機電子鐘/計時器學習板,它採用6位LED數碼管顯示時、分、秒,以24小時計時方式。可以通過按鍵實現時分調整、秒表/時鐘功能轉換、省電(關閉顯示)等功能。我們能提供的完整的彙編語言源程序清單及電路原理設計圖有助於學習者進行分析和進行實驗驗證

產品1:6位LED顯示單片機控制電子鐘/計數器成品板成品每套84元

本文引用地址:http://www.eepw.com.cn/article/201611/317464.htm

硬體參數板上資源:MCU STC89C52、6位Led顯示、3位按鍵。電源部分為5V直流電壓,需要穩壓、濾波電路,不能接反!

51單片機做的電子鐘在很多地方都有介紹, 對於單片機學習者來說這個程序基本上是一道門檻,掌握了電子鐘程序, 基本上可以說51單片機就掌握了80%。常見的電子鐘程序由顯示部分、計算部分、時鐘調整部分構成,本產品硬體上完全支持倒計時器,客戶只要自己修改程序就能實現倒計時功能。

為了實現LED顯示器的數字顯示,可以採用靜態顯示法和動態顯示法。由於靜態顯示法需要數據鎖存器等硬體,接口複雜一些。考慮時鐘顯示只有六位,且系統沒有其它複雜的處理任務,所以決定採用動態掃描法實現LED的顯示。單片機採用易購的AT89S51系列,這樣單片機可具有足夠的空餘硬體資源實現其它的擴充功能,硬體系統的總體構成如下圖所示:視頻演示http://xie-gang.com/SZDZZ.htm視頻演示

該板採用AT89S51單片機,最小化應用設計,採用共陽七段LED顯示器,P0口輸出段碼數據,P2.0~P2.5做列掃描輸出,P1.0,P1.2,P1.3,接三個按鍵開關,用以調時及功能設置。為了提高共陽數碼管的驅動電壓,用9012做電源驅動輸出。採用12M晶振,有利於提高秒計時的精度。

本設計中,計時採用定時器T0中斷完成,其餘狀態循環調用顯示子程序,當埠開關按下時,轉入相應功能程序。其主程序執行流程圖見下左圖:



數碼管顯示的數據存放在內存單元70H~75H中。其中70H~71H存放秒數據,72H~73H存放分數據,74H~75H存放時數據,每一地址單元內均為十進位BCD碼。由於採用軟體動態掃描實現數據顯示功能,顯示用十進位BCD碼數據的對應段碼存放在ROM表中。顯示時,先取出70H~~75H某一地址中的數據,然後查得對應的顯示用段碼,並從P0口輸出,P2口將對應的數碼管選中供電,就能顯示該地址單元的數據值。

定時器T0用於時間計時。定時溢出中斷周期可分別設為50mst和10ms。中斷進入後,先判斷是時鐘計時還是秒表計時,時鐘計時累計中斷20次(即1s)時,對秒計數單元進行加1操作,秒表計時每10ms進行加1操作。時鐘計數單元地址分別在70H~71H(秒)、76H~77H(分)和78H~79H(時),最大計時值為23時59分59秒。而秒表計數單元地址也在70H~~71H(0.01毫秒)、76H~~77H(秒)和78H~~79H(分),最大計時值為99分59.99秒。7AH單元內存放「熄滅符」數據(#0AH)。在計數單元中採用十進位BCD碼計數,滿60(秒表功能時有100)進位,T0中斷服務程序執行流程見上圖右

T1中斷服務程序用於指示調整單元數字的亮閃。在時間調整狀態下,每過0.3S將對應單元的顯示數據換成「熄滅符」數據(#0AH)。這樣在調整時間時,對應調整單元的顯示數據會間隔閃亮。

調時功能程序的設計方法是:按下P1.0口按鍵,若按下時間短於1 s則進入省電狀態(數碼管不亮,時鐘不停);否則進入調分狀態,等待操作,此時計時器停止走動。當再按下按鈕時,若按下時間短於0.5s,則時間加1分;若按下時間長於0.5s,則進入[小]時調整狀態。在[小]時調整狀態下,當按鍵按下的時間長於0.5s時,退出調整狀態,時鐘繼續走動。P1.1口按鍵在調時狀態下可實現減1功能。

使用方法:按下K1按鍵,如果按下時間小於1秒,就會進入省電模式,這時數碼管熄滅但是時鐘仍然運行。如果按下K1按鍵時間大於1秒,就會進入調分狀態,此時計時器停止走動等待操作,這時中間的兩位00會閃爍,這時當按下K1按鍵時間小於0.5秒時,時間信息就會加1(單位分鐘);若時間大於0.5秒,這時左邊的兩位00會閃爍,進入小時調整,在小時調整狀態下按下S6按鍵時間小於0.5秒時,時間信息就會加1(單位小時),如果按下按鍵時間大於0.5S時,就會退出調整狀態,時鐘繼續走動。

配件:採用PL2303晶片的USB轉TTL串口模塊每個15元含一根4芯杜邦連接線

你還可以另外購買我們的PL2303模塊,就能實現STC晶片的在線程序下載。只要連接3根線:一根串口入R連接單片機的P3.1TXD、一根串口出D連接單片機的P3.0 RXD、一根地線-連接單片機的電源地即可。

然後將PL2303的USB轉串口模塊插入電腦的USB口(已經安裝好2303的驅動),然後在STC編程軟體界面中選擇單片機型號STC89C52RC,選擇COM6(具體按電腦實際虛擬出的串口號)波特率選擇9600,點擊「OPEN FILE」選擇你的燒寫文件,點擊「下載」按鈕,然後接通超聲波測距成品學習板的電源,3秒左右就能完成程序下載並運行。

以下是部分彙編源程序,購買我們產品後我們可以通過電子郵件將完整的單片機彙編源程序和燒寫文件發送給客戶。;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; AT89S51時鐘程序 ;;(該程序不全,不要直接使用。購買產品後提供全部程序和圖紙)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; 定時器T0、T1溢出周期為50MS,T0為秒計數用, T1為調整時閃爍用,
; P1.0、P1.1、P1.2為調整按鈕,P0口 為字符輸出口,採用共陽顯示管。
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; 中斷入口程序 ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
ORG 0000H ;程序執行開始地址
LJMP START ;跳到標號START執行
ORG 0003H ;外中斷0中斷程序入口
RETI ;外中斷0中斷返回
ORG 000BH ;定時器T0中斷程序入口
LJMP INTT0 ;跳至INTTO執行
ORG 0013H ;外中斷1中斷程序入口
RETI ;外中斷1中斷返回
ORG 001BH ;定時器T1中斷程序入口
LJMP INTT1 ;跳至INTT1執行
ORG 0023H ;串行中斷程序入口地址
RETI ;串行中斷程序返回
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; 主 程 序 ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
START: LCALL ST ;上電顯示年月日及班級學號
MOV R0,#70H ;清70H-7AH共11個內存單元
MOV R7,#0BH ;
CLEARDISP: MOV @R0,#00H ;
INC R0 ;
DJNZ R7,CLEARDISP ;
MOV 20H,#00H ;清20H(標誌用)
MOV 7AH,#0AH ;放入"熄滅符"數據
MOV TMOD,#11H ;設T0、T1為16位定時器
MOV TL0,#0B0H ;50MS定時初值(T0計時用)
MOV TH0,#3CH ;50MS定時初值
MOV TL1,#0B0H ;50MS定時初值(T1閃爍定時用)
MOV TH1,#3CH ;50MS定時初值
SETB EA ;總中斷開放
SETB ET0 ;允許T0中斷
SETB TR0 ;開啟T0定時器
MOV R4,#14H ;1秒定時用初值(50MS×20)
START1: LCALL DISPLAY ;調用顯示子程序
JNB P1.0,SETMM1 ;P1.0口為0時轉時間調整程序
JNB P1.1,FUNSS ; 秒表功能,P1.1按鍵調時時作減1加能
JNB P1.2,FUNPT ;STOP,PUSE,CLR
SJMP START1 ;P1.0口為1時跳回START1
SETMM1: LJMP SETMM ;轉到時間調整程序SETMM
FUNSS: LCALL DS20MS
JB P1.1,START1
WAIT11: JNB P1.1,WAIT11
CPL 03H
MOV 70H,#00H
MOV 71H,#00H
MOV 76H,#00H
MOV 77H,#00H
MOV 78H,#00H
MOV 79H,#00H
AJMP START1
FUNPT: LCALL DS20MS
JB P1.2,START1
WAIT22: JNB P1.2,WAIT21
CLR ET0
CLR TR0
WAIT33: JB P1.2,WAIT31
LCALL DS20MS
JB P1.2,WAIT33
WAIT66: JNB P1.2,WAIT61
MOV R0,#70H ;清70H-79H共10個內存單元
MOV R7,#0AH ;
CLEARP: MOV @R0,#00H ;
INC R0 ;
DJNZ R7,CLEARP ;
WAIT44: JB P1.2,WAIT41
LCALL DS20MS
JB P1.2,WAIT44
WAIT55: JNB P1.2,WAIT51
SETB ET0
SETB TR0
AJMP START1
WAIT21: LCALL DISPLAY
AJMP WAIT22
WAIT31: LCALL DISPLAY
AJMP WAIT33
WAIT41: LCALL DISPLAY
AJMP WAIT44
WAIT51: LCALL DISPLAY
AJMP WAIT55
WAIT61: LCALL DISPLAY
AJMP WAIT66
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; 1秒計時程序 ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;T0中斷服務程序
INTT0: PUSH ACC ;累加器入棧保護
PUSH PSW ;狀態字入棧保護
CLR ET0 ;關T0中斷允許
CLR TR0 ;關閉定時器T0
JB 03H,FSS
MOV A,#0B7H ;中斷響應時間同步修正
ADD A,TL0 ;低8位初值修正
MOV TL0,A ;重裝初值(低8位修正值)
MOV A,#3CH ;高8位初值修正
ADDC A,TH0 ;
MOV TH0,A ;重裝初值(高8位修正值)
SETB TR0 ;開啟定時器T0
DJNZ R4, OUTT0 ;20次中斷未到中斷退出
ADDSS: MOV R4,#14H ;20次中斷到(1秒)重賦初值
MOV R0,#71H ;指向秒計時單元(71H-72H)
ACALL ADD1 ;調用加1程序(加1秒操作)
MOV A,R3 ;秒數據放入A(R3為2位十進位數組合)
CLR C ;清進位標誌
CJNE A,#60H,ADDMM ;
ADDMM: JC OUTT0 ;小於60秒時中斷退出
ACALL CLR0 ;大於或等於60秒時對秒計時單元清0
MOV R0,#77H ;指向分計時單元(76H-77H)
ACALL ADD1 ;分計時單元加1分鐘
MOV A,R3 ;分數據放入A
CLR C ;清進位標誌
CJNE A,#60H,ADDHH ;
ADDHH: JC OUTT0 ;小於60分時中斷退出
ACALL CLR0 ;大於或等於60分時分計時單元清0
MOV R0,#79H ;指向小時計時單元(78H-79H)
ACALL ADD1 ;小時計時單元加1小時
MOV A,R3 ;時數據放入A
CLR C ;清進位標誌
JB 03H,OUTT0 ;秒表時最大數為99
CJNE A,#24H,HOUR ;
HOUR: JC OUTT0 ;小於24小時中斷退出
ACALL CLR0 ;大於或等於24小時小時計時單元清0
OUTT0: MOV 72H,76H ;中斷退出時將分、時計時單元數據移
MOV 73H,77H ;入對應顯示單元
MOV 74H,78H ;
MOV 75H,79H ;
POP PSW ;恢復狀態字(出棧)
POP ACC ;恢復累加器
SETB ET0 ;開放T0中斷
RETI ;中斷返回
;秒表計時程序(10MS加1),低2位為0.1、0.01秒,中間2位為秒,最高位為分。
;最大計數值為99
FSS: MOV A,#0F7H ;中斷響應時間同步修正,重裝初值(10ms)
ADD A,TL0 ;低8位初值修正
MOV TL0,A ;重裝初值(低8位修正值)
MOV A,#0D8H ;高8位初值修正
ADDC A,TH0 ;
MOV TH0,A ;重裝初值(高8位修正值)
SETB TR0 ;開啟定時器T0
MOV R0,#71H ;指向秒計時單元(71H-72H)
ACALL ADD1 ;調用加1程序(加1秒操作)
CLR C ;
MOV A,R3 ;
JZ FSS1 ;加1後為00,C=0
SETB C ;加1後不為00,C=1
FSS1: AJMP ADDMM ;
》》》》》》》》》》》省略》》》》》
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; 加1子 程 序 ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
ADD1: MOV A,@R0 ;取當前計時單元數據到A
DEC R0 ;指向前一地址
SWAP A ;A中數據高四位與低四位交換
ORL A,@R0 ;前一地址中數據放入A中低四位
ADD A,#01H ;A加1操作
DA A ;十進位調整
MOV R3,A ;移入R3寄存器
ANL A,#0FH ;高四位變0
MOV @R0,A ;放回前一地址單元
MOV A,R3 ;取回R3中暫存數據
INC R0 ;指向當前地址單元
SWAP A ;A中數據高四位與低四位交換
ANL A,#0FH ;高四位變0
MOV @R0,A ;數據放入當削地址單元中
RET ;子程序返回
》》》》》》》》》》》省略》》》》》
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; 延時程序 ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
;1MS延時程序,LED顯示程序用
DL1MS: MOV R6,#14H

#############################################################################################################################################

產品2:採用AT89C2051的6位LED電子鐘(計數器)

一、原理說明:

1、顯示原理:

顯示部分主要器件為2位共陽紅色數碼管,驅動採用PNP型三極體驅動,各埠配有限流電阻,驅動方式為掃描,佔用P1.0~P1.6埠。冒號部分採用4個Φ3.0的紅色發光,驅動方式為獨立埠驅動,佔用P1.7埠。

2、鍵盤原理:

按鍵S1~S3採用復用的方式與顯示部分的P3.5、P3.4、P3.2口復用。其工作方式為,在相應埠輸出高電平時讀取按鍵的狀態並由單片機支除抖動並賦予相應的鍵值。

3、迅響電路及輸入、輸出電路原理:

迅響電路由有源蜂鳴器和PNP型三極體組成。其工作原理是當PNP型三極體導通後有源蜂鳴器立即發出定頻聲響。驅動方式為獨立埠驅動,佔用P3.7埠。
輸出電路是與迅響電路複合作用的,其電路結構為有源蜂鳴器,5.1K定值電阻R6,排針J3並聯。當有源蜂鳴器無迅響時J3輸出低電平,當有源蜂鳴器發出聲響時J3輸出高電平,J3可接入數字電路等各種需要。驅動方式為迅響複合輸出,不佔埠。

輸入電路是與迅響電路複合作用的,其電路結構是在迅響電路的PNP型三極體的基極電路中接入排針J2。引腳排針可改變單片機I/O口的電平狀態,從而達到輸入的目的。驅動方式為複合埠驅動,佔用P3.7埠。

4、單片機系統:

本產品採用AT89C2051為核心器件(AT89C2051燒寫程序必須藉助專用編程器,我們提供的單片機已經寫入程序),並配合所有的必須的電路,只具有上電復位的功能,無手動復位功能。

二、使用說明:

1、功能按鍵說明: S1為功能選擇按鍵,S2為功能擴展按鍵,S3為數值加一按鍵。
2、功能及操作說明:操作時,連續短時間(小於1秒)按動S1,即可在以上的6個功能中連續循環。中途如果長按(大於2秒)S1,則立即回到時鐘功能的狀態。

1、時鐘功能:上電後即顯示10:10:00 ,寓意十全十美。
2、校時功能:短按一次S1,即當前時間和冒號為閃爍狀態,按動S2則小時位加1,按動S3則分鐘位加1,秒時不可調。
3、鬧鐘功能:短按二次S1,顯示狀態為22:10:00,冒號為長亮。按動S2剛小時位加1,按動S3則分鐘位加1,秒時不可調。當按動小時位超過23時則會顯示--:--:--,這個表示關閉鬧鐘功能。鬧鈴聲為蜂鳴器長鳴3秒鐘。
4、倒計時功能:短按三次S1,顯示狀態為 0,冒號為長滅。按動S2則從低位依此顯示高位,按動S3則相應位加1,當S2按到第6次時會在所設定的時間狀態下開始倒計時,再次按動S2將再次進入調整功能,並且停止倒計時。
5、秒表功能:短按四次S1,顯示狀態為00:00:00,冒號為長亮。按動S2則開始秒表計時,再次按動S2則停止計時,當停止計時的時候按動S3則秒表清零。
6、計數器功能:短按五次S1,顯示狀態為00:00:00,冒號為長滅,按動S2則計數器加1,按動S3則計數器清零。

採用AT89C2051的6位LED電子鐘(計數器)散件每套28元

以下是部分C語言源程序,購買產品後可以向我們索要完整的單片機C語言源程序、燒寫文件和說明書。

#include

code senen_seg[10]={0x81,0xe7,0x92,0xa2,0xe4,0xa8,0x88,0xe3,0x80,0xa0}; //P1.7(冒號)口高電平

bit key1_enter=0,key2_enter=0,key3_enter=0,countdown_mark=0,stopwatch_mark=0,count_mark=0,bell_mark=0; //狀態標誌
unsigned char program=0,program_variable=0,count_bit=0,count=0;
unsigned char hour=10,minute=10,second=0; //時間變量
unsigned char delayed_hour=22,delayed_minute=10,delayed_second=0; //定時變量
unsigned char count_hour=0,count_minute=0,count_second=0; //計時計數變量
unsigned int count_time=0,count_count=0;

void delay(unsigned int t) //延時子程序
{
unsigned int i,j;
for(i=0;ifor(j=0;j<10;j++)
;
}

void time0_init(void){ //定時計數0器初始化
EA=0;
TR0=0;
TMOD=0x02;
TH0=0x4;
TL0=0x4;
ET0=1;
TR0=1;
EA=1;
}

static void timer0_isr(void) interrupt TF0_VECTOR using 1 //定時計數0器中斷函數
{
count_time++; //時鐘計時程序
if(count_time>=4020){
count_time=0;
second++;
if(second>=60){
second=0;
minute++;
if(minute>=60){
minute=0;
hour++;
if(hour>=24)hour=0;
}
}
}
if(delayed_hour==hour && delayed_minute==minute && second<4) P3_7=0;
else P3_7=1;
if(countdown_mark==1){ //倒計時程序
count_count++;
if(count_count>=4000 && (count_second!=0|count_minute!=0|count_hour!=0)){
count_count=0;
count_second--;
if(count_second>=60){
count_second=59;
count_minute--;
if(count_minute>=60){
count_minute=59;
count_hour--;
if(count_hour>=100) count_hour=99;
}
}
}
if(count_second==0&&count_minute==0&&count_hour==0&&count_count<=12000) P3_7=0;
else P3_7=1;
if(count_count>=15000) count_count=14000;
}
if(stopwatch_mark==1){ //秒表程序
count_count++;
if(count_count>=40){
count_count=0;
count_second++;
if(count_second>=100){
count_second=0;
count_minute++;
if(count_minute>=60){
count_minute=0;
count_hour++;
if(count_hour>=60) count_hour=0;
}
}
}
}
}

unsigned char show_key (void){
unsigned char x=0,y=0;
switch (program){
case 0: P1&=senen_seg[second%10]; //時鐘秒的個位
break;
case 1: if(count_time>=2000) P1&=senen_seg[second%10]; //校正秒的個位
break;
case 2: if(delayed_hour==24) P1=0xfe; //鬧鐘秒的個位
else P1&=senen_seg[delayed_second%10];
break;
case 3: if(count_bit>=0) P1&=senen_seg[count_second%10];//倒計時秒的個位
else P1=0xff;
break;
case 4: P1&=senen_seg[count_second%10]; //秒表秒的個位
break;
case 5: P1&=senen_seg[count_second%10]; //計數器個位
break;
}
P3_3=0;
delay(10);
if(P3_5==0){ //功能鍵1識別
key1_enter=1;
if(count<=254)count++;
}
if(P3_4==0) key2_enter=1; //功能鍵2識別
if(P3_2==0) key3_enter=1; //功能鍵3識別
P3_3=1;
P1|=0xff;

switch (program){
case 0: P1&=senen_seg[second/10]; //時鐘秒的十位
break;
case 1: if(count_time>=2000) P1&=senen_seg[second/10]; //校正秒的十位
break;
case 2: if(delayed_hour==24) P1=0xfe; //鬧鐘秒的十位
else P1&=senen_seg[delayed_second/10];
break;
case 3: if(count_bit>=1) P1&=senen_seg[count_second/10];//倒計時秒的十位
else P1=0xff;
break;
case 4: P1&=senen_seg[count_second/10]; //秒表秒的十位
break;
case 5: P1&=senen_seg[count_second/10]; //計數器十位
break;
}
P3_1=0;
delay(10);
P3_1=1;
P1|=0xff;

switch (program){
case 0: P1&=senen_seg[minute%10]; //時鐘分的個位
break;
case 1: if(count_time>=2000) P1&=senen_seg[minute%10]; //校正分的個位
break;
case 2: if(delayed_hour==24) P1=0xfe; //鬧鐘分的個位
else P1&=senen_seg[delayed_minute%10];
break;
case 3: if(count_bit>=2) P1&=senen_seg[count_minute%10];//倒計時分的個位
else P1=0xff;
break;
case 4: P1&=senen_seg[count_minute%10]; //秒表分的個位
break;
case 5: P1&=senen_seg[count_minute%10]; //計數器百位
break;
}
P3_2=0;
delay(10);
P3_2=1;
P1|=0xff;

switch (program){
case 0: P1&=senen_seg[minute/10]; //時鐘秒的個位
break;
case 1: if(count_time>=2000) P1&=senen_seg[minute/10]; //校正秒的個位
break;
case 2: if(delayed_hour==24) P1=0xfe; //鬧鐘秒的個位
else P1&=senen_seg[delayed_minute/10];
break;
case 3: if(count_bit>=3) P1&=senen_seg[count_minute/10];//倒計時秒的個位
else P1=0xff;
break;
case 4: P1&=senen_seg[count_minute/10]; //秒表秒的個位
break;
case 5: P1&=senen_seg[count_minute/10]; //計數器千位
break;
}
P3_5=0;
delay(10);
P3_5=1;
P1|=0xff;

switch (program){
case 0: P1&=senen_seg[hour%10]; //時鐘時的個位
break;
case 1: if(count_time>=2000) P1&=senen_seg[hour%10]; //校正時的個位
break;
case 2: if(delayed_hour==24) P1=0xfe; //鬧鐘時的個位
else P1&=senen_seg[delayed_hour%10];
break;
case 3: if(count_bit>=4) P1&=senen_seg[count_hour%10];//倒計時時的個位
else P1=0xff;
break;
case 4: P1&=senen_seg[count_hour%10]; //秒表時的個位
break;
case 5: P1&=senen_seg[count_hour%10]; //計數器萬位
break;
}
P3_0=0;
delay(10);
if(P3_4==1 && key2_enter==1){
x=3; //確認功能鍵2識別,返回3
key2_enter=0;
}
P3_0=1;
P1|=0xff;

switch (program){
case 0: P1&=senen_seg[hour/10]; //時鐘時的個位
break;
case 1: if(count_time>=2000) P1&=senen_seg[hour/10]; //校正時的個位
break;
case 2: if(delayed_hour==24) P1=0xfe; //鬧鐘時的個位
else P1&=senen_seg[delayed_hour/10];
break;
case 3: if(count_bit>=5)P1&=senen_seg[count_hour/10]; //倒計時時的個位
else P1=0xff;
break;
case 4: P1&=senen_seg[count_hour/10]; //秒表時的個位
break;
case 5: P1&=senen_seg[count_hour/10]; //計數器萬位
break;
}
P3_4=0;
delay(10);
if(P3_5==1 && key1_enter==1){ //確認功能鍵1識別,執行退出或進入下一個功能
if(count>=127) x=1; //確認功能鍵1為長按,返回1
else x=2; //確認功能鍵1為短按,返回2
key1_enter=0;
count=0;
}
if(P3_2==1 && key3_enter==1){
x=4; //確認功能鍵3識別,返回4
key3_enter=0;
}
P3_4=1;
P1|=0xff;
if(program<=1 && count_time>=2000) P1&=0xff; //校時和顯示功能時鐘時冒號閃爍
if(program<=1 && count_time<=2000) P1&=0x7f;
if(program==2) P1&=0x7f; //設置鬧鐘功能時冒號長亮
if(program==3) P1&=0xff; //設置倒計時功能時冒號長滅
if(program==4) P1&=0x7f; //設置秒表功能時冒號長亮
if(program==5) P1&=0xff; //設置計數時冒號長滅
y=x;
x=0;
return y;
}

void main(){ //主程序
P1=0xff;
P3=0xff;
time0_init();
while(1){
switch(program){
case 0: while(program==0){ //時鐘菜單
switch(show_key()){
case 0: break;
case 1: program=0;
break;
case 2: program=1;
break;
}
}
break; //校時菜單
case 1: while(program==1){
switch(show_key()){
case 0: break;
case 1: program=0;
break;
case 2: program=2;
break;
case 3: hour++;
if(hour>=24)hour=0;
break;
case 4: minute++;
if(minute>=60)minute=0;
break;
}
}
break;
case 2: while(program==2){ //鬧鐘菜單
switch(show_key()){
case 0: break;
case 1: program=0;
break;
case 2: program=3;
break;
case 3: delayed_hour++;
if(delayed_hour>=25)delayed_hour=0;
break;
case 4: delayed_minute++;
if(delayed_minute>=60)delayed_minute=0;
break;
}
}
break;
case 3: while(program==3){ //倒計時菜單
switch(show_key()){
case 0: break;
case 1: program=0;
break;
case 2: program=4;
break;
case 3: count_bit++;
if(count_bit>=7)count_bit=0;
break;
case 4: switch(count_bit){
case 0: count_second+=1;
break;
case 1: count_second+=10;
break;
case 2: count_minute+=1;
break;
case 3: count_minute+=10;
break;
case 4: count_hour+=1;
break;
case 5: count_hour+=10;
break;
case 6: break;
}
if(count_hour>=100) count_hour-=100;
if(count_minute>=60) count_minute-=60;
if(count_second>=60) count_second-=60;
break;
}
if(count_bit==6) countdown_mark=1;
else countdown_mark=0;
}
break;
case 4: count_hour=0; //秒表菜單
count_minute=0;
count_second=0;
while(program==4){
switch(show_key()){
case 0: break;
case 1: program=0;
break;
case 2: program=5;
break;
case 3: stopwatch_mark=~stopwatch_mark;
break;
case 4: if(stopwatch_mark==0){
count_hour=0;
count_minute=0;
count_second=0;
}
break;
}
}
break; //計數器菜單
case 5: count_hour=0;
count_minute=0;
count_second=0;
while(program==5){
switch(show_key()){
case 0: break;
case 1: program=0;
break;
case 2: program=0;
break;
case 3: count_second++;
if(count_second>=100){
count_second=0;
count_minute++;
if(count_minute>=100){
count_minute=0;
count_hour++;
if(count_hour>=100)count_hour=0;
}
}
break;
case 4: count_hour=0;
count_minute=0;
count_second=0;
break;
}
if(P3_7==0){
while(P3_7==0) show_key();
count_second++;
if(count_second>=100){
count_second=0;
count_minute++;
if(count_minute>=100){
count_minute=0;

相關焦點

  • 74ls47應用電路圖大全(五款74ls47顯示解碼器電路/十進位計數器電路)
    為方便自己做實驗,筆者利用手頭的元器件製作了一塊多功能數碼管顯示實驗板。這塊實驗板由八位共陽數碼管實驗模塊和四位共陰數碼管實驗模塊組成。 本實驗板電路分成兩部分,第一部分是基本顯示部分(圖1),第二部分是解碼器部分(圖2)。兩部分通過撥碼開關連接,可根據需要設置是否使用解碼器晶片。 基本顯示部分 圖1所示的基本顯示部分電路是用單片機控制數碼管比較常見的電路,多位數碼管的顯示一般採用動態掃描的方式。
  • STC89C52單片機對數字溫度計顯示系統的設計
    3.碼管顯示模塊:主要對單片機送來的時間、日期、溫度信息進行顯示。 4 。度採集模塊:採用D S 1 8 B 2 0溫度傳感器,向單片機提供實時溫度信息。 5.子鐘模塊:採用時鐘晶片DS1302,該晶片可以進行時、分、秒的計數,DS1302通過串行方式與單片機進行數據傳送,向單片機提供包括秒、分、時、日、月、年等在內的實時時間信息。
  • 一文看懂rtc實時時鐘和單片機時鐘的區別
    實時時鐘是指給日期及時間計數器累加的時鐘,通常是32768Hz,系統時鐘是指單片機內部的主時鐘,給各個模塊提供工作時鐘的基礎,CPU時鐘是指經過CPU的PLL後將系統時鐘改變為CPU工作的時鐘。在一般的低速單片機系統中,系統時鐘和CPU時鐘基本相等,在高速單片機系統中,CPU時鐘比系統時鐘高得多。而實時時鐘只有在需要日期時間的系統中才有,並且是最低的,有的系統也將它作為低功耗時CPU時鐘。   實鍾(RTC)由晶體控制精度,向主系統提供BCD碼表示間期器件。主系統與RTC間通信通並行口通串行口。並行器件速度快需較底板空間較昂貴。串行器件體積較且價格相便宜主頻CPU鍾頻率。
  • 跟電師傅學單片機(21):單片機位操作指令圖文講解(二)
    一:位運算指令(6條)如同累加器A,都在單片機編程指令中使用頻率較高。Bit:位尋址區內的某一位的狀態。ANL為邏輯「與」指令:ANL C,bit;指令功能是將位累加器CY的內容與直接尋址位進行邏輯「與」操作,並將結果送回累加器CY中。
  • 基於AT89S52的多功能電子萬年曆
    主控制模塊  單片機主控制模塊的設計  AT89S52單片機為40引腳雙列直插晶片,有四個I/O口P0,P1,P2,P3,MCS-51單片機共有4個8位的I/O口(P0、P1、P2、P3),每一條I/O線都能獨立地作輸出或輸入。
  • 高精度頻率計數器 SP3386
    SP3386 SP312系列高精度頻率計數器以高性能的AVR單片機為核心進行功能控制、測量時序控制、數據處理和結果顯示. 採用倒數計算技術,實現全範圍內的等精度測量.在工業生產、科研計量等領域有著廣泛的用途,是傳統電子計數器理想的更新換代產品 主要特點
  • 電子計數器電路圖_電子計數器接線方法
    打開APP 電子計數器電路圖_電子計數器接線方法 發表於 2019-09-26 10:06:37   電子計數器電路圖   該計數器可將機械或人工計數方式變為電子計數
  • 基於單片機的可測溫式電子萬年曆
    本文引用地址:http://www.eepw.com.cn/article/271886.htm  本文設計了一種基於單片機STC89C52的可測溫式電子萬年曆,能實時地將當前時間和周圍的環境溫度顯示出來,並具有鬧鐘、秒表、語音報時的功能。
  • 彙編電子鐘的設計
    借用老師的學習板子,一直搞到凌晨2點做出了一個24小時的計數器顯示,因為沒有學過按鍵的使用方法,昨天實驗課下課後問了老師,她給出了查詢方式。昨晚搞了下,可以置數,但是不能實現0~60範圍加,只能0~99加。今天上午在老師的指導下,終於可以了,總算沒有食言啊。呵呵,下面貼出程序了。
  • MCU單片機主流晶片公司有哪些_十大主流MCU單片機公司匯總
    微控制單元(Microcontroller Unit;MCU) ,又稱單片微型計算機(Single Chip Microcomputer )或者單片機,是把中央處理器(Central Process Unit;CPU)的頻率與規格做適當縮減,並將內存(memory)、計數器(Timer)、USB、A/D轉換、UART、PLC、DMA等周邊接口,甚至LCD
  • led電子屏無法顯示圖像該怎麼辦
    在led電子屏使用了一段時間之後,有時候會出現圖像無法顯示的現象,遇到這種情況以後,很多使用者都不知道該怎樣解決,如果打電話找維修的話,還需要花費很長的時間,影響我們的後期使用,下面我們來給大家介紹幾種方式,希望可以幫助到大家。
  • 5分鐘了解單片機數據、地址、控制總線結構!
    3、控制總線 51 系列單片機的控制總線包括讀控制信號P3.7 和寫控制信號P3.6 等,二者分別作為總線模式下數據讀和數據寫的使能信號。在T1 期間,P0 口作為數據總線使用,送出或讀入數據,數據的讀寫操作在讀、寫控制信號的低電平期間完成。 需要注意的是,在控制信號( 讀、寫信號) 有效期間,P2 口送出高8位地址,配合數據鎖存器輸出的低8 位地址,實現16 位地址總線,即64kB 範圍的內的尋址。
  • 基於單片機控制的帶鎖相環三路智能 同步採集卡設計
    1.2.1 鎖相環技術 鎖相環技術也稱自動相位控制技術,於20世紀30年代發展起來,現已廣泛應用於通信、電子、測控等領域,其結構組成見圖2,主要由相位比較器(pd亦稱鑑相器),低通濾波器(lpf),壓控振蕩器(vco)組成。
  • 基於單片機控制的DC-DC變換電路
    通過對DC-DC直流轉換器輸出電流進行監測,通過鍵盤輸入輸出電流設定信號,通過單片機輸出PWM信號與LM358比較器形成比較電壓,電流反饋閉環電路,從而對LM2596晶片進行控制,控制buck電路的接通關斷,以保證DC-DC的變換。升壓部分直接由LM2577電路控制穩壓其結構圖如圖1所示。
  • 基於Proteus單片機的音樂演奏實現系統
    圖2 在Proteus 環境下用單片機控制蜂鳴器發聲的原理圖。 需要的關鍵元件:單片機和蜂鳴器。 為了便於軟體編程,先要了解單片機唱歌的基本原理。 單片機唱歌的基本原理:利用程序來控制單處機某個口線出一定頻率的方波到蜂鳴器,蜂鳴器就可以發出一定音調的聲音,若再利用不同的延時程序改變輸出頻率,就可以改變音調,進而就可讓單片機發出"1"、"2","3","4","5","6","7"的音樂。 2 軟體設計 通過軟體延時或者定時器延時來的方式以不同頻率改變口線的的高低電平狀態來實現的。
  • 基於單片機的GPS/電子羅盤測姿定位系統
    針對電子羅盤經啟動後要較長時間才能穩定,而陀螺球轉速高、磨損大、壽命短等問題,本文做了載體姿態和位置測量的研究。就測姿定位問題,本文基於單片機最小系統,設計了基於GPS/電子羅盤的測姿定位系統,將GPS與電子羅盤組合,利用多種信息源相互補充,構成了一種有多餘度和高精度的導航定位系統。
  • 單片機實驗報告與心得體會
    其中8155 片內有256個ram單元,接6個7段碼顯示器和8個按鍵作輸入。串行口連接max232串行口轉換晶片,p1口留出作為一些控制量的輸入輸出用以擴展使用。在實驗板上可編寫鍵盤掃描程序、顯示程序、時間的設定及計時程序、從鍵盤上輸入兩個加數或減數顯示結果程序、位變量的邏輯運算程序及串行口和上位機通訊程序等,還可和其它課程相結合,進行實驗。
  • 基於AT89C2051的電子鐘設計
    一片20引腳的單片機AT89C2051為電子鐘主體,其顯示數據從P1口分時輸出,P3.0~3.3則輸出對應的位選通信號。本來筆者還有一種更簡的設計方案(見圖2),可省去VT1~VT4及R1~R4八個元件,但這種設計由於單片機輸出口的灌入電流有限(約20mA),數碼管亮度較暗而不向讀者介紹,除非你採用了高亮度的發光數碼管。
  • 單片機在微波功率控制技術中的應用方案
    微波作為一種新的能量傳遞方式,在電子電氣行業中發展很快,其中大功率微波源常用於加熱及無極光燈的激勵源,為了更好地滿足應用的需要,經常需要功率控制。為達到無極紫外燈在微波的激發作用下,能夠產生連續可變的光源,並且能夠較好地克服技術性與經濟性的矛盾,提高性價比,本文論述單片機微波功率控制技術。
  • CPLD擴展51單片機尋址範圍
    考慮到某些不需要高速度的應用場合,可以用單片機的一個八位IO口(如P0),多次輸出地址,通過CPLD將這些地址位整合起來,並輸出到相應的設備,這樣,即可實現用單片機的一個八位IO口來實現多位地址的功能。1.