查看: 1381|回复: 0
收起左侧

第二十七章:CH32V103应用教程——DMA(存储器到外设)

[复制链接]

  离线 

  • TA的每日心情
    慵懒
    2021-7-23 17:16
  • 签到天数: 17 天

    [LV.4]

    发表于 2021-4-25 21:53:17 | 显示全部楼层 |阅读模式

    有人预言,RISC-V或将是继Intel和Arm之后的第三大主流处理器体系。欢迎访问全球首家只专注于RISC-V单片机行业应用的中文网站

    您需要 登录 才可以下载或查看,没有帐号?立即注册

    x
    本帖最后由 草帽王子 于 2021-9-10 17:11 编辑

    关于DMA,具有三种数据传输方式:存储器到存储器、存储器到外设、外设到存储器。前面已讲解过关于存储器到存储器数据传输方式,本章将讲解存储器到外设的传输方式以及在下一章将会讲解外设到存储器的传输方式。关于DMA存储器到外设传输方式,程序中,首先定义一个静态的源数据,存放在内部 FLASH中,然后通过DMA的方式传输到串口的数据寄存器,然后通过串口把这些数据发送到电脑的上位机显示出来。


    1、DMA简介及相关函数介绍


    直接存储器访问控制器(DMA)提供在外设和存储器之间或者存储器和存储器之间的高速数据传输方式,无须CPU干预,数据可以通过DMA快速地移动,以节省CPU的资源来做其他操作。

    DMA控制器有7个通道,每个通道专门用来管理来自于一个或多个外设对存储器访问的请求。还有一个仲裁器来协调各通道之间的优先级。

    DMA作为一种高效、高速的数据传输方式,具有以下几个特性:

    • 具有7个独立可配置通道,且每个通道都连接专用的硬件DMA请求,并支持软件触发
    • 支持循环的缓冲器管理
    • 多个通道之间的请求优先权可以通过软件编程设置(最高、高、中和低),优先权设置相等时由通道号决定(通道号低优先级高)
    • 支持三种传输方式:存储器到存储器、存储器到外设、外设到存储器
    • 闪存、SRAM、外设的SRAM、APB1、APB2和AHB外设均可作为访问的源和目标
    • 独立数据源独立数据源和目标数据区的传输宽度(字节、半字、全字),模拟打包和拆包的过程。源和目标地址必须按数据传输宽度对齐。
    • 每个通道都有3个事件标志(DMA传输过半、DMA传输完成和DMA传输错误),这3个事件标志逻辑或成为一个单独的中断请求

    关于DMA具体信息,可参考CH32V103应用手册。DMA标准库函数第十三章已做过介绍,在此不再赘述。



    2、硬件设计

    本章教程所用资源均为CH32V103开发板内部资源,无需进行其他硬件连接,只需进行程序配置即可。


    3、软件设计
    .
    本章主要进行存储器到外设的DMA数据传输方式,其相较于存储器到存储器的传输方式,程序中对DMA配置进行一些修改即可,具体如下:


    dma.h文件
    1. #ifndef __DMA_H
    2. #define __DMA_H

    3. #include "ch32v10x_conf.h"

    4. void DMA1_CH4_Init(void); //DMA传输参数初始化配置

    5. #endif
    复制代码
    dma.h文件主要进行函数声明;

    dma.c文件
    1. #include "dma.h"

    2. u8 SRC_BUF[]= "DMA test: from memory to peripheral";
    3. #define TxSize1   (sizeof(SRC_BUF))

    4. /*******************************************************************************
    5. * Function Name  : DMA1_CH4_Init
    6. * Description    : Initializes Channel4 of DMA1 collection.
    7. * Input          : None
    8. * Return         : None
    9. *******************************************************************************/
    10. //DMA1通道4传输参数配置
    11. void DMA1_CH4_Init(void)
    12. {
    13.   DMA_InitTypeDef DMA_InitStructure;
    14.   RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);        //使能DMA1时钟

    15.   DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)(&USART1->DATAR);   //设置外设地址(外设串口1)
    16.   DMA_InitStructure.DMA_MemoryBaseAddr = (u32)(SRC_BUF);     //设置存储器地址
    17.   DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;            //设置传输方向:存储器到外设
    18.   DMA_InitStructure.DMA_BufferSize = TxSize1;                            //设置传输大小
    19.   DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;          //指定外设地址不变。
    20.   DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;                //指定存储器地址递增。
    21.   DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; //设置外设数据单位
    22.   DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;       //设置存储器数据单位
    23.   DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;              //设置对应DMA工作模式为正常模式
    24.   DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;       //设置DMA1通道4优先级
    25.   DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;                //禁止使能DMA存储器到存储器的传输方式
    26.   DMA_Init(DMA1_Channel4, &DMA_InitStructure);                    //根据DMA_InitStruct中指定的参数初始化DMA1通道4
    27.   DMA_ClearFlag(DMA1_FLAG_TC4);   //清除DMA1通道4传输完成挂起标志

    28.   DMA_Cmd(DMA1_Channel4, ENABLE); //使能DMA1通道4
    29. }

    复制代码
    dma.c文件主要进行DMA传输参数初始化配置。DMA存储器到外设传输方式,相较于存储器到存储器传输方式,具体修改如下:

    关于目标地址,改为外设地址,此处为串口1:
    1. DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)(&USART1->DATAR);
    复制代码

    关于源地址,改为存储器地址:
    1. DMA_InitStructure.DMA_MemoryBaseAddr = (u32)(SRC_BUF);
    复制代码

    关于DMA传输方式及方向,改为存储器到外设:
    1. DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
    复制代码

    关于DMA传输大小,根据源数据进行设置:
    1. DMA_InitStructure.DMA_BufferSize = TxSize1;
    复制代码

    关于DMA外设地址,设置外设地址不变:
    1. DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
    复制代码

    关于DMA存储器地址,与之前一样,设置存储器地址递增:
    1. DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
    复制代码

    关于DMA存储器数据单位和外设数据单位,设为一样,与之前一致:
    1. DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; //设置外设数据单位
    2. DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;       //设置存储器数据单位
    复制代码

    关于DMA工作模式以及DMA通道优先级,与之前一致:
    1. DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;              //设置对应DMA工作模式为正常模式
    2. DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;       //设置DMA1通道4优先级
    复制代码

    关于DMA传输方式及传输方向使能,禁止使能DMA存储器到存储器传输方式:
    1. DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
    复制代码

    此外,由CH32V103应用手册可知,本次所用外设串口1对应DMA通道4,如下图:

    CH32V CH573单片机芯片-第二十七章:CH32V103应用教程——DMA(存储器到外设)risc-v单片机中文社区(1)

    因此,初始化以及使能DMA通道4:
    1. DMA_Init(DMA1_Channel4, &DMA_InitStructure);                  //根据DMA_InitStruct中指定的参数初始化DMA1通道4
    2. DMA_ClearFlag(DMA1_FLAG_TC4);   //清除DMA1通道4传输完成挂起标志
    3. DMA_Cmd(DMA1_Channel4, ENABLE); //使能DMA1通道4
    复制代码


    4、下载验证
    .
    将编译好的程序下载到开发板并复位,可见存储器存储数据被发送到串口:

    CH32V CH573单片机芯片-第二十七章:CH32V103应用教程——DMA(存储器到外设)risc-v单片机中文社区(2)

    DMA(存储器到外设).rar附件下载
    CH32V CH573单片机芯片-第二十七章:CH32V103应用教程——DMA(存储器到外设)risc-v单片机中文社区(3) 26、DMA(存储器到外设).rar (463.59 KB, 下载次数: 19)
    链接:https://pan.baidu.com/s/1SyJmMouNVhpcip9lqsz1Ug
    提取码:hx9l
    复制这段内容后打开百度网盘手机App,操作更方便哦







    上一篇:第二十六章:CH32V103应用教程——FATFS文件系统(SD卡)
    下一篇:第二十八章:CH32V103应用教程——DMA(外设到存储器)
    RISCV作者优文
    全球首家只专注于RISC-V单片机行业应用的中文网站
    回复

    使用道具 举报

    高级模式
    B Color Image Link Quote Code Smilies

    本版积分规则

    关闭

    RISC-V单片机中文网上一条 /2 下一条



    版权及免责声明|RISC-V单片机中文网 |网站地图

    GMT+8, 2024-11-26 09:54 , Processed in 0.270555 second(s), 47 queries .

    快速回复 返回顶部 返回列表