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