XN297L 2.4G无线模块 寄存器读写测试

简单记录下XN297L 四线SPI读写寄存器

前言

        为避免吃灰,研究了下面买了很久的板子。因为便宜,照例只有发送板,没有接收板。配对不大可能,拆机比较现实。关于拆机价值最难利用的就是打磨过的MCU和其他IC。MCU是16p,12脚VCC,5脚GND,无从考证,放弃了。2.4g模块是本文重点。那个带天线独立于主板之外的红色小板就是2.4g模块,牛屎芯片,无管脚定义。主板上有丝印297,可以确认是XN297L无疑。剩下的就是确认管脚顺序了。

XN297L 2.4G无线模块 寄存器读写测试_第1张图片


一、管脚确认

        查了一下XN297L数据手册,XN297L有两种封装,QFN20 3x3 和SOP8。

XN297L 2.4G无线模块 寄存器读写测试_第2张图片

        开始认为SOP8小一点,牛屎糊起来更方便,可能是SOP8,于是找了SOP8的三线SPI程序编写了测试程序。管脚不知道,但先试吧,怎么试都不行。后来又研究了一下封装,感觉QFN20 3x3更为可能:

XN297L 2.4G无线模块 寄存器读写测试_第3张图片

         因为红色小板上引出了8个管脚,应该是VCC、GND、CE、CSN、SCK、MOSI、MISO、IRQ。sop8正好8个管脚,但XC1、XC2接的是晶振,ANT接天线,只剩5个需要引出。所以排除sop8封装。

        下面就要确认管脚顺序。如果盲目试管脚,不考虑VCC、GND、IRG(悬空),会有5*4*3*2*1种可能,非人力可为。换一种思路猜管脚顺序其实也很简单,VCC、GND万用表可以确认。其他6个管脚可以看线路的走势辨别,因为为了布线方便,管脚之间的前后关系应该是不会变的。于是得到下图

XN297L 2.4G无线模块 寄存器读写测试_第4张图片

二、XN297 四线SPI读写寄存器测试

        通过读写寄存器可以确认XN297是XN297,并且管脚正确。main.c源码如下:

#include 
#include 

sbit CE=P1^0;
sbit CS=P1^1;
sbit SCK=P1^2;
sbit MOSI=P1^3;
sbit MISO=P1^4;

const unsigned char TX_ADDRESS_DEF[5] = {0xcc,0xCC,0xCC,0xCC,0xCC};    		//RF 地址:接收端和发送端需一致

#define         HIGH                    (1)
#define         LOW                     (0)
#define         CSN_HIGH                (CSN |= HIGH)
#define         CSN_LOW                 (CSN &= LOW)
#define         SCK_HIGH                (SCK |= HIGH)
#define         SCK_LOW                 (SCK &= LOW)

#define         SPI_DATA_HIGH           (DATA |= HIGH)
#define         SPI_DATA_LOW            (DATA &= LOW)
#define         SPI_DATA_STATUS         (DATA)
#define         SPI_DATA_OUTPUT_MODE     ;
#define         SPI_DATA_INPUT_MODE      ;
#define         CE_HIGH                  RF_WriteReg(CE_FSPI_ON, 0)
#define         CE_LOW                   RF_WriteReg(CE_FSPI_OFF, 0)

/********************SPI  REGISTER  ********************/
#define		R_REGISTER			0x00                            //SPI read RF data
#define		W_REGISTER			0x20                            //SPI write RF data
#define		R_RX_PAYLOAD		        0x61                            //Read RX Payload
#define		W_TX_PAYLOAD		        0xA0                            //Write TX Payload
#define		FLUSH_TX			0xE1                            //Flush RX FIFO
#define		FLUSH_RX			0xE2                            //Flush TX FIFO
#define		REUSE_TX_PL			0xE3                            //Reuse TX Payload
#define		ACTIVATE			0x50                            //ACTIVATE
#define		DEACTIVATE			0x50                            //DEACTIVATE
#define		R_RX_PL_WID			0x60                            //Read width of RX data 
#define		W_ACK_PAYLOAD		        0xA8                            //Data with ACK
#define		W_TX_PAYLOAD_NOACK	        0xB0                            //TX Payload no ACK Request
#define		CE_FSPI_ON	                0xFD                            // CE HIGH
#define		CE_FSPI_OFF	                0xFC                            // CE LOW
#define		RST_FSPI	                0x53                            // RESET
#define		NOP_N				0xFF
             
/******************CONTROL  REGISTER*******************/
#define		CONFIG                          0x00            
#define		EN_AA				0x01
#define		EN_RXADDR			0x02
#define		SETUP_AW			0x03
#define		SETUP_RETR			0x04
#define		RF_CH				0x05
#define		RF_SETUP			0x06
#define		STATUS				0x07
#define		OBSERVE_TX			0x08
#define		DATAOUT			        0x09
#define		RX_ADDR_P0			0x0A
#define		RX_ADDR_P1			0x0B
#define		RX_ADDR_P2			0x0C
#define		RX_ADDR_P3			0x0D
#define		RX_ADDR_P4			0x0E
#define		RX_ADDR_P5			0x0F
#define		TX_ADDR				0x10
#define		RX_PW_P0			0x11
#define		RX_PW_P1			0x12
#define		RX_PW_P2			0x13
#define		RX_PW_P3			0x14
#define		RX_PW_P4			0x15
#define		RX_PW_P5			0x16
#define		FIFO_STATUS			0x17
#define		DEM_CAL				0x19
#define         RF_CAL2				0x1A
#define         DEM_CAL2			0x1B
#define		DYNPD				0x1C
#define		FEATURE				0x1D	
#define		RF_CAL				0x1E
#define		BB_CAL				0x1F

/
/*************************CONTROL CMD***********************************************/
#define         RF13dBm                         0x3F                            // 13dBm  发射档位功率设置
#define         RF10dBm                         0X0F                            // 10dBm 
#define         RF8dBm                          0x15                            // 8dbm      
#define         RF7dBm                          0x07                            // 7dbm   
#define         RF5dBm                          0x2c                            // 5dbm   
#define         RF4dBm                          0x06                            // 4dbm   
#define         RF2dBm                          0x05                            // 2dbm  
#define         RF0dBm                          0X0B                            // 0dBm  
#define         RF_3dBm                         0x04                            // -3dBm     
#define         RF_6dBm                         0x0A                            // -6dBm 
#define         RF_10dBm                        0x02                            // -10dBm 
#define         RF_18dBm                        0x01                            // -18dBm 
#define         RF_30dBm                        0x00                            // -30dBm 

#define         DR_1M                           0X00				//通信速率 1Mbps
#define         DR_2M                           0X40				//通信速率 2Mbps
#define         DR_250K                         0XC0                             //通信速率 250Kbps
#define         RX_DR_FLAG                      0X40                            // 接收中断标志位
#define         TX_DS_FLAG                      0X20                            // 发送完成中断标志位
#define         RX_TX_CMP_FLAG                  0X60                            // 发送接收完成中断标志位,ack_payload 模式下使用
#define         MAX_RT_FLAG                     0X10                            // 发送重传超时中断标志位
#define         TRANS_ENHANCE_MODE              1                               //传输类型增强型
#define         TRANS_BURST_MODE                2                               //传输类型普通型

#define         RxMode                           1
#define         RxMode_RTTE                      2
#define         DEFAULT_CHANNEL                78				//初始化时的频率: 2478 MHz           
#define         PAYLOAD_WIDTH                  16				//Payload宽度:     8bytes				
#define         TRANSMIT_TYPE                  TRANS_BURST_MODE 		//使用普通型模式           TRANS_BURST_MODE    TRANS_ENHANCE_MODE
#define         DATA_RATE                      DR_1M                           //通信速率1Mbps            DR_2M    DR_1M  DR_250K
#define         RF_POWER                      (RF13dBm |DATA_RATE)		//发射功率13dBm 
#define         RF_MODE                       RxMode_RTTE  //  RxMode_RTTE 



typedef unsigned long Uint16;
typedef unsigned char Uint8;

void UART_int(Uint16 baud);
void Sentdata(Uint8 dat);
unsigned char XN297_Check(void);
Uint8 temp;
void SPI_init(void);
void RF_WriteReg( unsigned char reg,  unsigned char wdata);
void RF_WriteBuf( unsigned char reg, unsigned char *pBuf, unsigned char length);
	

void Delay1000ms()		//@11.0592MHz
{
	unsigned char i, j, k;

	_nop_();
	i = 8;
	j = 1;
	k = 243;
	do
	{
		do
		{
			while (--k);
		} while (--j);
	} while (--i);
}


void Delay10ms()		//@11.0592MHz
{
	unsigned char i, j;

	i = 18;
	j = 235;
	do
	{
		while (--j);
	} while (--i);
}


void RF_Init(void)
{
#if(DATA_RATE == DR_1M) 
    unsigned char  BB_cal_data[]    = {0x0A,0x6D,0x67,0x9C,0x46};                               //1M速率配置
    unsigned char  RF_cal_data[]    = {0xF6,0x37,0x5D};
    unsigned char  RF_cal2_data[]   = {0x45,0x21,0xef,0x2C,0x5A,0x50};
    unsigned char  Dem_cal_data[]   = {0x01};  
    unsigned char  Dem_cal2_data[]  = {0x0b,0xDF,0x02};  
#elif(DATA_RATE == DR_250K) 
  /*
    //  unsigned char  BB_cal_data[]    = {0x0A,0x6D,0x67,0x9C,0x46};                                 //250K速率配置
    unsigned char  BB_cal_data[]    = {0x0A,0xeD,0x7F,0x9C,0x46}; 
    unsigned char  RF_cal_data[]    = {0xF6,0x37,0x5D};
    unsigned char  RF_cal2_data[]   = {0xD5,0x21,0xeb,0x2C,0x5A,0x40};
    unsigned char  Dem_cal_data[]   = {0x1e};  
    unsigned char  Dem_cal2_data[]  = {0x0b,0xDF,0x02}; 
     */
   unsigned char   BB_cal_data[]    = { 0x12,0xec,0x6f,0xa1,0x46}; 
   unsigned char    RF_cal_data[]    = {0xF6,0x37,0x5d};
   unsigned char   RF_cal2_data[]   = {0xd5,0x21,0xeb,0x2c,0x5a,0x40};
   unsigned char    Dem_cal_data[]   = {0x1f};  
   unsigned char    Dem_cal2_data[]  = {0x0b,0xdf,0x02};
    
#endif
       
    
    SPI_init();
    RF_WriteReg(RST_FSPI, 0x5A);								//Software Reset    			
    RF_WriteReg(RST_FSPI, 0XA5);    
   // RF_WriteReg(W_REGISTER + FEATURE, 0x20);                                                    // enable Software control ce 
   
    if(PAYLOAD_WIDTH <33)											
{
	RF_WriteReg(W_REGISTER +FEATURE, 0x27);							//切换到32byte模式   使能CE
}
else
{
  RF_WriteReg(W_REGISTER +FEATURE, 0x38);							//切换到64byte模式	   
}   
    //CE_LOW;   
		CE=0;//5.1
    RF_WriteReg(FLUSH_TX, 0);									// CLEAR TXFIFO		    			 
    RF_WriteReg(FLUSH_RX, 0);									// CLEAR  RXFIFO
    RF_WriteReg(W_REGISTER + STATUS, 0x70);							// CLEAR  STATUS	
    RF_WriteReg(W_REGISTER + EN_RXADDR, 0x01);							// Enable Pipe0
    RF_WriteReg(W_REGISTER + SETUP_AW,  0x03);							// address witdth is 5 bytes
    RF_WriteReg(W_REGISTER + RF_CH,     DEFAULT_CHANNEL);                                       // 2478M HZ
    RF_WriteReg(W_REGISTER + RX_PW_P0,  PAYLOAD_WIDTH);						// 8 bytes
    RF_WriteBuf(W_REGISTER + TX_ADDR,   ( unsigned char*)TX_ADDRESS_DEF, sizeof(TX_ADDRESS_DEF));	// Writes TX_Address to PN006
    RF_WriteBuf(W_REGISTER + RX_ADDR_P0,( unsigned char*)TX_ADDRESS_DEF, sizeof(TX_ADDRESS_DEF));	// RX_Addr0 same as TX_Adr for Auto.Ack   
    RF_WriteBuf(W_REGISTER + BB_CAL,    BB_cal_data,  sizeof(BB_cal_data));
    RF_WriteBuf(W_REGISTER + RF_CAL2,   RF_cal2_data, sizeof(RF_cal2_data));
    RF_WriteBuf(W_REGISTER + DEM_CAL,   Dem_cal_data, sizeof(Dem_cal_data));
    RF_WriteBuf(W_REGISTER + RF_CAL,    RF_cal_data,  sizeof(RF_cal_data));
    RF_WriteBuf(W_REGISTER + DEM_CAL2,  Dem_cal2_data,sizeof(Dem_cal2_data));
    RF_WriteReg(W_REGISTER + DYNPD, 0x00);					
    RF_WriteReg(W_REGISTER + RF_SETUP,  RF_POWER);						// 13DBM  		
     
#if(TRANSMIT_TYPE == TRANS_ENHANCE_MODE)      
    RF_WriteReg(W_REGISTER + SETUP_RETR,0x03);							//  3 retrans... 	
    RF_WriteReg(W_REGISTER + EN_AA,     0x01);							// Enable Auto.Ack:Pipe0  	
#elif(TRANSMIT_TYPE == TRANS_BURST_MODE)                                                                
    RF_WriteReg(W_REGISTER + SETUP_RETR,0x00);							// Disable retrans... 	
    RF_WriteReg(W_REGISTER + EN_AA,     0x00);							// Disable AutoAck 
#endif

}

void SPI_init(void)
{
	CE =0;
	CS = 1;
	SCK = 0;
	MOSI = 1;
}

void SPI_Write_Byte(unsigned char dat)
{
    unsigned char i;
    for (i = 0; i < 8; i++)
    {
				SCK = 0;
        MOSI = dat & 0x80;
        
        dat <<= 1;
        SCK = 1;
    }
		SCK = 0;
}

unsigned char SPI_Read_Byte(void)
{
    unsigned char i, dat = 0;
    for (i = 0; i < 8; i++)
    {
				SCK = 0;
        dat <<= 1;
        SCK = 1;
        if (MISO)
        {
            dat |= 0x01;
        }
        
    }
		SCK = 0;
    return dat;
}




unsigned char Read_Register(unsigned char reg_addr)
{
    unsigned char dat;
    CS = 0;
    SPI_Write_Byte(reg_addr | 0x80);
    dat = SPI_Read_Byte();
    CS = 1;
    return dat;
}


void RF_WriteReg( unsigned char reg,  unsigned char wdata)
{
    CS=0;
    SPI_Write_Byte(reg);
    SPI_Write_Byte(wdata);
    CS=1;
}

void RF_WriteBuf( unsigned char reg, unsigned char *pBuf, unsigned char length)
{
     unsigned char j;
    CS=0;
    j = 0;
    SPI_Write_Byte(reg);
    for(j = 0;j < length; j++)
    {
        SPI_Write_Byte(pBuf[j]);
    }
    j = 0;
    CS=1;
}

/*
 unsigned char ucRF_ReadReg( unsigned char reg)
{
     unsigned char data1;
    
    CS=0;
    SPI_Write_Byte(reg);
    data1 = SPI_Read_Byte();
    //SPI_DATA_OUTPUT_MODE;
    CS=1;
    
    return data1;
}

*/
void RF_ReadBuf( unsigned char reg, unsigned char *pBuf,  unsigned char length)
{
    unsigned char byte_ctr;

    CS=0;                   		                               			
    SPI_Write_Byte(reg);       		                                                		
    for(byte_ctr=0;byte_ctr

主要用于测试的函数是:

unsigned char XN297_Check(void)
{
    unsigned char check_in_buf[5]={0x55,0xaa,0x55,0xaa,0x55};
    unsigned char check_out_buf[5]={0x00};
    unsigned char i;
    
    //CE_HIGH;
    RF_WriteBuf(W_REGISTER+TX_ADDR,check_in_buf,5);
    RF_ReadBuf(R_REGISTER+TX_ADDR,check_out_buf,5);
    for(i=0;i<5;i++)
    {
        Sentdata(check_out_buf[i]);
    }
    if((check_out_buf[0]==0x55)&&\
        (check_out_buf[1]==0xaa)&&\
        (check_out_buf[1]==0x55)&&\
        (check_out_buf[1]==0xaa)&&\
        (check_out_buf[1]==0x55))
        return 0;
    else
        return 1;
}
 

        就是向TX_ADDR寄存器写入0x55,0xaa,0x55,0xaa,0x55,然后通过RF_ReadBuf(R_REGISTER+TX_ADDR,check_out_buf,5)读出来保存到check_out_buf并发送给串口,通过串口助手得到:

XN297L 2.4G无线模块 寄存器读写测试_第5张图片

        收到“0x55,0xaa,0x55,0xaa,0x55”,说明假设成立。

三、总结

        1、XN297L不同的封装,对应有三线或四线SPI。

        2、猜管脚顺序最好看明白数据手册再来,事半功倍。

XN297L 2.4G无线模块 寄存器读写测试_第6张图片

XN297L 2.4G无线模块 寄存器读写测试_第7张图片

XN297L 2.4G无线模块 寄存器读写测试_第8张图片

你可能感兴趣的:(51单片机)