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