STM32F103C8T6 HAL库 printf重定向 USART1 DMA方式发送数据

前言:

        在上一篇文章里,我采用printf重定向为usart1,但是这样发送,对于MPU的负载比较大,所以本篇文章采用DMA方式,解放MPU资源,去做其他的事情,这里仅做为自己的记录。

正文开始:

        Cubemx配置

        先是在Cubemx里对单片机进行配置,跟上一篇文章同样的配置

        增加DMA通道,并且将RX引脚置为上拉模式,因为本次只是作为发送,所以,这里也可以不把RX置为上拉模式,

        配置DMA,保持默认配置即可,可以根据自己的项目需求,将自己的优先级进行调整。

                这里已经是默认勾选了DMA中断,这里只将USART1的中断使能勾选上

        并且将RX引脚设置为上拉模式,因为在选择异步通信后,CubeMX会自动配置引脚的工作模式。这时的默认配置是不打开上下拉。这可能会使引脚在悬空状态时电平不确定,产生误接收。我们把RX接收引脚,修改为:上拉(Pull-up),给引脚固定一个弱上拉,以避免悬空时产生误接收。

        有些同学第一次会找不到如何将RX设置为上拉模式,按照我的箭头指示即可。

        至此,我们的配置部分基本完成,点击生辰代码即可。

        代码部分:

        在KEIL中新建文件夹USART_DMA.c和USAR_DMA.h文件。代码如下

        USART_DMA.c

#include "USART_DMA.h"
#include "stdio.h"
#include "stdarg.h"volatile uint8_t  usart_dma_tx_over = 1;int myprintf(const char *format,...)
{va_list arg;static char SendBuff[200] = {0};int rv;while(!usart_dma_tx_over);//等待前一次DMA发送完成va_start(arg,format);rv = vsnprintf((char*)SendBuff,sizeof(SendBuff)+1,(char*)format,arg);va_end(arg);HAL_UART_Transmit_DMA(&huart1,(uint8_t *)SendBuff,rv);usart_dma_tx_over = 0;//清0全局标志,发送完成后重新置1return rv;
}void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)
{if(huart->Instance==USART1){usart_dma_tx_over = 1;}
}//要用的时候,直接可以
//myprintf("num:%d\r\n",i++);	
//HAL_Delay(1000);

        USART_DMA.h

#ifndef __USART_DMA_H
#define __USART_DMA_H#include "main.h"
#include "usart.h"int myprintf(const char *format,...);
void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart);#endif

        使用的话,只要在while循环里添加myprintf即可。

        代码解释:

        这里我用到的是DMA传输,用到的函数是

HAL_UART_Transmit_DMA (&huart1, uint8_t *pData, uint16_t Num); 

        参数分别是选用的串口,数据地址(字符串数字形式的内容),发送的字节数。

        与HAL_UART_Transmit_IT (&huart1,  uint8_t *pData,  uint16_t Num);(中断发送)的区别在于100个字节,会产生100次中断。这个DMA发送函数,全程只产生一次中断。

        与HAL_UART_Transmit (&huart1,  uint8_t *pData,  uint16_t Num,  超时值);(阻塞式发送)区别在于阻塞式发送每发送一个字节,死等,好了继续发下一个,再死等,不断重复。就是以前标准库种那最普通的死等法,只是它增加了一个超时值。其中超时值的功能:如果指定时间内没发送完毕,就直接返回,防止卡死。数据发送通信需时间:1秒 ÷ 波特率 × 字节数 × 10 × 1000ms。举例:115200波特率,100字节,大约用时 9ms

        调用后,函数给DMA数据地址,DMA就自动开始搬砖,它会把数据逐字节搬运到串口的DR寄存器上,等串口发送完这个字节了,再自动搬运下一个,过程完全不占用程序运行资源。搬完了,就产生一个中断,给程序打个招呼。通常,我们程序上,把这个“招呼”也省略了,不用理会它。

        我们在串口的中断回调函数中,直接将标志位清零,然后等待下次将数据发送出去。

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

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

相关文章

web前端的实习记录:探索、挑战与成长

web前端的实习记录:探索、挑战与成长 踏入web前端实习的旅程,我怀揣着对未知的好奇与对技术的渴望,开始了一段全新的学习与实践。在这个过程中,我经历了四个方面的技术探索,五个方面的挑战应对,六个方面的…

Halcon 双相机标定与拼图(二)

一、概述 这种标定有两种模式,有一个标定板和多个标定板两种 一个标定板 两个相机的重叠区域比较大,那么我们可以把标定板放到那个重叠区域来统一坐标系,如下 这种是只需要一个标定板,这种是推荐的方式 。这种是比较简单的&…

第二十节:带你梳理Vue2:Vue子组件向父组件传参(事件传参)

1. 自定义事件 除了可以处理原生的DOM事件, v-on指令也可以处理组件内部触发的自定义的事件,调用this.$emit()函数就可以触发一个自定义事件 $emit() 触发事件函数接受一个自定义事件的事件名以及其他任何给事件函数传递的参数. 然后就可以在组件上使用v-on来绑定这个自定义事…

启动游戏出现concrt140.dll错误的解决方法

concrt140.dll是一个动态链接库文件,属于Microsoft Visual C 2015 Redistributable组件集的一部分。这个文件是并发运行时库(Concurrency Runtime)的一部分,对于支持和增强应用程序的多线程与并发执行能力至关重要。它包含了实现并…

基于Python+Flask框架实现的新冠疫情可视化的设计与实现

基于PythonFlask框架实现的新冠疫情可视化的设计与实现 “Design and Implementation of COVID-19 Visualization using Python Flask Framework” 完整下载链接:基于PythonFlask框架实现的新冠疫情可视化的设计与实现 文章目录 基于PythonFlask框架实现的新冠疫情可视化的设…

Python:处理矩阵之NumPy库(中)

目录 前言 1.onse函数 2.diag函数 3.random函数 4.rand函数 5.randn函数 6.randint函数 7.shape函数 8.reshape函数 9.resize函数 10.flatten函数 11.hstack函数 12.vstack函数 前言 本文章是续《Python:处理矩阵之NumPy库(上)》的第二篇文章…

Java实现简单词法、语法分析器

1、词法分析器实现 词法分析器是编译器中的一个关键组件,用于将源代码解析成词法单元。 词法分析器的结构与组件: 通常,词法分析器由两个主要组件构成:扫描器(Scanner)和记号流(Token Stream&a…

003-两台交换机堆叠(IRF)

两台交换机堆叠(IRF) 概念 IRF (Intelligent Resilient Framework) 是华为公司提出的一种交换机堆叠技术,它允许用户将多台物理交换机设备连接在一起,从而逻辑上形成一个单一的、统一的、大容量的虚拟交换机。IRF堆叠技术通过堆…

抽象java入门1.3.1

前言: 本期内容是为了更好补充关于方法(函数)的定义 开始: 函数(function)表示每个输入值对应唯一输出值的一种对应关系。 核心在于:输入值和输出值这两个元素 真的吗? 错&…

【自动部署】4.阿里云ECS服务器 IDEA自动部署项目

如何在IDEA中,自动部署项目到阿里云ECS服务器?今天我们就来实现一键部署功能。 执行maven命令打包免密登录,在IEDA中连接服务器执行stop服务上传jar包到服务器执行start脚本查看运行日志1.安装Alibaba Cloud Toolkit 2.配置host 3.自动化部署后端 右击项目,选择Alibaba CL…

第一篇红队笔记-百靶精讲之W1R3S-john

https://download.vulnhub.com/w1r3s/w1r3s.v1.0.1.zip 主机发现 nmap端口扫描及思路 扫描某个网段 扫描单个ip所有端口 重复扫描单个ip具体端口 udp协议再来一次 漏洞扫描 FTP渗透 尝试匿名登陆 防止文件损坏 识别加密方式-hash-identifier base64 Web目录爆破…

C#操作MySQL从入门到精通(19)——插入数据

前言: 谈到数据库,大家最容易脱口而出的就是增删改查,在本篇文章之前一直都是说的各种查询,本文就是说的增删改查中的增,所谓增也就是增加数据的意思,插入数据就是增加数据。 本文测试使用的数据库如下: 1、插入完整行 所谓插入完整行就是一行所有列的数据都是自己插…

C++中的常见I/O方式

目录 摘要 1. 标准输入输出(Standard I/O) 2. 文件输入输出(File I/O) 3. 字符串流(String Stream) 4. 低级文件I/O(Low-level File I/O) 5. 内存映射文件(Memory-…

《精通ChatGPT:从入门到大师的Prompt指南》第4章:避免常见错误

第4章:避免常见错误 在使用ChatGPT进行Prompt编写时,常见的错误可能会大大影响生成内容的质量和准确性。本章将详细讨论这些错误,并提供如何避免它们的建议。 4.1 不明确的指令 在使用ChatGPT时,一个常见的问题是指令不够明确。…

理解数仓建模

​​​在数仓建设的过程中,由于未能完全按照规范操作, 从而导致数据仓库建设比较混乱,常见有以下问题: 数仓常见问题 ● 数仓分层不清晰:数仓的分层没有明确的逻辑,难以管理和维护。 ● 数据域划分不明确…

[数据集][目标检测]高空抛物数据集VOC+YOLO格式259张+6段视频+yolov8模型+探讨

这个是从6段简短抛物视频里面截取的259张图片用labelImg进行标注得到提供voc和yolo格式以供大家训练和研究。目录我已经提供了yolov8s训练好的模型和训练日志,如果不想训练的可以直接用我这个模型即可,选择使用best.pt或last.pt即可。目录结构&#xff1…

【网络编程开发】10.UNIX套接字域

10.UNIX套接字域 UNIX域套接字是用于在同一台计算机上运行的进程之间进行通信的一种机制。它与传统基于TCP/IP协议栈的套接字不同,UNIX域套接字操作更为高效,因为它避免了网络层的开销,不涉及网络报头、检验和、顺序号等复杂的网络协议处理过…

ANSYS APDL中使用SF和SFFUN命令,对不同节点施加不同大小的面载荷

SF命令通常是对 所选择的节点集合 施加同样大小的载荷,如: NSEL, S, LOC, Y, 5 ! 选择y坐标值为5的全部结点 SF, ALL, PRES, 1 ! 施加均布荷载 完整命令流: Finish !退出当前处理器 /Clear,al…

websocket发送数据

1. 使用JSON格式传输参数 可以使用库如Jackson或Gson来处理JSON。 客户端发送JSON消息: var socket new WebSocket("ws://localhost:8080/ws"); socket.onopen function() {var message {"action": "greet","name": …

tensorRT 自定义算子plugin的实现

文章目录 1. 自定义算子导出onnx1.1 自定义算子的实现类1.2 自定义算子类1.3 onnx导出2. 自定义算子plugin的实现2.1 Plugin类的实现2.1.1 构造函数的实现2.1.2 析构函数实现2.1.3 serialize函数的实现2.1.4 destory函数的实现2.1.5 enqueue函数的实现(关键)2.1.5.1 customSc…