valores funky fuera de ADC en STM32

2

Tengo un STM32 con un divisor de voltaje sencillo que lleva una línea de nivel de batería a un ADC. El problema es que estoy obteniendo un valor que no tiene mucho sentido para mí. De acuerdo con mi alcance, B_LEV (que es la línea dividida, yendo al pin 1 / ADC1 de GPIOC) es 2.49V, con un VREF de 3.3V. El valor que estoy obteniendo es 2148 (12bit adc), que debería traducirse a 2148/4096 * 3.3 = 1.78V, lo que obviamente no es cierto.

¿Estoy arruinando la matemática o mi configuración de ADC?

Aquí está el código de inicialización y lectura:

void InitADC() {
  ADC_InitTypeDef ADC_InitStructure;

  RCC_ADCCLKConfig(RCC_PCLK2_Div4);
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);

  GPIO_InitTypeDef GPIO_InitStructure;
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
  GPIO_Init(GPIOC, &GPIO_InitStructure);

  ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
  ADC_InitStructure.ADC_ScanConvMode = DISABLE;
  ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
  ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
  ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
  ADC_InitStructure.ADC_NbrOfChannel = 1;
  ADC_Init(ADC1, &ADC_InitStructure);

  ADC_RegularChannelConfig(ADC1, ADC_Channel_11, 1, ADC_SampleTime_239Cycles5);    
  ADC_Cmd(ADC1, ENABLE);
  ADC_ResetCalibration(ADC1);

  while(ADC_GetResetCalibrationStatus(ADC1));
  ADC_StartCalibration(ADC1);

  while(ADC_GetCalibrationStatus(ADC1));
  ADC_SoftwareStartConvCmd(ADC1, ENABLE);  
}

int ReadBatteryValue() {
  // Make sure we have conversion completion
  if(ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) == RESET)
    return 500;
  // Reset the flag
  ADC_ClearFlag(ADC1, ADC_FLAG_EOC);
  // Get the conversion value
  return ADC_GetConversionValue(ADC1);
}
    
pregunta kolosy

2 respuestas

2

Así que, después de investigar un poco más, me di cuenta de que el problema es mucho más simple: estoy escribiendo código para un módulo de terceros que se basa en un chip STM32, y se les volvió a asignar sus GPIO. Estaba mirando el canal ADC incorrecto ( suspiro ).

    
respondido por el kolosy
10

Eche un vistazo a la impedancia de entrada del dispositivo frente a los valores de las resistencias en su divisor. Podrías estar bajando tu entrada.

Usted dice que tiene un "divisor de voltaje directo" en su ADC. Estoy sugiriendo que podría ser un poco menos sencillo de lo que crees.

En un mundo ideal, asumes que la resistencia de una entrada analógica (o cualquier amplificador) es infinita. De hecho, la entrada debe considerarse como una resistencia finita. En un ADC muy bueno, como el tipo que esperaría ver en una tarjeta de National Instruments, la impedancia de entrada está en el rango de MegaOhm. Sin embargo, en los microcontroladores típicos, es mucho más bajo, por lo general alrededor de 10 kiloohms.

Supongamos que su divisor de voltaje directo es de 5v pasando por una resistencia de 10K en serie con un resistor de 20K, y su voltaje en el ADC sería de 5V * 20Kohms / 30Kohms, o 5V * 0.66 = 3.35V. En realidad, debido a que la impedancia de entrada de su dispositivo es 10K, esa resistencia de 20K es realmente 20K en paralelo con los 10K del dispositivo, o 6.7K !!! Ahora lo que el ADC realmente ve es 5V * (6.7k / 16.7K), o 5V * 0.40, o 2V.

La forma más fácil de saber qué está pasando: con el circuito encendido, use un multímetro para medir el voltaje en el ADC, en lugar de suponer que el divisor de voltaje simple está actuando como usted cree.

De hecho, un hoja de datos de STM32 en la página 124 dice la impedancia de entrada el ADC es de 50 K, lo que sugiere que su divisor de voltaje está cerca de un 50 K en serie con 100 K de los números que ha dado, si este es el problema.

Intente mantener sus resistencias divisoras de voltaje en el orden de 1k a 2k para evitar este problema, o búfere su entrada analógica con un amplificador operacional configurado como seguidor de voltaje.

Corrección: parece que la impedancia de entrada real, al menos del dispositivo en la hoja de datos que elegí al azar, es 6K, o tal vez incluso una función funky de frecuencia de muestreo (como una función de tapa conmutada) - use los números en su riesgo propio, pero creo que tiene un problema de baja impedancia de entrada.

    
respondido por el Scott Seidman

Lea otras preguntas en las etiquetas