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.
Gast
#2847159
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...
Gast
#2847356
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 :-(
Gast
#3569145
Es könnte sein, dass die Sample-Zeit zu gering eingestellt ist. Laut Datenblatt sollten es mindestens 10µs sein!
Antwort schreiben
Bitte melde dich an, um einen Beitrag zu schreiben.