你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

关于STM32的多路ADC+DMA采集的问题

[复制链接]
FoNg0716 提问时间:2016-4-20 19:09 /
阅读主题, 点击返回1楼
收藏 2 评论30 发布时间:2016-4-20 19:09
30个回答
ccmm520 回答时间:2018-3-15 21:55:50
本帖最后由 ccmm520 于 2018-3-16 17:16 编辑

问题如楼下帖子代码
ccmm520 回答时间:2018-3-16 09:41:34

自己支持下,希望有大神帮忙回复下,谢谢
ccmm520 回答时间:2018-3-16 15:01:22
Paderboy 发表于 2016-4-20 20:56
刚好有这个板子。。。做了个工程,开了4个ADC 通道, PA0 PA1 内部温度和内部参考电压通道。。
测试结果

adc.c 代码:
  1. ADC_HandleTypeDef hadc1;
  2. DMA_HandleTypeDef hdma_adc1;
  3. void MX_ADC1_Init(void)
  4. {
  5.   ADC_ChannelConfTypeDef sConfig;

  6.   /**Configure the global features of the ADC (Clock, Resolution, Data Alignment and number of conversion) */
  7.   hadc1.Instance = ADC1;
  8.   hadc1.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV2;
  9.   hadc1.Init.Resolution = ADC_RESOLUTION_12B;
  10.   hadc1.Init.ScanConvMode = ENABLE;
  11.   hadc1.Init.ContinuousConvMode = ENABLE;
  12.   hadc1.Init.DiscontinuousConvMode = DISABLE;
  13.   hadc1.Init.ExternalTrigConvEdge = ADC_SOFTWARE_START;
  14.   hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
  15.   hadc1.Init.NbrOfConversion = 2;
  16.   hadc1.Init.DMAContinuousRequests = ENABLE;
  17.   hadc1.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
  18.   HAL_ADC_Init(&hadc1);

  19.   /**Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time. */
  20.   sConfig.Channel = ADC_CHANNEL_5;
  21.   sConfig.Rank = 1;
  22.   sConfig.SamplingTime = ADC_SAMPLETIME_6CYCLES_5;
  23.   HAL_ADC_ConfigChannel(&hadc1, &sConfig);

  24.   /**Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time. */
  25.   sConfig.Channel = ADC_CHANNEL_3;
  26.   sConfig.Rank = 2;
  27.   HAL_ADC_ConfigChannel(&hadc1, &sConfig);

  28. }

  29. void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc)
  30. {
  31.   GPIO_InitTypeDef GPIO_InitStruct;
  32.   if(hadc->Instance==ADC1)
  33.   {
  34.     /* Peripheral clock enable */
  35.     __HAL_RCC_ADC_CLK_ENABLE();
  36.   
  37.     /**ADC1 GPIO Configuration   
  38.     PA0-WKUP     ------> ADC1_IN5
  39.     PC2     ------> ADC1_IN3 */
  40.     GPIO_InitStruct.Pin = GPIO_PIN_0;
  41.     GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
  42.     GPIO_InitStruct.Pull = GPIO_NOPULL;
  43.     HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
  44.                
  45.     GPIO_InitStruct.Pin = GPIO_PIN_2;
  46.     GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
  47.     GPIO_InitStruct.Pull = GPIO_NOPULL;
  48.     HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);

  49.     /* Peripheral DMA init*/
  50.     hdma_adc1.Instance = DMA1_Channel1;
  51.     hdma_adc1.Init.Direction = DMA_PERIPH_TO_MEMORY;
  52.     hdma_adc1.Init.PeriphInc = DMA_PINC_DISABLE;
  53.     hdma_adc1.Init.MemInc = DMA_MINC_ENABLE;
  54.     hdma_adc1.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
  55.     hdma_adc1.Init.MemDataAlignment = DMA_MDATAALIGN_WORD;
  56.     hdma_adc1.Init.Mode = DMA_CIRCULAR;
  57.     hdma_adc1.Init.Priority = DMA_PRIORITY_MEDIUM;
  58.     HAL_DMA_Init(&hdma_adc1);

  59.     __HAL_LINKDMA(hadc,DMA_Handle,hdma_adc1);
  60.   }
  61. }

  62. void HAL_ADC_MspDeInit(ADC_HandleTypeDef* hadc)
  63. {

  64.   if(hadc->Instance==ADC1)
  65.   {
  66.     /* Peripheral clock disable */
  67.     __HAL_RCC_ADC_CLK_DISABLE();
  68.   
  69.     /**ADC1 GPIO Configuration   
  70.     PA0-WKUP     ------> ADC1_IN5
  71.     PC2     ------> ADC1_IN3 */
  72.     HAL_GPIO_DeInit(GPIOA, GPIO_PIN_0);
  73.     HAL_GPIO_DeInit(GPIOC, GPIO_PIN_2);
  74.     /* Peripheral DMA DeInit*/
  75.     HAL_DMA_DeInit(hadc->DMA_Handle);
  76.   }
  77. }
复制代码


main.c 代码:
  1. /* USER CODE BEGIN 0 */
  2. uint32_t uhADCxConvertedValue[2];
  3. unsigned long shijian=0;
  4. volatile uint8_t dmaflage=0;
  5. /* USER CODE END 0 */
  6. int main(void)
  7. {

  8.   /* USER CODE BEGIN 1 */       
  9.   uint16_t ad1=0, ad2=0;
  10.   /* USER CODE END 1 */

  11.   /* MCU Configuration----------------------------------------------------------*/

  12.   /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  13.   HAL_Init();

  14.   /* Configure the system clock */
  15.   SystemClock_Config();

  16.   /* Initialize all configured peripherals */
  17.   MX_GPIO_Init();

  18.   MX_DMA_Init();
  19.   MX_ADC1_Init();
  20.   /* USER CODE BEGIN 2 */
  21. #if DEBUG_ENABLE
  22.    debugInit(115200);
  23. #endif

  24.   shijian=HAL_GetTick();
  25.   HAL_ADC_Start_DMA(&hadc1, (uint32_t*)&uhADCxConvertedValue,2);
  26.   printf("HAL_ADC_Start_DMA\r\n");
  27.   while (1)
  28.   {
  29.     if(HAL_GetTick()-shijian>=500)
  30.     {
  31.       if(dmaflage==1)
  32.       {
  33.         dmaflage=0;
  34.         ad1 = uhADCxConvertedValue[0];
  35.         ad2 = uhADCxConvertedValue[1];
  36.         printf("ad1=%d, ad2=%d, Vad1=%0.2fV, Vad2=%0.2fV \r\n",ad1,ad2, ad1*3.3/4096,ad2*3.3/4096);
  37.         ad1 = (ad1*330)/4096; //扩大100倍 ,3.3V, 4096=12bit
  38.         ad2 = (ad2*330)/4096;
  39.         printf("V100ad1=%d, V100ad2=%d\r\n",ad1,ad2);
  40.         HAL_ADC_Start_DMA(&hadc1, (uint32_t*)&uhADCxConvertedValue,2);       
  41.         ad1 = 0;
  42.         ad2 = 0;
  43.       }
  44.       shijian=HAL_GetTick();       
  45.     }
  46.   }
  47. }

  48. void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
  49. {
  50.   dmaflage=1;
  51.   HAL_ADC_Stop_DMA(&hadc1);
  52. }
复制代码


dma.c 代码:
  1. void MX_DMA_Init(void)
  2. {
  3.   /* DMA controller clock enable */
  4.   //  __HAL_RCC_DMA2_CLK_ENABLE();
  5.   __HAL_RCC_DMA1_CLK_ENABLE();
  6.        
  7.   /* NVIC configuration for DMA Input data interrupt */
  8.   HAL_NVIC_SetPriority(DMA1_Channel1_IRQn, 5, 0);
  9.   HAL_NVIC_EnableIRQ(DMA1_Channel1_IRQn);  

  10. }
复制代码


stm32l4xx_it.c 代码:
  1. extern DMA_HandleTypeDef hdma_adc1;

  2. /**
  3. * @brief This function handles DMA1 channel1 global interrupt.
  4. */
  5. void DMA1_Channel1_IRQHandler(void)
  6. {
  7.   HAL_DMA_IRQHandler(&hdma_adc1);
  8. }
复制代码


大致的代码就是上面,采用ADC1,PA0通道5,PC2通道3;PA0口直接接3.3V,PC2口直接接地。MCU是stm32l476RC,不能直接下载你的例程到板子上。
问题:
   使用上面的代码,转出来的电压值都是0.4~0.45V,理论上应该分别采集到的是3.3V和0V的,不知道为什么?我是新手,是不是我哪里配置不对啊,求大神帮忙~
wqchifi 回答时间:2018-5-14 14:48:03
感谢分享
hati 回答时间:2018-6-4 11:58:44
感谢分享,新人学习
asdfg221111 回答时间:2018-6-4 20:57:27
是做无刷电机的吗?下来研究研究
lemon9527 回答时间:2018-8-4 01:54:56
我也遇到同样的问题了
lemon9527 回答时间:2018-8-4 01:57:24
callback函数要怎么设置呢,我把printf 放在callback里,就可以打印出值,但是程序不进入while loop
mochen32 回答时间:2018-8-17 11:02:55
同样的问题,没有解决。为甚么回调函数中一定要增加标志位呢?
chuchengyong-99 回答时间:2018-8-22 18:14:08
stxiaobai 回答时间:2018-8-24 15:50:20
感谢分享
absdjko 回答时间:2018-11-16 10:18:51
我F407做这个也是卡在HAL_ADC_Start_DMA这里,打印不出数据,我用STlink仿真看到数组里是有数值的,谢谢楼主分享。HAL_ADC_ConvCpltCallback和HAL_ADC_ConvhalfCpltCallback区别在哪,请大侠赐教
absdjko 回答时间:2018-11-16 10:23:20
你们的STM32CUBEmx输出的代码是跟那位兄弟的一样的嘛?我这都写在main.c,看着心烦。还是自己改的。
absdjko 回答时间:2018-11-16 10:36:00
lemon9527 发表于 2018-8-4 01:57
callback函数要怎么设置呢,我把printf 放在callback里,就可以打印出值,但是程序不进入while loop ...

放进回调里面打印的飞快
absdjko 回答时间:2018-11-16 10:57:17
wuwovicky 发表于 2016-4-20 21:01
卡在哪个函数?
我不知道cube的ADC是怎么样的,但是我来分析的话,有以下几点:
1、你是怎么触发ADC采集的 ...

大神,回调函数是和中断差不断嘛?每过一段时间或者满足一定触发的条件就进入该函数?

所属标签

相似问题

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版