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.
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
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
Ach und außerdem würden sich mit deiner Formel keine negativen Temperaturen darstellen lassen...
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 :-(
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.