SOGO論壇

標題: 8051 紅綠燈模擬 [列印本頁]

作者: 2237076    時間: 2011-12-8 16:22:39     標題: 8051 紅綠燈模擬

各位大大可以幫小弟看一下這個程式哪裡有問題,長時間執行就會出現誤差
電路使用P1來控制6個LED,P10~P12控制一組分別是G.Y.R三色,p13~p15控制另一組

Start:
        mov        a,#100001b
        outl        p1,a
        mov        r4,#500
        call        Timer
;
        mov        r5,#5
;
Loop:        anl        p1,#111110b
        mov        r4,#10
        call        Timer
        orl        p1,#000001b
        mov        r4,#10
        call        Timer
        djnz        r5,Loop
;
        mov        a,#100010b
        outl        p1,a
        mov        r4,#100
        call        Timer
;
        mov        a,#001100b
        outl        p1,a
        mov        r4,#500
        call        Timer
;
        mov        r5,#5
;
Loop1:        anl        p1,#110111b
        mov        r4,#10
        call        Timer
        orl        p1,#001000b
        mov        r4,#10
        call        Timer
        djnz        r5,Loop1
;
        mov        a,#010100b
        outl        p1,a
        mov        r4,#100
        call        Timer
        jmp        Start
;******************************
; Delay Time=(R4)*0.02 SEC.
;******************************
Timer:
        mov        a,#256-250
        mov        t,a
        strt        t
L:        jtf        X1
        jmp        L
X1:        djnz        r4,Timer
        ret
        end

作者: alphi    時間: 2011-12-8 21:45:48

本帖最後由 alphi 於 2011-12-8 23:56 編輯

你希望的動作原理與實際動作為何? 另外Delay部分由於使用的是迴圈式Delay必須計算每一個指令所耗費的指令週期與外部石英帳盪器之後才能得到精確度較高的延遲副程式

例如你雖然在Delay副程式中延時R4*0.02(實際可能是0.03).經過一百秒就會開始誤差1秒以上.時間越久越誤差越大.

另外紅綠燈這個屬於有規則性的可以使用查表法去建立.這樣可保證其執行比較穩定
作者: begti20    時間: 2011-12-9 05:51:49

本帖最後由 begti20 於 2011-12-9 06:03 編輯

簡易的紅綠燈控制,不外乎輸出燈號及延遲時間
P1來控制6個LED,P10~P12控制一組分別是G.Y.R三色,p13~p15控制另一組

以你的程式來看,錯誤相當多,至少我沒有用過可以組譯你的程式的組譯程式

Start:
        mov        a,#100001b
        outl        p1,a


        mov        a,#100001b ; 縱向通行
        outl        p1,a              ; 輸出
1. 8051 沒有outl的指令
2. 兩列可以改為 mov p1,#100001b



       mov        r4,#500
        call        Timer


       mov        r4,#500  ; 延遲500*0.02 SEC
        call        Timer
1. R4是8bit的Register,只能儲存的是0~255的值
2. 修改timer成延遲0.2sec的副程式,R4=50即可



;******************************
; Delay Time=(R4)*0.02 SEC.
;******************************
Timer:
        mov        a,#256-250
        mov        t,a
        strt        t
L:        jtf        X1
        jmp        L

1. 如果您想用timer/counter計算延遲時間,您沒有宣告計時計數器的操作模式
2. 您可以改用指令loop的方式,製作延遲副程式
3. 8051沒有t暫存器,不能使用它
4. 請參考http://elearning.stut.edu.tw/mechelec/ch6.htm


建議:您在寫程式時,應附加註解,方便閱讀及除錯

利用8051做簡易的紅綠燈控制,並不困難,加油


作者: alphi    時間: 2011-12-9 18:56:02

本帖最後由 alphi 於 2011-12-10 16:36 編輯

感謝"begti20" 大師提供編譯錯誤,原先我以為語法上沒問題只是邏輯上的問題,沒有編譯過測試.看到"begti20"的回覆.所以自己寫一個很簡單的8051組合語言測試.我對8051不是很熟悉.對ARM的Cortex-M3/M4組語比較熟悉(為了Porting RTOS).所以此8051程式也是修修改改.(有問題.請指教)
  1. ;           MCU:Atmel AT89S52
  2. ;           Compiler:Keil A51 V9.05
  3. ;        第一組紅綠燈        P0.0=紅燈,P0.1=黃燈,P0.2=紅燈
  4. ;        第二組紅綠燈        P0.3=紅燈,P0.4=黃燈,P0.5=紅燈
  5. ;        P0的I/O規劃
  6. ;        G1        Y1        R1        G2        Y2        R2        N/A        N/A       
  7. ;        1        0        0        0        0        1        0        0
  8. ;        1        0        0        0        0        1        0        0
  9. ;        0        1        0        0        0        1        0        0
  10. ;        0        0        1        1        0        0        0        0
  11. ;        0        0        1        1        0        0        0        0
  12. ;        0        0        1        0        1        0        0        0
  13.         ORG 00H
  14.         JMP START
  15. START:
  16.         MOV DPTR,#TABLE        ;載入TABLE的位址
  17.         MOV R0,#00H               ;初始化R0暫存器為0
  18. LOOP:
  19.         MOV A,R0           
  20.         MOVC A,@A+DPTR        ;將DPTR所儲存的位址(TABLE)加上通用暫存器A值所得到的位址
  21.         MOV P0,A                    ;將TABLE內的資料輸出到P0 Port
  22.         INC R0
  23.         CALL DELAY
  24.         CJNE R0,#6,LOOP        ;TABLE總共有六筆資料.當不等於6時繼續執行此迴圈內容
  25.         JMP START
  26. DELAY:
  27.         MOV R5,#5
  28. DL2:
  29.         MOV R4,#200
  30. DL1:
  31.         MOV R3,#249
  32.         DJNZ R3,$
  33.         DJNZ R4,DL1
  34.         DJNZ R5,DL2
  35.         RET
  36. TABLE:
  37.         DB        10000100B
  38.         DB        10000100B
  39.         DB        01000100B
  40.         DB        00110000B
  41.         DB        00110000B
  42.         DB        00101000B
  43.         END
複製代碼

作者: 又靜    時間: 2011-12-10 11:14:26

您好,
前天看了您的程式總覺得沒多大問題,但經 begti20 大大與alphi 大大的回文
只能說,您的程式是不是在 for 8049 或 8048
就像begti20 說的有些指令跟暫存器 8051己經不適用了

好久沒碰單晶片及ARM的組語,問過姐姐的意見
姐姐說,您的程式寫法是以8048來編寫的
所以要先問一下您的模擬器或晶片是用那一個

還有,您問到時間會有誤差除了begti20 大大所說的之外
最主要的原因在您的副程式寫法,在Timer 副程式中
Strt T 指令之前執行了三道指令,這三個指令共花了10μS的時間
因此R4的迴圈(最大值只有255)來算的話 255 x 10μS = 2.55 ms的誤差

另外,有這麼多會員一起討論您的問題,是否請您也回覆一下
這樣才能知道您的問題所在,不然大家只是猜測,跟本不能解決
而且,透過互相的交流討論,相信您能學習到更多。



作者: 又靜    時間: 2011-12-10 12:11:56

alphi  8048我只有在書中聽過.而且市面上應該很少有賣8048了.我從就學到工作只摸過8051,ARM7,Cortex-M3/M4.果然你姐姐非常厲害.可以看出這是8048組語  

那時跟著姐姐學的是8049,因為本身課業加重
所以8051就沒學到多少,因此現在要跟各位前輩們多多學習
作者: 2237076    時間: 2011-12-10 15:36:35

alphi 發表於 2011-12-8 21:45  
你希望的動作原理與實際動作為何? 另外Delay部分由於使用的是迴圈式Delay必須計算每一個指令所耗費的指令週 ...

大大你好,我們的專題是模擬街道車子,行人與紅綠燈之間的關係
而在下是分配到紅綠燈部份的制作,整個電路是共用同一石英帳盪器
整個電路經組員查證下是在下的程式有誤差,一直查不出是哪裡出錯
所以在這提出問題,謝謝大大的解說,感恩
作者: 2237076    時間: 2011-12-10 15:44:01

begti20 發表於 2011-12-9 05:51  
簡易的紅綠燈控制,不外乎輸出燈號及延遲時間

以你的程式來看,錯誤相當多,至少我沒有用過可以組譯你的程式 ...

大大你好,學校的課程是8051但是8051的設備幾乎都是壞的
小弟不才,關於程式部份也是參加前前前學長(可能好幾代前的)
看了幾位的分析解說讓小弟學習到新的知識,感恩

作者: 2237076    時間: 2011-12-10 15:53:06

又靜 發表於 2011-12-10 11:14  
您好,
前天看了您的程式總覺得沒多大問題,但經 begti20 大大與alphi 大大的回文
只能說,您的程式是不是 ...

版主大大(水水)你好,謝謝你的解說,沒辦法,學校的教具太老舊了
還得出動你解說,不過看你應該很年輕能知道8048這種十幾二十年前的產品
真是不容昜,總之一句謝啦
作者: 又靜    時間: 2011-12-10 16:45:09

本帖最後由 又靜 於 2011-12-10 22:28 編輯

您好,
我用您的副程式修改了一下,可以試看看
應該可以減少誤差
Timer:
          strt      t
Loop    mov     a,#256-250
          mov     t,a
L:        jtf       X1
          jmp      L
X1:     djnz      r4,Loop
          ret
作者: begti20    時間: 2011-12-10 21:33:22

sorry!! 很久很久沒有碰MCS-48系列,而很直接的以現行的MCS-51系列,果斷的說指令錯誤, 也誤導了alphi,真不好意思,又靜版主真厲害,佩服之至.
作者: 又靜    時間: 2011-12-10 21:52:57

begti20 發表於 2011-12-10 21:33  
sorry!! 很久很久沒有碰MCS-48系列,而很直接的以現行的MCS-51系列,果斷的說指令錯誤, 也誤導了alphi,真不 ...

begti20 您好,
其實我也是在學習當中,昨晚也跟alphi 討論了一下這個程式的問題
因為看法跟alphi 有點出入,早上看到您提出的看法,所以去請教姐姐
姐姐也是看到您提出的問題才想到他是用8048的語法,我才要求提問者
出來說明看看,因為他的標題是寫8051,所以,大家都沒錯,大家都辛苦了
又讓小妹學到一些東西   

作者: alphi    時間: 2011-12-10 22:13:20

begti20 發表於 2011-12-10 21:33
sorry!! 很久很久沒有碰MCS-48系列,而很直接的以現行的MCS-51系列,果斷的說指令錯誤, 也誤導了alphi,真不 ...

不要這麼說,你比我厲害更多。而且幫提問者编譯測試,而我只是提供一些想法,也讓我受益良多
作者: 2237076    時間: 2011-12-13 11:01:37

謝謝各位大大的支援,整個動作都正常在此向各位大大說聲感恩
作者: 2237076    時間: 2011-12-14 17:36:50

alphi 發表於 2011-12-9 18:56  
感謝"begti20" 大師提供編譯錯誤,原先我以為語法上沒問題只是邏輯上的問題,沒有編譯過測試.看到"begti20"的 ...

謝謝大大的支援,想請問大大你的程式中有沒有閃綠燈跟閃黃燈
閃黃燈時另一組的紅燈也一起閃,還是會恆亮
之前一直在分析你的程式,只是小弟功力不好可以請大大開示一下,感恩
作者: alphi    時間: 2011-12-14 17:44:46

本帖最後由 alphi 於 2011-12-14 17:50 編輯

會恆亮.你可以看我寫的註解.對應就知道
1:亮,0代表暗
  1. TABLE:
  2.         DB        10000100B
  3.         DB        10000100B
  4.         DB        01000100B
  5.         DB        00110000B
  6.         DB        00110000B
  7.         DB        00101000B
複製代碼
所以當另一邊黃燈時. 另一邊是紅燈亮.你如果要有閃爍功能.更改TAB的值與R0變數迴圈次數即可.所以查表法對於有規則性的修改會比較容易
作者: 又靜    時間: 2011-12-15 12:21:33

alphi 大師,問一下

        DB        10000100B
        DB        10000100B

        DB        00110000B
        DB        00110000B
為何要執行兩次


作者: alphi    時間: 2011-12-15 16:43:12

又靜 發表於 2011-12-15 12:21
alphi 大師,問一下

        DB        10000100B

我只是讓他紅燈與绿燈凉久一點是黃燈兩倍時間
作者: 又靜    時間: 2011-12-15 17:38:31

alphi 發表於 2011-12-15 16:43  
我只是讓他紅燈與绿燈凉久一點是黃燈兩倍時間

您是最專業的程式設計師怎麼可以這樣寫程式呢
本來還沒注意到,是2237076 提問,才仔細看了一下
果然跟我想的一樣 ,扣分!!!扣分  

作者: alphi    時間: 2011-12-15 19:53:56

又靜 發表於 2011-12-15 17:38  
您是最專業的程式設計師怎麼可以這樣寫程式呢
本來還沒注意到,是2237076 提問,才仔細看了一下 |08 ...

哈哈,8051我又不熟.沒有版主那麼厲害.加上用查表可以更清楚看出狀態與設定紅綠燈每一個需要時間.只要把
delay時間弄好.就可以得到每一秒一個單位
紅燈1:15秒.綠燈1:20秒,黃燈1:閃爍5秒;
紅燈2:25秒,綠燈2:10秒.黃燈2:閃爍5秒
作者: begti20    時間: 2011-12-16 05:41:05

本帖最後由 begti20 於 2011-12-16 05:49 編輯
  1. ; 交通號誌紅綠燈模擬控制程式
  2. ;                          begti20 2011.12.16 AM.
  3. ; MCU:Atmel AT89S51
  4. ; P0的I/O規劃
  5. ; 第一組紅綠燈(縱向) P0.2=紅燈,P0.1=黃燈,P0.0=綠燈
  6. ; 第二組紅綠燈(橫向) P0.5=紅燈,P0.4=黃燈,P0.3=綠燈
  7. ;
  8. ; 燈號流程變化表(觀察無倒數計秒的路口紅綠燈)
  9. ;        (橫向)  (縱向)  時間 
  10. ; STEP NC NC R2 Y2 G2 R1 Y1 G1  SEC   說明
  11. ;  1  0 0 1 0 0 0 0 1  20   縱向通行20秒
  12. ;                     STEP2-3重複三次(綠燈閃爍三次)
  13. ;  2    0 0 1 0 0 0 0 0  .5   縱向綠燈滅0.5秒
  14. ;  3    0 0 1 0 0 0 0 1  .5   縱向綠燈亮0.5秒
  15. ;  4    0 0 1 0 0 0 1 0  2    縱向黃燈亮2秒
  16. ;  5    0 0 0 0 1 1 0 0  20   橫向通行20秒
  17. ;                     STEP6-7重複三次(綠燈閃爍三次)
  18. ;  6    0 0 0 0 0 1 0 0  .5   橫向綠燈滅0.5秒
  19. ;  7    0 0 0 0 1 1 0 0  .5   橫向綠燈亮0.5秒
  20. ;  8  0 0 0 1 0 1 0 0  2    橫向通行20秒 
  21. ;  9  跳回STEP 1進入下一次縱向通行

  22.         
  23. LED:    REG     P0                    ;宣告P0接6個LED
  24.         ORG     0                     ;宣告程式起始位置
  25. STEP1:  MOV     LED,#00100001B        ;縱向通行20秒
  26.         CALL    DT20                  
  27.         MOV     R3,#3                 ;縱向綠燈閃爍三次
  28. STEP2:  MOV     LED,#00100000B        ;縱向綠燈滅0.5秒
  29.         CALL    DT05                  
  30.         MOV     LED,#00100001B        ;縱向綠燈亮0.5秒
  31.         CALL    DT05                  
  32.         DJNZ    R3,STEP2              ;STEP2-3重複三次(閃三次)
  33.         MOV     LED,#00100010B        ;縱黃亮2秒
  34.         CALL    DT2                  
  35.         MOV     LED,#00001100B        ;橫向通行20秒
  36.         CALL    DT20
  37.         MOV     R3,#3                 ;橫向綠燈閃爍3次
  38. STEP6:  MOV     LED,#00000100B        ;橫向綠燈滅0.5秒
  39.         CALL    DT05                  
  40.         MOV     LED,#000011000B       ;橫向綠燈亮0.5秒
  41.         CALL    DT05
  42.         DJNZ    R3,STEP6              ;重複3次
  43.         MOV     LED,#00010100B        ;橫向黃燈亮2秒
  44.         CALL    DT2
  45.         JMP     STEP1                 ;跳回STEP1,再次縱向通行

  46. DT20:   MOV     R4,#100              ;設定R4延遲20秒的參數
  47.         JMP     DTN

  48. DT05:   MOV     R4,#5                 ;設定R4延遲0.5秒的參數
  49.         JMP     DTN

  50. DT2:    MOV     R4,#20                ;設定R4,2秒的參數
  51.         JMP     DTN

  52. DTN:    CALL    DT01                  ;設定R4*0.1秒的時間
  53.         DJNZ    R4,DTN
  54.         RET


  55. DT01:   MOV     R6,#250               ;延遲0.1秒的副程式
  56. T01:    MOV     R7,#200
  57.         DJNZ    R7,$
  58.         DJNZ    R6,T01
  59.         RET

  60.         END                           ;宣告程式結束
複製代碼
寫程式說明比寫程式花更多的時間,好無聊!

終於完成了,以供參考,請多指教
作者: 2237076    時間: 2011-12-19 12:17:16

感謝各位大大的鼎力相助,你們的解說比上課學到的還多,begti20大大提供的程式解說太神奇我居然都了解,請受小弟一拜
剛開始做對程式都不清楚,程式也是東拼西湊到處"借"來的,經過大大們指點解說受益良多,各位大德請受小弟第二拜
.......第三拜我掰不開來了....總之感謝了




歡迎光臨 SOGO論壇 (https://oursogo.com/) Powered by OURSOGO.COM