Tengo algunos problemas al intentar que el ADC en una PCB personalizada con un STM32F042 funcione. Estoy usando CubeMX para generar todos los controladores / HAL / ... y SW4STM32 para escribir y depurar mi código.
Estoy configurando el ADC de esta manera en CubeMX:
ytieneelsiguientecódigo:
Antesdemain()
:
ADC_ChannelConfTypeDefsConfig;
Enmain()
:
intmain(void){HAL_Init();SystemClock_Config();MX_GPIO_Init();MX_ADC_Init();MX_I2C1_Init();MX_TIM1_Init();MX_TSC_Init();MX_USART1_UART_Init();MX_USART2_UART_Init();MX_USB_PCD_Init();HAL_TIM_PWM_Start(&htim1,TIM_CHANNEL_1);//neededtoswitchonthepositivechannelPWM/high-sidemosfetHAL_TIMEx_PWMN_Start(&htim1,TIM_CHANNEL_1);//neededtoswitchonthenegativechannelPWMn/low-sidemosfetHAL_ADC_Start(&hadc);initialise_monitor_handles();
Yenwhile(1)
:
while(1){uint32_tadcRaw;sConfig.Channel=ADC_CHANNEL_TEMPSENSOR;HAL_ADC_ConfigChannel(&hadc,&sConfig);HAL_ADC_Start(&hadc);HAL_Delay(50);//justasatest,sameresultwith/withoutthisdelayif(HAL_ADC_PollForConversion(&hadc,50)==HAL_OK){adcRaw=HAL_ADC_GetValue(&hadc);}printf("chTemp: %lu %lu \n", adcRaw, sConfig.Channel);
sConfig.Channel = ADC_CHANNEL_8; //read channel x
HAL_ADC_ConfigChannel(&hadc, &sConfig);
HAL_ADC_Start(&hadc);
HAL_Delay(50);
if(HAL_ADC_PollForConversion(&hadc, 50)==HAL_OK)
{
adcRaw = HAL_ADC_GetValue(&hadc);
}
printf("ch8: %lu %lu \n", adcRaw, sConfig.Channel);
}
Estoy obteniendo lo siguiente en el monitor serie, sin importar cómo barrí la tensión de entrada en el canal 8:
chTemp: 462 16
ch8: 485 8
chTemp: 615 16
ch8: 612 8
chTemp: 465 16
ch8: 485 8
chTemp: 1023 16
ch8: 484 8
chTemp: 1023 16
ch8: 465 8
chTemp: 1023 16
ch8: 465 8
chTemp: 614 16
ch8: 464 8
chTemp: 465 16
ch8: 463 8
[...]
Mi configuración de ADC generada automáticamente se ve así:
static void MX_ADC_Init(void)
{
ADC_ChannelConfTypeDef sConfig;
/**Configure the global features of the ADC (Clock, Resolution, Data Alignment and number of conversion)
*/
hadc.Instance = ADC1;
hadc.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV1;
hadc.Init.Resolution = ADC_RESOLUTION_10B;
hadc.Init.DataAlign = ADC_DATAALIGN_RIGHT;
hadc.Init.ScanConvMode = ADC_SCAN_DIRECTION_FORWARD;
hadc.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
hadc.Init.LowPowerAutoWait = DISABLE;
hadc.Init.LowPowerAutoPowerOff = DISABLE;
hadc.Init.ContinuousConvMode = ENABLE;
hadc.Init.DiscontinuousConvMode = DISABLE;
hadc.Init.ExternalTrigConv = ADC_SOFTWARE_START;
hadc.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
hadc.Init.DMAContinuousRequests = DISABLE;
hadc.Init.Overrun = ADC_OVR_DATA_PRESERVED;
if (HAL_ADC_Init(&hadc) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
/**Configure for the selected ADC regular channel to be converted.
*/
sConfig.Channel = ADC_CHANNEL_0;
sConfig.Rank = ADC_RANK_CHANNEL_NUMBER;
sConfig.SamplingTime = ADC_SAMPLETIME_55CYCLES_5;
if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
/**Configure for the selected ADC regular channel to be converted.
*/
sConfig.Channel = ADC_CHANNEL_1;
if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
/**Configure for the selected ADC regular channel to be converted.
*/
sConfig.Channel = ADC_CHANNEL_3;
if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
/**Configure for the selected ADC regular channel to be converted.
*/
sConfig.Channel = ADC_CHANNEL_8;
if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
/**Configure for the selected ADC regular channel to be converted.
*/
sConfig.Channel = ADC_CHANNEL_9;
if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
/**Configure for the selected ADC regular channel to be converted.
*/
sConfig.Channel = ADC_CHANNEL_TEMPSENSOR;
if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
}
¿Alguien tiene una idea sobre cómo usar el ADC correctamente? Intenté un par de tutoriales, pero desafortunadamente no me ayudaron. Soy bastante nuevo en Stm32 y un poco perdido ...
EDITAR: al final, terminé implementando las versiones basadas en DMA, hay varios tutoriales que lo explican muy bien. Sin embargo, nunca supe cuál era mi problema: / ¡Gracias por las sugerencias!