2012-01-04 104 views
1

我有8個LED和2個按鈕,最初第一個和最後一個LED點亮,如果我按第一個按鈕,第一個LED右移,如果按第二個按鈕最後帶領左轉。如果兩個燈「相遇」,通過相互轉換,它們就會關閉。在彙編程序中移動(移位)兩個寄存器

按下按鈕後,我不知道如何更新單行上的LED,所以我爲每個按鈕做了2行P1和P2。第一行似乎正確轉換,但第二行真的搞砸了。我究竟做錯了什麼?

下面是我的代碼:

$TITLE(5) 
$MOD51 
ORG 100H 
START: 
    ; 8 leds, P1.0-P1.7 
    ; 2 buttons, P0.1 P0.2 
    MOV P1, #00h 
    MOV P2, #00h 

    ; left LED positions 
    MOV 30H, #00000001b ; initial position 
    MOV 31H, #00000010b 
    MOV 32H, #00000100b 
    MOV 33H, #00001000b 
    MOV 34H, #00010000b    
    MOV 35H, #00100000b 
    MOV 36H, #01000000b 
    MOV 37H, #10000000b 

    MOV 38H, #00000000b ; leds meet 

    ; right led positions 
    MOV 39H, #10000000b ; initial position 
    MOV 40H, #01000000b 
    MOV 41H, #00100000b 
    MOV 42H, #00010000b 
    MOV 43H, #00001000b    
    MOV 44H, #00000100b 
    MOV 45H, #00000010b 
    MOV 46H, #00000001b 

    MOV R1, #0 
    MOV R2, #0 

LOOP: 
    JNB P0.1, INCREMENT_L ; left button pressed, led shifts right 
    JNB P0.2, INCREMENT_R ; right button pressed, led shifts left 

    CALL DISP_L ; display left led 
    CALL DISP_R ; display right led 

    JMP LOOP 

INCREMENT_L: 
    SETB P0.1 
    CJNE R1, #7, INC_L 
    MOV R1, #0 
    JMP LOOP 

INCREMENT_R: 
    SETB P0.2 
    CJNE R2, #7, INC_R 
    MOV R2, #0 
    JMP LOOP 

INC_L: 
    MOV A, R2 
    ADD A, #39H 
    MOV B, A 
    MOV A, R1 
    ADD A, #30H 
    CJNE A, B, INCL 
    JMP RESET 
    JMP LOOP 

INC_R: 
    MOV A, R1 
    ADD A, #30H 
    MOV B, A 
    MOV A, R2 
    ADD A, #39H 
    CJNE A, B, INCR 
    JMP RESET 
    JMP LOOP 

INCL: 
    INC R1 
    JMP LOOP 

INCR: 
    INC R2 
    JMP LOOP 

DISP_L: 
    MOV A, R1 
    ADD A, #30H 
    MOV R0, A 
    MOV P1, @R0 
    RET 

DISP_R: 
    MOV A, R2 
    ADD A, #39H 
    MOV R0, A 
    MOV P2, @R0 
    RET 

RESET: 
    MOV R1, #0 
    MOV R2, #0 
    JMP LOOP 

END 
+0

定義「搞砸了」。它在做什麼?另外,你有沒有試過註釋幾行代碼來看看它是如何反應的? – 2012-01-04 23:36:26

+0

如果您期望有用的答案,您需要提供更多的上下文。什麼樣的cpu以及LED /按鈕如何連接起來。 – 2012-01-05 00:00:10

+0

「搞砸了」,因爲在使用sim535程序進行測試時,LED的第一行從「10000000」(其中0表示未點亮的LED和1點亮的LED)「乾淨地」移動到00000001(一次移動1 ),而第二行,在第一次按下按鈕顯示11111100而不是00000010,並在第二次按下它顯示01111010而不是00000100,然後其他奇怪的值 – user573382 2012-01-05 00:07:48

回答

2

這聽起來極像是一個符號/無符號的問題。你的添加是無符號的,還是假定高位是一個符號位,併爲你做2s恭維的東西。如果不小心,遺留的任何遺留位也會影響事物。你有沒有使用add的直接轉換指令?

在線查看真正快速,並看到你有一個SHL/SHR指令,你可以用它來移動你的位置。然後,如果它們相匹配,您只需對抗您的位置即可關閉位置。

+0

哦,所以我只有2個寄存器,一個包含00000001和其他10000000作爲初始值,並使用SHR/SHL移動位。還有一個問題:我如何「合併」來自這兩個寄存器的位?例如,如果我有00001000和1000000,我想「合併」它們到10001000 – user573382 2012-01-05 00:20:41

+0

我使用8x51架構,所以我有RRC和RLC而不是SHR/SHL – user573382 2012-01-05 00:40:38

+0

使用異或。如果這些位是相同的,它將返回0.如dhl r0,xor對r1和r2。顯示r2。同樣,rr r1,xor反對r0,放置並顯示在r2中。這應該給你你想要的結果。順便說一句,使用RRC和RLC(假設它意味着左轉通過進位和右轉通過進位)意味着您可以將設置位一直移動通過​​任一方向的燈光,進入進位,然後通過反覆調用旋轉。有點整潔。 – 2012-01-05 00:49:11