Hi,

versuch mal folgendes:

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

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

#define	TRUE	1
#define	FALSE	0

/* USART initialisieren */
void uart_init(void);

volatile const prog_char *p_string;

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

int main(void)
{
	// USART initialisieren
	uart_init();
	
	sei();
	
	// Pointer zeigt auf die Daten im Flashspeicher
	p_string = daten;
	
	// erstes Byte senden
	UDR = pgm_read_byte( p_string++ );
	
	// Interrupt aktivieren
	UCSRB |= (1<<UDRIE);
	
	for(;;);
}

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<<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, weiteres Zeichen senden */
	if ( buffer != '\0' ) {
		UDR = buffer;
	
	} else {
		// Interrupt deaktivieren
		UCSRB &= ~(1<<UDRIE);
	}
}
Warum das andere Beispiel nicht funktioniert weiß ich im Moment auch noch nicht so genau.
Wenn man sich das Assemblerlisting anschaut, dann sieht man, dass er den Pointer p_string nicht neu lädt. Es wird also nach und nach der gesamte Inhalt des Flashspeichers ausgegeben.
Fügt man aber irgendeine Delayroutine hinter die Abfrage ein, so funktioniert auf einmal alles, auch der Pointer wird wieder richtig initialisiert.

Mit Delay:
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);

void delay_ms(uint16_t ms);

volatile unsigned char daten_gesendet = TRUE;
volatile const prog_char *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;
			
			// erstes Byte senden
			UDR = pgm_read_byte( p_string++ );
			
			// Interrupt aktivieren
			UCSRB |= (1<<UDRIE);
		}
		
		delay_ms(1);
	}
}

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, weiteres Zeichen senden */
	if ( buffer != '\0' ) {
		UDR = buffer;
		
	} else {
		// Flag setzen, das der String gesendet wurde
		daten_gesendet = TRUE;
		
		// Interrupt deaktivieren
		UCSRB &= ~(1<<UDRIE);
	}
}

/*
 *	eine kleine Warteschleife ( fürs debugging )
 */
void delay_ms(uint16_t ms)
{
	uint16_t zaehler;
	
	while (ms) 
	{
		zaehler = F_CPU / 5000;
		while (zaehler) 
		{
			asm volatile ("nop"::);
			zaehler--;
		}
		ms--;
	}
}
MfG Kjion