• STM32CubeIDE实现基于STM32的LoRa通信程序移植(SPI接口)


    一、硬件电路图

     LoRa模块链接:

    立创商城:LSD4RF-2F717N30_(LSD(利尔达))LSD4RF-2F717N30中文资料_价格_PDF手册-立创电子商城

    官网 :

    标准LoRa模组,产品型号:LSD4RF-2F717N30

    二、 配置工作

    1、准备好printf工程,参考之前的教程

    STM32CubeIDE实现printf重定向输出到串口_飞由于度的博客-CSDN博客STM32CubeIDE之printf重定向及串口https://blog.csdn.net/qq_35629563/article/details/126665838

    2、配置LoRa引脚

    ①SPI引脚(其他参数保持默认)

     ②控制引脚

    将PA15、PB7配置为GPIO_output模式,然后右击引脚分别重命名为LORA_NSS、LORA_RESET

     ③呼吸灯

    这里我是用的是PC1作为呼吸灯,其实不论使用哪个引脚控制的呼吸灯,只需将其命名为LED1即可

    生成代码

    三、代码移植

    1、将SX1278直接拷贝到Core文件夹下,然后在STM32CubeIDE中刷新工程(快捷键F5)

    SX1278文件可以从下面的连接获取

    STM32CubeIDE实现基于STM32的LoRa通信程序移植(SPI接口)-C文档类资源-CSDN下载内容概要:使用STM32F103RCT6作为核心,控制lora实现简单的通信,基本功能是通过main更多下载资源、学习资料请访问CSDN下载频道.https://download.csdn.net/download/qq_35629563/86509591

    2、将新添加的文件加入到路径中去

    右击platform文件夹,选择Add/remove include path...

    需要添加的文件夹一共有三个:platform、platform下的sx12xxEiger、radio

     四、代码修改

    1、spi.c

    在USER CODE BEGIN 1下添加以下代码

    1. uint8_t SpiInOut( uint8_t TxData )
    2. {
    3. uint8_t Rxdata;
    4. HAL_SPI_TransmitReceive(&hspi3,&TxData,&Rxdata,1, 1000);
    5. return Rxdata;
    6. }

    2、spi.h

    在USER CODE BEGIN Prototypes下添加以下代码

    uint8_t SpiInOut( uint8_t TxData );

    3、main.c

    ①在USER CODE BEGIN Includes下添加以下代码(为了简单,变量、函数都添加到了这里)

    1. #include
    2. #include
    3. #include "radio.h"
    4. #include "platform.h"
    5. #include "sx1276.h"
    6. #include "sx1276-Hal.h"
    7. #include "sx1276-LoRa.h"
    8. #include "sx1276-LoRaMisc.h"
    9. #define _DEBUG_LORA_TX_ENABLE
    10. #define BUFFERSIZE 200//收发数据的最大字节数
    11. #define CIRCLE 16 //收发循环的次�??
    12. uint8_t LoRa_TX_BUFF[BUFFERSIZE]={
    13. 00,01,//the ID of the send package
    14. 0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99,//constant,easy to find error in the transition
    15. 0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99,
    16. 0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99};
    17. uint8_t LoRa_RX_BUFF[BUFFERSIZE];//接收缓冲区,200字节
    18. uint16_t LoraTxLength=8;//记录发�?�数据的长度
    19. uint16_t LoraRxLength=8;//记录接收数据的长�??
    20. uint8_t START_RECEIVE_FLAG=0;
    21. uint16_t nRx=0;//接收LoRa数据包的个数
    22. uint16_t nTx=0;//发�?�LoRa数据包的个数
    23. tRadioDriver *Radio=NULL;
    24. bool LoraTxOn=false;
    25. uint16_t last_ID=0;//record the first package's ID when the received MCU started
    26. uint8_t ndelay=0;
    27. uint8_t hh=0,mm=0,ss=1;
    28. void Check_SPI_LoRa(void)
    29. {
    30. uint8_t Reg_Version=0;//LoRa的版本,0x12=18才说明SPI通了
    31. uint8_t CIRCLE_MAX=5;//发�?�循环的次数
    32. uint8_t t=0;
    33. uint32_t lora_process=0;
    34. while(1)//测试SPI是否正常
    35. {
    36. SX1276Read( REG_LR_VERSION, &Reg_Version );
    37. if(Reg_Version!=0x12){
    38. printf("--------SPI read ERROR !!! --------\r\n");
    39. printf("LoRa Version = %d !\r\n",Reg_Version);
    40. HAL_GPIO_TogglePin(LED1_GPIO_Port, LED1_Pin);
    41. HAL_Delay(100);
    42. }
    43. else{
    44. printf("SPI read SUCCESS !!!\r\n");
    45. printf("LoRa Version = %d !\r\n",Reg_Version);
    46. break;
    47. }
    48. }
    49. while(1)//测试LoRa是否正常
    50. {
    51. if(t++ > CIRCLE_MAX){
    52. SX1276LoRaSetTxPacket( LoRa_TX_BUFF, LoraTxLength);
    53. printf("-----------= TX START =-----------\r\n");
    54. printf("TX:%s \r\n",LoRa_TX_BUFF);
    55. t=0;
    56. }
    57. printf(" t = %d\r\n",t);
    58. lora_process=SX1276LoRaProcess();
    59. switch(lora_process)
    60. {
    61. case RF_IDLE: //空闲状�??
    62. printf("lora process:RF_IDLE\r\n");
    63. t=CIRCLE_MAX+1;
    64. break;
    65. case RF_BUSY: //模块执行任务�??
    66. printf("lora process:RF_BUSY\r\n");
    67. break;
    68. case RF_TX_DONE:
    69. // printf("lora process:RF_TX_DONE\r\n");
    70. printf("-----------= LoRa TX END =-----------\r\n");
    71. return;
    72. break;
    73. default:
    74. printf("lora process=%d:unknown status\r\n",(int)lora_process);
    75. break;
    76. }
    77. HAL_Delay(200);
    78. }
    79. }
    80. void LoRaTxTask(void)
    81. {
    82. uint8_t RSSI=0,i=0;
    83. nTx++;
    84. LoRa_TX_BUFF[0]=(nTx&0xff00)>>8;
    85. LoRa_TX_BUFF[1]=nTx&0xff;
    86. SX1276LoRaSetTxPacket( LoRa_TX_BUFF,LoraTxLength );//写入要发送的数据//LoraTxLength
    87. while(RF_TX_DONE!=SX1276LoRaProcess())HAL_Delay(10);//等待发�?�完�??
    88. for(i=0;i
    89. printf("%02X->",LoRa_TX_BUFF[i]);
    90. printf("\r\n===========LoRa_TX_DONE: %d===========\r\n",nTx);
    91. //读取RSSI
    92. SX1276Read( REG_LR_PKTRSSIVALUE, &RSSI );
    93. printf("REG_LR_PKTRSSIVALUE=%d\r\n",RSSI-137);
    94. SX1276Read( REG_LR_RSSIVALUE, &RSSI );
    95. printf("REG_LR_RSSIVALUE=%d\r\n",RSSI-137);
    96. printf("===========LoRa_TX_DONE: %d===========\r\n",nTx);
    97. }
    98. void Rx_data_process(void)
    99. {
    100. uint8_t RSSI=0;
    101. nRx++;//sometime send 5 pack,but only receive the fifth pack
    102. nTx=(((uint16_t)LoRa_RX_BUFF[0]<<8)&0xff00)+LoRa_RX_BUFF[1];//the numb of send package
    103. if(nTx==1){ //if this package is the first of send
    104. nRx=1;
    105. last_ID=nTx-1;
    106. }
    107. if(START_RECEIVE_FLAG==0)//if receive MCU is first start
    108. {
    109. START_RECEIVE_FLAG=1;
    110. nRx=1;
    111. last_ID=nTx-1;
    112. }
    113. //count the percentage of receive
    114. printf("ID=%d last_ID=%d\r\n",nTx,last_ID);//ID is the new package;last_ID is the received package ID when the MCU firstly started
    115. printf("rx=%d,tx=%d\r\n",nRx,nTx-last_ID);//rx is the number of received package from the received MCU started;
    116. //nTx-last_ID is the number of send package from the received MCU started
    117. printf("rx percentage=%f\r\n",(float)(nRx*100.0/(nTx-last_ID)));
    118. //read RSSI
    119. SX1276Read( REG_LR_PKTRSSIVALUE, &RSSI );
    120. printf("REG_LR_PKTRSSIVALUE=%d\r\n",RSSI-137); //the closer the lower;the lower the better,the lowest can be -45
    121. SX1276Read( REG_LR_RSSIVALUE, &RSSI );
    122. printf("REG_LR_RSSIVALUE=%d\r\n",RSSI-137);
    123. }
    124. void LoRaRxTask(void)
    125. {
    126. uint32_t lora_process=RF_IDLE,i=0;
    127. lora_process=SX1276LoRaProcess();
    128. switch(lora_process)
    129. {
    130. case RF_IDLE:
    131. // printf("loraprocess:RF_IDLE\r\n");
    132. break;
    133. case RF_RX_DONE:
    134. // printf("loraprocess:RF_RX_DONE\r\n");
    135. memset(LoRa_RX_BUFF,0,BUFFERSIZE);//娓呯┖缂撳啿鍖�
    136. SX1276LoRaGetRxPacket(LoRa_RX_BUFF,&LoraRxLength);//璇诲彇鎺ユ敹鏁版�???
    137. printf("LoRa RX data=\r\n");
    138. for(i=0;i
    139. printf("%02X->",LoRa_RX_BUFF[i]);
    140. printf("\r\n---------- LoRa RX DONE ----------\r\n");
    141. Rx_data_process();
    142. break;
    143. case RF_BUSY:
    144. // printf("loraprocess:RF_BUSY\r\n");
    145. break;
    146. default:
    147. printf("loraprocess=%d:unknown status\r\n",(int)lora_process);
    148. break;
    149. }
    150. }
    151. void TimeHandle(void)
    152. {
    153. HAL_GPIO_TogglePin(LED1_GPIO_Port, LED1_Pin);
    154. if(++ss>=60){
    155. ss=0;mm++;
    156. if(mm>=60){
    157. mm=0;hh++;
    158. }
    159. }
    160. printf(" time =%2dh - %02dm - %02ds \r\n",hh,mm,ss);
    161. }

    ②在USER CODE BEGIN 2下添加以下代码

    1. SX1276Init();// Initialize LoRa modem
    2. Check_SPI_LoRa();//to check whether SPI can work correctly
    3. SX1276StartRx();//

    ③在USER CODE BEGIN 3下添加以下代码

    1. if(++ndelay>100)//period
    2. {
    3. ndelay=0;
    4. TimeHandle();
    5. #ifdef _DEBUG_LORA_TX_ENABLE
    6. //LoRa send a package every 2s
    7. if(ss%2==0)
    8. LoRaTxTask();
    9. #else
    10. //LoRa receive package
    11. LoRaRxTask();
    12. #endif
    13. }
    14. HAL_Delay(10);

    注:到这里已经能够实现lora的发送功能,要实现接收只需要注释掉main.c中的

    #define _DEBUG_LORA_TX_ENABLE

    五、实验结果

  • 相关阅读:
    IO多路转接之select和poll
    Visual Studio Code的安装和使用
    ClickHouse进阶(十九):clickhouse管理与运维-权限管理
    第P6周—好莱坞明星识别(1)
    基于SpringBoot的仿小米商城系统
    C++第一天:C++面向对象高级开发上
    MySQL 不相关子查询怎么执行?
    mathtype试用期后如何继续使用?
    【ROS机器人】Autolabor Pro RTK室外厘米级导航
    使用VBA打印PDF文件
  • 原文地址:https://blog.csdn.net/qq_35629563/article/details/126675017