基于HAL库实现DMA串口通信

题目要求

1)STM32系统给上位机(win10)连续发送“hello windows!”。win10采用“串口助手”工具接收。
2)在完成以上任务基础,继续扩展功能:当上位机给stm32发送一个字符“0”后,stm32暂停发送“hello windows!”;发送一个字符“1”后,stm32继续发送;

基于HAL库实现DMA串口通信

一.DMA

DMA,全称Direct Memory Access,即直接存储器访问。DMA传输将数据从一个地址空间复制到另一个地址空间,提供在外设和存储器之间或者存储器和存储器之间的高速数据传输。

DMA用来提供在外设和存储器之间或者存储器和存储器之间的高速数据传输。无须CPU的干预,通过DMA数据可以快速地移动。这就节省了CPU的资源来做其他操作。

DMA的作用就是实现数据的直接传输,而去掉了传统数据传输需要CPU寄存器参与的环节。

我们知道,数据传输,首先需要的是数据的源地址、数据传输位置的目标地址、传递数据多少的数据传输量、进行多少次传输的传输模式。DMA所需要的核心参数,便是这四个。

每个通道都直接连接专用的硬件DMA请求,每个通道都同样支持软件触发。这些功能通过软件来配置。

一.创建CubeMX项目

这里我们使用的是STM32F103C8T6系统板,打开STM32CubeMX软件,选择对应的芯片,开始配置
1.设置RCC
在这里插入图片描述
2.设置USART1
选择异步通信
参数选择默认
在这里插入图片描述使能串口
在这里插入图片描述
添加两个通道
在这里插入图片描述
3.创建项目
把main函数中的内容修改为自己的代码
在这里插入图片描述
四、效果
把修改完的代码进行编译后再烧录,通过串口调试助手查看。
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
以下是基于DMA的STM32串口通信HAL实现代码: ```c #include "stm32f4xx_hal.h" UART_HandleTypeDef huart; void HAL_UART_MspInit(UART_HandleTypeDef* uartHandle) { GPIO_InitTypeDef GPIO_InitStruct = {0}; if(uartHandle->Instance==USART1) { /* USART1 clock enable */ __HAL_RCC_USART1_CLK_ENABLE(); __HAL_RCC_GPIOA_CLK_ENABLE(); /**USART1 GPIO Configuration PA9 ------> USART1_TX PA10 ------> USART1_RX */ GPIO_InitStruct.Pin = GPIO_PIN_9|GPIO_PIN_10; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; GPIO_InitStruct.Alternate = GPIO_AF7_USART1; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); /* USART1 DMA Init */ /* USART1_TX Init */ hdma_usart1_tx.Instance = DMA2_Stream7; hdma_usart1_tx.Init.Channel = DMA_CHANNEL_4; hdma_usart1_tx.Init.Direction = DMA_MEMORY_TO_PERIPH; hdma_usart1_tx.Init.PeriphInc = DMA_PINC_DISABLE; hdma_usart1_tx.Init.MemInc = DMA_MINC_ENABLE; hdma_usart1_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE; hdma_usart1_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE; hdma_usart1_tx.Init.Mode = DMA_NORMAL; hdma_usart1_tx.Init.Priority = DMA_PRIORITY_LOW; hdma_usart1_tx.Init.FIFOMode = DMA_FIFOMODE_DISABLE; if (HAL_DMA_Init(&hdma_usart1_tx) != HAL_OK) { Error_Handler(); } __HAL_LINKDMA(uartHandle,hdmatx,hdma_usart1_tx); /* USART1_RX Init */ hdma_usart1_rx.Instance = DMA2_Stream2; hdma_usart1_rx.Init.Channel = DMA_CHANNEL_4; hdma_usart1_rx.Init.Direction = DMA_PERIPH_TO_MEMORY; hdma_usart1_rx.Init.PeriphInc = DMA_PINC_DISABLE; hdma_usart1_rx.Init.MemInc = DMA_MINC_ENABLE; hdma_usart1_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE; hdma_usart1_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE; hdma_usart1_rx.Init.Mode = DMA_CIRCULAR; hdma_usart1_rx.Init.Priority = DMA_PRIORITY_LOW; hdma_usart1_rx.Init.FIFOMode = DMA_FIFOMODE_DISABLE; if (HAL_DMA_Init(&hdma_usart1_rx) != HAL_OK) { Error_Handler(); } __HAL_LINKDMA(uartHandle,hdmarx,hdma_usart1_rx); } } void HAL_UART_MspDeInit(UART_HandleTypeDef* uartHandle) { if(uartHandle->Instance==USART1) { /* Peripheral clock disable */ __HAL_RCC_USART1_CLK_DISABLE(); /**USART1 GPIO Configuration PA9 ------> USART1_TX PA10 ------> USART1_RX */ HAL_GPIO_DeInit(GPIOA, GPIO_PIN_9|GPIO_PIN_10); /* USART1 DMA DeInit */ HAL_DMA_DeInit(uartHandle->hdmatx); HAL_DMA_DeInit(uartHandle->hdmarx); } } void MX_USART1_UART_Init(void) { huart.Instance = USART1; huart.Init.BaudRate = 115200; huart.Init.WordLength = UART_WORDLENGTH_8B; huart.Init.StopBits = UART_STOPBITS_1; huart.Init.Parity = UART_PARITY_NONE; huart.Init.Mode = UART_MODE_TX_RX; huart.Init.HwFlowCtl = UART_HWCONTROL_NONE; huart.Init.OverSampling = UART_OVERSAMPLING_16; if (HAL_UART_Init(&huart) != HAL_OK) { Error_Handler(); } } ``` 这段代码使用了HAL实现了基于DMA串口通信。在这个例子中,我们使用了USART1作为串口,使用了DMA2的Stream7和Stream2作为发送和接收的DMA通道。在初始化函数中,我们设置了串口的波特率、数据位、停止位、校验位等参数,并且初始化了DMA通道。在使用串口进行通信时,我们可以使用HAL提供的函数来发送和接收数据,例如: ```c HAL_UART_Transmit_DMA(&huart, (uint8_t*)tx_buffer, tx_len); HAL_UART_Receive_DMA(&huart, (uint8_t*)rx_buffer, rx_len); ``` 这两个函数分别使用DMA通道发送和接收数据,可以大大提高串口通信的效率。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值