USART与DMA的区别与联系
STM32笔记---DMA(USART)的演示
分类:编程语言/Flash/文章
这里有个小小的例子,来演示DMA模块与系统程序并行工作。
用串口以低波特率发送一个10K的数据,花费近10s时间,此时按照以往方法,CPU 要不断等待数据发送、送数据;或者送数据、进中断、送数据,处理起来比较消耗时间。
使用了DMA功能以后,用户程序中只需配置好DMA,开启传输后,再也不需要操心,10K数据完成后会有标志位或中断产生,期间可以做任何想做的事,非常方便。
这个是相应的代码例子,基于STM32F103VBT6
/******************************************************************************
* 本文件实现串口发送功能(通过重构putchar函数,调用printf;或者USART_SendData() * 这里是一个用串口实现大量数据传输的例子,使用了DMA模块进行内存到USART的传输
* 每当USART的发送缓冲区空时,USART模块产生一个DMA事件,
* 此时DMA模块响应该事件,自动从预先定义好的发送缓冲区中拿出下一个字节送给USART
* 整个过程无需用户程序干预,用户只需启动DMA传输传输即可
* 在仿真器调试时,可以在数据传输过程中暂停运行,此时DMA模块并没有停止
* 串口依然发送,表明DMA传输是一个独立的过程。
* 同时开启接收中断,在串口中断中将数据存入缓冲区,在main主循环中处理
* 作者:jjldc(九九)
* 代码硬件基于万利199元的EK-STM32F开发板,CPU=STM32F103VBT6
*******************************************************************************/
/* Includes ------------------------------------------------------------------*/
#include "stm32f10x_lib.h"
#include "stdio.h"
/* Private typedef -----------------------------------------------------------*/ /* Private define ------------------------------------------------------------*/
#define USART1_DR_Base 0x40013804
/* Private macro -------------------------------------------------------------*/ /* Private variables ---------------------------------------------------------*/
#define SENDBUFF_SIZE 10240
vu8 SendBuff[SENDBUFF_SIZE];
vu8 RecvBuff[10];
vu8 recv_ptr;
/* Private function prototypes -----------------------------------------------*/ void RCC_Configuration(void);
void GPIO_Configuration(void);
void NVIC_Configuration(void);
void DMA_Configuration(void);
void USART1_Configuration(void);
int fputc(int ch, FILE *f);
void Delay(void);
/* Private functions ---------------------------------------------------------*/ /******************************************************************************* * Function Name : main
* Description : Main program.
* Input : None
* Output : None
* Return : None
*******************************************************************************/ int main(void)
{
u16 i;
#ifdef DEBUG
debug();
#endif
recv_ptr = 0;
RCC_Configuration();
GPIO_Configuration();
NVIC_Configuration();
DMA_Configuration();
USART1_Configuration();
printf("/r/nSystem Start.../r/n");
printf("Initialling SendBuff... /r/n");
for(i=0;i { SendBuff[i] = i&0xff; } printf("Initial success!/r/nWaiting for transmission.../r/n"); //发送去数据已经准备好,按下按键即开始传输 while(GPIO_ReadInputDataBit(GPIOD, GPIO_Pin_3)); printf("Start DMA transmission!/r/n"); //这里是开始DMA传输前的一些准备工作,将USART1模块设置成DMA方式工作USART_DMACmd(USART1, USART_DMAReq_Tx, ENABLE); //开始一次DMA传输! DMA_Cmd(DMA1_Channel4, ENABLE); //等待DMA传输完成,此时我们来做另外一些事,点灯 //实际应用中,传输数据期间,可以执行另外的任务 while(DMA_GetFlagStatus(DMA1_FLAG_TC4) == RESET) { LED_1_REV; //LED翻转 Delay(); //浪费时间 } //DMA传输结束后,自动关闭了DMA通道,而无需手动关闭 //下面的语句被注释 //DMA_Cmd(DMA1_Channel4, DISABLE); printf("/r/nDMA transmission successful!/r/n"); /* Infinite loop */ while (1) { } } /******************************************************************************* * Function Name : 重定义系统putchar函数int fputc(int ch, FILE *f) * Description : 串口发一个字节 * Input : int ch, FILE *f * Output : * Return : int ch * 这个是使用printf的关键 *******************************************************************************/ int fputc(int ch, FILE *f) { //USART_SendData(USART1, (u8) ch); USART1->DR = (u8) ch; /* Loop until the end of transmission */ while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET) { } return ch; } /******************************************************************************* * Function Name : Delay * Description : 延时函数 * Input : None * Output : None * Return : None *******************************************************************************/ void Delay(void) { u32 i; for(i=0;i<0xF0000;i++); return; } /******************************************************************************* * Function Name : RCC_Configuration * Description : 系统时钟设置 * Input : None * Output : None * Return : None *******************************************************************************/ void RCC_Configuration(void) { ErrorStatus HSEStartUpStatus; //使能外部晶振 RCC_HSEConfig(RCC_HSE_ON); //等待外部晶振稳定 HSEStartUpStatus = RCC_WaitForHSEStartUp(); //如果外部晶振启动成功,则进行下一步操作 if(HSEStartUpStatus==SUCCESS) { //设置HCLK(AHB时钟)=SYSCLK RCC_HCLKConfig(RCC_SYSCLK_Div1); //PCLK1(APB1) = HCLK/2 RCC_PCLK1Config(RCC_HCLK_Div2); //PCLK2(APB2) = HCLK RCC_PCLK2Config(RCC_HCLK_Div1); //FLASH时序控制 //推荐值:SYSCLK = 0~24MHz Latency=0 // SYSCLK = 24~48MHz Latency=1 // SYSCLK = 48~72MHz Latency=2 FLASH_SetLatency(FLASH_Latency_2); //开启FLASH预取指功能 FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable); //PLL设置SYSCLK/1 * 9 = 8*1*9 = 72MHz RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9); //启动PLL RCC_PLLCmd(ENABLE); //等待PLL稳定 while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET); //系统时钟SYSCLK来自PLL输出 RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK); //切换时钟后等待系统时钟稳定 while(RCC_GetSYSCLKSource()!=0x08); /* //设置系统SYSCLK时钟为HSE输入 RCC_SYSCLKConfig(RCC_SYSCLKSource_HSE); //等待时钟切换成功 while(RCC_GetSYSCLKSource() != 0x04); */ } //下面是给各模块开启时钟 //启动GPIO RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | / RCC_APB2Periph_GPIOC | RCC_APB2Periph_GPIOD,/ ENABLE); //启动AFIO RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); //启动USART1 RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE); //启动DMA时钟 RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); } /******************************************************************************* * Function Name : GPIO_Configuration * Description : GPIO设置 * Input : None * Output : None * Return : None *******************************************************************************/ void GPIO_Configuration(void) { GPIO_InitTypeDef GPIO_InitStructure; //PC口4567脚设置GPIO输出,推挽2M GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz; GPIO_Init(GPIOC, &GPIO_InitStructure); //KEY2 KEY3 JOYKEY //位于PD口的3 4 11-15脚,使能设置为输入 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_11 | GPIO_Pin_12 |/ GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_Init(GPIOD, &GPIO_InitStructure); //USART1_TX GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_Init(GPIOA, &GPIO_InitStructure); //USART1_RX GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_Init(GPIOA, &GPIO_InitStructure); } /******************************************************************************* * Function Name : NVIC_Configuration * Description : NVIC设置 * Input : None * Output : None * Return : None *******************************************************************************/ void NVIC_Configuration(void) { NVIC_InitTypeDef NVIC_InitStructure; #ifdef VECT_TAB_RAM // Set the Vector Table base location at 0x20000000 NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x0); #else /* VECT_TAB_FLASH */ // Set the Vector Table base location at 0x08000000 NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0); #endif //设置NVIC优先级分组为Group2:0-3抢占式优先级,0-3的响应式优先级NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //串口接收中断打开 NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQChannel; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); } /******************************************************************************* * Function Name : USART1_Configuration * Description : NUSART1设置 * Input : None * Output : None * Return : None *******************************************************************************/ void USART1_Configuration(void) { USART_InitTypeDef USART_InitStructure; USART_https://www.360docs.net/doc/fa18251587.html,ART_BaudRate = 9600; USART_https://www.360docs.net/doc/fa18251587.html,ART_WordLength = USART_WordLength_8b; USART_https://www.360docs.net/doc/fa18251587.html,ART_StopBits = USART_StopBits_1; USART_https://www.360docs.net/doc/fa18251587.html,ART_Parity = USART_Parity_No; USART_https://www.360docs.net/doc/fa18251587.html,ART_HardwareFlowControl = USART_HardwareFlowControl_None; USART_https://www.360docs.net/doc/fa18251587.html,ART_Mode = USART_Mode_Tx | USART_Mode_Rx; USART_Init(USART1, &USART_InitStructure); USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); USART_Cmd(USART1, ENABLE); } void DMA_Configuration(void) { DMA_InitTypeDef DMA_InitStructure; //DMA设置: //设置DMA源:内存地址&串口数据寄存器地址 //方向:内存-->外设 //每次传输位:8bit //传输大小DMA_BufferSize=SENDBUFF_SIZE //地址自增模式:外设地址不增,内存地址自增1 //DMA模式:一次传输,非循环 //优先级:中 DMA_DeInit(DMA1_Channel4); DMA_InitStructure.DMA_PeripheralBaseAddr = USART1_DR_Base; DMA_InitStructure.DMA_MemoryBaseAddr = (u32)SendBuff; DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST; DMA_InitStructure.DMA_BufferSize = SENDBUFF_SIZE; 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_InitStructure.DMA_Priority = DMA_Priority_Medium; DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; DMA_Init(DMA1_Channel4, &DMA_InitStructure); } 复习思考题 第章DMA控制器 1.试说明在DMA方式时内存往外设传输数据的过程。 2.对一个DMA控制器的初始化工作包括哪些内容? 3.DMA控制器8237A什么时候作为主模块工作?什么时候作为从模块工作?在这两种情况下,各控制信号处于什么状态? 4.8237A有哪几种工作方式?各自用在什么场合? 5.什么叫DMA控制器的自动预置功能?这种功能是用得很普遍的,举一个例子说明它的使用场合。 6.用DMA控制器进行内存到内存的传输时,有什么特点? 7.DMA控制器8237A是怎样进行优先级管理的? 8.设计8237A的初始化程序。8237A的端口地址为0000-000FH,设通道0工作在块传输模式,地址加1变化,自动预置功能;通道1工作于单字节读传输,地址减1变化,无自动预置功能;通道2、通道3和通道1工作于相同方式。然后对8237A设控制命令,使DACK 为高电平有效,DREQ为低电平有效,用固定优先级方式,并启动8237A工作。9.CPU对DMA控制器的总线请求响应要比对中断请求响应快,请分析其原因。10.8237A在进行单字节方式DMA传输和块方式DMA传输时,有什么区别? 11.什么是DMA传送?DMA传送与中断方式传送的基本区别是什么? 12.8237A在实行存储器与存储器之间传输时,与存储器和外设之间的传输有什么不同?13.8237A采用压缩时序方式,试估算在最好情况下传送10KB数据需要多少时间?再试用最高效的程序衽同样数量数据的传输,大约要多少时间?(时钟都以5MHz算) 14.8237A为了在16位以上的微机系统中应用,必须设计适当的页面地址寄存器。如个人计算机中那样设计,请问: (1)如何知道什么时候该换页?如何换页? (2) 换页时应对DMA控制器作什么处理? (3) 如果通道0也需要页面地址,如何获得RA、RB的控制信号? 15.在个人计算机中8237A的通道2为什么设置成单字节传送?如果用成块传送会发生什么问题?如何解决? 16.ADSTB信号与AEN有什么不同?它们各自起什么作用? 17.一个系统需要接6个用DMA控制的外设,如何用8237A实现这个系统的连接,请画出连接图,并说明方式控制字应如何设置。如用固定优先级请列出你所设计方案中6个设备的优先级排列。 18.用简化框图形式表示一个DMA系统的基本构成,请标明DMA控制器与CPU、系统总线及外设连接的关键信号。 19.8237A上设有一个READY控制端以适应慢速存储器或外设的需要,这是否与DMA的快速传送宗旨相违背?为什么? 20.DMA操作过程中,DMA控制器将代替CPU控制系统总路线,根据它的这一任务,请列出DMA控制器必须具有的几项功能。 21.单字节传送、成组传送与请示传送三种DMA方式在传送方式、DMA请示方面有什么差别? 22.图中是一个DMA系统框图,DMA控制器是个可编程器件,外设也由一个可编程接口电路控制。请在各框图间连上必要的线,并标明它胶的名称。(附图6-55) DMA简介(1) DMA,全称为:Direct Memory Access(即直接存储器访问),DMA 用来提供在外设和存储器之间、存储器和存储器之间的高速数据传输。当CPU 初始化这个传输动作,传输动作本身是由DMA控制器来实行和完成。DMA传输对于高效能嵌入式系统算法和网络是很重要的,因为DMA 传输方式无需CPU 直接控制传输,也没有中断处理方式那样保留现场和恢复现场的过程,而是直接通过硬件为RAM 与I/O 设备开辟一条直接传送数据的通路,能使CPU 的效率大为提高。 STM32 最多有2 个DMA 控制器(DMA2 仅存在大容量产品中),DMA1 有7 个通道(如上图所示),DMA2 有5个通道。每个通道专门用来管理来自于一个或多个外设对存储器访问的请求。例如,在通道1 上有以下几个DMA请求:ADC1、TIM2_CH3、TIM4_CH1。 由上可知,每一条独立的DMA通道都对应着若干个可以产生DMA请求的置外设,这些DMA请求信号通过逻辑或后输出到对应的DMA通道上,如通道1就是由ADC1、TIM2_CH3和TIM4_CH1产生的DMA 请求信号通过逻辑或后输出到通道1上,所以每一条通道任意一个时刻只能输出一个DMA请求(由于逻辑或是只要有一个请求信号便会输出到通道上,意味着在出现两个或以上的DMA请求信号的情况下无法分别到底是哪个外设的请求,因此,我们在使用某一条通道时,应尽可能做到只有一个外设的DMA请求或者时分复用)。 仲裁器是用来协调各个DMA 通道的优先级(这里我们所说的优先级指的是DMA通道的优先级,而不是来自外设的DMA请求的优先级)。然后,再由仲裁器根据优先级来处理各个通道的 从外设(TIMx、ADC、SPIx、I2Cx 和USARTx)产生的DMA 请求,通过逻辑或输入到DMA 控制器,这就意味着同时只能有一个请求有效(从7个通道输出的请求信号只有一个有效)。外设的DMA 请求可以通过设置相应的外设寄存器中的控制位,被独立地开启或关闭。下表是DMA1 各通道一览表: 1.试说明在DMA方式时内存往外设传输数据的过程。 答:当一个接口要由内存往其输出数据时,就往DMA 控制器发一个DMA 请求;DMA 控制器接到请求以后,便往控制总线上发一个总线请求;若CPU 允许让出总线便发出一个总线允许信号;DMA 控制器接到此信号后,就将地址寄存器的内容送到地址总线上,同时往接口发一个DMA 回答信号并发一个I/O 写信号和一个内存读信号;内存接到读信号后将数据送到数据总线,I/O 写信号将数据送到接口,并撤除DMA 请求信号,于是DMA 控制器的地址寄存器的内容加1 或减1,计数器的值减1,而且撤除总线请求信号,就完成了对一个数据的DMA 输出传输。 2.对一个DMA控制器的初始化工作包括哪些内容? 答:①将数据传输缓冲区的起始地址或者结束地址送到地址寄存器中; ②将传输的字节数或字数送到计数器中。 ③通过模式寄存器设置工作方式等。 3.DMA控制器8237A什么时候作为主模块工作?什么时候作为从模块工作?在这两种情况下,各控制信号处于什么状态? 答:1.在外设向8237A 发DMA 请求,8237A 向CPU 发总线请求得到CPU 总线允许时,获得了总线控制权就作为总线主模块工作。2.当CPU 把数据送到8237A 的寄存器或者从8237A 的寄存器取出时,8237A 就象I/O接口一样作为总线的从模块工作。3.主模块工作时的控制信号:DREQx 有效,HRQ 高,HLDA 高,DACKx 有效,AEN高,IOR、MEMW 或IOW、MEMR有效,16位地址送地址总线。从模块工作时的控制信号:CS和HRQ为低,A3 ~A0 为某一确定值,IOR或IOW有效。 第十章DMA控制器8237A 1.试说明在DMA方式下,传输单个数据的全过程。 答:内存往外设传输单个数据: (1)当一个接口准备就绪,要进行DMA传输时,该接口往DMA 控制器发一个DMA请求; (2)DMA控制器采样到DRED有效电平后,若屏蔽寄存器是开放的,便往控制总线上发一个总线保持请求; (3)若CPU允许让出总线,则发回一个总线保持允许信号;(4)DMA控制器接到此信号后,就将其内部地址寄存器的内容送到地址总线上; (5)同时,DMA控制器往接口发一个DMA回答信号,并发出一个内存读信号和一个I/O写信号; (6)接口收到DMA回答信号后,撤除DMA请求信号,且内存把数据送到数据总线上; (7)接口锁存数据总线上的数据后,一般往DMA控制器回送一个准备好信号; (8)DMA控制器的地址寄存器内容加1或减1,字节计数器的值减1; (9)DMA控制器撤除总线保持请求信号,CPU收回总线控制权。这样,就完成了对一个数据的DMA输出过程。 外设往内存传输单个数据的过程: (1)当一个接口中有数据要输入时,就往DMA控制器发一个DMA 请求信号; (2)DMA控制器接到DMA请求后,(若屏蔽触发器是开放的)便往控制总线上发一个总线保持请求信号; (3)若CPU允许让出总线,则发回一个总线保持允许信号;(4)DMA控制器接到此信号后,就将其内部地址寄存器的内容送到 地址总线上; (5)同时,DMA控制器往接口发一个DMA回答信号,并发一个I /O读信号和一个内存写信号; (6)接口收到DMA回答信号后,撤除DMA请求信号,并将数据送到数据总线上; (7)内存在收到数据后,一般往DMA控制器回送一个准备好信号;(8)DMA控制器的地址寄存器内容加1或减1,字节计数器的值减1; (9)DMA控制器撤除总线保持请求信号,CPU收回总线控制权。这样,就完成了对一个数据的DMA输入过程。 2.为使DMA控制器正常工作,系统对DMA控制器进行初始化的过程分为哪两个主要方面? 答: (1) 将数据传输缓冲区的起始地址或结束地址送到地址寄存器中; (2) 将传输的字节数或字数送到计数器中。 3.8237A什么时候作为主模块工作?什么时候作为从模块工作?在这两种情况下,各控制信号处于什么状态? 答:当DMA控制器得到总线控制权,可以控制系统总线时,便成为总线主模块;当DMA控制器接受CPU对它的读写操作时,便成了总线从模块。 作总线主模块时:它会往总线上提供要访问的内存地址,地址的低八位放在A0 ~ A7上,地址的高八位放在DB0~DB7上,此时,AEN信号为有效的高电平,存储器读和I/O写有效,或者存储器写和I/O读有效。 作总线从模块时:8237A接收16位地址,用较高的12位地址产生片选信号,据此判断本片是否被选中,用低4位地址来选择内部寄存器。片选信号为有效的低电平,HRQ和AEN都为无效的低电平,I/O读 中图分类号:TP332文献标识码:A文章编号:1009-2552(2011)03-0042-05 嵌入式音频处理器中DMA控制器的设计 王俊,应忍冬 (上海交通大学电子工程系,上海200240) 摘要:高性能的DMA控制器是音视频等多媒体处理器的重要组成部分。通过分析DMA控制器在嵌入式音频处理HiPAP中担负的数据传输任务及数据特点,设计了面向AMBA AHB总线的双通道高性能的DMA控制器。在FPGA平台上的实际运行结果显示,该DMA控制器的数据传输性能比使用CPU至少提升了45%。 关键词:DMA;控制器;AHB Design of DMA controller in embedded audio processor WANG Jun,YING Ren-dong (Department of Electronic Engineering,Shanghai Jiaotong University,Shanghai200240,China) Abstract:High-performance DMA controller is the key component in multimedia processor.After the analysis for data transfer in embedded audio processor HiPAP,an AHB supported2-channel audio DMA controller is proposed in this paper.Compared with CPU,the performance of data transfer is improved by up to45%on FPGA platform. Key words:DMA;controller;AHB 0引言 对于多媒体处理而言,使用ASIC(Application Specific Integrated Circuit)编解码IP(Intellectual Property)能够高速同时低功耗地完成编解码任务,但是它们不能被修改,当音视频标准或者协议升级时,必须开发新的IP。而使用配备专用加速指令的音视频处理器,则只需要更新固件就可以完成新的任务,由于这些处理器有着很好的灵活性,因此发展非常迅速[1]。近年来,各大公司都推出了针对音频编解码的音频处理器,比如,Tensilica公司的DIA-MOND330HiFi以及ARM公司的AudioDE等。 随着处理器性能的提高,系统各模块间的数据交换成为提高系统运行速度的瓶颈[2]。使用DMA (Direct Memory Access)方式能够有效代替CPU的load/store指令。在DMA方式下,CPU只需要在数据传输之前对DMA控制器(Direct Memory Access Controller)进行少量的初始化操作,之后CPU就无需介入数据传输过程,可以和DMA并发的工作。这样,CPU的利用率得到了大幅提升[3]。 面对嵌入式音频处理器的数据传输需求,传统的通用DMA控制器并不能很好的满足。本文介绍了音频处理器HiPAP(High Performance Audio Pro-cessor)中双通道音频DMA控制器的设计与实现。1系统架构与数据传输需求 1.1音频处理器的数据传输需求 在一个包含音频处理器芯片的SoC系统中,音频处理器负责诸如编解码之类的音频处理。除此之外,系统一般还拥有负责全局控制的主处理器,通用DMA控制器和存储器等的各种外设以及连接所有模块的总线。在音频处理器的运行过程中,涉及处理器控制的数据传输可按照其特点分为两类:第一类,大数据量、较低实时性的传输。这包括在音频处理器处理前将原始码流载入音频处理器的本地存储器内,以及在处理完成后将输出数据传输至主存或者音频DAC。 收稿日期:2010-09-16 作者简介:王俊(1985-),男,硕士研究生,主要研究方向为集成电路芯片设计与验证。 — 24 — 第一讲: 第六章DMA控制器和定时/计数器 回顾:微型计算机与外部设备之间的数据传送控制方式 本讲重点:DMA的基本概念,DMA 控制器芯片8237的性能概述,内、外部结构,工作周期,工作方式,通道的优先级及数据传输速率。 讲授内容: 6. 1 DMA控制器Intel8237 一、DMA概述 我们已经介绍了微机系统中各种常用的数据输入输出方法,有程控法(包括无条件及条件传送方式)和中断法,这些方法适用于CPU与慢速及中速外设之间的数据交换。但当高速外设要与系统内存或者要在系统内存的不同区域之间,进行大量数据的快速传送时,就在一定程度上限制了数据传送的速率。以Intel8088CPU为例,CPU从内存(或外设)读数据到累加器,然后再写到外设端口(或内存)中,若包括修改内存地址,判断数据块是否传送完,Intel8088CPU(时钟接近5MHz)传送一个字节约需要几十微秒的时间,由此可大致估计出用程控及中断的方式来进行数据传送,其数据传送速率大约为每秒几十KB字节。 为了提高数据传送的速率,人们提出了直接存储器存取(DMA)的数据传送控制方式,即在一定时间段内,由DMA控制器取代CPU,获得总线控制权,来实现内存与外设或者内存的不同区域之间大量数据的快速传送。 典型的DMAC的工作电路如图6-1。DMA数据传送的工作过程大致如下: ①外设向DMAC发出DMA 传送请求。 ②DMAC通过连接到CPU 的HOLD信号向CPU提出DMA 请求。 ③CPU在完成当前总线操作 后会立即对DMA请求做出响 应。CPU的响应包括两个方面: 一方面,CPU将控制总线、数据 总线和地址总线浮空,即放弃对 这些总线的控制权;另一方面, CPU将有效的HLDA信号加到 图6-1 DMAC的工作电路 DMAC上,用此来通知DMAC, DSP的DMA控制器与ARM的DMA控制器比较 分类:技术相关总结2009-10-17 15:18 1836人阅读评论(0) 收藏举报 工作任务c 去年,曾经使用过TI的DSP,TMS320VC5502(属于TMS320C5000系列),用过了它的DMA 功能,前段时间,又使用了STM32的DMA。现总结它们主要的区别: DSP的DMA传输的数据可以细分,一个总的传输块(BLOCK)里面,又可以分若干个帧(FRAME),每传完一帧都可以开启中断。而且在整个DMA传输期间,不管是循环模式或者是其他一次性的模式,都可以中途暂停,因为它的DMA控制器可以记录当前暂停时的传输大小,和传输地址索引,然后下次再次开启的时候,会紧接着上次中断后的地方来传输。而STM32的DMA就显得功能没那么大, 设定了传输大小后,不能再细分区域。而且传输过程中,不能暂停。缺了这些功能,其实不会影响一般使用的,只在某些特定的使用中,就显得没DSP的DMA那么方便了。 STM32的DMA控制器只有一套工作寄存器。而DSP的DMA控制器,不单单有一套工作寄存器,而且还多了一个备份寄存器,称为配置寄存器。按照其命名可以很容易的理解,工作寄存器肯定就是提高给DMA控制器使用,也就是说,当前DMA控制器传输所用的配置是由工作寄存器得来的。而配置寄存器,就是由用户配置的,该寄存器可以在任何时候,包括DMA在启用的时候,都可以配置(某些特定寄存器不能在DMA启动的时候配置,具体请参考其手册),假如使用AUTO自动初始 化模式,在完成一个BLOCK传输后,会讲配置寄存器值复制到工作寄存器,改变DMA传输参数;假如非AUTO模式,就在再次使能通道的时候进行寄存器复制。这样就带来了一个好处,DMA控制参数,可以在DMA传输的过程中,对下一次传输进行预配置,然后等传输完的时候,启用新参数继续传输。而STM32的DMA,假如DMA在启动,假如需要改变下一次传输的参数,那只能乖乖的等它将这次任务完成了,然后停止DMA,再去配置工作寄存器,再重新启动DMA。也就是说,DSP 的DMA,多了一个备份配置寄存器,带来的好处是,无需停止DMA,就可以实现传输参数的改变。 注:不管是STM32或者5502的DMA,在非循环模式下,每次传输完后,假如要传输新的数据,都需要重新配置目标地址和源地址和传输数据等参数。而且STM32还要重新给DMA配置通道。 DMA传输是“直接存储器访问”的缩写,由DMA控制器完成数据传输,不需要CPU操作,因此可节省CPU开销,传输速度快,突发操作每时钟搬移一个数据。要通过CPU搬移数据的话,CPU要先读到他的寄存器,再从寄存器写到存储器,就是流水操作总要4-8个时钟或更多,速度就差了几倍。 DSP的DMA传输的数据可以细分,一个总的传输块(BLOCK)里面,又可以分若干个帧(FRAME),每传完一帧都可以开启中断。而且在整个DMA传输期间,不管是循环模式或者是其他一次性的模式,都可以中途暂停,因为它的DMA控制器可以记录当前暂停时的传输大小,和传输地址索引,然后下次再次开启的时候,会紧接着上次中断后的地方来传输。 DMA都是为了成批传输数据的,不论单次DMA 和突发DMA。不同的是每次传输一个单元数据(比如使用32bit 使用8237A可编程DMA控制器实验目的 1、掌握8237A可编程DMA控制器和微机的接口方法。 2、学习使用8237A可编程控制器,实现数据直接快速传送的编程方法 1、实验内容 实验原理图如图5-26(见下页)所示,本实验学习使用8237A可编程DMA控制器进行RAM到RAM的数据传送方法。 实验中规定通道0为源地址,通道1为目的地址,通过设置0通道的请求寄存器产生软件请求,8237A响应这个软件请求后发出总线请求信号HRQ,图中8237HRQ直接连到8237A的HLDA上,相当于HRQ作为8237A的总线响应信号,进入DMA操作周期。 在8237A进行DMA传送时,当字节计数器减为0时,8237A的/EOP 引脚输出一个负脉冲,表示传送结束。/EOP可以作为系统的外部中断信号,通过8259A控制器使CPU 判断DMA传递是否结束。本实验中未用/EOP信号。 图中RAM 6264的地址为8000~9FFF,实验要求将RAM 6264中地址为8000~ 83FFH 的1KB数据传送到地址为9000H~93FFH的区域中去。为了验证传送的正确性,你可在源地址(8000H~83FFH)区首末几个单元填充标志字节,传送完再检查目的地址区的相应单元的标志字节是否与填入的一样。 2、实验步骤 (1)、将DMA扩展实验板按信号线的对应关系插入DVCC-8086H的Z5插座。 (2)、将DMA扩展实验板上的8237CS信号插孔和DVCC?8086H 的译码输出插孔00H-01FH相连。 (3)、打开DVCC-8086H电源,DVCC-8086H系统显示"DVCC -86H"。 (4)、运行实验程序 在系统显示"DVCC-86H"状态下,按任意键,系统显示命令提示符"-" 。 按GO键,显示器显示"1000 XX"。 输入F000 :B8C0 。 按EXEC键,显示器显示"8237-1"。 待数据传送结束,显示器显示"8237 good"。 AN2548 应用笔记 使用STM32F101xx和STM32F103xx DMA控制器 1 前言 这篇应用笔记描述了怎么使用STM32F101xx 和 STM32F103xx的直接存储器访问(DMA)控制 器。STM32F101xx和STM32F103xx的DMA控制器、Cortex TM-M3内核、高级微控制器总线架 构(AMBA)总线和存储器系统,使得STM32具有高的数据带宽,并能使用户开发出低延迟、快响 应的软件。 这篇文档也描述了怎样充分利用这些特性,以及对于不同的外设和子系统怎样保证正确的响应 时间。 在下文中STM32F101xx和STM32F103xx都记作STM32F10xxx,DMA控制器都记作DMA。 译注: 本应用笔记配套例程下载地址: https://www.360docs.net/doc/fa18251587.html,/stonline/products/support/micro/files/an2548.zip 本译文的英文版下载地址为: https://www.360docs.net/doc/fa18251587.html,/stonline/products/literature/an/13529.pdf 目录 1前言1 2DMA控制器3 2.1DMA的主要特性3 3性能分析5 3.1轮询优先级方案5 3.2多层结构和总线挪用5 3.3DMA延迟6 3.4数据总线带宽限制6 3.5通道优先级选择7 3.5.1应用需求7 3.5.2内部数据带宽8 4DMA编程示例9 4.1使用SPI传输获得ADC连续采样的数据9 4.2SPI直接传输实现ADC连续数据的获取9 4.3使用DMA实现GPIO快速数据传输9 2/9 参照2007年12月 AN2548 英文第2版10 DMA控制器
stm32DMA控制器的介绍
10 DMA控制器
微机原理 第10章 DMA控制器8237A 习题及参考
嵌入式音频处理器中DMA控制器的设计
DMA控制器定计数器
DSP的DMA控制器与ARM的DMA控制器比较
使用8237A可编程DMA控制器实验目的
使用 DMA 控制器指南