一、开发板平台简介:) [& L0 Z( L+ Y% H. c& i2 Z0 I. T
1、开发板资源简介8 ~2 U( q u3 [( ^0 h% u- q1 C& Q
(1)开发板主芯片型号:STM32L431RCT6
" Q/ `& E# _# [4 W7 O(2)开发板主芯片封装:LQFP-64_10x10x05P
5 M4 U' |/ e% U) [8 K3 Z c(3)开发板主芯片内核:ARM® Cortex®-M4
) E/ O" U: Q/ J(4)开发板主芯片主频:80MHz
; |+ g5 a# e* M(5)开发板主芯片Flash大小:256KB# u, S% Z: Y: i1 U5 n
(6)开发板主芯片RAM大小:64KB! ^: Q7 ]& n% J, V1 ]
: X* n4 E `; b+ T' H
. n9 |+ S2 u/ E6 _$ |' @6 ]# T- E( G5 R7 m0 C
: B5 n% x7 }5 Y1 G8 c
8 d+ |. N7 c! M- N8 q2、LED灯资源$ b1 Z0 f, W- Y* I: l
(1) STM32L431RCT6开发板共5个LED灯资源,其中一个红色LED为系统指示灯,指示开发板供电系统是否正常,如供电系统正常,红色LED为上电常亮状态,硬件原理图如下图所示:0 q! j8 f3 G1 u- l9 T
. |: t8 s" V1 b- _7 s% v; x0 h
$ K2 y/ y; n6 z! ^9 w+ Q/ G. T* S% F7 A* u" E0 ~+ s* z& q8 f
' S [+ } m9 N6 t
(2)其他四个LED灯为黄绿色可控LED,高电平点亮、低电平熄灭,计划用LED常亮验证看门狗的作用,硬件原理图如下图所示:
# B& V( |& _7 }- {9 @+ ?$ }7 A# a. B$ P
: o* E V9 e/ b7 e' |& @. u
$ c$ i; i& `. C- p5 G, v' `3、串口DMA收发工作原理
! {; X& R: ?& ?8 h1 M( f/ t6 R 串口全称为串行通讯接口,即数据在通信线上一次传输一位,按先后一定顺序传输。我们通常所说的单片机串口准确来说应该是串行异步收发传输器(Universal Asynchronous Receiver/Transmitter,UART),使用TTL电平,串口需要RXD、TXD、GND三根线进行通信。' h1 E: K$ R7 {0 {# D
# p# z6 M: \' @) c1 H# o
(1)我们选用的STM32L431RCT6开发板串口1已通过USB转TLL串口芯片CH340G引出,使用时,只需要用公对公USB线连接电脑即可(注意也得需要安装CH340G驱动),后期验证试验也可使用该串口作为debug串口。
* [2 `/ ]1 l- y* U6 j0 }0 B
, I0 q* h H0 g- y' `; `, ` (2)开发板上的其他串口已通过排针引出,为TTL电平,通信的时候需要注意选择对应的电平模块,如USB转TTL串口模块等。
$ c+ s, R" l& A5 }, T2 c6 i* u+ m+ @8 _: T" g7 {0 [
TTL转CH340串口,硬件原理图如下所示:! |$ Y: A3 P* G
! l$ q8 F! r& _. B
0 O1 l4 r9 x( r6 s0 H
+ |0 Y. e% |$ R3 [DMA(Direct Memory Access) :直接存储器存取,是单片机的一个外设,它的主要功能是用来搬数据,但是不需要占用 CPU,即在传输数据的时候, CPU 可以干其他的事情,好像是多线程一样。数据传输支持从外设到存储器或者存储器到存储器,这里的存储器可以是 SRAM 或者是 FLASH。& w6 r6 t3 C& M
# ~2 ^7 u& p" r1 S7 {
DMA 控制器包含了 DMA1 和 DMA2,其中 DMA1 有 7 个通道, DMA2 有 5 个通道,这里的通道可以理解为传输数据的一种管道。要注意的是 DMA2 只存在于大容量的单片机中。3 H" a0 l4 R- Y9 ]8 y
# S# K9 e" i% {2 a! P' Z/ z
5 i1 O4 ]1 e) v
1 n0 Z' L! N$ S4 W! Q/ M 二、串口DMA收发实验过程
+ o! Q8 ]; k* W- d9 R! f1、新建STM32CubeMX基础工程/ U; I0 N+ h: l+ z' i1 ]
(1)打开STM32CubeMX,点击“File”-->"New Project"
* ^9 _) k7 m- c1 f0 I& b7 v' P1 N7 J% t- }
/ x! a- c2 O8 G. x2 e" d6 R4 C0 K: u
7 T, P D# O$ d! q( j% E(2)等待打开主芯片选项界面(大约1分钟时间)。
2 i3 g8 x" O! z8 X
- a. ?. L" E0 t- I
& R; D7 O* z: j1 o7 A
% o7 j/ z( u' r9 k( @5 N(3)昨天搜索框中输入(或选择)所需的主芯片型号(因为我们用的是STM32L431RCT6开发板,所以此处选择STM32L431RC),然后在右下角选择STM32L431RCTx(因为开发板主芯片是STM32L431RCT6),左键双击即可打开新建的项目。. F) r. D, j' S' X& D8 `+ g
; X1 T9 x$ ~; F+ s; Z* a- m
, X/ p% C/ J B, g$ m& J3 p, H
7 {5 k/ ?. }2 I/ ?4 @. [(4)选择时钟源。
, A& d F: C1 E! ]6 p( @" ?( w
因为开发板上有8M外部时钟,硬件原理图如下所示,所以此处选择使用外部高速时钟(HSE)。2 u0 x2 m3 I$ J8 ?' G
' ?) w" l' H% ]! l$ o
; E: E) R; |: e! n8 q' s* T8 m) f) n2 J9 f% o) i I
" j$ C, X4 n" E; r( {; v% M
因为我们没有用到外部低速时钟(LSE),此处不做处理,如下图所示。1 z; l6 r6 Q6 O$ k5 J0 e! Z* M, ]2 ]
+ p3 q# U5 K; {0 ?/ k) u
; |" X$ d6 D$ a, g3 c: x/ z6 W7 J
8 B0 r, H5 d- e/ I2 w2、配置GPIO控制LED" _2 p" G" l5 O" z) d
(1)查开发板原理图得,LED1、LED2、LED3、LED4的控制引脚分别为:
8 a: t" X- t$ C. o# r" }& f: h* PLED1——PC0
. n8 [. X1 c3 j2 Q+ x4 sLED2——PC1
1 O( @* S. L1 C# J6 F4 `# b. ULED3——PC2
1 j# V* n9 {- {. {LED4——PC35 @. n. k- o( G& F; _
1 z6 [$ Y0 i/ W" f! u
(2)配置LED的控制引脚为输出,输出频率、输出方式默认即可。
5 i& e/ O: B/ `/ n& Y; V) h- g( V6 D& b s0 ^& ^
鼠标左键点击PC0,选择“GPIO_Output”,表示设置该引脚为输出模式
3 S: ~, R9 m6 Y# G" ~4 u& s鼠标左键点击PC1,选择“GPIO_Output”,表示设置该引脚为输出模式。
) \% Y4 c& m7 a9 s; Q$ j鼠标左键点击PC2,选择“GPIO_Output”,表示设置该引脚为输出模式。6 R4 a$ b! V3 ~2 v: u* a
鼠标左键点击PC3,选择“GPIO_Output”,表示设置该引脚为输出模式。( Z4 \+ b, P# @/ c% o
& E& ^) t$ H0 R) G: r9 w
% [& ^! c" t; ]3 h1 \
( A; K; e; v8 j. ?& s
* ]8 a7 U! P7 \5 c' X3 c
9 z5 D0 F5 i2 x+ o) O(3)也根据自己的需求配置GPIO的参数,如输出方式、输出频率、上拉下拉等。因为GPIO控制LED的要求比较低,此处采用默认参数即可,不用修改。2 r0 ^! _: y* S E; Z7 o. t8 m
2 h' z M& c' Z8 Z( u
/ j4 ?( K" [: `7 t" f! B# J# l# {4 D- K7 j
3、配置PA9、PA10为串口) i+ U: t0 _7 W6 j* }2 I: h2 q
(1)查原理图得知,串口1使用STM32L431RCT6引脚为PA9-USART1_TX,PA10-USART1_RX,引脚设置如下:% ~5 S& T% s4 \% C* U7 h) \6 \3 A
5 x# M7 |/ b0 v7 |0 H
% G$ a9 Q$ r- [3 i" I' m h& L
$ L( n c% N' F+ S( |
序号1用来设置串口收发引脚的选择。
1 a* P4 D7 x5 J! d' G序号2-3-4-5-6设置串口参数,如波特率115200、8位、NONE无奇偶校验等。. }3 y9 F/ S( t0 {
# Y- _% F) ]* \% Q6 B8 A8 T
(2)设置NVIC settings 使能接收中断
( E, K9 B$ g9 }7 H/ b* S
! k& e' c( U) ?7 [9 M% j
J1 |# ]- f/ U ^4 o/ b" o3 I6 f" A3 {
3、串口DMA设置 9 }. W% k' H4 o) A/ u
! j, F+ _; T3 }3 Y+ o
; [* C$ J, j: Y" Z7 y' J. W% n+ u$ K
(1)根据DMA1通道预览可以得出,我们用的串口1的TX、RX分别为通道4、通道5:) n# N( |& X3 |; d- A
点击DMASettings 点击 Add 添加通道! y. [& I* S% {' J7 w+ `
选择USART_RX USART_TX 传输速率设置为中速! s9 d, e. X' t3 n. X
DMA传输模式为正常模式,即发送一次就结束。* a! @6 d3 k- \
DMA内存地址自增,每次增加一个Byte(字节), d/ b+ {- Z0 L
. {+ B* t' h3 e ~ l
7 o0 z2 s+ h, q* M+ J& q" f' P$ J5 L# C; [/ S
(2)DMA相关参数解析6 E/ V a0 [0 @7 [& g' f( E1 G
Dirction : DMA传输方向有四类; m) `; J* F6 v. B
外设到内存 Peripheral To Memory1 @+ s$ e8 J* r: y8 x9 n( c
内存到外设 Memory To Peripheral8 H. f! B% j, S% M0 f9 V' J% o: u
内存到内存 Memory To Memory6 n' A9 q9 ^( \( _ L& f, F
外设到外设 Peripheral To Peripheral
2 O& n/ i6 ^) W7 |3 n @- z
" P% p" X, D0 v1 T2 \0 H0 gPriority: DMA通信传输速度有四类) p& k; k \. k
最高优先级 Very Hight3 X0 g; S) {8 S" ~+ L
高优先级 Hight
; Z+ [: \% P( v# S3 S中等优先级 Medium
2 `6 T y6 A s9 _' j0 @低优先级;Low" Z8 H2 M! ?1 ^3 S% a3 B G
! Y8 S1 A5 t" y" O9 a+ TMode:DMA传输模式有两类/ ?( b% s& u1 J, v' z. {# Q
, a) K, C; K9 T$ E
8 u; u: n* x$ F7 [- S1 J
0 L: x9 T* V- T e C1 d* {. [2 \$ X1 d
Normal正常模式:当一次DMA数据传输完后,停止DMA传送 ,也就是只传输一次。
8 X% {" V9 s( V1 T* k4 L: RCircle循环模式:传输完成后又重新开始继续传输,不断循环永不停止。
: H0 a' z; Y8 g& u0 c/ r9 }) a
4 Y+ J, G0 y' L& q$ C$ eIncrement Address-DMA指针递增设置:
, C- ?. R. q% _+ b) k' c, e4 W y7 c+ e* u0 j& v3 c4 ?
0 `6 U& `! h0 K; }; l7 I8 b& {0 S4 k6 c9 L1 h/ |( F( I
% E; y0 n" ?) V% w4、配置项目工程参数* C( r+ i/ W1 `5 F
(1)配置时钟树,用于系统内部时钟,以及各个外设时钟等。此处选择外部8M晶振作为主时钟频率,内部最大倍频80MHz。
8 S8 C# F% a9 J8 W, Y" Z! L8 p4 ~7 V- J, z% X6 _' ^
* {1 ^! O$ {2 X9 v/ z" E7 b
% P( U. v8 v b* t" [* M: a' i(2)完成配置工程。
) x; b0 D4 ^% z# v7 g. i- ~备注:需要注意代码生成过程中的继承关系,如图所示:需要保留开发者自己编写的代码时,请根据配置设置,不然生成代码后会删除自己编写的代码(从这个方面也可以看出开发者备份自己的代码是多么的重要。): o" S P: D* |- R! _/ \ o8 ^. Y
5 k$ K( g! j. U* w3 P1 \: m. k
7 z5 ^7 v3 ^! t$ z: B# {; O8 h1 I9 W+ }1 X: G/ s
4 w+ ]0 T* b% I( O
2 {; Z1 r: d; R5 a R# n(3)生成代码。
7 l4 U0 [) |! l! L; G u8 \# G) `- x
备注:使用Generate CODE生成工程代码前,请确保文件路径无中文,否则会生成项目失败。
! i+ f- I4 n& O" u: r, ~
3 x o) @4 c, e! ]
7 i/ t. _: q) w$ q* g4 M" D, g/ Z) I% ^$ \( u, N$ d
(4)工程代码生成成功。0 Y5 M1 r% G. G0 G
9 l. V& W) k: _; W; O7 z
/ m) y9 S8 e3 s9 m% h, k1 g0 P( z7 D0 J) V
三、在KEIL 5中编写代码
" |" g) {- V+ f; W2 W# \1、使用KEIL 5(MDK)打开项目工程文件0 m+ H4 Y* E) ^3 q0 {. j% F
源码使用说明:使用前必须把项目工程复制到无中文路径的文件夹下使用。
" k( _9 [4 l, `4 b& T' I(1)找到刚才新建工程的存储路径,安装项目名称,打开项目工程.uvprojx。6 z2 u- h) z0 |7 v P8 r% ~4 s
[# Q: {+ m) X/ s
) r' h; P8 f) ]( j
; N& c% }7 v5 f2、添加LED指示灯作为系统提示
; z+ c/ `" B j8 F- Y8 y* f添加每隔100ms,LED1、LED2、LED3、LED4闪烁一次的系统提示,用于提示程序运行正常。+ a) T. U. t4 l& _0 F' k& M
/ S; u5 q7 X! R% L/ N1 d
& C2 a p) V8 w2 ?* E: h( S0 l
7 I6 q: H; `, K) O' k3、添加HAL库UART DMA 发送函数代码
( N0 f0 U0 Q* a: R( U(1)STM32 HAL函数库的串口DMA相关函数如下:/ ?) C$ Y3 O( _3 C+ z: X
- HAL_UART_Transmit();串口发送数据,使用超时管理机制
; q* N, n0 F3 B) X# `4 u1 p - HAL_UART_Receive();串口接收数据,使用超时管理机制4 D" F& W& A/ d6 C
- HAL_UART_Transmit_IT();串口中断模式发送
" I# F. g2 K9 x; L6 a9 { - HAL_UART_Receive_IT();串口中断模式接收
) @, D. e) A* p8 B - HAL_UART_Transmit_DMA();串口DMA模式发送3 ^8 H5 _' r2 a1 B. a
- HAL_UART_Transmit_DMA();串口DMA模式接收% X4 b, a- X" t
- HAL_UART_DMAPause() 暂停串口DMA' ~+ o1 J2 C$ p1 M- l
- HAL_UART_DMAResume(); 恢复串口DMA& Z( v' i! h6 n/ v3 s; S
- HAL_UART_DMAStop(); 结束串口DMA
复制代码 4 Q% V" O5 K. e3 g" n# t6 W# R, m
(2)main.c添加串口DMA发送函数相关代码:
2 Q- F1 x+ i2 X$ E- D# n- {; V- /* Private user code ---------------------------------------------------------*/
5 N3 a" I! o! B% H U$ o# v! K - /* USER CODE BEGIN 0 */1 `) f* T: R; t) T" h u
- uart_rx_struct uart_rx_struct_t={0}; //串口接收数组+ S7 q+ n6 b. _( a, T- |' m% E
- /* USER CODE END 0 */
复制代码- int main(void)
4 B6 `* i; s& l2 P3 S - {
' J4 \9 f% p2 c" H+ Y! v8 } - /* USER CODE BEGIN 1 */
! \# U P, j: ` @ - uint8_t transmit_str[50]= {"hello world,this is uart dma function!\r\n"};6 i, g! l; p/ t4 b( R8 E9 A( h: F
- /* USER CODE END 1 */
" Z9 f' X8 j, W8 V -
% n4 Q8 _/ i% ~4 Y - /* MCU Configuration--------------------------------------------------------*/
, v1 C9 v/ j+ d& u7 L! G6 ` K -
& M9 ]8 R Z9 d3 d9 s- O+ p, v - /* Reset of all peripherals, Initializes the Flash interface and the Systick. */8 l0 o% h5 H T* x
- HAL_Init();8 D" L; t S% n B
-
" [4 f) b: Z4 v- q l - /* USER CODE BEGIN Init */. C" ^/ ]8 }4 R0 G6 \5 j* L
- ) h |; B5 I4 B0 A& r( s% p2 U
- /* USER CODE END Init */- [$ S) R3 @9 `& y5 r i9 {% l
- 9 e6 K6 H2 j% o' y. l; q
- /* Configure the system clock */ ]9 E* @8 ?/ Y+ V8 m
- SystemClock_Config(); _+ l$ L: H+ s" z ~5 X9 w% B
- ' o! ~( I7 Y" O. s* ?7 z9 i: C
- /* USER CODE BEGIN SysInit */
- Y9 K u$ i0 H% C% j" b -
2 R' l. x% Z/ R8 I; D% ?& X - /* USER CODE END SysInit */2 a y5 H8 X# \& I
- # O$ a, U4 }8 w+ r% ~9 C$ P
- /* Initialize all configured peripherals */. V- e* B" O% k
- MX_GPIO_Init();
+ J! q; W; D$ f0 r Z" N% x9 t - MX_DMA_Init();
+ N: f, |" W# M4 w - MX_USART1_UART_Init();
# P' C" x" h3 E* l8 D. c - /* USER CODE BEGIN 2 */0 w. s% U$ J* f" E$ E L ?0 V
- HAL_GPIO_WritePin(GPIOC,GPIO_PIN_0,GPIO_PIN_SET); //初始化LED灯,默认点亮
& l8 I; I$ p% l - HAL_GPIO_WritePin(GPIOC,GPIO_PIN_1,GPIO_PIN_SET); //初始化LED灯,默认点亮8 X% i' ]: O+ n' M" S5 V$ q7 a) L# ^
- HAL_GPIO_WritePin(GPIOC,GPIO_PIN_2,GPIO_PIN_SET); //初始化LED灯,默认点亮
9 I/ [) ]- B+ { - HAL_GPIO_WritePin(GPIOC,GPIO_PIN_3,GPIO_PIN_SET); //初始化LED灯,默认点亮
]3 l( a2 B& Z: H6 v6 p - HAL_UART_Transmit_DMA(&huart1, (uint8_t*)transmit_str, sizeof(transmit_str)); //
, ^( [& h, V" V9 a/ H2 F3 l' v+ r - HAL_Delay(5); P! A9 b, S2 y2 |' j& D# q7 V. M
- HAL_UART_Receive_DMA(&huart1, uart_rx_struct_t.uart_rx_buf, UART_RX_LEN); // 启动DMA接收
) y- u9 v1 D# p - __HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE); // 使能空闲中断- Y; F& V- m2 |5 L2 w. Z; c
-
; w* ^& c2 ]# R! n - /* USER CODE END 2 */
5 S! U& i1 ~- E. U, w4 C% H -
" l3 j4 @* C* {0 k) U6 I - /* Infinite loop */0 f3 o/ D9 y, E1 _( o
- /* USER CODE BEGIN WHILE */
2 J* A) z, F% N - while (1); m- p! N+ \* @$ q) U' v
- {
: Y* G$ V1 B3 W5 w2 ]1 ]7 f; r - /* USER CODE END WHILE */% q. d- z' J* y' B1 c
- . e4 h# y$ V/ C' M# k$ ]* w4 b
- /* USER CODE BEGIN 3 */
3 Q8 o. U8 t! E$ B/ Y - HAL_Delay(100);7 _7 S. u" T$ t* r' B3 \
- HAL_GPIO_TogglePin(GPIOC,GPIO_PIN_0); //反转LED点亮熄灭切换3 e6 B" ^7 I8 y; ~; S
- HAL_GPIO_TogglePin(GPIOC,GPIO_PIN_1); //反转LED点亮熄灭切换
. F8 D% Y, b+ X - HAL_GPIO_TogglePin(GPIOC,GPIO_PIN_2); //反转LED点亮熄灭切换% O! I, u; G: ?4 a6 M
- HAL_GPIO_TogglePin(GPIOC,GPIO_PIN_3); //反转LED点亮熄灭切换
9 X9 C* p$ j% {0 L( Y - if(uart_rx_struct_t.uart_rx_flag & 0X80) //DMA接收完成
4 f. u; F3 X; G - {
) k' K6 L' h3 Y( O' e& ]& v6 D5 v - HAL_UART_Transmit_DMA(&huart1, uart_rx_struct_t.uart_rx_buf, uart_rx_struct_t.uart_len); // 将接收到的数据发送回去) S! z8 z& r- a2 G( ?" u" M' r; t
- uart_rx_struct_t.uart_rx_flag = 0;
8 }# B" b( c# C5 k6 H2 |2 F9 C - }
* \: Z; @& ]3 @6 z0 _% G2 u" K -
! W3 ]: P! n {) }8 @2 K - }/ V+ {5 H9 p8 h* m" a4 l
- /* USER CODE END 3 */
# d% h- }) I: U - }
复制代码
: V( f' ?4 D& L; I(3)main.h相关变量声明: D; ?) ~% g* d5 |- ~$ @3 H
- /* USER CODE BEGIN ET */
/ z, I) U8 b$ j& v - #define UART_RX_LEN 1024 // 一次最大接收的数据量, n( f$ c z4 d
- typedef struct
- Q9 D1 Y* @6 w$ }; f- e' ^ - {
" R3 y4 `# _" w% S( U1 y" @7 A0 {1 I3 g - uint8_t uart_rx_buf[UART_RX_LEN]; // DMA数据接收缓存数组: q$ J2 _! ^$ [9 N
- uint16_t uart_len; //DMA数据接收长度* [2 F, K- `" [ N$ u
- uint8_t uart_rx_flag; //接收完成标志位8 \9 Q0 }; i5 h. A
- }uart_rx_struct;
5 X: l5 Y8 P" @. E* C4 H - extern uart_rx_struct uart_rx_struct_t;
0 M; g% l6 ~" v4 e, B - " T+ `6 z3 `- ^% \, w1 l
- /* USER CODE END ET */
复制代码 7 q; A# _3 e4 y- Y
4、添加HAL库UART DMA 接收函数代码
- s4 o" G$ A9 T! k% V1 }(1)DMA接收设置前铺垫知识点:1 L( U4 p3 c4 k" Y; B, ~' S
STM32的IDLE的中断产生条件:在串口无数据接收的情况下,不会产生,当清除IDLE标志位后,必须有接收到第一个数据后,才开始触发,一但接收的数据断流,没有接收到数据,即产生IDLE中断停止。& B# n4 O5 i; n
1 p& G4 U6 `# O8 T; }4 ]: r, o(2)添加DMA接收处理代码3 \4 g2 [% \* G' e2 _2 Z' F& u
) y# P% }; W, T1 D
stm32f1xx_it.c中添加代码如下:$ J- i/ |! Q. d* c$ E# a: {6 k. u
- void USART1_IRQHandler(void)
1 c* Z" g& z4 c4 U: e3 m/ l - {
! M; T4 _- B5 d. I- A6 E# [ - /* USER CODE BEGIN USART1_IRQn 0 */
1 b2 T2 R0 V, e% _3 x - if(__HAL_UART_GET_FLAG(&huart1, UART_FLAG_IDLE) != RESET) // 空闲中断标记被置位; l6 W3 B4 `: S$ D+ u
- {
, M) m; I* n' M; T" l - __HAL_UART_CLEAR_IDLEFLAG(&huart1); // 清除中断标记
/ b7 ?7 S, O( d9 S# z1 _ - HAL_UART_DMAStop(&huart1); // 停止DMA接收
7 u- k9 u% Z: N5 c - uart_rx_struct_t.uart_len = UART_RX_LEN - __HAL_DMA_GET_COUNTER(huart1.hdmarx); // 总数据量减去未接收到的数据量为已经接收到的数据量2 u. z4 E* p8 n: u2 a
- uart_rx_struct_t.uart_rx_buf[uart_rx_struct_t.uart_len] = 0; // 添加结束符6 M* x7 I$ m$ b. c2 _7 R
- uart_rx_struct_t.uart_rx_flag |= 0x80; // 标记接收结束
- `5 y1 d0 P* g4 W. z - HAL_UART_Receive_DMA(&huart1, uart_rx_struct_t.uart_rx_buf, UART_RX_LEN); // 重新启动DMA接收, O9 n0 A) ]7 S+ O, F7 Y
- }7 }# W4 V5 b |+ k& b1 O
- /* USER CODE END USART1_IRQn 0 */7 w( J) O! M/ w' ^3 j4 C
- HAL_UART_IRQHandler(&huart1);! ^' S6 {4 K# t- r$ w$ b# N8 V; [
- /* USER CODE BEGIN USART1_IRQn 1 */
) s4 w. n- f4 I0 `9 P8 e0 K- H7 C9 J -
* b: l% F- ]+ j - /* USER CODE END USART1_IRQn 1 */0 _: R/ T, Q* Z$ J6 z
- }
复制代码
, x/ a5 o" o. Q3 k" }) ~(3)至此,串口DMA收发数据需要添加的代码已经完成。( a5 f( I7 f# E
( [4 d6 |) A1 k! r- ]) y
5、设置编程仿真下载模式
% N! Q7 z4 c+ G6 l' |9 o) y$ p/ ](1)选择Options for target ...>>Debug>>J-Link/J-JTRACE Cortex,点击Settings>>选择Port(SW),可以看到搜索成功SW Device,表示芯片可用,可以下载。
* m7 F) r- B$ b- w3 i7 K6 }+ n* q" c& h1 `
0 B, t4 d3 z7 p/ J) z7 |) \) h9 ^: W/ v, G
(2)点击编译,完成后提示“0 error(s),0 warning(s)”。" Z% g* Y) n$ }: a1 k
; g& U" m! R5 d- d$ k& [2 i7 U
$ F0 u. n1 @$ P4 V2 {: d, E% X1 w3 D4 n& o) r6 h. j% j
(3)点击Download(或者快捷键F8),即可下载程序。3 ]' R K' x, t: |' D& k* S
% F( H, Z: @1 p* J# G0 J8 c; o& U% s
. w' I2 c9 o1 I* L: G+ J9 d# d* o2 s. @. Q3 g" @
- `% d- O0 G, m; d% H. k, U(4) 如果下载程序后,没有看到LED1、LED2、LED3、LED4闪烁,可以按下述方式设置一下(Reset and run表示下载后自动复位和重启运行)。或者重新彻底断电再次上电(或按开发板的Reset按键复位MCU即可)。
6 ?/ B- Z m7 E5 P }8 |2 r% n2 t7 r: b: m" m
. v# i6 j M3 V4 D6 ^) N' Y ; q! y( b$ d" m
6、串口DMA收发实验效果展示+ @( ?) t) H* ~% Z, K: Z6 I3 O; z
程序烧录到开发板后,即可看到LED1、LED2、LED3、LED4初始化后每隔100ms闪烁一次,并且打开串口助手后(串口参数:波特率115200、N、8、1),通过串口助手可以看到,开发板接收到发送的数据转发出来。 W/ j; S$ T. r2 M6 C+ R
1 y1 T: Q |3 P* L9 j' m" _
! x% g4 [8 I( D! L4 l& u$ K& o
# M! u/ L# ~. ?1 \2 O
————————————————
( j: X* A1 f" q7 R* P& V. E0 @版权声明:智能小屋ZYXC
4 d M( Y4 e! F: {, D8 `( Y% v9 v) r, u1 p
. w8 h. ~, E5 D y9 i" }
|