CC2530整理
一、IAR软件配置
1.打开Project---Options,
General Options 配置如图1.33 所示,单击圆圈所示按钮,先向上返
回上一级目录,然后打开Texas Instruments 文件夹,选择CC2530F256 芯片.
2.选择Linker—Config—Linker command file 选项。单击图1.35 所示
按钮,导出配置文件,先向上返回上一级目录,然后打开Texas Instruments 文件夹,选择lnk51ew_cc2530F256.xcl(这里是使用
CC2530F256 芯片)。
3.Debugger 选项的Driver 里选择Texas Instruments(使用编程器仿真),下面选择io8051.ddf 文件
二、IO口寄存器
1. IO 口配置我们需要配置的寄存器。(P*SEL. P*DIR. P*INP) P0----
P1INP:设置各个IO 口的输入模式,0为上拉/下拉,1为三态模式。P1INP 中只有D7~D2分别设置对应IO 口输入模式。D1D0无作用。
P2INP:D0~D4控制P2_0~P2_4的输入模式,0为上拉/下拉,
1为三态。
P2SEL:(D0到D2位)端口2功能选择,0为普通I/O 功能,1为外设功能
P2DIR :D0~D4设置P2_0到P2_4的方向
D7、D6位作为端口0外设优先级的控制
例子:
/*按照表格寄存器内容,我们对LED1,也就是P1_0 口进行配置,当P1_0 输出高电平时LED1 被点亮。所以配置如下:*/
P1SEL &=~0x01; //作为普通IO 口
P1DIR |= 0x01; //P1_0 定义为输出
P1INP |= 0X01; //打开下拉
/*由于CC2530 寄存器初始化时默认是:*/
P1SEL =0x00;
P1DIR =0x00;
P1INP =0X00;
/*所以IO 口初始化我们可以简化初始化指令:*/
P1DIR |= 0x01; //P1_0 定义为输出
P1INP |= 0X01; //打开下拉
/****************************
按键初始化函数
*****************************/
void InitKey()
{
P0SEL &= ~0X01; //设置P00 为普通IO 口
P0DIR &= ~0X01; //按键在P00 口,设置为输入模式
P0INP &= ~0x01; //打开P00 上拉电阻,不影响
}
三、外部中断
外部中断需要配置三个寄存器P*IEN 、PICTL 、P*IFG、IEN1。
PICTL:D0~D3设置各个端口的中断触发方式,0为上升沿触发,1为下降沿触发。
D7控制I/O引脚在输出模式下的驱动能力。选择输出驱动能力增强来补偿引脚DVDD 的低I/O电压,确保在较
低的电压下的驱动能力和较高电压下相同。0为最小驱动能力增强。1为最大驱动能力增强。
IEN0:中断使能0,0为中断禁止,1为中断使能
IEN1: D5为P0[7:0]中断使能位:0为中断禁止,1为中断使能,
:中断使能2,0为中断禁止,1为中断使能
IEN2
P0----
P0IFG :P0[7:0] 终端状态标志寄存器,当输入端口有中断请求时,相应的标志位置1
P0IEN : P0[7:0] 各个控制口的中断使能,0为中断禁止,1为中断使能。
P1----
P1IFG :P1[7:0] 终端状态标志寄存器,当输入端口有中断请求时,相应的标志位置1
P1IEN : P1[7:0] 各个控制口的中断使能,0为中断禁止,1为中断使能。
P2---
P2IFG:D0~D4为P2_0~P2_4的中断标志位。
D5为USD D+中断状态标志,当D+线有一个中断请求未决时设置该标志,用于检测USB挂起状态下的USB恢复事件。
当USB控制器没有挂起时不设置该标志。
P2IEN:D0~D4控制P2_0~P2_4的中断使能
D5控制USB D+的中断使能
例子:
//外部中断初始化:
void InitKey()
{
P0IEN |= 0X01; //P00 设置为中断方式
PICTL |= 0X01; // 下降沿触发
IEN1 |= 0X20; // 允许P0 口中断;
P0IFG &= ~0x10; // 初始化中断标志;
EA = 1; //开总中断
}
/****************************
中断处理函数
*****************************/
#pragma vector = P0INT_VECTOR //格式:#pragma vector = 中断向量,
// 紧接着是中断处理程序
__interrupt void P0_ISR(void)
{
// 执行代码;
P0IFG &= ~0x10; //清中断标志
P0IF = 0; //清中断标志
}
四、定时器
IRCON:中断标志4,;0为无中断请求。1为有中断请求。
TIMIF:定时器1的溢出中断屏蔽与定时器3、4的中断标志。D6为定时器1的溢出中断屏蔽,0为屏蔽,1为使能,默认为1.D5~D0为定时器3和4中各个通道的中断标志。
1. T1(查询方式)
T1CTL:定时器1的控制,D1D0控制运行模式,D3D2设置分频划分值
T1STAT:定时器1的状态寄存器,D4~D0为通道4~通道0的中断标志,D5为溢出标志位,当计数到最终技术值是自动置1。
T1CCTL0~T1CCTL4:定时器1通道0~通道4的工作方式设置。D1D0为捕捉模式选择:00为不捕捉,01为上升沿捕获,10为下降沿捕获,11为上升或下降沿都捕获。
D2位为捕获或比较的选择,0为捕获模式,1为比较模式。D5D4D3为比较模式的选择:000为发生比较式输出端置1,001为发生比较时输出端清0,010为比较时输出翻转,其他模式较少使用。
例子:
//定时器1 初始化:
void InitT1() //系统不配置工作时钟时使用内部RC 振荡器,即16MHz
{
T1CTL = 0x0d; //128 分频,自动重装0X0000-0XFFFF
//T1STAT = 0x21; //通道0, 中断有效0010 0001
}
void main(void)
{
uchar count;
//调用初始化函数
InitT1();
while(1)
{
if(IRCON>0) //查询方式
{ IRCON=0;
if(++count==1) //约1s 周期性闪烁
{
count=0;
//执行代码
}
}
}
重点:系统在不配置工作频率时默认为2 分频,即32M/2=16M,所以定时器每次溢出时T=1/(16M/128)*65536≈0.5s, 所以总时间Ta=T*count=0.5*1=0.5S切换1 次状态。
2.定时器T3/4(中断方式) (8 位)
T3 定时器主要是配置三个寄存器T3CTL,T3CCTL0,T3CC0,T3CCTL1,T3CC1。
T3CTL/T4CTL:定时器3或定时器4的方式控制寄存器。D7D6D5设置分频:000为无分频、001为2分频、010为4分频、011为8分频、100为16分频、101为32分频、110为64分频,111为128分频。D4为启动位,启动时1,停止工作为0。D3位为中断使能位,0为禁止,1为使能,默认为1;D2为复位,置1时定时器复位。D1D0为计数器模式选择:该位与T1CTL的D1D0位意义相同。
T3CCTL0/T3CCTL1/T4CCTL0/T4CCTL1:定时器3或定时器4的通道0和通道1的方式控制,D6为该通道的中断使能位,0为禁止,1为使能,默认为1;D5~D0与T1CCTL0相同
例子:
使用T3 定时器(8 位),
中断方式。寄存器配置如下:
T3CTL |= 0x08 ; //开溢出中断
T3IE = 1; //开总中断和T3 中断
T3CTL |=0XE0; //128 分频,128/16000000*N=0.5S,N=65200
T3CTL &= ~0X03; //自动重装00->0xff 65200/256=254(次)
T3CTL |=0X10; //启动
EA = 1; //开总中断
/************************************
中断函数
************************************/
#pragma vector = T3_VECTOR //定时器T3
__interrupt void T3_ISR(void)
{
IRCON = 0x00; //清中断标志, 也可由硬件自动完成
if(++count>254) //254 次中断后LED 取反,闪烁一轮(约为0.5 秒时间){
count = 0; // 计数清零
//执行代码
}
}
五、串口通讯
UART0 对应的外部设备IO 引脚关系为:
P0_2------RX
P0_3------TX
UART1 对应的外部设备IO 引脚关系为:
P0_5------RX
P0_4------TX
能够分别运行于异步USART 模式或者同步SPI 模式
USART 模式的操作具有下列特点:
1、8 位或者9 位负载数据
2、奇校验、偶校验或者无奇偶校验
3、配置起始位和停止位电平
4、配置LSB 或者MSB 首先传送
5、独立收发中断
6、独立收发DMA 触发
CC2530 配置串口的一般步骤:
1、配置IO,使用外部设备功能。此处配置P0_2 和P0_3 用作串口UART0
2、配置相应串口的控制和状态寄存器。此处配置UART0 的工作寄存器
3、配置串口工作的波特率。此处配置为波特率为115200
寄存器具体配置如下:
PERCFG = 0x00; //位置1 P0 口
P0SEL = 0x0c; //P0_2,P0_3 用作串口(外部设备功能)
P2DIR &= ~0XC0; //P0 优先作为UART0
U0CSR |= 0x80; //设置为UART 方式
U0GCR |= 11;
U0BAUD |= 216; //波特率设为115200
UTX0IF = 0; //UART0 TX 中断标志初始置位0
PERCFG:设置部分外设的I/O位置,0为默认I位置1,1为默认位置2
P0SEL:见上文。
P2DIR :见上文。
串口的波特率设置可以从CC2530 的datasheet 中查得波特率由下式求得:
设置系统时钟源:CLKCONCMD:时钟频率控制寄存器。
D7位为32KHZ时间振荡器选择,,0为32KRC震荡,1为32K晶振。默认为1。
D6位为系统时钟选择。0为32M晶振,1为16M RC震荡。当D7位为0时D6必须为1。D5~D3为定时器输出标记。000为32MHZ,001为16MHZ,010为8MHZ,011为4MHZ,100为2MHZ,101为 1MHZ,110为500KHZ,111为250KHZ。默认为001。需要注意的是:当D6为1时,定时器频率最高可采用频率为16MHZ。
D2~D0:系统主时钟选择:000为32MHZ,001为16MHZ,010为8MHZ,011为4MHZ,100为2MHZ,101为1MHZ,110为500KHZ,111为250KHZ。当D6为1时,系统主时钟最高可采用频率为16MHZ。
等待晶振稳定:CLKCONSTA:时间频率状态寄存器。
D7位为当前32KHZ时间振荡器频率。0为32KRC震荡,1为32K晶振。
D6位为当前系统时钟选择。0为32M晶振,1为16M RC震荡。
D5~D3为当前定时器输出标记。000为32MHZ,001为16MHZ,010为8MHZ,011为4MHZ,100为2MHZ,101为 1MHZ,110为500KHZ,111为250KHZ。
D2~D0为当前系统主时钟。000为32MHZ,001为16MHZ,010为8MHZ,011为4MHZ,100为2MHZ,101为1MHZ,110为500KHZ,111为250KHZ。
例子:
串口发送函数请参考下面源程序:
源程序代码(全)
/**************************************
描述:在串口调试助手上可以看到不停地
收到CC2530 发过来的:HELLO WEBEE
波特率:115200bps
**************************************/
#include
#include
#define uint unsigned int
#define uchar unsigned char
//定义LED 的端口
#define LED1 P1_0
#define LED2 P1_1
//函数声明
void Delay_ms(uint);
void initUART(void);
void UartSend_String(char *Data,int len);
char Txdata[14]; //存放”HELLO WEBEE “共14 个字符串
/**************************************************************** 延时函数
****************************************************************/ void Delay_ms(uint n)
{
uint I,j;
for(i=0;i { for(j=0;j<1774;j++); } } void IO_Init() { P1DIR = 0x03; //IO 方向输出 LED1 = 0; //关LED LED2 = 0; } /**************************************************************** 串口初始化函数 ****************************************************************/ void InitUART(void) { PERCFG = 0x00; //位置1 P0 口 P0SEL = 0x0c; //P0_2,P0_3 用作串口(外部设备功能) P2DIR &= ~0XC0; //P0 优先作为UART0 U0CSR |= 0x80; //设置为UART 方式 U0GCR |= 11; U0BAUD |= 216; //波特率设为115200 UTX0IF = 0; //UART0 TX 中断标志初始置位0 } /**************************************************************** 串口发送字符串函数 ****************************************************************/ void UartSend_String(char *Data,int len) { int j; for(j=0;j { U0DBUF = *Data++; while(UTX0IF == 0); UTX0IF = 0; } } /**************************************************************** 主函数 ****************************************************************/ void main(void) { CLKCONCMD &= ~0x40; //设置系统时钟源为32MHZ 晶振while(CLKCONSTA & 0x40); //等待晶振稳定为32M CLKCONCMD &= ~0x47; //设置系统主时钟频率为32MHZ IO_Init(); InitUART(); strcpy(Txdata,”HELLO WEBEE “); //将发送内容copy 到Txdata; while(1) { UartSend_String(Txdata,sizeof(“HELLO WEBEE “)); //串口发送数据 Delay_ms(500); //延时 LED1=!LED1; //标志发送状态 } } 串口接收和发送(send & receive) 寄存器配置请参考上方实验 1 的表格。实验1 较实验1 增加了串口接收功能,故寄存器配置有所改变,如下。 CLKCONCMD &= ~0x40; // 设置系统时钟源为32MHZ 晶振 while(CLKCONSTA & 0x40); // 等待晶振稳定 CLKCONCMD &= ~0x47; // 设置系统主时钟频率为32MHZ PERCFG = 0x00; //位置1 P0 口 P0SEL = 0x3c; //P0_2,P0_3,P0_4,P0_5用作串口,第二功能 P2DIR &= ~0XC0; //P0 优先作为UART0 ,优先级 U0CSR |= 0x80; //UART 方式 U0GCR |= 11; //U0GCR 与U0BAUD 配合 U0BAUD |= 216; // 波特率设为115200 UTX0IF = 0; //UART0 TX 中断标志初始置位1 (收发时候) U0CSR |= 0X40; //允许接收 IEN0 |= 0x84; // 开总中断,接收中断 源程序代码(部分)请读者自行分析 /************************************** 程序描述:例以abc#方式发送,#为结束符, 返回abc。波特率:115200bps **************************************/ /**************************************************************** 串口初始化函数 ****************************************************************/ void InitUart() { CLKCONCMD &= ~0x40; // 设置系统时钟源为32MHZ 晶振while(CLKCONSTA & 0x40); // 等待晶振稳定 CLKCONCMD &= ~0x47; // 设置系统主时钟频率为32MHZ PERCFG = 0x00; //位置1 P0 口 P0SEL = 0x3c; //P0_2,P0_3,P0_4,P0_5 用作串口,第二功能 P2DIR &= ~0XC0; //P0 优先作为UART0 ,优先级 U0CSR |= 0x80; //UART 方式 U0GCR |= 11; //U0GCR 与U0BAUD 配合 U0BAUD |= 216; // 波特率设为115200 UTX0IF = 0; //UART0 TX 中断标志初始置位1 (收发时候) U0CSR |= 0X40; //允许接收 IEN0 |= 0x84; // 开总中断,接收中断 } /**************************************************************** 串口发送字符串函数 ****************************************************************/ void Uart_Send_String(char *Data,int len) { { int j; for(j=0;j { U0DBUF = *Data++; while(UTX0IF == 0); //发送完成标志位 UTX0IF = 0; } } } /*************************** 主函数 ***************************/ void main(void) { InitLed(); //调用初始化函数 InitUart(); while(1) { if(RXTXflag == 1) //接收状态 { LED1 = 1; //接收状态指示 if( temp != 0) { if((temp!=’#’)&&(datanumber<50)) //’#’被定义为结束字符,最多能接收50 个字符 Rxdata[datanumber++] = temp; else { RXTXflag = 3; //进入发送状态 LED1 = 0; //关指示灯 } temp = 0; } } if(RXTXflag == 3) //发送状态 { LED2= 1; U0CSR &= ~0x40; //禁止接收 Uart_Send_String(Rxdata,datanumber); //发送已记录的字符串。 U0CSR |= 0x40; //允许接收 RXTXflag = 1; // 恢复到接收状态 datanumber = 0; //指针归0 LED2 = 0; //关发送指示 } } } /**************************************************************** 串口接收一个字符: 一旦有数据从串口传至CC2530, 则进入中断,将接收 到的数据赋值给变量temp. ****************************************************************/ #pragma vector = URX0_VECTOR __interrupt void UART0_ISR(void) { URX0IF = 0; // 清中断标志 temp = U0DBUF; 六、睡眠唤醒 前言: Zigbee 的特点就是远距离低功耗的无线传输设备,节点模块闲时可以进入睡眠模式,在需要传输数据时候进行唤醒,能进一步节省电量。本章将讲述CC2530 在睡眠模式下的2 种唤醒方法:外部中断唤醒和定时器唤醒。睡眠定时器用于设置系统进入和退出低功耗睡眠模式之间的周期。还用于当系统进入低功耗模式后,维持MAC 定时器(T2)的定时。其特性如下:长达24 位定时计数器,运行在32.768KHZ 的工作频率。24 位的比较器具有中断和DMA 触发功能在PM2 低功耗模式下运行系统电源管理(工作方式如下): 1. 全功能模式,高频晶振(16M 或者32M )和低频晶振(3 2.768K RCOSC/XOSC )全部工作, 数字处理模块正常工作。 2. PM1 : 高频晶振(16M 或者32M )关闭,低频晶振(32.768K RCOSC/XOSC )工作,数字核心模块正常工作。 3. PM2 :低频晶振(32.768K RCOSC/XOSC )工作, 数字核心模块关闭,系统通过RESET,外部中断或者睡眠计数器溢出唤醒。 4. PM3 : 晶振全部关闭,数字处理核心模块关闭,系统只能通过RESET 或外部中断唤醒。此模式下功耗最低。 1.中断唤醒CC2530 需要配置的主要寄存器如下:PCON ,SLEEPCMD 配置方法: SLEEPCMD |= i; // 设置系统睡眠模式,i=0,1,2,3 PCON = 0x01; // 进入睡眠模式,通过中断打断 PCON = 0x00; // 系统唤醒,通过中断打断 例子: 源程序代码(全) /********************************************** 程序描述:LED2 闪烁5 次后进入睡眠状态,通 过按下按键S1 产生外部中断进行唤 醒,重新进入工作模式。 ***********************************************/ #include #define uint unsigned int #define uchar unsigned char //定义控制LED 灯和按键的端口 #define LED2 P1_1 //定义LED2 为P11 口控制 #define KEY1 P0_0 //函数声明 void Delayms(uint); //延时函数 void InitLed(void); //初始化P1 口 void SysPowerMode(uchar sel); //系统工作模式 /**************************** 延时函数 *****************************/ void Delayms(uint xms) //i=xms 即延时i 毫秒 { uint I,j; for(i=xms;i>0;i--) for(j=587;j>0;j--); } /**************************** //初始化程序 *****************************/ void InitLed(void) { P1DIR |= 0x02; //P1_1 定义为输出 PICTL |= 0x02; //下降沿触发 LED2 = 0; //LED2 灯熄灭 P0INP &= ~0X01; //设置P0 口输入电路模式为上拉/ 下拉 P0IEN |= 0X01; //P00 设置为中断方式 PICTL |= 0X01; // 下降沿触发 } /*************************************************************** 系统工作模式选择函数 * para1 0 1 2 3 * mode PM0 PM1 PM2 PM3 ***************************************************************/ void SysPowerMode(uchar mode) { uchar I,j; I = mode; if(mode<4) { SLEEPCMD |= I; // 设置系统睡眠模式