STM32串口发送中断踩坑

article/2025/10/16 15:26:57

今天想测试下Modbus设备,手上暂时没有串口转485的模块,就打算用手上的stm32f042的开发板做个串口转485模块。如下所示
在这里插入图片描述

但是软件实际开发过程中,遇到了麻烦。

现象: 在打开串口接收中断时,串口会一直产生除接收中断外的其它中断,非常奇怪。

    USART_ITConfig(InitPort, USART_IT_RXNE, ENABLE); //使能接收中断

通过查手册发现,在打开接收中断时,默认会打开溢出中断
在这里插入图片描述
下面的方式是不能清除溢出中断标记。

   if (USART_GetFlagStatus(USART2, USART_FLAG_ORE) != RESET){USART_ClearFlag(USART2, USART_FLAG_ORE);}

可使用如下方式清除溢出中断,但是要使能溢出中断

USART_ITConfig(USART1, USART_IT_ORE, ENABLE); 

使用下面的方式清除溢出中断。

 if (USART_GetITStatus(USART2, USART_IT_ORE) == SET)  {USART_ClearITPendingBit(USART2,USART_IT_ORE);}

网上这篇文章也是不错的:http://news.eeworld.com.cn/mcu/article_2018060839675.html
虽然这种方式发送数据,暂时不会一直卡在中断里面,当发送长数据时,还是有时候会出现卡在中断里面的情况。如下我打印出了产生中断种类。
在这里插入图片描述
为此,在进入中断函数时,直接清理了中断标志,注意不要清理接收中断。

void  USART2_IRQHandler()
{USART_ClearITPendingBit(USART2,USART_IT_ORE);USART_ClearITPendingBit(USART2,USART_IT_IDLE);USART_ClearITPendingBit(USART2,USART_IT_TXE);USART_ClearITPendingBit(USART2,USART_IT_EOB);if( USART_GetITStatus(USART2,USART_IT_RXNE) != RESET ){  USART_ClearITPendingBit(USART2,USART_IT_RXNE);while((USART1->ISR&0x40) == 0);USART1->TDR = USART2->RDR;}
}

这样的话,串口2接收的数据,直接可以通过串口1转发。

完整的串口转485代码

void usart_config(uint8_t port,  uint32_t BaudRate)
{ USART_InitTypeDef USART_InitStructure;GPIO_InitTypeDef GPIO_InitStructure;NVIC_InitTypeDef NVIC_InitStructure;USART_TypeDef *InitPort = USART1;                           //默认是debug口RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);         //使能GPIOA的系统时钟if (port == 1) {RCC_APB2PeriphClockCmd (RCC_APB2Periph_USART1, ENABLE); //打开串口1串口时钟//GPIO MAPGPIO_PinAFConfig (GPIOA, GPIO_PinSource9, GPIO_AF_1);   //初始化GPIOA的PIN9为串口功能GPIO_PinAFConfig (GPIOA, GPIO_PinSource10, GPIO_AF_1);  //初始化GPIOA的PIN10为串口功能GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10; //初始化GPIOA PIN9,PIN10 口InitPort = USART1;NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;} else if (port == 2) {RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);  //打开串口2串口时钟//GPIO MAPGPIO_PinAFConfig(GPIOA, GPIO_PinSource2, GPIO_AF_1);     //初始化GPIOA的PIN2为串口功能;GPIO_PinAFConfig(GPIOA, GPIO_PinSource3, GPIO_AF_1);     //初始化GPIOA的PIN2为串口功能;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2 | GPIO_Pin_3;   //初始化GPIOA PIN2,PIN3 口InitPort = USART2;NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;}USART_DeInit (InitPort);/* Configure pins as AF pushpull */GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;                //串口GPIO复用功能GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;              //推挽输出GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;GPIO_Init (GPIOA, &GPIO_InitStructure);USART_InitStructure.USART_BaudRate = BaudRate;                  //模特率设置USART_InitStructure.USART_WordLength = USART_WordLength_8b;     //数据长度为8bitUSART_InitStructure.USART_StopBits = USART_StopBits_1;          //一个停止位USART_InitStructure.USART_Parity = USART_Parity_No;             //没有奇偶校验USART_InitStructure.USART_HardwareFlowControl =USART_HardwareFlowControl_None;                         //没有硬件流控,目前硬件没有引出USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //发送和接收工作模式USART_Init (InitPort, &USART_InitStructure);                    //串口使能USART_ITConfig(InitPort, USART_IT_RXNE, ENABLE); USART_ITConfig(USART1, USART_IT_ORE, ENABLE); USART_Cmd (InitPort, ENABLE);/* USART1 IRQ Channel configuration */NVIC_InitStructure.NVIC_IRQChannelPriority = 0x00;NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;NVIC_Init(&NVIC_InitStructure);
}void  USART1_IRQHandler()
{USART_ClearITPendingBit(USART1,USART_IT_ORE);USART_ClearITPendingBit(USART1,USART_IT_IDLE);USART_ClearITPendingBit(USART1,USART_IT_TXE);USART_ClearITPendingBit(USART1,USART_IT_EOB);if( USART_GetITStatus(USART1,USART_IT_RXNE) != RESET ){  USART_ClearITPendingBit(USART1,USART_IT_RXNE);while((USART1->ISR&0x40) == 0);USART2->TDR = USART1->RDR;}
}void  USART2_IRQHandler()
{USART_ClearITPendingBit(USART2,USART_IT_ORE);USART_ClearITPendingBit(USART2,USART_IT_IDLE);USART_ClearITPendingBit(USART2,USART_IT_TXE);USART_ClearITPendingBit(USART2,USART_IT_EOB);if( USART_GetITStatus(USART2,USART_IT_RXNE) != RESET ){  USART_ClearITPendingBit(USART2,USART_IT_RXNE);while((USART1->ISR&0x40) == 0);USART1->TDR = USART2->RDR;}
}

发送数据测试结果:
在这里插入图片描述
左边发送数据到右边。总共发送了28080个字符,但是接收了27841个字符,少接收了239个字符。
波特率为57600,每次发送184个字节,可以看到发送29256字符后,丢失2个字节。注意这里我在测试时一直电机发送按钮,没有等待。这个误码率还是可以接收。
在这里插入图片描述


http://chatgpt.dhexx.cn/article/aWQHNlMh.shtml

相关文章

STM32串口下载程序

STM32串口连接及下载程序 一、认识STM321、浅谈STM322、TTL串口与STM3连接 二、下载程序1、HEX文件生成2、烧录软件使用 三、总结四、参考文献 一、认识STM32 1、浅谈STM32 1、STM32型号的说明:以STM32F103RBT6这个型号的芯片为例,该型号的组成为7个部分&#xff…

STM32串口收发处理

STM32串口收发 STM32的串口接收和发送方式都有三种情况,即轮询、中断和DMA,俩俩组合便有9种可能的组合。 下面挑出其中三种收发方式进行研究,以及优缺点比较。 一、中断接收、轮询发送,无缓存模式 1.1 原理 当串口上有字节传送…

STM32 串口通讯及实现

目录 一、串口通讯概述1、广义的串口2、狭义的串口3、串口数据定义4、串口通讯应用 二、STM32串口工程标准库实现1、串口的初始化2、串口数据发送.3、串口的数据接收 一、串口通讯概述 1、广义的串口 广义的串口是针对并口来说的。串口是指设备之间通过一根数据信号线按数据位…

STM32串口配置

目录 串口设置的一般步骤: 1) 串口时钟使能,GPIO 时钟使能 2) 串口复位 3) GPIO 端口模式设置 4) 数据发送与接收 5) 串口状态 6) 使能串口 7) 开启串口响应中断 8.获取相应中断状态 串口设置的一般步骤: 1) 串口时钟使能&#xff0…

STM32串口详解

实验一:简单的利用串口接收中断回调函数实现数据的返回 关于串口调试助手,还应知道: 发送英文字符需要用一个字符即8位,发送汉字需要两个字符即16位,如上图,发送汉字“姜”实际是发送“BD AA”而发送英文字…

stm32串口实验

目录 (一)STM32 串口简介 (二)软件设计 (三)效果:​ 1.实现功能:STM32 通过串口和上位机的对话, STM32 在收到上位机发过来的字符串后,原原本本的返回给上位机。 (一&…

STM32 串口乱码

问题描述 用正点原子STM32F4探索者开发板调试野火骄阳电机驱动程序,发现串口输出一直是乱码。问题排查: 串口调试助手编码方式?同一个串口调试助手,用正点原子、STM32CubeMX生成的程序发送数据正常。排除串口调试助手问题。串口…

STM32串口通信编程

重庆交通大学信息科学与工程学院 《嵌入式系统基础A》课程 实验报告(2) 班 级: 物联网工程2002 姓名-学号 : 徐权-632007060327 实验项目名称: STM32串口通信编程 实验项目性质: 设计性 实验所…

STM32串口驱动

首先了解串口通信的一些基本原理: ⚫ 串口通信: 串口通信是指数据通过一条数据线(或者两条差分线)一位接着一位的传输出去。串口通信的优点是占用硬件资源少,且传输距离较远,缺点是传输速度慢(…

STM32串口

使用百问网的STM32F103MINI开发板完成下面实验。 1、通过STM32CubeMX配置串口。 串口1选择Asynchronous,异步通信。 115200bps,8N1,默认即可。 2、串口发送数据。 STM32Cube生成代码后,在main.c的while(1)前面加一句。 HAL_U…

STM32 串口详解

目录 01、USART的特点 02、USART简介 2.1、数据传输模型 2.2、帧结构 2.3、波特率 03、STM32的USART 04、代码配置 01、USART的特点 USART是通用异步收发传输器(UniversalAsynchronousReceiver/Transmitter),通常称作UART,是一种异步…

STM32入门教程——串口通讯

目录 1.认识串口 2.stm32串口介绍 2.1 查询方式 2.1 中断方式 2.2 DMA方式 3.使用stm32串口实现printf 串口作为嵌入式设备最常用的外设之一,被广泛的应用。本文介绍STM32串口的如何使用。从以下几个方面介绍: 1.认识串口 常用串口的引脚主要由TX…

STM32—串口

串口介绍 串行接口简称串口,也称串行通信接口或串行通讯接口(通常指COM接口),是采用串行通信方式的扩展接口。串行接口(Serial Interface)是指数据一位一位地顺序传送。其特点是通信线路简单,只…

【stm32】串口通信

串口通信 一、串口通信协议原理二、usart功能框图三、stm32库的配置 一、串口通信协议原理 串口在嵌入式系统当中是一类重要的数据通信接口,其本质功能是作为 CPU 和串行设备间的编码转换器。当数据从 CPU 经过串行端口发送出去时,字节数据转换为串行的…

STM32-串口通信详解

目录 前言 一、通信接口背景知识 1. 并行通信和串行通信 2. 串行通信的分类 二、STM32的串口通信基础 1. 串口通信接口 2. 串口通信框图 3. 串口通信相关寄存器 4. 波特率计算方法 三、库函数配置 1. 串口配置一般步骤 总结 前言 众所周知,串口通信是MC…

STM32串口通信

STM32串口通信 一、串口 1.串口概述 串口是单片机中最常用也是最简单的一种通信方式通信:两个或两个以上的设备进行数据交换 串口是用于两个设备之间的异步全双工通信 异步——》两个设备不需要共时钟 全双工——》两个设备之间服务于数据交换的“线”有两根 Tx&…

STM32-串口通信(串口的接收和发送)

文章目录 STM32的串口通信一、STM32里的串口通信二、串口的发送和接收串口发送串口接收 三、串口在STM32中的配置四、串口接收的两种实现方式1. 需要更改的地方2. 查询RXNE标志位3. 使用中断 总结 STM32的串口通信 本文在于记录自己的学习过程中遇到的问题和总结,各…

STM32串口通信详解

✅作者简介:嵌入式入坑者,与大家一起加油,希望文章能够帮助各位!!!! 📃个人主页:rivencode的个人主页 🔥系列专栏:玩转STM32 💬保持学…

MacOS 安装 Matlab R2021b 手记

MacOS 安装 Matlab R2021b Maci64手记 1.下载MATLAB R2021b 安装包 2.双击MatlabR2021b_Mac64.dmg打开安装包,双击InstallForMacOSX.app开始安装程序 3.出现「install_unix想要进行更改」,出入开机密码,点击好 4.出现安装界面,点击「高级选项」,选择「我有文件安装密…

linux安装matlabRuntime

1.找到自己需要的文件夹,下载压缩包,版本自己发挥 wget https://ssd.mathworks.com/supportfiles/downloads/R2021a/Release/6/deployment_files/installer/complete/glnxa64/MATLAB_Runtime_R2021a_Update_6_glnxa64.zip 2.解压 unzip MATLAB_Runtim…