第一篇:89C51單片機時鐘程序
SECOND EQU 40H
;給內(nèi)存RAM空間中40H單元起名SECOND MINUTE EQU 41H
;給內(nèi)存RAM空間中41H單元起名MINUTE HOUR EQU 42H
;給內(nèi)存RAM空間中42H單元起名HOUR SECONDGEWEI EQU 43H
;給43H單元起名SECONDGEWEI存秒的個位 SECONDSHIWEI EQU 44H
;給44H單元起名SECONDSHIWEI存秒的十位 MINUTEGEWEI EQU 45H
;給45H單元起名MINUTEGEWEI存分的個位 MINUTESHIWEI EQU 46H
;給46H單元起名MINUTESHIWEI存分的十位 HOURGEWEI EQU 47H
;給47H單元起名HOURGEWEI存小時的個位 HOURSHIWEI EQU 48H
;給48H單元起名HOURSHIWEI存小時的十位 ORG 0000H
;復位時程序從此開始 SJMP START
;跳到START進行初始化 ORG 000BH
;定時器 0中斷入口 AJMP TIMER0
;跳轉(zhuǎn)到TIMER0處
ORG 0030H
;初始化程序從30H開始;---------------初始化START------------------------------START:
MOV SECOND, #0
;給秒存儲單元SECOND賦初始值0 MOV MINUTE, #0
;給分存儲單元MINUTE賦初始值0 MOV HOUR , #12
;給小時存儲單元HOUR賦初始值12 MOV DPTR , #TAB
;給數(shù)據(jù)指針賦值,將DPTR指向TAB數(shù)據(jù)表頭處 MOV 30H, #0
;給30H單元賦初始值0(用于計20次的50ms中斷)MOV TH0,#3CH
;給計數(shù)容器的高8位TH0賦初始值3CH MOV TL0,#0B0H
;給計數(shù)容器的低8位TL0賦初始值B0H MOV TMOD,#00000001B
;C/T位設(shè)置為0,M1M0設(shè)置位10,即模式1定時 MOV TCON,#00010000B
;TR0設(shè)置為1,即啟動定時器0開始工作 SETB ET0
;IE中的ET0位設(shè)置為1,開定制器中斷0 SETB EA
;IE中的EA位設(shè)置為1,開總中斷;-----------------------主程序MAIN-----------------------------MAIN:CALL KEY
;調(diào)按鍵子程序KEY CALL PROCESS
;調(diào)數(shù)據(jù)處理子程序PROCESS CALL DISPLAY
;調(diào)顯示子程序DISPLAY SJMP MAIN
;跳轉(zhuǎn)到MAIN標號處;------------------------------按鍵子程序KEY調(diào)時-------------------KEY:MOV P1,#0FEH
;行掃描 LCALL DELAY
;JNB P1.4,HOURJIA
;P1.4引腳如果是低電平就跳到HOURJIA處
JNB P1.5,HOURJIAN
;P1.5引腳如果是低電平就跳到HOURJIAN處 JNB P1.6,MINUTEJIA
;P1.6引腳如果是低電平就跳到MIMUTEJIA處 JNB P1.7,MINUTEJIAN
;P1.7引腳如果是低電平就跳到MIMUTEJIAN處 FANHUI:RET
;子程序返回(如果沒有按鍵按下)
HOURJIA:CALL DELAY
;調(diào)延時程序目的是跳過按鍵抖動期(去抖)JB P1.4,FANHUI
;P1.4如果是高電平就跳到FANHUI處(沒鍵按)JNB P1.4,$
;如果P1.4是低電平就停在當前位置等鍵釋放 MOV R4,HOUR CJNE R4,#23,A1
;判斷時數(shù)字是否為23 AJMP A2
A1:INC HOUR
;把小時位加1 MOV SECOND, #0
;小時進位,秒歸0
RET
A2:MOV HOUR,#0
;小時數(shù)為23時加一為0
MOV SECOND, #0
;小時進位,秒歸0
RET
;子程序返回
HOURJIAN:CALL DELAY
;調(diào)延時程序目的是跳過按鍵抖動期(去抖)JB P1.5,FANHUI
JNB P1.5,$
MOV R5,HOUR CJNE R5,#0,A3
AJMP A4 A3:DEC HOUR
MOV SECOND, #0
RET A4:MOV HOUR,#23
MOV SECOND, #0 RET
MINUTEJIA:CALL DELAY
JB P1.6,FANHUI
JNB P1.6,$
MOV R6,MINUTE
CJNE R6,#59,A5
AJMP A6 A5:INC MINUTE
MOV SECOND, #0
RET A6:MOV SECOND, #0
MOV MINUTE, #0
MOV R4,HOUR CJNE R4,#23,A10
MOV HOUR,#0
RET A10:INC HOUR
RET
MINUTEJIAN:CALL DELAY
JB P1.7,FANHUI
JNB P1.7,$
MOV R7,MINUTE CJNE R7,#0,A7
AJMP A8 A7:DEC MINUTE
;P1.5如果是高電平就跳到FANHUI處(沒鍵按)
;如果P1.5是低電平就停在當前位置等鍵釋放
;判斷時數(shù)字是否為23
;把小時位減1
;小時數(shù)為0時減一為23
;子程序返回
;調(diào)延時程序目的是跳過按鍵抖動期(去抖)
;P1.6如果是高電平就跳到FANHUI處(沒鍵按)
;如果P1.6是低電平就停在當前位置等鍵釋放
;判斷分鐘數(shù)是否為59
;把分鐘位加1
;給秒存儲單元SECOND賦初始值0
;分鐘數(shù)為59則分鐘歸0
;判斷時數(shù)字是否為23
;23時增1歸0
;分鐘數(shù)為59 自增1后小時增1
;子程序返回
;調(diào)延時程序目的是跳過按鍵抖動期(去抖)
;P1.7如果是高電平就跳到FANHUI處(沒鍵按)
;如果P1.7是低電平就停在當前位置等鍵釋放
;判斷分鐘數(shù)是否為0
;分鐘不為0把分鐘位減1
MOV SECOND, #0
RET
A8:MOV MINUTE, #59
;分鐘數(shù)為0時減一為59 MOV R4,HOUR CJNE R4,#0,A9
;判斷時鐘數(shù)是否為0 MOV HOUR,#23
;時鐘數(shù)為0減1為23 MOV SECOND, #0 RET
A9:DEC HOUR
;時鐘數(shù)不為0則減1 MOV SECOND, #0
RET
;子程序返回;-------------------處理子程序PROCESS-----------------------PROCESS:MOV A, SECOND
;把SECOND中的秒值拷貝給A MOV B, #10
;給寄存器B賦值10 DIV AB
;A除以B,結(jié)果存入A中,余數(shù)存入B中 MOV SECONDSHIWEI , A
;結(jié)果即秒的十位數(shù)拷貝給SECONDSHIWEI MOV SECONDGEWEI , B
;余數(shù)即秒的個位拷貝給SECONDGEWEI MOV A, MINUTE
;把MINUTE中的分值拷貝給A MOV B, #10
;給寄存器B賦值10 DIV AB
;A除以B,結(jié)果存入A中,余數(shù)存入B中 MOV MINUTESHIWEI , A
;結(jié)果即分的十位拷貝給MINUTESHIWEI MOV MINUTEGEWEI , B
;余數(shù)即分的個位拷貝給MINUTEGEWEI MOV A, HOUR
;把HOUR中的小時值拷貝給A MOV B, #10
;給寄存器B賦值10 DIV AB
;A除以B,結(jié)果存入A中,余數(shù)存入B中 MOV HOURSHIWEI , A
;結(jié)果即小時的十位拷貝給HOURSHIWEI MOV HOURGEWEI , B
;余數(shù)即小時的個位拷貝給HOURGEWEI RET
;子程序結(jié)束返回到主程序;-----------------顯示子程序DISPLAY--------------DISPLAY:MOV A, HOURSHIWEI
;小時的十位拷貝給A MOVC A, @A+DPTR
;到A+DPRT這個數(shù)對應(yīng)的地方找顯示段碼拷貝給A MOV P0, A
;把顯示段碼(小時的十位)送到P0 CLR P2.0
;將P2.0置低電平,對應(yīng)的三極管導通 CALL DELAY
;調(diào)延時(讓顯示小時十位的數(shù)碼管持續(xù)亮一段時間)SETB P2.0
;將P2.0置高電平,對應(yīng)三極管截止,對應(yīng)數(shù)碼管滅 MOV A, HOURGEWEI
;小時的個位拷貝給A MOVC A,@A+DPTR
;到A+DPRT這個數(shù)對應(yīng)的地方找顯示段碼拷貝給A MOV P0, A
;把顯示段碼(小時的個位)送到P0 CLR P2.1
;將P2.1置低電平,對應(yīng)的三極管導通
CALL DELAY
;調(diào)延時(讓顯示小時個位的數(shù)碼管持續(xù)亮一段時間)SETB P2.1 MOV P0,#7FH CLR P2.1 CALL DELAY SETB P2.1
;將P2.1置高電平,對應(yīng)三極管截止,對應(yīng)數(shù)碼管滅 MOV A, MINUTESHIWEI
;分鐘的十位拷貝給A MOVC A,@A+DPTR
;到A+DPRT這個數(shù)對應(yīng)的地方找顯示段碼拷貝給A MOV P0, A
;把顯示段碼(分鐘的十位)送到P0 CLR P2.2
;將P2.2置低電平,對應(yīng)的三極管導通 CALL DELAY
;調(diào)延時(讓顯示分鐘十位的數(shù)碼管持續(xù)亮一段時間)SETB P2.2
;將P2.2置高電平,對應(yīng)三極管截止,對應(yīng)數(shù)碼管滅 MOV A, MINUTEGEWEI
;分鐘的個位拷貝給A MOVC A,@A+DPTR
;到A+DPRT這個數(shù)對應(yīng)的地方找顯示段碼拷貝給A MOV P0, A
;把顯示段碼(分鐘的個位)送到P0 CLR P2.3
;將P2.3置低電平,對應(yīng)的三極管導通
CALL DELAY
;調(diào)延時(讓顯示分鐘個位的數(shù)碼管持續(xù)亮一段時間)SETB P2.3
;將P2.3置高電平,對應(yīng)三極管截止,對應(yīng)數(shù)碼管滅
MOV P0,#7FH CLR P2.3 CALL DELAY SETB P2.3
MOV A, SECONDSHIWEI
;秒的十位拷貝給A MOVC A,@A+DPTR
;到A+DPRT這個數(shù)對應(yīng)的地方找顯示段碼拷貝給A MOV P0, A
;把顯示段碼(秒鐘的十位)送到P0 CLR P2.4
;將P2.4置低電平,對應(yīng)的三極管導通 CALL DELAY
;調(diào)延時(讓顯示秒鐘十位的數(shù)碼管持續(xù)亮一段時間)SETB P2.4
;將P2.4置高電平,對應(yīng)三極管截止,對應(yīng)數(shù)碼管滅 MOV A, SECONDGEWEI
;秒的個位拷貝給A MOVC A,@A+DPTR
;到A+DPRT這個數(shù)對應(yīng)的地方找顯示段碼拷貝給A MOV P0, A
;把顯示段碼(秒鐘的個位)送到P0 CLR P2.5
;將P2.5置低電平,對應(yīng)的三極管導通
CALL DELAY
;調(diào)延時(讓顯示秒鐘個位的數(shù)碼管持續(xù)亮一段時間)SETB P2.5
;將P2.5置高電平,對應(yīng)三極管截止,對應(yīng)數(shù)碼管滅 RET
;顯示子程序結(jié)束返回主程序;--------------------中斷服務(wù)子程序----------------------------TIMER0:MOV R3, A
;把A中的數(shù)據(jù)送入R3保護起來 INC 30H
;30H單元中的數(shù)加1 MOV A, 30H
;30H單元中的數(shù)據(jù)拷貝給A CJNE A,#20,JIXU
;A中的數(shù)據(jù)與20比較不相等就跳轉(zhuǎn)到JIXU處 MOV 30H,#0
;(如果30H單元計滿20了)給30H賦值0 INC SECOND
;把SECOND中的秒鐘數(shù)加1 MOV A,SECOND
;把SECOND中的數(shù)據(jù)拷貝給A CJNE A, #60, JIXU
;A中的數(shù)據(jù)與60比較不相等就跳轉(zhuǎn)到JIXU處 MOV SECOND, #0
;給秒SECOND賦值0 INC MINUTE
;把MINUTE中的分鐘數(shù)加1 MOV A, MINUTE
;把MINUTE中的數(shù)據(jù)拷貝給A CJNE A, #60, JIXU
;A中的數(shù)據(jù)與60比較不相等就跳轉(zhuǎn)到JIXU處 MOV MINUTE, #0
;給分鐘MINUTE賦值0 INC HOUR
;把HOUR中的小時數(shù)據(jù)加1 MOV A, HOUR
;把HOUR中的數(shù)據(jù)拷貝給A CJNE A, #24, JIXU
;A中的數(shù)據(jù)與24比較不相等就跳轉(zhuǎn)到JIXU處 MOV HOUR, #0
;給小時HOUR賦值0 JIXU: MOV A,R3
;把剛才送入R3中的數(shù)據(jù)還給A MOV TH0,#3CH
;給計數(shù)容器的高8位TH0賦初始值3CH MOV TL0,#0B0H
;給計數(shù)容器的低8位TL0賦初始值B0H RETI
;中斷子程序返回主程序;---------------------------延時子程序----------------------------DELAY:MOV R0, #50
;給R0賦值50 D2:MOV R1, #10
;給R1賦值10 D1:DJNZ R1, D1
;R1減1不等于0跳到D1處 DJNZ R0, D2
;R0減1不等于0跳到D2處
RET
;延時子程序結(jié)束返回調(diào)用該程序的下一條;---------------下面的數(shù)據(jù)表中存儲的是顯示段碼(共陽)-------------------TAB:DB 0C0H,0F9H,0A4H,0B0H,99H
;從TAB處開始存儲0、1、2、3、4
DB 92H ,82H ,0F8H,80H ,90H
;5、6、7、8、9對應(yīng)的顯示段碼 END
;程序結(jié)束
第二篇:基于單片機的時鐘控制器設(shè)計
時鐘控制器設(shè)計任務(wù)書
1.設(shè)計目的與要求
設(shè)計出一個用于數(shù)字時鐘的控制器,準確地理解有關(guān)要求,獨立完成系統(tǒng)設(shè)計,要求所設(shè)計的電路具有以下功能:
(1)顯示: 可以顯示時、分和秒
(2)調(diào)時功能:時(0-24)、分和秒(0-60)可以連續(xù)可調(diào)(3)時間日誤差< 2秒(4)增加整點報時功能(5)增加鬧鐘任意設(shè)定功能 2.設(shè)計內(nèi)容
(1)畫出電路原理圖,正確使用邏輯關(guān)系;(2)確定元器件及元件參數(shù);(3)進行電路模擬仿真;(4)SCH文件生成與打印輸出;(5)PCB文件生成與打印輸出; 3.編寫設(shè)計報告
寫出設(shè)計的全過程,附上有關(guān)資料和圖紙,有心得體會。4.答辯
在規(guī)定時間內(nèi),完成敘述并回答問題。
目錄
1.引言…………………………………………………………………………-1-2 總體設(shè)計方案………………………………………………………………-1-2.1 設(shè)計思路…………………………………………………………………-1-2.2 方案確立…………………………………………………………………-1-2.3 設(shè)計方框圖………………………………………………………………-2-3 設(shè)計原理分析………………………………………………………………-2-3.1 系統(tǒng)硬件電路設(shè)計 ……………………………………………………-2-3.2 主控器件AT89S51 ………………………………………………………-2-3.3 譯碼器74HC245 …………………………………………………………-3-3.4 顯示電路 …………………………………………………………………3-3.5 按鍵電路…………………………………………………………………-4-3.6 復位電路…………………………………………………………………-4-3.7 蜂鳴電路…………………………………………………………………-5-3.8 時鐘電路…………………………………………………………………-5-3.9 總體原理圖………………………………………………………………-5-3.10程序框圖…………………………………………………………………-5-4 結(jié)束語………………………………………………………………………-7-參考文獻………………………………………………………………………-8-附錄 1 電路總原理圖 ………………………………………………………-9-附錄 2 總程序………………………………………………………………-10-
基于單片機控制的時鐘控制器
摘要:本設(shè)計以Atmel公司的AT89S51單片機為控制系統(tǒng)的核心,模型采用單片機作為主控制器,以匯編語言為程序設(shè)計的基礎(chǔ),設(shè)計的一個用兩個四位一體數(shù)碼管串口顯示的時鐘控制電路,包含了時鐘控制電路的基本功能:數(shù)碼顯示,時間調(diào)整,鬧鐘設(shè)定,秒表顯示等,按照二十四小時循環(huán),具有調(diào)節(jié)方便,簡單實用,可靠性強的優(yōu)點,有很高的利用價值。關(guān)鍵詞:單片機 AT89C51 74LS245 數(shù)碼管 引言
數(shù)字鐘是采用數(shù)字電路實現(xiàn)對時、分、秒及數(shù)字顯示的計時裝置,廣泛用于個人家庭、車站、碼頭、辦公室等公共場所,成為人們?nèi)粘I钪胁豢缮俚谋匦杵?,由于?shù)字集成電路的發(fā)展和石英晶體振蕩器的廣泛應(yīng)用,使得數(shù)字鐘的精度,遠遠超過老式鐘表,鐘表的數(shù)字化給人們生產(chǎn)生活帶來了極大的方便,而且大大地擴展了鐘表原先的報時功能。諸如定時自動報警、按時自動打鈴、時間程序自動控制、定時廣播、自動起閉路燈、定時開關(guān)烘箱、通斷動力設(shè)備、甚至各種定時電氣的自動啟用等,所有這些,都是以鐘表數(shù)字化為基礎(chǔ)的。因此,研究數(shù)字鐘及擴大其應(yīng)用,有著非?,F(xiàn)實的意義。為了適應(yīng)時代的潮流,本設(shè)計采用AT89S51單片機為核心,使得計時的精度有了很大的提高,而且調(diào)節(jié)也變的簡單實用,采用數(shù)字顯示也跟加的直觀方便。總體設(shè)計方案
2.1 設(shè)計思路
本設(shè)計采用AT89S51單片機為控制核心,產(chǎn)生精確的時鐘震蕩,來控制數(shù)碼管顯示電路來進行數(shù)碼顯示,外圍電路主要有復位電路,震蕩電路,按鍵電路,顯示電路,蜂鳴電路組成;復位電路可及時的對單片機進行復位,恢復到初始的狀態(tài),震蕩電路主要用于計數(shù),定時,產(chǎn)生合適的波特率,按鍵電路主要是給人們提供一個合適的人機對話的界面,方便人們進行實時的調(diào)節(jié),顯示電路主要用于數(shù)碼的顯示,蜂鳴電路用于鬧鈴設(shè)定等輔助功能。2.2 方案確立
本設(shè)計主要有包含了時鐘電路,按鍵掃描,顯示電路等幾個部分。由單片機實現(xiàn)時鐘功能單片機內(nèi)部具有定時器,可方便實現(xiàn)定時功能。按鍵電路:鍵盤分為矩陣式鍵盤掃描電路和獨立式按鍵電路。。矩陣式鍵盤電路,此類鍵盤是采用行列掃描方式,優(yōu)點是當按鍵較多時可以降低占用單片機的I/O口數(shù)目,缺點是電路復雜且會加大編程難度。獨立按鍵電路,每個鍵單獨占有一根I/O接口線,每個I/O口的工作狀態(tài)互不影響,此類鍵盤采用端口直接掃描方式。缺點是當按鍵較多時占用單片機的I/O數(shù)目較多,優(yōu)點是電路設(shè)計簡單,且編程極其容易。由于該系統(tǒng)采用了常規(guī)鐘表式的校對方式,用鍵較少,系統(tǒng)資源足夠用,故采用了獨立按鍵電路。顯示電路分為:靜態(tài)顯示法與動態(tài)顯示法,由于靜態(tài)顯示法需要數(shù)據(jù)鎖存器等硬件,接口復雜一些,又考慮到時鐘顯示只有6位,且系統(tǒng)沒有其它復雜的處理任務(wù),所以決定采用動態(tài)顯示法。2.3 硬件設(shè)計方框圖
電路的設(shè)計以AT89S51單片機為核心,包含了按鍵電路,復位電路,震蕩電路,數(shù) 碼顯示電路,整點報時電路等一系列獨立環(huán)節(jié),下面介紹一下電路設(shè)計過程中的總體框圖,如圖1所示。
圖1 時鐘電路總體框圖 設(shè)計原理分析
用AT89S51單片機控制的數(shù)字時鐘電路,外接震蕩電路,按鍵電路,顯示電路,蜂鳴電路等:用單片機電路P0口來輸出7段碼數(shù)據(jù),P2.0~P2.5口作列掃描輸出;按鍵用P1口控制,分別用于調(diào)節(jié)時,分,以及秒表和鬧鐘的設(shè)定;P1.7口接5V的小蜂鳴器,用于按鍵發(fā)音以及定時提醒,整點報時提醒等;采用74HC245作為數(shù)碼管的段碼驅(qū)動,為了提供共陽LED數(shù)碼管的列掃描驅(qū)動電壓,用三極管8550做電源的驅(qū)動輸出;采用12MHZ晶振,可提高秒計時的精確性;在軟件設(shè)計方面,應(yīng)完成時鐘控制電路的各項要求。
3.1 系統(tǒng)硬件電路設(shè)計
系統(tǒng)硬件電路主要組成:主控制器AT89S52、譯碼器74HC245、顯示電路、蜂鳴器電路,復位電路時鐘電路。3.2 主控器件AT89C51 AT89S51是一款低功耗,高性能CMOS 8位單片機,片內(nèi)含4k Bytes ISP(In-system programmable)的可反復擦寫1000次的Flash只讀程序存儲器,器件采用ATMEL公司的高密度、非易失性存儲技術(shù)制造,兼容標準MCS-51指令系統(tǒng)及80C51引腳結(jié)構(gòu),芯片內(nèi)集成了通用8位中央處理器和ISP Flash存儲單元,AT89S51在眾多嵌入式控制應(yīng)用系統(tǒng)中得到廣泛應(yīng)用。管腳如圖2所示。
圖2 DIP-40封裝89C51引腳圖
3.3譯碼器74LS245 74LS245是我們常用的芯片,用來驅(qū)動led或者其他的設(shè)備,它是8路同相三態(tài)雙向總線收發(fā)器,可雙向傳輸數(shù)據(jù)。74LS245還具有雙向三態(tài)功能,既可以輸出,也可以輸入數(shù)據(jù)。當89S51單片機的P0口總線負載達到或超過P0最大負載能力時,必須接入74LS245等總線驅(qū)動器。當片選端/CE低電平有效時,DIR=“0”,信號由 B 向 A 傳輸;(接收)DIR=“1”,信號由 A 向 B 傳輸;(發(fā)送)當CE為高電平時,A、B均為高阻態(tài)。P0口與74LS245輸入端相連,E端接地,保證數(shù)據(jù)線暢通。管腳如圖3所示。
圖3 74LS245管腳圖
3.4 顯示電路
LED顯示塊是由發(fā)光二極管顯示字段的顯示器件。這種顯示塊有共陰與共陽兩種結(jié)構(gòu)。共陰極LED顯示塊的發(fā)光二極管陰極共地,當某個發(fā)光二極管的陽極為高電平時,發(fā)光二極管點亮。共陽極LED顯示塊的放光二極管陽極并接。顯示塊與單片機接口非常容易,只要將一個8位并行輸出口語顯示塊的發(fā)光二極管引腳相連即可(AT89S51需要加上拉電阻)。此次電路采用2個4位共陽LED數(shù)碼管,從P0口輸出段碼,列掃描用P2.0~P2.7來實現(xiàn)。如圖4所示。
圖4 74LS245驅(qū)動段碼顯示電路圖
3.5 按鍵電路
按鍵調(diào)節(jié)電路有四個獨立的按鍵接到P1口的P1.0—P1.3端口,控制著電路的調(diào)時,調(diào)分以及秒表功能和鬧鐘的設(shè)定。具體電路如下圖5所示。
圖5 按鍵電路圖
3.6 復位電路
AT89S51單片機的復位電路,如圖5所示中左邊電路。在RESET輸入端出現(xiàn)高電平時實現(xiàn)復位和初始化。在震蕩器運行的情況下,要實現(xiàn)復位操作,必須使RST引腳至少 保持兩個機器周期的高電平。在CPU在第二個機器周期內(nèi)執(zhí)行內(nèi)部復位操作,以后每一個機器周期重復一次,直至RST端電平變低復位期間不產(chǎn)生ALE信號。當RST引腳返回低電平以后,CPU從0地址開始執(zhí)行程序。3.7 蜂鳴電路
蜂鳴器是廣泛應(yīng)用于各種電子產(chǎn)品的一種元器件,它用于提示、報警、音樂等許多應(yīng)用場合。三極管8550作蜂鳴器的驅(qū)動,增加了蜂鳴器的驅(qū)動電流。蜂鳴器的正極性的一端接到三極管的集電極,另一端連接到地,三極管的基極由單片機的P1.7管腳控制,底電平時蜂鳴器響,高電平時不響。另外,蜂鳴器的聲音大小及音調(diào)可以通過調(diào)整P1.7管腳的置低時間及輸出的波形進行控制。蜂鳴器的連接電路的原理圖如圖5所示。3.8 時鐘電路
AT89S51內(nèi)部片內(nèi)有一個由反相放大器構(gòu)成的振蕩電路,XTAL1和XTAL2分別為震蕩電路的輸入端和輸出端。時鐘可以由內(nèi)部方式產(chǎn)生或外部方式產(chǎn)生。在XTAL1和XTAL2引腳上外接定時元件,內(nèi)部震蕩電路就產(chǎn)生自己震蕩。定時元件通常采用石英晶體和電容組成的并聯(lián)諧振回路。外部方式的時鐘電路,XTAL1接地,XTAL2接外部振蕩器。一般要求輸入方波信號的頻率低于33Mhz。本文設(shè)計的系統(tǒng)采用的是內(nèi)部方式的時鐘電路。如圖6所示。
圖6 時鐘電路原理圖
3.9 總體原理圖
見附錄1 3.10程序框圖
主程序如圖7所示首先是初始化部分,主要是計時單元清零,中斷初始化,啟動定時器工作,然后是調(diào)用顯示子程序,接著是判斷有無按鍵。無按鍵則回到調(diào)用顯示子程序處;有按鍵,則執(zhí)行按鍵處理子程序,執(zhí)行完后回到調(diào)用顯示子程序處,重復循環(huán)。定時器T0中斷如圖8所示
圖7 主程序流程圖
圖8 中斷程序流程圖 結(jié)束語
三周實習很快就過去了,通過自行設(shè)計、焊接和調(diào)試一個單片機系統(tǒng),我熟悉了單片機基本的開發(fā)流程和單片機的深入學習。在完成這個設(shè)計的同時,我復習了書本上的許多相關(guān)內(nèi)容,受益匪淺。因此我在獲得理論知識的同時,實踐中也獲得了許多書本上沒有的東西。提高了調(diào)試以及查找并解決問題的能力,我深入了解了焊普通元件與電路元件的技巧、數(shù)字時鐘的工作原理及其它各電路元件的作用等。這些知識不僅在課堂上有效,對以后的學習工作有很大的指導意義,在日常生活中更是有著現(xiàn)實意義;也對自己的動手能力是個很大的鍛煉。實踐出真知,縱觀古今,所有發(fā)明創(chuàng)造無一不是在實踐中得到檢驗的。沒有足夠的動手能力,就奢談在未來的科研尤其是實驗研究中有所成就。最后,感謝老師對我們這次實習的辛勤指導和幫助。
參考文獻
[1] 李光飛,樓然苗,胡佳文編著.單片機課程設(shè)計實例指導.北京:北京航空航天大學出版社.2004 [2] 黃仁欣主編.單片機原理及應(yīng)用技術(shù).北京: 清華大學出版社.2005.[3] 高吉祥主編.電子技術(shù)基礎(chǔ)實驗與課程設(shè)計.北京:電子工業(yè)出版社.2002 [4] 肖玲妮.印刷電路板設(shè)計教程.[M].北京:清華大學出版社,2003.[5] 康華光.電子技術(shù)基礎(chǔ).[M].北京;高等教育出版社,2006.[6] 余小平等.電子系統(tǒng)設(shè)計.[M].北京:北京航空航天大學出版社,2007.附錄1: 11 電路總原理圖
附錄2: 總程序
ORG 0000H LJMP START ORG 000BH LJMP INIT0 START: MOV 70H,#0 MOV 71H,#0 MOV 72H,#0 MOV 73H,#0 MOV 74H,#0 MOV 75H,#0 MOV 76H,#0 MOV 77H,#0 MOV 78H,#0 MOV 79H,#0 MOV 7AH,#0 MOV 7BH,#0 MOV 7CH,#0 MOV 7DH,#0 MOV 7EH,#0 MOV 72H,#0AH;對連字符進行裝值
MOV 75H,#0AH MOV 60H,#0 MOV 61H,#0 MOV 63H,#0 MOV 64H,#0 CLR P1.7 MOV TMOD,#01H;選擇定時器/計數(shù)器T0的方式1 MOV TL0,#0B0H;對低位賦初值 MOV TH0,#03CH;高位賦初值 SETB EA SETB ET0 SETB TR0 START1: LCALL SCAN LCALL KEYSCAN SJMP START1 DL1MS: MOV R6,#14H;延時1子程序 DL1: MOV R7,#19H DL2: DJNZ R7,DL2 DJNZ R6,DL1 RET DELAY: MOV R6,#10 D1: MOV R7,#30 DJNZ R7,$ DJNZ R6,D1 RET
DL20MS: ACALL SCAN;延時20ms子程序 ACALL SCAN ACALL SCAN RET
;整點報時將秒和分的單元與零比較 SCAN: MOV A,7EH;7F單元的內(nèi)容為0
CJNE A,79H,NEXT MOV A,7DH
CJNE A,7AH,NEXT SETB P1.7 AJMP NEXT1 NEXT: CLR P1.7 NEXT1:
MOV A,79H
CJNE A,#0,NEXT2 MOV A,78H
CJNE A,#0,NEXT2 SETB P1.7 LJMP NEXT3 NEXT2:CLR P1.7
;數(shù)碼管總顯示程序開始分兩部分
;校正時間和數(shù)碼管正常工作的顯示程序 NEXT3: MOV A,78H MOV B,#0AH
DIV AB;時間秒的十位送給A,時間秒的個位送B
MOV 71H,A;時間秒要顯示的十位
MOV 70H,B;時間秒要顯示的個位
MOV A,79H MOV B,#0AH
DIV AB;時間分的十位送給A,時間分的個位送B
MOV 74H,A;時間分要顯示的十位送地址
MOV 73H,B;時間分要顯示的個位送地址
MOV A,7AH MOV B,#0AH DIV AB;時間時的十位送給A,時間時的個位送B MOV 77H,A;時間時顯示的十位送地址
MOV 76H,B;時間時要顯示的個位送地址
MOV R1,#70H LCALL DL1MS JB P1.2,LAST HERE3:JNB P1.2,HERE3 INC 7EH MOV A,7EH
CJNE A,#3CH,LOOP3 MOV 7EH,#00H;調(diào)制鬧鈴的時間顯示 LOOP3: MOV DPTR,#TAB MOV R5,#0FEH MOV A,7DH MOV R3,#09H
MOV B,#10 SCAN1: MOV A,R5;數(shù)碼管正常工作的顯 DIV AB 示程序
MOV 64H,A MOV P2,A MOV 63H,B MOV A,@R1 MOV A,7EH MOV DPTR,#TAB
MOV B,#10 MOVC A,@A+DPTR;對字段表取值 DIV AB 顯示
MOV 61H,A MOV P0,A MOV 60H,B MOV A,R5 MOV P2,#0F7H LCALL DL1MS MOV A,60H INC R1 MOVC A,@A+DPTR MOV A,R5 MOV P0,A RL A LCALL DELAY MOV R5,A MOV P2,#0EFH DJNZ R3,SCAN1 MOV A,61H MOV P2,#00H MOVC A,@A+DPTR MOV P0,#00H MOV P0,A JB P1.3,QQ LCALL DELAY LCALL DL1MS MOV P2,#0DFH JB P1.3,QQ MOV P0,#40H HERE: JNB P1.3,HERE LCALL DELAY SJMP LOOP1 MOV P2,#0BFH
MOV A,63H QQ: LJMP LAST MOVC A,@A+DPTR LOOP1:JB P1.1,LOOP2 MOV P0,A LCALL DL1MS LCALL DELAY JB P1.1,LOOP2 MOV P2,#07FH HERE1:JNB P1.1,HERE1 MOV A,64H INC 7DH MOVC A,@A+DPTR MOV A,7DH
MOV P0,A CJNE A,#18H,LOOP2 LCALL DELAY MOV 7DH,#00H JB P1.3,LOOP4 LOOP2:JB P1.2,LOOP3 LCALL DL1MS 14 JB P1.3,LOOP4 HERE4:JNB P1.3,HERE4 LJMP LAST LOOP4:LJMP LOOP1 LAST: RET;“0~9”和“-”的字段表 TAB:
DB 3FH,06H,5BH,4FH,66H,6DH,7DH,07H,7FH,6FH,40H
;定時/計數(shù)器T0中斷程序 INIT0: PUSH ACC PUSH PSW CLR ET0 CLR TR0 MOV TL0,#0B0H MOV TH0,#03CH SETB TR0 INC 7BH MOV A,7BH CJNE A,#14H,OUTT0;50ms是否到20次,沒有到就繼續(xù)執(zhí)行50ms的延時
MOV 7BH,#00 INC 78H MOV A,78H CJNE A,#3CH,OUTT0;一秒的延時是否計到60次,沒有就繼續(xù)執(zhí)行
MOV 78H,#00 INC 79H MOV A,79H CJNE A,#3CH,OUTT0 MOV 79H,#00 INC 7AH MOV A,7AH CJNE A,#18H,OUTT0;60分鐘的延時是否計到24次,沒有就繼續(xù)執(zhí)行程序 MOV 7AH,#00 OUTT0: SETB ET0;啟動定時器T0 POP PSW POP ACC RETI;按鍵處理程序 KEYSCAN:CLR EA
JNB P1.0,KEYSCAN0;P1.0有按鍵按下則跳轉(zhuǎn)到子程序
JNB P1.1,KEYSCAN1;P1.1有按鍵按下則跳轉(zhuǎn)到子程序
JNB P1.2,KEYSCAN2;P1.2有按鍵按下則跳轉(zhuǎn)到子程序
KEYOUT: SETB EA RET
KEYSCAN0:LCALL DL20MS;20ms的延時消抖
JB P1.0,KEYOUT WAIT0: JNB P1.0,WAIT0;判斷按鍵是否松手,松手就往下執(zhí)行程序 INC 7CH MOV A,7CH CLR ET0 CLR TR0
CJNE A,#04H,KEYOUT;按下第一次和第二次對時、分選定
MOV 7CH,#00;按下第三次時就啟動計時
SETB ET0 SETB TR0 LJMP KEYOUT
KEYSCAN1:LCALL DL20MS;按鍵加一的程序
JB P1.1,KEYOUT WAIT1: JNB P1.1,WAIT1 MOV A,7CH
CJNE A,#03H,KSCAN11;如果功能鍵按下則對時加一調(diào)整 INC 78H MOV A,78H
CJNE A,#60,KEYOUT MOV 78H,#00 LJMP KEYOUT
KSCAN11: CJNE A,#02H,KSCAN12 INC 79H MOV A,79H
CJNE A,#60,KEYOUT;如果加到60則清零
MOV 79H,#00 LJMP KEYOUT KSCAN12:CJNE A,#01H,KEYOUT INC 7AH;如果功能鍵是按下第二次則對分進行加一調(diào)整
MOV A,7AH CJNE A,#18H,KEYOUT MOV 7AH,#00 LJMP KEYOUT KEYSCAN2:LCALL DL20MS;延時消抖程序 JB P1.2,KEYOUT WAIT2: JNB P1.2,WAIT2;判斷是否放開按鍵
MOV A,7CH;如果功能鍵是按下第一次對時進行減一 CJNE A,#03H,KSCAN22 DEC 78H MOV A,78H CJNE A,#00H,KEYOUT MOV 78H,#3BH LJMP KEYOUT KSCAN22:CJNE A,#02H,KSCAN23 DEC 79H MOV A,79H CJNE A,#00H,KEYOUT1 MOV 79H,#3BH LJMP KEYOUT KSCAN23:CJNE A,#01H,KEYOUT1 DEC 7AH MOV A,7AH;如果功能鍵是按下第二次則對分進行減一 CJNE A,#00H,KEYOUT1 MOV 7AH,#17H LJMP KEYOUT1 KEYOUT1: SETB EA RET END
第三篇:AVR單片機的時鐘設(shè)計(范文)
基于AVR單片機Mega16的時鐘設(shè)計報告
1摘 要
近年來隨著計算機在社會領(lǐng)域的滲透和大規(guī)模集成電路的發(fā)展,單片機的應(yīng)用正在不斷地走向深入,由于它具有功能強,體積小,功耗低,價格便宜,工作可靠,使用方便等特點,因此越來越廣泛地應(yīng)用各個領(lǐng)域.本文的電子鐘系統(tǒng)是以單片機(ATmega16)為核心,時鐘芯片、數(shù)碼管顯示驅(qū)動芯片等元器件組成。具體介紹應(yīng)用Proteus的ISIS軟件進行單片機系統(tǒng)的電子鐘設(shè)計與仿真的實現(xiàn)方法。該方法既能準確驗證所設(shè)計的系統(tǒng)是否滿足技術(shù)要求,又能提高系統(tǒng)設(shè)計的效率和質(zhì)量,降低開發(fā)成本,具有推廣價值。
關(guān)鍵詞:單片機; 時鐘芯片 ;數(shù)碼管顯示驅(qū)動芯片 ;電子鐘
2引 言
單片機電子時鐘系統(tǒng)可以用多種技術(shù)手段實現(xiàn)。本文借助于Proteus仿真系統(tǒng)進行系統(tǒng)虛擬開發(fā)成功之后再進行實際操作,可以節(jié)約開發(fā)時間,降低開發(fā)成本,具有很大的靈活性和可擴展性。在國外有包括斯坦福、劍橋等在內(nèi)的幾千家高校將Proteus作為電子工程學位的教學和實驗平臺;在國內(nèi)也有眾多大學正在體驗Proteus的獨一無二的功能并申報大學計劃。該方法具有普遍意義。通過實際應(yīng)用發(fā)現(xiàn),采用該方法可以大大簡化硬件電路測試和系統(tǒng)調(diào)試過程中電路板制作、元器件安裝、焊接等過程。很明顯,使用該方法可以提高開發(fā)效率、降低開發(fā)成本、提升開發(fā)…
AVR系列的單片機不僅具有良好的集成性能,而且都具備在線編程接口,其中的系列還具備仿真和下載功能;含有片內(nèi)看門狗電路、片內(nèi)程序FLASH、同步串行接口SPI;多數(shù)AVR單片機還內(nèi)嵌了A/D轉(zhuǎn)換器、EEPROM、模擬比較器、PWM定時計數(shù)器等多種功能;AVR單片機的I/O接口具有很強的驅(qū)動能力,灌人電流可直接驅(qū)動繼電器、LED等元件,從而省去驅(qū)動電路,節(jié)約系統(tǒng)成本。
3設(shè)計思路
利用單片機(ATmega16)制作簡易電子時鐘,由六個LED數(shù)碼管分別顯示小時十位、小時個位、分鐘十位、分鐘個位、秒鐘十位、秒鐘個位。6個PNP管分別控制六個數(shù)碼管的亮滅,此外還可以實現(xiàn)時間調(diào)整、等多種實用功能。整個設(shè)計分硬件和軟件兩大部分。硬件部分采用MEGA16單片機作為可編程芯片,字符液晶作為信號顯示;軟件部分利用C語言作為設(shè)計語言,對MEGA16進行編程實現(xiàn)各種功能。
硬件設(shè)計電路分解為單片機、晶體振蕩器和數(shù)碼管3個部分,其結(jié)構(gòu)簡單,經(jīng)濟實惠。單片機內(nèi)部晶體振蕩器的外接電路。由兩個電容和晶體振蕩器構(gòu)成,其電路如圖1所示。圖中X1和X2分別接MEGA16的兩個脈沖控制端,使得MEGA16的內(nèi)部脈沖電路為電子時鐘和整個系統(tǒng)時鐘提供脈沖。
圖1所示給出了采用單片機外加電源及晶體振蕩器構(gòu)成最小單片機系統(tǒng)。配合單片機開發(fā)的設(shè)計、調(diào)試和下載,最終將時鐘信息從端口輸出到字符液晶顯示。
圖26位模式與單片機的端口相連。
4軟件設(shè)計及調(diào)試過程
軟件設(shè)計包括Proteus的ISIS軟件、Code Vision AVR編輯軟件和AVRStudio4調(diào)試。利用ISP將生成程序timer.cof 下載到目標板。其主要程序如下:
void display(void)// 6 位LED 數(shù)碼管動態(tài)掃描函數(shù)
{
PORTC = 0xff;
PORTA = led_7[dis_buff[posit]];
if(point_on &&(posit==2||posit==4))PORTA |= 0x80;
PORTC = position[posit];
if(++posit >=6)posit = 0;
}
// Timer 0 比較匹配中斷服務(wù)
interrupt [TIM0_COMP] void timer0_comp_isr(void)
{
display();// 調(diào)用LED 掃描顯示
if(++time_counter>=100)
{
time_counter = 0;
time_1s_ok = 1;
}
}
void time_to_disbuffer(void)// 時鐘時間送顯示緩沖區(qū)函數(shù)
{
char i,j=0;
for(i=0;i<=2;i++)
{
dis_buff[j++] = time[i] % 10;
dis_buff[j++] = time[i] / 10;
}
}
// INT0 中斷服務(wù)程序
interrupt [EXT_INT0] void ext_int0_isr(void)
{
if(++time[2]>=24)time[2] = 0;
}
// INT1 中斷服務(wù)程序
interrupt [EXT_INT1] void ext_int1_isr(void)
{
if(++time[1]>=60)time[1]=0;
}
void main(void)
{
PORTA=0x00;// 顯示控制I/O 端口初始化
DDRA=0xFF;
PORTC=0x3F;
DDRC=0x3F;// T/C0 初始化
PORTA=0xFF;
DDRA=0xFF;
GICR|=0xC0;// 允許INT0、INT1 中斷
MCUCR=0x0A;// INT0、INT1 下降沿觸發(fā)
GIFR=0xC0;// 清除INT0、INT1 中斷標志位
TCCR0=0x0B;// 內(nèi)部時鐘,64 分頻(4M/64=62.5KHz),CTC 模式
TCNT0=0x00;
OCR0=0x7C;// OCR0 = 0x7C(124),(124+1)/62.5=2ms
TIMSK=0x02;// 允許T/C0 比較匹配中斷
time[2] = 14;time[1] = 01;time[0] = 55;// 設(shè)時間初值23:58:5
5posit = 0;
time_to_disbuffer();
#asm(“sei”)// 開放全局中斷
while(1)
{
if(time_1s_ok)// 1 秒到
{
time_1s_ok = 0;
point_on = ~point_on;
if(++time[0] >= 60)// 以下時間調(diào)整
{
time[0] = 0;
if(++time[1] >= 60)
{
time[1] = 0;
if(++time[2] >= 24)time[2] = 0;
}
} time_to_disbuffer();// 新調(diào)整好的時間送顯示緩沖區(qū)
5總結(jié)心得
這次設(shè)計報告培養(yǎng)了學生綜合運用所學知識,發(fā)現(xiàn),提出,分析和解決問題,鍛煉實踐能力的重要環(huán)節(jié),是對學生實際工作能力的具體訓練和考察過程.隨著科學技術(shù)發(fā)展的日新日異,單片機已經(jīng)成為當今計算機應(yīng)用中空前活躍的領(lǐng)域,在生活中可以說得是無處不在。因此作為二十一世紀的大學來說掌握單片機的開發(fā)技術(shù)是十分重要的。
回顧起此次單片機設(shè)計,我仍感慨頗多,的確,從選題到定稿,從理論到仿真,在這些日子里,我學到很多很多的的東西,同時不僅可以鞏固了以前所學過的知識,而且學到了很多在書本上所沒有學到過的知識。通過這次設(shè)計使我懂得了理論與實際相結(jié)合是很重要的,只有理論知識是遠遠不夠的,只有把所學的理論知識與實踐相結(jié)合起來,從理論中得出結(jié)論,才能真正為社會服務(wù),從而提高自己的實際動手能力和獨立思考的能力。在設(shè)計的過程中遇到問題,可以說得是困難重重,這畢竟第一次做的,難免會遇到過各種各樣的問題,同時在設(shè)計的過程中發(fā)現(xiàn)了自己的不足之處,對以前所學過的知識理解得不夠深刻,掌握得不夠牢固,比如說不懂一些元器件的使用方法,對單片機匯編語言掌握得不好……通過這次課程設(shè)計之后,一定把以前所學過的知識重新溫故。
這次設(shè)計終于順利完成了,在設(shè)計中遇到了很多編程問題,最后在老師的辛勤指導下,終于游逆而解。同時,在老師那里我學得到很多實用的知識,在次我表示感謝!同時,對給過我?guī)椭乃型瑢W和各位指導老師再次表示忠心的感謝!
}結(jié)束語
單片機自20世紀70年代問世以來,以其極高的性能價格比,受到人們的重視和關(guān)注,應(yīng)用很廣、發(fā)展很快。單片機體積小、重量輕、抗干擾能力強、環(huán)境要求不高、價格低廉、可靠性高、靈活性好、開發(fā)較為容易。尤其是AVR單片機可以用高級語言編程,極容易地實現(xiàn)系統(tǒng)移植,并且加快了軟件的開發(fā)過程。這次設(shè)計通過對它的學習、應(yīng)用,以Mage16單片機為核心,輔以必要的電路,采用高級C語言編程,設(shè)汁了一個簡易的電子時鐘,由
4.5 V直流電源供電,通過數(shù)碼管能夠準確顯示時間。
第四篇:單片機數(shù)字時鐘課程設(shè)計感想
五.實驗總結(jié)及感想
在實驗的開始幾天,基本上沒有收獲,不知何從下手,不知所措。為了看得更遠,不妨站在前人的肩膀上,我在整體思路模糊的情況下,在網(wǎng)上大量招資糧,各種與電子時鐘相關(guān)的文章,我閱讀了不少。隨著涉獵的點滴積累,我對電子時鐘的設(shè)計方案已經(jīng)慢慢醞釀而成。有了方向和不少知識儲備后,在接下來的幾天,幾乎每天都有突破,雖然有時只是一句程序的修改或誕生,但那種收獲的感覺很暖人心。
實驗中遇到了不少問題,接下來總結(jié)一下,共同探討。
1,按鍵問題。我的設(shè)計中,很多功能選擇是通過按鍵開關(guān)實現(xiàn)的。在仿真中發(fā)現(xiàn),調(diào)整數(shù)值時,有時按鍵反應(yīng)太快,按一次,跳了幾下,使設(shè)置時間,日期很不方便。但是仿真多了之后,找到了按鍵(實際上是按鼠標)的節(jié)奏,對按鍵的掌控力提高了不少,不怎么會出現(xiàn)跳變的情況了。有些開關(guān)我采用了長按鍵的方式來防抖,效果不錯,但是每次都要長按鍵,調(diào)整效率太低,我沒有普及。本來想把所有的按鍵都加延時防抖電路,但仿真中感覺對鍵盤的控制力沒提高多少,有時還是會出問題,這個方案放棄了。索性將板子焊接出來了在調(diào)試軟件吧,仿真畢竟不是那么“真”??!實際電路調(diào)試中,按鍵反應(yīng)沒有出現(xiàn)過于靈敏的問題,基本可控制。
出現(xiàn)以上問題,我認為是電路板上焊接點太多,接觸不是很好,影響了信號的傳輸時間,從而解決了按鍵問題!也有可能是按鍵質(zhì)量問題,接觸不良。
2,P0口開關(guān)問題。P0口比較特殊,它存在高阻態(tài),要使其輸入不是高電平就是低電平,就要接上拉電阻,給其高電平輸入。
3,音樂鬧鈴問題。在鬧鈴時間到,鬧鈴提醒時,我的數(shù)碼管為熄滅狀態(tài),因為開始我的響鈴程序內(nèi),沒有數(shù)碼管掃描顯示程序。但加入數(shù)碼管顯示子程序后,我的鬧鈴音樂被影響了,一開始不知所措,有點懷疑是顯示程序時間過長,影響音樂的定時(節(jié)拍),我就在響鈴程序中加延時模塊,延時長度逐漸提高,最后出現(xiàn)了類似的問題,看來時顯示程序占用時間太長,使音樂每個音符的節(jié)拍出現(xiàn)了紊亂,音樂功能被遏制了!魚和熊掌不能兼得,我只能犧牲顯示來獲得音樂鬧鈴,但為了彌補顯示,我設(shè)計了閃爍提醒方案,就是在手動或音樂自然停止后,進入當前時間閃爍提示,8秒后若不按返回鍵,則自動跳入主程序。
在仿真中,老師提供的響鈴電路不能實現(xiàn)功能,但是在我的電路板中效果很好,令人費解!4,中斷沖突問題,為了實現(xiàn)秒表,我在T0中斷嵌套了秒表相關(guān)進位程序,由于秒表要求精度0.01秒,故我的T0中斷定時為就剛好0.01秒,中斷100次,剛好1秒。秒表確實實現(xiàn)了,但是我的鬧鈴音質(zhì)變差了。一開始以為是鬧鈴程序存太多冗余環(huán)節(jié),影響了T1的音樂輸出中斷,但是檢查程序后,發(fā)現(xiàn)沒什么多余的,裁剪無從下手。
在仿真中,我讓音樂模塊運行,發(fā)現(xiàn)音質(zhì)很好。添加T0中斷服務(wù)程序,但是將中斷進入的間隔變大,即0.05秒進入一次中斷,發(fā)現(xiàn)音質(zhì)有所下降,有滋滋聲,但比原來的好。最后認定應(yīng)該是T0中斷過于頻繁,T1音樂頻率發(fā)生中斷被打破,當單位時間內(nèi)被打破的次數(shù)達到一定程度時,音符和節(jié)拍的對應(yīng)發(fā)生紊亂,最終音質(zhì)變差。
雖然如此,我的焊接的電路板的表現(xiàn)卻很爭氣,鬧鈴音質(zhì)可以接受!雖然這次實際表現(xiàn)不錯,但問題還是有的,還是要解決的,我的方案是把秒表程序放在T1中斷服務(wù)程序,雖然音樂的發(fā)生要用到T1中斷,但是秒表的顯示和鬧鈴音樂的演奏上不會重合在一起,鬧鈴判斷是在主程序,而秒表實現(xiàn)是在秒表子程序,故原本相互矛盾的兩個功能,在T1中斷服務(wù)程序中找到了共同的歸宿,和諧相處。
5,顯示數(shù)字分隔問題。本實驗中用8個共陰極數(shù)碼管顯示日歷及其時間,但是8個數(shù)碼管連在一起,顯示過程中不能有效地區(qū)分時,分,秒和年,月,日,數(shù)碼管是兩兩組合起來,形成某位的十位和個位,故用小數(shù)點在適當位置一直保持高亮狀態(tài),形成分隔符,實現(xiàn)方便的讀取數(shù)據(jù)。具體方法是,將需要小數(shù)點位高亮的數(shù)碼管找出來,在動態(tài)顯示掃描到該數(shù)碼管時,先將提取的字段碼的最高位變?yōu)?,利用語句 ORL A,#10000000B 實現(xiàn),修正字碼后,再將字碼送入P1口顯示數(shù)字,如此問題得以解決。
6,添加倒計時器嘀嘀聲提示功能。這個功能我用到了T1中斷,作為音調(diào)頻率發(fā)生器,但是T1已經(jīng)承擔了音樂鬧鈴的音調(diào)發(fā)生功能,在此通過設(shè)立標志位實現(xiàn)中斷服務(wù)程序的轉(zhuǎn)變。即使我將秒表的實現(xiàn)服務(wù)程序放入T1中斷實現(xiàn),也沒問題,只要選擇標志位判斷就可以了。在此,我們用調(diào)整狀態(tài)指示燈的狀態(tài)來做標志位,具體的說是P0.1口做標志位。
還有一個問題就是如何使鈴聲有間隔的響,這就牽涉到定時,在此我們用硬件定時,即T1中斷的次數(shù)作為定時參數(shù)。我的設(shè)計是音調(diào)響0.25秒,然后用T1延時0.5秒,由于計數(shù)器工作于方式1時,12MHZ時鐘頻率下時,一次中斷最多定時65536*1us=0.065536秒,為了實現(xiàn)0.5秒的響聲間隔,將T1中斷1次定時為0.05秒,中斷10次后,重新裝音調(diào)發(fā)生計數(shù)初值。對于響鈴時間的設(shè)定原理類似,可以有發(fā)聲頻率求出一次發(fā)聲定時中斷的時間,N次發(fā)聲定時中斷后,使時間變化0.25秒,而后轉(zhuǎn)入發(fā)聲間隔定時程序。
設(shè)計體會
以前看別人的一個電子表賣十幾塊錢,心里面有點憤憤不平,現(xiàn)在,自己做過一個電子鐘,才發(fā)現(xiàn),其中的不容易,還有艱辛。其實做其他的事情也是一樣,都會經(jīng)過很多的困難,才能成功。突然想起一句話“不經(jīng)歷風雨,怎么見彩虹”。其實想想,這一個月,也留下了很多美好的回憶。一分耕耘,一分收獲。只有親自用實踐來驗證這句話,在能得其要領(lǐng)。經(jīng)過這次單片機課程設(shè)計,我從一個單片機實踐的門外漢,已經(jīng)越升為略知一二的新手。雖然還有很多有關(guān)單片機的應(yīng)用有待學習,但萬變不離其宗,只要深入了解單片的原理,全部知識點,各個細節(jié),一切設(shè)計皆有可能。還記得那個晚上通宵達旦仿真,不成功,誓不睡覺,很困了,都還在弄著。卻當仿真成功時,沒有一絲睡意,有的只是心中的喜悅通過這次的設(shè)計使我認識到本人對單片機方面的知識知道的太少了,對于書本上的很多知識還不能靈活運用,尤其是對程序設(shè)計語句的理解和運用,不能夠充分理解每個語句的具體含義,導致編程的程序過于復雜,使得需要的存儲空間增大。損耗了過多的內(nèi)存資源。本次的設(shè)計使我從中學到了一些很重要的東西,那就是如何從理論到實踐的轉(zhuǎn)化,怎樣將我所學到的知識運用到我以后的工作中去。只要我們有耐心,夠細心,都可以把它們解決。在大學的課堂的學習只是在給我們灌輸專業(yè)知識,而我們應(yīng)把所學的用到我們現(xiàn)實的生活中去,此次的電子時鐘設(shè)計給我奠定了一個實踐基礎(chǔ),我會在以后的學習、生活中磨練自己,使自己適應(yīng)于以后的競爭,同時在查找資料的過程中我也學到了許多新的知識,在和同學協(xié)作過程中增進同學間的友誼,使我對團隊精神的積極性和重要性有了更加充分的理解。我知道,今后我的路還是很長,我要學的東西也有很多。通過這次實習,我深刻的認識到計算機專業(yè)的路的不平坦,但我會以一種良好的態(tài)度去迎接每一個挫折和挑戰(zhàn)。
第五篇:基于51單片機電子時鐘設(shè)計
基于51單片機的電子時鐘設(shè)計
摘要
本電子時鐘以STC89C52單片機作為主控芯片,采用DS12C887時鐘芯片,使用1602液晶作為顯示輸出。該時鐘走時精確,具有鬧鐘設(shè)置,以及可同時顯示時間、日期等多種功能。本文將詳細介紹該電子時鐘涉及到的一些基本原理,從硬件和軟件兩方面進行分析。
【關(guān)鍵詞】
STC89C52單片機
DS12C887時鐘芯片
1602液晶
蜂鳴器
目錄
一、緒論…………………………………………………………4
1.1 電子時鐘功能…………………………………………1.2設(shè)計方案………………………………………………4
二、硬件設(shè)計……………………………………………………4
2.151
2.2 單片機部分設(shè)計………………………………4
USB供電電路設(shè)計………………………………5
2.3 串行通信電路設(shè)計………………………………6
2.4DS12C887時鐘芯片電路的設(shè)計…………………6
2.51602LCD液晶屏顯示電路設(shè)計………………7
2.6
蜂鳴器電路設(shè)計………………………………8
2.7
按鍵調(diào)整電路設(shè)計…………………………8
三、軟件設(shè)計…………………………………………9
3.1 系統(tǒng)程序流程圖設(shè)計…………………………9
3.2程序設(shè)計……………………………………11
四、心得體會………………………………………………22 參考文獻……………………………………………………23
一、緒
論
1.1電子時鐘功能
(1)在1602液晶上顯示年、月、日、星期、時、分、秒,并且按秒實時更新顯示。(2)具有鬧鈴設(shè)定即到時報警功能,報警響起時按任意鍵可取消報警。
(3)能夠使用實驗板上的按鍵隨時調(diào)節(jié)各個參數(shù),四個有效鍵分別為功能選擇鍵、數(shù)值增大鍵、數(shù)值減小鍵和鬧鐘查看鍵。
(4)每次有鍵按下時,蜂鳴器都以短“滴”聲報警。
(5)利用DS12C887自身掉電可繼續(xù)走時的特性,該時鐘可實現(xiàn)斷電時間不停、再次上電時時間仍準確顯示在液晶上的功能。
1.2設(shè)計方案
DS12C887時鐘芯片+1602LCD液晶屏
DS12C887時鐘芯片功能豐富、價格適中,能夠自動產(chǎn)生世紀、年、月、日、時、分、秒等時間信息,其內(nèi)部含有世紀寄存器,從而利用硬件電路解決“千年”問題。DS12C887中自帶鋰電池,外部掉電時,其內(nèi)部時間信息還能保持10年之久。1602LCD液晶屏可以輸出2行,每行顯示16個字符。1602LCD液晶屏顯示清晰且不會閃爍,由于液晶屏是數(shù)字式的,因此和單片機系統(tǒng)的接口簡單,操作方便。
以STC89C52為主控芯片,DS12C887為時鐘芯片,1602LCD液晶屏作為顯示器。程序控制DS12C887時鐘芯片實現(xiàn)小時、分、秒和年、月、日的計時,并在1602LCD液晶屏上顯示出來。當時間走到程序所設(shè)定的時間時,蜂鳴器響起,起到鬧鐘功能。
二、硬
件
設(shè)
計
2.1 51單片機部分設(shè)計
單片機部分如圖2—1所示:
以STC89C52單片機為核心,選用12MHZ的晶振,由于晶振的頻率越高,單片機的運行速度就越快,考慮到單片機的運行速度快會導致對存儲器的要求就會變高,因此12MHZ為最佳選擇。外接電容的值雖然沒有嚴格的要求,但是外接電容的大小會影響振蕩器的頻率高低、振蕩器的穩(wěn)定性和起振的快速性,因此選用30pF的電容作為起振電容。復位電路為按鍵高電平復位,當按鍵按下,RES端為高電平,當高電平持續(xù)4us的時間單片機即復位。
2.2 USB供電電路設(shè)計
USB供電電路如下圖2—2所示:
該電子時鐘采用USB端口的方式為單片機供電,LPOW1為電源顯示燈,當按鍵S5按下,電源顯示燈LPOW1亮,表示給單片機供+5V電。
2.3 串行通信電路設(shè)計
串行通信電路如下圖2—3所示:
圖中通過MAX232進行RS—232電平與單片機TTL電平之間的轉(zhuǎn)換,從而為單片機和上位機之間通信提供通道。通信電路的目的就是讓通信雙方的電平匹配,單片機用的是TTL電平,上位機的串口用的是RS—232電平。TTL電平邏輯1的電壓范圍是+3.3V到+5V,邏輯0的電壓范圍是0到+3.3V;RS—232電平的邏輯1的電壓范圍是—15V到—5V,邏輯0的電壓范圍是+5V到+15V。MAX232可以把輸入的+5V電源電壓變換成為RS—232輸出電平所需的+10V電壓。所以采用此芯片接口的串行通信系統(tǒng)只需單一的+5V電源就可以了。對于沒有+12V電源的場合,其適應(yīng)性更強,2.4 DS12C887時鐘芯片電路的設(shè)計
時鐘芯片電路如下圖2—4所示:
DS12C887時鐘芯片共需要13條信號線,分別是并行數(shù)據(jù)地址復用線AD0~AD7,CS,AS,R/W,DS和IRQ。
MOT—總線操作時序選擇端。它有兩種工作模式,當MOT接
VCC時,選用Motorola模式;當MOT接GND或懸空時,選用Intel模式。NC—空引腳。
AD0~AD7—復用地址數(shù)據(jù)總線。在總線周期的前半部分,出現(xiàn)在AD0~AD7上的是地址信息,可用以選通DS12C887內(nèi)的RAM,總線周期的后半部分出現(xiàn)在AD0~AD7上的是數(shù)據(jù)信息。GND,VCC—系統(tǒng)電源接入端。當
VCC輸入為+5V時,用戶可以訪問DS12C887內(nèi)RAM的輸入小于+4.25V時,禁止用戶對內(nèi)部RAM中的數(shù)據(jù),并可對其進行讀/寫操作;當
VCC進行讀/寫操作,此時用戶不能正確芯片內(nèi)的時間信息;當
VCC的輸入小于+3V時,DS12C887會自動的將電源切換到內(nèi)部自帶的鋰電池上,以保證內(nèi)部的電路能正常工作。
CS—芯片片選端。
AS—地址選通輸入端。在進行讀/寫操作時,AS的上升沿將AD0~AD7上出現(xiàn)的地址信息鎖存到DS12C887上,而下一個下降沿清除AD0~AD7上的地址信息,不論CS是否有效,DS12C887都將執(zhí)行該操作。
R/W—讀/寫輸入端。該引接腳有兩種工作模式,當MOT接
VCC時,R/W工作在Motorola模式。此時該引腳的作用是區(qū)分讀操作還是寫操作,R/W高電平時為讀操作,R/W為低電平時為寫操作;當MOT接GND時,該引腳工作在Intel模式,此時該引腳為寫允許輸入,此信號的上升沿鎖存數(shù)據(jù)。
DS—數(shù)據(jù)選擇或讀輸入腳。該引腳有兩種工作模式,當MOT接
VCC時,選用Motorola模式,此時,每個總線周期后一部分的DS為高電平,稱為數(shù)據(jù)選通。在讀操作中,DS的上升沿使DS12C887將內(nèi)部數(shù)據(jù)送往總線AD0~AD7上,以供外部讀取。在寫操作中,DS的下降沿將使總線AD0~AD7上的數(shù)據(jù)鎖存在DS12C887中。當MOT接GND時,選用Intel模式,此時該引腳是讀允許輸入引腳。
RESET—芯片復位引腳。
IRQ—中斷請求輸出。用作處理器的中斷申請輸入。只要引起中斷的狀態(tài)位置位,并且相應(yīng)中斷使能位也置位,IRQ將一直保持低電平,處理器程序通常讀取C存儲器來清除IRQ引腳輸出,RESET引腳也會清除未處理的中斷。沒有中斷發(fā)生時,IRQ為高阻狀態(tài),可將多個中斷器件接到一條IRQ總線上,只要它們均為漏極開路輸出即可。IRQ引腳為漏極開路輸出,需要使用一個外接上拉電阻與SQW—方波輸出引腳。當供電電壓
VCC相連。
VCC大于4.25V時,SQW引腳可輸出方波。
2.5 1602LCD液晶屏顯示電路設(shè)計
1602LCD液晶屏顯示電路如下圖2—5所示:
1602液晶為5V電壓驅(qū)動,帶背光,可顯示2行,每行16個字符,不能顯示漢字,內(nèi)置含128個字符的ASCII字符集字庫,只有并行接口,無串行接口。接口說明如下:(1)液晶1,2端為電源;15,16為背光電源;為防止直接加5V電壓燒壞背光燈,在15腳串接一個1K?電阻用于限流。
(2)液晶3端為液晶對比度調(diào)節(jié)端,通過一個10K?電位器接地來調(diào)節(jié)液晶顯示對比度。首次使用時,在液晶上電狀態(tài)下,調(diào)節(jié)至液晶上面一行顯示出黑色小格為止。
(3)液晶4端為向液晶控制器寫數(shù)據(jù)/寫命令選擇端,接單片機的P3.5口。
(4)液晶5端為讀/寫選擇端,因為我們不從液晶讀取任何數(shù)據(jù),只向其寫入命令和顯示數(shù)據(jù),因此此端始終選擇為寫狀態(tài),即低電平接地。
(5)液晶6端為使能信號,是操作時必須的信號,接單片機的P3.4口。
2.6 蜂鳴器電路設(shè)計
蜂鳴器電路如下圖2—6所示:
蜂鳴器電路接在單片機的P2.3引腳上,當該引腳一個低電平,三極管導通,蜂鳴器發(fā)出聲音作為鬧鈴。
2.7 按鍵調(diào)整電路設(shè)計
按鍵調(diào)整電路如下圖2—7所示:
四個獨立鍵盤均采用查詢方式,將按鍵的一端接地,另一端各接一根輸入線直接與STC89C52的I/O口相連。當按鍵閉合時,相當于該I/O口通過按鍵與地相連,變成低電平,單片機通過檢測I/O口的電平狀態(tài),即可識別出按下的鍵。通過四個鍵實現(xiàn)參數(shù)的調(diào)節(jié),S1為功能選擇鍵,S2為數(shù)值增大鍵,S3為數(shù)值減小鍵,S4為鬧鐘查看鍵。
三、軟
件
設(shè)
計
3.1 系統(tǒng)程序流程圖設(shè)計
流程圖1:實驗主程序流程圖
流程圖2:定時中斷程序流程圖
流程圖3:調(diào)時功能流程圖
3.2 程序設(shè)計
#include
//延時函數(shù) {
uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);} void di()
//蜂鳴器報警聲音 {
beep=0;
delay(100);
beep=1;} void
write_com(uchar com)
//寫液晶命令函數(shù)
{
rs=0;
lcden=0;
P0=com;
delay(3);
lcden=1;
delay(3);
lcden=0;} void write_data(uchar
data)
//寫液晶數(shù)據(jù)函數(shù) {
rs=1;
lcden=0;
P0=data;
delay(3);
lcden=1;
delay(3);
lcden=0;} void
init()
//初始化函數(shù) {
uchar
num;
EA=1;
//打開總中斷
EX1=1;
//開外部中斷1
IT1=1;
//設(shè)置負跳變沿觸發(fā)中斷
flag1=0;
//變量初始化
t0_num=0;
s1num=0;
week=1;
dula=0;
//關(guān)閉數(shù)碼管顯示
wela=0;
lcden=0;
rd=0;/*以下幾行在首次設(shè)置DS12C887時使用,以后不必再寫入
write_ds(0x0A,0x20);
//打開振蕩器
write_ds(0x0B,0x26);
//設(shè)置24小時模式,數(shù)據(jù)二進制格式,開啟鬧鈴中斷
set_time();
//設(shè)置上電默認時間
---------------*/
write_com(0x38);
//1602液晶初始化
write_com(0x0c);
write_com(0x06);
write_com(0x01);
write_com(0x80);
for(num=0;num<15;num++)
//寫入液晶固定部分顯示
{
write_data(table[num]);
delay(1);}
write_com(0x80+0x40);
for(num=0;num<11;num++)
{
write_data(table1[num]);
delay(1);
} } void write_sfm(uchar add,char data)
{ //1602液晶刷新時分秒函數(shù),4為時,7為分,10為秒
char
shi,ge;
shi=data/10;
ge=data%10;
write_com(0x80+0x40+add);
write_data(0x30+shi);
write_data(0x30+ge);} void
write_nyr(uchar add,char
data)
{
//1602液晶刷新年月日函數(shù),3為年,6為月,9為日
char
shi,ge;
shi=data/10;
ge=data%10;
write_com(0x80+add);
write_data(0x30+shi);
write_data(0x30+ge);void
write_week(char we)
//寫液晶星期顯示函數(shù) {
write_com(0x80+12);
switch(we)
{
case 1:
write_data('M');delay(5);
write_data('O');delay(5);
write_data('N');
break;
case 2:
write_data('T');delay(5);
write_data('U');delay(5);
write_data('E');
break;
case 3:
write_data('W');delay(5);
write_data('E');delay(5);
write_data('D');
break;
case 4:
write_data('T');delay(5);
write_data('H');delay(5);
write_data('U');
break;
case 5:
write_data('F');delay(5);
write_data('R');delay(5);
write_data('I');
break;
case 6:
write_data('S');delay(5);
write_data('A');delay(5);
write_data('T');
break;
case 7:
write_data('S');delay(5);
write_data('U');delay(5);
write_data('N');
break;
} } void keyscan(){ if(flag_ri==1){
//這里用來取消鬧鐘報警,按任意鍵取消報警
if((s1==0)||(s2==0)||(s3==0)||(s4==0))
{
delay(5);
if((s1==0)||(s2==0)||(s3==0)||(s4==0))
{
while(!(s1&&s2&&s3&s&s4));di();
flag_ri=0;
//清除報警標志
}
}
}
if(s1==0)
//檢測s1
{
delay(5);
if(s1==0)
{
s1num++;
//記錄按下次數(shù)
if(flag1==1)
if(s1num==4)
s1num=1;
flag=1;
while(!s1);di();
switch(s1num)
{
//光標閃爍點定位
case 1: write_com(0x80+0x40+10);
write_com(0x0f);
break;
case 2: write_com(0x80+0x40+7);
break;
case 3: write_com(0x80+0x40+4);
break;
case 4: write_com(0x80+12);
break;
case 5: write_com(0x80+9);
break;
case 6: write_com(0x80+6);
break;
case 7: write_com(0x80+3);
break;
case 8: s1num=0;
write_com(0x0c);
flag=0;
write_ds(0,miao);
write_de(2,fen);
write_ds(4,shi);
write_ds(6,week);
write_ds(7,day);
write_ds(8,month);
write_ds(9,year);
break;
}
}
}
if(s1num!=0)
//只有當s1按下后,才檢測s2和s3
{
if(s2==0)
{
delay(1);
if(s2==0)
while(!s2);di();
switch(s1num)
{
//根據(jù)功能鍵次數(shù)調(diào)節(jié)相應(yīng)數(shù)值
case 1: miao++;
if(miao==60)
miao=0;
write_sfm(10,miao);
write_com(0x80+0x40+10);
break;
case 2: fen++;
if(fen==60)
fen=0;
write_sfm(7,fen);
write_com(0x80+0x40+7);
break;
case 3: shi++;
case 4:
case 5:
case 6:
case 7:
}
}
}
if(s3==0)
{
delay(1);
if(shi==24)
shi=0;
write_sfm(4,shi);
write_com(0x80+0x40+4);
break;week++;
if(week==8)
week=1;
write_week(week);
write_com(0x80+12);
break;day++;
if(day==32)
day=1;
write_nyr(9,day);
write_com(0x80+9);
break;month++;
if(month==13)
month=1;
write_nyr(6,month);
write_com(0x80+6);
break;year++;
if(year==100)
year=0;
write_nyr(3,year);
write_com(0x80+3);
break;
if(s3==0)
{
while(!s3);di();
switch(s1num)
{
//根據(jù)功能鍵次數(shù)調(diào)節(jié)相應(yīng)數(shù)值
case 1: miao--;
if(miao==-1)
miao=59;
write_sfm(10,miao);
write_com(0x80+0x40+10);
break;
case 2: fen--;
if(fen==-1)
fen=59;
write_sfm(7,fen);
write_com(0x80+0x40+7);
break;
case 3: shi--;
if(shi==-1)
shi=23;
write_sfm(4,shi);
write_com(0x80+0x40+4);
break;
case 4: week--;
if(week==0)
week=7;
write_week(week);
write_com(0x80+12);
break;
case 5: day--;
if(day==0)
day=31;
write_nyr(9,day);
write_com(0x80+9);
break;
case 6: month--;
if(month==0)
month=12;
write_nyr(6,month);
write_com(0x80+6);
break;
case 7: year--;
if(year==-1)
year=99;
write_nyr(3,year);
write_com(0x80+3);
break;
}
}
}
}
if(s4==0)
//檢測s4
{
delay(5);
if(s4==0)
{
flag1=~flag1;
while(!s4);di();
if(flag1==0)
{
//退出鬧鐘設(shè)置時保存數(shù)值
flag=0;
write_com(0x80+0x40);
write_data(' ');
write_data(' ');
write_com(0x0c);
write_ds(1,miao);
write_ds(3,fen);
write_ds(5,shi);
}
else
{
//進入鬧鐘設(shè)置
read_alarm();
//讀取原始數(shù)據(jù)
miao=amiao;
//重新賦值用以按鍵調(diào)節(jié)
fen=afen;
shi=ashi;
write_com(0x80+0x40);
write_data('R');
//顯示標志
write_data('i');
write_com(0x80+0x40+3);
write_sfm(4,ashi);
//送液晶顯示鬧鐘時間
write_sfm(7,afen);
write_sfm(10,amiao);
}
}
} } void write_ds(uchar add,uchar
data){
//寫12C887函數(shù)
dscs=0;
dsas=1;
dsds=1;
dsrw=1;
P0=add;
//先寫地址
dsas=0;
dsrw=0;
P0=data;
//再寫數(shù)據(jù)
dsrw=1;
dsas=1;
dscs=1;} uchar
read_ds(uchar add){
//讀12C887函數(shù)
uchar
ds_data;
dsas=1;
dsds=1;
dsrw=1;
dscs=0;
P0=add;
//先寫地址
dsas=0;
dsds=0;
P0=0xff;
ds_data=P0;
//再讀數(shù)據(jù)
dsds=1;
dsas=1;
dscs=1;
return ds_data;} /*---首次操作12C887時給予寄存器初始化-----void set_time(){
//首次上電初始化時間函數(shù)
write_ds(0,0);
write_ds(1,0);
write_ds(2,0);
write_ds(3,0);
write_ds(4,0);
write_ds(5,0);
write_ds(6,0);
write_ds(7,0);
write_ds(8,0);
write_ds(9,0);}----------------------*/
void
read-alarm(){
//讀取12C887鬧鐘值
amiao=read_ds(1);
afen=read_ds(3);
ashi=read_ds(5);} void main()
//主函數(shù) {
init();
//調(diào)用初始化函數(shù)
while(1)
{
keyscan();
//按鍵掃描
if(flag_ri==1)
//當鬧鐘中斷時進入這里
{
di();
delay(100);
di();
delay(500);
}
if(flag==0&&flag1==0)
//正常工作時進入這里
{
keyscan();
//按鍵掃描
year=read_ds(9);
//讀取12C887數(shù)據(jù)
month=read_ds(8);
day=read_ds(7);
week=read_ds(6);
shi=read_ds(4);
fen=read_ds(2);
miao=read_ds(0);
write_sfm(10,miao);
//送液晶顯示
write_sfm(7,fen);
write_sfm(4,shi);
write_week(week);
write_nyr(3,year);
write_nyr(6,month);
write_nyr(9,day);
}
} } void
exter()interrupt 2
//外部中斷1服務(wù)程序 {
uchar
c;
//進入中斷表示鬧鐘時間到
flag_ri=1;
//設(shè)置標志位,用于大程序中報警提示
c=read_ds(0x0c);
//讀取12C887的C寄存器表示響應(yīng)了中斷 }
_______________________________________________________________________________ 以下為define.h源代碼:
_______________________________________________________________________________ #define uchar unsigned char #define uint unsigned int sbit dula=P2^6;sbit wela=P2^7;sbit rs=P3^5;sbit lcden=P3^4;sbit s1=P3^0;
//功能鍵 sbit s2=P3^1;
//增大鍵 sbit s3=P3^2;
//減小鍵 sbit s4=P3^6;
//鬧鐘查看鍵 sbit rd=P3^7;sbit beep=P2^3;
//蜂鳴器 sbit dscs=P1^4;sbit dsas=P1^5;sbit dsrw=P1^6;sbit dsds=P1^7;sbit dsirq=P3^3;bit flag1,flag_ri;
//定義兩個位變量
uchar count,s1num,flag,t0_num;
//其他變量定義 char miao,shi,fen,year,month,day,week,amiao,afen,ashi;uchar code
table[]=“201-
”;
//液晶固定顯示內(nèi)容 uchar code
table1[]=“
:
:
”;
void write_ds(uchar,uchar);
//函數(shù)申明 void set_alarm(uchar,uchar,uchar);void read_alarm();uchar read_ds(uchar);void set_time();
四、心
得
體
會
在本次電子時鐘設(shè)計中對單片機的內(nèi)部結(jié)構(gòu)有了一定的了解,熟悉了各個引腳的功能,同時熟知了1602LCD液晶、DS12C887時鐘芯片的使用,以及各種電路的功能。
通過此次課程設(shè)計,無論是從軟件方面還是硬件方面,都進一步學習和鞏固了程序的總體設(shè)計和單片機的應(yīng)用。在軟件方面,進一步熟悉了各條指令的功能及用法,定時、中斷的用法,更深一步學習了用C語言編寫實現(xiàn)電子時鐘的功能。在硬件方面,進一步熟悉并使用了keil軟件,在keil中編程,調(diào)試,運行;對電路的一些基本結(jié)構(gòu)和設(shè)計有了更深一步的了解。在整個設(shè)計過程中,雖然出現(xiàn)了很多問題,有時確實叫人很心煩,但在發(fā)現(xiàn)問題后努力去解決,并獲得成功,這時會感到無比的快樂和具有成就感。只有自己動手去做,去應(yīng)用,才能將學到的知識變成自己的。
程序不要光看不寫,一定要自己寫一次。最開始的時候,可能自己啥都不懂,這時可以抄人家的程序過來。但在抄的時候一定要看看每一句是干什么用的,來達到什么目的,運行后有什么后果,看明白了之后,就要自己寫一次。此時會發(fā)現(xiàn),原來看明白別人的程序很容易,但到自己寫的時候卻一句也寫不出來,這就是差距。
單片機提高重在實踐,想要學好單片機,軟件編程必不可少。但是熟悉硬件對于學好單片機也是非常重要的。如何學習好硬件,動手實踐是必不可少的。我們可以通過自己動手做一個自己的電子制作,通過完成它,以提高對一些芯片的了解和熟練運用。這樣我們就可以多了解一些芯片的結(jié)構(gòu)。
我學習的目標是希望在若干年以后能夠獨立設(shè)計一個復雜的系統(tǒng),包括硬件電路和軟件部分??傊ㄟ^這次電子技術(shù)設(shè)計我學到了許多,似乎離自己的目標又近了一步。
參
考
文
獻
[1]郭天祥.51單片機C語言教程.電子工業(yè)出版社.2009 [2]譚浩強.C程序設(shè)計.清華大學出版社.1991 [3]孫育才 王榮興
孫華芳.ATMEL新型AT89S52系列單片機及其應(yīng)用.清華大學出版社.2006 [4]謝維成.單片機原理及應(yīng)用與51程序設(shè)計.清華大學出版社.2006
[5]鮑宏亞.MCS—51系列單片機應(yīng)用系統(tǒng)設(shè)計及實用技術(shù).中國宇航出版社.2005 [6]趙文博
劉文濤.單片機語言C51程序設(shè)計.人民郵電出版社.2006 [7]求是科技.8051系列單片機C程序設(shè)計.人民郵電出版社.2006