Also ich hab den AtMega8-16PU. Ich bin der Meinung dass im Datenblatt schon 2,56V Uref steht. Finde das schon komisch.
An der Umwandlung in signed long bin ich dran. Hab das jetzt mal soweit gemacht:
Code:
#include <avr/io.h>
#include <inttypes.h>
#include <stdlib.h>
#include <lcd.h>
#define F_CPU = 4000000UL
#define ad_nullwert 311
#define si_multiplyer 60
#define si_const 12
uint16_t readADC(uint8_t); //Prototyp von readADC
void display_temp(uint16_t result); //Prototyp von display
char buffer[8]; //Array für itoa anlegen
signed long int si_temp1; //Hilfvariable für Temperaturberechnung anlegen
signed long int si_temp2;
signed long int si_temp3;
signed long int si_ones;
signed long int si_komma;
int main(void)
{
DDRB = 0xff; //PORT B als Ausgang
//Auslesen der analogen Spannungen an Pin 0, also ADC0. In result steht das Ergebnis.
uint16_t result = readADC(0);
display_temp(result); //Umrechnung und Ausgabe der Temperatur auf Display und LED`s
return 0;
}
void display_temp(uint16_t result)
{
lcd_init(LCD_DISP_ON); //LCD initialisieren
lcd_gotoxy(0,0); //Cursor an erste Stelle setzen
lcd_puts("Temp.:"); //"Temperatur" ausgeben
lcd_gotoxy(0,1); // Cursor in die zweite Zeile setzen
itoa(result,buffer,10); //AD-Wert umrechnen
lcd_puts(buffer); //AD-Wert in der zweiten Zeile ausgeben
lcd_gotoxy(9,0); // Cursor hinter "Temperatur:" setzen
//Berechnung der Temperatur
si_temp1= (result-ad_nullwert);
si_temp2= (si_temp1*si_multiplyer);
si_temp3= (si_temp2/si_const);
// Die Ganzen Grade Berechnen
si_ones=si_temp3/10;
//Die eine Nachkommastelle Berechnen
si_komma=si_temp3%10;
// Die Zehnerstellen ans Display ausgeben
itoa(si_ones,buffer,10);
lcd_puts(buffer);
lcd_putc(',');
itoa(si_komma,buffer,10);
lcd_puts(buffer);
lcd_putc('C');
return;
}
uint16_t readADC(uint8_t channel)
{
uint8_t i;
uint16_t result = 0;
//Den ADC aktivieren und Teilungsfaktor auf 32 stellen
ADCSRA = (1<<ADEN) | (1<<ADPS0) | (1<<ADPS2);
//Kanal des Multiplexers waehlen (ADC 0)
ADMUX = (!(1<<MUX0)) | (!(1<<MUX1)) | (!(1<<MUX2));
//interne Referenzspannung verwenden (also 2,56 V)
ADMUX |= (1<<REFS1) | (1<<REFS0);
//Den ADC initialisieren und einen sog. Dummyreadout machen
ADCSRA |= (1<<ADSC);
while(ADCSRA & (1<<ADSC));
//Jetzt 3x die analoge Spannung and Kanal channel auslesen
//und dann Durchschnittswert ausrechnen.
for(i=0; i<3; i++)
{
// Eine Wandlung
ADCSRA |= (1<<ADSC);
// Auf Ergebnis warten...
while(ADCSRA & (1<<ADSC));
result += ADC;
}
//ADC wieder deaktivieren
ADCSRA &= ~(1<<ADEN);
result /= 3;
return result;
}
Wie habt ihr denn euren AD-Wandler beschaltet? So viel kann man da ja eigentlich nicht falsch machen....
Grüße!!
Bean
Lesezeichen