www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik C515c-l putchar


Autor: nic (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo miteinander,

ich versuche grad Daten über meine Serielle Schnittstelle mittels 
printf() zu schicken. Damit er die Daten überhaupt an den Sendebuffer 
übergibt, musste ich die putchar() überschreiben. Das habe ich wie folgt 
gemacht:

char putchar (char c)  {
  while (!TI);
  TI = 0;
  return (SBUF = c);
}

Mein ganzes Programm sieht so aus:

#include <reg515c.h>
#include "lcd_c0.c"
#include "stdio.h"

void main() {
   TMOD = 0x10; // Timer 1 autoreload
   TH1 = 0xf5; // reload value for 9600 Baud
   TR1 = 1;     // Timer1 starten
   SM1=1; //|\__ Serial Channel in mode 1
   SM0=0; //|/
   lcd_init();
   lcd_clr();
   while(1) {
  TI=1;
     printf("Test");
  lcd_clr();
  lcd_str("Test");
   }
}


char putchar (char c)  {
  while (!TI);
  TI = 0;
  return (SBUF = c);
}


Nun läuft das Programm bis an die Stelle while(!TI); .
Dort bleibt es dann hängen. Kommentiere ich die Schleife aus,
schreibt er mir immer den letzten Buchstaben auf die Serielle 
Schnittstelle. Irgendwie wird das Transmit-Interrupt flag nicht gesetzt.
An was kann das liegen?

Autor: Ralf (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi,

"TMOD = 0x10" konfiguriert den Timer 1 auf Mode 1, 16-Bit, nicht auf 
Mode 2, 8-Bit mit Autoreload. Das muss also 0x20 heissen.

Da es sich bei TMOD um ein Register handelt, welches zwei 
Peripherie-Einheiten bedient (Timer 0 und 1), würde ich dir empfehlen, 
die Konfiguration so vorzunehmen:

TMOD &= 0x0F;  //Alle relevanten Flags für Timer 1 löschen
TMOD |= 0x20;  //Alle nötigen Flags für Timer 1 setzen

Das sorgt dafür, dass wenn du irgendwo Timer 0 konfigurieren möchtest, 
du nicht die Konfiguration für beide in einem Rutsch machen musst. Das 
halte ich für übersichtlicher, weil dann die Konfiguration immer dort 
gemacht wird, wo sie gebraucht wird. Ist aber Geschmackssache.

Ralf

Autor: nic (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Ralf,

danke für die Schnelle Antwort, aber das hat mein Problem leider auch 
nicht behoben. Mein TI wird irgendwie nie gesetzt und mein Programm 
bleibt in der while-Schleife in putchar() hängen...

Autor: Andy (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Versuchs mal damit:

TI Flag in Interrupt zurücksetzen und in putchar warten,
bis letztes Byte gesendet wurde.

//************ UART Interrupt **************

void receive_Int( void ) interrupt 4
{
  if(RI==1)  // Byte empfangen
  {
    lkjafkljaskdfj........
    jadsfjaskldf........
    RI=0;
   }     // Ende von if RI ==1..


   if(TI==1) // Byte gesendet
   {
     TI=0;
   }
}

// *****************************************

char putchar (char c)  {
  while (TI==1);
  return (SBUF = c);
}

Autor: Andy (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nicht vergessen, den IRQ auch freizugeben:

ES = 1;   // Freigabe des UART IRQ's

Autor: Ralf (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Du darfst TI = 1 nicht in der while(1) Schleife setzen, weil es sein 
kann, dass der letzte Buchstabe noch nicht gesendet wurde. Das hilft 
zwar nicht ganz weiter, ist aber trotzdem ein Fehler. Du musst es vor 
der while Schleife setzen.

Dass TI NIE gesetzt wird, glaub ich nicht. Sobald etwas in SBUF 
geschrieben wird, wird auch etwas über die serielle rausgepustet, und am 
Ende der Übertragung das TI Flag gesetzt.

Woher weisst du denn, dass das Programm genau bei der Abfrage von TI 
hängenbleibt? Simulator?
Oder nur die Zeile auskommentiert und probiert?

Was macht denn der Compiler aus der Abfrage, also welche Assembler 
Befehle kommen denn da raus? Kannst du die mal posten?

Ralf

Autor: noch_ein_gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Schau mal ins Handbuch
oder auch beispielsweise in Quellcodebeispielen nach. TI wird immer dann 
gesetzt, wenn das Zeichen gesendet wurde (vor dem Stopp-Bit).

Dann musst Du bloß in der ISR das TI rücksetzen und ggf. weitere Zeichen 
senden.
Um auf meinen Vorschreiber bezug zu nehmen... du musst nicht nur ES=1 
setzen, sondern auch EAL (enable all interrupts). Die Maskierten sind 
dabei außen vor...

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.