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