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.rhkb.cn/news/338931.html

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

相关文章

2024四川三支一扶“考生信息表”照着填❗

2024四川三支一扶“考生信息表”照着填❗ ☑️四川三支一扶开始报名&#xff0c;大家要按照提示如实、准确、完整填写《高校毕业生“三支一扶”计划招募考生信息表》哦~ ☑️不知道怎么填写的宝子们&#xff0c;可以参考图1。 ☑️毕业证书编号如实填写&#xff0c;若是应届生&…

VGGNet

VGGNet CNN卷积网络的发展史 1. LetNet5(1998) 2. AlexNet(2012) 3. ZFNet(2013) 4. VGGNet(2014) 5. GoogLeNet(2014) 6. ResNet(2015) 7. DenseNet(2017) 8. EfficientNet(2019) 9. Vision Transformers(2020) 10. 自适应卷积网络(2021) 上面列出了发展到现在CNN的一些经典…

WPF Binding对象、数据校验、数据转换

在WinForm中&#xff0c;我们要想对控件赋值&#xff0c;需要在后台代码中拿到控件对象进行操作&#xff0c;这种赋值形式&#xff0c;从根本上是无法实现界面与逻辑分离的。 在WPF中&#xff0c;微软引入了Binding对象&#xff0c;通过Binding&#xff0c;我们可以直接将控件与…

基于MingGW64 GCC编译Windows平台上的 libuvc

安装cmake 打开cmake官网 https://cmake.org/download/&#xff0c;下载安装包&#xff1a; 安装时选择将cmake加到系统环境变量里。安装完成后在新的CMD命令窗口执行cmake --version可看到输出&#xff1a; D:\>cmake --version cmake version 3.29.3 CMake suite mainta…

mac多媒体影音库:Emby for Mac 中文版

Emby软件是一款功能强大的媒体服务器软件&#xff0c;旨在为用户提供丰富的多媒体体验。以下是关于Emby软件的详细介绍&#xff1a; 下载地址&#xff1a;https://www.macz.com/mac/7964.html?idOTI2NjQ5Jl8mMjcuMTg2LjE1LjE4Mg%3D%3D 主要功能 媒体管理&#xff1a;Emby允许用…

Java反序列化漏洞与URLDNS利用链分析

前言 前面学习过 Java 反序列化漏洞的部分知识&#xff0c;总结过几篇文章&#xff1a; 文章发布日期内容概括《渗透测试-JBoss 5.x/6.x反序列化漏洞》2020-07-08JBoss 反序列化漏洞 CVE-2017-12149 的简单复现&#xff0c;使用了 ysoserial 和 CC5 链&#xff0c;未分析漏洞…

网络网络层

data: 2024/5/25 14:02:20 周六 limou3434 叠甲&#xff1a;以下文章主要是依靠我的实际编码学习中总结出来的经验之谈&#xff0c;求逻辑自洽&#xff0c;不能百分百保证正确&#xff0c;有错误、未定义、不合适的内容请尽情指出&#xff01; 文章目录 1.协议结构2.封装分离3.…

搭建基于Django的博客系统增加广告轮播图(三)

上一篇&#xff1a;ChatGPT搭建博客Django的web网页添加用户系统&#xff08;二&#xff09; 下一篇&#xff1a;搭建基于Django的博客系统数据库迁移从Sqlite3到MySQL&#xff08;四&#xff09; 功能概述 增加轮播图显示广告信息。 需求详细描述 1. 增加轮播图显示广告信…

领导让我调研CI/CD,我给他看了这个

一、概念解释 CI/CD是指持续集成&#xff08;Continuous Integration&#xff09;和持续交付/持续部署&#xff08;Continuous Delivery/Continuous Deployment&#xff09;的缩写&#xff0c;是现代软件开发中的重要实践。它们旨在通过自动化和持续化的方式改善软件开发、测试…

轻松拿捏C语言——【文件操作】

&#x1f970;欢迎关注 轻松拿捏C语言系列&#xff0c;来和 小哇 一起进步&#xff01;✊ &#x1f389;创作不易&#xff0c;请多多支持&#x1f389; &#x1f308;感谢大家的阅读、点赞、收藏和关注&#x1f495; &#x1f339;如有问题&#xff0c;欢迎指正 目录 &#x1f…

论文阅读:Correcting Motion Distortion for LIDAR HD-Map Localization

目录 概要 Motivation 整体架构流程 技术细节 小结 论文地址&#xff1a;http://arxiv.org/pdf/2308.13694.pdf 代码地址&#xff1a;https://github.com/mcdermatt/VICET 概要 激光雷达的畸变矫正是一个非常重要的工作。由于扫描式激光雷达传感器需要有限的时间来创建…

LeetCode 算法:找到字符串中所有字母异位词c++

原题链接&#x1f517;&#xff1a;找到字符串中所有字母异位词 难度&#xff1a;中等⭐️⭐️ 题目 给定两个字符串 s 和 p&#xff0c;找到 s 中所有 p 的 异位词 的子串&#xff0c;返回这些子串的起始索引。不考虑答案输出的顺序。 异位词 指由相同字母重排列形成的字符…

Nginx实战:防盗链

防盗链的概念 内容不在自己的服务器上&#xff0c;通过技术手段将其他网站的内容&#xff08;比如 一些音乐、图片、软件的下载地址&#xff09;放置在自己的网站中&#xff0c;通过这 种方法盗取其他网站的空间和流量 防盗链技术背景 防止第三方引用链接访问我们的图片&#x…

mysql面试之分库分表总结

文章目录 1.为什么要分库分表2.分库分表有哪些中间件&#xff0c;不同的中间件都有什么优点和缺点&#xff1f;3.分库分表的方式(水平分库,垂直分库,水平分表,垂直分表)3.1 水平分库3.2 垂直分库3.3 水平分表3.4 垂直分表 4.分库分表带来的问题4.1 事务一致性问题4.2 跨节点关联…

UE_地编教程_创建地形洞材质

个人学习笔记&#xff0c;不喜勿喷。侵权立删&#xff01; 使用地形洞材质来遮罩地形上特定位置的可视性和碰撞。如要在山脉侧面创建进入洞穴的入口&#xff0c;此操作将非常有用。可使用地形材质和地形洞材质的相同材质&#xff0c;但注意&#xff1a;对比不使用不透明蒙版的…

【Linux】Linux工具——yum,vim

1.Linux 软件包管理器——yum Linux安装软件&#xff1a; 源代码安装&#xff08;不建议&#xff09;rpm安装&#xff08;类似Linux安装包&#xff0c;版本可能不兼容&#xff0c;不推荐&#xff0c;容易报错&#xff09;yum安装&#xff08;解决了安装源&#xff0c;安装版本&…

即时通讯平台及门户系统WorkPlus打造移动应用管理平台

在全球化和数字化时代&#xff0c;企业管理和沟通的方式正发生着巨大的变化。为了实现高效的协作和资源共享&#xff0c;企业越来越倾向于使用即时通讯及门户系统。这两种系统结合起来&#xff0c;可以提供一套完整的沟通和信息发布平台&#xff0c;促进内部协作和信息管理。 …

【Python内功心法】:深挖内置函数,释放语言潜能

文章目录 &#x1f680;一、常见内置函数&#x1f308;二、高级内置函数⭐1. enumerate函数&#x1f44a;2. eval函数❤️3. exec函数&#x1f4a5;4. eval与exec 中 globals与locals如何用☔4-1 globals 参数&#x1f3ac;4-2 locals 参数 ❤️5. filter函数&#x1f44a;6. z…

【Leetcode笔记】40.组合总和II

1. 题目要求 这道题目和39.组合总和不一样的地方在于&#xff1a;数组中含有相同的元素。同样地&#xff0c;结果不能含有重复组合。 拿第一个示例来看&#xff0c; candidates [1, 1, 2, 5, 6, 7, 10]问题在于&#xff1a;第一个path[1(index 0), 2]&#xff0c;绝不能出现…

0、机器学习知识点

机器学习知识点 知识点汇总 知识点汇总 https://blog.csdn.net/seagal890/article/details/105352987 https://blog.csdn.net/fengdu78/article/details/115878843