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