STM32cubeMX+keil+HAL库(DMA+空闲中断收发不定长数据)

目录

文章目录

前言

一、DMA介绍

二、配置

1.接口函数

2.STM32cubeMX的配置

3.keil代码

总结


 MCU型号:STM32H743ZI

IDE环境:MDK 535

文章目录

前言

我是一个单片机小白呀!!!!!!


一、DMA介绍

 1.    DMA概念

直接存储器访问 (DMA) :用于在外设与存储器之间以及存储器与存储器之间进行高速数据传输。DMA传输过程的初始化和启动由CPU完成,传输过 程由DMA控制器来执行,无CPU参与,从而节省CPU资源,提高利用率。

2.    DMA四要素

        ①  传输源  :DMA数据传输的来源

       ②  传输目标:DMA数据传输的目的

        ③  传输数量:DMA传输数据的数量

       ④  触发信号:启动一次DMA数据传输的动作  

3.  DMA数据传输方式

普通模式:传输结束后(即要传输数据的数量达到零),将不再产生DMA操作。若 开始新的DMA传输,需在关闭DMA通道情况下,重新启DMA传输。

循环模式:可用于处理环形缓冲区和连续数据流(例如ADC扫描模式)。当激活循 环模式后,每轮传输结束时,要传输的数据数量将自动用设置的初始值 进行加载, 并继续响应DMA请求。

二、配置

1.接口函数

串口DMA方式发送函数:

HAL_StatusTypeDef  HAL_UART_Transmit_DMA 

(UART_HandleTypeDef  *huart,uint8_t *pData, uint16_t Size)

2  串口DMA方式接收函数:

HAL_StatusTypeDef  HAL_UART_Receive_DMA

(UART_HandleTypeDef  *huart,uint8_t *pData, uint16_t Size)

目录

文章目录

前言

一、DMA介绍

二、配置

1.接口函数

2.STM32cubeMX的配置

3.keil代码

总结


3 获取未传输数据个数函数   HAL_DMA_GET_COUNTER

2.STM32cubeMX的配置

STM32cubeMX+keil+HAL库(DMA+空闲中断收发不定长数据)_第1张图片

STM32cubeMX+keil+HAL库(DMA+空闲中断收发不定长数据)_第2张图片

STM32cubeMX+keil+HAL库(DMA+空闲中断收发不定长数据)_第3张图片

STM32cubeMX+keil+HAL库(DMA+空闲中断收发不定长数据)_第4张图片

STM32cubeMX+keil+HAL库(DMA+空闲中断收发不定长数据)_第5张图片

STM32cubeMX+keil+HAL库(DMA+空闲中断收发不定长数据)_第6张图片

STM32cubeMX+keil+HAL库(DMA+空闲中断收发不定长数据)_第7张图片

STM32cubeMX+keil+HAL库(DMA+空闲中断收发不定长数据)_第8张图片

STM32cubeMX+keil+HAL库(DMA+空闲中断收发不定长数据)_第9张图片

STM32cubeMX+keil+HAL库(DMA+空闲中断收发不定长数据)_第10张图片

STM32cubeMX+keil+HAL库(DMA+空闲中断收发不定长数据)_第11张图片

 然后配置Project Managei,接着生成工程,此时,STM32cubeMX的配置已经做完了!!

3.keil代码

stm32h7xx_it.c文件中



extern DMA_HandleTypeDef hdma_usart3_rx;
extern DMA_HandleTypeDef hdma_usart3_tx;
extern UART_HandleTypeDef huart2;
extern UART_HandleTypeDef huart3;




void USART3_IRQHandler(void)
{
  
  HAL_UART_IRQHandler(&huart3);

	//添加idle中断处理
  if(__HAL_UART_GET_FLAG(&huart3,UART_FLAG_IDLE)!=RESET)  //是否发生idle中断
	{
		__HAL_UART_CLEAR_IDLEFLAG(&huart3);   //清除idle中断
		HAL_UART_IdleCpltCallback(&huart3);   //用户编写的中断回调函数
	}
	

}

 main.c文件,变量定义

uint8_t			Rx_Flag = 0;         //标志位
uint8_t		RecCount = 0;         //个数
uint8_t			Rx_Buf[256];	     //接收缓冲区
uint8_t    Tx_Buf[256];


extern DMA_HandleTypeDef hdma_usart3_rx;
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)         //接收中断函数
{
	if(huart->Instance == USART3)
	{
	   HAL_UART_Transmit(&huart3,(uint8_t *)Rx_Buf, 256,0xFFFF);    
	}
	
}
void HAL_UART_IdleCpltCallback(UART_HandleTypeDef *huart)     //空闲中断函数
{
   Rx_Flag = 1;                                              // 设置接收完成标志
   HAL_UART_DMAStop(huart);                                 // 停止DMA传输

   //发生空闲中断时,已接受的数据等于数据总减去dma中待接收的数据
   RecCount= 256 - __HAL_DMA_GET_COUNTER(&hdma_usart3_rx);   

	 memcpy(Tx_Buf, Rx_Buf, RecCount);                     //内存复制函数
	 memset(Rx_Buf, 0, sizeof(Rx_Buf));                    // 清零接收缓存区
	 HAL_UART_Receive_DMA(&huart3,Rx_Buf, sizeof(Rx_Buf));   //重新开启DMA传输
	 
	
}
int main(void)
{
  
  HAL_Init();
  SystemClock_Config();
  MX_GPIO_Init();
  MX_DMA_Init();
  MX_USART2_UART_Init();
  MX_USART3_UART_Init();

  HAL_UART_Receive_DMA(&huart3, Rx_Buf,256);           //使能dma中断

  __HAL_UART_ENABLE_IT(&huart3,UART_IT_IDLE);          //使能idle中断


  while (1)
  {
     HAL_Delay(5);
     if(Rx_Flag==1)                                    //判断数据是否接收完成
		{
	      Rx_Flag=0;                                   //清除标志位
	      HAL_UART_Transmit_DMA(&huart3,Tx_Buf,RecCount);   //采用DMA的方式将接收数据发送到PC
	      RecCount = 0;
		}

  }
		
}


总结

我只是一个小菜鸡啊。

你可能感兴趣的:(stm32,stm32,keil,mdk,dma)