找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

帖子
查看: 78908|回復: 146
打印 上一主題 下一主題
收起左側(cè)

STM32串口接收不定長數(shù)據(jù)原理與源程序

  [復制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:91350 發(fā)表于 2015-10-29 23:09 | 只看該作者 |只看大圖 回帖獎勵 |倒序瀏覽 |閱讀模式
今天說一下STM32單片機的接收不定長度字節(jié)數(shù)據(jù)的方法。由于STM32單片機帶IDLE中斷,所以利用這個中斷,可以接收不定長字節(jié)的數(shù)據(jù),由于STM32屬于ARM單片機,所以這篇文章的方法也適合其他的ARM單片機。
IDLE中斷什么時候發(fā)生?
IDLE就是串口收到一幀數(shù)據(jù)后,發(fā)生的中斷。什么是一幀數(shù)據(jù)呢?比如說給單片機一次發(fā)來1個字節(jié),或者一次發(fā)來8個字節(jié),這些一次發(fā)來的數(shù)據(jù),就稱為一幀數(shù)據(jù),也可以叫做一包數(shù)據(jù)。
如何判斷一幀數(shù)據(jù)結(jié)束,就是我們今天討論的問題。因為很多項目中都要用到這個,因為只有接收到一幀數(shù)據(jù)以后,你才可以判斷這次收了幾個字節(jié)和每個字節(jié)的內(nèi)容是否符合協(xié)議要求。
看了前面IDLE中斷的定義,你就會明白了,一幀數(shù)據(jù)結(jié)束后,就會產(chǎn)生IDLE中斷。這個中斷真是太TMD有用了。省去了好多判斷的麻煩。
如何配置好IDLE中斷?
下面我們就配置好串口IDLE中斷吧。

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

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

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

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

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

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

  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. }


復制代碼

   

評分

參與人數(shù) 14黑幣 +99 收起 理由
黑夜問白天-YEJ + 12 絕世好帖!
wzb1003 + 30
Tony不吃辣 + 24 回帖助人的獎勵!
菜雞一只314159 + 5 絕世好帖!
tangchenfei + 5 很給力!
kqk123 + 1 很給力!
電子星辰 + 1 贊一個!
JULIS + 5 很給力!
Zeuphoria + 4 贊一個!
1111_1111 + 5 共享資料的黑幣獎勵!
kkkMill + 2 很棒,正好需要這一塊的東西,謝謝樓主
xiaoguaishou + 1 很給力!
panx + 2 很給力!
jsnjzhw + 2 贊一個!

查看全部評分

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏45 分享淘帖 頂23 踩
回復

使用道具 舉報

沙發(fā)
ID:91390 發(fā)表于 2016-2-1 21:59 | 只看該作者
好詳細的帖子,謝謝lz
回復

使用道具 舉報

板凳
ID:105982 發(fā)表于 2016-2-21 19:27 | 只看該作者
程序下來試了,IDLE進不了�。�
回復

使用道具 舉報

地板
ID:109266 發(fā)表于 2016-3-17 08:13 | 只看該作者
這兩天正在琢磨STM32F103的串口中斷處理程序,之前以為只能一個字節(jié)一個字節(jié)接收,多謝樓主提醒還有IDLE這個幀數(shù)據(jù)接收,大愛啊!
回復

使用道具 舉報

5#
ID:109266 發(fā)表于 2016-3-17 08:13 | 只看該作者
這兩天正在琢磨STM32F103的串口中斷處理程序,之前以為只能一個字節(jié)一個字節(jié)接收,多謝樓主提醒還有IDLE這個幀數(shù)據(jù)接收,大愛�。�
回復

使用道具 舉報

6#
ID:110407 發(fā)表于 2016-3-23 17:50 | 只看該作者
好標記
回復

使用道具 舉報

7#
ID:114928 發(fā)表于 2016-4-18 15:13 | 只看該作者
謝謝樓主的分享,太贊了,終于解決我這個不定長GPS信息的接收問題了,贊贊贊
回復

使用道具 舉報

8#
ID:114928 發(fā)表于 2016-4-18 15:19 | 只看該作者
woodman100 發(fā)表于 2016-2-21 19:27
程序下來試了,IDLE進不了��!

你進不了嗎?我就是參考了 這個思想,很棒��!你看看是不是板子的型號不對,他這是F1的,修改程序,和你的板子相稱
回復

使用道具 舉報

9#
ID:115692 發(fā)表于 2016-4-21 14:09 | 只看該作者
感覺挺不錯,之前還有個什么串口延時處理,要是這個能用的話都不用那么麻煩了
回復

使用道具 舉報

10#
ID:119763 發(fā)表于 2016-5-10 13:28 | 只看該作者
贊,解決了我的問題
回復

使用道具 舉報

11#
ID:122041 發(fā)表于 2016-5-19 21:05 | 只看該作者
太感謝樓主了
回復

使用道具 舉報

12#
ID:122041 發(fā)表于 2016-5-19 21:06 | 只看該作者
感謝樓主
回復

使用道具 舉報

13#
ID:122221 發(fā)表于 2016-5-20 18:57 | 只看該作者
謝謝樓主分享,幫了大忙。。。。。。。
回復

使用道具 舉報

14#
ID:117525 發(fā)表于 2016-5-21 00:22 來自觸屏版 | 只看該作者
正在學這個,給點贊樓主
回復

使用道具 舉報

15#
ID:120530 發(fā)表于 2016-5-30 10:49 | 只看該作者
為什么最后串口發(fā)送的數(shù)據(jù)總是有個別數(shù)據(jù)丟失了呢?
回復

使用道具 舉報

16#
ID:120530 發(fā)表于 2016-5-30 10:50 | 只看該作者
樓主,為什么最好發(fā)送的數(shù)據(jù)總是有個別的數(shù)據(jù)丟失了呢?
回復

使用道具 舉報

17#
ID:120530 發(fā)表于 2016-5-30 11:08 | 只看該作者
樓主,波特率為9600的時候數(shù)據(jù)是正確的,當波特率設(shè)置為115200時,數(shù)據(jù)就不正確了,為什么呢?
回復

使用道具 舉報

18#
ID:124166 發(fā)表于 2016-5-31 08:52 | 只看該作者
真心是太TMD有用了
回復

使用道具 舉報

19#
ID:126634 發(fā)表于 2016-6-14 10:40 | 只看該作者
大家好,我是新來的,就像樓主說的方法我也試了,只不過是用的UART4,在發(fā)送的時候也是有數(shù)據(jù)丟失,是什么原因呢
回復

使用道具 舉報

20#
ID:126864 發(fā)表于 2016-6-15 16:05 | 只看該作者
zhichizhichi
回復

使用道具 舉報

21#
ID:103617 發(fā)表于 2016-6-30 17:21 | 只看該作者
非常謝謝。
回復

使用道具 舉報

22#
ID:128839 發(fā)表于 2016-7-1 17:02 | 只看該作者
學習了
回復

使用道具 舉報

23#
ID:130030 發(fā)表于 2016-7-11 15:40 來自觸屏版 | 只看該作者
好東西,謝謝!
回復

使用道具 舉報

24#
ID:134419 發(fā)表于 2016-7-20 20:53 | 只看該作者
好東西,學習了。
回復

使用道具 舉報

25#
ID:123377 發(fā)表于 2016-7-21 09:20 | 只看該作者
非常有用,modbus可以用上 前面說的9600可以有這個情況嗎
回復

使用道具 舉報

26#
ID:6553 發(fā)表于 2016-7-22 11:27 | 只看該作者
謝謝樓主的分享,太贊了
回復

使用道具 舉報

27#
ID:136557 發(fā)表于 2016-8-11 20:58 | 只看該作者

感謝樓主
回復

使用道具 舉報

28#
ID:136869 發(fā)表于 2016-8-16 11:13 | 只看該作者
很好,學習學習!
回復

使用道具 舉報

29#
ID:136903 發(fā)表于 2016-8-16 16:36 | 只看該作者
一直在找方法到底怎么做!�。。。。。。。。。�!
回復

使用道具 舉報

30#
ID:136903 發(fā)表于 2016-8-17 16:55 | 只看該作者
真心的良心帖子
回復

使用道具 舉報

31#
ID:136987 發(fā)表于 2016-8-17 18:08 | 只看該作者
強�。。�!為;樓主的態(tài)度點贊�。�
回復

使用道具 舉報

32#
ID:137439 發(fā)表于 2016-8-23 23:41 來自觸屏版 | 只看該作者
謝謝樓主的分享,太贊了
回復

使用道具 舉報

33#
ID:138053 發(fā)表于 2016-8-31 15:05 | 只看該作者
不錯,支持
回復

使用道具 舉報

34#
ID:136553 發(fā)表于 2016-9-25 21:56 | 只看該作者
繼續(xù)頂,終于有黑幣可以下載了
回復

使用道具 舉報

35#
ID:142422 發(fā)表于 2016-10-12 13:30 | 只看該作者

感謝樓主
回復

使用道具 舉報

36#
ID:75390 發(fā)表于 2016-10-12 15:11 | 只看該作者
感謝樓主教誨
回復

使用道具 舉報

37#
ID:61002 發(fā)表于 2016-10-13 16:48 | 只看該作者
好貼  推薦
回復

使用道具 舉報

38#
ID:143545 發(fā)表于 2016-10-20 10:26 | 只看該作者
正好需要串口傳速大量的數(shù)據(jù),不知道速度跟不跟得上
回復

使用道具 舉報

39#
ID:143559 發(fā)表于 2016-10-20 11:08 | 只看該作者
嗯,不錯不錯,我之前還是使用流控制界定幀的,移植性好一點,但是既然STM32自帶這個功能那為何不用呢,
回復

使用道具 舉報

40#
ID:146174 發(fā)表于 2016-11-5 09:37 | 只看該作者
兄弟,為什么我參考你的這個程序,串口助手發(fā)送11 22 33 44 55時,單片機接收出現(xiàn)FF 11 22 33 44 55
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規(guī)則

小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機教程網(wǎng)

快速回復 返回頂部 返回列表