- MultiPlus Wechselrichter Insel und Nulleinspeisung Conrad         
Seite 1 von 2 12 LetzteLetzte
Ergebnis 1 bis 10 von 11

Thema: ADC mit ATMEGA16

  1. #1
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    06.07.2004
    Beiträge
    122

    ADC mit ATMEGA16

    Anzeige

    LiFePo4 Akku selber bauen - Video
    Hallohallo

    Ich habe nun auf den ATMEGA umgestellt. Dort gibt es ja beim ADC ein ADCL und ADCH Register. Wie muss ich die jetzt zusammenknüpfen, dass ich zu meiner 10-bit auflösung komme?

    Ausserdem habe ich schon seit meinen ersten ADC Versuchen das Problem, dass 1. die Messung um 10-100 mV abweicht und 2. Starke Störschwankungen und Spannungssprünge gemessen werden (z.B. im ersten Moment wird 3.3V angezeigt, im nächsten 2.1V ???)...
    Ich habe den höchsten Prescaler gewählt und arbeite mit der Vref=Vcc...

    Ich hoffe ihr könnt mir helfen

  2. #2
    Super-Moderator Robotik Visionär Avatar von PicNick
    Registriert seit
    23.11.2004
    Ort
    Wien
    Beiträge
    6.842
    drei sachen fallen mir zum ADC ein:
    1 du mußt adcl u. adch in der richtigen reihenfolge lesen
    2 das Timing muß stimmen (auf Flag warten)
    3 du braucht einen gewissen mindest-strom zum Messen

    all das is im Datenblatt
    mfg robert
    Wer glaubt zu wissen, muß wissen, er glaubt.

  3. #3
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    06.07.2004
    Beiträge
    122
    Hallo PicNick

    Das mit der Reihenfolge ist klar, nur weiss ich nicht, wie ich die beiden Register zusammen in ein Int oder Float reinstecken kann....???

    Flag muss ich mal anschauen. Mindeststrom sollte ich eigentlich schon haben, da ich das Signal mit einem OP verstärke...

  4. #4
    Super-Moderator Robotik Visionär Avatar von PicNick
    Registriert seit
    23.11.2004
    Ort
    Wien
    Beiträge
    6.842
    Interrrupt oder Flag, daß der ADC fertig ist, weiß ich nicht auswendig.
    Int/float Kommt auf deine Sprache an, und ob du rechts-oder linksbündige werte hast.
    rechtsbündig:
    integer = ADCH * 256 + ADCL
    ODER du tust einfach über die beiden ein 16Bit Integer drüberdefinieren/casten)
    (auch sprachabhängig)
    mfg robert
    Wer glaubt zu wissen, muß wissen, er glaubt.

  5. #5
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    10.08.2004
    Ort
    Großbardorf
    Alter
    37
    Beiträge
    674
    zu der Anordnung der Bits im ADCL/ADCH steht auf jeden Fall was im Datenblatt
    soweit ich mich erinnere, kann man da verschiedene Sachen einstellen(ich glaube, es waren zwei Modi), zB, dass die unteren 8 Bit in ADCL stehen und die zwei anderen in ADCH (oder so ähnlich)

  6. #6
    Super-Moderator Robotik Visionär Avatar von PicNick
    Registriert seit
    23.11.2004
    Ort
    Wien
    Beiträge
    6.842
    Rechtsbündig wäre auch das sinnvollere.

  7. #7
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    06.07.2004
    Beiträge
    122
    Super!! Keine Störungen, relativ genaues Messergebnis---Danke!!!

    Nur noch eine kleine Frage:
    Man muss ja, um die Spannung zu bekommen die Formel Vin=(Vref*ADC)/1024 nehmen. Da könnte ja schon ein Messfehler entstehen, wenn man nicht genau weiss, wie gross Vref ist. Wenn man mal misst und dann den Werte einträgt (z.B. 5.16) stimmt es zwar, aber wenn dann mal etwas mit der Spannungsquelle nicht simmt, und Vref um ein paar mV schwankt, stimmt ja alles nicht mehr....
    Wäre es da besser, die internen 2.56V zu nehmen?

  8. #8
    Super-Moderator Robotik Visionär Avatar von PicNick
    Registriert seit
    23.11.2004
    Ort
    Wien
    Beiträge
    6.842
    Es ist immer schwer zu messen, wenn man nicht sicher ist, wie lang das Lineal gerade ist. Wenn du vorne auch noch einen OP hast, geht das Problem weiter. Dann solltest du vielleicht den OP und die Vref zusammen hochkonstant versorgen.
    Wie auch immer: EIN Bezugspunkt muß genau sein, sonst hast du Kummer
    mfg robert
    Wer glaubt zu wissen, muß wissen, er glaubt.

  9. #9
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    06.07.2004
    Beiträge
    122
    OK... Am besten 7805 als Vref... Merci

  10. #10
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    20.06.2004
    Beiträge
    1.941
    hallo , hier ein beispiel aus dem forum, von mir zusammengewürfelt.

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <avr/io.h>
    #include <stdint.h>
    #include <string.h>
    
    #define ADCchannel_init   DDRA=0x00                 // ADC Port als Eingang deklarieren
    #define ADCinit           ADCSRA|=_BV(ADEN)         // Teilt dem Board mit das der jeweilige Port für ADC verwendet wird
    #define ADCdisable        ADCSRA &=~_BV(ADEN)       // machs das vorherige wieder rückgänig
    #define ADCstart          ADCSRA|=_BV(ADSC)         // startet eine konvertierung auf dem gewünschten Kannal/Pin
    #define ADCfree           ADCSRA|=_BV(ADATE)        // schaltet den freilaufenden Modus ein
    #define ADCvintern        ADMUX|=_BV(REFS0)     // interne Spannungsversorgung
    #define ADCinterrupt_on   ADCSRA|=_BV(ADIE)                // ADC interrupt wird freigeschalten
    #define ADCprescaler_2    ADCSRA |=_BV(ADPS0)              // gewünschter Teilungsfaktor/Prescaler 
    #define ADCprescaler_4    ADCSRA|=_BV(ADPS1)
    #define ADCprescaler_8    ADCSRA=_BV(ADPS1) | _BV(ADPS0)
    #define ADCprescaler_16   ADCSRA|=_BV(ADPS2)
    #define ADCprescaler_32   ADCSRA=_BV(ADPS2) | _BV(ADPS0)
    #define ADCprescaler_64   ADCSRA=_BV(ADPS2) | _BV(ADPS1)
    #define ADCprescaler_128  ADCSRA=_BV(ADPS2) | _BV(ADPS1) | _BV(ADPS0)
    #define ADCprescaler_reset ADCSRA = ~_BV(ADPS2) & ~_BV(ADPS1) & ~_BV(ADPS0)        
    #define ADCchannel_1                                      //gewünschter Kannal z.B bei ATmega32 PINA0 - PINA7
    #define ADCchannel_2      ADMUX|=_BV(MUX0)                // bei nicht freilaufen muss ADCchannel_x vor
    #define ADCchannel_3      ADMUX|=_BV(MUX1)                // ADCstart kommen dann kann man mit getadc() der 
    #define ADCchannel_4      ADMUX= _BV(MUX1) | _BV(MUX0)    // Adcwert des gewählten Kannals auslesen
    #define ADCchannel_5      ADMUX|=_BV(MUX2)
    #define ADCchannel_6      ADMUX= _BV(MUX2) | _BV(MUX0)
    #define ADCchannel_7      ADMUX= _BV(MUX2) | _BV(MUX1)
    #define ADCchannel_8      ADMUX= _BV(MUX2) | _BV(MUX1) | _BV(MUX0)
    #define ADCchannel_reset  ADMUX= ~_BV(MUX2) & ~_BV(MUX1) & ~_BV(MUX0)
    
    uint16_t getadc(void)
    {
       while (ADCSRA & _BV(ADSC)) {}
       return ADC;
    }
    
    int main(void)
    {
    
    uint16_t x;
    
    ADCinit;
    ADCprescaler_16;
    //Aktivierung des ADC, festlegen eines Prescalers von 16 
    
    while (1)
    	{
    	ADCchannel_2;
    	//Aktivierung des Pins , an ihm soll die zu messende Spannung liegen
    		
    	ADCstart;
    	//Start einer Konvertierung
    	
    	x=getadc();	
        
    	}
    }
    mfg pebisoft

    ( Bei längeren Code Schnipseln doch bitte den Code-Tag benutzten, MfG Kjion )

Seite 1 von 2 12 LetzteLetzte

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •  

12V Akku bauen