Moin,
vielleicht hilft dir ja folgends weiter:
http://www.kreatives-chaos.com/index.php?seite=avr_b
MfG Kjion
Hallo,
ich bin gerade dabei mich in C einzuarbeiten. Doch ich komme leider an einer Stelle nicht weiter.
Ich habe es hinbekommen ein Byte über den UART auszugeben. Nun möchte ich gerne einen ganzen String ausgeben. In dem Tutorial von mikrocontroller.net habe ich einen Beispielcode gefunden. Nur leider kann ich diesen nicht nachvollziehen. Es wäre schön wenn jemand mir mal ein Beispiel geben könnte wo alles genau beschrieben ist, so das ich das nachvollziehen kann.
Vielen Dank im Voraus
gruß ceekay
Moin,
vielleicht hilft dir ja folgends weiter:
http://www.kreatives-chaos.com/index.php?seite=avr_b
MfG Kjion
falls du das "Beispiel zur Ansteuerung des UART" meinst. dann nein.
Denn das hab ich schon verstanden nur ich möchte zum beispiel folgende Bytes nacheinander ausgeben: 'a' 'b' 'c' 'd'
ohne das ich nacheinander jeden Buschstaben manuell in das UDR schreiben muss.
Wie müsste es aussehen wenn diese Bytes nacheinander übertragen werden.
gruß ceekay
ah sorry du meintest: Beispiel: "Strings aus dem Flash ausgeben"
sorry hab ich eben erst gesehen. Das sieht gut aus. ich werd mir das morgen mal genau ansehen und denn nochmal konkrete Fragen stellen.
Vielen Dank erstma.
gruß ceekay
Hi,
ich habe das Programm von kreatives-chaos.com mal compiliert und auf meinen Controller geladen. Vorher habe ich noch ein paar Dinge angepasst.
baudrate auf 9600 und Systemclock auf 16000000.
Leider funktioniert es nicht. Ich bekomme nur diese Zeichen permanent:
ÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀ ÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀ
ÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀ ÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀ
ÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀÀ ÀÀÀÀÀÀÀÀÀÀÀÀÀÀ
ich hoffe ihr könnt mir helfen.
Vielen Dank schonmal für die Mühen.
gruß ceekay
Hört sich nach einem falsch initialisiertem UART an. Hast du BAUD wie im Beispiel als "unsigned long" definiert ??
Ansonsten sollte das eigentlich funktionieren...Code:#define SYSCLK 16000000 #define BAUD 9600UL
MfG Kjion
Für mich schaut das mehr nach Durcheinender von address-of und value
aus (weil die Zeichen alle gleich sind. bei Baudfehlern ist das selten)
mfg robert
Wer glaubt zu wissen, muß wissen, er glaubt.
Hi,
versuch mal folgendes:
Warum das andere Beispiel nicht funktioniert weiß ich im Moment auch noch nicht so genau.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); } }
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:
MfG KjionCode:#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--; } }
Das mutet etwas seltsam an. Wenn etwas const ist, ist es kaum flüchtig (volatile).Zitat von Kjion
Du meinst wohl eher:
p_string ist volatile und das, worauf er zeigt, ist unveränderlich.const prog_char * volatile p_string;
Übrigens brauchst du nicht UDR zu schreiben, um das Senden anzustoßen. Da genügt ein UCSRB |= (1<<UDRIE); und man landet in der ISR, sobalt UDR bereit ist. Dort wird dann mit dem 1. Zeichen begonnen und nicht erst mit dem 2.
Spart Platz und ist klarer
Disclaimer: none. Sue me.
So wars eigentlich auch gemeint. Damit funktioniert es dann natürlich auch.Zitat von SprinterSB
Wie war das noch, der Computer macht das was man ihm sagt, nicht das was man meint ...
MfG KjionCode:#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); } }
Lesezeichen