Forum: Mikrocontroller und Digitale Elektronik STM32F4 ADC Problem


von David D. (davidd)


Lesenswert?

Guten Morgen,

ich habe ein Problem mit dem ADC meines STM32F4Discovery Boards: Ich 
versuche mithilfe des ADCs die Temperatur über den angeschlossenen 
Temperatursensor auszulesen, allerdings bekomme ich recht komische 
Werte. Hier mein Code:

int main(void)
{
  ADC_InitTypeDef       ADC_InitStructure;
  ADC_CommonInitTypeDef ADC_CommonInitStructure;
  GPIO_InitTypeDef      GPIO_InitStructure;

  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);

  /* Configure ADC Channel 12 pin as analog input */
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_All;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;
  GPIO_Init(GPIOC, &GPIO_InitStructure);

  /* ADC Common Init 
**********************************************************/
  ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent;
  ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div2;
  ADC_CommonInitStructure.ADC_DMAAccessMode = 
ADC_DMAAccessMode_Disabled;
  ADC_CommonInitStructure.ADC_TwoSamplingDelay = 
ADC_TwoSamplingDelay_20Cycles;
  ADC_CommonInit(&ADC_CommonInitStructure);

  /* ADC1 Init 
****************************************************************/
  ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
  ADC_InitStructure.ADC_ScanConvMode = DISABLE;
  ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
  ADC_InitStructure.ADC_ExternalTrigConvEdge = 
ADC_ExternalTrigConvEdge_None;
  ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
  ADC_InitStructure.ADC_NbrOfConversion = 1;
  ADC_Init(ADC1, &ADC_InitStructure);



    /* ADC1 regular channel configuration 
*************************************/
  ADC_RegularChannelConfig(ADC1, ADC_Channel_TempSensor, 1, 
ADC_SampleTime_144Cycles);

  /* Enable ADC1 */
  ADC_Cmd(ADC1, ENABLE);
  /* Enable Temp sensor*/
  ADC_TempSensorVrefintCmd(ENABLE);
  Delay(0xFFFFFF);
  ADC_SoftwareStartConv(ADC1);

  while (1)
  {
    unsigned int temp_reg=ADC_GetConversionValue(ADC1);
    Delay(0xFFFFFF);
  }
}

Der Wert in temp_reg liegt bei 1050(0x41A), bei einer Auflösung von 
12Bit bin ich bei 0.5127 der Referenzspannung, die laut Datenblatt 
(http://www.st.com/internet/com/TECHNICAL_RESOURCES/TECHNICAL_LITERATURE/DATASHEET/DM00037051.pdf 
Seite 129) bei V_REFINT=1.21V liegt. Das Ergebnis meiner ADC Messung ist 
also 1.21V*0.5127=0.62036V. Nun soll laut Datenblatt die eingelesene 
Spannung am Sensor bei einer Temperatur von 25°C V_25=0.76V betragen und 
der Slope bei Avg_Slope=2.5mV/°C=0.0025V/°C liegen. Rechne ich mir damit 
die Temperatur aus, komme ich auf einen Wert von 
25-((0.76V-0.62306V)/0.0025V°C)=-30,856°C. Da meine Wohnung gut beheizt 
ist, ist  dieser Wert falsch.

Die Frage ist nun, wo mein Fehler liegt. Ist der ADC falsch eingestellt? 
Berechne ich die Spannung falsch? Muss ich beim ADC irgendeinen Offset 
dazu rechnen?

In einem weiteren Versuch habe ich anstatt des Temperatur-Sonsors 
versucht direkt die Referenz-Spannung auszulesen (Zeile mit
ADC_RegularChannelConfig(ADC1, ADC_Channel_TempSensor, 1, 
ADC_SampleTime_144Cycles);
auf
ADC_RegularChannelConfig(ADC1, ADC_Channel_Vrefint, 1, 
ADC_SampleTime_144Cycles);
geändert). Ich bin mir aber nicht ganz sicher ob das so überhaupt 
funktioniert. Der dort eingelesene Wert lag bei 1666, er müsste doch 
aber bei 2048 liegen...

Vielen Dank schon einmal für die Antworten.

von abc (Gast)


Lesenswert?

Servus,

mir fällt auf das du deine Strukturen nicht vorinitialisierst. Mit dem 
falschen Compiler(Keil) können da mal schnell Fehler auftreten. Füge vor 
der ADC-Initialisierung noch folgende Zeile ein:

ADC_StructInit(&ADC_InitStructure);

Wenn es die Funktion auch für den Common Init gibt, würde ich die dort 
auch aufrufen. Selbiges gilt auch für die GPIOs.

Wo hast du deine Berechnungsvorschrift her?

Würde einfach Dreisatz nicht ausreichen?

Also T = 0,62306V*25° / 0,76V = 20,49°  ?

Wie warm ist es denn in der Wohnung?

Grüße

von David D. (davidd)


Lesenswert?

abc schrieb:
Hallo und danke für deine Antwort.

> Servus,
>
> mir fällt auf das du deine Strukturen nicht vorinitialisierst. Mit dem
> falschen Compiler(Keil) können da mal schnell Fehler auftreten. Füge vor
> der ADC-Initialisierung noch folgende Zeile ein:
>
> ADC_StructInit(&ADC_InitStructure);
>
> Wenn es die Funktion auch für den Common Init gibt, würde ich die dort
> auch aufrufen. Selbiges gilt auch für die GPIOs.
>
Habe ich gemacht. Keine Veränderung der Werte.

> Wo hast du deine Berechnungsvorschrift her?
>
Die steht im Reference Manual 
(http://www.st.com/internet/com/TECHNICAL_RESOURCES/TECHNICAL_LITERATURE/REFERENCE_MANUAL/DM00031020.pdf) 
auf Seite 230:
Calculate the temperature using the following formula:
Temperature (in °C) = {(VSENSE – V25) / Avg_Slope} + 25
Where:
– V25 = VSENSE value for 25° C
– Avg_Slope = average slope of the temperature vs. VSENSE curve (given 
in mV/°C
or μV/°C)
Refer to the datasheet’s electrical characteristics section for the 
actual values of V25
and Avg_Slope.
> Würde einfach Dreisatz nicht ausreichen?
>
> Also T = 0,62306V*25° / 0,76V = 20,49°  ?
>
> Wie warm ist es denn in der Wohnung?
>
Hmm, das ist eine Möglichkeit, aber wozu steht das sonst so im 
Datenblatt. Leider habe ich kein Thermometer hier um die Temperatur zu 
messen, aber der Wert passt ja eigentlich...
> Grüße

von David D. (davidd)


Lesenswert?

Ach und außerdem würden sich mit deiner Formel keine negativen 
Temperaturen darstellen lassen...

von abc (Gast)


Lesenswert?

Also um deinen ADC zu testen, leg einfach mal die Nullspannung an einen 
ADC-Pin...

Im Datenblatt steht auch noch etwas von Timingproblemen bezüglich der 
Temperatursensoren...

Meine Berechnung stimmt natürlich nicht, hab nur das Datenblatt nicht 
gehabt.

Versuch doch mal eine kontinuierliche (über deine While-Schleife) 
Wandlung, musst aber noch eine Abfrage bezüglich der End of Conversion 
Flag einfügen.

Wenn alles nichts hilft, hilft nur noch sukzessive durch den Code gehen 
:-(

von JJ (Gast)


Lesenswert?

Es könnte sein, dass die Sample-Zeit zu gering eingestellt ist. Laut 
Datenblatt sollten es mindestens 10µs sein!

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.