STM32L4 ADC 不工作(多通道无 DMA)

STM32L4 ADC not working (multiple channels no DMA)

我正在尝试 运行 我不久前在这里找到的代码,它允许从几个通道中选择一个 ADC 通道,并在必要时单独读取它。不涉及 DMA。我用的是STM32L4R5。我的想法只是通过打开和关闭状态 LED 来确认正确的 ADC 读数,如果某个级别可用并且到目前为止它根本不工作(状态 LED 始终打开)。 对于输入信号源,我使用一个设置为高电平的 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;
}

有什么我错的想法吗?

谢谢!

我发现了问题。我没有正确设置外围时钟源(最初由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;