找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 4197|回复: 5
收起左侧

stm32配置SI4463 443M公共频段通讯源码

[复制链接]
ID:342259 发表于 2018-5-31 16:16 | 显示全部楼层 |阅读模式
通过stm32 IO口模拟PSI通讯实现SI4463配置与使用
0.png

stm32单片机源程序如下:
  1. /*******************************************************
  2.   Copyright (C), 2016-10-15   liuzijian.All Rights Reserved
  3.   File name: Si4463.c
  4.   Author:    liuzijian   
  5.   Version:   V1.0.0      
  6.   Date:      2016-10-15
  7.   Description: IO simulation SPI, SI4463 initialization and communication
  8.                            SWD3 Software creates Si4463 configuration file(radio_config_Si4463.h)
  9.   Revision History:   
  10.      Version   Date          Author       Modification
  11.      V1.0.0    2016-10-15    liuzijain     初次编写

  12. *********************************************************/

  13. #include "stm32f10x.h"
  14. #include "Si4463.h"
  15. #include "radio_config_Si4463.h"
  16. #include "user_subfunction.h"
  17. #include <stdio.h>

  18. const u8 set[1000] = RADIO_CONFIGURATION_DATA_ARRAY;
  19. #define s46_BUFF_LEN    1                                           // 数据长度设置
  20. u8 s46_Send_Buff[s46_BUFF_LEN]={0};                                     // 发送数据缓冲数组
  21. u8 s46_Rece_Buff[s46_BUFF_LEN]={0};                              // 接收数据缓冲数组
  22. /*
  23. // 函数: SPIGPIO_Config()
  24. // 描述: 配置SPI模拟的输入输出端口
  25. // 配置IO模拟SPI
  26. // RF4463_IRQ--PC8输入  GPIO1--PB15输入   SDN--PB12输出   NSEL--PC6输出  SCLK--PB14输出   SDO--PC7输入   SDI--PB13输出  */
  27. void SPIGPIO_Config(void)
  28. {        //输出
  29.     GPIO_InitTypeDef   GPIO_InitStructure;
  30.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14;
  31.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  32.         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  33.         GPIO_Init(GPIOB, &GPIO_InitStructure);

  34.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
  35.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  36.         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  37.         GPIO_Init(GPIOC, &GPIO_InitStructure);
  38.         //输入
  39.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7 | GPIO_Pin_8;
  40.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
  41.         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  42.         GPIO_Init(GPIOC, &GPIO_InitStructure);

  43.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15;
  44.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
  45.         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  46.         GPIO_Init(GPIOB, &GPIO_InitStructure);
  47. }


  48. /*****************************************************************************
  49. 函数: s46_SPI_WR_Byte()
  50. 描述: 通过SPI写一个byte到Si4463,同时从寄存器读取一个Byte
  51. 参数: byte   待写入字节数据
  52.       return 读取到的字节数据                 
  53. ******************************************************************************/
  54. uint8 s46_SPI_WR_Byte(uint8 byte)
  55. {
  56.     uint8 i;
  57.     for(i=0; i<8; i++)
  58.     {// 循环8次
  59.             if((byte & 0x80) == 0x80)
  60.                 {SDI_SET;}         // 将byte最高位输出到SDI
  61.                 else
  62.                 {SDI_CLR;}           
  63.         byte <<= 1;                          // 低一位移位到最高位
  64.         SCLK_SET;
  65.                 delay4us(10);                           // 拉高SLCK,从SI读入1位数据,同时Si4463从SO输出1位数据
  66.         // byte |= SDO;                                                    // 读SDO到byte最低位      
  67.                 if(SDO==1){byte |= 0x01;}
  68.                 else{byte |= 0x00;}                    
  69.         SCLK_CLR;
  70.                 delay4us(10);                             // SCLK置低
  71.     }
  72.     return(byte);                                   // 返回读取的1Byte数据
  73. }

  74. /***********************************************************************
  75. 函数: s46_SPI_W_CMD()
  76. 描述: 向芯片中写入指令
  77. 参数: cmd    指令字
  78.        plen   写入参数数量(写入属性时最多为12个参数)
  79.        *p     写入参数存放地址
  80.        loopcts 0=忽略CTS检测; 1=检测CTS        
  81. *****************************************************************************/
  82. void s46_SPI_W_CMD(uint8 cmd, uint16 plen, uint8 *p, uint8 loopcts)
  83. {
  84.     uint8 i=0;

  85.     if(loopcts == 1){while(GPIO1 == 0);}            // 等待CTS为高(执行完成)

  86.     NSEL_CLR;                                       // nSEL置低,开始数据传输过程
  87.     s46_SPI_WR_Byte(cmd);                           // 写入指令字
  88.     for(i=0; i<plen; i++)
  89.         {        s46_SPI_WR_Byte(p[i]);                      // 写入后续数据
  90.     }
  91.     NSEL_SET;                                       // nSEL置高,结束数据传输过程
  92. }

  93. /*************************************************************
  94. 函数: s46_SPI_R_CMD()
  95. 描述: 从芯片中读取指令响应
  96. 参数: cmd    指令字
  97.       plen   读取响应数量(读取属性时最多为16个参数)
  98.       *p     读取响应存放地址
  99.       loopcts 0=忽略CTS检测; 1=检测CTS
  100.       return CTS响应值  
  101. ******************************************************************/
  102. uint8 s46_SPI_R_CMD(uint8 cmd, uint8 len, uint8 *p, uint8 loopcts)
  103. {
  104.     uint8 i=0;
  105.         //uint8_t cts=0;

  106.     if(loopcts == 1){while(GPIO1 == 0);}            // 等待CTS为高(执行完成)

  107.     NSEL_CLR;                                       // nSEL置低,开始数据传输过程
  108.         s46_SPI_WR_Byte(cmd);                                                        // 写入指令字
  109.     for(i=0; i<=len; i++)
  110.         {        p[i] = s46_SPI_WR_Byte(0);                  // 读取寄存器数值
  111.     }
  112.     NSEL_SET;                                       // nSEL置高,结束数据传输过程
  113.     return(p[0]);                                   // 返回CTS
  114. }

  115. /******************************************************************************
  116. 函数: s46_Power_ON_Reset()
  117. 描述: 芯片上电后的复位
  118. 参数: 无                 
  119. ******************************************************************************/
  120. void s46_Power_ON_Reset(void)
  121. {         
  122.     uint8 buff[7] = {RF_POWER_UP};

  123.     NSEL_SET;
  124.     SDI_CLR;
  125.     SCLK_CLR;   
  126.                                                       
  127.     SDN_SET;                                                         // SDN=1=进入掉电模式
  128.     delayms(1);                                                      // 等待1ms
  129.     SDN_CLR;                                                         // SDN=0=进入上电模式
  130.     while(GPIO1 == 0);                                               // 等待CTS为高,上电成功
  131.     s46_SPI_W_CMD(buff[0], 6, &buff[1], 1);                          // 写入POR指令及配置数据

  132.         
  133. }

  134. /*********************************************************************
  135. 函数: s46_Load_Radio_Config()
  136. 描述: 将WDS生成的配置列表写入芯片中
  137. 参数: none
  138. ************************************************************************/
  139. void s46_Load_Radio_Config(void)
  140. {
  141.    
  142.     uint16 i = 0;
  143.     i = set[i] + 1;                                                 // 跳过POR配置数据
  144.     do                                                                                   
  145.         {        s46_SPI_W_CMD(set[i+1], set[i]-1,(uint8 *)&set[i+2], 0);            // 写入配置列表中的数据
  146.         i = i + set[i] + 1;                                         // 指向下一组数据
  147.     }while (set[i] != 0x00);                                        // 空值(len=0x00)结束
  148. }

  149. /**************************************************
  150. 函数: s46_Clear_Interrupt_Status()
  151. 描述: 清除全部中断,并返回数据包处理器中断状态
  152. 参数: 无           
  153. *****************************************************/
  154. uint8 s46_Clear_Interrupt_Status(void)
  155. {
  156.     uint8 buff[9];

  157.     buff[0] = 0; buff[1] = 0; buff[2] = 0;

  158.     s46_SPI_W_CMD(s46CMD_GET_INT_STATUS_B0_CMD, 3, buff, 1);        // 写入返回中断状态指令
  159.     s46_SPI_R_CMD(s46CMD_READ_CMD_BUFF_B0_CMD, 9, buff, 1);         // 读取CTS和指令响应

  160.     return(buff[s46RIN_GET_INT_STATUS_B3_PH_PEND]);                 // 返回数据包处理器中断状态
  161. }

  162. /********************************************************************
  163. 函数: s46_Send_Packet()
  164. 描述: 发送数据包
  165. 参数: *p     发送数据的首地址  
  166. ************************************************************************/
  167. void s46_Send_Packet(uint8 *p)
  168. {
  169.     uint8 buff[8];

  170.     s46_Clear_Interrupt_Status();                                   // 清除全部中断
  171.     while(RF4463_IRQ != 1);                                         // 等待nIRQ为高(中断已清除)
  172.    
  173.     s46_SPI_W_CMD(s46CMD_WRITE_TX_FIFO_B0_CMD, s46_BUFF_LEN, p, 0); // 将待发送数据写入TX_FIFO

  174.     buff[0] = s46PRT_INT_CTL_PH_ENABLE_GROUP;                       // 属性分组=包处理器中断使能
  175.     buff[1] = 1;                                                    // 属性数量=1
  176.     buff[2] = s46PRT_INT_CTL_PH_ENABLE_INDEX;                       // 起始地址=PH_ENABLE
  177.     buff[3] = s46PFS_INT_CTL_PH_ENABLE_PACKET_SENT_EN;              // 使能PACKET_SENT中断
  178.     s46_SPI_W_CMD(s46CMD_SET_PROPERTY_B0_CMD, 4, buff, 1);          // 写入包处理器中断使能属性

  179.     buff[0] = RADIO_CONFIGURATION_DATA_CHANNEL_NUMBER;              // CHANNEL
  180.     buff[1] = s46RFP_START_TX_B2_NOCHANGE                           // 发送结束后进入READY状态
  181.             | s46RFP_START_TX_B2_USE                                // 更新参数并进入TX模式
  182.             | s46RFP_START_TX_B2_TRANSMIT_FIFO                      // 发送FIFO中的数据(下溢时产生中断)
  183.             | s46RFP_START_TX_B2_IMMEDIATE;                         // 立即发送
  184.     buff[2] = (uint8)(s46_BUFF_LEN >> 8);                           // TX_LEN bit12:8
  185.     buff[3] = (uint8)(s46_BUFF_LEN);                                // TX_LEN bit7:0
  186.     buff[4] = 0;                                                    // 数据包之间的间隔时间
  187.     buff[5] = 0;                                                    // 数据包重复次数
  188.     s46_SPI_W_CMD(s46CMD_START_TX_B0_CMD, 6, buff, 1);              // 启动发送

  189.     while(RF4463_IRQ != 0);                                       // 等待nIRQ为低(执行完成)
  190.     s46_Clear_Interrupt_Status();                                   // 清除全部中断
  191.     s46_Start_RX();                                                 // 返回RX状态
  192. }


  193. /******************************************************************************
  194. 函数: s46_Start_RX()
  195. 描述: 进入接收状态
  196. 参数: 无
  197. ******************************************************************************/
  198. void s46_Start_RX(void)
  199. {
  200.     uint8 buff[7];
  201.    
  202.     s46_Clear_Interrupt_Status();                                   // 清除全部中断

  203.     buff[0] = s46CFP_CHANGE_STATE_B1_READY;                         // 进入READY模式
  204.     s46_SPI_W_CMD(s46CMD_CHANGE_STATE_B0_CMD, 1, buff, 1);          // 发送指令

  205.     buff[0] = s46PRT_INT_CTL_PH_ENABLE_GROUP;                       // 属性分组=包处理器中断使能
  206.     buff[1] = 1;                                                    // 属性数量=1
  207.     buff[2] = s46PRT_INT_CTL_PH_ENABLE_INDEX;                       // 起始地址=PH_ENABLE
  208.     buff[3] = s46PFS_INT_CTL_PH_ENABLE_PACKET_RX_EN                 // 使能PACKET_RX中断
  209.             | s46PFS_INT_CTL_PH_ENABLE_CRC_ERROR_EN;                // 使能CRC_ERROR中断
  210.     s46_SPI_W_CMD(s46CMD_SET_PROPERTY_B0_CMD, 4, buff, 1);          // 写入包处理器中断使能属性

  211.     buff[0] = RADIO_CONFIGURATION_DATA_CHANNEL_NUMBER;              // CHANNEL
  212.     buff[1] = s46RFP_START_RX_B2_USE                                // 更新参数并进入RX模式
  213.             | s46CFP_START_RX_B2_IMMEDIATE;                         // 立即接收
  214.     buff[2] = (uint8)(s46_BUFF_LEN >> 8);                           // RX_LEN bit12:8
  215.     buff[3] = (uint8)(s46_BUFF_LEN);                                // TX_LEN bit7:0
  216.     buff[4] = s46CFP_START_RX_B5B7_NO_CHANGE;                       // 前导检测超时时自动进入的状态                           
  217.     buff[5] = s46CFP_START_RX_B5B7_READY;                           // 接收到有效数据包时自动进入的状态
  218.     buff[6] = s46CFP_START_RX_B5B7_READY;                           // 接收到无效数据包时自动进入的状态
  219.     s46_SPI_W_CMD(s46CMD_START_RX_B0_CMD, 7, buff, 1);              // 启动接收
  220. }


  221. /*******************************************************************************
  222. 函数: uint8 s46_RX_Check(uint8 *p)
  223. 描述: 检测接收状态
  224. 参数: *p     接收数据存放地址
  225.       return 接收完成标志(0=无接收, 1=接收到有效数据)
  226. *******************************************************************************/
  227. uint8 s46_RX_Check(uint8 *p)
  228. {
  229.     uint8 t=0;
  230.     uint8 buff[3];
  231.     uint8 r=0;

  232.     if(RF4463_IRQ == 0)
  233.         {
  234.         t = s46_Clear_Interrupt_Status();                                   // 清除全部中断,并返回数据包处理器中断状态
  235.         if(t & s46RFP_GET_INT_STATUS_B4_PACKET_RX){                         // 检查是否为数据包接收完成中断
  236.             s46_SPI_R_CMD(s46CMD_READ_RX_FIFO_B0_CMD, s46_BUFF_LEN, p, 0);  // 读取RX_FIFO中的数据
  237.             r = 1;                                                          // 检测到有效数据包                                          
  238. ……………………

  239. …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码

所有资料51hei提供下载:
stm32-si4463.rar (11.62 KB, 下载次数: 104)
回复

使用道具 举报

ID:365446 发表于 2019-1-7 16:26 | 显示全部楼层
谢谢分享,正需要,下载学习
回复

使用道具 举报

ID:443880 发表于 2019-1-8 10:55 | 显示全部楼层

谢谢分享
回复

使用道具 举报

ID:268693 发表于 2019-3-16 11:43 | 显示全部楼层
谢谢分享!谢谢!
回复

使用道具 举报

ID:52630 发表于 2019-3-28 11:36 | 显示全部楼层
谢谢,SI4463这模块挺难搞的,非常感谢
回复

使用道具 举报

ID:1023716 发表于 2023-2-3 12:49 | 显示全部楼层
虽然是stm32的应用程序,但设计思路应该也适用STM8S,谢谢楼主的分享。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表