STM32L151 多通道ADC DMA循环扫描STM32CubeIDE STM32CubeMX参考设计

简介

项目开发过程中,采用STM32L151 芯片进行涉及,其中需要使用其片上ADC进行多路ADC数据采样。这里就记录一下实际这块的开发过程,其中涉及工程代码再项目中实际投产使用。STM32L151 多通道ADC DMA循环扫描STM32CubeIDE STM32CubeMX参考设计。

 本文使用工程下载

STM32L151多通道ADCDMA循环扫描STM32CubeIDESTM32CubeMX参考设计资源-优快云文库

设计思路

由于需要采样11路ADC电压,所以采用DMA的方式,并设置ADC循环扫描,来减轻CPU的工作负担。采用STM32CubeIDE、STM32CubeMX+Keil uVision5进行设计验证。

调试过程关键问题

刚开始开发采用STM32CubeIDE,由于版本较低,出现了一个比较难搞的问题,后面切换到STM32CubeMX+Keil uVision5进行开发。该问题记录在博客,有兴趣的同学可以了解一下STM32CubeIDE使用ADC采用DMA重大BUG-优快云博客

是否需要打开ADC中断?

我看了很多网上的设计,都没有说清楚这个问题。这里其实没有必要打开ADC中断了,因为已经有使用DMA了,DMA传输完成后会给出DMA中断。如果有需要,可以在DMA中断处理函数,进行处理。

void DMA1_Channel1_IRQHandler(void)
{
  /* USER CODE BEGIN DMA1_Channel1_IRQn 0 */

  /* USER CODE END DMA1_Channel1_IRQn 0 */
  HAL_DMA_IRQHandler(&hdma_adc);
  /* USER CODE BEGIN DMA1_Channel1_IRQn 1 */

  /* USER CODE END DMA1_Channel1_IRQn 1 */
}

硬件设计

时钟方面,使能外部8Mhz时钟,时钟配置图如下图所示,从图中可以看出ADC的时钟是由内部高速时钟提供的。

ADC设计,如下图所示,打开11路ADC采样通道。

软件设计

 串口打印设置

添加串口打印宏定义如下:

#ifdef __GNUC__
#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif

PUTCHAR_PROTOTYPE
{
//#if (DEBUG_PRINTF_ON == 1)
    //HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1 , 0xffff);
	while((USART1->SR&0x40)==0){};
		USART1->DR = ch;
//	while((USART3->SR&0x40)==0);
//		USART3->DR = ch;
//#endif
    return ch;
}

这里需要提醒的是采用STM32CubeMX+Keil uVision5进行设计的时候,因为使用了printf函数,所以需要将工程的如下设置勾选。

ADC初始化

 ADC初始配置如下代码所示,这里针对hadc.Init.ContinuousConvMode = DISABLE;由于DMA数据深度设置为1,也就是说11路采样数据采样完成后,就有DMA中断,所以DMA中断太频繁,如果设置hadc.Init.ContinuousConvMode = ENABLE;会导致MCU一直处于DMA中断中,这里也可以加深DMA采样数据来解决这个问题,由于本项目需求较为简单,就是对采样率没有特别要求。所以无需加深DMA的采样数据。ADC如果采样数据不对,可以尝试调大单个通道sConfig.SamplingTime = ADC_SAMPLETIME_96CYCLES;来进行调试。

hadc.Instance = ADC1;
  hadc.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV1;
  hadc.Init.Resolution = ADC_RESOLUTION_12B;
  hadc.Init.DataAlign = ADC_DATAALIGN_RIGHT;
  hadc.Init.ScanConvMode = ADC_SCAN_ENABLE;
  hadc.Init.EOCSelection = ADC_EOC_SEQ_CONV;
  hadc.Init.LowPowerAutoWait = ADC_AUTOWAIT_DISABLE;
  hadc.Init.LowPowerAutoPowerOff = ADC_AUTOPOWEROFF_DISABLE;
  hadc.Init.ChannelsBank = ADC_CHANNELS_BANK_A;
  hadc.Init.ContinuousConvMode = DISABLE;
  hadc.Init.NbrOfConversion = 11;
  hadc.Init.DiscontinuousConvMode = DISABLE;
  hadc.Init.ExternalTrigConv = ADC_SOFTWARE_START;
  hadc.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
  hadc.Init.DMAContinuousRequests = ENABLE;
  if (HAL_ADC_Init(&hadc) != HAL_OK)
  {
    Error_Handler();
  }

  /** Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time.
  */
  sConfig.Channel = ADC_CHANNEL_1;
  sConfig.Rank = ADC_REGULAR_RANK_1;
  sConfig.SamplingTime = ADC_SAMPLETIME_96CYCLES;
  if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK)
  {
    Error_Handler();
  }

  /** Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time.
  */
  sConfig.Channel = ADC_CHANNEL_4;
  sConfig.Rank = ADC_REGULAR_RANK_2;
  if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK)
  {
    Error_Handler();
  }

  /** Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time.
  */
  sConfig.Channel = ADC_CHANNEL_5;
  sConfig.Rank = ADC_REGULAR_RANK_3;
  if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK)
  {
    Error_Handler();
  }

  /** Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time.
  */
  sConfig.Channel = ADC_CHANNEL_6;
  sConfig.Rank = ADC_REGULAR_RANK_4;
  if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK)
  {
    Error_Handler();
  }

  /** Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time.
  */
  sConfig.Channel = ADC_CHANNEL_7;
  sConfig.Rank = ADC_REGULAR_RANK_5;
  if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK)
  {
    Error_Handler();
  }

  /** Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time.
  */
  sConfig.Channel = ADC_CHANNEL_8;
  sConfig.Rank = ADC_REGULAR_RANK_6;
  if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK)
  {
    Error_Handler();
  }

  /** Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time.
  */
  sConfig.Channel = ADC_CHANNEL_9;
  sConfig.Rank = ADC_REGULAR_RANK_7;
  if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK)
  {
    Error_Handler();
  }

  /** Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time.
  */
  sConfig.Channel = ADC_CHANNEL_18;
  sConfig.Rank = ADC_REGULAR_RANK_8;
  if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK)
  {
    Error_Handler();
  }

  /** Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time.
  */
  sConfig.Channel = ADC_CHANNEL_19;
  sConfig.Rank = ADC_REGULAR_RANK_9;
  if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK)
  {
    Error_Handler();
  }

  /** Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time.
  */
  sConfig.Channel = ADC_CHANNEL_20;
  sConfig.Rank = ADC_REGULAR_RANK_10;
  if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK)
  {
    Error_Handler();
  }

  /** Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time.
  */
  sConfig.Channel = ADC_CHANNEL_21;
  sConfig.Rank = ADC_REGULAR_RANK_11;
  if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK)
  {
    Error_Handler();
  }

 调试记录

STM32CubeIDE 1.7.0工程测试记录:

STM32CubeMX 6.8.1+Keil uVision5测试记录

本文使用工程下载

STM32L151多通道ADCDMA循环扫描STM32CubeIDESTM32CubeMX参考设计资源-优快云文库

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

大牛攻城狮

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值