Moin, ich möchte mein OLED (sitzt auf einer Platine) mit meinem Atmega328p ansprechen. Die Platine unterstützt die Kommunikation nur über I²C. Ich lese mich schon seit heute Morgen in das Thema ein und mir ist immer noch nicht ganz klar, wie ich das ganze anstellen soll. Mittlerweile weiß ich, wie Daten über das I²C Protokoll übertragen werden, aber ich weiß nicht, wie man das mit dem Takt regeln soll und wie man innerhalb einer begrenzten Zeit die jeweiligen Bits übertragen soll. Mein Atmega328p ist mit 16mHz getaktet, für das OLED müsste ich natürlich den Clock Pegel niedriger halten. Meine Idee wäre, dass ich das mit einem Delay löse, entweder mit einem Timer Interrupt oder ohne. Weiter bin ich leider noch nicht gekommen. Mach mein Ansatz so Sinn?
int 21h schrieb: > Mein Atmega328p ist mit 16mHz getaktet ... Wie das denn? Solche Quarze sind doch absolut unüblich. Warum wird der Atmega so "untertaktet" betrieben? Aber in der Regel wird beim Schreiben eines Bytes über i2c doch der Takt automatisch durch den Schreibbefehl mit generiert. Warum machst Du das in deinem Code nicht genauso? Taktsignal setzen, Bit raus, Flanke des Takts erneut wechseln und so weiter und so weiter.
Tom schrieb: > Wie das denn? Solche Quarze sind doch absolut unüblich. Warum wird der > Atmega so "untertaktet" betrieben? Ich meine natürlich MHz, falls du das meinst. (Falls nicht, es liegt am Arduino Uno um genauer zu sein, aber das ist jetzt nicht Thema :D) Tom schrieb: > ber in der Regel wird beim Schreiben eines Bytes über i2c doch der Takt > automatisch durch den Schreibbefehl mit generiert. Warum machst Du das > in deinem Code nicht genauso? Taktsignal setzen, Bit raus, Flanke des > Takts erneut wechseln und so weiter und so weiter. Ok, ich werde mal morgen darüber nachdenken, danke schon mal für den Hinweis
Guckst Du z.B. hier nach: https://www.mikrocontroller.net/articles/AVR_TWI Oder da: https://www.mikrocontroller.net/attachment/308034/Sanbum_LBL-11337-1-01.zip MfG
Hallo, da bin ich wieder. Ich habe mich mal an die Arbeit gemacht und die Routine zum senden eines Bytes über das I²C Interface (bzw. TWI) fertig gestellt. Ich möchte mich nur vergewissern, ob die Routine theoretisch Sinn macht.
1 | ;Parameter_1 = temp1 (zu sendendes Byte, in dem Fall 0b01101101) |
2 | ;SDA = Pin3, SCL = Pin2 |
3 | oled_send_byte: |
4 | push temp1 |
5 | push temp2 |
6 | push counter |
7 | ldi counter, 0x08 |
8 | |
9 | ;Start I²C (Sobald SCL High ist und SDA Flanke fällt) |
10 | ldi temp2, 0b00001100 |
11 | out port, temp2 |
12 | ldi temp2, 0b00000100 |
13 | out port, temp2 |
14 | ldi temp2, 0b00000000 |
15 | out port, temp2 |
16 | |
17 | ;Senden der 8 Bits |
18 | oled_send_byte_loop: |
19 | com temp2 |
20 | andi temp2, 0b00000100 |
21 | lsl temp1 |
22 | brcs oled_send_byte_0 |
23 | cbr temp2, 0b00001000 |
24 | rjmp oled_send_byte_1 |
25 | oled_send_byte_0: |
26 | sbr temp2, 0b00001000 |
27 | oled_send_byte_1: |
28 | out port, temp2 |
29 | com temp2 |
30 | andi temp2, 0b00000100 |
31 | out port, temp2 |
32 | dec counter |
33 | brne oled_send_byte_loop |
34 | |
35 | ;rcall oled_acknowledge ;(Ist noch nicht fertig) |
36 | |
37 | pop counter |
38 | pop temp2 |
39 | pop temp1 |
40 | ret |
Ich frage mich halt, ob das ganze so vom SSD1780 richtig verarbeitet wird, da die Taktrate halt nicht konstant ist, sondern immer unterschiedlich. Ich beziehe mich hier also nur auf die Flanken! Wie man Daten über I²C sendet, habe ich dem Video entnommen: https://www.youtube.com/watch?v=qVujkT1XUiE Ich habe das ganze über den AVR Simulator laufen lassen was auch funktioniert hat. Ich habe mal ein Diagramm vom Ablauf gezeichnet und hochgeladen.
int 21h schrieb: > Ich möchte mich nur vergewissern, ob die Routine theoretisch Sinn macht. Nö, macht sie nicht. Mir fehlen da die diversen Wartezeiten, und der Test ob SDA/SCL überhaupt ein High erreichen wenn sie es sollten. Man bedenke das z.B. bei I²C der Slave die Clock stretchen kann...
Jim M. schrieb: > Mir fehlen da die diversen Wartezeiten Von welchen Wartezeiten sprichst du? Meinst du, ich sollte zwischen den Flanken ein Delay einbauen? Jim M. schrieb: > und der Test ob SDA/SCL > überhaupt ein High erreichen wenn sie es sollten Wieso muss man so etwas testen? Jim M. schrieb: > Man bedenke das z.B. > bei I²C der Slave die Clock stretchen kann... Aha... also wird es vorkommen, dass der Slave mit dem Takt nicht hinterherkommt und man mit dem Master deshalb prüfen muss, ob der Slave bereit ist für das nächste Bit. Aber wie signalisiert mir der Slave, dass er fertig ist, den vor dem Acknowledge Bit vom Slave hat der Master das sagen?
Gibt es eine Möglichkeit, dass ich mich nicht um die TWI Schnittstelle kümmern muss (evtl. über eine Lib) aber trotzdem den Rest des Codes mit Assembler anfertige? Ich könnte dafür C nehmen und eine TWI Lib einbinden, aber dann müsste ich den Assembler teil in eine Assembler Funktion schreiben oder wie das halt funktioniert. Das ist nicht so schön.
Hi
>Gibt es eine Möglichkeit, dass ich mich nicht um die TWI Schnittstelle
kümmern muss ...
Warum nutzt du nicht die TWI(i2C)-Schnittstelle deines ATMega328p. Da
brauchst du dich nicht um irgend welche Timings zu kümmern. Kurze
Codebeispiele in ASM und C findest du im Datenblatt.
MfG Spess
spess53 schrieb: > Warum nutzt du nicht die TWI(i2C)-Schnittstelle deines ATMega328p. Da > brauchst du dich nicht um irgend welche Timings zu kümmern. Kurze > Codebeispiele in ASM und C findest du im Datenblatt. > > MfG Spess Gefunden, danke (Ist zwar Interrupt basiert, aber etwas anderes habe ich leider nicht gefunden)
Hi >(Ist zwar Interrupt basiert, aber etwas anderes habe ich leider nicht >gefunden) Was ist da Interrupt gesteuert? TWINT ist ein Bit im TWCR-Register -> Datenblatt. MfG Spess
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.