STM32-DMA传输实验

关于DMA的笔记详见https://blog.csdn.net/Mr_rustylake/article/details/130140952?spm=1001.2014.3001.5501

实验要求:按下key0按键,实现内部RAM中内存到内存的传输。

首先介绍相关的函数和结构体。

函数:

1、__HAL_RCC_DMAx_CLK_ENABLE():启动相应DMAx的时钟信号;

2、HAL_Init():利用初始化结构体对DMA进行初始化,参数为相应的初始化结构体;

3、HAL_DMA_Start():开始DMA传输,参数为DMA初始化结构体,数据源数组和目标数组以及初始化函数相关,写0即不需要;

注意:在传输的时候,我们先要失能我们的DMA,传入数据长度之后,再使能DMA。

结构体:

DMA_HandleTypeDef g_dma_handler.Instance:选择我们相应的DMAx和它的通道Channelx;

DMA_HandleTypeDef g_dma_handler.Init.Direction:传输方向,有内存到内存,内存到外设,外设到外设,外设到内存;

DMA_HandleTypeDef g_dma_handler.Init.MemoryDataAlignment:数据接收长度;

DMA_HandleTypeDef g_dma_handler.Init.MemInc:是否需要进行接受数据的指针增量;

DMA_HandleTypeDef g_dma_handler.Init.PeriphDataAlignment:数据传输长度; 

DMA_HandleTypeDef g_dma_handler.Init.PeriphInc:是否需要进行传输数据的指针增量;

DMA_HandleTypeDef g_dma_handler.Init.Priority:DMA的软件设置优先级;

DMA_HandleTypeDef g_dma_handler.Init.Mode:选择普通模式或者循环模式。普通模式只传输一次,再传输的话是不会被记在目标数组中的;循环模式在数组满了的时候再传输则会把数据放在第一个这样循环传输,可以用于输出持续的波形。

---------------------------------------------------------------------------------

接下来编写我们的实验代码。

先编写我们的函数文件代码dma.c:

#include "./SYSTEM/sys/sys.h"
#Include "./BSPDMA/dma.h"

DMA_HandleTypeDef g_dma_handler;
uint8_t src_buf[10] = {0x0A, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09};
uint8_t dst_buf[10] = {0};

void dma_init(void){

    __HAL_RCC_DMA1_CLK_ENABLE();

    g_dma_handler.Instance = DMA1_Channel1;
    g_dma_handler.Init.Direction = DMA_MEMORY_TO_MEMORY; //数据传输方向
    g_dma_handler.Init.MemoryDataAlignment = DMA_MDATAALIGN_BYTE; //数据传输宽度
    g_dma_handler.Init.MemInc = DMA_MINC_ENABLE; // 数据传输增量,当传输完一个数据后,要移动到下一个数据
    g_dma_handler.Init.Mode = DMA_NORMAL; //不支持循环模式
    g_dma_handler.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
    g_dma_handler.Init.PeriphInc = DMA_PINC_ENABLE; // 数据接受增量,当接受完一个数据后,要移动到下一个数据
    g_dma_handler.Init.Priority = DMA_PRIORITY_HIGH;

    HAL_DMA_Init(&g_dma_handler);

    HAL_DMA_Start(&g_dma_handler, (uint32_t)src_buf, (uint32_t)dst_buf, 0);
}

void dma_enable_transmit(uint16_t cndtr){ //参数为传输内容长度

    __HAL_DMA_DISABLE(&g_dma_handler);
    g_dma_handler.Instance->CNDTR = cndtr; //(DMA1_Channel1->CNDTR = cndtr;)也可以
    __HAL_DMA_ENABLE(&g_dma_handler);
}

再编写函数头文件dma.h:

#ifndef __DMA_H
#define __DMA_H

DMA_HandleTypeDef g_dma_handler;
extern uint8_t src_buf[10];
extern uint8_t dst_buf[10];

void dma_init(void);
void dma_enable_transmit(uint16_t cndtr);

#endif

编写主函数代码main.c:

#include "./SYSTEM/sys/sys.h"
#include "./BSP/LED/led.h"
#include "./SYSTEM/DELAY/delay.h"
#include "./BSP/DMA/dma.h"
#include "./BSP/KEY/key.h"
#include "./BSP/BEEP/beep.h"
#include "string.h"
#include "./BSP/USART/usart.h"


int main(void){

    HAL_Iniy();
    sys_stm32_clock_init(RCC_PLL_MUL9);
    delay_init(72);
    led_init();
    beep_init();
    key_init();
    usart_init(115200);
    LED0(0);

    while(1){
        key = key_scan(0);

        if(key == KEY0_PRES){
            memset(dst_buf, 10, 0);
            dma_enable_transmit(10);

            while(1){ //查询传输情况
                if(__HAL_DMA_GET_FLAG(&g_dma_handler, DMA_FLAG_TC1)){
                    __HAL_DMA_CLEAR_FLAG(&g_dma_handler, DMA_FLAG_TC1);
                    printf("传输完成\n");
                    break;
                }
            }
        }
        LED0_TOGGLE();
        delay_ms(200);
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值