版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
CC2530简介1CC2530简介11CC2530芯片CC2530是基于2.4GHzIEEE802.15.4、ZigBee和RF4CE上的一个片上系统解决方案。其特点是以极低的总材料成本建立较为强大的网络节点。CC2530芯片结合了RF收发器,增强型8051CPU,系统内可编程闪存,8KBSRAM和许多其他模块的强大的功能。CC2530主要有四种不同的闪存版本:CC2530F32/64/128/256(32/64/128/256KB闪存)其具有多种运行模式,使得它能满足超低功耗系统的要求。同时CC2530运行模式之间的转换时间很短,使其进一步降低能源消耗。2CC2530芯片CC2530是基于2.4GHzIEEE802CC2530片内结构方框图数字模拟混合输入/输出控制器XOSC_Q2RESET_NXSOC_Q1P2_4P2_3P2_2P2_1P2_0P1_4P1_3P1_2P1_1P1_0RF_PP1_7P1_6P1_5P1_4P1_3P1_2P1_1P1_0P1_7P1_6P1_5复位看门狗片上稳压器32MHz晶振高速RC-OSC上电/复位/掉电32.768KHz晶振32.768KHzRC-OSC睡眠定时器调试接口多路时钟校准睡眠模式控制器DMA8051CPU内核存储器仲裁32/64/128/256KBFLASH8KBSRAMADC音频/直流8通道AES加密和解密IRQ控制FLASH写射频寄存器CSMA/CA选通处理器USART1USART2射步数据接口定时器1(16位)定时器2IEEE802.15.4MAC定时器定时器3(8位)定时器4(8位)调制器解调器自动增益控制频率合成器接收链RF_N先进选出和帧控制发送链VDD(2.0-3.6V)DCOUPL3CC2530片内结构方框图数字模拟混合输入/输出控制器XOS3CC2530引脚描述(1)4CC2530引脚描述(1)44CC2530引脚描述(2)5CC2530引脚描述(2)55CC2530封装6CC2530封装66CC2530需要极少的外部连接元件,同时有很多典型电路,其模块大致可以分为三类:1、CPU和内存相关模块2、外设,时钟和电源管理相关模块3、无线信号收发相关模块CC2530芯片内部结构7CC2530需要极少的外部连接元件,同时有很多典型电路,其模7强大的5通道DMAIEEE802.15.4MAC定时器,通用定时器(一个16位定时器,一个8位定时器)IR发生电路(IR中断)具有捕获功能的32-kHz睡眠定时器硬件支持CSMA/CA(载波侦听多路访问/冲突避免)
支持精确的数字化RSSI/LQI(链路质量指示)电池监视器和温度传感器21个通用I/O引脚看门狗定时CC2530的外设(1)8强大的5通道DMACC2530的外设(1)88两个8位定时器:定时器3,4为8位定时器,有一个可编程分频器,一个8位的周期值,一个计数器通道。MAC定时器:专为MAC或其他协议而设的定时器,可以跟踪已过周期,同时可以记录收发某一的帧精确时间和传输结束时间,以便产生不同的选通命令到无线模块ADC:支持7到12位的分辨率,带宽范围为7-30kHz,在DC与音频转换时,能够使用8个输入通道。AES加密/解密内核:CC2530用128位的AES算法进行加密或解密数据,从而保证了ZigBee网络层和应用层的安全要求。USART0和USART1分别被配置为一个主从或一个UART,其功能是为RX和TX提供双缓冲,以及硬件流控制。调试接口:用于内部电路调试,具有两线串形接口I/O控制器:负责所有的通用的I/O引脚CC2530的外设(2)9两个8位定时器:定时器3,4为8位定时器,有一个可编程分频器9CC2530具备一个IEEE802.15.4兼容无线收发器,其中的RF内核控制模拟无线模块,另外它还提供了一个连接外部设备的端口,从而可以发出命令和读取状态,操纵各执行电路的事件顺序。同时无线设备还包括数据包过虑模块和地址识别模块。无线设备10CC2530具备一个IEEE802.15.4兼容无线收发器10CC2530最小系统11CC2530最小系统1111CC2530的典型应用12CC2530的典型应用1212输入输出匹配:当使用单极子的一个不平衡天线,需要用一个巴伦(平衡非平衡转换器)来对性能进行优化,可以采用低成本分立电感或电容来实现,这里主要运用C262,L261,C252,L252.如果使用了诸如折叠偶极子这样的平衡天线,巴伦可以忽略。1.8V片上稳压器:用以提供1.8V的数字逻辑电压,采用这一个稳压器要求用一个去耦电容C401来获得稳定运行效果。电源去耦和过滤必须使用合适的电源去耦以获得最佳的性能。在一个应用中去耦电容和电源过滤的位置和尺寸对获得最佳性能是非常重要的。TI提供了一个紧凑的参考设计,应该很好地遵循。晶振32MHz晶振使用了一个外部32-MHz振荡器XTAL1和两个负载电容(C221和C231)。晶振XTAL2是一个可选的32.768kHz晶振,有两个负载电容(C321和C331)用于32.768-kHz晶振。32.768kHz晶振用于要求非常低的睡眠电流消耗和精确唤醒时间的应用。元件说明13输入输出匹配:当使用单极子的一个不平衡天线,需要用一个巴伦(13CC2530模块传感器板14CC2530模块传感器板1414步进电机结点15步进电机结点1515CCDebug仿真器16CCDebug仿真器1616CC2530使用的8051CPU是一个单周期的兼容内核,它有三种不同的访问总线。其中包括中断控制器,内存仲裁器,8KBSRAM,32/64/128/256KB闪存块。增强型8051内核使用标准的8051指令集。因为以下原因指令执行比标准的8051更快:每个指令周期是一个时钟,而标准的8051每个指令周期是12个时钟消除了总线状态的浪费。因为一个指令周期与可能的内存存取是一致的,大多数单字节指令在一个时钟周期内执行。除了速度提高之外,增强型8051内核还包括结构上的改善。第二个数据指针一个扩展的18源中断单元8051内核的对象代码兼容业界标准的8051微控制器。即对象代码使用8051内核上执行的业界标准的8051编译器或汇编器编译,在功能上是等同的。CC2530的CPU17CC2530使用的8051CPU是一个单周期的兼容内核,它有17CC2530的CPU中断控制器:其为18个中断源提供服务,它们中的每个中断都被赋予4个中断优先级中的某一个。内存仲裁器:位于系统中心,它负责执行仲裁,即决定同时访问系统物理存储器时的顺序,便于系统效率的提高。8KBSRAM:为超低功耗的SRAM,使数字部分即使掉电也能保存其中内容,是芯片低功耗原因所在。闪存块:用于保存电脑传输进入的程序代码以及常量数据,节约了搜寻时间。18CC2530的CPU中断控制器:其为18个中断源提供服务,它18CC2530的存储器CC2530里的四种存储空间:CODE程序存储器:用处存放程序代码和一些常量,寻址范围0000H~FFFFH共64KB。DATA:内部数据存储空间,可以直接或间接被一个单周期CPU指令访问。这一存储空间是256B。其中较低的128B可以直接或间接寻址,较高的128B只能间接寻址。XDATA:外部数据存储空间,通常需要4-5个CPU指令周期来访问。这一存储空间是64KB。访问XDATA存储器慢于访问DATA,因为CODE和XDATA存储空间共享CPU内核上的一个通用总线。SFR:寄存器存储空间,可以直接被一个CPU指令访问。这一存储空间含有128字节。对于地址是被8整除的SFR寄存器,每一位还可以单独寻址。
这四个存储空间在8051结构中是分开的,但是在设备中有部分是重叠的,以减轻DMA传输和硬件调试操作的负担。19CC2530的存储器CC2530里的四种存储空间:1919CC2530的XDATA存储器映射为使DMA访问全部物理存储空间,并由此使得DMA在不同8051存储空间之间进行传输,CODE和SFR部分存储空间映射到XDATA存储空间。XDATA较高的32KB是一个只读区域(XBANK),任何可用的32KB闪存区均可以映射到这里。这使得软件可以访问整个闪存存储器。这一区域主要用作存储另外的常量数据。20CC2530的XDATA存储器映射为使DMA访问全部物理存20CC2530的CODE存储器映射机制一
机制一是标准的8051映射,只有程序存储器(即闪存)映射到CODE存储空间,这是复位后默认映射方式。RootBankFMAP.MAP[2:0]确定过来的Bank21CC2530的CODE存储器映射机制一21CC2530的CODE存储器映射机制二22CC2530的CODE存储器映射机制二2222CPU存储空间SRAM映射到的地址范围是0x0000到(SRAM_SIZE–1)。XREG区域映射到1KB地址区域(0x6000–0x63FF)。这些寄存器是另外的寄存器,有效地扩展SFR寄存器空间。一些外设寄存器和大多数无线电控制和数据寄存器映射到这里。SFR寄存器映射到地址区域(0x7080–0x70FF)。闪存信息页面(2KB)映射到地址区域(0x7800–0x7FFF)。这是一个只读区域,包含有关设备的各种信息。XDATA存储空间(0x8000–0xFFFF)的较高32KB是一个只读的闪存代码区(XBANK),可以使用MEMCTR.XBANK[2:0]位映射到任何一个可用的闪存区。闪存存储器SRAM和寄存器到XDATA的映射允许DMA控制器和CPU访问在一个统一的地址空间内的所有物理存储器。写入存储映射中未执行的区域(图中的阴影部分)没有影响。从为执行的区域读出返回0x00。写只读区域比如闪存区域将被忽略。23CPU存储空间SRAM映射到的地址范围是0x0000到23物理存储器闪存存储器:片上闪存存储器主要是为了保存程序代码和常量数据。闪存存储器有以下功能:页面大小:2KB闪存页面擦除时间:20ms闪存芯片(批量)擦除时间:20ms闪存写时间(4字节):20μs数据保留(室温下):100年编程/擦除次数:20,000次信息页面是一个2KB的只读区域,存储设备信息。其他信息中它包括来自TI地址范围的一个唯一的IEEE地址。它以最低位优先的形式存储在XDATA地址0x780C。将出版一个单独的设计说明,详细介绍信息页面的内容。SFR寄存器:特殊功能寄存器(SFR)控制8051CPU内核和/或外设的一些功能。许多8051CPU内核的SFR和标准的8051SFR相同。但是有一些控制功能的另外的SFR,是标准8051中所没有的。另外的SFR用于和外设单元以及RF收发器接口。24物理存储器闪存存储器:片上闪存存储器主要是为了保存程序代码和24与端口有关的寄存器寄存器名称地址描述端口P00x80端口0。可从XDATA(0x7080)只读。P10x90端口1。可从XDATA(0x7090)只读。P20xA0端口2。可从XDATA(0x70A0)只读。寄存器名称地址描述端口控制寄存器P0SEL0xF3端口0功能选择(0-通用I/O,1-外围功能)P1SEL0xF4端口1功能选择(0-通用I/O,1-外围功能)P2SEL0xF5端口2功能选择(0-通用I/O,1-外围功能)P0INP0x8F端口0输入模式(0-三态,1-上拉)P1INP0xF6端口1输入模式(0-三态,1-上拉)P2INP0xF7端口2输入模式(0-三态,1-上拉)P0DIR0xFD端口0方向选择(0-输入,1-输出)P1DIR0xFE端口1方向选择(0-输入,1-输出)P2DIR0xFF端口2方向选择(0-输入,1-输出)25与端口有关的寄存器寄存器名称地址描述端P00x8025以下代码使P1_0引脚电平每隔一定时间反向一次:#include<ioCC2530.h>#defineBLEDP1_0//定义LED为P1_0口控制voidmain(){unsignedintd;P1SEL&=~0x01;//选择P1_0为通用I/O引脚P1DIR|=0x01;//I/O方向选择为输出while(1){for(d=0;d<30000;d++);//延时BLED=~BLED;//电平反向,LED闪烁}}26以下代码使P1_0引脚电平每隔一定时间反向一次:#inclu26将P1_2设为三态输入,读取按键状态#definekeyP0_1P0SEL&=~0X02;//P0_1作为通用I/O口P0DIR&=~0X02;//P0_1输入P0INP|=0x02;//P0_1上拉ucharkey_scan(void){ if(key==0){//低电平有效 delay(100);//延时消抖动 if(key==0){ ……//处理按键事件 while(!key);//直到松开按键 } }}27将P1_2设为三态输入,读取按键状态#definekey27定时器T1(1)16位递增或递减计数器由CLKCON.TICKSPD定义活动时钟边沿周期,它设置从0.25MHz到32MHz的不同的时钟标签频率(可以使用32MHzXOSC作为时钟源)。由T1CTL.DIV设置分频器值可以从1、8、32或128。因此当32MHz晶振用作系统时钟源时,定时器1可以使用的最低时钟频率是1953.125Hz,最高是32MHz。28定时器T1(1)16位递增或递减计数器2828可以通过两个8位的SFR读取16位的计数器值:T1CNTH和T1CNTL,分别包含在高位字节和低位字节中。当读取T1CNTL时,计数器的高位字节在那时被缓冲到T1CNTH,以便高位字节可以从T1CNTH中读出。因此T1CNTL必须总是在读取T1CNTH之前首先读取。对T1CNTL寄存器的所有写入访问将复位16位计数器。当达到最终计数值(溢出)时,计数器产生一个中断请求。可以用T1CTL控制寄存器设置启动并停止该计数器。当一个不是00值的写入到T1CTL.MODE时,计数器开始运行。如果00写入到T1CTL.MODE,计数器停止在它现在的值上。一般来说控制寄存器T1CTL用于控制定时器操作。状态寄存器T1STAT保存中断标志。定时器T1(2)29可以通过两个8位的SFR读取16位的计数器值:T1CNTH29与定时器1有关的寄存器寄存器名称地址描述T1CC0L0xDA通道0捕获/比较值低字节T1CC0H0xDB通道0捕获/比较值高字节T1CC1L0xDC通道1捕获/比较值低字节T1CC1H0xDD通道1捕获/比较值高字节T1CC2L0xDE通道2捕获/比较值低字节T1CC2H0xDF通道2捕获/比较值高字节T1CNTL0xE2计数器低字节T1CNTH0xE3计数器高字节T1CTL0xE4控制T1CCTL00xE5通道0捕获/比较控制T1CCTL10xE6通道1捕获/比较控制T1CCTL20xE7通道2捕获/比较控制T1STAT0xAF状态常用30与定时器1有关的寄存器寄存器名称地址描述T1CC030T1CTL定时器1的控制和状态位名称复位R/W描述7:4-0000RO保留3:2DIV[1:0]00R/W分频器划分值。产生主动的时钟边缘用来更新计数器,如下:00:标记频率/101:标记频率/810:标记频率/3211:标记频率/1281:0MODE[1:0]00R/W选择定时器1模式。定时器操作模式通过下列方式选择:00:暂停运行。01:自由运行,从0x0000到0xFFFF反复计数10:从0x0000到T1CC0反复计数。11:正计数/倒计数,从0x0000到T1CC0反复计数并且从T1CC0倒计数到0x000031T1CTL定时器1的控制和状态位名称复位R/W描31T1STAT定时器1状态寄存器位名称复位R/W描述7:6-0R0保留5OVFIF0R/W0定时器1计数器溢出中断标志。当计数器在自由运行或模模式下达到最终计数值时设置,当在正/倒计数模式下达到零时倒计数。写1没有影响。4CH4IF0R/W0定时器1通道4中断标志。当通道4中断条件发生时设置。写1没有影响。3CH3IF0R/W0定时器1通道3中断标志。当通道3中断条件发生时设置。写1没有影响。2CH2IF0R/W0定时器1通道2中断标志。当通道2中断条件发生时设置。写1没有影响。1CH1IF0R/W0定时器1通道1中断标志。当通道1中断条件发生时设置。写1没有影响。0CH0IF0R/W0定时器0通道0中断标志。当通道0中断条件发生时设置。写1没有影响。32T1STAT定时器1状态寄存器位名称复位R/W描32利用定时器中断实现指示灯的闪烁#include<ioCC2530.h>#defineuintunsignedint#defineucharunsignedchar#defineRLEDP1_0 //定义LED1为P10口控制#defineYLEDP1_1 //定义LED2为P11口控制uintcounter=0; //统计溢出次数uintLEDFlag; //标志是否要闪烁voidInitialT1test(void)//T1初始化程序{ P1DIR=0x03;//初始化LED控制端口P1,P10P11为输出 RLED=0; YLED=0; T1CTL=0x05;//初始化计数器1T1STAT=0x21;//通道0,中断有效,8分频}//自动重装模式(0x0000->0xffff)
33利用定时器中断实现指示灯的闪烁#include<ioCC233利用定时器中断实现指示灯的闪烁voidmain()//主函数{ InitialT1test();//调用初始化函数while(1){ //查询溢出 if(IRCON>0){//中断标志寄存器,其中bit1为T1IFIRCON=0;//清溢出标志counter++;if(counter==15){//中断计数,约0.25scounter=0;LEDFlag=!LEDFlag;}}if(LEDFlag){ YLED=RLED;RLED=!RLED; //每1sLED灯闪烁一下LEDFlag=!LEDFlag;//闪烁标志变量置0 } }}34利用定时器中断实现指示灯的闪烁voidmain()//主34串口0使用(初始化)voidinitUARTSEND(void){CLKCONCMD&=~0x40;//设置系统时钟源为32MHZ晶振while(CLKCONSTA&0x40);//等待晶振稳定CLKCONCMD&=~0x47;//设置系统主时钟频率为32MHZPERCFG=0x00; //位置1P0口P0SEL=0x3c;//P0_2,P0_3,P0_4,P0_5用作串口P2DIR&=~0XC0;//P0优先作为UART0U0CSR|=0x80; //UART方式U0GCR|=9; U0BAUD|=59; //波特率设为19200UTX0IF=0;//UART0TX中断标志初始置位0}函数功能:将系统时钟设为高速晶振,将P0口设置为串口0功能引脚,串口0使用UART模式,波特率设为19200,允许接收。该函数在使用串口之前调用。CLKCONCMDCLKCONSTAPERCFGU0CSRU0GCRU0BAUDUTX0IF35串口0使用(初始化)voidinitUARTSEND(vo35串口0使用(发送字符串)voidUartTX_Send_String(char*Data,intlen){intj;for(j=0;j<len;j++){U0DBUF=*Data++;while(UTX0IF==0);UTX0IF=0;}}函数功能:串口发送数据,*data为发送缓冲的指针,len为发送数据的长度该函数在初始化串口后才可以正常调用。36串口0使用(发送字符串)voidUartTX_Send_S36#include<ioCC2530.h>#include<string.h>#defineRLEDP1_0//定义控制灯的端口#defineGLEDP1_1charTxdata[25]="XWWKTestData!";voidmain(void){ uchari;P1DIR=0x03;//P1_0,P1_1输出,控制LED RLED=1; //RLED灭 GLED=0; //GLED亮 initUARTSEND(); UartTX_Send_String(Txdata,25);for(i=0;i<30;i++)Txdata[i]='';strcpy(Txdata,"HELLO");//将UART0TXtest赋给Txdata; while(1){UartTX_Send_String(Txdata,sizeof("HELLO"));//串口发送数据Delay(50000);//延时GLED=!GLED;//GLED闪烁Delay(50000);Delay(50000); }}串口0使用(主函数)37#include<ioCC2530.h>串口0使用(主函数37通过内置温度传感器实现温度采集(初始化)/***********************************************************温度传感器初始化函数 ************************************************************/voidinitTempSensor(void){DISABLE_ALL_INTERRUPTS();//关闭所有中断InitClock();//设置系统主时钟为32M*((BYTE__xdata*)0x624B)=0x01;//开启温度传感器*((BYTE__xdata*)0x61BD)=0x01;//将温度传感器与
//ADC连接起来}voidInitClock(void){CLKCONCMD=0x28;//设定计数器时钟为1MHz,系统时钟为32MHzwhile(CLKCONSTA&0x40);//等晶振稳定}#defineDISABLE_ALL_INTERRUPTS()(IEN0=IEN1=IEN2=0x00)38通过内置温度传感器实现温度采集(初始化)/*********38INT8getTemperature(void){UINT8i;UINT16AdcValue;UINT16value;AdcValue=0;for(i=0;i<4;i++){ADC_SINGLE_CONVERSION(ADC_REF_1_25_V|ADC_14_BIT|ADC_TEMP_SENS);//使用1.25V内部电压,12位分辨率,AD源为温度传感器ADC_SAMPLE_SINGLE();//开启单通道ADCwhile(!ADC_SAMPLE_READY());//等待AD转换完成value=ADCL>>2;//ADCL寄存器低2位无效value|=(((UINT16)ADCH)<<6);AdcValue+=value;//AdcValue被赋值为4次AD值之和}value=AdcValue>>2;//累加除以4,得到平均值returnADC14_TO_CELSIUS(value);//根据AD值,计算出实际的温度}通过内置温度传感器实现温度采集(读AD值)#defineADC_SINGLE_CONVERSION(settings)\do{ADCCON3=(settings);}while(0)#defineADC_SAMPLE_SINGLE()\do{ADC_STOP();ADCCON1|=0x40;}while(0)00HHHHHHADCHLLLLLLXXADCL0000HHHH00LLLLLLHH0000000000HHHHHHLLLLLL#defineADC14_TO_CELSIUS(ADC_VALUE)(((ADC_VALUE)>>4)-335)#defineADC_SAMPLE_READY()\(ADCCON1&0x80)39INT8getTemperature(void){通过内置39voidmain(void){ chari;charTempValue[10]; InitUART0();//初始化串口 initTempSensor();//初始化ADCwhile(1){AvgTemp=0;for(i=0;i<64;i++){AvgTemp+=getTemperature();AvgTemp>>=1;//每次累加后除2.}sprintf(TempValue,(char*)"%dC",(INT8)AvgTemp);UartTX_Send_String(TempValue,4);Delay(50000);}}通过内置温度传感器实现温度采集(主函数)40voidmain(void)通过内置温度传感器实现温度采集40CC2530BasicRF(简单无线点对点传输协议)BasicRF由TI公司提供,它包含了IEEE802.15.4标准的数据包的收发。这个协议只是用来演示无线设备是如何进行数据传输的,不包含完整功能的协议。但是它采用了与802.15.4MAC兼容的数据包结构及ACK包结构,其功能限制如下:不提供“多跳”、“设备扫描”及Beacon(信标
)。不提供不同种的网络设备,如协调器、路由器等,所有节点同级,只实现点对点传输。传输时会等待信道空闲,但不按802.15.4CSMA-CA要求进行两次CCA检测。不重传数据。简言之,BasicRF不适合直接用于产品的开发,但可用来进行无线设备数据传输的入门学习。41CC2530BasicRF(简单无线点对点传输协议)Ba41BasicRF工作原理(2)启动创建一个basicRfCfg_t的数据结构,并初始化其中的成员。调用basicRfInit()函数进行协议的初始化。数据发送1.创建一个buffer,把payload放入其中。2.调用basicRfSendPacket()函数发送。数据接收上层通过basicRfPacketIsReady()函数来检查是否收到一个新的数据包,调用basicRfReceive()函数,把收到的数据复制到buffer中。42BasicRF工作原理(2)启动4242基于BasicRF的无线灯光控制实验程序功能是一个基本的点对点通信实验,实现了一个节点板上的开关控制另一个节点板上的LED的功能。每一个节点是用来做开关还是用来做灯的控制器,可以通过源程序的不同定义进行选择。可作为一个无线通信的入门级程序。TI例程工程名:cc2530_sw_examples.eww43基于BasicRF的无线灯光控制实验程序功能4343baseRF通信基本流程1.初始化网络地址,打开接收机。2.初始化basicRfConfig,确定网络ID、信道。3.初始化外围设备,如时钟、各个I/O口等。4.事件的处理,如发送报文或接受报文后的数据处理等。44baseRF通信基本流程1.初始化网络地址,打开接收机。444初始化网络(1)voidmain(void){//射频配置basicRfConfig.panId=PAN_ID;basicRfConfig.channel=RF_CHANNEL;basicRfConfig.ackRequest=TRUE;//要求接受方应答//IO初始化halBoardInit();//初始化指示灯和按钮initUART0();//初始化串口//RF初始化if(halRfInit()==FAILED){HAL_ASSERT(FALSE);}45初始化网络(1)voidmain(void)4545初始化网络(2)uint8halRfInit(void)//上电设置默认参数
{FRMCTRL0|=(AUTO_ACK|AUTO_CRC);
//推荐的RX设置TXFILTCFG=0x09;//TX过滤器配置寄存器AGCCTRL1=0x15;//AGC控制寄存器FSCAL1=0x00;//调整频率校准halRfEnableRxInterrupt();//使能RX中断returnSUCCESS;}voidhalRfEnableRxInterrupt(void){//enableRXPKTDONEinterruptRFIRQM0|=1<<6;
//enablegeneralRFinterruptsIEN2|=1;}FRMCTRL0-帧控制寄存器46初始化网络(2)uint8halRfInit(void)46事件处理while(1){#ifdefTX_TESTappSwitch();//发送#endif#ifdefRX_TESTappLight();//接收#endif}47事件处理while(1){4747发送函数(按钮事件)staticvoidappSwitch(){pTxData[0]=LIGHT_TOGGLE_CMD;//开关指示灯的命令
//初始化BasicRFbasicRfConfig.myAddr=SWITCH_ADDR;//设置地址if(basicRfInit(&basicRfConfig)==FAILED){HAL_ASSERT(FALSE);}while(TRUE)//主循环{if(halButtonPushed()==HAL_BUTTON_1)//判断按钮是否按下{basicRfSendPacket(LIGHT_ADDR,pTxData,APP_PAYLOAD_LENGTH);//发送数据函数
halLedToggle(LED_RED);//改变状态Wait(3);halLedToggle(LED_RED);//改变状态while(halButtonPushed()==HAL_BUTTON_1);//等待按钮抬起}}}48发送函数(按钮事件)staticvoidappSwitc48staticvoidappLight(){//初始化射频配置basicRfConfig.myAddr=LIGHT_ADDR;//设置地址if(basicRfInit(&basicRfConfig)==FAILED){HAL_ASSERT(FALSE);}basicRfReceiveOn();//打开接收while(1)//主循环{while(!basicRfPacketIsReady());if(basicRfReceive(pRxData,APP_PAYLOAD_LENGTH,NULL)>0){if(pRxData[0]==LIGHT_TOGGLE_CMD){UartTX_Send_String(UartData,17);//向串口发送测试数据halLedToggle(LED_RED);//改变状态Wait(3);halLedToggle(LED_RED);//改变状态}}}}接收函数(点亮LED)49staticvoidappLight()接收函数(点亮L49发送数据包函数(1)uint8basicRfSendPacket(uint16destAddr,uint8*pPayload,uint8length){uint8mpduLength;uint8status;if(!txState.receiveOn){//如果没有打开接收机halRfReceiveOn();}length=min(length,BASIC_RF_MAX_PAYLOAD_SIZE);//包长度halRfWaitTransceiverReady();//等到收发空闲
halRfDisableRxInterrupt();//关闭接收帧完成中断避免对SPI接口的干扰
mpduLength=basicRfBuildMpdu(destAddr,pPayload,length);halRfWriteTxBuf(txMpdu,mpduLength);halRfEnableRxInterrupt();//打开接收帧ACK接收完成中断
if(halRfTransmit()!=SUCCESS){//如果发送帧不成功,返回失败
status=FAILED;}50发送数据包函数(1)uint8basicRfSendPac50发送数据包函数(2)if(pConfig->ackRequest){//等待确认被接受
;//自动进入接收
halMcuWaitUs((12*BASIC_RF_SYMBOL_DURATION)+(BASIC_RF_ACK_DURATION)+(2*BASIC_RF_SYMBOL_DURATION)+10);status=txState.ackReceived?SUCCESS:FAILED;}else{status=SUCCESS;}if(!txState.receiveOn){halRfReceiveOff();//关掉接收机
}if(status==SUCCESS){txState.txSeqNumber++;}returnstatus;}51发送数据包函数(2)if(pConfig->ackRequ51Z-Stack协议栈软件层次(1)APP用户应用程序目录HAL硬件接口层目录MAC、NWK底层封装目录(无源码)MT串口操作工具目录OSAL操作系统抽象层目录ZMAIN协议栈入口目录ZDO设备对象层管理代码目录TOOL工程配置文件目录(信道、PANID)52Z-Stack协议栈软件层次(1)APP用户应用程序目录52
整个Z-Stack采用分层的软件结构,硬件抽象层(HAL)提供各种硬件模块的驱动,包括定时器Timer,通用I/O口GPIO,通用异步收发传输器UART,模数转换ADC的应用程序接口API,提供各种服务的扩展集。操作系统抽象层OSAL实现了一个易用的操作系统平台,通过时间片轮转函数实现任务调度,提供多任务处理机制。用户可以调用OSAL提供的相关API进行多任务编程,将自己的应用程序作为一个独立的任务来实现。Z-Stack协议栈软件层次(2)53整个Z-Stack采用分层的软件结构,硬件抽53工程的选择设备类型协调器路由器节点设备开发板类型EB 54工程的选择设备类型5454工程的配置(1)预编译宏
Z-Stack协议栈的代码采用了大量的预编译宏定义来模块化代码,以此来节省硬件代码空间。用户可以根据具体应用环境适当添加或删除宏定义。 具体编译宏由协议栈相关文档详细解释。Project->Options->C/C++Compiler->Preprocessor中查看55工程的配置(1)预编译宏5555配置文件
在f8wConfig.cfg等配置文件中定义了工程相关的网络通讯设置。其中比较重要的是和ZigBee通信相关的信道通道的设置,和PANID的设置,用户可以通过更改该文件中的相关宏定义,来控制ZigBee网络的通道和PANID。 Project->Options->C/C++Compiler->Preprocessor中查看工程的配置(2)56配置文件工程的配置(2)5656如何使用ZStack——网络配置(1)1.PANID和Channel(在Tools\f8wConfig.cfg中)ZigBee协议使用一个14位的个域网标志符(PANID)来标识一个网络。ZStack允许用两种方式配置PANID,当ZDAPP_CONFIG_PAN_ID值不设置为0xFFFF时,那么设备建立或加入网络的PANID由ZDAPP_CONFIG_PAN_ID指定;如果设置ZDAPP_CONFIG_PAN_ID为0xFFFF,那么设备就将建立或加入一个“最优”的网络。-DZDAPP_CONFIG_PAN_ID=0xFFFF
//-DZDAPP_CONFIG_PAN_ID=0x2FFFIEEE802.15.4/ZIGBEE规范在2.4G频段上规定了16各频道,用户可以通过选择DEFAULT_CHANLIST不同的值选择不同的频道,协议默认频道为0xB即0x00000800。//-DDEFAULT_CHANLIST=0x04000000
//26-0x1A
//-DDEFAULT_CHANLIST=0x02000000
//25-0x19
-DDEFAULT_CHANLIST=0x01000000
//24-0x18
//-DDEFAULT_CHANLIST=0x00800000
//23-0x17
//-DDEFAULT_CHANLIST=0x00400000
//22-0x16
//-DDEFAULT_CHANLIST=0x00200000
//21-0x15
//-DDEFAULT_CHANLIST=0x00100000
//20-0x14
//-DDEFAULT_CHANLIST=0x00080000
//19-0x13
//-DDEFAULT_CHANLIST=0x00040000
//18-0x12
//-DDEFAULT_CHANLIST=0x00020000
//17-0x11
//-DDEFAULT_CHANLIST=0x00010000
//16-0x10
//-DDEFAULT_CHANLIST=0x00008000
//15-0x0F
//-DDEFAULT_CHANLIST=0x00004000
//14-0x0E
//-DDEFAULT_CHANLIST=0x00002000
//13-0x0D
//-DDEFAULT_CHANLIST=0x00001000
//12-0x0C
//-DDEFAULT_CHANLIST=0x00000800
//11-0x0B
57如何使用ZStack——网络配置(1)1.PANID和C57
2.网络结构(nwk_globals.h,nwk_globals.c)STACK_PROFILE_ID定义为NETWORK_SPECIFIC、HOME_CONTROLS、BUILDING_AUTOMATION、GENERIC_STAR、GENERIC_TREE中的一个,默认为HOME_CONTROLS,并据此设置MAX_NODE_DEPTH、NWK_MODE等,具体如下:#defineSTACK_PROFILE_ID
HOME_CONTROLS#if(STACK_PROFILE_ID==HOME_CONTROLS)
#defineMAX_NODE_DEPTH
5
#defineNWK_MODE
NWK_MODE_MESH
#defineSECURITY_MODE
SECURITY_RESIDENTIAL
#if
(SECURE!=0
)
#defineUSE_NWK_SECURITY
1
//trueorfalse
#defineSECURITY_LEVEL
5
#else
#defineUSE_NWK_SECURITY
0
//trueorfalse
#defineSECURITY_LEVEL
0
#endif网络最大设备数设定:#if!defined(NWK_MAX_DEVICE_LIST)
#defineNWK_MAX_DEVICE_LIST
20
//MaximumnumberofdevicesintheAssoc/Devicelist.
#endif如何使用ZStack——网络配置(2)58
2.网络结构(nwk_globals.h,nwk_glob58路由器和终端设备数设定:#ifdefined(RTR_NWK)
//changethisifusingadifferentstackprofile...
//Cskiparray
uint16*Cskip;
#if(STACK_PROFILE_ID==HOME_CONTROLS)
byteCskipRtrs[MAX_NODE_DEPTH+1]={6,6,6,6,6,0};
byteCskipChldrn[MAX_NODE_DEPTH+1]={20,20,20,20,20,0};
#elif(STACK_PROFILE_ID==GENERIC_STAR)
byteCskipRtrs[MAX_NODE_DEPTH+1]={5,5,5,5,5,0};
byteCskipChldrn[MAX_NODE_DEPTH+1]={5,5,5,5,5,0};
#elif(STACK_PROFILE_ID==NETWORK_SPECIFIC)
byteCskipRtrs[MAX_NODE_DEPTH+1]={5,5,5,5,5,0};
byteCskipChldrn[MAX_NODE_DEPTH+1]={5,5,5,5,5,0};
#endif//STACK_PROFILE_ID
#endif
//RTR_NWK其中CskipRtrs和CskipChldrn分别为每一级的最大路由器数和最大节点数,前者是后者的子集。如何使用ZStack——网络配置(3)59路由器和终端设备数设定:如何使用ZStack——网络配置(359PANIDZigBee协议使用一个16位的个域网标志符(PANID)来标识一个网络。ZStack允许用两种方式配置PANID,当ZDAPP_CONFIG_PAN_ID值不设置为0xFFFF时,那么设备建立或加入网络的PANID由ZDAPP_CONFIG_PAN_ID指定;如果设置ZDAPP_CONFIG_PAN_ID为0xFFFF,那么设备就将建立或加入一个“最优”的网络。PANID的出现一般是伴随在,确定信道以后的。PANID其全称是PersonalAreaNetworkID,网络的ID(即网络标识符),是针对一个或多个应用的网络,用于区分不同的ZigBee网络,一般是mesh或者clustertree两种拓扑结构之一。所有节点的panID唯一,一个网络只有一个PANID,它是由pan协调器生成的,PANID是可选配置项,用来控制ZigBee路由器和终端节点要加入那个网络。文件f8wConfg.cfg中的ZDO_CONFIG_PAN_ID参数可以设置为一个0~0x3FFF之间的一个值。协调器使用这个值,作为它要启动的网络的PANID。而对于路由器节点和终端节点来说只要加入一个已经用这个参数配置了PANID的网络。如果要关闭这个功能,只要将这个参数设置为0xFFFF。要更进一步控制加入过程,需要修改ZDApp.c文件中的ZDO_NetworkDiscoveryConfirmCB函数。当然,如果ZDAPP_CONFIG_PAN_ID被定义为0xFFFF,那么协调器将根据自身的IEEE地址建立一个随机的PANID(0~0x3FFF)。60PANIDZigBee协议使用一个16位的个域网标志符(P60Z-Stack协议栈工作流程Z-Stack采用操作系统的思想来构建,采用事件轮循机制,当各层初始化之后,系统进入低功耗模式,当事件发生时,唤醒系统,开始进入中断处理事件,结束后继续进入低功耗模式。如果同时有几个事件发生,判断优先级,逐次处理事件。
整个Z-stack的主要工作流程,大致分为系统启动,驱动初始化,OSAL初始化和启动,进入任务轮循几个阶段。61Z-Stack协议栈工作流程Z-Stack采用操作系统的思想61Z-Stack系统运行流程图62Z-Stack系统运行流程图6262主函数例子(即启动程序)ZSEGintmain(void){osal_int_disable(INTS_ALL);//关闭中断HAL_BOARD_INIT();//初始化HAL
zmain_vdd_check();//电压检测
zmain_ram_init();//初始化stack存储区
InitBoard(OB_COLD);//初始化板载IO
HalDriverInit();//初始化HAL驱动
osal_nv_init(NULL);//初始化NV系统
zmain_ext_addr();//确定MAC地址
zgInit();//初始化基本NV条目
ZMacInit();//初始化MAC
afInit();//初始化AF
osal_init_system();//初始化操作系统
osal_int_enable(INTS_ALL);//允许中断
InitBoard(OB_READY);//初始化开发板
zmain_dev_info();//显示设备信息
zmain_lcd_init();//液晶初始化
osal_start_system();//启动操作系统
}63主函数例子(即启动程序)ZSEGintmain(voi63应用程序任务Z-stack的任何一个子系统都作为OSAL的一个任务,因此在开发应用层的时候,必须通过创建OSAL任务来运行应用程序。通过osalInitTasks()函数创建OSAL任务任何OSAL任务必须分为两步:一是进行任务初始化;二是处理任务事件。64应用程序任务Z-stack的任何一个子系统都作为OSAL的一64OSAL的任务处理
主循环中的两个关键数组*tasksEvents与*tasksArr。tasksEvents存放从序号为0到tasksCnt每个任务在本次循环中是否要被运行,需要运行的任务其值非0,否则为0。tasksArr数组则存放了对应每个任务的入口地址,只有在tasksEvents中记录的需要运行的任务,在本次循环中才会被调用到。
65OSAL的任务处理主循环中的两个关键数组*tasksEve65Sensor发送数据的函数staticvoidsendReport(void){uint8pData[SENSOR_REPORT_LENGTH];//存放数据的数组staticuint8reportNr=0;uint8txOptions;pData[SENSOR_TEMP_OFFSET]=readTemp();//ReadandreporttemperaturevaluepData[SENSOR_VOLTAGE_OFFSET]=readVoltage();//Readandreportvoltage
valuepData[SENSOR_PARENT_OFFSET]=HI_UINT16(parentShortAddr);pData[SENSOR_PARENT_OFFSET+1]=LO_UINT16(parentShortAddr);//SetACKrequestoneachACK_INTERVALreport//Ifareportfailed,setACKrequestonnextreportif(++reportNr<ACK_REQ_INTERVAL&&reportFailureNr==0){txOptions=AF_TX_OPTIONS_NONE;}else{txOptions=AF_MSG_ACK_REQUEST;reportNr=0;}
//Destinationaddress0xFFFE:Destinationaddressissenttopreviously//establishedbindingforthecommandId.zb_SendDataRequest(0xFFFE,SENSOR_REPORT_CMD_ID,SENSOR_REPORT_LENGTH,pData,0,txOptions,0);}66Sensor发送数据的函数staticvoidsendR66Sensor读温度的函数staticint8readTemp(void){staticuint16voltageAtTemp22;staticuint8bCalibrate=TRUE;//Calibratethefirsttimethetempsensorisreaduint16value;int8temp;ATEST=0x01;TR0|=0x01;ADCIF=0;/*ClearADCinterruptflag*/ADCCON3=(HAL_ADC_REF_125V|HAL_ADC_DEC_512|HAL_ADC_CHN_TEMP);while(!ADCIF);/*Waitfortheconversiontofinish*/value=ADCL;/*Gettheresult*/value|=((uint16)ADCH)<<8;value>>=4;//Usethe12MSBofadcValue/*
/*AssumeADC=1480at25CandADC=4/C*/#defineVOLTAGE_AT_TEMP_251480#defineTEMP_COEFFICIENT4temp=22+((value-voltageAtTemp22)/TEMP_COEFFICIENT);if(temp>=100){//Set0Casminimumtemperature,and100Casmaxreturn100;}elseif(temp<=0){return0;}else{returntemp;}}67Sensor读温度的函数staticint8readTe67Sensor读取电压staticuint8readVoltage(void){uint16value;ADCIF=0;//ClearADCinterruptflag
ADCCON3=(HAL_ADC_REF_125V|HAL_ADC_DEC_128|HAL_ADC_CHN_VDD3);while(!ADCIF);//Waitfortheconversiontofinish
value=ADCL;//Gettheresultvalue|=((uint16)ADCH)<<8;
//valuenowcontainsmeasurementofVdd/3//0indicates0Vand32767indicates1.25V//voltage=(value*3*1.25)/32767volts//wewillmultiplybythisby10toallowunitsof0.1voltsvalue=value>>6;//dividefirstby2^6value=(uint16)(value*37.5);value=value>>9;
//...andlaterby2^9...topreventoverflowduringmultiplicationreturnvalue;}68Sensor读取电压staticuint8readVol68696969707070717171727272时钟控制寄存器CLKCONCMD位名称复位R/W描述7OSC32K1R/W32kHz时钟振荡器选择。设置该位只能发起一个时钟源改变。CLKCONSTA.OSC32K反映当前的设置。当要改变该位必须选择16MHzRCOSC作为系统时钟。0:32kHzXOSC1:32kHzRCOSC6OSC1R/W系统时钟源选择。设置该位只能发起一个时钟源改变。CLKCONSTA.OSC反映当前的设置。0:32MHzXOSC1:16MHzRCOSC5:3TICKSPD[2:0]001R/W定时器标记输出设置。不能高于通过OSC位设置的系统时钟设置。000:32MHz001:16MHz010:8MHz011:4MHz100:2MHz101:1MHz110:500kHz111:250kHz2:0CLKSPD001R/W时钟速度。不能高于通过OSC位设置的系统时钟设置。表示当前系统时钟频率。000:32MHz001:16MHz010:8MHz011:4MHz100:2MHz101:1MHz110:500kHz111:250kHz73时钟控制寄存器CLKCONCMD位名称复位R/W描73时钟控制状态寄存器CLKCONSTA位名称复位R/W描述7OSC32K1R当前选择的32kHz时钟源0:32kHzXOSC1:32kHzRCOSC6OSC1R当前选择的系统时钟0:32MHzXOSC1:16MHzRCOSC5:3TICKSPD[2:0]001R当前设置的定时器标记输出000:32MHz100:2MHz001:16MHz101:1MHz010:8MHz110:500kHz011:4MHz111:250kHz2:0CLKSPD001R当前时钟速度000:32MHz100:2MHz001:16MHz101:1MHz010:8MHz110:500kHz011:4MHz111:250kHz74时钟控制状态寄存器CLKCONSTA位名称复位R/W描74PERCFG(0xF1
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 购货合同购销合同的权益保障
- 放弃参加培训的理由说明
- 工程模板施工劳务分包协议
- 个人停车库租赁合同示例
- 还款协议合同样本
- 合同调整协议格式样本
- 董事服务合同的法律效力
- 权威采购合同范本样式
- 铝合金外门窗招标方案
- 水产品购销合同范本
- 以瞄准我的妹妹没剪板
- 弹性和塑性变形的区分
- 建设单位对施工单位的管理
- 针灸的步骤和流程-标准的针灸过程介绍
- 《学习的本质》读书会活动
- 石化年产15万吨腈项目-反应器设计说明书
- 浙江省宁波市宁海县六校联考2023-2024学年九年级上学期11月月考数学试题
- 医院保安服务方案(技术方案)
- Unit-4Natural-Disasters单元整体教学设计课件-高中英语人教版(2019)必修一
- 11D703-2 液位测量装置安装
- 武汉理工建筑工程概预算课程设计(新)
评论
0/150
提交评论