LoRa移植详细步骤说明

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录


前言

最近想实现长距离无线通讯,使用LoRa模块,其芯片采用的SX1278SEMTECH射频集成芯片SX127X的射频模块,这是一款高性能物联网无线收发器.为了方便今后的温故与学习,写一篇小文章记录一下。

一、软硬件使用

  • Keil5
  • STM32CubeMx
  • STM32L151C8 + LoRa模块(SX1278)

二、官网固件支持包下载

SEMTECH官网的链接 :https://www.semtech.com/

三、SPI通讯

LoRa芯片与MCU通过SPI进行通信。SPI(Serial Peripheral Interface Bus),是由摩托罗拉公司开发的高速全双工同步串行通信协议。SPI支持一主多从,这点类似于I2C,但是又与I2C选通从设备的方式不同,I2C是通过发送从机地址来选通从机,而SPI则是通过拉低连接到从机的NSS引脚对从机进行选通的。
SPI一般应用由四个引脚组成(一主一从):

  • NSS (CS) :选择信号,由主机发出,一般是低电位有效
  • SCLK:串行时钟,由主机发出
  • MOSI:主机输出从机输入信号,由主机发出
  • MISO:主机输入从机输出信号,由从机发出

SPI主要特点有:

  • 全双工
  • 提供频率可编程时钟
  • 写冲突保护,总线竞争保护
  • 发送结束中断标志
  • 可以当作主机或从机工作等
    以上是对LoRa通讯的简单描述,主要是进行移植详细步骤的说明。

四、LoRa驱动移植步骤

1. 移植官方的LoRa驱动前需要明确LoRa芯片与主芯片的引脚接线:

在这里插入图片描述

  • DIO0和DIO1为lora模块的输出引脚,连接的单片机引脚需要对应配置为输入模式进行检测。
  • NSS,SCK,MISO.MOSI为STM32与LoRa模块的SPI接口
  • DIO0——PB11
  • DIO1——PB10
  • SPI_SCK——PA4
  • SPI_MISO——PA5
  • SPI_MOSI——PA6

2.双击打开STM32CubeMX,选择File—>New Project

在这里插入图片描述

3.搜索STM32l151芯片型号,点击Strat Project

在这里插入图片描述

4.选择System Core下的 SYS 选择 Debug—>Serial Write

在这里插入图片描述

5.选择System Core下的 RCC 选择 HSE—>CCR 和 LSE—>CCR

在这里插入图片描述

6.配置时钟树为(32MHz)

在这里插入图片描述

7.SPI配置,模式为全双工主站(Full-Duplex Master),分频(Prescale)为8,波特率Baud Rate 为4MBits/s(其波特率和时钟树的主时钟频率有关)。CPOL = Low.表示SCLK = 0时处于空闲态,所以有效状态就是SCLK处于高电平有效。CPHA = 1 Edge 表示数据采样是在第一个边沿,数据发送是在第二个边沿。其通讯模式为 Mode:0。

在这里插入图片描述

8.GPIO配置 PA3和PB8为LED灯。

在这里插入图片描述

9.点击Project Manager—>Project,需要自己命名项目名称和设置项目路径(尽量不要出现汉字)

在这里插入图片描述

10.勾选Code Generator 下的每次都重新生成一个外设的 /.c/ .h文件 和 只复制必要的库文件。

在这里插入图片描述

11.点击GENERATE CODE,生成工程文件。

在这里插入图片描述

12.点击 Open Project.

在这里插入图片描述

13.生成如下工程,先点击编译(首次编译时间较长请耐心等待)在这里插入图片描述编译后无警告无错误即为工程新建成功。

在这里插入图片描述

14.先把Keil5最小化打开工程文件所在的文件夹位置

在这里插入图片描述

15.新建一个LoRa的文件夹,并且把从官网下载的固件加压下的radio和platform拷贝在此文件夹下。

在这里插入图片描述

16.此时需要把platform—>sx12xxEiger—>spi.c和spi.h删掉。因为会与STM32CubeMx自动生成的spi.c和spi.h冲突。

在这里插入图片描述

17.点击Manage Project Items —>Groups新建连个文件夹LoRa/radio和LoRa/platform并添加相应的/.c文件,添加完毕点击OK。

在这里插入图片描述
在这里插入图片描述

18.添加/.c对应的/.h文件。

在这里插入图片描述

19.修改platform.h,在MDK的project的Options选项卡中的C/C++的Preprocessor Symbols Define中添加PLATFORM=SX12xxEiger。

在这里插入图片描述

20.将sx12xxEiger.c 下的BoardInit()函数内容删掉或屏蔽掉。

在这里插入图片描述

21.sx12xxEiger.h的屏蔽如图所示。

在这里插入图片描述

22.更改较多的是sx1276-Hal.c文件,整体代码如下。

/*
 * THE FOLLOWING FIRMWARE IS PROVIDED: (1) "AS IS" WITH NO WARRANTY; AND 
 * (2)TO ENABLE ACCESS TO CODING INFORMATION TO GUIDE AND FACILITATE CUSTOMER.
 * CONSEQUENTLY, SEMTECH SHALL NOT BE HELD LIABLE FOR ANY DIRECT, INDIRECT OR
 * CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE CONTENT
 * OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING INFORMATION
 * CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
 * 
 * Copyright (C) SEMTECH S.A.
 */
/*! 
 * \file       sx1276-Hal.c
 * \brief      SX1276 Hardware Abstraction Layer
 *
 * \version    2.0.B2 
 * \date       Nov 21 2012
 * \author     Miguel Luis
 *
 * Last modified by Miguel Luis on Jun 19 2013
 */
#include <stdint.h>
#include <stdbool.h> 

#include "platform.h"

#if defined( USE_SX1276_RADIO )

#include "ioe.h"
#include "spi.h"
#include "../../radio/sx1276-Hal.h"

void SX1276InitIo( void )
{
	HAL_GPIO_WritePin(GPIOA,GPIO_PIN_4,GPIO_PIN_RESET);
//    GPIO_InitTypeDef GPIO_InitStructure;

//#if defined( STM32F4XX ) || defined( STM32F2XX ) || defined( STM32F429_439xx )
//    RCC_AHB1PeriphClockCmd( RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOB |
//                            RCC_AHB1Periph_GPIOG, ENABLE );
//#else
//    RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB |
//                            RCC_APB2Periph_GPIOC | RCC_APB2Periph_AFIO, ENABLE );
//#endif

//#if defined( STM32F4XX ) || defined( STM32F2XX ) || defined( STM32F429_439xx )
//    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
//    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
//    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
//    GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_UP;
//#else
//    GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_Out_PP;
//    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
//#endif
//    
//    // Configure NSS as output
//    GPIO_WriteBit( NSS_IOPORT, NSS_PIN, Bit_SET );
//    GPIO_InitStructure.GPIO_Pin = NSS_PIN;
//    GPIO_Init( NSS_IOPORT, &GPIO_InitStructure );

//    // Configure radio DIO as inputs
//#if defined( STM32F4XX ) || defined( STM32F2XX ) || defined( STM32F429_439xx )
//    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
//    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
//#else
//    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
//#endif

//    // Configure DIO0
//    GPIO_InitStructure.GPIO_Pin =  DIO0_PIN;
//    GPIO_Init( DIO0_IOPORT, &GPIO_InitStructure );
//    
//    // Configure DIO1
//    GPIO_InitStructure.GPIO_Pin =  DIO1_PIN;
//    GPIO_Init( DIO1_IOPORT, &GPIO_InitStructure );
//    
//    // Configure DIO2
//    GPIO_InitStructure.GPIO_Pin =  DIO2_PIN;
//    GPIO_Init( DIO2_IOPORT, &GPIO_InitStructure );
//    
//    // REAMARK: DIO3/4/5 configured are connected to IO expander

//    // Configure DIO3 as input
//    
//    // Configure DIO4 as input
//    
//    // Configure DIO5 as input
}

void SX1276SetReset( uint8_t state )
{
//    GPIO_InitTypeDef GPIO_InitStructure;

//    if( state == RADIO_RESET_ON )
//    {
//        // Set RESET pin to 0
//        GPIO_WriteBit( RESET_IOPORT, RESET_PIN, Bit_RESET );

//        // Configure RESET as output
//#if defined( STM32F4XX ) || defined( STM32F2XX ) || defined( STM32F429_439xx )
//        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
//        GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
//#else

//        GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_Out_PP;
//#endif        
//        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
//        GPIO_InitStructure.GPIO_Pin = RESET_PIN;
//        GPIO_Init( RESET_IOPORT, &GPIO_InitStructure );
//    }
//    else
//    {
//#if FPGA == 0    
//        // Configure RESET as input
//#if defined( STM32F4XX ) || defined( STM32F2XX ) || defined( STM32F429_439xx )
//        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
//#else
//        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
//#endif        
//        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
//        GPIO_InitStructure.GPIO_Pin =  RESET_PIN;
//        GPIO_Init( RESET_IOPORT, &GPIO_InitStructure );
//#else
//        GPIO_WriteBit( RESET_IOPORT, RESET_PIN, Bit_RESET );
//#endif
//    }
}

uint8_t SpiInOut(uint8_t outData)
{
	uint8_t RxData;
	HAL_SPI_TransmitReceive(&hspi1,&outData,&RxData,1,1000);
	return RxData;
}
void SX1276Write( uint8_t addr, uint8_t data )
{
    SX1276WriteBuffer( addr, &data, 1 );
}

void SX1276Read( uint8_t addr, uint8_t *data )
{
    SX1276ReadBuffer( addr, data, 1 );
}

void SX1276WriteBuffer( uint8_t addr, uint8_t *buffer, uint8_t size )
{
    uint8_t i;

    //NSS = 0;
    
		HAL_GPIO_WritePin(GPIOA,GPIO_PIN_4,GPIO_PIN_RESET);
    SpiInOut( addr | 0x80 );
    for( i = 0; i < size; i++ )
    {
        SpiInOut( buffer[i] );
    }

    //NSS = 1;
    HAL_GPIO_WritePin(GPIOA,GPIO_PIN_4,GPIO_PIN_SET);
}

void SX1276ReadBuffer( uint8_t addr, uint8_t *buffer, uint8_t size )
{
    uint8_t i;

    //NSS = 0;
    HAL_GPIO_WritePin(GPIOA,GPIO_PIN_4,GPIO_PIN_RESET);

    SpiInOut( addr & 0x7F );

    for( i = 0; i < size; i++ )
    {
        buffer[i] = SpiInOut( 0 );
    }

    //NSS = 1;
    HAL_GPIO_WritePin(GPIOA,GPIO_PIN_4,GPIO_PIN_SET);
}

void SX1276WriteFifo( uint8_t *buffer, uint8_t size )
{
    SX1276WriteBuffer( 0, buffer, size );
}

void SX1276ReadFifo( uint8_t *buffer, uint8_t size )
{
    SX1276ReadBuffer( 0, buffer, size );
}

inline uint8_t SX1276ReadDio0( void )
{
    return HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_11);
}

inline uint8_t SX1276ReadDio1( void )
{
    return HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_10);
}

23.更改sx1276-Hal.h 下的#define GET_TICK_COUNT( ) ( TickCounter ) 替换为 HAL_GetTick()。

在这里插入图片描述

24.点击编译,如果错误为:0,就说明工程移植成功了。

在这里插入图片描述
以上就是LoRa官方固件移植的全部步骤。
接下来就可以进行LoRa点对点相关实验的进行了。

  • 4
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值