|
导语/ r' F& [ u$ |7 [/ _" [
关键词:STM32 DMA
7 g* C6 k1 Y1 q/ `2 q) ?* N, m本次教程采用的是stm32f401ccu6 + HAL库V1.8.1(F1系列芯片兼容)
5 g1 |$ x" r3 ?$ hCubeMX配置
最后点击GENERATE CODE生成代码
4 Z$ i7 x. p3 ]6 k2 I/ _代码编写3 N! e/ O$ w8 R! K" z9 A2 b
测试串口功能(确定无误可跳过) - /* USER CODE BEGIN Header */$ Y* u9 p ]7 F# `
- #include <stdio.h> //C语言标准输入输出库
) V* ? M/ z2 _ - /* USER CODE END Header */
* N$ t8 g* e W - ...8 O+ A. g. w# p
- /* USER CODE BEGIN 1 */
5 m, R( I( w' D9 u' |7 z! P& J - int fputc(int ch, FILE *f){
: b* }) q2 f( [. x% D - uint8_t temp[1] = {ch};
0 E# L% ^2 @4 @: p5 e- s& f - HAL_UART_Transmit(&huart1, temp, 1, 0xffff); //注意这里的&huart1更改为你使用的串口&huartx2 ?( Y( @3 H" X" H p
- return ch;: O, K1 r6 A0 m6 Z
- }
- d* o u+ l! S* U' C - p& V; L% P4 g" H
- int fgetc(FILE * f)
, d4 \! I- H* `! ^ - {
6 a4 Y& E) |4 G! K6 |6 O9 Y/ i - uint8_t ch = 0;
8 W, }: x# g! [! F - HAL_UART_Receive(&huart1,&ch, 1, 0xffff); //同理! C4 y8 S/ ?6 G8 j8 ]* s+ c1 l
- return ch;! p, C' g5 Q% C' j+ _
- }% t1 T5 g" r; g4 z' d
复制代码
9 m, h/ z/ O0 U: n在main.c添加头文件#include <stdio.h> 打开KEIL菜单栏的魔术棒(Options for Target...) 在Target栏下勾选Use MicoLIB 在Debug - Setting - Flash Download栏下勾选Rest and Run(否则需要手动复位单片机) 在main.h中写上测试代码printf("nihao\r\n") 编译下载后,打开串口助手可以看到测试信息,至此串口配置完成。
: M+ f r9 d- Z) |" D ' ]6 h# O9 _3 l$ R/ a
! h/ _; X6 A, }, u, c2 H+ b: q- I, X
/ d1 H7 ~1 w3 t9 G dDMA测试及不定长DMA的配置DMA发送测试在usart.c中添加如下代码: * _, u, w0 C: B) F* [' X8 }- g
- void DMA_USART_Send(uint8_t *buf, uint8_t len)- J: g9 B1 `1 O6 }7 D
- {& ^1 g; Y3 t) U h7 h! o- o
8 k+ f) x: h' k ^9 m8 k. l- if(HAL_UART_Transmit_DMA(&huart1, buf, len) != HAL_OK)
: w: b1 G8 q1 | - {
* K1 ~. f# C+ e' u8 s" `$ R - Error_Handler();
3 e# k9 C5 y7 z/ ? - } }4 P$ \! _! _, z% |
- }
$ O& j. c& i4 e3 y* n- X# R - . W$ c4 L: y9 t$ e
- void DMA_USART_Read(uint8_t *Data, uint8_t len)
% p; ^) o b2 K! [$ }; k G - {1 v6 v3 Q3 T: b& z! B& D. G
- HAL_UART_Receive_DMA(&huart1, Data, len);
+ a8 j2 H. X, @% }- t8 r5 n; N2 _ - }
复制代码 ' }+ v( g& ?, r9 Q3 m
, d! V' x; `% B0 ~0 I" h4 _% F; m/ C在main.c相关位置添加代码
5 K6 i+ J1 |, b) o8 i' R0 n
- DMA_USART_Send((uint8_t*)"Hello\r\n",sizeof("Hello\r\n"));
复制代码 2 ~) e4 j, b3 S. l5 p: J0 @
编译运行后可在串口助手观察到输出。
* _" f, |. ]8 k0 A
3 |1 R8 a+ O5 c! T; q/ E, C/ e# G9 Z; D; p8 V2 u7 w; P7 i4 }9 q
5 S+ k; Y$ c" T/ G
DMA不定长接收 在usart.c中添加全局定义uint8_t rx_buffer[100] = {0};其中“100”可修改,其值为最大的单次接收字符个数。 (定义可放在别的文件,使用时包含该文件或者使用extern关键字)
; y% @: [4 j% G2 [* H; Y, d& x在usart.c中打开串口的空闲中断(IDLE中断)、找到串口初始化函数 void MX_USARTx_UART_Init(void),其中,X为使用的串口号 0 V. b! b1 X3 b5 ~' B
相关代码如下: - /* USER CODE BEGIN USART1_Init 2 */: Y# ?8 _) g% }) E a5 _$ O
- __HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE); //使能IDLE中断
3 F9 n0 p) d( c# i( Y) O3 [ - HAL_UART_Receive_DMA(&huart1,rx_buffer,100); //100对应了前面定义的数组大小
" M' c5 J3 v5 |9 _ - /* USER CODE END USART1_Init 2 */
复制代码
' ^& d0 h. l% r- p7 }, V
注意:此处HAL库较低版本没有用户自定义代码的区域,可自行更新HAL库版本或将代码添加到别处(否则cubemx更新代码时会丢失) * w/ s6 I- y5 f( G/ ~/ ~2 e
- // in stm32f*xx_it.c" O/ [ F, Z- a* Z9 c4 K
6 [: {# P2 h. ^: {( n- /* USER CODE BEGIN Header */
( P% }& n; N* K- w& U6 y
& b X9 h- y3 ^1 d* L! ]+ i8 J7 Z- #include "usart.h"
* Y1 E5 j- W6 S3 ~! p3 [& V1 T - #include <stdio.h>* u7 U; b9 e: e3 Q3 Q/ P
( V$ j0 N I" \5 `. Z- /* USER CODE END Header */
复制代码
+ [3 c O8 U! K3 u: K
' t+ {% V- x Y8 b* ^/ T- uint16_t tmp = 0;1 A4 n- ?4 h* p+ f3 Z3 e4 K
- uint16_t Rx_Len = 0;
. D# b' F( p& v) z s, O2 I -
% W# w* x9 Y; q+ ] - if(__HAL_UART_GET_FLAG(uartHandle, UART_FLAG_IDLE) != RESET) //是否进入空闲中断
) U( b9 C" R& r2 ^! u X L - {
. U" }# Y2 G( X6 `1 } - __HAL_UART_CLEAR_IDLEFLAG(uartHandle); //清除空闲中断标志位
2 i' @+ e8 F: B3 r# W9 L - HAL_UART_DMAStop(uartHandle); //此时信息已保存至rx_buffer,暂时停止DMA接收
9 k/ Z2 K( w; a$ t4 Z8 I7 g( o
$ m, ?& \' q/ b5 c- D% j6 A- //... 在此添加解码程序或其他自定义代码,此处以接收信息后回显代码为例
, U4 O3 h% B" [: N - tmp = __HAL_DMA_GET_COUNTER(hudma); //读取计数器后自动清除空闲中断,也可以直接读寄存器
/ H; s! ~. L& Q/ _ - Rx_Len = BUFFER_SIZE - tmp;
$ g. x1 h8 T" [. q- ~ T - DMA_USART_Send(rx_buffer, Rx_Len);
9 }- l N8 `( P$ T' Y% a - Rx_Len = 0;, ^. H9 S. ?# Q% y
- //
, l8 V9 }' u* G: e* n) d. u9 _ - HAL_UART_Receive_DMA(uartHandle,rx_buffer,BUFFER_SIZE); //重新打开DMA接收
复制代码 4 z' j. G/ `0 l8 N @; t/ V
u( G: g( e G6 V) B
/ s- }# Q7 M2 `9 y% [
, N" o1 a6 g7 ]转载自:hardware
& c g& ?% E# Z2 \9 _ |