CC2541晶振频率调谐 (原创) admin    17/11/26

简介:

    CC2541的射频系统高度依赖于晶振频率。晶振频率的波动将直接影响射频频率,这关系到系统收发灵敏度,甚至 在一些最坏的情况下,系统可能根本无法工作。根据BLE蓝牙协议规范这一频率偏差不应超过40ppm(百万分之40).除了选择满足这一要求的晶振外, 晶振负载电容(下图C1和C2)也很重要。

晶振电路

    晶振需要在准确的负载电容下才能按其标称的频率工作,但实际电路的寄生参数和器件固有的精度限制。为获得准确的振荡频率, 需要对电路调谐。外接负载电容比较难调,只能起粗调作用。好在CC2541内置了一对可调电容,它并在外接电容C1和C2上,通过向FREQTUNE寄存器写入合适的值来改变此电容,进而达到调谐作用。

调谐方法:

    测量射频频率通常需要昂贵的专业设备,业余条件下很难做到。但要测量晶振时钟是否准确,相对容易得多。我们让待测模块运行 一小段代码,产生一个标称值为100Khz的方波信号。PC上位机运行串口工具,向被测模块发送设置FREQTUNE寄存器的指令。用频率计或示波器就可以测出100Khz 信号的实际值,也就间接测出了晶振频率(系统时钟)。

蓝牙模块调谐

    模块上运行的测试代码如下,也可以直接获取烧录镜像。串口工具以9600波特率,发送一个字节要写入FREQTUNE的数据即可。

		#include <string.h>
		
		#include "hal_uart.h"
		#include "hal_types.h"
		
		#define TnCTL_DIV_1   (0<<5)
		#define TnCTL_DIV_2   (1<<5)
		#define TnCTL_DIV_4   (2<<5)
		#define TnCTL_DIV_8   (3<<5)
		#define TnCTL_DIV_16  (4<<5)
		#define TnCTL_DIV_32  (5<<5)
		#define TnCTL_DIV_64  (6<<5)
		#define TnCTL_DIV_128 (7<<5)
		
		#define TnCTL_STAR    (1<<4)
		#define TnCTL_CLEAR   (1<<3)
		
		#define TnCTL_MODE_FREE     (0)
		#define TnCTL_MODE_DWON     (1)
		#define TnCTL_MODE_MODULO   (2)
		#define TnCTL_MODE_UPDWON   (3)
		
		#define TnCCTL0_INT_ENB      (1 << 6) //中断使能
		#define TnCCTL0_CMP_SET      (0 << 3)
		#define TnCCTL0_CMP_CLEAR    (1 << 3)
		#define TnCCTL0_CMP_TOGGLE   (2 << 3)
		//more...
		#define TnCCTL0_MODE_COMPARE (1 << 2)
		#define TnCCTL0_CAP_NO       (0)
		#define TnCCTL0_CAP_RISING   (1)
		#define TnCCTL0_CAP_FALLING  (2)
		#define TnCCTL0_CAP_BOTH     (3)
		
		#define FREQTUNE          XREG( 0x6185 )
		
		static void UartCB(uint8 port, uint8 event)
		{
		  uint16 nLen;
		  uint8 ucRxBuff[1];
		  
		  nLen = HalUARTRead(port, ucRxBuff, sizeof(ucRxBuff));
		  if (nLen) {
		    FREQTUNE = ucRxBuff[0];
		  }
		 
		  (void)event;
		}
		
		
		void main(void)
		{
		  halUARTCfg_t tUartCfg;
		 
		  HAL_BOARD_INIT();  //系统时钟设置
		  
		  P1SEL |= (1 << 3);
		  T3CTL = TnCTL_DIV_1 | TnCTL_STAR | TnCTL_MODE_MODULO;
		  T3CCTL0 = TnCCTL0_CMP_TOGGLE | TnCCTL0_MODE_COMPARE;
		  T3CC0 = 159; //100Khz
		  P1DIR |= (1 << 2);
		  
		  HalUARTInit();
		    
		  memset(&tUartCfg, 0, sizeof(tUartCfg));
		  tUartCfg.baudRate = HAL_UART_BR_9600;
		  tUartCfg.callBackFunc = UartCB;
		  HalUARTOpen(HAL_UART_PORT_1, &tUartCfg);
		  
		  HAL_ENABLE_INTERRUPTS();
		  
		  while(1)
		    HalUARTPoll();
		}
  

测试结果:

    下表为网购的某一型号模块实际测量结果。可以看出,其频率牵引范围很窄,不到10ppm,在整个范围内模块频偏都没有超出协议规定容差(40ppm)。这个牵引范围同PCB设计、晶振选择有很大关系。 这个模块的牵引范围很窄,设置FREQTUNE起不到太大作用,调谐只能靠改变外接负载电容来实现,调整起来比较麻烦。但也有个好处,那就是我们拿它来烧自己的代码,可以不用考虑FREQTUNE取值。

FREQTUNE频率(Khz)偏差(ppm)
0x0F100.0077
0x0E100.0066
0x0D100.0055
0x0C100.0044
0x0B100.0044
0x0A100.0033
0x09100.0022
0x08100.0022
0x07100.0011
0x06100.0011
0x05100.0000
0x04100.0000
0x03100.0000
0x0299.9998-0.2
0x0199.9995-0.5
0x0099.9992-0.8

0

收藏

3309

阅读


0 评论 | 直到2024-04-26 16:48添加评论