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; //引脚13
GPIO_InitStruct.GPIO_Mode = Mode; //输出模式
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; //50MHZ
GPIO_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();//拉高CE
status = 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 FIFO
SPI_Write_Reg(W_REG+RF_STATUS,(SPI_Read_Reg(RF_STATUS)|RX_DR));
RF_CE_High();//拉高CE
return 1;
}
else
{
return 0;
}
}