STM32F072--ADC-DMA多路采集数据混乱

2019-07-21 03:33发布

没路单独测试偶没有问题,连续采集就会出现数据混乱,求指教!!! unsigned int after_value[5];
unsigned int average_value[5]; #define ADC1_DR_ADDRESS     ((uint32_t)0x40012440)
void ADC_DMA_Config(void)

      GPIO_InitTypeDef  GPIO_InitStructure;
      ADC_InitTypeDef   ADC_InitStructure;
      DMA_InitTypeDef   DMA_InitStructure;
 
      ADC_DeInit(ADC1);
      /* RCC Config */
      RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);
      RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
      RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
  
      /* GPIO Config */
      GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_3|GPIO_Pin_6|GPIO_Pin_7;
      GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
      GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
      GPIO_Init(GPIOA, &GPIO_InitStructure);
 
 
       /* DMA1 Config */
       DMA_DeInit(DMA1_Channel1);
       DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)ADC1_DR_ADDRESS;
       DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&after_value;
       DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
       DMA_InitStructure.DMA_BufferSize = 5;
       DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
       DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
       DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
       DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
       DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
       DMA_InitStructure.DMA_Priority = DMA_Priority_High;
       DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
       DMA_Init(DMA1_Channel1, &DMA_InitStructure);
  
       DMA_Cmd(DMA1_Channel1, ENABLE);
  
       ADC_DMARequestModeConfig(ADC1, ADC_DMAMode_Circular);
  
       ADC_DMACmd(ADC1, ENABLE);//Enable ADC_DMA
  
       /* ADC1 Config */
       ADC_StructInit(&ADC_InitStructure);
       ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
       ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
       ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;
       //ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T1_TRGO;
       ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
       ADC_InitStructure.ADC_ScanDirection = ADC_ScanDirection_Upward;
       ADC_Init(ADC1, &ADC_InitStructure); 
  
       ADC_ChannelConfig(ADC1, ADC_Channel_0, ADC_SampleTime_239_5Cycles);
       ADC_ChannelConfig(ADC1, ADC_Channel_1, ADC_SampleTime_239_5Cycles);
       ADC_ChannelConfig(ADC1, ADC_Channel_3, ADC_SampleTime_239_5Cycles);
       ADC_ChannelConfig(ADC1, ADC_Channel_6, ADC_SampleTime_239_5Cycles);
       ADC_ChannelConfig(ADC1, ADC_Channel_7, ADC_SampleTime_239_5Cycles);
   
       ADC_GetCalibrationFactor(ADC1);
      
       ADC_Cmd(ADC1, ENABLE);
  
       while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_ADRDY));
  
       ADC_StartOfConversion(ADC1);
}
void Read_ADC(void)
{
    unsigned char a,b,c,d,i;
 
    for(i=0;i<M;i++)
    {      
       while((DMA_GetFlagStatus(DMA1_FLAG_TC1)) == RESET);//Test DMA1 TC flag 
       DMA_ClearFlag(DMA1_FLAG_TC1);//Clear DMA TC flag      
       average_value = (unsigned int)((after_value*3342)/0x0FFF); 
    
       a = average_value/1000;
       b = (average_value - a*1000)/100;
       c = (average_value - a*1000 - b*100)/10;
       d = average_value - a*1000 - b*100 - c*10;
       USART_Put_Char(0x56);//"V"
       USART_Put_Char(i+48);
       USART_Put_Char(0x3D);//"="
       USART_Put_Char(a+48);
       USART_Put_Char(0x2e);//"."
       USART_Put_Char(b+48);
       USART_Put_Char(c+48);
       USART_Put_Char(d+48);
       USART_Put_Char(0x56);//"V"
       USART_Put_Char(0xD);
       USART_Put_Char(0xA);   
  }
}

void USART_Config()
{
  GPIO_InitTypeDef   GPIO_InitStructure;
  USART_InitTypeDef USART_InitStructure;
 
  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA,ENABLE);
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);
 
  GPIO_PinAFConfig(GPIOA,GPIO_PinSource9,GPIO_AF_1);
  GPIO_PinAFConfig(GPIOA,GPIO_PinSource10,GPIO_AF_1);
 
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9|GPIO_Pin_10;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(GPIOA,&GPIO_InitStructure);
 
  USART_InitStructure.USART_BaudRate = 9600;
  USART_InitStructure.USART_WordLength = USART_WordLength_8b;
  USART_InitStructure.USART_StopBits = USART_StopBits_1;
  USART_InitStructure.USART_Parity = USART_Parity_No;
  USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//
  USART_InitStructure.USART_Mode = USART_Mode_Rx|USART_Mode_Tx;
  USART_Init(USART1,&USART_InitStructure);//?®??????
  //USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);
  USART_Cmd(USART1,ENABLE);
}
void USART_Put_Char(unsigned char ch)
{
   USART_SendData(USART1,ch);
  while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==RESET);
}

int main(void)
{
   ADC_DMA_Config();
   USART_Config();
 
    while(1)
  {     
        delay_s(1);
        Read_ADC(); 
        USART_Put_Char(0xD);
        USART_Put_Char(0xA);
  }
}
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
11条回答
fanghuiopenedv
1楼-- · 2019-07-21 04:48
我也遇到这个问题了。
网上搜索了下。这个大神帮我解决了这个问题。
stmf030 用dma进行ADC采集的时候应该注意:
 " F0的ADC在使用之前需要校准。这个7位的校准值也是放在ADC_DR中的,它也会触发DMA请求。可以参照F0的ADC-DMA例程,
先做ADC校准、然后再设置DMA,再使能ADC的DMA。"---这是另外一个大神说的原话。

他的博客地址:
http://blog.csdn.net/lan120576664/article/details/41584577
正点原子
2楼-- · 2019-07-21 07:32
论坛有其它网友发过103的多路采集,072应该也差不多,你搜索参考下。
goodgft
3楼-- · 2019-07-21 09:33
回复【2楼】正点原子:
---------------------------------
103这样问题的帖子我基本上都试了一遍,还是不行啊,怎么办啊老大,帮忙看看,我实在找不到哪里出了问题。
goodgft
4楼-- · 2019-07-21 15:00


这是串口收到的数据

goodgft
5楼-- · 2019-07-21 18:44
 精彩回答 2  元偷偷看……
goodgft
6楼-- · 2019-07-21 21:46

现在改成非DMA方式,采样结果总是出现错位和重复,求解?

unsigned short int after_value[2];

unsigned short int average_value[2];


void ADC_DMA_Config(void)
{
    GPIO_InitTypeDef  GPIO_InitStructure;
    ADC_InitTypeDef   ADC_InitStructure;


    /* RCC Config */
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
   
     /* GPIO Config */
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
  
    /* ADC1 Config */
    ADC_StructInit(&ADC_InitStructure);
    ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
    ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
    ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;
    ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
    ADC_InitStructure.ADC_ScanDirection = ADC_ScanDirection_Upward;
    ADC_Init(ADC1, &ADC_InitStructure); 
   
    ADC_GetCalibrationFactor(ADC1);
    ADC_AutoPowerOffCmd(ADC1,ENABLE);  
    ADC_Cmd(ADC1, ENABLE);  
    while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_ADEN));
    ADC_StartOfConversion(ADC1);
}


void Read_ADC(void)

    unsigned char a,b,c,d,i;
 
    for(i=0;i<2;i++)
    {     
         switch(i)
        {
              case 0: ADC_ChannelConfig(ADC1, ADC_Channel_0, ADC_SampleTime_13_5Cycles); break;
              case 1: ADC_ChannelConfig(ADC1, ADC_Channel_1, ADC_SampleTime_13_5Cycles); break; 
              default: break;
        }
        if(ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC)!=RESET)
       {
              delay_ms(2);
              after_value = ADC_GetConversionValue(ADC1);
       }   
       average_value = (unsigned short int)(after_value*3342/0x0FFF); 
    
       a = average_value/1000;
       b = (average_value - a*1000)/100;
       c = (average_value - a*1000 - b*100)/10;
       d = average_value - a*1000 - b*100 - c*10;
       USART_Put_Char(0x56);//"V"
       USART_Put_Char(i+48);
       USART_Put_Char(0x3D);//"="
       USART_Put_Char(a+48);
       USART_Put_Char(0x2e);//"."
       USART_Put_Char(b+48);
       USART_Put_Char(c+48);
       USART_Put_Char(d+48);
       USART_Put_Char(0x56);//"V"
       USART_Put_Char(0xD);
       USART_Put_Char(0xA);            
    }
}


int main(void)
{
   ADC_DMA_Config();
   USART_Config();
   
    while(1)
  {    
       delay_s(1);
       Read_ADC();

      USART_Put_Char(0xD);
      USART_Put_Char(0xA);
  }
}


应该显示为:

V0=1.743V

V1=3.011V

实际现象确是:

一周热门 更多>