www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik 8051*AT89C51CC03


Autor: Stefan Schön (stefan0784)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
HI Leute,

ich habe ein Problem mit meiner seriellen Schnittstelle.
Ich kann mein Board über die serielle Schnittstelle programmieren.
Jedoch kann ich keine Daten über meine serielle Schnittstelle mit meinem
Rechner austauschen. Im Debugger hat alles soweit problemlos
funktioniert.
Ich stell mal meinen Quelltext rein - über konstruktive Kritik und eure
Hilfe würde ich mich freuen.

Programm besteht aus Unterprogrammen für das übertragen und das
Empfangen der Zeichen. Die globale Freigabe erfolgt in der Main-Routine.


#include "at89c51cc03.h"
#include "stdio.h"
#include "MyVariable.h"

extern void LCD(void);


//---------------------------------------------------------------------- 
----------------------------------
void UART_Init(void)
{
  SCON |= 0xD8;  //9-bit UART; REN = 1; TB8: 0=logic 0 in 9th bit
1=logic 1 in 9th bit (Transmitter Bit)
          //RB8: cleared by hardware if 9th bit received is logic 0
  SBUF = 0x00;   //Speicher leeren
  TMOD |= 0x20;  //Timer1 in Mode 2 = 8-bit auto reload
  TH1 = 0xF3;    //Zähler mit Baudrate 9600/4800 = 243
  TL1 = 0xF3;    //Zähler mit Baudrate 9600/4800 = 243
  ES = 1;      //Enable Serial Interrupt
}

//---------------------------------------------------------------------- 
----------------------------------
void UART_Senden(unsigned char DatenS)
{
  SBUF = DatenS;        //Schreiben der Daten in SBUF
  while (TI != 1);        //TI wird von Hardware nach Übertragungsende
gesetzt
  TI = 0;
}

//---------------------------------------------------------------------- 
----------------------------------
void UART_Empfangen(void)
{
  BefehlvPC = SBUF;
  if ((BefehlvPC > 0x20) && (BefehlvPC < 0x7F))  //Nur Zeichen aus
Alphabet
  {
    Aktualisieren = 1;    //Ausgabe LCD
  }
}

//------------Interrupt Routine für
UART---------------------------------------------------
void interrupt(void) interrupt 4
{
  if (RI == 1)    //Wenn Daten von UART empfangen
  {
    UART_Empfangen();
    RI = 0;
  }
}

Autor: Ralf (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Du verwendest für den Empfang den Interrupt und fürs Senden Polling, das 
geht so nicht. Du musst entweder beides über Polling oder im Interrupt 
machen, weil der serielle Interrupt eigentlich zwei Interrupts in einem 
beinhaltet, nämlich senden und empfangen. Und man kann das nur paarweise 
aktivieren.
Wenn du das Senden über Interrupt machen willst, dann definiere ein Bit, 
welches der Senderoutine anzeigt, dass wieder gesendet werden darf.
Ausserdem solltest du darauf verzichten, die LCD-Ausgabe u.ä. im 
Interrupt zu machen, weil du sonst u.a. Timing-Probleme bekommst. Auch 
hier wieder ein Bit, welches anzeigt, dass etwas ausgegeben werden soll, 
und das Ausgeben in der main machen.

Ralf

Autor: Ralf (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ups, sehe gerade, dass im Interrupt "Aktualisieren = 1" steht, hab zu 
schnell gelesen, sorry. Aber den Mischbetrieb Polling/Interrupt musst du 
trotzdem vermeiden.

Ralf

Autor: Ralf (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Und wenn wir schon dabei sind:

- wo wird der Timer gestartet?
- wo wird EA (globale Interrupt-Freigabe) aktiviert?

Ralf

Autor: Stefan Schön (stefan0784)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Beides geschieht in meiner Main nachdem ich alle Initialisierungen 
durchgegangen bin.
Ich soll also TI in der ISR zurücksetzen und nicht schon in meiner 
Funktion UART_Senden?
MfG & danke schon mal für deine Hilfe

Autor: Ralf (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Beides geschieht in meiner Main nachdem ich alle Initialisierungen
> durchgegangen bin.
Ah, okay...

> Ich soll also TI in der ISR zurücksetzen und nicht schon in meiner
> Funktion UART_Senden?
Ja, genau. Und dafür setzt du in der ISR ein Bit, welches der 
UART_Senden erlaubt, das Zeichen in SBUF zu schreiben. Du machst also 
die Abfrage "Schreiben in SBUF erlaubt", wenn ja, dann SBUF beschreiben 
und Bit löschen. Solange es eben gelöscht ist, darf in SBUF nicht 
geschrieben werden.

Ralf

Autor: Stefan Schön (stefan0784)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi Leute,

ich schreib euch nochmals wegen meiner Seriellen Schnittstelle.
Ich betreibe meinen µC mit 24MHZ.
Ich bekomme jetzt zwar eine Übertragung zustande - jedoch kommt entweder 
nur Müll an an meinem Hyperterminal oder ich sehe gar nichts.
Hat jemand schon Erfahrungen mit 24MHz und serieller Datenübertragung?
(Timerwerte usw.)
Wäre nett wenn Ihr mir weiterhelfen könnt.
Kann es sein dass die 24MHz nicht am besten geeignet sind für die 
serielle Übertragung? Der Fehler der beim Auf- bzw. Abrunden entsteht 
ist doch schon relativ groß.
Hab mir die Tabelle mal runter geladen für UART und da wäre am besten 
der Quarz mit 22,1184MHz geeignet.
Danke schon mal für eure Hilfe!

MfG

Autor: Ralf (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi,

> Hat jemand schon Erfahrungen mit 24MHz und serieller Datenübertragung?
> (Timerwerte usw.)
Du fragst jetzt aber nicht nach, ob wir bereits selber gerechnet haben? 
:)
Nein, ernsthaft, die ATMEL-Datenblätter sind etwas bescheiden 
geschrieben.
Guckst du hier:

http://www.atmel.com/dyn/resources/prod_documents/...

Solltest du dir gleich speichern. Aber beachte, dass nicht alle dort 
aufgeführten Features für deinen Controller gelten, sondern dass das nur 
ein Manual für die ganze Familie ist (ATMEL-spezifisch, natürlich)!

Auf Seite 99 findest du, was du suchst. Und bevor du fragst, 11.0592 ist 
die Hälfte von 22.1184 grins

> Hab mir die Tabelle mal runter geladen für UART und da wäre am besten
> der Quarz mit 22,1184MHz geeignet.
Korrekt, das ist ein sog. Baudratenquarz, d.h. damit bekommst du die 
üblichen Baudraten fehlerfrei hin.
Übrigens, auch mit einem solchen Quarz ist es möglich, Timer-Interrupts 
zu generieren, die exakt z.B. 1ms Takt haben (falls das an anderer 
Stelle deiner Applikation notwendig sein sollte, RTC o.ä.)

Ralf

Autor: Stefan Schön (stefan0784)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Natürlich hab ich schon selber gerechnet - aber wie gesagt - hab bis 
jetzt keine Baudrate gefunden mit der die serielle Übertragung 
funktioniert. g
Ich schreib mal meinen Code mit dem ich die serielle Schnittstelle 
teste. Das komische ist dass ich ein Zeichen im SBUF empfange - jedoch 
empfange ich definif nicht das Zeichen auf dem Mikrocontroller das ich 
aus dem Hyperterminal sende. Das komische daran ist dass wenn ich das 
gesendete Zeichen zurückschicke - das Zeichen wieder korrekt dargestellt 
wird. Allerdings kann ich keine Großbuchstaben über Hyperterminal senden 
- die werden nicht erkannt. (komisch)
In dem Code frage ich erst einmal ab ob überhaupt ein Zeichen in SBUF 
geschrieben wird. Dann habe ich versucht ob das Zeichen korrekt gesendet 
wird - was allerdings nicht der Fall ist. Hab dann noch versucht ein 
kleines 'a' == 0x61 zu senden. Jedoch kommt dies auch nicht richtig an.
Daher gehe ich davon aus dass ich irgendwelche Timing-Probleme habe.

Code:


#include "at89c51cc03.h"
char uart_data = 0x00;

void main (void)
{
SCON = 0x50; /* uart in mode 1 (8 bit), REN=1 */
TMOD = TMOD | 0x20 ; /* Timer 1 in mode 2 */
TH1 = 0xF6; /* 38400 Bds at 24MHz */
TL1 = 0xF6;
ES = 1; /* Enable serial interrupt*/
EA = 1; /* Enable global interrupt */
TR1 = 1; /* Timer 1 run */
P2 = 0xFE;

while(1)
{
  if (uart_data != 0x00)
  {
    if (uart_data == 0x61)
    {
      P2 = 0x00;
    }

    SBUF = 0x61; /* Send back same data on uart*/
    uart_data = 0x00;
  }
}
}

void serial_IT(void) interrupt 4
{
  if (RI == 1)
  {
    uart_data = SBUF;

    RI = 0; /* clear reception flag for next reception */
  }

  else TI = 0; /* if emission occur */
} /* clear emission flag for next emission*/

Autor: Ralf (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hi,

na dann gucken wir uns doch die Sache mal gemeinsam an :)
Ich empfehl dir, den Anhang ausgiebig zu lesen, der ist allemal besser 
als der Scheiss, den Atmel Datenblatt nennt.

Ich gehe davon aus, das im Hyperterminal 38400, 8n1 und kein Handshake 
eingestellt ist. Desweiteren nehme ich an, dass der X2-Mode deaktiviert 
ist, und das Bit SMOD in Register PCON nicht gesetzt ist. Diese beiden 
Einstellungen beeinflussen nämlich den Clock, den der UART bekommt.

> Das komische ist dass ich ein Zeichen im SBUF empfange - jedoch
> empfange ich definif nicht das Zeichen auf dem Mikrocontroller das ich
> aus dem Hyperterminal sende.
Wie erkennst du das? Ausgabe aufs Display, oder wie?

> Das komische daran ist dass wenn ich das gesendete Zeichen zurückschicke -
> das Zeichen wieder korrekt dargestellt wird.
Das ist aus deinem Code aber nicht ersichtlich. Dort schickst du bei 
jedem Zeichen ein 'a' zurück.

> Allerdings kann ich keine Großbuchstaben über Hyperterminal senden
> - die werden nicht erkannt. (komisch)
Ja, komisch... Kann ich mir grad nicht erklären, aber hängt sicherlich 
mit den anderen Problemen zusammen, kriegen wir schon hin...

> Hab dann noch versucht ein kleines 'a' == 0x61 zu senden. Jedoch kommt
> dies auch nicht richtig an.
Jetzt blick ich es sowieso nicht mehr, weil einmal sagst du, dass das, 
was du sendest, wieder korrekt zurückkommt, Großbuchstaben wiederum 
gehen aber trotzdem nicht, und das Senden eines festen Wertes geht gar 
nicht. Was denn nun?

Also, mal der Reihe nach:

fOsc = 24 MHz
Baudrate = 38400
BRG: Timer 1, 8-Bit Autoreload

Nach der Formel:

Baudrate = ((2^SMOD) / 32) * (fOsc / (12 * (256 - TH1))

ergibt sich:

Baudrate = 1 / 32 * 24000000 / (12 * (256 - 246)
         = 6250

Das deckt sich nicht mal ansatzweise mit deinen gewünschten 38400 
(vorbehaltlich, dass ich mich nicht verrechnet habe :)

Wenn ich TH1 mit 253 ansetze, komme ich auf etwa 20000 Baud, bei 254 
komme ich auf 31250 Baud. Selbst mit gesetztem SMOD Bit kommst du auf 
Werte, die die 3%-Toleranz der Baudrate sprengen, wenn die 
Geschwindigkeit so hoch angesetzt ist.
Setz die Baudrate mal wie in der Tabelle angegeben auf 4800 Baud, d.h. 
angegebener Reloadwert für 12MHz verwenden, und mit 9600(!) Baud im 
HyperTerminal arbeiten, weil du ja nicht 12, sondern 24 MHz hast.

Eine weitere Alternative wäre, den Timer 2 anstatt Timer 1 zu verwenden, 
damit bekommst du es vielleicht hin.

Ralf

Autor: Ralf (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Und nochwas:

Wenn Variablen sowohl in der normalen Applikation als auch in Interrupts 
verwendet werden, sollten sie in C als "volatile" deklariert sein!!!

Ralf

Autor: Stefan Schön (stefan0784)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi Ralf,

dann antworte ich mal. :-)
Die EInstellungen die Du aufgezählt hast stimmen mit denen überein die 
ich eingestellt habe.
Zu deiner ersten Frage:
- Ich bekomme das Zeichen definitiv nicht das ich erstens einmal 
probiert habe das Zeichen auf einem LCD auszugeben. Dies geschieht aber 
nicht - stattdessen kommt ein nicht definiertes Zeichen an. Display habe 
ich zuvor ausprobiert mit einem fest eingestellten Zeichen und habe dies 
auch ausgegeben. Zweitens habe ich dann probiert dass wenn ein 
bestimmtes Zeichen empfangen wird ein Pin freigegeben wird an dem eine 
LED anfängt zu leuchten. Auch dies hat nicht funktioniert.

Zu deiner zweiten Frage:
- Ist aus diesem Code nicht ersichtlich - habe es aber zuvor ausprobiert 
und über RS232 und USB getestet. Beides mal kam am Hyperterminal das 
gesendete Zeichen zurück. Jedoch nur bei den oben genannten 
EInstellungen. Sobald ich eine andere Baudrate beim Hyperterminal 
eingestellt habe kam entweder nur "Müll" oder gar nichts mehr an.

Zu deinen deiner 3. und 4. Frage:
- Ist wie schon gesagt nicht ersichtlich aus dem Code den ich 
eingestellt habe. Habe aber diverse Versuche schon gestartet um den 
Problem auf die Schliche zu kommen. Den Wert für den Timer habe ich aus 
einer Tabelle - die hat sich aber wie ich herausgefunden habe als falsch 
erwiesen. Die Formel habe ich aus meinem Skript schon gekannt. Habe es 
ja auch schon mit diesen Werten versucht - jedoch kam ich so auch nicht 
weiter.
Auf die oben genannten Einstellungen bin ich eher zufällig gestossen. 
Werde ja daraus auch nicht schlau. Deswegen bin ich ja froh dass ich 
mich hier mit einem User austauschen kann der sich die Zeit mir mit 
meinen Problemen zu helfen. :-)

Werde es jetzt mal versuchen mit deinen Einstellungen zu senden.
Mal schauen ob ich in meine Hochschule noch reinkomme.
Schon einmal ein großes Dankeschön für deine Hilfe!!

MfG Stefan0784

Autor: Ralf (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi,

zu der Displaysache kann ich so im Moment nix sagen, da müsste ich die 
Software dazu sehen, weil ich nicht weiss, ob man direkt die ASCII-Werte 
der Zeichen angeben kann, oder einen Offset abziehen muss, das ist immer 
Display-spezifisch.

> Zu deiner zweiten Frage:
> - Ist aus diesem Code nicht ersichtlich - habe es aber zuvor ausprobiert
> und über RS232 und USB getestet. Beides mal kam am Hyperterminal das
> gesendete Zeichen zurück. Jedoch nur bei den oben genannten
> EInstellungen. Sobald ich eine andere Baudrate beim Hyperterminal
> eingestellt habe kam entweder nur "Müll" oder gar nichts mehr an.
Der letzte Satz macht mich stutzig, du hast dann hoffentlich auch im 
Controller den Reloadwert auf die neue Baudrate angepasst? Sonst wird 
das nix, beide Teilnehmer müssen vorab bereits wissen, wie schnell 
kommuniziert wird. Du kannst mit dem Controller auch eine automatische 
Baudratenerkennung machen, aber soweit habe ich dich noch nicht ;)

> Werde ja daraus auch nicht schlau. Deswegen bin ich ja froh dass ich
> mich hier mit einem User austauschen kann der sich die Zeit mir mit
> meinen Problemen zu helfen. :-)
> Werde es jetzt mal versuchen mit deinen Einstellungen zu senden.
> Mal schauen ob ich in meine Hochschule noch reinkomme.
> Schon einmal ein großes Dankeschön für deine Hilfe!!
Kein Problem, ich helfe gern.

Kannst ja mal schreiben, wie weit du bist bzw. ob es was gebracht hat.

Ralf

Autor: Stefan Schön (stefan0784)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Beim Display muss ich keinen Offset-Wert abziehen. Man kann direkt ein 
ASCI-Zeichen ausgeben.
Zu den Einstellungen - ich habe nach jetzt fast einwöchigem Testen und 
lesen der PDF-Dokumentation einfach mal probiert mit verschiedenen 
Werten im Timer und im Hyperterminal.
Stutzig war ich auch - das darfst Du mir glauben. g
Ich stell dann mal meinen neuen Code ein.
Habe den Timer mit dem Wert für 4800 Baud geladen, beim Hyperterminal 
habe ich 9600 eingestellt. Es wird aber leider immer noch nichts 
gesendet. Kann jetzt leider nur von Hyperterminal über USB den 
Controller testen - die Profs haben das Kabel weggeschlossen.  *D'oh*
Funktionieren tut es leider immer noch nicht - Daten werden auf jeden 
FAll gesendet - haben an den TxD und RxD Leitungen kleine LEDs 
installiert.
Es wird weder der Port2 freigegeben noch wird das Zeichen 
zurückgeschickt.


#include "at89c51cc03.h"
volatile char uart_data = 0x00;
/**
* FUNCTION_PURPOSE: This file set up uart in mode 1 (8 bits uart) with
* timer 1 in mode 2 (8 bits auto reload timer).
* FUNCTION_INPUTS: void
* FUNCTION_OUTPUTS: void
*/
void main (void)
{

SCON = 0x50; /* uart in mode 1 (8 bit), REN=1 */
TMOD = TMOD | 0x20 ; /* Timer 1 in mode 2 */
TH1 = 0xF3; /* 9600 Bds at 24MHz */
TL1 = 0xF3;
ES = 1; /* Enable serial interrupt*/
EA = 1; /* Enable global interrupt */
TR1 = 1; /* Timer 1 run */
P2 = 0xFF;

while(1)
{
  if (uart_data == 0x61)
  {
    P2 = 0x00;


    SBUF = 0x61; /* Send back same data on uart*/
    uart_data = 0x00;

  }
}
}

void serial_IT(void) interrupt 4
{
  if (RI == 1)
  {
    uart_data = SBUF;

    RI = 0; /* clear reception flag for next reception */
  }

  else TI = 0; /* if emission occur */
}

Autor: Stefan Schön (stefan0784)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hab jetzt mal noch folgendes probiert:

.
.
.
while(1)
{
  if (uart_data != 0x00)
  {
    P2 = 0x00;


    SBUF = 0x61; /* Send back same data on uart*/
    uart_data = 0x00;
.
.
.

Port 2 wird jetzt ausgeschaltet - jedoch wird kein Zeichen 
zruückgeschickt.
Sobald ich jedoch ein spezielles Zeichen abfrage funktioniert es 
allerdings nicht mehr. Also gehe ich immer noch davon aus dass ich ein 
Timing-Problem habe.
MfG Stefan

Autor: Ralf (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Du musst die letzte Spalte der Baudratentabelle beachten, SMOD-Bit in 
PCON-Register muss 1 sein. Sorry, hatte ich vergessen zu erwähnen. D.h. 
du arbeitest momentan wirklich mit 4800 Baud. Sorry.

Also noch in die Initialisierung rein:

PCON |= 0x80

Alternativ wirklich 4800 im HyperTerminal einstellen ;)

In deinem vorletzten Posting fragst du aber nur 'a' ab. Alles andere 
wird ignoriert.

Mach mal das:

while(1) {
  if (uart_data != 0x00) {
    P2++;

    SBUF = uart_data; /* Send back same data on uart*/
    uart_data = 0x00;
    }
}

Somit wird erstmal eine Echo-Funktion implementiert. Desweiteren wird 
Port2 bei jedem empfangenen Zeichen inkrementiert (falls du LEDs dran 
hast, kannste ja mitzählen :)

Ralf

Autor: Stefan Schön (stefan0784)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
So - hab mir jetzt mal nen Quarz mit 22,1184 MHz besorgt.
Hab aber genau die gleichen Probleme.

Setz jetzt mal meinen Code für 19200 Baud rein. Im Anhang gibts nen 
Shortcut vom Hyperterminal. Hab da einfach mal das Alphabet eingetippt. 
Das Echo vom µC siehst Du ja auf dem Bild.

So langsam hab ich die Befürchtung dass es nicht an meinem Quarz oder 
Timing liegt sondern an nem Bauteil meiner Platine.

Code 19200:

#include "at89c51cc03.h"
volatile char uart_data = 0x00;

void main (void)
{

SCON = 0x50; /* uart in mode 1 (8 bit), REN=1 */
TMOD = TMOD | 0x20 ; /* Timer 1 in mode 2 */
TH1 = 0xFD; /* Baudrate 19200 @ 22,1184 MHz */
TL1 = 0xFD;
ES = 1; /* Enable serial interrupt*/
EA = 1; /* Enable global interrupt */
TR1 = 1; /* Timer 1 run */
//PCON |= 0x80;    // PCON ist gerade ausgeschaltet
P2 = 0xFF;

while(1)
{
  if (uart_data != 0x00)
  {
    P2 = 0x01;

    SBUF = uart_data; /* Send back same data on uart*/
    uart_data = 0x00;
  }
}
}

void serial_IT(void) interrupt 4
{
  if (RI == 1)
  {
    uart_data = SBUF;

    RI = 0; /* clear reception flag for next reception */
  }
  else TI = 0; /* if emission occur */
}

Autor: Stefan Schön (stefan0784)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hab jetzt dann auch mal noch nen Test gemacht mit der doppelten 
Baudrate.
WIe vorher gibts im Anhang das Echo vom Hyperterminal.
Ich kann zwar kleine Buchstaben senden - empfange diese auch wieder 
zurück - allerdings kann ich keine Großbuchstaben senden. Wenn ich dann 
meine Code dahingehend verändere dass ich ein bestimmtes Zeichen abfrage 
funktioniert das ganze nicht mehr.
So langsam bin ich mit meinem Latein am Ende.

Code für Baudrate 38400:

#include "at89c51cc03.h"
volatile char uart_data = 0x00;

void main (void)
{

SCON = 0x50; /* uart in mode 1 (8 bit), REN=1 */
TMOD = TMOD | 0x20 ; /* Timer 1 in mode 2 */
TH1 = 0xFD; /* Baudrate 19200 @ 22,1184 MHz */
TL1 = 0xFD;
ES = 1; /* Enable serial interrupt*/
EA = 1; /* Enable global interrupt */
TR1 = 1; /* Timer 1 run */
PCON |= 0x80;    // Baudrate wird verdoppelt
P2 = 0xFF;

while(1)
{
  if (uart_data != 0x00)
  {
    P2 = 0x01;

    SBUF = uart_data; /* Send back same data on uart*/
    uart_data = 0x00;
  }
}
}

void serial_IT(void) interrupt 4
{
  if (RI == 1)
  {
    uart_data = SBUF;

    RI = 0; /* clear reception flag for next reception */
  }
  else TI = 0; /* if emission occur */
}

Autor: Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
ich wäre etwas vorsichtig mit der Zeile zur Baudraten-Verdopplung:

PCON |= 0x80;    // Baudrate wird verdoppelt

Manche 8051er können das, aber ob der CC03er das kann, geht aus dem 
Datenblatt NICHT eindeutig hervor:
(Neueste Version 09_08): auf S.15 gibt es zwar die Bit SMOD1 und SMOD0. 
Bei der konkreten Beschreibung des SFRs PCON auf S.36 gibt es diese Bits 
nicht mehr !! Dort sind es auf einmal reservierte Bits, die nicht 
beschrieben werden dürfen.

Autor: Stefan Schön (stefan0784)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Also laut meinem Datenblatt das ich bei Atmel runtergeladen habe steht 
im PCON Register ganz klar das SMOD1 Bit.
Beschreibung: Set to select double baud rate in mode 1, 2 or 3.
Trotzdem danke für den Hinweis.

Autor: Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Stefan,
schau mal auf S.36 nach, wo díe Power-Down-Funktion beschrieben wird.
Eindeutig ist das alles nicht.

Autor: Stefan Schön (stefan0784)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wenn mal auf Seite 67 schaust steht es ein wenig anders - gehört aber zu 
dem UART - Kapitel.

Autor: Bernd (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Teste mal den Anhang.

Gruß,

Bernd

Autor: Ralf (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Dass der zweite Versuch mit der doppelten Baudrate funktioniert, ist 
klar, weil du ja nach wie vor das SMOD-Bit setzt.

Nach der Tabelle im Hardware Manual sind bei einem Reloadwert von 0xFD 
und einer Frequenz von 11,0592 MHz sowie gesetztem SMOD-Bit 19200 Baud 
eingestellt. Du hast aber die doppelte Quarzfrequenz, also dann auch 
38400 Baud(!).

Das heisst, das einzige Problem ist jetzt noch die Sache mit den 
Grossbuchstaben, richtig?

Gib mal das empfangene Zeichen am P2 aus. Also P2 = uart_data;
Nach jedem Zeichen mal die Portbits messen, welchen Zustand sie haben 
und mit dem Hexwert vergleichen.

@Gast:
> Manche 8051er können das, aber ob der CC03er das kann, geht aus dem
> Datenblatt NICHT eindeutig hervor:
Nein, nicht manche, sondern alle können das. Weil der Kern ein 8051 
ist, und das ist eine Kernfunktion. Sonst wäre der CC03 kein richtiges 
8051-Familienmitglied.

> Bei der konkreten Beschreibung des SFRs PCON auf S.36 gibt es diese Bits
> nicht mehr !!
Bei der konkreten Beschreibung in Table 29, S.67 gibt es das aber 
wiederum.
Deswegen sage ich auch, dass Atmel Datenblätter scheisse sind, weil die 
Typen einfach immer aus anderen Datenblättern zusammenkopieren, aber 
nicht anpassen. Die sind einfach faul!

Ralf

Autor: Bernd (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
was für ein Problem ? das ist einmal ISR und einmal Polling und beide 
gehen.

Autor: Stefan Schön (stefan0784)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hab das Testprogramm quickndirrty mal probiert.
Dasselbe Problem wie ursprünglich - funktioniert weder mit 24 MHz noch 
mit 22,1184.
Hab jeweils immer die Einstellungen bei den Timern und im Hyperterminal 
geändert.
Kann leider das gesendete Byte nicht an einem Port anzeigen lassen da 
ich keinen kompletten zur Verfügung habe.
Hab nur 2 Pins am Port 2 frei an denen ich die LEDs habe.
IM Anhang häng ich mal unser Schaltbild von unserer Seriellen 
Schnittstelle rein. Über Pin 2.0 schalten wir zwischen USB und RS232.

Ich probier jetzt mal noch ein anderes Testboard von nem Kollegen - die 
haben nur die RS232 Schnittstelle drauf und nicht wie wir USB und RS232.
Dann kann die HardwareSeite mal abchecken - nicht dass ein Bauteil auf 
unserer Platine nicht mitmacht!

Danke schon mal für euer reges Interesse und eure zahlreichen Tipps und 
Tricks.

Autor: Stefan Schön (stefan0784)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Unser Schaltbild noch!

Autor: Bernd (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Stefan,

dann hast du ein Hardwareproblem. Versuch es mal mit teraterm.

http://hp.vector.co.jp/authors/VA002416/teraterm.html

Das was du ins Terminal Fenster eingibst muß zurückkommen (echo).

Autor: Ralf (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Hab nur 2 Pins am Port 2 frei an denen ich die LEDs habe.
> IM Anhang häng ich mal unser Schaltbild von unserer Seriellen
> Schnittstelle rein. Über Pin 2.0 schalten wir zwischen USB und RS232.
Wenn du munter P2 komplett beschreibst, dann brauchst du dich nicht 
wundern.

Ersetz das Schreiben vom Port 2 mal durch:

P2_x = z; //1. freies Bit mit Zustand z beschreiben
P2_y = z; //2. freies Bit mit Zustand z beschreiben

Ralf

Autor: Stefan Schön (stefan0784)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Deswegen hab ich ja auch immer darauf geachtet dass mein Pin 2.0 nicht 
verändert wird.

Oder ändert sich bei P2 = 0xFE bzw. P2 = 0x00 was an Pin 2.0 ???

Autor: Bernd (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>> Oder ändert sich bei P2 = 0xFE bzw. P2 = 0x00 was an Pin 2.0 ???

wie meinen :-))

Autor: Stefan Schön (stefan0784)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi Leute,

hab jetzt nochmals was ausprobiert. Hab jetzt einfach mal den 
Multiplexer überbrückt.
Somit kann ich über RS232 von einem Rechner senden und das Signal im µC 
empfangen und gleich wieder zurück an meinen anderen Rechner senden.
Hab jetzt die Timer mit dem Wert für Baud 19200 geladen. Die gleichen 
Einstellungen hab ich auch ins Hyperterminal vorgenommen. Siehe da - ich 
kann jetzt korrekt schreiben - heißt - am 2. Rechner kommen die 
Buchstaben an die ich im ersten ins Hyperterminal eingebe. (Sogar groß 
und klein)
Jetzt die schlechte Nachricht. Wenn ich einen Buchstaben mehrmals 
hintereinander tippe dann kommt beim 2. mal immer ein falsches Zeichen 
an. ( Egal ob Groß- oder Kleinschreibung)
Wenn ich das Programm dahingehend verändere dass ich ein bestimmtes 
Zeichen abfrage funktioniert es auch noch nicht.
Vielleicht hat einer von euch ja nochmals einen Tipp.

Autor: Bernd (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Dann stell mal den ganzen Code hier rein.

Autor: Stefan Schön (stefan0784)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hier der Code

Autor: Bernd (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
TL1 = 0xFD; warum ? war so nicht in meinem Beispiel.

laß das mal weg und dann in main nur while (1); dann muß es zunächst 
gehen.

TeraTerm... ich hatte dir einen Link gesendet und TTerm hat eine 
Funktion SendFile... damit kannst Du einen kompletten Text Versenden (so 
schnell kannst Du garnicht Tippen) und es funktioniert.

Autor: Stefan Schön (stefan0784)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
TL1 ist doch der Reload Wert für TH1???
Mir ist jetzt gerade aufgefallen dass beim weiterleiten sozusagen auch 
wieder das Signal an den ersten Rechner laufen müsste - dies ist aber 
nicht der Fall.
Habs gerade ausprobiert indem ich in das NullMOdemKabel ein Käbelchen 
zwischen RxD und TxD gesteckt habe.
Also muss ich da mal suchen - evtl. ist da auch noch ein Fehler auf der 
Platine.
Dein Programm hab ich erhalten und auch gezogen - allerdings kann ich es 
auf den Hochschulrechern nicht installieren da ich kein AdminRechte 
besitze.
Auf meinem Laptop funktioniert es nicht da das Programm nur bis COM4 
geht und mein USB an COM 12 hängt.

Autor: Bernd (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Schau Dir mal die Grundlagen zu den Timern an.

http://www.8052.com/tutser.phtml#Serial%20Mode

Das kann doch nicht so schwer sein. Nullmodem Kabel an den MC (verwende 
mal einen Rechner, nicht 2) und dann sollte es gehen. Ansonsten den MC 
aus dem Sockel befördern und RXD, TXD verbinden und die Hardware ist bis 
zum MC getestet.

Autor: Stefan Schön (stefan0784)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Genau das will ich nachher auch noch probieren.
Danach kommt dann noch das TestProgrämmchen TeraTex.
Ich meld mich sobald ich wieder an meine Wissensgrenze stosse.

Autor: Stefan Schön (stefan0784)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hi Leute.
Hab das Problem jetzt lösen können.
Ich weiß zwar nicht wie es zusammen hängt - aber funktionieren tuts 
jetzt!!!
Bei meinen Versuchen zuvor hatte ich nie den T2CON initialisiert.
Der müsste zwar standardmässig auf 0x00 sein - jedoch funktioniert die 
Serielle Übertragung erst wenn ich es bei mir mit 0x00 initialisiere!

Im Anhang findet Ihr nochmals meine Datei für die serielle Übertragung! 
(Die Kommentare stimmen nicht immer überein mit den Einstellungen)
Danke für eure Hilfe - vielleicht hilft es einem anderen mal weiter wenn 
er diesen Beitrag hier liest!

Autor: Ralf (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Bei meinen Versuchen zuvor hatte ich nie den T2CON initialisiert.
> Der müsste zwar standardmässig auf 0x00 sein.
Da wär ich nicht so sicher, dazu müsstest du aber wirklich alles hier 
rein stellen, also auch das, was der Controller in der durch den 
C-Compiler vorgegebenen Initialisierung macht!

Ralf

Autor: Stefan Schön (stefan0784)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Du meinst die Header-Datei die Initialisiert wird?

Autor: Skua (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Bei der Galvanischen Trennung hast du ein VCC VCC_SER Problem beim 
zweiten Koppler von unten.
Und die beiden oberen Verstehe ich garnicht was die sollen.

Autor: Stefan Schön (stefan0784)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Also funktionieren tut jetzt alles - Hardware war bzw. ist definitiv 
nicht das Problem. Könnte aber sein dass auf dem Schaltbild dass ich 
oben eingestellt habe noch ein Fehler ist denn wir aber in der jetzigen 
Version ausgemerzt haben. :-)

Autor: Ralf (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Du meinst die Header-Datei die Initialisiert wird?
Nein, Header werden nicht "initialisierst". Die werden verwendet, um dem 
Compiler mitzuteilen, welches SFR an welcher Adresse liegt, oder um 
Einstellungen machen zu können, z.B. Puffergrößen usw.

Was ich meine ist, dass jeder C-Compiler für einen Controller 
üblicherweise eine Initialisierung durchführt, die noch vor der 
main()-Funktion liegt. Dort wird dann üblicherweise das RAM gelöscht, 
usw.
Wenn dort was mit deinem TCON passiert, dann ist der beim Aufruf deiner 
main()-Funktion nicht mehr (wie erwartet) 0x00 (oder genauer gesagt = 
dem Wert nach dem Reset).

Welchen Compiler verwendest du? Keil C51? Dort heisst die Datei 
STARTUP.A51 und sollte im Projekt-Verzeichnis liegen (bei 
Projekterstellung wird gefragt, ob sie ins Verzeichnis kopiert werden 
soll). Du müsstest sie auch im Projektfenster in µVision sehen können.

Ralf

Autor: Stefan Schön (stefan0784)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jou - benutze den Keil C51 Compiler.
Ich schau mal nach - wie dieser den T2CON initialisiert.
Was mir halt so komisch vorkommt ist, dass ich den Timer2 eigentlich gar 
nicht verwende - und der Timer für die Baudrate ist ja eigentlich der 
Timer1.

Autor: Ralf (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ja, aber Timer 2 kann die Baudrate ebenfalls generieren, wenn TCLK oder 
RCLK (entsprechend für Rx und Tx) in T2CON gesetzt sind. Somit wäre es 
z.B. möglich, entweder komplett mit Timer 2 zu arbeiten, oder für den 
Empfang und das Senden mit unterschiedlichen Baudraten zu arbeiten.

Ralf

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.