一、开发板平台简介:8 ]+ I$ B# \! Z! w2 z- X {
1、开发板资源简介7 K4 K- t& N2 g0 P- `8 A1 |/ I
(1)开发板主芯片型号:STM32L431RCT6; b6 `& ?9 J5 q' _% H
(2)开发板主芯片封装:LQFP-64_10x10x05P
' C# g! O) G( ^0 i4 L3 b) q! c9 a(3)开发板主芯片内核:ARM® Cortex®-M4
: _& S& v6 G$ x1 T% F5 o(4)开发板主芯片主频:80MHz4 ]& s" O: I' D' J
(5)开发板主芯片Flash大小:256KB/ T0 ~9 P# h* c, z" A! t0 l6 y/ K* q$ A
(6)开发板主芯片RAM大小:64KB% Y8 H' L: O; z) n
(7)其他外设:请参考芯片手册7 g- o/ g4 B3 _& D, h5 O
8 A+ i: O6 G8 a) W, r) z5 A! ?& Q
+ w- M- s; |4 m) j+ `2 s8 \
& F% f: l$ ?# h* _6 B+ M% V6 }! _/ W
' Q/ @, ~* @3 Q0 o( K
7 @! r* Y: T/ l- v, x6 D0 F
2、串口简介
; K) b; h3 v* k; l% q& f 串口全称为串行通讯接口,即数据在通信线上一次传输一位,按先后一定顺序传输。我们通常所说的单片机串口准确来说应该是串行异步收发传输器(Universal Asynchronous Receiver/Transmitter,UART),使用TTL电平,串口需要RXD、TXD、GND三根线进行通信。7 W! A" F! T* G% A& w
5 J* ^0 o6 U0 G (1)我们选用的STM32L431RCT6开发板串口1已通过USB转TLL串口芯片CH340G引出,使用时,只需要用公对公USB线连接电脑即可(注意也得需要安装CH340G驱动),后期验证试验也使用该串口1进行。
5 W* g9 R- Y4 w' u4 [( e; |: K- {' G' U$ Q
(2)开发板上的其他串口已通过排针引出,为TTL电平,通信的时候需要注意选择对应的电平模块,如USB转TTL串口模块等。% ?0 I8 L% D2 k. D
$ Y# p7 } p: a' B
! F6 K. l! t- R5 w" e 二、新建工程
: u$ O% G" ?$ z9 u; e1、新建STM32CubeMX基础工程+ h% _0 D: d5 u) D4 x. x
(1)打开STM32CubeMX,点击“File”-->"New Project"; n) H. i, {, C6 a0 c: K4 h9 l
6 Z, V. e# _0 m$ j
* Q" f+ B# M. A3 u! h6 r0 ]
( q5 ^/ Q8 b" X$ q1 H0 w- V- I
(2)等待打开主芯片选项界面(大约1分钟时间)。
# ]) ?0 j4 r- w. M5 s! i9 f+ V& Y6 o: ^7 L- l0 p( x
/ L C/ S8 `) r" f& L
3 w% k D2 g8 s# u$ V, ~* ?
, u+ n! I1 E9 @(3)昨天搜索框中输入(或选择)所需的主芯片型号(因为我们用的是STM32L431RCT6开发板,所以此处现在STM32L431RC),然后在右下角选择STM32L431RCTx(因为开发板主芯片是STM32L431RCT6),左键双击即可打开新建的项目。% |$ k) z) x2 N9 o! y* w2 @! Y
3 }5 Z# o: v4 L9 L: u4 P
& C2 M1 X) Q# i, Z# x- X* F
' r& X2 N7 z& V, D# {(4)选择时钟源。
[, v. Q Y* a(1)因为开发板上有8M外部时钟,此处选择外部高速时钟(HSE)。6 A: P3 v0 Z3 u! x7 g! `) _
(2)因为我们没有用到外部低速时钟(LSE),此处不做处理。
! g, j' A, W! T: [0 ?5 O) p8 _) A# F
# ~4 r: A, b9 D. h8 V3 ^: A/ y8 Q" _) ~( N; f A& z4 }
2、配置GPIO控制LED5 e3 r" ^4 g, O
备注:LED灯用来指示系统是否正常工作。1 I5 k' K% u! U) s7 n3 R
(1)查STM32L431RCT6开发板原理图得LED1控制引脚为PC0,则配置GPIO的引脚PC0。: z* e. e9 ^6 v4 m% j3 R
鼠标左键点击PC0,选择“GPIO_Output”,表示设置该引脚为输出模式。
X9 |' f' S: B4 `3 V" Q5 Q3 {3 S5 e7 J9 w+ j1 ^
' c+ t9 R+ Z' U6 ~ I5 i: V
0 A" L" F- I$ [/ l% o* y; g(2)根据自己的需求配置GPIO的参数,如输出方式、输出频率、上拉下拉等。因为GPIO控制LED的要求比较低,此处采用默认参数即可,不用修改。; P# ?4 q1 G, z- D, R ]1 @6 Z
% n, a3 W% E ~4 H
% Q& A( a1 |* L, J% Z
7 \% c; V! Q/ R" {$ A
3、设置串口1参数
, _) @' r$ t# E: B& Z6 }1、查原理图得知,串口0使用STM32L431RCT6引脚为PA9-USART1_TX,PA10-USART1_RX,引脚设置如下:$ A, f" d/ [9 w. o. F) k5 l
" l* I7 ^0 P6 C# Q2 N$ [) d
* R9 |3 ]) a& D' r9 y
! j; U+ _: {' Z x (1)序号1用来设置串口收发引脚的选择。
6 o+ B+ I0 \! U( n2 D5 {, A" |9 x5 ~. H, J. S- V/ H
(2)序号2-3-4-5-6设置串口参数,如波特率115200、8位、NONE无奇偶校验等。
- m1 O3 O( r# h A6 {) `6 _
3 T/ q* A/ x1 g% n. M' K* T) d2、设置NVIC settings 使能接收中断
, f# m) i2 o9 P2 y+ E! t7 V
, `( N: y, i- x4 G; i
2 o9 k7 P& `5 x; U, X; l% }1 u D
2 n$ d$ E" P" F& U& U4、串口DMA设置
6 M K9 _4 r3 n5 c8 p$ X& x4 p; G% V4 H$ D9 A7 D2 U
) \1 }' Y p/ V, w5 N/ |
7 @3 }: v1 b+ }+ K8 ]8 n0 X (1)根据DMA1通道预览可以得出,我们用的串口1的TX、RX分别为通道4、通道5:. c7 Y) g; D9 q8 o# F/ ^0 y
点击DMASettings 点击 Add 添加通道1 k& O. j( b" L8 I) Y2 J( p
选择USART_RX USART_TX 传输速率设置为中速' H$ g8 n3 ~" \- J, \5 M
DMA传输模式为正常模式,即发送一次就结束。
( @/ ?2 W! l2 ?) a" d( ]; T* FDMA内存地址自增,每次增加一个Byte(字节)* K6 F* e2 A7 F2 Z9 q! f& h7 [
7 u0 `0 r' A) Y. n7 Y: i
2 P2 F5 f( t7 f$ D. }/ {( {. v/ r' `$ n& y6 o3 K; @1 f
+ j6 }6 h# o0 E( R4 W! P4 j(2)DMA相关参数解析, U3 y; j: R8 E2 B( {( E
( o7 u/ Y( Y" d2 H! A8 ?; TDirction : DMA传输方向有四类3 w% z: O- N! [/ x! R; G
外设到内存 Peripheral To Memory
) C* x3 w# L$ f3 Z1 i( f6 `6 H内存到外设 Memory To Peripheral
# v3 a) ]: z1 T! o, x+ m内存到内存 Memory To Memory) k/ W6 N# q. w6 a' S N
外设到外设 Peripheral To Peripheral6 _; V+ ?5 O/ @) B' i) ~
Priority: DMA通信传输速度有四类
) a1 j/ w" i0 n最高优先级 Very Hight
: U0 ?( g8 X9 _高优先级 Hight& d- |7 ?5 [( v' d# n- Y# ^! M9 B
中等优先级 Medium
7 G% W: |" T `0 k# d& o+ c低优先级;Low& J6 I) {! V3 Z. y! _& f* [8 `
8 I" _( y5 E7 u% ^/ \Mode:DMA传输模式有两类# Z. l, G; m! A) C, p3 }
& s- ?$ W7 R8 \( c9 ?! ?6 g
0 z! h- J7 N- e0 F% Y- d, I- y! ^- e! V' P' Q4 C- `* L
+ Q9 r) c& ?) O/ RNormal正常模式:当一次DMA数据传输完后,停止DMA传送 ,也就是只传输一次。
1 D% b4 I5 T) G+ zCircle循环模式:传输完成后又重新开始继续传输,不断循环永不停止。9 N* h7 [' X; w6 y! o7 c
* }* W2 ~% Z+ y8 S! g# r8 MIncrement Address-DMA指针递增设置:
. S1 s3 C; l1 L+ [4 J3 o0 ^" O) I: D0 X2 E- {! Q7 X/ d
7 p2 d8 ^2 c- h: H- C. \! K# r0 b" O5 U8 X& |/ _) n: J
* ^! R7 p. r. P2 o' T
5、配置项目工程参数
; b- P- Y+ h2 ^(1)配置时钟树,用于系统内部时钟,以及各个外设时钟等。此处选择外部8M晶振作为主时钟频率,内部最大倍频80MHz。& ~9 ]# n* b |/ ~
8 m6 _# u3 P. N/ ~+ X2 M$ q: ]
# Z# L0 |" [9 u ^& Y/ S
8 h$ ]& ?3 ?/ q( u k( m1 w/ N(2)完成配置工程。( P& U+ n3 E$ M- p
备注:需要注意代码生成过程中的继承关系,如图所示:需要保留开发者自己编写的代码时,请根据配置设置,不然生成代码后会删除自己编写的代码(从这个方面也可以看出开发者备份自己的代码是多么的重要。)& m; W9 e3 h W( v- o
* @8 i' H. N6 e* }. O! V: o t
h& c; j) H2 T- s2 _6 H! w4 ]% l
- v2 ^8 @9 J- b1 t
; r6 B: e [& V* |5 v1 e: k2 U0 b j& a5 e$ p8 W n' \
(3)生成代码。. v9 r% w* @* h' q/ T4 p% f p0 B
1 U, e/ |& q% J; h; x
: z2 f' M) P- R6 w% k; _7 N. F4 Y/ H: n9 V5 l
三、在KEIL 5中编写代码+ ~$ ]/ P8 k, O( C7 x
1、使用KEIL 5(MDK)打开项目工程文件
3 _" `; ^" m. ^' d' c. ^9 k(1)找到刚才新建工程的存储路径,安装项目名称,打开项目工程。
0 k, P% I0 t. {$ B+ M& q) [5 J1 C0 _! d6 V: l$ _- }8 ?2 A
h' ^0 l3 h- {$ A! h# v& F
8 w9 R0 V! g# |* ?
2、添加LED指示灯作为系统提示( B+ r6 k3 x# @& e+ O7 s: u" v
添加每隔500ms,LED1闪烁一次的系统提示,用于提示程序运行正常。
$ w$ o8 }" p9 i: W3 `+ n% M$ H* c. v1 H' z$ }( |
+ y2 B) o' m) y% O- s$ V" A4 Z4 U6 ]0 p2 H4 s' a, I+ W# A
3、添加HAL库UART DMA 发送函数代码1 f7 r$ P0 B ^
(1)STM32 HAL函数库的串口DMA相关函数如下:
" w0 e5 V0 d5 ]7 r8 M- HAL_UART_Transmit();串口发送数据,使用超时管理机制
P+ F) T" c7 U \# O* f: n8 i - HAL_UART_Receive();串口接收数据,使用超时管理机制0 p# g8 } ?' F1 H9 D
- HAL_UART_Transmit_IT();串口中断模式发送
b2 m6 @0 h% p5 k. } - HAL_UART_Receive_IT();串口中断模式接收0 L, O% N3 k+ a
- HAL_UART_Transmit_DMA();串口DMA模式发送
8 C# T' _& P( F& x - HAL_UART_Transmit_DMA();串口DMA模式接收
3 s. e" u# E! a$ j8 } - HAL_UART_DMAPause() 暂停串口DMA
3 M2 |, b$ O9 g' b6 B- N - HAL_UART_DMAResume(); 恢复串口DMA
3 A7 Q8 R1 H- M7 r( I) n6 { - HAL_UART_DMAStop(); 结束串口DMA
复制代码
0 ~9 E! T5 B3 z1 k E(2)添加串口DMA发送log代码:1 M8 O$ x' \" S. @6 q: q7 H
- /* USER CODE BEGIN WHILE */
% K/ s5 [! a. c1 X% E! H - while (1)
, _4 O" k5 M1 W3 b3 t* R - {3 j' d8 V8 ?" e% t% l' n3 b) }) e
- /* USER CODE END WHILE */3 x5 ^( T, R3 w2 E" c$ P
-
7 E0 Y [0 N8 [+ l( t+ f4 v5 @ - /* USER CODE BEGIN 3 */
5 j- b1 ?( W0 Z" r b - HAL_Delay(500);! O- a6 e9 I2 C
- HAL_GPIO_TogglePin(GPIOC,GPIO_PIN_0);//控制LED1闪烁6 \/ o& s/ c( Y1 O( J2 K0 t
- 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"));//发送提示
2 ?! i8 z. W$ B( k. b6 U - }( w. b3 {, d4 c0 G# t- k9 T
- /* USER CODE END 3 */
复制代码
# W. ?- C; E. I& N- S; ]6 M9 |" Y4、添加HAL库UART DMA 接收函数代码
! _( V c) n- N" M& e$ K, K T(1)DMA接收设置前铺垫知识点: I8 _( [' Q) V' ^8 i
STM32的IDLE的中断产生条件:在串口无数据接收的情况下,不会产生,当清除IDLE标志位后,必须有接收到第一个数据后,才开始触发,一但接收的数据断流,没有接收到数据,即产生IDLE中断停止。. ^; S" X2 B% h4 _
8 V7 I1 f/ s- G( f) G(2)初始化中断接收配置:
/ T; A3 V6 w1 _) P5 }# l# e/ q; `uart.c添加代码如下:" O4 {* I# |. [- A4 S! {
- 6 ~$ R0 k- m/ T# m$ Z
- /* USER CODE BEGIN 0 */
* J- D" p, ^5 `2 _; v; d1 J - 4 z, Q# o' X, ^. H" ~+ T! A
- volatile uint8_t rx_len=0; //接收一帧数据的长度& n. d6 K; H2 {% p- q
- volatile uint8_t recv_end_flag; //接收一帧数据结束的标志位
+ ~/ ~, M- o& }* K5 O - uint8_t rx_buffer[100]={0}; //接收一帧数据的数组大小* h/ l7 t* I8 E# T* ?
- /* USER CODE END 0 */
复制代码- /* USART1 init function */
$ @" W* O) B/ l& M% M) ? - 7 L- ~- s" ?% f3 w" q- U
- void MX_USART1_UART_Init(void)
0 ]( A8 k% d1 @/ d0 o - {
, G0 c, B+ Y# _" {1 z - $ l5 K9 s; |4 I3 C z
- huart1.Instance = USART1;' ]( e9 W& g$ ?2 ~
- huart1.Init.BaudRate = 115200;0 a( ^! ~, r3 Y- ^0 c' Q! m
- huart1.Init.WordLength = UART_WORDLENGTH_8B;
0 K9 e/ o1 p. x* n' T - huart1.Init.StopBits = UART_STOPBITS_1;/ x1 k! _% I0 D- e* P
- huart1.Init.Parity = UART_PARITY_NONE;3 M# |: e6 ?( v }
- huart1.Init.Mode = UART_MODE_TX_RX;: b; A2 M- Q2 Z( k- M7 I/ ^: \
- huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
0 E3 G) q( p0 |; y: ?8 H0 f# A - huart1.Init.OverSampling = UART_OVERSAMPLING_16;
$ |( j) U, `1 ~- q/ Q - huart1.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;4 j6 t% ^1 @% y: f w9 m9 N, w( e
- huart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
4 J4 p( s' R5 j. e! j& l( ? - if (HAL_UART_Init(&huart1) != HAL_OK)7 I3 _$ z: h$ r; X
- {
) {) Y( o( @/ p! k - Error_Handler();
/ Q* N+ D6 |! m5 p; P - }; S0 _" g* p% e4 o) N& s
- /* USER CODE BEGIN 2 */
( { B6 b9 W8 N% ? -
- K+ A) ?/ ?9 [( A - __HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE); //使能IDLE中断9 K1 ? x8 B3 j
- HAL_UART_Receive_DMA(&huart1,rx_buffer,BUFFER_SIZE); //DMA接收函数3 O; D$ U! _; z
-
( A+ E7 d, I, s% d' R' D - /* USER CODE END 2 */# [3 A0 d, |1 i
- 3 G5 |( z, B. V, Q' r" R- _7 g
-
; c7 q" g" a9 Y - }
复制代码
9 R; K$ m/ z1 q% uuart.h添加代码如下:
8 | ^& r; E* X6 I3 V- /* USER CODE BEGIN Private defines */
+ T S t F/ c& z2 z - extern UART_HandleTypeDef huart1;- Y5 ?, L# r, H, B! O4 d* b
- extern DMA_HandleTypeDef hdma_usart1_rx;
8 X5 b. ], h- {- B - extern DMA_HandleTypeDef hdma_usart1_tx;
7 Q6 Y- `1 |$ i. @: x( l -
# v0 @6 ^- L. G0 ]* r9 ? - #define BUFFER_SIZE 100
+ [* j F, Z# E2 F7 S: j% J8 d" c - extern volatile uint8_t rx_len ; //接收数据的长度+ o" b; q; u( j# ]7 P$ _
- extern volatile uint8_t recv_end_flag; //接收数据完成标志位1 ?% [- X- `* i. c7 Z0 v2 q6 v. b
- extern uint8_t rx_buffer[100]; //接收数据存放数组
/ E& D5 E) U. G& m -
: [6 f8 J8 S4 a - /* USER CODE END Private defines */
复制代码
7 N. S) E6 C8 {* L& r# P) W; Kmain.c添加代码如下:
' D' ]; S( G3 W- /* Private includes ----------------------------------------------------------*/5 y8 s5 o) t9 m6 n3 K! H7 @
- /* USER CODE BEGIN Includes */7 R! a+ R W# K
- #include<string.h> //添加字符串头文件
7 D9 x) ~+ Z) M0 ]* J! ~. p. V - /* USER CODE END Includes */" H7 z5 a$ ?# I4 [7 A
- /* USER CODE BEGIN 0 */
$ E1 ]6 q5 c* [ v8 W* I1 b, J - /*******************************************' a* l; i) X. |' g, L6 d- D
- *函数名:DMA_Usart_Send
) p$ A5 v3 ^( E; g - *功能说明: 串口发送功能函数/ J4 B+ d/ ~) P8 P1 L
- *形 参: buf,len
9 y9 {: _/ k0 s, Z- P; u - *返 回 值: 无6 K, Q1 d" ~* ^. ^
- ********************************************/# Z) P o: j: G& c! m
- void DMA_Usart_Send(uint8_t *buf,uint8_t len) ; n6 I# p; ?# `
- {. g, f! }7 e" k* {
- if(HAL_UART_Transmit_DMA(&huart1, buf,len)!= HAL_OK) //判断是否发送正常,如果出现异常则进入异常中断函数
' U. P: N$ b4 Q: ^& ^3 N - {$ e- v3 ], k6 X f& \: x/ j! g5 w
- Error_Handler(); //异常提醒9 G( }% t$ h& u
- }
* ~) j8 \; `/ j% @ - }( P- H( z- V- J2 O2 V
- /*******************************************. n! c; j7 ^5 U7 d
- * 函 数 名: DMA_Usart1_Read
7 o# u z% _ D# W1 M - * 功能说明: 串口接收功能函数; X2 n- `( B, j* M5 o! F
- * 形 参: Data,len6 N7 Y! j0 S$ r& N1 y3 W/ R
- * 返 回 值: 无
, c0 k/ ^9 @8 m% E - ********************************************/, c9 d0 M2 W( m5 L% l% ~
- void DMA_Usart1_Read(uint8_t *Data,uint8_t len)
5 L( n' }3 V" H- |; w0 K. A - {3 {2 }4 D. c0 z. D! S/ s, r
- HAL_UART_Receive_DMA(&huart1,Data,len); //重新打开DMA接收
4 H! e' H6 a# K - }
% L# O$ Y8 W- l; C& c - /* USER CODE END 0 */
复制代码 ' E, A/ R0 k; z
main.c while(1)循环中添加代码如下:; I6 {9 R' d) z2 q1 U- g; k$ Z
- /* Infinite loop */9 Y4 u$ ^, ~6 O0 T
- /* USER CODE BEGIN WHILE */1 [' C. g2 c3 T, h+ c
- while (1)) N* ^4 Z2 {' T5 m) I: C
- {1 P) M. y0 Y2 M1 P0 A, F" v q' C
- /* USER CODE END WHILE */
3 n+ F) L& O* x- h4 _4 I8 u - 1 i1 w- a5 i1 i$ B7 y# |( [
- /* USER CODE BEGIN 3 */' [( o" r6 o9 ]- N t% i7 c
-
' T8 l( A5 Q7 l1 h5 O& R* A - if(recv_end_flag == 1) //接收完成标志,如果串口有数据接收,则执行该部分
8 l/ X$ {! Q3 h. G9 z, @! b - {
. P' c- ]% v: N8 n - DMA_Usart_Send(rx_buffer, rx_len);/ R( D& a% l; O% ~+ _# i; P; L Q
- HAL_Delay(200);( S7 N! Y1 ]% P$ {& _% S# S
- DMA_Usart_Send((uint8_t *)"\r\n", sizeof((uint8_t *)"\r\n")); & }/ F" a/ \5 k8 p6 P
- rx_len = 0; //清除计数
6 v6 K0 E. k5 f7 O( h - recv_end_flag = 0; //清除接收结束标志位5 {/ F, _; n5 s4 t
- memset(rx_buffer,0,rx_len);
/ B' a1 {( L* h- G' m# @ - }5 `0 f; Y. F" j- h2 ^2 ~% e( ~2 f& z8 U
- else //如果外部没有数据,则执行该部分7 I' ?% g0 a1 ]
- {
3 U/ P& `, w% m/ j/ C/ V$ j - 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"));
+ M5 X: T9 C" j% R% s* F - HAL_GPIO_TogglePin(GPIOC,GPIO_PIN_0); //控制LED1闪烁8 k. b( C. Y; I" P
- HAL_Delay(500);
( l# I% r' p- j! ^ - }
9 R; w% i6 j) t; W1 w1 M9 D. ~ - HAL_UART_Receive_DMA(&huart1,rx_buffer,BUFFER_SIZE); //重新打开DMA接收
6 S3 e& l- O: E - }
+ E) d- @+ A# n - /* USER CODE END 3 */
复制代码 7 X/ a6 C5 T- G! |) ^4 h$ e+ E
stm32f1xx_it.c中添加代码如下:
# d/ F m: X* \) t8 {3 l- /* Private typedef -----------------------------------------------------------*/
/ G I. M9 S. i - /* USER CODE BEGIN TD */
" e% E; A: p1 K* E2 p* U1 R - #include "usart.h"
4 a* t! C$ \, f - /* USER CODE END TD */
+ J2 B! l( ^2 B8 Q/ w -
) o* w5 ^% L$ W4 E - /**% x% o+ G0 r5 {' a; Z$ s+ J% `
- * @brief This function handles USART1 global interrupt.' y7 h; K) s& _& t
- */8 h5 _; X1 E" S8 t
- void USART1_IRQHandler(void)8 q, H- P& R5 E- b4 v
- {
0 D6 I1 I9 H7 C( \ - /* USER CODE BEGIN USART1_IRQn 0 */7 Z! J4 T" {" g( y
- uint32_t tmp_flag = 0;
2 s* X7 B/ h+ Q# o- ]# _6 R - uint32_t temp;
/ j3 B/ `- V+ @/ V3 Z' z3 y- @ - tmp_flag =__HAL_UART_GET_FLAG(&huart1,UART_FLAG_IDLE); //获取IDLE标志位
% b2 ^" `. A2 m5 R1 { - if((tmp_flag != RESET)) //idle标志被置位
' i" Y, S% Q* q) E - { 0 ?$ `; c0 D1 {- q. d# u
- __HAL_UART_CLEAR_IDLEFLAG(&huart1); //清除标志位
7 L0 V- G1 R; W' P- q8 g6 B/ ?; E - HAL_UART_DMAStop(&huart1); * E4 T3 u3 q* W' Z6 P9 I
- temp = __HAL_DMA_GET_COUNTER(&hdma_usart1_rx); // 获取DMA中未传输的数据个数
" ]' E* h. K0 f2 C' j& a% `! } - rx_len = BUFFER_SIZE - temp; //总计数减去未传输的数据个数,得到已经接收的数据个数/ U: v- R: K( S" B" [$ s6 B- f) l. H; u
- recv_end_flag = 1; // 接受完成标志位置1
- ~5 y [) a. Q* h( b3 k6 b1 X, |, H - }' M& Q. S5 Z4 b* Z% J) A4 A% c
- /* USER CODE END USART1_IRQn 0 */" E5 k1 Y2 d. a$ E0 d7 {- l% B
- HAL_UART_IRQHandler(&huart1);
9 ?8 G4 {9 [# u- S; d3 m) c - /* USER CODE BEGIN USART1_IRQn 1 */5 G; _. x9 @/ C* x# w* E
-
[8 Z1 _. N3 r% f - /* USER CODE END USART1_IRQn 1 */
5 f1 m/ q3 w1 ~: @* D4 F - }
复制代码 4 \; X7 i2 b# e- v6 g, w
(3)至此,串口DMA收发数据需要添加的代码已经完成。
0 H; u6 g+ b1 R: i) f5 f ~! w5 f8 F2 m/ h6 w2 ? \4 d
5、设置编程仿真下载模式
& R3 i; p1 O- h. f! E% b(1)选择Options for target ...>>Debug>>J-Link/J-JTRACE Cortex,点击Settings>>选择Port(SW),可以看到搜索成功SW Device,表示芯片可用,可以下载。
" J4 T# A$ m, u8 F# v E+ ~9 ]
& F1 X# b* N- o+ b7 X, j3 H: T) }
0 s6 ~6 i6 U {. r7 J; ?0 R; Y: Y0 L$ \+ k: o0 T( T P
(2)点击编译,完成后提示“0 error(s),0 warning(s)”。( e4 V& \) A$ X
- t% ]/ z' ^- I3 }3 N( D
4 {1 T! X5 g2 C2 V; ]1 ~
0 {" ?+ R# I2 o8 J
(3)点击Download(或者快捷键F8),即可下载程序。
6 g& N' i Z: ^3 M1 @' Z4 c. g9 }6 p; u. z. X
1 v- a( Y. ] l; X% h0 _8 E3 j
, H3 g* M9 k! X3 x. o" W# n. p3 J(3) 如果下载程序后,没有看到LED1灯闪烁,可以按下述方式设置一下(Reset and run表示下载后自动复位和重启运行)。或者重新彻底断电再次上电(或按开发板的Reset按键复位MCU即可)。
7 ?1 e8 R2 }0 X* v- A2 ~6 D9 f2 `' F) r/ i4 T/ a# ^0 @1 d
5 b0 [5 D$ N+ Q/ Y$ l% P7 G5 W6 [2 Q1 ?' S6 X. m, b6 J8 }
4、查看串口发送函数打印log效果9 B% O6 M, s' `
(1)设置串口助手参数为:115200、NONE、8、 1(和代码中串口初始化参数一致)。4 [/ F0 T5 e$ j+ u
1 N; U* ^7 b9 y! j: u; i
(2)设置成功后,就可以看到串口打印的效果。如果串口助手没有发送给MCU的数据,则MCU每隔500ms闪烁LED1指示灯一次,且串口输出一个log。7 V- w* y1 C7 n" T' F* m% O
0 P K( A* P; J& ?* t(3)如果串口助手往MCU发送数据,MCU把接收到的数据发送到串口助手进行打印显示。
" l' p! N" ]/ S5 G& E8 r9 l% B5 N _" n R X9 N# c
. d2 I* B, y! q* n7 W" u% \2 q
6 B, M/ ]+ Y: m
————————————————
+ V- H) a: `! J( C; }1 ]6 Q版权声明:智能小屋ZYXC. l) G6 {1 P) i+ z1 f0 O
, d4 F4 ]) h" w/ A
% t o% h6 X) H5 D" Y
|