Hallo, seit einigen Tage komme ich nun leider nicht mehr weiter und hoffe, dass ihr mir helfen könnt. Ich habe ein PIC18 Experimentierboard, ein PicKit2 und ein MGC3130 Board von Microchip. Mit meinem PIC18 möchte ich gerne die I2C Datenübertragung auf dem MGC3130 Board mitlesen. Dafür ist auch extra eine I2C Schnittstelle auf dem Board angebracht. Hierzu habe ich mit zwei Adern von einem Flachbandkabel, keine 10 cm lang, das PIC Experimentierboard mit dem MGC3130 Board verbunden. SCL kommt bei meinem PIC auf den External Interrupt INT0 Pin und SDA kommt bei meinem PIC auf den External Interrupt INT1 Eingang. Der Pic18 verfügt zwar über ein I2C Modul, welches ich jedoch bewusst nicht nutzen möchte, da dann das einfache Mitlesen der I2C Verbindung wegen der gleichen Slave Adresse, dem R/W Bit und dem ACK Bit nicht so einfach möglich ist. (Auf dem MGC3130 Board kommuniziert der MGC3130(Slave) mit einem Master). Deshalb habe ich die beiden Leitungen auf external Interrupteingänge gelegt. Im C - Code passiert bei mir folgendes : 1. INT1 SDA reagiert auf fallende Flanken 2. Warten auf eine fallende Flanke am SDA Eingang 3. Fallende Flanke am SDA Eingang kommt : SCL Pin High ? 4. JA SCL ist High --> Startbedinung. 5. Der INT1 Interrupt wird deaktiviert und INT0 hingegen aktiviert mit steigender Flanke. 6. Bei jeder SCL steigenden Flanke wird nun SDA auf HIgh oder Low abgefragt und dementsprechend ein Bit in buffer[20] gesetzt. 7. Nach 20 EInträgen werden alle Interrupts abgeschaltet. Das Problem ist nun aber, dass ständig falsche Werte in meinem Buffer stehen. Die I2C Adresse kommt ja nach der Startbedinung als erstes. Die ist 0x42 also 1000010 aber in meinem Buffer steht bei jedem Versuch etwas anderes drin ? Kommt ihr mir bitte weiterhelfen ? Ich hänge mal meinen C code an und ein Bild, dass ich von meinem Oszi
Gerade zu dem was ich sage nicht ganz sicher, da ich den PIC den du verwendest nicht kenne, aber: Laut deinem Code läuft der PIC mit 20 MHz. Bedeutet, der PIC braucht: (1 / 20MHz) * 4 = 200ns um einen Befehl auszuführen, welcher einen Maschinenzyklus braucht. Laut deinem KO Bild sendet dein I2C mit einer Frequenz con 370KHz (Vermute mal, I2C läuft bei dir im Fast Mode, also 400 KHz?) Heisst, du kriegst alle: 1 / 400KHz = 2,5 us eine neue Flanke. 2,5 us / 200ns = 12,5 Heisst, du kannst gerade mal 12 Befehle ausführen, bis die nächste Flanke eintrifft. Ich habe sowas wie du hier probierst zwar noch nie gemacht, bin mir auch absolut nicht sicher über meine Antwort, aber spontan würde ich sagen: Der PIC ist zu langsam und daran scheitert es.
Vielen Dank, du hast Recht. Habe das soeben mit meinem Oszilloskop überprüft. Alleine einen High/Low Pegel abzufragen und diesen anschließend in einem Buffer zu speichern, dauert auf meinem Controller in C fast 10us.
T.Gxxxx schrieb: > Vielen Dank, du hast Recht. > Habe das soeben mit meinem Oszilloskop überprüft. > > Alleine einen High/Low Pegel abzufragen und diesen anschließend in einem > Buffer zu speichern, dauert auf meinem Controller in C fast 10us. Hallo, dein Problem ist nicht, dass der Controller zu langsam wäre, sondern die Interrupt Latency. Bevor dein Controller in die ISR geht, muss erst einmal der ganze Käse aus den Registern weggespeichert werden etc etc. Das dauert. Wie lange steht im Datenblatt, aber sicher mal >10 Taktzyklen, eher viel mehr. Zu schaffen ist das trotzdem: Du wirst es vermutlich hinbekommen, wenn du das Startbit als "Trigger" verwendest und dann in die Empfangsroutine springst. Den Interrupt muss man dann abschalten. Wenn du in deiner Empfangsroutine bleibst, schafft der PIC das leicht. In der Empfangsroutine darfst du dich aber nicht unterbrechen lassen (Interrupts aus).
Somebody123 schrieb: > Bevor dein Controller in die ISR geht, muss erst einmal der ganze Käse > aus den Registern weggespeichert werden etc etc. Das dauert. Wie lange > steht im Datenblatt, aber sicher mal >10 Taktzyklen, eher viel mehr. Stimmt. Die Speicherung des Workregisters und des Statusregisters beanspruchen auch noch einmal ein paar Zyklen für sich, daran habe ich garnicht mehr gedacht. Denke aber auch ohne Interrupt wird das ganze sehr schwierig, da ich denke dass meine Berechnung oben korrekt ist. Wird schon relativ schwer mit 12 Maschinenzyklen da was anständiges zu schreiben. Denke, in Assembler würde man es evt. mit einer guten Lösung noch knapp hinkriegen, in C wohl kaum eine Chance, da der Code wirklich auf ein Minimum reduziert werden muss..
T.Gxxxx schrieb: > Mit meinem PIC18 möchte ich gerne die I2C Datenübertragung auf dem > MGC3130 Board mitlesen. Und was soll das ganze? Kann man dafür nicht einfach einen fertigen I2C-Logger für 10..12€ nehmen, der die Daten auf den PC streamt?
Somebody123 schrieb: > Bevor dein Controller in die ISR geht, muss erst einmal der ganze Käse > aus den Registern weggespeichert werden etc etc. Das dauert. Das war mal so (Mid-Range-Core). Bei den PIC18er sieht es anders aus: > 9.9 Context Saving During Interrupts > During interrupts, the return PC address is saved on > the stack. Additionally, the WREG, STATUS and BSR > registers are saved on the Fast Return Stack. Siehe: 5.1.3 FAST REGISTER STACK
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.
