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

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

[复制链接]
STMCU小助手 发布时间:2022-5-16 10:35
一、实验说明1 `7 l( g7 j+ ?) q& t% o+ A# {2 P
实验平台:STM32F103C8T6
& d5 L1 k2 m6 H  Y* ^实验内容:使用串口一空闲中断结合DMA 完成不定长数据接收6 f' F, I3 @/ {+ m- P$ I, t' Q, i* C
0 ?5 v) u: \1 ]( `1 K, [9 e+ j
STM32的串口接收数据的方式- c' Z0 X; `3 e
1、轮询接收
9 s1 Q, I1 ?) f  所谓轮询,就是在主函数中判断接收完成的标志位。举个不太恰当例子,就比如,此时你正在考试作弊,手机藏在兜里,你的队友再给你发答案,但是你的手机静音,所以你不得不写一会题看一会手机,有的时候答案已经发来了但是你此时在假装写,没有看,导致你没能及时看到答案浪费了时间(仅仅为了举例而已。。。。)。轮询接收数据也是这样。3 d$ T9 q/ |2 {

9 B$ T6 c, S' K# X' C2 X2、中断接收
& Q! a* y: r9 y; L$ Q  串口接收配置为中断模式,当有数据收到时,进入到串口接收中断中读取数据。继续上面的例子(你为了不浪费时间且及时抄到答案,你把手机开了震动,消息一来立马看,这是就比上面好多了,能够及时发现消息。但是又出了一个问题,你的猪队友,写一个选择给你发一次,不停的震动,完全扰乱了你的节奏)。其实也就是,串口接收数据时,一次接收一个字节,当数据量较大时,显然这样频繁的进入中断,打断主程序,严重影响系统性能。" q# a% l; F- ^

5 ~9 r& y" a/ [" x3 P! s4 i$ `3、空闲中断接收
  s8 g$ k8 z. }+ ]' m0 E% o
  空闲中断接收,当一帧数据接收完成之后,串口会进入到空闲中断中去,然后在空闲中断中处理收到的数据。这种模式对处理不定长数据帧带来很大的便利,我们不必频繁的进入接收中断处理数据,但是弊端也是明显的,由于每次都要接收完一个完整的数据帧后才空闲中断,所以当一帧数据出错时,我们也不得不接收这帧错误的数据。在通讯可靠的场合,使用空闲中断接收模式接收串口数据,将会大大提高系统的性能。
. Z" ?" Y5 ?* [8 c; ]! Q2 h% h/ }
二、实验步骤4 w+ b& R7 @0 D& i3 ~. R
1、基础配置
9 ~9 J2 M' h0 D6 ]
1)、sys中,选好调试方式,例如jtag-4pin。& }& M: S) O( M, B& U, m. H, ?
2)、RCC时钟,晶振选择。) g0 q. B; s0 v2 k
3)、时钟树配置。7 ]% Z9 }# y1 H7 J8 L# y6 G
4)、中断分组配置。
5 O3 }2 [  u* `# K: r; c以上步骤可以参考串口中断实验。# W0 j6 w) a, u$ U9 W8 f" D
. U! h* R  Y! P6 j6 h
串口中断实验配置
3 B. {+ Q) x2 {0 I本实验要配置好printf函数便于演示效果
+ q; r9 f0 L% O  R% t, X, {) ]; z0 c1 f4 |2 Q
2、串口和DMA配置+ C2 e- R; a! u2 K0 g7 L9 `# o. l' A
1)、串口一配置。
% P4 M  P0 d: E) C" V5 N( I; [& w3 u& c1 O
]CXMGGO%(~CVM(]Z)3~HG(Y.png
. w3 d8 Y4 M9 D8 U, N1 Q
' {, ?5 k. D  N  k4 X2)、DMA选择8 o- c1 \+ }% v4 h! `3 k8 R6 F
T(MA7CJTGMUHRZZU~9F.png * M. ]: P  k  z+ n

+ Y& w4 h6 K! M  V 71CDS@LW]C_6GUJ7RXXP@XN.png # J+ e+ V: y: C; n: v

' }) W+ I: K9 k5 ^3 [3)、生成工程代码
9 @7 Y. O$ q! P
9 q. Z( d3 [' u5 [( O IZOO[@GPHC5O@UK9ASY]IDI.png ) }' ?$ [( x1 q4 U* p, D4 q2 c
3 n# V& Q# Y' F* S
然后生成代码。
: X2 T! ?- ]( B, Z, F! I/ N4)、添加代码
9 C' D4 Z8 b0 ~" y4 M
* K$ S0 i/ e3 N 3@8(I63`AXKHYAEVQ4QLC30.png
, n- O) p* F3 V8 z9 w( y5 }  o# m) x/ ~
  1. // 这里没有使用中断回调函数,这样写更直接一点。( y# ]$ ?8 b% u: k  z
  2. extern volatile uint8_t rx_len;//接收到的数据长度9 {9 n# o0 L+ x2 @6 X
  3. extern volatile uint8_t recv_end_flag; //接收完成标志位
    9 e1 i- r: _' n: `4 ~
  4. extern uint8_t rx_buffer[200]; //数据缓存数组" `  r* s0 X% @/ ^& H
  5. void USART1_IRQHandler(void)' L8 t+ y  [6 J: ]
  6. {
    + M3 Q% y' U5 x, }( K. J& w0 c+ g
  7.   /* USER CODE BEGIN USART1_IRQn 0 */
    + ~3 e2 e. T9 l  ^1 g. X* {
  8.     uint32_t tmp_flag = 0;: ]# e7 V# }" r, g8 R0 Y& i
  9.     uint32_t temp;
    . w$ }1 t/ _! g+ i5 }9 S
  10.     tmp_flag =__HAL_UART_GET_FLAG(&huart1,UART_FLAG_IDLE);
    9 _( h3 W' F8 O
  11.     if((tmp_flag != RESET))& U3 t8 L( N0 d2 @0 M
  12.     { % p3 q: z' v( N8 s5 i) [
  13.         __HAL_UART_CLEAR_IDLEFLAG(&huart1);; P) A: t4 l! e( m: l
  14.         temp = huart1.Instance->SR;  
    5 _! n' x& ^" x
  15.         temp = huart1.Instance->DR;
    4 f, ^# k; x/ v' \+ m+ O& X
  16.         HAL_UART_DMAStop(&huart1); 4 v) X3 ~% U! e4 w6 l# y: b
  17.         temp  = hdma_usart1_rx.Instance->CNDTR;+ W& t) V7 G+ f$ z
  18.         rx_len =  200 - temp; 5 S& `% a& D5 r2 C9 f
  19.         recv_end_flag = 1;               
    3 e( d0 ?% G; f
  20.     }/ s/ ~+ }+ l* L/ R
  21.     HAL_UART_IRQHandler(&huart1);        
    ' Q  _9 J7 _  f: w/ ~: H  {
  22. }
复制代码
: B: y4 ~" {1 N( j1 L  D. @( e/ v
如下图,在usart.c 文件中先把变量定义上,同时把支持printf的函数添加上。0 b, s* U3 y: c# u" y

8 ]/ G+ U! _! x9 l; ~9 G
  1. //注:**这三个变量 需要在stm32f1xx_it.c和main.c中外部声明**- J( K& x8 T/ M( V) Y3 k& F
  2. volatile uint8_t rx_len=0;  //接收到的数据长度
    $ M* K' k- n) T
  3. volatile uint8_t recv_end_flag=0;//接收成功标志位
    . o- X+ T9 w7 @; [! F) |8 b
  4. uint8_t rx_buffer[200];//缓存数组
复制代码
( g! Z6 T- U4 w, s, g; I* h
ZD3I8)}08`}Y`@Y]W5QGW19.png ) l. ^: |* T1 N# H/ {& p/ p
# P9 k  \5 L! Y: k1 i& N& T7 t
10BJGM%V~TYC4W]DN6F1ALW.png # S8 ~( R* }& ~9 X

' {! M8 N4 T) B3 u7 b- Q
  1.         __HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE);
    ; {; k  p) X7 h6 N1 I  n) y
  2. HAL_UART_Receive_DMA(&huart1,rx_buffer,200);
复制代码

% E8 R3 u- @" X* v# n 3_4M~T~TU3DS7MZDRB24~GL.png
% q" j" Q% ]; I" S: k! W' _) F. Z  F; W) j: X% e
  1. int main(void)5 n" |1 p4 n" {+ j7 P4 G$ m
  2. {& \! T4 T  Q3 n: U7 [1 d
  3.         HAL_Init();. j: D  [4 g) Q9 a" U0 ^9 M
  4.         SystemClock_Config();" |0 o7 L. W8 V. y% A8 P
  5.         MX_GPIO_Init();
    5 m+ h. ?) C' F4 \* h$ S
  6.         MX_DMA_Init();$ C- y. e; B' R5 k8 `( M- e( B- H
  7.         MX_USART1_UART_Init();% J7 z2 @7 _) L9 ~5 }( \3 \% I0 E5 R
  8.         /* USER CODE BEGIN WHILE */
    % }8 r; O2 M8 o  L: H5 y- O
  9.         printf("DMA_TEST");% }& {4 Z$ \9 o4 p5 c
  10.         while (1)
    : v% _% |7 W2 h" v; v6 ^' f' e
  11.         {
    ' G, M& m( j$ x4 k* b' ^2 N1 u
  12.                 if(recv_end_flag ==1)                        ' S2 Q5 B# Q5 u' {9 c9 x# o
  13.                 {        
    - Q" G4 y( ?' z% v2 h0 x
  14.                         printf("接收到的数据长度为%d\r\n",rx_len);- F& N* z( g9 i; [% h
  15.                         HAL_UART_Transmit(&huart1,rx_buffer, rx_len,200);! M3 x1 Y) R& |& ]) x+ X8 D6 m
  16.                         for(uint8_t i=0;i<rx_len;i++)
    / d$ P9 n6 V% G3 p$ J1 E
  17.                         {( v3 v, d( C4 }
  18.                                 rx_buffer<i>=0;1 i% Q' j/ K5 @' z
  19.                         }
    4 ~' o1 I# v% Z2 a4 i6 c  V
  20.                         printf("\r\n");) g7 J0 v" e! X9 V: R
  21.                         rx_len=0;  C- t8 g. E% z" `
  22.                         recv_end_flag=0;
    1 M& j2 b4 N. t! L5 d* D
  23.                 }9 }$ {% S1 K8 |; }& b7 h# `; J8 Z, B5 x
  24.                 HAL_UART_Receive_DMA(&huart1,rx_buffer,200);        , M: M; k5 t8 d' {
  25.                 /* USER CODE END WHILE */
    6 T' S/ }! `3 J# ^8 W% f
  26.         }
    8 F1 S' u  i3 U9 a' `8 T5 e9 ?
  27. }
    7 Y# Z/ K4 V7 b' ?6 T# b1 P3 l. G
  28. </i>
复制代码

( h: v# v7 Q/ b) l1 D( f3 烧录调试
9 I' _( B  b5 e' z9 F, E0 c0 h添加链接描述) o: b; U5 F/ l- ^$ e+ @$ m$ {
" ]+ H1 J1 O$ q  W
2E6(L5`BW[C2NM5)0UHR3PC.png
! v: \+ C4 R* [0 c" S
赞 收藏 评论0 发布时间:2022-5-16 10:35

举报

0个回答

所属标签

相似技术帖

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版