STM32HAL库 (cubemx) 两个HC05蓝牙模块相互通信相关问题的解决 数组串口发送与接受的方法

2023-11-09

主要问题

1. 蓝牙模块的连接问题

2. 蓝牙模块的工作模式

3. CUBEMX 配置串口注意事项

4. 两个模块数据传输异常

前言

因为最近都在做基于STM32,MPU6050的手势控制机器人,遇到了无线数据传输的问题,正好手上有几个蓝牙模块,就用蓝牙模块来传输数据,但是并没有想象的那么顺利,最主要的还是两个模块串口传输数据的问题,一直得不到解决,因为简简单单的串口就OK。

首先是实物连接的问题

蓝牙模块与STM32的连接只需要四根线就好,VCC,GND,RX,TX,VCC,提供3.3或者5V,这块基本没有问题

蓝牙模块的工作模式

  1. AT指令
  2. 透传

AT

按住蓝牙模块的按钮,然后上电,之后在松开就可以进入AT指令模式,这是时候可以对模块进行必要的设置,比如波特率等,也可以查询模块的相关信息,AT指令要以\R\N结尾,而且此时的波特率固定为38400,常用的AT指令在下面啦!!
在这里插入图片描述
透传
正常上电,模块上的灯闪得比较快,这个时候就是透传,当使用两个模块相互通信的时候要先进入AT模式,将其中一个设置为主机,另外一个设置为从机,这样上电之后主机会自动连接从机。

cubemx 的配置

这个很简单,就是正常的配置串口,但是切记波特率要与蓝牙模块的波特率一致,透传模式下默认是9600,可以在AT指令中自行修改
在这里插入图片描述
在这里插入图片描述
如果是指定一边发送,另外一边接受的话,接受的一段 需要开启中断,发送的一段可以不开启,就是普通的阻塞模式。

今天最主要的不是上面的内容,这些都很简单,主要是两个模块的数据发送与接受的处理方式,这个是今天笔记的主要对象

首先来看发送端的

在这里插入图片描述
发送端的数据我放到了一个数组里,通过发送数组将数据发送出去
由于串口HAL库本身没有数组的发送函数,所以需要自己写一个数组发送的函数,原理是通过反复的调用串口发送函数来实现的,那么问题来了,

为什么不能使用printf函数来实现呢?

如果使用printf函数来实现的话,也可以传输十六进制的数据,但是,你传输出去之后,到接受端就会变成十进制,这可能是我自己软件的问题,但是网上大佬也是这么说的,所以最好使用HAL库自带的函数来实现,这里会有一个问题,就是串口调试助手可能会显示异常,但是不影响,因为你需要的是接收端能够正常的显示,发送端主要能正确的把数据发送就好。
在这里插入图片描述
发送端串口偶尔异常,还没探究具体的原因。

/*下面的函数时对数据进行打包处理,将一个完整的数组通过数组发送函数传输出去*/
void ack(int x,int y,int z)
{
	Inverse_X (x);
	Inverse_Y (y);
	Inverse_Z (z);
	uint8_t str[12]= {0};
	str[0] = 0xAA;
	str[1] = 0xBB;
	str[2] = X_H ;
	str[3] = X_L ;
	str[4] = Y_H ;
	str[5] = Y_L ;
	str[6] = Z_H ;
	str[7] = Z_L ;
	str[8] = X_flag ;
	str[9] = Y_flag ;
	str[10] =Z_flag ;
	str[11] = 0xCC;
	UART_SendStr (str,12);
}

这块代码是重点,因为串口发送的数据是8位的,也就是只能传输0-255,这样的256个数字,超过范围的就不能正常的显示,但是MPU6050的角度纵不能只到255度吧。得到300度甚至更多,所以有时候8位就不能满足要求啦,我的处理方法是将数据分为高位和低位,同时由于串口传输无符号数据,负数传输会出现错误。我的解决办法是通过判断是否为负数,然后设置一个标志位,通过置位标志位来判断是否是负数。
超出范围以及负数的处理办法如下

/*用于判断X的值是否超过255,以及X的正负*/
void Inverse_X (int x)
{
	/*如果X的值大于0不大于255,则高位直接存放X的值,低位不存数据,标志为不置1*/
	if((x>= 0) && (x < 255))
	{
		X_H = x;
		X_L = 0;
		X_flag = 0;
	}
	/*如果超过255,则将数据分为高低两位存储,高位存放255,低位存放剩余的数,标志位不置位*/
	else if(x>255)
	{
		X_H = 255;
		X_L = x-255;
		X_flag = 0;
	}
	/*如果数据的值低于-255,则同样分为高低两位,但是这两位存放的是正数,标志位置一,表示为负数*/
	else if ( x <= -255)
	{
		X_H = 255;
		X_L = -x-255;
		X_flag = 1;
	}
	/*如果数据的值在0到255之间,则高位存数据的正数,标志位置一*/
	else 
	{
		X_H = -x;
		X_L = 0;
		X_flag = 1;
	}
}

主函数发送三个数据

ack (300,-6,-200);

发送端的处理基本结束,接下来是接收端

/*三个变量用于存放目标数据,这里时MPU6050的角度*/
static int   X=0,Y=0,Z=0;
/*数据接收函数*/
void Openmv_Receive_Data(uint16_t Com_Data)
{
  /*循环体变量*/
  uint8_t i;
	/*计数变量*/
	static uint8_t RxCounter1=0;//计数
	/*数据接收数组*/
	static uint16_t RxBuffer1[50]={0};
	/*数据传输状态位*/
	static uint8_t RxState = 0;	
	/*对数据进行校准,判断是否为有效数据*/
  if((RxState==0)&&(Com_Data==0xAA))  //0x2c帧头
		{
			RxState=1;
			RxBuffer1[RxCounter1++]=Com_Data;
		}

	else if((RxState==1)&&(Com_Data==0xBB))  //0x12帧头
		{
			RxState=2;
			RxBuffer1[RxCounter1++]=Com_Data;
		}
		/*对数据进行处理*/
	else if(RxState==2)
		{
			/*接受的数据存放到数组里*/   
			RxBuffer1[RxCounter1++]=Com_Data;
			if(RxCounter1>=30||Com_Data == 0xCC)       //RxBuffer1接受满了,接收数据结束
				{
					RxState=3;
					/*X,Y,Z都是有高位与低位构成的,这里将高位与低位加到一起即可*/
					X  = RxBuffer1[2]+RxBuffer1[3];
					Y  = RxBuffer1[4]+RxBuffer1[5];
					Z  = RxBuffer1[6]+RxBuffer1[7];
					/*处理数据的符号,传输的过程不能传输符号,通过标志位的形式解决这个问题*/
					X  = Inverse (RxBuffer1 [8],X);
					Y  = Inverse (RxBuffer1 [9],Y);
					Z  = Inverse (RxBuffer1 [10],Z);
          printf("X  = %d\r\n",X);
          printf("Y = %d\r\n",Y);
          printf("Z  = %d\r\n",Z); 
					}
			}
		
				else if(RxState==3)//检测是否接受到结束标志
				{
						if(RxBuffer1[RxCounter1-1] == 0xCC)
						{
									//RxFlag1 = 0;
									RxCounter1 = 0;
									RxState = 0;
						}
						else   //接收错误
						{
							printf ("erro");
									RxState = 0;
									RxCounter1=0;
									for(i=0;i<10;i++)
									{
											RxBuffer1[i]=0x00;      //将存放数据数组清零
									}
						}
				} 
	
				else   //接收异常
				{
						RxState = 0;
						RxCounter1=0;
						for(i=0;i<10;i++)
						{
								RxBuffer1[i]=0x00;      //将存放数据数组清零
						}
//						printf ("接收异常00\r\n");
				}
}

上面是一个串口数据的接收函数,具体的接收方式已经在里面哟注释啦!
还有一个函数时对正负数的标志位进行处理的函数,如下

/*符号处理*/
int Inverse(uint8_t x,int X)
{
	/*判断标志为来解决符号问题,标志为为1,说明是负数,对数据进行求相反数*/
	if(x==0)
		X = X;
	else 
		X = -X;
	printf("******%d\r\n",X);
	return X ;
}

最后是串口中断的回调函数

/*回调函数*/
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
  uint16_t tempt  //定义临时变量存放接受的数据
  if(huart->Instance==USART1)
  {
    tempt=USART1_RXbuff;
    Openmv_Receive_Data(tempt);
  }	
HAL_UART_Receive_IT(&huart1,&USART1_RXbuff,1);
}

接收端记得在主函数中开启串口接收中断,否则不能进入中断。

 /* USER CODE BEGIN 2 */
HAL_UART_Receive_IT(&huart1,&USART1_RXbuff,1);
  /* USER CODE END 2 */

为了防止以后忘记怎么弄,来做一个笔记。
同时感谢这位大哥提供的数据处理思路哦

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

STM32HAL库 (cubemx) 两个HC05蓝牙模块相互通信相关问题的解决 数组串口发送与接受的方法 的相关文章

  • Nginx集群+websocket 获取websocket客户端的真实IP

    Nginx增加如下配置 proxy set header Host host proxy set header X Real IP remote addr proxy set header REMOTE HOST remote addr p
  • UMI多环境配置

    一般来说项目不止有dev和prod两个环境 umi可以通过环境变量 UMI ENV 区分不同环境来指定配置 需求 三套环境 gt 本地测试环境local 测试发布环境testbuild 正式环境probuild 1 在根目录新建 umirc

随机推荐

  • 云计算基础——云计算与移动互联网、物联网

    8 1 云计算与移动互联网 8 1 1 移动互联网的发展概况 移动互联网的发展概况 移动互联网是指以宽带IP为技术核心 可同时提供语音 数据 多媒体等业务服务的开什么是移动互联网 放式基础电信网络 从用户行为角度来看 移动互联网广义上是指用
  • shell命令以及运行原理(详解)

    Linux严格意义上说的是一个操作系统 我们称之为 核心 kernel 但我们一般用户 不能直接使用kernel 而是通过kernel的 外壳 程序 也就是所谓的shell 来与kernel沟通 1 从技术角度 Shell的最简单定义 命令
  • Redis实践(一):安装和部署

    memcache redis mongodb 是目前常用的内存数据库 他们应用的场景大致如下 redis 数据量较小的更性能操作和运算上 memcache 用于在动态系统中减少数据库负载 提升性能 做缓存 提高性能 适合读多写少 对于数据量
  • __builtin_expect, __builtin_unreachable和__builtin_prefetch

    builtin expect 该指令是gcc引入的 就是允许代码编写者把最有可能执行的分支告诉编译器 标准写法是 bultin expect exp n 意思是exp n的概率很大 这样编译器可以对代码进行优化 减少指令跳转带来的性能下降
  • elasticsearch bulk批量增删改(超详细)

    一 bulk的操作类型 1 1批量增 语法一 index操作 可以是创建文档 也可以是全量替换文档 类似于普通的put操作 POST bulk index index test index type test type id 12 scor
  • java调用串口,开箱即用

    作者 刘东标 撰写日期 2022 08 02 开发遇到问题 1 供应商提供的动态库各种底层代码有问题 指针也不对 参数也乱 加上长年不维护动态库 2 解决多个动态库问题 不同供应商提供动态库也不同 32位动态库和64位动态库 还有是供应商的
  • Python -BS4详细介绍

    Python BS4详细介绍 Python 在处理html方面有很多的优势 一般情况下是要先学习正则表达式的 在应用过程中有很多模块是非常方便的 先尝试使用BeautifulSoup和Urllib进行网页的处理 仅供学习 首先列举所需要导入
  • flutter 边框_Flutter作息定时器 app

    背景知识视频教程 学习Flutter Dart构建iOS和Android应用 国外课栈 viadean com Flutter Dart 完整的Flutter应用开发课程 国外课栈 viadean com Flutter的实际项目 国外课栈
  • 【OSATE学习笔记】失效模式与影响分析,FMEA(failure mode and effects analysis)

    目录 参考文献 简介 FMEA显著的作用案例 案例一 案例二 案例三 FMEA目标 FMEA进程 风险 Risk FMEA的特点及作用 FMEA的特点 FMEA的分类 专业术语 DFMEA与PFMEA的差别 六西格玛 SIX SIGMA 嵌
  • PHP内核探索:Apache运行与钩子函数

    Apache是目前世界上使用最为广泛的一种Web Server 它以跨平台 高效和稳定而闻名 按照去年官方统计的数据 Apache服务器的装机量占该市场60 以上的份额 尤其是在X Unix Linux 平台上 Apache是最常见的选择
  • 已解决(from docx import Document导包报错)ModuleNotFoundError: No module named ‘exceptions‘

    已解决 from docx import Document导包报错 ModuleNotFoundError No module named exceptions 文章目录 报错代码 报错翻译 报错原因 解决方法 千人全栈VIP答疑群联系博主
  • 1. R语言中grep函数和gsub()函数的使用

    1 grep 函数 1 语法结构 grep pattern x ignore case FALSE perl FALSE value FALSE fixed FALSE useBytes FALSE invert FALSE 各参数的含义如
  • linux内核分析:进程通讯方式

    信号 一旦有信号产生 我们就有下面这几种 用户进程对信号的处理方式 1 执行默认操作 Linux 对每种信号都规定了默认操作 例如 上面列表中的 Term 就是终止进程的意思 Core 的意思是 Core Dump 也即终止进程后 通过 C
  • 解决M1处理器安装PS闪退问题Photoshop 2021 fo mac(支持最新M1芯片处理器款mac)

    去年苹果在2020年11月11日突然发布了搭载自研M1芯片处理器的最新款Mac 由于这次新版mac系列史无前例的采用arm架构的芯片 导致很多之前为旧版mac开发的软件安装后不兼容无法使用 这其中就包括著名的Adobe系列软件 之前很多刚买
  • ppocrlabel简单教学

    前言 给我们小白成员的快速上手ppocrlabel的指南 1 ppocr环境配置 建议是先创建一个虚拟环境 直接参考 https blog csdn net weixin 42708301 article details 119864744
  • HDMI的DDC是什么

    DDC 是什么 DDC Display Data Channel 显示数据通道 在 HDMI 协议中用于 Source 和 Sink 两端进行数据交换 通常是基于 I2C 标准的一套通讯机制 在实际使用过程中 Source 端的 HDMI
  • 前端自动化测试之葵花宝典

    作者 京东零售 杜兴文 首先聊一下概念 Web 前端自动化测试是一种通过编写代码来自动化执行 Web 应用程序的测试任务的方法 它通常使用 JavaScript 和测试框架 如 Selenium Appium 等 来实现 Web 前端自动化
  • IRQL 和 分页内存

    IRQL是Interrupt ReQuest Level 中断请求级别 一个由windows虚拟出来的概念 划分在windows下中断的优先级 这里中断包括了硬中断和软中断 硬中断是由硬件产生 而软中断则是完全虚拟出来的 处理器在一个IRQ
  • python中把list列表所有或者部分的数变成整数,或者浮点数,字符串等等

    第一种 简单形式列表中是数字型 list x 1624865249825 0 316 0 351 0 32 0 107 0 4 0 1 7187 2970 0 1 0 list y 5249825 4 0 925 0 3903 1 7187
  • STM32HAL库 (cubemx) 两个HC05蓝牙模块相互通信相关问题的解决 数组串口发送与接受的方法

    主要问题 1 蓝牙模块的连接问题 2 蓝牙模块的工作模式 3 CUBEMX 配置串口注意事项 4 两个模块数据传输异常 前言 因为最近都在做基于STM32 MPU6050的手势控制机器人 遇到了无线数据传输的问题 正好手上有几个蓝牙模块 就