尊敬的,
我使用 CC1101进行数据通信、并且需要使用 WOR 模式以降低功耗。
WOR 空闲间隔分为1和50ms 两种。您可以看到函数 CC1101 WOR Init。
在正常情况下、空闲间隔在1和50ms 之间切换、但在某些情况下、
对应于50ms 的空闲间隔将大于6s、大于7s 或14.8s、
对应于1的时间间隔将增加10、60、70或148。
如下图所示、我仅在两种情况(1或50ms)下配置了 WOREVT。
但实际空闲时间与配置不一致、
错误图:

正确的示意图:

void CC1101_RX_Mode(uint8_t mode, uint8_t pkg_mode)
{
CC1101_radio_idle(RX);
rxData.pktFormat = pkg_mode;
Radio_mode = mode;
if (rxData.pktFormat == INFINITE)
{
#if (RF_EN == 2)
DTU = 3;
#endif
CC1101_SET_Pkg_infinite(RX);
}
else
{
CC1101_TRX_prepare(RX);
}
}
/**
* @brief :CC1101_radio_idle
* @param :type : TX RX
* @note :无
* @retval:无
*/
void CC1101_radio_idle(uint8_t type)
{
RESET_GDO0;
RESET_GDO2;
reset_rxData();
reset_txData();
if (Radio_mode == WOR_MODE)//if (type == TX && Radio_mode == WOR_MODE)
{
CC1101_SET_CSN_LOW();
Delay_Us(500); // cc1101.page30:CSn low to positive edge on SCLK, in power-down mode
}
CC1101_Write_Cmd(CC1101_SIDLE);
Delay_Us(1000); // 每次由空闲转换到发送或接受是延时必须超过810us。
CC1101_Write_Cmd(CC1101_SFRX);
CC1101_Write_Cmd(CC1101_SFTX);
if (type == TX)
{
CC1101_Write_Reg(CC1101_PATABLE, PaTabel[I_p.para[1]]);
if (Radio_mode == WOR_MODE)
{
CC1101_TRX_prepare(TX);
}
}
}
/**
* @brief :CC1101_TRX_prepare
* @param :type : TX RX
* @note :无
* @retval:无
*/
void CC1101_TRX_prepare(uint8_t type)
{
CC1101_Write_Reg(CC1101_PKTLEN, 0xff); //
// CC1101_Write_Reg(CC1101_IOCFG2,0x0E); //Carrier sense.
CC1101_Write_Reg(CC1101_IOCFG2, 0x07); // CRC_OK
CC1101_Write_Reg(CC1101_PKTCTRL0, 0x45); // 可变长度
// ADR_CHK:Address check, no broadcast
CC1101_Write_Reg(CC1101_PKTCTRL1, 0x0D);
CC1101_Write_Reg(CC1101_MCSM0, 0x18); // When going from IDLE to RX or TX (or FSTXON)
CC1101_Write_Reg(CC1101_IOCFG0, 0x06); // 收到同步字置位,数据包末尾\地址校验失败\RXFIFO溢出时取消置位
CC1101_Write_Reg(CC1101_MCSM2, 0x07); // RX_TIME:Until end of packet
if (reed_mode)
Group_addr = 65535;
else
memcpy(&Group_addr, &I_p.ADDR[1], 2);
CC1101_Set_Channel(Group_addr);
CC1101_Set_Address((Group_addr & 0xff) ^ ((Group_addr >> 8) & 0xff));
if (type == RX)
{
// Asserts when the RX FIFO has overflowed. De-asserts when the FIFO has been flushed.
if (Radio_mode == WOR_MODE)
{
CC1101_Set_Sync(1);
CC1101_WOR_Init();
SET_GDO2_UP;
}
else
{
CC1101_Set_Sync(0);
CC1101_check_RX(); // CC1101_Write_Cmd(CC1101_RX);//
SET_GDO0_DOWN; // 实时接收:GDO0超时
}
}
}
/**
* @brief :CC1101初始化WOR功能
* @param :无
* @note :无
* @retval:无
*/
void CC1101_WOR_Init(void)
{
//CC1101_Write_Cmd(CC1101_SIDLE);
// CC1101_Write_Reg(CC1101_MCSM2,0x10);//RX_RSSI=1(便于快速休眠)
//uint16_t sl_p;
if (WOR_short)
{
CC1101_Write_Reg(CC1101_MCSM0, 0x28); // When going from RX or TX back to IDLE automatically
//sl_p = (uint32_t)(50 * 26000 / 750); //0x06C5
CC1101_Write_Reg(CC1101_WOREVT1, 0x06); // Event0高8位 50ms
CC1101_Write_Reg(CC1101_WOREVT0, 0xC5); // Event0低8位
CC1101_Write_Reg(CC1101_MCSM2, 0x10); // 0x10 50ms*12.5%
}
else
{
CC1101_Write_Reg(CC1101_MCSM0, 0x38); // 每第四次当从 RX 或 TX 返回空闲时自动进行校准
//sl_p = (uint32_t)(1000 * 26000 / 750); //0x876A
CC1101_Write_Reg(CC1101_WOREVT1,0x87);//Event0高8位 1000ms
CC1101_Write_Reg(CC1101_WOREVT0,0x6A);//Event0低8位
CC1101_Write_Reg(CC1101_MCSM2, 0x13); // 1000ms*0.391%=391us
}
CC1101_Write_Reg(CC1101_WORCTRL, 0x38); // 事件 1 工作暂停前事件 0 后 WOR_RES==0 1LSB周期 (27μs – 31μs)
Delay_Ms(10);
CC1101_Write_Reg(CC1101_WORCTRL, 0x30);
uint8_t calib1 = CC1101_Read_Status(RCCTRL1_STATUS);
uint8_t calib0 = CC1101_Read_Status(RCCTRL0_STATUS);
CC1101_Write_Reg(CC1101_RCCTRL1, calib1);
CC1101_Write_Reg(CC1101_RCCTRL0, calib0);
CC1101_Write_Reg(CC1101_IOCFG0, 0x25); // 0x25 WOR ENVT1
//CC1101_Write_Reg(CC1101_IOCFG0, 0x24); // 0x24 WOR ENVT0
//CC1101_Write_Cmd(CC1101_SIDLE );
CC1101_Write_Cmd(CC1101_SWORRST); // Resets the real time clock
CC1101_Write_Cmd(CC1101_SWOR); // Starts Wake-on-Radi
//CC1101_Write_Cmd(CC1101_SPWD);
}




