- Labornetzteil AliExpress         
Ergebnis 1 bis 10 von 10

Thema: ATMega32, Werte vom ADC ins EEPROM

  1. #1
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    05.01.2005
    Beiträge
    130

    ATMega32, Werte vom ADC ins EEPROM

    Anzeige

    LiFePo4 Akku selber bauen - Video
    Hallo,
    ich versuche gerade verzweifelt die Werte, die mir mein ADC zurückliefert, ins EEPROM zu schreiben, damit ich sie am PC auswerten kann (Platine ist schon fertig geätzt, aber kein UART dran, da ich da wohl nich dran gedacht hatte, dass ich die 1N4148 (genutzt als Temperatursensor) vielleicht auch erstmal auswerten sollte).

    Im Anhang ist der Schaltplan, habe die Diode genauso an den ADC gehängt, wie es auch bei Thomas Pfeifer im Schaltplan von seinem Laminiergerät zu sehen ist. Bei 22°C messe ich 0,66V.

    Hier ist der Code, der mir Probleme bereitet. Im EEPROM landet immer 00FF00FF00FF (usw.). Kann mir nicht vorstellen, woran es liegen könnte. Der ATMega läuft bei 1MHz und der ADC hat den Prescaler 4.

    Code:
    #include <avr/io.h>
    #include <util/delay.h>
    #include <avr/eeprom.h>
    
    void waitms(int ms);
    
    int* offset=0;
    
    void initADC() {
    	// Den ADC aktivieren und Teilungsfaktor auf 4 stellen
    	ADCSRA = (1<<ADEN) | (1<<ADPS1);
    
    	// AREF als Referenzspannung nutzen [ist das Richtig?!]
    	
    	// Den ADC initialisieren und einen sog. Dummyreadout machen [auch unnötig, oder? Wartezeit von wenigen µS sollte auch reichen... Aber ich hab's nicht eilig ;)]
    	ADCSRA |= (1<<ADSC);
    	while(ADCSRA & (1<<ADSC));
    }
    
    uint16_t readADC(uint8_t channel) {
    	uint8_t i;
    	uint16_t result = 0;
    
    	// Kanal des Multiplexers waehlen
    	ADMUX = channel;
    
    	// 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 += ADCW;
    	}
    	
    	result /= 3;
    	return result;
    }
    
    
    int main() {
    	unsigned char val;
    
    	DDRA &= ~(1<<PA0);		/* Temperatursensor		-	Eingang	*/
    	DDRB |= (1<<PB0);		/* Fixierwalze u. LED	-	Ausgang */
    	DDRC |= (1<<PC0);		/* Power LED 			-	Ausgang */
    	DDRD |= (1<<PD5);		/* PWM f. Motor ON/OFF 	-	Ausgang */
    	
    	PORTB &= ~(1<<PB0);
    	PORTC |= (1<<PC0);
    	PORTD |= (1<<PD5);
    	initADC();
    	
    	while(1==1) { 
    		waitms(500);
    		val=readADC(0);
    		eeprom_write_byte ((void*)offset, &val);
    		offset=offset+0x01;
    	}
    
    	// ADC wieder deaktivieren
    	ADCSRA &= ~(1<<ADEN);
    	return 0;
    }
    
    void waitms(int ms) {
      int i;
      for (i=0;i<ms;i++) _delay_ms(1);
    }
    Die Diode hängt am PA0.

    Ich hoffe ihr könnt mir helfen, die richtigen Werte ins EEPROM zu bekommen, wird mit Sicherheit nur 'ne Kleinigkeit sein, die ich übersehen habe..
    Danke schonmal im Voraus
    Miniaturansichten angehängter Grafiken Miniaturansichten angehängter Grafiken schaltplan_120.png  

  2. #2
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    22.05.2005
    Ort
    12°29´ O, 48°38´ N
    Beiträge
    2.731
    Hallo,

    so auf die Schnelle sehe ich nur, daß die Variable, die den ADC-Wert aufnehmen soll (in main), nur 8 Bit breit ist, das reicht dann nicht ganz ?

  3. #3
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    05.01.2005
    Beiträge
    130
    Oh, ja. Das liegt daran, dass ich da mittlerweile zuviel mit rumprobiert habe...

    Ursprünglich war das eine Integer Variable.. Habe ich dann so in den Eeprom geschrieben:
    Code:
    void writeEeprom(int wert, void* address)
    {
    	float localfloat = wert;
        eeprom_write_block(&localfloat, address, sizeof(float));
    }
    Die Address (also Variable offset) wurde nach jedem Schreiben um 4 Byte erhöht. Trotzdem immer FFFFFFFF00000000FFFFFFFF (usw.)

  4. #4
    Erfahrener Benutzer Roboter Experte Avatar von sternst
    Registriert seit
    07.07.2008
    Beiträge
    672
    Code:
    int* offset=0;
    ...
          val=readADC(0);
          eeprom_write_byte ((void*)offset, &val);
          offset=offset+0x01;
    Du erhöhst offset in jedem Durchgang um 2, schreibst aber immer nur ein Byte. So kommt das Muster zustande, die 0x00 ist das was du schreibst, die 0xff ist die jeweils übersprungene leere EEPROM-Zelle.
    Und wegen dem "&" vor dem val schreibst du Müll ins EEPROM.
    MfG
    Stefan

  5. #5
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    05.01.2005
    Beiträge
    130
    Hallo, ok, hab den Dereferenzierer rausgenommen.
    *kopfkratz* Warum erhöhe ich den Offset um 2? Ist doch +1. (Muss zugeben: nach extrem langer Delphi Zeit sind meine C Kenntnisse wieder etwas eingerostet).

    Jedenfalls wird jetzt nurnoch 0xFF geschrieben.

  6. #6
    Erfahrener Benutzer Roboter Experte Avatar von sternst
    Registriert seit
    07.07.2008
    Beiträge
    672
    Zitat Zitat von Spessi
    *kopfkratz* Warum erhöhe ich den Offset um 2? Ist doch +1.
    "+1" bedeutet bei Pointern "lass den Pointer auf das nächste Element zeigen". Und da das "Element" hier ein int ist, erhöhst du offset damit um 2.

    Jedenfalls wird jetzt nurnoch 0xFF geschrieben.
    Wenn du GND als Referenzspannung nimmst, bekommst du natürlich als Ergebnis immer 0x03FF. Und davon schreibst du das Low-Byte ins EEPROM, also 0xFF.
    MfG
    Stefan

  7. #7
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    20.05.2006
    Ort
    Lippe
    Alter
    54
    Beiträge
    524
    Hallo,

    schau dir noch einmal die Beschaltung von AREF und AVCC. Du möchtest VREF nutzen und legst den Pin auf Gnd?
    AVCC mit einem Kondensator nach +5V zu verbinden ist böse.
    Das ist sogar dann schlecht, wenn man den ADC nicht nutzt.
    Hier sind die Beschaltungen sehr schön verdeutlicht (Abschnitt A/D-Wandler).

    Gruß

    Jens

  8. #8
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    05.01.2005
    Beiträge
    130
    Ja, das war die Sache die mich am meisten verwirrt hat. Die einen sagen: machs so, die anderen sagen: machs so und so... Naja... Ich würde einfach nur gerne den ADC Wert auslesen, wäre das trotz der offensichtlich vermurksten Schaltung noch möglich?

    Hab eben mal die EEPROM Schreibroutine komplett rausgehauen und mit einer if abgefragt... Der ADC Wert scheint immer 1024 zu sein (1023)

  9. #9
    Erfahrener Benutzer Roboter Experte Avatar von sternst
    Registriert seit
    07.07.2008
    Beiträge
    672
    Zitat Zitat von Spessi
    Naja... Ich würde einfach nur gerne den ADC Wert auslesen, wäre das trotz der offensichtlich vermurksten Schaltung noch möglich?
    Du musst C2 durch eine Drahtbrücke ersetzen und die Verbindung von AREF zu GND auftrennen. Wenn du dann über ADMUX als Referenzspannung AVCC oder die interne Referenz auswählst, kannst du was messen. Richtig gut wird das aber nicht gehen, denn du bräuchtest auch noch einen Kondensator von AREF nach GND.
    MfG
    Stefan

  10. #10
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    05.01.2005
    Beiträge
    130
    Hey. Besten Dank! So funktioniert es...


    Ich bin echt überrascht. Hab mir aus nem alten Drucker die Fixiereinheit ausgebaut und angesteuert für das Toner-Transfer-Verfahren. Eben mal ne Platine auf ne ungesäuberte Platine gebügelt. Ich hab ja mit allem gerechnet, aber nicht mit so geilen Ergebnissen. Besten Dank nochmal euch allen!

Berechtigungen

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

MultiPlus Wechselrichter Insel und Nulleinspeisung Conrad