標(biāo)題: STM32串口接收不定長數(shù)據(jù)原理與源程序 [打印本頁]

作者: piaolin    時(shí)間: 2015-10-29 23:09
標(biāo)題: STM32串口接收不定長數(shù)據(jù)原理與源程序
今天說一下STM32單片機(jī)的接收不定長度字節(jié)數(shù)據(jù)的方法。由于STM32單片機(jī)帶IDLE中斷,所以利用這個(gè)中斷,可以接收不定長字節(jié)的數(shù)據(jù),由于STM32屬于ARM單片機(jī),所以這篇文章的方法也適合其他的ARM單片機(jī)。
IDLE中斷什么時(shí)候發(fā)生?
IDLE就是串口收到一幀數(shù)據(jù)后,發(fā)生的中斷。什么是一幀數(shù)據(jù)呢?比如說給單片機(jī)一次發(fā)來1個(gè)字節(jié),或者一次發(fā)來8個(gè)字節(jié),這些一次發(fā)來的數(shù)據(jù),就稱為一幀數(shù)據(jù),也可以叫做一包數(shù)據(jù)。
如何判斷一幀數(shù)據(jù)結(jié)束,就是我們今天討論的問題。因?yàn)楹芏囗?xiàng)目中都要用到這個(gè),因?yàn)橹挥薪邮盏揭粠瑪?shù)據(jù)以后,你才可以判斷這次收了幾個(gè)字節(jié)和每個(gè)字節(jié)的內(nèi)容是否符合協(xié)議要求。
看了前面IDLE中斷的定義,你就會明白了,一幀數(shù)據(jù)結(jié)束后,就會產(chǎn)生IDLE中斷。這個(gè)中斷真是太TMD有用了。省去了好多判斷的麻煩。
如何配置好IDLE中斷?
下面我們就配置好串口IDLE中斷吧。

這是串口CR1寄存器,其中,對bit4寫1開啟IDLE中斷,對bit5寫1開啟接收數(shù)據(jù)中斷。(注意:不同系列的STM32,對應(yīng)的寄存器位可能不同)
(RXNE中斷和IDLE中斷的區(qū)別?
當(dāng)接收到1個(gè)字節(jié),就會產(chǎn)生RXNE中斷,當(dāng)接收到一幀數(shù)據(jù),就會產(chǎn)生IDLE中斷。比如給單片機(jī)一次性發(fā)送了8個(gè)字節(jié),就會產(chǎn)生8次RXNE中斷,1次IDLE中斷。)

這是狀態(tài)寄存器,當(dāng)串口接收到數(shù)據(jù)時(shí),bit5就會自動變成1,當(dāng)接收完一幀數(shù)據(jù)后,bit4就會變成1.
需要注意的是,在中斷函數(shù)里面,需要把對應(yīng)的位清0,否則會影響下一次數(shù)據(jù)的接收。比如RXNE接收數(shù)據(jù)中斷,只要把接收到的一個(gè)字節(jié)讀出來,就會清除這個(gè)中斷。IDLE中斷,如何是F0系列的單片機(jī),需要用ICR寄存器來清除,如果是F1系列的單片機(jī),清除方法是“先讀SR寄存器,再讀DR寄存器”。(我怎么知道?手冊上寫的)
下面以STM32F103為例給出源程序。
我們先來看程序中的主要部分。
串口初始化函數(shù)片段

如果你原來的串口初始化函數(shù)具有打開串口接收中斷的話,實(shí)際上就是在初始化函數(shù)中多了一條打開空閑中斷的語句。
串口中斷函數(shù)

串口中斷函數(shù)里面,最重要的兩條語句,就是上圖中圈出來的兩條語句。第一條語句用來判斷是否接收到1個(gè)字節(jié),第二條語句用來判斷是否接收到1幀數(shù)據(jù)。(是不是感覺超級方便?媽媽再也不用擔(dān)心我如何判斷是否接收完1幀數(shù)據(jù)了。)
主函數(shù)

我寫的這個(gè)主函數(shù),是用來驗(yàn)證接收的正確性的。RxCounter表示的是這一幀數(shù)據(jù)有幾個(gè)字節(jié),接收完一幀數(shù)據(jù),會在中斷函數(shù)里面把ReceiveState置1,然后,通過串口把接收到的數(shù)據(jù)發(fā)送回串口。這樣,既驗(yàn)證了接收了多少字節(jié)的正確性,又驗(yàn)證了接收到的數(shù)據(jù)是否正確。

上圖是結(jié)果驗(yàn)證。
點(diǎn)擊下載源程序: STM32串口接收不定長數(shù)據(jù)程序.7z (207.13 KB, 下載次數(shù): 1812)
                                       
                                我是瑞生,毫無保留的給大家透露電子設(shè)計(jì)經(jīng)驗(yàn),不定時(shí)分享實(shí)用的落地的電子設(shè)計(jì)技巧,希望能夠幫助到大家。   

  1. /**
  2.   ******************************************************************************
  3.   * @file    串口接收不定長字節(jié)數(shù)據(jù)
  4.   * @author  瑞生
  5.   * @version V1.0
  6.   * @date    2015.10.23
  7.   * @brief   Main program body
  8.   ******************************************************************************
  9.   ******************************************************************************
  10.   */  

  11. /* Includes ------------------------------------------------------------------*/
  12. #include "stm32f10x.h"
  13. #include "uart.h"


  14. volatile uint8_t aRxBuffer[100]={0x00};
  15. volatile uint8_t RxCounter=0;
  16. volatile uint8_t ReceiveState=0;
  17. /**
  18.   * @brief  Main program.
  19.   * @param  None
  20.   * @retval None
  21.   */
  22. int main(void)
  23. {
  24.         uint8_t i=0;
  25.         
  26.         USART1_Init();
  27.         
  28.   while (1)
  29.   {
  30.                 if(ReceiveState==1)//如果接收到1幀數(shù)據(jù)
  31.                 {
  32.                         ReceiveState=0;
  33.                         i=0;

  34.                         while(RxCounter--)// 把接收到數(shù)據(jù)發(fā)送回串口
  35.                         {
  36.                                 USART_SendData(USART1, aRxBuffer[i++]);        
  37.                                 while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET);
  38.                         }
  39.                         RxCounter=0;
  40.                 }
  41.   }
  42. }


復(fù)制代碼

   

作者: 0406445    時(shí)間: 2016-2-1 21:59
好詳細(xì)的帖子,謝謝lz
作者: woodman100    時(shí)間: 2016-2-21 19:27
程序下來試了,IDLE進(jìn)不了。

作者: My_Skity    時(shí)間: 2016-3-17 08:13
這兩天正在琢磨STM32F103的串口中斷處理程序,之前以為只能一個(gè)字節(jié)一個(gè)字節(jié)接收,多謝樓主提醒還有IDLE這個(gè)幀數(shù)據(jù)接收,大愛啊!
作者: My_Skity    時(shí)間: 2016-3-17 08:13
這兩天正在琢磨STM32F103的串口中斷處理程序,之前以為只能一個(gè)字節(jié)一個(gè)字節(jié)接收,多謝樓主提醒還有IDLE這個(gè)幀數(shù)據(jù)接收,大愛!
作者: duckfans    時(shí)間: 2016-3-23 17:50
好標(biāo)記
作者: seu_zhang    時(shí)間: 2016-4-18 15:13
謝謝樓主的分享,太贊了,終于解決我這個(gè)不定長GPS信息的接收問題了,贊贊贊
作者: seu_zhang    時(shí)間: 2016-4-18 15:19
woodman100 發(fā)表于 2016-2-21 19:27
程序下來試了,IDLE進(jìn)不了!

你進(jìn)不了嗎?我就是參考了 這個(gè)思想,很棒啊!你看看是不是板子的型號不對,他這是F1的,修改程序,和你的板子相稱
作者: 舞者0068    時(shí)間: 2016-4-21 14:09
感覺挺不錯,之前還有個(gè)什么串口延時(shí)處理,要是這個(gè)能用的話都不用那么麻煩了
作者: hdfjg    時(shí)間: 2016-5-10 13:28
贊,解決了我的問題
作者: 打醬油+1    時(shí)間: 2016-5-19 21:05
太感謝樓主了
作者: 打醬油+1    時(shí)間: 2016-5-19 21:06
感謝樓主
作者: doer    時(shí)間: 2016-5-20 18:57
謝謝樓主分享,幫了大忙。。。。。。。
作者: MUCV    時(shí)間: 2016-5-21 00:22
正在學(xué)這個(gè),給點(diǎn)贊樓主
作者: sqhua333    時(shí)間: 2016-5-30 10:49
為什么最后串口發(fā)送的數(shù)據(jù)總是有個(gè)別數(shù)據(jù)丟失了呢?
作者: sqhua333    時(shí)間: 2016-5-30 10:50
樓主,為什么最好發(fā)送的數(shù)據(jù)總是有個(gè)別的數(shù)據(jù)丟失了呢?

作者: sqhua333    時(shí)間: 2016-5-30 11:08
樓主,波特率為9600的時(shí)候數(shù)據(jù)是正確的,當(dāng)波特率設(shè)置為115200時(shí),數(shù)據(jù)就不正確了,為什么呢?
作者: mardin    時(shí)間: 2016-5-31 08:52
真心是太TMD有用了
作者: yaoyanyan    時(shí)間: 2016-6-14 10:40
大家好,我是新來的,就像樓主說的方法我也試了,只不過是用的UART4,在發(fā)送的時(shí)候也是有數(shù)據(jù)丟失,是什么原因呢
作者: lamdota    時(shí)間: 2016-6-15 16:05
zhichizhichi
作者: phantomplus    時(shí)間: 2016-6-30 17:21
非常謝謝。
作者: a7250658    時(shí)間: 2016-7-1 17:02
學(xué)習(xí)了

作者: 遺忘的心    時(shí)間: 2016-7-11 15:40
好東西,謝謝!
作者: 默默成長    時(shí)間: 2016-7-20 20:53
好東西,學(xué)習(xí)了。
作者: tanliang    時(shí)間: 2016-7-21 09:20
非常有用,modbus可以用上 前面說的9600可以有這個(gè)情況嗎
作者: senzh01    時(shí)間: 2016-7-22 11:27
謝謝樓主的分享,太贊了
作者: 1321498219    時(shí)間: 2016-8-11 20:58

感謝樓主
作者: biyaoyzs    時(shí)間: 2016-8-16 11:13
很好,學(xué)習(xí)學(xué)習(xí)!
作者: faguoduifangui    時(shí)間: 2016-8-16 16:36
一直在找方法到底怎么做。。。。。。。。。。!
作者: faguoduifangui    時(shí)間: 2016-8-17 16:55
真心的良心帖子
作者: qscdianzhi    時(shí)間: 2016-8-17 18:08
強(qiáng)!。。;樓主的態(tài)度點(diǎn)贊!!
作者: intersetings    時(shí)間: 2016-8-23 23:41
謝謝樓主的分享,太贊了
作者: tubage    時(shí)間: 2016-8-31 15:05
不錯,支持
作者: vitasnokia    時(shí)間: 2016-9-25 21:56
繼續(xù)頂,終于有黑幣可以下載了
作者: 單片機(jī)初始化    時(shí)間: 2016-10-12 13:30

感謝樓主
作者: johnsonxjq    時(shí)間: 2016-10-12 15:11
感謝樓主教誨
作者: g753388438    時(shí)間: 2016-10-13 16:48
好貼  推薦
作者: whole_hope    時(shí)間: 2016-10-20 10:26
正好需要串口傳速大量的數(shù)據(jù),不知道速度跟不跟得上
作者: tangquan    時(shí)間: 2016-10-20 11:08
嗯,不錯不錯,我之前還是使用流控制界定幀的,移植性好一點(diǎn),但是既然STM32自帶這個(gè)功能那為何不用呢,
作者: jackouy    時(shí)間: 2016-11-5 09:37
兄弟,為什么我參考你的這個(gè)程序,串口助手發(fā)送11 22 33 44 55時(shí),單片機(jī)接收出現(xiàn)FF 11 22 33 44 55
作者: dmgy343    時(shí)間: 2016-11-14 15:34
好辦法,下次嘗試使用這種方法
作者: jzxiecl    時(shí)間: 2016-11-15 17:28
果然是良心貼,頂。。。。。。。。
作者: 709360416    時(shí)間: 2016-11-17 14:16
我用的是串口2,但是不通
作者: bing20138    時(shí)間: 2016-11-22 13:15
這個(gè)方式很贊。。!
作者: 1725591298    時(shí)間: 2016-12-12 16:11
8錯~~~
作者: ljy773945726    時(shí)間: 2016-12-12 18:40
謝謝樓主分享,先收藏下。!
作者: ljy773945726    時(shí)間: 2016-12-12 18:40
謝謝樓主分享!。
作者: 520sky    時(shí)間: 2017-2-6 17:27
試了好多網(wǎng)上的idle+dma的都不行
作者: 520sky    時(shí)間: 2017-2-7 15:31
不知道怎么回事就是進(jìn)不了 IDLE
作者: 332052001    時(shí)間: 2017-2-26 12:36
我曹這個(gè)功能太有用了,以前做51的時(shí)候都是定了長度的
作者: jasonyu    時(shí)間: 2017-2-27 09:51
樓主你好,為什么我按照你的程序這樣改的,那個(gè)idle中斷每個(gè)字節(jié)都進(jìn)呢
作者: zhang135789    時(shí)間: 2017-3-4 09:23
良心貼,很有用處,只是修改
作者: xiangyang123    時(shí)間: 2017-3-4 14:57
好貼必須頂上去,贊贊贊贊贊贊贊贊贊贊贊贊贊贊贊贊贊贊贊贊贊贊贊贊贊贊贊贊贊贊贊贊贊贊贊贊贊贊贊贊贊贊
作者: splendid    時(shí)間: 2017-3-4 16:03
大兄弟,用了五黑幣下下來,連中斷程序都沒有是怎么回事??
作者: museum    時(shí)間: 2017-3-27 13:56
誰下載了給我一份  qq  1952488652
我積分不夠,謝謝
作者: cm7626    時(shí)間: 2017-4-8 11:14
講解的很詳細(xì) 大家需要你這樣的高手
作者: jdm2005    時(shí)間: 2017-4-26 13:22
高手,謝謝知道
作者: 落雁秋莎    時(shí)間: 2017-4-27 10:59
很好,希望有所幫助
作者: hongqintin    時(shí)間: 2017-5-18 11:36
好貼,謝謝樓主
作者: xiaoyue92    時(shí)間: 2017-5-19 18:16
我遇到和上面同志一樣的問題  有數(shù)據(jù)丟失現(xiàn)象  樓主能解下禍嗎
作者: 樹葉的人生    時(shí)間: 2017-5-20 10:36
這個(gè)真的很有用啊,謝謝分享,很有幫助的
作者: worinidege    時(shí)間: 2017-5-23 14:08
就是不知道后面的abuffer是怎么處理的
作者: victor6611    時(shí)間: 2017-6-12 09:40
不錯,下載學(xué)習(xí),學(xué)習(xí)
作者: dzfree    時(shí)間: 2017-6-30 15:56
很詳細(xì)很經(jīng)典的帖子,苦無頭緒的串口終于搞定了  謝謝謝謝謝謝謝謝 謝謝謝謝
作者: sfd123    時(shí)間: 2017-7-1 10:28
什么原理呢?單片機(jī)根據(jù)波特率自己得到一個(gè)幀超時(shí)時(shí)間?
作者: cqh757128    時(shí)間: 2017-7-4 08:28
很棒,正好需要這一塊的東西,謝謝樓主
作者: 君臨天下尹成    時(shí)間: 2017-8-4 16:33
很實(shí)用                  
作者: Allaneil    時(shí)間: 2017-9-13 10:40
感謝樓之分享
作者: 穿山躍海    時(shí)間: 2017-11-23 23:34
下來試試,借鑒一下,最近正在調(diào)這個(gè)東西
作者: www76307a    時(shí)間: 2017-12-5 16:45
好詳細(xì)的帖子,謝謝lz
作者: 竹軒2018    時(shí)間: 2018-1-2 23:27
給力樓主!謝謝分享!
作者: fan5572283    時(shí)間: 2018-1-7 15:22
感謝樓主
作者: xjjwws    時(shí)間: 2018-1-16 17:01
好東西,值得大家下載。原樓主多多奉獻(xiàn),不慎感激
作者: whj4674672    時(shí)間: 2018-3-19 11:06
好東西,正好有用
作者: 278821852    時(shí)間: 2018-3-27 19:51
好東西,謝謝樓主分享!
作者: 564646546465    時(shí)間: 2018-3-29 16:34
贊贊贊。。。。!程序試過了,沒問題
作者: gaojian218    時(shí)間: 2018-4-3 22:32
好詳細(xì)的帖子,謝謝lz
作者: wutuobangs    時(shí)間: 2018-4-8 14:02
感謝樓主分享
作者: fly_confidence    時(shí)間: 2018-5-22 22:14
好詳細(xì)的帖子,謝謝lz
作者: ljjmust    時(shí)間: 2018-5-25 09:36
真的很方便,非常感謝。
作者: caosongze    時(shí)間: 2018-6-2 17:04
收益匪淺
作者: user5448    時(shí)間: 2018-6-4 12:50
長知識了 感謝無私分享
作者: Jesus    時(shí)間: 2018-7-7 13:42
新手簽到,謝謝
作者: 一世界    時(shí)間: 2018-7-11 11:15
  牛逼  簡直學(xué)到了  
作者: 小歐陽    時(shí)間: 2018-7-12 17:31
我也用了出了一些問題
作者: kaneky    時(shí)間: 2018-7-31 14:09
學(xué)習(xí)了,謝謝樓主!
作者: 離落城    時(shí)間: 2018-10-12 13:10
很給力!
作者: hwasun    時(shí)間: 2018-11-6 10:29
感覺挺不錯,之前還有個(gè)什么串口延時(shí)處理,要是這個(gè)能用的話都不用那么麻煩了
作者: wdliming    時(shí)間: 2018-11-13 08:44
標(biāo)記一下~~~~~
作者: guguren    時(shí)間: 2018-11-19 15:32
學(xué)習(xí)下,新手
作者: 離落城    時(shí)間: 2018-12-2 15:13
先收藏了,有空一定試試
作者: SKYlink    時(shí)間: 2018-12-3 09:15
厲害厲害   
作者: Xchonger    時(shí)間: 2018-12-4 11:01
不錯 ,學(xué)習(xí)到了
作者: Adey楊    時(shí)間: 2018-12-17 13:35
有沒有庫函數(shù)版本的代碼呢,寄存器不會
作者: bucker    時(shí)間: 2018-12-21 21:54
雖然已經(jīng)用過,確實(shí)非常好用,還是為樓主點(diǎn)贊。
作者: 天風(fēng)情    時(shí)間: 2018-12-24 16:43
正學(xué)習(xí)中斷呢,看了好多程序,目前看到的只有這個(gè)比較好
作者: 天風(fēng)情    時(shí)間: 2018-12-24 16:44
jackouy 發(fā)表于 2016-11-5 09:37
**** 作者被禁止或刪除 內(nèi)容自動屏蔽 ****

是不是上電的時(shí)候多發(fā)的?你上電穩(wěn)定后把接收數(shù)據(jù)清除一下,再發(fā)送試試看
作者: amesim2019    時(shí)間: 2019-4-17 13:52
太感謝樓主了
作者: jiaxiangqi    時(shí)間: 2019-5-14 20:53
非常感謝樓主分享
作者: Caramel2    時(shí)間: 2019-6-30 19:43
謝謝樓主分享!




歡迎光臨 (http://www.torrancerestoration.com/bbs/) Powered by Discuz! X3.1