-         

Seite 1 von 2 12 LetzteLetzte
Ergebnis 1 bis 10 von 20

Thema: Externes EEPROM am PIC16F877A Codeproblem

  1. #1
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    19.11.2007
    Alter
    33
    Beiträge
    140

    Externes EEPROM am PIC16F877A Codeproblem

    Anzeige

    SMARTPHONES & TABLETS-bis zu 77% RABATT-Kostenlose Lieferung-Aktuell | Cool | Unentbehrlich
    Servus,

    also auf meinem Testboard ist ein externes EEPROM 24LC256 und dieses würde ich gerne absprechen(PIC16F877A). Also ich würde gerne Daten draufschreiben und diese dann auch wieder auslesen.
    Ich habe im Democode auch folgenden Code in asm gefunden.
    Code:
    write_eeprom	
    	banksel	SSPCON2			;write to EEPROM
    	bsf	SSPCON2,SEN		;start bit
    	btfsc	SSPCON2,SEN
    	goto	$-1	
    	movlw	B'10100000'		;send control byte (write)
    	banksel	SSPBUF	
    	movwf	SSPBUF
    	call	ssprw
    	banksel	SSPCON2
    	btfsc	SSPCON2,ACKSTAT		;ack?
    	goto	$-1
    
    	movlw	0x00			;send slave address HIGH byte
    	banksel	SSPBUF
    	movwf	SSPBUF
    	call	ssprw
    	banksel	SSPCON2
    	btfsc	SSPCON2,ACKSTAT		;ack?
    	goto	$-1
    
    	movlw	0x05			;send slave address LOW byte(0x0005)
    	banksel	SSPBUF
    	movwf	SSPBUF
    	call	ssprw
    	banksel	SSPCON2
    	btfsc	SSPCON2,ACKSTAT		;ack?
    	goto	$-1
    
    	banksel	temperature
    	movf	temperature,w		;send slave DATA = temperature
    	movwf	SSPBUF
    	call	ssprw
    	banksel	SSPCON2
    	btfsc	SSPCON2,ACKSTAT		;ack?
    	goto	$-1
    
    	bsf	SSPCON2,PEN		;stop bit
    	btfsc	SSPCON2,PEN
    	goto	$-1
    		
    	banksel	TMR1L
    	bcf	PIR1,TMR1IF		;clear TIMER1 overflow flag
    	clrf	TMR1L			;clear registers for next overflow
    	clrf	TMR1H
    
    	return
    ;------------------------ IDLE MODULE -------------------------------------
    ssprw					;check for idle SSP module 
    	movlw	0x00
    	banksel	SSPCON2
    	andwf	SSPCON2,w
    	sublw	0x00
    	btfss	STATUS,Z
    	goto	$-4
    
    	btfsc	SSPSTAT,R_W
    	goto	$-1
    	return

    Aber leider funktioniert die ganze Geschichte nicht. Und da ich davon nicht all zu viel Ahnung habe, brauche ich nun Hilfe.
    Hat irgendwer einen Beispielcode, der funzt?

    Danke

    Gruß

  2. #2
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    19.11.2007
    Alter
    33
    Beiträge
    140
    Noch eine weitere Frage, wie lese ich das ganze wieder aus?

  3. #3
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    26.05.2007
    Beiträge
    191
    Hallo,
    wenn du nicht weist wie man das ausliest, woher weist du dann das das Schreiben nicht geht? Das Auslesen geht folgendermaßen: Du sendest das Controlbyte mit Bit 0 = 0 (Bit 0 = 1 bedeutet lesen, Bit 0 = 0 bedeutet schreiben), anschließend die Adresse (High- und Lowteil), daraufhin ein Restart (gibts beim MSSP-Modul ein Bit; SSPCON2,RSEN), dann wieder das Controlbyte mit Bit 0 = 1 (=lesen) und dann liest du die Daten Byte für Byte (mit SSPCON2,RCEN wird ein Byte eingelesen, nach jedem Byte Acknowledge senden bcf SSPCON2,ACKDT und dann bsf SSPCON2,ACKEN), wenn du keine weiteren Daten mehr einlesen möchtest sendest du statt Acknowlede ein NotAcknowledge (bsf SSPCON2,ACKDT und dann bsf SSPCON2,ACKEN).
    Gruß,
    Michael

    PS: Entschuldigt den Schreibstil aber ich habe heute 11h gelötet.

  4. #4
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    19.11.2007
    Alter
    33
    Beiträge
    140
    Guten Morgen,

    also ich mein Oszi wahlweise an an der Daten und Wahlweise an der Clock Leitung. Aber ich sehe einfach kein Signal. Selbst, wenn ich die Frequenz runter schraube.... also ich habe einen 4 MHz Quarz dran, was ja bedeutet, dass diese intern mit 1Mhz arbeitet, was wiederum die oberste Grenze für den EEPROM ist. Aber es tut net...

  5. #5
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    26.05.2007
    Beiträge
    191
    Hallo,
    wie hast du das MSSP-Modul initialisiert? Bei mir läuft der Bus mit 100kHz. Dazu schreibe ich ins Register SSPCON 28h und in SSPADD 31h für 100kHz bei 20MHz. Außerdem müssen PORTC.3 und .4 auf Eingang stehen.
    Gruß,
    Michael

  6. #6
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    19.11.2007
    Alter
    33
    Beiträge
    140
    Servus,

    also irgendwie ist der Bereich der PIC schwach frequentiert. Ich habe nach wie vor das Problem mit dem EEPROM.

    Ich habe mich jetzt noch mal im Detail mit I2C Programmierung auseinander gesetzt und bin bei sprut fündig geworden und versuche das Beispiel mit dem EEPROM umzusetzen, doch auch das mag nicht so recht klappen!

    Code:
    EPPROM_INIT
    ; einstellen von RC3 & RC4 auf input 
        bsf     STATUS, RP0         ; Bank 1 
        movlw   B'00011000'         ; RC3,4 inputs 
        iorwf   TRISC, f            ; + RC2=CCP1 output 
        bcf     STATUS, RP0         ; Bank 0 
    ;bcf			PORTC,3
    ;bcf			PORTC,4
    
    
    ; einstellen des I2C-Taktes auf knapp 400 kHz 
        bsf     STATUS, RP0         ; Bank 1 
        movlw   d'9'                ; clock = 4MHz/(4*(9+1)) = 100kHz 
        movwf   SSPADD              ; für I2C 
        bcf     STATUS, RP0         ; Bank 0 
    
    	movlw   B'00001000'         ; master mode, clock=Fosc/(4*(SSPADD+1)) 
        movwf   SSPCON              ; 
    	bsf     SSPCON, SSPEN       ; MSSP-Modul enable
    
    
    
    EEPROM_SCHREIBEN
    ;**Schreibe Wert 5 auf Speicher-Adresse 3 in 24C04************* 
            call    i2c_on          ; Bus aktiv 
            movlw   H'A0'           ; 1010 0000 
            call    i2c_tx          ; 24C04 zum Schreiben adressieren 
    
            movlw   0x00            ; high Teil der Adresse (Page) 
            call    i2c_tx 
            movlw   0x03            ; low Teil der  Adresse 
            call    i2c_tx 
    
            movlw   0x05            ; Wert der auf Adresse 3 soll 
            call    i2c_tx 
    
            call    i2c_off         ; Bus freigeben 
    ; Fertig. Nun beginnt im EEPROM ein Lösch-Schreib-Zyklus 
    ; mit dem der Wert 5 in die EEPROM-Zelle 3 geschrieben wird. 
    ; Das wird etwa 10 ms dauern. Solange ist der 24C04 nicht ansprechbar. 
    ; 
     ;       ....                    ; das Programm geht dann irgentwie weiter 
    EEPROM_LESEN  
     ;**Stelle EEPROM auf Speicher-Adresse 3 ein************* 
            call    i2c_on          ; Bus aktiv 
            movlw   H'A0'           ; 1010 0000 
            call    i2c_tx          ; 24C04 zum Schreiben adressieren 
    
            movlw   0x00            ; high Teil der Adresse 
            call    i2c_tx 
            movlw   0x03            ; low Teil der  Adresse 
            call    i2c_tx 
    
            call    i2c_off         ; Bus freigeben 
    
    ;Nun steht der Adress-Pointer im 24C04 auf dem Wert 3. 
    ;Nun können wir den I2C-Bus erneut aktivieren, um ein Byte aus dem 24C04 zu lesen. Das ist unser Datenbyte. 
    
    ;**Lesen des aktuellen Bytes aus 24C04************* 
            call    i2c_on          ; Bus aktiv 
    
            movlw   H'A0'           ; 1010 0001 
            call    i2c_tx          ; 24C04 zum lesen adressieren 
    
            call    i2c_rx 
            movfw   SSPBUF          ; I2C Empfangsregister auslesen 
            movwf   DATENPUFFER     ; Byte in Speicherzelle Datenpuffer retten 
    
            call    i2c_off         ; Bus freigeben
     
    
    ;***I2C UNTERPROGRAMME************************************************************ 
    ; 
    ; I2C-Bus im Master-Mode übernehmen 
    i2c_on  bcf     PIR1, SSPIF     ; SSPIF Bit löschen 
            bsf     STATUS, RP0 
            bsf     SSPCON2, SEN    ; Bus Übernahme anweisen 
            bcf     STATUS, RP0 
            goto    i2c_warte 
    
    ; ein Byte aus W senden 
    i2c_tx 
            movwf   SSPBUF          ; -> zum I2C-Slave übertragen 
            goto    i2c_warte 
    
    ;ein Byte vom Slave empfangen (nach SSPBUF) 
    i2c_rx 
            bsf     STATUS, RP0 
            bsf     SSPCON2, RCEN   ; Daten Empfang einschalten 
            bcf     STATUS, RP0 
            goto    i2c_warte 
    
    ; I2C-Bus wieder freigeben 
    i2c_off 
            bsf     STATUS, RP0 
            bsf     SSPCON2, PEN    ; Bus Freigabe anweisen 
            bcf     STATUS, RP0 
    
    i2c_warte 
            btfss   PIR1, SSPIF     ; fertig? 
            goto    i2c_warte       ; nein, noch nicht 
            bcf     PIR1, SSPIF     ; ja, alles fertig, nun noch SSPIF zurücksetzen 
            return 
    
    ;***ENDE UNTERPROGRAMME**********************************************************
     
    
    
    
    
    
    ; End of I2C routines
    Das ist der Code von der Seite, den ich versuche zum laufen zu bekommen. Dort wird die Initialisierung genauso gemacht, wie ich das in meinem Code mache.
    Mein Problem ist, dass ich gleich bei der Aktivierung des Busses im Unterprogramm (voriger durchlauf von i2c_on) i2c_warte hängen bleibe und sich der PIC dann totläuft, wenn er das setzen von SSPIF wartet.
    Jemand ne Idee?

    Gruß und Danke

  7. #7
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    26.05.2007
    Beiträge
    191
    Hallo,
    ja die PICs sind hier in der Minderheit. Dein Problem klingt nach vergessenen Pullup-Widerständen. Können die EEPROMs wirklich 400kHz? Ich bin mir momentan nicht sicher. Mess einfach mal die Spannung an PortC.3 und .4, dort müssten eigentlich 5V anliegen. Wenn dem nicht so ist könnte ein Reset (Power-On-Reset) des Speicherbausteins nicht schaden.
    Gruß,
    Michael

  8. #8
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    19.11.2007
    Alter
    33
    Beiträge
    140
    Servus,

    ja der 24LC256 kann 400 kHz aber ich Takte mit nur 100kHz

  9. #9
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    19.11.2007
    Alter
    33
    Beiträge
    140
    Achja und die Widerstände sind selbstverständlich auch vorhanden

  10. #10
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    26.05.2007
    Beiträge
    191
    Hallo,
    ich habe mir jetzt mal den Code (von Sprut) im Detail angesehen. Das Einzige was mir auffällt ist ein Fehelr in der Zeile

    movlw H'A0' ; 1010 0001

    beim Lesen des aktuellen Bytes. Im Kommentar steht der Wert richtig drin, vorne aber nicht (H'A1' statt H'A0').

    Wenn der PIC den Bus garnicht erst übernehmen kann stimmt normalerweise was mit den Pegeln an den Busleitungen nicht. Mess also bitte mal mit einem Multimeter die 5V nach. Wenn man den Bus nämlich abschießt kann es vorkommen dass eine oder beide Leitungen dauerhaft auf LOW liegen.

    Ich habe soeben das Programm in einen 16F877 geladen, es läuft einwandfrei. Ich habe nur zwei Wartezeiten und ein paar nops zum Debuggen eingefügt. Die Adresse des EEPROMS (24C512) ist bei mir 0A4h.

    Gruß,
    Michael
    Angehängte Dateien Angehängte Dateien

Seite 1 von 2 12 LetzteLetzte

Berechtigungen

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