STM32 F429 DMA传输1-串口(外设)DMA传输

STM32 F429 DMA传输1-串口(外设)DMA传输

主要内容

本文主要是我自己记录DMA配置过程函数以及参数细节,同时与需要的人分享学习,对于DMA的作用、定义之类的在这不进行阐述,有需要者参考中文手册。

为方便对比学习,我分三部分分享我在正点原子f429板子上写的关于DMA的程序,从官方历程到扩展使用分别为:
1、由内存向串口(外设)DMA传输;
2、由ADC采集数据(内存)向内存DMA传输;
3、定时器下ADC采集向内存双缓冲DMA传输;
本文只对第一部分进行讲解。

如何配置

要实现串口(外设)DMA传输需要四部配置
1)使能 DMA2 时钟。
2) 初始化 DMA参数。
3)使能串口 的 DMA 发送
4)使能 DMA 数据流 ,启动传输。
配置过程官方历程讲的已经非常清晰了这里我把代码粘一下,各行都有注释

void myDMA_init(DMA_Stream_TypeDef *DMAa_Streamb, u32 chx)
{
		if((u32)DMAa_Streamb>(u32)DMA2)//得到当前stream是属于DMA2还是DMA1
	{
        __HAL_RCC_DMA2_CLK_ENABLE();//  第一步初始化DMA2时钟使能	
	}else 
	{
        __HAL_RCC_DMA1_CLK_ENABLE();//DMA1时钟使能 
	}
   __HAL_LINKDMA(&UART1_Handler,hdmatx,DAM_Handal);    //将DMA与USART1联系起来(发送DMA)
	
  /*     配置DMA各个参数     */
	DAM_Handal.Instance                          = DMAa_Streamb;  //寄存器基地址 设置DMA数据流
	DAM_Handal.Init.Channel                      = chx;    //通道
  DAM_Handal.Init.Direction                      = DMA_MEMORY_TO_PERIPH;	  //dma传输方向 内存到外设
	DAM_Handal.Init.PeriphInc                    = DMA_PINC_DISABLE;   //外设(非)增量模式
	DAM_Handal.Init.MemInc                       = DMA_MINC_ENABLE;     //使能存储器地址递增
	DAM_Handal.Init.PeriphDataAlignment          = DMA_PDATAALIGN_BYTE;   //设置外设数据宽度
  DAM_Handal.Init.MemDataAlignment               = DMA_MDATAALIGN_BYTE;   //设置外设数据宽度
  DAM_Handal.Init.Mode                           =DMA_NORMAL;             //外设普通模式
	DAM_Handal.Init.Priority                     =DMA_PRIORITY_MEDIUM;      //中等优先级
	DAM_Handal.Init.FIFOMode                     =DMA_FIFOMODE_DISABLE;       //fifo模式
	DAM_Handal.Init.FIFOThreshold                =DMA_FIFO_THRESHOLD_FULL;    //FIFO阀值设置
	DAM_Handal.Init.MemBurst                     =DMA_MBURST_SINGLE;                 //存储器突发单次传输
	DAM_Handal.Init.PeriphBurst                  =DMA_PBURST_SINGLE;              //外设突发单次传输
	
		  HAL_DMA_Init(&DAM_Handal);
	
}
void MYDMA_USART_Transmit(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
{
    HAL_DMA_Start(huart->hdmatx, (u32)pData, (uint32_t)&huart->Instance->DR, Size);//开启DMA传输
    
    huart->Instance->CR3 |= USART_CR3_DMAT;             //使能串口DMA发送


}	  

其中对于DMA串口传输函数可以使用HAL_DMA_Start,但是必须进行 huart->Instance->CR3 |= USART_CR3_DMAT; 使能串口DMA发送,同时也可以使用HAL_UART_Transmit_DMA函数进行传输,此函数内包含使能串口DMA发送,其参数是一样的,后两部分

2、由ADC采集数据(内存)向内存DMA传输;
3、定时器下ADC采集向内存双缓冲DMA传输;

均使用的是HAL_ADC_Start_DMA函数进行DMA传输,过程与HAL_UART_Transmit_DMA类似,所以推荐使用。

各参数含义及配置细节

对于DMA配置的各个参数出代码注释以为需要注意的还有:
1)
DAM_Handal.Init.Direction = DMA_MEMORY_TO_PERIPH;
dma传输方向 有自己写的字符串传输到串口方向是内存到外设,初学者学习不要直接搬用参数而不知道什么意思就直接搬用。
2)
DAM_Handal.Init.PeriphInc = DMA_PINC_DISABLE;
用于设置外设地址是否使能递增,即每完成一次传输,外设地址自增,增加的大小由参数PeriphDataAlignment (外设数据宽度)决定,也就是说如果你只用了一个外设,那么就不能使能递增,否者使能,很明显这里只用了一个串口传输。
3)成员MemInc
用于设置存储器地址是否使能递增,即每完成一次传输,存储器地址自增,增加的大小由参数 MemDataAlignment 决定,与2)类似。
4)成员 PeriphDataAlignment
用于设置外设支持的数据宽度,可以选择字节,半字和字进行传输。
5)成员MemDataAlignment
用于设置存储器支持的数据宽度,可以选择字节,半字和字进行传输。
6)成员Mode 用于设置正常模式、循环模式和流控制,Normal 正常模式 适合用于单次传输,比如存储器到存储器的数据复制粘贴,又比如串口的数据单次发送,下次还需要 发送的时候,使能下即可。
Circular 循环模式 适合用于需要连续传输的场合,比如定时器触发BDMA实现任意 IO 的 PWM输出。特别注意,循环模式不可用于存储器到存储器模式。
另外需要注意的还有传输源地址和目的地址的数据宽度可以不同,但是数据地址必须要跟其数据类型对齐 比如源地址是uint32 类型的,那么此数组的地址必须 4 字节对齐。

在函数HAL_DMA_StartHAL_UART_Transmit_DMA进行传输时,参数是一样的,各参数分别为UART_HandleTypeDef结构的指针指定配置信息,pData: 目的缓冲区地址,Length: 传输数据长度,在这是内存传输到外设的数据长度。

中断标志
 DMA_FLAG_TCIFx 传输完成标志。
 DMA_FLAG_HTIFx 半传输完成标志。
 DMA_FLAG_TEIFx 传输错误标志。
 DMA_FLAG_DMEIFx 直接模式错误标志。
 DMA_FLAG_FEIFx FIFO错误标志。
需要注意的是DMA_FLAG_FEIF0_4,表示DMA1或者DMA2的Stream0和Stream4的标志,而不是Stream0 到 Stream4,同理 1 和 5 就是 Srteam1 和 Stream5

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值