你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

【经验分享】STM32CubeMX—串口空闲中断+DMA接收

[复制链接]
STMCU小助手 发布时间:2022-5-16 10:35
一、实验说明
6 J7 w8 O& L1 ~. |7 @6 P# K实验平台:STM32F103C8T6/ }- |/ W6 f- `7 o  `% J
实验内容:使用串口一空闲中断结合DMA 完成不定长数据接收0 r! F& r, U; s1 K

/ E+ G9 k( c& q5 U- |+ z3 sSTM32的串口接收数据的方式
* x1 L3 b( d& _+ I& D1、轮询接收! y* ^7 H& E; Y5 P" Y- T. S, b
  所谓轮询,就是在主函数中判断接收完成的标志位。举个不太恰当例子,就比如,此时你正在考试作弊,手机藏在兜里,你的队友再给你发答案,但是你的手机静音,所以你不得不写一会题看一会手机,有的时候答案已经发来了但是你此时在假装写,没有看,导致你没能及时看到答案浪费了时间(仅仅为了举例而已。。。。)。轮询接收数据也是这样。6 h3 d# k3 \6 k8 h& \
/ a9 A3 [0 u# p2 Q) A) s
2、中断接收
, Q5 _$ k1 H! p2 ], v; q3 V4 p: K  串口接收配置为中断模式,当有数据收到时,进入到串口接收中断中读取数据。继续上面的例子(你为了不浪费时间且及时抄到答案,你把手机开了震动,消息一来立马看,这是就比上面好多了,能够及时发现消息。但是又出了一个问题,你的猪队友,写一个选择给你发一次,不停的震动,完全扰乱了你的节奏)。其实也就是,串口接收数据时,一次接收一个字节,当数据量较大时,显然这样频繁的进入中断,打断主程序,严重影响系统性能。
+ L- \0 l4 G+ s6 w4 J% c- c1 f* K% {# p- F
3、空闲中断接收

9 [3 F' r8 D. ^( y  空闲中断接收,当一帧数据接收完成之后,串口会进入到空闲中断中去,然后在空闲中断中处理收到的数据。这种模式对处理不定长数据帧带来很大的便利,我们不必频繁的进入接收中断处理数据,但是弊端也是明显的,由于每次都要接收完一个完整的数据帧后才空闲中断,所以当一帧数据出错时,我们也不得不接收这帧错误的数据。在通讯可靠的场合,使用空闲中断接收模式接收串口数据,将会大大提高系统的性能。. D9 n/ T8 h2 O9 @) p& E8 i

6 h4 c4 D7 F5 J. ^9 W5 }二、实验步骤! q0 M8 n! Z9 `: U
1、基础配置
3 ~" L$ p9 q& F9 b% i
1)、sys中,选好调试方式,例如jtag-4pin。4 t4 k: A/ z$ U" k- W# E1 U
2)、RCC时钟,晶振选择。8 \  L) a  i1 G9 w4 r9 r7 ~- a) \
3)、时钟树配置。1 R6 s+ Z$ V. O7 Y7 H
4)、中断分组配置。
! O4 y( m3 F# D  \! b以上步骤可以参考串口中断实验。
$ D3 ^- G" c% \1 `7 H  B3 _0 I& `* @; d% @
串口中断实验配置. R& T* [8 k% F9 b5 i
本实验要配置好printf函数便于演示效果
* P0 T7 v( K1 ?2 n& \& M; Z' ?' h& D0 k4 a5 E7 h. r
2、串口和DMA配置0 l% v7 ^) i* a0 ]: D9 v
1)、串口一配置。! \4 ]5 c( n' o3 N0 F1 M
5 C! H7 N4 d  z& ^% O. ~
]CXMGGO%(~CVM(]Z)3~HG(Y.png 1 y4 e. _* y- x% N& X
% |* l! _6 m6 W# P, M2 e2 y$ b4 b
2)、DMA选择; i" _2 ?5 b& U9 Z# _  U! r: l" Y
T(MA7CJTGMUHRZZU~9F.png
. q# t! \' C$ i5 i
3 ~2 B. w" w, g  z 71CDS@LW]C_6GUJ7RXXP@XN.png 3 V7 L$ M( |: A

* b& W  y9 c# `' `9 ~0 c: `3)、生成工程代码
- R2 X' s+ x0 |
  a+ Q8 d2 \; l0 O* h5 R IZOO[@GPHC5O@UK9ASY]IDI.png
5 P9 f' c; k9 ]* R2 C8 x
  z8 S8 A; t6 B, x5 i: m8 O8 M* C然后生成代码。/ f1 D2 G" I* ^/ C: }# w- B: A: _& [
4)、添加代码
4 ?( X1 F% X3 e6 T/ ^! W# A6 I( b% ]$ }0 ~( g" W( x
3@8(I63`AXKHYAEVQ4QLC30.png
3 `) ^9 E& Y" v- g, E
: b' w1 x9 S  z4 @
  1. // 这里没有使用中断回调函数,这样写更直接一点。
    3 a" H+ G1 y, N. s
  2. extern volatile uint8_t rx_len;//接收到的数据长度$ Q7 k9 x0 C& O: c+ b  S" b  H4 h
  3. extern volatile uint8_t recv_end_flag; //接收完成标志位$ Z3 d6 M+ u) l! m# _) C
  4. extern uint8_t rx_buffer[200]; //数据缓存数组
    1 j* |0 M" Q: O" r" P$ m
  5. void USART1_IRQHandler(void)4 n% o+ K2 M" A! `( l' ]( J" x
  6. {4 S6 m3 E7 c" k$ b
  7.   /* USER CODE BEGIN USART1_IRQn 0 */
    % B) y' q& S  n/ b
  8.     uint32_t tmp_flag = 0;$ `! S7 G, K& n* ?+ |+ L5 y' p0 }
  9.     uint32_t temp;: q0 I: D' e$ e7 [5 p* t
  10.     tmp_flag =__HAL_UART_GET_FLAG(&huart1,UART_FLAG_IDLE);
    , u; F) v' C0 Q, |
  11.     if((tmp_flag != RESET))/ ^8 k% a( i' R/ F) n5 ?0 c
  12.     { " N) j2 f5 u3 l* c
  13.         __HAL_UART_CLEAR_IDLEFLAG(&huart1);$ C, L; G) z& ]1 g6 G
  14.         temp = huart1.Instance->SR;  4 @6 B; d( t% t7 K( P. D/ Q( V0 |
  15.         temp = huart1.Instance->DR; , B" Z( L6 U0 m4 ]9 m: o
  16.         HAL_UART_DMAStop(&huart1); " T4 j& M4 Q7 c5 v
  17.         temp  = hdma_usart1_rx.Instance->CNDTR;
    3 e; }8 I. q0 ]3 R5 A1 W' S
  18.         rx_len =  200 - temp;
    9 b5 {9 I  j& w* @* h) [$ A7 T
  19.         recv_end_flag = 1;               
      u7 `0 _$ R9 I
  20.     }
    ) W4 G! }, R3 n! \0 F% Q! x" ~, Z
  21.     HAL_UART_IRQHandler(&huart1);        
    # a  F# U( O  p
  22. }
复制代码
0 f8 {, J6 E' ]8 g
如下图,在usart.c 文件中先把变量定义上,同时把支持printf的函数添加上。9 w) w$ y# i" v/ _5 h5 P) E5 Z
* o$ x/ W7 ^8 G0 s" k! J
  1. //注:**这三个变量 需要在stm32f1xx_it.c和main.c中外部声明**1 G9 w! D% R; [' n0 ~
  2. volatile uint8_t rx_len=0;  //接收到的数据长度; R9 D! G/ Z* I8 b- W# k
  3. volatile uint8_t recv_end_flag=0;//接收成功标志位- P- D8 X9 V/ J* V( t. T% H) D
  4. uint8_t rx_buffer[200];//缓存数组
复制代码
% y7 c# s+ y) }4 B& l
ZD3I8)}08`}Y`@Y]W5QGW19.png
9 @. O4 z7 Y3 a& S& }1 Q+ P, w# u. w& e
10BJGM%V~TYC4W]DN6F1ALW.png
4 H* q, v  F  F7 H: A
# A" I$ s4 ]1 G7 E1 e6 I+ B5 k
  1.         __HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE);
    / P8 a9 e/ G9 M) F: d2 S8 }# I; h6 L
  2. HAL_UART_Receive_DMA(&huart1,rx_buffer,200);
复制代码

- M7 e1 J) D% x% A 3_4M~T~TU3DS7MZDRB24~GL.png 2 ?# e( G. O+ F% x3 s2 t! I( h

* k2 v' P' b' \5 f( p. k1 B
  1. int main(void)6 P, ?7 G; m, M. U. |' G
  2. {0 d2 n  ]% e; c% y: o
  3.         HAL_Init();# Z$ {, U% u2 [+ v" S' o
  4.         SystemClock_Config();4 j/ s% n# }  V
  5.         MX_GPIO_Init();
    , |, r7 |) m) ^& C
  6.         MX_DMA_Init();6 [* T  L  u; t2 H8 n' ?
  7.         MX_USART1_UART_Init();
    ' B% ?' D' j" S- f% i6 T
  8.         /* USER CODE BEGIN WHILE */
    , R) p- p' Z9 k! G! f8 g
  9.         printf("DMA_TEST");# d, F3 I1 \6 W: i7 f& r# y
  10.         while (1)" k0 B5 s) k/ c) [4 m. a
  11.         {
    ) n1 x. t  T; w" \  ~7 Z
  12.                 if(recv_end_flag ==1)                        
    7 o8 ?* o1 G* R) g! j
  13.                 {        9 z9 i, R7 V! T) Q  l, h. e* p
  14.                         printf("接收到的数据长度为%d\r\n",rx_len);
    3 I; ^* @- s7 e9 p! I6 Q2 [4 g% D" I
  15.                         HAL_UART_Transmit(&huart1,rx_buffer, rx_len,200);
    0 F  s% C1 g( v5 R3 T. Y( S
  16.                         for(uint8_t i=0;i<rx_len;i++)0 B% Z: \4 s* i: X
  17.                         {* y8 g) A6 l6 I' }
  18.                                 rx_buffer<i>=0;# I' Q' a  n1 B* H' D9 z" v
  19.                         }
    3 }1 [) c1 A, s4 g' p1 N
  20.                         printf("\r\n");
    6 m0 `+ k5 X% z: Z
  21.                         rx_len=0;
    . J! A8 e, B& i5 @, }
  22.                         recv_end_flag=0;$ I6 \, A2 N/ D: y5 ^) A, h/ ?
  23.                 }
    : |( O+ ?* {, a5 q0 l
  24.                 HAL_UART_Receive_DMA(&huart1,rx_buffer,200);        6 B9 |& F0 w# y) \  U5 I+ k
  25.                 /* USER CODE END WHILE */* q/ T/ k$ t& H2 z/ V
  26.         }
    , D( M4 a0 q) D& x
  27. }
      {) B- h9 l/ V- _  S
  28. </i>
复制代码

+ a9 B4 n, s, p: E3 烧录调试* ~1 J7 l' f7 E
添加链接描述
% y) h: Q7 @/ B
# D( t5 i! R. x 2E6(L5`BW[C2NM5)0UHR3PC.png 0 \* z5 O6 R: A' _: j
收藏 评论0 发布时间:2022-5-16 10:35

举报

0个回答
关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新和工艺
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版