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

STM32CUBEIDE(7)----USART收发配置

[复制链接]
STMCU小助手 发布时间:2022-8-18 17:12
生成例程
9 g. ?6 g$ ^4 g. v$ s使用STM32CUBEMX生成例程,这里使用NUCLEO-F103RB开发板1 S& n, J7 |5 u$ z; ]$ _4 `0 o$ k
641406f4ab6d4ba3806608ea088511f0.png 1 A2 g2 ]. y: r1 ^' x/ ]: \( E$ }
# j9 `. Z. e9 ?/ C, l7 |
查看原理图,PA2和PA3设置为开发板的串口。
) a# `, ?, ~" p& c- ~& _6 m" l* K0 A1 T- D7 D) f0 n
6cde275d970445afaa522e74e1b05da0.png / k+ R( \) J6 k8 O3 ?+ a

5 o* u1 }- t5 |  A: k% D" f6 V; g配置串口。. D4 S0 \3 ~3 t; q( k  d2 x

/ M* x* x+ P* T, |7 s. a e5a35949ea484fe782de2237f57d2198.png
- B. V. F/ y! ~7 C4 B" O5 t! d# H& i% ~/ [$ C
开启中断。
; e6 _7 D1 [2 S' D" Y* M2 I  ~+ t  |) I* b- E8 E
4b8d8ee78fdc425485eb47d05a726d28.png . }6 {+ U& P0 V, Q" y0 S7 Y  y( j

' r2 J4 ^6 Y/ C, a5 e: K! ySTM32CUBEIDE配置
  ?0 U" f& T  R: f, G/ \, M* q( q) V
% \! O' P* m! ~; x1 \ cef307ee88fe48e9927c8672840c37f2.png
5 S' O% l* C  p0 o
; z( y8 v- ^. J  x0 f5 c$ L若需要打印浮点型,需要勾选下面的选项。
- ~5 j3 F$ L1 P" c0 S" A6 ~" v% ~- s
$ {8 k3 v/ a, t! |% Z3 Q 0f42e907240242bfbb736c31e9755617.png / y7 F( ]6 ~) \% [, g
9 E* ?, u- ]# L
串口重定向
9 F: s: r! r- `在main.c中,添加头文件,若不添加会出现 identifier “FILE” is undefined报错。" j# j: }2 ^+ K" S/ h$ e$ J2 ^, J

' q" d; k: N. B$ F4 x  p- h
  1. /* USER CODE BEGIN Includes */5 E* M4 c" i# O- {
  2. #include "stdio.h"
    % T. `- d. Q/ i) u3 q6 O
  3. /* USER CODE END Includes */
复制代码
  m, @0 E4 e" a( h8 C% h4 ?
函数声明和串口重定向:
& |9 \$ K% Q# {! r
. T, ~. V7 d3 c' e0 d& F
  1. /* USER CODE BEGIN PFP */7 ^) z( k/ `+ I$ p: F5 w
  2. #ifdef __GNUC__                                                                        //串口重定向
    , f) c; D! F* {: Z- g& p3 @4 w' j
  3. #define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
    8 ]4 ~; p% e' t) I9 O
  4. #else
    ' u. [: I) S4 _2 [6 q8 W! `1 ^% X
  5. #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
    : L! r; F( i+ T; V
  6. #endif , B, v2 F) K+ g4 ~" q
  7. PUTCHAR_PROTOTYPE
    7 P+ H  H; _( `( M
  8. {
    # o8 {/ `" i6 t9 l
  9.     HAL_UART_Transmit(&huart2 , (uint8_t *)&ch, 1, 0xFFFF);
    , o6 Y6 }  C  F. v6 [1 f
  10.     return ch;
    ' Z! W% _* I3 F: L
  11. }" M* ]$ a/ h2 Q  ~2 W# A5 g
  12. /* USER CODE END PFP */
复制代码
' I* U" a& P3 g6 n5 _  m( d
串口发送接收函数+ v$ z% y9 }- O5 I2 Y
一般情况下,串口发送接收函数有如下所示。: v' O- Z3 s5 g1 M, F6 ]
● HAL_UART_Transmit();串口轮询模式发送,使用超时管理机制。  @7 o# |1 R  I3 x: A2 _1 y
● HAL_UART_Receive();串口轮询模式接收,使用超时管理机制。, u8 Y+ D) w2 O( b) f5 m
● HAL_UART_Transmit_IT();串口中断模式发送- i/ @. s0 `# {0 n& M' W9 G8 C
● HAL_UART_Receive_IT();串口中断模式接收
# {) T: m$ s  i● HAL_UART_Transmit_DMA();串口DMA模式发送
: I5 j, v" C. U● HAL_UART_Receive_DMA();串口DMA模式接收# q  E9 M5 G  _0 R5 n7 c
: k. Z1 v1 y$ M7 b
HAL_UART_Transmit()发送; A  L0 ?( s, G0 h: S4 L
通过轮询,将数据发送出去。
2 v6 d# a. S5 a( t6 v$ c; f7 @! G2 A. n+ b
  1. . b# D: E0 |" T: i
  2.           uint8_t buffer1[10]="0123456789";
    ! H4 x# E) c+ d% ]
  3.           HAL_UART_Transmit(&huart2, buffer1, 10,0xFFFF);//把buffer1的内容通过uart2发送出去,长度为10,timeout的时间是0xffff
复制代码

7 z% w' H% N' y' O  W: f演示结果如下所示。$ d. n( ?3 s% Z/ h+ a3 i4 E

/ o1 A; E& c) m' d* P 4f47e2bccd5843609ea5eee1278d6bb5.png 0 Q; ~9 v& ~( K, w( R9 T5 i1 s
: B9 ^( J# m: j3 q# o
HAL_UART_Transmit_IT()发送- X, s1 K0 r. p7 i5 I, Q1 |# A
通过中断模式发送,这个模式下需要开启串口中断,否则无法发出数据。
6 a' R3 Q8 O. J; j& y; Q( t- Y9 J3 n* h; K. M$ z4 C
  1.           /***********方法1********************/
    / K( Z, t9 j$ P+ D- O4 X) |
  2.           uint8_t buffer2[10]="9876543210";
    % r4 V/ P/ Z" o2 b
  3.           HAL_UART_Transmit_IT(&huart2, buffer2, 10);//把buffer1的内容通过uart2发送出去,长度为10,
    - C9 G+ @3 y! G+ l) X5 {2 u5 \
  4.           while(huart2.gState != HAL_UART_STATE_READY);
    % ]0 ~# O0 J6 I' `

  5.   ?7 I3 h, T% G6 Y& \" q0 u

  6. : p* p8 i2 S9 e4 F# x6 A
  7.           /***********方法2********************/0 r8 z, X' `! y/ F4 z3 ?
  8. //          uint8_t buffer2[10]="9876543210";& r: _( ~. ~# A  E
  9. //          HAL_UART_Transmit_IT(&huart2, buffer1, 10);//把buffer1的内容通过uart2发送出去,长度为10,
    2 W, ?: W: U! ~+ W0 M, H
  10. //          while(HAL_UART_Transmit_IT(&huart2, buffer2, 10) != HAL_OK);
复制代码

4 @% B1 k2 K  o# W上述代码中,可以不使用while进行等待也可以发送,但是需要注意不能未发送完毕又重新发送。7 P; F! E: k! u+ T5 d0 D7 e
演示结果如下所示。
' ^2 D+ i5 Y4 w. h  a% b; c
, s& }7 c) @5 N1 `$ `. A9 aHAL_UART_Transmit()和HAL_UART_Transmit_IT()对比* f8 p: Y* K4 T' @- ?2 U6 a
若HAL_UART_Transmit_IT()不使用while进行等待,他的波形图如下所示。
: `1 U# ?$ L3 R, W# z$ T黄色线为波形,红色线为发送后的电平翻转。. y7 S6 F0 b, [  S) y, E/ K8 E
- g! e# v+ [7 K% L( I7 k! b
8f6e8a3e14e04e61a2a5438c6cd8d0a8.png
$ x. {+ C, u# x" ]5 y, K+ n( G/ h- G/ R; a+ ~
HAL_UART_Transmit()发送如下所示。+ r; b6 H2 {3 |5 [! R

3 z' h; O, M5 ]3 [$ A e958c697b81f4b35b7e20066a498be4a.png % m+ T' u( j( N7 ?( e) P

5 ~! m% m! l; p. K2 Q, X* S" f* F9 Z可以看到,HAL_UART_Transmit()发送必须要等待发送完毕才可以接着往下执行。
. c2 }6 e: Q7 W9 V2 D6 kHAL_UART_Transmit_IT()为中断发送,可以在发送数据时候执行其他指令。6 B7 U" F8 s$ H* N, w, S

$ M' ?; f: J0 k- BHAL_UART_Receive()接收
4 _' i  F/ `$ f- f串口轮询模式接收,使用超时管理机制。2 C* v: R! e$ [! `& A5 L
例如接收一个10个数据。
! P3 y; ]! [5 H. C
( |- _) B% B4 b0 {7 z
  1.           uint8_t rxdata1[10]={0,0,0,0,0,0,0,0,0,0};6 X# \, _% n, z% z$ Y  Z* L
  2.       /* 判断是否接收成功 */
    8 ^9 F$ t6 F# E/ ~, `# I
  3.       if(HAL_UART_Receive(&huart2, rxdata1, 10, 10000) == HAL_OK)
    4 z1 B. c9 Y+ P7 J
  4.       {) p9 T) R' i+ ]# V
  5.           /* 将接收成功的数据通过串口发出来 */
    ; [6 w2 i% m! |  X
  6.           HAL_UART_Transmit(&huart2,rxdata1, 10, 0xffff);9 [% O7 j  W" J. D% X, h! e9 j* f
  7.       }
复制代码

3 f# x5 [7 c6 z; Y. z测试结果如下所示。  X, {3 z: K( m0 o2 S0 ?0 ~
( r1 i1 Q( A7 r# X1 }! f$ q
bbf0d938f7144660818f09d760e58988.png % H/ y2 k3 K' l
5 U) x, h+ P" T! ]. d: Q* ^
HAL_UART_Receive_IT()接收

) ~' d0 L+ K% |6 D5 ?7 O1 c2 B串口中断模式接收,这样就可以不需要等待,单片机在没有数据接收时候可以进行其他工作。
; }* u$ X3 ]4 a7 M1 Y8 N例如接收一个10个数据。+ P) T2 c( p% _* |
定义接收数组。
7 X3 G4 {2 O9 a/ }/ P0 V- Y0 n
  p6 S1 k! L2 q4 C6 i2 ^
  1. /* USER CODE BEGIN PV */
    # Q& D$ b* O5 f$ A
  2.   uint8_t Rx_Data[10]={0,0,0,0,0,0,0,0,0,0};6 L4 \0 r! @( }3 K3 H: y1 {! X! J+ R
  3. /* USER CODE END PV */
复制代码

! [6 I& w; i8 S' Y" T2 [7 z开启接收中断。  p2 s7 W* n* ]7 q
3 S& f1 q& S9 k
  1.   /* USER CODE BEGIN 2 */
    ! O- {& k% A' c3 j5 d
  2.   HAL_UART_Receive_IT(&huart2, (uint8_t *)Rx_Data, 10); //开启接收中断,接收10个数据到Rx_Data
    5 f" \1 i- ~' o
  3.   /* USER CODE END 2 */
复制代码

! H' E5 Q! F' u" T# ^/ n读取回调函数。. x0 e5 y4 e2 u3 S9 o
# H( p! a0 n/ G7 }0 ?/ H, T
  1. /* USER CODE BEGIN 4 *// j1 `! v' A$ X/ R
  2. void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart); s' V; f! U/ Y8 u4 y% r
  3. {) R9 z# v; k6 Z# d; h' W: W5 v
  4.         /* 将接收成功的数据通过串口发出*/
    - T  O6 q7 g& H6 C9 q0 b' C' I! O3 f
  5.         HAL_UART_Transmit(&huart2,Rx_Data, 10, 0xffff);
    - h' ]6 l. ~+ F& M) e
  6.         HAL_UART_Receive_IT(&huart2, (uint8_t *)Rx_Data, 10); //重新开启,接收10个数据到Rx_Data
    6 s) G$ W- [! H2 p& N1 m) Y' K

  7. $ _7 ?$ s8 o9 K! f/ }2 w$ [2 O
  8. }
    8 k+ _  _. ~& @
  9. /* USER CODE END 4 */
复制代码

: l! c9 {3 k6 k  A测试结果如下。
) K6 Y. i/ |# }
. m+ g4 I0 z% C  C# e* u% ~ c4a159a0243441d49a046f4604aee3b1.png + E3 J. Y" U# _! U% D

3 R# o) ]8 [% ^, b; p2 VHAL_UART_Receive_IT和HAL_UART_Receive的区别就是:中断接收是有数据到了才去读;直接接收是直接读取,如果超时就返回。
! I3 E* q- e7 d& ]" J. u5 v/ ]
- h8 \5 Q. S. Q. u- H
/ y5 o+ Q; M3 R
0 g* ?2 e4 k  |; j" o# Z% s1 g2 V
赞 收藏 评论0 发布时间:2022-8-18 17:12

举报

0个回答

所属标签

相似技术帖

官网相关资源

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