移植前先唠嗑唠嗑:
在网上买了几块LORA-B1的开发板,开发板的LORA芯片用的是SX1278,微控制器是STM32F030F4P6,我这人底子薄没怎么用过STM32也没用过LORA,就玩过ZigBee用过IAR,所以就一边百度一边学STM32CubeMX和Keil5 MDK的基本使用。点了点灯再跑下例程的按钮点灯,不亦乐乎。
然后到移植LORA驱动这里时,犯难了,碰到了很多问题,虽然有现成移植好LORA驱动的例程,但我就是想自己试一试。店家给的教程对我这种菜鸡太不友好了,我脑抽没看懂,问到店家都怕了我吧?(学习的过程中脸皮一定要厚,嗯嗯~)鼓捣一两天终于弄出来了,还做了个笔记跟大家分享一下。这教程应该是非常适合像我这样一脸懵逼一无所知的小白了。
附上参考教程链接:
http://www.eemaker.com/lora-b1-qudongyizhi.html
下面就是我用的LORA-B1开发板:
(我这算是帮别人打广告吗?不过这篇文章估计看的人也不多)
1.DIO0-DIO3为lora模块的输出引脚,连接的单片机引脚需要对应配置为输入模式进行检测。
2.SPI_MOSI、SPI_MISO、SPI_SCK、CS脚为lora模块和stm32之间的spi接口引脚。
3.L_RST是lora模块的复位引脚,对应stm32的IO口要配置为输出模式。
①DIO0-DIO3为GPIO_INPUT模式
②SPI1_CS和LRST配置为GPIO_OUTPUT模式(注意CS脚这里是作为普通输出)
③SPI1_MOSI、SPI1_MISO、SPI1_CLK为标准SPI接口。
④然后再对相应管脚进行命名和SPI管脚设置:展开System Core,双击GPIO,在User Label处改标签名(注意:PB1管脚标签改为LRST,不是L_RST)
⑤展开Connectivity,点击SPI1,选择Full-Duplex Master模式(全双工主机),在Parameter Settings里将Data Size设为8 Bits,Prescaler(for Baud Rate)设为4,(注:灰色部分的Baud Rate与设置的Prescaler(for Baud Rate)和STM32的主时钟频率有关,下一步设置STM32的主时钟频率)其他参数默认不变,如图所示:
先关闭工程,下一步是代码移植。
解压后在src下找到并复制platform和radio文件夹
在自动生成的工程下,新建一个命名为lora的文件夹,在lora下黏贴platform和radio文件夹
(添加的.c文件是分别从工程下的lora文件夹下复制黏贴过来的platform和radio文件夹下选取的。)
添加文件后的工程视图如下:
①删除\lora\platform\sx12xxEiger\spi.c和spi.h文件(该文件没用,但是名称和cubemx生成的spi初始化文件名相同会造成后面编译失败)。
②打开platform.h文件,再打开宏定义#define PLATFORM SX12xxEiger(默认这条宏定义是被注释掉的,所以我们要打开它,这里我用的是Source Insight4.0打开的platform.h文件,用其他软件打开也可以,看个人习惯。更改后记得保存)
③打开sx12xxEiger.c文件,屏蔽或删除掉该文件内所有函数。(我这里就是用Keil5 MDK打开的sx12xxEiger.c文件,然后Ctrl+A全选,右键Advanced选择Comment Selection注释)
④打开sx12xxEiger.h文件,修改#include “stm32f10x.h” 为 #include “stm32f0xx_hal.h”
⑤修改sx1276-Hal.h中#define GET_TICK_COUNT( ) HAL_GetTick()
⑥接下来的错误都集中在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
#include
#include "main.h"
#include "spi.h"
#include "gpio.h"
#include "platform.h"
#include "../../radio/sx1276-Hal.h"
uint8_t SpiInOut( uint8_t outData )
{
uint8_t Rxdata;
HAL_SPI_TransmitReceive(&hspi1,&outData,&Rxdata,1, 1000);
return Rxdata;
}
void SX1276InitIo( void )
{
}
void SX1276SetReset( uint8_t state )
{
if(state==RADIO_RESET_ON)
{
HAL_GPIO_WritePin(LRST_GPIO_Port,LRST_Pin,GPIO_PIN_RESET);
}
else
{
HAL_GPIO_WritePin(LRST_GPIO_Port,LRST_Pin,GPIO_PIN_SET);
}
}
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 )
{
HAL_GPIO_WritePin(SPI1_CS_GPIO_Port,SPI1_CS_Pin,GPIO_PIN_RESET);
SpiInOut( addr | 0x80 );
for(uint8_t i = 0; i < size; i++ )
{
SpiInOut( buffer[i] );
}
HAL_GPIO_WritePin(SPI1_CS_GPIO_Port,SPI1_CS_Pin,GPIO_PIN_SET);
}
void SX1276ReadBuffer( uint8_t addr, uint8_t *buffer, uint8_t size )
{
HAL_GPIO_WritePin(SPI1_CS_GPIO_Port,SPI1_CS_Pin,GPIO_PIN_RESET);
SpiInOut( addr & 0x7F );
for(uint8_t i = 0; i < size; i++ )
{
buffer[i] = SpiInOut( 0 );
}
HAL_GPIO_WritePin(SPI1_CS_GPIO_Port,SPI1_CS_Pin,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(DIO0_GPIO_Port,DIO0_Pin);
}
inline uint8_t SX1276ReadDio1( void )
{
return HAL_GPIO_ReadPin(DIO1_GPIO_Port,DIO1_Pin);
}
inline uint8_t SX1276ReadDio2( void )
{
return 0;
}
inline uint8_t SX1276ReadDio3( void )
{
return HAL_GPIO_ReadPin(DIO3_GPIO_Port,DIO3_Pin);
}
inline uint8_t SX1276ReadDio4( void )
{
return 1;
}
inline uint8_t SX1276ReadDio5( void )
{
return 1;
}
inline void SX1276WriteRxTx( uint8_t txEnable )
{
}
⑦编译,MDK的编译会强制每个.c或.h文件最后都要空一行,根据提示把警告的文件后面回车多添加一行新行。
以上添加新行后编译,如果还存在错误,就把上面七步再重新检查一遍,看看有没有文件漏添新行,或者更改宏定义或者其他代码时是否有非法输入字符。例如我上个截图中除了需要添加新行外,就还有其他错误。经过逐步检查发现在第⑤步修改sx1276-Hal.h中#define GET_TICK_COUNT( ) HAL_GetTick() 时有中文输入法的字符出现,更改之后再保存,编译,就没事啦。
到此,官方LORA驱动的移植就完成啦~
之后我们就可以基于lora的驱动编写自己的应用代码了。