- MultiPlus Wechselrichter Insel und Nulleinspeisung Conrad         
Ergebnis 1 bis 10 von 30

Thema: I2C auf 16F876A klappt nicht

Hybrid-Darstellung

Vorheriger Beitrag Vorheriger Beitrag   Nächster Beitrag Nächster Beitrag
  1. #1
    Erfahrener Benutzer Begeisterter Techniker Avatar von Andre_S
    Registriert seit
    26.06.2005
    Beiträge
    365
    Hallo Christian,

    komme leider, da noch bis nächste Woche im Urlaub, nicht dazu es genauer zu prüfen, da hier am Ort einfach alles fehlt.
    Init habe ich mal geschaut, denke bist trotz errata deutlich unter 100 khz, da fehlen mir aber jetzt auch die Zugriffe auf die PDF's.
    Eventuell kannst Du ja etwas ausschließen, deshalb mal als Vergleich eine Auszug aus dem Quellcode der 16F876 Steuerung 4 Mhz (XT)

    - Init
    - 1 Byte schreiben
    - 10 Byte einzelnd lesen
    - I²C Unterprogramme

    Gruß André

    Code:
    ;*************************************************************************************************
    ;Clock 4 Mhz 16F876  (XT)
    
    #define Bank_0    bcf    STATUS,RP0
    #define Bank_1    bsf    STATUS,RP0
    
    ;*************************************************************************************************
    INIT
    ;PORT C initialisieren (RS232 TX als Ausgang)
                    bsf      STATUS,RP0            ; Bank 1
                    movlw    B'10111110'           ; Pin als Eingänge/Ausgänge 
                    movwf    TRISC
                    bcf      STATUS,RP0            ; Bank 0
                    clrf     PORTC                 ; Pin loeschen
    ;******* I²C Takt einstellen
                    Bank_1                
                    movlw    d'4'                  ; clock=4000/4*(7+1) ohne Errata
                    movwf    SSPADD                ; für I²C
                    Bank_0
    ;******* I²C Bus aktivieren und einschalten
                    movlw    B'00001000'           ; master Mode, clock=Fosc/(4*(SSPADD+1))
                    movwf    SSPCON
                    bsf      SSPCON,SSPEN          ; einschalten
    ;------------------------------------------------------------------------------------------------
    
    ;*************************************************************************
    MAIN
    
    ;********* 1 Byte Info auf I²C Speicher-Karte schreiben
    Info            clrwdt
                    call     i2c_on                ; I²C Bus übernehmen
                    movlw    b'10100000'           ; adressieren für Karte
                    call     i2c_tx                ; zum schreiben
                    movlw    d'0'
                    call     i2c_tx                ; high Adresse Speicherplatz
                    movlw    d'9'            
                    call     i2c_tx                ; low Adresse Speicherplatz
                    movlw    h'35'                 ; Merker für Karte voll
                    call     i2c_tx                ; low Adresse Speicherplatz
                    call     i2c_off               ; BUS freigeben
                    call     pause_02              ; fertig schreiben lassen (Pause 10ms - Karte)
                    return                    
    
    ;******** 10 Byte (einzelnd) von I²C Speicher-Karte lesen
    Info_holen      movlw    d'0'                 ; Byte 1 beginnen
                    movwf    z1
                    movlw    d'10'                ; 10 Byte lesen
                    movwf    z
                    movlw    0x20                 ; Adressierung wieder auf 20
                    movwf    FSR                  ; Index
    weiter_lesen    clrwdt                        ; Watch-Dog löschen
                    call     i2c_on               ; I²C Bus übernehmen
                    movlw    B'10100000'          ; zum schreiben adressieren
                    call     i2c_tx            
                    movlw    d'0'                 ; high Teil Adresse
                    call     i2c_tx               ; senden
                    movfw    z1                   ; low Teil Adresse
                    call     i2c_tx               ; senden
                    call     i2c_off              ; BUS freigeben
                    call     i2c_on               ; Bus wieder übernehmen
                    movlw    B'10100001'          ; zum lesen adressieren
                    call     i2c_tx
                    call     i2c_rx               ; Byte lesen
                    bcf      STATUS,IRP           ; bit für Bank 1 und 0 bei FSR
                    movwf    INDF                 ; sichern in adresse
                    call     i2c_off                 ; BUS freigeben
                    decfsz   z,1                  ; schon 10 byte gelesen
                    goto     ww_1
                    goto     absprung             ; -> ja weiter
    ww_1            incf     FSR,1                ; erhöhe Indexzeiger
                    incf     z1,1                 ; erhöhe low Adresse von Karte
                    goto     weiter_lesen
    
    absprung        movfw    ...
    
    ;----------------------------------------------------------------------------------------------
    
    
    ;*************************************************************************************
    ;******** I²C-Bus übernehmen
    i2c_on          bcf      PIR1,SSPIF            ; SSPIF BIT löschen
                    bsf      STATUS,RP0
                    bsf      SSPCON2,SEN           ; Bus übernehmen anweisen    
                    bcf      STATUS,RP0
    ok_1            btfss    PIR1,SSPIF            ; Testen ob BUS schon übernommen
                    goto     ok_1
                    bcf      PIR1,SSPIF            ; ja der Bus ist übernommen
                    return
    
    ;******** I²C-BUS freigeben
    i2c_off         bsf      STATUS,RP0
                    bsf      SSPCON2,PEN           ; Busfreigabe anweisen
                    bcf      STATUS,RP0
    ok_2            btfss    PIR1,SSPIF            ; Bus schon frei
                    goto     ok_2                  ; nochmal
                    bcf      PIR1,SSPIF            ; ja alles OK
                    return                         ; Rücksprung ohne Fehler
    
    ;******** I²C-Bus senden
    i2c_tx          movwf    SSPBUF                ; -> zum Slave übertragen
    ok_3            btfss    PIR1,SSPIF            ; ACK schon empfangen
                    goto     ok_3                  ; nein noch nicht
                    bcf      PIR1,SSPIF            ; ja, nun rücksetzen
                    return
    
    ;******** I²C-Bus empfangen
    i2c_rx          bsf      STATUS,RP0        
                    bsf      SSPCON2,RCEN          ; Datenempfang einschalten
                    bcf      STATUS,RP0
    ok_4            btfss    PIR1,SSPIF            ; Datenempfang fertig?
                    goto     ok_4                  ; nein noch nicht
                    bcf      PIR1,SSPIF            ; ja, noch zurücksetzen
                    movfw    SSPBUF                ; Empfangsregister lesen
                    return

  2. #2
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    02.09.2009
    Ort
    Berlin (Mariendorf)
    Beiträge
    1.023
    @witkatz
    Das Programm durchläuft - den LCD-Anzeigen nach zu urteilen - den ganzen Vorspann, landet in der Hauptschleife und zeigt auch den pro Schleifendurchlauf sich erhöhenden Zähler 'loopcount' an. Lediglich die scheinbar von I2C gelesenen Zeichen sind hartnäckig 0xFF.
    Im Augenblick - mit der geposteten Initalisierung - hängt es sich gar nicht auf. In manchen Situationen (fragt mich nicht, wovon das abhängt: experimentelle Codevariationen, Luftdruck ...) läuft das Programm bisweilen nur 3x, 7x, 84x ... durch die Hauptschleife, bevor es steckenbleibt.

    Programmtechnisch kommen in der Hauptschleife als Bremskeile eigentlich nur in Frage:
    - die Abfragen auf die Vollendung von Busaktivitäten des Masters (ziemlich unplausibel, da nur vom Baud Rate Generator abhängig)
    - die ausbleibenden Reaktionen des Slave
    Maßgeblich für das Eintreten dieser Ereignisse ist das Interruptbit SSPIF.

    @Andre_S
    Danke für deinen Codeextrakt. Ich habe ihn mit meinen Werken verglichen, soweit das wegen der unterschiedlichen Strukturierung überschaubar war. In den wesentlichen Passagen könnte ich glatt von Dir abgeschrieben haben. Aus meiner Sicht also kein Fortschritt - allerdings wird man mit der Zeit ja auch betriebsblind für die selbst programmierten Fehler...

    An dieser Stelle wäre es bestimmt aufschlussreich, mit einem DSO den gesamten Verlauf auf SLC und SDA anzusehen; auf dem analogen Oszi sehe ich vermutlich nur den Havaristen, nicht aber das Riff.

  3. #3
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    27.08.2013
    Ort
    Region Basel
    Alter
    67
    Beiträge
    2.435
    Hallo,

    Zitat Zitat von RoboHolIC Beitrag anzeigen
    Das Programm durchläuft - den LCD-Anzeigen nach zu urteilen - den ganzen Vorspann, landet in der Hauptschleife und zeigt auch den pro Schleifendurchlauf sich erhöhenden Zähler 'loopcount' an. Lediglich die scheinbar von I2C gelesenen Zeichen sind hartnäckig 0xFF.
    Im Augenblick - mit der geposteten Initalisierung - hängt es sich gar nicht auf. In manchen Situationen (fragt mich nicht, wovon das abhängt: experimentelle Codevariationen, Luftdruck ...) läuft das Programm bisweilen nur 3x, 7x, 84x ... durch die Hauptschleife, bevor es steckenbleibt.
    Das sieht nach Störungen aus. Liegt dann am konkreten Aufbau.

    MfG Peter(TOO)
    Manchmal frage ich mich, wieso meine Generation Geräte ohne Simulation entwickeln konnte?

  4. #4
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    02.09.2009
    Ort
    Berlin (Mariendorf)
    Beiträge
    1.023
    Zitat Zitat von Peter(TOO) Beitrag anzeigen
    Das sieht nach Störungen aus. Liegt dann am konkreten Aufbau.
    Das ist allmählich auch mein Verdacht. Die Software wurde hier ja von vielen Seiten erfolglos beleuchtet und mit funktionierendem Code verglichen.
    Was wie ein Hardwaredefekt oder Programmierfehler aussieht, ist vielleicht doch "nur" ein blockierter Bus bzw. wartender Master aufgrund einer einzigen elektrischen Störung, die nicht so leicht dingfest zu machen ist.

    Wie bereits angedeutet hängt vom Ausgang dieses Threads nicht Erfolg oder Scheitern eines Projekts ab. Daher würde ich ihn jetzt gerne beenden.
    Vielen Dank nochmals Euch allen, die Ihr Euch intensiv um eine Lösung bemüht habt!

    Christian.

  5. #5
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    27.08.2013
    Ort
    Region Basel
    Alter
    67
    Beiträge
    2.435
    Hallo Christian,
    Zitat Zitat von RoboHolIC Beitrag anzeigen
    Wie bereits angedeutet hängt vom Ausgang dieses Threads nicht Erfolg oder Scheitern eines Projekts ab. Daher würde ich ihn jetzt gerne beenden.
    Allerdings würde eine Lösung des Problems dazu führen, dass du den selben Fehler in Zukunft nicht mehr machst!

    Genau dies ist ein Teil des Profi-Wissens, wenn man weiss wie es nicht geht und, vor allem, warum es so nicht geht.

    Du solltest vor allem die Führung der Masseleitungen unter die Lupe nehmen und auch nicht zu wenige Abblockkondensatoren verwenden.

    Vor rund 40 Jahren habe ich Logikschaltungen für 60MHz entwickelt.
    Heute gewinnt man damit keinen Blumentopf mehr, aber damals ging dies nur mit der 74Sxx TTL-Familie oder ECL. Damalige µP liefen noch typischerweise mit rund 1MHz und schnelle ROMs und SRAMs hatten Zugriffszeiten von 450ns (Die langsamen lagen knapp unter 1µs).
    Die damals gemachten Erfahrungen, und damit erlerntes Wissen, bringen mir aber auch heute noch oft Vorteile wenn es Probleme gibt.


    MfG Peter(TOO)
    Manchmal frage ich mich, wieso meine Generation Geräte ohne Simulation entwickeln konnte?

  6. #6
    Erfahrener Benutzer Lebende Robotik Legende Avatar von PICture
    Registriert seit
    10.10.2005
    Ort
    Freyung bei Passau in Bayern
    Alter
    73
    Beiträge
    11.077
    Hallo!

    @ RoboHolIC

    Ändern von verwendeten µC habe ich immer in funktionierender Hardware (HW) mit einstecken des per Adapter umsockelnden µC angefangen. Ich kenne deshalb keine Probleme mit Wechseln vom µC für vorher richtig funktionierende HW.
    MfG (Mit feinem Grübeln) Wir unterstützen dich bei deinen Projekten, aber wir entwickeln sie nicht für dich. (radbruch) "Irgendwas" geht "irgendwie" immer...(Rabenauge) Machs - und berichte.(oberallgeier) Man weißt wie, aber nie warum. Gut zu wissen, was man nicht weiß. Zuerst messen, danach fragen. Was heute geht, wurde gestern gebastelt. http://www.youtube.com/watch?v=qOAnVO3y2u8 Danke!

  7. #7
    Erfahrener Benutzer Begeisterter Techniker Avatar von Andre_S
    Registriert seit
    26.06.2005
    Beiträge
    365
    Hallo Christian,

    sorry,… es sei mir gegönnt, auch wenn Du das Thema abschließen möchtest, noch einen letzten Hinweis zu geben!
    Du hast recht, in weiten Teilen sind die Sequenzen ähnlich. Ich kenne auch Deinen zu lesenden Sensor nicht, scheinbar hat dieser keine low/high Adressierung wie mein Beispiel, aber das ist nicht das Problem.
    Was mir aber aufgefallen ist und ich zumindest bei meinen I²C Baugruppen so nicht kenne, ist der Ablauf des Auslesens. Da fehlt mir die Stopp Bedingung, also die erneute Freigabe des Busses beim Lesen von Informationen.
    Ich habe aber nur mal eine Ausleseroutine von Deinem Beispiel (Protokollzyklus: Accelerometer auslesen) „versucht“ durchzugehen und ich hoffe ich habe nichts übersehen oder es ist bei Deinem Sensor eventuell nicht notwendig,… dann Sorry für die Verwirrung.


    • Bus übernehmen
    • zum schreiben Adressieren
    • zu lesende Adresse(n) senden
    • Bus wieder freigeben
    • Bus erneut übernehmen
    • Zum Lesen adressieren
    • Byte lesen


    Gruß André

  8. #8
    Erfahrener Benutzer Robotik Visionär Avatar von oberallgeier
    Registriert seit
    01.09.2007
    Ort
    Oberallgäu
    Beiträge
    8.694
    Zitat Zitat von Peter(TOO) Beitrag anzeigen
    .. Genau dies ist ein Teil des Profi-Wissens, wenn man weiss wie es nicht geht und, vor allem, warum es so nicht geht ..
    OT:
    Zitat Zitat von Platon, in Politei: ca. 390 bis ca. 370 v. Chr
    Ein guter Bäcker ist aber wohl nicht der, der gute Brötchen bäckt. Ein guter Bäcker ist einer, der weiß wie man schlechte Brötchen bäckt und doch gute macht . . .

    - - -
    Zitat Zitat von Andre_S Beitrag anzeigen
    ...
    • zu lesende Adresse(n) senden
    • Bus wieder freigeben
    • Bus erneut übernehmen
    • Zum Lesen adressieren
    • Byte lesen
    Darüber bin ich viele Tage lang gestolpert :-/
    Ciao sagt der JoeamBerg

  9. #9
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    02.09.2009
    Ort
    Berlin (Mariendorf)
    Beiträge
    1.023
    Hallo Ihr lieben Helfer.

    Zuerst das Wichtigste: Mein Code funktioniert jetzt !
    Der Lorbeerkranz dafür gebührt Andre_S mit seinem zutreffenden Hinweis auf den möglicherweise fehlenden STOP-Befehl.
    Mein anfänglicher Code für den BMA020 passte tatsächlich nicht zur Spezifikation des Bausteins.

    Aber warum ist das nicht schon früher aufgefallen??
    Es klingt absurd, aber ich habe es soeben verifiziert: Auf zwei Eigenbauten mit PIC16F886-Controllern funktioniert der I2C-Code tatsächlich auch ohne das zwischengeschaltete STOP-Signal.
    Auf dem hier behandelten PIC16F876A-System hingegen klappt es nur mit diesem STOP.

    Zur Bestätigung habe ich den existierenden Code für einen anderen Chip (eine RTC: PCF8583) in die PIC16F876A-Software eingebaut - auch hier die bekannte Blockierung.
    Gezielte Suche - es fehlte das STOP an der entsprechenden Stelle. STOP eingefügt - und schon lief auch dieser Baustein. Vermutlich hatte ich den zunächst folgenlos bleibenden Fehler bereits früher vom PCF8583-Code in den BMA020-Code übernommen.

    Nochmals herzlichen Dank an alle!
    Christian.

    P.S.: Nein, ich denke nicht im Traum daran, zu erforschen, warum der '886 ohne dieses STOP-Signal auskommt ...

Ähnliche Themen

  1. RP6 (M32) -- ISP klappt nicht ?!?
    Von AsuroPhilip im Forum Robby RP6
    Antworten: 3
    Letzter Beitrag: 24.03.2012, 05:53
  2. SPI klappt nicht
    Von p_mork im Forum Assembler-Programmierung
    Antworten: 0
    Letzter Beitrag: 22.04.2007, 13:10
  3. I2C Slave klappt nicht
    Von p_mork im Forum C - Programmierung (GCC u.a.)
    Antworten: 2
    Letzter Beitrag: 17.01.2007, 20:20
  4. suche 16F876A.inc Datei
    Von HoStAn im Forum PIC Controller
    Antworten: 2
    Letzter Beitrag: 06.09.2006, 10:39
  5. I2C klappt bei mir nicht
    Von Matthias Mikysek im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 14
    Letzter Beitrag: 16.02.2005, 06:27

Berechtigungen

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

Solar Speicher und Akkus Tests