Hallo Leute ich versuche seit einige zeit eine receive und transmit Programm mit buffer zu schreiben aber es geht nicht. die Daten sollen von der tastatur eingegeben und werden im HyperTerminal erscheinen. ich habe ein klein Programm ihne buffer geschrieben und es funtionniert aber wenn ich das Programm mit benutzen von buffer schreibt es functionniert nicht ich weiss nicht was falsch in meinem programm ist. kann jemand mir helfen dieser Programm mit benutzung von buffer zu schreiben? hier unten ist das quelle code meines unfunctioniertes Programms. Merci MFG #include <avr/io.h> #include <avr/interrupt.h> #include <avr/signal.h> /* ATmega with one USART */ #define ATMEGA_USART #define UART0_RECEIVE_INTERRUPT SIG_UART_RECV #define UART0_TRANSMIT_INTERRUPT SIG_UART_DATA #define UART0_STATUS UCSRA #define UART0_CONTROL UCSRB #define UART0_DATA UDR #define UART0_UDRIE UDRIE /*Size of the circular receive buffer, must be power of 2*/ #ifndef UART_RX_BUFFER_SIZE #define UART_RX_BUFFER_SIZE 32 #endif /*Size of the circular Transmit buffer, must be power of 2*/ #ifndef UART_TX_BUFFER_SIZE #define UART_TX_BUFFER_SIZE 32 #endif /*high byte error return code of uart_getc()*/ #define UART_NO_DATA 0x0100 // CHECK F_CPU WITH HARDWARE OSZILLATOR SETTING !!!! #define F_CPU 1000000UL #define UART_BAUD 9600 /* * module global variables */ static volatile unsigned char UART_TxBuf[UART_TX_BUFFER_SIZE]; static volatile unsigned char UART_RxBuf[UART_RX_BUFFER_SIZE]; static volatile unsigned char UART_TxHead; static volatile unsigned char UART_TxTail; static volatile unsigned char UART_RxHead; static volatile unsigned char UART_RxTail; static volatile unsigned char UART_LastRxError; void uart_init(void); unsigned int uart_getc(void); //unsigned char uart_getc(void); void uart_putc(unsigned char c); //int uart_putc(unsigned char c); void uart_puts (char *s); int main(void) { unsigned char c; uart_init(); uart_puts("hello world!\r\n\r\n"); while(1) { // Poll c = uart_getc(); // Funny conversion /************************************************************ This converion ist only use to convert the alphabetic letter and they will be return als echo to the screen ************************************************************/ //if (c >= 'a' && c <= 'z') // c += 'A' - 'a'; //else if (c >= 'A' && c <= 'Z') // c += 'a' - 'A'; // Echo uart_putc(c); } return 0; } void uart_init(void) /****************************************************************** Function: Uart_init() Purpose: Initialise UART and set baudrate Input: baudrate Returns: none ******************************************************************/ { unsigned char UART_TXHead; unsigned char UART_TXTail; unsigned char UART_RXHead; unsigned char UART_RXTail; UART_TXHead = 0; UART_TXTail = 0; UART_RXHead = 0; UART_RXTail = 0; UCSRB |= (1<<TXEN) |(1<<RXEN); // tx/rx enable UCSRC |= (1<<URSEL)|(3<<UCSZ0); // Asynchron 8N1 #if F_CPU < 2000000UL && defined(U2X) UCSRA |= (1<<U2X); /* improve baud rate error by using 2x clk */ UBRRL = (F_CPU / (8UL * UART_BAUD)) - 1; #else UBRRL = (F_CPU / (16UL * UART_BAUD)) - 1; #endif } void uart_putc(unsigned char c) { unsigned char tmphead; tmphead = UART_TxHead + 1; while ( tmphead == UART_TxTail ){ ;/* wait for free space in buffer */ } UART_TxBuf[tmphead] = c; UART_TxHead = tmphead; /* enable UDRE interrupt */ UART0_CONTROL |= _BV(UART0_UDRIE); } void uart_puts (char *s) /********************************************************************** Function: Uart_puts() Purpose: Transmit string to UART Input: String to be transmitted Returns: none **********************************************************************/ { while (*s) { /* so lange *s != '\0' also ungleich dem "String-Endezeichen" */ uart_putc(*s); s++; } } unsigned int uart_getc(void) { unsigned char tmptail; unsigned char c; //unsigned char data; if ( UART_RxHead == UART_RxTail ) { return UART_NO_DATA; /* no data available */ } /* calculate /store buffer index */ tmptail = UART_RxTail + 1; UART_RxTail = tmptail; /* get data from receive buffer */ c = UART_RxBuf[tmptail]; return (UART_LastRxError << 8) + c; }
In deinem Programm ist ziemlich viel falsch. Fangen wir mal damit an:
1 | unsigned int uart_getc(void) |
2 | {
|
3 | unsigned char tmptail; |
4 | unsigned char c; |
5 | //unsigned char data;
|
6 | |
7 | |
8 | if ( UART_RxHead == UART_RxTail ) { |
9 | return UART_NO_DATA; /* no data available */ |
10 | }
|
11 | |
12 | /* calculate /store buffer index */
|
13 | tmptail = UART_RxTail + 1; |
14 | UART_RxTail = tmptail; |
15 | |
16 | /* get data from receive buffer */
|
17 | c = UART_RxBuf[tmptail]; |
18 | |
19 | |
20 | return (UART_LastRxError << 8) + c; |
21 | |
22 | }
|
Wenn du abfrägst if ( UART_RxHead == UART_RxTail ) musst du dich auch mal fragen, wie denn UART_RxHead bzw. UART_RxTail jemals seinen Wert ändern kann. Da die Variable das nicht von alleine tun wird, wirst du wahl einen Interrupt brauchen, der von der UART Hardware ausgelöst wird wenn ein Zeichen empfangen wird. Beschäftige dich mal mit einer Vorstufe zu deinem Buffer: Empfang von Zeichen, wobei beim Empfang eine Interrupt Funktion aufgerufen werden soll. Im einfachsten Fall gibt die Interrupt Funktion das Zeichen einfach wieder aus (das ist dein erstes zu erreichendes Ziel). Dann gehts weiter: Die Interrupt Funktion speichert das Zeichen in einem Buffer.
Hallo herr Karl heinz Buchegger, du hast recht mit diener aussage. ich versuche zu schreiben wie du gesagt hast aber es klap immer nicht. ich glaube es hängt von meine fähigkeit zu programmiert ich bin eine anfängerin in diesem themas ich hatte vorher noch nicht eine controller programmiert. und jetzt brauche ich dieses programm um weiter zu kommen mit meiner Arbeit. die microcontroller ist nur eine zwischen fall in meiner Arbeit. Bitte wenn du schon eine solche programm mit Interrupt geschieben hat kannst du mir das senden? es wurde mir sehr helfen Merci vorraus MFG Marie
In dem Fall empfehle ich dir das Rad nicht noch mal neu zu erfinden, sondern dir eine fertige UART Library zu benutzen. zb. bei Peter Fleury findest du sowas http://jump.to/fleury Unter AVR-Software die 'Uart Library'.
ich habe auch dem library von peter fleury geschaut und herlich gesagt ich weiß nict wie ich mit den anfangen kann. weil dort gibt es 3 coden: die Test_uart, die uart.c, und die uart.h soll ich die drei code combienieren? wenn du in meine code schaust du kann sehen das meine function getc() und putc() sind nur eine copie die von peter fleury. ich bitte dich noch mal wenn du eine solche programm schreiben kannst bitte helfe mir danke MFG Marie
Es hilft alles nichts.
Du musst dich damit auseinandersetzen, wie man in C
eine Interruptfunktion macht.
Im Moment versuchst du zu laufen, bevor du gehen
kannst. Du musst mit den Grundlagen anfangen.
> soll ich die drei code combienieren?
Nein. uart.c und uart.h werden zu deinem Projekt
hinzugefügt. Die test_uart zeigt nur, wie man
die Bibliothek verwendet, welche Aufrufe es gibt.
Anstatt test_uart.c kommt dann deine Applikation
zum Einsatz.
Hast du denn schon mal versucht, dieses Testprogramm
so wie es ist zum laufen zu bringen?
nein ich habe es noch nicht. es ist ja klar das ich muss mit den Grundlagen anfangen. ich habe dieses library mehr mal gelesen und versucht wie ich kann mit den anfangen aber bis jetzt hat es nicht geklappt. ich weiss das die lösung steht da drin aber ich weiss nicht wie ich die kriegen kann. deeswegen braucht das Hilfe eines Expert. bitte Karl wie kann ich das machen? glaube mir ich habe schon mit meines verständnis alles versucht.
> nein ich habe es noch nicht.
Also das erste was ich immer mache, wenn ich mir von irgendwo
eine Bibliothek hole: Ich schaue nach ob es ein Testprogramm
gibt. Wenn ja (und in dem Fall gibt es eines), dann probiere
ich das mal aus!
Anchliessend fange ich meistens an mit dem Testprogramm ein
bischen rumzuspielen um zu sehen wie denn die Aufrufe funktionieren.
Also: Warum probierst du nicht einfach mal aus ob die
uart.c / uart.h überhaupt auf deinem System funktionieren.
Anschliessend kannst du immer noch anfangen in test_uart.c
mal ein paar Veränderungen zu machen. Und dann kannst du immer
noch anfangen dich in uart.c einzulesen und zu versuchen zu
verstehen, wie denn das überhaupt funktioniert.
Und nein: Ich werde da jetzt nichts programmieren.
Lies dir das hier http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#Programmieren_mit_Interrupts mal durch Und danach schaust du ins Datenblatt deines Prozessors und liest im UART Abschnitt nach, welche Interrupts es gibt, und wann sie ausgelöst werden. Danach schreibst du ein Programm, dass eine ISR aufsetzt, die genau dann aufgerufen wird, wenn die UART ein Zeichen empfangen hat. Die ISR kann zb. eine LED einschalten wenn das der Fall ist. Wenn du soweit bist, hast du auch mehr Verständnis davon, wie die Sache mit den Interrupts funktioniert und kannst ja mal Nachschauen was den Peter Fleury in seinem Interrupt- handler (der bei ihm noch SIGNAL und nicht ISR heist) so alles treibt.
danke karl ich versuche es mal. und ich schaue ob es klapp MFG Marie
Hallo Karl, ich probiere mal mit dem Test programm von Peter Fleury aber bei der kompilierung krieg ich einigen fehler meldung. ich zeigt dir die code und die meldungen und sagt mir bitte wie ich dieser fehler korrigieren kann danke #include <stdlib.h> #include <avr/io.h> #include <avr/interrupt.h> #include <avr/signal.h> #include <avr/pgmspace.h> //#include "uart.h" //#include <avr/uart.h> #define UART_FRAME_ERROR 0x0800 /* Framing Error by UART */ #define UART_OVERRUN_ERROR 0x0400 /* Overrun condition by UART */ #define UART_BUFFER_OVERFLOW 0x0200 /* receive ringbuffer overflow */ #define UART_NO_DATA 0x0100 /* no receive data available */ /* define CPU frequency in Mhz here if not defined in Makefile */ #ifndef F_CPU #define F_CPU 4000000UL #endif /* 9600 baud */ #define UART_BAUD_RATE 9600 int main(void) { unsigned int c; char buffer[7]; int num=134; /* * Initialize UART library, pass baudrate and AVR cpu clock * with the macro * UART_BAUD_SELECT() (normal speed mode ) * or * UART_BAUD_SELECT_DOUBLE_SPEED() ( double speed mode) */ uart_init( UART_BAUD_SELECT(UART_BAUD_RATE,F_CPU) ); /* * now enable interrupt, since UART library is interrupt controlled */ sei(); /* * Transmit string to UART * The string is buffered by the uart library in a circular buffer * and one character at a time is transmitted to the UART using interrupts. * uart_puts() blocks if it can not write the whole string to the circular * buffer */ uart_puts("String stored in SRAM\n"); /* * Transmit string from program memory to UART */ uart_puts_P("String stored in FLASH\n"); /* * Use standard avr-libc functions to convert numbers into string * before transmitting via UART */ itoa( num, buffer, 10); // convert interger into string (decimal format) uart_puts(buffer); // and transmit string to UART /* * Transmit single character to UART */ uart_putc('\r'); for(;;) { /* * Get received character from ringbuffer * uart_getc() returns in the lower byte the received character and * in the higher byte (bitmask) the last receive error * UART_NO_DATA is returned when no data is available. * */ c = uart_getc(); if ( c & UART_NO_DATA ) { /* * no data available from UART */ } else { /* * new data available from UART * check for Frame or Overrun error */ if ( c & UART_FRAME_ERROR ) { /* Framing Error detected, i.e no stop bit detected */ uart_puts_P("UART Frame Error: "); } if ( c & UART_OVERRUN_ERROR ) { /* * Overrun, a character already present in the UART UDR register was * not read by the interrupt handler before the next character arrived, * one or more received characters have been dropped */ uart_puts_P("UART Overrun Error: "); } if ( c & UART_BUFFER_OVERFLOW ) { /* * We are not reading the receive buffer fast enough, * one or more received character have been dropped */ uart_puts_P("Buffer overflow error: "); } /* * send received character back */ uart_putc( (unsigned char)c ); } } } fehler meldungen: Linking: uart1.elf avr-gcc -mmcu=atmega16 -I. -gstabs -DF_CPU=8000000UL -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -Wall -Wstrict-prototypes -Wa,-adhlns=uart1.o -std=gnu99 -Wundef -MMD -MP -MF .dep/uart1.elf.d uart1.o --output uart1.elf -Wl,-Map=uart1.map,--cref -lm uart1.o: In function `main': uart1.c:39: undefined reference to `UART_BAUD_SELECT' uart1.c:39: undefined reference to `uart_init' uart1.c:53: undefined reference to `uart_puts' uart1.c:58: undefined reference to `uart_puts_P' uart1.c:66: undefined reference to `uart_puts' uart1.c:72: undefined reference to `uart_putc' uart1.c:83: undefined reference to `uart_getc' uart1.c:99: undefined reference to `uart_puts_P' uart1.c:108: undefined reference to `uart_puts_P' uart1.c:116: undefined reference to `uart_puts_P' make.exe: *** [uart1.elf] Error 1 > Process Exit Code: 2 > Time Taken: 00:01
> //#include "uart.h" > //#include <avr/uart.h> Ich kenne zwar die Fleury-Lib nicht, aber für eine Version musste Dich schon entscheiden, je nachdem, wo Du die Bibliothek hinkopiert hast. Wenn Du keine der Headerdateien einbindest, kennt er natürlich die ganzen Funktionen nicht, und dann gibts für jede eine Fehlermeldung... Also wie Karl Heinz schon angedeutet hat: Die uart.h mit #include einbinden und die uart.c zu den Source-Dateien hinzufügen (entweder im Makefile oder im AVRStudio im "Projektbaum").
du muss die uart.h auf jedenfall "includen". also nicht auskommentieren. eine moeglichkeit: kopier die uart.h und uart.c vom Fleury in dein projektordner deines programmes und sag im AVR Studio (falls du das benutzt) add source file (und waehl die uart.c aus) und anschliessend auf "add existing header files" und waehl die uart.h. in deinem hauptprogramm musst dann uart.h einbezogen werden: folgende Zeilen muessen in deinem (test)programm sein:
1 | #include "uart.h" |
2 | #define UART_BAUD_RATE 57600
|
1 | int main(){ |
2 | |
3 | sei(); //now enable interrupt, since UART library is interrupt controlled |
4 | uart_init( UART_BAUD_SELECT(UART_BAUD_RATE,F_CPU) ); |
5 | uart_putc(0xAA); // 'AA' vesenden als Char |
6 | uart_puts("Hello World!"); //ein String verschicken usw |
ps: parlez vous francais?
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.