simpiciTi实例Word文件下载.docx
- 文档编号:21994310
- 上传时间:2023-02-02
- 格式:DOCX
- 页数:15
- 大小:307.67KB
simpiciTi实例Word文件下载.docx
《simpiciTi实例Word文件下载.docx》由会员分享,可在线阅读,更多相关《simpiciTi实例Word文件下载.docx(15页珍藏版)》请在冰豆网上搜索。
Digg
Yahoo!
Bookmarks
这段时间折腾了一下SimpliciTI,有些个人理解,和大家讨论一下,希望有这方面经验的人不吝赐教,一个人闷头搞确实听没意思的。
同时也在考虑从现有的MSP430向更强的M3平台移植(比如Stellaris),有兴趣的朋友可以一起讨论一下呀。
一、搭建SimpliciTI环境
一个MCU和一个RF模块,这就是搭建SimpliciTI环境的硬件需求(TI的SoC也是在芯片内部集成了RF模块)。
当然了,这个协议栈是有版权的,当你用作商业用途时需要向TI缴纳一定的费用,而用于学习时,TI也会要求你至少用他的RF芯片。
这里使用的是TI的eZ430-RF2500套件,板载MSP430F2274和CC2500射频芯片,使用芯片天线,传输距离并不远,如果离开一段距离或者有遮蔽物就会出现丢包,这个我们会在后面进行测试。
电路图如下(点击看大图),2274和CC2500之间通过SPI和两个IO(中断方式)通信,一般网上卖的模块也会留出这些接口。
如果对RFPCB设计没有信心,淘宝上有10块钱的CC2500模块,虽然是白菜价,但是PCB天线一般都是低于0dB的,通信距离可想而知。
TI官方的开发套件,$49
淘宝上可以找到的CC2500模块,¥10
原理图
同时,此平台也对外开放一个USB调试接口(包括UART和SBW)。
接口定义
二、SimpliciTI协议栈结构与移植
SimpliciTI协议的一大特点就是简单,所以在极大简化开发过程的同时也带了很多限制,比如缺少完备的路由协议,最多4个RE(使通信距离受限),即使低功耗也是在ED关闭RF接收功能的前提下实现的(限制双向通信)。
不过即使如此,也丝毫不影响它为无线网络通信带来的便利,你可以根据应用需求在ZigBee和SimpliciTI之间取舍。
想要使用它你需要下载协议栈代码,下面是及针对RF2500套件的演示代码:
通用协议栈SimpliciTI-IAR1.1.1可以在TI官网上下载:
安装后在安装目录下可以找到代码和说明文档,建议看一下DevelopersNotes、SampleApplicationUser'
sGuide和API文档,如果需要涉及加密、调频等应用,这里还有相应的ApplicationNote。
SimpliciTI本身的软件分为3层,即BSP、MRFI和NWK:
BSP是一个轻量级板级支持包,包含了MCU、SPI(这个必须有)、LED和Button,简单吧,TI的意思是尽可能的减少协议栈本身的硬件内容,因此如果想要用串口或者ADC,就要自行解决,我们暂且将这些额外添加的硬件控制代码称为Driver吧。
MRFI是最小射频接口,主要是与BSP中的SPI对接以及射频芯片的控制代码。
如果要移植协议栈,就需要更改与MCU定义、中断、IO和SPI相关的代码,不过只要你使用MSP430或CC系列SoC作为MCU可以直接在代码中找到相近的Board从而减少工作量。
当然啦,如果你是高手或者兼有求知和耐心的美德,甚至可以自己写底层而只保留NWK和APP层,不过这不是我们现在的目的,至少目前不是。
NWK网络层负责数据收发队列,同时包含很多网络层应用,注意区分NWKApplications与用户的应用代码(CustomerApplications)的区别,这些网络层应用是以端口作为标识的(如Ping是0x01,Link是0x02),相应的函数以nwk_作为前缀,而我们通常将用户代码称作应用层。
SimpliciTI的端口(Port)与TCP/IP的端口神似(similarinspirit^_^),每个端口对应一种应用,用户也可以定义自己的网络层应用。
网络层为用户提供了API函数,以SMPL_为前缀,如SMPL_Link等,我们的工作就是利用这些API实现组网及无线通信。
三、建立第一个简单双向通信程序
(1)配置工程
打开演示代码eZ430-RF2500WirelessSensorMonitor中的Sensor_Demo_AP_as_Data_Hub工程,如果你使用的是eZ430-RF2500套件,直接修改其中的Application文件就好了,如果不是TI的官方套件,可以选择一个硬件组成相近的工程,修改MCU定义和按键、LED等配置,这里不再深究,以后可以专门开贴讨论。
【Tips】在下载程序时可能出现这个错误,具体描述为:
Fatalerror:
TheObjectfilecontainsfeaturesnotsuportedbythedriver.
Sessionaborted!
Failedtoloaddebugee:
…
这是因为在新版本的IAR中同时使用了选项配置和命令行,Debugger的版本较旧不识别,只需要取消命令行即可。
打开工程后可以看到两种器件,AP(AccessPoint)和ED(EndDevice)。
AP是组网的关键,负责网络的建立和维护,同时负责对外通信,有点类似于ZigBee中的协调器。
网络中最多只能有一个AP,在某些模式下(如P2P)可以不需要AP,但是这样的网络需要固定参数而缺少灵活性。
ED是终端设备,在TI的演示中负责入网后通过片上温度传感器采集自身的温度,并发送给AP,由AP将接收到的数据转换成字符串后通过串给上位机。
在左侧的WorkSpace栏选择AP或者ED进行选择编译。
和网络相关的设置可以在几个配置文件中修改,其中smpl_config_AP.dat和smpl_config_ED.dat文件定义了设备类型、最大连接数、发送和接收帧队列长度等内容,smpl_nwk_config.dat文件则定义了基本的网络参数如网络和应用层负载长度、最大跳数等,这些配置可以在不同的应用中灵活选择,这里我们采用默认配置。
(2)AP节点
首先,通过BSP_Init函数初始化BSP,然后初始化需要的外围设备如串口、定时器、AD等,这里的串口函数并不包含在SimpliciTI中,而是以virtual_com_cmds.c文件的形式添加到工程中,也可以像我那样写自己的串口函数(参见我的SED430-RF2500一贴),甚至加入printf和scanf。
SED430-RF2500传送门:
在设备初始化完成后,需要初始化SimpliciTI网络,AP中对应的函数为:
SMPL_Init(sCB);
这里的sCB是一个回调函数,本例中用来在接收到帧时区分是入网还是数据,并分别处理,它会在CC2500RX接收中断后调用。
想要研究协议结构的童鞋可以一路Gotodefinition找到函数调用的地方,现在我们只需定义该函数而无须理会调用机制。
回调函数的原型如下,当lid为0时,表示有设备入网,此时sJoinSem++,在主函数的sJoinSem子过程中进行处理,建立连接并为其分配LinkID。
如果lid不为零则表示该设备已经入网并分配了LinkID,这个数据帧被作为通信数据在主函数的sPeerFrameSem子过程中通过SMPL_Recieve函数接收。
static
uint8_tsCB(linkID_tlid)
{
if
(lid)
{
sPeerFrameSem;
}
else
sJoinSem;
return
0;
}
至此整个初始化工作完成,然后AP进入while
(1)循环,这个循环中包含几个子过程,这里我们只需要sJoinSem和sPeerFrameSem两个过程。
sJoinSem过程内容如下:
if(sJoinSem&
&
(sNumCurrentPeers<
NUM_CONNECTIONS))
while
(1)
(SMPL_SUCCESS==SMPL_LinkListen(&
sLID[sNumCurrentPeers]))
break;
sNumCurrentPeers;
BSP_ENTER_CRITICAL_SECTION(intState);
sJoinSem--;
BSP_EXIT_CRITICAL_SECTION(intState);
一旦进入这个过程(有设备入网),软件将持续通过SMPL_LinkListen函数监听ED发起的链接,在链接建立后会为该链接分配一个LinkID,以后数据收发就考这个LinkID作为标识。
该函数的实参就是一个用来存放LinkID的数组。
sNumCurrentPeers是当前连接设备计数器,这里要注意的是在处理完入网帧后,需要减少sJoinSem的值,而sJoinSem是一个公共变量,同时受回调函数的控制。
sCB是一个在中断中执行的函数,所以要通过BSP_ENTER_CRITICAL_SECTION进行临界保护,参数intState其实是一个unsignedshort型变量,在主函数中定义,用于保存相关寄存器,在退出临界状态时恢复。
对接收到的通信数据的处理则要靠sPeerFrameSem:
(sPeerFrameSem)
uint8_t
msg[MAX_APP_PAYLOAD],len,i;
for
(i=0;
i
(SMPL_SUCCESS==SMPL_Receive(sLID[i],msg,&
len))
USCI0_SendDataString(msg,len);
sPeerFrameSem--;
SMPL_Receive函数读取接收到的数据帧,将APP_PAYLOAD分离出来保存在msg数组中,len作为实参保存msg的长度,最后通过USCI0_SendDataString发送给上位机。
void
USCI0_SendDataString(uint8_t*msg,uint8_tlen)
int
i;
for(i=0;
i
USCI0_PutChar(msg[i]);
其中USCI0_PutChar这个函数需要自己写,如果是带有USCI模块的430可以使用我的SED430-RF2500中的UART.c,若是USART模块的430则参见SED430中的串口文件。
传送门上面已经给出。
那么如果要给ED发数据怎么办呢,依然只要一个函数即可:
定义一个msg数组,写入要发送的数据,然后:
SMPL_Send(lid,msg,len);
lid是要目的设备的LinkID,len是要发送数据的长度,这里len和接收函数不同是形参,注意不要超过最大负载长度哦。
这就是AP的部分,可以完成入网,数据接收发送功能,另外还有一些跳频和信号强度检测的功能,可以自己研究一下。
(3)ED节点
修改代码之前,需要给ED设置一个32位地址,这个地址相当于TCP/IP中的IP地址,由于SimpliciTI没有MAC层,所以设备就要靠这个地址识别数据包是不是发给自己的。
网络中每一个设备的地址都应当是唯一的,否则会发生冲突。
可以在对应设备的.dat配置文件中修改这条语句:
-DTHIS_DEVICE_ADDRESS="
{0x7A,0x56,0x34,0x12}"
若不想一个一个设置,可以参考范例共给出的产生随机地址的方法,通过ADC或者VLO采集一个真随机数(虽然是真随机数不过不知道是什么分布的),换算成地址并写入Flash。
ED和AP的设备初始化过程一样,初始化完成后,开始检测是否存在网络并,直到检测到AP建立的网络并入网。
__bis_SR_register函数的作用是休眠并等待TA中断,如果不想采用这种方式,也可以通过__delay_cycles函数或自己编写Delay函数实现延时。
//搜寻并加入网络
(SMPL_SUCCESS!
=SMPL_Init(sCB))
BSP_TOGGLE_LED1();
//LED闪烁
BSP_TOGGLE_LED2();
__bis_SR_register(LPM0_bitsGIE);
如果ED不需要接收数据,SMPL_Init时可以不要回调函数:
SMPL_Init(0)。
如果需要接收数据,则应当开启RX:
SMPL_Ioctl(IOCTL_OBJ_RADIO,IOCTL_ACT_RADIO_RXON,0);
ED的回调函数中只处理数据帧而没有入网帧,其形式如下:
staticuint8_tsCB(linkID_tlid)
return0;
ED在加入网络后还不能直接和AP通信,首先需要建立一个连接(Link):
//向AP发起Link
while(SMPL_SUCCESS!
=SMPL_Link(&
LID_AP))
//替换成你自己的延时函数
连接建立好以后,AP的LinkID被保存在LID_AP变量中,因为我们只需要和一个固定的AP通信,所以不需要数组来保存多个LinkID。
至此,ED已经可以和AP自由的交换数据了,在sPeerFrameSem子过程中,我们将接收到的数据发还给AP并翻转一个LED。
//接收到RF数据
if(sPeerFrameSem)
uint8_tmsg[MAX_APP_PAYLOAD],len;
(SMPL_SUCCESS==SMPL_Receive(LID_AP,msg,&
SMPL_Send(LID_AP,msg,len);
//发回接收到的数据
//翻转LED状态
搞定,可以编译运行了。
设置Showbuildmessages显示全部消息,编译……
可以看到软件占用资源情况,想要运行这个协议栈,还要跑一些自己的程序,至少要有10KB的Flash和1KB的RAM,不过比起ZigBee那样的重量级协议,已经非常节省了。
四、运行结果
这是本例的工程文件(IAR5.30),分别将AP和ED的程序下载到模块中。
RF2500_Example_01.rar
装好各模块:
AP模块通过USBDebugger连接PC
ED模块,这里外接了电源
打开你的串口调试工具,发送数据。
接收到的数据与发送的一致,表明整个通信没有问题。
同时,每发送一帧数据,ED模块的LED的状态会改变一次。
这里设置了定时发送:
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- simpiciTi 实例