如何使用STM32连接射频SI4438模块详细方法说明 |
您所在的位置:网站首页 › si4438芯片 › 如何使用STM32连接射频SI4438模块详细方法说明 |
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) 所以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 retry++; if(retry>250) return0; } SPI2->DR=TxData; retry=0; while((SPI2->SR&1 { 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; } |
今日新闻 |
推荐新闻 |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |