Forum: Mikrocontroller und Digitale Elektronik Serielle Schnittstelle und TSIC 306 Temp.sensor


von Gast (Gast)


Lesenswert?

hallo.
darum gehts: 
http://www.mikrocontroller.net/attachment/48771/TSIC_ZACWIRE.pdf
bis jetzt habe ich zum auslesen des sensors nur ansätze gefunden selbst 
die steigenden und fallenden flanken zu detektieren, T_strobe zu 
berechnen und so das signal zu dekodieren. und das prinzip warum es 
T_strobe gibt erschließt sich mir auch nicht. warum gibt man nicht den 
takt des signals an ? der muss doch immer gleich sein.
ich wollte wissen ob das signal kompatibel zur seriellen schnittstelle 
ist bzw. zu der form der seriellen schnittstelle, so dass vielleicht der 
µC selbst das signal dekodieren kann, indem man ihn bzw seine serielle 
schnittstelle für das signal konfiguriert? denn das signal, das vom 
sensor kommt hat doch immer die gleiche form (frame), also auch den 
selben "takt".
das signal der serielle schnittstelle ist ja bis auf dieses 
"1/2-Stopbit" genauso wie das signal vom sensor.
wenn das klappen würde, wäre das um einiges besser, als selbst das 
signal auseinander zu nehmen...

von Michael U. (amiga)


Lesenswert?

Hallo,

ich gehe mal davon aus, Du meinst mit serieller Schnittstelle jestzt de 
USART und nicht TWI, SPI oder so, sind ja alles serielle Verfahren.

Nein, geht so nicht.
Der Pegel beim UART muß für die ganze Bitzeit konstant sein, ein 
Startbit und ein 0-Bit ist also L für die ganze Zeit, ein H-Nit und das 
Stopbit ist H für die ganze Zeit.
Was soll der UART also mit den Pegelwechseln mittendrin beim ZACwire 
machen?

Gruß aus Berlin
Michael

von Gast (Gast)


Lesenswert?

hast recht, war war mir entfallen.
aber welchen sinn hat die zeit T_Strobe? warum ist die nicht fest? 
sofern die betriebsspannung des sensors konstant ist, sollte die doch 
immer gleich groß sein oder? könnte da nicht einfach jemand mal einen 
erfahrungswert angeben?

von spess53 (Gast)


Lesenswert?

Hi

Bei mir hat das Abtasten in Bitmitte fehlerfrei funktioniert.

MfG Spess

von Gast (Gast)


Lesenswert?

@spess53: beziehst du dich jetzt auf UART?

von spess53 (Gast)


Lesenswert?

Hi

Bezog sich auf diesen Satz:

>aber welchen sinn hat die zeit T_Strobe?

Ich dachte, dir wäre klar, das mit der UART nicht geht.

MfG Spess

von Jörg S. (joerg-s)


Lesenswert?

Gast schrieb:
> aber welchen sinn hat die zeit T_Strobe? warum ist die nicht fest?
Die ist ja im prinzip fest (62,5µs). Wenn man auf Nummer sicher gehen 
will misst man sie halt. Hab ich bei meinen Programmen für TSic Sensor 
aber bisher nie gemacht. Der Beispiel C-Code von ZMD für 8051 verwendet 
auch feste Zeiten.

von TSIC (Gast)


Lesenswert?

Indirekt geht's schon mit seriellen Schnittstelle.

http://www.qsl.net/dk7nt/tdr/tsic.html

Nur als Tip.

von Jörg S. (joerg-s)


Lesenswert?

Tja, wenn man einen µC zwischen schaltet der das ganze wandelt geht das 
natürlich...

von Klaus W. (mfgkw)


Angehängte Dateien:

Lesenswert?

nachdem hier immer noch kein Quelltext dazu liegt, werfe ich mal meinen
in die Runde...

Das ist C++, sollte aber -soweit es um den Sensor geht- auch 1:1 in C
gehen.
Wer die C++-Version des LCD nicht mag, kann ja das Original aus
dem Tutorial nehmen.

Das Ganze eben nochmal unter Linux ausprobiert auf einem Mega32
(mit 16 MHz; bei anderen Geschwindigkeiten Anpassungen nötig
gem. Kommentaren im Quelltext!).
Im Makefile ist avrdude auf /dev/parport0 und stk200 gestellt.

von Jörg S. (joerg-s)


Lesenswert?

Quelltexte zu TSic gibt's schon in anderen Beiträgen. Nur nicht so gut 
kommentierte wie bei dir :)

von Klaus W. (mfgkw)


Lesenswert?

Ich wärme diese Geschichte nochmal auf.
Grund: ich bekam heute eine Frage zu meinem obigen Quelltext, habe
die Mail mit der Frage aber dummerweise vor dem Beantworten
versehentlich gelöscht. Deshalb die Antwort über diesen
Umweg - wenn sich der Frager nochmal meldet, kann ich den Beitrag
gleich wieder löschen (falls nicht noch jemand hier antwortet...).

Die gekürzte Timerroutine sieht etwa so aus:
1
ISR(TIMER0_OVF_vect)
2
{
3
  if( bTSic1Running )
4
  {
5
    switch( nTimer0TSic1 )
6
    {
7
      // Anm. zu den Werten in den case-labels: siehe Ausgabe des
8
      // Programms calc_nTimer0_fuer_TSic.c
9
10
      case    4: // [ 0]   Startbit
11
        break;
12
      case   12: // [ 1]   upper byte bit 7
13
        hbyteTSic1 |= (((PIN_TSIC1_DATA & (1<<PINNUMMER_TSIC1_DATA))!=0)<<7);
14
        break;
15
      case   20: // [ 2]   upper byte bit 6
16
        hbyteTSic1 |= (((PIN_TSIC1_DATA & (1<<PINNUMMER_TSIC1_DATA))!=0)<<6);
17
        break;
18
      case   27: // [ 3]   upper byte bit 5
19
        hbyteTSic1 |= (((PIN_TSIC1_DATA & (1<<PINNUMMER_TSIC1_DATA))!=0)<<5);
20
        break;
21
      case   35: // [ 4]   upper byte bit 4
22
        hbyteTSic1 |= (((PIN_TSIC1_DATA & (1<<PINNUMMER_TSIC1_DATA))!=0)<<4);
23
        break;
24
      case   43: // [ 5]   upper byte bit 3
25
        hbyteTSic1 |= (((PIN_TSIC1_DATA & (1<<PINNUMMER_TSIC1_DATA))!=0)<<3);
26
        break;
27
      case   51: // [ 6]   upper byte bit 2
28
        hbyteTSic1 |= (((PIN_TSIC1_DATA & (1<<PINNUMMER_TSIC1_DATA))!=0)<<2);
29
        break;
30
      case   59: // [ 7]   upper byte bit 1
31
        hbyteTSic1 |= (((PIN_TSIC1_DATA & (1<<PINNUMMER_TSIC1_DATA))!=0)<<1);
32
        break;
33
      case   66: // [ 8]   upper byte bit 0
34
        hbyteTSic1 |= (((PIN_TSIC1_DATA & (1<<PINNUMMER_TSIC1_DATA))!=0)<<0);
35
        break;
36
...
37
}

Die verlorene Frage bezog sich jetzt auf die Zuweisung im letzten
gezeigten case, und war sinngemäß etwa so (hoffe ich):
Wieso wird hier nochmal gegen 0 getestet, und dann nochmal
verschoben, anstatt gleich das Bitmuster aus der rechten Seite
für das |= zu verwenden?

Antwort: das liegt daran, daß jeweils ein Bit an der falschen
Stelle entsteht.
Die einzelnen case-Anweisungen beziehen sich auf jeweils den
soundsovielten Aufruf der Interruptroutine; das letzte case also
auf den 66 Aufruf.
Bei jedem dieser case wird genau ein Bit übernommen von einem
Pin, nämlich immer am Port PIN_TSIC1_DATA das Bit
PINNUMMER_TSIC1_DATA.
Ist PIN_TSIC1_DATA z.B. PINA (TSic angeschlossen an Port A)
und ist PINNUMMER_TSIC1_DATA z.B. 4 (angeschlossen an Pin 4 von
Port A), dann liefert PIN_TSIC1_DATA & (1<<PINNUMMER_TSIC1_DATA)
entweder den Wert 0b00010000, wenn das Bit gesetzt ist, und
0b00000000, wenn nicht - und zwar gleichermaßen in jedem
der case, egal um welchen Durchlauf es sich handelt.
Dementsprechend soll aber ein Bit im Ergebnis nicht immer an
derselben Stelle gesetzt werden, sondern bei case 12 das
höchste Bit 7, bei case 66 das unterste Bit 0, die
anderen entsprechend.
Deshalb bilde ich erst
((PIN_TSIC1_DATA & (1<<PINNUMMER_TSIC1_DATA))!=0),
das liefert statt z.B. 0b00010000 immer eine 0b00000001
(also das Ergebnis ins unterste Bit verschoben, unabhängig
von PINNUMMER_TSIC1_DATA) und mit <<0, <<1, <<2 etc. je
nach Nummer des Durchlaufs und damit je nach aktueller
Stelle im Ergebnis wird dann die 1 wieder entsprechend
weit nach links geschoben.
Beim Bit 0 ist das <<0 natürlich überflüssig, und nur
als Analogie zu den anderen Fällen mit <<1, <<2 etc. dabei.

Ich hoffe, das beantwortet die Frage. Sonst bitte nochmal
mailen; ich werde es nicht gleich wieder löschen :-)

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.