完整的課程設計論文下載(word格式 可編輯):
CPU LED顯示頻率計.doc
(386.19 KB, 下載次數: 13)
2017-5-9 09:31 上傳
點擊文件名下載附件
下面是部分內容預覽(無圖版):
單片機課程設計 課程題目: 基于單片CPU的8LED顯示頻率計設計
目錄 第一章 前言 1 1.1頻率計概述 1 1.2頻率計設計內容 1 第二章 系統總體方案設計 2 2.1測頻的原理 2 2.2總體思路 2 2.3具體模塊 2 第三章 硬件電路具體設計 3 3.1 AT89S52主控制器模塊 3 3.1.1 AT89S52的介紹3 3.1.2 復位電路及時鐘電路4 3.1.2 引腳功能4 74HC595芯片介紹6 3.2 顯示模塊 7 3.2.1 數碼管介紹7 3.2.2 頻率值顯示電路:八位數碼管顯示四位頻率和四位周期。7 第四章 系統的軟件設計 7 4.1 軟件模塊設計 7 4.2 中斷服務子程序 8 4.3 顯示子程序 9 4.4 應用軟件簡介 10 4.4.1 Keil簡介10 4.4.2 protues簡介11 第五章 頻率計的系統調試 11 5.1 軟件調試 11 5.1.1 Pouteus軟件調試11 5.1.2 功能調試11 5.2系統調試 12 5.2.1 系統軟件調試12 5.3 誤差分析 12 第六章 總結 13 參考文獻 13
第一章 前言頻率測量是電子學測量中最為基本的測量之一。由于頻率信號抗干擾性強,易于傳輸,因此可以獲得較高的測量精度。隨著數字電子技術的發展,頻率測量成為一項越來越普遍的工作,測頻原理和測頻方法的研究正受到越來越多的關注。 1.1頻率計概述數字頻率計是計算機、通訊設備、音頻視頻等科研生產領域不可缺少的測量儀器。它是一種用十進制數字顯示被測信號頻率的數字測量儀器。它的基本功能是測量正弦信號、方波信號及其他各種單位時間內變化的物理量。在進行模擬、數字電路的設計、安裝、調試過程中,由于其使用十進制數顯示,測量迅速,精確度高,顯示直觀,經常要用到頻率計。傳統的頻率計采用測頻法測量頻率,通常由組合電路和時序電路等大量的硬件電路組成,產品不但體積大,運行速度慢而且測量低頻信號不準確。本次采用單片機技術設計一種數字顯示的頻率計,測量準確度高,響應速度快,體積小等優點[1]。 1.2頻率計設計內容利用電源、單片機、分頻電路及數碼管顯示等模塊,設計一個簡易的頻率計能夠粗略的測量出被測信號的頻率。 參數要求如下: 基本要求: 1 用P1或P3口,產生一方波信號,頻率為1000Hz,用LED顯示頻率和周期 2 將輸出信號輸入到另一端口作頻率計的信號輸入端,測量此方波信號的頻率、周期和脈寬,在另一LED上將參數值顯示出來。 3 設置一功能鍵,能將當前LED上的信號值鎖定 發揮部分: 1 通過鍵盤,可修改方波的頻率。每按一次鍵,頻率值進給或后退100Hz,頻率范圍100Hz~1500Hz 2 按鍵時,蜂鳴器發出提示音,表示按鍵有效 3 用圖形方式顯示輸入波形
第二章 系統總體方案設計2.1測頻的原理測頻的原理歸結成一句話,就是“在單位時間內對被測信號進行計數”。被測信號,通過單片機內部定時、計數產生方波,從P3.2口輸入端輸入,從P1.0口輸出。通過網絡信號將其接入按鍵,控制輸出的信號掃描。由晶體振蕩器產生的基頻,按十進制分頻得出的分頻脈沖,經過基選通門去觸發主控電路,再通過主控電路以適當的編碼邏輯便得到相應的控制指令,用以控制主門電路選通被測信號所產生的方波波,至十進制計數電路進行直接計數和顯示。 2.2總體思路頻率的測量實際上就是在單位時間內對信號進行計數,計數值就是信號頻率。該頻率計實現1000HZ~1500HZ的頻率測量,而且可以實現通過KEY1可修改方波的頻率,每按一次鍵,頻率值進給+100Hz,用八位LED顯示頻率和周期測量結果。用KEY0實現能將當前LCD上的信號值鎖定。 2.3具體模塊根據上述系統分析,頻率計系統設計共包括五大模塊:單片機控制模塊、74HC595串入并出模塊及顯示模塊、蜂鳴器模塊。各模塊作用如下: 1、單片機控制模塊:以AT89S52單片機為控制核心,來完成它待測信號的計數,譯碼,和顯示以及對分頻比的控制。利用其內部的定時/計數器完成待測信號周期/頻率的測量。單片機AT89S52內部具有2個16位定時/計數器,定時/計數器的工作可以由編程來實現定時、計數和產生計數溢出時中斷要求的功能。 2、74HC595串入并出: 數據在SCHcp的上升沿輸入,在STcp的上升沿進入的存儲寄存器中去。如果兩個時鐘連在一起,則移位寄存器總是比存儲寄存器早一個脈沖。 移位寄存器有一個串行移位輸入(Ds),和一個串行輸出(Q7’),和一個異步的低電平復位,存儲寄存器有一個并行8位的,具備三態的總線輸出,當使能OE時(為低電平),存儲寄存器的數據輸出到總線。 3、顯示模塊:顯示電路采用八位共陽極數碼管動態顯示。 4、蜂鳴器模塊:按鍵每按一下,蜂鳴器響一下。 頻率計的總體設計 file:///C:\Users\shaoanqi\AppData\Local\Temp\ksohtml\wpsB2DE.tmp.jpg 圖1 頻率計總體設計框圖
第三章 硬件電路具體設計根據系統設計的要求,頻率計實際需要設計的硬件系統主要包括以下幾個部分:AT89S52單片機最小系統模塊、74HC595串入并出及顯示模塊,下面將分別給予介紹。 3.1 AT89S52主控制器模塊3.1.1 AT89S52的介紹 AT89S52片內集成256字節程序運行空間、8K字節Flash存儲空間,支持最大64K外部存儲擴展。根據不同的運行速度和功耗的要求,時鐘頻率可以設置在0-33M之間。片內資源有4組I/O控制端口、3個定時器、8個中斷、軟件設置低能耗模式、看門狗和斷電保護?梢栽4V到5.5V寬電壓范圍內正常工作。 3.1.2 復位電路及時鐘電路復位電路和時鐘電路是維持單片機最小系統運行的基本模塊。復位電路通常分為兩種:上電復位(圖2)和手動復位(圖3)。 file:///C:\Users\shaoanqi\AppData\Local\Temp\ksohtml\wpsB2EF.tmp.png file:///C:\Users\shaoanqi\AppData\Local\Temp\ksohtml\wpsB2F0.tmp.png 圖2 上電復位 圖3 手動復位 合適頻率的晶振對于選頻信號強度準確度都有好處,本次設計選取12.000M無源晶振接入XTAL1和XTAL2引腳。并聯2個30pF陶瓷電容幫助起振。AT89S52單片機最小系統如圖6所示。 file:///C:\Users\shaoanqi\AppData\Local\Temp\ksohtml\wpsB2F1.tmp.png 圖4 單片機最小系統原理圖 3.1.2 引腳功能P0口:P0口是一個8位漏極開路的雙向I/O口。作為輸出口,每位能驅動8個TTL邏輯電平。對P0端口寫“1”時,引腳用作高阻抗輸入。當訪問外部程序和數據存儲器時,P0口也被作為低8位地址/數據復用。在這種模式下,P0具有內部上拉電阻。在 flash編程時,P0口用來接收指令字節;在程序校驗時,輸出指令字節。程序校驗時,需要外部上拉電阻[7]。 P1口:P1口是一個具有內部上拉電阻的8位雙向I/O口,P1 輸出緩沖器能驅動4個TTL 邏輯電平。對 P1 端口寫“1”時,內部上拉電阻把端口拉高,此時可以作為輸入口使用。作為輸入使用時,被外部拉低的引腳由于內部電阻的原因,將輸出電流。此外,P1.0和P1.2分別作定時器/計數器2的外部計數輸入和定時器/計數器2的觸發輸入,P1口功能具體如表1所示。在flash編程和校驗時,P1口接收低8位地址字節。 表1 P1口的第二種功能說明表 引腳號 | | | T2(定時器/計數器T2的外部計數輸入),時鐘輸出 | | T2EX(定時器/計數器T2的捕捉/重載觸發信號和方向控制) | | | | | | |
P2口:P2口是一個具有內部上拉電阻的8位雙向I/O口,P2輸出緩沖器能驅動4 個TTL邏輯電平。對P2端口寫“1”時,內部上拉電阻把端口拉高,此時可以作為輸入口使用。作為輸入使用時,被外部拉低的引腳由于內部電阻的原因,將輸出電流。在訪問外部程序存儲器或用16位地址讀取外部數據存儲器時,P2口送出高八位地址。在這種應用中,P2口使用很強的內部上拉發送1。在使用8位地址訪問外部數據存儲器時,P2口輸出P2鎖存器的內容。在flash編程和校驗時,P2口也接收高8位地址字節和一些控制信號。 P3口:P3口是一個具有內部上拉電阻的8位雙向I/O口,P2輸出緩沖器能驅動4個TTL邏輯電平。對P3端口寫“1”時,內部上拉電阻把端口拉高,此時可以作為輸入口使用。作為輸入使用時,被外部拉低的引腳由于內部電阻的原因,將輸出電流。P3口亦作為AT89C51特殊功能(第二功能)使用。 表2 P3口的第二種功能說明表 引腳號 | | | | | | | file:///C:\Users\shaoanqi\AppData\Local\Temp\ksohtml\wpsB301.tmp.png(外部中斷0) | | file:///C:\Users\shaoanqi\AppData\Local\Temp\ksohtml\wpsB302.tmp.jpg(外部中斷1) | | | | | | file:///C:\Users\shaoanqi\AppData\Local\Temp\ksohtml\wpsB303.tmp.png(外部數據存儲器寫選通) | | file:///C:\Users\shaoanqi\AppData\Local\Temp\ksohtml\wpsB304.tmp.png(外部數據存儲器寫選通) |
RST:復位輸入。晶振工作時,RST腳持續2個機器周期高電平將使單片機復位。看門狗計時完成后,RST 腳輸出96個晶振周期的高電平。特殊寄存器 AUXR(地址8EH)上的DISRTO位可以使此功能無效。DISRTO默認狀態下,復位高電平有效。 XTAL1:振蕩器反相放大器和內部時鐘發生電路的輸入端。 XTAL2:振蕩器反相放大器的輸出端。 單片機引腳分配 根據系統設計及各模塊的分析得出,單片機的引腳分配如表3所示。 表 3 單片機端口分配表 74HC595芯片介紹引腳說明 符號 | | | | 15[size=10.5000pt], 1[size=10.5000pt], 7 | | | | | | | | | | | | | | | | | | | | | | | | | |
3.2 顯示模塊 顯示模塊由頻率值顯示電路和周期值顯示電路組成。用P3口設計程序,產生一方波信號,頻率為1000Hz,用LED顯示頻率和周期。 將輸出信號輸入到另一端口P1口作頻率計的信號輸入端,測量此方波信號的頻率、周期,在另一LED上將參數值顯示出來。 3.2.1 數碼管介紹根據其結構的不同,可分為共陽極數碼管和共陰極數碼管兩種。根據管腳資料,可以判斷使用的是何種接口類型[14].兩種數碼管內部原理如圖5所示。 file:///C:\Users\shaoanqi\AppData\Local\Temp\ksohtml\wpsB315.tmp.jpg 圖5 兩種數碼管內部原理圖 LED數碼管中各段發光二極管的伏安特性和普通二極管類似,只是正向壓降較大,正向電阻也較大。在一定范圍內,其正向電流與發光亮度成正比。由于常規的數碼管起輝電流只有1~2 mA,最大極限電流也只有10~30 mA,所以它的輸入端在5 V電源或高于TTL高電平(3.5 V)的電路信號相接時,一定要串加限流電阻,以免損壞器件。 3.2.2 頻率值顯示電路:八位數碼管顯示四位頻率和四位周期。第四章 系統的軟件設計4.1 軟件模塊設計頻率計開始工作或者完成一次頻率測量,系統軟件都進行測量初始化。測量初始化模塊設置堆棧指針(SP)、工作寄存器、中斷控制和定時/計數器的工作方式。定時/計數器的工作首先被設置為計數器方式,即用來測量信號頻率[15]。 首先定時/計數器的計數寄存器清0,運行控制位TR置1,啟動對待測信號的計數。計數閘門由軟件延時程序實現,從計數閘門的最小值(即測量頻率的高量程)開始測量,計數閘門結束時TR清0,停止計數。計數寄存器中的數值經過數制轉換程序從十六進制數轉換為十進制數。判斷該數的最高位,若該位不為0,滿足測量數據有效位數的要求,測量值和量程信息一起送到顯示模塊;若該位為0,將計數閘門的寬度擴大10倍,重新對待測信號的計數,直到滿足測量數據有效位數的要求。定時/計數器的工作被設置為定時器方式,定時/計數器的計數寄存器清0,在判斷待測信號的上跳沿到來后,運行控制位TR置為1,以單片機工作周期為單位進行計數,直至信號的下跳沿到來,運行控制位TR清0,停止計數。16位定時/計數器的最高計數值為65535,當待測信號的頻率較低時,定時/計數器可以對被測信號直接計數,當被測信號的頻率較高時,先由硬件十分頻后再有定時/計數器對被測信號計數,加大測量的精度和范圍。 4.2 中斷服務子程序T0中斷服務子程序流程如圖20所示。測頻時,定時器T0 工作在定時方式,每次定時50mS ,則T0 中斷20 次正好為1秒,即T0用來產生標準秒信號,定時器T0 用作計數器,對待測信號計數,每秒鐘的開始啟動T0 ,每秒鐘的結束關閉T0 ,則定時器T0 之值乘以分頻系數就為待測信號的頻率。 file:///C:\Users\shaoanqi\AppData\Local\Temp\ksohtml\wpsB316.tmp.png 圖6 T0中斷服務子程序 定時/計數器T1工作在計數方式, 對信號進行計數,計數器1中斷流程圖。 file:///C:\Users\shaoanqi\AppData\Local\Temp\ksohtml\wpsB317.tmp.png 圖7 計數器1中斷服務子程序 4.3 顯示子程序顯示子程序將存放在顯示緩沖區的頻率或周期值送往數碼管上顯示出來,由于所有4 位數碼管的8 根段選線并聯在一起由單片機的P2口 控制,因此,在每一瞬間4位數碼管會顯示相同的字符,要想每位顯示不同的字符就必須采用掃描方法輪流點亮各位數碼管,即在每一瞬間只點亮某一位顯示字符,在此瞬間,段選控制口P2輸出相應字符。由P0.0-P0.3逐位輪流點亮各個數碼管, 每位保持1mS ,在10mS~20mS 之內再點亮一次,重復不止,利用人的視角暫留,好像4 位數碼管同時點亮。數碼管顯示子程序流程如圖8所示。 file:///C:\Users\shaoanqi\AppData\Local\Temp\ksohtml\wpsB318.tmp.png 圖8 顯示子程序流程圖 4.4 應用軟件簡介4.4.1 Keil簡介Keil軟件是目前最流行開發系列單片機的軟件,Keil提供了包括C編譯器、宏匯編、連接器、庫管理和一個功能強大的仿真調試器等在內的完整開發方案,通過一個集成開發環境(uVision)將這些部份組合在一起。而Proteus與其它單片機仿真軟件不同的是,它不僅能仿真單片機CPU的工作情況,也能仿真單片機外圍電路或沒有單片機參與的其它電路的工作情況。 (1)建立工程文件 點擊“Project->New project”菜單,出現一個對話框,要求給將要建立的工程起一個名字,你可以在編緝框中輸入一個名字,點擊“保存”按鈕,出現第二個對話框,按要求選擇目標器件片。建立新文件并增加到組。分別設置“target1”中的“Target,output,debug”各項,使程序匯編后產生HEX文件。 (2)匯編,調試系統程序 Keil 單片機模擬調試軟件內集成了一個文本編輯器,用該文本編輯器可以編輯源程序。在集成開發環境中選擇菜單“File → New...”、單擊對應的工具按鈕或者快捷鍵Ctrl +N 將打開一個新的文本編輯窗口,完成匯編語言源文件的輸入,并且完成源程序向當前工程的添加。 然后在集成開發環境中選擇菜單“File→Save As...”可以完成文件的第一次存儲。注意,匯編語言源文件的擴展名應該是“ASM”,它應該與工程文件存儲在同一文件夾之內。在完成文件的第一次存儲以后,當對匯編語言源文件又進行了修改,再次存儲文件則應該選擇菜單“File→Save”、單擊對應的工具按鈕或者快捷鍵Ctrl +S 實現文件的保存。 接著的工作需要把匯編語言源文件加入工程之中。選擇工程管理器窗口的子目“Source Group 1”,再單擊鼠標右鍵打開快捷菜單。在快捷菜單中選擇“Add File to Group ‘Source Group 1’”,加入文件對話框被打開。雙擊要加入的文件名或者選擇要加入的文件名再單擊“Add”按鈕即可完成把匯編語言源文件加入工程。文件加入以后,加入文件對話框并不消失,更多的文件也可以利用它加入工程。如果不需要加入其它文件,單擊“Close”按鈕可以關閉加入文件對話框。這時工程管理窗口的文件選項卡中子目錄“Source Group 1”下出現一個匯編語言源文件。 (3)編譯源程序,出現錯誤時,返回上一級對錯誤更改后重新編譯,直到沒有錯誤為止。 4.4.2 protues簡介(1)首先將keil和 Protues兩個軟件安裝好。 (2)打開protues軟件,新建一文件將硬件原理圖繪入圖中。 (4)將KEIL生成的HEX文件下載入單片機中,點擊“開始”進行仿真。 (5)在keil中進行debug,同時在proteus中查看直觀的結果(如LED顯示⋯⋯)。
第五章 頻率計的系統調試5.1 軟件調試5.1.1 Pouteus軟件調試根據系統設計要求,進行Keil和Proteus系統仿真,不斷調試程序,直到符合功能要求。Proteus總體仿真圖9所示。 file:///C:\Users\shaoanqi\AppData\Local\Temp\ksohtml\wpsB319.tmp.jpg 5.1.2 功能調試當測量頻率值加200時,數碼管顯示頻率值,作為Hz檔單位指示。仿真顯示如圖10所示。 file:///C:\Users\shaoanqi\AppData\Local\Temp\ksohtml\wpsB32A.tmp.jpg 圖10 HZ檔頻率仿真 5.2系統調試5.2.1 系統軟件調試經軟件的調試—修改—再調試,如此反復,排除各種故障最終基本完成了設計所要求的任務。由系統軟件設計可以測出1000HZ-1500HZ的量程范圍,可以實現量程檔的自動轉換,使用的動態顯示測量時會出現閃爍現象,但顯示數值準確,穩定時顯示不閃爍。 表6:頻率的數據記錄表 表7:周期的數據記錄表 5.3 誤差分析從記錄的數據可以看出,系統軟件仿真誤差很小,在1000Hz-1500MHz范圍內測量出來的頻率基本上就是輸入信號的頻率。但是在硬件調試中,可能是由于標準元器件本身誤差,如隨著時間的延長,造成測量結果沒有軟件仿真精確。同時手工焊接單片機最小系統、分頻整形電路等也會帶來一定的干擾,造成信號的失真,從而導致測量精度下降,測量范圍有所縮小,但是可以看出,誤差在允許范圍內,所設計的電路基本符合要求
第六章 總結通過本次試驗我學到了很多書本以外的知識。了解了單片機的基本知識和在控制領域的作用和地位。在實驗的過程中我進一步了掌握了C語言的編寫程序,學會了使用PROTUTES和KEIL的仿真來實現,同時掌握了如何收集、查閱、應用文獻資料,如何根據實際需要有選擇的閱讀書籍和正確確定系統所要使用的元器件的類型。我明白了理論和實踐之間存在的距離只有靠不斷的思考不斷的動手才能將所學的知識真正運用到實踐上來。在設計中我的很多方面的能力都得到了提高,尤其在單片機軟件編程方面讓我感觸頗深。我個人認為軟件設計是個即靈活又細膩的工作,不僅僅要運用理科知識還要運用藝術中的很多元素。它要求耐心和細心去不斷完善,同時還需要有良好的邏輯思維能力。這長達兩周的課程設計讓我絞盡腦汁完成了自己認為完成不了的任務讓我很有成就感。也是我對單片機產生了更深的興趣。我很享受課程設計的過程。
參考文獻 [1]鄒大挺.頻率計的設計[J]. 《電子產品世界》出版社. 2006. 第193期. 4-7. [2]雷玉堂.光電檢測技術[M]. 中國計量出版社. 1995. [3]季建華. 智能儀表原理[M]. 山東教育出版社. 2004. [4]王永生. 電子測量學[M]. 西北工業大學出版社. 2003. [5]李華.單片機實用接口技術[M]. 航空航天大學出版社. 2006. [6]張鵬.王雪梅. 單片機原理與應用實例教程[M]. 海軍出版社. 2007. [7]赫建國等. 單片機在電子電路設計中的應用[M]. 清華大學出版社. 2005. [8]康華光.電子技術基礎(模擬部分)[M]. 高等教育出版社. 1998.
頻率計源程序 #include "stdio.h" #include "absacc.h" #include <intrins.h> #include <math.h> #include "LEDshow.h" sbit signal_out=P1^0; sbit key0=P2^6; sbit key1=P3^4; sbit beep=P2^7; bit state_old=0,state_new=0; bit int_flag; unsigned int frequency=1000,frequency_temp;//測量信號頻率Hz unsigned int signal=1000;//產生信號頻率Hz,初始值1000Hz unsigned char counter0,counter1;//用于記錄中斷次數 unsigned char hight=1; //高電平所需次數 unsigned char total=2;//一個周期所需中斷總次數,占空比 hight/total,題目要求為方波。 unsigned char th1,tl1;////產生信號頻率,定時時間為500us,初始值為1000Hz unsigned int f_count,t_count;// unsigned char temp_flag=0; void Display(void); void Mcu_init(void);
void main() { Mcu_init(); while(1) { Display(); } } void Display(void) { if(IE0==0 || IE1==0) beep=0; LED0_show(signal,(1000000/signal));//顯示信號發生器的頻率Hz,周期us LED1_show(frequency,(1000000/frequency)); }
void Mcu_init(void) { th1=((65536-1000000/(2*signal))/256),tl1=((65536-1000000/(2*signal))%256);//產生信號頻率 beep=0; TMOD=0x11; //定時器1 方式1 16位手動重裝初值 ; 定時器0 方式1 16位手動重裝初值 TH0 = 0x03c; TL0 = 0x0b0;//50ms TH1=th1; TL1=tl1; // ET0=1;//允許T/C0申請中斷 TR0=1;//啟動T/C0 ET1=1;//允許T/C1申請中斷 TR1=1;//啟動T/C1 IT0=1;//下降沿觸發 EX0=1;//啟動外部觸發器0 IT1=1;//下降沿觸發 EX1=1;//啟動外部觸發器1 TR2=1;//啟動T/C2 RCAP2H=0x00; RCAP2L=0x00; EA=1; } void EXint0(void) interrupt 0 //鎖存,停止刷新顯示 { if(frequency<2000)//Measure_T(); { TR2=1;//啟動T/C2 temp_flag++;//上升沿的個數 if(temp_flag==2)//第二個上升沿 { temp_flag=0;//上升沿的個數 t_count=TH2*256+TL2; TR2=0;//停止T/C2 TH2=0x00; TL2=0x00; frequency_temp=1000000/t_count; return; }
} else if(frequency>=2000)//Measure_F(); { f_count++;//單位時間內計到的沿個數 if(int_flag)///單位時間50ms { f_count=0;//單位時間內計到的沿個數 int_flag=0;//單位時間50ms frequency_temp=f_count*20;//frequency=f_count/50ms(Hz) } } } void time0(void) interrupt 1 //50ms測量一次頻率,并刷新顯示 { TH0 = 0x3c; TL0 = 0xb0;//50ms counter0 ++;//T/C0中斷次數加一 int_flag=1; //單位時間50ms if(counter0 ==2)//定時時間 50ms*counter0 { counter0 =0;//T/C0中斷次數清零 frequency=frequency_temp; } }
void EXint1(void) interrupt 2 { if(key0 ==0) TR0 =~TR0; if(key1 ==0)//頻率遞增100Hz { signal +=100; if(signal>1500) signal =100; th1=((65536-1000000/(2*signal))/256),tl1=((65536-1000000/(2*signal))%256);//產生信號頻率 return; } beep=1; } void time1(void) interrupt 3 //方波發生 { counter1++; //中斷次數加1 if(counter1 == hight) signal_out=0;//高電平時間到,轉為低電平 else if(counter1 == total) //低電平時間到,轉為高電平,并清零counter { signal_out =1; counter1 =0; } TH1=th1; TL1=tl1; }
LED顯示程序 #include "LEDshow.h" //const unsigned char Led_Disbuf[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x00,0x80}; //共陰極 const unsigned char Led_Disbuf[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0xff,0x7f,0xbf}; //共陽極 const unsigned char ComBuf[8] = {0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80}; void LED0_show(unsigned int high_4,unsigned int low_4) { unsigned char i,temp[8]; temp[0]= high_4 /1000; temp[1]= high_4 %1000/100; temp[2]= high_4 %100/10; temp[3]= high_4 %10; temp[4]= low_4 /1000; temp[5]= low_4 %1000/100; temp[6]= low_4 %100/10; temp[7]= low_4 %10; for(i=0;i<8;i++) { DATA0_HC595_Send_Data(Led_Disbuf[temp]); //送端口數據 CONTROL0_HC595_Send_Data(ComBuf); //選通位選端口 delay_ms(1); //延時 CONTROL0_HC595_Send_Data(0x00); //位選通關閉 } } void LED1_show(unsigned int high_4,unsigned int low_4) { unsigned char i,temp[8]; temp[0]= high_4 /1000; temp[1]= high_4 %1000/100; temp[2]= high_4 %100/10; temp[3]= high_4 %10; temp[4]= low_4 /1000; temp[5]= low_4 %1000/100; temp[6]= low_4 %100/10; temp[7]= low_4 %10; for(i=0;i<8;i++) { DATA1_HC595_Send_Data(Led_Disbuf[temp]); //送端口數據 CONTROL1_HC595_Send_Data(ComBuf); //選通位選端口 delay_ms(1); //延時 CONTROL1_HC595_Send_Data(0x00); //位選通關閉 } } void delay_ms(unsigned char time) { unsigned char i,j; for(i=time;i>0;i--) for(j=20;j>0;j--); } //發送一個字節 void CONTROL0_HC595_Send_Data(unsigned char byte) { unsigned char i; for(i = 0;i < 8;i++) { if(byte & 0x80) { CONTROL0_HC595_data=1; } else { CONTROL0_HC595_data=0; } byte <<=1; CONTROL0_HC595_sclk=1; //上升沿數據移位 CONTROL0_HC595_sclk=0; }
CONTROL0_HC595_latch=1; CONTROL0_HC595_latch=0; } /************* //發送字符串 void CONTROL0_HC595_Output_Data(unsigned char Data) { CONTROL0_HC595_latch=0; //下降沿鎖存器數據不變 CONTROL0_HC595_Send_Data(Data); CONTROL0_HC595_latch=1; //上升沿數據打入8位鎖存器 } *************/ //發送一個字節 void DATA0_HC595_Send_Data(unsigned char byte) { unsigned char i; for(i = 0;i < 8;i++) { if(byte & 0x80) { DATA0_HC595_data=1; } else { DATA0_HC595_data=0; } byte <<=1; DATA0_HC595_sclk=1; //上升沿數據移位 DATA0_HC595_sclk=0; }
DATA0_HC595_latch=1; DATA0_HC595_latch=0; } /**************** //發送字符串 void DATA0_HC595_Output_Data(unsigned char Data) { DATA0_HC595_latch=0; //下降沿鎖存器數據不變 DATA0_HC595_Send_Data(Data); DATA0_HC595_latch=1; //上升沿數據打入8位鎖存器 } *****************/ //發送一個字節 void CONTROL1_HC595_Send_Data(unsigned char byte) { unsigned char i; for(i = 0;i < 8;i++) { if(byte & 0x80) { CONTROL1_HC595_data=1; } else { CONTROL1_HC595_data=0; } byte <<=1; CONTROL1_HC595_sclk=1; //上升沿數據移位 CONTROL1_HC595_sclk=0; }
CONTROL1_HC595_latch=1; CONTROL1_HC595_latch=0; } /******************** //發送字符串 void CONTROL1_HC595_Output_Data(unsigned char Data) { CONTROL1_HC595_latch=0; //下降沿鎖存器數據不變 CONTROL1_HC595_Send_Data(Data); CONTROL1_HC595_latch=1; //上升沿數據打入8位鎖存器 } ***********************/ //發送一個字節 void DATA1_HC595_Send_Data(unsigned char byte) { unsigned char i; for(i = 0;i < 8;i++) { if(byte & 0x80) { DATA1_HC595_data=1; } else { DATA1_HC595_data=0; } byte <<=1; DATA1_HC595_sclk=1; //上升沿數據移位 DATA1_HC595_sclk=0;
}
DATA1_HC595_latch=1; DATA1_HC595_latch=0; } /*************** //發送字符串 void DATA1_HC595_Output_Data(unsigned char Data) { DATA1_HC595_latch=0; //下降沿鎖存器數據不變 DATA1_HC595_Send_Data(Data); DATA1_HC595_latch=1; //上升沿數據打入8位鎖存器 } |