www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik PIC16F627 USART Receive Frage


Autor: Alex22 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
ich hoffe bei dem folgenden Problem sieht jemand sofort meinen Fehler, 
ich finde ihn leider nicht.
Ich habe in MPLAB mit dem CC5X Compiler versucht ein Programm zu 
schreiben, dass Daten, die vom PC über RS232 gesendet werden, auf dem 
PIC entgegen nimmt und verarbeitet:

...
TRISB = 0b.0000.0000;
SPBRG = 25;
TXSTA = 0b.0010.0100;
RCSTA = 0b.1001.0000;
char c;
while(!PIR1.5);
c = RCREG;
if(c == 'a')
    PORTB.0 = 1;

Der PIC16F627 hat eine integrierte USART Schnittstelle, wenn ich das 
Datenblatt richtig verstanden habe wird Bit5 im Register PIR1 auf "1" 
gesetzt, wenn ein Byte empfange wurde.
Leider passiert bei diesem Programm gar nichts, egal was ich über 
Hyperterminal sende.
Daten über das TXREG Register zu senden klappt problemlos, Hyperterminal 
zeigt alle Zeichen an, die ich den PIC senden lassen.
Ich habe auch schon mal den PIC aus der Fassung genommen und RX und TX 
miteinander verbunden; es klappt, Hyperterminal empfängt alles was ich 
eintippe...
9600Baud, 1 Stoppbit, kein Handshake, 8Bit, keine Parität


Autor: Michael Stumpf (michael-s)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi Alex,

eigentlich sieht das soweit alles ganz gut aus. Vermute, du verwendest 
ein 4MHz-Quarz?! Das würde zu SPBRG und 9.6k passen... Ich würde mal 
versuchen, zu prüfen, ob die Software bis hinter den while(..)-Block 
kommt... Vielleicht einfach nach dem while eine LED leuchten lassen. 
Dann lässt sich soweit eingrenzen, ob überhaupt Daten ankommen, oder 
nicht... Mag ja auch sein, dass was ankommt, nur leider nicht korrekt 
(Timing-Problem)...

michael

Autor: Alex Bürgel (Firma: Ucore Fotografie www.ucore.de) (alex22) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Bis hinter den while() Block kommt er, PIR1.5 wird auf "1" gesetzt, wenn 
ich eine Taste am PC drücke.
Ich habe jetzt hinter diesen while() Block geschrieben:
TXREG = RCREG;
doch es passiert leider nichts...

Autor: Michael Stumpf (michael-s)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Versuch mal sowas wie

if(RCREG)
  PORTB.0 = 1;

oder sogar

PORTB = RCREG;


Dann weißt Du soweit, ob ein Zeichen größer 0x00 ankommt, und (mit der 
2. Variante) sogar, welches Zeichen (Bits zählen ;-)

-ms

Autor: tastendrücker (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wie sieht denn das ganze Programm aus?

Autor: Michael Stumpf (michael-s)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich vermute mal


void main(void)
{
TRISB = 0b.0000.0000;
SPBRG = 25;
TXSTA = 0b.0010.0100;
RCSTA = 0b.1001.0000;
char c;
while(!PIR1.5);
c = RCREG;
if(c == 'a')
    PORTB.0 = 1;
}

:-)

Autor: tastendrücker (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Versuch's mal so:

void main(void)
{
  TRISB = 0b.0000.0000;
  SPBRG = 25;
  TXSTA = 0b.0010.0100;
  RCSTA = 0b.1001.0000;
  char c;

  while (1=1)
  {
    while(!PIR1.5);
    c = RCREG;
    if(c == 'a')
       PORTB.0 = 1;
  }
}

Ein µC braucht immer eine Endloos-Loop, sonst durchläuft er das Progrmm 
nur einmal.

Autor: Michael Stumpf (michael-s)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
tastendrücker wrote:
> Versuch's mal so:
>
> void main(void)
> {
>   TRISB = 0b.0000.0000;
>   SPBRG = 25;
>   TXSTA = 0b.0010.0100;
>   RCSTA = 0b.1001.0000;
>   char c;
>
>   while (1=1)
>   {
>     while(!PIR1.5);
>     c = RCREG;
>     if(c == 'a')
>        PORTB.0 = 1;
>   }
> }
>
> Ein µC braucht immer eine Endloos-Loop, sonst durchläuft er das Progrmm
> nur einmal.

Hallo,

dann kannst Du statt 1=1 auch nur 1 schreiben, das spart zumindest eine 
Arithmetikoperation...

Nachdem der uC den main-Block durchlaufen hat, fängt er übrigens wieder 
am Anfang an, afaik.

Daher entweder wie oben geschrieben von tastendrücker, oder aber halt 
einfach while(1); als letzte Zeile in die void main...

michael

Autor: tastendrücker (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
oops, und ich meinte eigentlich

 while (1==1)

aber while (1) geht natürlich auch (optimiert doch sowieso der Compiler, 
oder)


>Nachdem der uC den main-Block durchlaufen hat, fängt er übrigens wieder
>am Anfang an, afaik.

Bin ich (Assembler-Fan ;-) mir nicht ganz sicher. Wenn dem so wäre, 
würde in diesem fall der ganze Init-Block

>   TRISB = 0b.0000.0000;
>   SPBRG = 25;
>   TXSTA = 0b.0010.0100;
>   RCSTA = 0b.1001.0000;

ja jedes mal neu durchlaufen werden.

Autor: Michael Stumpf (michael-s)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
tastendrücker wrote:

>>Nachdem der uC den main-Block durchlaufen hat, fängt er übrigens wieder
>>am Anfang an, afaik.
>
> Bin ich (Assembler-Fan ;-) mir nicht ganz sicher. Wenn dem so wäre,
> würde in diesem fall der ganze Init-Block
>
>>   TRISB = 0b.0000.0000;
>>   SPBRG = 25;
>>   TXSTA = 0b.0010.0100;
>>   RCSTA = 0b.1001.0000;
>
> ja jedes mal neu durchlaufen werden.

und ich vermute, dass das genau der Grund ist, warum es nicht 
funktioniert...

michael

Autor: tastendrücker (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
... und überhaupt sollte man das (Senden und Emfpangen) über Interrups 
machen.

Ansonsten mal bei www.michrochipc.com  suchen (viele Beispiele)
          ACHTUNG               ^

Autor: Michael Stumpf (michael-s)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
tastendrücker wrote:
> ... und überhaupt sollte man das (Senden und Emfpangen) über Interrups

Warum das?

Autor: tastendrücker (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>> ... und überhaupt sollte man das (Senden und Emfpangen) über Interrups

>Warum das?

Weil das Pollen den µC blockiert bis ein Zeichen angekommen ist. Und 
wenn nie eins kommt...

Ausserdem lernt man so gleich was über die Interrupts, die ja eigentlich 
das A&O bei µCs sind.

Autor: Michael Stumpf (michael-s)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
tastendrücker wrote:
>>> ... und überhaupt sollte man das (Senden und Emfpangen) über Interrups
>
>>Warum das?
>
> Weil das Pollen den µC blockiert bis ein Zeichen angekommen ist. Und
> wenn nie eins kommt...
>
> Ausserdem lernt man so gleich was über die Interrupts, die ja eigentlich
> das A&O bei µCs sind.

Ja, das ist klar... Aber man kann auch in einer Endlosschleife, die div. 
Routineaufgaben erfüllt, einmal abfragen. Und solange kein Zeichen 
ankommt, ist alles gut. Und solange Zeichen da sind, werden diese 
erstmal verarbeitet. Zum Beispiel so:


while(1)
{
   while(PIR1.5)
   {
      //irgendwas mit dem/den Bytes machen
   }

   //hier viele andere Aufgaben

}

Autor: tastendrücker (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>while(1)
>{
>   while(PIR1.5)
>   {
>      //irgendwas mit dem/den Bytes machen
>   }
>
>   //hier viele andere Aufgaben
>
>}

Dann muss aber darauf geachtet werden, dass "//hier viele andere 
Aufgaben" nicht zu lange dauert, da sonst evtl. Bytes verlorengehen.

(M)eine goldene Regel bei jedem µC-Projekt: Mache möglichst viel mit 
Interrupts, aber möglichst wenig in Interrupts.

Autor: Michael Stumpf (michael-s)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
tastendrücker wrote:
> Dann muss aber darauf geachtet werden, dass "//hier viele andere
> Aufgaben" nicht zu lange dauert, da sonst evtl. Bytes verlorengehen.
>
> (M)eine goldene Regel bei jedem µC-Projekt: Mache möglichst viel mit
> Interrupts, aber möglichst wenig in Interrupts.

Ja, das stimmt... Das geht wirklich nur, wenn nicht allzuviel 
passiert...

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.