19.4-STM32接收数据-状态显示在屏幕 openMV寻迹与小车控制 Openmv+STM32F103C8T6视觉巡线小车

这个是全网最详细的STM32项目教学视频。
第一篇在这里:
视频在这里

STM32智能小车V3-STM32入门教程-openmv与STM32循迹小车-stm32f103c8t6-电赛 嵌入式学习 PID控制算法 编码器电机 跟随

19.4-STM32接收数据-状态显示在屏幕

先通过串口上位机模拟发送、

STM32有视觉循迹模式、该模式下接收到数据根据状态显示在屏幕上,现在此状态并不控制电机。
在这里插入图片描述
复制一下18在上面基础改,命名成19-4_LED

可以先复制到桌面英文路径,防止出现中文路径兼容问题。
在这里插入图片描述
在这里插入图片描述
看原理图摄像头是预留什么引脚
在这里插入图片描述
PCB中可以看到接口位置
在这里插入图片描述
所以我们要初始化一下串口二,然后开启串口接收中断
在这里插入图片描述
串口2 开启初始化

在这里插入图片描述
开启串口中断
在这里插入图片描述
生成代码
在这里插入图片描述
打开代码

在这里插入图片描述
如果发现18章代码经常出现黑屏,那可能就是6050的初始化卡住了,我们可以注释掉一下MPU6050部分的代码。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
我们先定义一个串口二接收数据变量

uint8_t g_ucUsart2ReceiveData;  //保存串口二接收的数据

在这里插入图片描述
开启接收中断

  HAL_UART_Receive_IT(&huart2,&g_ucUsart2ReceiveData,1);  //串口二接收数据

在这里插入图片描述
声明一下变量

extern uint8_t g_ucUsart2ReceiveData;  //保存串口二接收的数据

在这里插入图片描述
我们需要在串口中断回调函数中加入我们对接收到数据的解析

	if(huart == &huart2)//判断中断源 是否来自串口二{//这里增加解析函数	HAL_UART_Receive_IT(&huart2,&g_ucUsart2ReceiveData,1);  //启动串口二接收数据}

在这里插入图片描述
在usart.c文件中定义一个函数
在这里插入图片描述
在这里插入图片描述

/*******************
*  @brief  摄像头串口协议解析函数 可以连接K210或openmv等
*  @param  data:串口接收到的每个字节
*  @return  
*
*******************/
void usartCamera_Receive_Data(uint8_t data)
{static uint8_t state = 0;//定义静态static 变量if(state==0&&data==0xA5) //判断第一个是不是帧头0xA5{state=1;//是帧头0xA5 赋值state=1 表示接收下一个数据//数据存储在数组中 "g_ucUsart2ReceivCounter++",这里是先用后加,比如g_ucUsart2ReceivCounter 初值为0,执行这个是先g_ucaUsart2ReceiveBuffer[0]=data,然后g_ucUsart2ReceivCounter++,即后g_ucUsart2ReceivCounter = 1的g_ucaUsart2ReceiveBuffer[g_ucUsart2ReceivCounter++] = data;}else if(state==1&&data==0xA6) //第二个是不是帧头0xA6{state=2;//如果第二个是帧头0xA6 赋值state=2 表示接收下一个数据g_ucaUsart2ReceiveBuffer[g_ucUsart2ReceivCounter++] = data;//保存数据}else if(state==2)//然后确定开头是0XA5 0XA6 就开始接收{g_ucaUsart2ReceiveBuffer[g_ucUsart2ReceivCounter++]=data;if(g_ucUsart2ReceivCounter>9||data==0x5B) state=3;  //接收大于9个或者接收到帧尾0X5B 就置位状态三}else if(state==3) //状态三{if(g_ucaUsart2ReceiveBuffer[g_ucUsart2ReceivCounter-1] == 0x5B)  //确定 最后一个是不是0x5B帧尾 是帧尾0x5B 就认为通信正确 处理数据{state = 0;					//这里就可以处理数据了、处理完记得清空数组和重置标志位与计数值g_ucUsart2ReceivCounter = 0;//清零计数值//比如根据数据设置红外旋转偏移状态//1.设置快速 慢速右边 左边 数字存储的变量意义: [0]和[1]:帧头、[2]:摄像头左边数第一个感兴趣区域、[3]:左边第二个、[4]:左边第三个、[5]:左边第四个、[6]:左边第五个、[7]:帧尾if(g_ucaUsart2ReceiveBuffer[6]==0&&g_ucaUsart2ReceiveBuffer[5]==0&&g_ucaUsart2ReceiveBuffer[3]==0&&g_ucaUsart2ReceiveBuffer[2]==0){g_cThisState=0;//前进g_lHW_State=22222;//设置这个显示在OLED上方便调试 五个值 以此从左向右表示 从左向右的五个区域}if(g_ucaUsart2ReceiveBuffer[6]==0&&g_ucaUsart2ReceiveBuffer[5]==1&&g_ucaUsart2ReceiveBuffer[3]==0&&g_ucaUsart2ReceiveBuffer[2]==0){g_cThisState=-1;//应该右转g_lHW_State=22212;	//表示右数第二个 识别到线}if(g_ucaUsart2ReceiveBuffer[6]==1&&g_ucaUsart2ReceiveBuffer[5]==0&&g_ucaUsart2ReceiveBuffer[3]==0&&g_ucaUsart2ReceiveBuffer[2]==0){g_cThisState=-2;//快速右转g_lHW_State=22221;}if(g_ucaUsart2ReceiveBuffer[6]==1&&g_ucaUsart2ReceiveBuffer[5]==1&&g_ucaUsart2ReceiveBuffer[3]==0&&g_ucaUsart2ReceiveBuffer[2]==0){g_cThisState=-3;//快速右转g_lHW_State=22211;}if(g_ucaUsart2ReceiveBuffer[6]==0&&g_ucaUsart2ReceiveBuffer[5]==0&&g_ucaUsart2ReceiveBuffer[3]==1&&g_ucaUsart2ReceiveBuffer[2]==0){g_cThisState=1;//应该左转g_lHW_State=21222;}if(g_ucaUsart2ReceiveBuffer[6]==0&&g_ucaUsart2ReceiveBuffer[5]==0&&g_ucaUsart2ReceiveBuffer[3]==0&&g_ucaUsart2ReceiveBuffer[2]==1){g_cThisState=2;//快速左转g_lHW_State=12222;}if(g_ucaUsart2ReceiveBuffer[6]==0&&g_ucaUsart2ReceiveBuffer[5]==0&&g_ucaUsart2ReceiveBuffer[3]==1&&g_ucaUsart2ReceiveBuffer[2]==1){g_cThisState=3;//快速左转g_lHW_State=11222;}//2.然后清空数组for(int i=0;i<10;i++) g_ucaUsart2ReceiveBuffer[i]=0x00;//清空数组}else //不是帧尾说明通信错误重新开始接收{state=0;g_ucUsart2ReceivCounter =0;for(int i=0;i<10;i++) g_ucaUsart2ReceiveBuffer[i]=0x00;//清空数组}}else{	//其他异常清空state=0;g_ucUsart2ReceivCounter =0;for(int i=0;i<10;i++) g_ucaUsart2ReceiveBuffer[i]=0x00;//清空数组}
}

然后声明一下变量

extern int8_t g_cThisState ;//这次状态

在这里插入图片描述
定义一个变量 并且在main文件中声明一下

int g_lHW_State = 0;//帮助视觉调试 用于表示红外对管或者视觉摄像头识别状态

在这里插入图片描述
声明一下

extern int g_lHW_State;//帮助视觉调试 用于表示红外对管或者视觉摄像头识别状态

在这里插入图片描述
我们需要再定义模式,这个模式是视觉循迹模式

视觉模式下 我们显示一下,我们之前赋值的变量 以测试我们接收的数据是否正确。

			//这里编写触发中断后要执行的程序if(g_ucMode == 6) g_ucMode = 1;//g_ucMode模式是0 1 2 3 4 5  6else{g_ucMode+=1;}

在这里插入图片描述
增加模式6,的功能,我们先只显示视觉识别结果

	if(g_ucMode == 6){sprintf((char*)OledString, "lHW:%d  ", g_lHW_State);//视觉识别结果OLED_ShowString(0,0,OledString,12);//这个是oled驱动里面的,是显示位置的一个函数,motorPidSetSpeed(0,0);//停住电机防止乱跑 方便调试}

在这里插入图片描述
别忘记我们的解析函数,加到串口中断处理函数中

		usartCamera_Receive_Data(g_ucUsart2ReceiveData);

在这里插入图片描述
修改上面程序经过测试,单片机

编译上面程序,并烧录到我们的单片机、单片机连接到电脑、然后电脑模拟openmv发送正确格式的数据,手动点击SSCOM发送数据、单片机可以接收到数据并显示在OLED上(观察的是OLED的第一行数值变化)、当我们设置每1ms发送一次数据时候,单片机的OLED有时候会出现卡死的情况。所以是单片机串口接收大量数据卡死的情况,经过网上搜索发现解决问题的办法。

**这个博客是搜索到可以解决问题的链接:**https://blog.csdn.net/qq_44629109/article/details/131002223

参考博客如下部分:
在这里插入图片描述
所以我们要更改如下代码:

  __HAL_UART_ENABLE_IT(&huart2, UART_IT_ERR);// 启用UART2的错误中断功能

在这里插入图片描述
在USART.C 中添加如下代码

/* UART 错误回调函数 处理串口错误 */
void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart)
{if(__HAL_UART_GET_FLAG(huart,UART_FLAG_ORE) != RESET) //使用__HAL_UART_GET_FLAG宏检查UART的overrun错误标志位是否被置位。如果返回值不等于RESET,表示overrun错误标志位被置位,即发生了overrun错误{__HAL_UART_CLEAR_OREFLAG(huart);//使用__HAL_UART_CLEAR_OREFLAG宏清除UART的overrun错误标志位HAL_UART_Receive_IT(&huart2,&g_ucUsart2ReceiveData,1);  //使用HAL库函数启动UART2接收中断,并设置接收缓冲区的大小为1字节}
}

在这里插入图片描述
添加串口2接收变量的声明

extern uint8_t g_ucUsart2ReceiveData;  //保存串口二接收的数据

在这里插入图片描述
让单片机处于模式6(按六下 KEY1)
在这里插入图片描述
上面我们测试通过上位机发送数据,然后观察屏幕。

然后我们把STM32底板接到openmv,openmv连接电脑,openmv使用的程序是19章3节的程序19-3-openmv
在这里插入图片描述
然后上面如果没有问题,就可以把openmv 程序通过"将打开的脚本保存到openmv Cam(作为main.py)"

接法如下:
在这里插入图片描述
这里就说明了如何接受的数据,后面的19.5讲解利用数据

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/21285.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【CSP】202012-2 期末预测之最佳阈值

2020年 第21次CCF计算机软件能力认证 202012-2 期末预测之最佳阈值 原题链接&#xff1a;期末预测之最佳阈值 时间限制&#xff1a; 1.0 秒 空间限制&#xff1a; 512 MiB 目录 题目背景 题目描述 输入格式 输出格式 样例1输入 样例1输出 样例1解释 样例2输入 样…

AI网络爬虫:无限下拉滚动页面的另类爬取方法

现在很多网页都是无限下拉滚动的。可以拉动到底部&#xff0c;然后保存网页为mhtml格式文件。 接着&#xff0c;在ChatGPT中输入提示词&#xff1a; 你是一个Python编程高手&#xff0c;要完成一个关于爬取网页内容的Python脚本的任务&#xff0c;下面是具体步骤&#xff1a; …

String,StringBuffer ,StringBuilder 的区别及其详解

目录 一、String1.1 String介绍1.2 深入理解String的不可变性1.3 String 操作字符串方法 二、StringBuffer2.1 StringBuffer介绍2.2 StringBuffer 构造方法2.3 StringBuffer 常用方法 三、StringBuilder2.1 StringBuffer介绍 四、String&#xff0c;StringBuffer &#xff0c;S…

为图片设置经纬度信息

一、java实现 小编看了很多技术博客&#xff0c;但是测试要么下载的jar包中的api和博客对不上&#xff0c;要么就是不对&#xff0c;总之没实现 Java 读取图片信息 java 写入 exif 信息 使用Java读取和修改图片的Exif信息 java获取图片的GPS信息 https://drewnoakes.com/code/e…

MySQL之数据库字段约束学习笔记(三)

MySQL 中的字段约束用于限制字段的取值范围&#xff0c;确保数据的一致性和完整性。常见的字段约束包括&#xff1a; PRIMARY KEY&#xff1a;定义主键约束&#xff0c;唯一标识表中的每一行数据。FOREIGN KEY&#xff1a;定义外键约束&#xff0c;确保两个表之间的关联完整性…

Python 介绍

python 发展简史 Python 起源&#xff08;1989-1991&#xff09; Python的诞生可以追溯到1989年&#xff0c;当时Guido van Rossum在荷兰国家数学和计算机科学研究所工作时&#xff0c;出于对当时编程语言的不满&#xff0c;开始构思一种新的编程语言。他希望这种语言能够弥补C…

【Python】使用 Pandas 统计每行数据中的空值

缘分让我们相遇乱世以外 命运却要我们危难中相爱 也许未来遥远在光年之外 我愿守候未知里为你等待 我没想到为了你我能疯狂到 山崩海啸没有你根本不想逃 我的大脑为了你已经疯狂到 脉搏心跳没有你根本不重要 &#x1f3b5; 邓紫棋《光年之外》 在数据分析…

传感器的基本特性

传感器的基本特性主要包括以下几个方面&#xff1a; 静态特性&#xff1a;这是指传感器在被测量的各个值处于稳定状态时的输入和输出关系。传感器的静态特性可以用一些静态性能指标来衡量&#xff0c;主要包括线性度、灵敏度、迟滞、重复性、漂移和分辨力等。其中&#xff0c;线…

Python 网络爬虫:深入解析 Scrapy

大家好&#xff0c;在当今数字化时代&#xff0c;获取和分析网络数据是许多项目的关键步骤。从市场竞争情报到学术研究&#xff0c;网络数据的重要性越来越被人们所认识和重视。然而&#xff0c;手动获取和处理大量的网络数据是一项繁琐且耗时的任务。幸运的是&#xff0c;Pyth…

vue3 todolist 简单例子

vue3 简单的TodList 地址&#xff1a; https://gitee.com/cheng_yong_xu/vue3-composition-api-todo-app-my 效果 step-1 初始化项项目 我们不采用vue cli 搭建项目 直接将上图文件夹&#xff0c;复制到vscode编辑器&#xff0c;清空App.vue的内容 安装包 # 安装包 npm…

云原生架构案例分析_2.云原生技术助力某汽车公司数字化转型实践

名词解释&#xff1a; 互联网 在“互联网”模式下&#xff0c;我们仅仅把互联网看作是一种传播工具、传播手段、传播渠道和传播平台&#xff0c;对于互联网的应用大体上是在既有的运作逻辑的基础之上&#xff0c;把互联网作为延伸传媒影响力、价值和功能的一种延伸型工具&…

Linux基础1-基本指令1

1.Linux学习前言 Linux的学习非常重要&#xff0c;我们学习Linux的第一步是在电脑中搭建Linux环境。 对于没有搭建过的可以看这阿伟t的一篇文章 【Linux入门】Linux环境配置-CSDN博客 我的环境为XShell,运行的云服务器是阿里云 2.本章重点 1.显示当前目录下的所有文件…

iperf

文章目录 1.安装1.1在 Ubuntu 上安装1.2在 CentOS 上安装 2.iperf服务端选项3.iperf客户端选项4.iperf常用命令5.结果展示5.1 tcp结果展示5.2 udp结果展示 Iperf是一款基于TCP/IP和UDP/IP的网络性能测试工具&#xff0c;它可以用来测量网络带宽和网络质量&#xff0c;还可以提供…

针对大模型的上下文注入攻击

大型语言模型&#xff08;LLMs&#xff09;的开发和部署取得了显著进展。例如ChatGPT和Llama-2这样的LLMs&#xff0c;利用庞大的数据集和Transformer架构&#xff0c;能够产生连贯性、上下文准确性甚至具有创造性的文本。LLMs最初和本质上是为静态场景设计的&#xff0c;即输入…

asio之winsock的初始化

简介 asio中&#xff0c;winsock初始化工作是放在winsock_init类中来处理的 类结构 #mermaid-svg-aC4x3cdr8TKGhsnX {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-aC4x3cdr8TKGhsnX .error-icon{fill:#552222;}#…

Xilinx RFSOC 47DR 8收8发 信号处理板卡

系统资源如图所示&#xff1a;  FPGA采用XCZU47DR 1156芯片&#xff0c;PS端搭载一组64Bit DDR4,容量为4GB,最高支持速率&#xff1a;2400MT/s;  PS端挂载两片QSPI X4 FLASH&#xff1b;  PS支持一路NVME存储&#xff1b;  PS端挂载SD接口&#xff0c;用于存储程序&…

解决kettle界面右上角的connect消失——且使用admin登录不上Kettle资源库

一、问题描述 1.1、Kettle界面右上角的connect消失了 当我们配置Kettle界面的资源库(Other Repositories)内容后,Kettle界面右上角的connect消失了;如下图所示: 1.2、使用默认的账户【admin】和密码【admin】登录不上kettle资源库 当我们切换到我们配置的数据库使用超管账…

uniapp实现微信小程序调用云函数【vue3】

本人是从微信开发者工具写原生微信小程序一步一步走来&#xff0c;由于vue3框架的慢慢的步入前端市场&#xff0c;为了不被前端市场遗弃&#xff0c;果断从vue2开始步入vue3的学习&#xff0c;本人习惯在在HBuilder X写uniapp的项目&#xff0c;过去uniapp默认vue2框架&#xf…

注册北京个体工商户条件和办理时间

在北京这座充满活力的城市中&#xff0c;每天都有无数的创业者怀揣着梦想&#xff0c;踏上创业之路。然而&#xff0c;对于许多初次接触企业注册的人来说&#xff0c;往往对注册流程和时间感到困惑。特别是选择代理服务时&#xff0c;更希望了解一个大概的时间范围。那么&#…

WHAT - 容器化系列(二)- docker

目录 一、前言二、Docker镜像&#xff1a;可运行软件包三、Docker容器&#xff1a;可执行环境四、容器和镜像的关系五、创建镜像的过程5.1 编写Dockerfile5.2 构建Docker镜像5.3 查看构建的镜像5.4 运行Docker容器5.5 验证容器运行状态5.6 推送镜像到镜像仓库&#xff08;可选&…