www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Atmega644 -Daten senden über Usart


Autor: Alex (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo

ich habe folgendes Problem. Ich benutze einen Atmega644 und will über 
die Usart daten schreiben. Leider bekomme ich aber nur nullen zurück 
(mittels Free Serial Prot Monitor). Der mC ist mit einem 14.756 Quarz 
geregelt und die F_CPU ist auf 14745600 HZ eingestellt.Hier der 
Quelltext:


uart.c :
#include "uart.h"
void init_uart(void)
{
int baud = BAUD;
  #if F_CPU <= 1000000UL
   UBRR0H = (uint8_t) ((F_CPU / (8 * baud)) - 1)>>8;
   UBRR0L = (uint8_t) (F_CPU / (8 * baud)) - 1;
  #else
   UBRR0H=(uint8_t)((F_CPU / (16 * baud)) - 1)>>8;
   UBRR0L=(uint8_t)(F_CPU / (16 * baud)) - 1;
  #endif

  UCSR0C = (1<<UCSZ01) | (1<<UCSZ00);    // Asynchron 8N1
  UCSR0B = (1<<TXEN0) | (1<<RXEN0);      // tx & rx enable
}

void uart_putc(unsigned char c)
{
    while (!(UCSR0A & (1<<UDRE0)))  /* warten bis Senden moeglich */
    {}
   UDR0 = c;
}

uart.h :
#ifndef uart_h
#define uart_h
#include<avr/io.h>
#define BAUD 9600UL
#define UBRR_VAL ((F_CPU+BAUD*8)/(BAUD*16)-1)   // clever runden

void init_uart(void);
int uart_putc(unsigned char c);
void uart_puts (char *s);

#endif




main.c :
#include<stdio.h>
#include<avr/io.h>
#include <util/delay.h>
#include "uart.h"


int main(void)
{
   init_uart();
  _delay_ms(10);
  uart_putc('=');

  while(1)
  {
    uart_putc('=');
  }
  return 0;
}

Jemand eine Idee ?

Vielen Dank im voraus

Alex

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Die Fuses sind nicht auf Quarz-Oszillator eingestellt.

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

Bewertung
0 lesenswert
nicht lesenswert
Alex wrote:

>   #if F_CPU <= 1000000UL
>    UBRR0H = (uint8_t) ((F_CPU / (8 * baud)) - 1)>>8;
>    UBRR0L = (uint8_t) (F_CPU / (8 * baud)) - 1;
>   #else
>    UBRR0H=(uint8_t)((F_CPU / (16 * baud)) - 1)>>8;
>    UBRR0L=(uint8_t)(F_CPU / (16 * baud)) - 1;
>   #endif

Hä?

Die Baudratenberechnung ist doch völlig unabhängig von der tatsächlichen 
Taktfrequenz immer gleich, oder ist das bei einem 644 anders? Das 
einzige was einen Unterschied machen könnte, wäre wenn U2X gesetzt wird. 
Aber das ist in deinem Code nicht der Fall.

Autor: Alex (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Beim Quarz habe ich den Fuse auf
Ext. Crystal Osc. 8.0-    MHz; Start-up time: 16K CK + 65 ms

stehen.
und Karl du hast recht den Teil
UBRR0H = (uint8_t) ((F_CPU / (8 * baud)) - 1)>>8;
UBRR0L = (uint8_t) (F_CPU / (8 * baud)) - 1;

hätte ich auch weglassen können da mein Programm hier nie hinspringen 
wird. Aber ich verstehe trotzdem nicht wieso ich nur 0 zurückbekommen 
(egal was ich an die uart_putc() übergebe es kommen nur 0 an.

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Kontrolliere, ob dur F_CPU korrekt gesetzt hast. Code anders 
strukturiert und mit bewährter Berechnung aus AVR-GCC-Tutorial:

uart.c

/*** uart.c ***/
#include <avr/io.h>
#include "uart.h"

void init_uart(void)
{
  UBRR0H = (unsigned char)(UBRR_VAL>>8);
  UBRR0L = (unsigned char)(UBRR_VAL);
  UCSR0B = (1<<TXEN0) | (1<<RXEN0);      // tx & rx enable
  UCSR0C = (1<<UCSZ01) | (1<<UCSZ00);    // Asynchron 8N1
}

void uart_putc(unsigned char c)
{
  while (!(UCSR0A & (1<<UDRE0)))
  {
    /* warten bis Senden moeglich */
  }
  UDR0 = c;
}

uart.h

/*** uart.h ***/
#ifndef uart_h
#define uart_h

#define BAUD 9600UL          // Baudrate

#ifndef F_CPU
#warning "F_CPU war noch nicht definiert, wird nun nachgeholt mit 14745600UL"
#define F_CPU 14745600UL    // Systemtakt in Hz
// Definition als unsigned long beachten
// Ohne UL ergibt Fehler in der Berechnung
#endif
 
// Berechnungen
#define UBRR_VAL ((F_CPU+BAUD*8)/(BAUD*16)-1)   // clever runden
#define BAUD_REAL (F_CPU/(16*(UBRR_VAL+1)))     // Reale Baudrate
#define BAUD_ERROR ((BAUD_REAL*1000)/BAUD)      
// Fehler in Promille, 1000 = kein Fehler
 
#if ((BAUD_ERROR<990) || (BAUD_ERROR>1010))
#error Systematischer Fehler der Baudrate grösser 1% und damit zu hoch! 
#endif

void init_uart(void);
void uart_putc(unsigned char c);
#endif /* uart_h */

main.c

/*** main.c ***/
#include <avr/io.h>
#include <util/delay.h>
#include "uart.h"

int main(void)
{
  init_uart();
  _delay_ms(10);

  uart_putc('#'); // vor while

  while(1)
  {
    uart_putc('=');  // in while
  }

  return 0;
}


Autor: Alex (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke für die schnelle Antwort!

Alex

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.