mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik PIC16F819 mit externem EEPROM


Autor: _Emsländer_ (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
ich habe ein Problem mit dem PIC16F819. Ich will mit dem PIC Daten über 
die SSP Schnittstelle (I2C) an ein externes EEPROM schicken und auslesen 
)alles in Assembler).
Die AN, die von Microchip angegeben werden (AN578, 554) habe ich 
gelesen, ich habe aber immer noch keine Ahnung, wie ich die 
Initialisierung oder die eigentliche Kommunikation machen soll.
Kennt jemand einen Link zu einen Code oder kann mir selber fertige 
Routinen zur Verfügung stellen?

Autor: Sven Stefan (stepp64) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
kannst ja mal meine Routinen probieren. Bei mir funktionieren die mit 
einem PIC16F886 und LM75 bzw. 24C256.

Definitionen:
; ***********   Macros definieren   *************
Bank0  macro
  bcf  STATUS,RP0  ;Bank 0
  bcf  STATUS,RP1
  endm

Bank1  macro
  bsf  STATUS,RP0  ;Bank 1
  bcf  STATUS,RP1
  endm

  constant  PIC_Takt  =.8000000
  constant  RS232_Takt  =.9600
  constant  I2C_Takt  =.100000
       
  constant  Wert_SSPADD  =PIC_Takt/(.4*I2C_Takt)-.1    ;100kHz = 8MHz/(4*(SSPADD+1))
  constant  Wert_SPBRG  =PIC_Takt/(.16*RS232_Takt)-.1   ;9,6kHz = 8MHz/(16*(SPBRG+1))


  constant  LM75_Adresse=0x90
  constant  sEPROM_Adresse=0xA0    ;I2C Adresse des seriellen EEPROMS (24C256)

Initialisierung
; I2C einschalten
  Bank1
  movlw  Wert_SSPADD ;8MHz/(4*(SSPADD+1)) = 400kHz
  movwf  SSPADD              
  bsf    SSPSTAT,SMP  ;keine Kontrolle der Signalanstiegszeiten

  Bank0
  movlw B'00001000' ;Master Mode
  movwf SSPCON              
  bsf   SSPCON,SSPEN ;MSSP-Modul einschalten
  call  i2c_idle

und die Routinen:
;***I2C UNTERPROGRAMME************************************************************
;
; I2C-Bus im Master-Mode übernehmen
; Warten bis MSSP-Modul frei ist
i2c_idle
  Bank1
  btfsc   SSPSTAT, R_W  ;läuft eine Übertragung?
  goto    $-1        ;ja, warten...
i2cidle_loop2
  movfw   SSPCON2      ;nein, läuft ein anderes Ereignis?
  andlw   0x1F            ;test auf ACKEN, RCEN, PEN, RSEN, SEN
  btfss   STATUS,Z    
  goto    i2cidle_loop2  ;ja, warten...
  Bank0
  return          ;MSSP Modul ist nicht beschäftigt

i2c_start
  call    i2c_idle    ;Bus frei?
    Bank1
    bsf     SSPCON2, SEN    ;Bus Übernahme anweisen und Startbit senden
    btfsc   SSPCON2, SEN  ;Auf das Ende der Startkondition warten
    goto    $-1
   Bank0
  return

;Restart aktivieren
i2c_rstart
    call    i2c_idle    ;Bus frei?
  Bank1
    bsf     SSPCON2, RSEN   ;Restart Sequence einleiten      
  btfsc   SSPCON2, RSEN
    goto  $-1
  Bank0
    return

;ein Byte aus W senden
;Rückgabewert in W: 0=ACK empfangen, 1=ACK nicht empfangen 
i2c_tx
  movwf  i2c_Puffer
    call    i2c_idle      ;Bus frei?
    bcf     PIR1, SSPIF     ;Lösche Interrupt Flag
  movfw  i2c_Puffer
    movwf   SSPBUF          ;Byte wird gesendet
    btfss   PIR1, SSPIF     ;Senden fertig?                
    goto  $-1

    Bank1
  btfss   SSPCON2, ACKSTAT ;Test ob ACK vom Slave empfangen wurde
  goto  i2c_tx_ack
  Bank0
    retlw   d'1'      ;ACK wurde nicht empfangen
i2c_tx_ack
  Bank0
    retlw   d'0'            ;ACK wurde empfangen

;ein Byte vom Slave empfangen ohne ACK
;Rückgabewert in W
i2c_rx
    call    i2c_idle
    bcf     PIR1,SSPIF    ;Interrupt Flag löschen
  Bank1                   
    bsf     SSPCON2, RCEN   ;Empfang einschalten
  Bank0     
  btfss   PIR1,SSPIF      ;Byte empfangen?
    goto  $-1        ;noch nicht

    Bank1
  bsf     SSPCON2, ACKDT  ;kein ACK senden (ACK=High)
    bsf     SSPCON2, ACKEN  ;sende negatives ACK
    btfsc   SSPCON2, ACKEN  ;fertig?
    goto    $-1
  Bank0
  movfw  SSPBUF      ;Empfangenen Wert nach W
    return

;ein Byte vom Slave empfangen mit ACK
;Rückgabewert in W
i2c_rx_ack
    call    i2c_idle
    bcf     PIR1,SSPIF    ;Interrupt Flag löschen
  Bank1
    bsf     SSPCON2, RCEN   ;Empfang einschalten
  Bank0     
  btfss   PIR1,SSPIF      ;Byte empfangen?
    goto  $-1        ;noch nicht

    Bank1
  bcf     SSPCON2, ACKDT  ;ACK senden
    bsf     SSPCON2, ACKEN
    btfsc   SSPCON2, ACKEN  ;fertig?
    goto    $-1
  Bank0
  movfw  SSPBUF      ;Empfangenen Wert nach W
    return

; I2C-Bus wieder freigeben
i2c_stop
    call    i2c_idle
  Bank1
    bsf     SSPCON2, PEN    ;Stop Bit senden und Bus frei geben
    btfsc   SSPCON2, PEN  ;fertig?
  goto  $-1
  Bank0
    return

Viel Spaß damit
Sven

Autor: _Emsländer_ (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke Sven!
Leider funkts das nicht ganz, werd aber versuchen den Code 
umzuschreiben. Der 16F819 hat nur ein SSPCON Register.
Aber ein dickes Danke!!!

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.