实验3:按键中断控制LED
1.中断使能的步骤
1)使能总中断
2)端口中断使能
3)位中断使能
4)触发沿设置
2.相关寄存器
1)中断使能寄存器(IENx)
i)IEN0(可位寻址):其最高位表示EA(使能总中断)。所以在使能总中断的时候可以EA=1或IEN1 |=0x80;
ii)IEN1(可位寻址):可以用来使能端口0,也可用来使能定时器(具体请查手册)
iii)IEN2(不可位寻址):可以用来使能端口1和端口2,只能采用整体赋值的方式
2)端口x位中断使能(以P0IEN为例)
3)PICTL(端口中断控制)
4)PxIFG:端口x位中断标志
5)PxIF端口x中断标志
P0IF和P1IF,P2IF位于不同的寄存器,但都是相应位为1表示中断未决
【注意】在进入中断服务函数后,PxIFG,PxIF通常需要手动清除。
清除时,通常先清PxIFG,后清PxIF。
3.中断服务函数的框架
#pragma vector = 中断名称_VECTOR
__interrupt void 函数名,可任意(void)
{
//程序代码,略
}
中断名称的查询可打开iocc2530.h进行查看(见下表)
/* ------------------------------------------------------------------------------------------------
* Interrupt Vectors
* ------------------------------------------------------------------------------------------------
*/
#define RFERR_VECTOR VECT( 0, 0x03 ) /* RF TX FIFO Underflow and RX FIFO Overflow */
#define ADC_VECTOR VECT( 1, 0x0B ) /* ADC End of Conversion */
#define URX0_VECTOR VECT( 2, 0x13 ) /* USART0 RX Complete */
#define URX1_VECTOR VECT( 3, 0x1B ) /* USART1 RX Complete */
#define ENC_VECTOR VECT( 4, 0x23 ) /* AES Encryption/Decryption Complete */
#define ST_VECTOR VECT( 5, 0x2B ) /* Sleep Timer Compare */
#define P2INT_VECTOR VECT( 6, 0x33 ) /* Port 2 Inputs */
#define UTX0_VECTOR VECT( 7, 0x3B ) /* USART0 TX Complete */
#define DMA_VECTOR VECT( 8, 0x43 ) /* DMA Transfer Complete */
#define T1_VECTOR VECT( 9, 0x4B ) /* Timer 1 (16-bit) Capture/Compare/Overflow */
#define T2_VECTOR VECT( 10, 0x53 ) /* Timer 2 (MAC Timer) */
#define T3_VECTOR VECT( 11, 0x5B ) /* Timer 3 (8-bit) Capture/Compare/Overflow */
#define T4_VECTOR VECT( 12, 0x63 ) /* Timer 4 (8-bit) Capture/Compare/Overflow */
#define P0INT_VECTOR VECT( 13, 0x6B ) /* Port 0 Inputs */
#define UTX1_VECTOR VECT( 14, 0x73 ) /* USART1 TX Complete */
#define P1INT_VECTOR VECT( 15, 0x7B ) /* Port 1 Inputs */
#define RF_VECTOR VECT( 16, 0x83 ) /* RF General Interrupts */
#define WDT_VECTOR VECT( 17, 0x8B ) /* Watchdog Overflow in Timer Mode */
4.程序代码
//功能:每当有按键按下时,改变LED1和LED2的状态
#include "iocc2530.h"
#define LED1 P1_0
#define LED2 P1_1
void Init_Port()
{
P1SEL &=~0x03;
P1DIR |=0x03;
LED1=0;
LED2=1;
P0INP &=~0x10;
P2INP &=~0x20;
}
void Init_P0INT()
{
EA=1; //使能总中断
P0IE=1; //端口0中断使能
P0IEN |=0x10; //P0_4位中断使能
PICTL |=0x01; //设置按键为下降沿触发
}
#pragma vector = P0INT_VECTOR
__interrupt void P0_ISR(void)
{
if(P0IFG>0)
{
LED1=!LED1;
LED2=!LED2;
}
P0IFG=0;
P0IF=0; //清除中断标志,别忘了!!!
}
void main()
{
Init_Port();
Init_P0INT();
while(1);
}