深圳鼎盛合科技代理芯海系芯海一级代理商,代理芯海高精度ADC芯片,SOC芯片,wifi及蓝牙模块
基于stm32的LoRa模块调试教程初识LoRa简单来讲,LoRa就是一种低功耗远程无线通信技术它是基于Semtech公司SX1276/1278芯片开发的无线数传模块,这种芯片集成规模小、效率高,从而让代理芯海LoRa模块拥有高接收灵敏度。
那么它相比于我们常用的蓝牙和WiFi有什么优势呢?总结而言,就是低功耗、远距离、抗干扰相同条件下,LoRa模块比WIFI模块传输距离更远多见的WIFI、蓝牙等近距离无线通信技术,通信距离一般也就只有几十米左右。
如果要覆盖某个代理芯海地区一个城市的网络,部署的成本会很高,不划算而作为低功耗广域网的LoRa技术,无线通信距离可以达到几公里,甚至十几公里,相对WIFI模块而言,距离要远得多而这些优势,使得LoRa在现在的物联网中应用广泛,得到了很快的发展。
上手LoRa本次教程使用的LoRa模块是正点原子的ATK-代理芯海LORA-01,实物图就长这样:
刚开始拿到手一看,不就是个无线串口嘛,写一下串口的数据收发就完事了,应该很快就能调好了可是最后前前后后调通大概花了我一天时间,这当然得归功于正点那个又臭又长的例程,和讲不明白重点的用户手册我觉得大家用这些模块肯定是想直接就可以拿来用的,程序应代理芯海该是很方便移植的那种,可是正点偏不,非要在程序里面加各种各样的显示屏、外设模块,然后写一些复复杂杂的看着就头大的程序。
于是我又上网参考了一下别人的程序,结合自己的调试经验,又重新写了LoRa模块的程序,移植十分方便拿到一个模块,在编程之前肯定是要看的用户手册和数据手册,先要代理芯海知道它要怎么用我把正点给的资料中一些重要的地方(和编程使用模块相关的地方)贴在这里,读者如果还有其他需求可以自行查阅手册。
首先便是引脚功能描述:除了串口常见的那四个引脚外,还多了两个引脚。参考它的说明我们可以得出这两个引脚是用于配置模块通信的引脚,因为是无线串口,肯定两个代理芯海模块得有相同的配置才能通信嘛。
接着就是这两个配置引脚的描述了,它关系到我们如何让模块处于不同的工作状态下:显然,当AUX和MD0引脚都为低电平时,才是模块的通信功能(即两个LoRa模块互相收发数据)而我们在刚开始给它配对的时候,需要进入配置功能,这时候需要MD0引脚为代理芯海高电平。
然后我们从手册中得知,MD0、 AUX 引脚悬空下为低电平 这也就是说,当我们已经配对好两个模块后,我们是可以不用接MD0、AUX这两个引脚的线的,让它们悬空处于低电平两个模块就可以通信了,这样基本就和串口没什么区别了,程序也会相应地简化很多了。
那么如何配对两个模块呢?我个代理芯海人的建议就是接一个USB转TTL连到电脑上,然后用正点提供的上位机去设置这样可以不去关心那些AT指令的写法及意义,达到最快速的上手使用LoRa模块这里连接好后修改模块基本参数配置就好,工作模式配置和发送状态先保持默认。
模块参数配置里面两个模块必须都保持一致,我个人建议把通信信道、模块地址可以修改一下代理芯海,这样可以减少干扰(以防万一嘛)
一旦我们的模块配对好后,程序的编写逻辑就很简单了,就只是串口的接收和发送了当然,我们完全可以把模块的配置之类的操作写在程序里,不过试想我们需要再连两个引脚的线,而且多写很多的逻辑控制,为什么不先把它配对好后当个串口用呢?。
程序编写这里我的目的是使stm32和电脑通过两代理芯海个LoRa模块实现无线通信,并都能显示接收到和发送的数据MCU端让LoRa使用串口3,然后将串口3接收端的数据通过串口1在电脑上打印出来usart3.h的编写:。
#ifndef __USART3_H #define __USART3_H #include"sys.h"代理芯海 #define USART3_MAX_RECV_LEN 1024
//最大接收缓存字节数 #define USART3_MAX_SEND_LEN 600 //最大发送缓存字节数 #define USART3_RX_EN 1
//0,不接收;1,接收. e代理芯海xternu8USART3_RX_BUF[USART3_MAX_RECV_LEN];//接收缓冲,最大USART3_MAX_RECV_LEN字节 externu8USART3_TX_BUF
[USART3_MAX_SEND_LEN];//发送缓冲,最大USART3_MAX_SEND_L代理芯海EN字节 externvu16USART3_RX_STA;//接收数据状态 voidusart3_init
(u32bound);//串口2初始化 voidusart3_set(u8bps,u8parity);voidusart3_rx(u8enable代理芯海);voidu3_printf(char*fmt,...);
#endifusart3.c的编写:#include"delay.h"#include"usart3.h"#include"stdarg.h" #include"stdio.h"
#include"string.h" #include"tim代理芯海er.h"externu8Lora_mode;//串口接收缓存区 u8USART3_RX_BUF[USART3_MAX_RECV_LEN
];//接收缓冲,最大USART3_MAX_RECV_LEN个字节. u8USART3_TX_BUF[USART3_MAX_SEND代理芯海_LEN];//发送缓冲,最大USART3_MAX_SEND_LEN字节
u8Temp;//通过判断接收连续2个字符之间的时间差不大于10ms来决定是不是一次连续的数据. //如果2个字符接收间隔超过timer,则认为不是1次连续数据.也就是超过timer没有接收到 /代理芯海/任何数据,则表示此次接收完毕.
//接收到的数据状态 //[15]:0,没有接收到数据;1,接收到了一批数据. //[14:0]:接收到的数据长度 vu16USART3_RX_STA=0;voidUSART3_IRQHandler(void
){u8re代理芯海s;if(USART_GetITStatus(USART3,USART_IT_RXNE)!=RESET)//接收到数据 {res=USART_ReceiveData(USART3);if((
USART3_RX_STA&(1<<15))==0)//接收完的一批数据,还没有被处理,则不再代理芯海接收其他数据 {if(USART3_RX_STA
{if(!Lora_mode)//配置功能下(启动定时器超时) {TIM_SetCounter(TIM7,0);//计数器清空 if(USART3_RX_STA
==0)//使能定时器7的中断 代理芯海 {TIM_Cmd(TIM7,ENABLE);//使能定时器7 }}USART3_RX_BUF[USART3_RX_STA++]=res;//记录接收到的值 }else
{USART3_RX_STA|=1<<15;//强制标记接收完成 }}}}USAR代理芯海T_InitTypeDefUSART_InitStructure;//初始化IO 串口3 //pclk1:PCLK1时钟频率(Mhz)
//bound:波特率 voidusart3_init(u32bound){NVIC_InitTypeDefNVIC_InitStru代理芯海cture;GPIO_InitTypeDefGPIO_InitStructure
;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);// GPIOB时钟 RCC_APB1PeriphClockCmd(RCC_APB1Periph_代理芯海USART3
,ENABLE);//串口3时钟使能 USART_DeInit(USART3);//复位串口3 //USART3_TX PB10 GPIO_InitStructure.GPIO_Pin=GPIO_Pin_10
;//PB10 代理芯海GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;//复用推挽输出
深圳鼎盛合科技系芯海一级代理商,代理芯海高精度ADC芯片,SOC芯片,wifi及蓝牙模块
GPIO_I代理芯海nit(GPIOB,&GPIO_InitStructure);//初始化PB10 //USART3_RX PB11 GPIO_InitStructure.GPIO_Pin=GPIO_Pin_11
;GPIO_InitStructure.GPIO_Mode=GPIO_Mo代理芯海de_IN_FLOATING;//浮空输入 GPIO_Init(GPIOB,&GPIO_InitStructure);//初始化PB11
USART_InitStructure.USART_BaudRate=bound;//波特率一般设置为9600; USART_Ini代理芯海tStructure.USART_WordLength=USART_WordLength_8b
;//字长为8位数据格式 USART_InitStructure.USART_StopBits=USART_StopBits_1;//一个停止位 USART_InitStru代理芯海cture.USART_Parity
=USART_Parity_No;//无奇偶校验位 USART_InitStructure.USART_HardwareFlowControl=USART_HardwareFlowControl_None
;//无硬件数据流控制 US代理芯海ART_InitStructure.USART_Mode=USART_Mode_Rx|USART_Mode_Tx;//收发模式 USART_Init(USART3,&USART_InitStructure
);//初始化串口3 USART_Cmd(USART3,ENAB代理芯海LE);//使能串口 //使能接收中断 USART_ITConfig(USART3,USART_IT_RXNE,ENABLE);//开启中断
//设置中断优先级 NVIC_InitStructure.NVIC_IRQChannel=USART3_IRQn代理芯海;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority
=2;//抢占优先级3 NVIC_InitStructure.NVIC_IRQChannelSubPriority=3;//子优先级3 NVIC_InitStru代理芯海cture.NVIC_IRQChannelCmd
=ENABLE;//IRQ通道使能 NVIC_Init(&NVIC_InitStructure);//根据指定的参数初始化VIC寄存器 TIM7_Int_Init(99,7199);//10ms中断 US代理芯海ART3_RX_STA
=0;//清零 TIM_Cmd(TIM7,DISABLE);//关闭定时器7 }//串口3,printf 函数 发送端LORA模块发送数据 //确保一次发送数据不超过USART3_MAX_SEND_LEN字节
voidu3_prin代理芯海tf(char*fmt,...){u16i,j;va_listap;va_start(ap,fmt);vsprintf((char*)USART3_TX_BUF,fmt,ap);//使用参数列表发送格式化输出到字符串
va_end(ap);i=strlen((constchar*)USART3_TX_代理芯海BUF);//此次发送数据的长度 for(j=0;j
(USART3,USART_FLAG_TC)==RESET);//循环发送,直到发送完毕 USART_SendData(USART3,USART3_TX_BUF[j]);}}//串口接收使能控制
//enable:0,代理芯海关闭 1,打开 voidusart3_rx(u8enable){USART_Cmd(USART3,DISABLE);//失能串口 if(enable){USART_InitStructure
.USART_Mode=USART_Mode_Rx|USART_Mode_Tx代理芯海;//收发模式 }else{USART_InitStructure.USART_Mode=USART_Mode_Tx;//只发送
}USART_Init(USART3,&USART_InitStructure);//初始化串口3 USART_Cmd(USART3,ENA代理芯海BLE);//使能串口 }lora.h的编写:#ifndef __LORA_H
#define __LORA_H #include"sys.h"voidLoRa_Process(void);voidLoRa_SendData(void);voidLoRa_ReceDat代理芯海a(void
);voidLora_Test(void);#endiflora.c的编写:#include"lora.h"#include"sys.h"#include"delay.h"#include"usart3.h"
#include"string.h"#include"stdio.h"#incl代理芯海ude"usart.h"#include"led.h"#include"key.h"//设备工作模式(用于记录设备状态)
u8Lora_mode=0;//0:配置模式 externu8USART_RX_BUF[USART_REC_LEN];//接收缓冲,最大USART_REC_LEN个代理芯海字节. EXTI_InitTypeDef
EXTI_InitStructure;NVIC_InitTypeDefNVIC_InitStructure;//LORA模块发送数据 voidLoRa_SendData(void){u8temp[256
]="Hello Lora代理芯海 !!!";u3_printf("%s\r\n",temp);}//Lora模块接收数据 voidLoRa_ReceData(void){u16len=0;if(USART3_RX_STA
&0x8000){len=USART3_RX_STA&0X7FFF;USART3_RX_BUF[代理芯海len]=0;//添加结束符 USART3_RX_STA=0;printf("接收到的数据为");printf
("%s\r\n",USART3_RX_BUF);}}//发送和接收数据处理进程 voidLoRa_Process(void){u8key=0;u8t=0;s代理芯海taticu8n=1;while(1){if
(n==1){printf("按下KEY0发送数据\r\n");n++;}key=KEY_Scan(0);if(key==KEY0_PRES){if(n==2){printf("KEY0已被按下\r\n
");LoRa_SendData();//发送数据 代理芯海 printf("数据已被发送\r\n");}}LoRa_ReceData();t++;if(t==20){t=0;LED1=~LED1;}delay_ms
(10);}}voidLora_Test(void){u8t=0;u8key=0;while(1){printf("按下KEY_UP代理芯海进入数据测试\r\n");key=KEY_Scan(0);if(key
==WKUP_PRES){printf("进入数据测试\r\n");LoRa_Process();//开始数据测试 }t++;if(t==30){t=0;LED1=~LED1;}delay_ms(10);
}}mai代理芯海n.c的编写:#include"sys.h"#include"delay.h"#include"usart.h"#include"key.h"#include"led.h"#include"lora.h"
#include"timer.h"#include"usart3.h"intmain(void)代理芯海{NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置中断优先级分组为组2:2位抢占优先级,2位响应优先级
delay_init();//延时函数初始化 uart_init(115200);//串口初始化为115200 代理芯海usart3_init(115200);//串口3初始化为115200 usart3_rx
(1);//开启串口3接收 LED_Init();KEY_Init();printf("LORA模块测试程序开始\r\n");Lora_Test();//主测试 代理芯海}在移植程序时,只需要将usart.h、usart.c、lora.h、lora.c包含进你的工程里即可。
也可以只移植lora.c和lora.h然后将串口3修改为你使用的串口即可(相比于正点那个复杂庞大的工程,我觉得这些模块还是这样好用)结果演示数据发送效果:
数据接收效果:
这里开两个串口助手就可以,一代理芯海个用于看和MCU相连的LoRa模块的数据,一个用于看和电脑相连的LoRa模块的数据,还是很好理解的再见LoRa需要完整工程代码的以及加LoRa配置代码的私聊我获取即可助大家都能很快上手LoRa并使用!。
深圳鼎盛合科技系芯海一级代理商,代理芯海高精度ADC芯片,SOC芯片,wifi及蓝牙模块