SI4438射频模块参数:
1、频率规模:425-525 MHz
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
u8 STM32SPI2_ReadWriteByte(u8 TxData)
{
u8 retry=0;
while((SPI2->SR11) == 0) {
retry++;
if(retry>250)
return 0;
}
SPI2->DR=TxData;
retry=0;
while((SPI2->SR10) == 0)//
{
retry++;
if(retry>250)
return 0;
}
return SPI2->DR;
}
//APB2=72M/8=9M
void STM32SPI2_Config(void)
{
SPI_InitTypeDef SPI_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE );
/* Configure SPI2 pins: SCK, MISO and MOSI */
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);
/* Configure NSEL pins */
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);
/* SPI2 configuration */
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);
/* Enable SPI2 */
SPI_Cmd(SPI2, ENABLE);
STM32SPI2_ReadWriteByte(0xff);//发动传输
}
//í?ò?ê±?????üê1?üò???SPIéè±?,2?êyTYPE_SPI_ALL?TD§
void STM32SPI2_Enable(TYPE_SPI type)
{
/*
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);//
/*
}
*/
}
void STM32SPI2_Disable(TYPE_SPI type)
{
if(type == TYPE_SPI_FLASH)
{
GPIO_SetBits(GPIOC,GPIO_Pin_4);//ê§?üFLASH
}
else if(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.c radio hal层 spi接口修正处
void radio_hal_SpiWriteByte(u8 byteToWrite)
{
STM32SPI2_ReadWriteByte(byteToWrite);
}
u8 radio_hal_SpiReadByte(void)
{
return STM32SPI2_ReadWriteByte(0xFF);
}
void radio_hal_SpiWriteData(u8 byteCount, u8* pData)
{
while(byteCount–)
{
STM32SPI2_ReadWriteByte(*pData++);
}
}
void radio_hal_SpiReadData(u8 byteCount, u8* pData)
{
while(byteCount–)
{
*pData++ = STM32SPI2_ReadWriteByte(0xFF);
}
}
Radio_Config:装备SDN power IRQ引脚
void Radio_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
//oíFLASH12ó?ò???SPI,SPIò??-?úFLASHμ?3?ê??ˉ?Dμ÷ó?
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);
}
接纳信号:
u8 radio_hal_NirqLevel(void)
{
return GPIO_ReadInputDataBit(RF_IRQ_PORT, RF_IRQ_PIN);
}
void radio_hal_AssertShutdown(void)
{
GPIO_SetBits(RF_SDN_PORT, RF_SDN_PIN);
}
void radio_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
#define SILABS_RADIO_SI446X
#include radio_comm.h
#include si446x_api_lib.h
#include si446x_defs.h
//#include si446x_nirq.h
#include
//#include driversradioSi446xsi446x_patch.h
把不是自己的渠道的屏蔽了!
Main接纳端
接纳函数:
int SI4338RecvData(void* buf,u32 len){
u16 i,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)
{
case SI446X_CMD_GET_INT_STATUS_REP_PH_PEND_PACKET_SENT_PEND_BIT:{
vRadio_StartRX(pRadioConfiguration->Radio_ChannelNumber, 64);
///* Clear Packet Sending flag */
}
break;
case SI446X_CMD_GET_INT_STATUS_REP_PH_PEND_PACKET_RX_PEND_BIT:{
memset(ptr,0,len);
memcpy(ptr,SI4338RecvData,SI4338RecvLen);
//recv OK ,you must start RX!
vRadio_StartRX(pRadioConfiguration->Radio_ChannelNumber,pRadioConfiguration->Radio_PacketLength);
return SI4338RecvLen;
}
break;
default:
break;
} /* switch */
return -1;
}
//留意:需要在U8 bRadio_Check_Tx_RX(void)函数把接纳的数据复制出来,然后再RECV函数memcpy过来就能够了。
U8 bRadio_Check_Tx_RX(void){
……………………………………….
if(Si446xCmd.GET_INT_STATUS.PH_PEND SI446X_CMD_GET_INT_STATUS_REP_PH_PEND_PACKET_RX_PEND_BIT)
{
/* Packet RX */
/* Get payload length */
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);
return SI446X_CMD_GET_INT_STATUS_REP_PH_PEND_PACKET_RX_PEND_BIT;
}
….
}
unsigned char buf[64];
int recvLen;
vRadio_StartRX(pRadioConfiguration->Radio_ChannelNumber,0u); 发动接纳
while(1){
if((recvLen = SI4338RecvData(void*( buf),64)) >0){
//处理接纳的数据
}
}
发送端:运用这个函数发送既能够!
int SI4338SendData(void* buf,u32 len){
u8* ptr;
int ret = -1;
u16 i;
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);
#if 1
bMain_IT_Status = bRadio_Check_Tx_RX();
switch (bMain_IT_Status)
{
case SI446X_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;
case SI446X_CMD_GET_INT_STATUS_REP_PH_PEND_PACKET_RX_PEND_BIT:{
vRadio_StartRX(pRadioConfiguration->Radio_ChannelNumber, pRadioConfiguration->Radio_PacketLength);
return SI4338RecvLen;
}
default: ;break;
}
#endif
return ret;
}
- STM32单片机中文官网
- STM32单片机官方开发东西
- STM32单片机参阅规划