繁体   English   中英

P18F4420 汇编语言中的 switch case 语句(asm)

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM