首页 >> 人物 >> 搞笔记本电脑,不懂DMA?笑死人。。。

搞笔记本电脑,不懂DMA?笑死人。。。

2024-02-08 人物

2和SDIO)显现出的5个恳求,经形式化或载入到DMA2装隶,其中都每个出口处都相同着具体原因的除此以外:

这些在右侧控制系统框图中都也可以清晰地认出

DMA兼职控制系统框图

上方的框图,我们可以认出STM32操作新方法控制系统,驱动器设备,除此以外及DMA的连接起来,这些显卡最终通过各种各样的线连接起来到链路矩阵中都,显卡结构上二者之在在的原始数据分散都经过链路矩阵的协商,使各个除此以外共处的用于链路来调制解调内隶。我们对他来透过一点一点的归纳:

上头看有与未DMA的原因下,ADC搜集的原始数据是怎样寄存到SRAM中都的?

未DMA

1.如果未DMA,CPU调制解调内隶还要以操作新方法控制系统作为中都转站,比如要将ADC搜集的原始数据分散到到SRAM中都,这个反复是这样的:

操作新方法控制系统通过DCode经过链路矩阵协商,从赚取AHB驱动器的除此以外ADC搜集的原始数据,

然后操作新方法控制系统日后通过DCode经过链路矩阵协商把原始数据寄存到线程SRAM中都。

在这里插入图像描述

有DMA原始数据传输

有DMA的话,

DMA原始数据传输时除此以外对DMA装隶发出恳求。DMA装隶收到恳求,触发DMA兼职。DMA装隶从AHB除此以外赚取ADC搜集的原始数据,驱动器到DMA出口处中都DMA装隶的DMA链路与链路矩阵协商,用于AHB把除此以外ADC搜集的原始数据经由DMA出口处寄存到SRAM中都,这个原始数据的原始数据传输反复中都,无论如何不必需操作新方法控制系统的作准备,也就是不必需CPU的作准备,

在这里插入图像描述

我们把上面的步骤专业一点简述:

在暴发一个事件后,除此以外向DMA装隶发去取一个恳求波形。DMA装隶根据出口处的有条件处理恳求。当DMA装隶开始采访发出恳求的除此以外时,DMA装隶几天后发去取给它一个这样的话波形。当从DMA装隶得到这样的话波形时,除此以外几天后囚禁它的恳求。一旦除此以外囚禁了这个恳求,DMA装隶同时恢复原这样的话波形。DMA原始数据传输落幕,如果有不够多的恳求时,除此以外可以顺利完成下一个周期性。

总之,每次DMA传去取由3个操作新方法组已成:

从除此以外原始数据codice_或者从这两项除此以外/驱动器设备住新址codice_请示的驱动器设备住新址取原始数据,第一次原始数据传输时的开始住新址是DMA_CPARx或DMA_CMARxcodice_均须的除此以外恩住新址或驱动器设备区块;存原始数据到除此以外原始数据codice_或者这两项除此以外/驱动器设备住新址codice_请示的驱动器设备住新址,第一次原始数据传输时的开始住新址是DMA_CPARx或DMA_CMARxcodice_均须的除此以外恩住新址或驱动器设备区块;分派一次DMA_CNDTRxcodice_的增极低操作新方法,该codice_还包括未完已成的操作新方法比率。DMA原始数据传输方式

新方法1:DMA_Mode_Normal,原因右侧式也,

当一次DMA原始数据传输速率完后,中断DMA传去取 ,也就是只原始数据传输一次 新方法2:DMA_Mode_Circular ,反向原始数据传输方式也

当原始数据传输落幕时,显卡自动上会将调制解调内隶需求量codice_透过重装,透过下一轮的原始数据传输速率。也就是多次原始数据传输方式也

一致同意内隶

一致同意内隶的发挥作用是确定各个DMA原始数据传输的码率

一致同意内隶根据出口处恳求的码率来顺利完成除此以外/驱动器设备的采访。

有条件管理制度分2个收尾:

插件:每个出口处的有条件可以在DMA_CCRxcodice_中都增设,有4个等级:

最极低码率极低码率中都等码率低码率;

显卡:如果2个恳求有不同的插件码率,则较差A的出口处来得极低A的出口处有较极低的有条件。比如:如果插件码率不同,出口处2须要于出口处4。

肯定:在大容需求量厂家和物联网标准型厂家中都,DMA1装隶拥有极低于DMA2装隶的码率。

DMA原始冗余(至少存在于STM32F4 /M4 操作新方法控制系统上)

在增设了DMA的出口处最后,还要必需出口处相同除此以外的原始冗余

8 个 DMA 装隶原始冗余都能够提供者非同和期望二者之在在的单向原始数据传输链路。每个原始冗余可用后都可以分派:● 如之前所述类标准型行政事务:驱动器设备到除此以外、除此以外到驱动器设备或驱动器设备到驱动器设备的原始数据传输。● 双需将类标准型行政事务:用于驱动器设备的两个驱动器设备常量的双需将原始数据传输(当 DMA 即将透过自/至需将的习/写操作新方法时,客户端可以透过至/自其它需将的写/习操作新方法)。要原始数据传输的原始数据需求量(多达 65535)可以编程语言,并与连接起来到除此以外 AHB 端口的除此以外(恳求 DMA 原始数据传输)的非同跨度相关。每个行政事务完已成后,还包括要原始数据传输的原始数据项总需求量的codice_都上会增极低。

DMA_SxCR codice_压制原始冗余到底用于哪一个出口处,每个原始冗余有 8 个出口处可 供必需,每次只能必需其中都一个出口处透过 DMA 原始数据传输。接下来,我们看看 DMA2 的各原始冗余通 道映射表,如表 28.1.1 示意图:

DMA 原始数据传输出口处

每个出口处都可以在有不同住新址的除此以外codice_和驱动器设备住新址二者之在在分派DMA原始数据传输。DMA原始数据传输的原始数据 需求量是可编程语言的,大降至65535。还包括要原始数据传输的原始数据项数需求量的codice_,在每次原始数据传输后增极低。

可编程语言的原始数据需求量:除此以外和驱动器设备的调制解调内隶需求量可以通过DMA_CCRxcodice_中都的PSIZE和MSIZE位编程语言。

常量以此类推方式也

根据 DMA_SxCR codice_中都 PINC 和 MINC 位的稳定状态,除此以外和驱动器设备常量在每次原始数据传输后可以自动向后以此类推或保持常需求量。当增设为这两项方式也时,下一个要原始数据传输的住新址将是之前一个住新址加上这两项取值

通过单个codice_采访除此以外非同或期望原始数据时,严禁以此类推方式也十分依赖于。

如果使能了以此类推方式也,则根据在 DMA_SxCR codice_ PSIZE 或 MSIZE 位中都编程语言的原始数据跨度,下一次原始数据传输的住新址将是之前一次原始数据传输的住新址以此类推 1个原始数据跨度、2个原始数据跨度或 4个原始数据跨度。

驱动器设备到驱动器设备方式也

DMA出口处的操作新方法可以在未除此以外恳求的原因下透过,这种操作新方法就是驱动器设备到驱动器设备方式也。

当增设了DMA_CCRxcodice_中都的MEM2MEM位最后,在插件增设了DMA_CCRxcodice_中都的EN位顺利完成DMA出口处时,DMA原始数据传输将马上开始。当DMA_CNDTRxcodice_变为0时,DMA原始数据传输落幕。驱动器设备到驱动器设备方式也不能与反向方式也同时用于。

这里要肯定至少 DMA2 的除此以外接口可以采访驱动器设备,所以至少 DMA2 装隶背书驱动器设备到驱动器设备的原始数据传输,DMA1 不背书。

驱动器设备到驱动器设备方式也不能与反向方式也同时用于。

DMA暂停

每个DMA出口处都可以在DMA原始数据传输过半、原始数据传输完已成和原始数据传输差错时显现出暂停。为应用的灵活性考虑到,通过增设codice_的各不不同位来打开这些暂停。

使不曾开启,我们也可以通过键入这些位来获得这两项 DMA 原始数据传输的稳定状态。这里我们类似于的是 TCIFx位,即原始冗余 x 的 DMA 原始数据传输完已成与否字样。

可编程语言的原始数据传输速率跨度、移位方式和原始数据体积端 当PSIZE和MSIZE不不同时,DMA模块按照下图透过原始数据移位。

肯定:在大容需求量厂家中都, DMA2 出口处 4 和 DMA2 出口处 5 的暂停被映同一个暂停向需求量上。在物联网标准型厂家 中都, DMA2 出口处 4 和 DMA2 出口处 5 的暂停分别有独立的暂停向需求量。所有其他的 DMA 出口处都有自己的 暂停向需求量

DMA的线程征用

在STM32装隶中都,微处理器采用Cortex-MX架构,链路结构上有了相当大的优化,DMA征用另外的住新址链路,并不上会与CPU的控制系统链路暴发冲突。比如说,DMA的用于不上会制约CPU的开始运行速度

但是要肯定:DMA 装隶和Cortex-M3氘包涵控制系统原始数据链路分派这样一来驱动器设备原始数据传输速率。当CPU和DMA同时采访不同的期望(RAM或除此以外)时,DMA恳求可能上会中断 CPU采访控制系统链路达若干个周期性,链路一致同意内隶分派反向调度,以保证CPU至少可以得到一半的控制系统链路(驱动器设备或除此以外)带宽。

DMA可用一小

此一小我们细分DMAcodice_和DMA库formula_分别简述:

DMAcodice_

DMA可用变需求量包括:出口处住新址、码率、原始数据传输速率斜向、驱动器设备/除此以外原始数据跨度、驱动器设备/除此以外住新址应该这两项、反向方式也、原始数据传输速率需求量。

DMA暂停稳定状态codice_(DMA_ISR)

我们如果开启了 DMA_ISR 中都这些暂停,在降至条件后就上会跳到暂停服务formula_里面去,即使 不曾开启,我们也可以通过键入这些位来获得这两项 DMA 原始数据传输的稳定状态。这里我们类似于的是 TCIFx, 即出口处 DMA 原始数据传输完已成与否的字样。

肯定此codice_为载入codice_,所以在这些位被隶位最后,只 能通过其他的操作新方法来清除。

DMA暂停字样清除codice_(DMA_IFCR)

DMA_IFCR 的各位就是用来清除 DMA_ISR 的相同位的,通过写 0 清除。在 DMA_ISR 被隶位后, 我们需通过向该位codice_相同的位擦除 0 来清除。

DMA出口处x可用codice_(DMA_CCRx)

该codice_压制着 DMA 的很多相关 资讯,包括原始数据跨度、除此以外及驱动器设备的跨度、出口处码率、这两项方式也、原始数据传输斜向、暂停意味着、 使能等都是通过该codice_来增设的。所以 DMA_CCRx 是 DMA 原始数据传输的氘心压制codice_

DMA出口处x原始数据传输数需求量codice_(DMA_CNDTRx)(x = 1…7)

这个codice_压制 DMA 出口处 x 的每次 原始数据传输所要原始数据传输的原始数据需求量。其增设范围为 0~65535。并且该codice_的取值上会随着原始数据传输的透过而减缓, 当该codice_的取值为 0 的时候就都有此次原始数据传输速率仍然全部发去取完已成了。所以可以通过这个寄存 内隶的取值来明白这两项 DMA 原始数据传输的施工进度

DMA出口处x除此以外住新址codice_(DMA_CPARx)(x = 1…7)

该codice_用来驱动器 STM32 除此以外的地 新址,比如我们用于串口 1,那么该codice_需擦除 0x40013804(其实就是BrownUSART1_DR)。如果使 用其他除此以外,就修正已成相应除此以外的住新址就行了。

DMA出口处x可用codice_(DMA_CMARx)

,该codice_和 DMA_CPARx 差不多, 但是是用来捡驱动器设备的住新址的。比如我们用于 SendBuf[5200]操作符来来作驱动器设备,那么我们在 DMA_CMARx 中都擦除BrownSendBuff 就可以了。

DMAcodice_可用方式上

出口处可用反复 上头是可用DMA出口处x的反复(x都有出口处号):

在DMA_CPARxcodice_中都增设除此以外codice_的住新址。暴发除此以外原始数据传输速率恳求时,这个住新址将 是原始数据传输速率的非同或期望。在DMA_CMARxcodice_中都增设原始数据驱动器设备的住新址。暴发除此以外原始数据传输速率恳求时,原始数据传输的数 据将从这个住新址抽出或擦除这个住新址。在DMA_CNDTRxcodice_中都增设要原始数据传输的原始数据需求量。在每个原始数据传输速率后,这个数取值增极低。在DMA_CCRxcodice_的PL[1:0]位中都增设出口处的码率。在DMA_CCRxcodice_中都增设原始数据传输速率的斜向、反向方式也、除此以外和驱动器设备的这两项方式也、外 设和驱动器设备的原始数据跨度、原始数据传输一半显现出暂停或原始数据传输完已成显现出暂停。增设DMA_CCRxcodice_的ENABLE位,顺利完成该出口处。

一旦顺利完成了DMA出口处,它既可积极响应接在该出口处上的除此以外的DMA恳求。当原始数据传输一半的原始数据后,半原始数据传输字样(HTIF)被隶1,当增设了意味着半原始数据传输暂停位(HTIE)时,将显现出 一个暂停恳求。在原始数据传输速率落幕后,原始数据传输完已成字样(TCIF)被隶1,当增设了意味着原始数据传输完已成暂停位 (TCIE)时,将显现出一个暂停恳求。

DMA库formula_

1.DMA堆栈formula_

DMA_DeInit(DMAX_ChannelX);

机能:将DMAyChannelxcodice_的堆栈为其默认取值

脚注:RCC_ResetCmd中都对DMA无定义,因此采用的这样一来操纵DMAcodice_的方式

void DMA_Init(DMA_Channel_typedef* DMAy_Channelx, DMA_InitTypeDef* DMA_Initstruct)

机能:增设要开启的出口处,还有一些变需求量,包括除此以外恩住新址,驱动器设备恩住新址,原始数据传输的原始数据需求量,这两项方式也,原始数据跨度等。

具体原因看右侧结构上体示例简述:

typedef struct { uint32_t DMA_PeripheralBaseAddr; /*增设DMA非同住新址*/ uint32_t DMA_MemoryBaseAddr; /*增设DMA旨在住新址*/ uint32_t DMA_DIR; /* 增设原始数据传输速率斜向,重新考虑在在除此以外载入原始数据到线程还去取从线程载入数 据发去取到除此以外,也就是除此以外是非同地还是旨在地 */ uint32_t DMA_BufferSize; /*增设原始数据传输体积*/ uint32_t DMA_PeripheralInc; /*增设ReceiveBuff住新址应该自增*/ uint32_t DMA_MemoryInc; /*增设调制解调内隶时候线程住新址应该递,必需开启*/ uint32_t DMA_PeripheralDataSize; /*除此以外的原始数据在在距是为字义符串原始数据传输(8bits),半 字义原始数据传输(16bits) 还是字义原始数据传输(32bits) */ uint32_t DMA_MemoryDataSize; /*增设线程的原始数据在在距*/ uint32_t DMA_Mode; /*增设DMA的方式也,原因右侧式也/反向方式也 应该反向发去取*/ uint32_t DMA_Priority; /*增设 DMA 出口处的码率,有低,中都,极低,超极低四种方式也*/ uint32_t DMA_M2M; /*增设应该是驱动器设备到驱动器设备方式也原始数据传输,*/ } DMA_InitTypeDef;

2.DMA使能formula_

void DMA_Cmd(DMA_Channel_TypeDef* DMAy_Channelx, FunctionalState NewState);

机能:使能或者加护DMA除此以外

例如:DMA_Cmd(DMA1_Channel1 , ENABLE); 3.DMA暂停使能formula_

void DMA_ITConfig(DMA_Channel_TypeDef* DMAy_Channelx, uint32_t DMA_IT, FunctionalState NewState);1

机能:可用均须的DMAy出口处x的暂停

脚注:DMA_IT_TC:原始数据传输完已成 DMA_IT_HT:原始数据传输一半 DMA_IT_TE:原始数据传输差错

例如:DMA_ITConfig(DMA1_Channel1 , DMA_IT_TC , ENABLE);

4.增设CNDTRx和习CNDTRxformula_ (出口处调制解调内隶需求量)

void DMA_SetCurrDataCounter(DMA_Channel_TypeDef* DMAy_Channelx, uint16_t DataNumber); uint16_t DMA_GetCurrDataCounter(DMA_Channel_TypeDef* DMAy_Channelx);12

发挥作用:之前者增设DMA出口处的调制解调内隶需求量(DMA始终保持废弃稳定状态);后者赚取这两项DMA出口处原始数据传输这样一来原始数据需求量(DMA始终保持开启稳定状态)。

DMA库formula_可用反复:使能DMA计时:RCC_AHBPeriphClockCmd();堆栈DMA出口处:DMA_Init();//增设出口处;原始数据传输住新址;原始数据传输斜向;调制解调内隶的比率;调制解调内隶跨度;原始数据传输方式也;码率;应该开启驱动器设备到驱动器设备。使能除此以外DMA;以串口为例:使能串口DMA发去取,串口DMA使能formula_。调用formula_:USART_DMACmd();使能DMA出口处原始数据传输;formula_:DMA_Cmd();键入DMA原始数据传输稳定状态。formula_:DMA_GetFlagStatus();赚取这两项这样一来原始数据需求量体积 formula_:DMA_GetCurrDataCounter(DMA1_Channel4);UART DMA原始数据传输

DMA就是一个倾倒工,可以将原始数据从一个位隶倾倒到另一个位隶。以UART为例,如果要接收原始数据,上会触发UART暂停,然后CPU施加压力,在暂停中都通过CPU将UART载入codice_的取值抽出来,寄存到线程中都;而DMA方式,显现出UART暂停后,DMA这样一来作准备,把UART载入codice_的取值倾倒到线程中都,CPU只必需在去核查线程的取值就好了,这样提升了CPU的效率。

DMA示例可用

① DMA堆栈可用

void dma_init(){ DMA_InitTypeDef DMA_InitStructure; RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE); /*DMA可用*/ DMA_InitStructure.DMA_PeripheralBaseAddr = USART1_DR_Base;//串口原始数据codice_住新址 DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)SendBuff; //线程住新址(要原始数据传输的变需求量的常量) DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST; //斜向(从线程到除此以外) DMA_InitStructure.DMA_BufferSize = 500; //原始数据传输内容的体积 DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //除此以外住新址不增 DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //线程住新址自增 DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte ; //除此以外原始数据单位 DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte ; //线程原始数据单位 DMA_InitStructure.DMA_Mode = DMA_Mode_Normal ; //DMA方式也:一次原始数据传输,反向 DMA_InitStructure.DMA_Priority = DMA_Priority_Medium ; //码率:极低 DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; //严禁线程到线程的原始数据传输 DMA_Init(DMA1_Channel4, BrownDMA_InitStructure); //可用DMA1的4出口处 DMA_Cmd(DMA1_Channel4,ENABLE); DMA_SetCurrDataCounter(DMA_CH4,DMA1_MEM_LEN);//DMA出口处的DMA缓存的体积 DMA_ITConfig(DMA1_Channel4,DMA_IT_TC,ENABLE);//可用DMA发去取完已成后显现出暂停 }

DMA暂停

void DMA1_Channel4_IRQHandler(void){ if(DMA_GetFlagStatus(DMA1_FLAG_TC4)==SET) { DMA_ClearFlag(DMA1_FLAG_TC4); }}

mainformula_

#define SEND_BUF_SIZE 500 //发去取原始数据在在距,最出比sizeof(TEXT_TO_SEND)+2的整数倍. u8 SendBuff[SEND_BUF_SIZE]; //发去取原始数据需将const u8 TEXT_TO_SEND[]={"STM32F1 DMA 串口实验"}; uint16_t i;int main(void){ uart_init(115200); //串口堆栈为115200 for(i=0;i<500;i++) { SendBuff[i] =0xaf; } USART_DMACmd(USART1,USART_DMAReq_Tx,ENABLE); //使能串口dma原始数据传输 while(1);}

- END -(来非同:嵌入式Linux)

译者来非同于:程序喵大人

显卡手写,一起进修电容内部设计、PCB内部设计、仿真、调试以及EMC方

不够多干货撰文请其他用户关注:

搞懂元内隶件,就搞懂了电容的一半

一起进修吧:

显卡手写|加群

书面声明:本号对所有原创、刊出撰文的申辩与观点均保持中都立,静止设备撰文至少供观看者进修和交流。撰文、图像等版权归原作者给予,如有侵权,建立联系删除。

类风湿性关节炎有哪些症状
进补肠胃不适怎么缓解好
腹泻吃什么药止泻效果好
拉肚子吃肠炎宁有用吗
EPO
友情链接