通过stm32 IO口模拟PSI通讯实现SI4463配置与使用
stm32单片机源程序如下:
- /*******************************************************
- Copyright (C), 2016-10-15 liuzijian.All Rights Reserved
- File name: Si4463.c
- Author: liuzijian
- Version: V1.0.0
- Date: 2016-10-15
- Description: IO simulation SPI, SI4463 initialization and communication
- SWD3 Software creates Si4463 configuration file(radio_config_Si4463.h)
- Revision History:
- Version Date Author Modification
- V1.0.0 2016-10-15 liuzijain 初次编写
- *********************************************************/
- #include "stm32f10x.h"
- #include "Si4463.h"
- #include "radio_config_Si4463.h"
- #include "user_subfunction.h"
- #include <stdio.h>
- const u8 set[1000] = RADIO_CONFIGURATION_DATA_ARRAY;
- #define s46_BUFF_LEN 1 // 数据长度设置
- u8 s46_Send_Buff[s46_BUFF_LEN]={0}; // 发送数据缓冲数组
- u8 s46_Rece_Buff[s46_BUFF_LEN]={0}; // 接收数据缓冲数组
- /*
- // 函数: SPIGPIO_Config()
- // 描述: 配置SPI模拟的输入输出端口
- // 配置IO模拟SPI
- // RF4463_IRQ--PC8输入 GPIO1--PB15输入 SDN--PB12输出 NSEL--PC6输出 SCLK--PB14输出 SDO--PC7输入 SDI--PB13输出 */
- void SPIGPIO_Config(void)
- { //输出
- GPIO_InitTypeDef GPIO_InitStructure;
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_Init(GPIOB, &GPIO_InitStructure);
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_Init(GPIOC, &GPIO_InitStructure);
- //输入
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7 | GPIO_Pin_8;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_Init(GPIOC, &GPIO_InitStructure);
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_Init(GPIOB, &GPIO_InitStructure);
- }
- /*****************************************************************************
- 函数: s46_SPI_WR_Byte()
- 描述: 通过SPI写一个byte到Si4463,同时从寄存器读取一个Byte
- 参数: byte 待写入字节数据
- return 读取到的字节数据
- ******************************************************************************/
- uint8 s46_SPI_WR_Byte(uint8 byte)
- {
- uint8 i;
- for(i=0; i<8; i++)
- {// 循环8次
- if((byte & 0x80) == 0x80)
- {SDI_SET;} // 将byte最高位输出到SDI
- else
- {SDI_CLR;}
- byte <<= 1; // 低一位移位到最高位
- SCLK_SET;
- delay4us(10); // 拉高SLCK,从SI读入1位数据,同时Si4463从SO输出1位数据
- // byte |= SDO; // 读SDO到byte最低位
- if(SDO==1){byte |= 0x01;}
- else{byte |= 0x00;}
- SCLK_CLR;
- delay4us(10); // SCLK置低
- }
- return(byte); // 返回读取的1Byte数据
- }
- /***********************************************************************
- 函数: s46_SPI_W_CMD()
- 描述: 向芯片中写入指令
- 参数: cmd 指令字
- plen 写入参数数量(写入属性时最多为12个参数)
- *p 写入参数存放地址
- loopcts 0=忽略CTS检测; 1=检测CTS
- *****************************************************************************/
- void s46_SPI_W_CMD(uint8 cmd, uint16 plen, uint8 *p, uint8 loopcts)
- {
- uint8 i=0;
- if(loopcts == 1){while(GPIO1 == 0);} // 等待CTS为高(执行完成)
- NSEL_CLR; // nSEL置低,开始数据传输过程
- s46_SPI_WR_Byte(cmd); // 写入指令字
- for(i=0; i<plen; i++)
- { s46_SPI_WR_Byte(p[i]); // 写入后续数据
- }
- NSEL_SET; // nSEL置高,结束数据传输过程
- }
- /*************************************************************
- 函数: s46_SPI_R_CMD()
- 描述: 从芯片中读取指令响应
- 参数: cmd 指令字
- plen 读取响应数量(读取属性时最多为16个参数)
- *p 读取响应存放地址
- loopcts 0=忽略CTS检测; 1=检测CTS
- return CTS响应值
- ******************************************************************/
- uint8 s46_SPI_R_CMD(uint8 cmd, uint8 len, uint8 *p, uint8 loopcts)
- {
- uint8 i=0;
- //uint8_t cts=0;
- if(loopcts == 1){while(GPIO1 == 0);} // 等待CTS为高(执行完成)
- NSEL_CLR; // nSEL置低,开始数据传输过程
- s46_SPI_WR_Byte(cmd); // 写入指令字
- for(i=0; i<=len; i++)
- { p[i] = s46_SPI_WR_Byte(0); // 读取寄存器数值
- }
- NSEL_SET; // nSEL置高,结束数据传输过程
- return(p[0]); // 返回CTS
- }
- /******************************************************************************
- 函数: s46_Power_ON_Reset()
- 描述: 芯片上电后的复位
- 参数: 无
- ******************************************************************************/
- void s46_Power_ON_Reset(void)
- {
- uint8 buff[7] = {RF_POWER_UP};
- NSEL_SET;
- SDI_CLR;
- SCLK_CLR;
-
- SDN_SET; // SDN=1=进入掉电模式
- delayms(1); // 等待1ms
- SDN_CLR; // SDN=0=进入上电模式
- while(GPIO1 == 0); // 等待CTS为高,上电成功
- s46_SPI_W_CMD(buff[0], 6, &buff[1], 1); // 写入POR指令及配置数据
-
- }
- /*********************************************************************
- 函数: s46_Load_Radio_Config()
- 描述: 将WDS生成的配置列表写入芯片中
- 参数: none
- ************************************************************************/
- void s46_Load_Radio_Config(void)
- {
-
- uint16 i = 0;
- i = set[i] + 1; // 跳过POR配置数据
- do
- { s46_SPI_W_CMD(set[i+1], set[i]-1,(uint8 *)&set[i+2], 0); // 写入配置列表中的数据
- i = i + set[i] + 1; // 指向下一组数据
- }while (set[i] != 0x00); // 空值(len=0x00)结束
- }
- /**************************************************
- 函数: s46_Clear_Interrupt_Status()
- 描述: 清除全部中断,并返回数据包处理器中断状态
- 参数: 无
- *****************************************************/
- uint8 s46_Clear_Interrupt_Status(void)
- {
- uint8 buff[9];
- buff[0] = 0; buff[1] = 0; buff[2] = 0;
- s46_SPI_W_CMD(s46CMD_GET_INT_STATUS_B0_CMD, 3, buff, 1); // 写入返回中断状态指令
- s46_SPI_R_CMD(s46CMD_READ_CMD_BUFF_B0_CMD, 9, buff, 1); // 读取CTS和指令响应
- return(buff[s46RIN_GET_INT_STATUS_B3_PH_PEND]); // 返回数据包处理器中断状态
- }
- /********************************************************************
- 函数: s46_Send_Packet()
- 描述: 发送数据包
- 参数: *p 发送数据的首地址
- ************************************************************************/
- void s46_Send_Packet(uint8 *p)
- {
- uint8 buff[8];
- s46_Clear_Interrupt_Status(); // 清除全部中断
- while(RF4463_IRQ != 1); // 等待nIRQ为高(中断已清除)
-
- s46_SPI_W_CMD(s46CMD_WRITE_TX_FIFO_B0_CMD, s46_BUFF_LEN, p, 0); // 将待发送数据写入TX_FIFO
- buff[0] = s46PRT_INT_CTL_PH_ENABLE_GROUP; // 属性分组=包处理器中断使能
- buff[1] = 1; // 属性数量=1
- buff[2] = s46PRT_INT_CTL_PH_ENABLE_INDEX; // 起始地址=PH_ENABLE
- buff[3] = s46PFS_INT_CTL_PH_ENABLE_PACKET_SENT_EN; // 使能PACKET_SENT中断
- s46_SPI_W_CMD(s46CMD_SET_PROPERTY_B0_CMD, 4, buff, 1); // 写入包处理器中断使能属性
- buff[0] = RADIO_CONFIGURATION_DATA_CHANNEL_NUMBER; // CHANNEL
- buff[1] = s46RFP_START_TX_B2_NOCHANGE // 发送结束后进入READY状态
- | s46RFP_START_TX_B2_USE // 更新参数并进入TX模式
- | s46RFP_START_TX_B2_TRANSMIT_FIFO // 发送FIFO中的数据(下溢时产生中断)
- | s46RFP_START_TX_B2_IMMEDIATE; // 立即发送
- buff[2] = (uint8)(s46_BUFF_LEN >> 8); // TX_LEN bit12:8
- buff[3] = (uint8)(s46_BUFF_LEN); // TX_LEN bit7:0
- buff[4] = 0; // 数据包之间的间隔时间
- buff[5] = 0; // 数据包重复次数
- s46_SPI_W_CMD(s46CMD_START_TX_B0_CMD, 6, buff, 1); // 启动发送
- while(RF4463_IRQ != 0); // 等待nIRQ为低(执行完成)
- s46_Clear_Interrupt_Status(); // 清除全部中断
- s46_Start_RX(); // 返回RX状态
- }
- /******************************************************************************
- 函数: s46_Start_RX()
- 描述: 进入接收状态
- 参数: 无
- ******************************************************************************/
- void s46_Start_RX(void)
- {
- uint8 buff[7];
-
- s46_Clear_Interrupt_Status(); // 清除全部中断
- buff[0] = s46CFP_CHANGE_STATE_B1_READY; // 进入READY模式
- s46_SPI_W_CMD(s46CMD_CHANGE_STATE_B0_CMD, 1, buff, 1); // 发送指令
- buff[0] = s46PRT_INT_CTL_PH_ENABLE_GROUP; // 属性分组=包处理器中断使能
- buff[1] = 1; // 属性数量=1
- buff[2] = s46PRT_INT_CTL_PH_ENABLE_INDEX; // 起始地址=PH_ENABLE
- buff[3] = s46PFS_INT_CTL_PH_ENABLE_PACKET_RX_EN // 使能PACKET_RX中断
- | s46PFS_INT_CTL_PH_ENABLE_CRC_ERROR_EN; // 使能CRC_ERROR中断
- s46_SPI_W_CMD(s46CMD_SET_PROPERTY_B0_CMD, 4, buff, 1); // 写入包处理器中断使能属性
- buff[0] = RADIO_CONFIGURATION_DATA_CHANNEL_NUMBER; // CHANNEL
- buff[1] = s46RFP_START_RX_B2_USE // 更新参数并进入RX模式
- | s46CFP_START_RX_B2_IMMEDIATE; // 立即接收
- buff[2] = (uint8)(s46_BUFF_LEN >> 8); // RX_LEN bit12:8
- buff[3] = (uint8)(s46_BUFF_LEN); // TX_LEN bit7:0
- buff[4] = s46CFP_START_RX_B5B7_NO_CHANGE; // 前导检测超时时自动进入的状态
- buff[5] = s46CFP_START_RX_B5B7_READY; // 接收到有效数据包时自动进入的状态
- buff[6] = s46CFP_START_RX_B5B7_READY; // 接收到无效数据包时自动进入的状态
- s46_SPI_W_CMD(s46CMD_START_RX_B0_CMD, 7, buff, 1); // 启动接收
- }
- /*******************************************************************************
- 函数: uint8 s46_RX_Check(uint8 *p)
- 描述: 检测接收状态
- 参数: *p 接收数据存放地址
- return 接收完成标志(0=无接收, 1=接收到有效数据)
- *******************************************************************************/
- uint8 s46_RX_Check(uint8 *p)
- {
- uint8 t=0;
- uint8 buff[3];
- uint8 r=0;
- if(RF4463_IRQ == 0)
- {
- t = s46_Clear_Interrupt_Status(); // 清除全部中断,并返回数据包处理器中断状态
- if(t & s46RFP_GET_INT_STATUS_B4_PACKET_RX){ // 检查是否为数据包接收完成中断
- s46_SPI_R_CMD(s46CMD_READ_RX_FIFO_B0_CMD, s46_BUFF_LEN, p, 0); // 读取RX_FIFO中的数据
- r = 1; // 检测到有效数据包
- ……………………
- …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码
所有资料51hei提供下载:
stm32-si4463.rar
(11.62 KB, 下载次数: 104)
|