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[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<length;byte_ctr++)
- pBuf[byte_ctr] = 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[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;
- }
-
-
-
- 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[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);
}
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并发送给串口,通过串口助手得到:
可以证明2.4g模块寄存器工作正常,访问正常。
|