ATmega2561 - USART

#693249
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
Gast #693254
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.
Gast #694580
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
#694583
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.
#699094
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
}
Gast #699107
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);
#701203
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.
#701643
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!!! ;-(
Gast #702186
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.
#702201
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.
#705245
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
#705247
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.
#705995
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.
Gast #706007
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.
Gast #706019
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.
Gast #706088
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
#707820
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
#707939
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
Gast #816372
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

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren