搜索
bottom↓
回复: 9

STM32F030 多通道ADC DMA读取问题

[复制链接]

出0入0汤圆

发表于 2014-2-23 01:06:30 | 显示全部楼层 |阅读模式
描述:用ADC连续采集11路模拟信号,并由DMA传输到内存。
#define         ADC1_DR_Address      0x40012440        
__IO uint16_t RegularConvData_Tab[2];                                
__IO uint16_t ADC_ConvertedValueLocal1[AD_Array_Size];      
__IO uint16_t ADC_ConvertedValueLocal2[AD_Array_Size];      
uint8_t AD_Array_count=0;
void ADC1_DMA_Init(void)
{
        ADC_InitTypeDef     ADC_InitStruct;
        DMA_InitTypeDef     DMA_InitStruct;
        GPIO_InitTypeDef    GPIO_InitStruct;
        NVIC_InitTypeDef    NVIC_InitStruct;
        
        /* ADC1 DeInit */
        ADC_DeInit(ADC1);        
        
        /* Enable  GPIOA clock */
        RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);
        /* ADC1 Periph clock enable */
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);  
        /* DMA1 clock enable */
        RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1 , ENABLE);
        
        /* Configure PA.1  as analog input */
        GPIO_InitStruct.GPIO_Pin = GPIO_Pin_1 |GPIO_Pin_2;
        GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AN;
        GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL ;
        GPIO_Init(GPIOA, &GPIO_InitStruct);         
        
        //DMA NVIC
        NVIC_InitStruct.NVIC_IRQChannel = DMA1_Channel1_IRQn;
        NVIC_InitStruct.NVIC_IRQChannelPriority = 2;
        NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
        NVIC_Init(&NVIC_InitStruct);
               
        /* DMA1 Channel1 Config */
        DMA_DeInit(DMA1_Channel1);
        DMA_InitStruct.DMA_PeripheralBaseAddr = (uint32_t)ADC1_DR_Address;//ÉèÖÃÍâÉèµØÖ·
        DMA_InitStruct.DMA_MemoryBaseAddr = (uint32_t)RegularConvData_Tab;//ÅäÖÃÄÚ´æÓ³ÉäµØÖ·
        DMA_InitStruct.DMA_DIR = DMA_DIR_PeripheralSRC;                                                                                
        DMA_InitStruct.DMA_BufferSize = 2;                                                                                                                                
        DMA_InitStruct.DMA_PeripheralInc = DMA_PeripheralInc_Disable;                       
        DMA_InitStruct.DMA_MemoryInc = DMA_MemoryInc_Enable;                                                        
        DMA_InitStruct.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
        DMA_InitStruct.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;      
        DMA_InitStruct.DMA_Mode = DMA_Mode_Circular;                                                                                       
        DMA_InitStruct.DMA_Priority = DMA_Priority_High;                                                                       
        DMA_InitStruct.DMA_M2M = DMA_M2M_Disable;                                                                                                        
        DMA_Init(DMA1_Channel1, &DMA_InitStruct);
  
        /* DMA1 Channel1 enable */
        DMA_Cmd(DMA1_Channel1, ENABLE);                                                                                                                                               
        /*Enables the specified DMAy Channelx interrupts */
        DMA_ITConfig(DMA1_Channel1,DMA_IT_TC,ENABLE);                                                                                       
       /* ADC DMA request in circular mode */
        ADC_DMARequestModeConfig(ADC1, ADC_DMAMode_Circular);                                                        
       /* Enable ADC_DMA */
        ADC_DMACmd(ADC1, ENABLE);
        
        /* Initialize ADC structure */
        ADC_StructInit(&ADC_InitStruct);
        
        /* Configure the ADC1 in continous mode withe a resolutuion equal to 12 bits  */
        ADC_InitStruct.ADC_Resolution  = ADC_Resolution_12b;
        ADC_InitStruct.ADC_ContinuousConvMode  = ENABLE;
        ADC_InitStruct.ADC_ExternalTrigConvEdge  = ADC_ExternalTrigConvEdge_None;
        ADC_InitStruct.ADC_DataAlign  = ADC_DataAlign_Right;
        ADC_InitStruct.ADC_ScanDirection  = ADC_ScanDirection_Backward;
        ADC_Init(ADC1, &ADC_InitStruct);  

        ADC_ChannelConfig(ADC1, ADC_Channel_1, ADC_SampleTime_55_5Cycles);        
        ADC_ChannelConfig(ADC1, ADC_Channel_2, ADC_SampleTime_55_5Cycles);        
        
       /* ADCУ׼ */
        ADC_GetCalibrationFactor(ADC1);
      /* Enable ADC1 */
       ADC_Cmd(ADC1, ENABLE);     
      
      while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_ADRDY));
      /* ADC1 regular Software Start Conv */
      ADC_StartOfConversion(ADC1);
}
DMA中断函数
void DMA1_Channel1_IRQHandler(void)
{
        if(DMA_GetFlagStatus(DMA1_FLAG_TC1) != RESET)
        {                     
                if(AD_Array_count>=AD_Array_Size)
                {
                        DMA_ClearFlag(DMA1_FLAG_TC1);
                }
                else
                {
                        ADC_ConvertedValueLocal1[AD_Array_count]=RegularConvData_Tab[0];
                        ADC_ConvertedValueLocal2[AD_Array_count]=RegularConvData_Tab[1];
                        DMA_ClearFlag(DMA1_FLAG_TC1);
                        AD_Array_count++;
                }               
        }
}

问题,PA1接低电平,PA2接高电平,通过串口显示DMA读取的数据应该是低,高,但实际结果却是(每组结果显示两次)
0000
0000
4095
4095

4093
4095
0000
0000

4093
4095
0000
0000

4095
4095
0000
0000
……
……

只有第一组数据是正确的(低高),此后数据都是相反的(高低),怎么回事?

阿莫论坛20周年了!感谢大家的支持与爱护!!

月入3000的是反美的。收入3万是亲美的。收入30万是移民美国的。收入300万是取得绿卡后回国,教唆那些3000来反美的!

出0入0汤圆

发表于 2014-2-23 01:17:17 | 显示全部楼层
电压不稳

出0入0汤圆

发表于 2014-2-23 01:18:12 | 显示全部楼层
本帖最后由 tianheyun12 于 2014-2-23 01:19 编辑

有的还有通道错位以前遇到过,具体也忘了,初始化顺序你换下

出0入0汤圆

 楼主| 发表于 2014-2-23 01:38:35 | 显示全部楼层
我用三通道DMA采集PA0,PA1,PA2的管脚电压。对应ADC Channel为0,1,2.但是在DMA的目标buffer里,bufer[0],bufer[1],bufer[2]分别对应的数据分别是PA0,PA2,PA1,而不是PA0,PA1,PA2。在STM32F103里面的设置函数里可以设置转换顺序,但是STM32F0里面是默认的。哪个大侠知道怎么修改DMA对应的转换顺序吗?

这是一个帖子中的问题,和我的差不多,但也没有答案

出0入0汤圆

 楼主| 发表于 2014-2-23 01:39:02 | 显示全部楼层
tianheyun12 发表于 2014-2-23 01:18
有的还有通道错位以前遇到过,具体也忘了,初始化顺序你换下

哪个初始化顺序??

出0入0汤圆

发表于 2014-9-17 16:39:34 | 显示全部楼层
楼主的问题解决了吗?  我也遇到相同的问题!

另若ADC通道不是连续的(比喻通道1、通道4、通道7),结果又会如何?

出0入0汤圆

 楼主| 发表于 2014-10-29 22:30:43 | 显示全部楼层
AVR_PIC 发表于 2014-9-17 16:39
楼主的问题解决了吗?  我也遇到相同的问题!

另若ADC通道不是连续的(比喻通道1、通道4、通道7),结果又 ...

问题就是他的读取通道是错误的,解决办法就是每个通道给一个电压值,然后读取后,记录,重新做一个新的对应路径。笨办法了

出0入0汤圆

发表于 2015-9-22 14:52:58 | 显示全部楼层
遇到了相同的问题,不知道楼主的问题解决了吗?

出0入0汤圆

 楼主| 发表于 2015-11-1 19:19:57 | 显示全部楼层
解决办法就是每个通道给一个电压值,然后读取后,记录,重新做一个新的对应路径。

出0入0汤圆

发表于 2016-9-23 23:10:30 | 显示全部楼层
学习下,刚好碰到这个
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-4-25 09:16

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表