mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik UART Probleme mit AT90CAN128


Autor: Simon (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo zusammen,
ich habe ein STK501 mit einem AT90Can128 Controller.
Zur inbetriebnahme meines UARTS Habe ich mal das Tutorial genutzt, 
möchte beim drücken einer Taste auf dem Board das Zeichen x an mein 
Terminalprogramm des PC`s senden.
Habe einen 4 MHz Quarz und auch die Fuse Bits dementsprechend 
eingestellt. Lieder bekomme ich beim drücken der Taste immer nur Müll am 
Terminalprogramm raus, wie bsp. zwei Zeilen voller yyyyyyy
Woran kann das noch liegen?? Mache schon den ganzen Tag daran rum und 
bekomme es einfach nicht zum rennen...
Bin verzweifelt....
Hier ist der Code:

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

#define F_CPU 3686400     /* Quarz mit 3.6864 Mhz */

int main (void)
{

//Port A und B initialisieren um Taster und LED`s zu steuern.
DDRB= 0xff;    //Ganzen Port B als Ausgang setzten
DDRA= 0x00;    //Ganzen Port A als Eingang setzten
PORTA= 0xff;  //Pull ab Widerstände für gesamten Port A aktiv



//USART Contollregister initialisieren siehe S.197 Datenblatt
                     /* USART-Init 19200 Baud bei 4MHz für AT90CAN128 */
UBRR1H  = 0;                           // Highbyte ist 0
UBRR1L  = 12;                // Lowbyte ist 12 ( dezimal ) ergibt 19,2k 
bei 4Mhz Clocktakt
UCSR1B |= ( 1 << TXEN1 );    // UART TX einschalten (Sendebereit machen)
UCSR1C |= ( 0 << UMSEL1 )|(0<<UPM1)|(0<<USBS1)|( 3<<UCSZ1 );  // 
Asynchron modus Character Size 8-bit,2 Stopbit, kein Parity


  while (1)
  {

  if (!(PINA & (1<<PA0)) )  //Wenn PIN 0 von Port A 0 ist dann....
    {


      // setzte Pin4 an Port B (LED)
      PORTB |= (1<<PB4);
    while (!(UCSR1A & (1<<UDRE1)))  /* warten bis Senden moeglich 
solange UDRE1 flag 0 ist */
       {
    asm volatile ("nop");            }

      UDR1 = 'x';   /* schreibt das Zeichen x auf die Schnittstelle */
    }

      else
      {
        PORTB &= ~(1<<PB4);
      }

  }
}

Kann mir da irgendwer helfen? Wäre wirklich froh darüber. Viel kann es 
nicht sein, da wenn ich die Taste drücke empfange ich ja was, leider 
aber nur scheiss....
Vielen Dank schon mal

Autor: Jörg X. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
"#define F_CPU 3686400 " -- das stimmt zwar nicht, aber wenn du das 
korrigierst, kannst du es auch benutzen (s.u.)

die Schleifen, in denen du auf ein bestimmtes Bit wartest, kannst du 
leer lassen:
while( !(UCSR1A & (1<<UDRE1)))
    ;
#ifndef F_CPU
#    define F_CPU 4000000UL //korrekten Wert eintragen!
#endif
#define BAUD((rate)) (F_CPU/(16*rate) -1)
UBRR1H = BAUD(19200)>>8;
UBRR1L = BAUD(19200);
// ... (0<<x) hat keine Auswirkungen
// 3<<UCSZ1 ist definitiv falsch, 
// UCSR1C |= ( 3<<UCSZ0 ); // 'korrigiert'
UCSR1C |= ((1<<UCSZ1)|(1<<UCSZ0)); // korrekt und besser lesbar ;)
Für '8N1' brauchst du eigentlich nichts extra einzustellen, das sind die 
Defaults nach dem Reset ("Initial Value" im Datenblatt)

hth. Jörg

Autor: Simon (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Jörg,

vielen dank für deine Antwort!
Leider haben die Änderungen auch nicht den gewünschten Erfolg gebracht, 
ich habe immer noch komische Zeichen im Terminalprgram!
Mir ist auch nicht ganz klar, warum ich die Baudrate über deine Rechnung 
angeben soll und nicht einfach über UBRR1 = 12;
Das müsste doch normal bei 4Mhz 19200 Baud ergeben!?!?
Wo könnte der Fehler jetzt noch liegen? Das ist echt zum verzweifeln, 
kann doch so schwer nicht sein!
Danke
Gruß
Simon

Autor: tex (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hast Du ggf noch den 1:8 Clock-Teiler gesetzt? Der ist von Hause aus 
immer aktiv.

Autor: Simon (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mhh gute Frage,

jedenfalls habe ich Ihn nicht bewust ausgeschaltet. Wie schalte ich den 
Timer aus? Ist das ein Register? Oder Muss man das im M-File machen?
Gruß
Simon

Autor: tex (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
... ich klicke einfach das Häkchen raus ... Umpf. Ist ein Fuse-Bit!

Autor: _CH_ (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

>hast Du ggf noch den 1:8 Clock-Teiler gesetzt? Der ist von Hause aus
>immer aktiv
in diese "Falle" bin ich auch schon mal getappt.
Warum hat der eigentlich den 1:8 standardmäßig aktiviert - macht ja 
nicht wirklich Sinn, oder?

Gruß,
Christian

Autor: tex (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Kompatibilät zu 103 glaube ich

Autor: Simon (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ist der Teiler aktiviert wenn das Häkchen gesetzt ist oder wenn es 
gelöscht ist?? Ist immer so en Scheiss mit den Null aktiven Fuses...???

Autor: tex (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
wenn Du das AVR-Studio benutzt, ist der Teiler aktiv, wenn das Häkchen 
gesetzt ist

Autor: Simon (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Funktioniert trotzdem nicht, so ein Scheiss!!
Ich hätte nicht gedacht das es so ein Problem ist ein Zeichen auf eiem 
UART auszugeben :-(

Autor: _CH_ (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
der Controller läuft aber schon mit externem Quarz und nicht mir dem 
standardmäßigem RC-Oszillator oder? (Fuses!)

Autor: _CH_ (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
sorry, wer lesen kann ist im Vorteil. Hast du ja gemacht.

Autor: tex (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ist es auch nicht.
Vielleicht suchst Du das Problem an der falschen Stelle
ggf ein daueraktiver Watchdog (fuse gesetzt) ohne WD-Routine
ein defekter XX232, oder die Cmos version mit Elkos statt keramischen 
Kondensatoren, oder ein nicht Cmos-XX232 mit Cmos-Beschaltung ...
hast Du z.B. mal die echte Frequenz an deinem CAN128 gemessen? Du kannst 
dazu den Takt an einen Port (PD7??) weiterleiten.

Autor: Simon (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ja hab ich gemacht, hat genau 3,7 Mhz, das passt alles...
Ist ein externer 4Mhz Quarz.
Was mich auch wundert ist das nach dem beschreiben des
UCSR1C |= (( 1<<UCSZ11 )|(1<<UCSZ10));
Registers werden auch die UBRR1H flags 9 und 10 beschrieben?!?!
Ich setzte sie einfach in der nächsten Zeile mit
UBRR1H  = 0;
wieder zurück, sonst passt ja meine Datenrate mit 19.2k bei 4 MHz nicht, 
dazu muss ich ja nur UBRR1L mit 12 beschreiben siehe:
UBRR1L  = 12;

Irgendwas stimmt mit dem Takt nicht oder mein Code hat einen morts Bug..

Please help me!
Danke

Autor: tex (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
nein es ist PC7

<< Ist immer so en Scheiss mit den Null aktiven Fuses...??? >>

Dieses Statement macht mich mistrauisch. Woher weisst Du, dass Du 
überhaupt die Richtige Einstellung für die Clock hast?

Autor: tex (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
3,7 Mhz? Was genau soll da noch aus der seriellen Schnittstelle 
rauskommen?

Autor: Jörg X. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
- Warum ich die Rechnung in den Code schreibe? -- Warum soll ich denn 
den Registerwert ausrechen, wenn der Compiler das doch selber kann (das 
muss der  nicht  AVR ausrechnen)
- Die CKDIV8 -Fuse ist von Haus ausprogrammiert, damit der µC bei jeder 
erlaubten KOmbination aus Spannung und Takt losläuft, sonst könnte man 
den evtl. nicht ISP-Programmieren

- Bist du sicher, dass der AVR mit 4Mhz läuft? (Woher kommen die: 
STK-500, Quarz, internerRC-Oszillator...)
- Benutzt du die richtige Serielle schnittstelle?

hth. Jörg

kannst du mal das aktulle Programm posten ? (möglichst in [c ] [/c 
]-Tags(ohne Leerzeichen ;) ))

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> ...werden auch die UBRR1H flags 9 und 10 beschrieben?!?!
Wer?

Autor: tex (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
probier mal UBRR1L  = 11 !

Autor: _CH_ (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>3,7 MHz... das passt alles... Ist ein externer 4Mhz Quarz.
widerspricht sich meiner Meinung nach, lässt aber auf 3.6864 Mhz Quaz 
schließen...

Autor: Simon (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo nochmal, ja wie gesagt ich verwende ein STK501 Board. Auf dem STK 
500 also dem unteren Teil ist ein 4Mhz Quarz gesteckt. Wenn ich am Pin 7 
messe, messe ich 3,7 Mhz.
Externen Clock habe ich über die Fuses auf
Ext. Cristal Osc. 3-8 Mhz Startuptime 65ms gestellt, den Teilerfaktor 
austeschaltet.
Der aktuelle Code sieht so aus:

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

#ifndef F_CPU
#define F_CPU 4000000UL     /* Quarz mit 3.6864 Mhz */
#endif

int main (void)
{

//Port A und B initialisieren um Taster und LED`s zu steuern.
DDRB= 0xff;    //Ganzen Port B als Ausgang setzten
DDRA= 0x00;  //Ganzen Port A als Eingang setzten
PORTA= 0xff;  //Pull ab Widerstände für gesamten Port A aktiv

//USART Contollregister initialisieren siehe S.197 Datenblatt

/* USART-Init 19200 Baud bei 4MHz für AT90CAN128 */


UBRR1L  = 12;                         // Lowbyte ist 12 ( dezimal ) 
ergibt 19,2k bei 4Mhz Clocktakt
UCSR1B |=  (1 << TXEN1);    // UART TX einschalten (Sendebereit machen)
UCSR1C |= (( 1<<UCSZ11 )|(1<<UCSZ10));  // Asynchron modus Character 
Size 8-bit,1 Stopbit, kein Parity
UBRR1H  = 0;     //UBRR1H auf 0 zurücksetzten

  while (1)
  {

    if (!(PINA & (1<<PA0)) )  //Wenn PIN 0 von Port A 0 ist dann....
    {

           PORTB |= (1<<PB4);    // setzte Pin4 an Port B (LED)


    while (!(UCSR1A & (1<<UDRE1)));  /* warten bis Senden moeglich

              UDR1 = 'x';


    }

      else
      {
        PORTB &= ~(1<<PB4);
      }


  }
}


Liegts am Code, am Quarz, an den Fuses?!?!

Danke für eure Hilfe!!!!!

Autor: tex (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Eben, und dafür muss UBRR1L  = 11 sein.

Autor: Jörg X. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
3,7MHz -- Ist der Takt vom stk-500, jaa auch dem must du wohl sagen, 
dass du einen Quarz benutzen willst, und NEIN 3,7 Mhz sind nicht ok, 
wenn man 4 haben will ;) .
Die Sache mit den UBRRnH Bits steht unter "Known Issues" (dt. bekannte 
Fehler) in der Doku des SIMULATORs! (AVR-Studio-help), hat also keine 
Auswirkungen auf den AVR.
In der AVR-Studio Software heißt Haken: Programmierte (aktive) Fuse, 
igorier einfach mal, ob das jetzt 0 oder 1 heißt.

Autor: Simon (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Also was stimmt jetzt??
Soll ich
#define F_CPU 4000000UL
schreiben oder
#define F_CPU 3700000UL
Wie soll ich dem dem sagen das ich einen 4 Mhz Quarz gesteckt 
habe??Zumindest steht das auf dem Quarzgehäuse.
Das Problem liegt sicher an dem Takt, ich denke der Code wäre sonst ok 
oder?

Autor: Simon (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jipiiiiiii!!!!!!
Es geht fast, ich hab jetzt das
UBRR1L mit 11 beschrieben und jetzt kommt mein Zeichen an!!!!!
Leider aber bestimmt 80 mal wenn ich die Taste drücke.
Wie bekomme ich das jetzt hin, das es nur einmal ankommt???

Hey voll cool, vielen Dank für euer aller Hilfe, echt Top, ihr habt mir 
einen riesen Gefallen getan. Bin gerade an meiner Diplomarbeit und dreh 
noch durch mit dem UART...
Vielleicht gibts jetzt noch nen Trick das ich nur ein Zeichen bekomme!!
Vielen Dank

Gruß
Simon

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Crystal Oscillator ist nicht gleich Crystal! Außerdem musst Du afaik 
einen Jumper umstecken, um einen Quarz im STK500 nutzen zu können.

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Simon wrote:
> Vielleicht gibts jetzt noch nen Trick das ich nur ein Zeichen bekomme!!
> Vielen Dank
Der Trick heißt "eindeutige Tasterzustandsauswertung" bzw. 
"Tastenentprellung". Da gibts hier tausende Threads zu (gib mal 
"Entprellung" in die Suche ein).

Autor: Jörg X. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
such nach "enprellung", in der Codesammlung und in den AVR-tutorials

bei dem #define F_CPU gehört DIE Frequenz hin, mit der der AVR 
tatsächlich läuft, natürlich ;)

hth. Jörg

Autor: _CH_ (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Vielleicht gibts jetzt noch nen Trick das ich nur ein Zeichen bekomme!!
den Taster kürzer drücken

Autor: Simon (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Tip Top, werd mal schauen ob ich das mit der entprellten Taste 
hinbekomme. Man kann sich kaum vorstellen das die kleinen Taster so 
prellen können :-)

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das hat in Deinem Fall primär gar nichts mit dem Prellen zu tun, sondern 
mit Deiner Abfrage. Du fragst nur ab, ob die Taste gedrückt ist. Und 
wenn das der Fall ist, dann wird gesendet, bis die Taste wieder 
losgelassen wurde. Und selbst bei einem "schnellen" Drücken ist der 
Kontakt mindestens einige zig ms geschlossen. Das reicht auf jeden Fall 
für mehrere Zeichen aus. Deshalb auch der Hinweis auf "eindeutige 
Tasterzustandsauswertung". Und dazu genügt es i.d.R. schon, bei der 
Abfrage des Tasterzustandes den jeweils aktuellen Zustand zu speichern 
und beim nächsten mal die Aktion nur dann durchzuführen, wenn der Taster 
gedrückt ist, aber im vorherigen Zyklus nicht gedrückt war (also beim 
letzten Mal 1 und jetzt 0). Alle anderen Zustände werden ignoriert.

Autor: Simon (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hey Jonny
Stimmt, da hast Du auch wieder recht.
Mal sehen ob eine solche Abfrage hin bekommen, hab eben auch noch nicht 
wirklich viel µC programmiert.
Falls Du eine solche Abfrage gerade aus dem Ärmel schütteln kannst, 
kannst Du sie gerne posten :-)

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hab doch schon alles beschrieben. Du musst nur jedes Mal, wenn Du den 
Taster abfragst, den Zustand des Tasters speichern (also ne 1 für "nicht 
gedrückt" und ne 0 für "gedrückt"). Und senden tust Du nur dann, wenn 
der gespeicherte alte Zustand (von der jeweils vorhergehenden Abfrage) 1 
und der aktuelle 0 ist. Das geht z.B. mit einer UND-Verknüpfung des 
alten Zustandes mit dem invertierten neuen Zustand (1 & !0 == 1, alle 
anderen Kombinationen ergeben 0). Für das Speichern und Vergleichen 
brauchste halt eine Variable. Der Rest ist basic (damit meine ich 
NICHT die Programmiersprache!)

Autor: Simon (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Funktioniert bestens :-)
Danke

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.