如题,ch57X系列确实是很不错的芯片,把无线和单片机结合起来了。但是入门例程对我们这种非科班出身的入门爱好者十分的不友好。能否出一版类似如nRF24L01,xn297l 的c程序。
附xn297l的c驱动程序
//===================================================================================//
// * @file rf.c
// * @author liuhaibing
// * @version V1.0.0
// * @date 2021/05/14
// * @brief 4线SPI,2M/1M速率,软件CE,无IRQ
//===================================================================================//
#include"rf.h"
uint8_t TX_ADDRESS_DEF[5] = {0xCC,0xCC,0xCC,0xCC,0xCC};
/******************************************************************************/
// !!!!!!!!!!!!!!!!!!!!该部分内容需要修改!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
// @brief 实现1ms延时,该部分内容需要用户根据自己实际使用的MCU做修改
// @param n_ms:需要延时的时间,单位为ms
// @retval None
/******************************************************************************/
void delay_ms(u16 n_ms)
{
uint16_t i,j;
for(i=0;i<n_ms;i++)
{
for(j=0;j<2300;j++)
{
nop();
}
}
}
/******************************************************************************/
// !!!!!!!!!!!!!!!!!!!!该部分内容需要修改!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
// @brief 实现100us延时,该部分内容需要用户根据自己实际使用的MCU做修改
// @param n_100us:需要延时的时间,单位为100us
// @retval None
/******************************************************************************/
void delay_100us(u16 n_100us)
{
uint16_t i,j;
for(i=0;i<n_100us;i++)
{
for(j=0;j<225;j++)
{
nop();
}
}
}
/******************************************************************************/
// !!!!!!!!!!!!!!!!!!!!该部分内容需要修改!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
// @brief 初始化SPI,该部分内容需要用户根据自己实际使用的MCU和实际情况(比如是否使用到IRQ,CE脚等)做修改
// @param None
// @retval None
/******************************************************************************/
void SPI_init(void)
{
GPIO_Init( GPIOB, GPIO_Pin_4, GPIO_Mode_Out_PP_High_Fast); //CSN output High pulling push
GPIO_Init( GPIOB, GPIO_Pin_5, GPIO_Mode_Out_PP_Low_Fast); //SCK output Low pulling push
GPIO_Init( GPIOB, GPIO_Pin_6, GPIO_Mode_Out_PP_High_Fast); //MOSI output High pulling push
GPIO_Init( GPIOB, GPIO_Pin_7, GPIO_Mode_In_PU_No_IT); //MISO input pull high
}
/******************************************************************************/
// @brief SPI写入一个BYTE的同时,读出一个BYTE返回
// @param R_REG:SPI写入的值
// @retval SPI读出的值
/******************************************************************************/
uint8_t SPI_RW( uint8_t R_REG)
{
uint8_t i;
for(i = 0; i < 8; i++)
{
SCK_LOW;
if(R_REG & 0x80)
{
MOSI_HIGH;
}
else
{
MOSI_LOW;
}
R_REG = R_REG << 1;
SCK_HIGH;
if( MISO_STATUS )
{
R_REG = R_REG | 0x01;
}
}
SCK_LOW;
return R_REG;
}
/******************************************************************************/
// @brief RF寄存器设置
// @param reg:写命令W_REGISTER+寄存器地址(比如CONFIG为0x00)
// wdata:需要为寄存器设置的值
// @retval None
/******************************************************************************/
void RF_WriteReg( uint8_t reg, uint8_t wdata)
{
CSN_LOW;
SPI_RW(reg);
SPI_RW(wdata);
CSN_HIGH;
}
/******************************************************************************/
// @brief RF寄存器读取
// @param reg:读命令R_REGISTER+寄存器地址(比如CONFIG为0x00)
// @retval 读取到的寄存器值
/******************************************************************************/
uint8_t RF_ReadReg( uint8_t reg)
{
uint8_t tmp;
CSN_LOW;
SPI_RW(reg);
tmp = SPI_RW(0);
CSN_HIGH;
return tmp;
}
/******************************************************************************/
// @brief RF寄存器设置
// @param reg:写命令W_REGISTER+寄存器地址
// pBuf:待写入数据的起始地址
// length: 待写入数据的长度
// @retval None
/******************************************************************************/
void RF_WriteBuf( uint8_t reg, uint8_t *pBuf, uint8_t length)
{
uint8_t j;
CSN_LOW;
j = 0;
SPI_RW(reg);
for(j = 0;j < length; j++)
{
SPI_RW(pBuf[j]);
}
j = 0;
CSN_HIGH;
}
/******************************************************************************/
// @brief RF寄存器读取
// @param reg:读命令R_REGISTER+寄存器地址
// pBuf:读取数据存放的起始地址
// length: 待写读取数据的长度
// @retval None
/******************************************************************************/
void RF_ReadBuf( uint8_t reg, uint8_t *pBuf, uint8_t length)
{
uint8_t byte_ctr;
CSN_LOW;
SPI_RW(reg);
for(byte_ctr=0;byte_ctr<length;byte_ctr++)
pBuf[byte_ctr] = SPI_RW(0);
CSN_HIGH;
}
/******************************************************************************/
// @brief RF设置为TX mode
// @param None
// @retval None
/******************************************************************************/
void RF_TxMode(void)
{
RF_WriteReg(W_REGISTER + CONFIG, 0X8E);
CE_LOW;
}
/******************************************************************************/
// @brief RF设置为RX mode
// @param None
// @retval None
/******************************************************************************/
void RF_RxMode(void)
{
RF_WriteReg(W_REGISTER + CONFIG, 0X8F );
delay_ms(10);
CE_HIGH;
delay_ms(10);
}
/******************************************************************************/
// @brief 读取RF状态标志
// @param None
// @retval 读出的状态值
// bit6:收到数据标志
// bit5:发射成功标志
// bit4:发射超时标志
// bit3-1:读取到数据后,判断是哪个通道接收,此处用不到
// bit0: TX FIFO状态标志,此处用不到
/******************************************************************************/
uint8_t RF_GetStatus(void)
{
return RF_ReadReg(STATUS)&0x70;
}
/******************************************************************************/
// @brief 清除RF状态标志
// @param None
// @retval None
/******************************************************************************/
void RF_ClearStatus(void)
{
RF_WriteReg(W_REGISTER + STATUS,0x70);
}
/******************************************************************************/
// @brief 清除RF FIFO,可根据实际情况单独清除TX_FIFO或RX_FIFO
// @param None
// @retval None
/******************************************************************************/
void RF_ClearFIFO(void)
{
RF_WriteReg(FLUSH_TX, 0); //清除RF 的 TX FIFO
RF_WriteReg(FLUSH_RX, 0); //清除RF 的 RX FIFO
}
/******************************************************************************/
// @brief 设置RF频道
// @param Channel:待设置的频点为“2400+Channel”MHz
// @retval None
/******************************************************************************/
void RF_SetChannel( uint8_t Channel)
{
RF_WriteReg(W_REGISTER + RF_CH, Channel);
}
/******************************************************************************/
// @brief RF发射数据
// @param ucPayload:发射数据的起始地址
// length:发射数据长度
// @retval None
/******************************************************************************/
void RF_TxData( uint8_t *ucPayload, uint8_t length)
{
CE_HIGH;
delay_100us(1);
RF_WriteBuf(W_TX_PAYLOAD, ucPayload, length); //rf entery tx mode start send data //rf entery stb3
delay_ms(1);
while(!(RF_GetStatus()&TX_DS_FLAG))
{
delay_ms(1);
}
RF_WriteReg(FLUSH_TX, 0); //清除RF的TX FIFO
RF_ClearStatus();
CE_LOW;
}
/******************************************************************************/
// @brief RF接收数据
// @param ucPayload:接收数据存放的起始地址
// length:接收数据长度
// @retval 1:收到数据
// 0: 没有收到数据
/******************************************************************************/
uint8_t RF_DumpRxData( uint8_t *ucPayload, uint8_t length)
{
if(!(RF_GetStatus()& RX_DR_FLAG))
{
return 0;
}
RF_ReadBuf(R_RX_PAYLOAD, ucPayload, length); //将接收到的数据读出到ucPayload
RF_WriteReg(FLUSH_RX, 0); //清除RF的RX FIFO
RF_ClearStatus();
return 1;
}
/******************************************************************************/
// @brief RF初始化
// @param None
// @retval 1:初始化成功
// 0: 初始化失败
/******************************************************************************/
uint8_t RF_Init(void)
{
uint8_t BB_cal_data[] = {0x12,0xED,0x67,0x9C,0x46};
uint8_t RF_cal_data[] = {0xF6,0x3F,0x5D};
uint8_t RF_cal2_data[] = {0x45,0x21,0xEF,0x2C,0x5A,0x40};
uint8_t Dem_cal_data[] = {0x01};
uint8_t Dem_cal2_data[] = {0x0B,0xDF,0x02};
uint8_t feature = 0x20; //使用软件CE
SPI_init();
RF_WriteReg(RST_FSPI, 0x5A); //Software Reset
RF_WriteReg(RST_FSPI, 0XA5);
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, TX_ADDRESS_DEF, sizeof(TX_ADDRESS_DEF)); // Writes TX_Address to XN297L
RF_WriteBuf(W_REGISTER + RX_ADDR_P0,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); // 9dbm 1Mbps
RF_WriteReg(ACTIVATE, 0x73);
RF_WriteReg(W_REGISTER + SETUP_RETR,0x00); // Disable retrans...
RF_WriteReg(W_REGISTER + EN_AA, 0x00); // Disable AutoAck
if(PAYLOAD_WIDTH >32)
feature |= 0x18;
RF_WriteReg(W_REGISTER + FEATURE, feature);
if(RF_ReadReg(RF_CH)!=DEFAULT_CHANNEL)
return 0;
return 1;
}
/******************************************************************************/
// @brief RF设置为载波模式
// @param ucChannel_Set:载波的频点
// @retval None
/******************************************************************************/
void RF_Carrier( uint8_t ucChannel_Set)
{
uint8_t BB_cal_data[] = {0x12,0xED,0x67,0x9C,0x46};
uint8_t RF_cal_data[] = {0xF6,0x3F,0x5D};
uint8_t RF_cal2_data[] = {0x45,0x21,0xEF,0x2C,0x5A,0x40};
uint8_t Dem_cal_data[] = {0xE1};
uint8_t Dem_cal2_data[] = {0x0B,0xDF,0x02};
RF_WriteReg(RST_FSPI, 0x5A); //Software Reset
RF_WriteReg(RST_FSPI, 0XA5);
uint8_t feature = 0x20; //使用软件CE
RF_WriteReg(W_REGISTER + FEATURE, feature);
CE_LOW;
delay_100us(5); //delay 500us
RF_WriteReg(W_REGISTER + CONFIG, 0X8E); //tx mode
RF_WriteReg(W_REGISTER + RF_CH, ucChannel_Set); //单载波频点
RF_WriteReg(W_REGISTER + RF_SETUP, RF_POWER); //9dbm
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));
delay_100us(5);
}
/***************************************end of file ************************************/
附完整代码