(→unter Verwendung von Timer1) |
|||
Zeile 8: | Zeile 8: | ||
Jeder diese Herangehensweisen hat ihre Vor- und Nachteile. Welcher Weg der bessere ist, kann nur im Gesamtzusammenhang des Programmes entschieden werden. | Jeder diese Herangehensweisen hat ihre Vor- und Nachteile. Welcher Weg der bessere ist, kann nur im Gesamtzusammenhang des Programmes entschieden werden. | ||
− | == | + | == Mit Verwendung von Timer1 == |
+ | === Dateikopf === | ||
+ | |||
+ | Im Dateikopf wird festgelegt, an welchen Ports die Ein- und Ausgabe stattfindet, mit welcher Baudrate übertragen wird und welche Teile des Soft-UARTs aktiv sind, also übersetzt werden und als Funktionen zur Verfügung stehen bzw. Flash verbrauchen. Damit eintreffende Daten nicht verloren gehen, können die Eingabedaten in einer FIFO (in <tt>fifo.h</tt>) zwischengespeichert werden. | ||
+ | ;<tt>#define BAUDRATE ...</tt>: Die Baudrate, gleich für Receiver und Transmitter | ||
+ | ;<tt>#define SUART_TXD</tt>: Wenn dieses Define gesetzt ist, wird der Transmitter aktiv bzw. die für ihn notwendigen Code-Sequenzen werden eingeblendet. | ||
+ | ;<tt>#define SUART_RXD</tt>: Wenn dieses Define gesetzt ist, wird der Receiver aktiv bzw. die für ihn notwendigen Code-Sequenzen werden eingeblendet. | ||
+ | ;FIFO aktivieren: Um die FIFO zu aktivieren, wird einfach der Header <tt>fifo.h</tt> includet und dadurch die entsprechende Codeerzeugung veranlasst. | ||
+ | :;<tt>#define INBUF_SIZE ...</tt>: Die Größe des Eingabe-Puffers für die Receiver-FIFO | ||
+ | <pre> | ||
+ | #include <avr/io.h> | ||
+ | #include <avr/signal.h> | ||
+ | #include <avr/interrupt.h> | ||
+ | #include "uart.h" | ||
+ | // #include "fifo.h" | ||
+ | |||
+ | #define BAUDRATE 38400 | ||
+ | |||
+ | #define nop() __asm__ __volatile ("nop") | ||
+ | |||
+ | #ifdef SUART_TXD | ||
+ | #define SUART_TXD_PORT PORTB | ||
+ | #define SUART_TXD_DDR DDRB | ||
+ | #define SUART_TXD_BIT PB1 | ||
+ | static volatile uint16_t outframe; | ||
+ | #endif // SUART_TXD | ||
+ | |||
+ | #ifdef SUART_RXD | ||
+ | #define SUART_RXD_PORT PORTB | ||
+ | #define SUART_RXD_PIN PINB | ||
+ | #define SUART_RXD_DDR DDRB | ||
+ | #define SUART_RXD_BIT PB0 | ||
+ | static volatile uint16_t inframe; | ||
+ | static volatile uint8_t inbits, received; | ||
+ | |||
+ | # ifdef _FIFO_H_ | ||
+ | #define INBUF_SIZE 4 | ||
+ | static uint8_t inbuf[INBUF_SIZE]; | ||
+ | fifo_t infifo = | ||
+ | { | ||
+ | .buf = inbuf, | ||
+ | .count = 0, | ||
+ | .pwrite = inbuf, | ||
+ | .pread = inbuf, | ||
+ | .buf_end = inbuf + INBUF_SIZE | ||
+ | }; | ||
+ | # else // _FIFO_H_ | ||
+ | static volatile uint8_t indata; | ||
+ | # endif // _FIFO_H_ | ||
+ | |||
+ | #endif // SUART_RXD | ||
+ | </pre> | ||
=== Initialisierung === | === Initialisierung === | ||
=== Transmitter === | === Transmitter === |
Version vom 7. Februar 2006, 12:44 Uhr
Ein Software-UART ist eine Software, welche die Funktionalität eines UART (Universal Asynchronous Receiver and Transmitter) implementiert., oder kurz: eine serielle Schnittstelle in Software nachbildet.
Inhaltsverzeichnis
Einführung
Stehen keine oder nicht genügend Hardware-UARTs zur Verfügung, muss man selbst Hand anlegen. Die Herausforderung ist dabei, die festgelegten Zeitrahmen bzw. Übertragungsraten/Bitlängen möglichst genau einzuhalten, um die Kommunikation fehlerfrei zu halten. Dies gilt in besonderem Maße für den Empfänger (Receiver), der nicht entscheiden kann, wann Daten eintreffen.
Dafür benötigt man eine Zeitbasis. Am konfortabelsten geht das mit einem Timer. Ohne Timer muss man die Zeit durch Abzählen von Maschinenzyklen machen, während die restliche Software warten muss bzw. Interrupts deaktiviert sein müssen.
Jeder diese Herangehensweisen hat ihre Vor- und Nachteile. Welcher Weg der bessere ist, kann nur im Gesamtzusammenhang des Programmes entschieden werden.
Mit Verwendung von Timer1
Dateikopf
Im Dateikopf wird festgelegt, an welchen Ports die Ein- und Ausgabe stattfindet, mit welcher Baudrate übertragen wird und welche Teile des Soft-UARTs aktiv sind, also übersetzt werden und als Funktionen zur Verfügung stehen bzw. Flash verbrauchen. Damit eintreffende Daten nicht verloren gehen, können die Eingabedaten in einer FIFO (in fifo.h) zwischengespeichert werden.
- #define BAUDRATE ...
- Die Baudrate, gleich für Receiver und Transmitter
- #define SUART_TXD
- Wenn dieses Define gesetzt ist, wird der Transmitter aktiv bzw. die für ihn notwendigen Code-Sequenzen werden eingeblendet.
- #define SUART_RXD
- Wenn dieses Define gesetzt ist, wird der Receiver aktiv bzw. die für ihn notwendigen Code-Sequenzen werden eingeblendet.
- FIFO aktivieren
- Um die FIFO zu aktivieren, wird einfach der Header fifo.h includet und dadurch die entsprechende Codeerzeugung veranlasst.
- #define INBUF_SIZE ...
- Die Größe des Eingabe-Puffers für die Receiver-FIFO
#include <avr/io.h> #include <avr/signal.h> #include <avr/interrupt.h> #include "uart.h" // #include "fifo.h" #define BAUDRATE 38400 #define nop() __asm__ __volatile ("nop") #ifdef SUART_TXD #define SUART_TXD_PORT PORTB #define SUART_TXD_DDR DDRB #define SUART_TXD_BIT PB1 static volatile uint16_t outframe; #endif // SUART_TXD #ifdef SUART_RXD #define SUART_RXD_PORT PORTB #define SUART_RXD_PIN PINB #define SUART_RXD_DDR DDRB #define SUART_RXD_BIT PB0 static volatile uint16_t inframe; static volatile uint8_t inbits, received; # ifdef _FIFO_H_ #define INBUF_SIZE 4 static uint8_t inbuf[INBUF_SIZE]; fifo_t infifo = { .buf = inbuf, .count = 0, .pwrite = inbuf, .pread = inbuf, .buf_end = inbuf + INBUF_SIZE }; # else // _FIFO_H_ static volatile uint8_t indata; # endif // _FIFO_H_ #endif // SUART_RXD