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

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

[复制链接]
STMCU小助手 发布时间:2022-5-16 10:35
一、实验说明
7 a6 [; N% H4 Y% R0 X& T9 G实验平台:STM32F103C8T6
" w% s( T% N0 L0 E( q3 F实验内容:使用串口一空闲中断结合DMA 完成不定长数据接收
" C8 E6 `" t5 g% v; h  P/ Z. R/ `" D" L. z6 ^- L5 a
STM32的串口接收数据的方式7 A# i# b' |. n9 L. U
1、轮询接收
9 F. ]) V+ w1 Z  所谓轮询,就是在主函数中判断接收完成的标志位。举个不太恰当例子,就比如,此时你正在考试作弊,手机藏在兜里,你的队友再给你发答案,但是你的手机静音,所以你不得不写一会题看一会手机,有的时候答案已经发来了但是你此时在假装写,没有看,导致你没能及时看到答案浪费了时间(仅仅为了举例而已。。。。)。轮询接收数据也是这样。
, i5 J% u- j7 D: p! {5 K3 B' u( ]
2、中断接收
0 I1 i! K5 s# g2 {5 G/ s  串口接收配置为中断模式,当有数据收到时,进入到串口接收中断中读取数据。继续上面的例子(你为了不浪费时间且及时抄到答案,你把手机开了震动,消息一来立马看,这是就比上面好多了,能够及时发现消息。但是又出了一个问题,你的猪队友,写一个选择给你发一次,不停的震动,完全扰乱了你的节奏)。其实也就是,串口接收数据时,一次接收一个字节,当数据量较大时,显然这样频繁的进入中断,打断主程序,严重影响系统性能。
" p6 ?6 v" }4 i8 T7 E7 V/ t; l' |4 S! L
3、空闲中断接收
! m9 Y. o, {4 r) ]. F+ y" H
  空闲中断接收,当一帧数据接收完成之后,串口会进入到空闲中断中去,然后在空闲中断中处理收到的数据。这种模式对处理不定长数据帧带来很大的便利,我们不必频繁的进入接收中断处理数据,但是弊端也是明显的,由于每次都要接收完一个完整的数据帧后才空闲中断,所以当一帧数据出错时,我们也不得不接收这帧错误的数据。在通讯可靠的场合,使用空闲中断接收模式接收串口数据,将会大大提高系统的性能。4 l% Y) y2 B# P  B6 \
# o; v' ?; D, P1 A* a7 G/ L( {
二、实验步骤
4 v0 G6 r) i+ _) L1、基础配置

6 Z. x6 B+ D, h$ E; y, p0 e, e; B1)、sys中,选好调试方式,例如jtag-4pin。
4 b1 l/ f7 E% j& X2 x/ K2)、RCC时钟,晶振选择。
. f3 Y7 i" e* a3)、时钟树配置。
) D: k9 R8 O) L! i/ {4)、中断分组配置。# r; X5 d- k. t8 b% r
以上步骤可以参考串口中断实验。6 N# t; D( U1 \' Q5 H5 c* E
+ S) p# _9 e: Q& l. W
串口中断实验配置! ]: P1 a: ]$ E8 `9 W% o( v9 ]& y8 q
本实验要配置好printf函数便于演示效果
  F  }# w4 i$ d$ Z1 ~: o0 o! \" K- L% V* c& C
2、串口和DMA配置, ~; K; D2 B6 `* u  I0 W6 P
1)、串口一配置。- I- g1 w1 c& X

. d: L: g) M* I8 n* ]4 p4 j$ i ]CXMGGO%(~CVM(]Z)3~HG(Y.png + n/ w$ E4 k. v4 Q3 v0 O7 y

+ Y% `6 F6 q4 H0 N# M2)、DMA选择
/ o) x/ F  C! C T(MA7CJTGMUHRZZU~9F.png # e* e3 U3 b7 W' `7 h% [
$ w0 v+ r0 J. S4 W9 z$ Q
71CDS@LW]C_6GUJ7RXXP@XN.png ) J! q1 ]; F+ k: y
$ t; v8 r# o5 M
3)、生成工程代码4 e; ~) ^5 @; T* p

- b" A- g( A: _9 I IZOO[@GPHC5O@UK9ASY]IDI.png ( Z" A0 Z* t+ j+ p* p

" E* b) c$ L, a9 ?然后生成代码。
0 s# j4 ]; A' k7 a$ U, H  o4)、添加代码
0 Q( I- K) B% y; a, g5 F' B8 J  D5 g% H, B
3@8(I63`AXKHYAEVQ4QLC30.png
/ C. z. U) Z# j8 Z$ |1 ?  F  v# X) }8 T; _: ]; ^- ^
  1. // 这里没有使用中断回调函数,这样写更直接一点。
    7 u. Z2 W7 q7 T/ S
  2. extern volatile uint8_t rx_len;//接收到的数据长度
    3 l# G# c* {" w1 s1 d1 B* F0 f
  3. extern volatile uint8_t recv_end_flag; //接收完成标志位# j. N# ^6 x, M- d
  4. extern uint8_t rx_buffer[200]; //数据缓存数组+ v& e: ~% [: ?
  5. void USART1_IRQHandler(void)) W# V" U! R; |9 v
  6. {& m. [( N. B( d7 v) d1 F
  7.   /* USER CODE BEGIN USART1_IRQn 0 */
    - q9 u+ a) H2 O4 b3 L& d9 W1 a0 z" a
  8.     uint32_t tmp_flag = 0;# r* G  A4 `! r0 @. `
  9.     uint32_t temp;# ]3 ]' ^$ @6 L4 m: Y* m
  10.     tmp_flag =__HAL_UART_GET_FLAG(&huart1,UART_FLAG_IDLE);
    $ P, x: Q) ]" F5 a
  11.     if((tmp_flag != RESET)), r+ i! B4 ]# Z& o1 ~
  12.     { ; y+ S& W* {% T2 ?& B
  13.         __HAL_UART_CLEAR_IDLEFLAG(&huart1);- ~8 I% f3 {5 T4 j, E; \
  14.         temp = huart1.Instance->SR;  
    ( f4 ?# D; X2 R
  15.         temp = huart1.Instance->DR;
    2 x& E4 R! r. _- M
  16.         HAL_UART_DMAStop(&huart1); : H$ R' D6 F( E4 u5 Z
  17.         temp  = hdma_usart1_rx.Instance->CNDTR;
    + k/ H1 }: G$ P1 h+ a8 b0 _3 Y
  18.         rx_len =  200 - temp; 1 y9 P: R6 @$ O7 i0 ]( q. y8 k; l
  19.         recv_end_flag = 1;               
    / T: M7 _0 Q3 Q$ D5 e$ j
  20.     }3 d, f" S' c# b$ ?; E. R" E
  21.     HAL_UART_IRQHandler(&huart1);        . D( G- o1 L5 g  G9 Z" K9 d
  22. }
复制代码

% s4 X$ P7 g$ }5 c& x3 U1 d如下图,在usart.c 文件中先把变量定义上,同时把支持printf的函数添加上。/ r3 ^" _' ]0 m7 G1 i( T1 ]8 x  d
& Y, R* P7 a/ ?- T) V; r6 R9 z
  1. //注:**这三个变量 需要在stm32f1xx_it.c和main.c中外部声明**. G, k- S3 _& t- s& E  h0 e
  2. volatile uint8_t rx_len=0;  //接收到的数据长度
    1 q4 ]: J( _0 Q
  3. volatile uint8_t recv_end_flag=0;//接收成功标志位
    - Z, ]2 v! r1 z! y4 J5 D; `
  4. uint8_t rx_buffer[200];//缓存数组
复制代码

# J! ~/ Z' W! q3 D ZD3I8)}08`}Y`@Y]W5QGW19.png
! u  S# G! k8 T& o5 Y( |/ Q
3 Y2 ^: r2 s6 Z2 Z2 z 10BJGM%V~TYC4W]DN6F1ALW.png
/ \7 ?' V6 c5 N) ^
; m& y( g( ~8 v0 u  Q+ }% W
  1.         __HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE);0 C5 t8 O7 W, t4 p5 W! i$ G. t8 [
  2. HAL_UART_Receive_DMA(&huart1,rx_buffer,200);
复制代码

& Y; C  |9 p: c  O) A! D! }9 y 3_4M~T~TU3DS7MZDRB24~GL.png
! e3 A& m& }8 M  Q. U
- q2 u& ?$ H, t; f
  1. int main(void)
    " ?+ O4 x0 B: L; o) V
  2. {
    / a5 b! m! W  h& D
  3.         HAL_Init();
    4 M/ X+ v; l, m" k+ r
  4.         SystemClock_Config();# @& J* M* L/ a" w( T
  5.         MX_GPIO_Init();
    + k: D) I# H, N& S
  6.         MX_DMA_Init();
    1 L3 F) }% `8 x0 E2 X( s/ D7 y
  7.         MX_USART1_UART_Init();
    ! `6 {+ o9 F7 Z! c4 e0 h( U  Q- {2 Z
  8.         /* USER CODE BEGIN WHILE */
    8 o: g0 u# }: b  g$ W: G5 o
  9.         printf("DMA_TEST");
    6 }& |/ o" j/ R! b) ^- J) h- x' T
  10.         while (1)
    , x; u, l2 p$ A' Y
  11.         {
    9 o2 ~3 e/ h% g  Y
  12.                 if(recv_end_flag ==1)                        ' f4 x: f- w8 g- Z+ M8 M
  13.                 {        2 n9 X8 G1 c" ?; J6 a- H" S7 }
  14.                         printf("接收到的数据长度为%d\r\n",rx_len);
    8 n- b  }8 X# v2 o& d0 n: [. @- Q
  15.                         HAL_UART_Transmit(&huart1,rx_buffer, rx_len,200);
    - Q, d7 ^' M- R8 ]3 x
  16.                         for(uint8_t i=0;i<rx_len;i++)
    ( ?2 D1 j7 J- g! p. J" P8 J2 b
  17.                         {7 D* _1 f# @4 S& }  ~! o/ s
  18.                                 rx_buffer<i>=0;8 d& o$ |- n# E- S  P/ C) z
  19.                         }$ n  i# Q8 n/ m( c, s& R: R
  20.                         printf("\r\n");
    " x% v% P. k0 i" O2 T# L4 `% M
  21.                         rx_len=0;
    # f) Q$ @! U, T5 N* H0 a
  22.                         recv_end_flag=0;+ y. }0 n8 w% W
  23.                 }
    ' Z: A2 X0 o  A& S6 @
  24.                 HAL_UART_Receive_DMA(&huart1,rx_buffer,200);        
    5 N7 i( x; n: L' w% A; `
  25.                 /* USER CODE END WHILE */
    ) j& Q! z' T# B5 b. E4 i! E% R
  26.         }
    . A$ `6 m$ l/ Q
  27. }
    . d" S( ?+ m$ [5 ^+ s
  28. </i>
复制代码

" }* c2 @& w, G" @* n9 h3 烧录调试
3 m  e$ R! {( e$ [: P) l添加链接描述" {: m0 d, ^/ X  j. u4 e! a
& m; E, t7 o5 d9 ~- Y/ K
2E6(L5`BW[C2NM5)0UHR3PC.png : {' i: N" m! Z9 g" Z+ d
收藏 评论0 发布时间:2022-5-16 10:35

举报

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