【软件STM32cubeIDE下H73xx配置串口uart1+中断接收/DMA收发+HAL库+简单数据解析-基础样例】

#【软件STM32cubeIDE下H73xx配置串口uart1+中断接收/DMA收发+HAL库+简单数据解析-基础样例】

  • 1、前言
  • 2、实验器件
  • 3-1、普通收发+中断接收实验
    • 第一步:代码调试-基本配置
      • (1)基本配置
      • (3)时钟配置
      • (4)保存后,就可以生成代码
    • 第二步:加入prinf打印
      • (1)不重复造轮子:打印相关连接
      • (2)加入代码片段,注意第四步要放到main里运行
      • (3)代码测试
    • 第三步:加入接收代码
      • (1)加入初始化配置
      • (2)加入回调函数部分
      • (3)加入到中断内
    • 第四步:实验验证
  • 3-2、DMA收发实验
    • 第一步:加入DMA初始化
    • 第二步:加入DMA相关数组
    • 第三步:加入回调函数
    • 第四步:加入到中断函数内
    • 第四步:简单数据解析功能
      • (1)加入接收部分代码
      • (2)加入处理部分代码
      • (3)测试代码
  • 4、代码连接
  • 5、注意细节
      • (1)总是多个字符,或者多个其它字符。
      • (2)复制函数的使用。
      • (3)逻辑调试与测试。
      • (4)十进制的1与十六进制0x31。
      • (5)不同串口工具,有些信息不显示。
      • (6)数据解析注意
      • (7)初始化顺序不对,不运行
      • (8)回调函数写的有问题,只返回一个字符
      • (9)在网上找到样例,进行测试,没有成功
  • 总结

1、前言

最近有段时间没有调试STM32了,想着H743调试串口1,也不能老师吃灰,也遇到了问题,即使最简单的功能,一些细节也是非常重要的,保持初学者之心,是非常重要的,同时也算做记录,对于初学者会有帮助,另外因为之前做过很多相关实验,遇到问题基本轻车熟路了,体现了记录的好处。

2、实验器件

软件环境:STM32cubeIDE 1.8.0
硬件环境:STM32H743xx(正点原子阿波罗开发板)
下载模块:ST-link下载器 (下载器)
串口模块:串口转换器 (可用开发板上232模块代替)

3-1、普通收发+中断接收实验

第一步:代码调试-基本配置

(1)基本配置

新建stm32项目,先配置(下载口)和(时钟口),如下图,在这里插入图片描述在这里插入图片描述

###q (2)uart1以及DMA相关配置
uart1配置稍微复杂点,但是配置串口多了,熟悉了,其实也就知道了,分为几个步骤。
(0)先锁定自己需要引脚,记得F4默认是FA9,FA10,但是H7不是,我们想使用特定引脚的话,需要选择引脚,然后再选择uart1
在这里插入图片描述

(1)配置异步通信与开启中断使能,这个时候uart1锁定的引脚就会变成绿色,没选好之前,是黄色的。
在这里插入图片描述
这里需要注意的是,在自己实际操作生成代码时,发现并没有生成中断函数,所以最好在中断上再点下。
在这里插入图片描述

(2)配置DMA,这部分直接添加就好,都是默认的也不需要改什么。
在这里插入图片描述

(3)配置串口的波特率相关设置,改成你需要的波特率,一般也只改波特率,其它不用动。

在这里插入图片描述

(3)时钟配置

也就是外部时钟配置,之前F4用的是168M,F1是72M,H7一般是480M,配置如下。
在这里插入图片描述

(4)保存后,就可以生成代码

建议先保存,然后生成代码,否则直接生成代码,可能导致软件崩掉,之前遇到过。
在这里插入图片描述在这里插入图片描述

第二步:加入prinf打印

(1)不重复造轮子:打印相关连接

具体打印方式,之前就写过,所以不要重复造轮子,之前看文章,将代码复制过来。
文章连接:# 关于软件stm32cubeIDE下配置printf重定向无法输出问题-解决方式之一

(2)加入代码片段,注意第四步要放到main里运行

另外注意自己测试发现,不能使用如下定义的方式。

//>>第三步:定义输出函数printf
#define printf(...)  HAL_UART_Transmit_DMA((UART_HandleTypeDef * )&huart3, (uint8_t *)u_buf,\sprintf((char *)u_buf,__VA_ARGS__));

需要使用以下方式,并且需要加入换行符号 \n

printf(“\r\n star \r\n\r\n”); //起来之后输出一条语句
printf(“\r\n star \r\n\r\n”); //起来之后输出一条语句
printf(“\r\n star \r\n\r\n”); //起来之后输出一条语句


//>>第一步:添加库
#include "string.h"
#include "stdint.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes *//* USER CODE END Includes */
//>>第二步:定义数组
uint8_t u_buf[64];/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
//>>第三步:定义输出函数printf
#ifdef __GNUC__
#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif
//STM32cubeIDE下
PUTCHAR_PROTOTYPE
{HAL_UART_Transmit(&huart1 , (uint8_t *)&ch, 1,0x200);return ch;
}//keil下 //没在keil下尝试过 一直使用软件stm32cubeIDE没有取keil验证
//UART_HandleTypeDef huart1; //UART句柄
int fputc(int ch,FILE *f)
{HAL_UART_Transmit(&huart1,(uint8_t*)&ch,1,0xffff);return ch;
}/* USER CODE END PTD *///>>第四步:打印输出printf("\r\n star \r\n\r\n");  //起来之后输出一条语句HAL_Delay(1000);

(3)代码测试

随便输出些什么,进行打印测试,在网上找个串口上位机工具,然后连接后串口转USB工具,对应引脚,就可以进行测了。
第四步代码放在主函数,这里没有截图上位机串口数据,打印可以放置的位置指示下,下图已经做完实验的一个截图,开始中断时还没有加入printf,这点请熟知,有疑问可以看代码或评论。
在这里插入图片描述

第三步:加入接收代码

(1)加入初始化配置

具体代码见下边连接,这里放置图片展示代码内容。
在这里插入图片描述

(2)加入回调函数部分

触发发送与接收,都会回调函数,我们这次就简单些,收到什么就发送什么。


uint8_t aRxBuffer[1];
void UART_RxCpltCallback(UART_HandleTypeDef *huart)
{static uint32_t rxIndex = 0;if(huart->Instance == USART1){HAL_UART_Transmit(&huart1, (uint8_t *)aRxBuffer, 1,0xFFFF);HAL_UART_Receive_IT(&huart1, (uint8_t *)aRxBuffer, 1);}}

在这里插入图片描述

(3)加入到中断内

这点还是挺重要,在中断函数内加入回调函数,不加入相应功能无法实现。
在这里插入图片描述

第四步:实验验证

(1)发送
在这里插入图片描述
(2)中断接收

在这里插入图片描述

3-2、DMA收发实验

因为上述步骤,相关配置已经完成了,我们不需要,再重新配置,直接使用即可。

第一步:加入DMA初始化

__HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE);//开启空闲中断/*.虽然我们使用的CubeMx来配置DMA,* 但只是配置DMA模式为串口到内存,* 所以还需要在程序中进一步指定:* DMA具体搬运到内存的哪一个位置中,* 我们建立一个数组用以存放DMA搬运的串口数据,* 并使用HAL_UART_Receive_DMA()函数来配置*/HAL_UART_Receive_DMA(&huart1, (uint8_t*)UART1_ReceBuf, UART1_Buf_LEN);

在这里插入图片描述

第二步:加入DMA相关数组

/* USER CODE BEGIN PTD */
//>>第二步:定义数组
uint8_t u_buf[64];
#define UART1_Buf_LEN 100uint8_t UART1_SendBuf[UART1_Buf_LEN];uint8_t UART1_ReceBuf[UART1_Buf_LEN];
/* USER CODE END PTD */

第三步:加入回调函数

/* USER CODE BEGIN PFP */uint8_t aRxBuffer[1];
//void UART_RxCpltCallback(UART_HandleTypeDef *huart)
//{
//  static uint32_t rxIndex = 0;
//
//  if(huart->Instance == USART1)
//      {
//
//	  HAL_UART_Transmit(&huart1, (uint8_t *)aRxBuffer, 1,0xFFFF);
//	  HAL_UART_Receive_IT(&huart1, (uint8_t *)aRxBuffer, 1);
//
//      }
//
//
//
//}
void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)//发送完成回调函数
{}//采用DMA空闲串口中断模式  貌似不会回调到这里
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)//接收完成回调函数
{}
/* USER CODE END 0 */uint8_t UART1_ReceBuf_deal_with_data[5];
void USAR_UART_IDLECallback(UART_HandleTypeDef *huart)
{//(1)HAL_UART_DMAStop(&huart1);                    //停止本次DMA传输 需要使用DMA发送则需要关掉  如果使用的阻塞方式HAL_UART_Transmit发送请使用本行
HAL_UART_Transmit(&huart1,(uint8_t*)UART1_ReceBuf,3,0x200);//阻塞方式发送 使用时需要关闭DMA模式 阻塞发送没有问题,收啥 发啥
//数据头正确了再赋值
if(UART1_ReceBuf[0]==0x31 &&  UART1_ReceBuf[1]==0x32)
{//		目标							源地址	    	数据量memcpy(&UART1_ReceBuf_deal_with_data,&UART1_ReceBuf,3);}memset(UART1_ReceBuf,0,UART1_Buf_LEN);                                            //清零接收缓冲区//  data_length = 0;
HAL_UART_Receive_DMA(&huart1, (uint8_t*)UART1_ReceBuf, UART1_Buf_LEN);                    //重启开始DMA传输 每次255字节数据}void USER_UART_IRQHandler(UART_HandleTypeDef *huart)
{if(  huart->Instance == USART1){if(RESET != __HAL_UART_GET_FLAG(&huart1, UART_FLAG_IDLE))   //判断是否是空闲中断{__HAL_UART_CLEAR_IDLEFLAG(&huart1);                     //清楚空闲中断标志(否则会一直不断进入中断)USAR_UART_IDLECallback(huart);                          //调用中断处理函数}}
}/* USER CODE END PFP */

第四步:加入到中断函数内

void USART1_IRQHandler(void)
{/* USER CODE BEGIN USART1_IRQn 0 *//* USER CODE END USART1_IRQn 0 */HAL_UART_IRQHandler(&huart1);/* USER CODE BEGIN USART1_IRQn 1 */USER_UART_IRQHandler(&huart1);/* USER CODE END USART1_IRQn 1 */
}

在这里插入图片描述

第四步:简单数据解析功能

(1)加入接收部分代码

我们收到什么数据,就发出什么数据,因为在回调函数里,不能再用DMA发送了,但可以堵塞发出。

在这里插入图片描述

(2)加入处理部分代码

我们将数据收到后,如果数据对了,我们只是将数据复制一份,处理不在回调内做,以免拖慢回调。
在这里插入图片描述

(3)测试代码

这里这里发放出成功接收并解析代码,处理后发送出来,就是如果接收到数据“123”,那么返回数据“ABC”。
在这里插入图片描述

4、代码连接

(1)中断接收

代码链接:https://download.csdn.net/download/qq_22146161/88500425

(2)DMA收发

代码链接:https://download.csdn.net/download/qq_22146161/88500428

5、注意细节

(1)总是多个字符,或者多个其它字符。

实际测试中发现,总会多个0x0D数字,不知道哪里来的,多次检查后,发现其实之前有发送,因为进入空闲中断后,停止了造成这种奇特现象。
在这里插入图片描述
原因点如下:发现有奇怪数据时候,一定看看有没其它地方输出。
在这里插入图片描述

(2)复制函数的使用。

调试解析时候,我甚至将收到数据打印出来了,但是就是无法触发发送,才发现复制函数数组赋值那块弄错了,还是需要注意的。
在这里插入图片描述

(3)逻辑调试与测试。

在我们不清楚的情况,或者要测试逻辑时候,可以让其将数据打印出来了,帮助我们定位错的原因。如下图,我们不知道收到什么是数据时候,可以让其直接发回来,帮助我们判断,甚至,复制完数据后,成没成功,也可以打印出来。

在这里插入图片描述

(4)十进制的1与十六进制0x31。

我这里代码有时候说“123”,有时候又说0x31,0x32,0x33,其实这是他们进制表示不同,一个是十进制,一个是十六进制,比如,十进制的1等同于十六进制0x31,跟ascii码对照表有关系。

(5)不同串口工具,有些信息不显示。

不同上位机串口工具,在使用的时候有差异的,如果不切换到16进制进行显示,我也不会发现十六进制的0x0D,后来发现这个其实是换行符‘\n’。
在这里插入图片描述

(6)数据解析注意

开始自己看之前的文章的时候,没主要,就发了数据“12”,发现不回,检查后,才知道,数据为12的时候,只复制,不在while进行发送,这点给忘了。
在这里插入图片描述
在这里插入图片描述
如下错误,为只输入了“12”
在这里插入图片描述

(7)初始化顺序不对,不运行

需要将DMA初始化,放在uart前在这里插入图片描述

(8)回调函数写的有问题,只返回一个字符

在这里插入图片描述

(9)在网上找到样例,进行测试,没有成功

在这里插入图片描述

总结

再次调试相同东西,再简单东西,也有细节值得记录吧~~~。

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

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

相关文章

shiro 框架使用学习

简介 Shiro安全框架是Apache提供的一个强大灵活的安全框架Shiro安全框架提供了认证、授权、企业会话管理、加密、缓存管理相关的功能,使用Shiro可以非常方便的完成项目的权限管理模块开发 Shiro的整体架构 1、Subject ​ Subject即主体(可以把当前用户…

微信小程序将后端返回的图片文件流解析显示导页面

说明 由于请求接口后端返回的图片格式不是一个完整的url,也不是其他直接能显示的图片格式,是一张图片 后端根据模板与二维码生成图片,返回二进制数据 返回为文件流的格式,用wx.request请求的时候,就自动解码成为了下面这样的数据数据格式,这样的数据没…

idea文件比对

idea文件比对 1.项目内的文件比对2.项目间的文件比对3. 剪切板对比4. 版本历史(不同分支和不同commit)对比 1.项目内的文件比对 在项目中选择好需要比对的文件(类),然后选择Compare Files Mac下的快捷键是Commandd, 这样的比对像是git冲突解决一样 …

STM32 GPIO 描述

一、GPIO功能描述 每个GPIO端口有两个32位配置寄存器(GPIOx_CRL,GPIOx_CRH) ,两个32位数据寄存器 (GPIOx_IDR和GPIOx_ODR) ,一个32位置位/复位寄存器(GPIOx_BSRR),一个16位复位寄存器(GPIOx_BRR)和一个32位锁定寄存器(GPIOx_LCKR…

Flutter:安装依赖报错doesn‘t support null safety

项目中需要引用http依赖,在pubspec.yaml文件中添加如下信息: 当同步时,报错信息如下: [myflutter] flutter pub upgrade Resolving dependencies... The current Dart SDK version is 3.1.3. Because myflutter depends on http &…

【leetcode】19.删除链表的倒数第 N 个结点

题目 给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点。 示例 1: 输入:head [1,2,3,4,5], n 2 输出:[1,2,3,5] 示例 2: 输入:head [1], n 1 输出:[] 示例 3&a…

校园安防监控系统升级改造方案:如何实现设备利旧上云与AI视频识别感知?

一、背景与需求分析 随着现代安防监控科技的兴起和在各行各业的广泛应用,监控摄像头成为众所周知的产品,也为人类的工作生活提供了很大的便利。由于科技的发达,监控摄像头的升级换代也日益频繁。每年都有不计其数的摄像头被拆掉闲置&#xf…

R语言爬虫代码模版:技术原理与实践应用

目录 一、爬虫技术原理 二、R语言爬虫代码模板 三、实践应用与拓展 四、注意事项 总结 随着互联网的发展,网络爬虫已经成为获取网络数据的重要手段。R语言作为一门强大的数据分析工具,结合爬虫技术,可以让我们轻松地获取并分析网络数据。…

【网络】五中IO模型介绍 + 多路转接中select和poll服务器的简单编写

高级IO 前言正式开始前面的IO函数简单过一遍什么叫做低效的IO钓鱼的例子同步IO和异步IO五种IO模型阻塞IO非阻塞IO信号驱动多路转接异步IO 小结 代码演示非阻塞IO多路转接select介绍简易select服务器timeout 为 nullptrtimeout 为 {0, 0}timeout 为 {5, 0}调用accept select编写…

ACmix:卷积和self-attention的结合,YOLOv5改进之ACmix

目录 一、ACmix理论部分 二、代码 三、YOLOv5改进 ACC3 一、ACmix理论部分 论文地址:2111.14556.pdf (arxi

【Database System Concept 7th】Chapter 24 Advanced Indexing Techniques 读书笔记

Chapter 24 Advanced Indexing Techniques 24.5 Hash Indices24.5.1 Static Hashing24.5.2 Dynamic Hashing24.5.2.1 Data Structure24.5.2.2 Queries and Updates 24.5 Hash Indices 24.5.1 Static Hashing 这一部分就不介绍了,在14.5中已经介绍过了。 24.5.2 D…

javascript中的new原理及实现

在js中,我们通过new运算符来创建一个对象,它是一个高频的操作。我们一般只是去用它,而很少关注它是如何实现的,它的工作机制是什么。 1 简介 本文介绍new的功能,用法,补充介绍了不加new也同样创建对象的方…

部署kubevirt教程

前提条件 已安装:kubernetes集群、kubectl、docker apt install -y qemu-kvm libvirt virt-install bridge-utils 【所有节点全部安装】 virt-host-validate qemu部署kubevirt 下载kubevirt-cr.yaml和kubevirt-operator.yaml 先执行: Kubectl apply …

047_第三代软件开发-日志分离

第三代软件开发-日志分离 文章目录 第三代软件开发-日志分离项目介绍日志分离用法 关键字: Qt、 Qml、 log、 日志、 分离 项目介绍 欢迎来到我们的 QML & C 项目!这个项目结合了 QML(Qt Meta-Object Language)和 C 的强…

LLM之幻觉(一):大语言模型幻觉解决方案综述

论文题目:《Cognitive Mirage: A Review of Hallucinations in Large Language Models》 ​论文链接:https://arxiv.org/abs/2309.06794v1 论文代码:https://github.com/hongbinye/cognitive-mirage-hallucinations-in-llms 一、幻觉介绍 …

编写软件产品使用说明书的重要技巧分享

编写软件产品使用说明书是确保用户能够准确了解和使用你的软件的重要一步。一份清晰、详尽的软件产品使用说明书不仅可以提高用户满意度,也能减少用户的疑惑和困惑。然而,要编写一份优秀的软件产品使用说明书并不容易。接下来就跟大家分享一些我的经验和…

《学懂java》:java基础篇

他们都告诉你,必须要做什么,却没告诉你为什么。 ##《 欢迎访问我的网站,ai工具箱,https://4398ai.com里面有免费的chatgpt网站,和很多免费的编程资源的干货》 首先说一下接口,抽象(abstract)&a…

vue实现商品列表,组件抽离

1.需求说明 my-tag 标签组件封装 ​ (1) 双击显示输入框,输入框获取焦点 ​ (2) 失去焦点,隐藏输入框 ​ (3) 回显标签信息 ​ (4) 内容修改,回车 → 修改标签信息 my-table 表格组件封装 ​ (1) 动态传递表格数据渲染 ​ (2) 表头支…

15 款 PDF 编辑器帮助轻松编辑、合并PDF文档

PDF 编辑器在当今的数字环境中至关重要,因为 PDF 已成为共享和存储信息的首选格式。只需几分钟,可靠的 PDF 编辑器即可让用户能够根据其特定需求修改、定制和定制文档。在本文中,我们全面汇编了 15 款最佳免费 PDF 编辑器,让您可以…

Javaweb之HTML,CSS的详细解析

2.4 表格标签 场景:在网页中以表格(行、列)形式整齐展示数据,我们在一些管理类的系统中,会看到数据通常都是以表格的形式呈现出来的,比如:班级表、学生表、课程表、成绩表等等。 标签&#xff…