一, 實驗目的
1. 學習8051定時器時間計時處理、按鍵掃描及LED數碼管顯示的設計方法。
2. 設計任務及要求 利用實驗平臺上4個LED數碼管, 設計帶有鬧鈴功能的數字時鐘
二,實驗要求
A.基本要求:
1. 在4位數碼管上顯示當前時間。顯示格式“時時分分”
2. 由LED閃動做秒顯示。
3. 利用按鍵可對時間及鬧玲進行設置,并可顯示鬧玲時間。當鬧玲時間到蜂鳴器發出聲響,按停止鍵使可使鬧玲聲停止。
4.實現秒表功能(百分之一秒顯示)
B.擴展部分:
1.日歷功能(能對年,月,日,星期進行顯示,分辨平年,閏年以及各月天數,并調整)
2.音樂鬧鈴(鈴音可選擇,鬧鈴被停止后,閃爍顯示當前時刻8秒后,或按鍵跳入正常時間顯示狀態)
3.定時功能(設定一段時間長度,定時到后,閃爍提示)
4.倒計時功能(設定一段時間長度,能實現倒計時顯示,時間長減到0時,閃爍提示)
5.鬧鈴重響功能(鬧鈴被停止后,以停止時刻開始,一段時間后鬧鈴重響,且重響時間的間隔可調)
三,實驗基本原理
利用單片機定時器完成計時功能,定時器0計時中斷程序每隔0.01s中斷一次并當作一個計數,設定定時1秒的中斷計數初值為100,每中斷一次中斷計數初值減1,當減到0時,則表示1s到了,秒變量加1,同理再判斷是否1min鐘到了,再判斷是否1h到了。
為了將時間在LED數碼管上顯示,可采用靜態顯示法和動態顯示法,由于靜態顯示法需要譯碼器,數據鎖存器等較多硬件,可采用動態顯示法實現LED顯示,通過對每位數碼管的依次掃描,使對應數碼管亮,同時向該數碼管送對應的字碼,使其顯示數字。由于數碼管掃描周期很短,由于人眼的視覺暫留效應,使數碼管看起來總是亮的,從而實現了各種顯示。
四,實驗設計分析
針對要實現的功能,采用AT89S51單片機進行設計,AT89S51 單片機是一款低功耗,高性能CMOS8位單片機,片內含4KB在線可編程(ISP)的可反復擦寫1000次的Flash只讀程序存儲器,器件采用高密度、非易失性存儲技術制造,兼容標準MCS- 51指令系統及80C51引腳結構。這樣,既能做到經濟合理又能實現預期的功能。
在程序方面,采用分塊設計的方法,這樣既減小了編程難度、使程序易于理解,又能便于添加各項功能。程序可分為鬧鐘的聲音程序、時間顯示程序、日期顯示程序,秒表顯示程序,時間調整程序、鬧鐘調整程序、定時調整程序,延時程序等。運用這種方法,關鍵在于各模塊的兼容和配合,若各模塊不匹配會出現意想不到的錯誤。
首先,在編程之前必須了解硬件結構尤其是各引腳的用法,以及內部寄存器、存儲單元的用法,否則,編程無從下手,電路也無法設計。這是前期準備工作。第二部分是硬件部分:依據想要的功能分塊設計設計,比如輸入需要開關電路,輸出需要顯示驅動電路和數碼管電路等。第三部分是軟件部分:先學習理解匯編語言的編程方法再根據設計的硬件電路進行分塊的編程調試,最終完成程序設計。第四部分是軟件畫圖部分:設計好電路后進行畫圖,包括電路圖和仿真圖的繪制。第五部分是軟件仿真部分:軟硬件設計好后將軟件載入芯片中進行仿真,仿真無法完成時檢查軟件程序和硬件電路并進行修改直到仿真成功。第六部分是硬件實現部分:連接電路并導入程序檢查電路,若與設計的完全一樣一般能實現想要的功能。最后進行功能擴展,在已經正確的設計基礎上,添加額外的功能!
五,實驗要求實現
A.電路設計
1. 整體設計
此次設計主要是應用單片機來設計電子時鐘,硬件部分主要分以下電路模塊:顯示電路用8個共陰數碼管分別顯示,星期(年份),小時、分鐘(月份)和秒(日),通過動態掃描進行顯示,從而避免了譯碼器的使用,同時節約了I/0端口,使電路更加簡單。單片機采用AT89S51系列,這種單片機應用簡單,適合電子鐘設計。
電路的總體設計框架如下:
2. 分塊設計
模塊電路主要分為:輸入部分、輸出部分、復位和晶振電路。
2.1 輸入部分
輸入信號主要是各種模式選擇和調整信號,由按鍵開關提供。
以下為輸入部分樣例:
在本實驗中主要用用P3口輸入按鍵信號,還用到了特殊的P0口。對于P0口,由于其存在高阻狀態,為了實現開關功能,給其添加上拉電阻,具體如下圖所示:
2.2 輸出部分
本電路的輸出信號為7段數碼管的位選和段選信號,鬧鈴脈沖信號,提示燈信號。
本實驗的數碼管是共陰的,為了防止段選信號不能驅動數碼管,故在P1口連接上拉電阻后,再送段選信號,以提高驅動,位選信號直接從P2口接入,如下圖:
鬧鈴由P2.6端輸出,模塊如下:
2.3 晶振與復位電路
本實驗單片機時鐘用內部時鐘,模塊如下:
復位電路為手動復位構成,模塊如下:
各模塊拼接組合,電路總體設計圖如下:
B.程序設計
B.1 程序總體設計
本實驗用匯編程序完成.
程序總的流程圖如下:
NO
YES
結合電路圖,程序設計的整體思路為:
接通電源,數碼管顯示星期數,時,分,秒。并且走時顯示LED燈每隔1秒改變一次明暗,此為正常工作模式。以下為在該工作方式下模式選擇的按鍵方式:
1. 按1鍵——日期模式。顯示年月日且可調整,調整狀態指示燈亮。
日期調整對應鍵如下:
6鍵——年(千位,百位),按一次該位加1
5鍵——年(十位,個位),按一次該位加1
4鍵——月,按一次該位加1
3鍵——日,按一次該位加1
0鍵——調整狀態指示燈滅,返回主程序,顯示時間
2. 按2鍵——調時模式。顯示時分秒且可調整,調整狀態指示燈亮。
時間調整對應鍵如下:
6鍵——時,按一次該位加1
5鍵——分,按一次該位加1
4鍵——秒,按一次該位清0
0鍵——調整狀態指示燈滅,返回主程序,顯示時間
3. 按3鍵——鬧鈴調整模式。顯示鬧鈴時刻且可調整,調整狀態指示燈亮。
鬧鈴調整對應鍵如下:
5鍵——時,按一次該位加1
4鍵——分,按一次該位加1
0鍵——調整狀態指示燈滅,返回主程序,顯示時間
4. 長按4鍵——定時調整(倒計時)模式。顯示定時長度且可調整,調整狀態顯示燈亮。
定時調整對應鍵如下:
6鍵——分,按一次該位加1
5鍵——秒,按一次該位加1
4鍵——開啟定時功能,并顯示倒計時
0鍵——調整狀態指示燈滅,返回主程序,顯示時間
5. 按5鍵鈴聲測試,揚聲器播放音樂。
6. 按下7鍵,進入秒表模式,顯示秒表走時。
撥上7鍵,秒表暫停;按下7鍵,秒表又繼續走時。
按下8鍵,秒表清零。
0鍵——調整狀態指示燈滅,返回主程序,顯示時間
7. 按下8鍵,數碼管熄滅,時鐘仍在走時,進入節能模式。
撥上8鍵,數碼管亮,恢復普通工作模式。
8. 9鍵為鬧鈴啟動(停止)鍵,按下可以選擇是否要鬧鈴,以及在鬧鈴響起時,按此鍵可以停止鬧鈴。
9. 10鍵為鈴聲選擇開關,按下與否,可以選擇兩手音樂。
10. 11鍵為鬧鈴重響控制開關,重響功能開啟時,從鬧鈴隨音樂結束而結束的時刻開始,或從手動按9鍵停止鬧鈴的時刻開始定時,一段時間后鬧鈴重響。
11. 12鍵為鬧鈴重響間隔選擇開關,可選兩個定時長度,以便在鬧鈴重響功能開啟時,鬧鈴初次響后,過一段時間鬧鈴繼續響。
B.2 程序主要模塊
B.2.1 延時模塊
數碼管顯示動態掃描時,用到延時程序,這里使用延遲1ms的程序,此程序需要反復調用程序如下:
D_1MS:
MOV R7,#2
D_5:
MOV R2,#250
DJNZ R2,$
DJNZ R7,D_5
RET
除數碼管動態掃描外,數碼管的閃爍提示,以及音樂模塊也用到了延時,只是延時的長短不同罷了,在此不再贅述。
B.2.2中斷服務程序
本實驗中,計數器T0,T1中斷都有運用,其中T0中斷為時鐘定時所用,T1中斷用于音樂播放。T0的定時長度為0.01s,工作于方式1,計數1次,時長1us,故計數器計數10000次,進入中斷,計數初值為65536-10000=55536=#0D8F0,裝滿定時器需要0.01s的時間,從而100次中斷為一秒,一秒之后,判斷是否到60秒,若不到則秒加一,然后返回,若到,則秒賦值為0,分加一,依次類推。包括日期顯示的功能也是如此。另外,由于要實現倒計時功能,因此在中斷程序中還要加入減一的寄存器,需要時將其進行顯示。基于以上考慮,以R3為倒計時中的秒,R4為倒計時的分,當秒加1時R3減一,減到0之后,秒賦值為59,分減一,直到分為0。
以下為定時中斷流程圖:
NO
YES
YES
NO
計數器T1工作于方式1, 當調用響鈴程序時,其計數功能開啟,為音樂音調不同頻率的方波的形成,提供延時。其中斷服務程序就是根據音調改變音樂方波輸出口電平的高低,用語句 CPL實現。
中斷服務程序中日歷的實現較為復雜,要考慮平年,閏年,特殊的2月,每月的天數的不盡相同。具體的邏輯判斷方法為:首先,要考慮年份是不是閏年,閏年的判斷方法是:將年份除以100,若能整除,則將年份除以400,若還能整除,則為閏年,若不能,則為平年;若不能被100整除,則判斷是否能被4整除,若能,則為閏年,若不能則為平年。只有2月與平、閏年相關,因此在閏年和平年的子程序中,要判斷是不是2月,若是則在相應的年中進行日期的增加,若不是則轉入平時的月份。其中1、3、5、7、8、10、12月是每月31天,4、6、9、11月為每月30天。
日歷進位判斷流程圖如下:
本實驗用8個數碼管,剛好能顯示年,月,日,掃描顯示與時間的掃描顯示類似。年比較特殊,由兩個寄存器存儲,個位,十位為0時,表明年數能被100整除,若此時千位,百位
組成兩位數能被4整除,則年數被400整除,為閏年。若十位,個位組成兩位數能被4整除,則年數能被4整除,為閏年。
B.2.3主程序
主程序主要對按鍵進行掃描,以及判斷定時和鬧鈴時間是否已到,若到則調用相關程序,該段程序如下:
MAIN:
JNB P3.0,DATETZ ;按下0鍵,顯示日期并可對日期進行調整
JNB P3.1,ZSTZ1 ;按下1鍵,顯示時間,并可調時
JNB P3.2,NLTZZ ;按下2鍵,進行鬧鈴設置
JNB P3.3,DSTZ ;按下3鍵,進行定時設置
JNB P3.4,CESHI ;鬧鈴測試
JNB P3.6,STOPWATCHTZ ;按下6鍵,進入秒表方式
ACALL DISP ;調用時鐘顯示子程序
JNB P0.6,RERING ;判斷是否開啟鬧鈴重響功能
RE: JNB P2.7,DSPDKQ ;判斷是否開啟鬧鈴功能,沒開則去判斷定時
FMQPD: ;判斷定時值R4,R3是否到零、鬧鈴時刻是否已到
MOV A,HOUR;
SUBB A,38H;
JZ FEN ;判斷小時數是否到鬧鈴所定時間,若到,則對分進行判斷;若不到,則對定時進行判斷
AJMP DSPDKQ
FEN:
MOV A,MINUTE;
SUBB A,37H;
JZ MIAO ;判斷分是否到鬧鈴所定時間,若到,則對秒進行判斷;若不到,則對定時進行判斷
AJMP DSPDKQ
MIAO:
MOV A,SECOND
SUBB A,#0
JZ SHENGYIN1 ;判斷秒是否到鬧鈴所定時間,若到,則時,分,秒都到達鬧鈴時刻,進入響鈴子程序;若不到則判斷定時
AJMP DSPDKQ
RERING: ;鬧鈴重響判斷程序
JNB F0, RE ;標志位F0為0,不進行鬧鈴重響設定
CPL F0
MOV 3CH,#1 ;定時判斷標志位賦1, 定時判斷功能開啟
JNB P0.7,M1 ;鬧鈴重響間隔時間選取
MOV R4,#0 ;鬧鈴重響間隔30秒
MOV R3,#30
AJMP MAIN
M1: ;鬧鈴重響間隔60秒
MOV R4,#1
MOV R3,#0
AJMP MAIN
DSPDKQ: ;判斷是否應該進行定時判斷
MOV A,3CH ;3CH是引入的判斷因子,當其為0時,不對定時時間是否到0進行判斷
JNZ DSPD2 ;當3CH不是0時,跳轉到定時判斷程序
AJMP MAIN
DSPD2:
MOV A,R4;
JZ S_PD ;R4所存定時分數為0,則轉而判斷R3所存定時秒數
AJMP MAIN;
S_PD:
MOV A,R3;
JNZ MAIN ;R4,R3所存參數減為0, 定時長度已到
JNB P0.6,SHENGYIN2 ;鬧鈴重響功能開啟時,跳入響鈴程序
AJMP TISHI ;不是鬧鈴重響定時,則定時時間到時,跳入提示程序
AJMP MAIN
CESHI:
ACALL RING
AJMP MAIN
SHENGYIN1: ;調用響鈴子程序
LCALL RING
AJMP MAIN
SHENGYIN2:
SETB F0 ;鬧鈴重響標志位設定
LCALL RING ;響鈴
CLR F0 ;標志位復位
AJMP MAIN
NLTZZ:
AJMP NLTZ1 ;跳入鬧鈴調整程序
DSTZ:
AJMP DSTZ1 ;跳入定時調整程序
DATETZ:
AJMP DATETZ1 ;跳入日期調整程序
STOPWATCHTZ:
AJMP STOPWATCHTZ1 ;跳入秒表程序
B.2.4 顯示子程序
8個數碼管輪流進行顯示,分別顯示1ms,依賴人的視覺 暫留效應,給人以數碼管持續高亮的錯覺。該段程序如下:
DISP: ;時間顯示子程序
JNB P3.7,OUT1 ;判斷節能開關7是否按下,按下則數碼管不顯示,延長其壽命
MOV DPTR,#LEDTAB
MOV A,SECOND ;顯示當前時間秒位
MOV B,#10
DIV AB ;A存十位,B存個位
MOVC A,@A+DPTR
MOV P1,A
CLR SEC_S
ACALL D_1MS ;顯示當前時間秒十位
SETB SEC_S
MOV A,B
MOVC A,@A+DPTR
MOV P1,A
CLR SEC_G
ACALL D_1MS ;顯示當前時間秒個位
SETB SEC_G
MOV A,MINUTE ;顯示當前時間分位
MOV B,#10
DIV AB
MOVC A,@A+DPTR
MOV P1,A
CLR MIN_S
ACALL D_1MS
SETB MIN_S
MOV A,B
MOVC A,@A+DPTR
MOV P1,A
CLR MIN_G
ACALL D_1MS
SETB MIN_G
MOV A,HOUR ;顯示當前時間時位
MOV B,#10
DIV AB
MOV DPTR,#LEDTAB
MOVC A,@A+DPTR
MOV P1,A
CLR HOU_S
ACALL D_1MS
SETB HOU_S
MOV A,B
MOVC A,@A+DPTR
MOV P1,A
CLR HOU_G
ACALL D_1MS
SETB HOU_G
MOV A,WEEK ;顯示當前星期數
MOVC A,@A+DPTR
MOV P1,A
CLR Y_S
ACALL D_1MS
SETB Y_S
OUT1:
RET
日期的顯示,秒表的顯示,倒計時的顯示,調鬧鈴,調定時的顯示,閃爍的顯示程序與以上的的掃描相似,有的以子程序的方式出現,通過子程序調用語句ACALL調用;有點直接嵌套在相應的程序里面,順序執行,或者用調轉語句AJMP調用。
B.2.5 調整程序
時鐘包括很多調整,如時間,日期,鬧鈴,秒表等,本程序,設計了相應的調整程序段,通過對應的按鍵,程序跳入調整模式或功能模式。在此著重分析一下鬧鈴重響以及定時功能的實現過程,這兩個功能都靈活運用了標志位。
1,定時功能運用了一個內存地址3CH為標志位,只有3CH中所存值非0時,在主程序中才判斷定時是否已到。3CH值初始化為0,程序開始運行時并不判斷定時是否已到。當通過按鍵進入定時初值設置,并開始倒計時,3CH的值被賦為1,
當倒計時顯示到0時,進入閃爍提示,提示結束后3CH又被賦值為0,程序回到主程序后,不必判斷定時是否已到。
但當倒計時未完,按返回鍵回到主程序時,3CH的值為1,故在主程序判斷未完成的定時任務,倒計時到0時調用同一個提示程序,最后仍可保證在主程序不再定時開啟時去判斷定時,從而節約資源。
2,重鬧鈴的精髓也是標志位的設計,以F0為標志位,其初值為0,正常響鈴時判斷重響功能鍵,若重響功能關閉,則跳過重響設定程序;若重響功能開啟,則判斷標志位F0,為了更好的說明,將相關程序截取如下:
//鬧鈴重響功能是否判斷//
JNB P0.6,RERING
//重響定時,//
RERING: ;鬧鈴重響判斷程序
JNB F0, RE ;標志位F0為0,不進行鬧鈴重響設定
CPL F0
MOV 3CH,#1 ;定時判斷標志位賦1, 定時判斷功能開啟
JNB P0.7,M1 ;鬧鈴重響間隔時間選取
MOV R4,#0 ;鬧鈴重響間隔30秒
MOV R3,#30
AJMP MAIN
M1: ;鬧鈴重響間隔60秒
MOV R4,#1
MOV R3,#0
AJMP MAIN
JB P2.7,GO ;判斷暫停鍵是否按下,未按下則響鈴
JNB P0.6,GO1 ; 音樂暫停鍵,再判斷鬧鈴重響功能是否開啟
AJMP END0
GO1: ;鬧鈴重響功能開啟處理程序
JB F0,GO ;重響標志位判斷,若F0為1,表明此次響鈴調用為重鬧鈴導致,進入重鬧鈴環節;若F0為0則表示此次鬧鈴調用為正常鬧鈴導致,因為重鬧鈴功能開啟,故將F0置1,以便重鬧鈴的實現!
CPL F0
AJMP END0
通過以上程序可知,鬧鈴初次響時,標志位F0總是0,若重響功能開啟,則在初次鬧鈴自然結束或人為按鍵結束后通過CPL F0 語句,使F0置1,為重響時間間隔的設置提供條件。當F0值為1時,才能在鬧鈴功能關閉的情況下重鬧鈴,重鬧鈴不像正常鬧鈴那樣,即使沒有人為關閉,音樂唱完后,自動回到主程序,而是一直再響,若要關閉重鬧鈴,則撥動重鬧鈴開啟開關即可。重鬧鈴結束后回到調用鬧鈴的位置,用CLR F0 使標志位復位,至此一個重鬧鈴循環結束。又回到初次鬧鈴前的狀態。若要重響開啟重鬧鈴,則需再次開啟重鬧鈴功能。
*******************************************************************************
JNB P0.6,SHENGYIN2 ;鬧鈴重響功能開啟時,跳入響鈴程序
AJMP TISHI ;不是鬧鈴重響定時,則定時時間到時,跳入提示程序
AJMP MAIN
SHENGYIN2:
SETB F0 ;鬧鈴重響標志位設定
LCALL RING ;響鈴
CLR F0 ;標志位復位
AJMP MAIN
以上程序段可以區別正常定時和重鬧鈴定時,通過若重鬧鈴功能選擇鍵按下,則定時,時間到通過一直響鈴來提示;若重鬧鈴功能關閉則定時到用閃爍來提示。我們不難發現重鬧鈴開關也可作為定時在主程序中判斷時,不同提示方式的選擇開關,我們不會影響重鬧鈴標志位,因為在鬧鈴子程序調用語句后有F0標志位的清零語句:CLR F0
*****************************************************************
C. 程序調試及仿真
本程序通過Keil單片機開發平臺實現程序的編譯,鏈接,生成HEX文件。程序再編譯過程中可以發現錯位,并及時改正,在設計時非常重要,使錯誤被扼殺在搖籃中。
通過Keil和硬件仿真平臺Proteus的聯合,可以將設計效果仿真出來,根據效果,有目的的改變設計,優化程序。
c.1 利用Keil軟件實驗過程截圖:
1,建一個工程,并設定與Proteus仿真相關的參數
2,匯編程序,并生成HEX文件
c.2利用Proteus仿真實驗過程截圖:
1.普通時間顯示模式仿真圖,表示:星期一 9點10分38秒
2.日期調節,顯示模式仿真圖,表示:2010年7月10日
3.鬧鈴調節顯示仿真圖,表示鬧鈴時刻為8點整
4.定時,倒計時顯示仿真圖,表示此時定時初值已經減到54秒,及還有54秒定時到。定時最大值為59分59秒。
5.秒表顯示仿真圖,表示秒表已經從0記到8.28秒。秒表可計時到小時,其中小時位數字可到99,即最大計時為100小時
D,電子時鐘電路板焊接實現
通過軟,硬件設計和仿真,基本上實現了自己想要的功能,就可以真刀真槍的干一場了。
軟件通過調試基本上是沒問題的,但是硬件仿真過于泛泛,對電路的細節要求不是那么高,有些問題是不能發現的,最后的實現效果還是要用實物來驗證的。
元器件的購買是個苦活,雖然中發市場那么大,但那些元件才是我要的那個它呢?我們購買的量少,對于那些元器件廠家來說,根本不屑做我們的生意,根本不用說砍價了。經過一番“跋涉”,終于搜刮齊了元器件。
根據以往經驗,焊接電路的布線非常重要,首先要在電路板上將線的大致走向規劃好,如何美觀,精簡是要領。一下是本次試驗的硬件電路實現
正面:
反面:
五.實驗總結及感想
一分耕耘,一分收獲。只有親自用實踐來驗證這句話,在能得其要領。經過這次單片機課程設計,我從一個單片機實踐的門外漢,已經越升為略知一二的新手。雖然還有很多有關單片機的應用有待學習,但萬變不離其宗,只要深入了解單片的原理,全部知識點,各個細節,一切設計皆有可能。
在實驗的開始幾天,基本上沒有收獲,不知何從下手,不知所措。為了看得更遠,不妨站在前人的肩膀上,我在整體思路模糊的情況下,在網上大量招資糧,各種與電子時鐘相關的文章,我閱讀了不少。隨著涉獵的點滴積累,我對電子時鐘的設計方案已經慢慢醞釀而成。有了方向和不少知識儲備后,在接下來的幾天,幾乎每天都有突破,雖然有時只是一句程序的修改或誕生,但那種收獲的感覺很暖人心。
實驗中遇到了不少問題,接下來總結一下,共同探討。
1,按鍵問題。我的設計中,很多功能選擇是通過按鍵開關實現的。在仿真中發現,調整數值時,有時按鍵反應太快,按一次,跳了幾下,使設置時間,日期很不方便。但是仿真多了之后,找到了按鍵(實際上是按鼠標)的節奏,對按鍵的掌控力提高了不少,不怎么會出現跳變的情況了。有些開關我采用了長按鍵的方式來防抖,效果不錯,但是每次都要長按鍵,調整效率太低,我沒有普及。本來想把所有的按鍵都加延時防抖電路,但仿真中感覺對鍵盤的控制力沒提高多少,有時還是會出問題,這個方案放棄了。索性將板子焊接出來了在調試軟件吧,仿真畢竟不是那么“真”啊!實際電路調試中,按鍵反應沒有出現過于靈敏的問題,基本可控制。
出現以上問題,我認為是電路板上焊接點太多,接觸不是很好,影響了信號的傳輸時間,從而解決了按鍵問題!也有可能是按鍵質量問題,接觸不良。
2, P0口開關問題。P0口比較特殊,它存在高阻態,要使其輸入不是高電平就是低電平,就要接上拉電阻,給其高電平輸入。
3, 音樂鬧鈴問題。在鬧鈴時間到,鬧鈴提醒時,我的數碼管為熄滅狀態,因為開始我的響鈴程序內,沒有數碼管掃描顯示程序。但加入數碼管顯示子程序后,我的鬧鈴音樂被影響了,一開始不知所措,有點懷疑是顯示程序時間過長,影響音樂的定時(節拍),我就在響鈴程序中加延時模塊,延時長度逐漸提高,最后出現了類似的問題,看來時顯示程序占用時間太長,使音樂每個音符的節拍出現了紊亂,音樂功能被遏制了!魚和熊掌不能兼得,我只能犧牲顯示來獲得音樂鬧鈴,但為了彌補顯示,我設計了閃爍提醒方案,就是在手動或音樂自然停止后,進入當前時間閃爍提示,8秒后若不按返回鍵,則自動跳入主程序。
在仿真中,老師提供的響鈴電路不能實現功能,但是在我的電路板中效果很好,令人費解!
4,中斷沖突問題,為了實現秒表,我在T0中斷嵌套了秒表相關進位程序,由于秒表要求精度0.01秒,故我的T0中斷定時為就剛好0.01秒,中斷100次,剛好1秒。秒表確實實現了,但是我的鬧鈴音質變差了。一開始以為是鬧鈴程序存太多冗余環節,影響了T1的音樂輸出中斷,但是檢查程序后,發現沒什么多余的,裁剪無從下手。
在仿真中,我讓音樂模塊運行,發現音質很好。添加T0中斷服務程序,但是將中斷進入的間隔變大,即0.05秒進入一次中斷,發現音質有所下降,有滋滋聲,但比原來的好。最后認定應該是T0中斷過于頻繁,T1音樂頻率發生中斷被打破,當單位時間內被打破的次數達到一定程度時,音符和節拍的對應發生紊亂,最終音質變差。
雖然如此,我的焊接的電路板的表現卻很爭氣,鬧鈴音質可以接受!雖然這次實際表現不錯,但問題還是有的,還是要解決的,我的方案是把秒表程序放在T1中斷服務程序,雖然音樂的發生要用到T1中斷,但是秒表的顯示和鬧鈴音樂的演奏上不會重合在一起,鬧鈴判斷是在主程序,而秒表實現是在秒表子程序,故原本相互矛盾的兩個功能,在T1中斷服務程序中找到了共同的歸宿,和諧相處。
5,顯示數字分隔問題。本實驗中用8個共陰極數碼管顯示日歷及其時間,但是8個數碼管連在一起,顯示過程中不能有效地區分時,分,秒和年,月,日,數碼管是兩兩組合起來,形成某位的十位和個位,故用小數點在適當位置一直保持高亮狀態,形成分隔符,實現方便的讀取數據。具體方法是,將需要小數點位高亮的數碼管找出來,在動態顯示掃描到該數碼管時,先將提取的字段碼的最高位變為1,利用語句 ORL A,#10000000B 實現,修正字碼后,再將字碼送入P1口顯示數字,如此問題得以解決。
6,添加倒計時器嘀嘀聲提示功能。這個功能我用到了T1中斷,作為音調頻率發生器,但是T1已經承擔了音樂鬧鈴的音調發生功能,在此通過設立標志位實現中斷服務程序的轉變。即使我將秒表的實現服務程序放入T1中斷實現,也沒問題,只要選擇標志位判斷就可以了。在此,我們用調整狀態指示燈的狀態來做標志位,具體的說是P0.1口做標志位。
還有一個問題就是如何使鈴聲有間隔的響,這就牽涉到定時,在此我們用硬件定時,即T1中斷的次數作為定時參數。我的設計是音調響0.25秒,然后用T1延時0.5秒,由于計數器工作于方式1時,12MHZ時鐘頻率下時,一次中斷最多定時65536*1us=0.065536秒,為了實現0.5秒的響聲間隔,將T1中斷1次定時為0.05秒,中斷10次后,重新裝音調發生計數初值。
對于響鈴時間的設定原理類似,可以有發聲頻率求出一次發聲定時中斷的時間,N次發聲定時中斷后,使時間變化0.25秒,而后轉入發聲間隔定時程序。
但是隨之又產生了問題,進入T1中斷后到底重裝誰的計數初值,是發聲中斷定時呢,還是響聲間隔定時呢?在此我們用到了標志位F0,通過對其設置,實現計數初值的準確裝入!
設計中,倒計時到最后10秒時,開始發出1KHZ的嘀嘀音,當倒計時到0時,開始發出3KHZ的嘀嘀音,并數碼管閃爍顯示四個0,表示倒計時到0分0秒。其實,我們可以設定倒計時最后10秒時,沒減1秒,提示音響一聲,定時到0時,使響音間隔縮短,發出急促的聲音,起到比較合適的提示作用。但仿真中總是不能得到我要的效果,提示CPU占用過大的警告,系統已經不工作于實時環境了。仿真怎么也不能發出間隔1秒,或更長的嘀嘀音,本想用自己焊好的電子時鐘實際試驗此功能,但是電路板已經上交給老師了,為了驗證我的設計理念,看來只有在開發板中,實物驗證了。
在整個電子時鐘系統中仿真時,響鈴音質不是很好,有雜音,我認為這是由于更高級的T0中斷打破了T1中斷,這在音樂鬧鈴中也出現過。比如發出1KHZ的音調,通過計算公式 1/(1000*2)=0.0005 得出T1發音中斷間隔為0.0005秒,而T0計時中斷的進入間隔為0.01秒(100次T0中斷為1秒),可見在發音時,最多連續正常進入20個發音中斷(0.01/0.0005=20),若T0中斷的服務時間長于T1發音定時時間長度,則即使通過修正重裝計數初值,得到的計數初值已經溢出,計數初值變更為0,則下一個T1中斷進入的時間為0.065536秒,而我們要求的T1中斷間隔時間為0.0005秒,顯然生成的方波的占空比出現紊亂,音質出現問題。我查看了我的T0中斷服務指令有近200行,由于MCS-51單片機的指令周期一般為1-2個機器周期,在本系統中,用12M的時鐘,每個機器周期為(1/12000000)*12=1us,則T0中斷服務占用時間至多為400us,可見中斷服務程序執行用時沒有超過0.0005秒,可見通過修正重裝計數初值后,下次進入中斷時,方波電平的反轉不會出現問題。但是如果同一時刻兩計數器都達到溢出時,優先執行T0中斷,此時本應電平反轉的方波仍保持此刻電平狀態,直到T0中斷服務程序結束才反轉電平,可知方波的占空比發生突變,影響音質。
在整個系統的仿真中,嘀嘀聲提示音只是偶爾比較靠譜的出現一次,但嘀嘀聲的間隔及音調發生的頻率不正常,通常結果是發出沉悶的噗噗聲,發聲頻率勉強分辨,發聲間隔不能仿真實現,似乎是一定的。如果我只將嘀嘀聲提示子程序作為主程序單獨運行,則能清晰地分辨高,低音頻,以及實現響音的間隔,但是若提高響音的間隔,運行的結果沒有什么變化,響音間隔沒多大變化。對于嘀嘀聲提示子程序的仿真文件,我將和電子時鐘整個系統的仿真文件一并提交。
我認為有些細節是仿真軟件不能模擬的,必須要通過開發板的實際操作得以驗證,PC機的資源有限,運行速度和性能的差異也有可能產生仿真的不同結果。
以下為具體實現程序段:
TIMER1: ;計數器T1中斷服務程序
JB P0.1,OO ;判斷中斷服務的種類
MOV A,56H ;此標志位決定倒計時最后10秒和
定時到時發出不同頻率的聲音
CJNE A,#0,PP
JNB F0,III
DJNZ 55H,OOT
CPL F0
III:
DJNZ 50H,EE ;定時前十秒嘀嘀聲提醒
MOV 50H,#100
DJNZ 51H,EE
MOV 51H,#10
MOV TH1,#3CH
MOV TL1,#0B0H
MOV 55H,#10
CPL F0
AJMP OT
OOT:MOV TH1,#3CH
MOV TL1,#0B0H
AJMP OT
EE:MOV TH1,#0FEH
MOV TL1,#0CH
CPL P2.6
AJMP OT
PP:
JNB F0,II
DJNZ 54H,OOT1
CPL F0
II:DJNZ 52H,FF ;定時到嘀嘀聲提示
MOV 52H,#150
DJNZ 53H,FF
MOV 53H,#10
MOV TH1,#3CH
MOV TL1,#0B0H
MOV 54H,#10
CPL F0
AJMP OT
OOT1:
MOV TH1,#3CH
MOV TL1,#0B0H
AJMP OT
FF:MOV TH1,#0FFH
MOV TL1,#5AH
CPL P2.6
AJMP OT
OO: ;音樂鬧鈴服務程序
MOV TH1,21H ;定時器T1置初值
MOV TL1,20H
CPL P2.6 ;音符對應頻率產生
OT:RETI
以上就是實驗中遇到的主要問題,基本上都找到了相應的解決之道。整個實驗的過程就是一個解決問題的過程,每天都解決一些問題,我的實驗也就解決了,當然結果不重要,功利化的追求結果,會使人浮躁,還是享受那份疑難迎刃而解的快感吧!
|