打印

双ADC+DMA 快速交替采集模式,麻烦给看下

[复制链接]
4181|9
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
aaaxmaaa007|  楼主 | 2013-3-2 14:13 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
ADC, DMA, ST, ni, TI
时钟和GPIO配置就不贴出来了,下面分别是DMA配置和ADC配置:
    DMA_InitTypeDef  DMA_InitStructure;

    /* DMA1 channel1 configuration ----------------------------------------------*/
    DMA_DeInit(DMA1_Channel1);
    DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&ADC_Adc->DR;
    DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)pCap_Line_Buf;
    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
    DMA_InitStructure.DMA_BufferSize = 90;//93;
    DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
    DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word;//DMA_PeripheralDataSize_HalfWord;
    DMA_InitStructure.DMA_MemoryDataSize = DMA_PeripheralDataSize_Word;//DMA_MemoryDataSize_HalfWord;
    DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
    DMA_InitStructure.DMA_Priority = DMA_Priority_High;
    DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
    DMA_Init(DMA1_Channel1, &DMA_InitStructure);
    /* Enable DMA1 channel1 */

    /*Enable DMA1 transfer interrupt*/
    DMA_ITConfig(DMA1_Channel1, DMA_IT_TC, ENABLE);
上面是DMA初始化,初始化之后暂时没有使能,后面在中断中使能

    ADC_InitTypeDef ADC_InitStructure;
    /* ADC1 configuration ------------------------------------------------------*/
    ADC_InitStructure.ADC_Mode = ADC_Mode_FastInterl;
    ADC_InitStructure.ADC_ScanConvMode = DISABLE;
    ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
    ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
    ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
    ADC_InitStructure.ADC_NbrOfChannel = 1;
    ADC_Init(ADC1, &ADC_InitStructure);

    /* ADC1 regular channel14 configuration */
    ADC_RegularChannelConfig(ADC1, ADC_Channel_10, 1, ADC_SampleTime_1Cycles5);
    ADC_DMACmd(ADC1, ENABLE);
    /* Enable ADC2 external trigger conversion */
    //ADC_ExternalTrigConvCmd(ADC1, ENABLE);

    /* ADC2 configuration ------------------------------------------------------*/
    ADC_InitStructure.ADC_Mode = ADC_Mode_FastInterl;
    ADC_InitStructure.ADC_ScanConvMode = DISABLE;
    ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
    ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
    ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
    ADC_InitStructure.ADC_NbrOfChannel = 1;
    ADC_Init(ADC2, &ADC_InitStructure);

    /* ADC1 regular channel14 configuration */
    ADC_RegularChannelConfig(ADC2, ADC_Channel_10, 1, ADC_SampleTime_1Cycles5);

    /* Enable ADC2 external trigger conversion, this operation is required for dual ADC mode */
    ADC_ExternalTrigConvCmd(ADC2, ENABLE);

    /* Enable ADC1 */

    ADC_Cmd(ADC1, ENABLE);

    /* Enable ADC1 reset calibaration register */
    ADC_ResetCalibration(ADC1);
    /* Check the end of ADC1 reset calibration register */
    while(ADC_GetResetCalibrationStatus(ADC1));

    /* Start ADC1 calibaration */
    ADC_StartCalibration(ADC1);
    /* Check the end of ADC1 calibration */
    while(ADC_GetCalibrationStatus(ADC1));

    /* Enable ADC2 */
    ADC_Cmd(ADC2, ENABLE);

    /* Enable ADC2 reset calibaration register */
    ADC_ResetCalibration(ADC2);
    /* Check the end of ADC2 reset calibration register */
    while(ADC_GetResetCalibrationStatus(ADC2));

    /* Start ADC2 calibaration */
    ADC_StartCalibration(ADC2);
    /* Check the end of ADC2 calibration */
    while(ADC_GetCalibrationStatus(ADC2));

    ADC_Cmd(ADC1, DISABLE);
    ADC_Cmd(ADC2, DISABLE);

上面是快速交替采集模式的ADC配置,配置完之后,将ADC1、ADC2失能,之后在中断中使能;

我是在模拟视频信号的行中断去采集视频信号的,程序如下所示:(行中断是由视频信号触发的,进入行中断中才打开ADC和DMA采集)
                DMA_ADC->CCR &= (uint32_t)0xFFFFFFFE;
                DMA_ADC->CNDTR = 90;
                DMA_ADC->CCR |= (uint32_t)0x00000001;
               
                ADC1->CR2 |= (uint32_t)0x00000001;
                ADC2->CR2 |= (uint32_t)0x00000001;



下面是由DMA传输结束后触发的中断 DMA1_Channel1_IRQHandler,此中断中,我首先关闭ADC采集:
         ADC1->CR2 &= (uint32_t)0xFFFFFFFE;
         ADC2->CR2 &= (uint32_t)0xFFFFFFFE;

之后将DMA转化到内存中的数据,写到另外的内存中存放,下一个行中断又打开ADC采集一行信号,之后在转存到内存中,
我整个程序的流程就是这样的,我之前用的单个ADC的采集模式,就是这样的:行信号产生中断,打开ADC采集,采集完之后
通过DMA转存到内存中,一直是行中断和DMA中断的来回转换,现在双ADC出现的问题是:采集貌似是正确的,但是,要2到3次
行中断,才会进一次DMA中断,这样采集的肯定不是整行的信息

麻烦给看下,我整个程序出现的问题是在哪里,无比感激!
沙发
cjhk| | 2013-3-2 20:07 | 只看该作者
建议楼主分模块  将每个功能分得仔细一点   这样大家才会有耐心帮你查错   呵呵

使用特权

评论回复
板凳
cjhk| | 2013-3-2 20:08 | 只看该作者
顺便顶一下   呵呵   希望版主能够出面解决哦

使用特权

评论回复
地板
aaaxmaaa007|  楼主 | 2013-3-4 10:16 | 只看该作者
cjhk 发表于 2013-3-2 20:07
建议楼主分模块  将每个功能分得仔细一点   这样大家才会有耐心帮你查错   呵呵 ...

谢谢你的提示,我一会儿重新整理下,这样估计确实不容易看懂

使用特权

评论回复
5
aaaxmaaa007|  楼主 | 2013-3-5 08:44 | 只看该作者
问题已经解决,可以正常采集了,谢谢大家

使用特权

评论回复
6
lzq1804| | 2013-3-5 11:20 | 只看该作者
能把完成程序发上来,学习下吗?

使用特权

评论回复
7
aaaxmaaa007|  楼主 | 2013-3-5 14:33 | 只看该作者
lzq1804 发表于 2013-3-5 11:20
能把完成程序发上来,学习下吗?

    ADC_InitTypeDef ADC_InitStructure;

    ADC_DeInit(ADC1);
    ADC_DeInit(ADC2);
    DMA_DeInit(DMA1_Channel1);
    //ADC1 configuration
    ADC_InitStructure.ADC_Mode = ADC_Mode_SlowInterl;
    ADC_InitStructure.ADC_ScanConvMode = DISABLE;
    ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;
    ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
    ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
    ADC_InitStructure.ADC_NbrOfChannel = 1;
    ADC_Init(ADC1, &ADC_InitStructure);
    //ADC1 regular channel14 configuration
    ADC_RegularChannelConfig(ADC1, ADC_Channel_10, 1, ADC_SampleTime_13Cycles5);

    //Enable ADC1 DMA
    ADC_DMACmd(ADC1, ENABLE);

    //ADC2 configuration
    ADC_InitStructure.ADC_Mode = ADC_Mode_SlowInterl;
    ADC_InitStructure.ADC_ScanConvMode = DISABLE;
    ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;
    ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
    ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
    ADC_InitStructure.ADC_NbrOfChannel = 1;
    ADC_Init(ADC2, &ADC_InitStructure);

    //ADC2 regular channel14 configuration
    ADC_RegularChannelConfig(ADC2, ADC_Channel_10, 1, ADC_SampleTime_13Cycles5);

    // Enable ADC2 external trigger conversion
    ADC_ExternalTrigConvCmd(ADC2, ENABLE);

    //DMA Config
    DMA_InitTypeDef DMA_InitStructure;
    //DMA1 channel1 configuration
    DMA_DeInit(DMA1_Channel1);
    DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&ADC_Adc->DR;//(uint32)ADC1_DR_Address;
    DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)pCap_Line_Buf;//(uint32)&adc_data0[0];
    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
    DMA_InitStructure.DMA_BufferSize = 55;
    DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
    DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word;
    DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Word;
    DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;//连续触发
    DMA_InitStructure.DMA_Priority = DMA_Priority_High;
    DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
    DMA_Init(DMA1_Channel1, &DMA_InitStructure);
    //Enable DMA1 channel1
    DMA_ITConfig(DMA1_Channel1, DMA_IT_TC, ENABLE);
    //DMA_Cmd(DMA1_Channel1, ENABLE);

    //Enable ADC1 DMA
    ADC_DMACmd(ADC1, ENABLE);

    //Enable ADC1
    ADC_Cmd(ADC1, ENABLE);
    Delay_1ms(1);

    //Enable ADC1 reset calibaration register
    ADC_ResetCalibration(ADC1);
    //Check the end of ADC1 reset calibration register
    while(ADC_GetResetCalibrationStatus(ADC1));

    //Start ADC1 calibaration
    ADC_StartCalibration(ADC1);
    //Check the end of ADC1 calibration
    while(ADC_GetCalibrationStatus(ADC1));

    //Enable ADC2
    ADC_Cmd(ADC2, ENABLE);
    Delay_1ms(1);

    //Enable ADC2 reset calibaration register
    ADC_ResetCalibration(ADC2);
    //Check the end of ADC2 reset calibration register
    while(ADC_GetResetCalibrationStatus(ADC2));

    //Start ADC2 calibaration
    ADC_StartCalibration(ADC2);
    //Check the end of ADC2 calibration
    while(ADC_GetCalibrationStatus(ADC2));

    //Start ADC1 Software Conversion
    ADC_SoftwareStartConvCmd(ADC1, ENABLE);
上面是初始化部分,配置时先后顺序一定要正确,我之前就是因为顺序没配对,导致采集的数据出现问题!

使用特权

评论回复
8
aaaxmaaa007|  楼主 | 2013-3-5 14:36 | 只看该作者
初始化之后,我并没有使能DMA,我是在之后采集的时候才使能的,请注意!我的程序也是借鉴别人的,互相学习

使用特权

评论回复
9
lzq1804| | 2013-3-5 15:38 | 只看该作者
太感谢了。上司只给2个月时间,要用此款芯片开发一块DAQ卡出来。
只要是对ST的东西是0基础,太抗爹,搞到压力山大了。
朋友有好例子,多点往这里掉。

使用特权

评论回复
10
aaaxmaaa007|  楼主 | 2013-3-5 16:00 | 只看该作者
lzq1804 发表于 2013-3-5 15:38
太感谢了。上司只给2个月时间,要用此款芯片开发一块DAQ卡出来。
只要是对ST的东西是0基础,太抗爹 ...

加我QQ吧,我也是刚开始工作,很懂东西都不懂的,共同学习嘛  Q:491813506

使用特权

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

本版积分规则

11

主题

66

帖子

0

粉丝