mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik ATmega2561 - USART


Autor: Patrik R. (patronic)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: STK500-Besitzer (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: patronic (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Patrik R. (patronic)
Datum:

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

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert

Autor: Patrik R. (patronic)
Datum:

Bewertung
0 lesenswert
nicht 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.

/*
bluecontrol v1.0
*/

#include <stdio.h>
#include <avr/io.h>
#include <avr/wdt.h>
#include <util/delay.h>
//#include <math.h>
#include <avr/pgmspace.h>
 
#include "glcd-Display3000-211.h"
extern const prog_uint8_t Font1[], Font2[];

//Include graphics files (if any)

#include "projekt.h"
#include "menu.h"

//USART
#define FOSC 14745600 //Clock speed
#define BAUD 2400
#define MYUBRR (FOSC/16/BAUD-1)

int main(void)
{
  LCD_Init();
  USART0_Init(MYUBRR);
  DDRD &= 0xFF;    // PortD as INPUT
  delay_ms(1000);

    Orientation = Portrait180;

    //projekt von
    LCD_Bitmap_256high(0, 0, 131, 175, projekt, Table_projekt, b_true);
    delay_ms(1500);
    
    //Anzeige des Menu
    LCD_Bitmap_256high(0, 0, 131, 175, menu, Table_menu, b_true);
    delay_ms(800);

while(1)
{  
    /*
    PD4= oben
    PD5=links
    PD7=unten
    PD6=rechts
    PD1=menuchange
    
    */
    if (PIND & (1 << PD7))
    {
      // PortD.7 is HIGH
      USART_Transmit('H');
    }
     
    else if(PIND & (0<<PD7))
    {
      //PortD.7 is LOW
         USART_Transmit('L');
    }
    delay_ms(1200);
    USART_Transmit('w');
    
  } 
  return 0; 
}


void delay_ms(uint16_t period)   //delay routine (milliseconds)
{
  unsigned int i;
  for(i=0; i<=period; i++)
    _delay_ms(1);
}

/*USART*/

/*USART Init*/
void USART0_Init(unsigned int ubrr)
{
  /*Power Reduction*/
  PRR0 &=0;

  /*Set baud rate*/
  UBRR0H = (unsigned char) (ubrr>>8);
  UBRR0L = (unsigned char) ubrr;
  
  /*Enable receiver and transmitter*/
  UCSR0B = (1<<RXEN0)|(1<<TXEN0);

  /*Set frame format: 8data, 2 stop bit */
  UCSR0C = (1<<USBS0)|(3<<UCSZ02);
}

/*USART Transmit*/
void USART_Transmit(unsigned char data)
{
  /*Wait for empty transmit buffer*/
  while(!(UCSR0A & (1<<UDRE0)))

  /*Put data into buffer, sends the data*/
  UDR0=data;
}

/*USART Receive*/
unsigned char USART_Receive(void)
{
  /*Wait for data to be reiceved*/
  while(!(UCSR0A & (1<<RXC0)))
  {
  /*Get and return received data from buffer*/
  return (UDR0);
  }
}

Autor: STK500-Besitzer (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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);

Autor: Patrik R. (patronic)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht 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_Checkl...
AVR-Tutorial: UART
http://www.mikrocontroller.net/articles/AVR-GCC-Tu...


MFG
Falk

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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:
#define FOSC 14745600 //Clock speed
#define BAUD 2400
#define MYUBRR (FOSC/16/BAUD-1)

int main(void)
{
  USART0_Init(MYUBRR);

  while( 1 ) {
    USART_Transmit( 'a' );
  }
}

(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.

Autor: Patrik R. (patronic)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
#include <stdio.h>
#include <avr/io.h>
#include <avr/wdt.h>
#include <util/delay.h>
//#include <math.h>
#include <avr/pgmspace.h>
 
#include "glcd-Display3000-211.h"
extern const prog_uint8_t Font1[], Font2[];

//USART
#define FOSC 14745600 //Clock speed
#define BAUD 2400
#define MYUBRR (FOSC/16/BAUD-1)

/*USART*/

/*USART Init*/
void USART0_Init(unsigned int ubrr)
{
  /*Power Reduction*/
  //PRR0 &=0;

  /*Set baud rate*/
  UBRR0H = (unsigned char) (ubrr>>8);
  UBRR0L = (unsigned char) ubrr;
  
  /*Enable receiver and transmitter*/
  UCSR0B = (1<<RXEN0)|(1<<TXEN0);

  /*Set frame format: 8data, 1 stop bit */
  UCSR0C = (1<<USBS0)|(1<<UCSZ00);
}

/*USART Transmit*/
void USART_Transmit(unsigned char data)
{
  /*Wait for empty transmit buffer*/
  while(!(UCSR0A & (1<<UDRE0)));

  /*Put data into buffer, sends the data*/
  UDR0=data;
}

/*USART Receive*/
unsigned char USART_Receive(void)
{
  /*Wait for data to be reiceved*/
  while(!(UCSR0A & (1<<RXC0)));
  /*Get and return received data from buffer*/
  return (UDR0);
}

int main(void)
{
  LCD_Init();
  USART0_Init(MYUBRR);
  unsigned char tmp;


  while(1)
  {  
    delay_ms(300);
    LCD_Box(30,30,40,40,blue);
    delay_ms(300);
    USART_Transmit('a');
    delay_ms(1000);
    tmp=USART_Receive();
    if(tmp=='e')
    {
      LCD_Box(0, 0,50,50, red);
    }
    
    
  } 
  return 0; 
}


void delay_ms(uint16_t period)   //delay routine (milliseconds)
{
  unsigned int i;
  for(i=0; i<=period; i++)
    _delay_ms(1);
}

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

Autor: Patrik R. (patronic)
Datum:

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

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

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

Autor: patronic (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
funzt das so wie oben...hmm?

Autor: Patrik R. (patronic)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Patrik R. (patronic)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Patrik R. (patronic)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
danke ich probier weiter, ansonsten würde ich mich auf tipps sehr freuen

Autor: sechseinssechs (Gast)
Datum:

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

Autor: kurfa (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: Patrik R. (patronic)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: sechseinssechs (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Peter Dannegger (peda)
Datum:

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


Peter

Autor: sechseinssechs (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Stefan (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wo gibt's die ??

Autor: sechseinssechs (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Patrik R. (patronic)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Patrik R. (patronic)
Datum:

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

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Patrik R. (patronic)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Karsten Donat (karstendonat)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Als fertiges Modul kann ich Peter Flurys empfehlen. Interuptgesteuert.

Karsten

Autor: Bääääär (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.