Forum: Mikrocontroller und Digitale Elektronik Problem mit AD Wandlung ATMega16


von Stefan V. (funny)


Lesenswert?

Hallo
Ich habe ein kleines Problem mit der Programmierung des ATMega16.
Ich benutze den internen 10bit AD-Wandler.
Ich habe an PinO PortA ein Poti welches von 0-5V regelt.
Am Ausgang von PortB sollen ab einer bestimmten Spannung jeweils eine
Lampe angehen bzw. ausgehen.
Das Programm dazu läuft leider nicht wie es soll. Vielleicht kann mir da
einer helfen.


#define     F_CPU 8000000   // Taktfrequenz des myAVR-Boards
#include    <avr\io.h>      // AVR Register und Konstantendefinitionen
#include    <avr\delay.h>   // AVR Zeitverzögerung in ms
#include    <avr\interrupt.h>   //Interrup-Header

int x;  // Merker für ADC

int main ()
{

    MCUCSR = (1<<JTD);      //JTAG disabel
    ADCSRA = (1<<ADEN);     //ADC aktivieren
    ADCSRA = ((1<<ADSC)&(1<<ADATE)); //ADC freilaufend
    ADCSRA = ((0<<ADPS0)&(1<<ADPS1)&(1<<ADPS2)); //Teilfaktor auf 64
    ADMUX =  ((0<<MUX0)&(0<<MUX1)&(0<<MUX2)&(0<<MUX3)&(0<<MUX4));
//PORTA PIN0 als AD Eingang


    //Ausgänge
    DDRB = 0x00;            //PortB Ausgang
    do
    {

        x=ADC;

        if((x<=2)&(x>=0))
        {
            PORTB=(1<<PB0); //Heizung Lampe an
        }
    else if((x>=5)&(x<=10))
        {
            PORTB=(1<<PB1); //Lüfter Lampe an
        }
    else
        {
            PORTB=(0<<PB0); //Heizung Lampe aus
            PORTB=(0<<PB1); //Lüfter Lampe aus
        }

    }
    while (1);
    return(0);

}

von spess53 (Gast)


Lesenswert?

Hi

DDRB = 0x00 heisst : alles Eingänge.

Richtig: DDRB = 0xFF ->alle Pins Ausgänge.

MfG Spess

von Kai (Gast)


Lesenswert?

Hallo,
ich programmiere auch den Mega16, benutze zwar den CodevisionAVR, weil 
es damit viel einfacher und schneller geht, aber ich glaube du hast 
unter anderem folgenden Fehler:

DDRB = 0x00;            //PortB Ausgang

definiert dir den PortB nicht als Ausgang, sondern als Eingang, versuchs 
doch mal mit

DDRB = 0xFF;            //PortB jetzt wirklich Ausgang und nicht nur im 
Kommentar :P


außerdem gibt dir eine ADC10 einen Wert zwischen 0 und 1024 zurück und 
nicht zwischen 0 und 10 :P

kleiner Tip: lad dir doch den CodevisionAVR runter (Freeware) der macht 
alles für dich :)

von crazy horse (Gast)


Lesenswert?

"außerdem gibt dir eine ADC10 einen Wert zwischen 0 und 1024"
meiner nicht.

von Rahul D. (rahul)


Lesenswert?

>"außerdem gibt dir eine ADC10 einen Wert zwischen 0 und 1024"
>meiner nicht.

Meine (ich hab ein paar mehr...) auch nicht.

von Stefan V. (funny)


Lesenswert?

Danke erstmal für die Tips. Den unteren Teil habe ich schon manuell 
getestet. Ich habe x einen Wert zugeordnet und die Lampen gingen an bzw. 
nicht.Also der Teil läuft.
Ist der Teil mit AD aktivierung OK.
Und kann ich die Anweisung x=ADC; so benutzen??
Kann es sein das der Wert der in x gespeichert wird garnicht als ganze 
Zahl vom AD ausgegeben wird sonder als hex-Wert??

von Axel R. (Gast)


Lesenswert?

>    ADCSRA = (1<<ADEN);     //ADC aktivieren
>    ADCSRA = ((1<<ADSC)&(1<<ADATE)); //ADC freilaufend

Erst aktivierst Du den ADC, danach schaltest Du ihn wieder aus.

    ADCSRA = (1<<ADEN);     //ADC aktivieren
    ADCSRA|= ((1<<ADSC)&(1<<ADATE)); //ADC freilaufend

usw.
kann man aber auch in eine Zeile packen.

AxelR.

von Karl H. (kbuchegg)


Lesenswert?

Stefan Van lin wrote:
> Danke erstmal für die Tips. Den unteren Teil habe ich schon manuell
> getestet. Ich habe x einen Wert zugeordnet und die Lampen gingen an bzw.
> nicht.Also der Teil läuft.

Er ist trotzdem falsch.
Du hast den Port mit den Pullup Widerständen des Eingangs
geschaltet.
Ändere es um, dass der Port wirklich auf Ausgang ist.

> Ist der Teil mit AD aktivierung OK.

Nein

> Und kann ich die Anweisung x=ADC; so benutzen??

Im Prinzip schon.
Allerdings solltest du abwarten und den Wert erst holen,
wenn der ADC mit seiner Arbeit fertig ist.

> Kann es sein das der Wert der in x gespeichert wird garnicht als ganze
> Zahl vom AD ausgegeben wird sonder als hex-Wert??

Nein.
Auch eine hex-Zahl ist eine Zahl.
Intern im µC gibt es nur Zahlen. Ob eine Zahl als hex oder als
dezimal ausgegeben wird ist eine reine Frage der Ausgabe und
hat nichts mit der Zahl an sich zu tun. Du verwechselst hier
die Zahl an sich mit der Form in der du dir eine Zahl ausgeben
lassen kannst.


http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#Aktivieren_des_ADC


von Kai (Gast)


Lesenswert?

>>"außerdem gibt dir eine ADC10 einen Wert zwischen 0 und 1024"
>>meiner nicht.

>Meine (ich hab ein paar mehr...) auch nicht.

Was soll ein ADC mit 10 Bit denn sonst ausgeben??
10 Bit = 11111111111 = 1023
bei 0V bekomme ich 0 zurück, bei VRef 1023
ich weiß nicht was ihr wollt, hab schon mehrere Sachen über ADC mit dem 
ATMega16 gemacht und das hat dann auch so funktioniert!

von STK500-Besitzer (Gast)


Lesenswert?

>>>"außerdem gibt dir eine ADC10 einen Wert zwischen 0 und 1024"
>>>meiner nicht.

>>Meine (ich hab ein paar mehr...) auch nicht.

>Was soll ein ADC mit 10 Bit denn sonst ausgeben??
>10 Bit = 11111111111 = 1023
>bei 0V bekomme ich 0 zurück, bei VRef 1023
>ich weiß nicht was ihr wollt, hab schon mehrere Sachen über ADC mit dem
>ATMega16 gemacht und das hat dann auch so funktioniert!

Fällt dir nicht auf, dass du die Lösung schon gebracht hast: 1023 != 
1024.
Ist zwar etwas kleinlich (von uns), aber ein gern gemachter Fehler (von 
anderen).

@Crazy Horse: Ob jetzt wieder die Diskussion wegen der ADC-Normierung 
mit 1024 oder 1023 anfängt?

von STK500-Besitzer (Gast)


Lesenswert?

    ADCSRA|= ((1<<ADSC)&(1<<ADATE)); //ADC freilaufend

Wird nichts, müsste

    ADCSRA|= ((1<<ADSC)|(1<<ADATE)); //ADC freilaufend

heissen...

von Kai (Gast)


Lesenswert?

ich gestehe alles ein^^
mein Fehler, nein ich wollte keine Diskussion anfangen :D

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.