PIC16F887中断只运行一次

时间:2015-09-17 22:07:22

标签: assembly pic

以下代码将计时器输出到七段显示。一切都很好,除了我无法停止计时器。中断服务程序补充了变量RUN,它将增量函数设置为运动。但是,当我第一次按RB0来调用中断时,时钟就会一直在滴答作响。



;******************************************************
;PIC Configuration for PIC16F887
#include "p16F887.inc"

; CONFIG1
; __config 0x2032
 __CONFIG _CONFIG1, _FOSC_HS & _WDTE_OFF & _PWRTE_OFF & _MCLRE_ON & _CP_ON & _CPD_ON & _BOREN_OFF & _IESO_OFF & _FCMEN_OFF & _LVP_OFF
; CONFIG2
; __config 0x3FFF
 __CONFIG _CONFIG2, _BOR4V_BOR40V & _WRT_OFF
;******************************************************

  ORG  000H
  GOTO INITIALIZE

  ORG   04H
  GOTO  ISROUTINE


  ORG   008H
  GOTO  MAIN

;*******************************************************
INITIALIZE
  DCOUNT       EQU 20H
  CNT_100th    EQU 21H    ; counter for 0.01s
  CNT_10th     EQU 22H    ; counter for 0.1s
  CNT_sec      EQU 23H    ; counter for seconds
  CNT_10sec    EQU 24H    ; counter for tens of seconds
  CNT_min      EQU 25H    ; counter for minutes
  CNT_10min    EQU 26H    ; counter for tens of minutes
  RUN          EQU 70H    ;the run variable that does stuff to things
  OCOUNT       EQU 28H
  ICOUNT       EQU 29H
  BSF    STATUS,RP1             ;change to bank 3
  BSF    STATUS,RP0

  CLRF   ANSEL                 ;Using all digital mode, turns off analog
  CLRF   ANSELH                ;Make all analog ports digital

  BCF    STATUS,RP1             ;change to correct bank to configure TRIS registers
                             ;MAKE RA0 OUTPUT, RB0 INPUT, PORTC AND PORTD ALL OUTPUTS

  CLRF  TRISA
  CLRF  TRISB
  COMF  TRISB,1
  CLRF  TRISD 

  MOVLW 090H
  MOVWF INTCON
  MOVLW 040H
  MOVWF OPTION_REG

  BCF   STATUS,RP0
  CLRF  CNT_100th
  CLRF  CNT_10th
  CLRF  CNT_sec
  CLRF  CNT_10sec
  CLRF  CNT_min
  CLRF  CNT_10min
  CLRF  RUN

  GOTO  MAIN


MAIN
  MOVF    CNT_100th,0 ; Put count of 1/100ths of second in W
  CALL    TABLE         ; Get value to write out to PORTD from table
  MOVWF   PORTD     ; Put value out to PORTD
  BCF     PORTA,5     ; Turn on and off display to show digit
  CALL    DELAY
  BSF     PORTA,5

  MOVF    CNT_10th,0 ; Put count of 1/100ths of second in W
  CALL    TABLE         ; Get value to write out to PORTD from table
  MOVWF   PORTD     ; Put value out to PORTD
  BCF     PORTA,4     ; Turn on and off display to show digit
  CALL    DELAY
  BSF     PORTA,4

  MOVF    CNT_sec,0 ; Put count of 1/100ths of second in W
  CALL    TABLE         ; Get value to write out to PORTD from table
  MOVWF   PORTD     ; Put value out to PORTD
  BCF     PORTA,3     ; Turn on and off display to show digit
  CALL    DELAY
  BSF     PORTA,3

  MOVF    CNT_10sec,0 ; Put count of 1/100ths of second in W
  CALL    TABLE         ; Get value to write out to PORTD from table
  MOVWF   PORTD     ; Put value out to PORTD
  BCF     PORTA,2     ; Turn on and off display to show digit
  CALL    DELAY
  BSF     PORTA,2


  MOVF    CNT_min,0 ; Put count of 1/100ths of second in W
  CALL    TABLE         ; Get value to write out to PORTD from table
  MOVWF   PORTD     ; Put value out to PORTD
  BCF     PORTA,1     ; Turn on and off display to show digit
  CALL    DELAY
  BSF     PORTA,1

  MOVF    CNT_10min,0 ; Put count of 1/100ths of second in W
  CALL    TABLE         ; Get value to write out to PORTD from table
  MOVWF   PORTD     ; Put value out to PORTD
  BCF     PORTA,0     ; Turn on and off display to show digit
  CALL    DELAY
  BSF     PORTA,0

  CALL    WAIT

  BTFSC   RUN,0
  CALL    INCCNT
  GOTO    MAIN

WAIT
    MOVLW     08H
    MOVWF     OCOUNT
    MOVLW     0FFH
    MOVWF     ICOUNT     

    OLOOP             
        ILOOP     
        DECFSZ    ICOUNT,1     
        GOTO      ILOOP      
        DECFSZ    OCOUNT,1                
        GOTO      OLOOP                 

        RETURN              

ISROUTINE
  COMF     RUN,1
  BCF      INTCON,1
  RETFIE

INCCNT
    INCF    CNT_100th,1            ; increment 0.01s counter storing back in counter
    MOVLW   0X0A                   ; check to see if equal to 10
    XORWF   CNT_100th,0
    BTFSC   STATUS,Z
    GOTO    OVER_100th             ; if it is 10, goto OVER100th
    RETURN                         ; if no overflow, return
OVER_100th    INCF    CNT_10th,1   ;there was overflow from previous digit, increment next dig
              CLRF    CNT_100th    ;clear previous digit
              MOVLW   0X0A         ;check if this results in overflow
              XORWF   CNT_10th,0
              BTFSC   STATUS,Z
              GOTO    OVER_10th    ;there was another overflow
              RETURN               ;no overflow, go back
OVER_10th     INCF    CNT_sec,1
          CLRF    CNT_10th
          MOVLW   0X0A
          XORWF   CNT_sec,0
          BTFSC   STATUS,Z
          GOTO    OVER_sec
          RETURN
OVER_sec      INCF    CNT_10sec,1
          CLRF    CNT_sec
          MOVLW   0x06
          XORWF   CNT_10sec,0
          BTFSC   STATUS,Z
          GOTO    OVER_10sec
          RETURN
OVER_10sec    INCF    CNT_min,1
          CLRF    CNT_10sec
          MOVLW   0x0A
          XORWF   CNT_min,0
          BTFSC   STATUS,Z
          GOTO    OVER_min
          RETURN
OVER_min      INCF    CNT_10min,1
          CLRF    CNT_min
          MOVLW   0x06
          XORWF   CNT_10min,0
          BTFSC   STATUS,Z
          GOTO    OVER_10min
          RETURN
OVER_10min    CLRF    CNT_100th
          CLRF    CNT_10th
          CLRF    CNT_sec
          CLRF    CNT_10sec
          CLRF    CNT_min
          CLRF    CNT_10min
          RETURN



DELAY 
    MOVLW   0FFH
    MOVWF   DCOUNT
DLOOP    DECFSZ  DCOUNT
         GOTO   DLOOP
         RETURN

TABLE 
 ADDWF   PCL,1                ;instruction register add excursion address
 RETLW   0C0H                 ;the code for 0( the common LED is anode)
 RETLW   0F9H                 ;the code for 1
 RETLW   0A4H                 ;the code for 2
 RETLW   0B0H                 ;the code for 3
 RETLW   99H                  ;the code for 4
 RETLW   92H                  ;the code for 5
 RETLW   82H                  ;the code for 6
 RETLW   0F8H                 ;the code for 7
 RETLW   80H                  ;the code for 8
 RETLW   90H                  ;the code for 9
 END   





我忘记了什么?

1 个答案:

答案 0 :(得分:1)

中断标志RBIF(位0)未被清除。在ISROUTINE中添加行BCF INTCON,0