- LiTime Speicher und Akkus         
Seite 1 von 2 12 LetzteLetzte
Ergebnis 1 bis 10 von 12

Thema: Fehler in AVR Studio???

  1. #1
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    08.05.2004
    Ort
    Wilhelmshaven
    Alter
    45
    Beiträge
    324

    Fehler in AVR Studio???

    Anzeige

    Praxistest und DIY Projekte
    Hallo,
    ich habe den AVR Studio 4.12 SP4 und dort versuche ich das Beschreiben des internen EEPROMS eines Mega8's zu simulieren.

    Die zu beschreibende Adresse wähle ich nach jedem Schreibzugriff so:

    inc r22
    out EEARL,r22

    das scheint aber nicht so richtig zu funktionieren. r22 wird zwar inkrementiert, aber der Wert aus r22 wird nicht in EEARL geschrieben. Das mit dem out habe ich aus dem mikrocontroller.net Tutorial. mov funktioniert leider auch nicht ohne Fehlermeldung.

    wenn ich EEARL manuell inkrementiere, dann funktioniert die Simulation, nur selber funktioniert dieses out EEARL,r22 nicht.

    Ist das jetzt ein Fehler im Simulator? Im Programm? Kann ich davon ausgehen, dass es auf einem µC richtig läuft?

    Ich verstehe auf jeden Fall nicht, warum dieser out Befehl nicht durchgeführt wird und rechne mit einem Simulatorfehler.

  2. #2
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    28.10.2004
    Ort
    Baoding
    Alter
    44
    Beiträge
    689
    Hast Du im Simulator auch den richtigen AVR drinn (Alt+O)?

    Bei mir funzt das einwandfrei.

    MfG

  3. #3
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    08.05.2004
    Ort
    Wilhelmshaven
    Alter
    45
    Beiträge
    324
    ATmega8

    Flash Size: 8192 bytes
    Eeprom Size: 512 bytes
    Internal SRAM Size: 1024 bytes
    IO Size: 64 bytes

    4MHz


    liegt wohl nicht an der Geschwindigkeit. Welche Version hast denn vom AVR Studio?

    Danke schonmal fürs nachschauen.

  4. #4
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    28.10.2004
    Ort
    Baoding
    Alter
    44
    Beiträge
    689
    Version 4.13 Build 528

    Aber obs daran liegt?

  5. #5
    Erfahrener Benutzer Robotik Einstein Avatar von wkrug
    Registriert seit
    17.08.2006
    Ort
    Dietfurt
    Beiträge
    2.187
    Beschreibst DU auch das EEARH ?
    Vieleicht wird die Adresse erst übernommen wenn beide Register in der richtigen Reihenfolge beschrieben sind - Schau mal ins Code Beispiel.

  6. #6
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    08.05.2004
    Ort
    Wilhelmshaven
    Alter
    45
    Beiträge
    324
    also ich habe es mal mit dem EEARH beschreiben ausprobiert:
    out EEARH,r21
    inc r22
    out EEARL,r22

    hat aber auch nicht funktioniert. Die neuste Version des AVR Studios habe ich mir auch runtergeladen, aber irgendwie startet der Installer nicht. Werde es mal morgen ausprobieren; heute habe ich den Nerv nicht dazu.

  7. #7
    Erfahrener Benutzer Robotik Einstein Avatar von wkrug
    Registriert seit
    17.08.2006
    Ort
    Dietfurt
    Beiträge
    2.187
    Also diese Routine funzt bei mir im Simulator ohne Probleme und schreibt den Wert 0x55 auf EEPROM Adresse 0x0020.

    Code:
    EEPROM_write:
    	sbic EECR,EEWE   
        rjmp EEPROM_write
       ldi temp,0x00
       out EEARH,temp
       ldi temp,0x20
       out EEARL,temp
       ldi temp,0x55
       out EEDR,temp
       sbi EECR,EEMWE
       sbi EECR,EEWE
    Hab Studio Version 4.12 Service Pack 4
    Built 498

  8. #8
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    08.05.2004
    Ort
    Wilhelmshaven
    Alter
    45
    Beiträge
    324
    puhh, dass war ein Theater heute. Also nachdem ich gestern den Fehler hatte, wollte ich mir die neuste Version dieses Programms installieren. Datei heruntergeladen und in der Zwischenzeit das alte AVR Studio deinstalliert. Hast gleich ne neue Version, dann löscht du mal die alten Installationsdateien. Wollte die neue Version installieren....ging nicht; drei Sekunden Sanduhr und nichts weiter. Ok, vielleicht ist die Datei defekt, habe sie dann nochmal dreimal heruntergeladen und ausprobiert. Ging nicht. Ok, dann installierst du halt wieder die alte Version. Heruntergeladen, versucht zu installieren, ging auch nicht. Dann erstmal gegoogelt und einen Forumslink gefunden, wo auf einem Beitrag einer von Atmel geantwortet hat. Habe also die Anweisungen befolgt und paar Verzeichnisse und Registrierungseinträge gelöscht, ging dann auch noch nicht. Und ganz unten im Beitrag stand dann, dass man die Dateien mit dem Explorer herunterladen soll und dann ging das Installieren auch. Merkwürdig, aber durch dieses Theater habe ich wieder drei Stunden verloren.

    So, jetzt zum Eigentlichen.
    @wkrug: so habe ich es auch, nur wollte ich beim nächsten Durchlauf von EEPROM_write die 0x55 auf die nächste Adresse schreiben (EEARL=0x21), was ich mit dem Inkrementierbefehl gemacht habe, nur dann ändert sich der Wert in EEARL nicht, wenn ich ihn dann mit out übergebe. In temp hat er dann inkrementiert, nur mit out wird nicht EEARL auf 0x21 geschrieben.
    Code:
    loop:
    ;--------DEIN CODE----------
    EEPROM_write:
       sbic EECR,EEWE   
        rjmp EEPROM_write
       ldi temp2,0x00
       out EEARH,temp
       ldi temp,0x20
       out EEARL,temp
       ldi temp1,0x55
       out EEDR,temp
       sbi EECR,EEMWE
       sbi EECR,EEWE
    ;--------------/DEIN CODE----------
       inc temp
       out EEARL,temp
    rjmp loop
    Also für mich war es logisch, dass wenn man den EEARL inkrementiert, er dann den Wert auf die nächste Adresse schreibt. Nur mit dem out ändert sich der Wert in EEARL nicht.


    hier mal der gesamte Code meines bisherigen Programms. Leider nicht so übersichtlich, wie ich es mir gewünscht hätte....
    Code:
    .include "m8def.inc"
    
    .def temp = r16
    .def temp1= r17
    .def temp2= r18
    .def temp3= r19
    .def adhigh=r20
    .def eepromh=r21
    .def eeproml=r22
    .equ CLOCK = 4000000 ; externer Oszi, weil sonst USART nicht funktioniert
    .equ BAUD = 9600
    .equ UBRRVAL = CLOCK/(BAUD*16)-1
    
    .org 0x00
            rjmp reset
    
    .org URXCaddr
            rjmp int_rxc
    ;//////////////////Initialisierung/////////
    reset:        ; Stackpointer initialisieren
            ldi temp, LOW(RAMEND)
            out SPL, temp
            ldi temp, HIGH(RAMEND)
            out SPH, temp
    ;---------------Uart---------------------
            ; Baudrate einstellen
            ldi temp, LOW(UBRRVAL)
            out UBRRL, temp
            ldi temp, HIGH(UBRRVAL)
            out UBRRH, temp
    
            ; Frame-Format: 8 Bit
    		ldi	temp, (1<<URSEL)|(3<<UCSZ0);|(0<<USBS);|(1<<UMSEL)
            ;URSEL muss 1 sein, wenn UCSRC beschrieben wird.
    		;UCSZ0 = 3 entspricht 011 binär und setzt Datenbreite auf 8Bits
    		out UCSRC, temp 
    
            sbi UCSRB, RXCIE                  ; Interrupt bei Empfang
            sbi UCSRB, RXEN                   ; RX (Empfang) aktivieren
            
            sei                               ; Interrupts global aktivieren
      
    ;--------------/Uart----------------------
    
    ;--------------ADC------------------------
    ; ADC initialisieren:
        ldi  temp, (1<<REFS0) | (5<<MUX0) | (1<<ADLAR)  ; REFS=1 entspricht interne Referenzspannung 5V; MUX wählt ADC5 Pin28 PC5 aus ;ADLAR=1 bei 8bit reicht ADCH
        out  ADMUX, temp
        ldi  temp, (1<<ADEN) | (7<<ADPS0); ADEN ADC Enable (anschalten); ADPS 111 entspricht Divisionsfaktor 128
        out  ADCSRA, temp
    ;--------------/ADC-----------------------
    
    
    ;-------EEPROM----------------------------
    	ldi r21,0x00              ; High-Adresse im EEPROM laden
    	out EEARH, r21                    ; und ins EEARH schreiben 
    	ldi r22, 0x00               ; Low-Adresse im EEPROM laden
    	out EEARL, r22                    ; und ins EEARL schreiben	
    ;-------/EEPROM----------------------------
    
    ;//////////////////Initialisierung ENDE/////////
    loop:
    ;	rcall threeminutes  ;nach drei Minuten den ADC Wert einlesen
    
    ;--------------ADC Wert einlesen------------
    sample_adc:
        sbi  ADCSRA, ADSC       ; den ADC starten
     
    wait_adc:
        sbic ADCSRA, ADSC       ; wenn der ADC fertig ist, wird dieses Bit gelöscht
        rjmp wait_adc
     
        in   adhigh, ADCH       ; High Byte des ADC in adhigh speichern
    
    ;--------------/ADC Wert einlesen------------
    ;--------------...und in EEPROM schreiben----
    
    EEPROM_write:
        cli								  ;Interrupts vorsichtshalber ausschalten
                                          
    	sbic EECR,EEWE                    ; Vorherigen Schreibvorgang abwarten                 
    	rjmp EEPROM_write 
    	                                  
    	out EEDR,adhigh                     ; Daten ins EEPROM-Datenregister	              
    	sbi EECR,EEMWE                    ; Schreiben vorbereiten
    	sbi EECR,EEWE                     ; muss innerhalb von 4 Zyklen geschrieben werden, deswegen Interrupts aus.
     	sei								;Interrupts wieder einschalten
    	inc r22
    	out EEARL,r22
    	sei
    
    ;--------------/...und in EEPROM schreiben----
    rjmp loop
    
    int_rxc:                                  ; wenn vom PC etwas empfangen wird, dann wird Interrupt ausgelöst und hierher gesprungen
            push temp                         ; temp auf dem Stack sichern
            in temp, UDR                      ; empfangenes Byte von UDR in temp speichern	
            BREQ 1 	;wenn eine 1 übertragen wurde, dann sollen die Werte aus dem EEPROM an den PC gesendet werden.
    		rcall DatenSenden
    		BREQ 2  ;wenn eine 2 gesendet wird, dann soll EEPROM gelöscht werden
    		rcall DatenLoeschen
            pop temp                          ; temp wiederherstellen
    reti
    
    
    
    
            sbi UCSRB,TXEN				; TX aktivieren
    	
    
    ldi temp, 0xAA
    
    
    DatenSenden:
    ret
    DatenLoeschen:
    ret
    
    
    
    
    serout:
            sbis UCSRA,UDRE                   ; Warten bis UDR für das nächste
                                              ; Byte bereit ist
            rjmp serout
            out UDR, temp
            ret                               ; zurück zum Hauptprogramm
    
    
    
    
    
    ;threeminutes:
    ; ============================= 
    ;    delay loop generator 
    ;     720000000 cycles:
    ; ----------------------------- 
    ; delaying 49939965 cycles:
              ldi  R17, $FF
    WGLOOP0:  ldi  R18, $FF
    WGLOOP1:  ldi  R19, $FF
    WGLOOP2:  dec  R19
              brne WGLOOP2
              dec  R18
              brne WGLOOP1
              dec  R17
              brne WGLOOP0
    ; ----------------------------- 
    ; delaying 49939965 cycles:
              ldi  R17, $FF
    WGLOOP3:  ldi  R18, $FF
    WGLOOP4:  ldi  R19, $FF
    WGLOOP5:  dec  R19
              brne WGLOOP5
              dec  R18
              brne WGLOOP4
              dec  R17
              brne WGLOOP3
    ; ----------------------------- 
    ; delaying 49939965 cycles:
              ldi  R17, $FF
    WGLOOP6:  ldi  R18, $FF
    WGLOOP7:  ldi  R19, $FF
    WGLOOP8:  dec  R19
              brne WGLOOP8
              dec  R18
              brne WGLOOP7
              dec  R17
              brne WGLOOP6
    ; ----------------------------- 
    ; delaying 49939965 cycles:
              ldi  R17, $FF
    WGLOOP9:  ldi  R18, $FF
    WGLOOP10: ldi  R19, $FF
    WGLOOP11: dec  R19
              brne WGLOOP11
              dec  R18
              brne WGLOOP10
              dec  R17
              brne WGLOOP9
    ; ----------------------------- 
    ; delaying 49939965 cycles:
              ldi  R17, $FF
    WGLOOP12: ldi  R18, $FF
    WGLOOP13: ldi  R19, $FF
    WGLOOP14: dec  R19
              brne WGLOOP14
              dec  R18
              brne WGLOOP13
              dec  R17
              brne WGLOOP12
    ; ----------------------------- 
    ; delaying 49939965 cycles:
              ldi  R17, $FF
    WGLOOP15: ldi  R18, $FF
    WGLOOP16: ldi  R19, $FF
    WGLOOP17: dec  R19
              brne WGLOOP17
              dec  R18
              brne WGLOOP16
              dec  R17
              brne WGLOOP15
    ; ----------------------------- 
    ; delaying 49939965 cycles:
              ldi  R17, $FF
    WGLOOP18: ldi  R18, $FF
    WGLOOP19: ldi  R19, $FF
    WGLOOP20: dec  R19
              brne WGLOOP20
              dec  R18
              brne WGLOOP19
              dec  R17
              brne WGLOOP18
    ; ----------------------------- 
    ; delaying 49939965 cycles:
              ldi  R17, $FF
    WGLOOP21: ldi  R18, $FF
    WGLOOP22: ldi  R19, $FF
    WGLOOP23: dec  R19
              brne WGLOOP23
              dec  R18
              brne WGLOOP22
              dec  R17
              brne WGLOOP21
    ; ----------------------------- 
    ; delaying 49939965 cycles:
              ldi  R17, $FF
    WGLOOP24: ldi  R18, $FF
    WGLOOP25: ldi  R19, $FF
    WGLOOP26: dec  R19
              brne WGLOOP26
              dec  R18
              brne WGLOOP25
              dec  R17
              brne WGLOOP24
    ; ----------------------------- 
    ; delaying 49939965 cycles:
              ldi  R17, $FF
    WGLOOP27: ldi  R18, $FF
    WGLOOP28: ldi  R19, $FF
    WGLOOP29: dec  R19
              brne WGLOOP29
              dec  R18
              brne WGLOOP28
              dec  R17
              brne WGLOOP27
    ; ----------------------------- 
    ; delaying 49939965 cycles:
              ldi  R17, $FF
    WGLOOP30: ldi  R18, $FF
    WGLOOP31: ldi  R19, $FF
    WGLOOP32: dec  R19
              brne WGLOOP32
              dec  R18
              brne WGLOOP31
              dec  R17
              brne WGLOOP30
    ; ----------------------------- 
    ; delaying 49939965 cycles:
              ldi  R17, $FF
    WGLOOP33: ldi  R18, $FF
    WGLOOP34: ldi  R19, $FF
    WGLOOP35: dec  R19
              brne WGLOOP35
              dec  R18
              brne WGLOOP34
              dec  R17
              brne WGLOOP33
    ; ----------------------------- 
    ; delaying 49939965 cycles:
              ldi  R17, $FF
    WGLOOP36: ldi  R18, $FF
    WGLOOP37: ldi  R19, $FF
    WGLOOP38: dec  R19
              brne WGLOOP38
              dec  R18
              brne WGLOOP37
              dec  R17
              brne WGLOOP36
    ; ----------------------------- 
    ; delaying 49939965 cycles:
              ldi  R17, $FF
    WGLOOP39: ldi  R18, $FF
    WGLOOP40: ldi  R19, $FF
    WGLOOP41: dec  R19
              brne WGLOOP41
              dec  R18
              brne WGLOOP40
              dec  R17
              brne WGLOOP39
    ; ----------------------------- 
    ; delaying 20840484 cycles:
              ldi  R17, $C4
    WGLOOP42: ldi  R18, $B3
    WGLOOP43: ldi  R19, $C5
    WGLOOP44: dec  R19
              brne WGLOOP44
              dec  R18
              brne WGLOOP43
              dec  R17
              brne WGLOOP42
    ; ----------------------------- 
    ; delaying 6 cycles:
              ldi  R17, $02
    WGLOOP45: dec  R17
              brne WGLOOP45
    ; ============================= 
    
    	ret
    
    .eseg                                     ; EEPROM-Segment aktivieren
    daten: 
    		.db 0b00000000

  9. #9
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    08.05.2004
    Ort
    Wilhelmshaven
    Alter
    45
    Beiträge
    324
    so, habe mich nach einer längeren Pause erstmal wieder dran gesetzt und intensiv analysiert. Dabei ist mir aufgefallen, dass es einen Unterschied machte, wo ich dieses Inkrementieren durchgeführt habe und da fing ich dann genauer an zu suchen.
    Es lag daran, dass ich direkt nach dem Schreiben den neuen Speicherort festlegen wollte und das ging nicht, weil dieses EEWE Bit noch auf 1 war. Habe also eine Abfrageschleife eingeführt und jetzt funktioniert es wie ich es mir vorgestellt habe. Bei jedem Durchlauf schreibt er den Wert des A/D Wandlers auf die nächste Speicherstelle. Genauso wollte ich es haben.

    Aber danke für eure Bemühungen.



    der korrekte Code sieht jetzt so aus (die Angabe des Speicherbeginns habe ich weggelassen)

    Code:
    EEPROM_write:
        cli								  ;Interrupts vorsichtshalber ausschalten
                                          
    	sbic EECR,EEWE                    ; Vorherigen Schreibvorgang abwarten                 
    	rjmp EEPROM_write 
    	                                  
    	out EEDR,adhigh                     ; Daten ins EEPROM-Datenregister	              
    	sbi EECR,EEMWE                    ; Schreiben vorbereiten
    	sbi EECR,EEWE                     ; muss innerhalb von 4 Zyklen geschrieben werden, deswegen Interrupts aus.
    EEWEfrei:
    	sbic EECR,EEWE                    ; Vorherigen Schreibvorgang abwarten                 
    	rjmp EEWEfrei 
    	inc r22
    	out EEARL,r22
     	sei								;Interrupts wieder einschalten
    
    ;--------------/...und in EEPROM schreiben----
    rjmp loop

  10. #10
    Erfahrener Benutzer Robotik Einstein Avatar von wkrug
    Registriert seit
    17.08.2006
    Ort
    Dietfurt
    Beiträge
    2.187
    ..... dann war das eigentlich kein Fehler im AVR Studio, sondern in deinem Programm und Studio hat richtig reagiert.

Seite 1 von 2 12 LetzteLetzte

Berechtigungen

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

LiTime Speicher und Akkus