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

【经验分享】STM32Cube的串口配置与使用

[复制链接]
STMCU小助手 发布时间:2022-5-17 21:00
一、串口的配置0 Y" C& l/ z( d; z7 I. K& U, n
1)首先打开你的工程,在STM32Cube里面找到USART1,此时串口默认是Disanle的,我们要使能它,选择Asynchronous.
8 Y8 i5 g4 s1 z
0 p% U- ~; z* I2 V, @" O `9~_`JB[)[BD{2{K7NO)`TO.png
! @3 E; H/ J3 K9 s8 u: o# X2 P& J* T9 S; d+ n
2)然后点击Configuration,就会有一个串口的配置图框,点进去配置串口,如果需要用到中断,选择NVIC进去进行相关配置。, G5 f9 P/ \! h6 h. z1 m: e

7 t9 H/ g* j0 Y# s$ \6 a1 ?5 P# W: C* a }O[87W3U_`G0[F{DJI6]@LK.png
4 }  x4 u+ T  P% F' g$ z* m" e
4 m3 ]- _# b# [+ j! q. R串口配置:  U. u4 O+ G% O7 R: ~: I
) I- o( ~# p% ]8 u4 B. b, e
CX9P9I(33K}1`[RLAIS$I@U.png
: g6 H! a: z8 o4 u3 u- x1 y" x( T8 p8 P
4 [0 D& u7 D  p3 V6 q2 X/ d+ K
串口中断使能:* Q  n* B3 C6 v+ N0 r

9 i* o# s+ i# d# t3 _ 20181128090413451.png
2 e, |; c4 l" V7 I6 p, J" h
" C: V# P9 o6 f2 L! y点击NVIC选项,设置优先级和分组, k7 i$ U2 L/ X+ x
& L) j: W2 V1 I0 |" G+ f, b
%_Y)~A)RVNEGF1WA[5ZWT~8.png   O/ |" D- ^* S' m
$ d, a$ {- T( K" h" y
二、查看串口内的函数API  K: k& b: y; R& l: ~2 j$ L" T8 d% y: h
Keil工程内选择{ }Functions,然后选择你需要查看的目标源文件,展开既是该源码内的函数
7 E0 _" f' N; O3 V- x4 @2 _- y( D7 d# T3 L2 Z8 P
`58NA6Y2WF}WPFLQZ~{7@AY.png
, n6 b( p2 Q% F6 F) H$ k
* O$ M# O% L2 S4 t! k0 Y9 f
9 l! X$ c, Y9 e2 M0 |串口的发送接收函数:1 O2 }- E9 W$ F9 E# s
$ s2 ?& h3 t( M( N- m7 W
  1. HAL_UART_Transmit();//串口轮询模式发送,使用超时管理机制
    * i: C1 Z, a# R5 L
  2. 8 e. m% e. U5 P" L. S. s, j
  3. HAL_UART_Receive();//串口轮询模式接收,使用超时管理机制5 a- B4 B- z  T# K: S* J
  4. ; u9 n  z% X7 L" F; f
  5. HAL_UART_Transmit_IT();//串口中断模式发送1 @4 c3 ?3 }1 ?/ d3 P
  6. 8 u9 s3 \5 j) ]  _
  7. HAL_UART_Receive_IT();//串口中断模式接收/ s6 j4 E& ?# q* K3 s4 k  N' \
  8. 9 y1 e/ j/ w" U/ J: z( M) ?1 _
  9. HAL_UART_Transmit_DMA();//串口DMA模式发送
    ; L* n, N9 Q: U3 K- W: D

  10. ( h$ R6 j& T; O2 P
  11. HAL_UART_Receive_DMA();//串口DMA模式接收
复制代码

  }' }& {6 ^7 \! d1 p( \3 T8 w串口相关的中断函数:
4 s: I* R. k- |4 ~5 U3 N, ~$ }5 l3 `# x0 S- D
  1. HAL_UART_TxHalfCpltCallback()://一半数据(half transfer)发送完成后,通过中断处理函数调用。- X* ?7 P! V# w6 W/ h! [- g7 r

  2. 1 d4 c: [* K! S; x& s0 p
  3. HAL_UART_TxCpltCallback()://发送完成后,通过中断处理函数调用。
    / h' z# S# O+ P( l* s
  4. & m( o. ?, j! k1 q
  5. HAL_UART_RxHalfCpltCallback()://一半数据(half transfer)接收完成后,通过中断处理函数调用。
    % }0 X: s0 x; B, [  n0 j/ m, o. v# y
  6. # Z- a5 ]2 f) r8 p+ o0 [. J8 Y1 n
  7. HAL_UART_RxCpltCallback():///接收完成后,通过中断处理函数调用。
    7 R6 Z7 @% x" X; d0 z

  8. ) i9 m' Y/ h0 y! S
  9. HAL_UART_ErrorCallback():/传输过程中出现错误时,通过中断处理函数调用。
复制代码

4 [7 P% O6 Y7 }$ E+ k串口有三种通信模式:
+ K7 K/ u6 p/ L- }" g8 p2 D2 F* s
. H. d* V" h" b$ }3 G2 ?第一种是轮询的模式。CPU不断查询IO设备,如设备有请求则加以处理。例如CPU不断查询串口是否传输完成,如传输超过则返回超时错误。轮询方式会占用CPU处理时间,效率较低。* j/ p' U: p$ c8 T
7 {7 A3 g2 r% P# i5 M
第二种就是中断控制方式。当I/O操作完成时,输入输出设备控制器通过中断请求线向处理器发出中断信号,处理器收到中断信号之后,转到中断处理程序,对数据传送工作进行相应的处理。
0 P- V7 y: A$ J/ i% {5 u8 x
1 G$ y, ^0 ~+ A# ?- T) M+ a第三种就是直接内存存取技术(DMA)方式。所谓直接传送,即在内存与IO设备间传送一个数据块的过程中,不需要CPU的任何中间干涉,只需要CPU在过程开始时向设备发出“传送块数据”的命令,然后通过中断来得知过程是否结束和下次操作是否准备就绪。# H$ Z6 \  H& ]

+ ]' O3 R6 r; J! e1 n/ b三、在main.c文件添加printf支持' }2 S' R4 T, Y# @# r
  1. /* USER CODE BEGIN 1 */( U. D" S- G; Z) I. V
  2. 5 G9 f+ N0 ?7 o: p+ {
  3. #ifdef __GNUC__
    ' x- P$ }2 w' S7 ?! l6 T
  4. / J6 r2 N6 y* `
  5.        /* With GCC/RAISONANCE, small printf (option LD Linker->Libraries->Small printf
    3 p6 K: I$ S! }# @* d  v
  6.      set to 'Yes') calls __io_putchar() */
    8 l5 `- r" j) N; z  q0 h

  7. ! _: O/ N7 `, q* o' y$ I+ G
  8. #define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
    + p+ A& o. ^, ]
  9. 0 R# U  ^& s/ P- x1 E
  10. #else
    # e0 n) o, Y  ?
  11.   #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)+ o( `; Y! M+ r! T3 ^, ]7 q0 K
  12. 7 R+ e5 ?# @( o* Y
  13. #endif /* __GNUC__ */! S3 T( r7 c8 [( q, [
  14. 4 S, E( _' ~7 A( D& m( l4 w# @& r
  15. /**& J/ l  ^4 K- `9 K; z+ k+ u
  16.   * @brief  Retargets the C library printf function to the USART.
    " V. `# t2 }. W) L
  17.   * @param  None
    3 \& y! L9 f' B$ Z8 P
  18.   * @retval None
    4 a4 `3 E& e" }! y6 z% {) k5 V
  19.   */
    6 M0 l$ ~' |9 G2 L' ^" j6 C
  20. PUTCHAR_PROTOTYPE6 ?" a" y) k! u. X( r
  21. {" z4 F; \7 c$ R! S- v4 l
  22. /* Place your implementation of fputc here */4 E0 t/ f* X+ t& s% f1 w) G
  23.   /* e.g. write a character to the EVAL_COM1 and Loop until the end of transmission */& x- X$ h( o. }  K( m- w! Z
  24.   HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xFFFF);
    . o* a4 B$ _0 u# L) S
  25.   return ch;
    1 i4 ?# N* Z* G6 l6 a5 k
  26. }: |/ |) E. @) O& X( h8 U; {9 b
  27. ) K8 T: ^' v) m. T; M
  28. /* USER CODE END 1 */
    " S8 n* `8 F  P" Y5 d
  29. + j) f; i# u0 d7 k, j6 U2 A
  30. 0 |7 y+ y( f9 q& Q
复制代码

$ q9 _4 n/ C; b0 V2 V1 y9 B }9NCWZ)Z2XKQX]F$Y@)0]X8.png
1 f1 \; \- {+ J4 `6 L: q% i; k& v! O+ h# z" V$ m+ O
四、单独串口中断的使用
% C. }; H- [2 M" }. ^1)在main函数前面添加两个数组变量
) l! t" \3 T# X
( Q+ U- u  w1 O& G& ]3 \; U5 K1 w% B8 _
  1. uint8_t aTxStartMessage[] = "\r\n UART-communication based on IT \r\n";$ ~+ }- @+ b0 l; X

  2. 6 l/ j& J/ W) x. Z# D8 }: S
  3. uint8_t aRxBuffer[20];
    3 S% z. c& |. g, l0 w
  4. /* USER CODE END PV */
复制代码
8 |1 a5 `9 A( t$ F
2)在main函数中添加语句接收数据10个字符,保存在数组aRxBuffer中。
" _5 {2 D9 `7 o4 O  g7 r
* E0 K' r" S! A$ f
  1. HAL_UART_Receive_IT(&huart1, (uint8_t *)aRxBuffer, 10);//串口接收中断使能,如果要循环使用就放到while(1)里面
复制代码

9 ?- `. F- `. F- ~2 W IGX`DZRO42[24L[O2YE$(%M.png
# T& [! y+ A' _2 `- v+ u& U: g  i+ d  `) f. i* _8 q
3)在main.c文件添加中断接收完成回调函数。中断回调函数中将接收到的数据又通过串口发送回去。6 D( w, b  W+ i1 I. Y

1 M% e0 L- n- f5 S
  1. /* USER CODE BEGIN 4 */
    ) q8 f/ W5 u8 U; Q4 z6 l
  2. /**
    8 _3 E. z  J* N
  3.   * @brief Rx Transfer completed callbacks0 Q& Q* d* d8 Z5 L8 L
  4.   * @param huart: uart handle
    & P% F8 K# {$ R9 ?% W3 l( g% g& I
  5.   * @retval None5 D8 R2 x1 ?7 s5 e2 C
  6.   */
    + n0 K2 B- g; I- l2 e
  7. void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)% e/ ^; e* K4 y- F7 k+ |3 K$ |
  8. {
    . A$ }! Q  A* b& ~$ I& E
  9.   /* Prevent unused argument(s) compilation warning */" V; g; }8 e2 L+ x
  10.   UNUSED(huart);
    , N1 ]) _. D2 j! p1 j8 `
  11. ' o/ m/ j! Z3 d! e9 v9 k4 N8 ~+ c
  12.   /* NOTE : This function should not be modified, when the callback is needed,
    + ~% U; [; f" b: K
  13.             the HAL_UART_RxCpltCallback can be implemented in the user file5 `. G1 K' H$ T2 k0 q
  14.    */
    6 m' d: ?4 u8 l2 x& Z
  15.     HAL_UART_Transmit(&huart1, (uint8_t *)aRxBuffer, 10,0xFFFF);//发送10个数据给串口1: x$ E& O4 T) i2 p" i9 M
  16.     HAL_UART_Receive_IT(&huart1,aRxBuffer,10);      // 重新使能串口1接收中断  & P0 H. d, Z9 ], s) ]
  17. }
    6 M" ?" F3 s3 C, L2 s4 |1 }7 a

  18. 5 p# A) w6 D/ w9 J5 l0 `0 m: P7 f
  19. /* USER CODE END 4 */
复制代码

! F( ]% q" A+ j9 q3 A五、多个串口同时使用

3 V2 f- X. m4 Q3 F6 i1)定义串口1和串口3的接收数据变量1 Y4 k' ]* I/ o" Q( t  K
: q( c2 ^) O7 m
20181128090413546.png
9 K; s" P, k1 k; a3 g8 N$ C4 C2 Z, M
2)中断回调函数& G. ^3 z6 F: t8 T5 k6 m6 k  d& K

* t, }6 Q6 U9 O- x
  1. void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)0 G3 F& |5 ^0 N% R# X+ y( P
  2. {3 b! Z. c+ S4 d! n
  3. /* Prevent unused argument(s) compilation warning */
    3 }; d! }1 @$ L5 ]( W* v( o' h
  4.   UNUSED(huart);
    4 y4 H* \+ m+ h+ M6 ^6 v& _

  5. : o3 [; f) C! T
  6.   /* NOTE : This function should not be modified, when the callback is needed,
    " |$ v1 b) D3 Q0 I# ~
  7.             the HAL_UART_RxCpltCallback can be implemented in the user file: y! f' v- j' n' |' ^
  8.    */
    . W% j' r/ u1 u" g4 D0 S9 T
  9.         if(huart->Instance ==  USART1)//串口1做调试: y+ v: s1 f' x* N* E
  10.         {
    1 A9 g: f. ]2 k( E) b7 n5 h
  11.            // HAL_UART_Transmit(&huart1, (uint8_t *)aRxBuffer1, 10,0xFFFF);
    : q* q3 c! r, `/ z
  12. 0 o  e: A4 R, y6 S
  13.              RECV_FLAG1 = 1;( `: h$ \  q2 V" T9 E% Q+ e2 u) z
  14. ) N7 Z, C7 u. c! {# z
  15.             HAL_UART_Receive_IT(&huart1,aRxBuffer1,10);  // 再次串口接收中断使能
      H( _; z: C# S8 s* m, _
  16.         }
    6 c8 P# f; S) F4 k$ ]# A6 N
  17. 5 t. w  ^0 x) f: P# C8 Q( b* j
  18.         else if(huart->Instance ==  USART2)//串口2接蓝牙
    + n8 {. L7 _7 i  b4 c0 g
  19.         {. I$ o# j/ Z4 `8 t/ ~) `9 f0 {
  20.            HAL_UART_Transmit(&huart1, (uint8_t *)aRxBuffer2, 3,0xFFFF);" S8 y+ X4 Z& b" ~% l& _
  21. # A% |3 _4 k4 ^$ S& [
  22.              RECV_FLAG2 = 1;
    , f6 c7 @# X: [- m7 ?
  23. % \) |9 |+ L5 M: \5 l% l
  24.             HAL_UART_Receive_IT(&huart2,aRxBuffer2,3);  //再次串口接收中断使能  
    # q. l6 ]  R2 P) J4 I6 o. Q
  25.         }   
    3 ~0 s9 q$ a' k3 b0 _& q, s% }8 v1 [
  26. }
复制代码

. U2 I0 S  P6 f( `6 r9 g
( q6 _2 P, _6 h9 G  l3 ]& U# m Z2GNG1FO2LDG%BU2]IC1FH4.png 8 \  F4 z' t  y: _

  `- p8 f9 \1 s; d5 b( j" ^, Q1 D3)主函数编写
% A. b& \( R9 z' S4 c: V2 L# n* f) m
  1. Int mai(void)
    ! ]8 j- S% o6 ~
  2. {
    % W0 L8 k1 l# g4 S8 X% |
  3.      While(1)
    , e. ?- L6 X5 B
  4.     {$ _7 A5 n* X0 G% D# w
  5.         if(RECV_FLAG2 == 1)
    # k: \+ y9 `# G" J$ S( y/ u9 N+ W
  6.        {
    , o& B! z. g3 {
  7.           RECV_FLAG2= 0;
      t7 `  u* p. R3 j( m* l: |
  8. 9 `# Y6 A5 X# v4 L7 c
  9.         Car_contrl(aRxBuffer2[0]);  //控制协议cmd[3]:cmd[0]=控制码  cmd[1]=0xD   cmd[2]= 0xA   
    1 D! R9 _+ v& O1 t5 F9 i
  10.        }' K  s1 c' f$ _
  11. . E3 ~9 W! K% n4 {9 w
  12.     HAL_UART_Receive_IT(&huart1, (uint8_t *)aRxBuffer1, 10); //串口1接收中断使能+ O9 m' o9 W! s. j  F/ X" q7 v/ p  S
  13. ) |, j9 n2 }! T0 M; e  w
  14.     HAL_UART_Receive_IT(&huart2, (uint8_t *)aRxBuffer2, 3); //串口3接收中断使能,所以大小为3:0D 0A 01
    . a& I- G/ @4 v& l

  15. 6 J: A) K/ @) ]2 ]  a
  16.     }
    4 m# l/ u" ^4 V. S
  17. # N% w+ c4 Y, o- k1 ~
  18. }
复制代码

' n4 u+ P" R; |; n B]M{9ZCX]IF_{G}Y67CP2T6.png
5 F/ I) [$ Q5 B- [0 o6 ^( s
( L0 d) X4 E9 x/ q
4 U6 c- G- Y8 i' Y-----------------------------------------------------------------------END--------------------------------------------------------------------------
5 b2 u' h. W, K2 y7 Z& {( V7 b1 U
. W( Y; I/ Y% ^$ r# O; M0 _# k& D6 H" K& j
收藏 评论0 发布时间:2022-5-17 21:00

举报

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