Forum: Mikrocontroller und Digitale Elektronik uart Kommunikation


von mario (Gast)


Lesenswert?

Hallo, ich versuche übers Terminal etwas zu Senden und zu Empfangen. 
Leider klappt das überhaupt nicht. Habe mich schon durch etliche Seiten 
gelesen, aber das funktioniert nicht mal mit nem Atmel Code. Was habe 
ich übersehen? Baudratenproblem? (Atmega 2560)
1
// AVR306: Using the AVR UART in C
2
// Routines for polled USART
3
// Last modified: 02-06-21
4
// Modified by: AR
5
6
/* Includes */
7
#include <avr/io.h>
8
9
/* Prototypes */
10
void USART0_Init( unsigned int baudrate );
11
unsigned char USART0_Receive( void );
12
void USART0_Transmit( unsigned char data );
13
14
15
16
#ifndef F_CPU
17
/* In neueren Version der WinAVR/Mfile Makefile-Vorlage kann
18
   F_CPU im Makefile definiert werden, eine nochmalige Definition
19
   hier wuerde zu einer Compilerwarnung fuehren. Daher "Schutz" durch
20
   #ifndef/#endif 
21
 
22
   Dieser "Schutz" kann zu Debugsessions führen, wenn AVRStudio 
23
   verwendet wird und dort eine andere, nicht zur Hardware passende 
24
   Taktrate eingestellt ist: Dann wird die folgende Definition 
25
   nicht verwendet, sondern stattdessen der Defaultwert (8 MHz?) 
26
   von AVRStudio - daher Ausgabe einer Warnung falls F_CPU
27
   noch nicht definiert: */
28
#warning "F_CPU war noch nicht definiert, wird nun nachgeholt mit 4000000"
29
#define F_CPU 4000000UL  // Systemtakt in Hz - Definition als unsigned long beachten 
30
                         // Ohne ergeben sich unten Fehler in der Berechnung
31
#endif
32
 
33
#define BAUD 4800UL      // Baudrate
34
 
35
// Berechnungen
36
#define UBRR_VAL ((F_CPU+BAUD*8)/(BAUD*16)-1)   // clever runden
37
#define BAUD_REAL (F_CPU/(16*(UBRR_VAL+1)))     // Reale Baudrate
38
#define BAUD_ERROR ((BAUD_REAL*1000)/BAUD) // Fehler in Promille, 1000 = kein Fehler.
39
 
40
#if ((BAUD_ERROR<990) || (BAUD_ERROR>1010))
41
  #error Systematischer Fehler der Baudrate grösser 1% und damit zu hoch! 
42
#endif 
43
44
45
46
/* Main - a simple test program*/
47
int main( void )
48
{
49
  USART0_Init( UBRR_VAL ); /* Set the baudrate to 19,200 bps using a 3.6864MHz crystal */
50
51
  for(;;)       /* Forever */
52
  {
53
        
54
    USART0_Transmit( USART0_Receive() ); /* Echo the received character */
55
  }
56
}
57
58
/* Initialize UART */
59
void USART0_Init( unsigned int baudrate )
60
{
61
  /* Set the baud rate */
62
  UBRR0H = (unsigned char) (baudrate>>8);                  
63
  UBRR0L = (unsigned char) baudrate;
64
  
65
  /* Enable UART receiver and transmitter */
66
  UCSR0B = ( ( 1 << RXEN0 ) | ( 1 << TXEN0 ) ); 
67
  
68
  /* Set frame format: 8 data 2stop */
69
  UCSR0C = (1<<USBS0)|(1<<UCSZ01)|(1<<UCSZ00);              //For devices with Extended IO
70
  //UCSR0C = (1<<URSEL)|(1<<USBS0)|(1<<UCSZ01)|(1<<UCSZ00);   //For devices without Extended IO
71
}
72
73
74
/* Read and write functions */
75
unsigned char USART0_Receive( void )
76
{
77
  /* Wait for incomming data */
78
  while ( !(UCSR0A & (1<<RXC0)) )   
79
    ;                      
80
  /* Return the data */
81
  return UDR0;
82
}
83
84
void USART0_Transmit( unsigned char data )
85
{
86
  /* Wait for empty transmit buffer */
87
  while ( !(UCSR0A & (1<<UDRE0)) )
88
    ;                       
89
  /* Start transmittion */
90
  UDR0 = data;               
91
}

von spess53 (Gast)


Lesenswert?

Hi

>Leider klappt das überhaupt nicht

Was klappt nicht? Kommen komische Zeichen oder garnichts?

>#define F_CPU 4000000UL

Wo kommen die 4MHz her?

MfG Spess

von Georg G. (df2au)


Lesenswert?

"Es klappt überhaupt nicht" ist herrlich diffus. Kannst du das etwas 
näher spezifizieren? Kommt nichts aus dem UART heraus? Kommt nur Müll 
heraus? Zeigt der Empfänger Müll?

von mario (Gast)


Lesenswert?

Es kommt gar nichts. Theoretisch sollte ja quasi ein Echo zurück kommen. 
Um die Frequenz zu messen hatte ich mal einen Port ein aund aus 
geschaltet, das waren ziemlich genau 4 MHz.

von Georg G. (df2au)


Lesenswert?

Wenn du ein Scope an den TxD Pin hälst, kommt dort ein Signal heraus?

von mario (Gast)


Lesenswert?

RxD und TxD sind beide high, wenn ich tippe sehe ich auch die Daten vom 
PC mit dem Scope auf der Leitung, zurück kommt nichts.

von Georg G. (df2au)


Lesenswert?

Wird denn jemals ein Zeichen empfangen? Toggele doch ein Portbit in der 
UART-Rx-Routine. Dann hast du das Problem schon mal auf die Hälfte 
reduziert.

Und dann was anderes: Du hast "etwa 4MHz gemessen". Wie erzeugst du den 
Takt? Bei einem externen Quarz solltest du dir mal den Aufdruck ansehen, 
welche Frequenz es wirklich ist. Deine "Baudrate liegt daneben" 
Fehlermeldung beruht nämlich auf der Annahme, dass FCPU richtig 
definiert ist.

von mario (Gast)


Lesenswert?

Habe noch mal im Datenblatt gesehen, dass der interne RC osc 8 MHz hat, 
also die gemessenen 4 MHz waren ja logischerweise nur die Hälfte. Wenn 
ich jetzt in der main-Schleife nur
1
USART0_Transmit(0x51);
 ausführe, kommt ein Q im Terminal an. Das funktioniert jetzt also. Nur 
die andere Richtung nicht.

von Route_66 H. (route_66)


Lesenswert?

Hallo!
Der interne RC-Oszillator könnte etwas daneben liegen, der PC ist da 
manchmal toleranter.

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.