[英]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.