0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

单片机怎样才能不死机之串口Overrun

FPGA之家 来源:开源博客 作者: TopSemic 2021-05-07 17:35 次阅读

闲言少叙,先上Code,大家看一下下面这段代码有没有问题?

// Note: USART demo code runs on STM32F030#include “main.h”

static __IO uint32_t TimingDelay;

RCC_ClocksTypeDef RCC_Clocks;

uint8_t uart_buffer[100];

// GPIO Configurationvoid GPIO_Configuration(void){ GPIO_InitTypeDef GPIO_InitStructure; GPIO_PinAFConfig(GPIOA,GPIO_PinSource9,GPIO_AF_1); // Tx PA9 GPIO_PinAFConfig(GPIOA,GPIO_PinSource10,GPIO_AF_1); // Rx PA10 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10; // USART1_TX | USART1_RX GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_Level_1; GPIO_Init(GPIOA, &GPIO_InitStructure); }

// USART Configurationvoid USART_Configuration(void){ USART_InitTypeDef USART_InitStructure; USART_InitStructure.USART_BaudRate = 115200; //USART_InitStructure.USART_BaudRate = 9600; 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_Tx | USART_Mode_Rx; USART_Init(USART1,&USART_InitStructure); USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); USART_Cmd(USART1,ENABLE); }

// Interrupt Configurationvoid NVIC_Configuration(void){ NVIC_InitTypeDef NVIC_InitStructure; // USART1 interrupt Config NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; NVIC_InitStructure.NVIC_IRQChannelPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure);}

// USART1 Interrupt Handlervoid USART1_IRQHandler (void){ static uint8_t i = 0;

if(USART_GetITStatus(USART1,USART_IT_RXNE)!= RESET) {// Clear Receive Data Register Not Empty Flag USART_ClearITPendingBit(USART1,USART_IT_RXNE); uart_buffer[i++] = USART_ReceiveData(USART1); if(i == 100) i = 0; }}

int main(void){ static uint8_t ch;

// Init a 1ms timer interrupt, for Delay function implementation. RCC_GetClocksFreq(&RCC_Clocks); SysTick_Config(RCC_Clocks.HCLK_Frequency / 1000); // Enable USART1 and GPIOA clock RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE); RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA,ENABLE); GPIO_Configuration(); USART_Configuration(); NVIC_Configuration(); ch = ‘A’; while(1) { Delay(50); while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET); USART_SendData(USART1, ch); ch++; }

}

/*** @brief Inserts a delay time.* @param nTime: specifies the delay time length, in 1 ms.* @retval None*/void Delay(__IO uint32_t nTime){ TimingDelay = nTime; while(TimingDelay != 0);}

/*** @brief Decrements the TimingDelay variable.* @param None* @retval None*/void TimingDelay_Decrement(void){ if(TimingDelay != 0x00) { TimingDelay--; }}

它是可以在 STM32F030 上调试通过的串口收发测试程序,发送采用延时循环,接收采用中断,接收到的数据存入缓冲区。

有很多比较认真的实战派的同学估计会下载到板子上跑一跑,它确实能跑通,看起来也没什么问题。很多教程甚至官方的代码都是类似的处理方法。

但这确实有点儿像陷马坑,看似一马平川,跑着跑着突然连马带人 kucha 一声掉坑里了。这还真不是开玩笑,某知名楼宇自控公司的产品就在安装到客户现场后,经常莫名奇妙的死机。查来查去,查去查来,才发现问题。可是解决起来不容易啊,一个一个的去拆开,更新代码,想想都。。。

所以同学们不要轻视任何一段代码啊!

这段代码的问题是,如果接收数据之间间隔时间较长,可以正常收数据。但是如果对方发送数据非常快,或者偶尔在自己还没从串口接收寄存器取走数据的时候突然又来了数据,会导致 Overrun 标志位的置位。这个标志位一置,串口基本上就罢工了。所以,在程序中一定要有对异常情况的处理。甚至觉得不会发生的异常也不要置之不理。(想一想为什么要填充Flash的空白区域?在正常情况下代码永远不会跑到空白区域是吧。)

对串口异常的处理可以参考下面中断处理函数代码。当然也可以在主程序中定时处理,以便在中断失效的情况下还能恢复。

// USART1 Interrupt Handlervoid USART1_IRQHandler (void){ static uint8_t i = 0;

if(USART_GetFlagStatus(USART1, USART_FLAG_ORE) != RESET) {// Clear Overrun Error Flag USART_ClearFlag(USART1, USART_FLAG_ORE); } else if(USART_GetFlagStatus(USART1, USART_FLAG_NE) != RESET) {// Clear Noise Error Flag USART_ClearFlag(USART1, USART_FLAG_NE); } else if(USART_GetFlagStatus(USART1, USART_FLAG_FE) != RESET) {// Clear Framing Error Flag USART_ClearFlag(USART1, USART_FLAG_FE); } else if(USART_GetFlagStatus(USART1, USART_FLAG_PE) != RESET) {// Clear Parity Error Flag USART_ClearFlag(USART1, USART_FLAG_PE); } else if(USART_GetITStatus(USART1,USART_IT_RXNE)!= RESET) {// Clear Receive Data Register Not Empty Flag USART_ClearITPendingBit(USART1,USART_IT_RXNE); uart_buffer[i++] = USART_ReceiveData(USART1); if(i == 100) i = 0; }}

编辑:jq

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 寄存器
    +关注

    关注

    31

    文章

    5304

    浏览量

    119887
  • 串口
    +关注

    关注

    14

    文章

    1540

    浏览量

    76101
  • 函数
    +关注

    关注

    3

    文章

    4290

    浏览量

    62346
  • STM
    STM
    +关注

    关注

    1

    文章

    555

    浏览量

    42355

原文标题:单片机(MCU)如何才能不死机之串口Overrun

文章出处:【微信号:zhuyandz,微信公众号:FPGA之家】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    通过简单的电阻电容组合怎样才能把25K方波变成正弦?

    通过简单的电阻电容组合怎样才能把25K方波变成正弦呢。加了滤波电路后方波的上升沿变缓了,可是下降沿基本没有变化。怎样才能把下降沿也变缓呢
    发表于 10-22 06:02

    什么原因会导致单片机系统死机

    ______________________________________ 什么原因会导致单片机系统死机
    发表于 10-16 22:32

    TPA3118D2怎样才能不使用静音功能,通电就能输出音频?

    如图,12脚MUTE接一个100K电阻到地,不使用静音功能,这样使用是否正确。焊接好后通电没声音输出,但手碰一下MUTE脚就有输出了,再碰一下又没声音了,就像是按了MUTE按钮。手触摸一次就等于加了一次高电平。不知是什么问题,怎样才能不使用静音功能,通电就能输出音频。
    发表于 09-29 08:38

    单片机WiFi模块怎样连接手机APP

    连接 :将WiFi模块与单片机物理连接。 编程单片机 :编写代码使单片机能通过WiFi模块与互联网通信。 创建服务器 :在单片机上创建一个小型服务器,以便手机APP可以与
    的头像 发表于 09-10 15:31 611次阅读

    单片机烧录程序的串口线怎么连接

    单片机开发过程中,烧录程序是一项重要的工作。而烧录程序通常需要使用串口线来实现。本文将介绍单片机烧录程序的串口线连接方法,包括串口线的类型
    的头像 发表于 09-02 09:50 1059次阅读

    请问ESP8266 IR红外例程怎样才能不发载波?

    有款产品需要没有载波的信号,请教例程怎样修改才能不用载波,谢谢!
    发表于 07-10 07:54

    怎样才能选到合适的无线模块?

    市面上无线模块的类型多种多样,如LoRa、蓝牙、ZigBee、SPI、SoC等等,怎样才能选择到合适的无线模块呢?为了确保所选模块能满足特定应用的需求并实现最佳性能,在选择模块时可以重点考虑以下几个
    的头像 发表于 05-31 08:21 750次阅读
    <b class='flag-5'>怎样才能</b>选到合适的无线模块?

    STM8单片机手一摸单片机死机是怎么回事?

    如题,STM8单片机 用手指一摸单片机死机了,有时还没接触到就死机了,关键我用的都是汽车级的STM8A系列单片机了怎么抗干扰性怎么还这么差
    发表于 05-07 06:38

    51单片机串口通信详细介绍-小白必看

    51单片机串口通信是单片机与外部设备通信的重要方式,它基于串行通信的原理,以字节为单位进行数据传输。在51单片机中,串口通信主要依赖于两个关
    的头像 发表于 04-17 09:33 1812次阅读
    51<b class='flag-5'>单片机</b><b class='flag-5'>串口</b>通信详细介绍-小白必看

    单片机学到什么程度可以找工作?

    找到工作,您需要达到一定的学习程度和技能水平。我们今天就来说一说究竟怎样才能算是可以去找工作了。一些关于单片机学习程度和就业能力的建议了解单片机的基本原理,包括内
    的头像 发表于 03-28 08:04 1488次阅读
    <b class='flag-5'>单片机</b>学到什么程度可以找工作?

    单片机串口通信的接收与发送

    单片机串口通信是一种常见的通信方式,它可以实现单片机与外部设备的数据交换。在实际应用中,单片机串口通信常用于与电脑、传感器、LCD显示屏等外
    的头像 发表于 12-20 14:03 3428次阅读

    单片机串口通信的接收与发送程序

    单片机串口通信的接收与发送程序 一、引言 单片机串口通信是一种常见的通信方式,广泛应用于各种嵌入式系统和工业控制领域。通过串口通信,
    的头像 发表于 12-19 13:57 5551次阅读

    什么是保护接地与保护接零?家用电器怎样才能不触电?

    什么是保护接地与保护接零?家用电器怎样才能不触电? 保护接地和保护接零是两种不同的电气安全保护措施。在家庭中使用电器时,遵守正确的安全操作规范是很重要的,以避免发生触电事故。本文将详细介绍保护接地
    的头像 发表于 12-18 16:58 1566次阅读

    请问怎样才能将SharcAudioToolbox导入SigmaStudio?具体如何操作?

    请问怎样才能将SharcAudioToolbox导入SigmaStudio?具体如何操作?
    发表于 11-30 07:47

    怎样才能学好单片机

    学会定时器的使用,就可以用单片机实现时序电路,时序电路的功能是强大的,在工业、家用电气设备的控制中有很多应用,例如,可以用单片机实 现一个具有一个按钮的楼道灯开关,该开关在按钮按下一次后,灯亮3分钟后自动灭,当按钮连续按下两次后,灯常亮不灭,当按钮按下时间超过2s,则灯灭
    发表于 11-28 10:27 432次阅读