| Next revision | Previous revision |
| de:avr:usart [2010/07/27 15:43] – angelegt Wember | de:avr:usart [2020/07/20 09:00] (current) – external edit 127.0.0.1 |
|---|
| ====== USART ====== | ====== USART ====== |
| USART ist ein Universal Synchrones Serielles Interface, UART ist die vereinfachte Version - Universelles Asynchrones Interface. Der Unterschied zwischen beiden ist, dass das USART auch eine Taktsignalleitung nutzt um Daten zu synchronisieren, aber das UART nur Datenleitungen benutzt. Das UART des AVR's kann Vollduplex Kommunikation nutzen, 5- bis 9-Bit Datenworte (8-Bit Wort = 1 Byte), 1 oder 2 Stop Bits, 3 Paritätsmodi und eine Vielzahl an Baud-Raten. | |
| AVR Microcontroller haben normalerweise bis zu 2 USART Interfaces, aber manche haben auch gar kein USART. Datenübertragungen werden mit einen Wort auf einmal ausgeführt - der AVR konvertiert das Wort was er vom Benutzer bekommt in Bits auf Hardwarelevel und sendet es unhabhängig und vice veersa. Der Benutzer kann das USART mit Schreib- und Lesekonfigurationen und Status- und Datenregister kontrollieren. | |
| |
| Jede Einstellungsoption hat ihr eigenes Register, welche recht einfach mit dem Datasheet einzustellen sind. Die Baud-Rate jedoch, ist etwas schwieriger einzustellen. Das Taktsignal für die Datenübertragung kommt vom Taktgeber des Controllers und der Nutzer kann eine Nummer von 1 bis 4096 eingeben, durch welche die Taktrate dividiert wird. Das Ergebnis wird zusätzlich durch 2, 8 oder 16 dividiert, je nach Modus. Das Problem ist, dass nicht alle Taktfrequenzen so dividiert werden können, dass das Ergebnis eine standard Baud-Rate ist. | USART ist ein Universal Synchrones Serielles Interface, UART ist die vereinfachte Version - Universelles Asynchrones Interface. Der Unterschied zwischen beiden liegt darin, dass das USART auch eine Taktsignalleitung nutzt um Daten zu synchronisieren, während das UART nur Datenleitungen benutzt. Das UART des AVR Mikrocontrollers Duplexverkehr, 5- bis 9-Bit Datenworte (8-Bit Wort = 1 Byte), 1 oder 2 Stop Bits, 3 Paritätsmodi und eine Vielzahl an Baud-Raten zulässt. AVR Mikrocontroller verfügen normalerweise über bis zu 2 USART Interfaces, jedoch gibt es auch einige ohne USART. Datenübertragungen werden mit einen Wort für Wort ausgeführt - der AVR konvertiert das Wort, welches er vom Benutzer bekommt in Bits auf Hardwareeinheiten und übermittelt es unabhängig und andersherum. Der Benutzer kann das USART mit Schreib- und Lesekonfigurationen sowie Status- und Datenregistern kontrollieren. |
| Mit manchen Frequenzen kann die Baud-Rate mit bis zu 10% vom standard abweichen. Das Datenblatt des AVRs haben Tabellen mit den typischen Taktfrequenzen, Baud-Raten, und den nötigen Multiplikatoren um die Baud-Raten zu erreichen mit ggf. anfallenden Abweichungen. | |
| |
| Da die Datenübertragung unabhängig vom Prozessor und viel langsamer geschiet, ist es notwendig festzustellen, ob das Interface bereit ist für das nächste Wort bevor eine weitere Übertragung stattfindet. Das kann bewerkstellig werden, wenn man auf das Ready Bit des Transmit Buffers achtet, welches anzeigt ob der Buffer bereit ist ein neues Wort zu empfangen oder nicht. Der Controller startet mit einen aktivierten Ready Bit. Sobald ein Wort übertragen wird und der Buffer leer ist, wird das Ready Bit "high" gesetzt. | Jede Einstellungsoption hat ein eigenes Register, welches recht einfach anhand des Datenblatts konfiguriert werden kann. Die Baud-Rate ist allerdings etwas schwieriger einzustellen. Das Taktsignal für die Datenübertragung wird vom Taktgeber des Controllers generiert und der Nutzer kann eine Zahl von 1 bis 4096 eingeben, durch welche die Taktrate dividiert wird. Das Ergebnis wird darüber hinaus, je nach Modus, durch 2, 8 oder 16 dividiert. Das Problem ist, dass nicht alle Taktfrequenzen so dividiert werden können, dass das Ergebnis eine Standard-Baud-Rate ergibt. Bei einigen Frequenzen kann die Baud-Rate bis zu 10% vom Standardwert abweichen. Die Datenblätter des AVR beinhalten Tabellen mit Angaben zu den typischen Taktfrequenzen, Baud-Raten, den nötigen Multiplikatoren um die Baud-Raten zu erreichen sowie den möglichen Rechenfehlern. |
| |
| Das Empfangen eines Wort ist wird durch ein spezielles Status-Bit gekennzeichnet. Zusätzlich gibt es Status-Bits Framingerror, Paritätserror und Bufferoverflows anzuzeigen. Ein Bufferoverflow kann stattfinden, wenn das letzte Wort noch aus dem Buffer gelesen werden muss, wenn ein neues Wort ankommt - darum ist es immer wichtig die empfangenen Datenwörter so schnell wie möglich ins Programm zu lesen, z.B. mit Hilfe eines Interrupts. Es gibt drei verschiedene Interruptgründe: Transmitbuffer bereit, Übertragung erfolgreich, Empfang erfolgreich. | Da die Datenübertragung unabhängig vom Prozessor und viel langsamer geschieht, ist es nötig zu bestätigen, dass das Interface für das nächste Wort bereit ist, bevor eine weitere Übertragung stattfindet. Das kann gewährleistet werden, indem das Ready Bit des Sendepuffers beachtet wird, welches anzeigt ob der Puffer bereit ist, ein neues Wort zu empfangen oder nicht. Der Controller startet mit einen aktivierten Ready Bit. Sobald ein Wort übertragen wird und der Puffer leer ist, wird das Ready Bit „high“ gesetzt. |
| |
| Der Übertragung- und Empfangsbuffer sind physikalisch getrennte Register, aber sie nutzen die gleiche Speicheradresse und Namen. Wenn man in ein gemeinsam benutztes Register schreibt, werden die Daten im Transmitbuffer gespeichert, und wenn man davon liest, werden die Daten aus dem Empfangsbuffer gelesen. Wenn man ein 9-Bit Wort benutzt, wird das 9. Bit in ein Einstellungsregister gesendet und ausgelesen. | Der Empfang eines Wortes ist wird durch ein spezielles Status-Bit gekennzeichnet. Zusätzlich gibt es Status-Bits, welche Rahmenfehler, Paritätsfehler und Pufferüberläufe anzeigen. Ein Pufferüberlauf tritt auf, wenn das letzte Wort noch aus dem Puffer gelesen werden muss, während ein neues ankommt. Aus diesem Grund ist es wichtig, die empfangenen Datenwörter stets so schnell wie möglich ins Programm zu lesen, z.B. mit Hilfe eines Interrupts. Es gibt drei mögliche Gründe für Interrupts: Sendepuffer bereit, Übertragung erfolgreich, Empfang erfolgreich. |
| |
| | Der Sende- und Empfangspuffer sind physikalisch getrennte Register, aber sie nutzen die gleiche Speicheradresse und den gleichen Namen. Während des Schreibens in ein gemeinsam benutztes Register, werden die Daten im Sendepuffer gespeichert, beim Auslesen werden sie aus dem Empfangspuffer gelesen. Werden 9-Bit Worte benutzt, wird das 9. Bit mit Hilfe eines Einstellungsregister übertragen und ausgelesen. |
| |
| ~~PB~~ | |
| |
| <box 100% round #EEEEEE|Example> | <pagebreak> |
| |
| Aufgabe: Konfiguriere ein 8 MHz ATmega128 USART0 Interface um ein 8-Bit Wort asynchron mit einer 9600 bps Baud-Rate, 1 Stop-Bit und keinem Paritätsbit zu übertragen. Sende das Symbol "X" | <box 100% round #EEEEEE|Beispiel> |
| Task: Configure an 8 MHz ATmega128's USART0 interface to transmit 8-bit words asynchronously using 9600 bps baud rate, 1 stop bit and no parity bits. Send the symbol "X". | |
| | Aufgabe: Konfigurieren Sie die USART0 Schnittstelle eines 8 MHz ATmega128 so, dass sie ein 8-Bit-Wort asynchron überträgt, wobei die Baudrate 9600 bps beträgt, 1 Stoppbit und kein Paritätsbit genutzt werden soll. Senden Sie das Symbol “X”. |
| |
| <code c> | <code c> |
| { | { |
| // Setzt die Baud-Rate auf 9600 bps. Formel: | // Setzt die Baud-Rate auf 9600 bps. Formel: |
| // Multiplikator = Taktfrequenz / 16 / Baud rate - 1 | // Faktor = Frequenz / 16 / Baudrate -1 |
| // UBRR = 8000000 / 16 / 9600 - 1 = ~51 | // UBRR = 8000000 / 16 / 9600 - 1 = ~51 |
| UBRR0H = 0; | UBRR0H = 0; |
| UBRR0L = 51; | UBRR0L = 51; |
| |
| // Übertragen erlauben | // Erlaube Senden |
| UCSR0B = (1 << TXEN0); | UCSR0B = (1 << TXEN0); |
| |
| // Konfiguriert asynchronen Modus, setzt die Datenwortgröße auf 8-Bits | // Konfiguriere den asynchronen Modus, setze die Wortgröße auf 8 Bit, |
| // 1 stop Bit, kein Paritätsbit. | // 1 Stoppbit, kein Paritätsbit. |
| UCSR0C = (1 << UCSZ01) | (1 << UCSZ00); | UCSR0C = (1 << UCSZ01) | (1 << UCSZ00); |
| |
| // warte darauf dass der Datenbuffer leer ist (previous word to transmit) | // Warte solange, bis der Datenpuffer leer ist (das vorherige Wort wurde gesendet) |
| // In diesem Beispiel brauch man nicht warten, da das erste Symbol noch | // In diesem Beispiel ist es jedoch nicht nötig zu warten, da nur das erste Symbol |
| // gesendet werden muss, aber es sollte gemacht werden, wenn man mehere Symbole sendet | // gesendet wird. Es sollte jedoch beachtet werden, wenn mehr als ein Symbol gesendet wird. |
| while (!(UCSR0A & (1 << UDRE))) continue; | while (!(UCSR0A & (1 << UDRE))) continue; |
| |
| // Schreibt das Symbol in den Buffer für die Übertragung | // Schreibe das Symbol in den Sendepuffer. |
| UDR0 = 'X'; | UDR0 = 'X'; |
| | |