STM32如何与si4438射频模块通信?
eeskill 2023-11-24

SI4438射频模块参数:

1、频率范围:425-525MHz


2、数字接收信号强度指示(RSSI)


3、64字节收发数据寄存器(FIFO)


4、跳频功能


等!


使用SI的WDS工具生成代码

1、 选择仿真模式


2、芯片选择si4438 B1模式


3、 Radio Configuration Application


4、 Select Application





1、 Select Project


选择Bidirectional packet ,双向通信模式


2、 Configure project 配置工程


Frequency and power: 频率和功率的设置,


base freq基频,中心频率,


Channel spacing 通道空间,某个通道回忆 base freq+ channel spacin*num 为频率通信,当然会有小浮动,但是浮动不会超过 Channel spacing。


计算通道号数量:


(Base freq + channel spacin*num) >=425MHz


(Base freq + channel spacin*num) <=525MHz



所以Base freq的设置以及channel spacing的设置会影响到通道的数量。


Crystal:晶振默认!


其他的不动



RF parameter




这里设置的射频参数,包括调制模式、数据速率等参数,RSSI threshold设置信号阈值。数据速率射频之间的距离有关系,速度越快,对应的距离要求越短。所以这应该按照自己的需求来选。





Pakect数据包的设置,包括TX和RX缓冲区的长度、前导码的配置Preamble、同步字的配置SyncWord、Field对应负载的字节数据,注意总的负载字节数为TX和RX阈值,具体分几个fields看个人需求。




NIRQ配置成RX data output,即NIRQ和单片机引脚相连单片机可以通过该引脚判断是否有数据接收。低电平有效!然后即可生成代码!


生成的代码是基于C8051F910单片机的,我们所用的是,所以必须做好移植。


SPI移植:


不需要生成spi.c,建立STM32 SPI配置文件:



#include


#include"stm32f10x_spi.h"


#include"STM32SPI2.h"



u8STM32SPI2_ReadWriteByte(u8TxData)


{


u8retry=0;


while((SPI2->SR&1<<1)==0){


retry++;


if(retry>250)


return0;


}


SPI2->DR=TxData;



retry=0;


while((SPI2->SR&1<<0)==0)//


{


retry++;


if(retry>250)


return0;


}


returnSPI2->DR;


}




//APB2=72M/8=9M


voidSTM32SPI2_Config(void)


{


SPI_InitTypeDefSPI_InitStructure;


GPIO_InitTypeDefGPIO_InitStructure;



RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);



/*ConfigureSPI2pins:SCK,MISOandMOSI*/


GPIO_InitStructure.GPIO_Pin=GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15;


GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;


GPIO_InitStructure.GPIO_Speed=GPIO_Speed_10MHz;


GPIO_Init(GPIOB,&GPIO_InitStructure);



/*ConfigureNSELpins*/


GPIO_InitStructure.GPIO_Pin=GPIO_Pin_12;


GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;


GPIO_InitStructure.GPIO_Speed=GPIO_Speed_10MHz;


GPIO_Init(GPIOB,&GPIO_InitStructure);


GPIO_SetBits(GPIOB,GPIO_Pin_12);



/*SPI2configuration*/


SPI_I2S_DeInit(SPI2);


RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2,ENABLE);


SPI_Cmd(SPI2,DISABLE);



SPI_InitStructure.SPI_Direction=SPI_Direction_2Lines_FullDuplex;


SPI_InitStructure.SPI_Mode=SPI_Mode_Master;


SPI_InitStructure.SPI_DataSize=SPI_DataSize_8b;


SPI_InitStructure.SPI_CPOL=SPI_CPOL_Low;


SPI_InitStructure.SPI_CPHA=SPI_CPHA_1Edge;


SPI_InitStructure.SPI_NSS=SPI_NSS_Soft;


SPI_InitStructure.SPI_BaudRatePrescaler=SPI_BaudRatePrescaler_128;//SPI_BaudRatePrescaler_64;


SPI_InitStructure.SPI_FirstBit=SPI_FirstBit_MSB;


SPI_InitStructure.SPI_CRCPolynomial=7;


SPI_Init(SPI2,&SPI_InitStructure);



/*EnableSPI2*/


SPI_Cmd(SPI2,ENABLE);


STM32SPI2_ReadWriteByte(0xff);//启动传输



}



//í?ò?ê±?????üê1?üò???SPIéè±?,2?êyTYPE_SPI_ALL?TD§


voidSTM32SPI2_Enable(TYPE_SPItype)


{


/*


if(type==TYPE_SPI_FLASH)//这其实没啥用


{


GPIO_SetBits(GPIOA,GPIO_Pin_4);//ê§?üRF


GPIO_ResetBits(GPIOC,GPIO_Pin_4);//ê1?üFLASH


}


else


{


*/


//GPIO_SetBits(GPIOC,GPIO_Pin_4);//ê§?üFLASH


GPIO_ResetBits(GPIOB,GPIO_Pin_12);//


/*


}


*/


}



voidSTM32SPI2_Disable(TYPE_SPItype)


{


if(type==TYPE_SPI_FLASH)


{


GPIO_SetBits(GPIOC,GPIO_Pin_4);//ê§?üFLASH


}


elseif(type==TYPE_SPI_RF)


{


GPIO_SetBits(GPIOB,GPIO_Pin_12);//ê§?üRF


}


else


{


GPIO_SetBits(GPIOC,GPIO_Pin_4);//ê§?üFLASH


GPIO_SetBits(GPIOA,GPIO_Pin_4);//ê§?üRF


}


}


radio.cradiohal层spi接口修改处


voidradio_hal_SpiWriteByte(u8byteToWrite)


{


STM32SPI2_ReadWriteByte(byteToWrite);


}



u8radio_hal_SpiReadByte(void)


{


returnSTM32SPI2_ReadWriteByte(0xFF);


}



voidradio_hal_SpiWriteData(u8byteCount,u8*pData)


{


while(byteCount--)


{


STM32SPI2_ReadWriteByte(*pData++);


}


}



voidradio_hal_SpiReadData(u8byteCount,u8*pData)


{


while(byteCount--)


{


*pData++=STM32SPI2_ReadWriteByte(0xFF);


}


}


Radio_Config:配置SDNpowerIRQ引脚


voidRadio_Config(void)


{


GPIO_InitTypeDefGPIO_InitStructure;



//oíFLASH12ó?ò???SPI,SPIò??-?úFLASHμ?3?ê??ˉ?Dμ&pide;ó?


RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOC,ENABLE);



//RF_POWER


GPIO_InitStructure.GPIO_Pin=RF_POWER_PIN;


GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;


GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;


GPIO_Init(RF_POWER_PORT,&GPIO_InitStructure);


GPIO_SetBits(RF_POWER_PORT,RF_POWER_PIN);



//RF_ON


GPIO_InitStructure.GPIO_Pin = RF_


GPIO_InitStructure.GPIO_Pin=RF_ON_PIN;


GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;


GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;


GPIO_Init(RF_ON_PORT,&GPIO_InitStructure);


GPIO_SetBits(RF_ON_PORT,RF_ON_PIN);



//RF_SDN


GPIO_InitStructure.GPIO_Pin=RF_SDN_PIN;


GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;


GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;


GPIO_Init(RF_SDN_PORT,&GPIO_InitStructure);


GPIO_SetBits(RF_SDN_PORT,RF_SDN_PIN);



//RF_IRQ


GPIO_InitStructure.GPIO_Pin=RF_IRQ_PIN;


GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN_FLOATING;//????ê?è?


GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;


GPIO_Init(RF_IRQ_PORT,&GPIO_InitStructure);


}


接收信号:


u8radio_hal_NirqLevel(void)


{


returnGPIO_ReadInputDataBit(RF_IRQ_PORT,RF_IRQ_PIN);


}



voidradio_hal_AssertShutdown(void)


{


GPIO_SetBits(RF_SDN_PORT,RF_SDN_PIN);


}



voidradio_hal_DeassertShutdown(void)


{


GPIO_ResetBits(RF_SDN_PORT,RF_SDN_PIN);


}





底层配置完毕,配置bsh头文件:



#include"stdio.h"


#include"compiler_defs.h"


//#include"platform_defs.h"


//#include"hardware_defs.h"



//#include"application_defs.h"



//#include"cdd_common.h"


#include"radio_config.h"


#include"radio.h"


//#include"sample_code_func.h"




#include"radio_hal.h"



#defineSILABS_RADIO_SI446X


#include"radio_comm.h"




#include"si446x_api_lib.h"


#include"si446x_defs.h"


//#include"si446x_nirq.h"


#include


//#include"drivers\radio\Si446x\si446x_patch.h"



把不是自己的平台的屏蔽了!



Main接收端


接收函数:



intSI4338RecvData(void*buf,u32len){


u16i,crc16;


u8*ptr;



SEGMENT_VARIABLE(bMain_IT_Status,U8,SEG_XDATA);



ptr=(u8*)buf;


if(ptr==NULL)return-1;



bMain_IT_Status=bRadio_Check_Tx_RX();



switch(bMain_IT_Status)


{


caseSI446X_CMD_GET_INT_STATUS_REP_PH_PEND_PACKET_SENT_PEND_BIT:{


vRadio_StartRX(pRadioConfiguration->Radio_ChannelNumber,64);


///*ClearPacketSendingflag*/


}


break;



caseSI446X_CMD_GET_INT_STATUS_REP_PH_PEND_PACKET_RX_PEND_BIT:{


memset(ptr,0,len);


memcpy(ptr,SI4338RecvData,SI4338RecvLen);


//recvOK,youmuststartRX!


vRadio_StartRX(pRadioConfiguration->Radio_ChannelNumber,pRadioConfiguration->Radio_PacketLength);


returnSI4338RecvLen;


}


break;



default:


break;


}/*switch*/


return-1;


}


//注意:需要在U8bRadio_Check_Tx_RX(void)函数把接收的数据拷贝出来,然后再RECV函数memcpy过来就可以了。


U8bRadio_Check_Tx_RX(void){


……………………………………….


if(Si446xCmd.GET_INT_STATUS.PH_PEND&SI446X_CMD_GET_INT_STATUS_REP_PH_PEND_PACKET_RX_PEND_BIT)


{


/*PacketRX*/



/*Getpayloadlength*/


si446x_fifo_info(0x00);



si446x_read_rx_fifo(Si446xCmd.FIFO_INFO.RX_FIFO_COUNT,&rxInformation[0]);


SI4338RecvLen=Si446xCmd.FIFO_INFO.RX_FIFO_COUNT;


memcpy(SI4338RecvData,rxInformation,Si446xCmd.FIFO_INFO.RX_FIFO_COUNT);


returnSI446X_CMD_GET_INT_STATUS_REP_PH_PEND_PACKET_RX_PEND_BIT;


}


….


}


unsignedcharbuf[64];


intrecvLen;


vRadio_StartRX(pRadioConfiguration->Radio_ChannelNumber,0u);启动接收


while(1){


if((recvLen=SI4338RecvData(void*(buf),64))>0){


//处理接收的数据


}


}



发送端:使用这个函数发送既可以!


intSI4338SendData(void*buf,u32len){


u8*ptr;


intret=-1;


u16i;



SEGMENT_VARIABLE(bMain_IT_Status,U8,SEG_XDATA);



ptr=(u8*)buf;



if(buf==NULL)return-1;



vRadio_StartTx_Variable_Packet(pRadioConfiguration->Radio_ChannelNumber,ptr,len);


#if1


bMain_IT_Status=bRadio_Check_Tx_RX();



switch(bMain_IT_Status)


{


caseSI446X_CMD_GET_INT_STATUS_REP_PH_PEND_PACKET_SENT_PEND_BIT:


//vRadio_StartTx_Variable_Packet(pRadioConfiguration->Radio_ChannelNumber,ptr,len);


vRadio_StartRX(pRadioConfiguration->Radio_ChannelNumber,pRadioConfiguration->Radio_PacketLength);


ret=0;


break;


caseSI446X_CMD_GET_INT_STATUS_REP_PH_PEND_PACKET_RX_PEND_BIT:{



vRadio_StartRX(pRadioConfiguration->Radio_ChannelNumber,pRadioConfiguration->Radio_PacketLength);


returnSI4338RecvLen;


}


default:;break;


}


#endif


returnret;


}



声明: 本文转载自其它媒体或授权刊载,目的在于信息传递,并不代表本站赞同其观点和对其真实性负责,如有新闻稿件和图片作品的内容、版权以及其它问题的,请联系我们及时删除。(联系我们,邮箱:evan.li@aspencore.com )
0
评论
  • 相关技术文库
  • RF
  • 射频
  • 通信
  • 无线
下载排行榜
更多
评测报告
更多
广告