一、Lora模块SX1278
LoRa(Long Range)是一种长距离、低功耗的无线通信技术,专为物联网(IoT)和远程传感应用而设计。LoRa技术基于半双工调制方式,通过扩频和前向纠错编码来提供可靠的通信连接。本文记录如何使用STM32F030来调安信可SX1278模块。
安信可SX1278模块:Ra-01 或Ra-02。
二、STM32F030代码
1.GPIO初始化
Lora使用SPI通信,本次使用硬件SPI。
#include "hal_spi.h"
static void hal_SpiConfig(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
SPI_InitTypeDef SPI_InitStruct;
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA | RCC_AHBPeriph_GPIOB, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource5, GPIO_AF_0);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource6, GPIO_AF_0);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource7, GPIO_AF_0);
// SPI1 GPIO Configuration (PA5 -> SCK, PA6 -> MISO, PA7 -> MOSI)
//SPI1复用功能
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_DOWN;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStruct.GPIO_Pin = SCK_PIN | MISO_PIN | MOSI_PIN;
GPIO_Init(GPIOA, &GPIO_InitStruct);
//片选 PA4 ->CS
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStruct.GPIO_Pin = CS_PIN;
GPIO_Init(CS_PORT, &GPIO_InitStruct);
GPIO_ResetBits(CS_PORT,CS_PIN);
// 复位脚PB0 ->RST
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStruct.GPIO_Pin = RF_RST_PIN;
GPIO_ResetBits(RF_RST_PORT,RF_RST_PIN);
delay_ms(1);
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN;
GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(RF_RST_PORT, &GPIO_InitStruct);
delay_ms(6);
//DIO0 下拉输入
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN;
GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_DOWN;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStruct.GPIO_Pin = RF_IRQ_DIO0_PIN;
GPIO_Init(RF_IRQ_DIO0_PORT, &GPIO_InitStruct);
SPI_I2S_DeInit(SPI1); //将寄存器重设为缺省值
SPI_InitStruct.SPI_Direction = SPI_Direction_2Lines_FullDuplex;//设置SPI单向或者双向的数据模式:SPI设置为双线双向全双工
SPI_InitStruct.SPI_Mode = SPI_Mode_Master;//设置SPI工作模式:设置为主SPI
SPI_InitStruct.SPI_DataSize = SPI_DataSize_8b;//设置SPI的数据大小:SPI发送接收8位帧结构
SPI_InitStruct.SPI_CPOL = SPI_CPOL_Low;//设置时钟极性(串行同步时钟的空闲状态为高电平还是低电平)
SPI_InitStruct.SPI_CPHA = SPI_CPHA_1Edge;//设置相位(串行同步时钟的第几个跳变沿(上升或下降)数据被采样)
SPI_InitStruct.SPI_NSS = SPI_NSS_Soft;//NSS信号由硬件(NSS管脚)还是软件(使用SSI位)管理:设置为软件控制(SSI控制)
SPI_InitStruct.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_64;//定义波特率预分频的值:波特率预分频值为256(256是最低,可以设置完成之后调整速度,如果速度过快导致通信失败再调小)
SPI_InitStruct.SPI_FirstBit = SPI_FirstBit_MSB;//指定数据传输从MSB位还是LSB位开始:数据传输从MSB位开始
SPI_InitStruct.SPI_CRCPolynomial = 7;//CRC值计算的多项式(CRC校验相关)
SPI_Init(SPI1, &SPI_InitStruct);//根据SPI_InitStruct中指定的参数初始化外设SPIx寄存器
SPI_RxFIFOThresholdConfig(SPI1, SPI_RxFIFOThreshold_QF);//配置接收FIFO触发阈值
SPI_Cmd(SPI1, ENABLE);
}
2.SPI通信字节读写和寄存器读写
注:STM32F030和STM32F103接收字节函数不同
#include "hal_spi.h"
//SPIx 读写一个字节
//TxData:要写入的字节
//返回值:读取到的字节
unsigned char SPI1_ReadWriteByte(unsigned char Data)
{
unsigned char retry=0;
while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET) //等待发送区空
{
retry++;
if(retry>200)return 0;
}
SPI_SendData8(SPI1,Data);
retry=0;
while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET) //等待接收完一个 byte
{
retry++;
if(retry>200)return 0;
}
return (SPI_ReceiveData8(SPI1)); //返回通过 SPIx 最近接收的数据
}
//功能:SX1276 寄存器写
void SX1276WriteBuffer( unsigned char addr, unsigned char *buffer, unsigned char size )
{
unsigned char i;
//NSS = 0;
CS_LOW;
SPI1_ReadWriteByte( addr | 0x80 );
for( i = 0; i < size; i++ )
{
SPI1_ReadWriteByte( buffer[i] );
}
CS_HIGH;
}
//功能: SX1278 单个寄存器写搓澡
void SX1276WriteReg( unsigned char addr, unsigned char dat)
{
CS_LOW;
SPI1_ReadWriteByte( addr | 0x80 );
SPI1_ReadWriteByte( dat);
CS_HIGH;
}
//功能:SX1276 寄存器读
void SX1276ReadBuffer( unsigned char addr, unsigned char *buffer, unsigned char size )
{
uint8_t i;
CS_LOW;
SPI1_ReadWriteByte( addr & 0x7F );
for( i = 0; i < size; i++ )
{
buffer[i] = SPI1_ReadWriteByte( 0 );
}
CS_HIGH;
}
//功能: SX1278 单个寄存器读搓澡
unsigned char SX1276ReadReg(unsigned char addr)
{
unsigned char dat;
CS_LOW;
SPI1_ReadWriteByte( addr & 0x7F );
dat = SPI1_ReadWriteByte(0);
CS_HIGH;
return dat;
}
hal_spi.h
#define RF_RST_PORT GPIOB
#define RF_RST_PIN GPIO_Pin_0
#define RF_RST_HIGH GPIO_SetBits(RF_RST_PORT,RF_RST_PIN)
#define RF_RST_LOW GPIO_ResetBits(RF_RST_PORT,RF_RST_PIN)
//输入
#define MISO_PORT GPIOA
#define MISO_PIN GPIO_Pin_6
#define MISO_DATABIT GPIO_ReadInputDataBit(MISO_PORT,MISO_PIN)
//输出
#define MOSI_PORT GPIOA
#define MOSI_PIN GPIO_Pin_7
#define MOSI_HIGH GPIO_SetBits(MOSI_PORT,MOSI_PIN)
#define MOSI_LOW GPIO_ResetBits(MOSI_PORT,MOSI_PIN)
#define SCK_PORT GPIOA
#define SCK_PIN GPIO_Pin_5
#define SCK_HIGH GPIO_SetBits(SCK_PORT,SCK_PIN)
#define SCK_LOW GPIO_ResetBits(SCK_PORT,SCK_PIN)
//CS
#define CS_PORT GPIOA
#define CS_PIN GPIO_Pin_4
#define CS_HIGH GPIO_SetBits(CS_PORT,CS_PIN)
#define CS_LOW GPIO_ResetBits(CS_PORT,CS_PIN)
//输入
#define RF_IRQ_DIO0_PORT GPIOB
#define RF_IRQ_DIO0_PIN GPIO_Pin_1
#define RF_IRQ_DIO0_DATABIT GPIO_ReadInputDataBit(RF_IRQ_DIO0_PORT,RF_IRQ_DIO0_PIN)
3.SX1278初始化配置
3.1 寄存器定义和描述
"sx1278.h"
#define LR_RegFifo 0x00 //FIFO读写访问,当器件处于睡眠模式时,FIFO被清零,无法访问
// Common settings
#define LR_RegOpMode 0x01 //运行模式 Lora和FSK选择
#define LR_RegFrMsb 0x06 //RF载波频率最高有效位
#define LR_RegFrMid 0x07 //RF载波频率中间有效位
#define LR_RegFrLsb 0x08 //RF载波频率最低有效位 若F(XOSC)=32MHz,则分辨率为61.035Hz。
// Tx settings 发送设置
#define LR_RegPaConfig 0x09 //PA选择和输出功率控制
#define LR_RegPaRamp 0x0A //PA斜升/斜将时间和低相噪PLL的控制
#define LR_RegOcp 0x0B //过流保护控制
// Rx settings 接收设置
#define LR_RegLna 0x0C //LNA设置
// LoRa registers
#define LR_RegFifoAddrPtr 0x0D //FIFO数据缓冲区中SPI接口地址指针
#define LR_RegFifoTxBaseAddr 0x0E //FIFO数据缓冲区发送调制器的写入基地址
#define LR_RegFifoRxBaseAddr 0x0F //FIFO数据缓冲区接收调制器的读取基地址
#define LR_RegFifoRxCurrentaddr 0x10 //接收到最后一个数据包的起始地址
#define LR_RegIrqFlagsMask 0x11 //可选中断标志屏蔽
#define LR_RegIrqFlags 0x12 //中断标志
#define LR_RegRxNbBytes 0x13 //最后一次接收到的数据包的负载字节数
#define LR_RegRxHeaderCntValueMsb 0x14 //最后一次转换至Rx模式后接收的有效报头数(高位有效)
#define LR_RegRxHeaderCntValueLsb 0x15 //最后一次转换至Rx模式后接收的有效报头数(低位有效)
#define LR_RegRxPacketCntValueMsb 0x16 //最后一次转换至Rx模式后接收的有效数据包数(高位有效)
#define LR_RegRxPacketCntValueLsb 0x17 //最后一次转换至Rx模式后接收的有效数据包数(低位有效)
#define LR_RegModemStat 0x18 //LoRa调制解调器现场状态
#define LR_RegPktSnrValue 0x19 //最后接收到的数据包的SNR(信噪比)预估值
#define LR_RegPktRssiValue 0x1A //最后接收到的数据包的RSSI(dBm) RSSI[dBm]=-137+PacketRssi
#define LR_RegRssiValue 0x1B //电流RSSI值(dBm)RSSI[dBm]=-137+Rssi
#define LR_RegHopChannel 0x1C //FHSS起始信道
#define LR_RegModemConfig1 0x1D //调制解调器物理层配置1:7-4位信号带宽(0x07默认125kHz) 3-1位纠错编码率(默认001->4/5) 0位报头模式(0 0->显式报头模式 )
#define LR_RegModemConfig2 0x1E //调制解调器物理层配置2:7-4位SF值(以 2 基对数表示 默认0x07->128 码片/符号 ) 3位(0正常模式发送单个数据包 1持续模式通过FIFO发送多个数据包(用于频谱分析)) 2位发送端CRC信息(0关闭CRC 1开启CRC) 1-0位RX超时最高有效位
#define LR_RegSymbTimeoutLsb 0x1F //接收机超时值,RX超时最低有效位RX操作超时值以符号数表示:TimeOut=SymbTimeout-Ts
#define LR_RegPreambleMsb 0x20 //前导码长度(最高位)=PreambleLength+4.25 符号
#define LR_RegPreambleLsb 0x21 //前导码长度(最低位)
#define LR_RegPayloadLength 0x22 //LoRa负载长度:隐式报头模式下 需要设置寄存器,以达到预期的 数据包长度。不允许将寄存器值 设置为 0。
#define LR_RegMaxPayloadLength 0x23 //LoRa负载长度最大值:如果报头负载 长度超过该最大值,则会产生报 头 CRC 错误。允许对长度不正 确的数据包进行过滤。
#define LR_RegHopPeriod 0x24 //FHSS跳频周期:(0= 关闭)。第一跳总是发生在第一个 报头符号后
#define LR_RegFifoRxByteAddr 0x25 //FIFO中最后写入字节的地址,接收数据缓存当前指针(由 Lora 接收机写入的最后一个字节的地址)
#define LR_RegModemConfig3 0x26 //调制解调器物理层配置3
#define LR_RegPacketConfig2 0x31 //RESERVED
#define LR_RegSeqConfig2 0x37 //RESERVED
#define REG_LR_DIOMAPPING1 0x40 //DIO0到DIO3引脚映射
#define REG_LR_DIOMAPPING2 0x41 //DIO4到DIO5引脚映射、ClkOut频率
// Version
#define REG_LR_VERSION 0x42 //芯片版本
// Additional settings
#define REG_LR_PLLHOP 0x44 //unused
#define REG_LR_TCXO 0x4B //TCXO或XTAL输入设置
#define REG_LR_PADAC 0x4D //PA更大功率设置 输出20dBm
#define REG_LR_FORMERTEMP 0x5B //IQ校准期间存储温度
#define REG_LR_BITRATEFRAC 0x5D
#define REG_LR_AGCREF 0x61 //AGC阈值调整
#define REG_LR_AGCTHRESH1 0x62 //AGC阈值调整
#define REG_LR_AGCTHRESH2 0x63 //AGC阈值调整
#define REG_LR_AGCTHRESH3 0x64 //AGC阈值调整
#define REG_LR_PLL 0x70 //PLL带宽控制
3.2 SX1278参数列表
SX1278参数有:工作模式、发射功率、扩频因子、工作频率、信号带宽和编码率
使用枚举列出所有的情况。
"sx1278.h"
//工作模式
typedef enum
{
WORKMODE_NOMAL, ///普通工作模式
WORKMODE_LOW, //低功耗模式
}en_workmode;
//发射功率
typedef enum
{
LORAPOWER_2DBM = 2,
LORAPOWER_3DBM,
LORAPOWER_4DBM,
LORAPOWER_5DBM,
LORAPOWER_6DBM,
LORAPOWER_7DBM,
LORAPOWER_8DBM,
LORAPOWER_9DBM,
LORAPOWER_10DBM,
LORAPOWER_11DBM,
LORAPOWER_12DBM,
LORAPOWER_13DBM,
LORAPOWER_14DBM,
LORAPOWER_15DBM,
LORAPOWER_16DBM,
LORAPOWER_17DBM,
LORAPOWER_20DBM = 20,
}en_LoraPower;
//扩频因子
typedef enum
{
LORASF_6 = 6,
LORASF_7,
LORASF_8,
LORASF_9,
LORASF_10,
LORASF_11,
LORASF_12,
}en_LoraSf;
//工作频率
typedef union
{
unsigned long fredat;
unsigned char Fre[4];
}un_lorafre;
//信号带宽
typedef enum
{
LORA_RATE_7_8KHZ,
LORA_RATE_10_4KHZ,
LORA_RATE_15_6KHZ,
LORA_RATE_20_8KHZ,
LORA_RATE_31_25KHZ,
LORA_RATE_41_7KHZ,
LORA_RATE_62_5KHZ,
LORA_RATE_125KHZ,
LORA_RATE_250KHZ,
LORA_RATE_500KHZ,
}en_LoraRate;
//编码率
typedef enum
{
LORA_CR_4_5 = 1,
LORA_CR_4_6,
LORA_CR_4_7,
LORA_CR_4_8,
}en_LoraCr;
//所有参数结构体
typedef struct comdat
{
en_workmode workmode;
en_LoraPower loraPower;
en_LoraSf loraSf;
en_LoraRate loraRate;
en_LoraCr loraCr;
un_lorafre loraFre;
}Str_LoraVari;
3.3 SX1278参数和寄存器配置
sx1278代码移植说明:
第一步:sx1278的初始化
1.完成SX1278芯片和单片机之间的SPI通讯。完成SPI的读写操作
2.配置SX1278芯片的D0对应的单片机接口为输入模式(非中断)打开D0 IO 对应的外部中断打开
(特别说明:LORA无线接收到数据 D0 口有上升沿)
3.上电调用函数hal_sx1278_Rest 完成SX1278芯片的复位
4.配置发送和接收D0 口配置函数
第二步:无线发射功能:
1.配置sx1278芯片的D0 端口为输入模式,没有中断;
2.调用void hal_Sx1278_LoRaSentBuffer(unsigned char *dat,unsigned char len)函数 完成数据的发送
(特别说明:LORA无线数据发送完成后 D0口有上升沿输出)
第三步:无线接收功能
1.上电完成SPI的驱动后,需要将SX1278芯片配置成 接收模式:void hal_SX1278_LoRaRxConfig(Str_LoraVari loraPara)
2.在D0端口外部中断函数中添加串口接收数据处理函数void hal_Sx1278RxDateGete(void)
3.void hal_Sx1278RxDateGete(void)函数中添加接收到的数据处理代码。
①SX1278参数初始化
Str_LoraVari loraRegPara;
//SX1278参数初始化
void hal_sx1278Init(void)
{
loraRegPara.workmode = WORKMODE_NOMAL;
loraRegPara.loraPower = LORAPOWER_13DBM;
loraRegPara.loraFre.fredat = 433000;
loraRegPara.loraSf = LORASF_7;
loraRegPara.loraRate = LORA_RATE_250KHZ;
loraRegPara.loraCr = LORA_CR_4_5;
hal_SX1278_LoRaRxConfig(loraRegPara);
}
②Lora接收和发射模式配置
void hal_SX1278_LoRaRxConfig(Str_LoraVari loraPara)
{
uint8_t addr;
hal_sx1278_Config(loraPara);
SX1276WriteReg(LR_RegHopPeriod,0);//SPIWrite(LR_RegHopPeriod+0xFF);
SX1276WriteReg(REG_LR_DIOMAPPING1,0x00);// SPIWrite(REG_LR_DIOMAPPING1+0x01); 1011
SX1276WriteReg(LR_RegIrqFlagsMask,0xBF); //SPIWrite(LR_RegIrqFlagsMask+0x3F); //Open RxDone interrupt & Timeout
SX1276WriteReg(LR_RegIrqFlags,0xFF);中断清0 SX1276_LoRaClearIrq();
addr = SX1276ReadReg(LR_RegFifoRxBaseAddr); Read RxBaseAddr
SX1276WriteReg(LR_RegFifoAddrPtr,addr); ///RxBaseAddr -> FiFoAddrPtr
SX1276WriteReg(LR_RegOpMode,0x8D); //Continuous Rx Mode
hal_Sx1278_RxGpioConfig();
}
static void hal_Sx1278_LoRaEntryTxConfig(Str_LoraVari loraPara)
{
uint8_t addr;
hal_sx1278_Config(loraPara); //
SX1276WriteReg(LR_RegHopPeriod,0x00); //
SX1276WriteReg(REG_LR_DIOMAPPING1,0x41); //DIO0=01, DIO1=00, DIO2=00, DIO3=01
SX1276WriteReg(LR_RegIrqFlags,0xFF); // 清除中断标志位 SX1276_LoRaClearIrq();
SX1276WriteReg(LR_RegIrqFlagsMask,0xF7); //Open TxDone interrupt
addr = SX1276ReadReg(LR_RegFifoTxBaseAddr); //RegFiFoTxBaseAddr
SX1276WriteReg(LR_RegFifoAddrPtr,addr);
}
③SX1278寄存器参数配置
static void hal_sx1278_Config(Str_LoraVari loraPara)
{
uint8_t temp;
hal_sx1278_Rest();///sx1278 系统复位
SX1276WriteReg(LR_RegOpMode,0x00); ///进入休眠模式
hal_sx1278_delay(1);
SX1276WriteReg(REG_LR_TCXO,0x09); //0x4b 0x09 XTAL带外部晶体的晶体振荡器
SX1276WriteReg(LR_RegOpMode,0x88); ///配置成Lora模式
频率配置
hal_sx1278_SentFreConfig(loraPara.loraFre.fredat);
///输出功率的配置
hal_sx1278_SentPowerConfig(loraPara.loraPower);
SX1276WriteReg(LR_RegOcp,0x0B); ///发送设置 过流保护控制 OCP 电流微调 100MA
SX1276WriteReg(LR_RegLna,0x23); ///接收设置 LNA 设置 7-5最大增益001 4-3LNA电流00 1-0高频RFI_HF 11
// Sx1278_SpreadFat = loraPara.CommodeVar.loraSf;
if(loraPara.loraSf==6) //SFactor=6
{
SX1276WriteReg(LR_RegModemConfig1,((loraPara.loraRate<<4)+(loraPara.loraCr<<1)+0x01));//Implicit Enable CRC Enable(0x02) & Error Coding rate 4/5(0x01), 4/6(0x02), 4/7(0x03), 4/8(0x04)
SX1276WriteReg(LR_RegModemConfig2,((loraPara.loraSf<<4)+(Sx1278_CRC<<2)+0x03));
temp = SX1276ReadReg(LR_RegPacketConfig2);
temp &= 0xF8;
temp |= 0x05; ///b101
SX1276WriteReg(LR_RegPacketConfig2,temp);
SX1276WriteReg(LR_RegSeqConfig2,0x0C);
}
else
{
SX1276WriteReg(LR_RegModemConfig1,((loraPara.loraRate<<4)+(loraPara.loraCr<<1)+0x00));//Explicit Enable CRC Enable(0x02) & Error Coding rate 4/5(0x01), 4/6(0x02), 4/7(0x03), 4/8(0x04)
SX1276WriteReg(LR_RegModemConfig2,((loraPara.loraSf<<4)+(Sx1278_CRC<<2)+0x03)); //SFactor & LNA gain set by the internal AGC loop
SX1276WriteReg(LR_RegModemConfig3,0x08);//LowDataRateOptimize en
}
SX1276WriteReg(LR_RegSymbTimeoutLsb,0xFF); //
SX1276WriteReg(LR_RegPreambleMsb, 0); //
SX1276WriteReg(LR_RegPreambleLsb,16); //
///11 00 01 10 11
SX1276WriteReg(REG_LR_DIOMAPPING2,0x01); //RegDioMapping2
SX1276WriteReg(LR_RegOpMode,0x09); //Entry standby mode 待机模式
}
④Lora接收和发送中断引脚配置
static void hal_Sx1278_RxGpioConfig(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
EXTI_InitTypeDef EXTI_InitStruct; //外部中断定义
NVIC_InitTypeDef NVIC_InitStruct; //嵌套中断定义
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN;
GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_DOWN;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStruct.GPIO_Pin = RF_IRQ_DIO0_PIN;
GPIO_Init(RF_IRQ_DIO0_PORT, &GPIO_InitStruct);
SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOB, EXTI_PinSource1);
EXTI->IMR |= EXTI_Line1;
EXTI_InitStruct.EXTI_Line = EXTI_Line1;
EXTI_InitStruct.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStruct.EXTI_Trigger = EXTI_Trigger_Rising;//上升沿触发
EXTI_InitStruct.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStruct);
NVIC_InitStruct.NVIC_IRQChannel=EXTI0_1_IRQn;
NVIC_InitStruct.NVIC_IRQChannelPriority=0x01;
NVIC_InitStruct.NVIC_IRQChannelCmd=ENABLE;
NVIC_Init(&NVIC_InitStruct);
}
static void hal_Sx1278TxGpioConfig(void)
{
//D0 设置为上拉输入
GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN;
GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_DOWN;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStruct.GPIO_Pin = RF_IRQ_DIO0_PIN;
GPIO_Init(RF_IRQ_DIO0_PORT, &GPIO_InitStruct);
EXTI->IMR &= ~(EXTI_Line1);//关闭中断
}
⑤ 芯片复位函数、无线发射功率配置和工作频率配置
static void hal_sx1278_Rest(void)
{
RF_RST_LOW;
hal_sx1278_delay(1);
RF_RST_HIGH;
hal_sx1278_delay(7);
}
void hal_sx1278_SentPowerConfig(unsigned char Power)
{
if(Power == 20)
{
SX1276WriteReg(REG_LR_PADAC,0x87); // 配置高功率寄存器
SX1276WriteReg(LR_RegPaConfig,0xFF); /// 20dbm
}
else if((Power > 1)&&(Power < 18))
{
SX1276WriteReg(REG_LR_PADAC,0x84); //
SX1276WriteReg(LR_RegPaConfig,(0xF0 + Power - 2)); /// 11dbm
}
}
typedef union
{
uint32_t fredat;
uint8_t Fre[4];
}un_sx1278Fre;
void hal_sx1278_SentFreConfig(uint32_t fre) ///470000000
{
double fredat;
static un_sx1278Fre sx1278Fre;
fredat = fre/0.06103515625L;
sx1278Fre.fredat = (uint32_t)fredat;
SX1276WriteReg(LR_RegFrMsb,sx1278Fre.Fre[2]); ///
SX1276WriteReg(LR_RegFrMid,sx1278Fre.Fre[1]); ///
SX1276WriteReg(LR_RegFrLsb,sx1278Fre.Fre[0]); ///
}
⑥无线数据发射功能函数
void hal_Sx1278_LoRaSentBuffer(unsigned char *dat,unsigned char len)
{
hal_Sx1278TxGpioConfig();
hal_Sx1278_LoRaEntryTxConfig(loraRegPara);
hal_sx1278_delay(1);
SX1276WriteReg(LR_RegPayloadLength,len);
SX1276WriteBuffer(0,dat,len);
SX1276WriteReg(LR_RegOpMode,0x8b);
while(!(RF_IRQ_DIO0_DATABIT));
hal_sx1278_delay(1);
hal_SX1278_LoRaRxConfig(loraRegPara);
}
⑦无线数据接收中断处理函数
sx1278.h
typedef void (*LoraDateRx)(unsigned char *pBuff,unsigned char len);
sx1278.c
LoraDateRx LoraDateRxCBS;//回调函数
void hal_sx1278_DataRxRegister(LoraDateRx pCBS)
{
if(LoraDateRxCBS == 0)
{
LoraDateRxCBS = pCBS;
}
}
void hal_Sx1278RxDateGete(void)
{
uint8_t addr,packet_size;
uint8_t lorarxbuf[256];
addr = SX1276ReadReg(LR_RegFifoRxCurrentaddr); /// addr = SPIRead((u8)(LR_RegFifoRxCurrentaddr>>8));//last packet addr 数据包的最后地址(数据的尾地址)
SX1276WriteReg(LR_RegFifoAddrPtr,addr); //SPIWrite(LR_RegFifoAddrPtr+addr);//RxBaseAddr -> FiFoAddrPtr
if(loraRegPara.loraSf == 6)//When SpreadFactor is six,will used Implicit Header mode(Excluding internal packet length)
{
packet_size=21; ///
}
else
{
packet_size = SX1276ReadReg(LR_RegRxNbBytes); SPIRead((u8)(LR_RegRxNbBytes>>8));//Number for received bytes
}
SX1276ReadBuffer(0x00,&lorarxbuf[0],packet_size);
if(LoraDateRxCBS)
{
LoraDateRxCBS(&lorarxbuf[0],packet_size);
}
SX1276WriteReg(LR_RegIrqFlags,0xFF);
}
void EXTI0_1_IRQHandler(void)
{
if(EXTI_GetITStatus(EXTI_Line1)!=RESET)
{
hal_Sx1278RxDateGete();//中断处理
}
//退出中断时注意清除标志位
EXTI_ClearFlag(EXTI_Line1);
}
至此,Lora模块所有配置均已完成。