Assembly 如何使用PIC16F877A将一个值与几个范围中的一个进行比较

Assembly 如何使用PIC16F877A将一个值与几个范围中的一个进行比较,assembly,embedded,pic,mplab,Assembly,Embedded,Pic,Mplab,作业问题:保持作业1中的所有内容不变,设计一个系统,可以读取电位计的设置,并在LCD模块上显示高、中、低的实时电压范围。 您的程序应显示高=4.5 V及以上、中=2.0 V至3.0 V、低=1.5 V及以下的实时电压,并每5秒更新一次读数和显示,以反映电位计上的变化。如果电压不在范围内,则在LCD上显示“未知” 我已经让ASM做了所有的事情,但是能够对范围做“大于”、“小于”。我可以在PIC的C代码中看到如何做到这一点,但在ASM中没有。任何帮助都将不胜感激 董事会:uC培训系统手册修订版。3来

作业问题:保持作业1中的所有内容不变,设计一个系统,可以读取电位计的设置,并在LCD模块上显示高、中、低的实时电压范围。 您的程序应显示高=4.5 V及以上、中=2.0 V至3.0 V、低=1.5 V及以下的实时电压,并每5秒更新一次读数和显示,以反映电位计上的变化。如果电压不在范围内,则在LCD上显示“未知”

我已经让ASM做了所有的事情,但是能够对范围做“大于”、“小于”。我可以在PIC的C代码中看到如何做到这一点,但在ASM中没有。任何帮助都将不胜感激

董事会:uC培训系统手册修订版。3来自ODU 微芯片:PIC16F877A 编码语言:MPLAB中的ASM(MPASM汇编程序v5.50)

简化的测试代码只关注范围比较:

; 
; File: main.asm
; Target: PIC16F877A
; 
; Description:
;   Simplified range compare test code
; 
    #include <P16F877A.INC>


    __CONFIG  0x3F32                ;This is the control bits for CONFIG register

    ORG     0x0000                  ;RESET or WDT reset vector
    GOTO    START

    ORG     0x0004                  ;Regular INT vector

;This is the area where your interrupt service routine goes

    RETFIE
;
;Table of messages
;
Message_High:
    DT "High"
Message_Mid:
    DT "Mid"
Message_Low:
    DT "Low"
Message_Unknown:
    DT "Unknown"

ValueToCheck EQU    0x20

START:                              ;The starting place of the user codes

    banksel ValueToCheck
    clrf    ValueToCheck

TestLoop:
    movf    ValueToCheck,W
    sublw   d'45'                   ; Do calculation: WREG - ValueToCheck
    btfsc   STATUS,C                ; CARRY not set so ValueToCheck < 45
    goto    ShowHigh

    movf    ValueToCheck,W
    sublw   d'30'                   ; Do calculation: WREG - ValueToCheck
    btfsc   STATUS,C                ; CARRY not set so ValueToCheck < 30
    goto    ShowUnknown

    movf    ValueToCheck,W
    sublw   d'20'                   ; Do calculation: WREG - ValueToCheck
    btfsc   STATUS,C                ; CARRY not set so ValueToCheck < 20
    goto    ShowMid

    movf    ValueToCheck,W
    sublw   d'15'                   ; Do calculation: WREG - ValueToCheck
    btfsc   STATUS,C                ; CARRY not set so ValueToCheck < 15
    goto    ShowUnknown

ShowLow:
    movlw   Message_Low             ; Load WREG with message pointer
    goto    ShowMessage

ShowMid:
    movlw   Message_Mid             ; Load WREG with message pointer
    goto    ShowMessage

ShowHigh:
    movlw   Message_High            ; Load WREG with message pointer
    goto    ShowMessage

ShowUnknown:
    movlw   Message_Unknown         ; Load WREG with message pointer
ShowMessage:
;
; This is test code so no output
;
    nop     ; With breakpoint here. WREG not loaded with expected message pointer.
;
;
;
    incf    ValueToCheck,F
    goto    TestLoop

    END                             ;End program
;
; 文件:main.asm
; 目标:PIC16F877A
; 
; 说明:
;   简化范围比较测试代码
; 
#包括
__配置0x3F32;这是配置寄存器的控制位
组织0x0000;重置或WDT重置向量
开始
组织0x0004;正则整数向量
;这是您的中断服务例程所处的区域
雷特菲
;
;信息表
;
信息(高):
DT“高”
消息:
DT“中”
信息(低):
DT“低”
消息\u未知:
DT“未知”
值检查等式0x20
开始:;用户代码的起始位置
banksel值检查
clrf值检查
测试循环:
movf值检查,W
小艇d'45';执行计算:WREG-值检查
btfsc状态,C;进位未设置为使值检查<45
后藤秀海酒店
movf值检查,W
小艇d'30';执行计算:WREG-值检查
btfsc状态,C;进位未设置为使值检查<30
后藤秀未知
movf值检查,W
小艇d'20';执行计算:WREG-值检查
btfsc状态,C;进位未设置为使值检查<20
后藤秀美
movf值检查,W
小艇d'15';执行计算:WREG-值检查
btfsc状态,C;进位未设置为使值检查<15
后藤秀未知
ShowLow:
movlw消息_低;用消息指针加载WREG
转到ShowMessage
ShowMid:
movlw消息_Mid;用消息指针加载WREG
转到ShowMessage
ShowHigh:
movlw消息_高;用消息指针加载WREG
转到ShowMessage
ShowUnknown:
movlw消息_未知;用消息指针加载WREG
ShowMessage:
;
; 这是测试代码,因此没有输出
;
否;这里有断点。WREG未加载预期的消息指针。
;
;
;
incf值检查,F
转到测试循环
结束;结束程序

我只是需要帮助,弄清楚如何让程序显示电压范围内的ASM的液晶显示器。非常感谢您的帮助!谢谢大家!

首先,我要感谢Peter Cordes让这个话题重开。我们将看看我的回答是否值得

在汇编语言中与PIC16F877A进行关系比较会给新生代带来一些问题。以下是我感到困惑的事情

PIC16F不进行有符号算术运算

减法指令通过断言NOT进位来指示借用

操作码'SUBLW'让我对减法的顺序感到困惑

从数据表中,我发现进位和零标志是:(k-WREG)对于文字常量“k”的结果

“SUBLW k”语句后的文字常量“k”和WREG之间的关系在状态标志中表示为:

  • 设置零,当“k”=WREG时设置进位
  • 零清除,进位设置为“k'>WREG”
  • 零为清除状态,当“k”小于WREG时进位为清除状态
通过对状态标志行为的更清晰描述,工作代码如下所示:

; 
; File: main.asm
; Target: PIC16F877A
; 
; Description:
;   Simplified range compare test code
;
;   Bugs corrected 2019-NOV-05
; 
    #include <P16F877A.INC>


    __CONFIG  0x3F32                ;This is the control bits for CONFIG register

    ORG     0x0000                  ;RESET or WDT reset vector
    GOTO    START

    ORG     0x0004                  ;Regular INT vector

;This is the area where your interrupt service routine goes

    RETFIE
;
;Table of messages
;
Message_High:
    DT "High"
Message_Mid:
    DT "Mid"
Message_Low:
    DT "Low"
Message_Unknown:
    DT "Unknown"

ValueToCheck EQU    0x20

START:                              ;The starting place of the user codes

    banksel ValueToCheck
    clrf    ValueToCheck

TestLoop:
    movf    ValueToCheck,W
    sublw   d'45'                   ; Do calculation: 45 - ValueToCheck
    btfss   STATUS,Z                ; ZERO  set so ValueToCheck = 45
    btfss   STATUS,C                ; CARRY set so ValueToCheck < 45
    goto    ShowHigh                ; When ValueToCheck >= 45

    movf    ValueToCheck,W
    sublw   d'30'                   ; Do calculation: 30 - ValueToCheck
    btfss   STATUS,C                ; CARRY set so ValueToCheck < 30
    goto    ShowUnknown             ; When 30 > ValueToCheck < 45

    movf    ValueToCheck,W
    sublw   d'20'                   ; Do calculation: 20 - ValueToCheck
    btfss   STATUS,Z                ; ZERO  set so ValueToCheck = 20
    btfss   STATUS,C                ; CARRY set so ValueToCheck < 20
    goto    ShowMid                 ; When 20 >= ValueToCheck <= 30

    movf    ValueToCheck,W
    sublw   d'15'                   ; Do calculation: 15 - ValueToCheck
    btfss   STATUS,C                ; CARRY set so ValueToCheck <= 15
    goto    ShowUnknown             ; When 15 > ValueToCheck < 20

ShowLow:                            ; When ValueToCheck <= 15
    movlw   Message_Low             ; Load WREG with message pointer
    goto    ShowMessage

ShowMid:
    movlw   Message_Mid             ; Load WREG with message pointer
    goto    ShowMessage

ShowHigh:
    movlw   Message_High            ; Load WREG with message pointer
    goto    ShowMessage

ShowUnknown:
    movlw   Message_Unknown         ; Load WREG with message pointer
ShowMessage:
;
; This is test code so no output
;
    nop     ; With breakpoint here. WREG now loaded with expected message pointer.
;
;
;
    incf    ValueToCheck,F
    goto    TestLoop

    END                             ;End program
;
; 文件:main.asm
; 目标:PIC16F877A
; 
; 说明:
;   简化范围比较测试代码
;
;   错误已纠正2019-11-05
; 
#包括
__配置0x3F32;这是配置寄存器的控制位
组织0x0000;重置或WDT重置向量
开始
组织0x0004;正则整数向量
;这是您的中断服务例程所处的区域
雷特菲
;
;信息表
;
信息(高):
DT“高”
消息:
DT“中”
信息(低):
DT“低”
消息\u未知:
DT“未知”
值检查等式0x20
开始:;用户代码的起始位置
banksel值检查
clrf值检查
测试循环:
movf值检查,W
小艇d'45';执行计算:45-值检查
btfss状态,Z;设置为零,以便值ToCheck=45
btfss状态,C;将设置值带到检查<45
后藤秀海;当ValueToCheck>=45时
movf值检查,W
小艇d'30';执行计算:30-值检查
btfss状态,C;将设定值带到检查<30
后藤秀未知;当30>值检查<45时
movf值检查,W
小艇d'20';执行计算:20-值检查
btfss状态,Z;设置为零,因此值ToCheck=20
btfss状态,C;将设定值带到检查<20

后藤秀美;当20>=ValueToCheck时,欢迎使用堆栈溢出。请阅读,采取,阅读,以及。最后,请学习如何创建一个你自己的尝试,重点是