Forum: Mikrocontroller und Digitale Elektronik ATmega2561 - USART


von Patrik R. (patronic)


Lesenswert?

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

von STK500-Besitzer (Gast)


Lesenswert?

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.

von patronic (Gast)


Lesenswert?

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

von Karl H. (kbuchegg)


Lesenswert?

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.

von Patrik R. (patronic)


Lesenswert?

sry bin noch ein anfänger.^^
danke für die aufmunterung.
ein kleiner tipp wär super, danke.

von Falk B. (falk)


Lesenswert?


von Patrik R. (patronic)


Lesenswert?

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
}

von STK500-Besitzer (Gast)


Lesenswert?

>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);

von Patrik R. (patronic)


Lesenswert?

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

von Falk B. (falk)


Lesenswert?

@ 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

von Karl H. (kbuchegg)


Lesenswert?

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.

von Patrik R. (patronic)


Lesenswert?

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!!! ;-(

von Patrik R. (patronic)


Lesenswert?

kann mir jemand sagen, ob das testprogramm so funktionieren kann.
kompilieren kann ich es, nur sendet und empfange ich nichts.

von Karl H. (kbuchegg)


Lesenswert?

Sieht nicht so schelcht aus.
Hast du die Hardware durchgemessen?

von patronic (Gast)


Lesenswert?

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.

von Karl H. (kbuchegg)


Lesenswert?

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.

von Gast (Gast)


Lesenswert?

funzt das so wie oben...hmm?

von Patrik R. (patronic)


Lesenswert?

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

von Patrik R. (patronic)


Lesenswert?

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

von Johannes M. (johnny-m)


Lesenswert?

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.

von Patrik R. (patronic)


Lesenswert?

danke ich probier weiter, ansonsten würde ich mich auf tipps sehr freuen

von sechseinssechs (Gast)


Lesenswert?

Versduch zuerst mal ein Zeichen zu senden und mess mit dem Oszilloscope 
ob die Baudrate etwa hinkommt.

von kurfa (Gast)


Lesenswert?

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?

von Patrik R. (patronic)


Lesenswert?

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.

von sechseinssechs (Gast)


Lesenswert?

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.

von Peter D. (peda)


Lesenswert?

Hast Du das SPI angeschlossen, dann beißen sich die Pins mit UART0, nimm 
lieber UART1.


Peter

von sechseinssechs (Gast)


Lesenswert?

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.

von Stefan (Gast)


Lesenswert?

Wo gibt's die ??

von sechseinssechs (Gast)


Lesenswert?

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

von Patrik R. (patronic)


Lesenswert?

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

von Patrik R. (patronic)


Lesenswert?

ENDLICH!!!! mit USART1 hat nun alles geklappt. vielen vielen dank!!!!!
was der kleine unterschied zwischen 0 und 1 so ausmacht.^^

von Peter D. (peda)


Lesenswert?

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

von Patrik R. (patronic)


Lesenswert?

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

von Karsten D. (karstendonat)


Lesenswert?

Als fertiges Modul kann ich Peter Flurys empfehlen. Interuptgesteuert.

Karsten

von Bääääär (Gast)


Lesenswert?

@  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
Noch kein Account? Hier anmelden.