一、开发板平台简介:3 E( Q# @( i) \) b0 j/ z( j9 A7 M2 }
1、开发板资源简介: k. c$ b7 T' k( c' y
(1)开发板主芯片型号:STM32L431RCT6+ i, s/ B- P+ z& u
(2)开发板主芯片封装:LQFP-64_10x10x05P
0 ?3 {! l* P& X; s: O; m(3)开发板主芯片内核:ARM® Cortex®-M40 W* L6 g& E d- w* L
(4)开发板主芯片主频:80MHz. H" m# v( ^6 W) b
(5)开发板主芯片Flash大小:256KB0 G' C: i! g* F' N% B6 p. g& D
(6)开发板主芯片RAM大小:64KB
- z- ], @( [% ^& U% k (7)其他外设:请参考芯片手册
- H" ~1 n2 ~; h8 Y0 Z9 k! O
. v" X4 y# d9 O# B% g
3 B0 a% V* Z: W) l1 a/ g) ?6 f
- |; J, O' F! `( G
: i4 W4 X) {4 `! N* R& A: {
8 q9 A( g( J1 z2、串口简介
3 s6 V. O+ I( k5 K8 ]( ` 串口全称为串行通讯接口,即数据在通信线上一次传输一位,按先后一定顺序传输。我们通常所说的单片机串口准确来说应该是串行异步收发传输器(Universal Asynchronous Receiver/Transmitter,UART),使用TTL电平,串口需要RXD、TXD、GND三根线进行通信。
# f1 M* A; m* W4 k
( k' O( x6 Q: _- [; P% [+ [ (1)我们选用的STM32L431RCT6开发板串口1已通过USB转TLL串口芯片CH340G引出,使用时,只需要用公对公USB线连接电脑即可(注意也得需要安装CH340G驱动),后期验证试验也使用该串口1进行。
- ~+ j& n' c! B4 `7 e. H# ~8 V
7 V. q4 f7 ?" X- B( o: [ (2)开发板上的其他串口已通过排针引出,为TTL电平,通信的时候需要注意选择对应的电平模块,如USB转TTL串口模块等。
/ V j* I4 a; j! _ r( c, i0 j8 A$ O
9 n# o& M$ ?: {. ] 二、新建工程
. `' c5 j4 `; B7 ^) i& I1、新建STM32CubeMX基础工程1 m- T- v& f. M- P0 |0 f- z/ U
(1)打开STM32CubeMX,点击“File”-->"New Project"4 S" i: l" a1 K$ z6 _7 e
# x- q) L' h# }8 Q- c3 f+ F$ b* W
" E# Y+ F6 M' E: e- `8 |7 I
; U. B+ O% o* y2 s(2)等待打开主芯片选项界面(大约1分钟时间)。3 i0 B( a, i5 H1 q& S3 q9 ]
: {) Z8 ~; {- M
# \ o1 _0 o I( Z/ m7 ^: x
1 \& H0 e( U( B- G# n. u" W
+ r N- f. o: s1 S(3)昨天搜索框中输入(或选择)所需的主芯片型号(因为我们用的是STM32L431RCT6开发板,所以此处现在STM32L431RC),然后在右下角选择STM32L431RCTx(因为开发板主芯片是STM32L431RCT6),左键双击即可打开新建的项目。
. L2 j( m5 Z1 P9 p
8 H" D: I8 L/ L' L/ m# x
9 H {) h" G# N, @3 b9 s
3 {& a& o6 s/ b7 p5 N(4)选择时钟源。
6 s9 t# J' q+ f6 ](1)因为开发板上有8M外部时钟,此处选择外部高速时钟(HSE)。
3 m* {; `* Y+ B(2)因为我们没有用到外部低速时钟(LSE),此处不做处理。
# k( ?/ F- r9 r0 E4 }! q; B5 J
* t! h5 H S" B2 |$ H
- t' i8 }5 [$ p0 `6 @3 l
- c( @; N l! l) {$ H7 z8 H: k; M# g
2、配置GPIO控制LED
1 }( d2 O% T4 N备注:LED灯用来指示系统是否正常工作。
: I+ _7 h' d+ {, J(1)查STM32L431RCT6开发板原理图得LED1控制引脚为PC0,则配置GPIO的引脚PC0。; i/ N2 w$ ^* |: @) S7 B
鼠标左键点击PC0,选择“GPIO_Output”,表示设置该引脚为输出模式。
; i/ d* \- ^+ v% ?9 S; h# Q8 {" Q
?/ W- w9 y' @
# u& N9 P" s* a" n$ C7 @
/ f j# ~) ]# S3 D(2)根据自己的需求配置GPIO的参数,如输出方式、输出频率、上拉下拉等。因为GPIO控制LED的要求比较低,此处采用默认参数即可,不用修改。5 {3 _6 e* g# A6 D' x- ]5 ~( o
& v7 y2 }5 Z& d5 e
! W. @# @3 y9 ~ y8 a2 ^5 J* d
- f6 y. R# G8 `3、设置串口1参数. ]1 M" P7 h. F/ N) G, h
1、查原理图得知,串口0使用STM32L431RCT6引脚为PA9-USART1_TX,PA10-USART1_RX,引脚设置如下:+ {/ w3 _: M$ x9 q
9 L2 g3 @' W& W6 K- e, R
2 D/ a3 M8 g* R+ W- g! _# l2 [& F1 I6 B- A7 x
(1)序号1用来设置串口收发引脚的选择。
6 f: X9 I! G e% Y4 t7 ~4 ]
* C1 E1 b, ]5 T* G(2)序号2-3-4-5-6设置串口参数,如波特率115200、8位、NONE无奇偶校验等。6 I6 H& ^" ]) ]7 S Z
$ y3 D& Z5 W2 q7 f0 f/ }2、设置NVIC settings 使能接收中断; }$ \* @# |- I
. V4 r* Z7 m, v
, b( w" @4 h& O8 g0 q" U
[0 _8 w5 T; ~ L% F' r
4、串口DMA设置 2 P0 Q* _3 I% m7 U2 p0 _5 C N& I
* i- m3 S; C) e6 L; Q
, K" H* u( E* | G0 R6 I' p
; L- Z0 y+ d) f
(1)根据DMA1通道预览可以得出,我们用的串口1的TX、RX分别为通道4、通道5:
) r+ l7 T3 Z0 I# @点击DMASettings 点击 Add 添加通道
* p$ l: w0 J. d) E/ w- b选择USART_RX USART_TX 传输速率设置为中速- `5 o0 \% e2 i
DMA传输模式为正常模式,即发送一次就结束。
; J; X; Y2 e1 x* TDMA内存地址自增,每次增加一个Byte(字节). _0 M# l* ^ \- |7 G7 W
+ q2 L1 X) I3 y" o, r" L
" W- z; ~$ ^) t8 b9 @
( B" y0 d% Y, X' x6 W1 \! O' Z2 X: A& _! J7 B
(2)DMA相关参数解析
! A7 ~. L# @5 C, d: n) C# p9 W3 S+ T; d
Dirction : DMA传输方向有四类: l; O0 `6 r9 I# U
外设到内存 Peripheral To Memory% y3 j9 D! q2 X8 f, Y6 ?
内存到外设 Memory To Peripheral
! y' u& j% v# F/ W& C$ Y& \, l4 \7 [- o内存到内存 Memory To Memory! i5 }' I3 j i& I" R7 X' {
外设到外设 Peripheral To Peripheral
x# ?) U4 Q3 ?Priority: DMA通信传输速度有四类7 {4 y2 j J! i( Z: N3 A. H
最高优先级 Very Hight7 C' ]+ T: r) N$ b, s- x; B/ U
高优先级 Hight
6 q# z4 o" D) T+ [) O1 Q中等优先级 Medium
8 n, j& }8 j# S9 }8 i- K低优先级;Low
" K, b) a, ]# I( `# v: G' D& p l4 G) V" L6 @
Mode:DMA传输模式有两类1 y9 w* j0 n. Q3 k
3 P6 k4 k' q" w) u& {
7 h0 p3 Z6 p* i7 h- j `
$ S( g+ j$ E# i0 x4 w2 j
2 D1 a; H$ J. d5 p; l. [Normal正常模式:当一次DMA数据传输完后,停止DMA传送 ,也就是只传输一次。
, F& H' }" `, K1 KCircle循环模式:传输完成后又重新开始继续传输,不断循环永不停止。
; X I* y! d6 {% P6 `7 j5 b$ N ?6 o0 s, b) @ [5 i4 z9 c
Increment Address-DMA指针递增设置:
6 |8 s5 i: L7 c! X
# c7 [5 y: R: }. w2 O8 I3 c; `1 i, C
1 v, T4 a0 l2 I0 N/ y' z/ k
, c$ X; u# h* S {3 H
7 r {8 I3 S! z% h/ n. n M 5、配置项目工程参数
+ R. C3 S6 x" d% [2 x(1)配置时钟树,用于系统内部时钟,以及各个外设时钟等。此处选择外部8M晶振作为主时钟频率,内部最大倍频80MHz。 E; n/ H7 R1 B/ K3 F1 t6 e
0 G, I0 v6 J# l. V5 {. F9 S
7 B2 ]* { i0 \1 Z" ]
: n) `8 [ p' w7 q4 `2 o
(2)完成配置工程。
% n4 H. j/ T- g- \# ]: X备注:需要注意代码生成过程中的继承关系,如图所示:需要保留开发者自己编写的代码时,请根据配置设置,不然生成代码后会删除自己编写的代码(从这个方面也可以看出开发者备份自己的代码是多么的重要。)
* G3 f/ I( S& d* V! d4 l) l) N3 Q1 z* ~5 K
2 \( j6 f5 `+ a: @" D" P: |$ C( O' E' g; @
. L: J! k, x( ^, ~& T/ G2 G! q( z1 i3 G& e6 \+ Z% q+ k
(3)生成代码。3 L# I0 L- w$ L. E5 F
0 W+ @% e6 t) e L5 W* r' Y
' G& e9 I9 V$ }6 o
F0 k" w3 T0 m1 B# z4 Z. o6 J; B
三、在KEIL 5中编写代码
6 J( n( f% C c1、使用KEIL 5(MDK)打开项目工程文件
$ q, W' |% I" m; T3 F5 g+ |# y(1)找到刚才新建工程的存储路径,安装项目名称,打开项目工程。5 K/ A7 w6 L2 b7 W5 U
) r3 l9 ?2 J0 L" V. g
7 k) Z2 g6 ~3 J, a2 j9 p+ R
, J+ v" @) X, d6 ~* }- G3 `2、添加LED指示灯作为系统提示' Y m0 B3 J. d2 D
添加每隔500ms,LED1闪烁一次的系统提示,用于提示程序运行正常。
/ @+ Q3 u Z: d1 A0 X/ Y% b5 d4 K' p" o- n" W+ h+ g
" ^2 ~. I! z) C- }! c; L; E9 [1 t3 Y
# u0 x9 N; u7 d3 l) n/ `( L Z3、添加HAL库UART DMA 发送函数代码
) R2 I* Y; p1 ]& Z(1)STM32 HAL函数库的串口DMA相关函数如下:$ B& U, {8 I* Z0 h6 K$ ?/ ^
- HAL_UART_Transmit();串口发送数据,使用超时管理机制
2 c) I$ v& o% o u- t1 H - HAL_UART_Receive();串口接收数据,使用超时管理机制$ L0 Q# g9 v. O0 D
- HAL_UART_Transmit_IT();串口中断模式发送7 V o u$ ^1 r$ ~1 _2 }3 E: k
- HAL_UART_Receive_IT();串口中断模式接收) p+ k4 U1 N7 v! o/ f
- HAL_UART_Transmit_DMA();串口DMA模式发送
; O9 c6 f1 \* }1 ~0 J% H4 [ - HAL_UART_Transmit_DMA();串口DMA模式接收1 v2 M/ K. N' e: d' k) K P/ k) ?
- HAL_UART_DMAPause() 暂停串口DMA2 Q- W2 W5 i% V F5 R- I# G3 h2 {
- HAL_UART_DMAResume(); 恢复串口DMA; n0 T- z e9 z+ s$ m% o
- HAL_UART_DMAStop(); 结束串口DMA
复制代码 6 p& T: f% h: u. t% `1 {( Z
(2)添加串口DMA发送log代码:
2 N8 W. A$ ^, E7 {7 W3 h. @- /* USER CODE BEGIN WHILE */
: H% o$ E7 m4 H' `7 h3 h0 k - while (1)
: m: T: S( M% J$ f4 {4 _0 E6 l - {
8 B4 Q/ k, \: v% c) B$ Q - /* USER CODE END WHILE */
9 S' J- i9 m& i, I0 R; V, T -
$ |1 E. Q8 p& T. V2 K3 u l - /* USER CODE BEGIN 3 */
' v3 B5 x7 x+ [ C' c' N - HAL_Delay(500);
( b3 |4 R' R. s: W. q - HAL_GPIO_TogglePin(GPIOC,GPIO_PIN_0);//控制LED1闪烁
. d# J8 o2 B" \* e6 ^ - 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"));//发送提示
. N) K( S/ G9 }4 {! i7 S8 j1 S! ]7 Q - }: v/ M6 X8 r, y& H
- /* USER CODE END 3 */
复制代码
9 M0 ~" [1 N# X( w, } x2 w/ i4、添加HAL库UART DMA 接收函数代码1 h: A& Z1 Y& g7 Y4 }& B
(1)DMA接收设置前铺垫知识点:: z5 `& y( A8 x* w! P
STM32的IDLE的中断产生条件:在串口无数据接收的情况下,不会产生,当清除IDLE标志位后,必须有接收到第一个数据后,才开始触发,一但接收的数据断流,没有接收到数据,即产生IDLE中断停止。& b/ V ]4 Q* T/ z7 s: }! ^
& B1 T4 }, E/ Q% U( ~
(2)初始化中断接收配置:
* W" j; p1 i7 q' x# V: vuart.c添加代码如下:. k+ q- z: x. Q
-
2 b3 d. m5 w/ T0 j* U$ k - /* USER CODE BEGIN 0 */2 l3 v% b7 L O/ U! Q# C. m
- h8 F5 E5 ]$ K. q5 g7 R! B6 }
- volatile uint8_t rx_len=0; //接收一帧数据的长度
2 C, y7 I6 [, ^4 A) ^$ Q/ @7 k) i - volatile uint8_t recv_end_flag; //接收一帧数据结束的标志位+ ^9 x4 X4 ^. j6 g+ A1 N* G$ Z
- uint8_t rx_buffer[100]={0}; //接收一帧数据的数组大小! c7 O6 s8 ]3 ~4 F3 |
- /* USER CODE END 0 */
复制代码- /* USART1 init function */
3 _) \/ D; C% i+ P -
" F- a$ A+ E F& E: V4 o - void MX_USART1_UART_Init(void)
$ p, t1 v1 f0 a9 d7 K$ ^ - {
, j0 h6 ~. e" c. C( u5 a* H5 y -
. R7 W3 o7 w. p5 s7 z9 C - huart1.Instance = USART1;
9 f. W# f3 a. z1 ^9 B7 u5 h$ Z - huart1.Init.BaudRate = 115200;
( a* b* B3 h6 @3 V6 d - huart1.Init.WordLength = UART_WORDLENGTH_8B;' P. C+ O# Q' M2 R* N& w( |
- huart1.Init.StopBits = UART_STOPBITS_1;8 g P. q% \. `, s( k& E7 ]6 p1 i; @
- huart1.Init.Parity = UART_PARITY_NONE;9 V" o* ~' Y# n. p: n: u
- huart1.Init.Mode = UART_MODE_TX_RX;
9 k3 J D2 D7 U/ A" p0 d e - huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;/ N( ?# n% X5 D" |( V" P5 F6 r2 C
- huart1.Init.OverSampling = UART_OVERSAMPLING_16;
- v$ f w# S0 W* g - huart1.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
* `: M9 b) h! ^ - huart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
0 E; o! v- \7 e' G7 B$ }8 N: H - if (HAL_UART_Init(&huart1) != HAL_OK)8 t9 z0 p) t2 i5 n1 `8 b
- {; ^ J8 D8 s( V9 B" u
- Error_Handler();
: p5 u8 ?7 @% G9 O/ z - }! N* _7 S! h5 w: F3 z& @
- /* USER CODE BEGIN 2 */: R$ Q0 h+ U# [9 I: s" e3 s3 Z
- $ | ?8 Y7 Q5 g! A
- __HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE); //使能IDLE中断
4 B/ H# f5 t/ P9 V$ z4 F - HAL_UART_Receive_DMA(&huart1,rx_buffer,BUFFER_SIZE); //DMA接收函数
2 F: k" f. g" q8 c3 D -
% ]( G1 p* f+ |% X, K. Y - /* USER CODE END 2 */
0 _" z/ t; p" ]+ F3 v - ' j b. Q9 }' z1 M, q; {) C& h
- - u2 g2 @0 E. t9 e v" d( z" Z
- }
复制代码
8 s; v7 p2 Z1 k$ `: {uart.h添加代码如下: W! q4 r# a0 j; S! P0 |
- /* USER CODE BEGIN Private defines */
9 E: m" o: Q( Y - extern UART_HandleTypeDef huart1;
- V2 e. ~) U+ Z% i1 U/ J: [ - extern DMA_HandleTypeDef hdma_usart1_rx;: W& _, y' f& P" |6 o/ C
- extern DMA_HandleTypeDef hdma_usart1_tx;
5 M( m, K9 U7 |) K5 O8 H -
- ?$ g/ U& f4 f% A - #define BUFFER_SIZE 100
) {- q2 V$ m) y' ~0 ]8 X - extern volatile uint8_t rx_len ; //接收数据的长度& J+ \9 u; k% a ]2 m' [5 N
- extern volatile uint8_t recv_end_flag; //接收数据完成标志位% }5 D! q) {2 m, {1 F5 j+ o
- extern uint8_t rx_buffer[100]; //接收数据存放数组
a7 W" }8 R7 O$ T -
9 s' L% H- V0 \2 `7 \: h! i - /* USER CODE END Private defines */
复制代码
, d! p* b4 b- `6 ?) ^0 xmain.c添加代码如下:
% N! ~4 ^4 f) E8 p( \- /* Private includes ----------------------------------------------------------*/) `+ n3 ^! _9 _9 u- {/ L* S5 M( @
- /* USER CODE BEGIN Includes */
5 m; q$ I$ K+ U1 W7 P" J) i4 v# P - #include<string.h> //添加字符串头文件
0 q0 ^7 B- |& T3 |, O - /* USER CODE END Includes */3 q! i2 k; n7 X# O0 o2 P
- /* USER CODE BEGIN 0 */; C, g4 Q/ b6 l8 |, X% u
- /*******************************************8 y2 D( F# {) F# t" M0 L$ t. Q
- *函数名:DMA_Usart_Send
. j; R5 I7 o1 y: c$ w% O - *功能说明: 串口发送功能函数
+ {( F& o4 K# g8 K% H6 `4 a1 X - *形 参: buf,len
; ~. I Y3 z3 K9 V6 i - *返 回 值: 无
- c* H* M' [/ x5 H; ^ - ********************************************/- x5 Q X `$ y, D" K0 `
- void DMA_Usart_Send(uint8_t *buf,uint8_t len)
* Y; u% u( D6 t* X4 D; `8 F - {
W4 p4 k3 A6 |/ A - if(HAL_UART_Transmit_DMA(&huart1, buf,len)!= HAL_OK) //判断是否发送正常,如果出现异常则进入异常中断函数
) ^3 S$ l: N; i7 O5 \, c2 C - {
5 |- G3 i" Y, {% q) |8 Y! h - Error_Handler(); //异常提醒
* G/ S" t+ f0 S2 X5 u* q% r - }
) u+ {4 K( @$ O. ~+ [8 T2 q - }6 u& W; M0 R0 p: l2 L3 i/ D3 }
- /*******************************************
9 |4 t8 R1 ?7 a2 z - * 函 数 名: DMA_Usart1_Read- S3 c% x, J6 E; n$ H7 g
- * 功能说明: 串口接收功能函数
9 q% I7 ~8 P% c! h; \3 c% }/ k. x7 p - * 形 参: Data,len
3 S: k, ^, _! ]# B7 |2 H - * 返 回 值: 无
1 |" w. t8 l' f6 x# q - ********************************************/
8 t9 \1 E- X# q( Q5 H, d% j, D. u! U - void DMA_Usart1_Read(uint8_t *Data,uint8_t len)+ h# x; C! ]1 ^
- {6 W8 Z4 P# a% h* i) }
- HAL_UART_Receive_DMA(&huart1,Data,len); //重新打开DMA接收3 O0 r% {" `1 Y( \/ E# d4 K9 J
- }
( i- I8 ?: {3 g( h/ i - /* USER CODE END 0 */
复制代码
/ Y* d) q# M5 V7 {( qmain.c while(1)循环中添加代码如下:% Z( |7 W% y/ d6 b d
- /* Infinite loop */
R4 n' B9 Z2 N' t2 U+ P - /* USER CODE BEGIN WHILE */" U8 C4 S$ K; M/ E3 b1 q7 W
- while (1)
/ [+ R# ]% U% I" \' j) L: u - {
1 v( n/ W: t8 M5 w6 d - /* USER CODE END WHILE */
7 E' o- e$ C# P. A# g% i+ W( ^7 P$ l -
2 G0 t+ o6 @! H* E6 g( [ - /* USER CODE BEGIN 3 */ V# |9 Y0 z6 N
-
3 d) R3 |6 ^( t! ~4 V" X+ j/ O - if(recv_end_flag == 1) //接收完成标志,如果串口有数据接收,则执行该部分
3 |( g! L* z% U% V( m) S - {+ K" m, \7 T: `" y! H% P2 E
- DMA_Usart_Send(rx_buffer, rx_len);4 Q9 i2 m+ @& Q* F! [
- HAL_Delay(200);
( U) |( d( K5 k - DMA_Usart_Send((uint8_t *)"\r\n", sizeof((uint8_t *)"\r\n")); / R* g" N- }, ~4 e) G2 Q5 W1 `9 s. g4 x
- rx_len = 0; //清除计数
/ p: J! }" A1 p$ x. q. P3 Z1 o& l - recv_end_flag = 0; //清除接收结束标志位
5 O" N: }( `; y3 ^) b# q8 I8 z1 C) n - memset(rx_buffer,0,rx_len);7 R8 ^1 b1 d0 a7 g) ~: p4 X# s) w
- }
* A o3 j5 L. `+ e$ s5 W/ h8 I - else //如果外部没有数据,则执行该部分5 N% }* c/ t. b3 Q
- {
% D" U6 [9 o) g/ K2 s$ x - 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"));
- V% m" c. H3 h/ T/ N5 j9 m! S' e' e - HAL_GPIO_TogglePin(GPIOC,GPIO_PIN_0); //控制LED1闪烁
5 |# _" f6 d% s3 g N$ @% h; r - HAL_Delay(500);1 T7 ?* F; ?2 C: d- P
- }. ?1 h# {! |& \4 n# c
- HAL_UART_Receive_DMA(&huart1,rx_buffer,BUFFER_SIZE); //重新打开DMA接收 5 I1 W, m- p8 H
- }" W2 w: Y7 J& R- F+ W4 m) _! j
- /* USER CODE END 3 */
复制代码
1 M3 B) q% x( H2 N4 wstm32f1xx_it.c中添加代码如下:+ m% f2 l' m7 L+ u0 _) f4 x4 k
- /* Private typedef -----------------------------------------------------------*/4 V6 X# j* l# L5 T6 J' {3 S
- /* USER CODE BEGIN TD */! Q" T" A; ?) [
- #include "usart.h"
9 B. w9 f- V4 |6 K( C - /* USER CODE END TD */; v. O1 s- N9 x- I/ @ c
- % A9 h; W2 c4 |3 ?; D8 D& L& q0 U
- /**
+ t, U l5 B; F1 R; d+ R - * @brief This function handles USART1 global interrupt.
3 c8 O5 g+ v6 I8 [2 \5 y - */
' C; g$ \: [; K% i2 x6 h - void USART1_IRQHandler(void)5 A2 F N w3 z7 ]) r. c/ B& l+ P
- {
5 X' n$ u6 U% B; k - /* USER CODE BEGIN USART1_IRQn 0 */, @) C/ j$ `' E. H1 X
- uint32_t tmp_flag = 0;
+ J- d3 g P6 e i' y+ t - uint32_t temp;% {9 s8 N4 K5 n- Y6 ?0 K
- tmp_flag =__HAL_UART_GET_FLAG(&huart1,UART_FLAG_IDLE); //获取IDLE标志位" y; G, A. e' k& C
- if((tmp_flag != RESET)) //idle标志被置位
/ g6 F' F* i/ ^5 B8 ^8 G - { 6 o, g4 [4 p% ~9 m
- __HAL_UART_CLEAR_IDLEFLAG(&huart1); //清除标志位& x y& E1 u, |- c6 ?
- HAL_UART_DMAStop(&huart1); / S$ R* ?9 t- r: b; f
- temp = __HAL_DMA_GET_COUNTER(&hdma_usart1_rx); // 获取DMA中未传输的数据个数
, f7 q7 G4 A; V* _ - rx_len = BUFFER_SIZE - temp; //总计数减去未传输的数据个数,得到已经接收的数据个数
0 ?& M1 y' \3 g9 Q& e - recv_end_flag = 1; // 接受完成标志位置1
+ M% x q4 [ e7 _+ B$ P. H - }
# m" u) V, h* S& h2 f - /* USER CODE END USART1_IRQn 0 */
6 y# \6 Q* A/ n2 a( ^5 p - HAL_UART_IRQHandler(&huart1);* C# r, Q* C6 M3 e! c4 G! R
- /* USER CODE BEGIN USART1_IRQn 1 */
" |4 ^+ h/ `( R2 n& s - 2 q* W, k3 ]- N
- /* USER CODE END USART1_IRQn 1 */, G- v* R; ^3 q
- }
复制代码 % g1 F# D# \& C: X) {. x5 ^
(3)至此,串口DMA收发数据需要添加的代码已经完成。
5 X- P, ~/ O0 ~; B
# S' h+ j1 G' ^) n& k% ]2 o" ` 5、设置编程仿真下载模式 c" X$ Q7 r- d8 F c7 x
(1)选择Options for target ...>>Debug>>J-Link/J-JTRACE Cortex,点击Settings>>选择Port(SW),可以看到搜索成功SW Device,表示芯片可用,可以下载。
0 @ A1 U5 O1 F
3 R* S* u; P. _ L
- Q5 v2 T% _+ N$ @' F; c/ U, p
/ g2 }1 V8 @% Y1 J) u
(2)点击编译,完成后提示“0 error(s),0 warning(s)”。
0 |8 {) X9 ~$ t) Q7 g) r7 n& A1 k5 N* K. m& s
8 T. l! K2 Q/ x# C! x
8 k/ A( @: e |! b2 t5 d5 N! w' @% |) V* I(3)点击Download(或者快捷键F8),即可下载程序。2 s$ \ A7 h E# R% r
& Y/ q- \# W( D0 l
4 Z( g$ o8 N% u) t* X% F' E# E
4 C w, A5 ?* d8 [) K2 ]9 w(3) 如果下载程序后,没有看到LED1灯闪烁,可以按下述方式设置一下(Reset and run表示下载后自动复位和重启运行)。或者重新彻底断电再次上电(或按开发板的Reset按键复位MCU即可)。' Y5 @2 d4 w1 B, W L! Y
& n: |7 ^0 t1 h, q' ~9 z9 @, }
4 j, \; B) e) i6 Y
, y2 a) `5 z0 B/ p3 t1 l# f% T/ Z4、查看串口发送函数打印log效果
$ [, n7 C$ k) ]" r7 j(1)设置串口助手参数为:115200、NONE、8、 1(和代码中串口初始化参数一致)。
% J' n2 l2 Y9 Y% s9 ? [0 L: A
& n' T8 U( [$ W( U5 M(2)设置成功后,就可以看到串口打印的效果。如果串口助手没有发送给MCU的数据,则MCU每隔500ms闪烁LED1指示灯一次,且串口输出一个log。
7 W+ ~" k# q) | `6 I' f
7 s& D6 [# y: f0 ^(3)如果串口助手往MCU发送数据,MCU把接收到的数据发送到串口助手进行打印显示。! {, X; C5 @$ d1 n; N
/ W7 Y1 P6 l5 L* ?
. U, Y7 ~) t- ?' Y, w: e' e( M/ Q. p; V% { \
————————————————
) l# L0 b& e( R5 e5 y版权声明:智能小屋ZYXC1 D; i3 ?& r' [
( }) P7 }1 r' P+ A g: } e+ n4 o- m3 a$ v
|