Ich habe in meinem Projekt die TWI Schnittstelle verwendet, in der ISR lese ich die Daten ein, nur habe ich das Problem, falls ich z.B. 3 Packete über die I2C-Schnittstelle gleich hintereinander bekomme, kann ich mur auf das erste reagieren. Ich möchte aber, nach dem ich ein STOP erhalten habe eine Funktion aufrufen, abarbeiten und dann wieder die nächsten Pakete empfangen. Wie kann ich solange die Clockleitung halten, als Slave?
Wenn Du uns sagst welchen µC du verwendest könnte wir Dir evtl. mehr helfen, aber ansonsten bietet Atmel im (vollständigen) Datenblatt von dem ATMega32 eine reine Softwarelösung,. grüüüße
Der "klassische" Ansatz ist ein Jobflag+Puffer: die ISR empfängt ein ganzes Paket und setzt, sobald eins da ist, eine Variable/ein Bit (Flag), die Main loop fragt das Bit regelmäßig ab, und ruft die Funktion auf, wenn das flag gesetzt ist (auch in den Atmel appnotes zu TWi wird das so gemacht). Wieso willst du die Clock-Leitung halten??? (Dann kommt ja auch keine stop-condition, weil der Bus blockiert ist) Wenn dein Slave signalisieren soll, dass er beschäftigt ist, antwortet er einfach nicht auf seine Adresse. hth. Jörg ps.: bei AVRs wird die Clock-Leitung immer auf Low gehalten, wenn das TWINT-Bit gesetzt ist ...
Ich verwende einen Atmega. Die Softwareschnittstelle kann ich jetzt nicht mehr nehmen, da die Hardware bereits steht (will ich auch nicht). Zu dem TWI Slave habe ich glaub ich hier was gefunden und angepasst. Soweit funktioniert das ganze, bloss wenn mehrere Pakete direkt hintereinander ankommen, wird das zweite immer ignoriert. Ich müsste praktisch die SCL Leitung auf low halten, was man theoretisch mit dem TWINT Flag machen kann, das klappt aber nicht. Hier ist das problematische Stück vom Code
1 | case TW_SR_STOP: // 0xA0 STOP empfangen |
2 | rx_ready = 0x01; |
3 | tx_ready = 0x01; |
4 | i2c_busy = 0x00; |
5 | buffer_adr = 0xFF; |
6 | |
7 | TWCR |= (1<<TWINT); |
8 | printf("\r\n"); |
9 | for(i=0; i< 32; i++) |
10 | {
|
11 | printf("x0%X ", rxbuffer[i]); |
12 | TWCR |= (1<<TWINT); |
13 | }
|
14 | transform_i2c_to_para(); |
15 | TWCR &= ~(1<<TWINT); |
TWCR |= (1<<TWINT); Hiermit will ich SCL low time stretchen, um diese Funktion "transform_i2c_to_para()" problemlos ausführen zu können.
> TWCR |= (1<<TWINT); damit löschst du das flag! Wie die allermeisten AVR-Interruptflags, wird das TWINT mit einer 1 gelöscht. Um das Flag gesetzt zu lassen, brauchst du einfach NICHTs zu tun, weil das Flag gesetzt ist, wenn die ISR läuft. Wenn der Slave NACH der Stop-Condition warten soll, lösche einfach das TWEA-Bit, und setze es sobald der Slave wieder ansprechbar ist. Der Master muss dann eben pollen, d.h. solange die Slave-addresse senden, bis der Slave antwortet. hth. Jörg
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.