XL2400P芯片引脚
选用的模块,CH32V003与此模块连接
芯领XL2422开发板作为发送测试数据用
SPI接口注意
SPI接口采用3线制,DATA引脚既是输出引脚又是输入引脚。目前我还没有用硬件SPI实现驱动测试,只实现了软件模拟驱动测试。
软件模拟参考压缩包里的驱动文件。
CH32V003工程结构
XL2400.h代码
#ifndef XL2400P_H
#define XL2400P_H#include <ch32v00x.h>extern u8 Rec_Buff[16];
extern u8 Data_Len;
/***************************************************************************************************/
/********************************* XL2400P引脚定义 **************************************************/
/***************************************************************************************************/
#define SPI_GPIO_CLK RCC_APB2Periph_GPIOC
#define SPI_PORT GPIOC#define CSN_PIN GPIO_Pin_3
#define SCK_PIN GPIO_Pin_2
#define DATA_PIN GPIO_Pin_1#define SCK_High GPIO_SetBits(SPI_PORT,SCK_PIN)
#define SCK_Low GPIO_ResetBits(SPI_PORT,SCK_PIN)#define DATA_High GPIO_SetBits(SPI_PORT,DATA_PIN)
#define DATA_Low GPIO_ResetBits(SPI_PORT,DATA_PIN)#define CSN_High GPIO_SetBits(SPI_PORT,CSN_PIN)
#define CSN_Low GPIO_ResetBits(SPI_PORT,CSN_PIN)#define DATA_READ() GPIO_ReadInputDataBit(SPI_PORT, DATA_PIN)
/***************************************************************************************************/
/************************************ 操作函数声明 **************************************************/
/***************************************************************************************************/
void DATA_Mode(GPIOMode_TypeDef Mode);
void RF_GPIO_Init(void);
void RF_SPI_Init(void);
void SPI_Write_Byte(u8 buff);
u8 SPI_Read_Byte(void);
void SPI_Write_Reg(u8 RfAdress,u8 RfData);
u8 SPI_Read_Reg(u8 RfAdress);
void Write_RF_Buff(u8 RFAdress , u8 *pBuff , u8 Len);
void Read_RF_Buff(u8 RFAdress , u8 *pBuff , u8 Len);
void RF_Init(void);
void RF_CE_High(void);
void RF_CE_Low(void);
void RF_Clear_Buf(void);
void RF_Reset(void);
void RF_Set_Chn(u8 Chn);
void RF_Set_Address(u8 * AddrBuff);
void RF_Set_Power(u8 Power);
void RF_Sleep(void);
void RF_Tx_Mode(void);
void RF_Rx_Mode(void);
void RFAPIChannelNext(void);
void RFAPIChannelNext_RX(void);u8 Rec_Data(u8 * rec_buff);/***************************************************************************************************/
/************************************ XL2400P相关指令 ***********************************************/
/***************************************************************************************************/#define TRIPLE 1
#define DUAL 0#define setbit(x,y) ((x) |= (1<<(y)))
#define clrbit(x,y) ((x) &= ~(1<<(y)))
#define setbit_array(x,y) (setbit((x)[(y)/8],(y)%8))
#define clrbit_array(x,y) (clrbit((x)[(y)/8],(y)%8))/******************************* 寄存器宏定义 ********************************/
#define CFG_TOP (0X00)//配置寄存器
#define EN_AA (0X01)//使能自动应答寄存器
#define EN_RXADDR (0X02)//接收地址允许寄存器
#define SETUP_AW (0X03)//设置地址宽度(所有数据管道)
#define SETUP_RETR (0X04)//
#define RF_CH (0X05)//频点 RF通道 工作通道频率
#define RF_SETUP (0X06)
#define RF_STATUS (0X07)//状态寄存器
#define OBSERVE_TX (0X08)
#define RSSI (0X09)
#define RX_ADDR_P0 (0X0A)
#define RX_ADDR_P1 (0X0B)
#define RX_ADDR_P2 (0X2)
#define RX_ADDR_P3 (0X3)
#define RX_ADDR_P4 (0X4)
#define RX_ADDR_P5 (0X5)
#define RX_ADDR_P2TOP5 (0X0C)
#define BER_RESULT (0X0D)
#define AGC_SETTING (0X0E)
#define PGA_SETTING (0X0F)
#define TX_ADDR (0X10)
#define RX_PW_PX (0X11)
#define ANALOG_CFG0 (0X12)
#define ANALOG_CFG1 (0X13)
#define ANALOG_CFG2 (0X14)
#define ANALOG_CFG3 (0X15)
#define STATUS_FIFO (0X17)
#define RSSIREC (0X18)
#define TXPROC_CFG (0X19)
#define RXPROC_CFG (0X1A)
#define DYNPD (0X1C)
#define FEATURE (0X1D)
#define RAMP_CFG (0X1E)
/******************************** 寄存器操作指令 **************************************/
#define R_REG 0x00//读寄存器指令
#define R_REGISTER 0x00//读寄存器指令
#define W_REG 0x20//写寄存器指令
#define W_REGISTER 0x20//写寄存器指令
#define R_RX_PLOAD 0x61//读 RX 有效数据
#define W_TX_PLOAD 0xA0//写 TX 有效数据
#define FLUSH_TX 0xE1//清除TX FIFO 1110 0001
#define FLUSH_RX 0xE2//清除RX FIFO 1110 0010
#define REUSE_TX_PL 0xE3//应用于发射端。重新使用上一包发射的有效数据
#define R_RX_PL_WID 0x60//0110 0000
#define W_ACK_PLOAD 0xA8//
#define W_TX_PLOAD_NOACK 0xB0//@
#define CMD_NOP 0xFF//空操作。可用来操作状态寄存器#define TX_ADDR_3BYTE (0x1 << 2)//@
#define TX_ADDR_4BYTE (0x2 << 2)//@
#define TX_ADDR_5BYTE (0x3 << 2)//@#define RX_ADDR_3BYTE (0x1)//@
#define RX_ADDR_4BYTE (0x2)//@
#define RX_ADDR_5BYTE (0x3)//@/* STATUS Interrupt status */
#define RX_DR (0x40)//接收到数据中断标志位
#define TX_DS (0x20)//发送数据完成中断标志位
#define MAX_RT (0x10)//达到最大发送次数中断标志位/* FIFO Status */
#define TX_REUSE (0x1 << 6)//@
#define TX_FULL (0x1 << 5)//@
#define TX_EMPTY (0x1 << 4)//@
#define RX_FULL (0x2)//@
#define RX_EMPTY (0x1)//@
/************************ 射频功率 ****************************/
//1Mpbs只能使用0dBm
//250Kpbs可以用以下功率:
#define C_RF10dBm 0x3f // 10dBm
#define C_RF9dBm 0x38 // 9dbm
#define C_RF8dBm 0x34 // 8dbm
#define C_RF7dBm 0x30 // 7dbm
#define C_RF6dBm 0x2c // 6dbm
#define C_RF5dBm 0x28 // 5dbm
#define C_RF4dBm 0x24 // 4dbm
#define C_RF3dBm 0x20 // 3dbm
#define C_RF2dBm 0x14 // 2dbm
#define C_RF0dBm 0x10 // 0dBm
#define C_RF_2dBm 0x0c // -2dBm
#define C_RF_6dBm 0x08 // -6dBm
#define C_RF_12dBm 0x04 // -12dBm
#define C_RF_18dBm 0x02 // -18dBm
#define C_RF_24dBm 0x01 // -24dBm/*********************** 通讯速率 *****************************************/
#define C_DR_1M 0x02 //1Mpbs
#define C_DR_250K 0x22 //250Kpbs //----------------------------------------------------------
#define RF_PACKET_SIZE 8//数据长度
#define ADD_WIDTH 5//
#define C_MAX_CHN_INDEX 4//
//==========================================================#endif
XL2400.c代码
#include "XL2400P.h"
u8 gRFChnl;//跳频变量
const u8 CHANNELTABLE[] = {05, 76, 19};//频点
u8 RF_Test_Adrress[5]={0xcc,0xcc,0xcc,0xcc,0xcc};//RF地址
/*********************************************************************************************/
/****************************** XL2400P_SPI通讯 ********************************************/
/*********************************************************************************************///射频GPIO引脚初始化
void RF_GPIO_Init(void)
{GPIO_InitTypeDef GPIO_InitStructure = {0};RCC_APB2PeriphClockCmd(SPI_GPIO_CLK , ENABLE);GPIO_InitStructure.GPIO_Pin = CSN_PIN|SCK_PIN|DATA_PIN;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(SPI_PORT, &GPIO_InitStructure);
}
void DATA_Mode(GPIOMode_TypeDef Mode)//
{GPIO_InitTypeDef GPIO_InitStruct;GPIO_InitStruct.GPIO_Pin = DATA_PIN; //引脚13GPIO_InitStruct.GPIO_Mode = Mode; //输出模式GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; //50MHZGPIO_Init(SPI_PORT, &GPIO_InitStruct);
}//SPI通讯初始化
void RF_SPI_Init(void)
{CSN_High;SCK_Low;
}//SPI写数据(1字节)
//参数 需要写入的数据
void SPI_Write_Byte(u8 buff)
{u8 i;DATA_Mode(GPIO_Mode_Out_PP);for(i = 0; i < 8; i++){SCK_Low;if(buff & 0x80){DATA_High;}else{DATA_Low;}buff = buff << 1;SCK_High;}DATA_High;SCK_Low;
}//SPI读数据(1字节)
//返回 读取到的数据
u8 SPI_Read_Byte(void)
{u8 i;u8 buff = 0;DATA_Mode(GPIO_Mode_IN_FLOATING);for(i = 0; i < 8; i++){SCK_Low;buff = buff << 1;SCK_High;if(DATA_READ()){buff |= 0x01;} }SCK_Low;return buff;
}//SPI写数据到寄存器
//参数1 寄存器地址+写指令
//参数2 需要写入的数据
void SPI_Write_Reg(u8 RfAdress,u8 RfData)
{CSN_Low;//拉低片选SPI_Write_Byte(RfAdress);//1写入地址SPI_Write_Byte(RfData);//2写入数据CSN_High;//写入完成拉高片选
}//SPI从寄存器读取数据
//参数 寄存器地址+读指令
//返回 读取到的数据
u8 SPI_Read_Reg(u8 RfAdress)
{u8 rTemp;CSN_Low;SPI_Write_Byte(RfAdress);//写入地址+读取指令rTemp = SPI_Read_Byte();//读取数据CSN_High;return rTemp;
}//写入多个数据到寄存器
//参数1 寄存器地址+指令
//参数2 需要写入的数据地址
//参数3 写入次数
void Write_RF_Buff(u8 RFAdress , u8 *pBuff , u8 Len)
{u8 i;u8 rTemp;CSN_Low;SPI_Write_Byte(RFAdress);for(i = 0 ; i < Len ; i++){rTemp = pBuff[i];SPI_Write_Byte(rTemp);}CSN_High;
}//从寄存器读取多个数据
//参数1 寄存器地址+指令
//参数2 读取到的数据存放地址
//参数3 读取的次数
void Read_RF_Buff(u8 RFAdress , u8 *pBuff , u8 Len)
{u8 i;CSN_Low;SPI_Write_Byte(RFAdress);for(i = 0 ; i < Len ; i++){pBuff[i] = SPI_Read_Byte();}CSN_High;
}/*********************************************************************************************/
/*********************************** XL2400P ***********************************************/
/*********************************************************************************************///射频初始化
void RF_Init(void)
{u8 RF_Init_Buff[16]={0};SPI_Write_Reg(W_REG+CFG_TOP,0x02);Delay_Ms(2);SPI_Write_Reg(W_REG+CFG_TOP,0x3E);Delay_Ms(2);/* 配置模拟寄存器 */Read_RF_Buff(ANALOG_CFG3 , RF_Init_Buff , 6);RF_Init_Buff[5] =((RF_Init_Buff[5]&0xff) | 0x6d);Write_RF_Buff(W_REG+ANALOG_CFG3 , RF_Init_Buff , 6);/* 配置应答PIPE */SPI_Write_Reg(W_REGISTER + EN_AA, 0x00);//不使用应答/* 配置使能地址 */SPI_Write_Reg(W_REGISTER + EN_RXADDR, 0x3f);/* 配置地址长度 */SPI_Write_Reg(W_REGISTER + SETUP_AW, 0xaf);/* 配置重传次数和时间间隔 */SPI_Write_Reg(W_REGISTER + SETUP_RETR,0x33); /* 配置通讯速率 */SPI_Write_Reg(W_REGISTER + RF_SETUP, C_DR_250K);//250Kpbs/* 配置PIPE0&PIPE1接收包长度 */// RF_Init_Buff[0] = RF_PACKET_SIZE;// RF_Init_Buff[1] = RF_PACKET_SIZE;// Write_RF_Buff(W_REGISTER+RX_PW_PX, RF_Init_Buff ,2);/* 配置PIPE动态长度使能位 */SPI_Write_Reg(W_REGISTER+DYNPD, 0x3f);//使用动态长度//配置其他RF特性:
//bit7&6=00 发送寄存器地址时返回State
//bit5=0 非长数据包
//bit4=1 禁止FEC功能
//bit3=1 FEATURE 配置有效
//bit2=0 动态长度功能打开
//bit1=0 ACK不用带PL
//bit0=0 未开启W_TX_PAYLOAD_NOACK模式SPI_Write_Reg(W_REGISTER+FEATURE, 0x1c);//打开动态长度功能RF_Set_Power(C_RF6dBm);//设置发射功率RF_Set_Address(RF_Test_Adrress);//设置RF地址RF_Clear_Buf();//清除状态
}//拉高RF_CE
void RF_CE_High(void)
{SPI_Write_Reg(W_REGISTER+CFG_TOP, 0xEF);
}//拉低RF_CE
void RF_CE_Low(void)
{SPI_Write_Reg(W_REGISTER+CFG_TOP, 0xEE);
}//清除状态
void RF_Clear_Buf(void)
{SPI_Write_Reg(W_REGISTER+RF_STATUS, (SPI_Read_Reg(RF_STATUS)|RX_DR | TX_DS | MAX_RT));SPI_Write_Reg(FLUSH_TX, CMD_NOP);SPI_Write_Reg(FLUSH_RX, CMD_NOP);
}//复位RF
void RF_Reset(void)
{SPI_Write_Reg(W_REG+CFG_TOP,0xEA);Delay_Us(200);SPI_Write_Reg(W_REG+CFG_TOP,0xEE);Delay_Ms(1);
}//设置频点
void RF_Set_Chn(u8 Chn)
{SPI_Write_Reg(W_REGISTER + EN_AA, 0x00);SPI_Write_Reg(W_REGISTER + RF_CH, Chn + 0x60);SPI_Write_Reg(W_REGISTER + EN_AA, 0x40);
}//设置地址
void RF_Set_Address(u8 *AddrBuff)
{Write_RF_Buff(W_REGISTER+TX_ADDR,AddrBuff , 5);Write_RF_Buff(W_REGISTER+RX_ADDR_P0, AddrBuff ,5);
}//设置发射功率
void RF_Set_Power(u8 Power)
{u8 Power_Buff[3]={0};Read_RF_Buff(R_REGISTER+RF_SETUP , Power_Buff, 2);Power_Buff[1] = Power;Write_RF_Buff(W_REGISTER+RF_SETUP , Power_Buff ,2);
}//RF休眠
void RF_Sleep(void)
{SPI_Write_Reg(W_REGISTER+CFG_TOP, 0x00);
}//设置为发射模式
void RF_Tx_Mode(void)
{u8 Mode_Buff[3]={0};Mode_Buff[0] = 0xee;Mode_Buff[1] = 0x80; Write_RF_Buff(W_REG+CFG_TOP, Mode_Buff ,2);RF_Clear_Buf();Delay_Ms(1);
}//设置为接收模式
void RF_Rx_Mode(void)
{u8 Mode_Buff[3]={0};Mode_Buff[0] = 0xee;Mode_Buff[1] = 0xc0; Write_RF_Buff(W_REG+CFG_TOP , Mode_Buff ,2);RF_Clear_Buf();RF_CE_High();Delay_Ms(1);
}/***********************************************************************************************/
/*************************************** 跳频 **************************************************/
/***********************************************************************************************/void RFAPIChannelNext(void)
{static u8 gChannelIndex;if(gChannelIndex < 2){gChannelIndex++ ;}else{gChannelIndex = 0;}gRFChnl = CHANNELTABLE[gChannelIndex];RF_Set_Chn(gRFChnl);
}void RFAPIChannelNext_RX(void)
{static u8 gChannelIndex;if(gChannelIndex < 2){gChannelIndex++ ;}else{gChannelIndex = 0;}gRFChnl = CHANNELTABLE[gChannelIndex];gRFChnl -= 1;RF_Set_Chn(gRFChnl);
}/***********************************************************************************************/
/************************************* 通讯测试 *************************************************/
/***********************************************************************************************/u8 Data_Len=0;//接收到的数据的长度//接收数据
u8 Rec_Data(u8 * rec_buff)
{u8 status;u8 RfPlwid;if(SPI_Read_Reg(RF_STATUS) & RX_DR) //如果触发接收中断{ RF_CE_Low();//拉高CEstatus = SPI_Read_Reg(RF_SETUP);if((status & 0x0e) != 0x0e){RfPlwid = SPI_Read_Reg(R_RX_PL_WID);Data_Len = RfPlwid;Read_RF_Buff(R_RX_PLOAD,rec_buff,RfPlwid); //读取有效数据}SPI_Write_Reg(FLUSH_RX, CMD_NOP);//清空RX FIFOSPI_Write_Reg(W_REG+RF_STATUS,(SPI_Read_Reg(RF_STATUS)|RX_DR));RF_CE_High();//拉高CEreturn 1;}else{return 0;}
}