Zitat Zitat von SprinterSB
const prog_char * volatile p_string;
p_string ist volatile und das, worauf er zeigt, ist unveränderlich.
So wars eigentlich auch gemeint. Damit funktioniert es dann natürlich auch.

Wie war das noch, der Computer macht das was man ihm sagt, nicht das was man meint ...

Code:
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/signal.h>
#include <avr/pgmspace.h>

#define SYSCLK		7372800
#define BAUD		9600UL
#define UBRR_BAUD	((SYSCLK/(16*BAUD))-1)

#define	TRUE	1
#define	FALSE	0

// USART initialisieren
void uart_init(void);

volatile unsigned char daten_gesendet = TRUE;
const prog_char* volatile p_string;

// Zeichenkette im Flashspeicher
prog_char daten[] = "Hello World!\n";

int main(void)
{
	// USART initialisieren
	uart_init();
	
	sei();
	
	while (1)
	{
		if (daten_gesendet)
		{
			// Flag zurücksetzen
			daten_gesendet = FALSE;
			
			// Pointer zeigt auf die Daten im Flashspeicher
			p_string = daten;
			
			/* Interrupt aktivieren, damit wird sofort zur
			   Interruptroutine gesprungen und das erste Zeichen gesendet. */
			UCSRB |= (1<<UDRIE);
		}
	}
}

void uart_init(void)
{
	// Baudrate einstellen ( Normaler Modus )
	UBRRH = (unsigned char) (UBRR_BAUD>>8);
	UBRRL = (unsigned char) (UBRR_BAUD & 0x00FF);

	// Aktivieren des Empfängers, des Senders und des "Daten empfangen"-Interrupts
	UCSRB = (1<<RXEN)|(1<<TXEN);
	
	// Einstellen des Datenformats: 8 Datenbits, 1 Stoppbit
	UCSRC = (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0);	
}

/* Interrupt wird ausgelöst sobald der Sendepuffer leer ist */
SIGNAL(SIG_UART_DATA)
{
	char buffer = pgm_read_byte(p_string++);
	
	/* Wenn nicht das Ende der Zeichenkette erreicht wurde, 
	   dann weiteres Zeichen senden */
	if ( buffer != '\0' ) {
		UDR = buffer;
		
	} else {
		// Flag setzen, das der String gesendet wurde
		daten_gesendet = TRUE;
		
		// Interrupt deaktivieren
		UCSRB &= ~(1<<UDRIE);
	}
}
MfG Kjion