Ich beginne gerade mit der C-Programmierung mit AVRs und habe mir aus
einigen Beispielen etwas zusammengebastelt, was mir per UART ein Zeichen
empfangen soll und dann wieder per UART und auf einem HD44780-Display
ausgeben soll, mit einem mega16.
Mein Compiler ist der avr-gcc 4.2.2, als IDE hab' ich das AVR-Studio und
den Code schieb ich mit Ponyprog auf den Controller.
Wenn ich jetzt z.B. im Terminal ABCDEFG eintippe, dann wird bei einem
Tastendruck immer nur das letzte Zeichen angezeigt. Also, wenn ich noch
gar nichts gedrückt habe und drücke A dann zeigt es nichts an (Display
und Terminal), drücke ich dann B, dann zeigt es A an, drücke ich dann C,
dann zeigt es B an uswuswusw....
Zum Ansteuern der Displays habe ich Peter Fleury's lcdlib verwendet. Die
lcd.h stelle ich jetzt mal nicht rein, da das Display ja soweit
funktioniert, falls ihr sie doch sehen wollt, kann ich sie ja mit
reinstellen.
Hier der Code, ich hoffe ihr könnt mir da helfen, ich hab mir schon 'ne
halbe ewigkeit den Kopf darüber zerbrochen:
1 | #define F_CPU 8000000L
|
2 | #define BAUD 9600L
|
3 | #define UBRR_VAL ((F_CPU+BAUD * 8)/(BAUD*16)-1) //clever runde
|
4 | #define BAUD_REAL (F_CPU/(16*(UBRR_VAL+1))) //reale Baudrate
|
5 | #define BAUD_ERROR ((BAUD_REAL*1000)/BAUD-1000) //Fehler in Promille
|
6 | #if ((BAUD_ERROR>10)||(BAUD_ERROR<-10))
|
7 | #error Systematischer Fehler in der Baudrate größer 1% und damit zu hoch!
|
8 | #endif
|
9 |
|
10 | #include "lcd.h"
|
11 | #include <avr/io.h>
|
12 | #include <stdlib.h>
|
13 | #include <inttypes.h>
|
14 | #include <util/delay.h>
|
15 | #include <avr/pgmspace.h>
|
16 |
|
17 | int uart_putc(unsigned char c) {
|
18 | while (!(UCSRA & (1<<UDRE))){}// warten bis Senden moeglich
|
19 | UDR = c; // sende Zeichen
|
20 | _delay_ms(10);
|
21 | return(0);
|
22 | }
|
23 |
|
24 |
|
25 |
|
26 | void uart_puts (char *s) {
|
27 | while (*s) {
|
28 | uart_putc(*s);
|
29 | s++;
|
30 | }
|
31 | }
|
32 |
|
33 | int init_uart(void) {
|
34 | UBRRH = UBRR_VAL >> 8;
|
35 | UBRRL = UBRR_VAL & 0xFF;
|
36 | UCSRB = (1<<RXEN)|(1<<TXEN); //UART TX einschalten
|
37 | UCSRC = (1<<URSEL)|(1<<USBS)|(3<<UCSZ0); //Asynchron 8N1
|
38 | UCSRB |= ( 1 << RXEN ); // UART RX einschalten
|
39 | return(0);
|
40 | }
|
41 |
|
42 |
|
43 | int main(void) {
|
44 |
|
45 | lcd_init(LCD_DISP_ON);
|
46 | lcd_clrscr();
|
47 |
|
48 | init_uart();
|
49 | uart_puts("blubb\r\n\r\n");
|
50 |
|
51 | while(1) {
|
52 | while (!(UCSRA & (1<<RXC))) // warten bis Zeichen verfuegbar
|
53 | ;
|
54 |
|
55 | if(UDR == 0x0D) { // \r\n am uart senden, wenn zeichen = ENTER-Taste
|
56 | uart_puts("\r\n");
|
57 | }
|
58 | else {
|
59 | uart_putc(UDR);
|
60 | if( (UDR >= 0x61 && UDR <= 0x7A) || (UDR >= 0x41 && UDR <= 0x5A) || (UDR >= 0x30 && UDR <= 0x39) || (UDR == 0x20) ) {
|
61 | // nur aufs display ausgeben wenn das zeichen eines von denen ist
|
62 | // a bis z ODER A bis Z ODER 0 bis 9 ODER <SPACE>
|
63 | lcd_putc(UDR);
|
64 | }
|
65 | // }
|
66 | }
|
67 | }
|
68 |
|
69 |
|
70 | return 0;
|
71 | }
|
Schonmal vielen Dank im Vorraus!