天天看点

STM32CUBEMX-----ADC单次转换模式连续转换+DMA传输模式遇到的问题

平台:STM32F103C8T6最小系统板

STM32CUBEMX-V6.1.2-1.8.4版本的F1固件包+MDK5.31

目录

单次转换模式

连续转换+DMA传输模式

遇到的问题

单次转换模式

以配置ADC1的IN0,IN1这两通道为例

1:勾选IN0,IN1

STM32CUBEMX-----ADC单次转换模式连续转换+DMA传输模式遇到的问题
2:数据选择右对齐
STM32CUBEMX-----ADC单次转换模式连续转换+DMA传输模式遇到的问题
3:选择是否使能规则转换
STM32CUBEMX-----ADC单次转换模式连续转换+DMA传输模式遇到的问题

因为我们采用单次转换模式,所以此选项可以先失能掉。

4:其它保持默认,完成时钟等其它配置后,生成代码

5:添加如下函数

/**
 * @brief 获取指定通道的ADC采集值
 * @param channel 要采集的ADC通道
 * @retval 采集到的ADC数据
 */ 
uint16_t adc_get(uint32_t channel)
{
  ADC_ChannelConfTypeDef sConfig = {0};
  sConfig.Channel = channel;
  sConfig.Rank = ADC_REGULAR_RANK_1;
  sConfig.SamplingTime = ADC_SAMPLETIME_239CYCLES_5; 
  if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
  {
    Error_Handler();
  }
  HAL_ADC_Start(&hadc1);
  HAL_ADC_PollForConversion(&hadc1,100);     //等待规则组转换完成
  return (uint16_t)HAL_ADC_GetValue(&hadc1);
}
           
6:通过调用上述函数传入ADC采集通道,就可以获取相应通道的ADC数据。

连续转换+DMA传输模式

以配置ADC1的IN0,IN1这两通道为例,重复的步骤看前面

1:扫描模式和连续转换模式都要使能

     扫描模式在使能规则转换且转换数量大于1之后会自动使能

STM32CUBEMX-----ADC单次转换模式连续转换+DMA传输模式遇到的问题
2:规则转换的配置如下
STM32CUBEMX-----ADC单次转换模式连续转换+DMA传输模式遇到的问题
3:在DAM_Setting中配置如下
STM32CUBEMX-----ADC单次转换模式连续转换+DMA传输模式遇到的问题

mode选择Circular,这样才会循环的去搬运数据

搬运到地址空间的Data Width设置为字,也就是32位。这样方便后续的读数。若设置为半字,那么在后续读数的时候,需要将DMA的目标缓冲区(32位的)进行拆分后再进行读数。

4:生成代码,在开始读取数据之前加入如下代码

HAL_ADCEx_Calibration_Start(&hadc1);            //执行ADC的自动校准
  HAL_NVIC_DisableIRQ(DMA1_Channel1_IRQn);        //失能DMA的中断
  HAL_ADC_Start_DMA(&hadc1,(uint32_t *)ad_buf,2); //设置数据缓冲区
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */
    /* USER CODE BEGIN 3 */
    My_Pri_log_x(1,"ad_va1:%d    ",ad_buf[0]);
    My_Pri_log_x(1,"ad_va2:%d\r\n",ad_buf[1]);
    HAL_Delay(500);
  }
           
其中,之所以要失能DMA中断,是因为在CUBEMX配置DMA传输的时候会强制使能DMA Channel1 的全局中断,如图
STM32CUBEMX-----ADC单次转换模式连续转换+DMA传输模式遇到的问题

但我并不需要,所以将其关闭。

数据缓冲区  ad_buf 是一个32位两个元素的数组。

5:读取DMA传输目的地址 ad_buf  的值,就可以获得两个ADC通道的数据。

遇到的问题

现象:

无论是单次转换模式,还是连续转换+DMA传输的模式,都会遇到一个问题,那就是通道之间会相互干扰。即一个通道电压的变化会微量的影响到其它通道电压的变化。

原因:

多个通道是通过模拟多路开关自动切换的,这就导致,在切换的瞬间上一个通道的电压值会干扰到下一个通道,切换速度越快,影响越大,切换的时间间隔越久,影响越小

解决办法:

1:增大Sampling Time可以一定程度上减小影响

2:在单次转换模式中,可以在转换之间插入一定延时,也可以采用平均求值的方式

3:将通过1和通道2配置到ADC1和ADC2上面,彻底隔离,单次转换中试过此方法,连续转换+DMA中没试过,有待验证。

4:在AD通道管脚上并联一个100nf左右的电容,没试过,有待验证。

继续阅读