CC2541蓝牙学习——通用I/O中断

标签:
it蓝牙 |
分类: 蓝牙 |
学习目标:掌握中断使能寄存器IEN0、IEN1、IEN2,中断标志寄存器PxIFG、IRCON、IRCON2,端口中断触发沿控制寄存器PICTL
CC2541有18个中断源,每个中断源都可以产生中断请求,这18个中断源如下
中断请求通过SFR寄存器IEN0、IEN1、IEN2使能或禁止,定义如下:
其中IEN0和IEN1可以位寻址,寄存器IEN2不可以位寻址
EA:1开总中断
IEN1.P0IE:P0端口中断使能
IEN2.P1IE:P1端口中断使能
IEN2.P2IE:P2端口中断使能
IEN1寄存器的第5位控制P0口的中断,当设置IEN1.P0IE时,将设置P0端口所有引脚的中断使能
IEN2寄存器的第4位和第1位分别控制P1端口和P2端口,控制P1和P2端口的所有引脚中断使能
如果要对P0、P1、P2端口具体某一个引脚设置使能,则需要设置寄存器P0IEN、P1IEN、P2IEN,其定义如下:
0xAB、0x8D、0xAC 不可位寻址
端口 | Bit位 | 名称 | 初始化 | 读写 | 描述 |
P0IEN | 7:0 | P0_[7:0]IEN | 0x00 | R/W | 端口0,位7至位0中断使能。0:中断禁止;1:中断使能 |
P1IEN | 7:0 | P1_[7:0]IEN | 0x00 | R/W | 端口1,位7至位0中断使能。0:中断禁止;1:中断使能 |
P2IEN | 7:6 | --- | 00 | R0 | 未使用 |
P2IEN | 5 | DPIEN | 0 | R/W |
USB |
P2IEN | 4:0 | P2_[4:0]IEN | 00000 | R/W | 端口2,位4至位0中断使能。0:中断禁止;1:中断使能 |
所以通用I/O口中断使能有三层:总中断使能、端口中断使能、引脚中断使能
I/O中断除了配置中断使能之外,还需要配置中断触发方式,中断触发方式可由端口中断控制寄存器PICTL设置,I/O中断触发方式分为输入的上升沿触发和下降沿触发,PICTL寄存器定义如下:
0x8c 不可位寻址
端口 | Bit位 | 名称 | 初始化 | 读写 | 描述 |
PICTL | 7 | PADSC | 0 | R/W | 强制引脚在输出模式。选择输出驱动能力,由DVDD引脚提供。0:最小驱动能力;1:最大驱动能力 |
PICTL | 6:4 | --- | 000 | R0 | 未使用 |
PICTL | 3 | P2ICON | 0 | R/W | 端口2,引脚4至0输入模式下的中断配置,0:输入的上升沿引起中断;1:输入的下降沿引起中断 |
PICTL | 2 | P1ICONH | 0 | R/W | 端口1,引脚7至4输入模式下的中断配置,0:输入的上升沿引起中断;1:输入的下降沿引起中断 |
PICTL | 1 | P1ICONL | 0 | R/W | 端口1,引脚3至0输入模式下的中断配置,0:输入的上升沿引起中断;1:输入的下降沿引起中断 |
PICTL | 0 | P0ICON | 0 | R/W |
端口0,引脚7至0输入模式下的中断配置,0:输入的上升沿引起中断;1:输入的下降沿引起中断 |
与中断使能有三层类似,中断标志也有两层,分别为端口中断标志和引脚中断标志
端口中断标志位在寄存器IRCON和IRCON1中,分别为P0IF、P1IF、P2IF,都可以位寻址
由于CC2541的外部中断共用一个中断向量,因此需要判断是哪个引脚发生中断,通过判断中断状态标志寄存器(P0IFG,P1IFG,P2IFG)可以判断是哪一个引脚发生中断,寄存器定义如下:
0x89、0x8A、0x8B 不可位寻址
端口 | Bit位 | 名称 | 初始化 | 读/写 | 描述 |
P0IFG | 7:0 | P0IF[7:0] | 0x00 | R/W0 | 端口0,位7至位0输入中断状态标志。0:未发生中断,1:发生中断 |
P1IFG | 7:0 | P1IF[7:0] | 0x00 | R/W0 | 端口1,位7至位0输入中断状态标志。0:未发生中断,1:发生中断 |
P2IFG | 7:5 | --- | 000 | R0 | 未使用 |
P2IFG | 4:0 | P2IF[4:0] | 0x00 | R/W0 |
端口2,位4至位0输入中断状态标志。0:未发生中断,1:发生中断 |
通用I/O口中断配置过程:
- 设置需要发生中断的I/O口为通用I/O口,配置寄存器PxSEL
- 设置I/O口为输入方式,配置寄存器PxDIR
- 清除中断标志,对应的寄存器PxIFG状态标志位置0
- 设置I/O口的中断触发方式
- 开端口中断,设置对应引脚的端口的中断使能位为1,设置寄存器IEN0或IEN1
- 开总中断,设置IEN0中的EA为1
01 void InitKey(void)
02 {
03 P0SEL &= ~0x02;
//P0.1设置为通用I/O口
04 P0DIR &= ~0x02;
//P0.1设置为输入
05 P0IFG &= ~0x02;
//P0.1中断状态标志位清0
06 PICTL |= 0x00;
//P0端口下降沿触发
07 P0IEN |= 0x02;
//P0.1中断使能
08 IEN1 |= 0x20;
//端口P0中断使能
09 EA = 1;
//开总中断
10 }
02
03
04
05
06
07
08
09
10
- 判断引脚中断是否发生(如果该端口只有一个引脚中断,可以不判断)
- 完成具体中断工作
- 清引脚中断标志,PxIFG对应引脚位清0(必须软件清0,不清0的话中断服务程序反复执行)
- 清端口中断标志,P0IF/P1IF/P2IF位清0(实验验证端口中断标志不清0也可以,但是该位不会自动清0,需要软件清0,为了保险,统一为清0)
01
07 #pragma vector = P0INT_VECTOR
08 __interrupt void P0_ISR(void)
09 {
10 if(0x02 & P0IFG)
//判断按键中断
11 {
12
//具体功能代码
13 }
14 P0IFG = 0;
//清中断标志
15 P0IF = 0;
//清中断标志,IRCON[5],P0口中断
16 }
07
08
09
10
11
12
13
14
15
16
示例程序:按键控制LED灯
01
08 #include
09 #include
"delay.h"
10
11 typedef unsigned char uchar;
12 typedef unsigned int uint;
13
14 #define
LED1 P1_0
15 #define LED2 P1_1
16 #define
LED3 P1_4
17 #define
KEY P0_1
18
19
25 void InitLED(uchar mode)
26 {
27 P1SEL &= ~0x13;
//P1.0,P1.1,P1.4设置为通用I/O口
28 P1DIR |= 0x13;
//P1.0,P1.1,P1.4设置为输出
29 LED1 = mode;
//LED灯亮熄控制
30 LED2 = mode;
31 LED3 = mode;
32 }
33
34
40 void InitKey(void)
41 {
42 P0SEL &= ~0x02;
//P0.1设置为通用I/O口
43 P0DIR &= ~0x02;
//P0.1设置为输入
44 P0IFG &= ~0x02;
//P0.1中断状态标志位清0
45 PICTL |= 0x00;
//P0端口下降沿触发
46 P0IEN |= 0x02;
//P0.1中断使能
47 IEN1 |= 0x20;
//端口P0中断使能
48 EA = 1;
//开总中断
49 }
50
51
57 #pragma
vector = P0INT_VECTOR
58 __interrupt void P0_ISR(void)
59 {
60 if(0x02 & P0IFG)
//判断按键中断
61 {
62
LED1 = !LED1;
//流水灯
63
Delay1ms(1000);
//延时1s
64
LED2 = !LED2;
65
Delay1ms(1000);
66
LED3 = !LED3;
67
Delay1ms(1000);
68 }
69 P0IFG = 0;
//清中断标志
70 P0IF = 0;
//清中断标志,IRCON[5],P0口中断
71 }
72
73
76 int main(void)
77 {
78 InitLED(0);
//LED初始化,熄灭LED1~3
79 InitKey();
//按键中断初始化
80
81 while(1)
82 {
83 }
84 }
08
09
10
11
12
13
14
15
16
17
18
19
25
26
27
28
29
30
31
32
33
34
40
41
42
43
44
45
46
47
48
49
50
51
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
76
77
78
79
80
81
82
83
84
前一篇:CC2541蓝牙学习——I/O口