RS232 Verbindung funktioniert nich

OP #4469192
Lesenswert?

Hallo zusammen,

ich habe meinen Laptop mit meinem ATMega2561 per RS232-Verbindung 
(USB-to-Serial (RS232) Converter Model: UC-232A von Aten) verbunden. 
Leider klappt die Kommunikation nicht. Wenn ich Daten per HTERM sende 
blinkt das LED auf dem Converter. Daten gehen also raus. Sobald Daten 
auf dem ATMega2561 empfangen werden soll ein LED toggeln. Kommen keine 
Daten toggeln drei andere LEDs. Leider toggeln nur die drei LEDs, es 
kommen keine Daten an.

Mein Programm wird fehlerfrei kompiliert. Wo liegt der Fehler? Vielen 
Dank für eure Hilfe.

// CPU clock
#define F_CPU 8000000

// Baudrate
#define BAUD 19200UL

// Berechnung der Baudrate
#define UBRR_VAL ((F_CPU+BAUD*8) / (BAUD*16)-1)

// Präprozessor Makros für Ausgänge
#define set_bit(port,portbit) ((port) |= (1<<portbit))          // PORTB 
|= (1<<PB6);      -> PB6 high
#define clr_bit(port,portbit) ((port) &= ~(1<<portbit))         // PORTB 
&= ~(1<<PB6);     -> PB6 low
#define tog_bit(port,portbit) ((port) ^= (1<<portbit))      // PORTB ^= 
(1<<PB6);      -> Portbit abwechselnd high oder low

// Präprozessor Makros für Eingänge
#define input_bit(portpin,portbit) ((portpin) & (1<<portbit))    // 
(PIND & (1<<PD2))  -> while(!(PIND & (1<<PD2))); Solange kein 
Eingangssignal

// includes
#include <avr/io.h>
#include <util/delay.h>
#include <stdlib.h>

void USART_INIT(void)
{
  // Im Datenblatt des ATMega2561 steht auf Seite 400 die 
Registerbeschreibung für die USART
  // Baudrate einstellen
  UBRR0H = (unsigned char)(UBRR_VAL>>8);
  UBRR0L = (unsigned char)UBRR_VAL;
  // Receiver und Transmitter einschalten
  UCSR0B = (1<<RXEN0)|(1<<TXEN0);
  // Frame Format: Asynchron 8N1
  UCSR0C = (1<<UCSZ01)|(1<<UCSZ00);
}

/* Zeichen empfangen */
uint8_t uart_getc(void)
{
  while (!(UCSR0A & (1<<RXC0)))   // warten bis Zeichen verfuegbar
  ;
  return UDR0;                   // Zeichen aus UDR an Aufrufer 
zurueckgeben
}

int main(void)
{
  // Init UART
  USART_INIT();
  // PB7, PB6 ist Ausgang
  DDRB = ((1<<PB7 | 1<<PB6));
  DDRF |= ((1<<PF0) | (1<<PF1) | (1<<PF2) | (1<<PF3));

  set_bit(PORTB,PB6);
  tog_bit(PORTF,PF0);
  _delay_ms(1000);
  _delay_ms(1000);
  _delay_ms(1000);
  _delay_ms(1000);
  _delay_ms(1000);
  _delay_ms(1000);
  tog_bit(PORTF,PF0);
  _delay_ms(1000);

  // Endlosschleife
  while(1)
  {
    if ( (UCSR0A & (1<<RXC0)) )
    {
      // Zeichen wurde empfangen, jetzt abholen
      uint8_t c;
      c = uart_getc();
      tog_bit(PORTF,PF0);
      _delay_ms(1000);
      _delay_ms(1000);
      // hier etwas mit c machen
      /*switch(c)
      {
      case 'A':
      tog_bit(PORTF,PF0);
      break;
      }*/
    }
    else
    {
      // Kein Zeichen empfangen, Restprogramm ausführen...
      //tog_bit(PORTF,PF1);
      tog_bit(PORTF,PF2);
      tog_bit(PORTF,PF3);
      _delay_ms(1000);
      _delay_ms(1000);
    }

  }
}
Gast #4469780
Lesenswert?

In dieser Zeile
1
#define UBRR_VAL ((F_CPU+BAUD*8) / (BAUD*16)-1)

addierst du immerhin einen Wert von 153600 auf deine 8000000 
Taktfrequenz drauf. das sind etwa 1,9% Abweichung vom Zielwert. Deshalb 
vielleicht?
#4469881
Lesenswert?

Als erstes sollte man über Zahlenbereiche und Überläufe nachdenken. 
8000000 lässt sich nicht als Integer darstellen. Das muss ein Long sein. 
Ein Blick in zB die Fleury Lib kann helfen:

/** @brief  UART Baudrate Expression
 *  @param  xtalcpu  system clock in Mhz, e.g. 4000000UL for 4Mhz
 *  @param  baudrate baudrate in bps, e.g. 1200, 2400, 9600
 */
#define UART_BAUD_SELECT(baudRate,xtalCpu)  (((xtalCpu) + 8UL * 
(baudRate)) / (16UL * (baudRate)) -1UL)

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