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);
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();
}
}
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?
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.