A. 哪位有基於單片機的數字鍾的設計開題報告
相關資料:
多功能數字鍾設計
一 簡介
時鍾, 自從它發明的那天起,就成為人類的朋友,但隨著時間的推移,人們對它的功能又提出了新的要求,怎樣讓時鍾更好的為人民服務,怎樣讓我們的老朋友煥發青春呢?這就要求人們不斷設計出新型時鍾。本方案設計的多功能電子鍾除了傳統的顯示時間功能之外還可以測試溫度、電網頻率、電壓、並提供了過壓報警、非接觸止鬧等功能。其中溫度採用AD590溫度感測器電路測得,非接觸止鬧則採用紅外控制技術實現。
二 方案論證
時鍾模塊方案
方案一 基本門電路搭建 用基本門電路來實現數字鍾,電路結構復雜,故障系數大,不易調試。
方案二 單片機編程 用單片機設計電路,由於使用軟硬體結合的方式,所以電路結構簡單、調試也相對方便。與第一種方案比較優點是非常明顯的。我們選擇了第二種方案
測溫模塊方案
方案一 熱電阻測溫 熱電阻測量溫度,精度和靈敏度都可以,但是它的電阻值與溫度的線性關系不好.不便用數字的方法處理。
方案二 熱電偶測溫 熱電偶是溫度測量中應用最廣泛的一種感測器 .在一般的測量和控制中,常用於中高溫的溫度檢測.在 測量中需要溫度的冷端補償,在數字電子中實現不方便
方案三 AD590加運算放大器 二端式半導體溫度感測器 AD590的工作電壓要求不高,測溫的范圍比較寬最重要的是它的輸出電流是緊隨溫度變化的電流源,所以它的線性非常好.我們選擇了這種方案。
測電壓模塊方案
方案一 取樣測試。用高速的取樣電壓取樣,可得電壓的峰值與主頻率,並根據其電壓大小進行相應的報警操作。此方案功能實現復雜,造價相對較高,不適合一般的家用。
方案二 測得電壓有效值 測電壓的有效值的方法比較簡單,可以把一段時間內的電壓的整體情況反映出來 ,但不能測出電壓的瞬時變化的情況,對電網的突然沖擊不能測出.
方案三 測得峰值推得有效值。交流電經過整流濾波後得到直流電壓大小就是交流電的峰值,分壓測出此電壓大小,後根據交流電有效值和峰值的關系可推得有效值。這種方案採用的電路簡單,實現方便,易於調試,精度較高, 為我們的設計採用。
非接觸止鬧模塊方案
方案一 聲音止鬧
聲音代替肢體給人帶來了很大便利,但是要採用聲控裝置不得不考慮外界雜訊對正常聲音信號帶來的干擾,而這一點又很難控制,因此雖然聲控方便,但在這里不太適用所以割捨。
方案二 紅外止鬧
紅外控制技術現在已被廣泛地應用到各個領域,此技術有其獨特的特點,首先操作方便抗干擾性好、探測靈敏度高、工作濕度范圍寬設計電路有不太復雜,造價也不高,由於這些特點我們選用了紅外遙控來止鬧。
顯示模塊方案
方案一 段碼顯示。段碼顯示需要專門的驅動,增大了硬體電路,調試不易。而且用段碼表示不夠直觀,因此不採用這種方案
方案二 單片機控制液晶顯示。控制部分集成在單片機內軟體調試,硬體集成度大,為本方案所採用。
綜上所述得到以下方塊圖:
三 各模塊功能
單片機控制顯示部分:液晶顯示片上顯示時間、電壓、溫度,鍵盤控制,鍵盤如下圖所示:
調節 ↑
鬧鈴 ↓
鬧鈴鍵用來設置鬧鈴,鬧鈴響時按下鬧鈴鍵可用來止鬧,平時鬧鈴鍵可用來設置鬧鈴的開關,鬧鈴關時按下此鍵鬧鈴功能將被打開,反之鬧鈴功能將被關閉。需要調節時間時,按動調節按鈕,顯示片上需要設置的時間值以閃爍的方式出現,以示區別,表示當前調節內容,再次按動,跳至下個需要設置的時間值,我們可以通過切換選擇我們需要調整的時間部分,然後按「上」「下」按鈕進行設定。其中時鍾部分以二十四或十二小時(AM/PM)制顯示。
此外單片機還控制溫度和電壓的測量,通過測溫端和測電壓端輸出的電壓,由相應的函數關系求得被測端的被測參數,然後顯示在液晶顯示屏上.
測溫部分
原理方塊圖:
溫度檢測電路的設計,電路圖如下:
測溫元件使用溫度感測器AD590。A/D590在0℃時輸出的電流I=273 uA,溫度T每增加1℃,I增加1u A。輸出的電壓變化為:
Δv=1uA×R2
系統要求電壓變化范圍在0—5伏,可解得R2<62.5K,設計中R2採用了52K的電阻。
當溫度為-10攝氏度時,要求輸出電壓盡量接近於0 V,
U0=(It-Vcc/R1) ×R2=0
由上述公式,得R1約為56k,本設計中取R1=56.3
3.A/D轉換及顯示電路的設計。本設計中所採用的單片機內置十位A/D轉換器,顯示電路也是通過編程單片機控制,控製程序見附錄。
電壓測量及欠壓過壓報警
電壓測試電路如下:
交流電經變壓器後,經半波整流後分壓測得電壓。電路圖如下:
在變壓器的中線上引出15v的交流電壓,經過二極體以後相當濾掉了 負向電壓。當電壓從峰值下降到一定程度時,電容C1開始放電。取R3*C1>60ns,電阻上得到約等於交流電峰值的直流電壓,分壓後測得輸出電壓,有電路連接和交流電峰值、有效值的關系,
把三極體的基極接到單片機的一個控制口上,控制電容放電,保證每次的采樣結果的正確性,也可以防止放電電流對電源的影響。由於我們已經知道現在用的是標準的電源,所以我們可以用電源的有效值計算出電壓的最大值用於電壓的上下限的報警。
我們用計數器接在J2 J3兩端,通過每分鍾計的的高電平或低電平個數就可以得出電網的頻率。
非接觸止鬧:我們用紅外控制技術控制鬧鍾的關閉。發射電路如下圖
其中38khz方波發生電路由555接成,經74ls08後由三極體驅動兩個發光二極體,當按鈕按下時,發出控制光線。
接收電路如下圖所示:
當接收到紅外信號時,OUT端產生低電平信號,傳到控制端,實現止鬧功能。
單片機控制系統原理圖如下:
控制系統主要由單片機應用電路、存儲器介面電路、LCD顯示介面電路、鍵盤電路、模擬量輸入輸出介面電路、供電電路及程序下載和調試介面電路組成。其中單片機應用電路是系統工作的核心,它主要負責控制各個部分協調工作.由於系統構成介面較多,為了更好的組織各個功能部件正常工作,我們選用功能強大的AVR單片機作為主控CPU.它集各種存儲器(FLASH,RAM,EEPROM)、模擬器件(A/D轉換器,模擬比較器)於一體,同時還集成了各種匯流排控制器等數字通信器件,是真正的片上系統(SOC).由於本系統涉及各種數字和模擬電子器件的應用,因此使用此單片機作為本系統的主控CPU,使開發速度大大提高。
四 系統調試過程與測試結果
本實驗需要調試的主要有兩部分:溫度測試部分的調試和電壓測試部分的調試
溫度測試部分
實驗數據如下
溫度T(℃) 理論AD590輸出電流(uA) 理論電壓值Ut (V) 實際電壓值Uo (V)
0 273 0.416 0.640
10 283 0.930 0.790
20 293 1.444 1.568
26.4 299.4 1.795 2.07
27.5 3090.5 1.852 2.10
30 303 1.985 2.35
40 313 2.471 3.130
50 323 2.985 3.312
60 333 3.499 3.845
70 343 4.013 4.378
100 373 5.62 5.98
表中AD590輸出理論電流值由AD590本身的性質決定,理論電壓輸出則由模擬軟體模擬計算得到。可以看出,理論電壓和實際電壓有明顯的差別,實際輸出電壓高於理論算得的電壓值,經不斷分析測試可作如下總結:由於系統本身工作產生熱量,使得AD590所測溫度高於環境溫度,但可以看出,實際電壓值與溫度依然呈線性關系變化,於是對測得數據進行一元線性回歸處理,用最小二乘法求得此線性關系的斜率和初象,得到輸出電壓與溫度變化之間的函數變化關系如下:
T=(100Uo-64)/5.34
在所得式中代入測得數據計算,其誤差都不超過1攝氏度,可驗證所得式的正確性。將此公式寫入單片機控製程序中,就可以根據輸入的電壓變化得到相應的溫度值。
電壓調試部分:
測輸入交流電壓和輸出交流電壓的值,調10K電位器,市的交流輸入為15是電壓在2.5V到3V之間。保持電位器不變化,測得輸入輸出電壓關系,得出相應函數關系。輸入電壓為十五伏時一邊調電位器,一邊觀察輸出電壓。接入輸出電壓的電阻為2.17時輸出電壓在要求范圍。這時測輸入電壓輸出電壓值如下表:
輸入經變壓器後的交流電壓Ui』 (v) 輸出直流電壓Uo (v)
19.7 3.64
16.3 3
15 2.71
11.7 2.12
7.1 1.25
由表中數據可得以下結論:輸入和輸出約成正比變化,而經變壓器後的電流是原電流的3/22,在由上述關系可得
Vi=Vo*80.2
測試過程中,經變壓器後的交流電壓和輸出的直流電壓線性關系符合得很好,上式作為最後的結果被寫在程序中.
五 結束語
這款多功能計數器採用了現在廣泛使用用的單片機技術為核心,軟硬體結合,使硬體部分大為簡化,提高了系統穩定性,並採用大屏幕液晶顯示、紅外遙控裝置和電壓報警裝置使人機交互簡便易行,較為有效地完成了題目的要求。
其他相關:
http://www.bysj120.cn/lunwen/jsj/3151.html
僅供參考,請自借鑒
希望對您有幫助
B. 用單片機設計一個時鍾,可顯示時和分,可以調時間,也要有鬧鍾功能,要有設計的電路圖
其實不用定時中斷也能實現功能:
#include<reg51.h> 主函數
unsigned char tab[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};定義0-9數組
unsigned int tmp;定義變數
void delay(unsigned int xms)定義延時函數
{unsigned int j,i;
for(i=0;i<xms;i++)
for(j=0;j<100;j++);
}
void disp()定義子函數
{
P1=tmp;
delay(1);
P2=0xff;
tmp=tmp<<1;
}
void main( )
{
unsigned char z,s=00,m=00,h=00;給時鍾初始值
while(1)
{
for(z=0;z<100;z++)
{
tmp=0x01;
P2=tab[h/10];小時顯示
disp();
P2=tab[h%10];
disp();
P2=tab[m/10];分鍾顯示
disp();
P2=tab[m%10];
disp();
P2=tab[s/10];秒顯示
disp();
P2=tab[s%10];
disp();
}
s++;
while(s==60)秒進一位,到60清0
{
m++;
s=00;
}
while(m==60)分鍾進一位,到60清0
{
h++;
m=00;
}
while(h==24)小時進一位,到24清0
{
h=00;
}
}
}
C. 基於單片機的數字鍾 論文設計
ORG 0000H ;程序入口地址
LJMP START
ORG 000BH ;定時器0中斷入口地址
LJMP TIMER_0
ORG 0300H
/*****程序開始,初始化*****/
START:
SETB 48H ;使用一個bit位用於調時閃爍標志
SETB 47H ;使用一個bit位用於產生脈沖用於調時快進時基
MOV R1,#0 ;調整選擇鍵功能標志:0正常走時、1調時、2調分、3調秒
MOV 20H,#00H ;用於控制秒基準時鍾源的產生
MOV 21H,#00H ;清零秒寄存器
MOV 22H,#00H ;清零分寄存器
MOV 23H,#00H ;清零時寄存器
MOV 24H,#00H ;用於控制調時閃爍的基準時鍾的產生
MOV IP,#02H ;IP,IE初始化
MOV IE,#82H
MOV TMOD,#01H ;設定定時器0工作方式1
MOV TH0,#3CH
MOV TL0,#0B0H ;賦定時初值,定時50ms
SETB TR0 ;啟動定時器0
MOV SP,#40H ;重設堆棧指針
/*****主程序*****/
MAIN:
LCALL DISPLAY ;調用顯示子程序
LCALL KEY_SCAN ;調用按鍵檢測子程序
JZ MAIN ;無鍵按下則返回重新循環
LCALL SET_KEY ;調用選擇鍵處理子程序
JB 46H,MAIN ;如果已進行長按調整(調時快進),則不再執行下面的單步調整
LCALL ADD_KEY ;調用增加鍵處理子程序,加一
LCALL DEC_KEY ;調用減少鍵處理子程序,減一
LJMP MAIN ;重新循環
/*****定時器中斷服務程序*****/
TIMER_0:
PUSH ACC
PUSH PSW ;保護現場
MOV TH0,#3CH
MOV TL0,#0B0H ;重新賦定時初值
CPL 47H ;產生脈沖用於調時快進時基
INC 24H
MOV A,24H
CJNE A,#10,ADD_TIME ;產生0.5秒基準時鍾,用於調時閃爍
CPL 48H ;取反調時閃爍標志位
MOV 24H,#00H
ADD_TIME: ;走時
INC 20H
MOV A,20H
CJNE A,#20,RETI1 ;產生1秒基準時鍾
MOV 20H,#00H ;一秒鍾時間到,清零20H
MOV A,21H
ADD A,#01H
DA A ;作十進制調整
MOV 21H,A
CJNE A,#60H,RETI1
MOV 21H,#00H ;一分鍾到
MOV A,22H
ADD A,#01H
DA A
MOV 22H,A
CJNE A,#60H,RETI1
MOV 22H,#00H ;一小時到
MOV A,23H
ADD A,#01H
DA A
MOV 23H,A
CJNE A,#24H,RETI1
MOV 23H,#00H ;到24點,清零小時
RETI1:
POP PSW
POP ACC ;恢復現場
RETI ;中斷返回
/*****顯示處理*****/
DISPLAY:
MOV A,21H ;秒
ANL A,#0FH
MOV 2FH,A ;轉換出秒個位,存入2FH
MOV A,21H
ANL A,#0F0H
SWAP A
MOV 2EH,A ;轉換出秒十位,存入2EH
JB 46H,MIN ;如果長按按鍵(調時快進),則跳過閃爍處理程序
CJNE R1,#3,MIN ;如果R1為3,閃爍秒位待調整
JB 48H,MIN
MOV 2FH,#0AH ;使該位為10,查表得到使該位不顯示的輸出
MOV 2EH,#0AH
MIN:
MOV A,22H ;分
ANL A,#0FH
MOV 2DH,A ;轉換出分個位,存入2DH
MOV A,22H
ANL A,#0F0H
SWAP A
MOV 2CH,A ;轉換出分十位,存入2CH
JB 46H,HOUR ;如果長按按鍵(調時快進),則跳過閃爍處理程序
CJNE R1,#2,HOUR ;如果R1為2,閃爍分位待調整
JB 48H,HOUR
MOV 2DH,#0AH ;使該位為10,查表得到使該位不顯示的輸出
MOV 2CH,#0AH
HOUR:
MOV A,23H ;時
ANL A,#0FH
MOV 2BH,A ;轉換出時個位,存入2BH
MOV A,23H
ANL A,#0F0H
SWAP A
MOV 2AH,A ;轉換出時十位,存入2AH
JB 46H,DISP ;如果長按按鍵(調時快進),則跳過閃爍處理程序
CJNE R1,#1,DISP ;如果R1為1,閃爍時位待調整
JB 48H,DISP
MOV 2BH,#0AH ;使該位為10,查表得到使該位不顯示的輸出
MOV 2AH,#0AH
/*****數碼管動態掃描顯示*****/
DISP:
MOV DPTR,#TABLE
MOV A,2FH
MOVC A,@A+DPTR
MOV P0,A
setb P2.7
LCALL DELAY
clr P2.7 ;顯示秒個位
MOV A,2EH
MOVC A,@A+DPTR
MOV P0,A
setb P2.6
LCALL DELAY
clr P2.6 ;顯示秒十位
MOV A,#0BFH
MOV P0,A
setb P2.5
LCALL DELAY
clr P2.5 ;顯示"-"
MOV A,2DH
MOVC A,@A+DPTR
MOV P0,A
setb P2.4
LCALL DELAY
clr P2.4 ;顯示分個位
MOV A,2CH
MOVC A,@A+DPTR
MOV P0,A
setb P2.3
LCALL DELAY
clr P2.3 ;顯示分十位
MOV A,#0BFH
MOV P0,A
setb P2.2
LCALL DELAY
clr P2.2 ;顯示"-"
MOV A,2BH
MOVC A,@A+DPTR
MOV P0,A
setb P2.1
LCALL DELAY
clr P2.1 ;顯示時個位
MOV DPTR,#TABLE1 ;該位使用TABLE1以消除前置0
MOV A,2AH
MOVC A,@A+DPTR
MOV P0,A
setb P2.0
LCALL DELAY
clr P2.0 ;顯示時十位
RET
/*****按鍵檢測子程序*****/
KEY_SCAN:
CLR 46H ;關閉長按調整(調時快進)標志
MOV P1,#0FFH ;將P1口設置成輸入狀態
MOV A,P1
CPL A
ANL A,#07H ;P1口低3位連接3個按鍵,只判斷該3位
JZ EXIT_KEY ;無鍵按下則返回
LCALL DELAY ;延時去抖動
MOV A,P1 ;重新判斷
CPL A
ANL A,#07H
JZ EXIT_KEY ;鍵盤去抖動
MOV R5,A ;臨時將鍵值存入R5
MOV R4,#00H ;用於控制調時快進速度
;設置為00H是為了在進入長按處理前加長延時區分用戶的長按與短按,防止誤快進
LOOP: ;進入長按處理
LCALL DISPLAY ;使長按時顯示正常
MOV A,P1
CPL A
ANL A,#07H
JB 47H,LOOP1
INC R4 ;調時快進間隔時間基準加1
LOOP1:
CJNE R1,#03H,LOOP2 ;如果調秒時長按,則不處理
LJMP LOOP3
LOOP2:
CJNE R4,#99H,LOOP3
MOV R4,#70H ;確認用戶長按後,重新設定起始值,加快調時快進速度
SETB 46H ;長按調整(調時快進)標志
LCALL ADD_KEY
LCALL DEC_KEY
LOOP3:
JNZ LOOP ;等待鍵釋放
MOV A,R5 ;輸出鍵值
RET
EXIT_KEY:
RET
/*****延時子程序*****/
DELAY:
MOV R7,#150
DJNZ R7,$
RET
/*****選擇鍵處理子程序*****/
SET_KEY:
CJNE R5,#01H,EXIT ;選擇鍵鍵值
INC R1 ;調整選擇功能標志加一
CJNE R1,#4,EXIT
MOV R1,#0
MOV 24H,#00H ;調時閃爍基準清零
RET
/*****增加鍵處理子程序*****/
ADD_KEY:
CJNE R5,#02H,EXIT ;增加鍵鍵值
CJNE R1,#01H,NEXT1 ;選擇鍵功能標志為1,調時,否則跳出
MOV A,23H
ADD A,#01H
DA A
MOV 23H,A
CJNE A,#24H,EXIT
MOV 23H,#00H
NEXT1:
CJNE R1,#02H,NEXT2 ;選擇鍵功能標志為2,調分,否則跳出
MOV A,22H
ADD A,#01H
DA A
MOV 22H,A
CJNE A,#60H,EXIT
MOV 22H,#00H
NEXT2:
CJNE R1,#03H,EXIT ;選擇鍵功能標志為3,調秒,否則跳出
MOV 21H,#00H ;如增加鍵按下直接清零秒
RET
/*****減少鍵處理子程序*****/
DEC_KEY:
CJNE R5,#04H,EXIT ;減少鍵鍵值
CJNE R1,#01H,NEXT3 ;選擇鍵功能標志為1,調時,否則跳出
MOV A,23H
ADD A,#99H
DA A
MOV 23H,A
CJNE A,#99H,EXIT
MOV 23H,#23H
NEXT3:
CJNE R1,#02H,NEXT4 ;選擇鍵功能標志為2,調分,否則跳出
MOV A,22H
ADD A,#99H
DA A
MOV 22H,A
CJNE A,#99H,EXIT
MOV 22H,#59H
NEXT4:
CJNE R1,#03H,EXIT ;選擇鍵功能標志為3,調秒,否則跳出
MOV 21H,#00H ;如較少鍵按下直接清零秒
RET
/*****萬用返回子程序*****/
EXIT:
RET
/*****數碼管字形編碼表*****/
TABLE:
DB 0C0H,0F9H,0A4H,0B0H,99H,92H,82H,0F8H,80H,90H,0FFH ;字形顯示編碼
TABLE1:
DB 0FFH,0F9H,0A4H,0B0H,99H,92H,82H,0F8H,80H,90H,0FFH ;小時位的十位數編碼,該位如果為0則不顯示
END ;程序結束
D. 基於單片機多功能數字鍾
帶萬年歷的LCD顯示多功能數字鍾
程序清單:
;SMC1602介面程序(MCS51模擬口線方式)
;***************************************************************************
;連線圖:*LCM---8031**LCM---8031**LCM------------8031*
;*DB0---P0.0**DB4---P0.4**RS-------------P2.0*
;*DB1---P0.1**DB5---P0.5**RW-------------P2.1*
;*DB2---P0.2**DB6---P0.6**E--------------P2.2*
;*DB3---P0.3**DB7---P0.7**VLCD接10K可調電阻到GND*
;注:8051的晶振頻率為11.0592MHzR0設置數據存放S8為設置鍵S7為加鍵S4為確認鍵
;**************************************************************************
;P0口液晶顯示
;P2.4位選鍵P2.3加一鍵P2.2返回鍵及報時功能鍵鬧鍾設置P2.0控制顯示鍵
;寄存器clrrs0setbrs1R0R4R5在按鍵中用到延時中用到SETBRS0SETBRS1的R0R1R2
;SETBRS0CLRRS1顯示中用到CLRRS0CLRRS1在鬧鍾調整子程序中用到R1
;*********************************************************************
;
;報時功能P2.6和鬧鍾功能P2.5鬧鍾調整時間功能已經可以設置顯示的切換方式變了再關閉的情況下一切正常運行
;*****************************
RSPINBITP1.2
RWPINBITP1.1
EPINBITP1.0
WEIXUANBITP2.4;位選鍵設置鍵
JIAJIANBITP2.3;加一鍵
JIANJIANBITP2.2;減一鍵
FANHUIBITP2.1;返回鍵
NZKGBITP2.0;鬧鍾設置鍵
SECONTLEQU30H;秒
SECONTHEQU31H;秒
MAOHAOLEQU32H;:
MINIUTLEQU33H;分
MINIUTHEQU34H;分
MAOHAOHEQU35H;:
HOURLEQU36H;時
HOURHEQU37H;時
;*****************************日期部分***************************
DAYLEQU40H;日個
DAYHEQU41H;日十
HENLEQU42H;-
MONTHLEQU43H;yue
MONTHHEQU44H;yue
HENHEQU45H;-
YEAROEQU46H;年
YEARTEQU47H
YEARSEQU48H
YEARFEQU49H
TEMPEQU50H;用做存儲單元顯示子程序(DISPLAY)里用到
BIJIAOEQU51H;加一子程序(JIAYI)中用到
ZDRQOEQU55H;中斷加一程序中用到
ZDRQTEQU56H;中斷加一程序中用到
ZDRQSEQU57H;中斷加一程序中用到
ZDRQFEQU58H;中斷加一程序中用到
DIZHIEQU59H;鍵盤(JIANPAN)子程序里用到
NZBZBIT60H;定時標志位在(鬧鍾開關部分)
;38H到3FH沒用到
BSCSBZBIT39H;報時次數轉換標志(BSCS)里用到
BSCSCCEQU3AH;報時次數存儲(BSCS)里用到
ZDBSBZBIT3BH;整點報時標志(SSBS)里用到
ZMBSBZBIT3CH;整秒閃爍標志(SSBS)里用到
BSKGBZBIT3DH;報時開啟標志(BSKG)里用到
XKQHBZBIT3EH;顯示開啟關閉標志(XIANKONG)里用到
ORG0000H
AJMPMAIN
ORG000BH
AJMPZD
ORG0030H
MAIN:MOVSP,#60H;給堆棧指針賦初值
MOV30H,#05H;秒
MOV31H,#05H;秒
MOV32H,#3AH;:
MOV33H,#09H;分
MOV34H,#05H;分
MOV35H,#3AH;:
MOV36H,#03H;時
MOV37H,#01H;時
;*****************************日期部分***************************
MOV40H,#09H;日個
MOV41H,#02H;日十
MOV42H,#2DH;-
MOV43H,#09H;yue
MOV44H,#00H;yue
MOV45H,#2DH;-
MOV46H,#09H;年
MOV47H,#09H
MOV48H,#09H
MOV49H,#02H
CLRP2.5;鬧鍾
CLRP2.6;整點報時
MOV03H,#00H;鬧鍾分個位
MOV04H,#00H;鬧鍾分十位
MOV06H,#04H;鬧鍾時個位
MOV07H,#01H;鬧鍾時十位
;CLRP1.5
;CLRP1.4
MOVB,#20
MOVTMOD,#01H;定時器工作方式1
MOVTH0,#4CH
MOVTL0,#08H
SETBET0;允許T0中斷
SETBEA;總中斷開放
LCALLLCDRESET;初始化LCD
LCALLDISPSTART;調用顯示初始狀態
SETBTR0;開啟定時器
CLRNZBZ;鬧鍾開啟關閉標志
CLRBSKGBZ;報時開啟關閉標志
CLRXKQHBZ;顯示開啟關閉標志
LOOP:LCALLJIANPAN;按鍵子程序
LCALLDISPLAY;顯示子程序
LCALLNZBF;NAOZHONGBUFENG
LCALLNZBJ;NAOZHONGBIJIAO
LCALLBSKG;BAOSHIKAIGUAN
LCALLBSCS;BAOSHICISHU
LCALLSSBS;閃爍報時
SJMPLOOP
;==============================中斷加一程序===================================
ZD:PUSHACC
MOVTH0,#4CH
MOVTL0,#08H
DJNZB,ZDEND
MOVB,#20
INCSECONTL
SETBZMBSBZ
MOVA,SECONTL
CJNEA,#0AH,ZDEND
MOVSECONTL,#00H
INCSECONTH
MOVA,SECONTH
CJNEA,#06H,ZDEND
MOVSECONTH,#00H
INCMINIUTL
MOVA,MINIUTL
CJNEA,#0AH,ZDEND
MOVMINIUTL,#00H
INCMINIUTH
MOVA,MINIUTH
CJNEA,#06H,ZDEND
MOVMINIUTH,#00H
INCHOURL
SETBBSCSBZ
SETBZDBSBZ
MOVA,HOURL;24小時的判斷
CJNEA,#04H,ZDF
MOVA,HOURH
CJNEA,#02H,ZDEND
MOVHOURL,#00H
MOVHOURH,#00H
LCALLZDRQ
SJMPZDEND
ZDF:CJNEA,#0AH,ZDEND
MOVHOURL,#00H
INCHOURH
ZDEND:POPACC
RETI
;日期部分
ZDRQ:PUSHACC
INCDAYL
;判斷天數28,30,31部分
MOVA,MONTHH;用於判斷月份時為31天30天28天
CJNEA,#01H,LL
MOV55H,#0AH;存放月份的十位轉化為個位是0AH
MOVA,MONTHL
ADDA,55H;月分高低相加用於查表
SJMPLL3
LL:MOVA,MONTHL
ADDA,MONTHH
LL3:MOV56H,A;存放相加後的月份數據
MOVDPTR,#TAB5
MOVCA,@A+DPTR;查十位和天數的十位比較
MOV57H,A
MOVA,56H
MOVDPTR,#TAB6;查個位和天數的個位比較
MOVCA,@A+DPTR
MOV58H,A
MOVA,DAYH
CJNEA,57H,LL2
MOVA,DAYL
CJNEA,58H,LL2
MOVDAYH,#00H
MOVDAYL,#01H
SJMPLL4
LL2:MOVA,DAYL
CJNEA,#0AH,ZDRQEND
MOVDAYL,#00H
INCDAYH
MOVA,DAYH;比較天數是否要進位
CJNEA,57H,ZDRQEND
MOVA,DAYL
CJNEA,58H,ZDRQEND
MOVDAYH,#00H
MOVDAYL,#01H
;月份和年份
LL4:INCMONTHL
MOVA,MONTHL
CJNEA,#03H,ZDRQ1;用於判斷月份時為12月時進位
MOVA,MONTHH
CJNEA,#01H,ZDRQ1
MOVMONTHL,#01H;天數符合要求
MOVMONTHH,#00H
SJMPZDRQ2
ZDRQ1:CJNEA,#0AH,ZDRQEND
MOVMONTHL,#00H
INCMONTHH
SJMPZDRQEND
ZDRQ2:INCYEARO;年的加一
MOVA,YEARO
CJNEA,#0AH,ZDRQEND
MOVYEARO,#00H
INCYEART;年的進位
MOVA,YEART
CJNEA,#0AH,ZDRQEND
MOVYEART,#00H
INCYEARS
MOVA,YEARS
CJNEA,#0AH,ZDRQEND
MOVYEARS,#00H
INCYEARF
MOVA,YEARF
CJNEA,#0AH,ZDRQEND
MOVYEARF,#00H
ZDRQEND:
POPACC
RET
;液晶初始化
;========================初始化程序=======================================
LCDRESET:;初始化程序
LCALLDELAY5MS;延時15MS
LCALLDELAY5MS
LCALLDELAY5MS
MOVA,#38H;顯示模式設置(不檢測忙信號)
LCALLLCDWCN;共三次
LCALLDELAY5MS
MOVA,#38H
LCALLLCDWCN
LCALLDELAY5MS
MOVA,#38H
LCALLLCDWCN
MOVA,#38H;顯示模式設置(以後均檢測忙信號)
LCALLLCDWC
MOVA,#08H;顯示關閉
LCALLLCDWC
MOVA,#01H;顯示清屏
LCALLLCDWC
MOVA,#06H;顯示游標移動設置
LCALLLCDWC
MOVA,#0CH;顯示開及游標設置
LCALLLCDWC
RET
;==============================寫指令===================================
LCDWC:;送控制字子程序(檢測忙信號)
LCALLWAITIDLE
;******寫指令*******;送控制字子程序(不檢測忙信號)
LCDWCN:CLRRSPIN;RS=0RW=0E=高脈沖
CLRRWPIN
MOVP0,A
SETBEPIN;(
NOP;給高電平脈沖
CLREPIN;)
RET
;==========================寫數據=======================================
LCDWD:;寫字元子程序
LCALLWAITIDLE
SETBRSPIN;RS=1RW=0E=高脈沖
CLRRWPIN
MOVP0,A
SETBEPIN
NOP
CLREPIN
RET
;===============================等待控制器空閑==================================
WAITIDLE:
PUSHACC;正常讀寫操作之前必須檢測LCD控制器狀態
MOVP0,#0FFH
lcallDELAY5MS;666666666666666666666666
CLRRSPIN;RS=0RW=1E=高電平
SETBRWPIN
SETBEPIN
lcallDELAY5MS;98
WTD_PA:NOP;DB7:0LCD控制器空閑
JBP0.7,WTD_PA;1LCD控制器忙
CLREPIN
POPACC
RET
;***********************初始狀態子程序*******************************
DISPSTART:;顯示初始狀態子程序
PUSHACC
MOVA,#80H
LCALLLCDWC
MOVDPTR,#TAB;顯示字元
DISP1:CLRA
MOVCA,@A+DPTR
JZDISP2
LCALLLCDWD
INCDPTR
SJMPDISP1
DISP2:MOVA,#0C0H
LCALLLCDWC
MOVDPTR,#TAB1
DISP3:CLRA
MOVCA,@A+DPTR
JZDISP_END
LCALLLCDWD
INCDPTR
SJMPDISP3
DISP_END:
POPACC
RET
;==========================顯示子程序=======================================
DISPLAY:PUSHPSW
PUSHACC
SETBRS0
CLRRS1
MOVA,#85H
LCALLLCDWC
MOVR1,#38H;第一行顯示數據存儲單元的啟始地址
MOVTEMP,#30H;第一行顯示數據存儲單元的結束地址
MOVR6,#2
PLAY:DECR1
CJNER1,#32H,PLY;判斷是否為冒號位
MOVA,MAOHAOL;是者送冒號的ACSI碼
SJMPPLAY1
PLY:CJNER1,#35H,PLY1
MOVA,MAOHAOH
SJMPPLAY1
PLY1:CJNER1,#42H,PLY2;判斷是否為橫杠的位置
MOVA,HENL;是者送橫杠的ACSI碼
SJMPPLAY1
PLY2:CJNER1,#45H,PLY3
MOVA,HENH
SJMPPLAY1
PLY3:MOVA,@R1;用查表法送要顯示的數據
MOVDPTR,#TAB2
MOVCA,@A+DPTR
PLAY1:LCALLLCDWD
MOVA,R1
CJNEA,TEMP,PLAY;判斷第一行是否顯示好了
MOVA,#0C5H
LCALLLCDWC
MOVR1,#4AH;第二行顯示數據存儲單元的啟始地址
MOVTEMP,#40H;第二行的結束地址
DJNZR6,PLAY;R6為0時兩行顯示結束
POPACC
POPPSW
RET
;************************按鍵子程序************************
JIANPAN:clrrs0;鍵盤子程序
setbrs1;鍵盤子程序
JBWEIXUAN,JIAN_ZEND;設置鍵的判斷
LCALLDELAY5MS
JBWEIXUAN,JIAN_ZEND
PUSHACC
JNBWEIXUAN,$
;MOVA,#0FH;開啟游標閃爍設置
;LCALLLCDWCN
fah:JNBNZBZ,JPNZSJ;為「1」鬧鍾為「0」時鍾
LCALLJPXS
MOVR4,#86H;鬧鍾設定時間R4存放顯示位地址
MOVR5,#2;鬧鍾設定時間第一行第二行•••••位置改變次數
MOVDIZHI,#8CH;鬧鍾設定時間第一行結束地址
MOVR0,#06H
SJMPGIVED
JPNZSJ:CLRTR0
MOVR4,#86H;R4存放顯示位地址
MOVR5,#2;第一行第二行•••••位置改變次數
MOVDIZHI,#8DH;第一行結束地址
MOVR0,#36H
GIVED:MOVA,#0FH;開啟游標閃爍設置
LCALLLCDWCN
MOVA,R4
LCALLLCDWC
UPONE:JBFANHUI,UPtwo;返回鍵的判斷
LCALLDELAY5MS
JBFANHUI,UPtwo
JNBFANHUI,$
SJMPGOBACK
JIAN_ZEND:SJMPJIAN_END;中繼跳轉
UPtwo:JBJIAJIAN,IAM;加一鍵的判斷
LCALLDELAY5MS
JBJIAJIAN,IAM
JNBJIAJIAN,$
LCALLJIAYI;調用按鍵加一子程序
;MOVA,#0FH;開啟游標閃爍設置
;LCALLLCDWCN
IAM:JBJIANJIAN,IAM22;減一鍵的判斷
LCALLDELAY5MS
JBJIANJIAN,IAM22
JNBJIANJIAN,$
LCALLJIANYI;調用按鍵減一子程序
AJMPGIVED
IAM22:JBWEIXUAN,UPONE;位選鍵的判斷
LCALLDELAY5MS
JBWEIXUAN,UPONE
JNBWEIXUAN,$
DECR0
INCR4
LCALLJIAN;調用位選比較程序
CJNEr4,#88H,JJ11
DECR0
INCR4
SJMPJJ22
JJ11:CJNEr4,#8BH,JJ22
DECR0
INCR4
JJ22:MOVA,R4
CJNEA,DIZHI,GIVED
JBNZBZ,fah;為「1」鬧鍾為「0」時鍾
MOVR4,#0C5H
MOVDIZHI,#0CFH
MOVR0,#49H
DJNZR5,GIVED
LJMPfah
GOBACK:MOVA,#0CH;關閉游標閃爍設置
LCALLLCDWCN
POPACC
JIAN_END:
SETBTR0
RET
;111111
;1111
JPXS:MOVA,#85H
LCALLLCDWC
MOVR1,#08H;第一行顯示數據存儲單元的啟始地址
JPXS_LL:DECR1
CJNER1,#05H,JPXS_LP
MOVA,#3AH
SJMPJPXS_LY
JPXS_LP:MOVA,@R1;用查表法送要顯示的數據
MOVDPTR,#TAB2
MOVCA,@A+DPTR
JPXS_LY:LCALLLCDWD
CJNER1,#03H,JPXS_LL
RET
;
;
;************************位選比較控製程序************************
;在調整時間時這幾位是符號冒號和橫杠的數據
;在這幾位時跳過到下一位
JIAN:CJNER4,#87H,JIAN5
DECR0
INCR4
SJMPJIANEND
JIAN5:CJNER4,#8AH,JIAN1
DECR0
INCR4
SJMPJIANEND
JIAN1:CJNER4,#0C9H,JIAN2
DECR0
INCR4
SJMPJIANEND
JIAN2:CJNER4,#0CCH,JIANEND
DECR0
INCR4
JIANEND:RET
;************************按鍵加一子程序********************
JIAYI:INC@R0
CJNE@R0,#0AH,JIAYI_END
MOV@R0,#0
CJNER4,#86H,JIAYI55
SJMPJIAYI33
JIAYI55:CJNEr4,#89H,JIAYI11
SJMPJIAYI33
JIAYI11:CJNEr4,#8CH,JIAYI22
SJMPJIAYI33
JIAYI22:CJNER0,#30H,JIAYI_END
JIAYI33:INCR0
INC@R0
CJNE@R0,#06H,JIAYI44
MOV@R0,#0
JIAYI44:DECR0
JIAYI_END:MOVA,#0CH;開啟游標閃爍設置
LCALLLCDWCN
JNBNZBZ,JIAYI88;為「1」鬧鍾為「0」時鍾
LCALLJPXS
SJMPJIAYI99
JIAYI88:LCALLDISPLAY;顯示子程序
JIAYI99:RET
;%%%%%%%%%%%%%%%%%%減一%%%%%%%%%%%%%%%%%%%%%%%%
JIANYI:DEC@R0
CJNE@R0,#00H,JIANYI_END
MOV@R0,#9
CJNER4,#86H,JIANYI55
SJMPJIANYI33
JIANYI55:CJNEr4,#89H,JIANYI11
SJMPJIANYI33
JIANYI11:CJNEr4,#8CH,JIANYI22
SJMPJIANYI33
JIANYI22:CJNER0,#30H,JIANYI_END
JIANYI33:INCR0
DEC@R0
CJNE@R0,#0FFH,JIANYI44
MOV@R0,#5
JIANYI44:DECR0
JIANYI_END:MOVA,#0CH;開啟游標閃爍設置
LCALLLCDWCN
JNBNZBZ,JIANYI88;為「1」鬧鍾為「0」時鍾
LCALLJPXS
SJMPJIANYI99
JIANYI88:LCALLDISPLAY;顯示子程序
JIANYI99:RET
;******************************鬧鍾開關部分************************
NZBF:JBNZKG,NZBF_END
LCALLDELAY5MS
JBNZKG,NZBF_END
JNBNZKG,$
CPLNZBZ
JBNZBZ,NZBF_LL
MOVA,#01H;顯示清屏
LCALLLCDWC
CLRP2.5
LCALLDISPSTART;調用顯示初始狀態
LCALLDISPLAY;調用顯示初始狀態
JBBSKGBZ,NZBF_LP;|
SJMPNZBF_END;|
NZBF_LP:MOVA,#8FH;報時標志顯示位置;|
LCALLLCDWC;|保護報時標志在清屏是不被誤清
MOVA,#25H;顯示報時標志;|
LCALLLCDWD;|
SJMPNZBF_END;|
NZBF_LL:MOVA,#8EH;鬧鍾標志顯示位置
LCALLLCDWC
MOVA,#26H;顯示鬧鍾標志
LCALLLCDWD
NZBF_END:RET
;******************************鬧鍾比較部分************************
NZBJ:JBNZBZ,NZBJ_LL
SJMPNZBJ_END
NZBJ_LL:MOVA,07H
CJNEA,37H,NZBJ_END
MOVA,06H
CJNEA,36H,NZBJ_END
MOVA,04H
CJNEA,34H,NZBJ_END
MOVA,03H
CJNEA,33H,NZBJ_END
SETBP2.5
NZBJ_END:RET
;***************報時開關********************
BSKG:JBFANHUI,BSKG_END
LCALLDELAY5MS
JBFANHUI,BSKG_END
JNBFANHUI,$
CPLBSKGBZ
JBBSKGBZ,BSKG_LL
MOVA,#01H;顯示清屏
LCALLLCDWC
CLRP2.6
LCALLDISPSTART;調用顯示初始狀態
LCALLDISPLAY;調用顯示
JBNZBZ,BSKG_LP;|
SJMPBSKG_END;|
BSKG_LP:MOVA,#8EH;|
LCALLLCDWC;|保護鬧鍾標志在清屏是不被誤清
MOVA,#26H;|
LCALLLCDWD;|
SJMPBSKG_END;|
BSKG_LL:MOVA,#8FH;報時標志顯示位置
LCALLLCDWC
MOVA,#25H;顯示報時標志
LCALLLCDWD
BSKG_END:RET
;*********************報時次數********************
BSCS:JNBBSKGBZ,BSCS_END
JNBBSCSBZ,BSCS_END
MOVA,37H
CJNEA,#01H,BSCS_LL
MOVA,#0AH
SJMPBSCS_LP
BSCS_LL:CJNEA,#02H,BSCS_LP
MOVA,#14H
BSCS_LP:ADDA,36H
RLA
MOVBSCSCC,A
CLRBSCSBZ
BSCS_END:RET
;**********************閃爍報時********************************
SSBS:JNBBSKGBZ,SSBS_END
JNBZDBSBZ,SSBS_END
JNBZMBSBZ,SSBS_END
CPLP2.6
CPLP2.7
CLRZMBSBZ
DJNZBSCSCC,SSBS_END
CLRZDBSBZ
CLRP2.6
SSBS_END:RET
;************************延時子程序(5MS)************************
DELAY5MS:
PUSHPSW
SETBRS0
SETBRS1
MOVR1,#25;延時子程序(5MS)
DL5_PA:MOVR2,#100
DJNZR2,$
DJNZR1,DL5_PA
POPPSW
RET
TAB:DB"TIME:",00h
TAB1:DB"DATE:",00h
TAB2:DB"01234567891"
TAB3:DB0AH,06H,00H,0AH,06H,00H,0AH,03H;用於比較調整時間時的比較
TAB4:DB0AH,04H,00H,0AH,02H,00H,0AH,0AH,0AH,0AH;用於調整日期時的比較
TAB5:DB00H,03H,02H,03H,03H,03H,03H,03H,03H,03H,03H,03H,03H;用於天數十位比較
TAB6:DB00H,02H,09H,02H,01H,02H,01H,02H,02H,01H,02H,01H,02H;用於天數個位比較
E. 用C語言編寫AT89C51單片機程序,設計一個智能數字鍾。
#include<reg52.h>
#define uint unsigned int
#define uchar unsigned char
sbit QB1=P1^0;
sbit QB2=P1^1; //數碼管段選
sbit QB3=P1^2;
sbit QB4=P1^3;
sbit QB5=P1^4;
sbit QB6=P1^5;
sbit fm=P1^6; //蜂鳴器
sbit s1=P2^4; //s5按鍵,切換顯示
sbit s2=P2^3; //s2按鍵,設置調時
sbit s3=P2^2; //s3按鍵,加1
sbit s4=P2^1; //s4按鍵,減1
sbit led1=P0^0;
sbit led2=P0^1;
sbit led3=P0^2;
uchar count;
uchar sec,minu,hour,day,week,mon;
uchar n_sec,n_minu,n_hour;
uint year;
uchar set_2=1,set_1=1;
uchar hs,hg,mis,mig,ss,sg;
uchar nhs,nhg,nms,nmg,nss=0,nsg=0;
uchar ms,mg,ds,dg,w;
uchar code table[]={0XC0,0XF9,0XA4,0XB0,0X99,0X92,0X82,0XF8,0X80,
0X90,0X88,0X83,0XC6,0XA1,0X8E,0X86,0xbf}; //0~F,-,共陽
//uchar code tableyi[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,
//0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x40};//0-F,-,共陰
uchar code table_d[]={0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,
0x87,0xff,0xef}; //0~9數組,帶小數點
uchar table1[]={31,31,29,31,30,31,30,31,31,30,31,30,31}; //閏年
uchar table2[]={31,31,28,31,30,31,30,31,31,30,31,30,31}; //非閏年
void delay(uint); //延時函數
void timer0(); //走時中斷函數
void jishi(); //計時函數
void key_change(); //切換顯示按鍵函數
void key_set(); //設置時間按鍵函數
void disp(uchar,uchar,uchar,uchar,uchar,uchar); //顯示函數
void zd_clock(); //整點報時函數
void nz_clock(); //鬧鍾函數
uchar incone(uchar); //加1函數
uchar decone(uchar); //減1函數
void set_time(); //設置時間函數
void set_clock(); //設置鬧鍾函數
void set_mdw(); //設置月日星期函數
void main() //主函數
{
EA=1;
ET0=1;
TR0=1;
TMOD=0x01;
TH0=0x4c; //50ms初值 晶振11.0592
TL0=0x00;
hour=23;minu=59;sec=49; //賦初值:11點59分0秒
n_hour=12;n_minu=56;n_sec=0; //鬧鍾賦初值12點1分0秒
year=2008;mon=5;day=14;week=3;//年月日星期賦初值2008年5月11日星期天;祝天下所有母親節日快樂
while(1)
{
hs=hour/10; //時分秒HH.MM.SS
hg=hour%10;
mis=minu/10;
mig=minu%10;
ss=sec/10;
sg=sec%10;
ms=mon/10; //月日-星期MM.DD.-W
mg=mon%10;
ds=day/10;
dg=day%10;
w=week;
nhs=n_hour/10; //鬧鍾定時HH.MM.SS
nhg=n_hour%10;
nms=n_minu/10;
nmg=n_minu%10;
nss=n_sec/10;
nsg=n_sec%10;
key_change(); //s4按鍵掃描
key_set(); //s2按鍵掃描
set_time(); //設置時間
set_mdw(); //設置月日星期
set_clock(); //設置鬧鍾
if(set_1==1) //正常走時顯示
{
disp(hs,hg,mis,mig,ss,sg);
}
if(set_1==2) //設置時間,LED1閃亮
{
disp(hs,hg,mis,mig,ss,sg);
if(sec%2==0)
{led2=1;led3=1;led1=~led1;}
// else
// {led1=1;}
}
if(set_1==3) //正常顯示月日-星期
{
disp(ms,mg,ds,dg,16,w);
}
if(set_1==4) //設置月日-星期,LED2閃亮
{
disp(ms,mg,ds,dg,16,w);
if(sec%2==0)
{led1=1;led3=1;led2=~led2;}
// else
// {led2=1;}
}
if(set_1==5) //正常顯示定時
{
disp(nhs,nhg,nms,nmg,nss,nsg);
}
if(set_1==6) //設置鬧鍾定時,LED3閃亮
{
disp(nhs,nhg,nms,nmg,nss,nsg);
if(sec%2==0)
{led1=1;led2=1;led3=~led3;}
// else
// {led3=1;}
}
zd_clock(); //整點報時
nz_clock(); //鬧鍾
}
}
void timer0() interrupt 1 //50ms中斷函數
{
TMOD=0x01;
TH0=0x4c; //50ms初值 晶振11.0592
TL0=0x00;
count++;
if(count==20)
{
count=0;
sec++;
jishi(); //調計時函數
}
}
void jishi() //計時函數
{
if(sec==60)
{
sec=0;
minu++;
if(minu==60)
{
minu=0;
hour++;
if(hour==24)
{ hour=0;
day++;
week++;
if(week==8)
{week=0;}
if(year%4==0&&year%100!=0||year%400==0) //閏年
{
if(day==table1[mon]+1)
{
day=0;
mon++;
if(mon==13)
{mon=0;year++;}
}
}
else //非閏年
{
if(day==table2[mon]+1)
{
day=0;
mon++;
if(mon==13)
{mon=0;year++;}
}
}
}
}
}
}
void key_change() //s1按鍵掃描
{
if(s1==0)
{
delay(200);
if(s1==0)
{
set_1++;
while(!s1);
if(set_1==7)
{set_1=1;}
}
}
}
void key_set() //s2按鍵掃描
{
if(s2==0)
{
delay(10);
if(s2==0)
{
set_2++;
while(!s2);
if(set_2==4)
{set_2=1;}
}
}
}
void disp(uchar a1,uchar a2,uchar a3,uchar a4,uchar a5,uchar a6) //顯示函數
{
QB1=1;
QB2=0;
QB3=0;
QB4=0;
QB5=0;
QB6=0;
P3=table[a1]; //段碼送P0口
delay(10); //延時一小會
QB1=0;
QB2=1;
QB3=0;
QB4=0;
QB5=0;
QB6=0;
P3=table[a2]; //第2個數碼管顯示,帶小數點
delay(10);
QB1=0;
QB2=0;
QB3=1;
QB4=0;
QB5=0;
QB6=0;
P3=table[a3]; //第3個數碼管顯示
delay(10);
QB1=0;
QB2=0;
QB3=0;
QB4=1;
QB5=0;
QB6=0;
P3=table[a4]; //第4個數碼管顯示,帶小數點
delay(10);
QB1=0;
QB2=0;
QB3=0;
QB4=0;
QB5=1;
QB6=0;
//第5個數碼管顯示
P3=table[a5];
delay(10);
QB1=0;
QB2=0;
QB3=0;
QB4=0;
QB5=0;
QB6=1;
P3=table[a6]; //第6個數碼管顯示
delay(10);
QB1=0;
QB2=0;
QB3=0;
QB4=0;
QB5=0;
QB6=0;
}
void zd_clock() //整點報時函數
{
if(minu==59&&(sec==53||sec==55||sec==57))
{
fm=0;
delay(5);
fm=1;
delay(5);
}
fm=0;
if(minu==59&&sec==59)
{
fm=0;
delay(5);
fm=1;
delay(5);
fm=0;
}
}
void nz_clock() //鬧鍾函數
{
if(hour==n_hour&&minu==n_minu&&sec==n_sec)
//if((sec%2==0)&&sec<30)
{
fm=0;
delay(1);
fm=1;
delay(1);
}
}
void set_time() //設置時間函數
{
if(set_1==2)
{
if(set_2==1)
{
hour=incone(hour);
if(hour==24)
{hour=0;}
// if(hour<0)
// {hour=23;}
hour=decone(hour);
}
if(set_2==2)
{
minu=incone(minu);
if(minu==60)
{minu=0;}
// if(minu<0)
// {minu=59;}
minu=decone(minu);
}
}
}
void set_mdw() //設置月日星期函數
{
if(set_1==4)
{
if(set_2==1)
{
mon=incone(mon);
if(mon==13)
{mon=1;}
mon=decone(mon);
// if(mon==0)
// {mon=12;}
}
if(set_2==2)
{
day=incone(day);
if(day==32)
{day=0;}
day=decone(day);
// if(day==0)
// {day=0;}
}
if(set_2==3)
{
week=incone(week);
if(week==8)
{week=0;}
week=decone(week);
// if(week==0)
// {week=7;}
}
}
}
void set_clock() //設置鬧鍾函數
{
if(set_1==6)
{
if(set_2==1)
{
n_hour=incone(n_hour);
if(n_hour==24)
{n_hour=0;}
n_hour=decone(n_hour);
if(n_hour==0)
{n_hour=0;}
}
if(set_2==2)
{
n_minu=incone(n_minu);
if(n_minu==60)
{n_minu=0;}
n_minu=decone(n_minu);
if(n_minu==0)
{n_minu=0;}
}
}
}
uchar incone(uchar n) //加1函數
{
if(s3==0)
{ delay(200);
if(s3==0)
{
n++;
while(!s3);
}
}
return(n);
}
uchar decone(uchar m) //減1函數
{
if(s4==0)
{
delay(200);
if(s4==0)
{
m--;
while(!s4);
if(m<0)
{m=0;}
}
}
return(m);
}
void delay(uint k) //延時函數
{
uint i,j;
for(i=k;i>0;i--)
for(j=80;j>0;j--);
}
F. 基於單片機的數字鍾
電子鍾(DS1302+AT89C2051的紅外遙控鍾)
http://hi..com/lyzhangxiang/blog/item/84c87508738259a92eddd487.html(電路圖)
我的博客hi..com/lyzhangxiang(有空去看看都是講單片機和有關製作的問題的)QQ8250932729(我也很喜歡單片機)
;遙控器各按鍵數據碼,可根據不同的遙控器修改對應的鍵碼
muteM EQU 10h ;靜音鍵 鬧鈴開/關
timerT EQU 0Ch ;菜單鍵 進入/退出設置狀態
leftL EQU 46h ;左移鍵
rightR EQU 47h ;右移鍵
upU EQU 19h ;增加鍵
downD EQU 1dh ;減少鍵
d_off EQU 16H ;顯示鍵 LED數碼管顯示/關閉
recall EQU 44H ;日歷鍵 DS1302初始化操作
K_on BIT P3.0 ;鬧鈴輸出
LED1 BIT P3.3
LED2 BIT P3.4
LED3CLK BIT P3.5 ;DS1302
LED4IO BIT P3.7
RST BIT P3.1
SECOND EQU 60H
;60H 秒
;61h 分
;62h 時
;63h 日
;64h 月 ;65h DAY
;66h 年
;6Ah 鬧分 from 00(1302)
;6BH 鬧時 from 01(1302)
;***************************
ORG 0000H
AJMP START
ORG 0003H
LJMP S_INT ;IRF
ORG 000BH ;200Us
LJMP P_INT ;
ORG 001BH ;display LED
LJMP DISPLAY
;**************************** ;main program
ORG 0030H
START: CLR RST
MOV SP,#2AH
SETB 05H
CLR 06H
SETB 07H;CLR 07H
CLR 08H
CLR 09H
CLR 0AH
CLR 0BH
CLR 0CH
SETB 0DH
CLR 0EH
CLR 0FH
CLR 10H
CLR 11H
MOV R2,#00H ;
MOV R3,#00H ;
MOV TMOD,#12H
MOV TL1,#0e5H ;wait
MOV TH1,#0BeH
MOV TH0,#3FH ;200uS 3f
MOV TL0,#3FH
SETB ET0
SETB ET1
setb pt0
SETB TR0
SETB TR1
SETB IT0 ;
SETB EX0 ;
CLR PX0 ;LCALL SET1302 ;初始化
MOV R1,#0C1H ;取定時參數從1302中
acall T_6061
MOV 6AH,A ;M
MOV R1,#0C3H
ACALL T_6061
MOV 6BH,A ;H
MOV 61H,#0
MOV 62H,#0
SETB EA
sjmp $
;********************************
DISPLAY: PUSH ACC
PUSH PSW
MOV TL1,#0e0H ;wait how long to display (20ms)
MOV TH1,#0b0H
MOV dptr,#tab1
JB 0EH,DIS2
JB 0FH,DIS3
JB 10H,DIS4
JB 11H,DIS5
JNB 0DH,D_OUT
JNB 08H,D_GO ;定時到時,顯示閃爍
JNB 07H,D_OUT
D_G MOV DPTR,#TAB1
MOV A,62H
ANL A,#0FH
MOV B,A
MOV A,62H
SWAP A
ANL A,#07H
MOVC A,@A+DPTR
MOV P1,A
CLR LED1
LCALL DL2M
SETB LED1
MOV A,B
MOVC A,@A+DPTR
MOV C,07H
MOV acc.7,C ;秒燈閃爍
MOV P1,A
CLR LED2
LCALL DL2M
SETB LED2
MOV dptr,#tab2 ;倒裝LED欄位表
MOV A,61H
ANL A,#0FH
MOV B,A
MOV A,61H
SWAP A
ANL A,#0FH
MOVC A,@A+DPTR
MOV C,07H
MOV acc.6,C ;秒燈閃爍
MOV P1,A
CLR LED3CLK
LCALL DL2M
SETB LED3CLK
MOV dptr,#tab1
MOV A,B
MOVC A,@A+DPTR
MOV C,06H
cpl c
MOV acc.7,C ;鬧鈴指示燈
MOV P1,A
CLR LED4IO
LCALL DL2M
SETB LED4IO
D_OUT: SETB TR1
POP PSW
POP ACC
RETI
;*********************
DIS2: AJMP DIS_2
DIS3: AJMP DIS_3
DIS4: AJMP DIS_4
DIS5: AJMP DIS_5
;********************
DIS_2: MOV dptr,#tab1 ;顯示設置小時
MOV 6FH,62H
ACALL BCD_HEX
MOV B,#10
DIV AB
MOVC A,@A+DPTR
MOV P1,A
CLR LED1
LCALL DL2M
SETB LED1
MOV A,B
MOVC A,@A+DPTR
MOV P1,A
CLR LED2
LCALL DL2M
SETB LED2
SETB TR1
POP PSW
POP ACC
RETI
;*****************
DIS_3: MOV DPTR,#TAB2 ;顯示設置分
MOV 6FH,61H
ACALL BCD_HEX
MOV B,#10
DIV AB
MOVC A,@A+DPTR
MOV P1,A
CLR LED3CLK
LCALL DL2M
SETB LED3CLK
MOV A,B
MOV DPTR,#TAB1
MOVC A,@A+DPTR
MOV P1,A
CLR LED4IO
LCALL DL2M
SETB LED4IO
SETB TR1
POP PSW
POP ACC
RETI
;*****************
DIS_4: MOV dptr,#tab1 ;顯示設置鬧時
JNB 07H,D4_OUT ;顯示時閃爍
MOV A,6BH
MOV B,#0AH
DIV AB
MOVC A,@A+DPTR
MOV P1,A
CLR LED1
LCALL DL2M
SETB LED1
MOV A,B
MOVC A,@A+DPTR
MOV P1,A
CLR LED2
LCALL DL2M
SETB LED2
D4_OUT: SETB TR1
POP PSW
POP ACC
RETI
;***********************
DIS_5: MOV DPTR,#TAB2
JNB 07H,D5_OUT ;顯示時閃爍
MOV A,6AH ;顯示設置鬧分
MOV B,#0AH
DIV AB
MOVC A,@A+DPTR
MOV P1,A
CLR LED3CLK
LCALL DL2M
SETB LED3CLK
MOV DPTR,#TAB1
MOV A,B
MOVC A,@A+DPTR
MOV P1,A
CLR LED4IO
LCALL DL2M
SETB LED4IO
D5_OUT: SETB TR1
POP PSW
POP ACC
RETI
;*****************************
DL2M: MOV 43H,#14H ; every LED(2ms)
DL2: MOV 44H,#14H
DL1: NOP
NOP
DJNZ 44H,DL1
DJNZ 43H,DL2
RET
;************************定時讀取1302時間及判斷鬧鈴時間是否到*******
P_INT: PUSH ACC
PUSH PSW
INC R2
CJNE R2,#250D,P_OUT
MOV R2,#00H
INC R3
CJNE R3,#10D,P_OUT
MOV R3,#00H
CPL 07H
MOV P1,#0FFH
ACALL R_1302
OUT: JNB 06H,P_OUT
MOV A,6BH
MOV B,#10
DIV AB
SWAP A
ADD A,B
CJNE A,62H,PP_OUT
MOV A,6AH
MOV B,#10
DIV AB
SWAP A
ADD A,B
CJNE A,61H,PP_OUT
SETB 08H ;定時到標志
MOV C,07H
cpl c
MOV K_ON,C
P_OUT: POP PSW
POP ACC
RETI
PP_OUT: SETB K_ON
CLR 08H
POP PSW
POP ACC
RETI
;************************有接收到遙控器信號*******
S_INT:CLR EA
PUSH ACC
PUSH PSW
PUSH DPH
PUSH DPL
PUSH 02H
PUSH 03H
MOV R6,#10D ;
SB: ACALL YS1
JB P3.2,EXIT
DJNZ R6, SB
JNB P3.2, $ ;
ACALL YS2 ;
JB P3.2,EXIT
MOV R1,#1AH ;
MOV R2,#4D
PP: MOV R3,#8D
JJJJ: JNB P3.2,$
ACALL YS1
MOV C,P3.2
JNC UUU
JB P3.2,$
UUU: MOV A,@R1
RRC A
MOV @R1,A
DJNZ R3,JJJJ
INC R1
DJNZ R2,PP
;-------------------------------------
MOV A,1AH ;
XRL A,#40h ;判斷1AH的值是否等於遙控器低8位地址(40h)
JNZ EXIT ;
MOV A,1bH
XRL A,#0bfh ;再判斷高8位地址是否正確(0bfh)
JNZ EXIT
MOV A,1CH
CPL A
XRL A,1DH ;將1CH的值取反後和1DH比較 不同則無效丟棄(核對數據是否准確)
JNZ EXIT
ACALL DO ;相應按鍵的處理
EXIT: SETB EA
POP 03H
POP 02H
POP DPL
POP DPH
POP PSW
POP ACC
RETI
;--------------------delay-----------------------
YS1: MOV 70H,#16D ;延時1
D1: MOV 71H,#21D
DJNZ 71H,$
DJNZ 70H,D1
RET
YS2: MOV 70H,#09D ;延時2
D2: MOV 71H,#220D
DJNZ 71H,$
DJNZ 70H,D2
RET
;---------------------------------------------------------
TAB: DB 00H,01H,02H,03H,04H,05H,06H,07H,08H,09H ;TAB1 LED數碼管顯示表 TAB遙控器鍵值表(未用)
;TAB1: DB 3FH,11H,5EH,5BH,71H,6BH,6FH,19H,7FH,7bH,77H,7CH,39H,5EH,79H,71H
tab1: DB 0C0H,0F9H,0a4h,0b0h,99h,92h,82h,0f8h,80h,90h,88h,83h,0a7h,0a1h,86h,8EH
TAB2: DB 0c0H,0f9H,64H,70H,59H,52H,42H ;倒裝LED段碼表
;0CH 為設置標志,0DH為全顯示標志,0EH為顯示設置小時標志,0FH為顯示設置分標志
;10H 為顯示設置鬧時標志,11H為顯示設置鬧分標志
;增加鬧時靜音功能
;mute-10h,timer-0eh,left-46h,right-47h,up-19h,down-1dh
D MOV A,1CH
CJNE A,#TIMERT,REDO ;代碼不是設置/退出鍵
JNB 0CH,SET1 ;是,則進入
CLR 0CH ;是,已經進入,則退出
SETB 0DH ;恢復正常顯示
CLR 0EH
CLR 0FH
CLR 10H
CLR 11H
RET
SET1: SETB 0CH
SETB 0EH
CLR 0DH
CLR 0FH
CLR 10H
CLR 11H
RET
RED CJNE A,#MUTEM,REDO1 ;不是設置鍵的處理REDO1,2,3,4...
LJMP MUTE ;MUTE?
REDO1: CJNE A,#D_OFF,DO_SET2
LJMP DIS_OFF ;關閉顯示
DO_SET2:JB 0CH,SET2 ;時間設置的處理
RET
SET2: CJNE A,#UPU,SET2A
LJMP INC1 ;+加(^)
SET2A: CJNE A,#DOWND,SET2B
LJMP DEC2 ;- 減
SET2B: CJNE A,#RIGHTR,SET2C
LJMP RIGHT ;RIGHT右移(>)
SET2C: CJNE A,#LEFTL,SET2D LJMP LEFT ;LEFT左移(<)
SET2D: CJNE A,#RECALL,SET2EXT ;DS1302初始化
LJMP SET1302
SET2EXT:RET
;--------------------------------INC------------------------
INC1: JB 0EH,INCH
JB 0FH,INCM
JB 10H,INC_H
JB 11H,INC_M
RET
INC_H: INC 6BH ;鬧鍾小時增加
MOV A,6BH
CJNE A,#24D,INCH3
MOV 6BH,#0
INCH3: MOV R1,#0C2H
MOV R0,6BH
ACALL SETONE ;寫入DS1302
RET
INC_M: INC 6AH ;鬧鍾分增加
MOV A,6AH
CJNE A,#60D,INCH4
MOV 6AH,#0
INCH4: MOV R1,#0C0H
MOV R0,6AH
ACALL SETONE ;
RET
INCH: ;INC 62H ;
MOV 6FH,62H
ACALL BCD_HEX
INC A
CJNE A,#24D,INCH1
MOV A,#0
INCH1: MOV 6FH,A
ACALL HEX_BCD
MOV 62H,A
MOV R1,#84H
MOV R0,62H
ACALL SETONE ;
RET
INCM: ;INC 61H ;
MOV 6FH,61H
ACALL BCD_HEX
INC A
CJNE A,#60D,INCH2
MOV A,#0
INCH2: MOV 6FH,A
ACALL HEX_BCD
MOV 61H,A
MOV R1,#82H
MOV R0,61H
ACALL SETONE ;
RET
;----------------------------------DEC----------------------
DEC2: JB 0EH,DECH
JB 0FH,DECM
JB 10H,DEC_H
JB 11H,DEC_M
RET
DECH: MOV 6FH,62H
ACALL BCD_HEX
DEC A
CJNE A,#0FFH,DECH1
MOV A,#23
DECH1: MOV 6FH,A
ACALL HEX_BCD
MOV 62H,A
MOV R1,#84H
MOV R0,62H
ACALL SETONE
RET
DECM: MOV 6FH,61H
ACALL BCD_HEX
DEC A
CJNE A,#0FFH,DECM1
MOV A,#59
DECM1: MOV 6FH,A
ACALL HEX_BCD
MOV 61H,A
MOV R1,#82H
MOV R0,61H
ACALL SETONE
RET
DEC_H: DEC 6BH
MOV A,6BH
CJNE A,#0FFH,DECH3
MOV 6BH,#23D
DECH3: MOV R1,#0C2H
MOV R0,6BH
ACALL SETONE
RET
DEC_M: DEC 6AH
MOV A,6AH
CJNE A,#0FFH,DECH4
MOV 6AH,#59D
DECH4: MOV R1,#0C0H
MOV R0,6AH
ACALL SETONE
RET
;--------------------------------RIGHT----------------------
RIGHT: JB 0EH,RIGHT1
JB 0FH,RIGHT2
JB 10H,RIGHT3
JB 11H,RIGHT4
RET ;右移
RIGHT1: CLR 0EH
SETB 0FH
RET
RIGHT2: CLR 0FH
SETB 10H
RET
RIGHT3: CLR 10H
SETB 11H
RET
RIGHT4: CLR 11H
SETB 0EH
RET
;--------------------------------LEFT-----------------------
LEFT: JB 0EH,LEFT1
JB 0FH,LEFT2
JB 10H,LEFT3
JB 11H,LEFT4
RET ;左移
LEFT1: SETB 11H
CLR 0EH
RET
LEFT2: SETB 0EH
CLR 0FH
RET
LEFT3: SETB 0FH
CLR 10H
RET
LEFT4: SETB 10H
CLR 11H
RET
;------------------------------MUTE--------------
MUTE: setb k_ON
CPL 06H ;靜音
CLR 08H
RET
;-----------------------------DISPLAY OFF--------
DIS_OFF:CLR ET1
CPL 05H
JNB 05H,REDORE
SETB ET1
REDORE: RET
;------------------------------------初始化1302
SET1302: CLR RST ;2002年1月1日12:00:00
CLR LED3CLK
MOV SECOND,#0
MOV 61H,#0
MOV 62H,#18 ;
MOV 63H,#1
MOV 64H,#1
MOV 65H,#1
MOV 66H,#2
SETB RST
MOV A,#8EH
LCALL R_BIT
MOV A,#00H
LCALL R_BIT
SETB LED3CLK
CLR RST
MOV R0,#SECOND
MOV R7,#7
MOV R1,#80H
SET1302A:CLR RST
CLR LED3CLK
SETB RST
MOV A,R1
LCALL R_BIT
MOV A,@R0
LCALL R_BIT
INC R0
INC R1
INC R1
SETB LED3CLK
CLR RST
DJNZ R7,SET1302A
CLR RST
CLR LED3CLK
sETB LED3CLK
nop
CLR RST
nop
clr led3clk
SETB RST
MOV A,#90H
LCALL R_BIT
MOV A,#10100101B ;充電器設置
LCALL R_BIT
SETB LED3CLK
CLR RST
CLR LED3CLK
SETB RST
MOV A,#8EH
LCALL R_BIT
MOV A,#80H
LCALL R_BIT
SETB LED3CLK
CLR RST
RET
;----------------------讀取一RAM ------
T_6061: CLR RST
CLR LED3CLK
SETB RST
MOV A,R1
LCALL R_BIT
LCALL W_BIT
SETB LED3CLK
CLR RST
RET
;-----------------------------
R_1302: MOV R0,#SECOND
MOV R7,#7
MOV R1,#81H
R_1302A: CLR RST
CLR LED3CLK
SETB RST
MOV A,R1
LCALL R_BIT
LCALL W_BIT
MOV @R0,A
INC R0
INC R1
INC R1
SETB LED3CLK
CLR RST
DJNZ R7,R_1302A
RET
;------------------R_BIT------------------
R_BIT: MOV R4,#8
R_BIT1: RRC A
MOV LED4IO,C
SETB LED3CLK
CLR LED3CLK
DJNZ R4,R_BIT1
RET
;-------------------W_BIT-----------------------
W_BIT: MOV R4,#8
W_BIT1: MOV C,LED4IO
RRC A
SETB LED3CLK
CLR LED3CLK
DJNZ R4,W_BIT1
RET
;--------------------------------------------------
BCD_HEX:
MOV A,6FH
ANL A,#0FH
MOV B,A
MOV A,6FH
MOV 6FH,B
SWAP A
ANL A,#0FH
MOV B,#0AH
MUL AB
ADD A,6FH
;MOV 6FH,A
RET
HEX_BCD:
MOV A,6FH
MOV B,#10
DIV AB
SWAP A
ADD A,B
;MOV 6FH,A
RET
;-----寫一地址---R1 為地址,R0 為數據----------
SETONE: CLR LED3CLK
CLR RST
CLR LED3CLK
NOP
SETB RST
MOV A,#8EH
LCALL R_BIT
MOV A,#00H
LCALL R_BIT
SETB LED3CLK
CLR RST
CLR LED3CLK
NOP
CLR RST
CLR LED3CLK
SETB RST
MOV A,R1
LCALL R_BIT
MOV A,R0
LCALL R_BIT
NOP
SETB LED3CLK
CLR RST
NOP
NOP
CLR RST
CLR LED3CLK
SETB RST
MOV A,#8EH
LCALL R_BIT
MOV A,#80H
LCALL R_BIT
SETB LED3CLK
CLR RST
RET
G. 單片機課程設計 設計製作一個24小時制多功能數字鍾
額。。。。。這個東西就是零碎的東西加起來變成一個一個整體的啊,講個思路,寫個中斷服務程序,裡面的是led燈亮的程序,和1秒的計時程序,寫個beep子程序控制蜂鳴器,寫個display子程序,控制icl0809,主程序循環控制,顯示數碼管,顯示am,過了12,進入中斷,顯示pm,這個其實很簡單的,我才大三,單片機才學了四個星期,我都會做,相信你能行的。。。