STM32实现基于HAL库的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下添加以下代码

uint8_t SpiInOut( uint8_t TxData )
{
  uint8_t Rxdata;
  HAL_SPI_TransmitReceive(&hspi3,&TxData,&Rxdata,1, 1000);
  return Rxdata; 
}

2、spi.h

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

uint8_t SpiInOut( uint8_t TxData );

3、main.c

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

#include <stdio.h>
#include <string.h>

#include "radio.h"
#include "platform.h"
#include "sx1276.h"
#include "sx1276-Hal.h"
#include "sx1276-LoRa.h"
#include "sx1276-LoRaMisc.h"

#define _DEBUG_LORA_TX_ENABLE

#define BUFFERSIZE 200//收发数据的最大字节数

#define CIRCLE     16 //收发循环的次�??

uint8_t LoRa_TX_BUFF[BUFFERSIZE]={
		00,01,//the ID of the send package
		0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99,//constant,easy to find error in the transition
		0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99,
		0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99};
uint8_t LoRa_RX_BUFF[BUFFERSIZE];//接收缓冲区,200字节
uint16_t LoraTxLength=8;//记录发�?�数据的长度
uint16_t LoraRxLength=8;//记录接收数据的长�??

uint8_t START_RECEIVE_FLAG=0;
uint16_t nRx=0;//接收LoRa数据包的个数
uint16_t nTx=0;//发�?�LoRa数据包的个数


tRadioDriver *Radio=NULL;

bool LoraTxOn=false;


uint16_t last_ID=0;//record the first package's ID when the received MCU started

uint8_t ndelay=0;
uint8_t hh=0,mm=0,ss=1;

void Check_SPI_LoRa(void)
{
	uint8_t Reg_Version=0;//LoRa的版本,0x12=18才说明SPI通了
	uint8_t CIRCLE_MAX=5;//发�?�循环的次数
	uint8_t t=0;
	uint32_t lora_process=0;

	while(1)//测试SPI是否正常
	{
		SX1276Read( REG_LR_VERSION, &Reg_Version );
		if(Reg_Version!=0x12){
			printf("--------SPI read ERROR !!! --------\r\n");
			printf("LoRa Version = %d !\r\n",Reg_Version);
			HAL_GPIO_TogglePin(LED1_GPIO_Port, LED1_Pin);
			HAL_Delay(100);
		}
		else{
			printf("SPI read SUCCESS !!!\r\n");
			printf("LoRa Version = %d !\r\n",Reg_Version);
			break;
		}
	}

	while(1)//测试LoRa是否正常
	{
		if(t++ > CIRCLE_MAX){
			SX1276LoRaSetTxPacket( LoRa_TX_BUFF, LoraTxLength);
			printf("-----------= TX START =-----------\r\n");
			printf("TX:%s \r\n",LoRa_TX_BUFF);
			t=0;
		}
		printf(" t = %d\r\n",t);
		lora_process=SX1276LoRaProcess();
		switch(lora_process)
		{
		case RF_IDLE:	//空闲状�??
			printf("lora process:RF_IDLE\r\n");
			t=CIRCLE_MAX+1;
			break;
		case RF_BUSY:	//模块执行任务�??
			printf("lora process:RF_BUSY\r\n");
			break;
		case RF_TX_DONE:
			//      printf("lora process:RF_TX_DONE\r\n");
			printf("-----------= LoRa TX END =-----------\r\n");
			return;
			break;
		default:
			printf("lora process=%d:unknown status\r\n",(int)lora_process);
			break;
		}
		HAL_Delay(200);
	}
}

void LoRaTxTask(void)
{
	uint8_t RSSI=0,i=0;
	nTx++;
	LoRa_TX_BUFF[0]=(nTx&0xff00)>>8;
	LoRa_TX_BUFF[1]=nTx&0xff;
	SX1276LoRaSetTxPacket( LoRa_TX_BUFF,LoraTxLength );//写入要发送的数据//LoraTxLength
	while(RF_TX_DONE!=SX1276LoRaProcess())HAL_Delay(10);//等待发�?�完�??

	for(i=0;i<LoraTxLength;i++)
	        printf("%02X->",LoRa_TX_BUFF[i]);
	printf("\r\n===========LoRa_TX_DONE: %d===========\r\n",nTx);
	//读取RSSI
	SX1276Read( REG_LR_PKTRSSIVALUE, &RSSI );
	printf("REG_LR_PKTRSSIVALUE=%d\r\n",RSSI-137);
	SX1276Read( REG_LR_RSSIVALUE, &RSSI );
	printf("REG_LR_RSSIVALUE=%d\r\n",RSSI-137);
	printf("===========LoRa_TX_DONE: %d===========\r\n",nTx);
}



void Rx_data_process(void)
{
  uint8_t RSSI=0;
  nRx++;//sometime send 5 pack,but only receive the fifth pack
  nTx=(((uint16_t)LoRa_RX_BUFF[0]<<8)&0xff00)+LoRa_RX_BUFF[1];//the numb of send package

  if(nTx==1){ //if this package is the first of send
    nRx=1;
    last_ID=nTx-1;
  }

  if(START_RECEIVE_FLAG==0)//if receive MCU is first start
  {
    START_RECEIVE_FLAG=1;
    nRx=1;
    last_ID=nTx-1;
  }

  //count the percentage of receive
    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
    printf("rx=%d,tx=%d\r\n",nRx,nTx-last_ID);//rx is the number of received package from the received MCU started;
    										//nTx-last_ID is the number of send package from the received MCU started
    printf("rx percentage=%f\r\n",(float)(nRx*100.0/(nTx-last_ID)));
  //read RSSI
  SX1276Read( REG_LR_PKTRSSIVALUE, &RSSI );
  printf("REG_LR_PKTRSSIVALUE=%d\r\n",RSSI-137); //the closer the lower;the lower the better,the lowest can be -45
  SX1276Read( REG_LR_RSSIVALUE, &RSSI );
  printf("REG_LR_RSSIVALUE=%d\r\n",RSSI-137);

}
void LoRaRxTask(void)
{
  uint32_t lora_process=RF_IDLE,i=0;

  lora_process=SX1276LoRaProcess();
  switch(lora_process)
  {
  case RF_IDLE:
//    printf("loraprocess:RF_IDLE\r\n");
    break;
  case RF_RX_DONE:
//    printf("loraprocess:RF_RX_DONE\r\n");
    memset(LoRa_RX_BUFF,0,BUFFERSIZE);//娓呯┖缂撳啿鍖�
    SX1276LoRaGetRxPacket(LoRa_RX_BUFF,&LoraRxLength);//璇诲彇鎺ユ敹鏁版�???
    printf("LoRa RX data=\r\n");
    for(i=0;i<LoraRxLength;i++)
        printf("%02X->",LoRa_RX_BUFF[i]);
    printf("\r\n---------- LoRa RX DONE ----------\r\n");

    Rx_data_process();
    break;
  case RF_BUSY:
    //      printf("loraprocess:RF_BUSY\r\n");
    break;
  default:
    printf("loraprocess=%d:unknown status\r\n",(int)lora_process);
    break;
  }
}



void TimeHandle(void)
{
	HAL_GPIO_TogglePin(LED1_GPIO_Port, LED1_Pin);
	if(++ss>=60){
		ss=0;mm++;
		if(mm>=60){
			mm=0;hh++;
		}
	}
	printf(" time =%2dh - %02dm - %02ds \r\n",hh,mm,ss);
}

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

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

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

	  if(++ndelay>100)//period
	  {
		  ndelay=0;
		  TimeHandle();
#ifdef _DEBUG_LORA_TX_ENABLE
	  //LoRa send a package every 2s
	  if(ss%2==0)
		  LoRaTxTask();
#else
	  //LoRa receive package
	  LoRaRxTask();
#endif
	  }
	  HAL_Delay(10);

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

#define _DEBUG_LORA_TX_ENABLE

五、实验结果

  • 3
    点赞
  • 65
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值