首页 > 其他分享 >lora串口通信实验

lora串口通信实验

时间:2023-05-06 15:44:06浏览次数:39  
标签:接收 u8 lora void RX 通信 串口 include USART3

记录一下lora串口通信的测试

用的亿佰特E32 170T30D(230的大概率也是一样的,后面测一下)+STM32F103(正点原子的mini,后面会改成小的stm32板子方便使用)+lora的TTL工具E15-USB-T2+电脑

因为亿佰特的引脚很多,对于M0M1还有AUX这种配置工作状态的引脚

先通过上位机软件配置好,然后就可以把lora模块当做正常的串口模块使用了。

上位机配置的时候记得拔跳冒(用他们亿佰特专门的TTL工具的,20块,蛮贵的,不过用的方便,不然接线很麻烦)

配置好后直接使用串口控制即可,CSDN上抄了一些代码,遇到些问题,不过都解决了。

程序编写

抄了点别人的代码和用正点原子的一些例程。可以使用

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<USART3_MAX_RECV_LEN)	//还可以接收数据
			{			
				if(!Lora_mode)//配置功能下(启动定时器超时)
				{
					TIM_SetCounter(TIM3,0);             //计数器清空          				
					if(USART3_RX_STA==0) 				//使能定时器7的中断 
					{
						TIM_Cmd(TIM3,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寄存器
	
	TIM3_Int_Init(99,7199);	//10ms中断
	USART3_RX_STA=0;		//清零
	TIM_Cmd(TIM3,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<i;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("%s\r\n",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("%s\r\n",USART3_RX_BUF);
  }

}

//发送和接收数据处理进程
void LoRa_Process(void)
{
	 u8 key=0;
	 u8 t=0;
	 static u8 n = 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);	
			
	  }
}


void Lora_Test(void)
{   
	  u8 t=0;
		u8 key=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(100);
		}
}

main.c

#include "led.h"
#include "delay.h"
#include "sys.h"
#include "usart.h"
#include "lcd.h"
#include "usart3.h"
#include "lora.h"
#include "timer.h"

		 	 
#include "string.h"	 
#include "key.h"

int main(void)
 {	 
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置中断优先级分组为组2:2位抢占优先级,2位响应优先级
	delay_init();	    	 //延时函数初始化	  
	uart_init(9600);	 //串口初始化为115200
	usart3_init(9600);  //串口3初始化为115200 
	usart3_rx(1);//开启串口3接收
	LED_Init();
	KEY_Init();
	printf("LORA模块测试程序开始\r\n");
	 
	 
		Lora_Test();
	 while(1){
		GPIO_ResetBits(GPIOA,GPIO_Pin_8); //LED0输出低
		GPIO_SetBits(GPIOD,GPIO_Pin_2);//LED1输出高
		delay_ms(300);
		GPIO_SetBits(GPIOA,GPIO_Pin_8);//LED0输出高
		GPIO_ResetBits(GPIOD,GPIO_Pin_2);//LED1输出低
		delay_ms(300);
		 
		 
		 
	}
		
}

 注意:代码中的timer.h我直接复制了正点原子的定时器例程,之前抄网络上的用的TIM7,死活跑不了,后来发现通用定时器和基本定时器的使用有区别,后面好好学学。

结果演示

发送端:按下KEY_UP进行数据测试,按下KEY0发送数据

接收端:发送端按下KEY0,接收到信息。

标签:接收,u8,lora,void,RX,通信,串口,include,USART3
From: https://www.cnblogs.com/cjl520/p/17377502.html

相关文章

  • RocketMQ之通信机制
    一、概述RocketMQ消息队列集群主要包括NameServer、Broker(Master/Slave)、Producer、Consumer4个角色,基本通讯流程如下:Broker启动后需要完成一次将自己注册至NameServer的操作;随后每隔30s时间定时向NameServer上报Topic路由信息。消息生产者Producer作为客户端发送消息时候,需......
  • USART-CH32FV1x_2x_V3x--串口波特率误差分析及计算
    串口通讯波特率出现误差的因素串口通讯是一种异步通讯,收发双方需要按照约定的波特率进行通讯。当波特率出现误差时,在一些高精度要求场所可能会导致通讯出错。那导致波特率出现误差的因素都有哪些呢,今天就来分析一下。1.分频误差 首先,波特率是根据系统时钟分频产生的,而系统时......
  • linux局域网通信软件都有哪些?要如何选择?
    出于安全性考虑和上级单位要求,不少原本使用Windows系统电脑的单位都在逐渐把单位内的电脑替代为linux系统电脑,但由于原先使用的局域网通信软件没有做linux适配,无法使用,只能替换为能在linux系统上使用的局域网通信软件。那么linux局域网通信软件如何选择?可以参考以下几点:功能不同的l......
  • IM开发者的零基础通信技术入门(十二):上网卡顿?网络掉线?一文即懂!
    【来源申明】本文引用了微信公众号“鲜枣课堂”的《上网慢?经常掉线?这篇文章告诉你该怎么办!》文章内容。为了更好的内容呈现,即时通讯网在引用和收录时内容有改动,转载时请注明原文来源信息,尊重原作者的劳动。1、本文内容概述对于不太了解网络通信的人来说(包括开发者),可能会经常碰......
  • python 串口读取gps
    #coding:utf-8#lastmodified:20220824importtimeimportserialimportre utctime=''lat=''ulat=''lon=''ulon=''numSv=''msl=''cogt=''cogm='&#......
  • C# 串口通信
    这里浅说一下蓝牙与串口的区别:        蓝牙:连接以mac地址为主,显示名称可以更改,低功耗蓝牙还需要配置服务与特征(服务有读,写,可读可写区别)特点:不同设备连接同一台蓝牙设备,mac地址与显示名称都是唯一的    串口:连接以端口名称为主,例如com1,com2,连接时需要配置参数......
  • C# WinForm使用Socket通信搭建简易聊天室
    1、创建WinForm应用程序 主入口两个按钮事件:///<summary>///打开客户端///</summary>///<paramname="sender"></param>///<paramname="e"></param>privatevoidbtn_OpenClient_Click(object......
  • 虚拟串口工具VSPD简单使用
    1、下载资源下载 [虚拟串口+串口调试工具]2、安装及破解解压vspd7.2.308.zip件如下,点击vspd.exe安装(安装没啥技巧一直下一步就好了,不过需要记住安装地址),在安装完成之后vspdctl.dll覆盖至安装文件夹覆盖掉原有文件(破解) 3、创建虚拟串口运行软件如下:点击新增,虚拟串......
  • 在 linux-4.9/drivers/usb/serial/ch341.c 上串口收发数据异常
    有天做USBhost串口驱动的时候发下FT\CP都没有问题,就CH341有问题,读写正常,但数据不正常。有一点稀奇,可能是ch中间有版本变更了吧。解法就更新到https://github.com/torvalds/linux/blob/master/drivers/usb/serial/ch341.c最新的代码就行,有一些函数有出入,但大体影响......
  • Xenomai 进程间通信方式
    Xenomai进程间通信方式分成Xenomai域内的IPC以及Xenomai域和Linux域之间的IPC,目前采用的rtipc(RTDM驱动)的方式,主要是给用户空间提供socket接口,实时应用通过调用对应的接口可以避免切换到Linux域而导致实时性降低。rtipc对应了三个协议:XDDP(Xenomai域和Linux域之间的IPC)IDDP和BUFP......