問題描述: 在一個項目中,下位機使用的是STM8S003F3為主芯片。在使用RS485進行與上位機通信時,會一直進入接收中斷,根本未接收到上位機的正確數(shù)據(jù)。 解決過程: 一開始以為是485芯片R0引腳未上拉的緣故導(dǎo)致這個問題,經(jīng)過將此引腳通過MCU內(nèi)部上拉,問題得到緩解。程序工作也穩(wěn)定了,運行了一周也沒問題,所以一直以為問題解決了,結(jié)果在實地安裝后,沒過多久又出現(xiàn)了這個問題,按理說,如果是外部電磁干擾,應(yīng)該是偶發(fā),也不應(yīng)該出現(xiàn)了就不會好起來,干擾源不可能一直都在。然后又是一個頭疼的事啊。。繼續(xù)找答案解決。 這時又跑去官網(wǎng)下載了stm8s類芯片的應(yīng)用手冊,重點就是它了。 原來stm8s類型芯片的UART使用時在接收中斷時要注意一個過載問題,下面呢就是手冊原文: 過載錯誤如果RXNE還沒有被復(fù)位,又接收到一個字符,則發(fā)生溢出錯誤。數(shù)據(jù)只有當RXNE位被清零后才能從移位寄存器轉(zhuǎn)移到RDR寄存器。當溢出錯誤產(chǎn)生時:● OR位被置位。● RDR內(nèi)容將不會丟失。讀UART_DR寄存器仍能得到先前的數(shù)據(jù)。● 移位寄存器中以前的內(nèi)容將被覆蓋。隨后接收到的數(shù)據(jù)都將丟失。● 如果RIEN位被置1,則產(chǎn)生中斷。順序執(zhí)行對UART_SR和UART_DR寄存器的讀操作,可復(fù)位OR位。 首先STM8的UART接收中斷的使能位是RIEN,而當RIEN為1的時候就會進入接收中斷,而能讓RIEN為1的時候是有兩種情況的。 1,一個就是在接收寄存器不為空的時候。(對應(yīng)的中斷請求標志RXNE) 2,另一個就是上面說的過載錯誤了,在RXNE標志位還沒有復(fù)位,又接收到一個字符,這時也會觸發(fā)接收 中斷。(對應(yīng)的中斷標志位OR) 那么我們的問題就是出現(xiàn)在這里了,我們在每次接收中斷都會清除RXNE標志位,但是并沒有清除OR標志位,故當出現(xiàn)一次RXNE還沒有被復(fù)位,又接收到一個字符的情況也就出現(xiàn)了OR一直沒被清除,所以就一直進入接收中斷了。所以解決問題就是只要每次接收中斷都需要清除RXEN和OR這兩個標志位就可以解決問題了。 解決方法: 對于RXNE清零有兩種方法:直接手動清零或讀UART_DR寄存器就可以讓RXNE清零。 對于OR清零就不能直接手動寫0了,這時為了同時能清除RXNE和OR標志位,我們就使用手冊上最后一句給的方案。順序讀取這兩個寄存器,這樣即清除了OR同時又清除了RXNE標志位。 代碼:(用的stm8s lib庫) INTERRUPT_HANDLER(UART1_RX_IRQHandler, 18){ /* Read one byte from the receive data register */
if( UART1_GetITStatus(UART1_IT_RXNE) == SET)
{ Rxdata = UART1_ReceiveData8();
}} if( UART1_GetITStatus(UART1_IT_RXNE) == SET) 這句就是讀取UART_SR寄存器,函數(shù)是庫函數(shù) Rxdata = UART1_ReceiveData8(); 這句就是讀取UART_DR寄存器,Rxdata就是自己定義接收數(shù)據(jù)的一個變量(緩存區(qū))。函數(shù)是庫函數(shù),讀 取八位數(shù)據(jù)。 至此,無限進入接收中斷的問題就解決了。 |