Hallo µC-community, ich befasse mich gerade mit dem Atmega2561 und möchte bei diesem über USART Daten an meinem Computer senden. Ich benötige so etwas wie eine USART Libary, welche zB.: Init, write, read beinhaltet. Bitte um Links zu einer bereits fertig programmierten Libary, mit der Ihr gute Erfahrungen habt. Vielen Dank
Sowas zieht man sich aus dem Datenblatt. Da wirst du eh reingucken müssen, wenn du mehr als nur das USART betreben willst. Das Tutorium hier auf der Seite sollte auch eine gute Hilfestellung sein. Vielleicht findest du aber auch was in der Codesammlung.
ja im ich möchte jedoch einen string senden können. ich suche eine funktion, bei der ich den Inhalt und die länge des strings übergeben muss, und diese schreibt mir diese über usart raus. das gleiche eben fürs empfangen. vielen dank
patronic wrote:
> ja im ich möchte jedoch einen string senden können.
In C?
Ist doch kein Problem.
Wenn du erst mal eine Funktion hast, die ein einzelnes Zeichen
korrekt versendet, dann ist es doch trivial darauf aufbauend
eine Funktion zu schreiben, die einen String versendet.
sry bin noch ein anfänger.^^ danke für die aufmunterung. ein kleiner tipp wär super, danke.
So möchte jetzt die Init, Transmit Funktionen aus dem Datenblatt verwenden. Ich arbeite gerade mit dem Display3000 Board mit dem ATmega2561. Ich möchte die Tasten unterhalb des Displays als Eingabeperipherie nehmen und bei unterschiedlichen Eingaben, verschiedene Zeichen an den PC senden. Bin noch Neuling, kann mir jemand sagen was hier falsch ist, compilieren kann ich, nur funken tut es nicht.
1 | /*
|
2 | bluecontrol v1.0
|
3 | */
|
4 | |
5 | #include <stdio.h> |
6 | #include <avr/io.h> |
7 | #include <avr/wdt.h> |
8 | #include <util/delay.h> |
9 | //#include <math.h>
|
10 | #include <avr/pgmspace.h> |
11 | |
12 | #include "glcd-Display3000-211.h" |
13 | extern const prog_uint8_t Font1[], Font2[]; |
14 | |
15 | //Include graphics files (if any)
|
16 | |
17 | #include "projekt.h" |
18 | #include "menu.h" |
19 | |
20 | //USART
|
21 | #define FOSC 14745600 //Clock speed
|
22 | #define BAUD 2400
|
23 | #define MYUBRR (FOSC/16/BAUD-1)
|
24 | |
25 | int main(void) |
26 | {
|
27 | LCD_Init(); |
28 | USART0_Init(MYUBRR); |
29 | DDRD &= 0xFF; // PortD as INPUT |
30 | delay_ms(1000); |
31 | |
32 | Orientation = Portrait180; |
33 | |
34 | //projekt von
|
35 | LCD_Bitmap_256high(0, 0, 131, 175, projekt, Table_projekt, b_true); |
36 | delay_ms(1500); |
37 | |
38 | //Anzeige des Menu
|
39 | LCD_Bitmap_256high(0, 0, 131, 175, menu, Table_menu, b_true); |
40 | delay_ms(800); |
41 | |
42 | while(1) |
43 | {
|
44 | /*
|
45 | PD4= oben
|
46 | PD5=links
|
47 | PD7=unten
|
48 | PD6=rechts
|
49 | PD1=menuchange
|
50 |
|
51 | */
|
52 | if (PIND & (1 << PD7)) |
53 | {
|
54 | // PortD.7 is HIGH
|
55 | USART_Transmit('H'); |
56 | }
|
57 | |
58 | else if(PIND & (0<<PD7)) |
59 | {
|
60 | //PortD.7 is LOW
|
61 | USART_Transmit('L'); |
62 | }
|
63 | delay_ms(1200); |
64 | USART_Transmit('w'); |
65 | |
66 | }
|
67 | return 0; |
68 | }
|
69 | |
70 | |
71 | void delay_ms(uint16_t period) //delay routine (milliseconds) |
72 | {
|
73 | unsigned int i; |
74 | for(i=0; i<=period; i++) |
75 | _delay_ms(1); |
76 | }
|
77 | |
78 | /*USART*/
|
79 | |
80 | /*USART Init*/
|
81 | void USART0_Init(unsigned int ubrr) |
82 | {
|
83 | /*Power Reduction*/
|
84 | PRR0 &=0; |
85 | |
86 | /*Set baud rate*/
|
87 | UBRR0H = (unsigned char) (ubrr>>8); |
88 | UBRR0L = (unsigned char) ubrr; |
89 | |
90 | /*Enable receiver and transmitter*/
|
91 | UCSR0B = (1<<RXEN0)|(1<<TXEN0); |
92 | |
93 | /*Set frame format: 8data, 2 stop bit */
|
94 | UCSR0C = (1<<USBS0)|(3<<UCSZ02); |
95 | }
|
96 | |
97 | /*USART Transmit*/
|
98 | void USART_Transmit(unsigned char data) |
99 | {
|
100 | /*Wait for empty transmit buffer*/
|
101 | while(!(UCSR0A & (1<<UDRE0))) |
102 | |
103 | /*Put data into buffer, sends the data*/
|
104 | UDR0=data; |
105 | }
|
106 | |
107 | /*USART Receive*/
|
108 | unsigned char USART_Receive(void) |
109 | {
|
110 | /*Wait for data to be reiceved*/
|
111 | while(!(UCSR0A & (1<<RXC0))) |
112 | {
|
113 | /*Get and return received data from buffer*/
|
114 | return (UDR0); |
115 | }
|
116 | }
|
>while(!(UCSR0A & (1<<UDRE0))) da fehlt ein Semikolon >(0<<PD7)) Eine 0 um 7 Stellen zu verschieben ist auch sehr sinnfrei... > if (PIND & (1 << PD7)) > { > // PortD.7 is HIGH > USART_Transmit('H'); > } > > else if(PIND & (0<<PD7)) > { > //PortD.7 is LOW > USART_Transmit('L'); > } Wieviele Zustände kann dein Taster denn noch einnehmen? Wenn die erste Abfrage falsch ist, dann ist der Pin low. Das muß man nicht noch extra abfragen. falsch: > while(!(UCSR0A & (1<<RXC0))) > { > /*Get and return received data from buffer*/ > return (UDR0); > } richtig: while(!(UCSR0A & (1<<RXC0))); /*Get and return received data from buffer*/ return (UDR0);
vielen dank für die "nette" hilfe.^^ wie schon gesagt bin ich noch n00b und noch nicht so erfahren. Leider sendet der yC immer noch nichts, nicht einmal das 'w' bekomme ich im Hyperterminal zu sehen. Kann mir bitte jemand helfen!!!! vielen dank
@ Patrik Rothenbuchner (patronic) >Leider sendet der yC immer noch nichts, nicht einmal das 'w' bekomme ich >im Hyperterminal zu sehen. >Kann mir bitte jemand helfen!!!! http://www.mikrocontroller.net/articles/AVR_Checkliste#UART.2FUSART AVR-Tutorial: UART http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#Der_UART MFG Falk
Konzentrier dich erst mal nur auf die UART alleine. Das heist: Fang ein neues Testprogramm an, in dem es nur um die UART geht. Keine Taster, kein sonstiges. Nur UART. Also:
1 | #define FOSC 14745600 //Clock speed
|
2 | #define BAUD 2400
|
3 | #define MYUBRR (FOSC/16/BAUD-1)
|
4 | |
5 | int main(void) |
6 | {
|
7 | USART0_Init(MYUBRR); |
8 | |
9 | while( 1 ) { |
10 | USART_Transmit( 'a' ); |
11 | }
|
12 | }
|
(Du ergänzt noch die restlichen Funktionen). Und damit wird erst mal alles debuggt. Zuerst schaust du mal mit einem Multimeter nach, ob auf dem Tx Ausgang des Prozessors Signale rauskommen (Oszi wäre besser als Multimeter, aber wer hat das schon. Zur Not: Baudrate runterdrehen auf 300 Baud und mal eine Led an den Pin halten). Wenn auf dem Pin Signale rauskommen, dann sendet der Prozessor schon mal und deine USART Initialisierung kann so falsch nicht sein. Dann verfolgst du das Signal mit dem Multimeter zum RS232 Wandler und siehst nach ob dann am Ausgang +/-12 Volt Signale rauskommen (können auch weniger als 12 Volt sein). Dann verfolgst du die Signale weiter durch das Kabel zum PC. Am PC-Ende des Kabels siehst du nach, ob die Signale auch am richtigen Pin wieder rauskommen. Es gibt nämlich 2 Arten von Kabeln: gekreuzte und nicht gekreuzte. Wenn du das falsche hast, dann wirst du nie was sehen. Wenn das alles in Ordnung ist, dann ist die häufigste Fehlerursache: Du hast zwar im Pgm eingetragen, dass dein µC mit 3.irgendwas Mhz arbeitet, allerdings stimmt das nicht, weil der µC immer noch mit der Voreinstellung 'interner RC-Oszillator' arbeitet. Und die ist so ca. 1Mhz. Wenn die Baudrate falsch, aber nicht zu falsch ist, dann sieht man häufig folgendes Verhalten: Am PC Ende kommen im Hyperterminal Zeichen an, es sind aber nicht die Zeichen die weggeschickt wurden. Das bedeutet schon mal: Die Hardware dürfte grundsätzlich in Ordnung sein, aber die Taktfrequenz stimmt nicht.
1 | #include <stdio.h> |
2 | #include <avr/io.h> |
3 | #include <avr/wdt.h> |
4 | #include <util/delay.h> |
5 | //#include <math.h>
|
6 | #include <avr/pgmspace.h> |
7 | |
8 | #include "glcd-Display3000-211.h" |
9 | extern const prog_uint8_t Font1[], Font2[]; |
10 | |
11 | //USART
|
12 | #define FOSC 14745600 //Clock speed
|
13 | #define BAUD 2400
|
14 | #define MYUBRR (FOSC/16/BAUD-1)
|
15 | |
16 | /*USART*/
|
17 | |
18 | /*USART Init*/
|
19 | void USART0_Init(unsigned int ubrr) |
20 | {
|
21 | /*Power Reduction*/
|
22 | //PRR0 &=0;
|
23 | |
24 | /*Set baud rate*/
|
25 | UBRR0H = (unsigned char) (ubrr>>8); |
26 | UBRR0L = (unsigned char) ubrr; |
27 | |
28 | /*Enable receiver and transmitter*/
|
29 | UCSR0B = (1<<RXEN0)|(1<<TXEN0); |
30 | |
31 | /*Set frame format: 8data, 1 stop bit */
|
32 | UCSR0C = (1<<USBS0)|(1<<UCSZ00); |
33 | }
|
34 | |
35 | /*USART Transmit*/
|
36 | void USART_Transmit(unsigned char data) |
37 | {
|
38 | /*Wait for empty transmit buffer*/
|
39 | while(!(UCSR0A & (1<<UDRE0))); |
40 | |
41 | /*Put data into buffer, sends the data*/
|
42 | UDR0=data; |
43 | }
|
44 | |
45 | /*USART Receive*/
|
46 | unsigned char USART_Receive(void) |
47 | {
|
48 | /*Wait for data to be reiceved*/
|
49 | while(!(UCSR0A & (1<<RXC0))); |
50 | /*Get and return received data from buffer*/
|
51 | return (UDR0); |
52 | }
|
53 | |
54 | int main(void) |
55 | {
|
56 | LCD_Init(); |
57 | USART0_Init(MYUBRR); |
58 | unsigned char tmp; |
59 | |
60 | |
61 | while(1) |
62 | {
|
63 | delay_ms(300); |
64 | LCD_Box(30,30,40,40,blue); |
65 | delay_ms(300); |
66 | USART_Transmit('a'); |
67 | delay_ms(1000); |
68 | tmp=USART_Receive(); |
69 | if(tmp=='e') |
70 | {
|
71 | LCD_Box(0, 0,50,50, red); |
72 | }
|
73 | |
74 | |
75 | }
|
76 | return 0; |
77 | }
|
78 | |
79 | |
80 | void delay_ms(uint16_t period) //delay routine (milliseconds) |
81 | {
|
82 | unsigned int i; |
83 | for(i=0; i<=period; i++) |
84 | _delay_ms(1); |
85 | }
|
Vielen Dank für die vielen Antworten Ich werde mich jetzt nur auf UART konzentrieren, hab jetzt das "Testprogramm" raufgespielt, und leider reagiert der atmega2561 gar nicht. Weder Transmit noch Receive funken!!! ;-(
kann mir jemand sagen, ob das testprogramm so funktionieren kann. kompilieren kann ich es, nur sendet und empfange ich nichts.
noch nicht, aber mach ich heute abend noch. das programm müsste also laufen. aber an der hardware müsste doch alles klappen, ist ja vom hersteller (display3000) und nur mit einem normalen RS232 zum pc verbunden.
Grundregel #1: Beim Fehlersuchen erst mal alles solange in Frage stellen bis man nachweisen kann, dass es funktioniert. Dein Kabel könnte einen Kabelbruch haben (ok. geb ich zu, ist eher unwahrscheinlich). Es ist aber trotzdem beruhigend wenn man das Zappeln des Pins vom µC bis zum PC nachverfolgen kann (auch drauf achten, dass es am PC am richtigen Eingang der RS232 zappelt!). Dann kann man Hardware Probleme erst mal ausschliessen. Ein ganz schneller Test: Nimm den µC erst mal aus seiner Fassung (der ist doch gesockelt, oder nicht?). Dann brückst du mit einem Stück Draht im Sockel den Tx und den Rx Anschluss (µC kommt nicht wieder in den Sockel). Wenn du jetzt am PC im hyperterminal Tasten drückst, dann müssen die auch erscheinen (lokales Echo im Hyperterminal muss dazu ausgeschaltet sein). Die Zeichen laufen vom PC durch das Kabel durch den RS232 Wandler bis zum µC-Sockel. Dort schickt sie die Drahtbrücke über den Tx Anschluss wieder zurück. Sie durchlaufen wieder den RS232 Wandler und gehen über das Kabel wieder zum PC. Mit diesem einfachen Test kann man die komplette Hardware Seite schon mal sehr gut testen. Nur wenn alles funktioniert, kommen am Hyperterminal die Zeichen wieder an. Im Umkehrschluss kann man sagen: Kommen die Zeichen nicht wieder an, dann ist irgendwas in der Hardware faul. Aber Achtung: Das 'lokale Echo' im Hyperterminal muss dazu ausgeschaltet sein! Als Gegentest kann man das mal einschalten. Dann muss jeder Tastendruck zu einem doppelten Echo führen.
hallo, is ja der wahnsinn, wie viele tolle mitglieder dieses forum hat, vielen herzlichen dank für die super hilfe. der ic ist leider nicht gesockelt, ist ja ein atmega2561, werde trotzdem heute noch versuchen, den test durchzuführen. vielen dank noch einmal
so der test hat funktioniert. µC aus der schaltung getan, per rs232 kabel mit dem PC verbunden und RX und TX verbunden. im hyperterminal 'd' eingeben und ein 'd' ist erschienen. natürlich habe ich vorher das lokale echo deaktiviert.^^ also hardware mässig müsste es funktionieren, nur leider funkt es immer noch nicht. auf meinem display3000 board befindet sich ein 14.?? MHZ Quarz, mit diesem habe ich auf die BAUDrate berechnet, nur befindet sich ebenfalls ein 32MHz Uhrenquarz auf dem Board, wie kann ich nun feststellen welcher der beiden verwendet wird? Kann das an der Nichtfunktionalität der UART liegen, da vl. der falsche Quarz verwendet wird? vielen dank
Patrik Rothenbuchner wrote: > [...] nur befindet sich ebenfalls > ein 32MHz Uhrenquarz auf dem Board, wie kann ich nun feststellen welcher > der beiden verwendet wird? Wohl eher ein 32,768 kHz-Uhrenquarz... und der wird garantiert nicht für die Baudratenerzeugung verwendet. Der ATMega kann die Baudrate nur aus dem CPU-Takt erzeugen. Der Uhrenquarz ist vermutlich für die RTC-Funktionalität des asynchronen Timers da.
Versduch zuerst mal ein Zeichen zu senden und mess mit dem Oszilloscope ob die Baudrate etwa hinkommt.
Nichts dagegen, aber wäre nicht einfacher mit einem z.B. ATmega8 zu anfangen und erst wenn man die trivialsten Sachen beherscht sich mit etwa dem mega2561 zu beschäftigen?
danke für den tipp, nur mit dem atmega8 und 32 funkt ja alles. der atmega 2561 hat eine andere USART Struktur, sprich mehr register, und der atmega befindet sich auf meinem display3000 board, da kann ich leider nicht einen atmega32 hernehmen da dieser leider, für meine "bilder" zu klein ist.
Die Uarts sind nicht sehr kompliziert. Wenn man nur eine Library funktion einbindet hat man noch nicht begriffen was geschieht. Die Initialisierung besteht in der Regel durch Schreiben von 3-5 Registern, Dann kann man noch etwas buffern und ein interrupt drum rum. Das war's dann etwa. Die vielen Tabellen blasen das Thema im Datenblatt auf mehrere Seiten auf. Schau's dir an.
Hast Du das SPI angeschlossen, dann beißen sich die Pins mit UART0, nimm lieber UART1. Peter
Externer Datenspeicher ist uebrigens viel guenstiger als interner. Fuer Webseiten hab ich zB das AT45DB161, ein 2 MegaByte Datenflash mit SPI Schnittstelle an einem Mega32. Kostet 1.70Euro und hat genuegend Geschwindigkeit fuer einen Webserver.
Der Hersteller ist Atmel, sie sollten daher beim ueblichen Atmelhaendler zu haben sein. Die naechst groesseren sind das AT45DB321, mit 32MBit, das AT45DB642, mit 64MBit. Es gibt auch noch ein kleineres, das AT45DB040, ein 4MBit, dh 512kByte
danke für die idee, ich werde nachdem ich endlich den atmega2561 zum laufen gebracht habe, ein modul mit externem speicher bauen. ich werde heute am abend nun die usart1 einmal ausprobieren. vielen dank
ENDLICH!!!! mit USART1 hat nun alles geklappt. vielen vielen dank!!!!! was der kleine unterschied zwischen 0 und 1 so ausmacht.^^
Patrik Rothenbuchner wrote: > ENDLICH!!!! mit USART1 hat nun alles geklappt. vielen vielen dank!!!!! > was der kleine unterschied zwischen 0 und 1 so ausmacht.^^ Der Unterschied ist nicht zwischen UART0 und 1 sondern, daß Dein Programmieradapter mit an UART0 hängt. Wenn Du nen Bootloader reinbrennst, kannst Du die UART0 genauso gut benutzen. Peter
okay danke hab ich nicht gewusst, bin noch ziemlicher neuling, vielen dank noch einmal. ich möchte nun das bluesmirf von sparkfun verwenden, damit ich "kabellos" unterwegs sein kann. mit kabel funkt alles, jede sekunde mein zeichen (spannend nicht war^^), und wenn ich tx und rx vom bluetooth module zusammenschliesse bekomme ich das eingegebene zeichen auch wieder zurück, so weit so gut. nur wenn ich nun tx vom bluetooth modul mit tx vom µC verbinde und dann eine bluetoothverbindung zum pc aufbaue, geschieht nichts mehr. im hyperterminal ist kein zeichen zu sehen. dass müsste doch auch funktieren, oder? mfg
Als fertiges Modul kann ich Peter Flurys empfehlen. Interuptgesteuert. Karsten
@ Patrik Rothenbuchner: >nur wenn ich nun tx vom bluetooth modul mit tx vom µC verbinde und dann >eine bluetoothverbindung zum pc aufbaue, geschieht nichts mehr. Weiß nicht, ob sich dein Problem schon gelöst hat, falls nicht: Die TX-Leitung ist immer die, auf der die Daten das entsprehende Modul verlassen. Folglich musst du die TX des Prozessors mit der RX des Funkmoduls verbinden. Ich hoffe, das hilft weiter, Bääääär
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.