Ok,
Eine ISR habe ich nicht.
es wird aber auch nicht vom
https://www.roboternetz.de/wissen/in...RT_mit_avr-gcc
explizit erwähnt, oder ich habe es überlesen....
Habe ja auch fast alles von dort kopiert...
Hier der Gesamte Kode:
Main.c
uart.h:Code:#include <avr/interrupt.h> /* Wird nur gebraucht bei der Interrupt-Version */ #include "uart.h" /*==================[macros]=================================================*/ /* Ein Zeilenumbruch, abhängig davon, was die Gegenstelle haben will */ /* Windows: "rn" */ /* Linux : "n" */ /* MacOS : "r" */ #define CR "\r\n" /*==================[type definitions]=======================================*/ /*==================[internal function declarations]=========================*/ /*==================[external constants]=====================================*/ /*==================[internal constants]=====================================*/ /*==================[internal data]==========================================*/ /*==================[external function definitions]==========================*/ /*==================[internal function definitions]==========================*/ int main() { uart_init(); sei(); // Wird nur gebraucht bei der Interrupt-Version uart_putc ('f'); /*uart_puts ("Hallo Welt!" CR);*/ while (1); return 0; } /** @} doxygen end group definition */ /*==================[end of file]============================================*/
Code:#include <avr/io.h> /*==================[macros]=================================================*/ /*==================[type definitions]=======================================*/ /*==================[external function declarations]=========================*/ extern void uart_init(); extern int uart_putc(const uint8_t); extern uint8_t uart_getc_wait(); extern int uart_getc_nowait(); extern void uart_puts (char *string_data); /* Wartet, bis die Übertragung fertig ist. */ static inline void uart_flush() { while (UCSRB & (1 << UDRIE)); } /*==================[external constants]=====================================*/ /*==================[external data]==========================================*/ /** @} doxygen end group definition */ #endif /* _UART_H_ */ /*==================[end of file]============================================*/
uart.c:
fifo.hCode:#include <avr/io.h> #include <avr/interrupt.h> #include "uart.h" #include "fifo.h" /*==================[macros]=================================================*/ #ifndef F_CPU /* In neueren Version der WinAVR/Mfile Makefile-Vorlage kann F_CPU im Makefile definiert werden, eine nochmalige Definition hier wuerde zu einer Compilerwarnung fuehren. Daher "Schutz" durch #ifndef/#endif Dieser "Schutz" kann zu Debugsessions führen, wenn AVRStudio verwendet wird und dort eine andere, nicht zur Hardware passende Taktrate eingestellt ist: Dann wird die folgende Definition nicht verwendet, sondern stattdessen der Defaultwert (8 MHz?) von AVRStudio - daher Ausgabe einer Warnung falls F_CPU noch nicht definiert: */ #warning "F_CPU war noch nicht definiert, wird nun nachgeholt mit 8000000" #define F_CPU 8000000L // Systemtakt in Hz, das L am Ende ist wichtig, NICHT UL verwenden! #endif #define BAUD 9600L // Baudrate, das L am Ende ist wichtig, NICHT UL verwenden! // Berechnungen #define UBRR_VAL ((F_CPU+BAUD*8)/(BAUD*16)-1) /* clever runden */ #define BAUD_REAL (F_CPU/(16*(UBRR_VAL+1))) /* Reale Baudrate */ #define BAUD_ERROR ((BAUD_REAL*1000)/BAUD-1000) /* Fehler in Promille */ /* #if (((BAUD_ERROR) > (10)) || ((BAUD_ERROR) < (-10))) #error Systematischer Fehler der Baudrate grösser 1% und damit zu hoch! #endif */ #define BUF_SIZE_IN 0x40 /* FIFO-Buffergröße */ uint8_t in_buffer[BUF_SIZE_IN]; fifo_t in_fifo; #define BUF_SIZE_OUT 0x40 /* FIFO-Buffergröße */ uint8_t out_buffer[BUF_SIZE_OUT]; fifo_t out_fifo; /********* FUNKTIONEN ***********/ void uart_init() { uint8_t sreg = SREG; UBRRH = UBRR_VAL >> 8; UBRRL = UBRR_VAL & 0xFF; cli(); /* Interrupts kurz deaktivieren */ UCSRB |= (1<<TXCIE) | (1<<TXEN); /* TXCompleteInterrupt u. TX einschalten */ UCSRC |= (1<<URSEL)| (1<<UCSZ1) | (1<<UCSZ0); /* Asynchron 8N1 */ /* Flush Receive-Buffer (entfernen evtl. vorhandener ungültiger Werte) */ do { /* UDR auslesen (Wert wird nicht verwendet) */ UDR; }while (UCSRA & (1 << RXC)); /* Rücksetzen von Receive und Transmit Complete-Flags */ UCSRA = (1 << RXC) | (1 << TXC); /* Global Interrupt-Flag wieder herstellen */ SREG = sreg; /* FIFOs für Ein- und Ausgabe initialisieren */ fifo_init (&in_fifo, in_buffer, BUF_SIZE_IN); fifo_init (&out_fifo, out_buffer, BUF_SIZE_OUT); } /* Senden eines Chars */ int uart_putc (const uint8_t data) { int ret = fifo_put (&out_fifo, data); UCSRB |= (1 << UDRIE); return ret; } /**/ int uart_getc_nowait () { return fifo_get_nowait (&in_fifo); } /**/ uint8_t uart_getc_wait () { return fifo_get_wait (&in_fifo); } /* Senden eines Strings */ void uart_puts (char *string_data) { while (*string_data) /* Wiederhole bis im String '\0' erreicht wurde (*s != '\0') */ { uart_putc (*string_data); /* Gebe ein Zeichen aus*/ string_data++; /* Erhöhe den String um ein Character */ } } /*********************** INTERRUPTS ****************************************/ // Empfangene Zeichen werden in die Eingabgs-FIFO gespeichert und warten dort SIGNAL (SIG_UART_RECV) { _inline_fifo_put (&in_fifo, UDR); } // Ein Zeichen aus der Ausgabe-FIFO lesen und ausgeben // Ist das Zeichen fertig ausgegeben, wird ein neuer SIG_UART_DATA-IRQ getriggert // Ist die FIFO leer, deaktiviert die ISR ihren eigenen IRQ. SIGNAL (SIG_UART_DATA) { if (out_fifo.count > 0) UDR = _inline_fifo_get (&out_fifo); else UCSRB &= ~(1 << UDRIE); } /*********************** ENDE INTERRUPTS ***********************************/ /** @} doxygen end group definition */ /*==================[end of file]============================================*/
Code:#ifndef FIFO_H_ #define FIFO_H_ #include <avr/io.h> #include <avr/interrupt.h> typedef struct { uint8_t volatile count; // # Zeichen im Puffer uint8_t size; // Puffer-Größe uint8_t *pread; // Lesezeiger uint8_t *pwrite; // Schreibzeiger uint8_t read2end, write2end; // # Zeichen bis zum Überlauf Lese-/Schreibzeiger } fifo_t; extern void fifo_init (fifo_t*, uint8_t* buf, const uint8_t size); extern uint8_t fifo_put (fifo_t*, const uint8_t data); extern uint8_t fifo_get_wait (fifo_t*); extern int fifo_get_nowait (fifo_t*); /* Schreibt das nächste Byte "data" in die FIFO. * Liefer 1 bei Erfolg und 0, falls die FIFO voll ist. */ static inline uint8_t _inline_fifo_put (fifo_t *f, const uint8_t data) { if (f->count >= f->size) return 0; uint8_t * pwrite = f->pwrite; *(pwrite++) = data; uint8_t write2end = f->write2end; if (--write2end == 0) { write2end = f->size; pwrite -= write2end; } f->write2end = write2end; f->pwrite = pwrite; uint8_t sreg = SREG; cli(); f->count++; SREG = sreg; return 1; } /* Liefert das nächste Zeichen aus der FIFO. Ob überhaubt ein Zeichen in der FIFO * ist, muss vorher extra abgeprüft werden */ static inline uint8_t _inline_fifo_get (fifo_t *f) { uint8_t *pread = f->pread; uint8_t data = *(pread++); uint8_t read2end = f->read2end; if (--read2end == 0) { read2end = f->size; pread -= read2end; } f->pread = pread; f->read2end = read2end; uint8_t sreg = SREG; cli(); f->count--; SREG = sreg; return data; } #endif /*FIFO_H_*/
fifo.c:
Code:#include "fifo.h" /* Initialisiert die FIFO, setzt Lese- und Schreibzeiger, etc. * Die FIFO verwendet den Puffer "buffer", der "size" Bytes sein muss. */ void fifo_init (fifo_t *f, uint8_t *buffer, const uint8_t size) { f->count = 0; f->pread = f->pwrite = buffer; f->read2end = f->write2end = f->size = size; } /* Schreibt das nächste Byte "data" in die FIFO. * Liefer 1 bei Erfolg und 0, falls die FIFO voll ist. */ uint8_t fifo_put (fifo_t *f, const uint8_t data) { return _inline_fifo_put (f, data); } /* Liefert das nächste Byte aus der FIFO, bei leerer FIFO wird gewartet, * bis das nächste Zeichen eintrift. */ uint8_t fifo_get_wait (fifo_t *f) { while (!f->count); return _inline_fifo_get (f); } /* Liefert das nächste Byte aus der FIFO als "int" bzw. -1, * falls die FIFO leer ist. */ int fifo_get_nowait (fifo_t *f) { if (!f->count) return -1; return (int) _inline_fifo_get (f); }







Zitieren

Lesezeichen