PIC的中断系统

一、编写程序,使用RB0的外部中断,实现对key1事件的响应。每按下key1一次,则令LED点亮的位向左移位1位。

;********************************************************************************
; 跳线接法:用短接帽短接P14
; 功能描述: 使用RB0的外部中断,实现对key1事件的响应。每按下key1一次,则令LED点亮的位
; 向左移位1位。
;*******************************************************************************

 list       p=16f877A       ; 标明所用的处理器类型
 #include   <p16f877A.inc>  ; 调用头文件 
 __CONFIG _CP_OFF & _WDT_OFF & _BODEN_OFF & _PWRTE_OFF & _HS_OSC & _WRT_OFF & _LVP_OFF & _CPD_OFF;熔丝位配置字
; _CP_OFF: 代码保护关闭
; _WDT_OFF: 看门狗关闭
; _BODEN_OFF: 低压复位关闭
; _PWRTE_OFF: 上电延时计数关闭
; _HS_OSC : 外部高速振荡器使能
; _WRT_OFF : 写程序存储器保护关闭 
; _LVP_OFF : 低电压编程关闭
; _CPD_OFF : EEPROM存储器代码保护

;***** 变量声明*******************************************************
D1            EQU   0x20        ; 变量1,在HC595的初始化中使用
PORTD_SHADOW  EQU   0x23        ; PORTD的影子变量

i             EQU   0x7A
w_temp        EQU   0x7D        ; 中断现场保护
status_temp   EQU   0x7E        ; 中断现场保护
pclath_temp   EQU   0x7F        ; 中断现场保护             
;**********************************************************************
    ORG         0x0000          ; 复位入口地址
    nop                         ; 与ICD调试配合的nop
            movlw   high(main)    
            movwf   PCLATH         
    goto        main            ; 跳转到Main
;**********************************************************************
    ORG         0x0004          ; 中断向量入口地址
    movwf       w_temp          ; 入栈保护
    movf        STATUS,w                    
    movwf       status_temp        
    movf        PCLATH,w      
    movwf       pclath_temp   
;**********************************************************************
            clrf     PCLATH            ; 设定PCLATH指向page0,即中断程序所在页面
            btfss    INTCON, INTE      ; 是否开外设中断
            goto     EndOfInt          ; 否,则跳转至中断处理程序尾部
            btfss    INTCON, INTF      ; 是否置位外设中断的标志
            goto     EndOfInt          ; 否,则跳转至中断处理程序尾部           
            bcf      INTCON, INTF      ; 清除外设中断标志位  
            banksel  PORTD_SHADOW 
            btfss    PORTD_SHADOW,0    ; 左移到L1后重新从L8开始
            goto     NEXT1
            goto     NEXT2
       NEXT1
            bcf      STATUS,C
            goto     NEXT3
       NEXT2
            bsf      STATUS,C
            goto     NEXT3
       NEXT3 
            RRF      PORTD_SHADOW      ; 右移一位
            goto     EndOfInt          ; 跳转至中断处理程序尾部                     
EndOfInt  
    movf         pclath_temp,w         ; 出栈
    movwf        PCLATH       
    movf         status_temp,w    
    movwf        STATUS                
    swapf        w_temp,f
    swapf        w_temp,w           
;********************************************************************** 
    retfie                             ;  中断返回      

;--------------------------------------Main的代码--------------------------------
main       
;************************开发板显示界面的通用初始化*******************************
           banksel      TRISD                 ; 选择bank1
           clrf         TRISD                 ; 设置RD0-RD7为输出模式
           bcf          TRISE, PSPMODE        ; 设置D端口为I/O端口模式      
           call         HC595_Init            ; 74HC595初始化
           movlw        0x00;                 ; 写0x00数据,关掉LED点阵显示
           call         HC595_Write_Byte      
           call         TurnOff_7LEDs         ; 调用子程序,关闭七段码LED 
;*************************************************************************
           banksel      OPTION_REG            ; 选择bank1      
           bsf          OPTION_REG, NOT_RBPU  ; 关闭上拉电阻使能
           bcf          OPTION_REG, INTEDG    ; RB0下降沿输入
           bcf          TRISB, RB5            ; RB5设置成输出
           bsf          TRISB, RB0            ; RB0设置成输入
           banksel      PORTB                           
           bcf          PORTB, RB5            ; RB5输出0  
           bcf          INTCON, INTF          ; 清外设中断标志
           bsf          INTCON, INTE          ; 开外设中断
           bsf          INTCON, GIE           ; 开总中断
          
           movlw        b'01111111'
           movwf        PORTD_SHADOW     
Loop              
           movf         PORTD_SHADOW, w       ; 将中断处理结果移入w寄存器 
           movwf        PORTD                  
           goto         Loop
;--------------------------------------------Main函数结束--------------------------


;--------------------------------------------子函数--------------------------------
;********HC595_Init******************
HC595_Init                              ; 初始化 74HC595
          banksel     TRISA             
          bcf         TRISA, 5          ; SCK_595
          bcf         TRISE, 0          ; RCK_595
          bcf         TRISC, 0          ; SER_595
          return                             ;
;********HC595_Write_Byte***********
HC595_Write_Byte                ; 设置 74HC595选中的行,具体的行数由W寄存器的值决定
          banksel     D1                        
          movwf       D1                         
          movlw       .8                           
          movwf       i                             
Loop_595
          btfsc      D1, 7                    
          goto       SET1_595          
          goto       SET0_595          
SET1_595
          bsf        PORTC, 0           
          goto       Clock_595         
 SET0_595
          bcf        PORTC, 0           
          goto       Clock_595         
Clock_595
          nop                                      
          bcf        PORTA, 5                     
          RLF        D1, f                     
          bsf        PORTA, 5           
          decfsz     i, f                         
          goto       Loop_595               
          bcf        PORTE, 0          
          nop                                     
          bsf        PORTE, 0                  
          nop   
          return                               
;********TurnOff_7LEDs ***********
TurnOff_7LEDs                    ; 关闭七段码显示器
          banksel    ADCON1      
          movlw      0x8E;
          movwf      ADCON1               
          bcf        TRISA, 2      
          bcf        TRISA, 3      
          bcf        TRISA, 4      
          banksel    PORTA        
          bsf        PORTA, 2   
          bsf        PORTA, 3   
          bsf        PORTA, 4   
          return                         
;*************************************************************
END                              ; 程序结束

二、编写程序,主程序Main点亮LED,持续1S后,关闭LED,进入休眠状态。使用RB0的外部中断唤醒CPU,重复上述的点亮、持续、关闭、休眠过程。

;********************************************************************************
; 跳线接法:用短接帽短接P14
; 功能描述: 编写程序,主程序Main点亮LED,持续1S后,关闭LED,进入休眠状态。
           ;使用RB0的外部中断唤醒CPU,重复上述的点亮、持续、关闭、休眠过程。
;*******************************************************************************

 list       p=16f877A       ; 标明所用的处理器类型
 #include   <p16f877A.inc>  ; 调用头文件 
 __CONFIG _CP_OFF & _WDT_OFF & _BODEN_OFF & _PWRTE_OFF & _HS_OSC & _WRT_OFF & _LVP_OFF & _CPD_OFF;熔丝位配置字
; _CP_OFF:    代码保护关闭
; _WDT_OFF:   看门狗关闭
; _BODEN_OFF: 低压复位关闭
; _PWRTE_OFF: 上电延时计数关闭
; _HS_OSC :   外部高速振荡器使能
; _WRT_OFF :  写程序存储器保护关闭 
; _LVP_OFF :  低电压编程关闭
; _CPD_OFF :  EEPROM存储器代码保护

;***** 变量声明*******************************************************
D1            EQU   0x20        ; 变量1,在HC595的初始化中使用
L1            EQU  0x79         ; 延时函数循环变量
L2            EQU  0x7A         ; 延时函数循环变量
L3            EQU  0x7B         ; 延时函数循环变量
i             EQU  0x7C
w_temp        EQU   0x7D        ; 中断现场保护
status_temp   EQU   0x7E        ; 中断现场保护
pclath_temp   EQU   0x7F        ; 中断现场保护             
;**********************************************************************
    ORG         0x0000          ; 复位入口地址
    nop                         ; 与ICD调试配合的nop
            movlw   high(main)    
            movwf   PCLATH         
    goto        main            ; 跳转到Main
;**********************************************************************
    ORG         0x0004          ; 中断向量入口地址
    movwf   w_temp              ; 入栈保护
    movf    STATUS,w                    
    movwf   status_temp        
    movf    PCLATH,w      
    movwf   pclath_temp   
;**********************************************************************
            clrf     PCLATH            ; 设定PCLATH指向page0,即中断程序所在页面
            btfss    INTCON, INTE      ; 是否开外设中断
            goto     EndOfInt          ; 否,则跳转至中断处理程序尾部
            btfss    INTCON, INTF      ; 是否置位外设中断的标志
            goto     EndOfInt          ; 否,则跳转至中断处理程序尾部           
            bcf      INTCON, INTF      ; 清除外设中断标志位  
            goto     EndOfInt          ; 否,则跳转至中断处理程序尾部                      
EndOfInt  
    movf     pclath_temp,w             ; 出栈
    movwf    PCLATH       
    movf     status_temp,w    
    movwf    STATUS                
    swapf    w_temp,f
    swapf    w_temp,w           
;********************************************************************** 
    retfie                             ;  中断返回      


;-------------------------------Main的代码--------------------------------------
main       
;***********************开发板显示界面的通用初始化******************************
           banksel      TRISD                 ; 选择bank1
           clrf         TRISD                 ; 设置RD0-RD7为输出模式
           bcf          TRISE, PSPMODE        ; 设置D端口为I/O端口模式      
           call         HC595_Init            ; 74HC595初始化
           movlw        0x00;                 ; 写0x00数据,关掉LED点阵显示
           call         HC595_Write_Byte      
           call         TurnOff_7LEDs         ; 调用子程序,关闭七段码LED 
;*************************************************************************
           banksel      OPTION_REG            ;  选择bank1      
           bsf          OPTION_REG, NOT_RBPU  ; 关闭上拉电阻使能
           bcf          OPTION_REG, INTEDG    ; RB0下降沿输入
           bcf          TRISB, RB5            ; RB5设置成输出
           bsf          TRISB, RB0            ; RB0设置成输入
           banksel PORTB                      ; RB5输出0
           bcf          PORTB, RB5                  
           bcf          INTCON, INTF          ; 清外设中断标志
           bsf          INTCON, INTE          ; 开外设中断
           bsf          INTCON, GIE           ; 开总中断
           
           movlw       b'11111111'
           movwf       PORTD  
  NEXT 
           bcf          PORTD,RD0
           movlw        .100
           call         Delay1S
           bsf          PORTD,RD0
           SLEEP
           goto         NEXT
;-------------------------------------Main函数结束--------------------------------

;------------------------------------子函数----------------------------------------
;********HC595_Init******************
HC595_Init                              ; 初始化 74HC595
          banksel TRISA             
          bcf         TRISA, 5          ; SCK_595
          bcf         TRISE, 0          ; RCK_595
          bcf         TRISC, 0          ; SER_595
          return                             
;********HC595_Write_Byte***********
HC595_Write_Byte                  ; 设置 74HC595选中的行,具体的行数由W寄存器的值决定
          banksel  D1                        
          movwf    D1                         
          movlw    .8                           
          movwf    i                              
Loop_595
          btfsc    D1, 7                    
          goto     SET1_595          
          goto     SET0_595          
SET1_595
          bsf      PORTC, 0           
          goto     Clock_595         
SET0_595
          bcf      PORTC, 0           
          goto     Clock_595         
Clock_595
          nop                                      
          bcf      PORTA, 5                      
          RLF      D1, f                     
          bsf      PORTA, 5           
          decfsz   i, f                         
          goto     Loop_595               
          bcf      PORTE, 0          
          nop                                     
          bsf      PORTE, 0                  
          nop   
          return                               
;********TurnOff_7LEDs ***********
TurnOff_7LEDs                    ; 关闭七段码显示器
          banksel  ADCON1      
          movlw    0x8E;
          movwf    ADCON1                
          bcf      TRISA, 2      
          bcf      TRISA, 3      
          bcf      TRISA, 4      
          banksel  PORTA        
          bsf      PORTA, 2   
          bsf      PORTA, 3   
          bsf      PORTA, 4   
          return                         
;**************DelayUS**************
Delay1S                           ; 延时1秒
          movwf   L1                 
Loop1 
          movlw   .200               
          movwf   L2                              
          Loop2
          movlw   .62          
          movwf   L3                          
          Loop3 
          nop                    
          decfsz  L3, f          
          goto    Loop3          
          decfsz  L2, f           
          goto    Loop2           
          decfsz  L1, f                
          goto    Loop1                
          return                          
;******************************************************************************
END                                        ; 程序结束