Dies ist eine alte Version des Dokuments!
/* * LED-Blinker * Einfacher Code, der den UART initialisiert und die * empfangenen Bytes in einen Rinpuffe schiebt * Sind Bytes im Ringpuffer werden diese zurueckgeschickt * Als Baudrate wird 9600Bd eingestellt * http://www.eHaJo.de * (C) Hannes Jochriem, 2013 */ #define F_CPU 8000000UL /* 8MHz */ #include <avr/io.h> #include <util/delay.h> #include <avr/interrupt.h> // Prototypen void long_delay(uint16_t); // Defines: #define LED1 (1<<PD6) #define PUFFERSIZE 8 // globale Variablen // volatile ist noetig da die Variablen in der ISR veraendert werden volatile uint8_t ringpuffer[PUFFERSIZE]; volatile uint8_t ring_schreibe = 0; volatile uint8_t ring_lese = 0; // Interrupt Serviceroutine für "Byte am USART empfangen" ISR(USART_RXC_vect) { uint8_t temp; // Empfangenes Byte in den Speicher schreiben temp = UDR; // Schreibeposition inkrementieren ring_schreibe++; //Schreibeposition auf Puffergroesse beschraenken ring_schreibe %= PUFFERSIZE; if(ring_schreibe != ring_lese) { // Puffer ist nicht voll, Byte schreiben // LED aus PORTD &= ~LED1; ringpuffer[ring_schreibe] = temp; } else { // Puffer ist voll, Schreibeposition wieder dekrementieren // LED an zeigt vollen Buffer an PORTD |= LED1; ring_schreibe--; } } int main() { // LED-Pin als Ausgang definieren DDRD |= LED1; // Receive-Interrupt einschalten, RX und TX einschalten UCSRB |= (1<<RXCIE) | (1<<RXEN) | (1<<TXEN); // 8 Bit Daten: UCSRC |= (1<<UCSZ0) | (1<<UCSZ1); // Baudrate auf 9600Bd einstellen: UBRRH = 0; UBRRL = 51; // Globales Interruptflag einschalten: sei(); while(1) { if(ring_lese != ring_schreibe) { // He, es ist was im Rinpguffer!!! // Leseposition inkrementieren ring_lese++; // Leseposition auf Puffergroesse beschraenken ring_lese %= PUFFERSIZE; // Byte im Puffer zurücksenden UDR = ringpuffer[ring_lese]; // Eine Sekunden warten damit man Versuchsweise den // Rinpuffer volllaufen lassen kann long_delay(1000); } } return 0; } void long_delay(uint16_t ms) { for(; ms>0; ms--) _delay_ms(1); }