STM32L073RZ ADC通道切换不起作用?

huangapple go评论135阅读模式
英文:

STM32L073RZ ADC Channel switching not working?

问题

在使用三个通道6、7和8读取每个通道100个样本的数据后,无法使用连续模式来读取数据。必须在读取一个通道的100个样本后切换通道。为简单起见,将样本减少为1,并编写了以下代码。

MX_ADC_Init();
MX_TIM2_Init();
/* USER CODE BEGIN 2 */

HAL_TIM_Base_Start(&htim2);

select_adc_channel(6);
HAL_ADC_Start_IT(&hadc);
HAL_Delay(250);
uint8_t adc = HAL_ADC_GetValue(&hadc);
HAL_ADC_Stop_IT(&hadc);

select_adc_channel(7);
HAL_ADC_Start_IT(&hadc);
HAL_Delay(250);
adc = HAL_ADC_GetValue(&hadc);
HAL_ADC_Stop_IT(&hadc);

select_adc_channel(8);
HAL_ADC_Start_IT(&hadc);
HAL_Delay(250);
adc = HAL_ADC_GetValue(&hadc);
HAL_ADC_Stop_IT(&hadc);

MX_ADC_Init() 代码如下:

static void MX_ADC_Init(void)
{

  /* USER CODE BEGIN ADC_Init 0 */

  /* USER CODE END ADC_Init 0 */

  ADC_ChannelConfTypeDef sConfig = {0};

  /* USER CODE BEGIN ADC_Init 1 */

  /* USER CODE END ADC_Init 1 */

  /** Configure the global features of the ADC (Clock, Resolution, Data Alignment and number of conversion)
  */
  hadc.Instance = ADC1;
  hadc.Init.OversamplingMode = DISABLE;
  hadc.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV1;
  hadc.Init.Resolution = ADC_RESOLUTION_8B;
  hadc.Init.SamplingTime = ADC_SAMPLETIME_1CYCLE_5;
  hadc.Init.ScanConvMode = ADC_SCAN_DIRECTION_FORWARD;
  hadc.Init.DataAlign = ADC_DATAALIGN_RIGHT;
  hadc.Init.ContinuousConvMode = DISABLE;
  hadc.Init.DiscontinuousConvMode = DISABLE;
  hadc.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_RISING;
  hadc.Init.ExternalTrigConv = ADC_EXTERNALTRIGCONV_T2_TRGO;
  hadc.Init.DMAContinuousRequests = DISABLE;
  hadc.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
  hadc.Init.Overrun = ADC_OVR_DATA_PRESERVED;
  hadc.Init.LowPowerAutoWait = DISABLE;
  hadc.Init.LowPowerFrequencyMode = DISABLE;
  hadc.Init.LowPowerAutoPowerOff = DISABLE;
  if (HAL_ADC_Init(&hadc) != HAL_OK)
  {
    Error_Handler();
  }
}

select_adc_channel() 代码如下:

void select_adc_channel(uint8_t channel)
{
    ADC_ChannelConfTypeDef sConfig = {0};

    switch(channel)
    {
        case 0: sConfig.Channel = ADC_CHANNEL_0;
                sConfig.Rank = 1;
                if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK)
                {
                   Error_Handler();
                }
                break;
        case 6: sConfig.Channel = ADC_CHANNEL_6;
                sConfig.Rank = 1;
                if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK)
                {
                   Error_Handler();
                }
                break;
        case 7: sConfig.Channel = ADC_CHANNEL_7;
                sConfig.Rank = 1;
                if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK)
                {
                   Error_Handler();
                }
                break;
        case 8: sConfig.Channel = ADC_CHANNEL_8;
                sConfig.Rank = 1;
                if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK)
                {
                   Error_Handler();
                }
                break;
        case 9: sConfig.Channel = ADC_CHANNEL_9;
                sConfig.Rank = 1;
                if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK)
                {
                   Error_Handler();
                }
                break;

    }
}

根据电路设计,6、7和8通道应分别读取78、130和190的ADC值。但是上面的代码只给出了所有3个通道的值为78。

然后将读取顺序更改为7、6和8,因此读取变为130、78和78。

在选择通道6之后发生了什么?

英文:

I have used three channels 6,7,8 to read data of 100 samples each. Hence I cannot use sequence continuous mode to read data. I have to switch the channel after reading 100 samples of one channel. For simplicity, I just reduced the sample to 1 and written the following code.

  MX_ADC_Init();
  MX_TIM2_Init();
  /* USER CODE BEGIN 2 */

  HAL_TIM_Base_Start(&htim2);

  select_adc_channel(6);
  HAL_ADC_Start_IT(&hadc);
  HAL_Delay(250);
  uint8_t adc=HAL_ADC_GetValue(&hadc);
  HAL_ADC_Stop_IT(&hadc);

  select_adc_channel(7);
  HAL_ADC_Start_IT(&hadc);
  HAL_Delay(250);
  adc=HAL_ADC_GetValue(&hadc);
  HAL_ADC_Stop_IT(&hadc);

  select_adc_channel(8);
  HAL_ADC_Start_IT(&hadc);
  HAL_Delay(250);
  adc=HAL_ADC_GetValue(&hadc);
  HAL_ADC_Stop_IT(&hadc);

MX_ADC_Init() code

static void MX_ADC_Init(void)
{

  /* USER CODE BEGIN ADC_Init 0 */

  /* USER CODE END ADC_Init 0 */

  ADC_ChannelConfTypeDef sConfig = {0};

  /* USER CODE BEGIN ADC_Init 1 */

  /* USER CODE END ADC_Init 1 */

  /** Configure the global features of the ADC (Clock, Resolution, Data Alignment and number of conversion)
  */
  hadc.Instance = ADC1;
  hadc.Init.OversamplingMode = DISABLE;
  hadc.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV1;
  hadc.Init.Resolution = ADC_RESOLUTION_8B;
  hadc.Init.SamplingTime = ADC_SAMPLETIME_1CYCLE_5;
  hadc.Init.ScanConvMode = ADC_SCAN_DIRECTION_FORWARD;
  hadc.Init.DataAlign = ADC_DATAALIGN_RIGHT;
  hadc.Init.ContinuousConvMode = DISABLE;
  hadc.Init.DiscontinuousConvMode = DISABLE;
  hadc.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_RISING;
  hadc.Init.ExternalTrigConv = ADC_EXTERNALTRIGCONV_T2_TRGO;
  hadc.Init.DMAContinuousRequests = DISABLE;
  hadc.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
  hadc.Init.Overrun = ADC_OVR_DATA_PRESERVED;
  hadc.Init.LowPowerAutoWait = DISABLE;
  hadc.Init.LowPowerFrequencyMode = DISABLE;
  hadc.Init.LowPowerAutoPowerOff = DISABLE;
  if (HAL_ADC_Init(&hadc) != HAL_OK)
  {
    Error_Handler();
  }
}

select_adc_channel() code

void select_adc_channel(uint8_t channel)
{
	ADC_ChannelConfTypeDef sConfig = {0};

	switch(channel)
	{
		case 0: sConfig.Channel = ADC_CHANNEL_0;
	            sConfig.Rank = 1;
	            if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK)
	            {
	               Error_Handler();
	            }
	            break;
		case 6: sConfig.Channel = ADC_CHANNEL_6;
				sConfig.Rank = 1;
				if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK)
				{
				   Error_Handler();
				}
				break;
		case 7: sConfig.Channel = ADC_CHANNEL_7;
				sConfig.Rank = 1;
				if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK)
				{
				   Error_Handler();
				}
				break;
		case 8: sConfig.Channel = ADC_CHANNEL_8;
				sConfig.Rank = 1;
				if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK)
				{
				   Error_Handler();
				}
				break;
		case 9: sConfig.Channel = ADC_CHANNEL_9;
				sConfig.Rank = 1;
				if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK)
				{
				   Error_Handler();
				}
				break;

	}
}

As per the circuit, 6, 7, and 8th channels should read 78, 130, 190 adc values.But the above code, only gives 78 value for all 3 channels.

Then changed the reading order to 7, 6, and 8. so the reading become 130, 78, and 78.

what is happening after channel 6 is selected?

答案1

得分: 0

每当你切换ADC通道时,你需要配置'旧'通道为ADC_RANK_NONE,否则它仍然会被视为有效的启用通道。

以下是我曾经完成的一个项目中的一些代码,用于在两个通道之间切换ADC:

static void configure_channel_as(uint32_t channel, uint32_t rank)
{
    ADC_ChannelConfTypeDef sConfig = {0};

    sConfig.Channel = channel;
    sConfig.Rank = rank;
    sConfig.SamplingTime = ADC_SAMPLETIME_1CYCLE_5;
    if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK)
    {
        dprintf("配置通道6失败\r\n");
    }
}

void adc_configure_for_head(void)
{
    configure_channel_as(ADC_CHANNEL_0, ADC_RANK_CHANNEL_NUMBER);
    configure_channel_as(ADC_CHANNEL_6, ADC_RANK_NONE);
}

void adc_configure_for_voltage(void)
{
    configure_channel_as(ADC_CHANNEL_6, ADC_RANK_CHANNEL_NUMBER);
    configure_channel_as(ADC_CHANNEL_0, ADC_RANK_NONE);
}

每当你切换时,你需要对'旧'通道执行类似的操作。

英文:

Whenever you switch ADC channels, you'll need to configure the 'old' channel to have ADC_RANK_NONE, otherwise it will still be considered a valid, enabled channel.

Here's some code from a project I did which switched the ADC between two channels:

static void configure_channel_as( uint32_t channel, uint32_t rank )
{
    ADC_ChannelConfTypeDef sConfig = { 0 };

    sConfig.Channel      = channel;
    sConfig.Rank         = rank;
    sConfig.SamplingTime = ADC_SAMPLETIME_1CYCLE_5;
    if ( HAL_ADC_ConfigChannel ( &hadc, &sConfig ) != HAL_OK )
    {
        dprintf ( "Failed to configure channel 6\r\n" );
    }
}

void adc_configure_for_head( void )
{
    configure_channel_as ( ADC_CHANNEL_0, ADC_RANK_CHANNEL_NUMBER );
    configure_channel_as ( ADC_CHANNEL_6, ADC_RANK_NONE );
}

void adc_configure_for_voltage( void )
{
    configure_channel_as ( ADC_CHANNEL_6, ADC_RANK_CHANNEL_NUMBER );
    configure_channel_as ( ADC_CHANNEL_0, ADC_RANK_NONE );
}

You'll need to do something similar for the 'old' channel whenever you switch.

huangapple
  • 本文由 发表于 2023年5月29日 18:35:25
  • 转载请务必保留本文链接:https://go.coder-hub.com/76356602.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定