Stm32f103X HAL库 串口DMA空闲中断学习 踩坑记

捡 了一个Stm32f103X的工控板,

开发工具是 STM32cubeide  ,复制了之前闲的时候建的一个485通讯的空工程,只配置了圈中的引脚,用的是usart3 ,增加了需要用的io,编程器是网上几块钱买的jlink-ob,带模拟串口的.


 

在学习串口通信的过程中总感觉不太顺利 ,刚开始用串口中断接收的时候有时正常有时不正常 ,后来每次都多出来一个字节(最后多出  00),怀疑是编程器模拟串口有问题,于是换了一个CH340模块,换了之后,竟然无法通讯了.此时发现只有上位机用编程器模拟串口可以和工控板的usart3通讯,

此时为了对比测试启用了uart4, 同样的代码,模拟串口和ch340都可以和工控板正常通讯,没有多出00.对我来说这是一个好消息至少有一个是正常的.

学习用空闲中断接收的时候,同样的接收完的数据也会多出00,死活查不出原因,有了前面的经验,经过处理,也算是正常通讯了.

学习DMA空闲中断收发的时候就出大问题了,工控板只有第一次收到数据能正常响应,再发送就没反应了,以为是没再次启动DMA空闲中断收发导致的,根据网上的资料一点点查,确定没有遗漏相关代码.于时放断点跟踪 ,发现单步调试的时候工控板可以正常收发5次左右才没有响应.同样代码使用uart4很正常.

为了找原因 重新建工程使用了usart3和uart4两个串口做对比测试,十分正常正常的.于是我就怀疑是不是我拷485通讯空工程的时候有一个报错导致的.于是重新拷过一遍,编译后还是出来同样的问题,

后来终于想到会不会是电路上有些特殊,于是找来原理图,才发现配置了  DE  RE 两个引脚,于是复位了引脚 .再次编译测试.头疼的问题终于解决了...

附上DMA空闲中断接收的代码

定义接收数组等 

#define REC_LENGTH  1
#define MAX_REC_LENGTH  100struct COMM
{uint8_t Rx_flg;//USARTx接收完成标志uint8_t Rx_cnt;//USARTx接受数据计数器uint8_t timeOut;uint8_t Rx_temp[MAX_REC_LENGTH];//USARTx接收数据缓存uint8_t Rx_Buf[MAX_REC_LENGTH]; //USARTx存储接收数据uint8_t Tx_Buf[MAX_REC_LENGTH];
} ;extern struct COMM comm1, comm3,comm4;

启动DMA空闲中断,放main中

	  /* USER CODE BEGIN 2 *///启动串口DMA空闲中断接收HAL_UARTEx_ReceiveToIdle_DMA(&huart3, comm3.Rx_temp,MAX_REC_LENGTH);//关闭DMA半满中断__HAL_DMA_DISABLE_IT(&hdma_usart3_rx, DMA_IT_HT) ;/* USER CODE END 2 */

回调函数

void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)
{/* Prevent unused argument(s) compilation warning */UNUSED(huart);UNUSED(Size);//获取中断类型HAL_UART_RxEventTypeTypeDef RxEventType = HAL_UARTEx_GetRxEventType(huart);if (huart==&huart3) {switch (RxEventType){case HAL_UART_RXEVENT_TC:// 传输完成事件printf("Reception Complete\r\n");break;case HAL_UART_RXEVENT_HT:// 半传输完成事件printf("Half Reception Complete\r\n");break;case HAL_UART_RXEVENT_IDLE:// 空闲事件printf("Idle Event Detected\r\n");comm3.Rx_flg=1;comm3.Rx_cnt=Size;memset(comm3.Rx_Buf,0x00,sizeof (comm3.Rx_Buf));memcpy(comm3.Rx_Buf,comm3.Rx_temp,Size);break;default:// 其他事件printf("Unknown Event\r\n");break;}//因为是normal模式再次开启DMA的空闲中断接收HAL_UARTEx_ReceiveToIdle_DMA(&huart3,comm3.Rx_temp,sizeof(comm3.Rx_temp));__HAL_DMA_DISABLE_IT(&hdma_usart3_rx, DMA_IT_HT) ;}

通讯出错后会进,在这里需要再次开启DMA空闲中断接收,不然就没响应了.

void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart)
{if(huart->Instance == USART3){// 接收发生错误后重启HAL_UARTEx_ReceiveToIdle_DMA(&huart3, comm3.Rx_temp,sizeof(comm3.Rx_temp)); __HAL_DMA_DISABLE_IT(&hdma_usart3_rx, DMA_IT_HT);          // 关闭DMA_IT_HT中断memset(comm3.Rx_Buf,0x00,sizeof (comm3.Rx_Buf));           // 清除接收缓存}printf("HAL_UART_ErrorCallback\r\n");
}

网上有网友推荐放在这里,不会因为进不了回调函数导致通讯出错后不能自动恢复.

void USART3_IRQHandler(void)
{/* USER CODE BEGIN USART3_IRQn 0 *//* USER CODE END USART3_IRQn 0 */HAL_UART_IRQHandler(&huart3);/* USER CODE BEGIN USART3_IRQn 1 *///启动串口DMA空闲中断接收HAL_UARTEx_ReceiveToIdle_DMA(&huart3, comm3.Rx_temp,MAX_REC_LENGTH);__HAL_DMA_DISABLE_IT(&hdma_usart3_rx, DMA_IT_HT) ;/* USER CODE END USART3_IRQn 1 */
}

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

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

相关文章

云服务器部署WebSocket项目

WebSocket是一种在单个TCP连接上进行全双工通信的协议,其设计的目的是在Web浏览器和Web服务器之间进行实时通信(实时Web) WebSocket协议的优点包括: 1. 更高效的网络利用率:与HTTP相比,WebSocket的握手只…

PDF内容提取,MinerU使用

准备环境 # python 3.10 python3 -m pip install huggingface_hub python3 -m pip install modelscope python3 -m pip install -U magic-pdf[full] --extra-index-url https://wheels.myhloli.com下载需要的模型 import json import osimport requests from huggingface_hub…

掌握 Spring 事务管理:深入理解 @Transactional 注解

在业务方法上使用Transactional开启声明式事务时,很有可能由于使用方式有误,导致事务没有生效。 环境准备 表结构 CREATE TABLE admin (id bigint(20) unsigned NOT NULL AUTO_INCREMENT,username varchar(255) DEFAULT NULL,password varchar(255) …

设计模式之 观察者模式

观察者模式(Observer Pattern)是一种行为型设计模式,它定义了一种一对多的依赖关系,让多个观察者对象同时监听一个主题对象(Subject)。当主题对象的状态发生变化时,所有依赖于它的观察者都会得到…

【python】将word文档内容转换为excel表格

在日常工作中,我们经常需要将Word文档中的内容提取并转换为Excel表格,以便进行数据分析和处理。本文将介绍如何使用Python编写一个简单的程序,将Word文档中的内容转换为Excel表格。 一.实例 使用以下word文档作为例子: 工具界面如…

Linux|进程程序替换

目录 什么是进程替换 替换原理 exec函数 exec* 函数的共性 什么是进程替换 进程程序替换是指将一个进程中正在运行的程序替换为另一个全新的程序的过程,但替换不是创建新进程,只是将对应程序的代码和数据进行替换。具体来说,这个替换过程涉…

大数运算(加减乘除和输入、输出模块)

为什么会有大数呢?因为long long通常为64位范围约为 -9,223,372,036,854,775,808 到 9,223,372,036,854,775,807,最多也就19位,那么超过19位的如何计算呢?这就引申出来大数了。 本博客适合思考过这道题,但是没做出来或…

IntelliJ+SpringBoot项目实战(四)--快速上手数据库开发

对于新手学习SpringBoot开发,可能最急迫的事情就是尽快掌握数据库的开发。目前数据库开发主要流行使用Mybatis和Mybatis Plus,不过这2个框架对于新手而言需要一定的时间掌握,如果快速上手数据库开发,可以先按照本文介绍的方式使用JdbcTemplat…

flex布局 昵图网【案例】

效果展示 只是个大概&#xff0c;可自己完善。 昵图网 代码展示 <body><!-- https://static.ntimg.cn/original/images/soso.png --><div class"container"><div class"header"><!-- <div class"logo"><i…

[第五空间 2021]pklovecloud 详细题解

知识点: 构造POP链 PHP类的作用域 NULL强比较 目录穿越 源码如下: <?php include flag.php; class pkshow { function echo_name() { return "Pk very safe^.^"; } } class acp { protected $cinder; public $neutron;public $n…

dockerfile构建Nginx镜像练习二(5-2)

环境准备&#xff1a; (1)保证拥有centos基础镜像 docker images | grep centos (2)服务器保证可以连接外网 1.创建工作目录 mkdir nginx cd nginx 2.在工作目录中创建并编写Dockerfile文件 vim dockerfile #定义基础镜像 FROM centos:7#维护者信息(可缺省) MAINTAINER d…

Android Surfaceflinger显示图层合成方式

Android SurfaceFlinger是Android系统中负责窗口管理和图像合成的核心组件。它接收来自不同应用的图层数据&#xff0c;并将这些图层合并成一个单一的图像&#xff0c;然后输出到显示设备上。SurfaceFlinger的合成方式主要涉及两种&#xff1a;Client合成和Device合成。 adb s…

wsl安装

一. wsl简介 1. wsl和wsl2的区别 wsl需要把linux命令翻译为windows命令&#xff0c;性能差一些。 wsl2直接使用linux内核&#xff0c;不需要翻译&#xff0c;性能好&#xff0c;但开销相对大一点&#xff0c;因为需要多运行一个hyper-v虚拟机 (并非完整的虚拟机&#xff0c;是…

任务通知的本质(任务通知车辆运行) 软件定时器的本质(增加游戏音效)

任务通知的本质 没有任务通知 所谓"任务通知"&#xff0c;你可以反过来读"通知任务"。 我们使用队列、信号量、事件组等等方法时&#xff0c;并不知道对方是谁。使用任务通知时&#xff0c;可 以明确指定&#xff1a;通知哪个任务。 使用队列、信号量、…

Kubernetes的pod控制器

文章目录 一&#xff0c;什么是pod控制器二&#xff0c;pod控制器类型&#xff08;重点&#xff09;1.ReplicaSet2.Deployment3.DaemonSet4.StatefulSet5.Job6.Cronjob 三&#xff0c;pod与控制器的关系1.Deployment2.SatefulSet2.1StatefulSet组成2.2headless的由来2.3有状态服…

【单元测试】【Android】JUnit 4 和 JUnit 5 的差异记录

背景 Jetbrain IDE 支持生成 Test 类&#xff0c;其中选择JUnit5 和 JUnit&#xff0c;但是感觉这不是标准的单元测试&#xff0c;因为接口命名吧。 差异对比 两者生成的单测API名称同原API&#xff0c;没加test前缀的。使用差异主要表现在&#xff1a; setUp &#xff06; …

知识中台在多语言客户中的应用

在全球化的商业环境中&#xff0c;企业面临着多语言客户服务的挑战。HelpLook知识中台作为一种智能化解决方案&#xff0c;为企业提供了一个强大的工具&#xff0c;以实现多语言客户服务的自动化和优化。 一、多语言客户服务的重要性 多语言客户服务对于跨国企业至关重要&…

使用 Elastic AI Assistant for Search 和 Azure OpenAI 实现从 0 到 60 的转变

作者&#xff1a;来自 Elastic Greg Crist Elasticsearch 推出了一项新功能&#xff1a;Elastic AI Assistant for Search。你可以将其视为 Elasticsearch 和 Kibana 开发人员的内置指南&#xff0c;旨在回答问题、引导你了解功能并让你的生活更轻松。在 Microsoft AI Services…

【K8S问题系列 |18 】如何解决 imagePullSecrets配置正确,但docker pull仍然失败问题

如果 imagePullSecrets 配置正确&#xff0c;但在执行 docker pull 命令时仍然失败&#xff0c;可能存在以下几种原因。以下是详细的排查步骤和解决方案。 1. 检查 Docker 登录凭证 确保你使用的是与 imagePullSecrets 中相同的凭证进行 Docker 登录&#xff1a; 1.1 直接登录…

Redis的特性ubuntu进行安装

文章目录 1.六大特性1.1内存存储数据1.2可编程1.3可扩展1.4持久化1.5集群1.6高可用1.7速度快 2.具体应用场景&#xff08;了解&#xff09;3.Ubuntu安装Redis3.1安装指令3.2查看状态3.3查找配置文件3.4修改文件内容3.5重启服务器生效3.6安装客户端并进行检查 4.Redis客户端介绍…