「嵌入式开发」 CC2530卷一 外部中断控制

关键字:CC2530、ZigBee
摘要: 关于CC2530的学习总结1

一 InitLed初始化部分

  • P0DIR、P1DIR和P2DIR
    P0DIR指端口0的方向寄存器,用于配制端口P0_0到P0_7的方向(输入为0,输出为1)
    P1DIR指端口1的方向寄存器,用于配制端口P1_0到P1_7的方向(输入为0,输出为1)
截屏2022-03-01 上午11.10.17.png
  • P0SEL、P1SEL和P2SEL功能选择寄存器

同理对应0_0,1_0等端口方向。(0为通用IO,1为外设功能)

截屏2022-03-01 上午11.24.36.png

【赋值问题?】

将根据表格一一对应的二进制转换为十六进制。(记得学会使用科学计算器哦)

截屏2022-03-01 下午2.23.16.png 截屏2022-03-13 下午3.26.31.png

二 InitKey初始化部分

  • 按键key的引脚原理

    注意!当P0_1为低电平0说明被按下,高电平为抬起状态。

截屏2022-03-01 下午2.47.05.png

  • 读取按键状态的keyScan

截屏2022-03-01 下午3.02.04.png

三 通过按键中断控制LED

CC2530共18个中断源,即可以设置这18个中断源的优先级完成项目要求。

截屏2022-03-01 下午3.18.02.png

格式要求如下:

截屏2022-03-01 下午3.22.04.png

截屏2022-03-01 下午3.22.04.png

在配置中断的过程中,需要配置如下四个寄存器

截屏2022-03-01 下午3.23.26.png

S1按键的中断函数例子

截屏2022-03-01 下午3.25.42.png

四 代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
//********************************************************************
//describe:use key to achieve EXTI for circle_led and breath_led.
//*********************************************************************

#include <ioCC2530.h>
#include <stdio.h>
#include <stdbool.h>

#define uint unsigned int
#define uchar unsigned char


//定义控制灯的端口
#define LED1 P1_4 //定义 LED1 为 P14 口控制
#define LED2 P0_1 //定义 LED2 为 P01 口控制
#define LED3 P1_0 //定义 LED3 为 P10 口控制
#define LED4 P1_1 //定义 LED4 为 P11 口控制

#define S5 P0_4 //宏定义 P0_4 为 S5 的控制端口
#define S6 P0_5 //宏定义 P0_5 为 S6 的控制端口
#define KEY5 5 //宏定义按键 S5 的返回值为 5
#define KEY6 6 //宏定义按键 S5 的返回值为 6
bool S6_FLAG = 0; //S6相关标志位
int S5_flag = 0; //S5相关标志位


//函数声明
void Delay(uint n); //延时函数
void Init_led(void); //初始化 LED 控制函数
void EXTI_Init(void); //初始化 TIMER1 控制函数
void Clock_Init(void); //初始化时钟函数

void circle_led(void); //流水灯函数
void breath_led(void); //呼吸灯
void breath_circle_led(void); //呼吸流水灯


/****************************
//延时函数
*****************************/
void Delay(uint n)
{
uint i,j;
for(i = 0;i<n;i++)
{
for(j = 0;j<100;j++);
}
}


/****************************
//初始化 LED 程序
*****************************/
void Init_led(void)
{
P1SEL &= ~0X13; //定义 P1_4 P1_1 P1_0 为普通IO //0001 0011
P1DIR |= 0x13; //P1_4 定义为输出
LED1 = 1; //LED 灯初始化为关

P0SEL &= ~0X02; //定义 P0_1为普通IO //0000 0010
P0DIR |= 0x02; //P0_1 定义为输出
LED2 = 1; //LED 灯初始化为关

//P1SEL &= ~0X00; //定义 P1_0为普通IO //0000 0000
//P1DIR |= 0x00; //P1_0 定义为输出
LED3 = 1; //LED 灯初始化为关

//P1SEL &= ~0X02; //定义 P1_1为普通IO //0000 0010
//P1DIR |= 0x02; //P1_1 定义为输出
LED4 = 1; //LED 灯初始化为关
}


/****************************
//初始化 中断触发 程序
*****************************/
void EXTI_Init(void)
{
P0INP &= ~0x30; // P0_4 P0_5 0011 0000
P0IEN |= 0x30;
PICTL |= 0X00; // 0000 0000
IEN1 |= 0x20; //0010 0000
P0IFG = 0;
EA = 1;
}


/****************************
//初始化时钟
*****************************/
void Clock_Init(void)
{
CLKCONCMD &= ~0x40; //系统时钟源选择:外部32MHz 。
while(CLKCONSTA & 0x40);//等待晶振稳定
CLKCONCMD &= ~0x47; //128分频 CLKSPD不发分频
}


/****************************
//流水灯函数
*****************************/
void circle_led(void)
{
while(1)
{
LED1 = 0;
LED2 = 1;
LED3 = 1;
LED4 = 1;
Delay(10000);
LED1 = 1;
LED2 = 0;
LED3 = 1;
LED4 = 1;
Delay(10000);
LED1 = 1;
LED2 = 1;
LED3 = 0;
LED4 = 1;
Delay(10000);
LED1 = 1;
LED2 = 1;
LED3 = 1;
LED4 = 0;
Delay(10000);
if(P0IFG&0X10 || P0IFG&0X20)
{
break;
}
}
}



/****************************
//呼吸流水灯函数
*****************************/
void breath_circle_led(void)
{
int stime=0,htime=0;
int pwm=0;
int num_led=0;

while(1)
{
LED2=1;
stime++;
if(stime>=1000) stime=0;
if(stime>pwm)
{
if(num_led>8000) num_led = 0;
if(num_led<2000)
{
LED1=0;
LED2=1;
LED3=1;
LED4=1;
}
else if(num_led<4000 && num_led>2000)
{
LED1=1;
LED2=0;
LED3=1;
LED4=1;
}
else if(num_led<6000 && num_led>4000)
{
LED1=1;
LED2=1;
LED3=0;
LED4=1;
}
else
{
LED1=1;
LED2=1;
LED3=1;
LED4=0;
}
}
else
{
if(num_led>8000) num_led = 0;
if(num_led<2000)
{
LED1=1;
LED2=1;
LED3=1;
LED4=1;
}
else if(num_led<4000 && num_led>1800)
{
LED1=1;
LED2=1;
LED3=1;
LED4=1;
}
else if(num_led<6000 && num_led>4000)
{
LED1=1;
LED2=1;
LED3=1;
LED4=1;
}
else
{
LED1=1;
LED2=1;
LED3=1;
LED4=1;
}
}
if(stime%100==0)
{
num_led++;
if(htime==0)
{
pwm++;
if(pwm>1000)
htime=1;
}
if(htime==1)
{
pwm--;
if(pwm<0)
htime=0;
}
}

if(P0IFG&0X10 || P0IFG&0X20)
break;

}
}



/****************************
//LED1呼吸灯函数
*****************************/
void breath_led(void)
{
int stime=0,htime=0;
int pwm=0;
while(1)
{
stime++;
if(stime>=1000) stime=0;
if(stime>pwm) LED1=0;
else LED1=1;
if(stime%100==0)
{
if(htime==0)
{
pwm++;
if(pwm>1000)
htime=1;
}
if(htime==1)
{
pwm--;
if(pwm<0)
htime=0;
}
}

if(P0IFG&0X10 || P0IFG&0X20)
break;
}

}



/***************************
//主函数
***************************/
void main(void)
{
Clock_Init();
EXTI_Init();
Init_led();
circle_led();

while(1){

Delay(5);
}

}


/***************************
//中断服务函数
****************************/
#pragma vector = P0INT_VECTOR
__interrupt void P0_ISR(void)
{
if(P0IFG&0X10) //S5按下
{
P0IFG = 0x00;
if(S5_flag==0) //LED全亮
{
LED1 = 0;
LED2 = 0;
LED3 = 0;
LED4 = 0;
S5_flag=1;
}
else if(S5_flag==1) //LED全灭
{
LED1 = 1;
LED2 = 1;
LED3 = 1;
LED4 = 1;
S5_flag=0;
}
}


else if(P0IFG&0X20) // S6按下
{
P0IFG = 0x00;
LED2 = 1;
LED3 = 1;
LED4 = 1;
LED1 = 1;
S6_FLAG = !S6_FLAG; //改变S6标志位
if(S6_FLAG==1) breath_led();
else if(S6_FLAG==0) breath_circle_led();
}
}

六 结语

完成了各引脚的基本配置(PxDIR、PxSEL)和中断的基本配置(四个)后,我们通过外部中断(Key)控制了小灯点亮。

下一步将继续就串口通信的部分进行学习和练习。

七 文献及资料整理

「资料整理」

·Torch目录