PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : ATmega 168 AD-Wandler geht nicht



drew
22.05.2008, 18:58
Hallo,
ich will gerade meinen ADC von meinem ATmega 168 in Betrieb nehmen.
Mein Programm sieht so aus:

void AdcInit(void)
{
ADMUX=0;
ADMUX|=0x00; // VREF=AREF Pin
ADMUX|=0x01; // Kanal AIN1
ADCSRA=0;
ADCSRA|=0x04; // Prescaler clk/16REFS 6 92
ADCSRB=0;
ADCSRA|=0x80; // Enable
}

void AdcStart(void)
{
ADCSRA|=0x40; // Start
}

u8 AdcReady(void)
{
if( (ADCSRA&0x40)==0x40 )
{ return(1); }
else
{ return(0); }
}

s16 main(void)
{

AdcInit();

while( 1 )
{
AdcStart();
while( AdcReady()==0 )
{ ; }
}
}


Das Ergebnis werte ich mit meinem Emulator aus. Darum fehlt das Auslesen des ADC-Data-Registers.
Bei der Hardware habe ich einfach GND(8 ) mit AGND(22) und VCC(7) mit AVCC(20) und AREF(21) verbunden.
Ich hab jetzt mal AIN1(13) auf GND gelegt und erwartet, dass der ADC 0 liefert. Ich bekomme aber immer 0x01D2 (+-2).
Hab ich was übersehen?

Drew

PS: ich hab auch schon mal DIDR0 alle auf 1 gelegt. Das hat aber auch nicht viel gebracht...

Herkulase
22.05.2008, 20:16
Du setzt doch im ADCSRA einmal Bit 2, und bit 6, und zuletzt bit 7. Im Register steht dann der Wert 0xC4, und in deiner ADCReady() fragst du nach dem Wert 0x40. Die liefert also immer 0 zurück, also bleibst Du am Ende im while hängen.

Ich seh eh grad:

>> (ADCSRA&0x40)==0x40 ) << Hier fragst Du ja nur das Bit6 ab, und das kann ja nie den wert 0x40 haben...

Es hat schon seinen Grund, dass man bits mit 1<<BIT-NAME setzt, denn dann verliert man den Überblick nicht so schnell...

Gruß

Gerald

drew
22.05.2008, 20:44
Hallo Herkulase,
danke für Deine Antwort.
Ups, Du hast Recht, ich muss auf 1 abfragen. Ich habs jetzt mal umgeschrieben. Es ist bestimmt besser durchschaubar, wenn man die Bit-Namen verwendet.

void AdcInit(void)
{
ADMUX=0;
ADMUX|=0x00; // VREF=AREF Pin
ADMUX|=0x01; // Kanal AIN1
ADCSRA=0;
ADCSRA|=(1<<ADPS2); // Prescaler clk/16REFS 6 92
ADCSRB=0;
ADCSRA|=(1<<ADEN); // Enable
}

void AdcStart(void)
{
ADCSRA|=(1<<ADSC); // Start
}

u8 AdcReady(void)
{
if( (ADCSRA&(1<<ADSC))==(1<<ADSC) )
{ return(1); }
else
{ return(0); }
}

s16 main(void)
{

AdcInit();

while( 1 )
{
AdcStart();
while( AdcReady()==1 )
{ ; }
}
}
Leider ändert das nichts am Ergebnis. Ich bekomme immer noch 0x01D2. Da ich's im Emulator laufen habe sehe ich , das die Wandlung ausgeführt wurde ADIF ist gesetzt und der ADC-Wert ändert sich.
Kann es sein, dass mit meinem Hardware-Aufbau was nicht stimmt? Oder ist am Ende mien Controller defekt?

Drew

drew
22.05.2008, 20:52
Hallo noch mal,
ich hab's gerade noch mal mit einem anderen Controller ATMega 168 getestet: Das gleiche Ergebnis...
Das war es also schon mal nicht. :-k

linux_80
22.05.2008, 20:55
Hallo,

AIN1 hat nix mit dem ADC zu tun, Du musst schon einen ADC-Eingang verkabeln, beginnen mit ADC ;-)

AIN1 ist für den Komperator.

drew
22.05.2008, 21:00
:oops: Danke Linux_80, jetzt gehts. :oops: