STM32串口DMA与接收不定长数据

DMA模式简介:

什么是DMA?(Direct Memory Access)

        DMA"Direct Memory Access"(直接内存访问)的缩写,是计算机系统中允许外部设备(如硬盘、网卡等)直接访问主存储器(内存)的一种技术,而无需通过中央处理器(CPU)的干预

        这样做可以提高系统的效率,因为它减少了 CPU 在数据传输中的负担使其能够专注于其他处理任务

        在使用 DMA 时,设备会通过一个被称为 DMA 控制器的硬件模块管理数据的读写DMA 控制器会请求访问内存总线,一旦获得总线控制权,它就可以直接将数据传输到内存或从内存中读取数据CPU 只需在传输开始和结束时进行一些基本的设置和控制

数据发送与接收:

DMA通道创建:

因此,在使用DMA时,我们需要创建DMA通道。

 进入配置界面:Connectivity--->USART2--->Add--->将DMA Request 改为USARTT2_TX和USARTT2_RX(表示此DMA通道用于USART2的串口发送and接收)

(从USARTT2_TX这一栏可以看到数据搬运方向被设置为从内存(Memory)向外设(Peripheral)搬运——即内存变量向发送数据寄存器进行搬运

串口接收不定长数据: 

                                            

串口空闲中断触发条件与接收的字节数无关,当串口接收从忙碌转为空闲时才会触发,因此我们一般认为空闲中断发生时,就是一帧数据包接收完成了

使用处理函数

HAL_UARTEx_ReceiveToIdle_DMA(&huart2, receiveData, Sizeof(receiveData));

此时,我们需要用到该函数对应的回调函数

stm32f1xx_it.c文件中--->找到void USART2_IRQHandler(void)函数,按住Ctrl键,点击HAL_UART_IRQHandler,进入到HAL_UART_IRQHandler所在的stm32f1xx_hal_uart.c--->找到void HAL_UARTEx_RxEventCallback回调函数

void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)

问题与解决:

在使用串口的DMA模式时,除了串口空闲中断以外,DMA的“传输过半中断”也会触发RxEventCallback回调函数。

我们在后面添加以下代码就可以解决问题了

__HAL_DMA_DISABLE_IT(&hdma_usart2_rx,DMA_IT_HT);

代码:

定义全局变量

uint8_t receiveData[50];

回调处理 

void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)
{
	if(huart == &huart2)
	{
		HAL_UART_Transmit_DMA(&huart2, receiveData, Size);
		GPIO_PinState state =GPIO_PIN_SET;
				  if(receiveData[1]=='0')
				  {
					  state = GPIO_PIN_RESET;
				  }
				  else if(receiveData[1]=='1')
				  {
					  state = GPIO_PIN_SET;
				  }
				  if(receiveData[0]=='R')
				  {
			          HAL_GPIO_WritePin(LED_RED_GPIO_Port, LED_RED_Pin, state);
				  }
				  else if(receiveData[0]=='G')
				  {
			          HAL_GPIO_WritePin(LED_GREEN_GPIO_Port, LED_GREEN_Pin, state);
				  }
				  else if(receiveData[0]=='B')
				  {
			          HAL_GPIO_WritePin(LED_BLUE_GPIO_Port, LED_BLUE_Pin, state);
				  }

		HAL_UARTEx_ReceiveToIdle_DMA(&huart2, receiveData, sizeof(receiveData));
		__HAL_DMA_DISABLE_IT(&hdma_usart2_rx,DMA_IT_HT);
	}
}

发送处理

HAL_UARTEx_ReceiveToIdle_DMA(&huart2, receiveData, sizeof(receiveData));
  __HAL_DMA_DISABLE_IT(&hdma_usart2_rx,DMA_IT_HT);

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

庆庆知识库

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值