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

Thema: Ram mit PIC18F4455 ansprechen

  1. #1
    Neuer Benutzer Öfters hier
    Registriert seit
    14.05.2010
    Beiträge
    7

    Ram mit PIC18F4455 ansprechen

    Anzeige

    Powerstation Test
    Hallo zusammen,
    ich möchte den Ramspeicher mit o.g. PIC ansprechen. Ich möchte aber anders als im Datenblatt beschrieben eine indirekte Adressierung mit Variablen, die die Adresse beinhalten, durchführen. Nur klappt das leider nicht. Ich habe unter anderem versucht, mit
    lfsr 0,0x800
    movf SpeicherZähler,0
    Addwf FSR0,1
    .. die 12- Adresse mit der 8 Bit Adresse, die im WREG steht zu addieren und in die 12-Bit Adresse zu speichern. Ohne Erfolg!!??
    Kann mir jemand weiterhelfen?
    Gruss..

  2. #2
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    05.11.2007
    Beiträge
    1.076
    Ich bin mir nicht ganz sicher, ob ich dein Problem richtig verstanden habe,
    aber ich vermute schon...

    Die folgende Variable soll eine beliebige Adresse festhalten, die später auf deine Ramstelle zeigen soll. Ist also ein 16 Bit Variable welche später deine 12 Bit Adresse auf eine RAM Speicherstelle beinhalten soll. Ich lege sie einfach mal bei Adresse 0x0100 Low Byte und 0x0101 High Byte ab:
    var_Address_Low EQU 0x0100
    var_Address_High EQU 0x0101


    ; nun müssen wir erstmal festlegen worauf die Variable zeigen soll.
    ; var_Address soll zum Beispiel auf die Speicherstelle 0x0300 zeigen

    movlw LOW 0x0300
    movff WREG,var_Address_Low
    movlw HIGH 0x0300
    movff WREG,var_Address_High


    ; das FSR Register bekommt nun die Adresse worauf die Variable zeigt
    movff var_Address_Low,FSR0L
    movff var_Address_High,FSR0H


    ; nun wird ein Wert aus dem RAM geladen, danach wird das FSR0 Register automatisch um eins erhöht
    movf POSTINC0,W

    ; irgend was damit machen
    movf POSTINC0,W ; jetzt wird das nächste Byte aus dem RAM geladen
    ; zudem wird das FSR0 Register um
    ; irgend was damit machen

    Folgenden Code kannst Du NICHT benutzen
    LFSR FSR0,var_Address_Low
    movf POSTINC0,W

    ; hier wird FSR0 mit der Adresse von var_Address_Low geladen und nicht mit dem Wert wo die Variable hinzeigt



    Ich hoffe ich konnte Dir etwas weiterhelfen.
    mfg. Siro

  3. #3
    Neuer Benutzer Öfters hier
    Registriert seit
    14.05.2010
    Beiträge
    7
    Hallo und danke!
    Bin gerade aus dem Urlaub wieder da und werde es im Laufe des Tages ausprobieren....

  4. #4
    Neuer Benutzer Öfters hier
    Registriert seit
    14.05.2010
    Beiträge
    7
    .... und das beschreiben des RAM-Speichers würde nach der Adressierung doch mit z.B.
    movlw D'3'
    movwf INDF0
    funktionieren müssen oder??
    Also ich habe folgendes probiert um die Adresse 900 mit 9 zu beschreiben und 800 mit 8:
    movlw D'0'
    movwf var_Address_Low
    movlw D'8'
    movwf var_Address_High

    movff var_Address_Low,FSR0L
    movff var_Address_High,FSR0H
    movlw D'8'
    movwf POSTINC0;INDF0

    movlw D'9'
    movwf var_Address_High

    movff var_Address_Low,FSR0L
    movff var_Address_High,FSR0H
    movlw D'9'
    movwf POSTINC0;INDF0


    ;auslesen:
    movlw D'0'
    movwf var_Address_Low
    movlw D'8'
    movwf var_Address_High

    movff var_Address_Low,FSR0L
    movff var_Address_High,FSR0H


    movf POSTINC0,W
    movwf Zeichen
    call SendeZeichen
    call WarteLänger

    movlw D'0'
    movwf var_Address_Low
    movlw D'9'
    movwf var_Address_High

    movff var_Address_Low,FSR0L
    movff var_Address_High,FSR0H


    movf POSTINC0,W
    movwf Zeichen
    call SendeZeichen
    call WarteLänger

    und es funktioniert nicht !
    Ich erhalte 2x die 9 zurück

  5. #5
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    05.11.2007
    Beiträge
    1.076
    Hallo,
    ich hoffe doch der Urlaub war okay.
    Ja, das kann so noch nicht funktionieren aus mehreren Gründen.

    1) Der PIC18F4455 hat ab Adresse 0x800 gar keinen RAM mehr, er besitzt nur 2048 Bytes und damit endet der RAM bei 0x07FF.
    Siehe Datenblatt Seite 60

    2) Der Ram ist unterteilt in verschiedene Blöcke. Um entsprechend darauf zuzugreifen benötigt man ein sogenanntes BANKSELECT.
    Zuständig ist dafür das Register BSR
    Solange Du mit MOVFF arbeitest, brauchst Du Dir keine Gedanken um das Bankselect machen. Sobald aber MOVWF oder MOVF ins Spiel kommt, musst Du sicherstellen, daß auch die richtige Rambank aktiv ist.

    ich hab mal deinen Code abgeändert und ausprobiert. So geht es dann:


    Code:
    #include P18F4455.inc
    
    	org 0
    	goto main
    
    
    var_Address_Low EQU 0x0100
    var_Address_High EQU 0x0101 
    
    Zeichen EQU 0x102
    
    main:
    ; ich schreibe in diesem Beispiel an die Adresse 0x0600 eine 6
    ; und an die Adresse 0x0700 eine 7
    
     BANKSEL var_Address_Low    ; so kannst Du dafür sorgen, daß MPLAB (der Assembler) automatisch die richtige Bank auswählt
     movlw D'0'
     movwf var_Address_Low
     movlw D'6'
     movwf var_Address_High
    
     ; hier brauchen wir kein Bankselect wegen dem MOVFF
     movff var_Address_Low,FSR0L
     movff var_Address_High,FSR0H
     movlw D'6'
     movwf POSTINC0;INDF0
    
     ; hier setze ich z.B die BANK mal direkt mit dem BSR Register,
     ; eigentlich brauche ich es nicht mehr, da die Bank immer noch richtig steht
     ; nur zur Verdeutlichung...
     bsf  BSR,0		     ; BANK 1   Speicherbereich 100..1FF auswählen
     movlw D'7'
     movwf var_Address_High
    
     movff var_Address_Low,FSR0L
     movff var_Address_High,FSR0H
     movlw D'7'
     movwf POSTINC0;INDF0
    
    ;auslesen:
     movlw D'0'
     movwf var_Address_Low
     movlw D'6'
     movwf var_Address_High
    
     movff var_Address_Low,FSR0L
     movff var_Address_High,FSR0H
    
    
     movf POSTINC0,W
     movwf Zeichen
    ; call SendeZeichen
    ; call WarteLänger
    
     movlw D'0'
     movwf var_Address_Low
     movlw D'7'
     movwf var_Address_High
    
     movff var_Address_Low,FSR0L
     movff var_Address_High,FSR0H
    
    
     movf POSTINC0,W
     movwf Zeichen
    ; call SendeZeichen
    ; call WarteLänger 
    
     end
    ich hoffe, ich konnte Dir damit helfen.
    Siro

  6. #6
    Neuer Benutzer Öfters hier
    Registriert seit
    14.05.2010
    Beiträge
    7

    klappt so

    ich habe es jetzt so gelöst:

    Code:
    Speichern
    ;speichern: // Bank 1-6: 1=Position1LowIst;2=Position1HighIst;3=Position2LowIst;4=Position2HighIst;5=MessWertLow;6=MessWertHigh
     
     movlw	D'1'
     movff	WREG,FSR0H
     movff	SpeicherZähler,	FSR0L
     movff	Position1LowIst,INDF0			
     
     movlw	D'2'
     movff	WREG,FSR0H
     movff	Position1HighIst,INDF0	
    
    
     movlw	D'3'
     movff	WREG,FSR0H
     movff	Position2LowIst,INDF0	
    
     movlw	D'4'
     movff	WREG,FSR0H
     movff	Position2HighIst,INDF0	
     
     movlw	D'5'
     movff	WREG,FSR0H
     movff	MessWertLow,INDF0		
     
     movlw	D'6'
     movff	WREG,FSR0H
     movff	MessWertHigh,INDF0	
    
    return
    ;;**************************************************************
    SpeicherAuslesen
    ;Istpositionen retten:
     movff	Position1LowIst,Position1LowIstKopie
     movff	Position1HighIst,Position1HighIstKopie
     movff	Position2LowIst,Position2LowIstKopie
     movff	Position2HighIst,Position2HighIstKopie
    
    
    SpeicherAuslesenLoop
     
     movlw	D'1'
     movff	WREG,FSR0H
     movff	SpeicherZähler,	FSR0L
     movff	INDF0,Position1LowIst
    
     movlw	D'2'
     movff	WREG,FSR0H
     movff	INDF0,Position1HighIst
    
     movlw	D'3'
     movff	WREG,FSR0H
     movff	INDF0,Position2LowIst	
    
     movlw	D'4'
     movff	WREG,FSR0H
     movff	INDF0,Position2HighIst	
    
     movlw	D'5'
     movff	WREG,FSR0H
     movff	INDF0,MessWertLow	
    
     movlw	D'6'
     movff	WREG,FSR0H
     movff	INDF0,MessWertHigh	
     
     call	Sende6BytePositionsUndMesswerte
    
     decf	SpeicherZähler,1
     movlw	D'0'
     CPFSEQ	SpeicherZähler
     goto	SpeicherAuslesenLoop
    
     clrf	SpeicherZähler
    
    ;Ab hier ist der Speicher ausgelesen:
    ;aktuellen Ist-Wert zurücklesen:
     movff	Position1LowIstKopie,Position1LowIst
     movff	Position1HighIstKopie,Position1HighIst
     movff	Position2LowIstKopie,Position2LowIst
     movff	Position2HighIstKopie,Position2HighIst
     ;call	ADWandlung
     ;call	Sende6BytePositionsUndMesswerte			;letzte Istposition dem PC mitteilen
     return

    Ich habe zwar noch einen scheinbar sporadischen Fehler bei der Messwertaufnahme, der sich so äußert, dass ein Positionswert mal nicht stimmt, aber dass wird wohl an etwas anderem liegen....

    Vielen Dank für Deine Hilfe!!! =D>

  7. #7
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    05.11.2007
    Beiträge
    1.076
    Hallo nochmal,
    das sieht ja etwas merkwürdig aus, aber wenns dann geht okay.
    Kannst Du mal etwas genauer erklären was Du machen möchtest.
    Sieht aus als wenn Du eine Tabelle von Messwerten irgendwo ablegen willst und diese dann später zum PC senden willst.
    Fragst Du mehrere ADU Kanäle ab. Ich blick da nicht ganz durch.
    Was sind denn die Position1LowIst und Position1HighIst und
    Position2LowIst und Position2HighIst.
    Ich denke mal das sollen zwei 16 Bit Variablen sein.
    Du benutzt anscheinend FSR0L als index um innerhalb einer RAM Bank zuzugreifen. Kannst damit also 256 Werte adressieren.
    Während Du mit FSR0H die Bank auswählst. Dagegen gibt es eigentlich auch nichts zu sagen, nur etwas ungewohnt. Ich denke mal das geht alles etwas eleganter, wenn Du mir dein Problem genauer schilderst, werd ich Dir gern weiter helfen. Das Wochenende ist noch lang

    mfg. Siro

  8. #8
    Neuer Benutzer Öfters hier
    Registriert seit
    14.05.2010
    Beiträge
    7
    Also...
    Ich möchte mit einem XY-Schlitten der mit Schrittmotoren ausgestattet ist Messwerte aufnehmen. Die Positionsdaten müssen also den Messdaten zugeordnet sein. Die Positionsdaten setzen sich aus High/Low werten zusammen. Also für 2 Schrittmotoren werden 4 Byte Sollpositionsdaten zum Pic übertragen, die er anfahren soll. Der Rasterwert wurde dem Pic vorher durch den PC(Anwendersoftware die ich in VB6 schreibe) mitgeteilt. Es wird also ein vordefiniertes zweidimensionaltes Feld gerastert und abgetastet. Anfangs hatte ich die Positionsdaten und Messwerte (auch 2Byte) mit jedem Schrittmotorschritt per RS232 übertragen, was das ganze langsam werden lies... . Nun nutze ich 6x 256Byte für die 4 Positionsdaten und 2 Messdaten. Das geht nun deutlich schneller. Bei der feinsten Abrasterung (12µm pro Schritt) dauert es natürlich etwas länger.
    Aber dank Dir klappt es ja nun mit der Zwischenspeicherung.
    Ich hatte das ganze schonmal mit dem 16F876-20 gemacht, der war aber bis an seine Grenzen ausgelastet. Ich musste sogar den Messkanal andauernd umschalten.. - ich hatte einfach nicht genügend Ports....
    Den PIC18F.. programmiere ich zu ersten Mal. Eigendlich müsste ich mich bei solchen recht grossen Programmen auf C -Compiler umgewöhnen aber ich komme im Moment noch nicht klar mit dem C-Compiler von CSS.
    Hast Du damit Erfahrung?
    MFG

  9. #9
    Neuer Benutzer Öfters hier
    Registriert seit
    14.05.2010
    Beiträge
    7
    Also...
    Ich möchte mit einem XY-Schlitten der mit Schrittmotoren ausgestattet ist Messwerte aufnehmen. Die Positionsdaten müssen also den Messdaten zugeordnet sein. Die Positionsdaten setzen sich aus High/Low werten zusammen. Also für 2 Schrittmotoren werden 4 Byte Sollpositionsdaten zum Pic übertragen, die er anfahren soll. Der Rasterwert wurde dem Pic vorher durch den PC(Anwendersoftware die ich in VB6 schreibe) mitgeteilt. Es wird also ein vordefiniertes zweidimensionaltes Feld gerastert und abgetastet. Anfangs hatte ich die Positionsdaten und Messwerte (auch 2Byte) mit jedem Schrittmotorschritt per RS232 übertragen, was das ganze langsam werden lies... . Nun nutze ich 6x 256Byte für die 4 Positionsdaten und 2 Messdaten. Das geht nun deutlich schneller. Bei der feinsten Abrasterung (12µm pro Schritt) dauert es natürlich etwas länger.
    Aber dank Dir klappt es ja nun mit der Zwischenspeicherung.
    Ich hatte das ganze schonmal mit dem 16F876-20 gemacht, der war aber bis an seine Grenzen ausgelastet. Ich musste sogar den Messkanal andauernd umschalten.. - ich hatte einfach nicht genügend Ports....
    Den PIC18F.. programmiere ich zu ersten Mal. Eigendlich müsste ich mich bei solchen recht grossen Programmen auf C -Compiler umgewöhnen aber ich komme im Moment noch nicht klar mit dem C-Compiler von CSS.
    Hast Du damit Erfahrung?
    MFG

  10. #10
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    05.11.2007
    Beiträge
    1.076
    Vorab, ich benutze auch keinen C-Compiler, programmiere die PICs seit zig Jahren in Assembler.

    Also wenn ich es richtig verstanden habe, dann sendet deine PC-Software eine Serie von X und Y Position an den PIC.
    Also eine gerasterte Strecke. Diese wird zunächst im PIC in einer Tabelle gespeichert.
    Der PIC soll nun mittels zweier Schrittmotoren die Positionen bzw. die Strecke abfahren und je einen Messwert zu jeder Position zum PC zurücksenden.
    Trifft das in etwas dein Vorhaben ?

    Da ist deine Idee mit der Aufteilung der Daten in den einzelnen RAM-Banken garnicht schlecht, gefällt mir sogar ganz gut.
    So hast Du immer ein gleiches Indexregister FSR0L und die Tabelle wird über FSR0H gewählt.
    Ehrlich gesagt, da würd ich auch garnichts dran ändern, das past gut zu deinem Problem.

    Ich hatte nur die Idee, da Du im PIC18xx drei solcher Indexregister hast, könnte man die Adressen
    separat über jeweils einen Satz der Indexregister ansprechen. Hab das mal eben so aufgeschrieben,
    ist aber auch nicht viel effektiver.

    Wir benutzen eine FSR-Registersatz für die X Position
    den zweiten für die Y Position
    und den dritten für die Messwerte

    So kannst Du nun alle Adressen deiner 3 Tabellen in die FSR0 bis FSR2 Register laden.
    Für den Messwertzähler benutze ich mal das Register TBLPTRL, das ist wahrscheinlich in deiner Software noch unbenutzt.

    Wenn Du jetzt deine Daten an den PC senden willst, würde es im Prinzip so aussehen:

    Code:
    LFSR FSR0,0x100 ; Adresse X-Koordinaten
    LFSR FSR1,0x300 ; Adresse Y-Koordinaten
    LFSR FSR2,0x500 ; Adresse Messwerte
    
    movl	D'255'                 ; 256 Positionen und Messwerte sollen gesendet werden
    movwf	TBLPTRL                ; ich benutze gerne dieses 8 Bit Register zum zählen
    
    Sende_Schleife:
    movf	POSTINC0,W             ; X Position Low Byte laden, x-index +1
    call	Sende_W_Register       ; 
    movf	POSTINC0,W             ; X Position High Byte laden, x-index +1
    call	Sende_W_Register
    
    movf	POSTINC1,W             ; Y Position Low Byte laden, Y-index +1
    call	Sende_W_Register
    movf	POSTINC1,W             ; Y Position High Byte laden, Y-index +1
    call	Sende_W_Register
    
    movf	POSTINC2,W             ; Messwert Low Byte laden, Messindex +1
    call	Sende_W_Register
    movf	POSTINC2,W             ; Messwert High Byte laden, Messindex +1
    call	Sende_W_Register
    decfsz	TBLPTRL,F              ; Zähler -1, scip if zero (überspringe nächste Zeile wenn 0 rauskommt)
    goto	Sende_Schleife         ; Schleifen bis alle Messwerte gesendet wurden
    
    
    ;;;;;;;;;; mal zu Vergleich mit deiner Idee:
    
    
    movl	D'127'              ; 127 Positionen und Messwerte sollen gesendet werden
    movwf	TBLPTRL             ; ich benutze gerne dieses 8 Bit Register zum zählen
    
    movlw	1                   ; Ram Bank für Position X Low Byte wählen
    movwf	FSR0L               ;
    
    Sende_Schleife:
    
    movf	INDF0,W             ; X Position Low Byte laden
    call	Sende_W_Register    ; 
    incf	FSR0H,F             ; Ram Bank für Position X High Byte wählen
    movf	INDF0,W             ; X Position High Byte laden
    call	Sende_W_Register    ; 
    incf	FSR0H,F             ; Ram Bank für Position Y Low Byte wählen
    movf	INDF0,W             ; Y Position Low Byte laden
    call	Sende_W_Register    ;
    incf	FSR0H,F             ; Ram Bank für Position Y High Byte wählen
    movf	INDF0,W             ; Y Position High Byte laden
    call	Sende_W_Register    ;
    incf	FSR0H,F             ; Ram Bank für Messwert Low Byte wählen
    movf	INDF0,W             ; Messwert Low Byte laden
    call	Sende_W_Register    ;
    incf	FSR0H,F             ; Ram Bank für Messwert High Byte wählen
    movf	  POSINC0,W             ; Messwert High Byte laden, !!! und gleich den Zähler eins hoch setzen
    call	Sende_W_Register    ;
    
    decfsz	TBLPTRL,F           ; Zähler -1, scip if zero (überspringe nächste Zeile wenn 0 rauskommt)
    goto	Sende_Schleife      ; Schleifen bis alle Messwerte gesendet wurden
    ; FAZIT: eigentlich ist das eine gute Idee, wie Du es gelöst hast.
    Ich denke mal die Hauptzeit geht eh in die Datenübertragung und nicht in der Code-Optimierung.
    So wünsche ich Dir noch ein schönes Wochenende.
    Siro

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