当前位置: 首页 > news >正文

基于STM32L431+Liteos的串口空闲中断加DMA循环接收

①MCU为STM32L431,使用串口2。
②Liteos采用接管中断的方式。

STM32CubeMX配置生成串口代码:
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
串口DMA接收和发送配置区别是接收采用循环模式,发送为正常模式。

将生成的代码移植到liteos工程中,由于使用的接管中断的方式,所以使能中断的时候需要先注册中断。

    HAL_NVIC_SetPriority(USART2_IRQn, 1, 0);HAL_NVIC_EnableIRQ(USART2_IRQn);HAL_NVIC_SetPriority(DMA1_Channel6_IRQn, 1, 0);HAL_NVIC_EnableIRQ(DMA1_Channel6_IRQn);HAL_NVIC_SetPriority(DMA1_Channel7_IRQn, 2, 0);HAL_NVIC_EnableIRQ(DMA1_Channel7_IRQn);改为:uvIntSave = LOS_IntLock();LOS_HwiCreate(USART2_IRQn,1,(HWI_MODE_T)0,(HWI_PROC_FUNC)USART2_IRQHandler,(HWI_ARG_T)0);LOS_HwiCreate(DMA1_Channel6_IRQn,1,(HWI_MODE_T)0,(HWI_PROC_FUNC)DMA1_Channel6_IRQHandler,(HWI_ARG_T)0);LOS_HwiCreate(DMA1_Channel7_IRQn,2,(HWI_MODE_T)0,(HWI_PROC_FUNC)DMA1_Channel7_IRQHandler,(HWI_ARG_T)0);		LOS_IntRestore(uvIntSave);

创建一个事件标志组,并用其中的一位来表示串口接收到数据。

	#define ZigbeeUartIdle    (0x01<<0)#define ZigbeeUartRecv    (0x01<<1)UINT32 uwRet  = LOS_OK;uwRet = LOS_EventInit(&SysEventGroup);if(uwRet != LOS_OK){PRINT_ERR("Event Error Code:0x%X\n",uwRet);return uwRet;}

串口初始化函数中使能串口接收:

	__HAL_UART_CLEAR_IDLEFLAG(&huart2);  HAL_UARTEx_ReceiveToIdle_DMA(&huart2, (uint8_t*)Usart2RxBuf, USART2_RX_BUFFER_LEN);

不要使用HAL_UART_Receive_DMA函数,直接使用HAL_UARTEx_ReceiveToIdle_DMA函数,该函数会以DMA方式接收一定数量的数据,直到收到预期数量的数据或者发生IDLE事件时会产生中断,这样的话在中断服务函数中可以直接调用回调函数,去处理DMA接收的数据。
在这里插入图片描述
串口的中断服务函数:

void ClearError(UART_HandleTypeDef *huart)
{uint32_t isrflags   = READ_REG(huart->Instance->ISR);uint32_t errorflags;/* If no error occurs */errorflags = (isrflags & (uint32_t)(USART_ISR_PE | USART_ISR_FE | USART_ISR_ORE | USART_ISR_NE));if (errorflags != 0U)	{__HAL_UART_CLEAR_FLAG(&huart2, UART_CLEAR_OREF | UART_CLEAR_NEF | UART_CLEAR_PEF | UART_CLEAR_FEF);}
}void USART2_IRQHandler(void)
{ClearError(&huart2);HAL_UART_IRQHandler(&huart2);
}

在中断服务函数中调用ClearError是为了防止因为上溢错误或者帧错误导致一直进入中断服务函数中,所以在处理中断事件时先把错误清除。

如果在初始化串口的时候注册了DMA通道的中断的话,当使用DMA发送数据时半发送或者发送完成时,都会进入DMA通道中断,同样的在接收数据的时候当收到定义的缓冲区一半或者接收满时也会进入DMA通道中断。

void DMA1_Channel6_IRQHandler(void)
{HAL_DMA_IRQHandler(&hdma_usart2_rx);
}void DMA1_Channel7_IRQHandler(void)
{HAL_DMA_IRQHandler(&hdma_usart2_tx);
}

使用DMA发送数据完成会调用HAL_UART_TxCpltCallback回调函数,可以在这里表示串口空闲。

/*** @brief  Tx Transfer completed callback* @param  UartHandle: UART handle. * @note   This example shows a simple way to report end of DMA Tx transfer, and *         you can add your own implementation. * @retval None*/
void HAL_UART_TxCpltCallback(UART_HandleTypeDef *UartHandle)
{/* Set transmission flag: transfer complete*/LOS_EventWrite(&SysEventGroup,ZigbeeUartIdle);
}

当发生空闲中断的时候会调用HAL_UARTEx_RxEventCallback函数来处理,函数参数Size表示接收到的字节数,如果使用的循环模式,那么传进来的Size会自动循环。比如定义的接收缓冲区共有56个字节,第一次产生空闲中断时接收20字节,Size大小为20,第二次产生空闲中断时接收20字节,Size大小为40,第三次产生空闲中断时接收20字节,Size大小为4。

Usart2RxLen为一个全局变量,用来表示任务在每次处理数据时需要处理的数据长度,比如第一次收到20字节,任务立刻处理,那么会在任务中把Usart2RxLen清零;如果第一次收到20字节,任务没有处理,第二次又收到20字节,Usart2RxLen会累加,那么这个时候任务需要从接收缓存区中读取的数据长度就是40。RecvOnce是一个静态的全局变量,用来记录上次执行HAL_UARTEx_RxEventCallback函数时传入的Size值,以此来区分本次空闲中断产生时,接收的数据有没有从头开始,从而正确的计算出本次接收到数据的长度。

volatile uint16_t Usart2RxLen = 0;
static uint16_t RecvOnce = 0;
/*** @brief  Reception Event Callback (Rx event notification called after use of advanced reception service).* @param  huart UART handle* @param  Size  Number of data available in application reception buffer (indicates a position in*               reception buffer until which, data are available)* @retval None*/
void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)
{if(huart->Instance == USART2){LOS_EventWrite(&SysEventGroup,ZigbeeUartRecv);//通知任务接收到数据if(Size > RecvOnce){PRINT_INFO("size = %d\r\n",Size-RecvOnce);Usart2RxLen = (Usart2RxLen + Size - RecvOnce) % USART2_RX_BUFFER_LEN;		}else{PRINT_INFO("size = %d\r\n",(USART2_RX_BUFFER_LEN - RecvOnce + Size));Usart2RxLen = (Usart2RxLen+(USART2_RX_BUFFER_LEN - RecvOnce + Size)) % USART2_RX_BUFFER_LEN;	}	RecvOnce = Size;}
}

任务中读取数据:

void Process_Task(void)
{UINT32 uwRet = LOS_OK; UINT16 msglen = 0;UINT8 msg[USART2_RX_BUFFER_LEN];while(1){uwRet = LOS_EventRead(&SysEventGroup,ZigbeeUartRecv,LOS_WAITMODE_AND | LOS_WAITMODE_CLR,0);if(uwRet & ZigbeeUartRecv){msglen = Usart2RxLen;Usart2RxLen = 0;//待处理数据长度清零memset(msg,0x00,USART2_RX_BUFFER_LEN);if((msglen + DealAddr) <= USART2_RX_BUFFER_LEN){memcpy(msg,&Usart2RxBuf[DealAddr],msglen);}else{memcpy(msg,&Usart2RxBuf[DealAddr],(USART2_RX_BUFFER_LEN - DealAddr));memcpy(&msg[USART2_RX_BUFFER_LEN - DealAddr],Usart2RxBuf,(msglen+DealAddr-USART2_RX_BUFFER_LEN));}DealAddr = (DealAddr+msglen) % USART2_RX_BUFFER_LEN;HAL_UART_Transmit_DMA(&huart2,msg,msglen);}LOS_TaskDelay(LOS_MS2Tick(50));//50ms轮询一次}
}

任务处理串口数据的周期是50ms,使用LOS_EventRead读取事件标志的时候超时时间设置为0,作用相当于轮询状态后直接返回,处理数据的时候使用DealAddr变量来记录上次处理之后的位置,通过(msglen + DealAddr)的值和接收缓冲区的长度比较,来确定读取数据的方式,并使用HAL_UART_Transmit_DMA函数来完成数据回环测试。

接收缓冲区的长度是56,可以看到在第三次和第六次接收的时候,一帧数据调用了两次HAL_UARTEx_RxEventCallback函数,这是因为DMA通道产生了半接收(28)和接收完成中断(56),但是对一帧数据的接收没有影响。
在这里插入图片描述
如果不想有这种情况,可以不使能串口RX绑定的DMA通道中断。
在这里插入图片描述
模拟串口收到一帧数据,但是任务没有处理数据,又来一帧时一起处理。
在这里插入图片描述

相关文章:

基于STM32L431+Liteos的串口空闲中断加DMA循环接收

①MCU为STM32L431&#xff0c;使用串口2。 ②Liteos采用接管中断的方式。 STM32CubeMX配置生成串口代码&#xff1a; 串口DMA接收和发送配置区别是接收采用循环模式&#xff0c;发送为正常模式。 将生成的代码移植到liteos工程中&#xff0c;由于使用的接管中断的方式&#…...

BZOJ4403 序列统计

题目描述 给定三个正整数N、L和R&#xff0c;统计长度在1到N之间&#xff0c;元素大小都在L到R之间的单调不降序列的数量。输出答案对106310^631063取模的结果。 输入 输入第一行包含一个整数T&#xff0c;表示数据组数。 第2到第T1行每行包含三个整数N、L和R&#xff0c;N、…...

如何正确使用 钳位二极管

在电路设计中,经常遇到需要IO保护的场景,比如ADC采样,GPIO接收电平信号等。 常见的保护方法有分压,限幅,限流等。本次我们讨论限幅方法中的 钳位二极管。 我们以BAT54S为例,它的符号是这样的, 而在很多手册里,我们可以看到,一般是这样使用的: 因此,我设计了简化…...

【C语言进阶】动态内存管理

&#x1f466;个人主页&#xff1a;Weraphael ✍&#x1f3fb;作者简介&#xff1a;目前是C语言学习者 ✈️专栏&#xff1a;C语言航路 &#x1f40b; 希望大家多多支持&#xff0c;咱一起进步&#xff01;&#x1f601; 如果文章对你有帮助的话 欢迎 评论&#x1f4ac; 点赞&a…...

第一批因ChatGPT坐牢的人,已经上路了

大家好&#xff0c;我是 Jack。 ChatGPT 的火爆有目共睹&#xff0c;有人靠着它赚了第一桶金&#xff0c;也有人靠着它即将吃上第一顿牢饭。 任何一件东西的火爆&#xff0c;总会给一些聪明人带来机会。 艾尔登法环火的时候&#xff0c;一堆淘宝卖魂的&#xff1b;羊了个羊火…...

Eclipse下Maven的集成

Eclipse下Maven的集成 2.1指定本地maven环境 参考&#xff1a;Eclipse的Maven创建_叶书文的博客-CSDN博客_eclipse创建maven项目 指定用本地maven指定maven仓库设置和地址2.2创建maven项目 1.新建 2.目录设置 3.坐标设置&#xff08;随便写就行&#xff09; 4.目录结构 2.3配置…...

Elasticsearch7学习笔记(尚硅谷)

文章目录一、ElasticSearch概述1、ElasticSearch是什么2、全文搜索引擎3、ElasticSearch 和 Solr3.1 概述3.2 比较总结二、Elasticsearch入门1、Elasticsearch安装1.1 下载使用1.2 数据格式2、索引操作3、文档操作&#xff08;了解&#xff09;3.1 创建文档3.2 文档查询3.3 文档…...

前端学习第一阶段-第7章 品优购电商项目

7-1 品优购项目介绍及准备工作 01-品优购项目导读 02-网站制作流程 03-品优购项目规划 04-品优购项目搭建 05-品优购项目-样式的模块化开发 06-品优购项目-favicon图标制作 07-品优购项目-TDK三大标签SEO优化 7-2 首页Header区域实现 08-品优购首页-快捷导航shortcut结构搭建 0…...

cocos2dx 4.0 - cpp - pc版 环境搭建

开发环境vs2022 cocos2dx4.0 python2.7.18 cmake3.25安装教程&#xff08;环境搭建&#xff09;安装VS2022-Community&#xff0c; 勾选c进行安装安装cmake3.25, 勾选环境变量进行安装安装python2.7.18, 勾选环境变量进行安装下载cocos2dx4.0并解压配置cocos2dx:运行cmd,进入…...

剑指 Offer 53 - I. 在排序数组中查找数字 I

原题链接 难度&#xff1a;easy\color{Green}{easy}easy 题目描述 统计一个数字在排序数组中出现的次数。 示例 1: 输入: nums [5,7,7,8,8,10], target 8 输出: 2示例 2: 输入: nums [5,7,7,8,8,10], target 6 输出: 0提示&#xff1a; 0<nums.length<1050 <…...

华为OD机试 - 删除指定目录(Python) | 机试题算法思路 【2023】

最近更新的博客 华为OD机试 - 热点网络统计 | 备考思路,刷题要点,答疑 【新解法】 华为OD机试 - 查找单入口空闲区域 | 备考思路,刷题要点,答疑 【新解法】 华为OD机试 - 好朋友 | 备考思路,刷题要点,答疑 【新解法】 华为OD机试 - 找出同班小朋友 | 备考思路,刷题要点…...

PowerShell Install Office 2021 Pro Plus Viso Professional

前言 微软Office在很长一段时间内都是最常用和最受欢迎的软件。从小型创业公司到大公司,它的使用比例相当。它可以很容易地从微软的官方网站下载。但是,微软只提供安装程序,而不提供完整的软件供下载。这些安装文件通常比较小。下载并运行后,安装的文件将从后端服务器安装M…...

KubeSphere实战

文章目录一、KubeSphere平台安装1、Kubernetes上安装KubeSphere1.1 安装docker1.2 安装Kubernetes1.3 前置环境之nfs存储1.4 前置环境之metrics-server1.5 安装KubeSphere2、Linux单节点部署KubeSphere3、Linux多节点部署KubeSphere(推荐)二、KubeSphere实战1、多租户实战2、中…...

Linux 简介

Linux 内核最初只是由芬兰人林纳斯托瓦兹&#xff08;Linus Torvalds&#xff09;在赫尔辛基大学上学时出于个人爱好而编写的。 Linux 是一套免费使用和自由传播的类 Unix 操作系统&#xff0c;是一个基于 POSIX 和 UNIX 的多用户、多任务、支持多线程和多 CPU 的操作系统。 …...

java面试题-泛型异常反射

泛型1.什么是泛型&#xff1f;Java是一种强类型语言&#xff0c;数据类型在编译时必须确定。如果我们想要在代码中使用不同类型的数据&#xff0c;那么就需要为每种类型分别写出相应的代码。这样会导致代码冗长、重复&#xff0c;也不便于维护。为了解决这个问题&#xff0c;Ja…...

详细解读ChatGPT:如何调用ChatGPT的API接口到官方例子的说明以及GitHub上的源码应用和csdn集成的ChatGPT

文章目录1. 解读ChatGPT1.1 词语解释1.2 功能解读2. GitHub上ChatGPT的应用源码3. 调用ChatGPT的API4. 官方例子说明5. 集成ChatGPT自ChatGPT出来到如今&#xff0c;始终走在火热的道路上&#xff0c;如今日活用户破亿&#xff0c;他为何有如此大的魅力&#xff0c;深受广大用户…...

九龙证券|最新评级情况出炉,机构扎堆这一板块!聚氨酯龙头获得最多关注

本周算计254家上市公司获组织“买入型”评级。 电子板块评级组织扎堆 证券时报数据宝计算&#xff0c;2月13日至17日&#xff0c;A股市场53家组织算计进行347次评级&#xff0c;254家上市公司获“买入型”评级&#xff08;包含买入、增持、强烈推荐、推荐&#xff09;。 从申…...

考研复试机试 | C++ | 尽量不要用python,很多学校不支持

目录1.1打印日期 &#xff08;清华大学上机题&#xff09;题目&#xff1a;代码&#xff1a;1.2改一改&#xff1a;上一题反过来问题代码&#xff1a;2.Day of Week &#xff08;上交&&清华机试题&#xff09;题目&#xff1a;代码&#xff1a;3.剩下的树&#xff08;清…...

ChatGPT时代,别再折腾孩子了

今天这篇完全是从两件事儿有感而发。昨天在文印店&#xff0c;在复印机上看到装订好的几页纸&#xff0c;我瞥了一眼&#xff0c;是历史知识点&#xff1a;隋朝大运河分为四段&#xff0c;分别是___ ___ ___ ___&#xff0c;连接了五大河___ ___ ___ ___ ______ 年&#xff…...

万字干货 | 荔枝魔方基于云原生的架构设计与实践

近年来&#xff0c;荔枝集团在国内和海外的业务迅速发展&#xff0c;业务数据规模也是成几何式地增长&#xff0c;海量数据的计算分析场景、业务智能算法应用需求随之而生&#xff0c;为了快速地满足业务发展的需要&#xff0c;我们面临着诸多的技术挑战。技术挑战工程问题资源…...

#科研筑基# python初学自用笔记 第九篇 面向对象编程

面向对象编程 Object Oriented Programming &#xff0c;简称OOP&#xff0c;是一种程序设计思想&#xff0c;这种思想把对象作为程序的基本单元。类是抽象的&#xff0c;对象是具体的&#xff0c;一种类包括其特定的数据或属性&#xff0c;以及操作数据的函数&#xff08;方法…...

Python快速上手系列--邮件发送--详解篇

本章就来一起学习一下跑完自动化脚本后如何自动的发送邮件到指定的邮箱。zmail操作&#xff1a;1. 导包 import zmail2. 邮件内容&#xff0c;包含&#xff1a;主题(subject)、正文(content_text)、附件(attachments)3. 发件人信息&#xff0c;包含&#xff1a;发件人账号&…...

【Bluetooth开发】蓝牙开发入门

BLE 蓝牙设备在生活中无处不在&#xff0c;但是我们也只是将其作为蓝牙模块进行使用&#xff0c;发送简单的AT命令实现数据收发。 那么&#xff0c;像对于一些复杂的使用场合&#xff1a;“车载蓝牙”、"智能手表"、“蓝牙音箱”等&#xff0c;我们不得不去了解底层…...

07:进阶篇 - 在程序中嵌入 CTK Plugin Framework

作者: 一去、二三里 个人微信号: iwaleon 微信公众号: 高效程序员 如果已经创建了一个应用程序,现在要将 CTK Plugin Framework 嵌入其中,该如何进行呢? 下面,以《06:进阶篇 - Hello,CTK!》中的插件为例,来演示如何使用 CTK Plugin Framework 来加载插件并获取特定…...

快速低成本动画视频课

快速低成本动画视频课Character Animator能做什么如何用character animator制作动画视频Animate能做什么Adobe Animate和Character Animator结合&#xff0c;如何快速制作低成本动画视频课Character Animator能做什么 Character Animator是Adobe公司的一个动画制作软件&#x…...

大数据平台测试-软件测试常见面试回答(持续更新)

面试造航母&#xff0c;入职拧螺丝。面试&#xff0c;讲点面试官想听的。。。 1、你有过漏测的经历吗&#xff1f; 答&#xff1a;这道题肯定是回答有。然后展开描述。就类似面试官问 你印象比较深的一个bug。。。 测试无穷尽&#xff0c;质量也并非测试一个岗位的责任&…...

链表学习之反转链表

链表解题技巧 额外的数据结构&#xff08;哈希表&#xff09;&#xff1b;快慢指针&#xff1b;虚拟头节点&#xff1b; 反转链表 分别实现单向链表和双向链表的反转。 要求&#xff1a;长度为N的链表&#xff0c;时间复杂度为O(N)&#xff0c;额外空间复杂度为O(1)。 反转…...

ONNXRUNTUIME实例分割网络说明

ONNXRUNTUIME c使用&#xff08;分割网络&#xff09;与相关资料&#xff08;暂记&#xff09; initiate a env with an id name(使用id名称启动env) create session (创建会话 ) onnxenv -> sessioninputname [“x”] ,outputname [“t”]inputnodedim [[1,1,192,192…...

几行代码,就写完懒加载啦?

Ⅰ、前言 「懒加载」是网页中非常 常见的&#xff1b;为了减少系统的压力&#xff0c;对于一些电商系统出场频率非常高&#xff1b;那么大家一般用什么方式去实现 「懒加载」 呢 &#xff1f; ① 通过 scroll 的形式&#xff1a; 通过 滚动「scroll」事件&#xff0c;然后去判…...

PyTorch常用的损失函数(ChatGPT)

L1Loss nn.L1Loss 也称为平均绝对误差&#xff08;Mean Absolute Error&#xff0c;MAE&#xff09;。它计算预测值与真实值之间的差异&#xff08;即误差&#xff09;&#xff0c;然后取绝对值并求和&#xff0c;最后除以样本数量得到平均误差。具体来说&#xff0c;对于一批…...

直播网站怎么做的/郑州网站建设公司哪家好

Bean的自动装配 自动装配说明 自动装配是使用spring满足bean依赖的一种方法 spring会在应用上下文中为某个bean寻找其依赖的bean。 Spring中bean有三种装配机制&#xff0c;分别是&#xff1a; 在xml中显式配置&#xff1b; 在java中显式配置&#xff1b; 隐式的bean发现机…...

lamp网站开发项目文档/中国推广网站

目前中国产业园区数量较多&#xff0c;同质化问题严重&#xff0c;相互之间竞争激烈。随着大数据时代的到来&#xff0c;大数据和社会经济的深度融合&#xff0c;产业园区将向智慧产业园区发展。 智慧园区是园区引入物联网、大数据、云计算等新技术进行全面数字化的基础之上&a…...

一个完整网站开发/汕头seo推广外包

每个 PAT 考生在参加考试时都会被分配两个座位号&#xff0c;一个是试机座位&#xff0c;一个是考试座位。正常情况下&#xff0c;考生在入场时先得到试机座位号码&#xff0c;入座进入试机状态后&#xff0c;系统会显示该考生的考试座位号码&#xff0c;考试时考生需要换到考试…...

wordpress代码编辑/南宁seo排名收费

当你搜索到pagehelper多表分页实现的时候&#xff0c;我想你对mybatis pagehelper插件的整合与使用已经没有问题了&#xff0c;你遇到的问题应该是List分页数据来源于多张表的时候&#xff0c;pagehelper分页失效了&#xff0c;所以本文只讲述pagehelper多表分页与普通分页细节…...

织梦网站如何做404/中国突然宣布一重磅消息

"," 逗号运算符可以完成两个语句的连接&#xff0c;完成相当于在一个语句中完成两个语句的任务。 但是以下情况不行&#xff0c;数据的初始化声明运用到“,”运算符只能完成一种数据的声明与初始化。 #include <iostream> using namespace std;int main(){int …...

做网站 用 显示器/网站改版

Ubuntu上进行php开发确实是一个不错的选择&#xff0c;但是搭建ApacheMySQLPHP环境对于新手来说并不是一件容易的事情。ubuntu之家给大家介绍一个linux下的集成环境XAMPP&#xff0c;只需要简单的几步安装即可使用。最新版的XAMPP for linux为1.8.0&#xff0c;包含的软件如下&…...