Eu tenho um ADC com dois canais em um Nucleo F401RE: um que lê valores de um termistor (canal 8, classificação 1) e outro que lê valores de um potenciômetro (canal 1, classificação 2). Pressionar o botão no microcontrolador deve alternar entre os canais, mas eu só consigo alternar do canal 8 para o canal 1
Tentei trocar as classificações ou dar a elas a mesma classificação, mas não funcionou.
void change_channel(uint32_t channel, uint32_t rank)
{ ADC_ChannelConfTypeDef sConfig = {0};
sConfig.Channel = channel;
sConfig.Rank = rank;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{
Error_Handler();
}
global_channel=sConfig.Channel;
global_rank= sConfig.Rank;
}
Também tentei desabilitar o outro canal, mas ainda não funciona (ele lê valores apenas do potenciômetro). Quando tento dar sConfig.Rank = 2 ao desabilitar os canais, leio um valor em torno de 1310 para o termistor e não sei de onde ele vem.
void change_channel(uint32_t channel, uint32_t rank)
{
ADC_ChannelConfTypeDef sConfig = {0};
// Disable all channels
for (uint32_t ch = ADC_CHANNEL_0; ch <= ADC_CHANNEL_10; ch++) // Adjust range based on your MCU's ADC channels
{
sConfig.Channel = ch;
sConfig.Rank = 0; // Set rank to 0 to disable the channel (no valid rank)
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{
Error_Handler();
}
}
// Enable the desired channel
sConfig.Channel = channel;
sConfig.Rank = rank; // Explicitly set the desired rank
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{
Error_Handler();
}
// Store the global variables for tracking
global_channel = sConfig.Channel;
global_rank = sConfig.Rank;
}
Eu li os valores na segunda tarefa (mod é uma variável que muda entre 0 e 1 quando pressiono o botão para me ajudar a selecionar o canal, 0 significa modo automático e 1 significa modo manual)texto
void StartTask02(void *argument)
{
/* USER CODE BEGIN StartTask02 */
float readValue;
float voltage;
float d=3.3;
int mod1;
/* Infinite loop */
for(;;)
{osMessageQueueGet (mod_for_ADCHandle, &mod1, 0, 0);
if(mod1==0)//
{
change_channel(8,1);
HAL_ADC_Start(&hadc1);
if(HAL_ADC_PollForConversion(&hadc1,1000)==HAL_OK){
readValue=HAL_ADC_GetValue(&hadc1);
voltage=(float)readValue/(float)4095*d;
globalvoltage= voltage;
globalreadValue=readValue;
}
HAL_ADC_Stop(&hadc1);
osMessageQueuePut (queque_voltageHandle, &voltage, 0, 0);
osDelay(100);
}
if(mod1==1)//
{
change_channel(1,2);
HAL_ADC_Start(&hadc1);
if(HAL_ADC_PollForConversion(&hadc1,1000)==HAL_OK){
readValue=HAL_ADC_GetValue(&hadc1);
voltage=(float)readValue/(float)4095*d;
globalvoltage= voltage;
globalreadValue=readValue;
}
HAL_ADC_Stop(&hadc1);
osMessageQueuePut (queque_voltageHandle, &voltage, 0, 0);
osDelay(100);
}
}
/* USER CODE END StartTask02 */
}
Configuração ADC
/** Configure the global features of the ADC (Clock, Resolution, Data Alignment and number of conversion)
*/
hadc1.Instance = ADC1;
hadc1.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV4;
hadc1.Init.Resolution = ADC_RESOLUTION_12B;
hadc1.Init.ScanConvMode = ENABLE;
hadc1.Init.ContinuousConvMode = DISABLE;
hadc1.Init.DiscontinuousConvMode = DISABLE;
hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;
hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
hadc1.Init.NbrOfConversion = 2;
hadc1.Init.DMAContinuousRequests = DISABLE;
hadc1.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
if (HAL_ADC_Init(&hadc1) != HAL_OK)
{
Error_Handler();
}
/** Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time.
*/
sConfig.Channel = ADC_CHANNEL_8;
sConfig.Rank = 1;
sConfig.SamplingTime = ADC_SAMPLETIME_480CYCLES;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{
Error_Handler();
}
/** Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time.
*/
sConfig.Rank = 2;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{
Error_Handler();
}