- fchao-Sinus-Wechselrichter AliExpress         
Seite 1 von 2 12 LetzteLetzte
Ergebnis 1 bis 10 von 11

Thema: Brauche einen Tipp bzgl. EEPROM_write() und EEPROM_read()

  1. #1
    Benutzer Stammmitglied
    Registriert seit
    12.06.2007
    Beiträge
    42

    Brauche einen Tipp bzgl. EEPROM_write() und EEPROM_read()

    Anzeige

    Powerstation Test
    Moin!

    Ich habe folgendes Problem: Wenn ich mit EEPROM_write() Charakters speichere und sie dann wieder einlesen möchte, dann kommt immer nur 0xff zurück. Dabei habe ich mich (meiner Meinung nach) an das Datenblatt des Tiny2313 gehalten. Diesem habe ich nämlich die beiden benutzten Funktionen entnommen.

    Code:
      unsigned char cTest[2];
      //
      EEPROM_write(0,'A');
      EEPROM_write(1,'B');
      EEPROM_write(2,'C');
      myWait(2000);
      cTest[0] = EEPROM_read(0);
      cTest[1] = EEPROM_read(1);
      cTest[2] = EEPROM_read(2);
      myWait(2000);
      USART_transmit(cTest[0]);
      USART_transmit(cTest[1]);
      USART_transmit(cTest[2]);
    Irgendjemand eine Idee, wo der Fehler liegen könnte?

  2. #2
    Benutzer Stammmitglied
    Registriert seit
    12.06.2007
    Beiträge
    42
    Hier noch die beiden Funktionen:

    Code:
    /***************/
    void EEPROM_write(unsigned int uiAddress, unsigned char ucData)
    /***************/
    {
    /* Wait for completion of previous write */
      while(EECR & (1<<EEPE)) {
        ;
      }
      /* Set up address and data registers */
      EEAR = uiAddress;
      EEDR = ucData;
      /* Write logical one to EEMPE */
      EECR |= (1<<EEMPE);
      /* Start eeprom write by setting EEPE */
      EECR |= (1<<EEPE);
      return;
    }
    
    /***************/
    unsigned char EEPROM_read(unsigned int uiAddress)
    /***************/
    {
      /* Wait for completion of previous write */
      while(EECR & (1<<EEPE))
      ;
      /* Set up address register */
      EEAR = uiAddress;
      /* Start eeprom read by writing EERE */
      EECR |= (1<<EERE);
      /* Return data from data register */
      return EEDR;
    }

  3. #3
    Erfahrener Benutzer Robotik Einstein Avatar von wkrug
    Registriert seit
    17.08.2006
    Ort
    Dietfurt
    Beiträge
    2.188
    Ist das nicht so, das man da ein EEMWE bit setzen muss bevor man auf das EEProm schreiben kann und man dann auch nur ein paar Takte hat um den Schreibvorgang zu beginnen ?

    Was sagt das Datenblatt dazu, da sind doch so Musterroutinen drin ?

  4. #4
    Benutzer Stammmitglied
    Registriert seit
    12.06.2007
    Beiträge
    42
    Ich dreh noch durch!

    Erstmal herzlichen Dank an wkrug für den Tipp. Du hast Recht, auch wenn das Register und die Bits beim Tiny2313 anders benannt sind. Jedoch habe ich nun einen mir absolut unerklärlichen Effekt vorliegen.

    Meine Schleife sah anfangs so aus (alles überflüssige wie USART_init(), LED-Spielchen etc. habe ich weggekürzt):

    Code:
    	for(;;) {
    		//
    		if( UCSRA & (1<<RXC) ) {	//bei einer Eingabe wird diese direkt zurück ans Terminal geschickt
    			USART_transmit(UDR);
    
          }
        }
    Dabei wurde einfach jedes empfangene Zeichen zurück ans Terminal (bei mir HTerm) geschickt. Das hat perfekt funktioniert! Dann wollte ich mal die EEPROM-Funktionen testen und hab das ganze folgendermaßen erweitert:

    Code:
      unsigned char cTest[2];
      //
      //EECR &= ~( (1<<EEPM1)|(1<<EEPM0) );  //(1)
      //
      EEPROM_write(0,'A');
      EEPROM_write(1,'B');
      EEPROM_write(2,'C');
      myWait(2000);
      cTest[0] = EEPROM_read(0);
      cTest[1] = EEPROM_read(1);
      cTest[2] = EEPROM_read(2);
      myWait(2000);
      USART_transmit(cTest[0]);
      USART_transmit(cTest[1]);
      USART_transmit(cTest[2]);
    
      for(;;) {
    		//
    		if( UCSRA & (1<<RXC) ) {	//bei einer Eingabe wird diese direkt zurück ans Terminal geschickt
    			USART_transmit(UDR);
    
    
          USART_transmit(cTest[0]);
          USART_transmit(cTest[1]);
          USART_transmit(cTest[2]);
    
    
    		}
      }
    Dann empfing ich, wie gesagt, nur Schrott über die EEPROM-Funktionen. Zumindest dachte ich, dass es daran liegt. Als ich dann aber gesehen habe, dass USART_transmit(UDR) auch nur noch Blödsinn schickt, habe ich die Funktion durch Auskommentieren wieder in den Ursprungszustand versetzt.

    Das Ergebnis ist erschütternd: Jetzt liefert mir USART_transmit(UDR) dauerhaft seltsame Werte (jedenfalls nicht die zuvor eingegebenen!). Z.B. kommt 5 mal hintereinander 0xff (255), dann z.B. 0xc0 (192). Dabei kommt es scheinbar nicht darauf an, welche Zeichen ich sende.

    Den 2313 habe ich auch mal ausgetauscht, daran kann es nicht liegen. Hat jemand dafür eine Erklärung?

    Zu (1): Ich kenne mich noch nicht so gut mit bitweisen Operationen aus. Ist dieser Ausdruck richtig, wenn ich die Bits EEPM1 und EEPM0 löschen will? Dann hätte ich zumindest schonmal die Lösung für mein ursprüngliches Problem, dank des Tipps von wkrug.

    Schonmal vielen Dank für jede nützliche oder unnütze Antwort!

    Gruß Matze

  5. #5
    Benutzer Stammmitglied
    Registriert seit
    12.06.2007
    Beiträge
    42
    Hier im Anhang ein ScreenShot von HTerm. Unten sieht man die eingegebenen Werte, oben die von HTerm empfangenen. Man sieht, es scheint egal zu sein, welche Zeichen man nun sendet...
    Miniaturansichten angehängter Grafiken Miniaturansichten angehängter Grafiken hterm.jpg  

  6. #6
    Benutzer Stammmitglied
    Registriert seit
    12.06.2007
    Beiträge
    42
    So, bevor ihr euch alle die Köpfe zerbrecht: Ich hab den (wirklich blöden) Fehler gefunden. Die Fuses waren anders gesetzt als ich das mal eingerichtet hatte. Es war eine falsche Taktung angegeben, und das war der Grund für die unsinnigen Outputs.

    Hat eigentlich jemand eine Ahnung, warum das AVR Studio teilweise tagelang meine Fuses-Einstellungen behält, dann aber plötzlich und gänzlich unerwartet alles ändert (wahrscheinlich auf Standard-Werte)? Ich kann mir das nicht erklären...

    Ich habe immer wieder das Problem, dass die Fuses zurückgesetzt werden (Frequenz anders, Clock divide by 8 plötzlich wieder an...), obwohl es sich immer um mein Testprogramm mit unveränderter Hardware handelt.

    @wkrug:
    Wenn du jetzt eine Ewigkeit umsonst über das beschriebene Phänomen gegrübelt hast, entschuldige ich mich hiermit. War ein blöder Fehler. Bin halt noch ganzt am Anfang der AVR-Programmierung...

    Gruß Matze

  7. #7
    Benutzer Stammmitglied
    Registriert seit
    12.06.2007
    Beiträge
    42
    Es wäre nett, wenn mir noch einer sagen kann, ob der von mir formulierte Ausdruck (Code-Ansicht, siehe //(1) ) richtig ist. Damit wäre mir sehr geholfen.

  8. #8
    Benutzer Stammmitglied
    Registriert seit
    12.06.2007
    Beiträge
    42
    So, das Ursprungsproblem ist leider noch vorhanden. Ich habe mal testweise versucht, das komplette EEPROM (beim Tiny2313 128 Bytes) zu beschreiben und auszulesen, jedoch bekomme ich immer nur 0xff zurück.

    Die Register sollten doch eigentlich richtig gesetzt sein, oder (siehe oben, 2. Code-Block)? Schließlich ist der Code direkt dem Datenblatt entnommen.

    So, wie ich es verstehe, sollten die beiden Funktionen zum Lesen und Schreiben ausreichen, ohne dass ich mir noch eine init()-Funktion basteln muss. Nur, dass es einfach nicht klappt.

  9. #9
    Benutzer Stammmitglied
    Registriert seit
    12.06.2007
    Beiträge
    42
    Ich habe die Lösung des Problems gefunden!

    Der Fehler war tatsächlich, die im Datenblatt enthaltenen Funktionen EEPROM_write() und EEPROM_read() zu nutzen. Die scheinen fehlerhaft zu sein. Stattdessen habe ich nun die Funktionen eeprom_write_byte() und eeprom_read_byte() aus der eeprom.h probiert, und siehe da! Es läuft!

    Wirklich schade, dass im Datenblatt, auf das man sich verlassen können sollte, und auf das hier im Forum ständig verwiesen wird, solche Fehler manifestiert sind. Das hat mich unnötigerweise einen guten halben Arbeitstag gekostet...

    Gruß Matze

  10. #10
    Erfahrener Benutzer Robotik Einstein Avatar von wkrug
    Registriert seit
    17.08.2006
    Ort
    Dietfurt
    Beiträge
    2.188
    Das Datenblatt muss hier nicht zwingend falsch sein.
    Das ist vermutlich auch vom Compiler abhängig.
    Wenn der Compiler zu viele Schritte zum Setzen der Bits braucht funktioniert es nicht mehr.
    Vieleicht wäre auch Inline Assembler für die Routine eine Lösung gewesen?

Seite 1 von 2 12 LetzteLetzte

Berechtigungen

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

Solar Speicher und Akkus Tests