
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
Lesezeichen