首页 > 解决方案 > STM32L4 ADC 不工作(多通道无 DMA)

问题描述

我正在尝试运行一段时间前在这里找到的代码,它允许从几个通道中选择一个 ADC 通道,并在必要时单独读取它。不涉及 DMA。我使用STM32L4R5。我的想法只是通过打开和关闭状态 LED 来确认正确的 ADC 读数,如果某个级别可用并且到目前为止它根本不工作(状态 LED 始终为 ON)。对于输入信号源,我使用一个设置为高电平的 GPIO 引脚,它通过一个 1k 电阻和一个 LED,因此电压约为 0.7V。我打电话给 __HAL_RCC_ADC_CLK_ENABLE(); 和 __HAL_RCC_GPIOC_CLK_ENABLE(); 在 HAL_ADC_MspInit() 中。status_led() 函数没有显示,但我经常使用它,没问题。

其余代码如下:

uint32_t pdlvl=0;

int main(void)
{
    HAL_Init();
    SystemClock_Config();
    MX_GPIO_Init();
    MX_ADC1_Init();
    MX_TIM1_Init();

    // Test ADC reading voltage input
    //

    while(1){
        pdlvl=read_ADC_channel(ADC_CHANNEL_13);
        if(pdlvl<10){
            status_led(4,1);
            status_led(3,0);
        }
        if(pdlvl>10){
            status_led(3,1);
            status_led(4,0);
        }
    }

} // end of main
static void MX_ADC1_Init(void)
{

  ADC_ChannelConfTypeDef sConfig = {0};

  hadc1.Instance = ADC1;
  hadc1.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV1;
  hadc1.Init.Resolution = ADC_RESOLUTION_12B;
  hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
  hadc1.Init.ScanConvMode = DISABLE;
  hadc1.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
  hadc1.Init.LowPowerAutoWait = DISABLE;
  hadc1.Init.ContinuousConvMode = DISABLE;
  hadc1.Init.NbrOfConversion = 1;
  hadc1.Init.DiscontinuousConvMode = DISABLE;
  hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;
  hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
  hadc1.Init.DMAContinuousRequests = DISABLE;
  hadc1.Init.Overrun = ADC_OVR_DATA_PRESERVED;
  hadc1.Init.OversamplingMode = DISABLE;
  if (HAL_ADC_Init(&hadc1) != HAL_OK)
  {
    Error_Handler();
  }

  sConfig.Channel = ADC_CHANNEL_13;
  sConfig.Rank = ADC_RANK_NONE;
  sConfig.SamplingTime = ADC_SAMPLETIME_640CYCLES_5;
  sConfig.SingleDiff = ADC_SINGLE_ENDED;
  sConfig.OffsetNumber = ADC_OFFSET_NONE;
  if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
  {
    Error_Handler();
  }

  sConfig.Channel = ADC_CHANNEL_14;
  if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
  {
    Error_Handler();
  }

}

引脚初始化

static void MX_GPIO_Init(void)
{
  GPIO_InitTypeDef GPIO_InitStruct = {0};

  __HAL_RCC_GPIOC_CLK_ENABLE();

  GPIO_InitStruct.Pin = ROUT1_Pin|ROUT2_Pin; // ADC_CHANNEL_13 and ADC_CHANNEL_14
  GPIO_InitStruct.Mode = GPIO_MODE_ANALOG_ADC_CONTROL;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);

}

现在是通道预配置的棘手部分:


void config_ADC_channel(uint32_t channel, uint8_t val)
{
    ADC_ChannelConfTypeDef sConfig;

    sConfig.Channel = channel;
    sConfig.SamplingTime = ADC_SAMPLETIME_640CYCLES_5;
    sConfig.SingleDiff = ADC_SINGLE_ENDED;
    sConfig.OffsetNumber = ADC_OFFSET_NONE;

    if(val==1){
        sConfig.Rank = 1;
    }
    else{
        sConfig.Rank = ADC_RANK_NONE;
    }
    HAL_ADC_ConfigChannel(&hadc1, &sConfig);
}

和阅读功能

uint32_t read_ADC_channel(uint32_t channel)
{
  uint32_t digital_result;

  config_ADC_channel(channel, 1);

//  HAL_ADCEx_Calibration_Start(&hadc1,ADC_SINGLE_ENDED);

  HAL_ADC_Start(&hadc1);
  HAL_ADC_PollForConversion(&hadc1, 1000);
  digital_result = HAL_ADC_GetValue(&hadc1);
  HAL_ADC_Stop(&hadc1);

  config_ADC_channel(channel, 0);

  return digital_result;
}

有什么想法我错了吗?

谢谢!

标签: stm32adc

解决方案


我发现了问题。我没有正确设置外围时钟源(最初由 CubeMX 生成,后来由我修改):

PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_ADC;
  PeriphClkInit.I2c1ClockSelection = RCC_I2C1CLKSOURCE_PCLK1;
  PeriphClkInit.AdcClockSelection = RCC_ADCCLKSOURCE_PLLSAI1;
  PeriphClkInit.UsbClockSelection = RCC_USBCLKSOURCE_HSI48;
  PeriphClkInit.PLLSAI1.PLLSAI1Source = RCC_PLLSOURCE_HSE;
  PeriphClkInit.PLLSAI1.PLLSAI1M = 6;
  PeriphClkInit.PLLSAI1.PLLSAI1N = 20;
  PeriphClkInit.PLLSAI1.PLLSAI1P = RCC_PLLP_DIV2;
  PeriphClkInit.PLLSAI1.PLLSAI1Q = RCC_PLLQ_DIV2;
  PeriphClkInit.PLLSAI1.PLLSAI1R = RCC_PLLR_DIV2;
  PeriphClkInit.PLLSAI1.PLLSAI1ClockOut = RCC_PLLSAI1_ADC1CLK;


推荐阅读