Kommunikation mit UART, Code-Fehler in Funktion?

Gast #1286807
Lesenswert?

Hallo miteinander,

sieht jemand von Euch einen offensichtlichen Grund, warum die folgende 
Funktion nicht funktionieren sollte?

Aufgabe soll es sein, über den UART eine beliebige Anzahl von Bits zu 
übertragen.


unsigned int SchreibeUART(int outlen, unsigned char* outbuf)
{
     unsigned int Nr;

     for (Nr=0;Nr<outlen;Nr++)
     {
      *pUART = outbuf[Nr];
      while((*pUART+1)&0x40)==0);  //Abfrage Statusregister->Sendepuffer 
leer
     }

/*     warten bis das letzte Byte weg ist   */

 return(1);
}

Vielen Dank,
Cris
#1286843
Lesenswert?

Cris schrieb:

> Aufgabe soll es sein, über den UART eine beliebige Anzahl von Bits zu
> übertragen.

Das das Statusregister eine um 1 höhere Adresse als das Senderegister 
hat, hast du kontrolliert?

> sieht jemand von Euch einen offensichtlichen Grund, warum die folgende
> Funktion nicht funktionieren sollte?

Ja

>       while((*pUART+1)&0x40)==0);  //Abfrage Statusregister->Sendepuffer

 *pUART+1

ist der um 1 erhöhte Inhalt von *pUART.

Du willst

     *(pUART+1)


Ich würde die Abfrage, ob das Sendregister beschrieben werden kann, vor 
das Beschreiben ziehen.
1
     for (Nr=0;Nr<outlen;Nr++)
2
     {
3
      while((*(pUART+1))&0x40)==0)  //Abfrage Statusregister->Sendepuffer
4
leer
5
        ;
6
      *pUART = outbuf[Nr];
7
     }

auf die Art, brauchst du beim AUfruf der Funktion nicht darauf achten, 
ob eine vorhergehende Sendeoperation schon abgeschlossen ist, und du 
brauchst auch in der Funktion nicht darauf warten, dass das letzte Byte 
schon draussen ist.
Die UART schiebt das letzte Byte raus, während dein Programm schon 
wieder weiterläuft.

Das hier im Funktionsinterface
1
unsigned int SchreibeUART(int outlen, unsigned char* outbuf)
das int bei outlen ungeschickt ist, brauch ich wohl nicht extra 
erwähnen.
#1286901
Lesenswert?

Cris schrieb:
> Danke schonmal,
>
> aber weshalb ist 'int outlen' ungeschickt gewählt?

Weil du ständig signed/unsigned Warnungen kriegen wirst.
Zumal du ja auch innerhalb der Funktion deinen Schleifenzähler als 
unsigned hast.

Wenn schon, dann sei konsequent und mach alles unsigned oder alles 
signed (wobei sich allerdings die Frage erhebt welchen Sinn dort eine 
Länge von -1 haben könnte)

Für solche Fälle gibt es in C den Datentyp size_t. Damit dokumentiert 
man dann auch, dass es sich hierbei um eine Längenangabe handelt. strlen 
liefert zb. einen size_t zurück. malloc möchte einen size_t haben, etc 
...

> Kann die Reihenfolge Schreiben/Status-abfrage dafür verantwortlich sein,
> dass mein Programm bisher nicht lief?


             while((*pUART+1)&0x40)==0)

Nochmal (zur Verdeutlichung füge ich Klammern ein, wie der Compiler die 
Sache anhand der Vorrangregeln sieht)

   Du hast          ( ( (*pUART)+1  ) & 0x40 ) == 0
   Du willst aber   ( ( *(pUART+1)  ) & 0x40 ) == 0

Deine original while Schleife testet, ob im Senderegister der Wert 0x3F 
drinnensteht. Du willst aber ganz was anderes: Du willst das 
Statusregister testen, ob dort Bit 6 gesetzt ist.
#1286906
Lesenswert?

Cris schrieb:
> volatile unsigned int *pUART = (unsigned int*) ADR_FLEX_L

Also ist es wohl doch kein AVR.

Es muß irgendein Chip sein, dessen UART 16bittig ist (unsigned int *), 
was zumindest ungewöhnlich ist.

Und das volatile sagt, daß ein Interrupt Dir die UART-Adresse unter den 
Füßen wegziehen darf, was auch ungewöhnlich ist.


Peter
#1286912
Lesenswert?

Peter Dannegger schrieb:
> Cris schrieb:
>> volatile unsigned int *pUART = (unsigned int*) ADR_FLEX_L
>
> Also ist es wohl doch kein AVR.
>
> Es muß irgendein Chip sein, dessen UART 16bittig ist (unsigned int *),
> was zumindest ungewöhnlich ist.

Yep. Ist mir gar nicht aufgefallen.

Wird Zeit für mehr Informationen des TO über seine Umgebung.

(Den unsigned int glaub ich ihm schon mal nicht. Halt ich für den Fehler 
eines übereifrigen Einsteigers)
Gast #1286943
Lesenswert?

Mist, Fehler von mir...

Ich hatte natürlich schon:
while(*(pUART+1)&0x40)==0);

Spielt dann die Reihenfolge immernoch ein Rolle?


Nein Nein ist kein AVR..sorry hätte ich dazu sagen sollen...ist ein DSP 
von TI. Ich hoffe, dass das nicht so wild ist...
#1286957
Lesenswert?

Cris schrieb:
> Mist, Fehler von mir...
>
> Ich hatte natürlich schon:
> while(*(pUART+1)&0x40)==0);
>
> Spielt dann die Reihenfolge immernoch ein Rolle?
>
>
> Nein Nein ist kein AVR..sorry hätte ich dazu sagen sollen...ist ein DSP
> von TI. Ich hoffe, dass das nicht so wild ist...

trotzdem sieht das hier
1
volatile unsigned int *pUART
seltsam aus.
Bist du sicher, dass das Senderegister deiner UART 16 Bit breit ist?

Das hier
    pUART+1
gibt dir dann die numerisch um 2 höhere Adresse nach pUART 
(sizeof(unsigned int) mal als 2 angenommen)
#1286984
Lesenswert?

Kannst du einen Link zu einem vernünftigen Datenblatt geben. Mit dem was 
ich mir auf die Schnelle ergoogle, kann ich das irgendwie nicht so recht 
nachvollziehen.

Danach sind die Memory Mapped Register

    808040h     Serial Global Control
    808042h     FSX/DX/CLKX Serial Port Control
    808043h     FSR/DR/CLKR Serial Port Control
    808044h     Serial R/X Timer Control
    808045h     Serial R/X Timer Control
    808046h     Serial R/X Timer Period Register
    808048h     Data Transmit
    80804Ch     Data Receive

Data Transmit dürfte das Senderegister sein. Die Control Register sind 
dann allerdings weit weg davon, und vor allen Dingen nicht auf +1

PS: Ich würde auch mal sagen, dass die Grafik, die ich in einem TI 
Datenblatt gefunden habe, deine Aussage nicht unterstützt, dass du es 
mit 16 Bit Registern zu tun hast. Aber ich hab auch nur so ein schmufti 
Übersichtsdatenblatt gefunden, welches mehr über Pin-Timings und electr. 
Characteristics quasselt.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren