CC1101的WOR电磁波唤醒方式用法
博客很久没更新,总没抽出时间来做更多的博文,最近把CC1101玩了一遍,现在把CC1101的一些用法和比较深入的东西拿出来分享下。
我的辛苦愿为你分享,转帖请保留http://blog.ednchina.com/jikeppq163/
WOR很多人只见其音不见其容,最近经过一翻折腾终于在CC1101上把WOR解决了。
这个配置方式其实对于 CC1100/CC1100E/CC2500等芯片都是通用的,对于SOC 芯片,CC1110和CC2510等芯片可以借鉴下,原理上没区别。
首先,先来简单说明下WOR到底是个什么功能。WOR就是使芯片处于SLEEP状态下,定时唤醒扫描空中信号的功能。米错,虽然说的是电磁波唤醒,但并不是无消耗的无线功能,需要设定一个定时扫描的周期.然后,每个周期醒过来一次扫描空间信号。
需要注意的是,如果引导码正确,即使不是发给它的数据,它也会接收,然后醒过来。
下面来看一下源代码:
/******************************************************************************
<函数说明>
函数名称:CC1101_IntWOR
函数入参:Time 时间 分 秒级和毫秒级 使用TimeLive来选择
函数说明:电磁波WOR唤醒功能初始化
函数备注:进入电磁波唤醒,也会同时进去到掉电模式,即SLEEP. 再次进入SLDE将会退出掉电模式
当 TimeLive = WOR_MS 时, 不可大于60000ms 可用60000
当 TIMELIVE = WOR_S 时,不可大于 61947S
#define WOR_S 0x11
#define WOR_MS 0x22
返回值:
******************************************************************************/
uint8 CC1101_InitWOR(uint32 Time)
{
//uint16 T_Event0=60; //把 EVENT0的时间设定为1S
uint32 EVENT0=0;
uint16 WOR_RES=1;
uint16 WOR_rest=1; //2^(5*WOR_RES) 的值
WORmode =1; //开启WORMOD模式
//当输入数据 不符合规则的时候返回错误
if(Time<15 | Time>61946643) return 0;
/* WOR WOR_RES设定
以WOR_RES所能区分的最大时限 区分WOR_RES大小
WOR_RES值 时间(极限最大值)(ms)
0 1890.4615 *14.34 (最小值)
1 60494.7692
2 1935832.6153
3 61946643.6923
*/
if(Time<1890) WOR_RES=0;
else if(Time<60494) WOR_RES=1;
else if(Time<1935832) WOR_RES=2;
else if(Time<61946643) WOR_RES=3;
// WOR_rest 默认等于1
// WOR_rest=2^5WOR_RES
/*
if(!WOR_RES) WOR_rest=1;
else{
for(uint8 t=0;t<(5*WOR_RES);t++)WOR_rest *= 2;
}
*/
WOR_rest <<= 5*WOR_RES;
// 设置 Event0 timeout (RX 轮询间隔时间);
// 事件0 EVENT0时间长度公式 T_event0 = 750 / f_xosc * EVENT0 * 2^(5*WOR_RES) = 1 s, f_xosc 使用的是 26 MHz
// EVENT0 = (F_xosc*Time)/((750*WOR_rest)*Tms);
//由于计算的值普遍偏大,如果照常计算会出现溢出, 所以分段处理
EVENT0 = F_xosc/1000;
if(EVENT0>Time)
{
EVENT0 = EVENT0*Time;
EVENT0 = EVENT0/(750*WOR_rest);
}
else
{
EVENT0 = (Time/(750*WOR_rest))*EVENT0;
}
CC1101_WriteCode(CCxxx0_SIDLE); //空闲模式
// 设置接收超时 Rx_timeout =2.596 ms.
// MCSM2.RX_TIME = 001b
// => Rx_timeout = EVENT0*C(RX_TIME, WOR_RES)
CC1101_WriteReg(CCxxx0_MCSM2, 0x10); //RX_TIME 0 占空比最大
// Enable automatic FS calibration when going from IDLE to RX/TX/FSTXON (in between EVENT0 and EVENT1)
//在TX,RX后 自动校准 XSOC时限 (10) 149-155uS
CC1101_WriteReg(CCxxx0_MCSM0, 0x18); //校准 FS_AUTOCAL[1:0] 01 重IDLE转到TX OR RX模式时
//
//写入 事件0 时间
CC1101_WriteReg(CCxxx0_WOREVT1, (uint8)(EVENT0>>8)); // High byte Event0 timeout
CC1101_WriteReg(CCxxx0_WOREVT0, (uint8)EVENT0); // Low byte Event0 timeout.
// 启动 WOR RCosc 校准
// 因为进入休眠后只使用RC频率周期,RC受环境和温度影响较大,所以必须一段时间或者WOR唤醒后重新校准一次时钟.
// 在WOR没启动之前 RC须得先行启动
// tEvent1 时间设置为最大,设置 T_event1 ~ 1.4 ms
CC1101_WriteReg(CCxxx0_WORCTRL, 0x78| WOR_RES); //tEvent1 =0111
//--RC_CAL =1 自动校准
//halWait(30); //等待校准完成
//CC1101_WriteReg(CCxxx0_WORCTRL, 0x70 | WOR_RES); // tEvent1 =0111 即 48 (1.333-1.385 ms)
// RC_CAL =0
//CC1101_WriteReg(CCxxx0_RCCTRL1, RCC1);
//CC1101_WriteReg(CCxxx0_RCCTRL0, RCC0);
//把SO口 设置成通知口 当有数据过来时 置低
CC1101_WriteReg(CCxxx0_IOCFG2, 0x06); //0x24);
CC1101_WriteCode(CCxxx0_SFRX);
CC1101_WriteCode(CCxxx0_SWORRST); //复位到 事件1
CC1101_WriteCode(CCxxx0_SWOR); //启动WOR
// CC1101_WriteCode(CCxxx0_SPWD); //进入断电模式
return 1;
}
最后再来说几个注意事项:
1. 接收端使用的是WOR的时候,发送端一定要使用连续发送模式。
2. 设置好GPIO口,上面的代码中有设置GPIO,GPIO可以作为一个接收指示器。
3. 如果发现经常收到一些乱码,那么你环境的干扰强度太高,建议增加引导码长度,或者使用CCA空闲信道评估。
4. WOR的使用会导致CC1101进入休眠状态,这种状态可以在给予GPIO口信号来激活,回到空闲状态。
5. 要打开接收中断。
我的辛苦愿为你分享,转帖请保留http://blog.ednchina.com/jikeppq163/
下面我们来看看WOR的一些原理。
上面是一个WOR使用时间的示意图,看得到事件0所占用的时间最长,而WOR就是一个接一个的事件0。
时间的时间长度,在这里面可以参照源代码,要注意WOR_RES值的时间定义有个区间,每个区间都不是和下一个区间刚好相连的。
睡眠的最短时长是依照晶振的频率设定的。26M的时候最短时间为11.08ms。
事件0的时间长度为事件1+空闲模式+接收溢出+休眠时间。下面我们可以看一个电平图:
图上标注的时间就是一个周期的电平变化,事件1激活芯片,然后进入空闲模式,接收扫描,时间溢出,如果有收到数据,那么会延长事件0的时间。
我的辛苦愿为你分享,转帖请保留http://blog.ednchina.com/jikeppq163/
用户377235 2015-6-16 15:51
EVENT0 = F_xosc/1000; 这里为什么要除1000,计算公式里没这一步啊
用户343036 2014-12-3 17:54
用户377235 2013-10-22 09:14
能指导下吗,发送方连续发送是什么概念
用户445390 2013-8-27 17:33
用户377235 2013-2-23 11:56
用户377235 2012-8-27 16:42
辛苦了,谢谢。
用户1603637 2012-8-19 15:32
用户377235 2012-4-23 17:54
比较详细,不错,试试看