sujingliang 发表于 2023-11-26 11:06:59

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


2.4G无线模块常用于无线鼠标键盘,遥控等场合。MCU和2.4G模块通过4线SPI通讯。本测采用XN297 2.4g模块原理图见下图:


XN297 四线SPI读写寄存器测试
#include <STC89C5xRC.H>
#include <intrins.h>

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 = {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)

/********************SPIREGISTER********************/
#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
            
/******************CONTROLREGISTER*******************/
#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_1MDR_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 charBB_cal_data[]    = {0x0A,0x6D,0x67,0x9C,0x46};                               //1M速率配置
    unsigned charRF_cal_data[]    = {0xF6,0x37,0x5D};
    unsigned charRF_cal2_data[]   = {0x45,0x21,0xef,0x2C,0x5A,0x50};
    unsigned charDem_cal_data[]   = {0x01};
    unsigned charDem_cal2_data[]= {0x0b,0xDF,0x02};
#elif(DATA_RATE == DR_250K)
/*
    //unsigned charBB_cal_data[]    = {0x0A,0x6D,0x67,0x9C,0x46};                                 //250K速率配置
    unsigned charBB_cal_data[]    = {0x0A,0xeD,0x7F,0x9C,0x46};
    unsigned charRF_cal_data[]    = {0xF6,0x37,0x5D};
    unsigned charRF_cal2_data[]   = {0xD5,0x21,0xeb,0x2C,0x5A,0x40};
    unsigned charDem_cal_data[]   = {0x1e};
    unsigned charDem_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);                                                                        // CLEARRXFIFO
    RF_WriteReg(W_REGISTER + STATUS, 0x70);                                                        // CLEARSTATUS       
    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 = 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<length;byte_ctr++)
            pBuf = SPI_Read_Byte();
    SPI_DATA_OUTPUT_MODE;
    CS=1;                                                                              
}


void RF_TxMode(void)
{

                CE=0;
    RF_WriteReg(W_REGISTER + CONFIG,0X8E);                                                        // 将RF设置成TX模式
    Delay10ms();
                CE=1;//5.1
    Delay10ms();
}

void main(void)
{
       
        UART_int(9600);
        EA =1;
        RF_Init();       
        RF_TxMode();
       
        Sentdata(0x33);

// 进一步处理读取结果
        while(1){
                XN297_Check();
                Delay1000ms();
        }
}




unsigned char XN297_Check(void)
{
        unsigned char check_in_buf={0x55,0xaa,0x55,0xaa,0x55};
        unsigned char check_out_buf={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);
        }
        if((check_out_buf==0x55)&&\
                (check_out_buf==0xaa)&&\
                (check_out_buf==0x55)&&\
                (check_out_buf==0xaa)&&\
                (check_out_buf==0x55))
                return 0;
        else
                return 1;
}



void UART_int(Uint16 baud)
{
        TMOD = (TMOD&0X0F)|0X20;
        TH1 = 256-11059200/32/12/baud;
        TL1        = TH1;
        TR1 = 1;
        ET1 = 0;
        SCON = 0X50;
        ES        = 1;
}
void Sentdata(Uint8 dat)
{
        SBUF =dat;
        while(TI==0);
        TI =0;
}

void UART() interrupt 4
{
        if(RI==1)
        {
                RI=0;
                temp =SBUF;
        }
}主要用于测试的函数是:

unsigned char XN297_Check(void)
{
    unsigned char check_in_buf={0x55,0xaa,0x55,0xaa,0x55};
    unsigned char check_out_buf={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);
    }
    if((check_out_buf==0x55)&&\
      (check_out_buf==0xaa)&&\
      (check_out_buf==0x55)&&\
      (check_out_buf==0xaa)&&\
      (check_out_buf==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并发送给串口,通过串口助手得到:



可以证明2.4g模块寄存器工作正常,访问正常。
页: [1]
查看完整版本: 2.4G无线模块 寄存器SPI读写测试