STM32学习笔记(九)DMA(Direct memory access controller)

直接存储器读取

DMA简介

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

DMA框图

由图可见,DMA 一共有 DMA1 和 DMA2 两个控制器。DMA1 有7个通道,DMA2 有5个通道。

在存储器和存储器之间传输数据时,可任选通道进行传输;但在外设和存储器之间传输数据时,需要用到专用的通道。

各个通道的 DMA1 请求
各个通道的 DMA2 请求

DMA寄存器

  • 中断状态寄存器 --- ISR(interrupt status register):存放DMA中断的标志位;

    • 注意:若为DMA2,只有低19位有效;
    • 作用---传输错误(TE)标志位:位3,7,11,15,19,23,27,发生传输错误时置1;
    • 作用---半传输(HT)标志位:位2,6,10,14,18,22,26,传输了一半数据并产生对应事件时置1;
    • 作用---传输完成(TC)标志位:位1,5,9,13,17,21,25,传输完成并产生了对应事件时置1;
    • 作用---全局中断(GI)标志位:位0,4,8,12,16,20,24,上述3个寄存器任一寄存器置1,该寄存器置1;
    • 复位值:0x0000 0000
  • 中断标志清除寄存器 --- IFCR(interrupt flag clear register):清除ISR中DMA中断的标志位;

    • 注意:若为DMA2,只有低19位有效;
    • 作用---清除传输错误(TE)标志位:位3,7,11,15,19,23,27,置1时将 TE 置0;
    • 作用---清除半传输(HT)标志位:位2,6,10,14,18,22,26,置1时将 HT 置0;
    • 作用---清除传输完成(TC)标志位:位1,5,9,13,17,21,25,置1时将 TC 置0;
    • 作用---清除全局中断(GI)标志位:位0,4,8,12,16,20,24,置1时将 TE、HT、TC寄存器均置0;
    • 复位值:0x0000 0000
  • 通道x配置寄存器 --- CCRx(channel x configuration register):设置通道x的各项配置;

    • 注意:若为DMA1,该寄存器有7组(即x可为 0~7);DMA2 就只有5组;
    • 作用---开启通道:位0 置1时通道开启,置0时关闭;
    • 作用---允许传输完成(TC)中断:位1,置1时允许产生传输完成中断(可检测TC标志位查看是否产生) ;
    • 作用---允许半传输(HT)中断:位2,置1时允许产生半传输中断;
    • 作用---允许传输错误(TE)中断:位3,置1时允许产生传输错误中断;
    • 作用---设置数据来源:位4,置0时表示从外设读取数据,置1时表示从存储器读取数据;
    • 注意:若是存储器到存储器,则一般把发送存储器当作外设来进行设置,位14 再置1即可;
    • 作用---设置是否循环操作:位5,置0时表示只读取1次数据,置1时表示循环读取该数据;
    • 作用---设置外设地址增量模式:位6,置0时传输数据时外设地址不增加,置1则为增加;
    • 作用---设置存储器地址增量模式:位7,置0时传输数据时存储器地址不增加,置1则为增加;
    • 作用---设置外设数据宽度:位9:8;00为8位,01为16位,10为32位,11为保留;
    • 作用---设置存储器数据宽度:位11:10;00为8位,01为16位,10为32位,11为保留;
    • 作用---设置通道的优先级:位13:12,00为低,01为中,10为高,11为最高;
    • 注意:当通道优先级相同时,DMA1通道比DMA2通道优先级高,DMAx比DMAy通道优先级高(x<y);
    • 作用---设置存储器和存储器之间传输:位14,置0表示是外设和存储器之间传输,置1表示是存储器和存储器之间传输;
    • 复位值:0x0000 0000
  • 通道x传输数量寄存器 --- CNDTRx(channel x number of data register):设置通道x需要传输的数据个数;

    • 注意:若为DMA1,该寄存器有7组(即x可为 0~7);DMA2 就只有5组;
    • 作用---设置需要传输的数据的个数:位15:0,表示需要传输的数据的个数(易知一次最多只能传输65335个数据);
  • DMA通道x外设地址寄存器 --- CPARx(channel x peripheral address register):存储在外设中需要传输的数据的地址;

    • 注意:若为DMA1,该寄存器有7组(即x可为 0~7);DMA2 就只有5组;
    • 作用---存储地址:位31:0,存储在外设中需要传输的数据的地址;
  • DMA通道x存储器地址寄存器 --- CMARx(channel x memory address register):存储在存储器中需要传输的数据的地址;

    • 注意:若为DMA1,该寄存器有7组(即x可为 0~7);DMA2 就只有5组;
    • 作用---存储地址:位31:0,存储在存储器中需要传输的数据的地址;

常用DMA固件库函数 (stm32f10x_dma.h)

USART初始化函数 --- USART_Init

void DMA_Init(DMA_Channel_TypeDef* DMAy_Channelx, DMA_InitTypeDef* DMA_InitStruct);
  • DMAy_Channelx:选择通道端口,y可为 1~2 ,y=1时x可为 1~7 ,y=2时x可为 1~5 ;
  • DMA_InitStructDMA_InitTypeDef 结构体
    • DMA_MemoryBaseAddr:存储器(发送或将要接收的)数据地址;
    • DMA_PeripheralBaseAddr:外设(发送或将要接收的)数据地址;
    • DMA_DIR:数据传输方向,可选 外设为源(PeripheralSRC)、外设为目标(PeripheralDST);
    • DMA_BufferSize:传输的数据的个数,最大为65335;
    • DMA_PeripheralInc:外设是否启动增量模式( Enable 或 Disable);
    • DMA_PeripheralDataSize:外设数据的字长;
    • DMA_MemoryInc:存储器是否启动增量模式( Enable 或 Disable);
    • DMA_MemoryDataSize:存储器数据的字长;
    • DMA_Mode:是否循环传输数据,( Normal 或 Circular );
    • DMA_Priority:该通道优先级,可为 低(Low)、中(Medium)、高(High)、超高(VeryHigh);
    • DMA_M2M:是否是存储器和存储器之间的传输,是(Enable) 或 不是(Disable);
  • 示例:
// DMA_M2M 初始化
//定义DMA初始化结构体
DMA_InitTypeDef DMA_InitStructure;
    
//打开DMA1时钟
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
//配置DMA
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)aSRC_Const_Buffer;         //源数据地址
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)aDST_Buffer;           //目标数据地址
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;                          //设置外设(Flash)为源
    
DMA_InitStructure.DMA_BufferSize = 8;                                       //配置传输数据的个数为8
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Enable;             //外设(源)设置为增量模式
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word;     //外设数据字长设置为32位
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;                     //存储(SRAM)设置为增量模式
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Word;             //存储数据字长设置为32位

DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;                               //只发送一次数据(非循环发送)
DMA_InitStructure.DMA_Priority = DMA_Priority_High;                         //设置为高优先级
DMA_InitStructure.DMA_M2M = DMA_M2M_Enable;                                 //打开 M2M

//初始化DMA通道
DMA_Init(DMA1_Channel6, &DMA_InitStructure);

DMA清除标志位函数 --- DMA_ClearFlag

void DMA_ClearFlag(uint32_t DMAy_FLAG);
  • DMAy_FLAG:对应的标志位,y可以为 1~2 ;
    DMA1的标志位

DMA通道使能函数 --- DMA_Cmd

DMA_Cmd(DMA_Channel_TypeDef* DMAy_Channelx, FunctionalState NewState);
  • DMAy_Channelx:选择通道端口,y可为 1~2 ,y=1时x可为 1~7 ,y=2时x可为 1~5 ;
  • NewState:使能或关闭,ENABLE、DISABLE;
  • 示例:
//使能DMA1的通道6
DMA_Cmd(DMA1_Channel6, ENABLE);

DMA获取标志位函数 --- DMA_GetFlagStatus

FlagStatus DMA_GetFlagStatus(uint32_t DMAy_FLAG);
  • DMAy_FLAG:对应的标志位,y可以为 1~2;
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 200,667评论 5 472
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,361评论 2 377
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 147,700评论 0 333
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,027评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,988评论 5 361
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,230评论 1 277
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,705评论 3 393
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,366评论 0 255
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,496评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,405评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,453评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,126评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,725评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,803评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,015评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,514评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,111评论 2 341

推荐阅读更多精彩内容