【问题标题】:Basic interrupt for PIC16f887 on 44pinBoard44pinBoard 上 PIC16f887 的基本中断
【发布时间】:2016-11-29 13:47:39
【问题描述】:

我正在尝试在 PIC16F887 上创建基本中断代码,但我不确定 LED1 为何不亮(表明它已进入中断状态) 任何帮助表示赞赏

#include <p16F887.inc>
__CONFIG    _CONFIG1, _LVP_OFF & _FCMEN_OFF & _IESO_OFF & _BOR_OFF & _CPD_OFF & _CP_OFF & _MCLRE_OFF & _PWRTE_ON & _WDT_OFF & _INTRC_OSC_NOCLKOUT
__CONFIG    _CONFIG2, _WRT_OFF & _BOR21V



org 0
goto    START

org 4
goto INT

 INT:        
LOOP:   bsf PORTD,1
            ;call    DELAY
            ;incf    PUSH_COUNT,f    ;increment PUSH_COUNT
           ; bcf     INTCON,INTF     ;clear int flag
       goto LOOP
            retfie

START:

 clrf    INTCON          ;clear INTCON register
 bsf     INTCON,INTE     ;enable external int on INT pin
 bsf     INTCON,GIE      ;enable global int

 bsf     STATUS,RP0  ; select Register Bank 1
 bcf     TRISD,0     ; make IO Pin RD0 an output
 movlw   0x01     ;set RB0 as input
 movwf   TRISB           ;move value to TRISB
 bcf     STATUS,RP0  ; back to Register Bank 0
 bsf     PORTD,0     ; turn on LED RD0 (DS0)
 goto     $          ; wait here



 end

【问题讨论】:

  • 使用 MPLAB 调试器调试您的程序!

标签: assembly interrupt pic microchip


【解决方案1】:

我知道这个答案对于原始发帖者来说已经晚了好几年,但它为其他阅读这篇文章的人提供了帮助。

原始代码没有为数字 I/O 启用 PORTB 位 RB0。
这是通过将 ANSELH 位 ANS12 清零来完成的。

这是原始发帖人要求的代码:

;
; Project: 16F887_INT+LED
; File: main.asm
; Target: PIC16F887
; Assembler: MPASM v5.22
; Assembler mode: absolute
;
; Additional files:
;   p16F887.inc
;
; Description:
;
; Using DM164120-2 44-pin Demo board catch interrupt from SW1 and light DS0.
;
;                                               PIC16F887
;             +---------+            +---------+            +-----------+            +-----------+
;       <>  1 : RC7/RX  :      -- 12 : NC      :      <> 23 : RA4       :      -- 34 : NC        :
;  LED4 <-  2 : RD4     :      -- 13 : NC      :      <> 24 : RA5       :      <> 35 : RC1/T1OSI :
;  LED5 <-  3 : RD5     :      <> 14 : RB4     :      <> 25 : RE0       :      <> 36 : RC2       :
;  LED6 <-  4 : RD6     :      <> 15 : RB5     :      <> 26 : RE1       :      <> 37 : RC3       :
;  LED7 <-  5 : RD7     :  PGC <> 16 : RB6/PGC :      <> 27 : RE2       : LED0 <- 38 : RD0       :
;   GND ->  6 : VSS     :  PGD <> 17 : RB7/PGD :  5v0 -> 28 : VDD       : LED1 <- 39 : RD1       :
;   5v0 ->  7 : VDD     :  VPP -> 18 : RE3/VPP :  GND -- 29 : VSS       : LED2 <- 40 : RD2       :
;   SW1 ->  8 : RB0/INT :  POT -> 19 : RA0     :      <> 30 : RA7/OSC1  : LED3 <- 41 : RD3       :
;       <>  9 : RB1     :      <> 20 : RA1     :      <> 31 : RA6/OSC2  :      <> 42 : RC4       :
;       <> 10 : RB2     :      <> 21 : RA2     :      <> 32 : RC0/T1OSO :      <> 43 : RC5       :
;       <> 11 : RB3/PGM :      <> 22 : RA3     :      -- 33 : NC        :      <> 44 : RC6/TX    :
;             +---------+            +---------+            +-----------+            +-----------+
;                                                TQFP-44
;
    list p=16F887, n=0, c=255
    errorlevel -302         ; Suppress warning: Register in operand not in bank 0 

#include "p16F887.inc"
    __CONFIG    _CONFIG1, _LVP_OFF & _FCMEN_OFF & _IESO_OFF & _BOR_OFF & _CPD_OFF & _CP_OFF & _MCLRE_OFF & _PWRTE_ON & _WDT_OFF & _INTRC_OSC_NOCLKOUT
    __CONFIG    _CONFIG2, _WRT_OFF & _BOR21V
;
; Reset vector
    org     0
    goto    START
;
; Interrupt handler
;
; Note:
;   This is a bad implementation of an interrupt handler.
;   Does not save the interrupted context.
;   Expects that regieter bank 0 is always selected.
;   This only works in the very special case.
;   Do not think that this is good code.
;   You have been warned.
;   
    org     4
    bsf     PORTD,0         ; turn on LED RD0 (DS0)
    bcf     INTCON,INTF
    retfie
;
; Main application
START:
    clrf    INTCON          ; clear INTCON register
    bsf     INTCON,GIE      ; enable global int

    bsf     STATUS,RP0      ; select Register Bank 1
    bcf     TRISD,0         ; make IO Pin RD0 an output
    movlw   0x01            ; set RB0 as input
    movwf   TRISB           ; move value to TRISB
    bsf     STATUS,RP1      ; select Register Bank 3
    bcf     ANSELH,ANS12    ; Make RB0 a digital I/O pin
    bcf     STATUS,RP1      ; select Register Bank 1
    bcf     STATUS,RP0      ; back to Register Bank 0
    bcf     PORTD,0         ; turn off LED RD0 (DS0)
    bsf     INTCON,INTE     ; enable external int on INT pin
    goto    $               ; wait here

    end

【讨论】:

    【解决方案2】:

    您将 PORTD.0 (bcf TRISD,0) 设置为输出,但您的 ISR 正在修改 PORTD.1 (bsf PORTD,1)

    试试bsf PORTD,0

    【讨论】:

    • 嗨,是的,这是一个愚蠢的错误,谢谢!我现在遇到了直接进入中断的问题。有什么想法吗?
    • 您在未先清除标志的情况下启用了中断。如果该标志已启用,则中断将立即触发。由于这是一个外部中断(即由某些外部事件触发),我无法帮助您解释为什么它可能会或可能不会被触发,只能说触发是由上升或下降(取决于 INTEDG)边沿引起的INT 引脚。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-11-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多