最近整理东西,找到两个串口通信的Lora模块:SX1278。
本文介绍以下两个Lora模块通信的问题。
一,Lora模块介绍
1,引脚定义及模块连接图
注意:某些5v单片机连接模块AUX和TXD引脚时最好接一个4-10K的上拉电阻。
2,发送方式
(1),定点发送
(2),广播发送
地址设为ff ff或0000为广播发送。
3,模式选择
4,指令格式
5,默认出厂设置
即:0x00 0x00 0x1a 0x17 0x44
6,参数设置
M0,M1拉高,设置模块为模式三。然后向模块发送HEAD字节(0XC0:设置的参数可以断电保存;0XC2:设置参数断电不保存)
然后紧接发送5个字节。
第一字节设置模块高地址(默认0x00)
第二地址设置模块低地址(默认0x00)
第三字节设置模块通信参数,例如:设置波特率,传播速度等
(默认0x1a:即9600 N 8 1)
第四字节设置模块通信信道(默认433M即0x17)
第五字节设置发送方式、唤醒时间等(默认0x44)
具体配置参数选项见下图:
更多详细信息见用户手册。
二,参数配置
我们使用亿佰特官方提供的软件设置上述参数信息,准备一根USB转TTL线。
1,将M0,M1拉高,3.3v供电,AUX悬空,TXD连接串口线的RXD,RXD连接串口线的TXD。
2,打开软件,波特率设为9600,在软件界面可以界面画配置参数,然后点击写入参数即可。
三,程序实现,引脚图连接如图
亿佰特提供的SX1278Lora模块:E32 433T20DC(串口通信方式)
1,初始化串口
usart.c:
#include "sys.h"#include "usart.h" #include "lora.h"////加入以下代码,支持printf函数,而不需要选择use MicroLIB #if 1#pragma import(__use_no_semihosting) //标准库需要的支持函数 struct __FILE { int handle; }; FILE __stdout; //定义_sys_exit()以避免使用半主机模式 void _sys_exit(int x) { x = x; } //重定义fputc函数 int fputc(int ch, FILE *f){ while((USART1->SR&0X40)==0);//循环发送,直到发送完毕 USART1->DR = (u8) ch; return ch;}#endif /*使用microLib的方法*/ /* int fputc(int ch, FILE *f){USART_SendData(USART1, (uint8_t) ch);while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET) {} return ch;}int GetKey (void) { while (!(USART1->SR & USART_FLAG_RXNE)); return ((int)(USART1->DR & 0x1FF));}*/ void uart_init(u32 bound){//GPIO端口设置GPIO_InitTypeDef GPIO_InitStructure;USART_InitTypeDef USART_InitStructure;NVIC_InitTypeDef NVIC_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA, ENABLE);//使能USART1,GPIOA时钟USART_DeInit(USART1); //初始化串口1//USART1_TX GPIOA.9GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //PA.9GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;//复用推挽输出GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.9//USART1_RX GPIOA.10初始化GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;//PA10GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.10 //Usart1 NVIC 配置NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3 ;//抢占优先级3NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;//子优先级3NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//IRQ通道使能NVIC_Init(&NVIC_InitStructure);//根据指定的参数初始化VIC寄存器//USART 初始化设置USART_InitStructure.USART_BaudRate = bound;//串口波特率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(USART1, &USART_InitStructure); //初始化串口1USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//开启串口接受中断USART_Cmd(USART1, DISABLE); //失能串口1 }#if EN_USART1_RX //如果使能了接收//串口1中断服务程序//注意,读取USARTx->SR能避免莫名其妙的错误 u8 USART_RX_BUF[USART_REC_LEN]; //接收缓冲,最大USART_REC_LEN个字节.//接收状态//bit15,接收完成标志//bit14,接收到0x0d//bit13~0,接收到的有效字节数目u16 USART_RX_STA=0; //接收状态标记void USART1_IRQHandler(void) //串口1中断服务程序{u8 Res;if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) //接收中断(接收到的数据必须是0x0d 0x0a结尾){Res =USART_ReceiveData(USART1);//读取接收到的数据if((USART_RX_STA&0x8000)==0)//接收未完成{if(USART_RX_STA&0x4000)//接收到了0x0d{if(Res!=0x0a)USART_RX_STA=0;//接收错误,重新开始else USART_RX_STA|=0x8000;//接收完成了 }else //还没收到0X0D{if(Res==0x0d)USART_RX_STA|=0x4000;else{//lora.EmitData[USART_RX_STA&0X3FFF]=Res;lora.ReadData[USART_RX_STA&0X3FFF]=Res;USART_RX_BUF[USART_RX_STA&0X3FFF]=Res ;USART_RX_STA++;if(USART_RX_STA>(USART_REC_LEN-1))USART_RX_STA=0;//接收数据错误,重新开始接收 } }} } } #endif
usart.h:
#ifndef __USART_H#define __USART_H#include "stdio.h"#include "sys.h" #define USART_REC_LEN 200 //定义最大接收字节数 200#define EN_USART1_RX 1//使能(1)/禁止(0)串口1接收 extern u8 USART_RX_BUF[USART_REC_LEN]; //接收缓冲,最大USART_REC_LEN个字节.末字节为换行符 extern u16 USART_RX_STA; //接收状态标记//如果想串口中断接收,请不要注释以下宏定义void uart_init(u32 bound);#endif
lora.h:
#ifndef __lora_H#define __lora_H#include "sys.h"#include "delay.h"#include "usart.h"typedef struct _LORA{u8 SetWParameterSave; //设置工作参数,断电保存u8 SetWParameterNSave; //设置工作参数,断电不保存u8 SetParameterReturn[3]; //查询当前保存工作参数u8 VersionInformationReturn[3]; //查询版本信息u8 SystemReset[3]; //系统复位指令u8 SaveActualParameter[5]; //工作参数u8 ReadData[USART_REC_LEN]; //保存数据,最大接收数据根据串口接收数据最大长度,USART_REC_LEN定义见串口u8 EmitData[USART_REC_LEN]; //保存数据,最大接收数据根据串口接收数据最大长度,USART_REC_LEN定义见串口}LORA;extern LORA lora;#define LORA_PORT GPIOB//#define LORA_TXD_Pin GPIO_Pin_11//#define LORA_RXD_Pin GPIO_Pin_10#define LORA_M0_Pin GPIO_Pin_3#define LORA_M1_Pin GPIO_Pin_4#define LORA_AUX_Pin GPIO_Pin_15#define LORA_M0 PBout(3)#define LORA_M1 电脑 PBout(4)#define LORA_AUX PBin(15)void lora_Init(void);void Read_Lora_Para(u8 mode);void Reset_Lora(void);void LORA_Set_Working_Parameters(u8 save,u8 parameter[5]);void LORA_Mode_Change(u8 mode);u8 Read_Lora_Data(u8 time);void Emit_Lora_Data(u8 *str,u8 len);#endif
通过结构体LORA,保存相关配置所需的命令:例如:0XC0和相关配置信息以及返回信息等。将接收的到数据保存在lora.ReadData中,将要发送的程序保存在lora.EmitData中
lora.c中书写相关发送数据,接收数据,复位模块,设置模块参数的函数,在主函数中调用这些函数达到两个Lora中的数据相互传送。
测试,天线安装位置会影响传输数据,理论上,空旷距离可传输3电脑km
电脑