搜档网
当前位置:搜档网 › 【原创】stm32f407之ADC与DMA

【原创】stm32f407之ADC与DMA

【原创】stm32f407之ADC与DMA
【原创】stm32f407之ADC与DMA

【原创】【原创】stm32f407stm32f407stm32f407之

之ADC 与DMA 2012-05-0116:31:00|分类:stm32|

标签:stm32cortex-m4

dma printf

adc

|字号大中小订

昨天调试了stm32f407的ADC 功能,因为那个恼人的printf 函数问题这篇ADC 文章一直没有发表出来,今天5.1归来抽空补上。功能为实现ADC 的单通道电压采集,并实现DMA 数据管理,同时加了ADC 看门狗功能,并用printf 函数通过串口返回采集值与换算后的实际电压值。代码如下:

/************************************************************Copyright (C),2012-2022,yin.FileName:main.c Author:小枣年糕

Date:

2012\05\01

Description:ADC3DMA printf Version:V3.0IDE:MDK 4.22a

HardWare:stm32F407IG HSE =25M PLL =168M History:

V1.0

***********************************************************/#include#include

/*定义ADC3的数据寄存器地址,DMA 功能要用到外设的数据地址

*ADC3的数据地址为外设基地址+偏移地址,基地址在RM0090Reference *manual (参考手册)的地址映射表里,为0x40012200,ADC_DR

*偏移地址为0x4C,故实际地址为0x40012200+0x4C=0x4001224C*/

#define ADC3_DR_Addr((uint32_t)0x4001224C)

__IO uint16_t ADCoverVaule;

//uint16_t Buffer2[]={0x1122};//这个是我进行内存测试用的,程序没用到

void GPIO_Config(void);

void ADC_Config(void);

void USART_Config(void);

void USART6_Puts(char*str);

void DMA_Config(void);

void NVIC_Config(void);

void Delay(uint32_t nCount);

/*printf函数重定向*/

int fputc(int ch,FILE*f);

int GetKey(void);

main()

{

/*在主函数main之前通过调用启动代码运行了SystemInit函数,而这个函数位于system_stm32f4xx.c”。

程序运行起始于启动文件的第175行(LDR R0,=SystemInit)。sys时钟为HSE频率/PLL_M*PLL_N/PLL_P,

定义HSE为25M,则sys时钟频率为168M*/

GPIO_Config();

ADC_Config();

USART_Config();

DMA_Config();

NVIC_Config();

GPIO_SetBits(GPIOG,GPIO_Pin_6);//关闭LED

ADC_SoftwareStartConv(ADC3);//如果不是外部触发则必须软件开始转换while(1)

{

Delay(0x0ffffff);

//printf("size of int is%d\n",sizeof(int));//测试可知32位系统的int占4个字节

printf("ADCoverVaule=%04X VolVaule=%d mV\n",ADCoverVaule,

ADCoverVaule*3300/4096);//串口输出电压值

/*因为DMA工作是独立于CPU之外的,所以在DMA工作的同时CPU可以做其他事*/ }

}

/*************************************************

Function:void GPIO_Config(void)

Description:GPIO配置函数

Input:无

Output:无

Return:无

*************************************************/

void GPIO_Config(void)

{

GPIO_InitTypeDef GPIO_InitStructure;

/*使能GPIOC\GPIOF\GPIOG时钟*/

RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC|RCC_AHB1Periph_GPIOG| RCC_AHB1Periph_GPIOF,ENABLE);

GPIO_StructInit(&GPIO_InitStructure);

/*初始化GPIOG的Pin_6为LED输出*/

GPIO_InitStructure.GPIO_Pin=GPIO_Pin_6;//指定第六引脚

GPIO_InitStructure.GPIO_Mode=GPIO_Mode_OUT;//模式为输出

GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;//频率为快速

GPIO_Init(GPIOG,&GPIO_InitStructure);//调用IO初始化函数

/*初始化GPIOG的Pin_9为模拟量输入*/

GPIO_InitStructure.GPIO_Pin=GPIO_Pin_9;

GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AN;

GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_NOPULL;

GPIO_Init(GPIOF,&GPIO_InitStructure);

/*配置GPIOC_Pin6为TX输出*/

GPIO_InitStructure.GPIO_Pin=GPIO_Pin_6;

GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF;//设置为复用,必须为AF,OUT 不行

GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;

GPIO_Init(GPIOC,&GPIO_InitStructure);

/*配置GPIOC_Pin7为RX输入*/

GPIO_InitStructure.GPIO_Pin=GPIO_Pin_7;

GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF;//这也必须为复用,与M3不同!GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;

GPIO_Init(GPIOC,&GPIO_InitStructure);

/*GPIO引脚复用功能设置*/

GPIO_PinAFConfig(GPIOC,GPIO_PinSource6,GPIO_AF_USART6);//这相当于M3的开启复用时钟,只配置复用的引脚,

GPIO_PinAFConfig(GPIOC,GPIO_PinSource7,GPIO_AF_USART6);//

}

/*************************************************

Function:void ADC_Config(void)

Description:ADC配置函数

Input:无

Output:无

Return:无

*************************************************/

void ADC_Config(void)

{

ADC_InitTypeDef ADC_InitStructure;

ADC_CommonInitTypeDef ADC_CommonInitStructure;

RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC3,ENABLE);//开ADC时钟

ADC_DeInit();

ADC_InitStructure.ADC_Resolution=ADC_Resolution_12b;//精度为12位

ADC_InitStructure.ADC_ScanConvMode=DISABLE;//扫描转换模式失能,单通道不用ADC_InitStructure.ADC_ContinuousConvMode=ENABLE;//连续转换使能

ADC_InitStructure.ADC_ExternalTrigConvEdge=ADC_ExternalTrigConvEdge_None;//不用外部触发,软件触发转换

ADC_InitStructure.ADC_ExternalTrigConv=ADC_ExternalTrigConv_T1_CC1;

ADC_InitStructure.ADC_DataAlign=ADC_DataAlign_Right;//数据右对齐,低字节对齐ADC_InitStructure.ADC_NbrOfConversion=1;//规定了顺序进行规则转换的ADC通道的数目

ADC_Init(ADC3,&ADC_InitStructure);

ADC_CommonInitStructure.ADC_Mode=ADC_Mode_Independent;//独立模式

ADC_CommonInitStructure.ADC_Prescaler=ADC_Prescaler_Div4;//分频为4,

f(ADC3)=21M

ADC_CommonInitStructure.ADC_DMAAccessMode=ADC_DMAAccessMode_Disabled; //失能DMA_MODE

ADC_CommonInitStructure.ADC_TwoSamplingDelay=

ADC_TwoSamplingDelay_5Cycles;//两次采样间隔5个周期

ADC_CommonInit(&ADC_CommonInitStructure);

ADC_RegularChannelConfig(ADC3,ADC_Channel_7,1,ADC_SampleTime_15Cycles); //规则通道配置,1表示规则组采样顺序

//ADC_ITConfig(ADC3,ADC_IT_EOC,ENABLE);//使能ADC转换结束中断

ADC_Cmd(ADC3,ENABLE);//使能ADC3

/*********************ADC看门狗配置***************************/

ADC_AnalogWatchdogCmd(ADC3,ADC_AnalogWatchdog_SingleRegEnable);

ADC_AnalogWatchdogThresholdsConfig(ADC3,0x0E8B,0x0555);//阈值设置。高:3V 低:1V

ADC_AnalogWatchdogSingleChannelConfig(ADC3,ADC_Channel_7);

ADC_ITConfig(ADC3,ADC_IT_AWD,ENABLE);

ADC_DMACmd(ADC3,ENABLE);//使能ADC3的DMA

ADC_DMARequestAfterLastTransferCmd(ADC3,ENABLE);//单通道模式下上次转换完成

后DMA请求允许,也就是持续DMA

}

/*************************************************

Function:void USART_Config(void)

Description:USART配置函数

Input:无

Output:无

Return:无

*************************************************/

void USART_Config(void)

{

USART_InitTypeDef USART_InitStructure;

USART_ClockInitTypeDef USART_ClockInitStruct;

RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART6,ENABLE);//开启USART6时钟

/*配置USART6*/

USART_StructInit(&USART_InitStructure);

USART_https://www.sodocs.net/doc/8b294524.html,ART_BaudRate=115200;

USART_https://www.sodocs.net/doc/8b294524.html,ART_WordLength=USART_WordLength_8b;

USART_https://www.sodocs.net/doc/8b294524.html,ART_StopBits=USART_StopBits_1;

USART_https://www.sodocs.net/doc/8b294524.html,ART_Parity=USART_Parity_No;

USART_https://www.sodocs.net/doc/8b294524.html,ART_HardwareFlowControl=

USART_HardwareFlowControl_None;

USART_https://www.sodocs.net/doc/8b294524.html,ART_Mode=USART_Mode_Rx|USART_Mode_Tx;

USART_Init(USART6,&USART_InitStructure);

USART_ClockStructInit(&USART_ClockInitStruct);//之前没有填入缺省值,是不行的USART_ClockInit(USART6,&USART_ClockInitStruct);

USART_ITConfig(USART6,USART_IT_RXNE,ENABLE);//使能USART6中断USART_Cmd(USART6,ENABLE);//使能USART6

}

void NVIC_Config()

{

/*USART6中断配置*/

NVIC_InitTypeDef NVIC_InitStructure;

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);//嵌套优先级分组为1 NVIC_InitStructure.NVIC_IRQChannel=USART6_IRQn;//嵌套通道为

USART6_IRQn

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0;//抢占优先级为0

NVIC_InitStructure.NVIC_IRQChannelSubPriority=0;//响应优先级为0

NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;//通道中断使能

NVIC_Init(&NVIC_InitStructure);

/*DMA中断配置*/

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);//嵌套优先级分组为1 NVIC_InitStructure.NVIC_IRQChannel=DMA2_Stream0_IRQn;//嵌套通道为

DMA2_Stream0_IRQn

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1;//抢占优先级为1

NVIC_InitStructure.NVIC_IRQChannelSubPriority=1;//响应优先级为0

NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;//通道中断使能

NVIC_Init(&NVIC_InitStructure);

/*ADC中断配置*/

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);//嵌套优先级分组为1

NVIC_InitStructure.NVIC_IRQChannel=ADC_IRQn;//嵌套通道为

ADC_IRQn

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1;//抢占优先级为1

NVIC_InitStructure.NVIC_IRQChannelSubPriority=2;//响应优先级为2

NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;//通道中断使能

NVIC_Init(&NVIC_InitStructure);

}

/*************************************************

Function:void USART6_Puts(char*str)

Description:USART6发送数据

Input:待发送数据指针

Output:无

Return:无

*************************************************/

void USART6_Puts(char*str)

{

while(*str)

{

USART_SendData(USART6,*str++);

/*Loop until the end of transmission*/

while(USART_GetFlagStatus(USART6,USART_FLAG_TXE)==RESET);//详见英文参

考的521页,当TXE被置起时,一帧数据传输完成

}

}

/*************************************************

Function:void DMA_Config(void)

Description:DMA配置函数

Input:延时的时间

Output:无

Return:无

*************************************************/

void DMA_Config(void)

{

DMA_InitTypeDef DMA_InitStructure;

/*首先开DMA2时钟,由407参考手册-RM0090-Reference manual

*165页可知,UASRT6与DMA2映射,而且DMA2挂载在AHB1时钟总线上*/

RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2,ENABLE);

DMA_DeInit(DMA2_Stream0);

DMA_StructInit(&DMA_InitStructure);

DMA_InitStructure.DMA_Channel=DMA_Channel_2;//选择Channel_2 DMA_InitStructure.DMA_PeripheralBaseAddr=(uint32_t)ADC3_DR_Addr;//数据传输的外设首地址,详解见上

DMA_InitStructure.DMA_Memory0BaseAddr=(uint32_t)&ADCoverVaule;//自己定义待发送数组的首地址,要强制转换为32位

DMA_InitStructure.DMA_DIR=DMA_DIR_PeripheralToMemory;//数据传输方向选择

为外设到内存

DMA_InitStructure.DMA_BufferSize=1;//传输数据大小为1,单位由以下确定,大小要配合定义的数组类型和外设数据类型

DMA_InitStructure.DMA_PeripheralInc=DMA_PeripheralInc_Disable;//外设地址寄存器自动增加禁止,因为这里只用到了DR数据寄存器

DMA_InitStructure.DMA_MemoryInc=DMA_MemoryInc_Disable;//内存地址自增不允许

DMA_InitStructure.DMA_PeripheralDataSize=DMA_PeripheralDataSize_HalfWord;//外设的数据大小,因为ADC6_DR数据寄存器为16为,故选HalfWord

DMA_InitStructure.DMA_MemoryDataSize=DMA_MemoryDataSize_HalfWord;//这里也选Byte

DMA_InitStructure.DMA_Mode=DMA_Mode_Circular;//DMA传输模式为Circular,将会循环传输

DMA_InitStructure.DMA_Priority=DMA_Priority_High;//优先级为High

DMA_Init(DMA2_Stream0,&DMA_InitStructure);

DMA_Cmd(DMA2_Stream0,ENABLE);//使能DMA2_Stream0通道

/*DMA中断开*/

DMA_ITConfig(DMA2_Stream6,DMA_IT_TC,ENABLE);

DMA_ITConfig(DMA2_Stream0,DMA_IT_TC,ENABLE);

}

/*************************************************

Function:void Delay(uint32_t nCount)

Description:延时函数

Input:延时的时间

Output:无

Return:无

*************************************************/

void Delay(uint32_t nCount)

{

while(nCount--);

}

/*************************************************

Function:int fputc(int ch,FILE*f)

Description:fputc重定向函数--发送

Input:

Output:无

Return:ch

*************************************************/

int fputc(int ch,FILE*f)

{

USART_SendData(USART6,(unsigned char)ch);//USART1可以换成USART2等while(!(USART6->SR&USART_FLAG_TXE));

return(ch);

}

/*************************************************

Function:int GetKey(void)

Description:fputc重定向函数--接收

Input:无

Output:无

Return:USART6->DR&0x1FF

*************************************************/

int GetKey(void)

{

while(!(USART6->SR&USART_FLAG_RXNE));

return((int)(USART6->DR&0x1FF));

}

中断服务函数:

/**名称:DMA中断服务程序

*作用:ADC3_DMA数据完全完成后产生中断

*/

void DMA2_Stream0_IRQHandler(void)

{

if(DMA_GetITStatus(DMA2_Stream0,DMA_IT_TCIF0)!=RESET) {

DMA_ClearITPendingBit(DMA2_Stream0,DMA_IT_TCIF0);

/*添加用户代码*/

}

}

/**名称:ADC看门狗中断服务程序

*作用:ADC输入超过界限产生中断,并点亮LED

*/

void ADC_IRQHandler(void)

{

GPIO_ResetBits(GPIOG,GPIO_Pin_6);

if(ADC_GetITStatus(ADC3,ADC_IT_AWD)==SET) {

ADC_ClearITPendingBit(ADC3,ADC_IT_AWD);

ADC_Cmd(ADC3,DISABLE);

printf("Input is out of threrd!!");

}

}

10 DMA控制器

复习思考题 第章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)

stm32DMA控制器的介绍

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 各通道一览表:

10 DMA控制器

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有效。

微机原理 第10章 DMA控制器8237A 习题及参考

第十章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读

嵌入式音频处理器中DMA控制器的设计

中图分类号: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的基本概念,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控制器比较

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控制器实验目的

使用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"。

使用 DMA 控制器指南

AN2548 应用笔记 使用STM32F101xx和STM32F103xx DMA控制器 1 前言 这篇应用笔记描述了怎么使用STM32F101xx 和 STM32F103xx的直接存储器访问(DMA)控制 器。STM32F101xx和STM32F103xx的DMA控制器、Cortex TM-M3内核、高级微控制器总线架 构(AMBA)总线和存储器系统,使得STM32具有高的数据带宽,并能使用户开发出低延迟、快响 应的软件。 这篇文档也描述了怎样充分利用这些特性,以及对于不同的外设和子系统怎样保证正确的响应 时间。 在下文中STM32F101xx和STM32F103xx都记作STM32F10xxx,DMA控制器都记作DMA。 译注: 本应用笔记配套例程下载地址: https://www.sodocs.net/doc/8b294524.html,/stonline/products/support/micro/files/an2548.zip 本译文的英文版下载地址为: https://www.sodocs.net/doc/8b294524.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版

相关主题