打印

关于adc3与dma2的配置问题

[复制链接]
5313|6
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
liulcy|  楼主 | 2012-9-7 14:12 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
我是一个新手,正在学习stm32,目前遇到这样一个问题,描述如下:
我想测试adc3与dma2功能,方法如下:
1,配置adc3和dma2:

   RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC3, ENABLE);
   RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA2, ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOF|    RCC_APB2Periph_AFIO , ENABLE);  

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7 | GPIO_Pin_8 ;
   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
   GPIO_Init(GPIOF, &GPIO_InitStructure);
DMA_DeInit(DMA2_Channel5);//复位DMA通道5
DMA_InitStructure3.DMA_PeripheralBaseAddr = ADC3_DR_Address+1;
DMA_InitStructure3.DMA_MemoryBaseAddr = (u32)&ADCConvertedValue;
DMA_InitStructure3.DMA_DIR = DMA_DIR_PeripheralSRC;
DMA_InitStructure3.DMA_BufferSize = 16384;
DMA_InitStructure3.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure3.DMA_MemoryInc = DMA_MemoryInc_Enable;//当前存储器地址不变
DMA_InitStructure3.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;//定义外设数据宽度16位
DMA_InitStructure3.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; //定义存储器数据宽度16位
DMA_InitStructure3.DMA_Mode = DMA_Mode_Circular;//DMA通道操作模式位环形缓冲模式
DMA_InitStructure3.DMA_Priority = DMA_Priority_High;//DMA通道优先级高
DMA_InitStructure3.DMA_M2M = DMA_M2M_Disable;//禁止DMA通道存储器到存储器传输
DMA_Init(DMA2_Channel5, &DMA_InitStructure3);
DMA_Cmd(DMA2_Channel5, ENABLE); //使能DMA通道5
DMA_ITConfig(DMA2_Channel5, DMA_IT_TC, ENABLE);

ADC_InitStructure3.ADC_Mode = ADC_Mode_Independent;//ADC1和ADC2工作在独立模式
ADC_InitStructure3.ADC_ScanConvMode = ENABLE; //使能扫描
ADC_InitStructure3.ADC_ContinuousConvMode = ENABLE;//ADC转换工作在单次模式
ADC_InitStructure3.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;//定时器2的捕获比较2为转换外部触发
ADC_InitStructure3.ADC_DataAlign = ADC_DataAlign_Left;//转换数据右对齐
ADC_InitStructure3.ADC_NbrOfChannel = 2;//转换通道为通道1
ADC_Init(ADC3, &ADC_InitStructure3); //初始化ADC
ADC_RegularChannelConfig(ADC3, ADC_Channel_5, 1,  ADC_SampleTime_1Cycles5 );
ADC_RegularChannelConfig(ADC3, ADC_Channel_6, 2,  ADC_SampleTime_1Cycles5 );
ADC_DMACmd(ADC3, ENABLE);//使能ADC3模块DMA
ADC_Cmd(ADC3, ENABLE);//使能ADC3
ADC_ResetCalibration(ADC3); //重置ADC3校准寄存器
while(ADC_GetResetCalibrationStatus(ADC3));//等待ADC3校准重置完成
ADC_StartCalibration(ADC3);//开始ADC3校准
while(ADC_GetCalibrationStatus(ADC3));//等待ADC3校准完成
ADC_Cmd(ADC3, ENABLE);
  ADC_SoftwareStartConvCmd(ADC3, ENABLE);

2,中断设定
NVIC_InitStructure.NVIC_IRQChannel = DMA2_Channel4_5_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);

3,写了一个很简单的中断程序
void DMA2_Channel4_5_IRQHandler(void)
{  
//...........
}
4,测试结果有两个方面:一是发现dma2似乎没有工作,二是发现keil3.8里面调试时竟然没有dma2和adc3的寄存器,晕死我了。
然后我采用单次采样的方式测试adc3,能够取得数据(getadcconverter()之类函数),初步定为时dma2没有工作,郁闷啊郁闷,已经通宵到现在了,还是没有头绪。
请大侠看在我码了这些字的面子上,给我点有效的指导吧.......
沙发
香水城| | 2012-9-7 14:45 | 只看该作者
ST有ADC的DMA例程,你可以参考下

使用特权

评论回复
板凳
figo20042005| | 2012-9-7 16:06 | 只看该作者
多看例程

使用特权

评论回复
地板
IJK| | 2012-9-7 17:29 | 只看该作者
首先,用的是哪款STM32?

有些问题要弄清楚:DMA2_Channel5 是给ADC3用的吗?
有问题:DMA_InitStructure3.DMA_PeripheralBaseAddr = ADC3_DR_Address+1;
有疑问,buffer有那么大吗?:DMA_InitStructure3.DMA_BufferSize = 16384;
有问题,按理应该是16位数据:
DMA_InitStructure3.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;//定义外设数据宽度16位
DMA_InitStructure3.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; //定义存储器数据宽度16位

使用特权

评论回复
5
liulcy|  楼主 | 2012-9-7 21:44 | 只看该作者
本帖最后由 liulcy 于 2012-9-7 21:45 编辑

4# IJK
您好。
我用的是STM32f103zet,大容量的那款。
我用的是8bit数据,所以只要一个字节就可以了。
缓冲区,我开辟了16384个字节,够大了。

使用特权

评论回复
6
伐多2011| | 2012-9-8 08:44 | 只看该作者
ADC3_DR_Address+1你这个地址为何加1?不是直接为ADC3的DR寄存器地址吗?
#define ADC1_DR_Address    ((u32)0x4001244C)//定义ADC的地址(ADC1_DR规则数据寄存器)


//DMA1通道1初始化,对应为ADC1,即外设为ADC1
void DMA1_Init(DMA_Channel_TypeDef*DMA_CHx,unsigned long ADC_Temp)
{
        RCC->AHBENR |= BIT(0);//使能DMA1时钟

        DMA_CHx->CNDTR |=BIT(1)|BIT(0);//传输的数据量为3
        DMA_CHx->CMAR  = ADC_Temp;//DMA存储器地址(用来存储数据)
    DMA_CHx->CPAR  = ADC1_DR_Address;//DMA读取数据的地址

        DMA_CHx->CCR &=~BIT(14);//非存储模式到存储模式(外设到存储器模式)
        DMA_CHx->CCR &=~BIT(6);//不执行外设地址增量操作
        DMA_CHx->CCR &=~BIT(4);//数据从外设读

        DMA_CHx->CCR |= BIT(13)|BIT(12);//通道优先级最高
        DMA_CHx->CCR |= BIT(10);//存储数据宽度为16位
        DMA_CHx->CCR |= BIT(8);//外设数据宽度为16位
        DMA_CHx->CCR |= BIT(7);//执行存储器地址增量操作
        DMA_CHx->CCR |= BIT(5);//执行循环操作       
//        DMA_CHx->CCR |= BIT(1);//允许传输完成产生中断

        DMA_CHx->CCR |= BIT(0);//DMA通道开启
}
,这是我以前用ADC跟DMA结合的代码,或许楼主可以参考一下

使用特权

评论回复
7
81190865| | 2015-3-12 16:55 | 只看该作者
我也遇到这样问题,经过检查发现是因为DMA2时钟没有开
/* Enable DMA1 clock */
  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA2, ENABLE);

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

1

主题

2

帖子

1

粉丝