STM32-UART-DMA HAL库缓冲收发

文章目录

    • 1、说明
      • 1.1、注意事项:
      • 1.2、接收部分
      • 1.3、发送部分
    • 2、代码
      • 2.1、初始化
      • 2.2、缓冲接收
      • 2.3、缓冲发送
      • 2.4、格式化打印

1、说明

1.1、注意事项:

  • HAL库的DMA底层基本都会默认开启中断使能,如果在STM32CubeMx禁用了中断相关的功能,程序可能会进入空中断回调出不来。
  • 切记使用STM32-HAL库的DMA发送时需要开启USART中断和DMA中断。
  • 在一般时间要求不是很高很高的场合,使用HAL库自带的函数就可以,并不会很频繁的触发中断占用资源。

1.2、接收部分

  • 接收DMA初始化成循环传输模式。开启对应DMA通道中断和串口全局中断
  • 之前担心开启串口中断会在接收数据时连续触发中断、导致消耗CPU资源,实际HAL底层未开启接收中断,不会触发中断。

1.3、发送部分

  • 发送时如果要使用DAM功能,必须开启DMA中断和串口中断。HAL的全局状态需要在中断中得到更新,否则会发送完一次状态一直处于被占用中。
  • HAL底层开启了串口数据发送完成中断TC。该中断只有在DMA没有新的数据传入后,并且移位寄存器为空时才会触发一次,不会每发送一个字节就会触发中断

在这里插入图片描述


在这里插入图片描述

2、代码

2.1、初始化

初始化接收即可,发送会在有数据时才会去操作DMA
开启中断


在这里插入图片描述


在这里插入图片描述

 
#include "SEGGER_RTT.h"

#define TX_FIFO_SIZE 36
#define RX_FIFO_SIZE 128

static uint8_t rxbuff[RX_FIFO_SIZE];
static uint8_t txbuff[TX_FIFO_SIZE];

static uint16_t tx_tail = 0;
static uint16_t tx_head = 0;

2.2、缓冲接收

循环接收、需要开启DMA和UART中断

void dma_uart_init()
{
  HAL_UART_Receive_DMA(&huart1, rxbuff, RX_FIFO_SIZE);
}
///查询读取一个字节数据
int dma_uart_read_char()
{
  static int rx_tail = 0;
  int rx_head = (RX_FIFO_SIZE)-huart1.hdmarx->Instance->CNDTR; // 接收到的数据偏移量
  if (rx_head != rx_tail)
  {
    int ch = rxbuff[rx_tail++];
    if (rx_tail >= RX_FIFO_SIZE)
    {
      rx_tail = 0;
    }
    return ch;
  }
  return -1;
}

2.3、缓冲发送

单次DMA发送,需要开启DMA和UART中断

///查询状态并触发一次发送
static void dma_uart_write_trig()
{
  static int lock = 0;
  if (lock)//中断重入锁
    return;
  lock = 1;

  if (huart1.gState == HAL_UART_STATE_READY)
  {
    static uint8_t dma_tx_fifo[128];
    for (size_t n = 0; n < 128; n++)
    {
      if (tx_head != tx_tail)
      {
        dma_tx_fifo[n] = txbuff[tx_tail++];
        if (tx_tail >= TX_FIFO_SIZE)
          tx_tail = 0;
      }
      else
      {
        if (n > 0)
        {
          HAL_UART_Transmit_DMA(&huart1, dma_tx_fifo, n);
        }
        break;
      }
    }
  }
  lock = 0;
}

///DMA缓冲发送多个字节数据
void dma_uart_writes(const uint8_t *data, int size)
{
  for (size_t i = 0; i < size; i++)
  {
    uint16_t tmp = tx_head + 1;
    if (tmp >= TX_FIFO_SIZE)
    {
      tmp = 0;
    }
#if 0 // 丢弃新的数据
    if (tmp == tx_tail) // 数据溢出 发送慢于写入
    {
      break;  
    }
#else // 等待旧数据发送完
    if (tmp == tx_tail)
    {
      while (tmp == tx_tail)
      {
      }
    }
#endif
    txbuff[tx_head] = data[i];
    tx_head = tmp;
  }
  dma_uart_write_trig();
}

///中断回掉函数,该函数由串口发送完成中断TC触发
void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)
{
  dma_uart_write_trig();
}

2.4、格式化打印

#include "stdarg.h"
#include "stdio.h"

#define PRINT_BUFF_SIZE 500
static char print_buff[PRINT_BUFF_SIZE];
void print_x(void *format, ...)
{
  va_list ap;
  va_start(ap, format);
  int n = vsnprintf(print_buff, PRINT_BUFF_SIZE, format, ap);
  va_end(ap);
  if (n > 0)
  {
    dma_uart_writes((uint8_t *)print_buff, n);
  }
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

PPT插件-好用的插件-PPT 素材该怎么积累-大珩助手

PPT 素材该怎么积累&#xff1f; 使用大珩助手中的素材库功能&#xff0c;将Word中的&#xff0c;或系统中的文本文件、图片、其他word文档、pdf&#xff0c;所有见到的好素材&#xff0c;一键收纳。 步骤&#xff1a;选中文件&#xff0c;按住鼠标左键拖到素材库界面中&…

[论文笔记] chatgpt系列 SparseMOE—GPT4的MOE结构

SparseMOE: 稀疏激活的MOE Swtich MOE,所有token要在K个专家网络中,选择一个专家网络。 显存增加。 Experts Choice:路由MOE:​​​​​​​ 由专家选择token。这样不同的专家都选择到某个token,也可以不选择该token。 由于FFN层的时间复杂度和attention层不同,FFN层的时…

Unity中URP Shader 的 SRP Batcher

文章目录 前言一、SRP Batcher是什么二、SRP Batcher的使用条件1、可编程渲染管线2、我们用URP作为例子3、URP 设置中 Use SRP Batcher开启4、使 SRP Batcher 代码路径能够渲染对象5、使着色器与 SRP Batcher 兼容&#xff1a; 三、不同合批之间的区别BuildIn Render Pipeline下…

WX小程序案例(一):弹幕列表

WXML内容 <!--pages/formCase/formCase.wxml--> <!-- <text>pages/formCase/formCase.wxml</text> --> <view class"bk bkimg"><!-- <image src"/static/imgs/ceeb653ely1g9na2k0k6ug206o06oaa8.gif" mode"scal…

Redis 的常见使用场景

01 缓存 作为 Key-Value 形态的内存数据库&#xff0c;Redis 最先会被想到的应用场景便是作为数据缓存。而使用 Redis 缓存数据非常简单&#xff0c;只需要通过 string 类型将序列化后的对象存起来即可&#xff0c;不过也有一些需要注意的地方&#xff1a; 必须保证不同对象的…

Cockpit upload文件上传漏洞(CVE-2023-1313)

0x01 产品简介 Cockpit 是一个自托管、灵活且用户友好的无头内容平台,用于创建自定义数字体验。 0x02 漏洞概述 Cockpit assetsmanager/upload接口处存在文件上传漏洞,攻击者可通过该漏洞在服务器端任意上传代码,写入后门,获取服务器权限,进而控制整个web服务器。 0x0…

springboot发送邮件,内容使用thymeleaf模板引擎排版

springboot发送邮件,内容使用thymeleaf模板引擎排版 1、导入jar包2、yml设置3、收件人以及收件信息设置4、发邮件service5、模版页面6、controller 1、导入jar包 <!--发送邮件--><dependency><groupId>org.springframework.boot</groupId><artifac…

lv12 linux内核的安装与加载

目录 1 tftp加载Linux内核及rootfs 1.1 uboot内核启动命令 1.2 uboot自启动参数环境变量 1.3 实验 2 EMMC加载Linux 内核及rootfs ​编辑 2.1 emmc中写入uimage ​编辑 2.2 emmc中写入dtb 2.3 emmc中写入根文件系统 2.4 设置环境变量 3 tftp加载Linux内核nfs挂载ro…

Tomcat-安装部署(源码包安装)

一、简介 Tomcat 是由 Apache 开发的一个 Servlet 容器&#xff0c;实现了对 Servlet 和 JSP 的支持&#xff0c;并提供了作为Web服务器的一些特有功能&#xff0c;如Tomcat管理和控制平台、安全域管理和Tomcat阀等。 简单来说&#xff0c;Tomcat是一个WEB应用程序的托管平台…

设计模式-策略(Strategy)模式

又被称为政策&#xff08;方针&#xff09;模式策略模式(Strategy Design Pattern)&#xff1a;封装可以互换的行为&#xff0c;并使用委托来决定要使用哪一个策略模式是一种行为设计模式&#xff0c;它能让你定义一系列算法&#xff0c;并将每种算法分别放入独立的类中&#x…

【从零开始学习--设计模式--装饰者模式】

返回首页 前言 感谢各位同学的关注与支持&#xff0c;我会一直更新此专题&#xff0c;竭尽所能整理出更为详细的内容分享给大家&#xff0c;但碍于时间及精力有限&#xff0c;代码分享较少&#xff0c;后续会把所有代码示例整理到github&#xff0c;敬请期待。 此章节介绍装…

【Jmeter】Jmeter基础5-Jmeter元件介绍之线程(用户)

2.5.1、线程组 一个线程组即一个虚拟用户组&#xff0c;线程组中的每个线程即为1个虚拟用户&#xff0c;每个线程互相隔离&#xff0c;互不影响参数说明&#xff1a; 在取样器错误后要执行的动作 继续&#xff1a;忽略错误&#xff0c;继续执行启动下一进程循环&#xff1a; 终…

12G全国30米高程DEM原始数据

但可能大部分朋友更关注国内范围的30米高程DEM原始数据有多大&#xff0c;以及数据的具体覆盖情况。 我们在这里&#xff0c;再为大家分享全国30米高程DEM原始数据的基本情况。 全国30米高程DEM原始数据 全国30米高程DEM原始数据共分1159个文件块&#xff0c;每个文件块在经…

Go delve调试工具的简单应用

Delve是个啥 Delve is a debugger for the Go programming language. The goal of the project is to provide a simple, full featured debugging tool for Go. Delve should be easy to invoke and easy to use. Chances are if you’re using a debugger, things aren’t go…

机器学习练习题

例1: 解&#xff1a; 最大似然估计&#xff1a; P &#xff08;男&#xff09; 8 / 20 0.4 &#xff0c; P &#xff08;女&#xff09; 12 / 20 0.6 P&#xff08;男&#xff09; 8/200.4&#xff0c;P&#xff08;女&#xff09; 12/20 0.6 P&#xff08;男&#xff0…

three.js模拟太阳系

地球的旋转轨迹目前设置为了圆形&#xff0c;效果&#xff1a; <template><div><el-container><el-main><div class"box-card-left"><div id"threejs" style"border: 1px solid red"></div><div c…

服务器被攻击宕机的一些小建议

现在网络攻击屡有发生&#xff0c;任何网站服务器都面临这样的危险&#xff0c;服务器被攻击造成的崩溃宕机是损失是我们无法估量的。网络攻击我们无法预测&#xff0c;但做好防御措施是必须的&#xff0c;建议所有的网站都要做好防范措施&#xff0c;准备相应的防护预案&#…

RT-DETR 目标过线计数

使用 Ultralytics RT-DETR 进行目标计数 🚀 实际应用场景 物流水产养殖使用 Ultralytics RT-DETR 进行传送带包裹计数使用 Ultralytics RT-DETR 在海中进行鱼类计数请使用最新代码(2023年12月8日后),旧版本不支持! 示例 “目标计数示例” 目标计数 from ultralytics

高并发如何实现单用户信息查询接口

高并发如何实现单用户信息查询接口 故事情节 产品&#xff1a;小李&#xff0c;有个单用户信息查询的功能&#xff0c;需要你实现一下小李&#xff1a;这还不简单&#xff0c;两分钟我给你实现两分钟过去…小李&#xff1a;欧克了&#xff0c;部署上线了运维&#xff1a;哪个…

git checkout进行更改分支

git clone https://gitee.com/yaleguo1/minit-learning-demo.git下载代码。 cd minit-learning-demo/进入目录里边。 ls -l看一下当前分支的内容。 git checkout geek_chapter02更改分支到geek_chapter02。 ls -l看一下目录里边的内容。
最新文章