[转]STM32 串口传输处理方式 FreeRTOS+队列+DMA+IDLE (二)

2023-05-16

紧接着上一篇文章,如何合理处理多个串口接收大量数据。此种方法,很厉害,很NB,首先,利用DMA 可节省大量CUP资源。其次,利用IDLE空闲中断来接收位置个数的数据。最后利用串口DMA环形数据的偏移量、长度,入队,出队处理数据。保证了任务的流畅处理。
串口接收数据:
中心思想
1、开启DMA 环形接收数据模式。
2、触发接收数据中断。
3、假如数据有进来,将上面环形数据的偏移量与长度 入队。
4、出队函数,处理数据。

直接上代码
两个任务完成

#define MAX_FRAME_DISP_LEN       125       #define MAX_FRAME_DISP_ITEM      5         #define MaxSize_FRAME_DISP    (MAX_FRAME_DISP_LEN*MAX_FRAME_DISP_ITEM)  static void RecUart1Temp_Task(void* parameter){		uint16_t len;	uint16_t ndtr_last;//上次剩余个数	BufferLoopData_Typedef buffer_loop;	BaseType_t xReturn = pdPASS;	 	buffer_loop.start_addr = 0;	buffer_loop.len = 0;	ndtr_last = MaxSize_FRAME_DISP;        while (1)        {           //等待有数据消息	   xReturn = xSemaphoreTake(BinarySem_Handle,  portMAX_DELAY); 	   len = Reg_Usart1_CHANNEL_CNDTR;//DMA剩余个数	   //环形数组	   if (ndtr_last != len)//上次与这次不同,表示有新数据	   {		buffer_loop.start_addr = buffer_loop.start_addr + buffer_loop.len;                //环形数据地址偏移量		if (buffer_loop.start_addr >= MaxSize_FRAME_DISP)		{		     buffer_loop.start_addr = buffer_loop.start_addr - MaxSize_FRAME_DISP;		}			if (ndtr_last > len)		{		    buffer_loop.len = ndtr_last - len;                    //接收数据长度=上次长度-这次长度		}		else		{		    buffer_loop.len = MaxSize_FRAME_DISP  - len+ ndtr_last;                    //环形数据到头后,总数-这次剩余+上次剩余		} 		ndtr_last = len;							if ((buffer_loop.len > 0)||(buffer_loop.len < MAX_FRAME_DISP_LEN))		{			xQueueSendToBack(xQueue_Smrj_rx,(void *)&buffer_loop,0);		}            	}	taskYIELD();        	    }} 

任务出队,处理函数

extern  uint8_t rxbuf_Uart1_DMA[MaxSize_FRAME_DISP]; static void RecUart1DealTask(void* pvParameters){    uint16_t i;    BufferLoopData_Typedef buffer_loop;       for (;;)    {        xQueueReceive(xQueue_Smrj_rx,&buffer_loop,portMAX_DELAY);          if ((buffer_loop.len > 0)&&(buffer_loop.len < MAX_FRAME_DISP_LEN))        {            for (i=0;i= MaxSize_FRAME_DISP)                {                    buffer_loop.start_addr = buffer_loop.start_addr - MaxSize_FRAME_DISP;                }                rxbuf_Uart1_tmp[i] = rxbuf_Uart1_DMA[buffer_loop.start_addr];                                buffer_loop.start_addr += 1;                 }                  __nop();            /*此处处理接收的数据*/            //Smrj_RecUserHandle(&rxbuf_Uart1_tmp[0],buffer_loop.len);	    //SMRJ_Data_Dec(&rxbuf_Smrj_tmp[0],buffer_loop.len);        }        taskYIELD();     }  }

中断处理函数:

void USART1_IRQHandler(void){     uint32_t ulReturn;     ulReturn = taskENTER_CRITICAL_FROM_ISR();     if(USART_GetITStatus(DEBUG_USARTx,USART_IT_IDLE)!=RESET)        {				Uart_DMA_Rx_Data();   		USART_ReceiveData(DEBUG_USARTx); 		taskEXIT_CRITICAL_FROM_ISR( ulReturn );         }} void Uart_DMA_Rx_Data(void){	BaseType_t pxHigherPriorityTaskWoken;	DMA_Cmd(USART_RX_DMA_CHANNEL, DISABLE);      	DMA_ClearFlag( DMA1_FLAG_TC5 );                  Reg_Usart1_CHANNEL_CNDTR=  USART_RX_DMA_CHANNEL->CNDTR;//循环数组里剩余个数	DMA_Cmd(USART_RX_DMA_CHANNEL, ENABLE);       	xSemaphoreGiveFromISR(BinarySem_Handle,&pxHigherPriorityTaskWoken);		portYIELD_FROM_ISR(pxHigherPriorityTaskWoken);} 

串口初始化见上面一篇文章
总结,从上面代码我们可以看到,我们是巧妙的利用的串口DMA环形模式,利用队列来处理数据。
下一篇,我们直接利用环形缓存buf来实现数据的处理,是的更加的通用性。

————————————————
版权声明:本文为CSDN博主「断雁孤鸿」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/oDuanYanGuHong/article/details/100576160

---------------------
作者:ba_wang_mao
来源:CSDN
原文:https://blog.csdn.net/ba_wang_mao/article/details/103817626?utm_medium=distribute.pc_relevant.none-task-blog-2defaultbaidujs_title~default-0.pc_relevant_default&spm=1001.2101.3001.4242.1&utm_relevant_index=2
版权声明:本文为作者原创文章,转载请附上博文链接!
内容解析By:CSDN,CNBLOG博客文章一键转载插件

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

[转]STM32 串口传输处理方式 FreeRTOS+队列+DMA+IDLE (二) 的相关文章

  • 当一个任务写入变量而其他任务读取该变量时,我们是否需要信号量?

    我正在研究 freeRtos 并且我有一个名为 x 的变量 现在 每秒只有一个任务正在写入该变量 而其他任务正在读取该变量值 我需要用互斥锁来保护变量吗 如果变量为 32 位或更小 并且其值是独立的并且不与任何其他变量一起解释 则不需要互斥
  • 毕业设计 江科大STM32的智能温室控制蓝牙声光报警APP系统设计

    基于STM32的智能温室控制蓝牙声光报警APP系统设计 1 项目简介 1 1 系统构成 1 2 系统功能 2 部分电路设计 2 1 stm32f103c8t6单片机最小系统电路设计 2 2 LCD1602液晶显示电路设计 2 2 风
  • 在 Atollic TrueStudio、STM32CubeMX 中导入 C 库

    我目前正在开发 STM32F767ZI Nucleo 板和一个小安全芯片 microchip atecc508a 通过 i2c 连接进行连接 该芯片有一个可用的库加密验证库 https github com MicrochipTech cr
  • 最终启动顺序错误 - STM32L476 的 Eclipse System Workbench 调试

    我正在尝试调试和运行 STM32L476 的简单汇编代码 我已经设置了 Eclipse Oxygen 在 Eclipse 中安装了最新版本的 System Workbench 插件并安装了 ST Link 驱动程序 IDE 成功构建了程序
  • 串口通讯第一次发送数据多了一字节

    先初始化IO再初始化串口 导致第一次发送时 多出一个字节数据 优化方案 先初始化串口再初始化IO 即可正常通讯
  • 串口通讯第一次发送数据多了一字节

    先初始化IO再初始化串口 导致第一次发送时 多出一个字节数据 优化方案 先初始化串口再初始化IO 即可正常通讯
  • 1.69寸SPI接口240*280TFT液晶显示模块使用中碰到的问题

    1 69寸SPI接口240 280TFT液晶显示模块使用中碰到的问题说明并记录一下 在网上买了1 69寸液晶显示模块 使用spi接口 分辨率240 280 给的参考程序是GPIO模拟的SPI接口 打算先移植到FreeRtos测试 再慢慢使用
  • 启用 DMA 的 UART Tx 模式

    我已经为 UART 在传输模式下编写了一个简单的设备驱动程序 并启用了 DMA 和中断 我使用的硬件是 omap 4460 pandaboard 其中加载了 Linux 3 4 下面我分享一下相关部分的代码 在开放阶段 dma map io
  • CMSIS & STM32,如何开始? [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我想在 STM32 上使用 CMSIS 启动项目 网上一搜 没找到具体的教程 有些使用 SPL 开始项
  • FreeRTOS 匈牙利表示法 [重复]

    这个问题在这里已经有答案了 我是 RTOS 和 C 编程的新手 而且我仍在习惯 C 的良好实践 因此 我打开了一个使用 FreeRTOS 的项目 我注意到操作系统文件使用匈牙利表示法 我知道一点符号 但面临一些新的 标准 FreeRTOS
  • Cortex-M3与M4权威指南

    处理器类型 所有的ARM Cortex M 处理器是32位的精简指令集处理器 它们有 32位寄存器 32位内部数据路径 32位总线接口 除了32位数据 Cortex M处理器也可以有效地处理器8位和16位数据以及支持许多涉及64位数据的操作
  • 从没有中断引脚并且在测量准备好之前需要一些时间的传感器读取数据的最佳方法

    我正在尝试将压力传感器 MS5803 14BA 与我的板 NUCLEO STM32L073RZ 连接 根据 第 3 页 压力传感器需要几毫秒才能准备好读取测量值 对于我的项目 我对需要大约 10 毫秒来转换原始数据的最高分辨率感兴趣 不幸的
  • STM32 上的 ADC 单次转换

    我正在研究 STM32 F103x 上的 ADC 编程 并从最简单的情况 单次转换开始 测量内部温度传感器 连接到 ADC1 的值 并使用 USART 将其发送到 COM 端口 目标似乎很明确 但是当我尝试将源代码下载到闪存时 它不会向 C
  • STM32 上的位置无关代码 - 指针

    我已成功在 STM32 上构建并运行位置无关的代码 向量表和 GOT 已修补 一切正常 但我对这样的代码有问题 double myAdd double x return x 0 1 double ptrmyAdd double myAdd
  • PWM DMA 到整个 GPIO

    我有一个 STM32F4 我想对一个已与掩码进行 或 运算的 GPIO 端口进行 PWM 处理 所以 也许我们想要 PWM0b00100010一段时间为 200khz 但随后 10khz 后 我们现在想要 PWM0b00010001 然后
  • GNU Arm Cortex m4 上的 C++ 异常处理程序与 freertos

    2016 年 12 月更新现在还有一个关于此行为的最小示例 https community nxp com message 862676 https community nxp com message 862676 我正在使用带有 free
  • 使用 STM32 USB 设备库将闪存作为大容量存储设备

    我的板上有这个闪存IC 它连接到我的STM32F04 ARM处理器 处理器的USB端口可供用户使用 我希望我的闪存在通过 USB 连接到 PC 时被检测为存储设备 作为第一步 我在程序中将 USB 类定义为 MSC 效果很好 因为当我将主板
  • 哪些变量类型/大小在 STM32 微控制器上是原子的?

    以下是 STM32 微控制器上的数据类型 http www keil com support man docs armcc armcc chr1359125009502 htm http www keil com support man d
  • GCC 变量映射和 MISRA-C

    我主要知道两种使用 GCC 声明内存映射寄存器的方法 有许多变体 使用双字段 每个外设的数据结构等 要么使用初始化为正确地址的指针 例如volatile uint32 t pMyRegister uint32 t 0xDEADBEEFUL
  • 读取STM32 MCU SPI数据寄存器的值

    有很多类似的问题 但似乎没有一个问题完全相同 我正在将 STML4 MCU 连接到 6 轴传感器 LSM6DS3 我已经成功地在 I2C 中实现了所有内容 但想要 SPI 的额外速度 和 DMA 如果我能让这些第一步工作起来的话 因此 第一

随机推荐

  • 【图像识别与处理】构建用于垃圾分类的图像分类器

    1 构建图像分类器 训练一个卷积神经网络 xff0c 用fastai库 xff08 建在PyTorch上 xff09 将图像分类为纸板 xff0c 玻璃 xff0c 金属 xff0c 纸张 xff0c 塑料或垃圾 使用了由Gary Thun
  • kitti数据集各个榜单介绍

    kitti数据集网站 下面我们分别介绍下KITTI的几项benchmark Stereo Stereo Evaluation xff08 立体评估 xff09 基于图像的立体视觉和3维重建 xff0c 从一个图像中恢复结构本质上是模糊的 x
  • 解决ubuntu20.04虚拟机无法上网的问题

    64 linux虚拟机无法正常上网 前言 刚建立好的linux虚拟机使用NAT方式可以连接外网 xff0c 系统重启几次 xff0c 系统无法上网 xff0c 这是什么问题导致的呢 xff1f 提示 xff1a 以下是本篇文章正文内容 xf
  • [Linux] 使用vim保存文件时报E45错误

    今天在使用vim为Linux系统设置静态IP时 xff0c 报了E45错误 xff1a 环境说明 系统 xff1a Ubuntu18 04 操作步骤 1 打开到静态IP配置文件 打开到netplan目录 cd etc netplan amp
  • 【C++】类和对象-继承

    目录 一 继承基本方式 1 公 共 继 承 2 保 护 继 承 3 私 有 继 承 二 继承中的对象模型 三 继承中的构造和析构顺序 四 继承中同名成员处理方式 1 成员变量的处理方式 2 成员函数的处理方式 五 继承同名静态成员处理方式
  • Pytorch param.grad.data. 出现 AttributeError: ‘NoneType‘ object has no attribute ‘data‘

    程序中有需要优化的参数未参与前向传播
  • 大白话谈谈ChatGPT:多点人工,多点智能

    对于NLP领域 xff0c 本人也是门外汉 xff0c 就是最近了看到的博文 xff0c 记录自己的一些体会 ChatGPT简介 ChatGPT的全称是 34 Conversational Generative Pre training T
  • GO如何查看变量大小和数据类型

    如何查看一个变量的大小和数据类型 如何查看一个变量的大小和数据类型 paceage main import 34 fmt 34 34 unsafe 34 var n2 int64 61 10 fmt Printf 34 n2的类型 T n2
  • GO语言百分号参数

    常用 参数 v 值的默认格式 T 值得类型的GO语法表示 t 单词true或者false b 表示为二进制 c 该值对应的unicode码值 d 表示十进制 o 表示八进制 f 有小数部分但无指数部分 q 双引号输出
  • java第八节-重复执行

    import java util Scanner public class hello public static void main String args for System out println 34 hello 34 impor
  • java基础第九节-跳转控制语句-数组

    continue用在循环中 xff0c 基于条件控制 xff0c 跳过某次循环体内容的执行 xff0c 继续下一次的执行 break用在循环中 xff0c 基于条件控制 xff0c 终止循环体内容的执行 xff0c 结束当前的整个循环 数组
  • JAVA基础-基本类型转换

    int 和string的相互转换 1 int转换String public static String valuesOf int i 返回int参数的字符串表示形式 xff0c 该方法是String类的方法 1 String转换int pu
  • ubuntu系统-查看系统版本信息

    cat etc issue
  • Ubuntu查看cpu使用情况

    top命令查看cpu等信息 id是 xff1a 空闲 CPU 占用的 CPU 百分比
  • Ubuntu系统查看内存信息

    free命令查看内存信息 h 选项会在数字后面加上适于可读的单位 free h total xff1a 总物理内存大小 used xff1a 内存使用量 free xff1a 剩余可用内存
  • 嘉立创打样的阻抗匹配

    一 适用条件 最好使用4层板以上 xff0c 2层做匹配没啥意义 xff0c 套用大佬的话 主要是中间层和表层的距离近 xff0c 表层和中间层的玻璃纤维厚度是0 2mm xff0c 双层板最少是0 6mm xff0c 这里的差距很大 xf
  • echo 命令总结

    echo命令的功能是在显示器上显示一段文字 xff0c 一般起到一个提示的作用 此外 xff0c 也可以直接在文件中写入要写的内容 也可以用于脚本编程时显示某一个变量的值 xff0c 或者直接输出指定的字符串 echo命令的语法是 xff1
  • Android音频子系统(十三)------audio音频测试工具

    你好 xff01 这里是风筝的博客 xff0c 欢迎和我一起交流 测试音频延时的话 xff0c 一般使用WALT来测试是最为准确的 xff0c 他是借助了外部硬件来捕获音频信号 xff0c 某宝上有卖 xff1a 就是有丢丢小贵 xff0c
  • 一位北邮信通硕士的求职历程,看看 或许有帮助

    序 xff1a 写在前面的话 这篇文章的适用对象为 xff1a 非技术类方向的同学 xff0c 如果你是技术大牛 xff0c 你可以跳过这篇文章了 如果你觉得自己不喜欢技术或者技术不适合你 xff0c 此文或许会给你些有用的东西 简单介绍一
  • [转]STM32 串口传输处理方式 FreeRTOS+队列+DMA+IDLE (二)

    紧接着上一篇文章 xff0c 如何合理处理多个串口接收大量数据 此种方法 xff0c 很厉害 xff0c 很NB xff0c 首先 xff0c 利用DMA 可节省大量CUP资源 其次 xff0c 利用IDLE空闲中断来接收位置个数的数据 最