Offensichtlich ist mein Problem so trivial, dass ich nichts darüber
finde.
Der Temperaturfühler TSic 506 sendet in Abständen von ca. 3ms seine 2
Bytes langen Daten seriell auf einer Datenleitung. (mit 8kHz).
Die Datenleitung soll bei mir an P2.5 des MSP430 angeschlossen sein. Und
jetzt mein Problem:
Wie kriege ich die ankommenden Nullen und Einsen seriell in einen
Puffer, um dann diese weiterverarbeiten zu können.
Als Ansatz hatte ich mir gedacht, ich definiere eine Variable, und
schiebe den Inhalt der Variablen nach jedem Takt um eine Stelle nach
links.
Aber wie kann ich P2.5 abfragen, ob dort eine Null oder Eins steht und
diesen Wert mit der Variablen so verknüpfen, dass die kompletten Daten
nach Empfang von 2 Bytes in der Variablen stehen?
Oder wie macht man es richtig? Programmierung in C.
MfG
Wolfgang
Hmm...da haste dir ja einen Sensor ausgesucht. 11 Bit Single Wire Output
für State of the Art µControllers. Ohje.
Eventuell lässt sich was über die UART machen, die irgendwie
missbrauchen. Aber das wird alles schwierig. Du musst ja den Takt auch
irgendwie rückgewinnen. Gibts da nen komplettes Datenblatt irgendwo?
Kannst du mal verlinken?
Eine Möglichkeit ist die von dir beschriebene. Das heißt, einzeln im
Takt von 8kHz den Pinzustand abfragen und immer ein weiter nach links
schieben. Nach 16 Takten hast du dann dein fertigen Wert stehen.
Wenn du noch frei in der Pinanordnung bist, würde ich persönlich eine
Hardware-SPI Schnittstelle verwenden. Dann übernimmt der MSP für dich
das schieben und zusammensetzen.
Viele Grüße
Michael
Hier geht es zum Datenblatt
http://www.zmd.biz/temp.php?group=temp&content=products
den TSic 506 habe ich mir als „Referenznormal“ beschafft. Die Fehler
soll bei < 0,1° liegen.
Es muss P2.5 als Eingang für den seriellen Datenstrom verwendet werden,
da meine Leiterplatte als Datenschreiber fertig ist und der
Temperaturfühler nur angeschlossen werden soll. Da eine serieller
Anschluss häufiger mal gebraucht wird (z.B. 1wire) , möchte ich
gleichzeitig auch noch etwas dazulernen
Von ZMD gibt es ein Programmbeispiel in C für einen 8051, welches ich
leider nicht richtig verstehe.
Deshalb würde ich noch mal meine Kernfrage in den Raum stellen: Wie
fragt man den Eingang P2.5 ab, ob dort eine logische 1 oder Null steht
und wie verknüpft man das Ergebnis mit einem Puffer?
Oder wie kann man es unter den vorgegeben Bedingungen besser machen?
Mit freundlichen Grüßen
Wolfgang
Im Wesentlichen würde das so aussehen:
Messwert = Messwert << 1;
if (P2IN&0x20)
Messwert |= 0x01;
Diesen Code müsstest du im 8 kHz Takt aufrufen.
Viele Grüße
Michael
Naja, das ist doch kein komplettes Datenblatt. Da steht nix zum Timing
usw. drin. Schon ein seltsames Teil. Seh ich das richtig, dass er alle
3ms einfach so seine 11 Bit rausfeuert? Ohne extra Takt, ohne Kodierung
ohne alles? Was soll´n das für ein Unsinn sein. Du müsstest dich ja
irgendwie exakt auf den Anfang eines Datenwortes synchronidieren, da man
ja aber nie weiß, ob das jetzt 0 oder 1 ist, wird´s bissl schwierig.
Wenn man das erste Bit hat, kann man mit einem Timer-Int abtasten, keine
Frage. Die Synchronisierung ist halt tricky. Gibts da kein richtiges
Datenblatt? In dem 6-Seiten-Wisch steht ja nix drinne....
Hmmm, hab mal bei dem Link gesucht, unter
http://www.zmd.biz/pdf/IST_TSic_ZACwire_V2.3%20Digital%20Output_17-Oct-06.pdf
steht die Beschreibung zum Protokoll. Ist schon etwas abartig, aber mit
dem MSP wohl machbar.
Also, wie in der Beschreibung mal folgendes testen:
1. Einen Timer mit 125kHz takten
2. Das Ausgangssignal auf einen interruptfähigen Eingang führen und so
konfigurieren, dass bei negativer Flanke die ISR ausgeführt wird.
3. Timerwert (T1) beim Einsprung merken
4. In der ISR solange den Eingang pollen, bis er auf high geht.
Timerwert (T2) merken und Differenz zu T1 bilden. Dabei kommt dT heraus.
5. Damit hast Du die "Strobe" Time beim Startbit ermittelt
6. Beim nächsten Einsprung in die ISR Timerwert (T3) wieder merken, T4 =
T3+dT berechnen. Warten, bis der Timer T4 erreicht hat
7. In diesem Moment auf den Eingang schauen (am besten dreimal mit
Majoritaetsenscheidung). Ist er high, hat der Sensor eine 1 ausgegeben,
ist er 0, dann hat er eine 0 ausgegeben.
8. Nacheinander in dieser Art und Weise die Bits aufsammeln. Nach 21
Bits (inclusive Startbit) ist ein Telegramm komplett und Du fängst
wieder bei 1. an
Was die ISR-Last betrifft, er ist bei einem Telegramm (2,65ms) die
Hälfte dieser Zeit in der ISR (1,3ms) beschäftigt. Bei einem Zyklus von
100ms ist das eine CPU-Belastung von ca. 1,3%. Geht also noch (ich hoffe
mal ich hab mich nicht arg verrechnet). In der Beschreibung kommen die
auf Doppelte. Weiss allerdings nicht, warum.
Probiere es halt mal aus. Schoene Aufgabe, würde ich auch gerne machen,
sicherlich interessant.
Christian R. wrote:
> Ohne extra Takt, ohne Kodierung> ohne alles? Was soll´n das für ein Unsinn sein.
Nix Unsinn, sondern schlicht PWM. Jedem, der schon man DCF77 dekodiert
hat, sollte das verdammt bekannt vorkommen. Funktioniert exakt genauso,
nur schneller, 8KHz statt 1Hz.
> Du müsstest dich ja> irgendwie exakt auf den Anfang eines Datenwortes synchronidieren, da man> ja aber nie weiß, ob das jetzt 0 oder 1 ist, wird´s bissl schwierig.
125µs lang high: Startbit folgt.
125µs lang low: Startbit isses.
Hat man einen capture-fähigen Timer, der auf beide Flanken reagieren
kann, oder den man entsprechend umschaltet, ist das problemlos so
nebenher zu erledigen. Aber bei dem dezenten Timing tut's ggf. auch ein
externer Interrupt, wie oben beschrieben. Nur sollte die
Interrupt-Latenzzeit dann unbedingt angenehm kurz bleiben.
Zunächst einmal an alle vielen Dank.
Ich denke mal, dass ich jetzt ein Stück weiterkomme und werde zunächst
mal mit Supa Michas Programmschnipsel beginnen, falls dies der dafür
gängige und einzige Weg ist, einen seriellen Datenstrom an einem Eingang
zu erfassen.
@szimmi
Wenn ich es richtig verstanden habe, wird in dem von Dir zitierten
Artikel eine weitere Möglichkeit beschrieben. Der Fühler wird über einen
µC Ausgang zu- und abgeschaltet. Nach dem Zuschalten des Fühlers wartet
man auf die fallende Flanke des Starbits auf der Datenleitung und hat
somit den Anfang des Telegramms. Mal sehen, ob das so geht.
Mit freundlichen Grüßen
Wolfgang
Nein,da habe ich mich wohl missverständlich ausgedrückt. Der Sensor wird
nur über eine Signalleitung mit einem Eingang des µC verbunden.
Der Sensor wird nicht zu- oder abgeschaltet.
Andreas Kaiser wrote:
> Christian R. wrote:>>> Ohne extra Takt, ohne Kodierung>> ohne alles? Was soll´n das für ein Unsinn sein.>> Nix Unsinn, sondern schlicht PWM. Jedem, der schon man DCF77 dekodiert> hat, sollte das verdammt bekannt vorkommen. Funktioniert exakt genauso,> nur schneller, 8KHz statt 1Hz.
Jo, is schon recht. Da kannte ich das vollständige Datenblatt noch
nicht.
@szimmi
Wahrscheinlich noch ein Missverständnis.
Ich meinte den angehängten Artikel. Lt. Abschnitt 1.4.2 erfolgt hier die
Stromversorgung des Fühlers vom µC aus. Der Stromverbrauch ist so
gering, dass er von einem Ausgang des µC versorgt werden kann. 65ms bis
85ms nach dem Zuschalten des Fühlers beginnt der Fühler mit dem Senden
des ersten Temperaturtelegramms. So habe ich es verstanden.
Mit freundlichen Grüßen
Wolfgang Gröbel
Wo ist denn da jetzt eigentlich das Problem? Ein C-Code wird von ZMD ja
schon zur verfügung gestellt. Einfach passend anwandeln und gut. Ein
Source Code für den TSic für MSP430 hab ich mal in den Anhang gepackt.
Hallo,
Habe mal versucht den Code für einen PIC 16F876A umzustricken.
Leider ist bei dem zweiten Byte der ParityCheck immer FAIL und die
Temperatur wird um 10,00°C zu wenig angezeigt.
Allersings verstehe ich dieses Verhakten absolut nicht!!
Hat jemand eine Idee????
Bin am Verzweifeln
martin
Guten Abend.
Ich versuche z.Z einen TSIC 306 zum laufen zu bringen.
atm verwende ich dazu das von Robert K. gepostete programm (zwei drei
posts über meinem)
folgendes verstehe ich aber nicht.
temperatur ist eine 16bit unsigned integer variable...was bedeutet das
float davor?
in diese variable wird der tempsensor output geladen bei 25°C sind das
0x2FF
der sensor sendet immer 11bit pakete
gut, die rechnung läuft dann mit nachkommastellen ab...
aaaber: was passiert dann? dann wird eine kommazahl auf ein uint8_t
variable geschrieben?
oder wirkt sich der cast auch irgendwie auf die Temp_celsius aus?
und wie sieht das im klartext aus, wenn eine kommazahl auf einen integer
geschrieben wird?
wird die kommazahl einfach abgerundet?
mich wundert das es überhaupt möglich ist und der compiler keinen terror
schiebt :/
danke jörg
habs jetzt am laufen :)
die angezeigte temp. macht mich zwar etwas stutzig (ich glaube 1 bis 2°C
zuviel) aber das sollte nur ein kleines problem sein
Guten Abend,
wenn ich hier einfach mal Anknüpfen darf.
Bin nun schon seit einiger Zeit am probieren, den TSIC 306 zum laufen zu
bringen, allerdings zeigt dieser mir nur Scheiße auf dem LCD an :(
Erstmal die Codeschnipsel:
Hauptprogramm:
1
// Definitionen
2
// lcd-anschlussbelegung
3
#define LCD_PORT PORTC
4
#define LCD_DDR DDRC
5
6
#define LCD_DB PC0
7
#define LCD_E PC4
8
#define LCD_RS PC5
9
10
// INCLUDE
11
#include<avr/io.h>
12
#include<avr/interrupt.h>
13
#include<util/delay.h>
14
#include<stdint.h>
15
#include"lcd_steuerung.h"
16
#include"tempsensor_ansteuerung.h"
17
18
// MAIN
19
voidmain(void)
20
21
{
22
lcd_init();
23
24
// Temperturmessung mit TSIC ausführen und Daten auf dem LCD ausgeben
25
while(1)
26
{
27
unsignedcharparity=0;// referenz für 2. übergabewert
28
uint16_twert=0;
29
lcd_string("WERT:;");
30
wert=temp_messung(&parity);//temp_byte = übergabe
31
lcd_zahl_16(wert);
32
lcd_cursor(0,2);
33
lcd_string("parity:;");
34
lcd_zahl_8(parity);
35
_delay_ms(500);
36
lcd_befehl(1);
37
38
//ende while
39
//33246 bei 20°C
40
}
41
42
43
44
while(1){};
45
46
47
}
LCD-Ansteuerung:
1
// LCD_FUNKTIONEN
2
/* ansteuerung eines LC-Displays im 4bit modus.
3
Wartezeiten nach Datenblatt, Pinbelegung einsellbar.
4
5
6
// Definitionen
7
// lcd-anschlussbelegung
8
#define LCD_PORT PORTC
9
#define LCD_DDR DDRC
10
11
#define LCD_DB PC0
12
#define LCD_E PC4
13
#define LCD_RS PC5
14
*/
15
16
// lcd-Befehle
17
18
// clear display----------------0b00000001
19
#define lcd_display_löschen 0x01
20
21
// cursor bewegen
22
#define LCD_CURSOR_HOME 0x02
23
24
// DDRAM - Adresse festelgen
25
#define LCD_DDRAM 0x80
26
27
/* lcd-adressen für die Zeilen
28
angaben sind für ein 4x20 Zeichen lcd.
29
bei anderen auflösungen müssen die werte angepasst werden.
while(fallende_flanke);// warte auf fallende Flanke
20
21
while(steigende_flanke);// auf steigende Flanke warten
22
23
for(uint8_ti=0;i<8;i++)// hier nun Bits auswerten
24
{
25
while(fallende_flanke);// warten bis zum ersten bit.
26
_delay_us(tsic_delay_us);// 60µSekunden warten
27
if(steigende_flanke)// wenn eingang 1,
28
temp_byte|=1<<(15-i);// dann bit schreiben
29
else// wenn nicht,
30
while(steigende_flanke);// dann warten bis flanke wieder steigt, bzw. immernoch eingang = 1.
31
}
32
33
// parity auswerten bzw. erstmal abwarten
34
while(fallende_flanke);// Parity_bit
35
_delay_us(tsic_delay_us);// 60µs warten
36
if(steigende_flanke)
37
*parity_byte|=1<<1;// wenn parity = 1, dann eine 1. eine stelle nach links schieben
38
elsewhile(steigende_flanke);// wenn parity_byte = 0, dann warten bis flanke wieder steigt
39
40
// stoppbit absitzen
41
while(fallende_flanke);// stop bit
42
43
// startbit absitzen
44
while(steigende_flanke);// start bit
45
46
// 2 byte LSB
47
for(uint8_ti=0;i<8;i++)// hier nun Bits auswerten
48
{
49
while(fallende_flanke);// warten bis zum ersten bit.
50
_delay_us(tsic_delay_us);// 60µSekunden warten
51
if(steigende_flanke)// wenn eingang 0,
52
temp_byte|=1<<(7-i);// dann bit schreiben
53
else// wenn nicht,
54
while(steigende_flanke);// dann warten bis flanke wieder steigt, bzw. immernoch eingang = 1.
55
}
56
// parity auswerten bzw. erstmal abwarten
57
while(fallende_flanke);// Parity_bit
58
_delay_us(tsic_delay_us);// 60µs warten
59
if(steigende_flanke)
60
*parity_byte|=1<<0;// wenn parity = 1, dann eine 1. 0 stellen nach links schieben
61
62
tsic_off;// Sensor ausschalten
63
64
returntemp_byte;// gemessenen Wert zurückgeben
65
}
Ich verwende aktuell im "main"-Abschnitt die direkte Wert-Ausgabe, d.h.
er zeigt mir den eingelesenen Wert direkt an.
Da kommt aber absoluter Mist raus. Verändere ich die T-strobe Zeit auf 1
µS, so zeigt er mir 65471 an, wobei nach meinem Verständnis hier 0
angezeigt werden sollte. Allgemein kommt mit jeder anderen Wartezeit ein
anderer Wert raus und ich kapier einfach nicht warum. Der Code ist stark
an den im Datenblatt angegebenen angelehnt. Vielleicht kann ja mal
jemand schnell drüber schauen ob er einen Fehler findet. Oder besser
jemand hat mal ein Digitaloszi an den Sensor gehangen und kann mir
beschreiben, wie der genaue Ablauf zwischen dem 1. und 2. Byte mit
Stop/Start-Bit vonstatten geht. Die LCD-Funktionen funktionieren
einwandfrei, der Fehler muss in der letzten Datei liegen, irgendwo bei
der einleserei. Ich find einfach keinen Fehler.
Ich Danke Euch schonmal für die Hilfe.