文章延续之前【物联网无线通信技术】系列文章的风格,首先对ZigBee这种在物联网发展初期出现的无线通信技术进行了相关背景概念的介绍,并横向介绍了几款时间跨度比较大的ZigBee芯片。然后以CC2530为例,从硬件到软件介绍了ZigBee这中无线通信技术的实现。相信读者通过通读本篇文章,能够对ZigBee无线通信的实现有一个直观的认识。因篇幅有限,本篇中有些概念和功能没有详细展开,读者可以通过文中的外链进行更深的探究。
目录
ZigBee概述
CC2530EM+SmartRF05
例程解析
工程代码结构
Basic RF
Hardware Abstraction Layer
工程编译与下载
ZigBee技术是一种短距离无线通信技术,主要的特色有数据传输速率低、功耗低、实现成本低、网络容量大等,常用于智能家居,工业自动化等领域。Zigbee基于IEEE 802.15.4标准,该标准定义了用于低速无线个人局域网(LR-WPANs)的物理层和介质访问控制(MAC)层。Zigbee在此基础上提供了网络层、安全特性和各种用例的应用框架,应用层的开发可以根据用户的应用需要,对其进行灵活的组网、开发利用。常见的ZigBee的工作频段为2.4G,一共具有16个信道11 (2405 MHz) to 26 (2480 MHz),理论上通信速率可达250kbps,采用O-QPSK调制,实际的通信距离取决于发射功率和天线的效率。
下面介绍几款常见的ZigBee芯片厂商。
射频板我们使用CC2530EM,它是使用CC2530为核心基于推荐的参考设计实现的完整射频模块。该模块配备一个32 MHz 晶振、一个32.768 kHz 晶振、射频电路上的巴伦和天线匹配滤波器等无源元件以及用于连接天线的SMA 连接器。其相关的参考原理设计可以点击此处跳转。
这里如果需要有更远的传输距离,可以选用CC2530-CC2591EM,它增加了具有高达+22dBm增益的2.4GB射频前端芯片CC2591。
底板我们使用SmartRF05,它能连接多个德州仪器(TI)低功耗射频模块。该板具有广泛的外围接口,例如:
我们在上图的底板红框处插入射频板,然后通过CC Debug连接到底板即可进行程序下载调试,点击这里跳转底板相关参考设计。
Ti官网提供了相关例程供用户评估射频性能,点击这里跳转下载(不要私信博主要代码了,能上传的网络资源均已上传或者在文章中添加链接,具体的项目工程代码绝不会给)。
官网的例程一共包含以下三个功能实现:
工程代码主要由以下三个部分组成(组件):
工程的帮助文档位于docs文件夹中。工作区文件位于ide文件夹中。不同应用程序的代码可以在文件夹 source/Apps 中找到。组件文件夹包括应用程序使用的不同组件的源代码。HAL和基本射频
源代码组件位于组件文件夹下。
基本射频层使用双向射频链路提供简单的发射和接收协议。基本射频协议提供数据包传输和接收服务。它还通过使用CCM-64身份验证和数据包加密/解密进行通信,提供安全功能。安全功能的使能可以通过定义编译开关SECURITY_CCM来实现。该协议使用符合IEEE 802.15.4的MAC标准数据包。然而,它不提供完整的MAC层,仅提供用于两个节点之间通信的简单数据链路层。
数据帧如下图所示。
Basic RF的使用主要分为以下三个部分。
通过调用 basicRfReceiveOn(),无线电接收器将始终保持开启状态。节点能够随时接收数据包,缺点是电流消耗较高。通过调用 basicRfReceiveOff()关闭无线电接收器。
如果需要调用Basic RF层相关API,需要提前包含basic_rf.h与basic_rf_security.h。
下面是结构体与API原型代码,代码中包含API的功能说明。
typedef struct {
uint16 myAddr;
uint16 panId;
uint8 channel;
uint8 ackRequest;
#ifdef SECURITY_CCM
uint8* securityKey;
uint8* securityNonce;
#endif
} basicRfCfg_t;
/***********************************************************************************
* GLOBAL FUNCTIONS
*/
/* Initialise basic RF datastructures. Sets channel, short address and PAN ID in the chip and configures interrupt on packet reception. The board peripherals and radio interface must be called before this function with the function halBoardInit(). */
uint8 basicRfInit(basicRfCfg_t* pRfConfig);
/* Send packet to the given destination short address. Returns TRUE if packet was sent
successfully, and FAILED otherwise. If ackRequest is TRUE the return value of this function will only be TRUE if an acknowledgment is received from the destination. */
uint8 basicRfSendPacket(uint16 destAddr, uint8* pPayload, uint8 length);
/* Returns TRUE if a received packet is ready to be retrieved by higher layer. */
uint8 basicRfPacketIsReady(void);
/* Returns the RSSI value of the last received packet */
int8 basicRfGetRssi(void);
/* Retrieve packet from basic RF layer. The caller is responsible for allocating buffer space for data and the RSSI value. */
uint8 basicRfReceive(uint8* pRxData, uint8 len, int16* pRssi);
/*Turn on receiver on radio. After calling this function the radio is kept on until basicRfReceiveOff is called. */
void basicRfReceiveOn(void);
/* Turn off receiver on radio, and keep it off unless for transmitting a packet with Clear Channel Assessment. */
void basicRfReceiveOff(void);
下面的时序图介绍了软件组件在初始化工作中完成的调用流程。
下面的时序图介绍了软件组件在发送工作中完成的调用流程。
下面的时序图介绍了软件组件在接收工作中完成的调用流程。
最后再次强调以下例程中的Basic RF只是一种非常简单的IEEE 802.15.4实现,它并不完整,建议使用TIMAC或SimplicTI代替 Basic RF进行产品开发。
要使用HAL组件中的API,需要包含hal_rf.h和hal_rf_security.h。
下面的代码包含此组件涉及的API以及对应的功能说明。
/* Powers up the radio, configures the radio with recommended register settings, enables
autoack and configures the IO on the radio. This function must be called after halBoardInit(). */
uint8 halRfInit(void);
/* Set TX output power */
uint8 halRfSetTxPower(uint8 power);
/* Transmit frame */
uint8 halRfTransmit(void);
/* Set gain mode. This is only used if external LNA/PA is used. */
void halRfSetGain(uint8 gainMode); // With CC2590/91 only
/* return radio chip id register */
uint8 halRfGetChipId(void);
/* Return radio chip version register */
uint8 halRfGetChipVer(void);
/* Return random byte. */
uint8 halRfGetRandomByte(void);
/* Return RSSI offset for radio. */
uint8 halRfGetRssiOffset(void);
/
/* Write the number of bytes given by length from the memory location pointed to by the pointer data to the radio TX buffer. */
void halRfWriteTxBuf(uint8* pData, uint8 length);
/* Read the number of bytes given by length from radio RX buffer to the memory location pointed to by the pointer data. The radio status byte is returned. */
void halRfReadRxBuf(uint8* pData, uint8 length);
/* Wait until the transceiver is ready */
void halRfWaitTransceiverReady(void);
/* Turn on receiver on radio. */
void halRfReceiveOn(void);
/* Turn off receiver on radio. */
void halRfReceiveOff(void);
/* Clear and disable RX interrupt. */
void halRfDisableRxInterrupt(void);
/* Enable RX interrupt. */
void halRfEnableRxInterrupt(void);
/* Configure RX interrupt, and setting the function to be called on interrupt. */
void halRfRxInterruptConfig(ISR_FUNC_PTR pfISR);
///
// IEEE 802.15.4 specific interface
/* Set RF channel. Channel must be in the range 11-26. */
void halRfSetChannel(uint8 channel);
/* Write 16 bit short address to the radio. */
void halRfSetShortAddr(uint16 shortAddr);
/* Write 16 bit PAN ID to the radio. */
void halRfSetPanId(uint16 PanId);
首先,连接好底板和主板,并将开发板与电脑通过USB线连接。
首先确保EM选择开关(SmartRF05EB上的P19)位于SoC/TRX位置,使用IAR打开CC2530_SW_examples.eww。可以看到下图有针对三种不同例程的工程。选择对应工程,然后选择Project->Rebuild All进行代码编译。
此时可以直接通过IAR进行在线仿真调试,也可以通过通过Ti提供Flash Programmer进行hex程序烧写。
十六宿舍 原创作品,转载必须标注原文链接。
©2023 Yang Li. All rights reserved.
欢迎关注 『十六宿舍』,大家喜欢的话,给个,更多关于嵌入式相关技术的内容持续更新中。