UART-Fehler :(

Gast #542732
Lesenswert?

Hallo!

Ich möchte - so wie es im Tutorial beschrieben ist - über die RS232 von 
meinem STK500 das Zeichen "x" ausgeben.

Klappt jedenfalls nicht: Kompilierfehler: undefined UCR, UBRR, usw.

#include <inttypes.h>
#include <avr/io.h>

#define F_CPU 4000000
#define UART_BAUD_RATE 9600

int main (void)
{


UCR |= (1<<TXEN);

UBRR = F_CPU / (UART_BAUD_RATE * 16L) - 1;




while (! (USR & (1<<UDRE)))
{
}

UDR = 'x';

}


Woran kann das liegen?

Woher weiß ich die Taktfrequenz vom µC?
#542746
Lesenswert?

M@cFreak wrote:
>
> Woran kann das liegen?

Welchen Prozessor benutzt du?

Danach holst du dir von Atmel das Datenblatt und siehst
nach, wie die bewussten Register in deinem Prozessor
heissen. Je nach AVR heissen die ein klein wenig anders.

>
> Woher weiß ich die Taktfrequenz vom µC?

Wenn du nichts gemacht hast, dann läuft der
Prozessor wahrscheinlich auf 1Mhz mit internem Takt.
Mach dich schon mal darauif gefasst, dass eine stabile
RS232 damit nicht funktionieren wird.

Der andere Fall ist: Du hast auf externen Quarz oder
Quarzoszillator umgestellt. Dann steht auf dem Quarz
bzw. Oszillator drauf, wie schnell er taktet.
Gast #542754
Lesenswert?

ich habe einen ATmega8515, bin mir nicht sicher, dass ich nichts 
verstellt habe. Habe nämlich schon ein paar Programme auf ihm laufen 
gehabt.

ich verwende das STK500. Da ist doch ein Quarz drauf....Weiß aber nicht 
wie der taktet
Gast #542761
Lesenswert?

habe es nun so abgeändert:



#include <inttypes.h>
#include <avr/io.h>

#define F_CPU 4000000
#define UART_BAUD_RATE 9600

int main (void)
{


UCSRB |= (1<<TXEN);

UBRRL = F_CPU / (UART_BAUD_RATE * 16L) - 1;




while (! (UCSRB & (1<<TXEN)))
{
}

UDR = 'x';

}

Gast #542782
Lesenswert?

was heißt bunt genug...kannst du mir vllt. helfen, was in dem Datenblatt 
in der Tabelle "Examples of UBRR Settings for commoncly used oscillator 
frequencies" die zahlen 41 83 usw unter "U2x =1" sein sollen? ist das 
Hex, was in das Register reingeschrieben werden muss???
#542850
Lesenswert?

Vergiss die Tabelle.
Du hast doch eine schöne Formel in die du nur
die Werte einsetzen musst (eigentlich macht das
sogar der Compiler) und schon kriegst du die
richtigen Werte raus.

Aber du kannst ja spasseshalber einfach mal einen
Taschenrechner nehmen und deine Zahlen einsetzen
und schaun was dabei rauskommt.
Die Zahl dann probehalber mal auf Hex umrechnen
und dann beides (dezmal und hex) mit den
Angaben im Datenblatt vergleichen.
#542990
Lesenswert?

Hallo zusammen!

Also, ich habe auch kein Glück mit der UART. Ich bin leider auch 
Anfänger und hoffe, Ihr könnt mir helfen. Das mit der Taktfrequenz habe 
ich auch nicht ganz verstanden. Ja, die Formel habe ich gesehen.
[UBRR = Taktfrequenz / (16 *Baudrate)-1]

Leider weiß ich nicht, mit welcher Frequenz mein AVR Butterfly getaktet 
wird (32KHz für RTC) und ob und wie ich die Interne Taktfrequenz ändern 
kann. Liegt daran... bin Anfänger.

Wäre super, wenn Ihr mir weiterhelfen könnt...

Danke!!

Gruß Christian




#include <avr/interrupt.h>
#include <avr/io.h>
#include <avr/iom169p.h>
#include <avr/portpins.h>
#include <avr/sfr_defs.h>
#include <stdint.h>
#define BAUD 9600
#define FOSC 1843200  //Taktgeschwindigkeit 1,8 Mhz
#define MYUBRR FOSC/16/BAUD-1  //what ever that mean... Formel???

// Receive Interrupt
ISR(USART0_RX_vect ) // veraltet: SIGNAL(SIG_OVERFLOW0)

{
// ISR: Zeichen wurde empfangen
  while ( !( UCSR0A & (0x20)) ); //Warten bis alles empfangen wurde = 
UART Data empty
//  UDR0 = UDR0 + 1; // Gesendet: 0x01 Antwort: 0xFF
  UDR0 = 0x01;   // Gesendet: 0x01 Antwort: Endlosschleife 20 04 3F 20 
3F 44 80 10 20 3F 04...
  //Frage, warum bekomme ich bei 0x01 eine Endlosschleife???
}

//Zeichen wurde komplett gesendet
ISR(USART0_TX_vect ) // veraltet: SIGNAL(SIG_OVERFLOW0)
{


}

void USART_Init (unsigned int ubrr)
{
// zuerst Baudrate setzen
  UBRR0H = (unsigned char) (ubrr>>8);
  UBRR0L = (unsigned char) (ubrr);
//nun Sender und Empfänger initialisieren
  UCSR0A = 0x00;
/*
 RXC
 TXC
 UDRE
 Frame Error
 DOR
 USart Parity Error
 Double USART Transmission Speed
 MPCM: Multi processor Comm. Mode
*/

  UCSR0B = 0xF8;
/*
 RXCIE  RX Complete Interrupt Enable
 TXCIE  TX Complete Interrupt Enable
 UDRIE  USART Data Register Empty IE
 RXEN  Receiver Enable
 TXEN  Transmitter Enable
 UCSZ2  Character Size (Number of Databits
 RXB8  Receive Data Bit 8
 TXB8   Transmit Data Bit 8
*/

//Frameformat setzen: 8 Datenbits, 1 Stopbits

  UCSR0C = 0x86;

/*
 ----  No Funktion
 UMSEL USART Mode Select (Synch / ASynch)
 UMP1  Parity Mode
 UMP2  Parity Mode
 USBS  Stop Bit Select
 UCXZ1 Character Size
 UCXZ0 Character Size
 UCPOL Clock Polarity (only synch Mode)
*/
}

// UART main

int main(void)
{
  DDRD = 0xff;    //enable PortD as output
  sei();        //enable Interrupt
  USART_Init (MYUBRR);

  while (1)
  {

  };

}
#543093
Lesenswert?

Christian Beuge wrote:
> Hallo zusammen!
>
> Anfänger und hoffe, Ihr könnt mir helfen. Das mit der Taktfrequenz habe
> ich auch nicht ganz verstanden. Ja, die Formel habe ich gesehen.
> [UBRR = Taktfrequenz / (16 *Baudrate)-1]

Ist nicht weiter schwer.
Eine UART arbeitet in einem fixen Zeitraster.
Dieses Zeitraster wird durch 2 Faktoren bestimmt
* zum einen die gewünschte Baudrate,
* zum anderen die fixe Taktgeschwindigkeit des Prozessors.

Stell es dir einfach so vor: Die UART muss zwischen dem
Versenden von einzelnen Bits gewisse Wartezeiten einhalten.
Zum einen bestimmt natürlich die gewünschte Baudrate wie
lange (in Zeiteinheiten) die UART 'Däumchen drehen' muss.
Zum anderen bestimmt natürlich die vorhandene Taktfrequenz
wie schnell die UART 'Däumchen drehen kann'. Ergo muss
man irgendwann mal ausrechnen, wieviele 'Däumchen gedreht
werden müssen', damit eine bestimmte Zeit vergeht.

Genau das macht die Formel.
Sie rechnet aus, wie oft die UART in einer Schleife laufen
muss, bis die für eine bestimmte Baudrate notwendige Wartezeit
zwischen 2 Bits abgelaufen ist.

>
> Leider weiß ich nicht, mit welcher Frequenz mein AVR Butterfly getaktet
> wird (32KHz für RTC) und ob und wie ich die Interne Taktfrequenz ändern
> kann. Liegt daran... bin Anfänger.

Steht im Datenblatt.
Gewöhn dich daran. Du wirst das Datenblatt noch oft brauchen.

Laut Datenblatt arbeitet dein Mega169 mit 1Mhz Taktfrequenz
(leider auf internem Oszillator. Der ist leider meist seht
ungenau. Ob damit eine vernünftige Verbindung mittels RS232
zusatande kommt, ist fraglich. Aber möglich).

>
> Wäre super, wenn Ihr mir weiterhelfen könnt...

Schreib am Anfang kein so 'kompliziertes' Programm, das mittels
Interrupt Zeichen verschickt. Machs dir einfach.
Und im übrigen solltest du dch an die Beispiele im Tutorial
halten. Angepasst an die Registernamen die auf deinem µC gelten.
1
#include <avr/io.h>
2
#include <stdint.h>
3

4
#ifndef F_CPU
5
#define F_CPU 1000000          /* Oszillator-Frequenz in Hz */
6
#endif
7
 
8
// Hilfsmakro zur UBRR-Berechnung ("Formel" laut Datenblatt)
9
#define UART_UBRR_CALC(BAUD_,FREQ_) ((FREQ_)/((BAUD_)*16L)-1)
10
 
11
#define UART_BAUD_RATE 9600
12

13
int main(void)
14
{
15
  UCSRB |= ( 1 << TXEN );   // UART TX einschalten
16
  UCSRC |= ( 3<<UCSZ0 );    // Asynchron 8N1
17

18
  // Baudrate setzen
19
  UBRRH = (uint8_t)( UART_UBRR_CALC( UART_BAUD_RATE, F_CPU ) >> 8 );
20
  UBRRL = (uint8_t)UART_UBRR_CALC( UART_BAUD_RATE, F_CPU );
21

22
  while( 1 ) {
23
    //
24
    // warten bis die UART 'fertig' meldet
25
    //
26
    while (!(UCSRA & (1<<UDRE)))
27
      ;
28

29
    //
30
    // und ein Zeichen senden
31
    // 
32
    UDR = 'x';
33
  }
34
}

  
Gast #543175
Lesenswert?

so. Jetzt stelle ich mal mein Beispiel rein, mit dem es auf der RS232 
SPARE von meinem STK 500 ebenfalls nicht funktioniert:

Vllt. könntet ihr mir den Fehler sagen. Ich habe übrigens keinen 
externen Oscillator/Quarz, sondern den Internen auf 4 MHz in den Fuses 
gesetzt.

----------------------------------

#include <inttypes.h>
#include <avr/io.h>

#define F_CPU 4000000

/////////////////// Im Terminalprogramm wird eine Baudrate von 9600 
eingestellt

int main (void)
{



UCSRB |= (1<<TXEN);              //Senden aktivieren
UCSRC |= (1<<URSEL)|(3<<UCSZ0);  //

UBRRH = 00;                      //Baudrate einstellen
UBRRL = 25;


//UCSRA |= (1<<U2X);               //UCSRA: Bit "U2x" setzen     BRAUCHE 
ICH DAS??????


while (!(UCSRA & (1<<UDRE)))  /* warten bis Senden moeglich 
*/
{
}

UDR = 'x';             //x zum senden ins Datenregister
while (1);
}




Vielen Dank
Gast #543207
Lesenswert?

> BRAUCHE ICH DAS??????
Nein, das ist in dem Falle (für 9600 Baud) sogar falsch! U2X verdoppelt 
die Baudrate bei gleichen UBRRx-Settings. Du hast damit also 19200 Baud.

Außerdem: Bist Du sicher, dass die Einstellungen vom Hyperterminal exakt 
mit denen des Controllers übereinstimmen (Stopbits, Parity)?

Außerdem ist der interne Oszillator der AVRs für asynchrone 
Datenübertragung nicht wirklich geeignet, weil er u.U. zu ungenau ist 
und eine starke Temperaturdrift hat. Es kann Dir also auch passieren, 
dass bei korrekten Einstellungen am PC nur Murks ankommt. Wenn es 
zuverlässig laufen soll, nimm einen Quarz. Mit dem internen Oszi ist das 
alles Glückssache.
Gast #543215
Lesenswert?

Also. Danke erstmal für deine antwort.

Ich habe - wie du geschrieben hast - nun einen Quarz von 8 MHz. Somit 
auch 8 MHz in den Fuses eingestellt.
Jetzt kommentiere ich das mit dem U2X noch aus,....habe nun 9600 
Baudrate: Terminal-Einstellungen: Data: 8bit, Parity: none, Stop: 1 bit.

Stimmt das soweit?

danke
Gast #543237
Lesenswert?

Ich versuche nachzuvollziehen, warum du solche Probleme beim Einstieg 
hast.
Auf dieser Seite gibt es ein Tutorial da steht eine ganze Menge drin 
aber nicht speziell zum STK500 aber der Stolperstein Fuseproblematik ist 
angesprochen.

Im Datenblatt ab Seite 151 findest du C-Programmcode zur Initialisierung 
der UART und zum Senden, den kannst du übernehmen (copy und Paste)
Im AVR-Studio in der Hilfe ist die Beschreibung des STK500 und speziell
Description of User RS232 Interface da sind Bilder (ok nicht bunt) zum 
Anschluß und es steht da welche du benutzen mußt.
Dein Terminalprogramm mußt du nur auf die Werte der Verbindung 
einstellen
(Baudrate,Stopbits, Parität) Das solltest du selbst wissen wie das geht.

Bis jetzt habe ich nur die Erklärung, daß du die dir zur Verfügung 
stehenden Informationsquellen nicht ordentlich nutzt. Ändere das, sonst 
wird das ein sehr frustrierender Einstieg.

Wenn du ins Forum postest sind Sätze wie "...ebenfalls nicht 
funktioniert:"
nicht sehr hilfreich. Beschreibe was passiert, bei welchen 
Einstellungen.
Gast #543244
Lesenswert?

aber wenn meines richtig ist und deines richtig ist, dann müsste doch 
auch meins funktionieren und kein Unterschied von der Funktion gegeben 
sein....

Jedenfalls funktioniert die Lösung aus dem Tutorial NICHT
#543248
Lesenswert?

M@cFreak wrote:
> aber wenn meines richtig ist und deines richtig ist, dann müsste doch
> auch meins funktionieren und kein Unterschied von der Funktion gegeben
> sein....
>
> Jedenfalls funktioniert die Lösung aus dem Tutorial NICHT

Doch die funktioniert.
Wenns bei dir nicht funktioniert, dann liegt der Fehler
in einem Bereich, der ausserhalb des Tutorials liegt:
* irgendwas in der Hardware
* Kabel falsch rum beschaltet
* am häufigsten aber: Die angegebene Taktfrequenz stimmt
  nicht mit der Realität überein.

Was mich zb. verblüfft ist, dass du als Anfänger in noch
nicht mal einer Stunde einen Quarz eingebaut hast und den
auch noch korrekt gefused hast.
Allerdings gibt mir der Satz zu denken:
"Somit auch 8 MHz in den Fuses eingestellt."

Das klingt nicht danach, als ob du den externen Quarz
aktiviert hast. Das hört sich eher an als ob du die CLKDIV
Fuse ausgeschaltet hast. Dein µC läuft dann zwar mit 8Mhz
aber immer noch am internen Oszillator.
Gast #543253
Lesenswert?

Der Quarzeinbau ist bei dem STK500 ja nur gesteckt. Ich habe also einen 
8 MHz Quarz reingesteckt. Als nächstes habe ich in meinem Programmcode
UBRRL = 51 gesetzt. Dann habe ich unter "Fuses" das Häkchen bei "Ext. 
Crystal/Resonator Medium Frequ.; Start-up time: 1K CK + 64 ms;" gesetzt, 
welches vorher bei int RC Osc. 4 MHz stand.

Dann habe ichs kompiliert, Terminal geöffnet, Auf RS232 SPARE umgesteckt 
und Nix empfangen.

so ist der Stand der dinge
#543264
Lesenswert?

@ M@cFreak

>UBRRL = 51 gesetzt. Dann habe ich unter "Fuses" das Häkchen bei "Ext.
>Crystal/Resonator Medium Frequ.; Start-up time: 1K CK + 64 ms;" gesetzt,
>welches vorher bei int RC Osc. 4 MHz stand.

Hoffentlich ist auch die DIV8 Fuse NICHT programmiert.

MFG
Falk
Gast #543267
Lesenswert?

>Dann habe ichs kompiliert, Terminal geöffnet, Auf RS232 SPARE umgesteckt
>und Nix empfangen.
Du sagst weder welche Einstellungen du im Terminal hast, noch ob du dir 
die Hilfe im AVRStudio durchgelesen hast.
Da ist nämlich auch zu sehen, daß du eine Verbindung zwischen den 
Portpins und den RX/TX Anschlüssen des STK500 machen mußt. Kann es sein 
das du dies vergessen hast?
Gast #543271
Lesenswert?

#include <inttypes.h>
#include <avr/io.h>

#define F_CPU 8000000

/////////////////// Im Terminalprogramm wird eine Baudrate von 9600 
eingestellt

int main (void)
{



UCSRB |= (1<<TXEN);              //Senden aktivieren
UCSRC |= (1<<URSEL)|(1<<USBS)|(1<<UCSZ1);  //

UBRRH = 0;                      //Baudrate einstellen
UBRRL = 51;


while (!(UCSRA & (1<<UDRE)))  /* warten bis Senden moeglich 
*/
{
}

UDR = 'x';             //x zum senden ins Datenregister
while (1);
}





Hier nochmal der momentane Code
#543299
Lesenswert?

Ändere mal dein Programm um:

Lass den µC in einer Endlosschleife ständig senden
1
  while( 1 ) {
2
    while (!(UCSRA & (1<<UDRE)))  /* warten bis Senden moeglich */
3
    {
4
    }
5

6
    UDR = 'x';             //x zum senden ins Datenregister
7
  }
8
}

Und dann begibst du dich mit einem Voltmeter auf Fehlersuche.
Du kannst auch eine LED + Vorwiderstand (330 Ohm) nehmen.
Damit überprüfst du mal direkt an den Prozessorpins (PD0,
PD1), ob der Prozessor sendet. Mit einer LED müsstest du
an einem der Pins ein deutliches Flackern sehen.

Wenn du das Flackern hast, dann verfolgst du es weiter
(über alle Verbindungen), bis du am Stecker angelangt bist.


(Led + Vorwiderstand: Ein Bein von der Led kommt an den
Prozessorpin, das andere an den Vorwiderstand. Von dort
gehts weiter zum Widerstand und das andere Bein vom Widerstand
kommt fix an Masse. Probier aber aus, ob du die Led richtig
rum gepolt hast. Wenn du das frei Led Beinchen an +5V hälts,
muss sie leuchten).


Gast #543302
Lesenswert?

Hier der aktuelle Code. Den obigen könnt ihr vergessen. War en Fehler 
drin.

#include <inttypes.h>
#include <avr/io.h>

#define F_CPU 8000000

/////////////////// Im Terminalprogramm wird eine Baudrate von 9600 
eingestellt

int main (void)
{



UCSRB |= (1<<TXEN);              //Senden aktivieren
UCSRC |= (1<<URSEL)|(3<<UCSZ0);  //

UBRRH = 00;                      //Baudrate einstellen
UBRRL = 51;


while (!(UCSRA & (1<<UDRE)))  /* warten bis Senden moeglich 
*/
{
}

UDR = 'x';             //x zum senden ins Datenregister
while (1);
}
Gast #543317
Lesenswert?

Also...ich habe nun bei meinem ATmega8515 eine Leuchtdiode wie folgt 
drangehalten:  An Pin11 (Transmit-Pin) die Anode der Diode und an Pin 20 
(mit vorwiderstand) die Katode der Diode.
Sie Leuchtet! von flackern ist nichts zu sehen.
Gast #543339
Lesenswert?

achso, du meinst diese While-Schleife....die habe ich schon drin...

Dass er praktisch nonstop dieses Zeichen schickt: ich sagte, mit der 
"Modifikation" leuchtet meine Diode permanent. (wird wohl flackern, ist 
eben nicht zu sehen).

Habe leider kein Oszi zur verfügung.
#543348
Lesenswert?

M@cFreak wrote:
> achso, du meinst diese While-Schleife....die habe ich schon drin...
>
> Dass er praktisch nonstop dieses Zeichen schickt: ich sagte, mit der
> "Modifikation" leuchtet meine Diode permanent. (wird wohl flackern, ist
> eben nicht zu sehen).
>

Dann geh mit der Baudrate runter.
300 Baud musst du sehen können.

> Habe leider kein Oszi zur verfügung.
#543383
Lesenswert?

Dann stimmt am Timing was nicht.

Also nochmal: Taktfrequenz kontrollieren

#define F_CPU  8000000
#include <avr/io.h>
#include <utils/delay.h>

int main()
{
  int i;

  DDRB = 0xFF;  // Port B auf Ausgang oder wo du halt sonst
                // ein paar LED drann hast

  while( 1 ) {
    PORTB = 0xFF;

    for( i = 0; i < 100; ++i )
      _delay_ms( 10 );

    PORTB = 0x00;

    for( i = 0; i < 100; ++i )
      _delay_ms( 10 );
  }
}

Die Leds müssen im Sekundentakt blinken (das kann man auch
mit freiem Auge noch gut abschätzen).

#543423
Lesenswert?

Hast du debug compiliert, oder den Optimizer eingeschaltet.
Damit die delay Funktionen klappen, muss der Optimizer
eingeschaltet sein.

Im AVR Studio findest sich das im 2-ten Menüpunkt
ganz unten (hab keines da, drum kann ich nicht nachschauen
wie der heist: Irgendwas mit Project - Properties oder so
ähnlich).

Stell die Optimierung auf -Os

Wenn du dann immer noch 1.9 Sekunden hast, dann
läuft der µC offensichtlich nicht mit 8 Mhz.
#543450
Lesenswert?

M@cFreak wrote:
> ok habe das gemacht. Schwer mit der Stoppuhr zu messen.

Das brauchts auch nicht.
Meistens hat man ja ein Vielfaches.
Wenn also im Pgm 8 Mhz steht und der µC macht in Wirklichkeit
4Mhz, dann sind die Leds anstelle von 1 Sekunde deren 2
eingeschaltet.
Läuft der µC gar nur auf 1 Mhz, dann leuchten die Led
ganze 8 Sekunden statt 1

Das erkennt auch ein Blinder.

> Jedenfalls länger als 1 Sekunde blinken die.

Schlecht.

http://www.mikrocontroller.net/articles/AVR_Fuses

Da du einen Quarz benutzt ist die richtige Einstellung
bei dir "external Crystal".

Gast #543462
Lesenswert?

> ok habe das gemacht. Schwer mit der Stoppuhr zu messen.

Miss den Puls deines AVR ;-)

Setz dir eine vernünftige Zeitspanne fest z.B. 20 Sekunden. Zähle wie 
oft es in der Zeitspanne blinkt. Teile Zählwert durch Zeitspanne und du 
hast die Frequenz.
#543468
Lesenswert?

Stefan wrote:
>> ok habe das gemacht. Schwer mit der Stoppuhr zu messen.
>
> Miss den Puls deines AVR ;-)
>
> Setz dir eine vernünftige Zeitspanne fest z.B. 20 Sekunden. Zähle wie
> oft es in der Zeitspanne blinkt. Teile Zählwert durch Zeitspanne und du
> hast die Frequenz.

Aber Achtung: Das Programm lässt die LED 1 Sekunde eingeschaltet
und 1 Sekunde ausgeschaltet. Das ergibt eine Soll-Frequenz
von 0.5 Herz.

Und weil es wichtig ist: Die Zeiten stimmen nur dann, wenn
im Compiler die Optimierung eingeschaltet ist.
Gast #543475
Lesenswert?

Ja die Optimierung ist eingeschaltet. Habe ich so gemacht, wie es 
Karl-Heinz beschrieben hat.

Möchte vielmehr sicher gehen, dass der Mikrocontroller "einfach" über 
den Quarz taktet. Anscheinend tut er das ja nicht, habe ja vorhin scho 
ngeschrieben, dass die Daten in das Terminal weiterhin strömen, wenn ich 
den Quarz rausziehe!


danke
#543480
Lesenswert?

M@cFreak wrote:
> Ja die Optimierung ist eingeschaltet. Habe ich so gemacht, wie es
> Karl-Heinz beschrieben hat.
>
> Möchte vielmehr sicher gehen, dass der Mikrocontroller "einfach" über
> den Quarz taktet. Anscheinend tut er das ja nicht, habe ja vorhin scho
> ngeschrieben, dass die Daten in das Terminal weiterhin strömen, wenn ich
> den Quarz rausziehe!
>

Oha.
Das ist aber ein deutliches Indiz dafür, dass
der µC auf 'interner Oszillator' läuft.
Gast #543564
Lesenswert?

und nun zum Empfangen vom terminal. Mein Ziel ist es, ein Zeichen ins 
Terminal zu schreiben und dieses dann an "PORTB" (Leuchtdioden) 
ausgeben, damit ich seh, ob was bei µC ankommt:

Würde das funktionieren?
-------------------------------------------------------------
#include <avr/io.h>


int main (void)

{
DDRB = 0xFF;

UCSRB |= (1<<RXEN);
UBRRH = 00;                      //Baudrate auf 9600 einstellen
UBRRL = 51;


while (!(UCSRA & (1<<RXC)));

PORTB = UDR;
}
----------------------------------------------------------------
Danke!
#543579
Lesenswert?

Und wieder die übliche Frage:
Was funktioniert denn nicht?

('funktioniert nicht' ist keine vernünftige Fehlermeldung)


PS: Du solltest dir wirklich angewöhnen, solche
Dinge in Schleifen zu packen.

  while( 1 ) {
    // warte auf ein Zeichen
    while (!(UCSRA & (1<<RXC)));

    // und am Port das Bitmuster ausgeben
    PORTB = UDR;
  }
}


PS2: Einrückungen sind kein Luxus! Sie helfen die
Struktur eines Programmes schneller zu erfassen.
#543601
Lesenswert?

M@cFreak wrote:
> hm ich kann schon garnichts auf mein Terminal schreiben.

Das ist bei Hyperterminal normal.
Da ist standardmässig das 'lokale Echo' ausgeschaltet.
Das heist: Du siehst nicht was du tippst.
Das heist aber nicht, dass die Zeichen nicht rausgehen.

Die Zeichen gehen sehr wohl raus. Das Standardverfahren
ist: Die Zeichen gehen raus und der Empfänger schickt
die empfangenenn Zeichen sofort wieder zurück. Und erst
dann zeigt das Terminal sie an.
Das hat den Vorteil, dass man eine unterbrochene Verbindung
sofort erkennt.

Man kann allerdings auf den meisten Terminals auch ein
sog. 'lokales Echo' einschalten. Dann schreibt das Terminal
mit, was es so rausgeschickt hat.
#543648
Lesenswert?

Probier das mal aus:
1
#include <avr/io.h>
2
#include <stdint.h>
3

4
#ifndef F_CPU
5
#define F_CPU 8000000          /* Oszillator-Frequenz in Hz */
6
#endif
7
 
8
// Hilfsmakro zur UBRR-Berechnung ("Formel" laut Datenblatt)
9
#define UART_UBRR_CALC(BAUD_,FREQ_) ((FREQ_)/((BAUD_)*16L)-1)
10
 
11
#define UART_BAUD_RATE 9600
12

13
int main(void)
14
{
15
  char c;
16

17
  UCSRB |= ( 1 << TXEN ) | ( 1 << RXEN );
18
  UCSRC |= ( 1 << URSEL) | ( 3<<UCSZ0 );    // Asynchron 8N1
19

20
  // Baudrate setzen
21
  UBRRH = (uint8_t)( UART_UBRR_CALC( UART_BAUD_RATE, F_CPU ) >> 8 );
22
  UBRRL = (uint8_t)UART_UBRR_CALC( UART_BAUD_RATE, F_CPU );
23

24
  while( 1 ) {
25
    // warte auf ein Zeichen
26
    while (!(UCSRA & (1<<RXC)))
27
      ;
28

29
    // das Zeichen holen
30
    c = UDR;
31

32
    // warten bis die UART 'fertig' meldet
33
    while (!(UCSRA & (1<<UDRE)))
34
      ;
35

36
    // und das Zeichen zurückschicken
37
    UDR = c;
38
  }
39
}

  
Gast #544275
Lesenswert?

Tut er aber anscheinend nicht. Und das kann verschiedene Ursachen haben.

Der Vorschlag von Karl heinz (1) läuft darauf hinaus, einen anderen - 
bekannt zuverlässigen - Code einzusetzen, um die grundsätzliche Funktion 
der Entwicklungsumgebung zu testen.

Ich sehe als Schwachpunkt deines Codes (2) die mehrfach angesprochene 
fehlende Endlosschleife. Dein Code ist ruckizucki fertig und main() wird 
verlassen.

U.U. so schnell, dass PORTB zwar gesetzt wird aber der µC sich einen 
Mückenwimpernschlag später schon in einen undefinierten Zustand verrannt 
hat.

(1) Beitrag "Re: UART-Fehler :("
(2) Beitrag "Re: UART-Fehler :("
#544298
Lesenswert?

Stefan wrote:
> Tut er aber anscheinend nicht. Und das kann verschiedene Ursachen haben.
>

Ich denke mal die Hauptursache ist das fehlende

  UCSRC |= ( 1 << URSEL) | ( 3<<UCSZ0 );    // Asynchron 8N1


aber um ehrlich zu sein bin ich jetzt zu faul im
Datenblatt nachzusehen, wofür die UCSZ0 und UCSZ1 Bits
gut sind (Was URSEL macht weiss ich auswendig :-)

Das ist meine Standard-UART-Initialisierung. Wenn ich eine
UART brauche, dann hole ich mir den Code mit Cut&Paste
in das aktuelle Projekt und fertig. Von dem Code weiss
ich dass er funktioniert und ich sehe wirklich keinen
Sinn darin, jedesmal wieder für dieselbe Funktionalität
die Bits aus dem Datenblatt raussuchen zu müssen.

Aus demselben Grund bin ich auch gegen die Zuweisung von 51
an das Baudratenregister allergisch. Ich setzte einfach
die Formel mittels Cut&Paste ein, achte darauf dass der
F_CPU Wert stimmt und mach ein #define für die gewünschte
Baudrate.
Ich mach mir doch nicht die Finger mit schnöden
Taschenrechnertricks ( FOSC/16/BAUD-1 selber ausrechnen, igitt)
oder raussuchen aus Tabellen schmutzig.
Diese 'Drecksarbeit' überlasse ich dem Compiler. Ich kümmere
mich lieber darum wo die Daten herkommen, die über
die UART müssen.

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