一、开发板平台简介:' W9 V/ V9 K- Q3 ~/ h+ i4 Q- w
1、开发板资源简介
* C/ s% g7 g; n* {8 ~! K(1)开发板主芯片型号:STM32L431RCT65 L. M. t* t5 `0 w7 h: N0 e. d
(2)开发板主芯片封装:LQFP-64_10x10x05P
$ p) b. k; A6 q, l! a(3)开发板主芯片内核:ARM® Cortex®-M4
+ h1 S1 ]% T+ J5 j4 n(4)开发板主芯片主频:80MHz
5 L4 B1 r @0 t$ o(5)开发板主芯片Flash大小:256KB3 d7 e( @; ?! L& v+ H; G4 P3 H
(6)开发板主芯片RAM大小:64KB
) u; W$ G4 |$ g( T' B
; l$ p5 {5 p9 w
( X3 [1 U) Y5 O4 P5 @( K! v% s% Z) H5 z
# E2 l [9 q" D `5 y! |4 ]" }
" ?, p. f0 x- U9 c, y8 g: z' S9 P
2、LED灯资源7 S2 ?" z8 N1 F$ I; F9 J
(1) STM32L431RCT6开发板共5个LED灯资源,其中一个红色LED为系统指示灯,指示开发板供电系统是否正常,如供电系统正常,红色LED为上电常亮状态,硬件原理图如下图所示:
" t5 S8 S, o! K& P7 k
& e$ P* M" M* W1 j4 n
) k, \, v6 g% T4 Y) [
6 \. q n. ^0 Y, N: k- X8 x4 p; n1 s
8 E/ t6 f+ p( w
(2)其他四个LED灯为黄绿色可控LED,高电平点亮、低电平熄灭,计划用LED常亮验证看门狗的作用,硬件原理图如下图所示:
/ T6 F1 o3 h/ C3 ~/ ]! ?! a' m' g) f
! ?; X. V- j0 a
0 ?4 `0 k2 ^& Y$ {3、串口DMA收发工作原理) e9 p9 I n0 O! M
串口全称为串行通讯接口,即数据在通信线上一次传输一位,按先后一定顺序传输。我们通常所说的单片机串口准确来说应该是串行异步收发传输器(Universal Asynchronous Receiver/Transmitter,UART),使用TTL电平,串口需要RXD、TXD、GND三根线进行通信。# s8 D6 c X2 W9 z
- S) {8 k1 O3 P5 q
(1)我们选用的STM32L431RCT6开发板串口1已通过USB转TLL串口芯片CH340G引出,使用时,只需要用公对公USB线连接电脑即可(注意也得需要安装CH340G驱动),后期验证试验也可使用该串口作为debug串口。* D _( P& B7 G6 x+ d
' X4 p, ~! o$ P2 \3 B2 k( u& s (2)开发板上的其他串口已通过排针引出,为TTL电平,通信的时候需要注意选择对应的电平模块,如USB转TTL串口模块等。
1 h+ U- U; p/ p+ b5 h. [* a# e& I4 l' W
TTL转CH340串口,硬件原理图如下所示:2 v- Q. `$ J' `( @* E
* X; D' N- L, A5 m7 o
: ]4 W# O5 t6 C
5 C' V. u9 @- u; h* I2 y: aDMA(Direct Memory Access) :直接存储器存取,是单片机的一个外设,它的主要功能是用来搬数据,但是不需要占用 CPU,即在传输数据的时候, CPU 可以干其他的事情,好像是多线程一样。数据传输支持从外设到存储器或者存储器到存储器,这里的存储器可以是 SRAM 或者是 FLASH。
. h2 q4 l: K# P5 Y1 }4 s6 y3 L+ Y- c
DMA 控制器包含了 DMA1 和 DMA2,其中 DMA1 有 7 个通道, DMA2 有 5 个通道,这里的通道可以理解为传输数据的一种管道。要注意的是 DMA2 只存在于大容量的单片机中。/ j" i5 F0 `, h$ {
) g; K5 c8 p) Q
7 c! a0 d+ q5 f/ o0 y. H6 h
: b2 L2 k7 m, h. \8 W 二、串口DMA收发实验过程5 C1 X* ]8 r. W* t
1、新建STM32CubeMX基础工程! Q$ o6 a" W, t5 a! q3 a/ D% b3 O
(1)打开STM32CubeMX,点击“File”-->"New Project"
# }& ^* Y4 |0 [; |
& u/ ?3 ~& J) R9 [* G3 `! ?
: _7 i( W6 h0 b" a& i* W
2 W( d( `( [9 k7 ~! y(2)等待打开主芯片选项界面(大约1分钟时间)。0 z/ G* Y% [4 n B- n' V
! V2 r% X6 ` {# S: H: L: u/ U3 o
# ` T p1 v3 {% f+ u" V+ r t& _
$ o, x2 D% ^) \1 q0 p( V8 i
(3)昨天搜索框中输入(或选择)所需的主芯片型号(因为我们用的是STM32L431RCT6开发板,所以此处选择STM32L431RC),然后在右下角选择STM32L431RCTx(因为开发板主芯片是STM32L431RCT6),左键双击即可打开新建的项目。
& i/ i7 x5 `7 r1 B+ K/ l1 R0 _! O' L
; e0 @" a' E4 o6 x) h: p" i- V
2 @3 _7 B" ?9 X/ R$ v
( F, Q+ e2 ~ l0 U! N/ n0 {& p) O! u
(4)选择时钟源。! ]; z! U( V( e
6 T4 J& _7 S3 p. ^& s2 y 因为开发板上有8M外部时钟,硬件原理图如下所示,所以此处选择使用外部高速时钟(HSE)。, \- M8 t' x( _3 u
# x7 F3 D: `8 t. O2 R" N1 v/ D
w0 n3 B' @% @
4 s6 y( B) i8 x
+ ]: D+ L/ i+ O 因为我们没有用到外部低速时钟(LSE),此处不做处理,如下图所示。% k$ \1 n% w: Y: V
' ?* s6 ~2 W! i
. u1 z7 i9 I0 ?; o; `0 U) \
( B5 h5 s: M) T$ V7 J+ n8 C c
2、配置GPIO控制LED8 T# u$ L3 _: K% `9 _: F
(1)查开发板原理图得,LED1、LED2、LED3、LED4的控制引脚分别为:; R; I7 U6 f( R$ [( F" b( {, q1 C
LED1——PC0 ]2 U# S' q+ I& O+ n5 z
LED2——PC1
8 M, r8 V7 J! r0 RLED3——PC2
+ l- P% u# Y* O8 ]/ NLED4——PC3 G5 V0 p7 F! O/ w
# U3 n! f% B6 x* N(2)配置LED的控制引脚为输出,输出频率、输出方式默认即可。: h+ ?& |* K7 D6 z
0 B$ s8 r( o4 _5 ~" u
鼠标左键点击PC0,选择“GPIO_Output”,表示设置该引脚为输出模式* ~+ z+ n* p! j2 J
鼠标左键点击PC1,选择“GPIO_Output”,表示设置该引脚为输出模式。$ d. `: W- I- g
鼠标左键点击PC2,选择“GPIO_Output”,表示设置该引脚为输出模式。2 T7 H' Y% R$ P; \1 y1 G
鼠标左键点击PC3,选择“GPIO_Output”,表示设置该引脚为输出模式。
5 p' M4 M5 t: R# a* {$ c3 G# W# D3 b% o0 e/ t
3 Q5 i9 V7 B' g; B" e4 k- V) r
( e' L j! }+ Q& l- ?( B n
$ c3 k( U' D& k+ I7 }/ N1 ~. L; A; c- M9 R' ~
(3)也根据自己的需求配置GPIO的参数,如输出方式、输出频率、上拉下拉等。因为GPIO控制LED的要求比较低,此处采用默认参数即可,不用修改。
9 v# ]/ X; o9 E/ g+ x' r
/ {% L' O0 `2 E, o; @4 Q
4 C8 T; f4 N% ~; A
/ _3 }* r& H8 x4 P$ T+ d4 p3、配置PA9、PA10为串口1 a" L; K1 m+ N! i
(1)查原理图得知,串口1使用STM32L431RCT6引脚为PA9-USART1_TX,PA10-USART1_RX,引脚设置如下:
% u7 o; D( X# S4 i. |; q
- f7 M% k V' o' C4 o
4 K$ }7 j: K7 ?& b2 {. \& Z, P
& E5 x" S( D" _, u' W, ~- L 序号1用来设置串口收发引脚的选择。
8 n5 }0 _* Z- n: D: |, o序号2-3-4-5-6设置串口参数,如波特率115200、8位、NONE无奇偶校验等。
4 ^8 f9 j5 N; H. ?( H8 `+ u9 D
( ], A7 T) H/ L' c7 Y+ G(2)设置NVIC settings 使能接收中断
% D& K0 ~; \4 g0 n1 F# q- B; u
2 `8 m" Z; v: |4 Q! `( n
: p% c# P7 g! B) J8 f& n4 y; \" d8 _7 E) @5 P! d0 A. h2 N
3、串口DMA设置 1 r) U, w" r5 \- }3 o
* E {) T4 z+ U2 x2 S, A3 K
4 O& ~" T% [) S H8 z% I, }
E- ~. V) ?; Z& V5 e( h
(1)根据DMA1通道预览可以得出,我们用的串口1的TX、RX分别为通道4、通道5:, z" Q6 V7 n4 {
点击DMASettings 点击 Add 添加通道
' A' H6 U( @6 @: s$ O- |选择USART_RX USART_TX 传输速率设置为中速; O8 l1 h* Q4 W! w
DMA传输模式为正常模式,即发送一次就结束。, c! S& `5 P$ J3 s3 W
DMA内存地址自增,每次增加一个Byte(字节)
+ o0 `) J0 b; Q9 D: b2 ?
! n6 E9 v/ u P1 f6 @+ S
" I! V: C8 |2 ^* B+ U: F k: \
9 { ]7 V/ [7 l! G& o8 X
(2)DMA相关参数解析- O, G% C- m! L4 h: H& o, k" Z0 [
Dirction : DMA传输方向有四类
! G- ]! N- I7 Q" g0 e- T' j外设到内存 Peripheral To Memory
( H- L. x' F8 R n0 C# S1 g! w, f7 M/ K内存到外设 Memory To Peripheral
2 G! i) k2 E1 U/ ? g) r7 E内存到内存 Memory To Memory8 [5 @$ E1 E# y. v3 n, V
外设到外设 Peripheral To Peripheral
% u7 {& N/ e" E, K2 O& r$ g, j: z w5 f9 ?
Priority: DMA通信传输速度有四类
- J- \- s% d( ~# `9 K5 l最高优先级 Very Hight" z2 N% \+ }# b& @5 S" d
高优先级 Hight8 |5 T6 V. W' [$ D- k' Y
中等优先级 Medium
8 R" W5 a9 ?# u低优先级;Low: q" X2 L) {! B: S
1 S, k! R& y, T! t. q8 |3 m
Mode:DMA传输模式有两类
6 X8 }7 N4 S' q9 u: b5 D6 i) _
1 z, W% O/ \8 u/ e
/ y8 Y5 x6 v( i3 k: m$ Z7 f# c8 A3 V% U& ^, i
Normal正常模式:当一次DMA数据传输完后,停止DMA传送 ,也就是只传输一次。$ I6 Z' I" j* @" C
Circle循环模式:传输完成后又重新开始继续传输,不断循环永不停止。+ x5 k) e! |* ?: G9 ?
/ }/ N6 P$ `/ p$ h9 N
Increment Address-DMA指针递增设置:
+ M9 q0 a. t4 U8 p% E
/ X% N% l+ T0 B0 |+ N: s8 [, h
/ u& V2 e& m( A7 e# ~. k% R+ t: A
; W' D D4 Q* M# B
: x/ c. m6 ~0 `4 ~0 s. ^: U5 N4、配置项目工程参数9 l) O# M0 K5 o
(1)配置时钟树,用于系统内部时钟,以及各个外设时钟等。此处选择外部8M晶振作为主时钟频率,内部最大倍频80MHz。
6 u7 d! ]- u& ^- E( y% E' X
/ J! x5 U% A3 P; x0 D- S4 b
" E |1 l# N: J" b) B5 Q9 G C# J- g
7 u8 E! l. j# \- V* d% ^
(2)完成配置工程。
5 U! n$ Q1 Y, T4 }备注:需要注意代码生成过程中的继承关系,如图所示:需要保留开发者自己编写的代码时,请根据配置设置,不然生成代码后会删除自己编写的代码(从这个方面也可以看出开发者备份自己的代码是多么的重要。)* @# r L' t5 \5 g- k
! `; M/ a; U- [- V& ^( [1 H
( E9 X5 t5 l5 C4 m" I
/ a+ [1 O4 y; Q# A/ Q- b- f/ S
# }& V) k5 M0 l6 c# ~' J0 @2 B
3 {" T) m7 p% O( P5 ~(3)生成代码。; N0 @4 i: Y, ?& e. Z7 R
) _ b# a/ O7 @" Z: f' ~, B$ r
备注:使用Generate CODE生成工程代码前,请确保文件路径无中文,否则会生成项目失败。# |# a" t( P0 F, l* h
' C1 k9 i( Z$ S
: l5 R. ?5 ^, @! i% y) r( w* w. `8 K, R9 {
(4)工程代码生成成功。
e7 W) {' c1 j& ?) U2 n
% f: X3 L6 c5 _- e- P) V& d
5 t# S; Z% y6 x9 I: J
/ U" h- i& h$ ~4 O4 B! T 三、在KEIL 5中编写代码) r3 B- G: q! O- e) K, z
1、使用KEIL 5(MDK)打开项目工程文件
q0 w- g9 ^0 r1 {5 ]0 R, V- J源码使用说明:使用前必须把项目工程复制到无中文路径的文件夹下使用。
8 R s, ^6 |; ^! H. J1 O(1)找到刚才新建工程的存储路径,安装项目名称,打开项目工程.uvprojx。! V: D% m1 s3 B3 t- \5 }$ j. Q5 j
3 L4 S$ T6 f* [" m
5 O! ? B: f+ f: i
3 f" S3 n/ ]) {, _, M$ E
2、添加LED指示灯作为系统提示
) f5 K8 g# T1 P/ c Y, q3 _添加每隔100ms,LED1、LED2、LED3、LED4闪烁一次的系统提示,用于提示程序运行正常。
$ c3 f+ ^! F" Q. b% ~9 E3 E8 X
0 M+ Q5 Z6 ?; t: j( s3 _
F) }9 {5 K2 H( E- Y
% @. _2 _& B8 M, h% y( B3、添加HAL库UART DMA 发送函数代码
/ A4 o& E- r$ U% v# ~% [(1)STM32 HAL函数库的串口DMA相关函数如下:. Z( o, b# j8 E3 L
- HAL_UART_Transmit();串口发送数据,使用超时管理机制
+ c C9 }6 b$ w) {) W9 P - HAL_UART_Receive();串口接收数据,使用超时管理机制; ?: ?' X& A- ]( N$ G0 ]
- HAL_UART_Transmit_IT();串口中断模式发送
" ~ E4 V" B+ H/ e - HAL_UART_Receive_IT();串口中断模式接收
4 t7 z; ~& d& } - HAL_UART_Transmit_DMA();串口DMA模式发送
: C, e, G1 M: L - HAL_UART_Transmit_DMA();串口DMA模式接收
' P! }" f& d. S- Y' Y* g - HAL_UART_DMAPause() 暂停串口DMA
$ d/ T# V& u" z/ k$ N# b% Z/ o - HAL_UART_DMAResume(); 恢复串口DMA1 L* G' [* ]% G0 y- {8 Q2 ?
- HAL_UART_DMAStop(); 结束串口DMA
复制代码
% d* q- S" o, S(2)main.c添加串口DMA发送函数相关代码:0 Z, [0 Y( A1 p7 J5 F# M+ Z
- /* Private user code ---------------------------------------------------------*/6 X9 `) K# G& d1 q7 C n/ H
- /* USER CODE BEGIN 0 */
/ J) }1 g+ h; ^( R- d - uart_rx_struct uart_rx_struct_t={0}; //串口接收数组
* t9 x$ x9 R, K2 c6 n - /* USER CODE END 0 */
复制代码- int main(void); w9 x' q% ~; ~. m2 n; Y0 W$ Z
- {7 d4 w$ q4 `7 c4 B
- /* USER CODE BEGIN 1 */
_0 x, D4 S3 b, B% ? - uint8_t transmit_str[50]= {"hello world,this is uart dma function!\r\n"};
( I' ]9 i) Q$ U6 l, K5 |' U - /* USER CODE END 1 */
3 M& c+ Y( c' ~" N - . Q& G8 V! F7 `# i2 g- L
- /* MCU Configuration--------------------------------------------------------*/" o' M( {$ q( w8 u. R
- 3 x- w; h: _: r7 Q
- /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
6 a1 E. U. m3 t3 t K8 p# b - HAL_Init();! c0 K1 }2 ^( {3 F8 r
- / G3 u2 U$ p$ C' q4 Q! ~
- /* USER CODE BEGIN Init */
4 y8 L' z# ]6 P1 X) O - & O! N! y5 Q2 C4 Q
- /* USER CODE END Init */
; j6 n% w2 \6 x4 G! [5 G9 j5 U7 h -
: i {: F {' Q8 ]0 l% k. Q; H/ u - /* Configure the system clock */
# [7 M; o. Y9 u! O' [ - SystemClock_Config();
4 j' b$ _- F+ d2 }& m% d& A% f - " B5 ^6 T" ^- e' ~$ Z
- /* USER CODE BEGIN SysInit */
1 I0 V7 d f \' o# f -
) X- k1 ~+ P6 Z& l - /* USER CODE END SysInit */3 s# P" O8 B6 M5 w: S$ {) [! T) X& w
- , E0 m8 W p) y4 O' @9 y
- /* Initialize all configured peripherals */% w" w! c" q" g# N C
- MX_GPIO_Init();
$ n# I. |8 L" H# x. m% [; D - MX_DMA_Init();) P! ]6 {# U! F2 G, x, e/ B7 I& S
- MX_USART1_UART_Init();
) O; R7 g- O& u ]* g - /* USER CODE BEGIN 2 */
) ] V: |0 \* w: n! o# `, M - HAL_GPIO_WritePin(GPIOC,GPIO_PIN_0,GPIO_PIN_SET); //初始化LED灯,默认点亮
& C0 ?+ R' G( i o4 D; A - HAL_GPIO_WritePin(GPIOC,GPIO_PIN_1,GPIO_PIN_SET); //初始化LED灯,默认点亮
E, K# l3 L5 y1 a, `2 p - HAL_GPIO_WritePin(GPIOC,GPIO_PIN_2,GPIO_PIN_SET); //初始化LED灯,默认点亮
2 ~1 a2 ^- O" |6 ^- k+ M& o' i - HAL_GPIO_WritePin(GPIOC,GPIO_PIN_3,GPIO_PIN_SET); //初始化LED灯,默认点亮# S1 a* v" y+ B! n# \; u
- HAL_UART_Transmit_DMA(&huart1, (uint8_t*)transmit_str, sizeof(transmit_str)); // 1 c: E& o3 U6 f! X
- HAL_Delay(5);
2 [7 O& |7 |( R$ q- W3 i$ o - HAL_UART_Receive_DMA(&huart1, uart_rx_struct_t.uart_rx_buf, UART_RX_LEN); // 启动DMA接收
2 E- e% S$ }9 G7 R - __HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE); // 使能空闲中断
5 M" j1 w* I' y# V -
4 C3 m9 G! y0 J6 `5 ] - /* USER CODE END 2 */$ W C% `- W* }9 l. S0 ~, I8 a# V
- 2 t' e) K( m8 [" a* \" l% H: P
- /* Infinite loop */) b% x- M9 }" b' H7 T6 N
- /* USER CODE BEGIN WHILE */- P! g/ U2 ]- m, g! \; S
- while (1)7 @: f" f1 _$ D1 d5 N
- {1 ?/ h9 k$ e( R" U7 |
- /* USER CODE END WHILE */
" H5 G f- [3 [, m) d -
$ c" q+ [9 a0 b/ J. Q6 i* D9 `0 w, V - /* USER CODE BEGIN 3 */
) R3 F1 C7 z+ w$ N- x+ _5 r% A' x - HAL_Delay(100);
6 V- f- a( F" g - HAL_GPIO_TogglePin(GPIOC,GPIO_PIN_0); //反转LED点亮熄灭切换- g5 C( ~2 U9 c2 B
- HAL_GPIO_TogglePin(GPIOC,GPIO_PIN_1); //反转LED点亮熄灭切换: p- U9 m4 ^ p$ W; b$ [. B& U0 S
- HAL_GPIO_TogglePin(GPIOC,GPIO_PIN_2); //反转LED点亮熄灭切换( @5 |( T% i9 _) U, z8 s' b
- HAL_GPIO_TogglePin(GPIOC,GPIO_PIN_3); //反转LED点亮熄灭切换8 G+ V6 e$ N `) s6 C/ q2 ]6 G
- if(uart_rx_struct_t.uart_rx_flag & 0X80) //DMA接收完成6 b% M! f4 E. ]' C; J0 B4 ^
- {) s% z- I3 E+ m: ~. _$ W
- HAL_UART_Transmit_DMA(&huart1, uart_rx_struct_t.uart_rx_buf, uart_rx_struct_t.uart_len); // 将接收到的数据发送回去
0 k5 L0 R3 D8 Q/ \ - uart_rx_struct_t.uart_rx_flag = 0;' N, D% W X" R& `
- }2 a& d7 ~0 ~; P' H
-
3 J8 D& M9 D* r8 \4 c - }2 {( `# V& A: W* _1 |8 T6 u* G
- /* USER CODE END 3 */
9 O4 u4 N& t0 _1 u' J! X! I6 V - }
复制代码 ' n% m$ F- }+ x2 A6 T! U2 w
(3)main.h相关变量声明5 D' Y9 G3 S; K4 V, L
- /* USER CODE BEGIN ET */4 t- T! O1 [5 i9 i3 t
- #define UART_RX_LEN 1024 // 一次最大接收的数据量2 v& z' A0 Q" o- C7 M4 G
- typedef struct
8 J4 A4 R) N) P8 H1 C. p, B - {6 i% J" |4 @7 {2 y0 T
- uint8_t uart_rx_buf[UART_RX_LEN]; // DMA数据接收缓存数组 v' [; m3 I- \' Q _
- uint16_t uart_len; //DMA数据接收长度+ S$ x% P% \5 W+ z y* O4 o
- uint8_t uart_rx_flag; //接收完成标志位% S7 ~6 a U9 v# n/ ^& {
- }uart_rx_struct;
+ H; T" X5 w; n' [% T+ @ - extern uart_rx_struct uart_rx_struct_t;
! t! W4 R( H0 e: i) E: r4 c' T- i- A -
3 g! p6 C; F2 ?* _ - /* USER CODE END ET */
复制代码
. ^! D% [4 K: b5 k4 R( }! _$ q4、添加HAL库UART DMA 接收函数代码" l5 f1 k8 d4 v v$ k/ d K
(1)DMA接收设置前铺垫知识点:
0 u7 Y* u; Q$ J3 w STM32的IDLE的中断产生条件:在串口无数据接收的情况下,不会产生,当清除IDLE标志位后,必须有接收到第一个数据后,才开始触发,一但接收的数据断流,没有接收到数据,即产生IDLE中断停止。
k( H' t2 ~# y3 W% E9 U% N" r+ u! x/ a
(2)添加DMA接收处理代码3 [, D* H6 @: T$ w
- {/ M" p" {3 e$ _. y% nstm32f1xx_it.c中添加代码如下:
( w* _; \' U n A6 ?- void USART1_IRQHandler(void)
& Q- M, l1 ^# i% W' ? - {
" v V( i* p2 r+ b - /* USER CODE BEGIN USART1_IRQn 0 */
0 _4 [7 X. z3 W - if(__HAL_UART_GET_FLAG(&huart1, UART_FLAG_IDLE) != RESET) // 空闲中断标记被置位
) |2 @, U0 a# u0 e9 X4 j - {
4 q8 ?+ B) l% ^; M7 X8 T; g - __HAL_UART_CLEAR_IDLEFLAG(&huart1); // 清除中断标记
5 I+ ^3 R" k" i - HAL_UART_DMAStop(&huart1); // 停止DMA接收
+ l' Z4 o( A( k& g" U/ I - uart_rx_struct_t.uart_len = UART_RX_LEN - __HAL_DMA_GET_COUNTER(huart1.hdmarx); // 总数据量减去未接收到的数据量为已经接收到的数据量
0 R) e8 G6 H$ Z - uart_rx_struct_t.uart_rx_buf[uart_rx_struct_t.uart_len] = 0; // 添加结束符; e" x, |+ i9 Y/ v+ m* ?
- uart_rx_struct_t.uart_rx_flag |= 0x80; // 标记接收结束, ]' ?. t& h7 N/ g4 d- ~
- HAL_UART_Receive_DMA(&huart1, uart_rx_struct_t.uart_rx_buf, UART_RX_LEN); // 重新启动DMA接收
* H& |$ U9 z. W8 j: k, ]& _ - }
. Y V# x# N8 b: J+ [2 q - /* USER CODE END USART1_IRQn 0 */
: j# }7 a1 d1 M* l4 i7 M9 r2 `# h - HAL_UART_IRQHandler(&huart1);0 ]6 ^9 j% d: ]4 C. e4 j# K/ g
- /* USER CODE BEGIN USART1_IRQn 1 */
7 w* Y: l6 T7 F) ^7 V7 O -
% V0 y" I) v6 c! d8 T+ E% o8 ^ - /* USER CODE END USART1_IRQn 1 */
: \+ ~; p8 H* j) [2 s - }
复制代码 ! l6 d% o- Y( V/ K& P5 ]& d! V2 o. v
(3)至此,串口DMA收发数据需要添加的代码已经完成。
9 W$ u+ r1 c! F2 D% V7 W4 v% \
4 t) [ s# d# D" a) g5、设置编程仿真下载模式. R" m) `- D- ?" F- U8 I7 c" h
(1)选择Options for target ...>>Debug>>J-Link/J-JTRACE Cortex,点击Settings>>选择Port(SW),可以看到搜索成功SW Device,表示芯片可用,可以下载。; G" S) y U+ W) }0 y/ ~/ d
$ t* y& A* p0 @
# k8 ]5 t; e1 ~; T& n5 B! V& c7 A9 {! e5 X
(2)点击编译,完成后提示“0 error(s),0 warning(s)”。
1 t- F/ G8 ~" @( N$ h
/ X' B1 y$ l$ S- b, E" U' b
" B) ~- i1 Y9 ^: S2 h3 d' h% ]4 R4 X. Y7 U, O# M9 L) E8 ?
(3)点击Download(或者快捷键F8),即可下载程序。0 l2 T9 M$ ~; _
! ? _# t U9 x5 J- k
5 v! j$ F- g! `1 L/ ~
0 k/ y5 X$ n3 `% v8 F0 J8 y+ V& [% f& q! ^) \( j+ A
(4) 如果下载程序后,没有看到LED1、LED2、LED3、LED4闪烁,可以按下述方式设置一下(Reset and run表示下载后自动复位和重启运行)。或者重新彻底断电再次上电(或按开发板的Reset按键复位MCU即可)。8 A% v. h( i# w4 C4 I
* s7 C& j' p6 Y& d6 o+ X* t) X- s% a1 G. ?
9 q/ W; \3 A& {; R! h
6、串口DMA收发实验效果展示
6 I- b8 ]; M/ I$ ^ 程序烧录到开发板后,即可看到LED1、LED2、LED3、LED4初始化后每隔100ms闪烁一次,并且打开串口助手后(串口参数:波特率115200、N、8、1),通过串口助手可以看到,开发板接收到发送的数据转发出来。
+ ^0 e( T1 x+ F7 s
4 d- x# F, |+ G8 ~8 e# ]1 G- H
' o! y9 Z1 M' i: j0 }2 b
* p* r& j" f K' X+ B5 y. u& L————————————————4 s& S |! ]' K
版权声明:智能小屋ZYXC8 j3 g4 g) w6 l1 v" h/ _
3 x( a6 l" S+ f! y. E- d
) F$ X5 J, B1 i |