STM32入门HAL库-DMA直接内存访问

目录

1. 目标

2. 背景知识

3. 过程

3.1 内存 <=> 内存

3.1.1 代码

3.1.2 问题 

3.2 内存 <=> 外设 

3.2.1 代码

3.2.2 问题 

3.3 外设 <=> 外设

附录


1. 目标

使用HAL库控制DMA

2. 背景知识

在一般的代码中,搬运数据是通过CPU来完成的,为了减轻CPU负担让CPU完成更重要的任务,就可以用到DMA直接存储器访问控制器

F103只有DMA1(7通道),L4R5有DMA1(7通道)和DMA2(7通道),具体见手册

来源于外设和内存的数据通过DMA通道互相传输,数据的传输也具有优先级,每个DMA都有一个仲裁器来对此仲裁

DMA会因三个事件产生中断:传输完成,半传输,传输错误

翻阅手册,DMA框图长这样,DMAMUX为DMA请求复用器,可以不关心这个

3. 过程

比较简单,并没有深入DMA内核,还需进一步学习

3.1 内存 <=> 内存

在CubeMX中设置从内存到内存,使用了DMA1通道1,自增指针,数据宽度为字节

3.1.1 代码

将数据从from传送到to,一共四字节数据,上位机收到的数据是abce,假如只有源地址自增应该是e,只有目标地址自增那就是aaaa

虽然这里是通过DMA发送不会阻塞,但在使用之前仍应该通过检查DMA传输是否完成,形参可以是FULL传输完成或者HALF传输一半,然后通过返回值来判断状态

uint8_t from[4] = {'a', 'b', 'c', 'e'};
uint8_t to[5] = {};

HAL_DMA_Start(&hdma_memtomem_dma1_channel1, (uint32_t) from, (uint32_t) to, 4);
while (HAL_DMA_PollForTransfer(&hdma_memtomem_dma1_channel1, HAL_DMA_FULL_TRANSFER, 0) != HAL_OK);
printf("%s\r\n", to);

除了阻塞查询以外,还有常用的中断,这里的中断比较麻烦,需要自己对中断函数进行注册,注册函数第三个形参是状态,可选类型较多(完成,半传输,错误,中止,所有)

以下代码可以完成和上面阻塞式相同的任务

HAL_DMA_Start_IT(&hdma_memtomem_dma1_channel1, (uint32_t) from, (uint32_t) to, 4);

void dmaTransComplete (DMA_HandleTypeDef *_hdma) {
    if (_hdma == &hdma_memtomem_dma1_channel1) {
        printf("%s IT\r\n", to);
    }
}

void dmaRegister () {
    HAL_DMA_RegisterCallback(&hdma_memtomem_dma1_channel1, HAL_DMA_XFER_CPLT_CB_ID, dmaTransComplete);
}

3.1.2 问题 

这一坨运行完成以后,可以发现该通道半传输标志位HTIF仍为1,但数据仍可正常传输,所以可以不管?

3.2 内存 <=> 外设 

使用UART5作为外设,在CubeMX中配置初始参数,既可以在DMA那里配置也可以在UART那里配置

UART5接收,DMA循环,数据宽度字节(后面代码用的单次)

UART5发送,DMA单次,数据宽度字节

Normal单次,Circular循环

3.2.1 代码

对于发送,一行就行了

HAL_UART_Transmit_DMA(&huart5, from, 4);
HAL_Delay(1);
printf(" memToPer\r\n");

发送也差不多,和中断接收一样需编写接收函数

HAL_UART_Receive_DMA(&huart5, from, 4);

void HAL_UART_RxCpltCallback  ( UART_HandleTypeDef *  huart ) {

}

3.2.2 问题 

在DMA发送中产生了一些问题(printf重定向的也是uart5),当去掉HAL_Delay后,printf内容并没有发出,后面的代码正常执行。推测,应该是DMA未发送完成导致碰撞

3.3 外设 <=> 外设

保留字段

附录

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值