导语
关键词:STM32 DMA
本次教程采用的是stm32f401ccu6 + HAL库V1.8.1(F1系列芯片兼容)
CubeMX配置
最后点击GENERATE CODE生成代码
代码编写
测试串口功能(确定无误可跳过) - /* USER CODE BEGIN Header */
- #include <stdio.h> //C语言标准输入输出库
- /* USER CODE END Header */
- ...
- /* USER CODE BEGIN 1 */
- int fputc(int ch, FILE *f){
- uint8_t temp[1] = {ch};
- HAL_UART_Transmit(&huart1, temp, 1, 0xffff); //注意这里的&huart1更改为你使用的串口&huartx
- return ch;
- }
- int fgetc(FILE * f)
- {
- uint8_t ch = 0;
- HAL_UART_Receive(&huart1,&ch, 1, 0xffff); //同理
- return ch;
- }
复制代码
在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") 编译下载后,打开串口助手可以看到测试信息,至此串口配置完成。
DMA测试及不定长DMA的配置DMA发送测试- void DMA_USART_Send(uint8_t *buf, uint8_t len)
- {
- if(HAL_UART_Transmit_DMA(&huart1, buf, len) != HAL_OK)
- {
- Error_Handler();
- }
- }
- void DMA_USART_Read(uint8_t *Data, uint8_t len)
- {
- HAL_UART_Receive_DMA(&huart1, Data, len);
- }
复制代码
- DMA_USART_Send((uint8_t*)"Hello\r\n",sizeof("Hello\r\n"));
复制代码
DMA不定长接收 在usart.c中添加全局定义uint8_t rx_buffer[100] = {0};其中“100”可修改,其值为最大的单次接收字符个数。 (定义可放在别的文件,使用时包含该文件或者使用extern关键字)
在usart.c中打开串口的空闲中断(IDLE中断)、找到串口初始化函数 void MX_USARTx_UART_Init(void),其中,X为使用的串口号
相关代码如下: - /* USER CODE BEGIN USART1_Init 2 */
- __HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE); //使能IDLE中断
- HAL_UART_Receive_DMA(&huart1,rx_buffer,100); //100对应了前面定义的数组大小
- /* USER CODE END USART1_Init 2 */
复制代码
注意:此处HAL库较低版本没有用户自定义代码的区域,可自行更新HAL库版本或将代码添加到别处(否则cubemx更新代码时会丢失)
- // in stm32f*xx_it.c
- /* USER CODE BEGIN Header */
- #include "usart.h"
- #include <stdio.h>
- /* USER CODE END Header */
复制代码
- uint16_t tmp = 0;
- uint16_t Rx_Len = 0;
-
- if(__HAL_UART_GET_FLAG(uartHandle, UART_FLAG_IDLE) != RESET) //是否进入空闲中断
- {
- __HAL_UART_CLEAR_IDLEFLAG(uartHandle); //清除空闲中断标志位
- HAL_UART_DMAStop(uartHandle); //此时信息已保存至rx_buffer,暂时停止DMA接收
- //... 在此添加解码程序或其他自定义代码,此处以接收信息后回显代码为例
- tmp = __HAL_DMA_GET_COUNTER(hudma); //读取计数器后自动清除空闲中断,也可以直接读寄存器
- Rx_Len = BUFFER_SIZE - tmp;
- DMA_USART_Send(rx_buffer, Rx_Len);
- Rx_Len = 0;
- //
- HAL_UART_Receive_DMA(uartHandle,rx_buffer,BUFFER_SIZE); //重新打开DMA接收
复制代码
转载自:hardware
|