新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > 8051模塊化編程分析

        8051模塊化編程分析

        作者: 時間:2011-08-04 來源:網絡 收藏

        程序設計就是用計算機所能接受的語言把解決問題的步驟描述出來,也就是把計算機指令或語句組成一個有序的集合。一個好的應用程序不僅是執行效率高,而且還要結構清晰、便于調試。所以人們都采用結構化程序設計方法來編制應用程序。目前單片機的教材側重于匯編語言。因此學習用單片機匯編語言程序進行結構化設計還是很有必要的。本文以“60秒倒計時電路”為例談一談51 單片機匯編語言的一點技巧。

          一、60秒倒計時電路及編程

          1. 功能要求

          所謂倒計時,就是首先給定一個初始值,然后對初始值進行減“1”操作,直到該值為“0”為止。60 秒倒計時就是對給定的初始值“60”每隔1 秒鐘對其進行減“1”,一直減到該值為“0”為止。

          該倒計時電路要求有兩個按鈕。一個是“復位”按鈕,按下按鈕設置倒計時初始值,并把指示燈熄滅;另一個是“開始”按鈕,按下按鈕開始倒計時。并用兩位LED 數碼管顯示當前倒計時值。計時時間到,指示燈點亮。

          2. 電路組成

          實現上述功能要求的單片機接口電路如圖1 所示。

        8051模塊化編程分析

        圖1單片機接口電路

          圖中用按鈕SB1 作為“置初值”按鈕,按鈕SB2 作為“開始”按鈕。按下SB1 按鈕,將顯示值設置為“60”。

          按下按鈕SB2,每隔一秒顯示值減“1”,直到值為“0”

          停止計數。按鈕和指示燈接在P0 口上,P0.0 為初始按鈕,P0.1 為開始按鈕,P0.7 為指示燈。十位LED 數碼管接P2 口,個位LED 數碼管接P1 口。圖2 為單片機基本系統電路。

        單片機基本系統電路

        圖2 單片機基本系統電路

          3. 功能分析

          根據60 秒倒計時的功能要求,需要單片機完成以下任務:

          ⑴ 按鍵掃描。用來判斷有沒有鍵被按下,是哪個鍵被按下?根據不同的鍵,給出相應的鍵值。

          ⑵ 計時顯示。這里時間值使用的是兩位數,故需要將被顯示的時間值取出個位數和十位數,然后才能進行顯示。

          ⑶ 被顯示數轉換成7 段碼。由于單片機中的數據都是以二進制形式存放或運算的。而這里輸出顯示使用了兩位LED 數碼管來顯示計時數值的,一個被顯示的數要點亮數碼管的某幾段才能顯示出這個數,不同的數需要點亮數碼管的不同段。因此需要將被顯示的這個數轉換成相應的顯示段碼,才能被正確顯示出來。

          ⑷ 延時。包括1秒鐘延時和按鍵消抖的10毫秒延時。

          ⒋ 程序編制

          程序按實現功能采用模塊化結構,有一個主程序和若干個子程序組成。每個子程序分別是完成某個任務的獨立模塊,有時會用到調用參數。本實例共有5 個子程序,分別是按鍵掃描子程序、10ms 延時子程序、1s 延時子程序、顯示子程序、取段碼子程序。

          ⑴ 按鍵掃描子程序

          按鍵掃描子程序完成對按鍵進行掃描,確定有沒有鍵被按下,當有鍵被按下并抬起后將相關鍵值返回給主程序的任務。其流程如圖3 所示。該子程序沒有入口參數,但有一個出口參數,即按鍵的鍵值,存放在寄存器R3 中。寄存器R3 中的值為“60H”表示SB1 鍵被按下;寄存器R3 中的值為“00H”表示SB2 鍵被按下。

        按鍵掃描子程序流程圖

        圖3 按鍵掃描子程序流程圖

          按照圖3 的流程圖和51 單片機的指令系統編制的子程序如下:

          ;----------- 按鍵掃描描--------------

          ; 出口參數鍵值存放在寄存器R3 中,用于識別哪個鍵。

          ;R3=60H, 說明SB1 被按下;R3=00H, 說明SB2 被按下

          key_scan: jnb kb_init, k1check ; SB1 按下轉移

          jnb kb_begin, k2check ; SB2 按下轉移

          sjmp ksr ;

          k1check: acall del10 ; 調用毫秒延時,去抖

          jb kb_init, ksr ; 干擾,返回

          jnb kb_init,$ ; 等待按鍵釋放

          mov r3, #60h; 是SB1,鍵值“60H”送寄存器R3

          sjmp ksr ; 是,不進行任何操作返回

          k2check: acall del10 ; 調用毫秒延時,去抖

          jb kb_begin, ksr ; 干擾,返回

          jnb kb_begin,$ ; 等待按鍵釋放

          mov r3, #00h; 是SB2,鍵值“00H”送寄存器R3

          ksr: ret ; 返回

          ;---------------------------------

          ⑵ 顯示子程序

          顯示子程序完成從被顯示值中取出十位數將其轉換成顯示斷碼,并送單片機的P2 口;從被顯示值中取出個位數將其轉換成顯示斷碼,并送單片機的P1 口任務。其流程如圖4 所示。該子程序有一個入口參數,即被顯示的值,存放在寄存器R2 中。

        顯示子程序流程圖

        圖4 顯示子程序流程圖

          按照圖4 的流程圖和51 單片機的指令系統編制的子程序如下:

          ;------------ 顯示子程序------------

          ; 入口參數存放在寄存器R2 中

          display:mov a, r2 ; 取被顯示值

          mov b, #10; 取被顯示值的十位數

          div ab;

          acall seg7; 調用轉換子程序,取顯示斷碼

          mov p2, a ; 十位數段碼送P2 口

          mov a, b; 取個位數

          acall seg7 ; 調用轉換子程序,取顯示斷碼

          mov p1, a ; 個位數段碼送P1 口

          ret ; 返回

          ;---------------------------------

          ⑶ 取段碼子程序

          取段碼子程序完成將被顯示的數轉換成7 段共陽LED 數碼管對應數的段碼的任務。其流程如圖5 所示。

        取段碼子程序流程圖

        圖5 取段碼子程序流程圖

          該子程序有一個入口參數和一個出口參數。入口參數就是被顯示的數,出口參數就是該數的段碼(相應位=0表示亮),都存放在累加器A 中。

          按照圖5 的流程圖和51 單片機的指令系統編制的子程序如下:

          ;-------------- 取段碼--------------

          ; 對累計器A 中的值由查表得到顯示斷碼

          ; 入口和出口參數存放在累計器A 中

          seg7: inc a ; 取被顯示數,累加器A 加1

          movc a, @a+pc ; 查表

          ret ; 返回

          db 0c0h,0f9h,0a4h,0b0h;0123

          db 99h,92h,82h,0f8h;4567

          db 80h,90h,88h,83h;89AB

          db 0c6h,0a1h,86h,8eh;cdEF

          ;---------------------------------

          ⑷ 延時子程序

          延時子程序完成一定的延時時間任務。這里有兩個延時時間不同的子程序(也可以調用100 次10mS 做1S 延遲),其流程如圖6 所示。延時子程序沒有入口和出口參數。

        延時子程序流程圖

        圖6 延時子程序流程圖

          按照圖6 的流程圖和51 單片機的指令系統編制的子程序如下:

          ;----------- 延時10ms 程序----------

          ; 用到寄存器組1 中的R6 和R7 寄存器

          del10: setb psw.3 ; 切換至第1 組寄存器

          mov r7, #0bh ;

          dl1: mov r6, #0ffh ;

          dl2: djnz r6, dl2 ;

          djnz r7, dl1;

          clr psw.3 ; 切換至第0 組寄存器

          ret ;

          ;---------------------------------

          ;------------- 延時1s 程序-----------

          ; 用到寄存器組1 中的R1、R2 和R3 寄存器

          del1s: setb psw.3 ; 選用寄存器區1

          mov r1 , #46; 立即數46 送寄存器R1

          del0: mov r2 , #100; 立即數100 送寄存器R2

          del1: mov r3 , #100 ; 立即數100 送寄存器R3

          djnz r3 , $ ; 寄存器R3 中的內容減1,不為零轉移到當

          前指令

          djnz r2 , del1; 寄存器R2 中的內容減1,不為零轉移到

          del1

          djnz r1 , del0; 寄存器R1 中的內容減1,不為零轉移到

          del0

          clr psw.3 ; 選用寄存器區0

          ret ; 子程序返回

          ;---------------------------------

          ⑸ 主程序編制

          主程序需要實現的功能是:完成單片機端口定義;初始化任務;調用鍵掃描子程序,根據按鍵狀態實現置初值或進行倒計時,并調用顯示子程序等。其流程如圖7 所示。

        主程序編制流程圖

        圖7 主程序編制流程圖

          按照圖7 的流程圖和51 單片機的指令系統、以上編制的各子程序,主程序如下:

          ;**********************************************************

          ; 文件名:counter.asm 功能:60 秒倒計時

          ; 說明:p2 和p1 口分別接一個LED 數碼管, 顯示兩位

          十進制數。

          ; p0.0 和p0.1 口接置初值按鈕和開始倒計時按鈕,p0.7

          接提示LED。

          ; 晶振頻率11.0592MHz.

          ;**********************************************************

          ;------------ 端口定義--------------

          kb_init bit p0.0 ; 置初值按鈕定義

          kb_begin bit p0.1 ; 開始按鈕定義

          warn bit p0.7 ; 提示

          ;---------------------------------

          org 0000h

          ajmp begin

          ;============ 主程序===============

          org 00b0h

          begin:

          mov sp, #50h ; 初始化

          mov p0, #0ffh

          mov p1, #0ffh

          mov p2, #0ffh

          mov r2, #60

          mov r3, #0ffh

          main:

          lcall key_scan ; 按掃描鍵

          mov a, r3 ; 取返回值

          cjne a, #60h, lp1 ; 非SB1 按鍵轉移

          mov r2, #60 ; 初值送寄存器R2

          setb p0.7 ; 清指示燈

          acall display ; 調顯示子程序

          ajmp main ; 轉移

          lp1: mov a, r3 ; 取返回值

          cjne a, #00h, main ; 非SB2 按鍵轉移

          setb p0.7

          mov r2, #60

          lp2: acall display

          acall del1s ; 調用1 秒延時子程序

          dec r2

          cjne r2, #00h,lp2

          acall display

          clr p0.7

          mov r3, #0ffh

          ajmp main

          ;=================================

          二、Keil C 中編譯

          1. 新建項目

          打開“Keil C”軟件,新建一個項目。項目名也不妨為“counter”。

          點擊桌面上的圖標 ,進入Keil C51 μVision2集成開發環境。在主界面上點下拉菜單“Project”,選“New Project?”命令。在彈出的對話框中將項目命名為“counter”。點“保存”按鈕,選“Atmel”下的“AT89S52”后返回。

          2. 添加源程序

          打開已建立的文件“counter.asm”;并將該文件添加到“Source Group 1”中。

          在μVision2 主界面上點擊打開文件按鈕 ,在彈出的對話框內找到剛才新建并保存的文件“counter.asm”。點“打開”按鈕打開。

          在中間左邊的“項目空間(Project Workspace)”內,點擊“+”展開。再用右鍵點擊“Source Group 1”文件夾,在彈出的菜單命令中選“Add Files to group‘Source Group 1’”。

          3. 參數設置

          在“Options for Target‘ Target 1’”中的“Output”標簽頁上進行設置。

          點下拉菜單“Project”, 選“Options for Target‘Target 1’”。在彈出對話框上的“Target”標簽頁內,把單片機的運行頻率調整為11.0592MHz。在“Output”標簽頁上,點“Create HEX File”前的復選框,使其內出現“√”,這樣編譯后就能生成目標文件了。點“確定”按鈕返回。

          4. 程序編譯

          點編譯和建立目標文件,得到“counter.hex”文件。

          在μVision2 主界面上點重新編譯按鈕,對源程序文件進行編譯,結果如圖8 所示。

        圖8

        圖8

          三、Preteus仿真

          ISIS 仿真圖如圖9 所示。設置CPU:89C51 的特性,加載counter.HEX 代碼加載,運行仿真。將光標移至按鈕SB1,使光標變成一只“手”時,點擊鼠標左鍵,使按鈕按下。按鈕釋放后,數碼管顯示值加“60”,如圖9 所示。啟動倒計時。將光標移至按鈕SB2,使光標變成一只“手”時,點擊鼠標左鍵,使按鈕按下。按鈕釋放后倒計時開始。源程序counter.DSN 請到www.ele169.com 下載。

        8051模塊化編程分析

        圖9ISIS 仿真圖

          四、基本系統上運行

          用單片機基本系統板來驗證程序,首先準備好實驗用器材基本系統板、下載器、電源和萬能板及所需元器件。然后按下面步驟進行操作。

          ⒈在應用實驗板上按圖1 焊接好電阻、電容、數碼管和接插件、按鈕等。

          ⒉拔去最小系統板上的跳線J101、J102、J103,插上AT89S52 芯片。將下載線的接口板插入電腦的并口上,連接電纜把最小系統與接口板連好,再在最小系統上接上電源。如圖10 所示。

        圖10

        圖10

          ⒊打開下載軟件,并設置好有關參數;加載待寫文件“counter.hex”;點“編程”按鈕下載程序。必要時須先對芯片進行“擦寫”( 若該芯片中曾燒錄過程序)。

          ⒋完成上面的操作后,關閉電源,拔下連接電纜,插上跳線J101,接上實驗電路。

          ⒌上電驗證程序,按下按鍵SB1 置初值,按下按鍵SB2 開始倒計時。若不符合要求則進行修改(可以先在μVision2 進行調試或Proteus 中仿真)。

          ⒍重復上述步驟直到實現要求的功能。

          五、結束語

          用匯編語言編制應用程序時雖然要考慮單片機的硬件資源的分配,且實現相同功能時的語句可能比C51 編程更多,匯編的模塊按結構化編程,同樣也能編制出結構清晰、功能明確、可讀性強、的應用程序。



        關鍵詞: 8051 模塊化編程

        評論


        相關推薦

        技術專區

        關閉
        主站蜘蛛池模板: 泉州市| 垫江县| 新疆| 晋江市| 彩票| 册亨县| 宝坻区| 太和县| 盐边县| 大厂| 依安县| 宁海县| 连云港市| 遂昌县| 武穴市| 南昌县| 姜堰市| 山西省| 浪卡子县| 凉山| 凤翔县| 平南县| 扬州市| 潼关县| 万源市| 石首市| 环江| 麻城市| 乐都县| 铜山县| 巴中市| 吐鲁番市| 洪湖市| 刚察县| 隆林| 宣武区| 崇文区| 集贤县| 阳原县| 辽中县| 普兰店市|