ZigBee应用操作教育资料.doc

上传人:一*** 文档编号:809686 上传时间:2019-07-16 格式:DOC 页数:135 大小:555.50KB
返回 下载 相关 举报
ZigBee应用操作教育资料.doc_第1页
第1页 / 共135页
ZigBee应用操作教育资料.doc_第2页
第2页 / 共135页
点击查看更多>>
资源描述

《ZigBee应用操作教育资料.doc》由会员分享,可在线阅读,更多相关《ZigBee应用操作教育资料.doc(135页珍藏版)》请在得力文库 - 分享文档赚钱的网站上搜索。

1、ZigBee 学习之学习之 1点灯点灯我用的编译环境是 IARfor51 7.30B,再介绍一下我的开发板的情况,ZigBee 模块用的是 CC2430.这块芯片是一款Soc 的芯片,集成了 8051 内核和 ZigBee 射频部分,只要很少的外部电路就可以搭建一个射频模块。因为其中的是8051 的内核,所有对于熟悉 8051 系列的同学们来说,基本的一些操作就很简单了,这里我们在温习一下,顺便对CC2430 芯片进行一下熟悉。嵌入式的一大特点是其底层的软件和硬件紧密相关,如果没有数字电路的知识,那么作起来是很困难的。我们先介绍一下基本的管脚分配情况:P0 的 2 和 3 接到了一个 232

2、电压转换芯片上,可以用来和 PC进行通信,LCD_RST,LCD_CS,接的是 LCD 的复位和片选端,这里我用到的 LCD 是兼容 PCD8544 的 NOkia5110 的LCD,为 SPI 总线 LCD,84X48 点阵。CC2430_MOSI,CC2430_CLK 都接到 LCD 上了。P1_0 接到一个调试 LED 上面,为高电平点亮。下面的第一个实验就很简单了,我们只要把 P1_0 配置为通用 IO,输出方式,然后从这里输出高电平,那么就可以点亮这个 LED 了。用到的寄存器为:P1 配置寄存器 P1SEL,P1 方向寄存器 P1DIR程序如下:#include#define DE

3、BUG_LED P1_0void delay(unsigned int n)/26 cycles delaywhile(-n)asm(“NOP“);void LEDInit()P1SEL /P1_0 defined General purpose I/OP1DIR |= 0X01; /P1_0 defined Outputmain()LEDInit();while(1)DEBUG_LED = 1; /Led lightdelay(50000);DEBUG_LED = 0;delay(50000);编译通过以后就用 TI 的官方工具 SmartRF Flash Programmer 将生成的 H

4、EX 文件,烧录到 CC2430 吧,激动的时刻,呵呵如果点亮了这个小小的 LED 那么恭喜你,你的硬件因该是没有问的了,一个小小的胜利后我们就有更多的勇气和信心前进咯!ZigBee 学习之学习之 2SPIvoid LCD_IOInit()P0SEL P0DIR |= 0X03;P1SEL P1DIR |= 0XF0;void LCD_WriteOneByte(uchar data)uchar i = 0;for(i=0;ivoid delay(uint n)/26 cycles delaywhile(-n)asm(“NOP“);void LEDInit()P1SEL /P1_0 define

5、d General purpose I/OP1DIR |= 0X01; /P1_0 defined OutputDEBUG_LED = 1; /LED light up/=/Initial P1-USART1-SPIvoid SPIInit_U1_P1(void)PERCFG |= 0X02; /USART1.alt.2,P1P1SEL |= 0XE0; /P1,ISP,P1_4(LCD_DnC) defined general IOP2SEL |= 0X40; /USART1 has priorityU1GCR |= 0x20; /MSB first,Negative clock polar

6、ity,Data is output on MOSI on the falling edge of CLKU1GCR |= 19; /MAX Baud rate(17),falling edgeU1BAUD = 0;UTX1IF = 0; /Clear interrupt/=/P1-USART1-SPI Send One Bytevoid SPI_SendOne_U1_P1(uchar data)U1DBUF = data;while(!UTX1IF);UTX1IF = 0;/=/P1-USART1-SPI Send Multily Bytevoid SPI_Send_U1_P1(uchar

7、*data,uint length)while(length)SPI_SendOne_U1_P1(*data);data+;length -= 1;/=/LCD Use SPI BUS,Set the first display piex./When after call this function can direct call SPI data output function/0packetLength = payloadLength + BASIC_RF_PACKET_OVERHEAD_SIZE;/pConfig 为基本配置数据结构/*typedef struct uint16 myAd

8、dr;uint16 panId;uint8 channel;uint8 ackRequest; basicRfCfg_t;*/pHdr-frameControlField = pConfig-ackRequest ? BASIC_RF_FCF_ACK : BASIC_RF_FCF_NOACK;fcf= pConfig-ackRequest ? BASIC_RF_FCF_ACK : BASIC_RF_FCF_NOACK;/分别得到 16 位数的低 8 位和高 8 位/#define HI_UINT16(a) (uint16)(a) 8) pHdr-fcf1 = HI_UINT16(fcf);/得

9、到数据序列pHdr-seqNumber= txState.txSeqNumber;pHdr-panId= pConfig-panId;pHdr-destAddr= destAddr;pHdr-srcAddr= pConfig-myAddr;#ifdef SECURITY_CCM/ Add security to FCF, length and security headerpHdr-fcf0 |= BASIC_RF_SEC_ENABLED_FCF_BM_L;pHdr-packetLength += PKT_LEN_MIC;pHdr-packetLength += BASIC_RF_AUX_HD

10、R_LENGTH;pHdr-securityControl= SECURITY_CONTROL;pHdr-frameCounter0= LO_UINT16(LO_UINT32(txState.frameCounter);pHdr-frameCounter1= HI_UINT16(LO_UINT32(txState.frameCounter);pHdr-frameCounter2= LO_UINT16(HI_UINT32(txState.frameCounter);pHdr-frameCounter3= HI_UINT16(HI_UINT32(txState.frameCounter);#end

11、if/ Make sure bytefields are network byte order/这里把大的字节放到了前面,但有不是完全按从大到小的顺序排列字节,不知道为什么?UINT16_HTON(pHdr-panId);UINT16_HTON(pHdr-destAddr);UINT16_HTON(pHdr-srcAddr);/1 字节长度,2 字节 FCF,1 字节序列,2 字节 PanID,2 字节目的地址,2 字节源地址=10return BASIC_RF_HDR_SIZE;/* fn basicRfBuildMpdu* brief Builds mpdu (MAC header + p

12、ayload) according to IEEE 802.15.4* frame format* param destAddr - Destination short address* pPayload - pointer to buffer with payload* payloadLength - length of payload buffer* return uint8 - length of mpdu*/构造 MPDUstatic uint8 basicRfBuildMpdu(uint16 destAddr, uint8* pPayload, uint8 payloadLength

13、)uint8 hdrLength, n;/txMpdu 是定义txMpduBASIC_RF_MAX_PAYLOAD_SIZE+BASIC_RF_PACKET_OVERHEAD_SIZE+1hdrLength = basicRfBuildHeader(txMpdu, destAddr, payloadLength);/将有效载荷数据放入 MPDU 单元中for(n=0;n0) *pData+= RFD;length-;*/读取 MPDU 的长度/ Read payload length.halRfReadRxBuf(/指定 MPDU 的长度字节的高位默认固定为 0,所以去掉高位,得到长度真实值p

14、Hdr-packetLength / Ignore MSB/ Is this an acknowledgment packet?/ Only ack packets may be 5 bytes in total.if (pHdr-packetLength = BASIC_RF_ACK_PACKET_SIZE) /如果只有 5 个字节长度,则此帧为应答帧/ Read the packethalRfReadRxBuf(/ Make sure byte fields are changed from network to host byte orderUINT16_NTOH(pHdr-panId)

15、;UINT16_NTOH(pHdr-destAddr);UINT16_NTOH(pHdr-srcAddr);#ifdef SECURITY_CCMUINT32_NTOH(pHdr-frameCounter);#endifrxi.ackRequest = !(pHdr-fcf0 /条过 RSSI 指到 CRC 校验/ Read the status word and check for CRC OKpStatusWord= rxMpdu + 4;/ Indicate the successful ACK reception if CRC and sequence number OKif (pSt

16、atusWord1 / No, it is data else / It is assumed that the radio rejects packets with invalid length./ Subtract the number of bytes in the frame overhead to get actual payload.rxi.length = pHdr-packetLength - BASIC_RF_PACKET_OVERHEAD_SIZE;#ifdef SECURITY_CCMrxi.length -= (BASIC_RF_AUX_HDR_LENGTH + BAS

17、IC_RF_LEN_MIC);authStatus = halRfReadRxBufSecure(#elsehalRfReadRxBuf(#endif/ Make sure byte fields are changed from network to host byte orderUINT16_NTOH(pHdr-panId);UINT16_NTOH(pHdr-destAddr);UINT16_NTOH(pHdr-srcAddr);#ifdef SECURITY_CCMUINT32_NTOH(pHdr-frameCounter);#endifrxi.ackRequest = !(pHdr-f

18、cf0 / Read the source addressrxi.srcAddr= pHdr-srcAddr;/ Read the packet payloadrxi.pPayload = rxMpdu + BASIC_RF_HDR_SIZE;/ Read the FCS to get the RSSI and CRCpStatusWord= rxi.pPayload+rxi.length;#ifdef SECURITY_CCMpStatusWord+= BASIC_RF_LEN_MIC;#endifrxi.rssi = pStatusWord0;/ Notify the applicatio

19、n about the received data packet if the CRC is OK/ Throw packet if the previous packet had the same sequence numberif( (pStatusWord1 #elseif ( (pHdr-fcf0 #endifrxi.seqNumber = pHdr-seqNumber;/ Enable RX frame done interrupt againhalIntOff();halRfEnableRxInterrupt();/* GLOBAL FUNCTIONS*/* fn basicRfI

20、nit* brief Initialise basic RF datastructures. Sets channel, short address and* PAN id in the chip and configures interrupt on packet reception* param pRfConfig - pointer to BASIC_RF_CONFIG struct.* This struct must be allocated by higher layer* txState - file scope variable that keeps tx state info

21、* rxi - file scope variable info extracted from the last incoming* frame* return none*/几个重要的底层函数:/*RF 初始化,调用 hal_rf.c 中的函数uint8 halRfInit(void)uint8 i;/ turning on power to analog part of radio and waiting for voltage regulator./模拟稳压器上电,延时 250uS 上电RFPWR = 0x04;/等待 ADI_RADIO_PD 为 0,也可以通过检测中断标志 RFIF.I

22、RQ_RREG_ON 为 1 来等待稳压器稳定while( RFPWR /根据需要设置 RF 功能,自动 CRC,自动应答 0x03/ Setting for AUTO CRC and AUTOACKMDMCTRL0L |= (AUTO_CRC | AUTO_ACK);/打开自动收发转换,接收包后 12 个符号超时,接受应答包控制/ Turning on AUTO_TX2RXFSMTC1 = (FSMTC1 /当 SRXON 发送时包接收不终止/ Turning off abortRxOnSrxon.FSMTC1 /FIFO 门限设为最大值 127/ Set FIFOP threshold t

23、o maximumIOCFG0 = 0x7F;/增益这部分没看懂,好像是用来优化的/ tuning adjustments for optimal radio performance; details available in datasheet */RXCTRL0H = 0x32;RXCTRL0L = 0xF5;/ Turning on receiver to get output from IF-ADCISRXON();halMcuWaitUs(1);/运行随机数发生器/ Enable random generatorADCCON1 for(i = 0 ; i channel);/设置短地

24、址和 PAN id/ Write the short address and the PAN ID to the CC2520 RAMhalRfSetShortAddr(pConfig-myAddr);halRfSetPanId(pConfig-panId);/ if security is enabled, write key and nonce#ifdef SECURITY_CCMbasicRfSecurityInit(pConfig);#endif/*/设置接收中断函数在 hal_types.h 中有中断函数的定义:#define HAL_ISR_FUNC_DECLARATION(f,v

25、) _PRAGMA(vector=v) _near_func _interrupt void f(void)#define HAL_ISR_FUNC_PROTOTYPE(f,v) _PRAGMA(vector=v) _near_func _interrupt void f(void)#define HAL_ISR_FUNCTION(f,v) HAL_ISR_FUNC_PROTOTYPE(f,v); HAL_ISR_FUNC_DECLARATION(f,v)可以看出 HAL_ISR_FUNCTION(f,v)其实就定义了中断函数了。然后中断函数如下:HAL_ISR_FUNCTION( macMc

26、uRfIsr, RF_VECTOR )uint8 rfim;uint8 x;HAL_INT_LOCK(x);rfim = RFIM;if (RFIF / Execute the custom ISRS1CON= 0;RFIFHAL_INT_UNLOCK(x);进入中断后会检查中断类型,然后执行 pfISR 指针指向的中断函数。typedef void (*ISR_FUNC_PTR)(void);/定义中断服务程序的函数指针static ISR_FUNC_PTR pfISR= NULL;void halRfRxInterruptConfig(ISR_FUNC_PTR pf)uint8 x;HAL

27、_INT_LOCK(x);pfISR= pf;HAL_INT_UNLOCK(x);/#define HAL_INT_LOCK(x) st( (x) = EA; EA = 0; )/#define HAL_INT_UNLOCK(x) st( EA = (x); )/中断锁。实际上就是在操作之前关闭总的中断,等操作完成后再打开中断,避免产生不必要的中断*/ Set up receive interrupt (received data or acknowlegment)halRfRxInterruptConfig(basicRfRxFrmDoneIsr);/开所有中断halIntOn();retu

28、rn SUCCESS;/* fn basicRfSendPacket* brief Send packet* param destAddr - destination short address* pPayload - pointer to payload buffer. This buffer must be* allocated by higher layer.* length - length of payload* txState - file scope variable that keeps tx state info* mpdu - file scope variable. Bu

29、ffer for the frame to send* return basicRFStatus_t - SUCCESS or FAILED*/*发送函数uint8 halRfTransmit(void)uint8 status;ISTXON(); / Sending/ Waiting for transmission to finishwhile(!(RFIF RFIF = IRQ_TXDONE;status= SUCCESS;return status;*/uint8 basicRfSendPacket(uint16 destAddr, uint8* pPayload, uint8 len

30、gth)uint8 mpduLength;uint8 status;/*打开接收#define FLUSH_RX_FIFO() st( ISFLUSHRX(); ISFLUSHRX(); )void halRfReceiveOn(void)/发送 CPS 指令FLUSH_RX_FIFO();ISRXON();*/ Turn on receiver if its not onif(!txState.receiveOn) halRfReceiveOn();/ Check packet lengthlength = min(length, BASIC_RF_MAX_PAYLOAD_SIZE);/*等

31、待传输完成void halRfWaitTransceiverReady(void)while (RFSTATUS / Well enter RX automatically, so just wait until we can be sure that the ack reception should have finished/ The timeout consists of a 12-symbol turnaround time, the ack packet duration, and a small margin/BASIC_RF_SYMBOL_DURATION 为 0.5us,因为

32、2MChip/s 的速度是固定的halMcuWaitUs(12 * BASIC_RF_SYMBOL_DURATION) + (BASIC_RF_ACK_DURATION) + (2 * BASIC_RF_SYMBOL_DURATION) + 10);/ If an acknowledgment has been received (by RxFrmDoneIsr), the ackReceived flag should be setstatus = txState.ackReceived ? SUCCESS : FAILED; else status = SUCCESS;/ Turn off

33、 the receiver if it should not continue to be enabledif (!txState.receiveOn) halRfReceiveOff();if(status = SUCCESS) txState.txSeqNumber+;#ifdef SECURITY_CCMhalRfIncNonceTx(); / Increment nonce value#endifreturn status;/* fn basicRfPacketIsReady* brief Check if a new packet is ready to be read by nex

34、t higher layer* param none* return uint8 - TRUE if a packet is ready to be read by higher layer*/检查包是否已准备好被上层读取uint8 basicRfPacketIsReady(void)return rxi.isReady;/* fn basicRfReceive* brief Copies the payload of the last incoming packet into a buffer* param pRxData - pointer to data buffer to fill.

35、This buffer must be* allocated by higher layer.* len - Number of bytes to read in to buffer* rxi - file scope variable holding the information of the last* incoming packet* return uint8 - number of bytes actually copied into buffer*/uint8 basicRfReceive(uint8* pRxData, uint8 len, int16* pRssi)/ Acce

36、ssing shared variables - this is a critical region/ Critical region starthalIntOff();memcpy(pRxData, rxi.pPayload, min(rxi.length, len);if(pRssi != NULL) if(rxi.rssi asdu)解析 Bind_rsp, Unbind_rsp 或 End_Device_Bind_rsp 消息a -指向要解析的消息的指针ZDO_MgmNwkDiscRsp_t *ZDO_ParseMgmNwkDiscRsp( zdoIncomingMsg_t *inMs

37、g );解析 Mgmt_NWK_Disc_rsp 消息ZDO_MgmtLqiRsp_t *ZDO_ParseMgmtLqiRsp( zdoIncomingMsg_t *inMsg );ZDO_MgmtRtgRsp_t *ZDO_ParseMgmtRtgRsp( zdoIncomingMsg_t *inMsg );ZDO_MgmtBindRsp_t *ZDO_ParseMgmtBindRsp( zdoIncomingMsg_t *inMsg );#define ZDO_ParseMgmtDirectJoinRsp(a) (uint8)(*(a-asdu)#define ZDO_ParseMgmt

38、LeaveRsp(a) (uint8)(*(a-asdu)#define ZDO_ParseMgmtPermitJoinRsp(a) (uint8)(*(a-asdu)ZDO_UserDescRsp_t *ZDO_ParseUserDescRsp( zdoIncomingMsg_t *inMsg );void ZDO_ParseServerDiscRsp( zdoIncomingMsg_t *inMsg,ZDO_ServerDiscRsp_t *pRsp );解析 Server_Discovery_rsp 消息void ZDO_ParseEndDeviceBindReq( zdoIncomin

39、gMsg_t *inMsg,ZDEndDeviceBind_t *bindReq );void ZDO_ParseBindUnbindReq( zdoIncomingMsg_t *inMsg,ZDO_BindUnbindReq_t *pReq );#define ZDO_ParseUserDescConf(a) (uint8)(*(a-asdu)void ZDO_ParseDeviceAnnce( zdoIncomingMsg_t *inMsg, ZDO_DeviceAnnce_t *pAnnce );ZDO_MgmtNwkUpdateNotify_t *ZDO_ParseMgmtNwkUpd

40、ateNotify(zdoIncomingMsg_t *inMsg ); ZigBee 学习之学习之 15ZStack API 解读解读 3应用框架(应用框架(AF)应用框架层是应用道 APS 层的 OTA 数据接口。此层也接收数据消息的终端多路复用器。AF为应用提供以下功能: 终端(Endpoint)管理 发送和接收数据哈哈,这里的函数应该就是我们经常要用到的函数了。终端管理终端管理每个设备都是 Zigbee 中的节点,每个节点有长地址和短地址,短地址被其他设备用来发送数据。每个节点又 241 个终端(0 保留,1-240 可分配给应用)。每个终端可以独立设置地址;当设备发送数据时必须指定目

41、标设备的短地址和接收终端。一个应用必须注册一个或多个终端用来接收或者发送数据。简单描述符简单描述符-SimpleDescriptionFormat_t每个终端都必须有一个 Zigbee 简单描述。这些描述对 Zigbee 网络刻画了这个终端,其他设备可以询问这个终端以知道这个设备的类型。typedef structbyte EndPoint;uint16 AppProfId;uint16 AppDeviceId;byte AppDevVer:4;byte Reserved:4; / AF_V1_SUPPORT uses for AppFlags:4.byte AppNumInClusters;

42、cId_t *pAppInClusterList;byte AppNumOutClusters;cId_t *pAppOutClusterList; SimpleDescriptionFormat_t;EndPoint 终端号:1-240 这是节点的子地址,用来接收数据AppProfId 定义了这个终端上支持的 Profile ID(剖面 ID), ID 最好遵循由 ZigBee 联盟的分配。AppDeviceId 终端支持的设备 ID,ID 最好遵循 ZigBee 联盟的分配。AppDevVer 此终端上设备执行的设备描述的版本:0x00 为 Version 1.0.Reserved 保留A

43、ppNumInClusters 终端支持的输入簇数目pAppInClusterList 指向输入 Cluster ID 列表的指针AppNumOutClusters 终端支持的输出簇数目pAppOutClusterList 指向输出 Cluster ID 列表的指针终端描述符终端描述符-endPointDesc_t节点中的每一个终端都必须有一个终端描述符typedef structbyte endPoint;byte *task_id; / Pointer to location of the Application task ID.SimpleDescriptionFormat_t *sim

44、pleDesc;afNetworkLatencyReq_t latencyReq; endPointDesc_t;task_id -任务 ID 指针,当接收到消息时,此任务 ID 将指示消息传递目的。接收到的消息是以OSAL 消息形式包装的,将发送到一个任务simpleDesc -指向这个终端的 ZigBee 简单描述latencyReq -必须用 noLatencyReqs 来填充afStatus_t afRegister( endPointDesc_t *epDesc );为设备注册一个新的终端epDesc -指向终端描述符返回值:afStatus_t -若成功则返回 ZSuccess,否

45、则返回 ZComDef.h 中定义的错误epList_t *afRegisterExtended( endPointDesc_t *epDesc, pDescCB descFn );在上面函数功能的基础上增加了回调函数,当终端的简单描述符被查询时将调用此回调函数。这样应有就可以动态改变简单描述符而不用 RAM/ROM 来储存描述符了。descFn -回调函数指针。相关函数必须为简单描述符分配足够的空间,填充简单描述符,然后返回指向简单描述符的指针,调用者将释放为描述符分配空间。epList -指向终端列表元件的指针,如果失败则为 NULLendPointDesc_t *afFindEndPoi

46、ntDesc( byte endPoint );从一个终端找到终端描述符endPoint -要寻找的终端描述符的终端号endPointDesc_t -指向终端描述符的指针,若失败则为 NULLbyte afFindSimpleDesc( SimpleDescriptionFormat_t *ppDesc, byte EP );从一个终端找到终端描述符。若返回值非零则必须调用 osal_mem_free()来释放描述符的内存占用。ppDesc -指向指向简单描述符的指针。EP 终端简单描述符需要uint8 afGetMatch( uint8 ep );默认情况下,设备将响应 ZDO 匹配描述符请求。用这个函数来获得 ZDO 匹配描述符应答的设置。ep -用来获得 ZDO 匹配描述符响应行为的终端返回值:TRUE-允许响应,FALSE-不允许或者终端未找到uint8 afSetMatch( uint8 ep, uint8 action );默认情况下,设备将响应 ZDO 匹配描述符。可以用这个函数来改变这个行为,比如 ep 为1,action 为 FALSE,ZDO 将不响应终端 1 的 ZDO 匹配面述符请求。ep -用来获得 ZDO 匹配描

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 教育专区 > 教案示例

本站为文档C TO C交易模式,本站只提供存储空间、用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。本站仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知得利文库网,我们立即给予删除!客服QQ:136780468 微信:18945177775 电话:18904686070

工信部备案号:黑ICP备15003705号-8 |  经营许可证:黑B2-20190332号 |   黑公网安备:91230400333293403D

© 2020-2023 www.deliwenku.com 得利文库. All Rights Reserved 黑龙江转换宝科技有限公司 

黑龙江省互联网违法和不良信息举报
举报电话:0468-3380021 邮箱:hgswwxb@163.com