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);

}