Hallo! Bin gerade dabei ein TWI auf meinem ATMEGA168 zu programmieren. Nun hab ich schon ausprobiert ob er mit dem anderen Prozessor kommuniziert, was er leider nicht macht. Am oszilloskop bekomm ich nur eine Start- Flanke. Da ich nur das STK500 verwende zum draufprogrammieren verwend ich nur den Simulator um ein paar Sachen zu testen. Hab also im Simulator das TWI Programm, zumindest den Anfang, getestet. Was mir dabei aufgefallen is, dass er bei meiner Start Routine das TWINT Flag nicht setzt obwohl ich es gesetzt habe. Kann das der Grund sein? Und wie kann ich es dazu bringen es zu setzen? ldi temp,(1<<TWINT)|(1<<TWSTA)|(1<<TWEN) sts TWCR, temp So sieht die start routine aus nur eben im simulator sehe ich nicht dass das TWINT gesetzt wird nach den befehlszeilen. Geht das gar nicht im SImulator? Normal müsste es funktionieren oder? MfG Lukas
Aja TWIE und GIE hab ich gesetzt. Hab auch externe Pull up Widerstände von 4k7.
Hi Welches AVR-Studio benutzt du? Für das AVR Studio 4.19 steht bei den 'Known Issues': Simulation of TWI, USI and analog peripheral is not yet implemented. All instructions, interrupts and other peripherals are supported. See the Simulator Modules for more information. MfG Spess
Ja ich benutze das AVR Studio 4.19. Alles klar. Glaube jedoch trotzdem das es daran liegen könnte warum meine Kommunikation nicht funktioniert. Wenn ich eben mit dem Slave kommuniziere wird am Oszi nur eine Start Flanke (sieht zumindest so aus) angezeigt beim Pin Data. Beim Pin Clock bekomm ich überhaupt eine seltsam aussehende Flanke. Weißt du vllt was das Problem ist ? LG Lukas
Hi
>Weißt du vllt was das Problem ist ?
Was kommt denn nach deinen 2 Zeilen? Bei mir sieht das so aus:
1 | ; Startbedingung senden |
2 | ; out: Z=1 wenn ok |
3 | |
4 | .if use_start_i2c |
5 | |
6 | start_i2c: ldi r16,(1<<TWINT)|(1<<TWSTA)|(1<<TWEN) |
7 | sts TWCR, r16 ; Start senden |
8 | |
9 | start_i2c10: lds r16,TWCR |
10 | sbrs r16,TWINT |
11 | rjmp start_i2c10 |
12 | lds r16,TWSR ; Statusregister |
13 | andi r16,$F8 ; Prescaler ausblenden |
14 | ret |
MfG Spess
Nach den 2 Zeilen kommt : ldi temp,(1<<TWINT)|(1<<TWSTA)|(1<<TWEN) sts TWCR, temp rcall TWI_TWINT_wait ldi temp,TWSR andi temp,0b11111000 cpi temp, 0x08 brne TWI_MASTER_TRANSMITTER_ERROR mov temp, ADRESSE_SLAVE sts TWDR, temp TWI_TWINT_wait: ldi temp, TWCR sbrs temp, TWINT rjmp TWI_TWINT_wait ret LG Lukas
Lukas Hub schrieb:
1 | TWI_TWINT_wait: |
2 | ldi temp, TWCR |
3 | ; ^^^- lds |
4 | sbrs temp, TWINT |
5 | rjmp TWI_TWINT_wait |
6 | ret |
Schau mal das ldi passt da nicht so. Steffen
Stattdessen ein lds ? Worin liegt da genaue unterschied.. hab mir die Befehle in der Befehlstabelle angeschaut. Kann er das Register mit ldi nicht ins temp laden? LG Lukas
TWCR wird im IncludeFile des m168 ja eine Adresse zugewiesen.
1 | .equ TWCR = 0xbc ; MEMORY MAPPED |
Mit ldi lädst du halt die Adresse "0xbc" in dein temp Register. Und mit lds den Inhalt der Adresse. Steffen
Hi
>Stattdessen ein lds ?
Ja. ldi lädt ein Register mit einem festen Wert. Lds mit dem Inhalt
einer Speicherstelle.
MfG Spess
Super danke Leute! Werde es umschreiben und dann nochmals ausprobieren. Melde mich! LG Lukas
Ach ja, wenn du für einen Master TWI im Interrupt schon etwas fast fertiges haben willst, da habe ich mir schonmal Gedanken drüber gemacht. Beitrag "[ASM] Hardware TWI-MASTER Interrupt basierend für Mega AVR" Steffen
Hallo, Habe jetzt im ganzen Programm statt den falschen ldi ein lds daraus gemacht, start routine sieht somit, 1:1 mit der von Spess aus. Bekomme jedoch immer noch nur eine Start Routine am Oszi dargestellt, sonst nichts. LG Lukas
So bekomme jetzt Daten aus dem TWI heraus. Habs jetzt soweit überprüft, dass beim SDA nur die Start Daten herauskommen. Also nach dem Start einfach mal ein rjmp main und eine Warteschleife gesetzt. Diese 2 Zeilen immer wieder hintereinander: ldi temp,(1<<TWINT)|(1<<TWSTA)|(1<<TWEN) sts TWCR, temp Jetzt sehe ich am Oszi aber in einem Zyklus (also nach der Warteschleife) 01010101010101010101 statt einer Start Flanke (01). Wie kommt der TWI zu dem Bitmuster? LG Lukas
Hallo, ich kapere diesen halbwegs aktuellen Thread mit einer kleinen Zusatzinfo, die vielleicht anderen auch helfen kann. Das Problem: TWINT wird nicht gesetzt und der Controller hängt bei
1 | while (!(TWCR & (1<<TWINT))); |
nach dem Setzen der Start Condition. Benutzt habe ich die Lib von Peter Fleury, Hardware TWI an einem ATmega32, 10k Pull-Ups an SCL und SDA auf dem Breakboard des PCA9685 Auf dem Oszi bzw. Logic Analyzer habe ich eine korrekte Start Condition gesehen, danach passierte nichts mehr. Durch LED blinken lassen habe ich herausgefunden, dass der Controller hängt und es bis auf obige Codezeile eingegrenzt. Alles mehrfach überprüft, aber alles schien ok. Letzter Verdacht waren die LEDs mit Vorwiderstand an meinen SCL und SDA Pins. Und siehe da, diese waren die Ursache... LEDs entfernt und es läuft! Hoffe jemandem geholfen zu haben.
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.