完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
电子发烧友论坛|
初识LoRa
简单来讲,LoRa就是一种低功耗远程无线通信技术。它是基于Semtech公司SX1276/1278芯片开发的无线数传模块,这种芯片集成规模小、效率高,从而让LoRa模块拥有高接收灵敏度。那么它相比于我们常用的蓝牙和WiFi有什么优势呢?总结而言,就是低功耗、远距离、抗干扰。相同条件下,LoRa模块比WIFI模块传输距离更远。多见的WIFI、蓝牙等近距离无线通信技术,通信距离一般也就只有几十米左右。如果要覆盖某个地区一个城市的网络,部署的成本会很高,不划算。而作为低功耗广域网的LoRa技术,无线通信距离可以达到几公里,甚至十几公里,相对WIFI模块而言,距离要远得多。而这些优势,使得LoRa在现在的物联网中应用广泛,得到了很快的发展。 上手LoRa 本次教程使用的LoRa模块是正点原子的ATK-LORA-01,实物图就长这样: 拿到一个模块,在编程之前肯定是要看的用户手册和数据手册,先要知道它要怎么用。我把正点给的资料中一些重要的地方(和编程使用模块相关的地方)贴在这里,读者如果还有其他需求可以自行查阅手册。 首先便是引脚功能描述:除了串口常见的那四个引脚外,还多了两个引脚。参考它的说明我们可以得出这两个引脚是用于配置模块通信的引脚,因为是无线串口,肯定两个模块得有相同的配置才能通信嘛。 这也就是说,当我们已经配对好两个模块后,我们是可以不用接MD0、AUX这两个引脚的线的,让它们悬空处于低电平两个模块就可以通信了,这样基本就和串口没什么区别了,程序也会相应地简化很多了。 程序编写 这里我的目的是使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,接收. extern u8 USART3_RX_BUF[USART3_MAX_RECV_LEN]; //接收缓冲,最大USART3_MAX_RECV_LEN字节 extern u8 USART3_TX_BUF[USART3_MAX_SEND_LEN]; //发送缓冲,最大USART3_MAX_SEND_LEN字节 extern vu16 USART3_RX_STA; //接收数据状态 void usart3_init(u32 bound); //串口2初始化 void usart3_set(u8 bps,u8 parity); void usart3_rx(u8 enable); void u3_printf(char* fmt,...); #endif usart3.c的编写: #include "delay.h" #include "usart3.h" #include "stdarg.h" #include "stdio.h" #include "string.h" #include "timer.h" extern u8 Lora_mode; //串口接收缓存区 u8 USART3_RX_BUF[USART3_MAX_RECV_LEN]; //接收缓冲,最大USART3_MAX_RECV_LEN个字节. u8 USART3_TX_BUF[USART3_MAX_SEND_LEN]; //发送缓冲,最大USART3_MAX_SEND_LEN字节 u8 Temp; //通过判断接收连续2个字符之间的时间差不大于10ms来决定是不是一次连续的数据. //如果2个字符接收间隔超过timer,则认为不是1次连续数据.也就是超过timer没有接收到 //任何数据,则表示此次接收完毕. //接收到的数据状态 //[15]:0,没有接收到数据;1,接收到了一批数据. //[14:0]:接收到的数据长度 vu16 USART3_RX_STA=0; void USART3_IRQHandler(void) { u8 res; 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; //强制标记接收完成 } } } } USART_InitTypeDef USART_InitStructure; //初始化IO 串口3 //pclk1:PCLK1时钟频率(Mhz) //bound:波特率 void usart3_init(u32 bound) { NVIC_InitTypeDef NVIC_InitStructure; GPIO_InitTypeDef GPIO_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; //复用推挽输出 GPIO_Init(GPIOB, &GPIO_InitStructure); //初始化PB10 //USART3_RX PB11 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //浮空输入 GPIO_Init(GPIOB, &GPIO_InitStructure); //初始化PB11 USART_InitStructure.USART_BaudRate = bound; //波特率一般设置为9600; USART_InitStructure.USART_WordLength = USART_WordLength_8b; //字长为8位数据格式 USART_InitStructure.USART_StopBits = USART_StopBits_1; //一个停止位 USART_InitStructure.USART_Parity = USART_Parity_No; //无奇偶校验位 USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//无硬件数据流控制 USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //收发模式 USART_Init(USART3, &USART_InitStructure); //初始化串口3 USART_Cmd(USART3, ENABLE); //使能串口 //使能接收中断 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_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能 NVIC_Init(&NVIC_InitStructure); //根据指定的参数初始化VIC寄存器 TIM7_Int_Init(99,7199); //10ms中断 USART3_RX_STA=0; //清零 TIM_Cmd(TIM7,DISABLE); //关闭定时器7 } //串口3,printf 函数 发送端LORA模块发送数据 //确保一次发送数据不超过USART3_MAX_SEND_LEN字节 void u3_printf(char* fmt,...) { u16 i,j; va_list ap; va_start(ap,fmt); vsprintf((char*)USART3_TX_BUF,fmt,ap); //使用参数列表发送格式化输出到字符串 va_end(ap); i=strlen((const char*)USART3_TX_BUF); //此次发送数据的长度 for(j=0;j { while(USART_GetFlagStatus(USART3,USART_FLAG_TC)==RESET); //循环发送,直到发送完毕 USART_SendData(USART3,USART3_TX_BUF[j]); } } //串口接收使能控制 //enable:0,关闭 1,打开 void usart3_rx(u8 enable) { 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, ENABLE); //使能串口 } lora.h的编写: #ifndef __LORA_H #define __LORA_H #include "sys.h" void LoRa_Process(void); void LoRa_SendData(void); void LoRa_ReceData(void); void Lora_Test(void); #endif lora.c的编写: #include "lora.h" #include "sys.h" #include "delay.h" #include "usart3.h" #include "string.h" #include "stdio.h" #include "usart.h" #include "led.h" #include "key.h" //设备工作模式(用于记录设备状态) u8 Lora_mode=0;//0:配置模式 extern u8 USART_RX_BUF[USART_REC_LEN]; //接收缓冲,最大USART_REC_LEN个字节. EXTI_InitTypeDef EXTI_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; //LORA模块发送数据 void LoRa_SendData(void) { u8 temp[256] = "Hello Lora !!!"; u3_printf("%srn",temp); } //Lora模块接收数据 void LoRa_ReceData(void) { u16 len=0; if(USART3_RX_STA&0x8000) { len = USART3_RX_STA&0X7FFF; USART3_RX_BUF[len]=0;//添加结束符 USART3_RX_STA=0; printf("接收到的数据为"); printf("%srn",USART3_RX_BUF); } } //发送和接收数据处理进程 void LoRa_Process(void) { u8 key=0; u8 t=0; static u8 n = 1; while(1) { if(n==1) { printf("按下KEY0发送数据rn"); n++; } key = KEY_Scan(0); if(key==KEY0_PRES) { if(n==2) { printf("KEY0已被按下rn"); LoRa_SendData();//发送数据 printf("数据已被发送rn"); } } LoRa_ReceData(); t++; if(t==20) { t=0; LED1=~LED1; } delay_ms(10); } } void Lora_Test(void) { u8 t=0; u8 key=0; while(1) { printf("按下KEY_UP进入数据测试rn"); key = KEY_Scan(0); if(key==WKUP_PRES) { printf("进入数据测试rn"); LoRa_Process();//开始数据测试 } t++; if(t==30) { t=0; LED1=~LED1; } delay_ms(10); } } main.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" int main(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模块测试程序开始rn"); Lora_Test();//主测试 } 在移植程序时,只需要将usart.h、usart.c、lora.h、lora.c包含进你的工程里即可。也可以只移植lora.c和lora.h然后将串口3修改为你使用的串口即可。(相比于正点那个复杂庞大的工程,我觉得这些模块还是这样好用) 结果演示 数据发送效果: 再见LoRa 需要完整工程代码的以及加LoRa配置代码的私聊我获取即可。助大家都能很快上手LoRa并使用! |
|
|
|
|
只有小组成员才能发言,加入小组>>
1599 浏览 0 评论
imx6ull 和 lan8742 工作起来不正常, ping 老是丢包
4738 浏览 0 评论
4229 浏览 9 评论
3822 浏览 16 评论
4398 浏览 1 评论
4210浏览 3评论
2379浏览 0评论
3393浏览 0评论
1158浏览 0评论
2843浏览 0评论
/9
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2025-12-2 02:43 , Processed in 0.687659 second(s), Total 44, Slave 34 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191

淘帖
3975