0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫(xiě)文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

單片機(jī)怎樣才能不死機(jī)之串口Overrun

FPGA之家 ? 來(lái)源:開(kāi)源博客 ? 作者: TopSemic ? 2021-05-07 17:35 ? 次閱讀

閑言少敘,先上Code,大家看一下下面這段代碼有沒(méi)有問(wèn)題?

// 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 上調(diào)試通過(guò)的串口收發(fā)測(cè)試程序,發(fā)送采用延時(shí)循環(huán),接收采用中斷,接收到的數(shù)據(jù)存入緩沖區(qū)。

有很多比較認(rèn)真的實(shí)戰(zhàn)派的同學(xué)估計(jì)會(huì)下載到板子上跑一跑,它確實(shí)能跑通,看起來(lái)也沒(méi)什么問(wèn)題。很多教程甚至官方的代碼都是類(lèi)似的處理方法。

但這確實(shí)有點(diǎn)兒像陷馬坑,看似一馬平川,跑著跑著突然連馬帶人 kucha 一聲掉坑里了。這還真不是開(kāi)玩笑,某知名樓宇自控公司的產(chǎn)品就在安裝到客戶(hù)現(xiàn)場(chǎng)后,經(jīng)常莫名奇妙的死機(jī)。查來(lái)查去,查去查來(lái),才發(fā)現(xiàn)問(wèn)題??墒墙鉀Q起來(lái)不容易啊,一個(gè)一個(gè)的去拆開(kāi),更新代碼,想想都。。。

所以同學(xué)們不要輕視任何一段代碼??!

這段代碼的問(wèn)題是,如果接收數(shù)據(jù)之間間隔時(shí)間較長(zhǎng),可以正常收數(shù)據(jù)。但是如果對(duì)方發(fā)送數(shù)據(jù)非???,或者偶爾在自己還沒(méi)從串口接收寄存器取走數(shù)據(jù)的時(shí)候突然又來(lái)了數(shù)據(jù),會(huì)導(dǎo)致 Overrun 標(biāo)志位的置位。這個(gè)標(biāo)志位一置,串口基本上就罷工了。所以,在程序中一定要有對(duì)異常情況的處理。甚至覺(jué)得不會(huì)發(fā)生的異常也不要置之不理。(想一想為什么要填充Flash的空白區(qū)域?在正常情況下代碼永遠(yuǎn)不會(huì)跑到空白區(qū)域是吧。)

對(duì)串口異常的處理可以參考下面中斷處理函數(shù)代碼。當(dāng)然也可以在主程序中定時(shí)處理,以便在中斷失效的情況下還能恢復(fù)。

// 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

聲明:本文內(nèi)容及配圖由入駐作者撰寫(xiě)或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 寄存器
    +關(guān)注

    關(guān)注

    31

    文章

    5250

    瀏覽量

    119197
  • 串口
    +關(guān)注

    關(guān)注

    14

    文章

    1533

    瀏覽量

    75455
  • 函數(shù)
    +關(guān)注

    關(guān)注

    3

    文章

    4237

    瀏覽量

    61965
  • STM
    STM
    +關(guān)注

    關(guān)注

    1

    文章

    555

    瀏覽量

    42272

原文標(biāo)題:?jiǎn)纹瑱C(jī)(MCU)如何才能不死機(jī)之串口Overrun

文章出處:【微信號(hào):zhuyandz,微信公眾號(hào):FPGA之家】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏

    評(píng)論

    相關(guān)推薦

    STM8單片機(jī)手一摸單片機(jī)死機(jī)是怎么回事?

    如題,STM8單片機(jī) 用手指一摸單片機(jī)死機(jī)了,有時(shí)還沒(méi)接觸到就死機(jī)了,關(guān)鍵我用的都是汽車(chē)級(jí)的STM8A系列單片機(jī)了怎么抗干擾性怎么還這么差
    發(fā)表于 05-07 06:38

    ?51單片機(jī)串口通信詳細(xì)介紹-小白必看

    51單片機(jī)串口通信是單片機(jī)與外部設(shè)備通信的重要方式,它基于串行通信的原理,以字節(jié)為單位進(jìn)行數(shù)據(jù)傳輸。在51單片機(jī)中,串口通信主要依賴(lài)于兩個(gè)關(guān)
    的頭像 發(fā)表于 04-17 09:33 ?1535次閱讀
    ?51<b class='flag-5'>單片機(jī)</b><b class='flag-5'>串口</b>通信詳細(xì)介紹-小白必看

    單片機(jī)學(xué)到什么程度可以找工作?

    找到工作,您需要達(dá)到一定的學(xué)習(xí)程度和技能水平。我們今天就來(lái)說(shuō)一說(shuō)究竟怎樣才能算是可以去找工作了。一些關(guān)于單片機(jī)學(xué)習(xí)程度和就業(yè)能力的建議了解單片機(jī)的基本原理,包括內(nèi)
    的頭像 發(fā)表于 03-28 08:04 ?1145次閱讀
    <b class='flag-5'>單片機(jī)</b>學(xué)到什么程度可以找工作?

    單片機(jī)串口通信的接收與發(fā)送

    單片機(jī)串口通信是一種常見(jiàn)的通信方式,它可以實(shí)現(xiàn)單片機(jī)與外部設(shè)備的數(shù)據(jù)交換。在實(shí)際應(yīng)用中,單片機(jī)串口通信常用于與電腦、傳感器、LCD顯示屏等外
    的頭像 發(fā)表于 12-20 14:03 ?2930次閱讀

    單片機(jī)串口通信的接收與發(fā)送程序

    單片機(jī)串口通信的接收與發(fā)送程序 一、引言 單片機(jī)串口通信是一種常見(jiàn)的通信方式,廣泛應(yīng)用于各種嵌入式系統(tǒng)和工業(yè)控制領(lǐng)域。通過(guò)串口通信,
    的頭像 發(fā)表于 12-19 13:57 ?4403次閱讀

    什么是保護(hù)接地與保護(hù)接零?家用電器怎樣才能不觸電?

    什么是保護(hù)接地與保護(hù)接零?家用電器怎樣才能不觸電? 保護(hù)接地和保護(hù)接零是兩種不同的電氣安全保護(hù)措施。在家庭中使用電器時(shí),遵守正確的安全操作規(guī)范是很重要的,以避免發(fā)生觸電事故。本文將詳細(xì)介紹保護(hù)接地
    的頭像 發(fā)表于 12-18 16:58 ?862次閱讀

    請(qǐng)問(wèn)怎樣才能將SharcAudioToolbox導(dǎo)入SigmaStudio?具體如何操作?

    請(qǐng)問(wèn)怎樣才能將SharcAudioToolbox導(dǎo)入SigmaStudio?具體如何操作?
    發(fā)表于 11-30 07:47

    怎樣才能學(xué)好單片機(jī)?

    學(xué)會(huì)定時(shí)器的使用,就可以用單片機(jī)實(shí)現(xiàn)時(shí)序電路,時(shí)序電路的功能是強(qiáng)大的,在工業(yè)、家用電氣設(shè)備的控制中有很多應(yīng)用,例如,可以用單片機(jī)實(shí) 現(xiàn)一個(gè)具有一個(gè)按鈕的樓道燈開(kāi)關(guān),該開(kāi)關(guān)在按鈕按下一次后,燈亮3分鐘后自動(dòng)滅,當(dāng)按鈕連續(xù)按下兩次后,燈常亮不滅,當(dāng)按鈕按下時(shí)間超過(guò)2s,則燈滅
    發(fā)表于 11-28 10:27 ?355次閱讀

    怎樣才能在有限的容量下發(fā)揮電池的極限續(xù)航能力

    電子發(fā)燒友網(wǎng)站提供《怎樣才能在有限的容量下發(fā)揮電池的極限續(xù)航能力.doc》資料免費(fèi)下載
    發(fā)表于 11-14 14:38 ?0次下載
    <b class='flag-5'>怎樣才能</b>在有限的容量下發(fā)揮電池的極限續(xù)航能力

    怎樣才能準(zhǔn)確的而獲取高頻信號(hào)的頻率10Mhz以?xún)?nèi)的?

    使用51單片機(jī)怎樣才能準(zhǔn)確的而獲取高頻信號(hào)的頻率10Mhz以?xún)?nèi)的
    發(fā)表于 11-10 06:52

    單片機(jī)高溫死機(jī)是怎么回事?

    最近遇到一個(gè)問(wèn)題,單片機(jī)用的是16M有源晶振,在高溫50度左右的時(shí)候死機(jī)了,測(cè)試電源3.3V紋波為25mV左右,有源晶振正常震蕩,且在死機(jī)瞬間,晶振波形與電源波形未有抖動(dòng)。檢測(cè)有無(wú)死機(jī)
    發(fā)表于 10-27 07:03

    基于GPRS和單片機(jī)串口通訊設(shè)計(jì)

    電子發(fā)燒友網(wǎng)站提供《基于GPRS和單片機(jī)串口通訊設(shè)計(jì).doc》資料免費(fèi)下載
    發(fā)表于 10-26 14:16 ?6次下載
    基于GPRS和<b class='flag-5'>單片機(jī)</b>的<b class='flag-5'>串口</b>通訊設(shè)計(jì)

    基于單片機(jī)串口通信模塊設(shè)計(jì)

    電子發(fā)燒友網(wǎng)站提供《基于單片機(jī)串口通信模塊設(shè)計(jì).doc》資料免費(fèi)下載
    發(fā)表于 10-19 11:29 ?8次下載
    基于<b class='flag-5'>單片機(jī)</b>的<b class='flag-5'>串口</b>通信模塊設(shè)計(jì)

    剖析單片機(jī)串口最底層的本質(zhì)?

    精華 | 剖析單片機(jī)串口最底層的本質(zhì)?
    的頭像 發(fā)表于 10-18 18:16 ?624次閱讀
    剖析<b class='flag-5'>單片機(jī)</b><b class='flag-5'>串口</b>最底層的本質(zhì)?

    基于Linux的ARM和單片機(jī)串口通信設(shè)計(jì)

    電子發(fā)燒友網(wǎng)站提供《基于Linux的ARM和單片機(jī)串口通信設(shè)計(jì).pdf》資料免費(fèi)下載
    發(fā)表于 10-11 10:35 ?0次下載
    基于Linux的ARM和<b class='flag-5'>單片機(jī)</b>的<b class='flag-5'>串口</b>通信設(shè)計(jì)