Conversión de ADM STM32 usando HAL

8

Estoy tratando de aprender a usar la "nueva" biblioteca HAL de stm32.
Cuando intento hacer una conversión simple de ADC, funciona solo una vez, pero luego deja de convertir. Supongo que el indicador de fin de conversión no se establece. Estoy utilizando la placa de descubrimiento STM32f429I, que tiene STM32f429ZI a bordo.
Tenga en cuenta que sé que Sprintf es una mala práctica y que hacer adc con interrupción es mejor, sé que, por favor, no lo señale, esto no es relevante para la pregunta, solo estoy probando HAL aquí.
Entonces, la pregunta es ¿por qué el indicador EOC no está establecido o qué podría hacer para que funcione? Google no está ayudando mucho, ya que hay muy pocos buenos materiales sobre HAL.

Aquí está el código:

__IO uint16_t ADCValue=0;
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc);

int main(void)
{
  char str[15];

  /* Various initializations */

  HAL_ADC_Start(&hadc1);
  while (1)
  {

        if (HAL_ADC_PollForConversion(&hadc1, 1000000) == HAL_OK)
        {
            ADCValue = HAL_ADC_GetValue(&hadc1);
            sprintf(str, "%d", ADCValue);
            BSP_LCD_DisplayStringAt(130,30, (uint8_t*)str, LEFT_MODE);
        }

  }

void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{
    ADCValue = HAL_ADC_GetValue(&hadc1);
}

También creé el proyecto con CubeMX, la configuración de adc es la siguiente:

EDIT 1
Traté de depurar todo y parece que el programa se atasca en la comprobación del indicador de EOC: ve que no se muestra y, por lo tanto, emite un temporizador que espera a que aparezca EOC (pero nunca se configura) Aquí está el código donde se atasca en el depurador:

/* Check End of conversion flag */
  while(!(__HAL_ADC_GET_FLAG(hadc, ADC_FLAG_EOC)))
  {
    /* Check for the Timeout */
    if(Timeout != HAL_MAX_DELAY)
    {
      if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))
      {
        hadc->State= HAL_ADC_STATE_TIMEOUT;
        /* Process unlocked */
        __HAL_UNLOCK(hadc);
        return HAL_TIMEOUT;
      }
    }
    
pregunta ScienceSamovar

3 respuestas

5

En su código original, configure la Selección de fin de conversión como deshabilitada.

 hadc1.Init.EOCSelection = DISABLE;

Resultó que el valor de #define ADC_EOC_SEQ_CONV ((uint32_t)0x00000000) es igual a DISABLE . Entonces, en realidad, la EOCSelection debe configurarse como:
parapodersondearelADCvariasveces.

LuegopuedeleerelADCcontinuamentesindetenereiniciarelADC:

intmain(void){HAL_Init();SystemClock_Config();ConfigureADC();HAL_ADC_Start(&hadc1);while(1){if(HAL_ADC_PollForConversion(&hadc1,1000000)==HAL_OK){ADCValue=HAL_ADC_GetValue(&hadc1);}}}

Deestamanerafuncionóbienparamí.

DadoqueHALesunabibliotecabastantenueva,nohaymuchosrecursosparaencontrarperonoesimposible.Aprendímuchodeeste tutorial , demuestra todo el uso posible de ADC paso a paso; desde el simple sondeo hasta el uso de interrupciones y DMA.

    
respondido por el Bence Kaulics
2

Hm ... Encontré un par de tutoriales que usaron HAL_ADC_Stop (& hadc1) para finalizar la conversión ... Estuve viendo estos tutoriales antes y pensé que esta es una manera bastante bárbara, parece que desactiva el ADC completamente, así que Yo pensé que debería haber un método diferente. Pero parece que esto realmente funciona bien.
Sea bienvenido a publicar la respuesta si hay una forma más elegante de hacerlo, ya que creo que usar HAL_ADC_Stop () es bastante horrible, pero se puede usar para fines de aprendizaje.

while (1)
  {
        HAL_ADC_Start(&hadc1);
        if (HAL_ADC_PollForConversion(&hadc1, 1000000) == HAL_OK)
        {
            ADCValue = HAL_ADC_GetValue(&hadc1);
                        sprintf(str, "%d", ADCValue);
                        BSP_LCD_DisplayStringAt(130,30, (uint8_t*)str, LEFT_MODE);
        }
        HAL_ADC_Stop(&hadc1);

  }
    
respondido por el ScienceSamovar
0

Esto me funciona, espero que ayude:

if (HAL_ADC_Start(&hadc) != HAL_OK)
{
    /* Start Conversation Error */
    // Error_Handler();
}
if (HAL_ADC_PollForConversion(&hadc, 500) != HAL_OK)
{
    /* End Of Conversion flag not set on time */
    // Error_Handler();
    ADCValue=-1;
}
else
{
    /* ADC conversion completed */
    /*##-5- Get the converted value of regular channel ########################*/
    ADCValue = HAL_ADC_GetValue(&hadc);
}
HAL_ADC_Stop(&hadc);
    
respondido por el yaniv maor

Lea otras preguntas en las etiquetas