STM32 串口中断 BUG

发布者:EuphoricVoyage最新更新时间:2021-07-07 来源: eefocus关键字:STM32  串口中断  BUG 手机看文章 扫描二维码
随时随地手机看文章

调试串口时,发现串口会出现频繁跳中断,导致无法执行主循环的问题!


调试发现是串口中断硬件BUG:


1. USART_ITConfig(USART1,USART_IT_RXNE, ENABLE);使能了接收中断,那么ORE中断也同时被开启了。


2. ORE中断只能使用USART_GetFlagStatus(USART1,USART_FLAG_ORE) 读到(没有使能USART_IT_ERR中断时)

解决办法:


1. 初始化时,开启中断


USART_ITConfig(USART1, USART_IT_PE, ENABLE); //开启PE错误接收中断Bit 8PEIE: PE interrupt enable

//CR2 开启ERR中断

USART_ITConfig(USART1, USART_IT_ERR, ENABLE);


2. 在STM32中断函数增加USART_IT_ORE等异常中断的处理!


//开启CR3,bit0的EIE: Error interrupt enable, 处理USART_IT_ERR,USART_IT_ORE_ER,USART_IT_NE,USART_IT_FE 错误

if(USART_GetFlagStatus(USART1, USART_FLAG_ORE) != RESET)

{//同 @arg USART_IT_ORE_ER : OverRun Error interrupt if the EIE bit is set

ushTemp = USART_ReceiveData(USART1); //取出来扔掉

USART_ClearFlag(USART1, USART_FLAG_ORE);

}


if(USART_GetFlagStatus(USART1, USART_FLAG_NE) != RESET)

{//同 @arg USART_IT_NE : Noise Error interrupt

USART_ClearFlag(USART1, USART_FLAG_NE);

}


if(USART_GetFlagStatus(USART1, USART_FLAG_FE) != RESET)

{//同 @arg USART_IT_FE : Framing Error interrupt

USART_ClearFlag(USART1, USART_FLAG_FE);

}


if(USART_GetFlagStatus(USART1, USART_FLAG_PE) != RESET)

{//同 @arg USART_IT_PE : Parity Error interrupt

USART_ClearFlag(USART1, USART_FLAG_PE);

}


网络上也有一篇文章讲的比较仔细,请看!


http://bbs.21ic.com/viewthread.php?tid=160999&highlight=USART


今天在使用USART模块,遇到了一些问题并解决了,于是发贴共享。


问题描述:

在使用USART做串口通讯时,我只把接收中断打开,并设置抢占优先级为最低一个级别,而接收中断上一个优先级处理事情比较多,可能占用了2ms时间。当我使用9600波特率往下位机发送数据,速度非常快,就是一直按回车发!问题就出来,不到1分钟时间,通讯没有反应了。USART配置代码如下:

void uart_config(void)

{

USART_InitTypeDefUSART_InitStructure;

USART_InitStructure.USART_BaudRate = UART_GetBaud(BaudRate);

USART_InitStructure.USART_WordLength =USART_WordLength_8b;

USART_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_InitStructure.USART_Clock =USART_Clock_Disable;

USART_InitStructure.USART_CPOL =USART_CPOL_Low;

USART_InitStructure.USART_CPHA =USART_CPHA_2Edge;

USART_InitStructure.USART_LastBit =USART_LastBit_Enable;

/* ConfigureUSART1 */

USART_Init(USART1, &USART_InitStructure);

/* EnableUSART1 receive interrupt */

USART_ITConfig(USART1,USART_IT_RXNE, ENABLE);

/* Enable theUSART1 */

USART_Cmd(USART1, ENABLE);

}


分析问题:


1.为什么没有通讯了?

通过仿真器仿真,发现程序一直进入接收中断中,由于我没有使用中断发送,于是程序就死在了接收中断,也就没有数据发送到电脑上来。接收中断代码如下:

void UART_Receive(void)

{

//正在处理上一条通讯,接收到数据不处理

if(bRecieveOK)

{

if(USART_GetITStatus(USART1,USART_IT_RXNE) != RESET)

USART_ClearITPendingBit(USART1,USART_IT_RXNE);

return;//processing receive data,don't receive again

}

if(USART_GetITStatus(USART1,USART_IT_RXNE) != RESET)

{

if(MoudBusExpir == 0)

{

ucRcePtr = 0;

MoudBusExpir = 20;//50ms

}

else

MoudBusExpir = 20;

/* Read one byte from the receive data register */

ucRS485Buff[ucRcePtr++] =USART_ReceiveData(USART1);

/* Clear theUSART1 Receive interrupt */

USART_ClearITPendingBit(USART1,USART_IT_RXNE);

}


2.为什么会一直跑到接收中断?

断点之后发现(USART_GetITStatus(USART1,USART_IT_RXNE)==RESET的,也就是说没有数据接收到也进了中断,而且在USART配置中我也只打开了接收中断!没有数据送过来应该是不可能进入中断的!


3.响应了什么中断?

我想通过函数(USART_GetITStatus()把所有中断状态都读出来,但失败了,USART_IT_XXX所有中断状态都是RESET!也就是说没有中断也进入到这个中断服务程序来了!?


4.找资料

STM32F10x微控制器参考手册(2009年12月第10版)P541发现如下说明:

P541.JPG

也就是说只要接收中断打开,即RXNEIE设置为1,那么ORE中断也自动打开了。

可是USART_GetITStatus(USART1,USART_IT_ORE )== RESET!!!!

找到USART_GetITStatus(USART1,USART_IT_RXNE)函数,发现只有当USART_IT_ERR中断使能时,才能读到ORE中断。

在这里要指出这个BUG:产生ORE中断了,但使用USART_GetITStatus()函数却无法读到这个中断被SET起来!


5.把ORE中断标志位清除

既然找到了是什么中断,那么把相应的中断标志位清除,就应该可以了吧?

USART_ClearITPendingBit(USART1,USART_IT_ORE);

但是,结果是没有任何效果!清除之后,马上读ORE中断状态,USART_GetITStatus(USART1,USART_IT_ORE)==RESET.程序仍然跑死在接收中断。再使用另一个函数USART_GetFlagStatus(USART1,USART_FLAG_ORE) = SET,原来ORE标志位还没有清除。


6.问题解决

为什么清除不掉?头疼了,再找找资料,有发现,在P523页如下图:

P523.JPG

接收中断程序改为:

void UART_Receive(void)

{

if (USART_GetFlagStatus(USART1,USART_FLAG_ORE) != RESET)


//注意!不能使用if(USART_GetITStatus(USART1,USART_IT_RXNE) != RESET)来判断

{

USART_ReceiveData(USART1);

}

//正在处理上一条通讯,接收到数据不处理

if(bRecieveOK)

{

if(USART_GetITStatus(USART1,USART_IT_RXNE) != RESET)

USART_ClearITPendingBit(USART1,USART_IT_RXNE);

return;//processing receive data,don't receive again

}

if(USART_GetITStatus(USART1,USART_IT_RXNE) != RESET)

{

if(MoudBusExpir == 0)

{

ucRcePtr = 0;

MoudBusExpir = 20;//50ms

}

else

MoudBusExpir = 20;

/* Read one byte from the receive data register */

ucRS485Buff[ucRcePtr++] =USART_ReceiveData(USART1);

/* Clear theUSART1 Receive interrupt */

USART_ClearITPendingBit(USART1,USART_IT_RXNE);

}


总结:

注意问题:1.USART_ITConfig(USART1,USART_IT_RXNE, ENABLE);使能了接收中断,那么ORE中断也同时被开启了。


2.ORE中断只能使用USART_GetFlagStatus(USART1,USART_FLAG_ORE) 读到(没有使能USART_IT_ERR中断时)

BUG建议:1.在STM32库中,能不能修改USART_GetITStatus()函数对USART_IT_ORE中断的处理?也就是我只要打开了接收中断,那么有ORE中断时,我也能使用USART_GetITStatus(USART1,USART_IT_ORE)读到.

其它:在找资料的同时,发现STM32F10x微控制器参考手册(2009年12月第10版)中文翻译P538有错误,如下图:

P538.JPG

英文P696如下图:

P696.JPG


关键字:STM32  串口中断  BUG 引用地址:STM32 串口中断 BUG

上一篇:基于STM32的嵌入式语音识别模块设计
下一篇:STM32 SysTick---系统滴答定时器

推荐阅读最新更新时间:2024-11-11 12:04

UCOSIII简介于移植
UCOSIII简介 UCOSIII是一个可裁剪,可固化,可剥夺的多任务系统。相比于前代产品其最大任务数目没有限制,优先级相同的任务数目没有限制且有无需调度的的发送机制。 UCOSIII文件 在移植UCOSIII之前我们需要准备两样东西:一个是UCOSIII的源码,一个是Micrium官方在STM32F1xx上移植好的工程文件。 在Micrium文件夹中有四个文件夹 1、EvaBoards文件夹 这个文件夹里面就是关于STM32F107的工程文件。其中的处app.c和stm32f10x_conf.h外的文件的八个文件使我们需要添加到工程文件当中的。 2、uC-CPU文件夹 这个文件夹里面是与CPU相关的代码,有下面几个文
[单片机]
stm32常见错误与工程模板
1.新建工程的时候编译出现如下错误(MDK4.12 使用v3.4的库) ..CMSISstm32f10x.h(80): error: #35: #error directive: Please select first the target STM32F10x device used in your application (in stm32f10x.h file) 解决方法:双击错误进入出错的地方,在stm32f10x.h处 #if !defined (STM32F10X_LD) && !defined (STM32F10X_LD_VL) && !defined (STM32F10X_MD) && !defined (STM
[单片机]
<font color='red'>stm32</font>常见错误与工程模板
STM32高级定时器那些事
首先说下我使用飞、高级定时器的一些坑爹经历,由于开始高级定时器使用不当,造成有如下问题: 1、PWM输出占空比反向(这个也还能接受点) 2、程序烧进去了就不能烧第二次了,下载时候提示如下图(这个够坑爹的了) 错误而提示 仔细看提示信息说是CPU一直在复位,解决的方法是通过出厂IAP用串口擦除芯片程序。需要准备的工作是:USB转串口工具、把BOOT0拉高、使用ISPMCU擦除芯片。 3、从外部flash读取出来的图片不能够正常显示,屏幕显示的是黑色,后来发现是因为SPI1的I/O与TIM8的N通道冲突了。(由此我下决心要找到问题的原因) 通过一番搜寻和查看相关资料,发现造成上述原因是因为我对高级定时器初始化的时候漏掉了部分成员
[单片机]
<font color='red'>STM32</font>高级定时器那些事
重返STM32之---RTC使用
STM3f10x的RTC时能涉及到的寄存器有RCC,BKP和RTC这三个大类寄存器;其中RCC主要控制了实时时钟和备份区的电源使能和时钟使能;RTC模块和时钟配置系统的寄存器是在后备区域的(即BKP),通过BKP后备区域来存储RTC配置的数据可以让在系统复位或待机模式下唤醒后RTC里面配置的数据维持不变;为此备份区还得涉及一个寄存器PWR,电源管理寄存器,备份区的写保护位在PWR- CR的第八位。 由于整个RTC都是位于后备区,而且RTC的APB1总线和内核的APB1总线是独立的,所以在系统复位和唤醒时,RTC和BKP的那些时钟不用从新配置;他们只受Backup domain software reset这个位和系统完全掉电的影响。
[单片机]
重返<font color='red'>STM32</font>之---RTC使用
STM32单片机的酒精浓度探测仪设计
引言 酒后驾车是导致交通事故的一个重要原因,给人们的生活和生命安全带来巨大的危害。为了防止机动车辆驾驶人员酒后驾车,现场实时对人体呼气中酒精含量的检查已日益受到重视。本系统针对现有酒精传感器恢复时间较长的问题,通过计算斜率成功地实现了快速酒精浓度检测,缩短了检测间隔时间,大大提升了酒精检测的效率。 1 酒精浓度探测仪的整体结构 酒精浓度探测仪由单片机、酒精传感器、信号调理电路、语音报警模块、TFTLCD显示模块、通信模块、功放模块等部分组成,结构框图如图1所示。由于语音报警模块和TFTLCD显示模块对于单片机的处理速度和处理数据量要求高,再加上酒精检测反应速度较快,实时性较高,因此采用了ST公司的STM32系列的单片机作
[单片机]
<font color='red'>STM32</font>单片机的酒精浓度探测仪设计
STM32串口接收不定长数据原理与源程序
今天说一下STM32单片机的接收不定长度字节数据的方法。由于STM32单片机带IDLE中断,所以利用这个中断,可以接收不定长字节的数据,由于STM32属于ARM单片机,所以这篇文章的方法也适合其他的ARM单片机。 IDLE中断什么时候发生? IDLE就是串口收到一帧数据后,发生的中断。什么是一帧数据呢?比如说给单片机一次发来1个字节,或者一次发来8个字节,这些一次发来的数据,就称为一帧数据,也可以叫做一包数据。 如何判断一帧数据结束,就是我们今天讨论的问题。因为很多项目中都要用到这个,因为只有接收到一帧数据以后,你才可以判断这次收了几个字节和每个字节的内容是否符合协议要求。 看了前面IDLE中断的定义,你就会明白了,一帧数据结束后
[单片机]
<font color='red'>STM32</font><font color='red'>串口</font>接收不定长数据原理与源程序
STM32的GPIO操作配置和使用方法
一、前言 本篇开始对STM32的GPIO在实际开发设计中的使用配置和技巧进行探讨,可以先去回顾下之前介绍的GPIO的相关理论基础知识包括基本结构,工作模式和寄存器原理。 了解过STM32的GPIO相关的理论知识,这样在应用GPIO开发过程中,能更好的理解GPIO的特点,应用起来会更加的得心应手。 后续将从以下图1中所示的几个方面对GPIO应用设计中的步骤展开介绍。本篇先介绍GPIO的基本API函数定义,配置初始化的流程,以及使用技巧;针对将GPIO的引脚用于外部中断的功能将作为单独的一篇进行详细的讨论介绍。 图1 GPIO应用设计 二、API函数 STM32有多种类型的库,本节所介绍的STM32的GPIO函
[单片机]
<font color='red'>STM32</font>的GPIO操作配置和使用方法
stm32 堆和栈(stm32 Heap & Stack)
关于堆和栈已经是程序员的一个月经话题,大部分有是基于os层来聊的。 那么,在赤裸裸的单片机下的堆和栈是什么样的分布呢?以下是网摘: 刚接手STM32时,你只编写一个 int main() { while(1); } BUILD://Program Size: Code=340 RO-data=252 RW-data=0 ZI-data=1632 编译后,就会发现这么个程序已用了1600多的RAM,要是在51单片机上,会心疼死了,这1600多的RAM跑哪儿去了, 分析map,你会发现是堆和栈占用的,在startup_stm32f10x_md.s文件(这个是stm32的启动文件)中,它的前面几行就有以上定义, 这下该明白
[单片机]
<font color='red'>stm32</font> 堆和栈(<font color='red'>stm32</font> Heap & Stack)
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved