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

【实测教程】STM32CubeMX研究串口通信(RS485)

[复制链接]
STMCU小助手 发布时间:2023-1-14 17:49
一、开发板平台简介:3 ]+ o/ a0 V+ e, {1 s
1、开发板资源简介
& \9 W% k- T* F9 g6 k
(1)开发板主芯片型号:STM32L431RCT6
5 W. p, ^& ]+ c+ N, }0 V(2)开发板主芯片封装:LQFP-64_10x10x05P
% y1 O1 W4 j* g# @$ L(3)开发板主芯片内核:ARM® Cortex®-M4
$ W  f/ b3 [3 O8 x1 ?% D(4)开发板主芯片主频:80MHz
' |  P3 Z0 W; a. b1 ?8 G5 u; l(5)开发板主芯片Flash大小:256KB) O' J4 [* T0 s" W1 I7 K7 Z( Q% H
(6)开发板主芯片RAM大小:64KB
0 P: ]$ ^$ q9 |9 L- t' v) |" x (7)其他外设:请参考芯片手册
# g. D/ d  Z1 m8 U# M7 O5 ?! F% w8 O9 f
bb91345227434ee7a43a34bf3fe366e6.png 7 `  x5 J. y4 a. b; @" p

+ b- W( u+ D* F+ N  T" F/ d6 { 929c0cce04aa4115a8623703982bf3e1.png . M) m4 y4 c7 X0 T1 ?4 C& j8 |

7 S- ?  F) G9 n# Y% i% w3 z2、串口简介5 c$ v. w) |' \* G2 d" S6 \
         串口全称为串行通讯接口,即数据在通信线上一次传输一位,按先后一定顺序传输。我们通常所说的单片机串口准确来说应该是串行异步收发传输器(Universal Asynchronous Receiver/Transmitter,UART),使用TTL电平,串口需要RXD、TXD、GND三根线进行通信。
( G* w" n8 \* _

8 v7 p2 z  f+ ]        (1)我们选用的STM32L431RCT6开发板串口1已通过USB转TLL串口芯片CH340G引出,使用时,只需要用公对公USB线连接电脑即可(注意也得需要安装CH340G驱动),后期验证试验也使用该串口1进行。, O3 {. Y  x2 ~' K+ W* K1 N

' z; r$ r! i* F5 d9 S% N        (2)开发板上的其他串口已通过排针引出,为TTL电平,通信的时候需要注意选择对应的电平模块,如USB转TTL串口模块等。
3 R" Q' z. o( E& F. e7 y1 y6 y  {4 T

; ~& ~& b1 ~6 \7 c$ ^" d  二、新建工程5 @5 @3 l7 s4 M/ M) W
1、新建STM32CubeMX基础工程
' ]0 X9 W$ U' |7 F& J+ I0 h
(1)打开STM32CubeMX,点击“File”-->"New Project"​
3 E% w: L0 x" ]2 C; O# D/ f, a" S  l1 h9 Z) b/ ~9 c8 Y4 z# {6 ]
2399170347904e959c855fefd5877f84.png
6 c7 f! \. k9 [) B# o
, R- Q. v8 ^1 s% Y5 c(2)等待打开主芯片选项界面(大约1分钟时间)。
6 Y& l7 L+ q4 O9 J
4 G- b1 b/ a4 V& k: Q
d74d2fdc60c9440483e2b7cf8d928e7f.png , @9 j- u3 _+ ^' t- H( U* i9 ]; o
+ z% ~" e7 M9 O( }' H
(3)昨天搜索框中输入(或选择)所需的主芯片型号(因为我们用的是STM32L431RCT6开发板,所以此处现在STM32L431RC),然后在右下角选择STM32L431RCTx(因为开发板主芯片是STM32L431RCT6),左键双击即可打开新建的项目。" I! U0 U* u; x; {
( y; c1 M+ y& D: F' Z
7b80345238d74bea82ce70e1a348f7b4.png
, x4 I1 C7 v5 E
# ^% Q+ f3 D/ l" X9 c) G0 J$ L1 C(4)选择时钟源。- q7 D* ~$ H$ m
(1)因为开发板上有8M外部时钟,此处选择外部高速时钟(HSE)。
  |- q) v1 D' _  _: `9 c+ G3 Q+ b
(2)因为我们没有用到外部低速时钟(LSE),此处不做处理。% N+ Y! c% k- A. ?* ^( J

3 L' B( }' L- e* Z* W' ?; r
72119b971f62410fa8344f7f9fb9f389.png
, \7 A$ s8 u; s* }' i. ^  Q7 O8 e# p7 Q  q: ]8 U$ k
2、配置GPIO控制LED5 [+ W" T" b0 {
备注:LED灯用来指示系统是否正常工作。5 f, z: D2 n+ u' n$ o
(1)查STM32L431RCT6开发板原理图得LED1控制引脚为PC0,则配置GPIO的引脚PC0。0 K3 v: z& l3 T9 V1 ]7 X0 K* @$ T
鼠标左键点击PC0,选择“GPIO_Output”,表示设置该引脚为输出模式。" R8 ?4 ^! G% r: V3 S3 a0 Y! l
& V" N$ {$ e: H3 J
492907c1e71149819adbaee4516a2af4.png
4 N+ r" E7 Q* k4 B( S
8 ^2 V# D2 w- |$ ](2)根据自己的需求配置GPIO的参数,如输出方式、输出频率、上拉下拉等。因为GPIO控制LED的要求比较低,此处采用默认参数即可,不用修改。​( @; o1 x+ [" ^4 i

; J* Q. E6 c# A0 G* n7 e  a) \- {
38ff4b80e1c5495ba3076a5158fd91fa.png # m- x2 E& Z& I! w1 q

% l$ l4 k# V# V+ h6 q. D: w5 ^" }3、设置串口1参数7 i! j( g) n: b$ F
1、查原理图得知,串口2使用STM32L431RCT6引脚为PA2-USART2_TX,PA3-USART2_RX,引脚设置如下:2 |+ H. [# K1 q
(1)序号1用来设置串口收发引脚的选择。
4 j1 h* Y/ \; g8 C0 t+ c+ m+ l$ _(2)序号2-3-4-5-6设置串口参数,如波特率115200、8位、NONE无奇偶校验等。, R( R7 w& S2 H% _' u5 A
1 A# N- t4 D2 D+ j
2、设置NVIC settings 使能接收中断. k3 |* \# E) I: {- c+ Z+ P

9 N8 A3 z" f, w6 H
f9d7783b08304465815834f4d2095571.png
' J0 G7 _4 Q7 y0 B7 x
) _3 C" E. e0 D; ~9 e2 D4、串口DMA设置
; i6 @  C! v) x; `% \

8 E  a/ X, \0 H5 x% k 6d26b13dd9d34039a2b426ca47680f8c.png
% V3 l- _; N9 U+ L7 ]- d0 z6 t; r  v
6 J/ h. z$ g! Z. ^5 _: _
(1)根据DMA1通道预览可以得出,我们用的串口1的TX、RX分别为通道4、通道5:
' A0 c( D" [) V  B点击DMASettings 点击 Add 添加通道2 D# I8 @+ N0 ?% n% @
选择USART_RX USART_TX 传输速率设置为中速
' O. f8 m% B! }: X$ f) T2 vDMA传输模式为正常模式,即发送一次就结束。
& O0 Y. Y9 i7 A) B; A/ |: CDMA内存地址自增,每次增加一个Byte(字节)
- A+ c0 K0 l4 \0 O/ r! }
1 z# V; X( E- \' Z  m 976712e0494a4482bf65c69fc09fcabd.png 0 g) K6 o. k8 C  D& U

9 b) w$ {* N& l9 n! J* O# x" O) k(2)DMA相关参数解析
# l* a; p! H0 U' ]" D( n" k/ C4 ~4 z% L2 b! w6 k) o
Dirction : DMA传输方向有四类# v, u5 S' x1 S. g2 F
外设到内存 Peripheral To Memory
0 K: U( c- z. v% f- T6 y8 M  V内存到外设 Memory To Peripheral9 m$ ?8 ]2 p' j! P$ Y! W& f/ @8 Q. I
内存到内存 Memory To Memory5 j5 x: _% V, S7 j
外设到外设 Peripheral To Peripheral
5 j# y8 a8 G( Q1 _: C
Priority: DMA通信传输速度有四类
4 D/ T( X9 Z* d  o8 K
最高优先级 Very Hight  G6 t- t) ]# o- ~" N/ W' V
高优先级 Hight4 N5 G% a. ^  N: Q* d+ |2 v8 K
中等优先级 Medium
1 i* g0 P( T1 [) c低优先级;Low) n  \" c- R/ w7 g7 C$ v
' f- t; p* V" V7 [; Z! N- ~9 A5 P/ O
Mode:DMA传输模式有两类
3 b% Z8 W$ H" u7 X
1 J- W6 j6 V9 h0 P, z' I
9021c11fed3e4c1885477e062b846258.png
1 s) S5 M/ b3 k
8 ^. t1 N0 k' nNormal正常模式:当一次DMA数据传输完后,停止DMA传送 ,也就是只传输一次。
- ]7 j7 `5 p1 @# Z) h( SCircle循环模式:传输完成后又重新开始继续传输,不断循环永不停止。
: F9 L6 I9 Y* y7 ^: c4 X7 G& `9 z5 k1 e2 m9 Q# j2 v
Increment Address-DMA指针递增设置:
* q* c9 A- D& b8 {  S) Y, o6 ?" `: {. W* U" @4 I4 Q
2b1a952d6514444e9dbb019a9ae88c42.png
. g8 W. j8 J: H' M3 Y) I5 {2 N

# i+ P" b7 E# ]. C% f 5、配置项目工程参数
1 s& V" ]* V! t4 v+ K7 h(1)配置时钟树,用于系统内部时钟,以及各个外设时钟等。此处选择外部8M晶振作为主时钟频率,内部最大倍频80MHz。
( l/ u9 H& n- R& b5 c5 S# n6 T, ?! P5 L0 |# L" E7 Y$ b4 P
2ce1933c10484d819234682f4abc0228.png 5 K0 g& J( W4 u* Y
( E' W+ H( r6 O: L$ Q
(2)完成配置工程。
+ i' s) X3 C+ R$ A$ W3 s1 ]# \% g/ k  b7 o' p) h
备注:需要注意代码生成过程中的继承关系,如图所示:需要保留开发者自己编写的代码时,请根据配置设置,不然生成代码后会删除自己编写的代码(从这个方面也可以看出开发者备份自己的代码是多么的重要。)
! U+ N' ~  N% F. @; j9 K* U# I- F! O5 f; z# D7 d
efdb616174f54925b6eac31109f227b5.png 2 W% z- x: f+ I& T) R8 O3 [

1 O  {$ v' \; }- D 41c3f2716e4e4eda8f62fa3a1d871322.png
$ q1 |  C  t" H* P% ?: v

; z: U/ p5 X* P(3)生成代码。
; T5 X2 i( |( U% R8 p0 [( r( X" {9 L9 P% [( B) f
8eaa7d0babea40ee93f158481a6ee471.png % b( {4 _7 m3 P4 r% k
1 t+ p% {3 h7 x5 L# C; [1 l/ O: g
三、在KEIL 5中编写代码
! N$ s! o' ]. l4 G1、使用KEIL 5(MDK)打开项目工程文件
# x) n. n2 S8 z0 L* b# Y
(1)找到刚才新建工程的存储路径,安装项目名称,打开项目工程。1 ?4 U( R  d# I7 [. o
* N9 J& S; y! g/ j
9837b01954cc4d3ba3e25073f31b30b5.png
0 M6 B; h# K: B; q+ P+ Q
) ~7 i1 G7 S4 G, L" w' v  k' b2、添加LED指示灯作为系统提示: E, t/ l* C% h7 n9 K; y
添加每隔500ms,LED1闪烁一次的系统提示,用于提示程序运行正常。% V: ^/ z1 B$ M- p5 i

1 v) s% \# E# n# n2 z# {
6ab72ceaeb7a41af833842fe5ba6f34d.png + z. i( b% X7 |# T, A
7 \. H1 l$ M% n4 `) S/ o
3、添加HAL库UART  DMA 发送函数代码
. }4 X' B5 h1 Q5 H(1)STM32 HAL函数库的串口DMA相关函数如下:
$ O" U$ ^5 m. I  M) x; R$ j
  1. HAL_UART_Transmit();串口发送数据,使用超时管理机制
    . _3 d2 c6 W8 x  g
  2. HAL_UART_Receive();串口接收数据,使用超时管理机制
    / I, o- w. d0 D
  3. HAL_UART_Transmit_IT();串口中断模式发送
    : X7 s9 c  T1 G! k# w/ Q& H9 C
  4. HAL_UART_Receive_IT();串口中断模式接收% }) [2 f9 ~3 U
  5. HAL_UART_Transmit_DMA();串口DMA模式发送
    , p& D& M1 X1 A" |$ N# q1 W. U. e
  6. HAL_UART_Transmit_DMA();串口DMA模式接收
    " o7 ]; Z8 _' t  V
  7. HAL_UART_DMAPause() 暂停串口DMA- P: N2 W0 L# a* @4 v
  8. HAL_UART_DMAResume(); 恢复串口DMA' d* T; @: E6 W
  9. HAL_UART_DMAStop(); 结束串口DMA
复制代码
$ F, X! r" P. b' F# }7 ?5 {
(2)添加串口DMA发送log代码:0 V5 @* F5 @" K0 b
  1. /* USER CODE BEGIN WHILE */) c$ E! b; F+ O; K
  2.   while (1)0 x, O+ z, G" g2 ~! ~
  3.   {! B& _3 e, M" c) V- ~: k  J. i3 I
  4.     /* USER CODE END WHILE */
    ; A  E1 V- c( y4 J

  5. " |  `3 n& J* f+ p$ |' m- X( {
  6.     /* USER CODE BEGIN 3 */% l- T# e* G+ L, ~
  7.             HAL_Delay(500);
    + N2 s; r4 N0 @* v) F5 S
  8.                 HAL_GPIO_TogglePin(GPIOC,GPIO_PIN_0);//控制LED1闪烁
    7 D/ K: j# r8 g9 s/ _
  9.                 HAL_UART_Transmit_DMA(&huart1, (uint8_t *)"hello world,this is usart dma send and receive...\r\n", sizeof("hello world,this is usart dma send and receive...\r\n"));//发送提示  4 R* m' D; N9 B6 c) M$ ~
  10.         }; }( p. K& ?" g! J6 O( Y
  11.   /* USER CODE END 3 */
复制代码
4 B3 g  o- g: M% F
4、添加HAL库UART  DMA 接收函数代码8 d% c3 O- f9 Y8 F; ^/ p0 C- ^6 O
(1)DMA接收设置前铺垫知识点:1 h" Z- h$ @# _
        STM32的IDLE的中断产生条件:在串口无数据接收的情况下,不会产生,当清除IDLE标志位后,必须有接收到第一个数据后,才开始触发,一但接收的数据断流,没有接收到数据,即产生IDLE中断停止。% m0 k) H- P5 J; _" ^/ J! |

1 v, D; T4 Q# R( H% |(2)初始化中断接收配置:
6 f% q0 E* o4 b" Y6 P* c$ ]3 Huart.c添加代码如下:
8 {. N6 }& c* a, ~% q
  1. 4 D8 C0 o6 i- Z. ~: H# d" P! M
  2. /* USER CODE BEGIN 0 */
    ! U8 S2 j# o4 a/ ~! K# c

  3. ; Q: v( a3 [' [9 o+ ]/ F( A- v
  4. volatile uint8_t rx_len=0;                        //接收一帧数据的长度8 e* [. J3 f  ^$ a/ ^
  5. volatile uint8_t recv_end_flag;            //接收一帧数据结束的标志位; }3 j" }" t; I; i; ]; k5 q4 o
  6. uint8_t rx_buffer[100]={0};                        //接收一帧数据的数组大小: s& r1 I  L' b- A1 P. `
  7. /* USER CODE END 0 */
复制代码
  1. /* USART1 init function */
    # g- t- e1 c: w+ h4 h

  2. 7 T! V3 \7 q+ ~: ^3 B
  3. void MX_USART1_UART_Init(void)
    7 t# h# Z' H# d/ `" p$ @/ a
  4. {! P2 k; ]* h3 T
  5. 1 m( O2 J& L  Y8 `
  6.   huart1.Instance = USART1;
    ! \; z3 d7 u; I# G' P, P
  7.   huart1.Init.BaudRate = 115200;  _8 X2 \( B/ g0 A% k- A
  8.   huart1.Init.WordLength = UART_WORDLENGTH_8B;
    1 n, l. z/ D, M; A- I9 U
  9.   huart1.Init.StopBits = UART_STOPBITS_1;
    ! q& L" e! N, O" m! X3 \
  10.   huart1.Init.Parity = UART_PARITY_NONE;
    0 d/ J- i  m9 C8 R
  11.   huart1.Init.Mode = UART_MODE_TX_RX;
    . p. Q! a% j) @# F  d
  12.   huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
    0 _! U8 o* Q# F/ V7 N. l" D1 M
  13.   huart1.Init.OverSampling = UART_OVERSAMPLING_16;* q$ o7 f' o* |& M4 ^5 j
  14.   huart1.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;! I0 q6 X9 F; i/ [1 R
  15.   huart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
    8 A: R  V( ]1 \( g& @/ f7 p
  16.   if (HAL_UART_Init(&huart1) != HAL_OK)
    , ?7 n8 J) k- ^2 \- w; Q
  17.   {
    % t) y, }! r* z. ~" w  k/ d, g
  18.     Error_Handler();: ^/ B/ t4 a9 J, _' v  ~0 [
  19.   }  R0 ^7 a# O# J2 z* d
  20.         /* USER CODE BEGIN 2 */1 v$ }9 Z( H& |3 D: Q
  21.         ) k+ p" a6 B% G5 n
  22.                 __HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE);                     //使能IDLE中断: [# W( [4 Z& n7 c
  23.                 HAL_UART_Receive_DMA(&huart1,rx_buffer,BUFFER_SIZE);            //DMA接收函数
    * T6 f# b  @: P& a" O% w
  24. 3 n  f: M5 H, b, [  ]# R
  25.         /* USER CODE END 2 */
    ; E* g) l) _; W1 b, w
  26.         % I1 B8 N+ }* r! N. _
  27. % Q$ @3 s6 g6 D& j8 y
  28. }
复制代码

& n& V- C1 n; J# }
4 i! B8 o) E9 _3 Q. l
uart.h添加代码如下:
( v. [/ ?  n1 a4 G/ W# G: S
  1. /* USER CODE BEGIN Private defines */% z% T9 F% }( U: j, c) M2 }% ?
  2. extern UART_HandleTypeDef huart1;
    2 p/ o3 ?0 Z9 s/ \0 K
  3. extern DMA_HandleTypeDef hdma_usart1_rx;
    6 Y8 V. w* |6 {! ]9 ^
  4. extern DMA_HandleTypeDef hdma_usart1_tx;
    # s- W# |* {1 C1 j

  5. 3 R& k/ U% _- [- I
  6. #define BUFFER_SIZE  100  " H4 H6 n) z( }8 t3 l, v* p
  7. extern  volatile uint8_t rx_len ;                                  //接收数据的长度4 m/ ~' Y& L- ~: S
  8. extern volatile uint8_t recv_end_flag;                     //接收数据完成标志位( u9 m2 z6 R  V6 P
  9. extern uint8_t rx_buffer[100];                                  //接收数据存放数组
      n5 `' ]2 q/ L+ ]+ w/ r0 T

  10.   R6 r( W0 O$ ^' R& k
  11. /* USER CODE END Private defines */
复制代码
9 b/ `9 [, _4 S* b
main.c添加代码接收函数如下:
0 b$ l' h7 [* I" k2 m
7 }6 |/ B- g. r/ t3 A
  1. /*******************************************8 @, ~$ j% b, Q: L
  2. * 函 数 名: DMA_Usart1_Read
    8 z- P! x4 h2 t; B. B
  3. * 功能说明: 串口接收功能函数/ }# e( ?2 D2 b; O% K; F
  4. * 形  参: Data,len8 b1 N# n  ]9 Z) o' L
  5. * 返 回 值: 无
    2 _* ~, \6 N  W
  6. ********************************************/
    1 [0 b6 Z- `# ~& ~' e
  7. void DMA_Usart_Read(uint8_t *Data,uint8_t len)
    # I# d1 v+ q2 v
  8. {                               
    ; y% S, K# z6 [" c4 F9 @
  9.                 HAL_UART_Receive_DMA(&huart2,Data,len);                                 //重新打开DMA接收# o3 \$ H+ l0 e6 y) Z& U6 e
  10. }
    : @/ m( H9 ]/ r- N% N1 q
  11. /* USER CODE END 0 */
复制代码

7 ^1 M2 L0 k' g9 ~1 A) }$ n) l' e3 ~5、添加收发处理函数
+ h) P6 O4 w3 l  S' W' r(1)main.c  while(1)循环中添加收发处理代码如下:
. u8 k. b; v, j" b: w
# ]) w2 K4 H* {! ^: I
  1. /* Infinite loop */; C+ X. d, R6 s  j6 y1 b; `+ v
  2.   /* USER CODE BEGIN WHILE */
    1 F7 F& X$ a1 L+ A3 ?
  3.   while (1), G6 u- ?; i( N" p
  4.   {
    / M9 O) a, W6 i2 O+ y
  5.     /* USER CODE END WHILE */
    ( D% ^" }2 t' J6 @
  6. 4 M& A0 l% ]' O8 t. w7 J9 B7 T2 }
  7.     /* USER CODE BEGIN 3 */
    % K& \$ C' _3 u- {+ _
  8.                                 if(recv_end_flag == 1)                                                                                                                                            //接收完成标志,如果串口有数据接收,则执行该部分
    . u# f% l% U" \! u7 c% V
  9.                           {
    & b' |- E4 m: f5 _7 \
  10.                                          DMA_Usart_Send(rx_buffer, rx_len);: }3 k0 p4 a3 W# J  C: \
  11.                                          DMA_Usart_Send((uint8_t *)"\r\n", sizeof((uint8_t *)"\r\n"));       
    4 a5 `$ j! X" r  o: H8 H* k4 s
  12.                                          rx_len = 0;                                                                                                                                                                     //清除计数: b' }, I( @& n4 K! t" X6 k! ^& w
  13.                              recv_end_flag = 0;                                                                                                                                                         //清除接收结束标志
    8 u1 ~$ i& Q0 F& u
  14.                                    memset(rx_buffer,0,rx_len);# h4 e3 D) h! y! w( }' G. T9 i
  15.                           }& ?# Q/ J( A( a" J! ]5 t
  16.                                 else                                                                                                                                                                                                                                //如果外部没有数据,则执行该部分
    ( O, N: D& j, T9 N# w& y7 V& K
  17.                                 {! ]5 z1 f+ L: [) Y! Q( T' u
  18.                                                 3 m5 Q: B: ~5 k
  19.                                                 DMA_Usart_Send((uint8_t *)"hello world,this RS485 send...\r\n", sizeof("hello world,this RS485 send...\r\n"));1 \6 o7 J  q& e, j: _! ?+ M0 [# |* T
  20.                                                 HAL_GPIO_TogglePin(GPIOC,GPIO_PIN_0);                                                                                //控制LED1闪烁
    - o) T' {! g" e3 s2 ~
  21.                                                 HAL_Delay(500);
    5 l9 E' g1 a3 H
  22.                                 }8 U  E/ l& `7 g8 `9 x+ t
  23.                           HAL_UART_Receive_DMA(&huart2,rx_buffer,BUFFER_SIZE);       //重新打开DMA接收                               
      \" ]1 N& [! z
  24.         }2 c( [: A% }+ t
  25.   /* USER CODE END 3 */
复制代码
7 q4 K( B- J$ A- P
(2)stm32f1xx_it.c中添加接收中断处理代码如下:
# |" y  P# P1 S" ^1 y9 C: e8 J1 y5 j
  1. /**1 h6 ^6 E2 K7 T8 V$ U- L; K
  2.   * @brief This function handles USART2 global interrupt.
    / C& s8 p! ^# o1 }8 p
  3.   */
    4 {& |: i# o3 u9 {0 R# ~/ @
  4. void USART2_IRQHandler(void)8 {4 v9 t0 T- U! F
  5. {
    0 {+ P) p6 n2 V6 E& I" T6 f
  6.   /* USER CODE BEGIN USART2_IRQn 0 */
    ' j+ q% D: C" r7 _, `
  7.         uint32_t tmp_flag = 0;& Y+ m. I. a- J- ]
  8.         uint32_t temp;% _+ ?, [4 }. p2 }( g
  9.         tmp_flag =__HAL_UART_GET_FLAG(&huart2,UART_FLAG_IDLE); //获取IDLE标志位! d% A& j" a# T6 \1 z
  10.         if((tmp_flag != RESET))                                //idle标志被置位* R- X- S" T- E$ A+ X. \$ x
  11.         { ! @0 L  q# J- E0 j6 N
  12.                 __HAL_UART_CLEAR_IDLEFLAG(&huart2);                  //清除标志位
    / [0 E' b3 ]: O. H5 c
  13.                 HAL_UART_DMAStop(&huart2);     
    9 s. n# [; u: O% j
  14.                 temp  =  __HAL_DMA_GET_COUNTER(&hdma_usart2_rx);     // 获取DMA中未传输的数据个数   # \$ w' C( A1 G2 b; K
  15.                 rx_len =  BUFFER_SIZE - temp;                                             //总计数减去未传输的数据个数,得到已经接收的数据个数
    ( o/ G+ l  F. L8 ^
  16.                 recv_end_flag = 1;                                         // 接受完成标志位置1        4 V: _! D% @5 |' G
  17.          }8 C. {" q9 _4 t- z& i8 \0 X/ u
  18.   /* USER CODE END USART2_IRQn 0 */# O, ^7 e! c( n3 D- g5 N, H0 ]' R
  19.   HAL_UART_IRQHandler(&huart2);+ R  W  l+ I) w6 [' c/ u, B
  20.   /* USER CODE BEGIN USART2_IRQn 1 */( N  x, X- \( o

  21. " y+ ~3 b( S- G( ^
  22.   /* USER CODE END USART2_IRQn 1 */) C: l1 a0 U6 p* q2 j8 ~
  23. }
复制代码
) X; `& x; }$ H; a) j
(3)至此,串口DMA收发数据需要添加的代码已经完成。2 \( L0 z- Z& q+ e

% ~/ N8 g. o( p) J 5、设置编程仿真下载模式
( W# W9 `0 I2 s& E- [  h! z; t(1)选择Options for target ...>>Debug>>J-Link/J-JTRACE Cortex,点击Settings>>选择Port(SW),可以看到搜索成功SW Device,表示芯片可用,可以下载。! G6 Y1 V3 S) a+ E8 m+ ]+ G
9 W9 e! t# x( B6 K+ P
edefb6b9a2a14be3b1221ad6d5c7a8a2.png
# ~4 \2 \2 V1 d% k4 Y6 ^, o8 ]% W" }

) [3 l% H& q+ ~1 f  R+ F(2)点击编译,完成后提示“0 error(s),0 warning(s)”。
# q3 x# F7 G: l+ S1 m
4 U6 \; p; y3 c% q: y6 Y
f0ed816a3ed14487bf9e857c317fc99b.png * V* k. O, H4 A" v4 G2 Q

6 I0 C" l4 L8 a& v5 i6 l* d& }(3)点击Download(或者快捷键F8),即可下载程序。
+ `/ q, ]' X! \1 x2 |8 J# F( X& E1 M# Y4 b7 ?. x
ba221842d5db40808aa129dd83c593d0.png + q6 P. a/ V$ [- ?1 T, t& X- _1 r
( G. h2 d+ L4 k( E  [
(3) 如果下载程序后,没有看到LED1灯闪烁,可以按下述方式设置一下(Reset and run表示下载后自动复位和重启运行)。或者重新彻底断电再次上电(或按开发板的Reset按键复位MCU即可)。8 ]" q) S4 N: o4 Q; i
5 s# [! d' m* s! H. c
9f8aa1a4e8f04041bcf5cb183facd100.png
/ X1 F& }. G- y& x; [
; N9 J" ?4 D. Q- s7 l+ i4、查看串口发送函数打印log效果0 |5 s( B5 p: g7 m) `5 M1 u
(1)设置串口助手参数为:115200、NONE、8、 1(和代码中串口初始化参数一致)。
" v. T( y: I6 u8 P8 e# g(2)设置成功后,就可以看到串口打印的效果。如果串口助手没有发送给MCU的数据,则MCU每隔500ms闪烁LED1指示灯一次,且串口输出一个log。
$ j! `( o/ u2 {) M# G(3)如果串口助手往MCU发送数据,MCU把接收到的数据发送到串口助手进行打印显示。
( g1 ^5 m; i8 \* M5 r; Q" p5 a2 ]# f# q5 s9 s
8f65172eef06499987e27edddf5320f2.png
9 w: q1 s8 a% D. k
1 v! ~; A  v6 q" d* i" Y————————————————
5 S8 s1 i0 Z$ N0 w! h6 F$ T4 W版权声明:智能小屋ZYXC
, c5 _0 Z1 {/ X/ P( g
. ^" _4 q8 ?0 ]3 R- J$ t6 m; p  k  o+ x' T
收藏 1 评论0 发布时间:2023-1-14 17:49

举报

0个回答

所属标签

相似分享

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版