一、前提准备
为了使得代码的逻辑更加清晰,我们这里在.h文件中定义三个结构体,用于存放LoRa的各个参数、任务状态以及工作模式。
typedef struct _sLoRaSettings
{
uint32_t RFFrequency; //频率,单位Hz
int8_t Power; //发射功率2~20
uint8_t SignalBw; // 带宽 [0: 7.8 kHz, 1: 10.4 kHz, 2: 15.6 kHz, 3: 20.8 kHz, 4: 31.2 kHz,
// 5: 41.6 kHz, 6: 62.5 kHz, 7: 125 kHz, 8: 250 kHz, 9: 500 kHz, other: Reserved] 带宽
uint8_t SpreadingFactor;// 扩频因子 [6: 64, 7: 128, 8: 256, 9: 512, 10: 1024, 11: 2048, 12: 4096 chips] 扩频因子
uint8_t ErrorCoding; // 误码编码率 [1: 4/5, 2: 4/6, 3: 4/7, 4: 4/8] 编码率
uint16_t PreambleLength; //前导码长度
}tLoRaSettings;
//定义模块状态机
typedef enum
{
RF_IDLE, //空闲状态
RF_BUSY, //模块执行任务中
RF_RX_DONE, //接收完成
RF_RX_TIMEOUT, //接收超时
RF_TX_DONE, //发送完成
RF_TX_TIMEOUT, //发送超时
RF_CAD_DETECTED, //CAD检测到前导码
RF_CAD_EMPTY, //CAD检测完成,没有检测到前导码
RF_CAD_TIMEOUT, //CAD超时
RF_UNKNOW_STATUS //异常状态机
}tRFProcessReturnCodes;
//硬件工作模式
typedef enum{
LORA_OPMODE_SLEEP=0,//睡眠
LORA_OPMODE_STANDBY,//待机
LORA_OPMODE_SYNTHESIZER_TX,
LORA_OPMODE_TRANSMITTER,//发送
LORA_OPMODE_SYNTHESIZER_RX,//
LORA_OPMODE_RECEIVER,//接收
LORA_OPMODE_RECIVER_SINGLE,//单次接收
LORA_OPMODE_CAD,//CAD
}LoRaOpModeType;
同时,为了使得我们快速完成对各个寄存器的读写,我们通过宏定义来定义一些寄存器。
二、设置LoRa模式的函数
lora一共有八种模式,同时更具数据手册,初始化LoRa时需要不断改名其相应的模式
读写LoRa模式的函数如下:
//设置Lora模式
void SX127xSetLoRaMode(void)
{
if(0 != (Read127xReg(REG_LR_OPMODE) & RFLR_OPMODE_LONGRANGEMODE_ON))
{
// &0x80 设置第七位,0-fsk,1-lora
return; //如果已经是lora模式返回
}
SX127xSetOpMode(LORA_OPMODE_SLEEP);
Write127xReg(REG_LR_OPMODE,Read127xReg(REG_LR_OPMODE) | RFLR_OPMODE_LONGRANGEMODE_ON);
//先设置为sleep,然后设置为lora模式
}
//设置opMode
void SX127xSetOpMode(LoRaOpModeType opMode)
{
if(opMode == SX127xGetOpMode())
{
return;
}
Write127xReg(REG_LR_OPMODE,(Read127xReg(REG_LR_OPMODE) & RFLR_OPMODE_MASK) | opMode | RFLR_OPMODE_FREQMODE_ACCESS_LF);
HAL_Delay(1);
}
//获取opMode
LoRaOpModeType SX127xGetOpMode(void)
{
return (LoRaOpModeType)(Read127xReg(REG_LR_OPMODE) & RFLR_OPMODE_MASK);
}
三、设置载波频率
LoRa工作在非工业授权频段,最好不要将频率设置为32的整数倍。需要向载波频率地址0x06开始连续写三个数,来表示频率。
void SX127xSetFrf(void)
{
SX127xSetOpMode(LORA_OPMODE_SLEEP);
Write127xReg( REG_LR_FRFMSB, Frequency[0]);//射频载波频率最高有效位
Write127xReg( REG_LR_FRFMID, Frequency[1]);//射频载波频率中间有效位
Write127xReg( REG_LR_FRFLSB, Frequency[2]);//射频载波频率最低有效位
}
四、初始化函数
初始化函数,参入一共结构体参数,完成对LoRa的载波频率、带宽、纠错码、CRC校验、超时时间、超时时间、功率、前导码长度设置。
//SX127x初始化
void LoRa01Init(tLoRaSettings *stting)
{
LoRaInit(); //完成初始化
LoRa01Restart();
while(0x6c!=Read127xReg(0x06))
{
UsartPrintf(&huart1,"error %d pi error\r\n",Read127xReg(0x06));
HAL_Delay(100);
}
UsartPrintf(&huart1,"SPI init OK\r\n");
SX127xSetLoRaMode(); //设置为lora模式
if(NULL != stting)
{//复制配置信息
memcpy(&localSettingSave,stting,sizeof(tLoRaSettings));
}
//setting指向备份数据,避免修改导致setting原值改变
stting = &localSettingSave;
if(stting->SignalBw > 9) //带宽不大于9
{
UsartPrintf(&huart1,"WARRING SignalBw setting error,auto fix\r\n");
stting ->SignalBw = 9;
}
if(stting->ErrorCoding > 4)
{
UsartPrintf(&huart1,"WARRING ErrorCoding setting error,auto fix\r\n");
stting->ErrorCoding = 4;
}
if(stting->ErrorCoding < 1)
{
UsartPrintf(&huart1,"WARRING ErrorCoding setting error,auto fix\r\n");
stting->ErrorCoding = 1;
}
if(stting->SpreadingFactor > 12)
{
UsartPrintf(&huart1,"WARRING SpreadingFactor setting error,auto fix\r\n");
stting->SpreadingFactor = 12;
}
if(stting->SpreadingFactor <6)
{
UsartPrintf(&huart1,"WARRING SpreadingFactor setting error,auto fix\r\n");
stting->SpreadingFactor = 6;
}
if(stting->Power > 20)
{
UsartPrintf(&huart1,"WARRING Power setting error,auto fix\r\n");
stting->Power = 20;
}
SX127xSetFrf(stting->RFFrequency); //设置载波频率
Write127xReg(REG_LR_MODEMCONFIG1,u8_BWList[stting->SignalBw] | u8_CRList[stting->ErrorCoding -1] | RFLR_MODEMCONFIG1_IMPLICITHEADER_OFF);//带宽、纠错码
Write127xReg(REG_LR_MODEMCONFIG2,u8_SFList[stting->SpreadingFactor-6] | RFLR_MODEMCONFIG2_TXCONTINUOUSMODE_OFF|RFLR_MODEMCONFIG2_RXPAYLOADCRC_ON|0x03);//设置SD,CRC,超时时间
Write127xReg(REG_LR_SYMBTIMEOUTLSB,0xFF);//设置超时时间
Write127xReg(REG_LR_MODEMCONFIG3,0x0C);//设置低速率(包长超过16ms必须打开),开启低速率
if(stting->Power > 17)
{
Write127xReg(REG_LR_PACONFIG,0x80+stting -> Power - 5);
Write127xReg(0x4d,0x87);//更改为更大功率
}else{
Write127xReg(REG_LR_PACONFIG,0x80+stting->Power-2);
Write127xReg(0x4d,0x84); //关闭更大功率
}
Write127xReg(REG_LR_OCP,0x3B); //过流保护
//设置前导码长度
Write127xReg(REG_LR_PREAMBLELSB,stting->PreambleLength >> 8); //高八位前导码
Write127xReg(REG_LR_PREAMBLELSB,stting->PreambleLength&0x00ff); //第八位前导码
}
注意,这里的
while(0x6c!=Read127xReg(0x06))
{
UsartPrintf(&huart1,"error %d pi error\r\n",Read127xReg(0x06));
HAL_Delay(100);
}
是为了等待SPI协议正确读取,可以读取其他的寄存器如版本号寄存器。
评论(0)