[英]P18F4420 Switch case statement in assembly language(asm)
我目前正在使用 PIC18f4420 在匯編語言的 Mplab IDE 上進行一個項目,其中我有四個 LED。 2 個 LED 告訴我操作#1 的狀態,另外 2 個 LED 告訴我另一個操作#2 的狀態。 最后,我還有 2 個輸出 LED,可以根據它們的狀態告訴我這 4 個 LED 的狀態。 例如,下面有一張我想要實現的真值表的圖片。
我需要幫助,用匯編語言寫一個算法函數。 我正在考慮使用 switch 語句來檢查 4 個 LED 的狀態,從而將 OUTPUT LED 驅動為綠色或紅色。
4 個 LED 連接到 PIC 中的不同端口引腳,輸出 LED 連接到另一個引腳。 我只是在如何為 Mplab V8 上的 PIC18f4420 編寫匯編代碼時遇到了麻煩。 我對如何創建此功能沒有明確的想法。 歡迎任何幫助。 謝謝
最終輸出 LED 將基於 4 個 LED 的顏色狀態紅/綠/關。
到目前為止,這是我得到的:
Leds_out ; function name
; LED OUT Green = op2_green & ~op1_red
movlw op1_red ; Put the value of op1_red it on the working register
movwf 0x39, f, a ; save it on the file register at this location
comf 0x39, f, a ; complement op1_red of the value on the file register and keep vlaue on the same location on the file register
movlw op2_green ; move op2_green value into the working register
andwf 0x39, w, a ; AND the complement of op1_red in the file register with the vlaue bit of op2_green on the working register and keep value on the Wreg
movwf 0x40, f, a ; move the contents of the Wreg into the file register at this location
movff 0x40, l_out_green, a ; finally move content from file register 0x40 to the l_out_green
;LED Out red = op1red | op2red
movlw op1_red ; put op1_red on the wokring register
movwf 0x41, f, a ; move contents of the Wreg to file register 0x41
movlw op2_red ; Then move op2_red on the working register
iorwf 0x41, f, a ; OR the contents of the working register with what is in the file register 0x41 which is the bit value of op1_red, and keep OR value in the same location on the file register
movff 0x41, l_out_red, a ; Finally move the value bit in the location 0x41 into the port bit l_out_red
OP#1 紅色 | OP#1 綠色 | OP#2 紅色 | OP#2 綠色 | LED 輸出紅色 | LED 輸出綠色 | |
---|---|---|---|---|---|---|
1 | 0 | 0 | 0 | 0 | 0 | 0 |
2 | 0 | 0 | 0 | 1 | 0 | 1 |
3 | 0 | 0 | 1 | 0 | 1 | 0 |
4 | 0 | 1 | 0 | 0 | 0 | 0 |
5 | 1 | 0 | 0 | 0 | 0 | 0 |
6 | 1 | 0 | 1 | 0 | 1 | 0 |
7 | 0 | 1 | 0 | 1 | 0 | 1 |
8 | 0 | 1 | 1 | 0 | 1 | 0 |
9 | 1 | 0 | 0 | 1 | 1 | 0 |
有多種方法可以為您的問題實現解決方案代碼。 但我們盡量保持簡單。 注意這不是一個完整的代碼。 我只是給你函數實現,你必須通過使用這個實現來合並大圖。
首先,我們將定義一個輸入保持寄存器,它的位和輸出紅色和輸出綠色的有效情況。 現在我們已經定義了所有情況,在主循環中我們需要掃描輸入狀態並將最后一個狀態保存在一個名為inStates
的寄存器中,或者inStates
調用它。 之后,我們根據您在問題中顯示的表格更新輸出 LED。
shared UDATA_SHR ; Declare variables in shared RAM
inStates RES 1 ; Input states holder variable
; Bit definitions for inputs
OP1RED_BIT EQU 0 ; bit-0 holds value for op#1 Red
OP1GREEN_BIT EQU 1 ; bit-1 holds value for op#1 Green
OP2RED_BIT EQU 2 ; bit-2 holds value for op#2 Red
OP2GREEN_BIT EQU 3 ; bit-3 holds value for op#2 Green
; Active case definitions for out LED red
OUT_LED_RED_CASE_1 EQU (1 << OP2RED_BIT) ; case 1
OUT_LED_RED_CASE_2 EQU ( (1 << OP1RED_BIT) | (1 << OP2RED_BIT) ) ; case 2
OUT_LED_RED_CASE_3 EQU ( (1 << OP1GREEN_BIT) | (1 << OP2RED_BIT) ) ; case 3
OUT_LED_RED_CASE_4 EQU ( (1 << OP1RED_BIT) | (1 << OP2GREEN_BIT) ) ; case 4
; Active case definitions for out LED green
OUT_LED_GREEN_CASE_1 EQU (1 << OP2GREEN_BIT) ; case 1
OUT_LED_GREEN_CASE_2 EQU ( (1 << OP2GREEN_BIT) | (1 << OP1GREEN_BIT) ) ; case 2
; Maybe here there is some piece of init codes
main_loop:
; Other codes if applicable...
; Somewhere in the main loop
call readInStats ; read the input states
call setStateForOutLedRed ; set out red LED accordingly
call setStateForOutLedGreen ; set out green LED accordingly
; Other codes if applicable...
goto main_loop
; Assuming that the access bit is enabled...
readInStats:
clrf inStates
btfsc OP1RED_PORT, OP1RED_BIT
bsf inStates, 0
btfsc OP1GREEN_PORT, OP1GREEN_BIT
bsf inStates, 1
btfsc OP2RED_PORT, OP2RED_BIT
bsf inStates, 2
btfsc OP2GREEN_PORT, OP2GREEN_BIT
bsf inStates, 3
; Read complete
return
setStateForOutLedRed:
movlw OUT_LED_RED_CASE_1
xorwf inStates, w
bz doSetOutRed
movlw OUT_LED_RED_CASE_2
xorwf inStates, w
bz doSetOutRed
movlw OUT_LED_RED_CASE_3
xorwf inStates, w
bz doSetOutRed
movlw OUT_LED_RED_CASE_4
xorwf inStates, w
bz doSetOutRed
; if the flow reaches here then no cases match to set red LED
bcf OUT_LED_RED_PORT, OUT_LED_RED_BIT
return
doSetOutRed:
; One of the cases matches to set red LED
bsf OUT_LED_RED_PORT, OUT_LED_RED_BIT
return;
setStateForOutLedGreen:
movlw OUT_LED_GREEN_CASE_1
xorwf inStates, w
bz doSetOutGreen
movlw OUT_LED_GREEN_CASE_2
xorwf inStates, w
bz doSetOutGreen
; if the flow reaches here then no cases match to set green LED
bcf OUT_LED_GREEN_PORT, OUT_LED_GREEN_BIT
return
doSetOutGreen:
; One of the cases matches to set green LED
bsf OUT_LED_GREEN_PORT, OUT_LED_GREEN_BIT
return;
更新 inStates 結構信息
位7 | 位6 | 位5 | 位 4 | 位 3 | 位2 | 位 1 | 位0 |
---|---|---|---|---|---|---|---|
不曾用過 | 不曾用過 | 不曾用過 | 不曾用過 | 持有 OP2GREEN_BIT | 持有 OP2RED_BIT | 持有 OP2RED_BIT | 持有 OP1RED_BIT |
如果您查看readInStats
函數,我們會按此順序讀取值並將其保存到 inState 寄存器中。 如果您翻轉順序,它將與您的真值表中的順序相同。 我將以二進制格式分享活動案例分配,而不是為了讓您更好地理解而轉移。
; Active case definitions for out LED red
OUT_LED_RED_CASE_1 EQU B'00000100' ; case 1
OUT_LED_RED_CASE_2 EQU B'00000101' ; case 2
OUT_LED_RED_CASE_3 EQU B'00000110' ; case 3
OUT_LED_RED_CASE_4 EQU B'00001001' ; case 4
; Active case definitions for out LED green
OUT_LED_GREEN_CASE_1 EQU B'00001000' ; case 1
OUT_LED_GREEN_CASE_2 EQU B'00001010' ; case 2
如果翻轉低半字節(低 4 位),您將看到與將相應輸出設置為 1 的真值表中相同的值。這就是如何將真值表解釋為編碼常量值的方法。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.