PIC的中断系统

2019-04-15 13:03发布

一、编写程序,使用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 ; 程序结束