Forum: Mikrocontroller und Digitale Elektronik printf Funktion C167 Problem Leerzeichen


von Richard Wegener (Gast)


Lesenswert?

Hallo,
ich habe ein Problem mit meinem C167 Microcontroller.
Ich möchte die Signale eines Inkrementalgebers auswerten und die
aktuelle Geschwindigkeit bzw. Position 1 mal pro Sek. über die serielle
Schnittstelle an meinen PC senden. Zur Übertragung möchte ich die printf
funktion nutzen doch mit genau dieser habe ich Probleme. Noch bevor die
Messung und auswertung gestartet wird, also auch vor der while Schleife
in der main Funktion, soll eine Information an das Hyper terminal
gesendet "Inkrementalmessung wird gestartet".
Diese Info wird nie an das terminal gesendet. Es werden fast nur
Leerzeichen versendet und diese Übertragung der Leerzeichen wird nicht
beendet. Also die printf Funktion wird erst gar nicht abgearbeitet bzw
nicht beendet.
Kann mir da vielleicht jemand weiter helfen? Liegt es an den
Einstellungen die ich bei dem Controller machen muss? Die Beispiel
Programme von Phytec kann ich nämlich alle ausführen auch die mit einer
printf funktion.
Gruß
Richard

von Profi (Gast)


Lesenswert?

am besten erlaubst Du uns einen Blick in Deinen Code.
Stimmt die Baudrate?
Kommen wirkleich Spaces (0x20) an oder sind es andere nicht
darstellbare Zeichen?

von Richard Wegener (Gast)


Lesenswert?

Hier eine vereinfachte version die ich vorab zum laufen bringen möchte.
Wenn ich nur die printf Funktion auskommentiere funktioniert alles.
Greetz


#include <reg167.h>             /* include 80C167 header file*/
#include <stdio.h>

sbit P2_0 = P2^0;               /* declare portpin to use*/
sbit DP2_0 = DP2^0;             /* declare direction bit to use*/
void wait(unsigned int);
void initwait(void);
void initdisplay(void);

void wait (unsigned int ms)     /* wait function */
{
  T3 = 0;
  T3R = 1;
  while(T3<(ms * 480));
}

void initwait(void)
{
  T3CON = 0x007;
  //T3 = 0;
}

void initdisplay(void)
{
  IEN = 0;
  //#ifndef MCB167
  P3  |= 0x0400;
  DP3 |= 0x0400;

  DP3 &= 0xF7FF;

  S0TIC = 0x80;
  S0RIC = 0x00;

  S0BG  = 0x81;         // set baudrate to 9600 baud at 40Mhz
  S0CON = 0x8011;       // set serial mode
    //#endif
    IEN =1;
}

void main (void)
{
  initdisplay();
  initwait();
    DP2_0 = 1;           /* init direction to output */
  P2_0 = 1;
    printf ("\aHello World\n"); /* print 'Hello World' to the
serial*/

  while (1)           /* loop forever */
    {
    wait(150);
    P2_0 = 0;
    wait(150);
    P2_0 = 1;
    }
}

von zverjatko (Gast)


Lesenswert?

Hallo Richard,

du mußt noch den Sendebuffer freigeben, wenn du ohne Interrupt
arbeitest.

S0TIR=1;

Gruß
zverjatko

von (geloescht) (Gast)


Lesenswert?

(Dieser Beitrag wurde geloescht)

von zverjatko (Gast)


Lesenswert?

Nein für C167 gib es nicht freies,
Eval. Version von Keil (www.Keil.com) (limit 8KByte)
oder Compiler von Tasking, vermutlich ähnliche begrenzung.
Gruß
Zverjatko

von (geloescht) (Gast)


Lesenswert?

(Dieser Beitrag wurde geloescht)

von Robert Teufel (Gast)


Lesenswert?

@Guido,

den GNU compiler fuer den 16x gabs mal von
http://www.hightec-rt.com/

Robert

von Steffen (Gast)


Lesenswert?

@Guido,

bei PLS war auch immer ein GNU C Compiler für den 16x dabei.
http://www.pls-mc.com/howdoesitwork/index.htm?a_architecture_c16x.htm

von Take it Easy (Gast)


Lesenswert?

Hallo,

printf ist eine Funktion, die auf (eine) Grundfunktion(en)
zurückgreift. Je nach Compiler muss eine Funktion z.B. iowrite() erst
definiert werden. Hier wird dann der Output Stream festgelegt.

Woher soll printf denn wissen, wohin die Daten ausgegeben werden sollen
(z.B. RS232, LCD-Display1, LCD-Display2, CAN,...)?

von Richard Wegener (Gast)


Lesenswert?

Hallo,
leider haben Eure Tipps noch nicht geholfen.
@zverjatko
habe S0TIR = 1; eingefügt, leider keine veränderung.

@Take it Easy
Ich kann deinen Hinweis wohl nachvollziehen, aber in den beispielen von
Phytec ist die printf() funktion auch nicht anders konfiguriert worden.

Hat vielleicht noch jemand eine idee ?

Greetz Richard

von zverjatko (Gast)


Lesenswert?

Programmierst du mit Keil ?
Wenn ja, hast du schon mit dem µVision das Programm simuliert ?
Du schreibst:  // set baudrate to 9600 baud at 40Mhz
Der alte C167 so weit ich weiß läuft maximal bis 24Mhz.
Gruß

von Richard Wegener (Gast)


Lesenswert?

Also ich arbeite mit Keil µVision3 (eval. Vers.).
Wie schon erwähnt kann ich die Beispiel Programme von Phytec auch
compilieren und auf meinem C167 laufen lassen.
hat vielleicht noch jemand eine idee woran es liegen kann ?

Hier habe ich mal das Programm das läuft:
Mein c167HSE hat einen Takt von 40MHz.

#include <REG167.H>         /* Register Set of 80C167 controller   */
#include <stdio.h>          /* Standard I/O functions              */

/* main program  */
void main (void)          /* execution starts here      */
{
                          /* init serial0 port:         */
  P3  |= 0x0400;          /* set port 3.10 output latch (TXD)*/
  DP3 |= 0x0400;          /* configure port 3.10 for output   */
                          /* operation. ( TXD output)         */
  DP3 &= 0xF7FF;          /* configure port 3.11 for input    */
                          /* operation. ( RXD input)          */
  S0TIC = 0x80;           /* set transmit interrupt flag      */
  S0RIC = 0x00;           /* delete receive interrupt flag    */

/*  PLEASE CHECK YOUR phyCORE-167-HS/E Quarz frequency and choose the
right   */
/* reload value to set the baudrate to 9600 Baud  */
//S0BG  = 0x40;         /* set baudrate to 9600 baud at 20Mhz  */
//S0BG  = 0x50;         /* set baudrate to 9600 baud at 25Mhz  */
//S0BG  = 0x6A;         /* set baudrate to 9600 baud at 33Mhz  */
  S0BG  = 0x80;         /* set baudrate to 9600 baud at 40Mhz  */
  S0CON = 0x8011;       /* set serial mode                     */

  putchar(' ');         /* send dummy-Byte for compatibility   */
  printf ("\aHello World\n");   /*print 'Hello World' to the
serial port.*/
  while (1)             /* An embedded program without any     */
  {                     /* operating system usually does not   */
                        /* stop and never returns.             */
                        /* We've used an endless loop in
                           this example.                       */
  printf ("  char = %02bX\n",getchar()); /* print the two digit hex
              code of   */                             /* any received
character              */
  }
}

von Take it Easy (Gast)


Lesenswert?

Falsche Baudrate:
--> Keil      S0BG = 0x80;
--> Dein Code S0BG = 0x81;  // Abweichung ein paar Prozent!

von zverjatko (Gast)


Lesenswert?

Also ich habe dein Programm jetzt im µVision3 Simuliert und
es fehlte   S0TIR=1.
Das Programm funktioniert.

void main (void)          /* execution starts here      */
{
                          /* init serial0 port:         */
  P3  |= 0x0400;          /* set port 3.10 output latch (TXD)*/
  DP3 |= 0x0400;          /* configure port 3.10 for output   */
                          /* operation. ( TXD output)         */
  DP3 &= 0xF7FF;          /* configure port 3.11 for input    */
                          /* operation. ( RXD input)          */
  S0TIC = 0x80;           /* set transmit interrupt flag      */
  S0RIC = 0x00;           /* delete receive interrupt flag    */
  S0TIR=1;
  S0BG  = 0x81;         /* set baudrate to 9600 baud at 40Mhz  */
  S0CON = 0x8011;       /* set serial mode
 ....

die reale Baudrate beträgt 9615 (+0,15%) d.h jetzt muss es
funktionieren, falls es doch nicht geht,dann hast du ein Hardware
Problemm.
Beim Phytec gibt es aber nur phyCORE-ST10F168/269/276 HS/E  und kein
C167HSE, die schnellsten alten C167 sind mit 25MHz.
Dieses Programm habe ich auch anschliesend  mit einem ST10F269
simuliert.Es funktioniert ebenfalls.


Gruß
zverjatko

von Richard Wegener (Gast)


Lesenswert?

Vielen dank allen denen die mir hier geholfen haben.
Ich habe gestern noch einmal versucht das beispiel programm von Phytec
zu starten und es hatte genau den selbigen Fehler wie das von mir
erstellte Programm !! Daraufhin habe ich alle Programme von Phytec und
Keil gelöscht, neu aufgespielt und anschließend mein Programm wieder
neu und sauber programmiert (incl. S0TIR=1;) !!! und siehe da alles
funzt.
Ich denke das einfach im laufe der Zeit und der unzähligen Versuche von
mir einige Einstellungen so verändert wurden das es einfach nicht mehr
funktionieren konnte. Also nochmal vielen dank für die unterstützung.

Gruß
Richard

von Stefan Neubert (Gast)


Lesenswert?

Hallo,
ich beschäftige mich zur Zeit auch mit dem printf Befehl und dem C167 
Controller.
Ich möchte ein Gyroskop steuern und habe auch soweit mit dem Keil 
Compiler einen Quellcode erstellt.
Das Gyroskop gibt einen binären Datenstrom aus, den ich via einem 
Hyperterminal anzeigen möchte. Mit dem Oszilloskop sieht man, dass das 
Gyroskop vom Prinzip her funktioniert und Daten ausgibt.
 Wenn ich mit integer Werten Berechnungen mache, werden diese Variablen 
wunderbar angezeigt. Am Programmcode habe ich mich am Beispiel "Hello 
World" orientiert und möchte eigentlich nur einen Zustand eines Pins mit 
printf anzeigen lassen.
Den Datenstrom des Gyroskop kann man sehr schön sehen, aber leider kann 
ich mit dem printf Befehl nur Nullen ausgeben.

Stefan

von Thomas M. (Gast)


Lesenswert?

Hallo!

Ich habe das selbe Problem, allerdings, nach vielen Versuchen und mit 
Hilfe dieses Threads -> noch immer!!!!

Meine Programm laufen zwar im Monitor (Programmiere mit Keil) 
einwandfrei, allerdings im Flash wird nur noch das erste Zeichen normal 
geschickt, dann kommen nur noch Leerzeichen (0x20).

Kann jemand irgend ein kleines funktionierendes Testprojekt zur 
Verfügung stellen? Ich komme z.Zt. echt nicht weiter!

Danke.

von Robert (Gast)


Lesenswert?

Hallo!

Mein Problem ist derzeit noch das einlesen. Ich möchte den Hex-Wert 
einer gedrückten Taste auf der Tastatur über das Hyperterminal einlesen 
und diesen dann im c167 verwerten.

Wie lese ich ich den Wert in S0TIR ein bzw. greife wieder darauf zu um 
ihn auszugeben?

Sorry meine banale Frage aber bin erst Anfänger mit im µC-programmieren.

gtx, Robert



von Thomas M. (Gast)


Lesenswert?

Naja passt zwar nicht unbedingt zum Thema aber egal.

Also erstens geht es nicht um das S0TIR-Register, weil es 1. kein 
InterruptRequest sein soll sondern der Wert aus dem Buffer und zweitens 
geht es hierbei nicht um den Transmitter sondern um den Receiver.

Das Register, welches du auslesen musst ist das S0RBUF. Dies machst du 
am Besten in einer Methode die vom interrupt 43 (0x2B in hex, der 
ReceiverInterrupt) verwendet wird.
Zum Beispiel:
1
void isr_serial_receive() interrupt 43
2
{
3
unsigned char c = S0RBUF;       // Empfangspuffer lesen
4
....
5
}


Diesen Interrupt musst du nur noch enablen. Dies schaut bei mir so aus:
1
S0RIC = 0x56;
und dann dürft eigentlich gar nichts mehr schief gehen (wenn du die 
Serielle schon initialisiert hast).

Was allerdings meist ein Problem ist:
Wenn du einen Monitor verwendest, dann verwendet meist der Monitor 
(zumindest bei mir war es so, ich habe einen Keil-Monitor) diese 
Interrupt-Routine und überschreibt dir quasi deinen Interruptvektor. 
Läuft das Programm von Rom oder Flash läuft es auch so einwandfrei, für 
den Monitor musste ich noch einiges hinzufügen:
1
unsigned short *p = 0xAC;    // Pointer auf 16 bit Wort
2
*p = 0x00FA;      // JMPS bits 16 - 23 der Sprungadresse werden hier 0 gesetzt !!!
3
p++;          // nächstes Wort
4
*p = (unsigned short)&isr_serial_receive;  //Vector der ISR auf Adresse schreiben

von Moccamixer (Gast)


Lesenswert?

Hallo - ich hatte gestern abend das gleiche problem mit meinem c167:

jedes printf sendet den ersten buchstaben und daraufhin nur noch 0x20 an 
das terminal über die serielle schnittstelle. ich habe neu installiert, 
unterschiedlichste beispielprogramme der evaluation software probiert - 
überall das gleiche problem. Andere Dinge schienen zu funktionieren 
(Blinky etc...) lediglich printf() bereitete die erwähnten probleme.

ich konnte es jedoch wie folgt lösen (mache das alles hier erst seit ein 
paar tagen - den grund konnte ich nicht wirklich ermitteln, aber eine 
lösung - zumindest für mich):

demo software unter http://www.phytec.com/zip/ runterladen - bei mir war 
es http://www.phytec.com/zip/Demos_PCM-009_K.zip (s. Anhang des 
Beitrags). dieses Paket enthält ebenfalls ein Hello World - und zwar 
eins das mit dem C167 CR-LM funktioniert. ich nehme diese demo als 
ausgangsprojekt und füge meinen code hinzu. ich denke es liegt entweder 
an der start167.a66 oder an der projektkonfiguration selbst. wobei ich 
bei letzteren unterschiede finden konnte (Options -> L166 Locate im Feld 
Target Classes und im Feld Linker Control String) jedoch, weiß ich nicht 
wo man diese Werte selbst anpassen kann... Wäre aber interessant, wenn 
mir das jemand sagen könnte, dann brauche ich nicht immer ein kopiertes 
ausgangsprojekt, sondern könnte die einstellungen selbst vornehmen. ich 
bin da wirklich ganz unerfahren und kein c profi, aber ich vermute mal, 
dass da irgendwas falsch gelinkt wird, wenn diese einstellungen nicht 
angepasst werden. ich war hartnäckig, hier ist meine lösung - ich hoffe 
sie hilft einigen.

grüße,

mocca

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.