STM32F030 Lora射频模块SX1278学习过程

 一、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模块所有配置均已完成。

  • 8
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
STM32F030是意法半导体(STMicroelectronics)公司推出的一款32位嵌入式微控制器,具有低功耗和高性能的特点。而LoRa是一种远程无线通信技术,是低功耗广域网(LPWAN)中的一种重要技术标准。 STM32F030 LoRa是指在STM32F030系列微控制器上集成了LoRa通信模块的设计方案。这个设计方案将STM32F030的处理能力和低功耗特点与LoRa技术相结合,使得在物联网等应用场景中的无线通信更加方便和可靠。 STM32F030 LoRa方案的优势体现在以下几个方面: 1. 高性能:STM32F030系列微控制器具有高性能和低功耗的特点,可以提供快速且高效的数据处理能力,满足实时应用的需求。 2. 低功耗:LoRa技术本身就是一种低功耗通信技术,结合STM32F030的低功耗特点,可以延长设备的续航时间,实现长时间的无线通信。 3. 远距离传输:LoRa技术具有较远的传输距离,可以实现数公里甚至数十公里的通信范围,适用于覆盖范围广、设备分散的应用场景。 4. 抗干扰能力强:LoRa技术具有较强的抗干扰能力,可以在复杂的无线环境下稳定可靠地传输数据。 5. 易于集成和开发:STM32F030 LoRa方案提供了丰富的软件开发工具和开发板支持,使得开发者可以快速上手,进行应用程序开发和定制。 综上所述,STM32F030 LoRa方案将STM32F030微控制器的优势与LoRa无线通信技术相结合,可以实现低功耗、高性能的无线通信,是物联网等应用场景下的一种理想选择。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值