CC2530 学习笔记

需要使用的软件有:

  • IAR Embedded Workbench IDE

  • SmartRF Flash Programmer

硬件:

  • 一个 CC Debugger 仿真器、USB 充电器

  • 蓝色 zigbee 智能节点盒及其充电器

  • 一台装有职业院校技能大赛物联网专用 win10 系统的 PC

IAR 创建工程文件

  1. 创建一个空目录

  2. 打开 IAR 软件,创建一个空 workspace(工作区) File -> New -> Workspace

  3. 创建工程 Project -> Create New Project... -> Tool chain 选 8051, Empty project -> OK -> 弹出的窗口找到新建的空目录,把保存文件名字改下 -> 保存

  4. 基础设置 在软件的左边 Workspace 区的工程文件上右击 -> 选 Options... -> 在 Device 框 点击右边的 ... -> 弹出窗口下拉找到 Texas Instruments 打开 -> 选 CC2530F2256.i51 文件打开 -> 在 Debugger 栏 -> Driver 下拉菜单找到 Texas Instruments 点击 -> 在 Linker 栏 -> Output -> Output file -> 勾选 Override default -> 文件名可以不改,把后缀名改成. hex 就行 -> Format -> 勾选 Other 单选框,Output format 默认 inter-extended,如果不是,请改正 -> OK

  5. 新建文件,然后把文件保存到空目录下 File -> New -> File

  6. 右击左边的工程文件 -> Add -> Add "main.c": main.c 是新建的文件

  7. 创建 eww 工作区文件 Project -> Rebuild All -> 在当前目录下保存

将寄存器中的某些位清 0 或置 1

基本思路: 将要操作的位置为 1,如果是与运算,则要使用到取反 (~) 操作符

需要用到 16 进制的 8421 法则

将某些位置 1 同时不影响其他位

操作 |=

任何值与 0 相或,保持原值;

任何值与 1 相或,结果为 1;

将某些位置 0 同时不影响其他位

操作 &=:

任何值与 1 相与,保持原值;

任何值与 0 相与,结果为 0;

CC2530 端口引脚概述

  • 采用 QFN40 封装,有 40 个引脚。

  • 有 21 个数字 I/O 端口,其中 P0 和 P1 是 8 个引脚,P2 仅有 5 个可以使用。

  • 实际开发可用 I/O 端口只有 17 个

  • 可配置为通用 I/O 端口,或外部设备 I/O

  • 输入端口具备上拉或下拉能力

  • 每个 I/O 端口都可以配置成外围中断源的输入引脚

  • P1_0 和 P1_1 都没有上拉 / 下拉能力

  • P1_0 和 P1_1 具备 20mA 搞驱动输出,其余 I/O 引脚是 4mA 的驱动能力

在程序编写中,引入头文件 #include <iocc2530.h>

与通用 I/O 端口相关的常用寄存器有下面 4 个:

  1. PxSEL: 端口功能选择,设置端口是通用 I/O 还是外设功能端口。置为 0,端口设置为通用 I/O 模式;置为 1,端口设置为外设功能

  2. PxDIR: 端口方向选择,作为通用 I/O 时,用来 设置数据的传输方向。置为 0,输入;置为 1,输出

  3. PxINP: 作为通用输入端口时,选择输入模式上拉下拉 还是 三态(高电平、低电平、高阻态)。置为 0,上拉 / 下拉;置为 1,三态

    1. P0INP,对上拉 / 下拉控制,需要结合 P2INP 实现
  4. Px: 数据端口,用来 控制端口的输入 获取端口的输入

1
2
3
4
P0SEL&=~0x06;
P0DIR|=0x06;
P0INP&=~0x06;
P2INP&=~0x20;

按键扫描

基本原理:

按键的两个引脚,一端 通过电阻上拉到高电平,一端 接地

没有按键按下 时,输入引脚为 高电平;同理,按下时,则为 低电平

扫描原理:通过 反复读取按键输入引脚的信号,然后 识别高低电平 来判断 是否有按键触发

按键去抖动

通过这个操作可以规避一些干扰信号,从而获取真实的按键触发信号

去抖动原理:

由于抖动产生的低电平往往都很短,所以可以分两次检测,如果第一次是低电平,延迟一会,进一步判断,如果还是低电平,则为真实信号,否则为干扰

代码实例:

1
2
3
4
5
6
7
8
9
10
11
uint Key_Check(void){
// 按下 K1 为低电平,置为 0;未按下 K1 为高电平,置为 1
if(K1 == 0){
Delay(5000);
if(K1 == 0){
return(0);
}
}
return(1);
}

CC2530 的中断系统

CC2530 的 P0、P1、P2 端口中的每个引脚都具有 外部中断输入功能,要使某些引脚具有外部中断功能,需要对 IENx 寄存器、PxIEN 寄存器和 PICTL 寄存器 进行适当的设置

PxIEN 寄存器 外部中断功能

PICTL 寄存器 端口输入信号控制

P0、P1 和 P2 端口分别使用 P0IF、P1IF 和 P2IF 作为 中断标志位,端口组上的任何一个引脚产生 外部中断 时,都会将 对应端口组的中断标志为自动置位

端口状态标志 寄存器 P0IFG、P1IFG 和 P2IFG,分别对应 3 个端口中隔音教的中断触发状态,当某引脚产生了 设定的外部中断触发信号 时,该寄存器 对应的标志位会自动置位

外部中断标志 PxIF 和 PxIFG 必须在中断服务函数中 **手工清除 **,否则 CPU 会反复进入中断

先清除 PxIFG,再清除 PxIF

外部中断相关的寄存器:

寄存器置 0 中断禁止,置 1 中断使能

IEN1 的第 5 位:P0IE(端口 0 中断使能)

IEN2 的第 4 位:P1IE(端口 1 中断使能),IEN2 的第 1 位:P2IE(端口 2 中断使能)

Px(P0&P1&P2)IEN 寄存器和 PICTL 寄存器 (置 0 上升沿触发,置 1 下降沿触发)

例:将 P1_2 和 P1_4 设置为外部中断引脚,P1_2 下降沿触发,P1_4 上升沿触发,使能相关中断控制位

1
2
3
4
5
6
7
8
9
10
void Init_INTP1(){
P1SEL &= ~0x14; //P1_2 和 P1_4 设置为通用 I/O 端口,
P1DIR &= ~0x14; //P1_2 和 P1_4 设置为输入模式
//CC2530 芯片复位后,I/O 引脚被配置成带上拉的输入模式,故上述两行代码可省略。
PICTL |= 0x02; //P1_2 的外部中断信号设置为下降沿触发
PICTL &= ~0x04; //P1_4 的外部中断信号设置为上升沿触发
P1IEN |= 0x14; //P1_2 和 P1_4 使能位外部中断引脚
IEN2 |= 0x10; // 使能 P1 端口外部中断
EA = 1; // 打开总中断
}
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
//SW2(P0_1) 初始化
void Init_INTP0(){
P0SEL &= ~0x02; // 设置为 I/O

P0DIR &= ~0x02; // 设置为输入

P0INP &= ~0x02; // 设置为上拉 / 下拉

P2INP &= ~0x20; // 设置为上拉

IEN1 |= 0x20; // 设置 P0 端口的中断使能

P0IEN |= 0x02; // 设置 P0_1 这个引脚为中断使能

PICTL |= 0x01; // 设置 P0 端口为下降沿触发

EA = 1; // 打开总中断
}

//4 个 LED 灯初始化
void Init_Port(){
P1SEL &= ~0x1B; // 把 P1_4、P1_3、P1_1、P1_0 四个端口设置为 I/O 模式

P1DIR |= 0x1B; // 把 4 个端口设置为输出

P1 &= ~0x1B; //4 个 LED 灯设置为 0(灭)
}

// 中断服务函数
#pragma vector = P0INT_VECTOR // 向量可以在 ioCC2530.h 头文件中 "Interrupt Vectors" 找
__interrupt void Service_INIP0(){
//P0IFG
if((P0IFG & 0x02) == 0x02)
D5 = ~D5;

P0IFG = 0; // 手动置 0;先 IFG,后 IF
P0IF = 0;
}

// 延时函数
void Delay(unsigned int t){
while(t--);
}

void main(){
Init_Port();
Init_INTP0();
while(1){
D4 = 1;
Delay(60000);
Delay(60000);
D4 = 0;
Delay(60000);
Delay(60000);
}
}

端口组中断使能 -> 端口组具体引脚中断使能 -> 上升 (0)、下降(1) 沿触发 -> 总中断使能