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