首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用PIC16F877A比较处于多个范围之一内的值

如何使用PIC16F877A比较处于多个范围之一内的值
EN

Stack Overflow用户
提问于 2019-10-14 20:05:36
回答 1查看 205关注 0票数 0

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

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

电路板: uC培训系统手册版本3,出自ODU Microchip: PIC16F877A编码语言: MPLAB内的ASM (MPASM汇编程序v5.50)

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

代码语言:javascript
复制
; 
; 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到LCD。任何帮助都是非常感谢的!谢谢!

EN

回答 1

Stack Overflow用户

发布于 2019-11-06 10:14:03

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

在汇编语言中与PIC16F877A进行关系比较会给新手带来一些问题。以下是我发现令人困惑的事情。

PIC16F不执行带符号的算术运算。

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

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

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

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

当'k‘=WREG

  • 零时设置进位,当'k’=WREG

  • 零时设置进位,当'k‘>WREG

  • 零时设置进位,当’k‘= WREG

时设置进位

通过更清晰地描述状态标志的行为,工作代码如下所示:

代码语言:javascript
复制
; 
; 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
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/58376434

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档