SX1208 FEI应用实例介绍 1. FEI概念及用途 FEI全称:频率误差指示(Frequency Error Indicator),该功能提供本地振荡器(LO)与从接收机输入进来的调制信号载波的频率误差。当通过寄存器配置打开FEI功能块时,频率误差被测量并将测试结果加载在相应的寄存器内。用户可以使用FEI功能实现频率误差检测、频率校准等应用,包括SX1208自带的AFC(Automatic Frequency Correction)功能也是基于FEI实现的。
2. FEI具体实现介绍 为了保证正确实现FEI,必须满足以下两点: - FEI执行必须在前导码接收的过程中完成,SX1208 FEI执行所需要的时间是4个比特位传输所用时间。所以为了可靠起见,发射端发射前导码在20个比特位传输时间以上;
- 信号的20dB带宽和频率偏差的总和必须小于基带滤波器带宽;
信号的20dB带宽可使用以下公式计算得到: 频率偏差可使用以下公式计算得到,计算值单位是Hz:
具体FEI实现的流程图如下: 图1 FEI流程图
3. 频率校正实现方法 SX1208 AFC功能可以自动实现频率校准。当AFC执行完毕后,设置的频率寄存器会直接将AfcValue减去。在AFC运行阶段,SX1208会提供一个更大带宽的通道滤波器(寄存器RegAfcBw)以满足较大的本振偏移,同时增大了接收机的底噪电平,降低了接收灵敏度。因为AFC对于频偏校准的范围非常小,而且付出了降低灵敏度的代价,所以下面给出另一种频率校准方法。 该频率校准方法需要事先准备一个标准信号源,可以是标准模块或者矢量信号发生器,信号源发射长前导码信号(010101…序列),被校准模块上电后处于RxMode,当被校准模块检测到前导码信号时开启FEI,FEI执行完毕后MCU读出寄存器FeiValue值。判断FeiValue如果在频偏指标范围内则置位校准标志位,否则就将FeiValue与频率寄存器的值相加作为校正后的频偏值,为了准确起见,总共执行10次FEI取平均值,最后将频率校正值结果保存到存储器内,图2是频率校准流程图:
图2 频率校正流程图 以下是频率偏差值获取具体函数实现: - int ReadFei(void) // Must be called while in RX
- {
- u8 i;
- extern u8 err_frq[],position;
- uint16_t tmp=0;
- for(i=0;i<10;i++)
- {
- LSD_RF_WriteReg(REG_AFCFEI, RF_AFCFEI_FEI_START); // Triggers FEI measurement
- while ((LSD_RF_ReadReg(REG_AFCFEI) & RF_AFCFEI_FEI_DONE) == 0x00); // Waits for FEI measurement to be completed
- value[0] =((LSD_RF_ReadReg(REG_FEIMSB) << 8) | LSD_RF_ReadReg(REG_FEILSB)); // Reads the FEI result
- value[0] = value[0]+((LSD_RF_ReadReg(REG_FEIMSB) << 8) | LSD_RF_ReadReg(REG_FEILSB));
- }
- value[0]=value[0]/10; //calculate FEI average value
- if((value[0]<16)&&(value[0]>-16)) //if FEI average value is within ±1KHz
- {
- FLASH_ProgramByte(0x9080,1);
- FLASH_ProgramByte(0x9083,value[1]); //write frequency offset correction value to flash
- }
- else //otherwise correcting frequency
- {
- value[1]=value[1]+value[0];
- LSD_RF_StandbyMode();
- err_frq[1] = LSD_RF_ReadReg(REG_FRFMID);
- err_frq[2] = LSD_RF_ReadReg(REG_FRFLSB);
- tmp = (uint16_t)(err_frq[1]<<8) + err_frq[2] + value[0];
- err_frq[3] = (uint8_t)(tmp>>8);
- err_frq[4] = (uint8_t)(tmp);
- LSD_RF_WriteReg(REG_FRFMID, err_frq[3]); //write corrected frequency to register
- LSD_RF_WriteReg(REG_FRFLSB, err_frq[4]);
- err_frq[1] = LSD_RF_ReadReg(REG_FRFMID);
- err_frq[2] = LSD_RF_ReadReg(REG_FRFLSB);
- }
- return 1;
- }
复制代码 |