- Labornetzteil AliExpress         
Seite 2 von 3 ErsteErste 123 LetzteLetzte
Ergebnis 11 bis 20 von 30

Thema: Dieses Mal: ADC-Probleme

  1. #11
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    09.11.2006
    Ort
    Hamburg
    Alter
    39
    Beiträge
    199
    Anzeige

    LiFePo4 Akku selber bauen - Video
    So, mein Code sieht jetzt so aus:
    Code:
    #include <avr/io.h>
    #include <stdint.h>
    #define F_CPU 1000000UL
    
    int main(void)
      {
      DDRC = (1<<PC0);
      uint16_t x;
      
      SFIOR = ((0<<ADTS2) | (0<<ADTS1) | (0<<ADTS0));
      
      ADCSRA = ((1<<ADEN) | (1<<ADATE) | (1<<ADPS0) | (1<<ADPS1));
      
      ADMUX = (1<<REFS0);
      ADMUX |= PA0;
      
      ADCSRA |= (1<<ADSC); //hiermit wird die Messung initialisiert und gestartet
      
      while(1)
        {
    	x = ADCW;	//hier wird das ADC-Register ausgelesen
    	
    	if (x >= 800)	//wenn der gemessene Wert die 128 erreicht oder überschreitet soll die LED
    						//an PC0 leuchten also wenn die Spannung die hälfte von 0V zu AREF
    						//(hier 2,5V) überschreitet
    	  {
    	  PORTC |= (1<<PC0);
    	  }
    	else
    	  {
    	  PORTC &= ~(1<<PC0);
    	  }
        }
      }
    Jetzt klappt das auch schon besser, aber wenn ich "if (x<=500)" schreibe geht die Lampe bei etwa 4,2V an. x ist doch aber 16 bit groß.
    das müsste doch jetzt auf 0xffff verteilt sein, oder? Ich versteh das nicht.

    Gruß Jan

  2. #12
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    08.05.2005
    Ort
    Issum
    Alter
    52
    Beiträge
    2.236

    Das ist alles Käse

    Zuerst(und zum letztem, ich habe schon 2 mal drauf hingewiesen)
    ADMUX |= PA0;
    ES IST EIN ZUFALL,DAß DIESES KLAPPT!!!!!!!
    Was willst Du damit erreichen ?
    ADC0 abfragen ?
    dazu gibt es im ADMUX Register 5 Bits MUX4...0(Seite 215 M32 Dattenblatt)
    Ende der Durchsage, in DB nachsachauen und (hoffentlich) verstehen.

    Als nächstes Du läßt den ADC in Freeruning Modus laufen (habe so aus M32 DB rausgelesen,sorry, den benutze ich garnicht, egal)
    DAS berechtigt Dich aber nicht dazu einfach mal nach Lust und Laune
    Code:
    x = ADCW;
    zu schreiben!
    Nein, so eine Wandlung dauert schon ein paar Takte und man muß solange warten
    bis sie auch fertig ist, erst dann darf man sich das Ergebnis abholen !!!
    WOHER weißt man aber, daß eine Wandlung fertig ist ?
    Code:
     while ( ADCSRA & (1<<ADSC) ) {
          ;   // auf Abschluss der Konvertierung warten
        }
    habe ich von dort kopiert
    puh, (schweiß wegwisch)....ich hoffe geholfen zu haben

    Gruß Sebastian

    P.S. nein, ich habe gute Laune, manchmal muß man eben einen Schlag auf den Hinterkopf geben
    Software is like s e x: its better when its free.
    Linus Torvald

  3. #13
    Moderator Robotik Visionär Avatar von radbruch
    Registriert seit
    27.12.2006
    Ort
    Stuttgart
    Alter
    61
    Beiträge
    5.799
    Blog-Einträge
    8
    Hallo

    Nein, so eine Wandlung dauert schon ein paar Takte und man muß solange warten bis sie auch fertig ist, erst dann darf man sich das Ergebnis abholen !!!
    WOHER weißt man aber, daß eine Wandlung fertig ist ?
    Das dachte ich bisher auch, inzwischen bin ich aber nicht mehr sicher, ob es wirklich nur mit handshake funktioniert. Ich habe eher den Verdacht, der ADC wartet bis man die Daten gelesen hat. Für das Low-Byte steht es auch so im Datenblatt:

    When ADCL is read, the ADC Data Register is not updated until ADCH is read. Consequently,
    if the result is left adjusted and no more than 8-bit precision is required, it is
    sufficient to read ADCH. Otherwise, ADCL must be read first, then ADCH.
    (Aus der Beschreibung des Datenregisters S. 217)

    Bei meinen Versuchen lese ich ohne Handshake im free-running-Modus vom linksbüdigen Ergebniss nur das High-Byte aus, nach meiner Schätzung schneller als der ADC wandeln kann (Schneller geht's wohl kaum: while (ADCH > 20); ). Wenn ich den prescaler ändere (ich takte mit /2!), ändert sich auch die Datenleserate. Ich bin aber nicht wirklich sicher, weil ich das erst einmal gesehen habe und nicht näher untersucht habe.

    In iom32.h wird PA0 so definiert:
    /* PA7-PA0 = ADC7-ADC0 */
    /* PORTA */
    #define PA7 7
    #define PA6 6
    #define PA5 5
    #define PA4 4
    #define PA3 3
    #define PA2 2
    #define PA1 1
    #define PA0 0
    Also kann man auch PAx direkt in ADMUX.MUX0-4 schreiben.

    Gruß

    mic
    Bild hier  
    Atmel’s products are not intended, authorized, or warranted for use
    as components in applications intended to support or sustain life!

  4. #14
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    21.12.2004
    Alter
    39
    Beiträge
    165
    Zitat Zitat von radbruch
    Also kann man auch PAx direkt in ADMUX.MUX0-4 schreiben.
    Du kannst natuerlich auch TOIE0 oder was weiss ich schreiben, nur fuehrt das leider die ganze #define-Orgie ad absurdum. Denn wer sagt das beim Mega64231 das ganze genauso definiert ist? Portabilitaet ade.
    Viel Spass auch beim Verstehen von Code, wenn man erstmal nachschlagen muss wie denn nun PA0 definiert ist, was man bei MUX0 direkt im Datenblatt beim richtigen Thema sehen kann...

    Das dachte ich bisher auch, inzwischen bin ich aber nicht mehr sicher, ob es wirklich nur mit handshake funktioniert. Ich habe eher den Verdacht, der ADC wartet bis man die Daten gelesen hat. Für das Low-Byte steht es auch so im Datenblatt:
    Das hast du falsch verstanden. Wenn du ADCL gelesen hast dann wartet der ADC solange mit dem Eintragen eines neuen Wertes bis du auch ADCH gelesen hast. Damit wird verhindert das der ADC das H-Byte aendert wenn du schon das L hast aber das H noch nicht, das wuerde falsche Werte bringen.
    Dies ist quasi wie die cli() sei() Sache wenn man 16bit Werte verarbeitet und man nichts im L-Byte haben will was nicht zum H-Byte passt.

  5. #15
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    08.05.2005
    Ort
    Issum
    Alter
    52
    Beiträge
    2.236
    Radbruch, ich muß leider protestieren, Du verbreitest hier ziemlich viel Unsinn
    In iom32.h wird PA0 so definiert: Zitat:
    /* PA7-PA0 = ADC7-ADC0 */
    /* PORTA */
    #define PA7 7
    #define PA6 6
    #define PA5 5
    #define PA4 4
    #define PA3 3
    #define PA2 2
    #define PA1 1
    #define PA0 0
    Schön, und ? hier die ADC Multiplexer Belegung aus dem Dattenblatt:
    MUX4...0
    00000 ->ADC0
    00001 -> ADC1
    00010 -> ADC2
    00011 -> ADC3
    00100 -> ADC4
    00101 -> ADC5
    00110 -> ADC6
    00111-> ADC7

    Darfst selber überlegen, bis wann es gut geht, und warum ich sagte, daß es durch ein Zufall klappt
    Und was ist, wenn ich Deine ADCroutine in meinem M8 einsetzen möchte, oder einem Tiny?

    Was die Sache mit warten auf das Ergebnis angeht, lese was fluchpunkt gesagt hat, oder lese Appnotes von Atmel, bevor der Wandler nicht signalisiert, daß es fertig ist, hat mal ADC* nicht auszulesen, und bevor man das Ergebnis nicht abgeholt hat, nachdem der Wandler fertig ist werden ADC* nicht aktualisiert

    Gruß Sebastian
    P.S. Du darfst auch einen Interrupt benutzen, um ADC auszulesen, der wird auch angesprungen, wenn der Wandler fertig ist
    Software is like s e x: its better when its free.
    Linus Torvald

  6. #16
    Moderator Robotik Visionär Avatar von radbruch
    Registriert seit
    27.12.2006
    Ort
    Stuttgart
    Alter
    61
    Beiträge
    5.799
    Blog-Einträge
    8
    Na, das weiß man doch:

    /* PA7-PA0 = ADC7-ADC0 */
    Mal im Ernst: Ich will hier keine Glaubenskriege auslösen. C ist tückisch und jeder mag programmieren, wie er will. Ich versuche nur zu verstehen, wie so ein AVR tickt.

    Gruß

    mic
    Bild hier  
    Atmel’s products are not intended, authorized, or warranted for use
    as components in applications intended to support or sustain life!

  7. #17
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    08.05.2005
    Ort
    Issum
    Alter
    52
    Beiträge
    2.236
    Ne.ne kriege wollen wir nicht, wir wollen es nur richtig machen und vor allem wollen wir, daß Leute, die in ein paar Monaten diesen Beitrag finden auch alles richtig machen

    Gruß Sebastian
    Software is like s e x: its better when its free.
    Linus Torvald

  8. #18
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    09.11.2006
    Ort
    Hamburg
    Alter
    39
    Beiträge
    199
    Moin.
    Ich hab es immer noch nicht hinbekommen. Ich hab jetzt einen Kondensator mit 100nF zwischen AREF und GND geschaltet und im Programm alles mögliche gemacht:
    Code:
    #include <avr/io.h>
    #include <stdint.h>
    #define F_CPU 1000000UL
    
    int main(void)
      {
      DDRC = (1<<PC0);
      uint16_t x;
      
      SFIOR = ((0<<ADTS2) | (0<<ADTS1) | (0<<ADTS0));
    
      ADCSRA = ((1<<ADEN) | (1<<ADATE) | (1<<ADPS0) | (1<<ADPS1));
      
      ADMUX = (1<<REFS0);
      ADMUX = ((0<<MUX0) | (0<<MUX1) | (0<<MUX2) | (0<<MUX3) | (0<<MUX4)); 	//damit ist ADC0-Eingang 
    																			//gewählt
      
       ADCSRA |= (1<<ADSC);   //hiermit wird die Messung initialisiert und gestartet
      
      while(1)
        {
        while (ADCSRA & (1<<ADSC))
    	  {
    	  ;
    	  }
    	  
        x = ADCL;       
        x += (ADCH<<8);
    	
    	if (x >= 8000)
    	  {
    	  PORTC |= (1<<PC0);
    	  }
    	else
    	  {
    	  PORTC &= ~(1<<PC0);
    	  }
    	}
      }
    Ich werde mich heute auf jeden Fall noch mal ransetzen und ganz in ruhe versuchen das mal im Single Convention Mode zu programieren.
    Das ergebnis wird doch in 16 bit dargestellt sein, wobei 8000 doch ca. 2,5V bedeuten, wenn ich an AREF 5V Anlege, oder?

    MfG Jan

  9. #19
    Erfahrener Benutzer Robotik Visionär Avatar von Hubert.G
    Registriert seit
    14.10.2006
    Ort
    Pasching OÖ
    Beiträge
    6.220
    Mit 10 Bit und in deinem Fall 512 wirst du dich begnügen müssen.

  10. #20
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    09.11.2006
    Ort
    Hamburg
    Alter
    39
    Beiträge
    199
    Aber 10 bit sind doch 1024. Warum 512?
    Ich dachte es gibt ein More Significant Byte und ein Low Significant Byte also 2 Byte also 16 Bit. Warum hab ich denn plötzlich nur noch 10, bzw. 9?
    Oder versteh ich jetzt was völlig falsch?

Seite 2 von 3 ErsteErste 123 LetzteLetzte

Berechtigungen

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

LiFePO4 Speicher Test