F407 芯片 DMA 获取 ADC数据异常

2019-07-21 03:44发布

我现在使用stm32f4上一个dma ,同时获取 adc1 上12个通道的数据,adc2 上一个通道的数据 和 adc3 上8个通道的数据,但是现在获取的数据都是0xFF,代码如下
首先配置ADC 1,2,3
void MX_ADC1_Init(void) {   ADC_ChannelConfTypeDef sConfig_ADC1;     __ADC1_CLK_ENABLE();
     hadc1.Instance = ADC1;   hadc1.Init.ClockPrescaler = ADC_CLOCKPRESCALER_PCLK_DIV8;   hadc1.Init.Resolution = ADC_RESOLUTION8b;   hadc1.Init.ScanConvMode = ENABLE;   hadc1.Init.ContinuousConvMode = ENABLE;   hadc1.Init.DiscontinuousConvMode = DISABLE;   hadc1.Init.NbrOfDiscConversion = 0;   hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;   hadc1.Init.ExternalTrigConv = ADC_EXTERNALTRIGCONV_T1_CC1;   hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;   hadc1.Init.NbrOfConversion = 12;   hadc1.Init.DMAContinuousRequests = ENABLE;   hadc1.Init.EOCSelection = DISABLE;   HAL_ADC_Init(&hadc1);
  sConfig_ADC1.Channel = ADC_CHANNEL_0;   sConfig_ADC1.Rank = 1;   sConfig_ADC1.SamplingTime = ADC_SAMPLETIME_480CYCLES;   HAL_ADC_ConfigChannel(&hadc1, &sConfig_ADC1);
  sConfig_ADC1.Channel = ADC_CHANNEL_1;   sConfig_ADC1.Rank = 2;   HAL_ADC_ConfigChannel(&hadc1, &sConfig_ADC1);
  sConfig_ADC1.Channel = ADC_CHANNEL_2;   sConfig_ADC1.Rank = 3;   HAL_ADC_ConfigChannel(&hadc1, &sConfig_ADC1);
  sConfig_ADC1.Channel = ADC_CHANNEL_3;   sConfig_ADC1.Rank = 4;   HAL_ADC_ConfigChannel(&hadc1, &sConfig_ADC1);
  sConfig_ADC1.Channel = ADC_CHANNEL_4;   sConfig_ADC1.Rank = 5;   HAL_ADC_ConfigChannel(&hadc1, &sConfig_ADC1);
  sConfig_ADC1.Channel = ADC_CHANNEL_5;   sConfig_ADC1.Rank = 6;   HAL_ADC_ConfigChannel(&hadc1, &sConfig_ADC1);
  sConfig_ADC1.Channel = ADC_CHANNEL_6;   sConfig_ADC1.Rank = 7;   HAL_ADC_ConfigChannel(&hadc1, &sConfig_ADC1);
  sConfig_ADC1.Channel = ADC_CHANNEL_7;   sConfig_ADC1.Rank = 8;   HAL_ADC_ConfigChannel(&hadc1, &sConfig_ADC1);      sConfig_ADC1.Channel = ADC_CHANNEL_8;   sConfig_ADC1.Rank = 9;   HAL_ADC_ConfigChannel(&hadc1, &sConfig_ADC1);      sConfig_ADC1.Channel = ADC_CHANNEL_9;   sConfig_ADC1.Rank = 10;   HAL_ADC_ConfigChannel(&hadc1, &sConfig_ADC1);      sConfig_ADC1.Channel = ADC_CHANNEL_10;   sConfig_ADC1.Rank = 11;   HAL_ADC_ConfigChannel(&hadc1, &sConfig_ADC1);
  sConfig_ADC1.Channel = ADC_CHANNEL_11;   sConfig_ADC1.Rank = 12;   HAL_ADC_ConfigChannel(&hadc1, &sConfig_ADC1); }
void MX_ADC2_Init(void) {   ADC_ChannelConfTypeDef sConfig_ADC2;   __ADC2_CLK_ENABLE();        hadc2.Instance = ADC2;   hadc2.Init.ClockPrescaler = ADC_CLOCKPRESCALER_PCLK_DIV8;   hadc2.Init.Resolution = ADC_RESOLUTION8b;   hadc2.Init.ScanConvMode = ENABLE;   hadc2.Init.ContinuousConvMode = ENABLE;   hadc2.Init.DiscontinuousConvMode = DISABLE;   hadc2.Init.NbrOfDiscConversion = 0;   hadc2.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;   hadc2.Init.ExternalTrigConv = ADC_EXTERNALTRIGCONV_T1_CC1;   hadc2.Init.DataAlign = ADC_DATAALIGN_RIGHT;   hadc2.Init.NbrOfConversion = 1;   hadc2.Init.DMAContinuousRequests = ENABLE;   hadc2.Init.EOCSelection = EOC_SEQ_CONV;   HAL_ADC_Init(&hadc2);        sConfig_ADC2.Channel = ADC_CHANNEL_12;   sConfig_ADC2.Rank = 1;   HAL_ADC_ConfigChannel(&hadc2, &sConfig_ADC2);   }

/* ADC init function */ void MX_ADC3_Init(void) {
  ADC_ChannelConfTypeDef sConfig_ADC3;   __ADC3_CLK_ENABLE();      hadc3.Instance = ADC3;   hadc3.Init.ClockPrescaler = ADC_CLOCKPRESCALER_PCLK_DIV8;   hadc3.Init.Resolution = ADC_RESOLUTION8b;   hadc3.Init.ScanConvMode = ENABLE;   hadc3.Init.ContinuousConvMode = ENABLE;   hadc3.Init.DiscontinuousConvMode = DISABLE;   hadc3.Init.NbrOfDiscConversion = 0;   hadc3.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;   hadc3.Init.ExternalTrigConv = ADC_EXTERNALTRIGCONV_T1_CC1;   hadc3.Init.DataAlign = ADC_DATAALIGN_RIGHT;   hadc3.Init.NbrOfConversion = 8;   hadc3.Init.DMAContinuousRequests = ENABLE;   hadc3.Init.EOCSelection = DISABLE;   HAL_ADC_Init(&hadc3);
  sConfig_ADC3.Channel = ADC_CHANNEL_0;   sConfig_ADC3.Rank = 1;   sConfig_ADC3.SamplingTime = ADC_SAMPLETIME_480CYCLES;   HAL_ADC_ConfigChannel(&hadc3, &sConfig_ADC3);
  sConfig_ADC3.Channel = ADC_CHANNEL_1;   sConfig_ADC3.Rank = 2;   HAL_ADC_ConfigChannel(&hadc3, &sConfig_ADC3); 
  sConfig_ADC3.Channel = ADC_CHANNEL_2;   sConfig_ADC3.Rank = 3;   HAL_ADC_ConfigChannel(&hadc3, &sConfig_ADC3);
  sConfig_ADC3.Channel = ADC_CHANNEL_3;   sConfig_ADC3.Rank = 4;   HAL_ADC_ConfigChannel(&hadc3, &sConfig_ADC3);
  sConfig_ADC3.Channel = ADC_CHANNEL_4;   sConfig_ADC3.Rank = 5;   HAL_ADC_ConfigChannel(&hadc3, &sConfig_ADC3); 
  sConfig_ADC3.Channel = ADC_CHANNEL_5;   sConfig_ADC3.Rank = 6;   HAL_ADC_ConfigChannel(&hadc3, &sConfig_ADC3); 
  sConfig_ADC3.Channel = ADC_CHANNEL_6;   sConfig_ADC3.Rank = 7;   HAL_ADC_ConfigChannel(&hadc3, &sConfig_ADC3);      sConfig_ADC3.Channel = ADC_CHANNEL_7;   sConfig_ADC3.Rank = 8;   HAL_ADC_ConfigChannel(&hadc3, &sConfig_ADC3); 
}

再处理gpio  void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc) {
  GPIO_InitTypeDef GPIO_InitStruct;   if (hadc == &hadc3)   { //    F6 ------>ADC3_IN4   IR1 //    F7 ------>ADC3_IN5      IR2 //    F8 ------>ADC3_IN6   IR3 //    F9 ------>ADC3_IN7   IR4 //    F10------>ADC3_IN8   IR5 //    F3 ------>ADC3_IN9   IR6 //    F4 ------>ADC3_IN14   IR7 //    F5 ------>ADC3_IN15   IR8     GPIO_InitStruct.Pin = IR_DAT_PIN0|IR_DAT_PIN1|IR_DAT_PIN2|IR_DAT_PIN3                           |IR_DAT_PIN4|IR_DAT_PIN5|IR_DAT_PIN6|IR_DAT_PIN7;     GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;     GPIO_InitStruct.Pull = GPIO_NOPULL;     HAL_GPIO_Init(IR_DAT_PORT, &GPIO_InitStruct);     
  }           if (hadc == &hadc2)   {     GPIO_InitStruct.Pin = GPIO_PIN_2;     GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;     GPIO_InitStruct.Pull = GPIO_NOPULL;     HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);        }   if (hadc == &hadc1)   {     /**ADC1 GPIO Configuration     PA0-WKUP     ------> ADC1_IN0     PA1     ------> ADC1_IN1     PA2     ------> ADC1_IN2     PA3     ------> ADC1_IN3     PA4     ------> ADC1_IN4     PA5     ------> ADC1_IN5     PA6     ------> ADC1_IN6     PA7     ------> ADC1_IN7     PB0     ------> ADC1_IN8     PB1     ------> ADC1_IN9         PC0     ------> ADC1_IN10     PC1     ------> ADC1_IN11     */     GPIO_InitStruct.Pin = M_DAT_PIN0|M_DAT_PIN1|M_DAT_PIN2|M_DAT_PIN3|M_DAT_PIN4|     M_DAT_PIN5|M_DAT_PIN6|M_DAT_PIN7;     GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;     GPIO_InitStruct.Pull = GPIO_NOPULL;     HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);          GPIO_InitStruct.Pin = M_DAT_PIN8|M_DAT_PIN9;     GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;     GPIO_InitStruct.Pull = GPIO_NOPULL;     HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
         GPIO_InitStruct.Pin = M_DAT_PIN10|M_DAT_PIN11;     GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;     GPIO_InitStruct.Pull = GPIO_NOPULL;     HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);          //ADC1 IO CONFIG FINISH          GPIO_InitStruct.Pin = GPIO_PIN_2|GPIO_PIN_3;     GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;     GPIO_InitStruct.Pull = GPIO_NOPULL;     HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);          hdma_adc1.Instance = DMA2_Stream0;     hdma_adc1.Init.Channel = DMA_CHANNEL_0;     hdma_adc1.Init.Direction = DMA_PERIPH_TO_MEMORY;     hdma_adc1.Init.PeriphInc = DMA_PINC_DISABLE;     hdma_adc1.Init.MemInc = DMA_MINC_ENABLE;     hdma_adc1.Init.PeriphDataAlignment = DMA_MDATAALIGN_WORD;     hdma_adc1.Init.MemDataAlignment = DMA_MDATAALIGN_WORD;     hdma_adc1.Init.Mode = DMA_CIRCULAR;     hdma_adc1.Init.Priority = DMA_PRIORITY_MEDIUM;     hdma_adc1.Init.FIFOMode = DMA_FIFOMODE_DISABLE;     hdma_adc1.Init.FIFOMode = DMA_FIFOMODE_DISABLE;              hdma_adc1.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_HALFFULL;     hdma_adc1.Init.MemBurst = DMA_MBURST_SINGLE;     hdma_adc1.Init.PeriphBurst = DMA_PBURST_SINGLE;      HAL_DMA_Init(&hdma_adc1);     __HAL_LINKDMA(hadc,DMA_Handle,hdma_adc1);   }    }

然后启动
    if(HAL_ADC_Start(&hadc1) != HAL_OK)   {
    Error_Handler();    }       if(HAL_ADC_Start(&hadc2) != HAL_OK)   {     /* Start Error */    Error_Handler();    }        if(HAL_ADC_Start(&hadc3) != HAL_OK)   {
    Error_Handler();    }        ADC_MultiModeTypeDef   mode;   mode.Mode = ADC_TRIPLEMODE_INTERL;   mode.DMAAccessMode = ADC_DMAACCESSMODE_1;   mode.TwoSamplingDelay = ADC_TWOSAMPLINGDELAY_20CYCLES;          if(HAL_ADCEx_MultiModeConfigChannel(&hadc1, &mode) != HAL_OK)   {     /* Channel Configuration Error */     Error_Handler();    }
    if(HAL_ADCEx_MultiModeStart_DMA(&hadc1, (uint32_t*)&uhADCxConvertedValue, 40) != HAL_OK)   {     /* Start Error */     Error_Handler();    }

最终在这里获取上数据 void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* AdcHandle) { 这里直接断点看结果
00000000 00000000 00000000 ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff 00000000 00000000 00000000 }
为啥会这样??? 我的ref脚 3.3v已经ok ,其他脚上的电压应该是七零八落不会全是ff这么整齐呀
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
3条回答
正点原子
1楼-- · 2019-07-21 05:36
帮顶....
xuande
2楼-- · 2019-07-21 09:48
1、质疑这么做的意义。
DMA的优势,是速度快,软件需求量少。
但LZ这需求,必须频繁更换ADC的输入切换开关,这必须用软件实现。这样,DMA的意义就打了折扣。
与其DMA,不如软件直接实现。

2、如果一定要这么做,给些建议:

这种把几个动作连贯起来的事,还是有点难度的。
一定要明确物理过程:希望实现什么过程?要分解成几个动作?每个动作如何实现?
friendzj
3楼-- · 2019-07-21 10:03
回复【3楼】xuande:
---------------------------------
1、原因,主要是为了保证逻辑处理的连贯性,因为我要测试的对象逻辑都一样,全部用dma处理以后,可以保证逻辑的单一性,当然么,复杂性转移到驱动层了。

2、我希望的目标不停的、或者说尽量快的同时测量21个对象,输出到一个内存块中。后续有算法单独处理这些数据。

一周热门 更多>