Forum: Mikrocontroller und Digitale Elektronik Probleme ArduinoMega2560 UART mit C


von Max K. (max_blanket)


Lesenswert?

Hey Leute,

ich habe einen ArduinoMega2560 auf den Tisch bekommen und soll damit 
eine Verbindung zum PC-Terminal aufbauen. Hab an UART gedacht und mich 
versucht, aber das Signal was durchgegeben wird, ist nur Blödsinn.
Ich hoffe jemand hier kann mir helfen.

Hier mein C-Code:
1
#define F_CPU 2000000UL    // Systemtakt in Hz
2
3
#define BAUD 9600UL      // Baudrate
4
5
// Berechnungen
6
#define UBRR_VAL ((F_CPU+BAUD*8)/(BAUD*16)-1)   // runden
7
#define BAUD_REAL (F_CPU/(16*(UBRR_VAL+1)))     // Reale Baudrate
8
#define BAUD_ERROR ((BAUD_REAL*1000)/BAUD) // Fehler in Promille, 1000 = kein Fehler.
9
10
#if ((BAUD_ERROR<990) || (BAUD_ERROR>1010))
11
#error Systematischer Fehler der Baudrate grösser 1% und damit zu hoch!
12
#endif
13
14
15
#include <avr/io.h>
16
#include <inttypes.h>
17
#include <util/delay.h>
18
#include <stdio.h>
19
#include <stdlib>
20
21
volatile unsigned char value;
22
23
void usart_init();
24
void usart_send();
25
26
int main() {
27
  
28
  usart_init();
29
30
        usart_send();
31
        
32
     return 0;
33
}  
34
35
void usart_init()
36
{
37
  //Baudrate einstellen in Baudraten-Register
38
  UBRR0H = (uint8_t)(UBRR_VAL>>8);
39
        UBRR0L = (uint8_t)UBRR_VAL;
40
        
41
  //Enable Recceiver and Transmitter
42
  UCSR0B = (1<<TXEN0);
43
  
44
  //Einstellen des Frame-Formates auf 8data-, 2stop-bits
45
  UCSR0C = (0<<USBS0) | (1<<UCSZ00) | (1<<UCSZ01);
46
}
47
48
void usart_send()
49
{
50
   while (!(UCSR0A & (1<<UDRE0)))    // warten bis Senden moeglich ist
51
   {}
52
   uint8_t wert = 'A';
53
   UDR0 = wert;
54
}

Kann doch nicht so schwer sein. Hoffe jemand spielt mal den Lehrer für 
mich. ;-)

Mfg
Max

von Karl H. (kbuchegg)


Lesenswert?

Max K. schrieb:
> Hey Leute,
>
> ich habe einen ArduinoMega2560 auf den Tisch bekommen und soll damit
> eine Verbindung zum PC-Terminal aufbauen. Hab an UART gedacht und mich
> versucht, aber das Signal was durchgegeben wird, ist nur Blödsinn.

'Blödsinn' bedeutet im Regelfall, dass das hier

> #define F_CPU 2000000UL    // Systemtakt in Hz

nicht stimmt.
Dein µC wird nicht mit 20Mhz getaktet.

AVR Checkliste: UART/USART

von Georg W. (gewe)


Lesenswert?

Wenn der Takt wirklick 20MHz ist, dann stimmt IMHO das Define nicht:

> #define F_CPU 2000000UL    // Systemtakt in Hz

Das sind für mich nur 2MHz (2.000.000)

von Max K. (max_blanket)


Lesenswert?

F_CPU 2000000UL sind doch aber 2MHz oder hab ich da nen totalen 
Denkfehler?
Und die Fuse für CLKDIV8 ist gesetzt, also 16MHz(eigentliche Frequenz) 
durch 8 --> 2 MHz und somit müsste ich das Programm doch auch auf 2MHz 
setzen, oder?

von Karl H. (kbuchegg)


Lesenswert?

Max K. schrieb:
> F_CPU 2000000UL sind doch aber 2MHz oder hab ich da nen totalen
> Denkfehler?

Ne, stimmt schon. Ich hab die 0-en nicht gezählt sondern geschätzt.
Mea culpa

> Und die Fuse für CLKDIV8 ist gesetzt, also 16MHz(eigentliche Frequenz)
> durch 8 --> 2 MHz und somit müsste ich das Programm doch auch auf 2MHz
> setzen, oder?

Wieder die Fragestellung:
Hast du das kontrolliert, ob dein µC mit 2Mhz arbeitet?

(Siehe Link, wie man die Kontrolle auch ohne Messgeräte machen kann)

von Konrad S. (maybee)


Lesenswert?

Karl Heinz Buchegger schrieb:
> Hast du das kontrolliert, ob dein µC mit 2Mhz arbeitet?

Berechtigte Frage! Arduino Mega2560 laufen im Auslieferungszustand mit 
16MHz.

von Karl H. (kbuchegg)


Lesenswert?

Konrad S. schrieb:
> Karl Heinz Buchegger schrieb:
>> Hast du das kontrolliert, ob dein µC mit 2Mhz arbeitet?
>
> Berechtigte Frage! Arduino Mega2560 laufen im Auslieferungszustand mit
> 16MHz.

Vertrauen ist gut, Kontrolle ist besser.

WEnn ich für jeden der hier behauptet hat sein µC läuft ganz sicher mit 
der Frequenz die er angegeben hat, einen Euro kriegen würde, wär ich 
zwar kein gemachter Mann, aber für ein schönes Wochenende würde es schon 
reichen.

von Max K. (max_blanket)


Lesenswert?

Ja, das habe ich geprüft. Er läuft mit 2MHz.

von Max K. (max_blanket)


Lesenswert?

Habs zur Sicherheit nochmal mit 16MHz probiert und mit 9600Baud. Und 
laut Datenblatt muss ich rechen:
Frequenz/(16*Baudrate) = UBBR

Kam aber nichts vernünftiges bei rum. -.-

von spess53 (Gast)


Lesenswert?

Hi

>Kam aber nichts vernünftiges bei rum. -.-

Einen TTL-RS232-Wandler hast du aber zwischen Arduino und PC?

MfG Spess

von Max K. (max_blanket)


Lesenswert?

Wollte es über den USB-Anschluss machen. Müsste ja nach einigen 
Beschreibungen hier funktionieren.
Und er sendet auch im richtigen Intervall. Bloß die Zeichen, die 
ankommen, sind falsch.

von Christoph (Gast)


Lesenswert?

Hast Du mal in die Arduino-Bibliothek geguckt? Die können das ja von 
Haus aus mit Serial.write und Serial.print.

von Max K. (max_blanket)


Lesenswert?

Über den Arduino-Code bekomme ich es auch hin das analoge Signal 
einzulesen und die Messwerte am Terminal auszuspucken. Aber ich soll 
alles in C schreiben. Das ist mein Problem.

von Max K. (max_blanket)


Lesenswert?

Hat sich erledigt. Hab es hinbekommen mit der UART-Übertragung. Jetzt 
muss nur noch mein ADC-Signal richtig ausgelesen werden und ich bin 
glücklich. Danke für die Hilfestellungen. ;)

von Konrad S. (maybee)


Lesenswert?

Max K. schrieb:
> Hab es hinbekommen mit der UART-Übertragung.

Lass uns nicht neugierig sterben! Woran lag es?

von Max K. (max_blanket)


Lesenswert?

Die Berechnung der Baudrate, die ich oben im Code verwendet hatte, 
scheint nicht zu stimmen. Hab es jetzt mit der setbaud.h versucht und es 
läuft alles. Hatte die obigen Formeln in einem Tutorial gefunden und 
einfach so darauf vertraut. Keine Ahnung, ob die einfach nicht 
funktionieren oder einfach nicht zu meinem restlichen Code passten.


hier der eue Code:
1
#define F_CPU 16000000    // Systemtakt in Hz
2
3
#define BAUD 9600      // Baudrate
4
5
#include <avr/io.h>
6
#include <inttypes.h>
7
#include <util/delay.h>
8
#include <stdio.h>
9
#include <stdlib.h>
10
#include <util/setbaud.h>
11
12
void usart_init();
13
int usart_send(unsigned char zeichen);
14
15
int main() {
16
  
17
  usart_init();
18
        while(1)
19
        {
20
              char text = 't';
21
              usart_send(text);
22
              _delay_ms(500);
23
        }
24
     return 0;
25
}  
26
27
void usart_init()
28
{
29
      
30
  //Baudrate einstellen in Baudraten-Register
31
  UBRR0H = UBRRH_VALUE;;
32
        UBRR0L = UBRRL_VALUE;
33
        
34
        #if USE_2X
35
        /* U2X-Modus erforderlich */
36
        UCSR0A |= (1 << U2X0);
37
        #else
38
        /* U2X-Modus nicht erforderlich */
39
        UCSR0A &= ~(1 << U2X0);
40
        #endif
41
  
42
        //Enable Recceiver and Transmitter
43
  UCSR0B = (1<<TXEN0);
44
  
45
  //Einstellen des Frame-Formates auf 8data-, 2stop-bits
46
  UCSR0C = (0<<USBS0) | (1<<UCSZ00) | (1<<UCSZ01);
47
}
48
49
50
int usart_send(unsigned char zeichen)
51
{
52
   while (!(UCSR0A & (1<<UDRE0)))    // warten bis Senden moeglich ist
53
   {}
54
          UDR0 = zeichen;
55
 
56
}

Ich muss jetzt nur noch daran arbeiten, dass ich den vom ADC 
ausgelesenen Wert über das UART zurückgeben kann.^^

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.