如何使用PIC16F877A比较值是否在四个范围之一内

问题描述 投票:0回答:1

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

我已经让ASM做所有事情,但是能够对范围进行“大于”,“小于”。我可以在PIC的C代码中看到如何执行此操作,而在ASM中则看不到。任何帮助,将不胜感激。

董事会:ODU的uC培训系统手册修订版3芯片: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

我只需要帮助弄清楚如何使程序在ASM中将RANGES中的电压显示到LCD。任何帮助是极大的赞赏!谢谢!

assembly embedded pic mplab
1个回答
0
投票
首先,我要感谢Peter Cordes重新开始这个话题。我们将看看我的回答是否值得。

使用汇编语言与PIC16F877A进行关系比较会给新孩子们带来问题。这是我感到困惑的事情。

PIC16F不执行带符号算术。

减法指令通过断言NOT CARRY来表示借入。

操作码“ SUBLW”使我对减法顺序感到困惑。

从数据表中,我发现CARRY和ZERO标志是以下结果:(k-WREG)字面常数'k'。

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

    设置为零,当'k'= WREG时设置进位
  • 零清零,当'k'> WREG时设定进位
  • 清除为零,当'k'
  • 关于状态标志如何表现工作代码的更清晰描述如下:

; ; 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

© www.soinside.com 2019 - 2024. All rights reserved.