欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

LoRa 之一旧版驱动(sx12xxDrivers-V2.1.0)移植及驱动架构详解

程序员文章站 2022-06-16 17:00:23
  在之前的项目中,一直使用 LoRa 通信。很早之前就想写写文章记录一下学习过程。怎奈一直是一知半解的状态,想写不敢写!LoRa 这个东西在国内用的貌似不是太多。  对于无线通信,各个国家或者地区都有严格的限制。例如,我们国家就有<<*无线电频率划分规定>>。前两年,工信部出了个指导意见还是啥东西来着,差点把 LoRa 搞黄了!LoRa 是工作在免费频段的。关于免费频段各个国家或者地区是有区别的!我们国家的各种规定在工信部官网可以找到!废话不多说,想要了解 LoRa...

  在之前的项目中,一直使用 LoRa 通信。很早之前就想写写文章记录一下学习过程。怎奈一直是一知半解的状态,想写不敢写!LoRa 这个东西在国内用的貌似不是太多。
  对于无线通信,各个国家或者地区都有严格的限制。例如,我们国家就有<<*无线电频率划分规定>>。前两年,工信部出了个指导意见还是啥东西来着,差点把 LoRa 搞黄了!LoRa 是工作在免费频段的。关于免费频段各个国家或者地区是有区别的!我们国家的各种规定在工信部官网可以找到!废话不多说,想要了解 LoRa 是啥的自己去搜索,我们重点说用法!

LoRa 和 LoRaWAN

  在介绍使用之前,我们必须要先区分好这两个概念!LoRa 是低功耗广域网通信技术中的一种,而按照 LoRa 联盟官方白皮书《what is LoRaWAN》的介绍,LoRaWAN 是为 LoRa 远距离通信网络设计的一套通讯协议和系统架构。类比于我们的网络通信,LoRa 定了物理层,而 LoRaWAN 定义了 MAC 层、数据链路层。LoRaWAN 定义了一套通信系统的架构,底层使用的是 LoRa 通信。这个应该就和我们的网络协议栈差不多吧。
  在我们的实际使用中,我们可以仅仅使用 LoRa 进行最基本的通信,通信的应用层协议则有我们自己定义。当然,我们的通信只能和我们自己定义的应用层协议的设备通信。Semtech 出了好几款 LoRa 收发器芯片供我们选择。当然也可以按照 LoRaWAN 的要求来实现系统中的通信,这个就要复杂好多了,完整的 LoRaWAN 网络架构中包含了终端、网关、NS(网络服务器)、应用服务器这四个部分。

  当前有好多公司都出了各种各样的 LoRa 模块以及 LoRa 网关模块。我的环境是自己画的 LoRa 模块,使用了的芯片时 SX1276。我这里也不需要 LoRaWAN。

驱动

  首先,我们需要知道 Semtech 的 LORA 芯片支持 LORA 模式和 FSK 模式,所以驱动中是包含对这两种模式的处理的。目前,Semtech 官网有两款驱动,一款是旧的驱动,驱动内部只实现了对于 LoRa 芯片的基本操作,另一个款是最新的包含对 LoRa 芯片的基本操作和 LoRaWAN 定义的实现。老版驱动 Semtech 已经停止更新了,也不建议用在新的生成环境中。两种驱动对比如下图:
LoRa 之一旧版驱动(sx12xxDrivers-V2.1.0)移植及驱动架构详解
这里我们重点来介绍一下旧版的驱动。下面来具体说说移植!

驱动架构

驱动的架构并不复杂,如下图所示:
LoRa 之一旧版驱动(sx12xxDrivers-V2.1.0)移植及驱动架构详解
在初始化阶段,驱动内部首先将全部寄存器的值读取到 uint8_t SX1276Regs[0x70]; 中,而后所有接口的操作都是按照上面的图,先修改 uint8_t SX1276Regs[0x70]; 中的寄存器,然后在通过 SPI 将 uint8_t SX1276Regs[0x70]; 中的数据写入到芯片中。我们以 sx1276 为例来说明一下:

  • sx1276.h/c:该文件主要是以上两种模式(LORA、FSK)的统一的对外接口。通过 radio.h 中宏 LORA 是否为 1 区分以上两种模式。此外该文件中还定义了一个与芯片中寄存器一一对应的全局变量 uint8_t SX1276Regs[0x70];
  • sx1276-LoRaMisc.c/h:该文件主要是提供一些 LORA 参数的设置接口
  • sx1276-LoRa.c/h:该文件定义了 LORA 寄存器以及各种寄存器的具体数值、LORA 的初始化及配置,LORA 处理状态机。

下面是对各文件(夹)的一个简单的介绍:

 *          src
 *          │  main.c       这其中有个给出了使用方法(初始化、收发数据等),作为参考在自己的项目中使用。!!!知道如何测试后删除即可!!!
 *          ├─platform
 *          │  │  platform.h        在此文件中对驱动进行配置。!!!这个必须要保留!!!
 *          │  ├─bleeper            以下这些平台自己在移植时其实我们就需要其中的某个文件即可。所以所谓的平台对我自己的项目来说根本无用。
 *          │  ├─stm32libs          其他代码文件都是一些针对测试开发版的文件,我们不需要。
 *          │  ├─sx1200dvk          因为,我们自己的项目中必然有自己的实现。
 *          │  ├─sx1243ska          其实,最终我们就需要其中一个文件:xxx-Hal.c(根据自己的芯片类型)
 *          │  └─sx12xxEiger     <- 这里以它为例,我们只需要以下文件,其他平台(以上俩目录)的文件和该目录下类似。!!!都不需要使用,直接删除即可!!!
 *          │      │  sx1232-Hal.c
 *          │      │  sx1272-Hal.c
 *          │      │  sx1276-Hal.c   我们仅需要自己选择的芯片对应的硬件抽象层文件,根据自己的MCU修改里面的代码(各GPIO、函数中的SPI接口)即可。!! 函数名不能更改!!
 *          └─radio   这个是 LORA的驱动源码,针对每个不同信号芯片的不同调制模式都有独立文件。!!!必须根据自己的LoRa芯片选择对应文件。!!!
 *                  radio.c      对于不同LORA芯片的部分操作接口的封装。这两文件非常简单。
 *                  radio.h
 *                  !!-----这里省略其他文件,其他文件与以下文件类似。以sx1276来进行说明------!!
 *                  sx1276-Fsk.c     Fsk模式的源码文件,主要就是对Fsk模式下各寄存器的读写函数
 *                  sx1276-Fsk.h
 *                  sx1276-FskMisc.c  Fsk模式的参数配置函数
 *                  sx1276-FskMisc.h
 *                  sx1276-Hal.h    硬件抽象层对应的头文件,对应的.c文件在platform目录下,这俩文件主要就是初始化LORA使用的GPIO及SPI通信。函数在.h文件中以给出。只需要根据自己的平台实现.c文件即可。
 *                  sx1276-LoRa.c   LoRa 模式的源码文件,主要就是LORA模式下各寄存器的读写函数。注意:LoRa模式下可以读取Fsk模式的寄存器。
 *                  sx1276-LoRa.h
 *                  sx1276-LoRaMisc.c LoRa 模式的参数配置函数,用户可以直接使用该文件的中的函数对LoRa进行配置(例如频率、带款等等)。
 *                  sx1276-LoRaMisc.h
 *                  sx1276.c      主要是以上两种模式(LORA、FSK)的统一的对外接口。通过 radio.h 中宏 LORA 是否为 1 区分以上两种模式
 *                  sx1276.h

驱动文件整理

  移植的第一步就是整理源码文件。旧源代码在使用 Ride 7 作为 IDE(Ride 7 使用 gcc-arm 作为编译器)写出来的,所以在源码中有些 Ride 7 的文件。下面我们整理一下需要的驱动文件:
LoRa 之一旧版驱动(sx12xxDrivers-V2.1.0)移植及驱动架构详解

配置

移植的第二步就是修改驱动的配置项!

platform.h

  由于源码实际是一个 Ride 7 项目示例,同时针对多个测试平台(开发板)的,因此配置文件中有一些和测试平台相关的代码。我习惯于不再代码中残留一些无用的代码,所以该清理的清理。清理后如下:

/*!
 * Radio choice. Please uncomment the wanted radio and comment the others
 * or add/change wanted radio definition on the compiler Defines option
 * 这里其实就是选择使用的 LORA 芯片型号,我们使用的是 SX1278,其与SX1276基本一样。Semtech 给出的驱动源码中,SX1278 可以直接使用 SX1276 的驱动源码。
 * 后面也会看到,所有驱动文件的名字均为 SX1276 开头的文件名,却没有一个是 SX1278 开头的文件。具体原因也是这里所说的原因。
 * 但是,需要对源码进行一定的修改,具体修改见下面的说明!
 */
//#define USE_SX1232_RADIO
//#define USE_SX1272_RADIO
#define USE_SX1276_RADIO
//#define USE_SX1243_RADIO

/*!
 * Module choice. There are three existing module with the SX1276.
 * Please set the connected module to the value 1 and set the others to 0
 * 这个模块选择:这里主要是指Semtech官方给出的不同的外围电路设计用例。因为其给出的三种电路设计中,使用的芯片引脚等时有区别的。
 * 因此,这里需要根据硬件设计。来选择合适的模块。以下三种硬件电路设计用例,可直接在Semtech官网找到!
 * 以下几个宏值,仅在调用初始化时才会用到,具体可查看函数void SX1276LoRaInit( void );这里也需要注意:频率的问题,源码对于不同频率,
 * 其会选择不同的配置。
 */
#ifdef USE_SX1276_RADIO
#define MODULE_SX1276RF1IAS                         0
#define MODULE_SX1276RF1JAS                         0
#define MODULE_SX1276RF1KAS                         1
#endif

整理之后,就上面两个宏值是必须的!对于每个宏上面的注释已经很详细了,不再多说!

sx1276-Hal.c

  这个文件看名字就知道,负责实现驱动库与实际芯片的通信的封装。如果看源码中的示例文件,会发现其中也是很多和测试平台相关的配置。同样该清理的清理,最终该文件大体可以分为两大部分:

  1. 包含自己需要的头文件
    LoRa 之一旧版驱动(sx12xxDrivers-V2.1.0)移植及驱动架构详解
  2. 实现必须的函数接口。函数接口总的可以分为四大类:
    1. LORA 芯片使用 MCU 的 IO 的配置及复位。函数 void SX1276InitIo(void) 用来初始化使用的各 IO。函数 void SX1276SetReset( uint8_t state ) 用来复位模块。

    2. SPI 通信使用的接口。LORA 芯片是使用 SPI 进行通信的。

      • void SX1276Write( uint8_t addr, uint8_t data );
      • void SX1276Read(uint8_t addr, uint8_t *data)
      • void SX1276WriteBuffer(uint8_t addr, uint8_t *buffer, uint8_t size)
      • void SX1276ReadBuffer( uint8_t addr, uint8_t *buffer, uint8_t size )
      • void SX1276WriteFifo( uint8_t *buffer, uint8_t size )
      • void SX1276ReadFifo( uint8_t *buffer, uint8_t size )

      我们只需要根据自己的 SPI 的配置,修改 void SX1276ReadBuffer( uint8_t addr, uint8_t *buffer, uint8_t size )void SX1276WriteBuffer(uint8_t addr, uint8_t *buffer, uint8_t size) 即可,其他几个接口都是直接调用上面这俩接口的!不知道为啥驱动库要放出这么多函数。

    3. LORA 芯片 独立 IO 的配置。LORA 芯片有几个 IO 是需要直接和 MCU 相连的,这些 IO 的高低状态指示了 LORA 芯片的一些工作状态。

      • inline uint8_t SX1276ReadDio0( void )
      • inline uint8_t SX1276ReadDio1( void )
      • inline uint8_t SX1276ReadDio2( void )
      • inline uint8_t SX1276ReadDio3( void )
      • inline uint8_t SX1276ReadDio4( void )
      • inline uint8_t SX1276ReadDio5( void )

      需要注意的是,根据我们的需求,以上 5 个 IO 并不一定全部使用。例如我的就只使用 DIO0、DIO1、DIO3。至于如果选择,在手册中有说明这 5 个 IO 的说明。

    4. 天线切换接口。inline void SX1276WriteRxTx( uint8_t txEnable )。在 Semtech 给出的设计原理图中,是需要进行天线状态的切换的!如果是买的其他厂家的现成的模块,可能不需要该函数,留空即可!

sx1276-Hal.h

  还是由于驱动测试遗留的问题,我们必须要修改该文件中的部分代码。清理一些测试过程中引入的文件,同时定义一个函数函数。具体如下:
LoRa 之一旧版驱动(sx12xxDrivers-V2.1.0)移植及驱动架构详解
这个文件如果设计的足够好的话,是不需要用户来更改的!

至此,LORA 的驱动移植完成了,接下来就是在自己的开发环境中添加使用的文件、头文件路径,然后编译即可!

使用

  驱动库通过 radio.h/c 对驱动库的接口进行了封装。正常的初始化、收发数据等都是使用 tRadioDriver 中的函数指针。当然,该结构体仅仅是封装了部分接口。有些功能接口我们还是需要直接使用对应驱动库头文件中的函数。

  1. 首先调用初始化驱动库
    LoRa 之一旧版驱动(sx12xxDrivers-V2.1.0)移植及驱动架构详解
  2. 周期调用 Radio->Process() 以处理驱动库的状态机
    LoRa 之一旧版驱动(sx12xxDrivers-V2.1.0)移植及驱动架构详解
  3. 收发数据 Radio->GetRxPacket( const void *buffer, uint16_t size );Radio->SetTxPacket( const void *buffer, uint16_t size );

注意

  1. 只有 LORA 参数都一致的情况下,两者才能通信!
  2. 默然情况下,LORA 驱动内部是开启了低速率优化的。
    LoRa 之一旧版驱动(sx12xxDrivers-V2.1.0)移植及驱动架构详解

参考

本文地址:https://blog.csdn.net/ZCShouCSDN/article/details/110183620