Einleitung
Beim TSIC™ (Temperature Sensor Integrated Circuit) [1] handelt es sich um ein Sensor IC, zum Messen von Temperaturen. Dieser Sensor ist in verschiedenen Bauformen, Präzisionsklassen und Ausgangs-Datenformaten verfügbar. Dieser Artikel befaßt sich mit den Typen x06, die den Meßwert digital als 11-Bit Wort liefern.
Zacwire™ Protokoll
Das Zacwire™-Protokoll [2] benötigt nur eine Datenleitung und liefert neben den Daten auch den Takt. Die fallenden Flanken des Signals definieren den Takt, der bei ca. 8 kHz liegt. Die Kodierung der Bits erfolgt durch die Pulsweite (Duty Cycle) und beträgt 25% (L) bzw. 75% (H). Da die Signalperiode durch den Takt auf eine feste und konstante Länge definiert ist, kann bei 50% dieser Periode das Bit direkt gelesen werden.
Abbildung 1 zeigt die Zusammenhänge. Das Signal vom Sensor ist an Channel 1 (gelb) angelegt, während an Channel 2 (blau) der daraus isolierte Takt mit einer Pulsweite von 50% (tSTROBE)dargestellt wird. Man kann gut erkennen, daß tSTROBE die Hälfte eines Taktzyklus (50%) beträgt und das Signal bei der steigenden Flanke der blauen Kurve verfügbar ist. Man kann auch gut die gesamte Signal-Sequenz erkennen, die aus genau 20 TSIC™ Takten besteht. Der TSIC™ sendet das Signal mit einer Frequenz von ca. 8 kHz. Diese Frequenz ist leider nicht stabil und ändert sich geringfügig im laufenden Betrieb. Daher sollte die Frequenz gemessen werden um den Zeitpunkt für das Lesen des Signals möglichst genau in der Mitte einer Taktperiode festzulegen. Im Gegensatz zu einer fest definierten Wartezeit, reduziert das die Störanfälligkeit enorm. Die Frequenz läßt sich mit Hilfe des Start-Bits ermitteln, da der TSIC™ das Startbit mit einem Duty Cycle von genau 50% sendet, das Signal also genau in der Mitte des Taktes auf H wechselt. Im Abschnitt Software wird das genauer beschrieben. Der Sensor sendet das Messergebnis als 11-Bit Daten-Wort. Dazu ist die Übertragung von zwei Bytes notwendig. Jedes Byte beginnt mit einem Startbit und endet mit einem Parity-Bit. Daraus ergibt sich eine Sequenz von insgesamt 20 Bits. Das High-Byte des Datenwortes wird zuerst übertragen (Abbildung 2).
Das Startbit des ersten Bytes wird also zur Ermittlung der Frequenz und damit zur Errechnung der Wartezeit nachfolgender ISR Aufrufe genutzt. Das Start/Stop-Bit zwischen den Bytes hat die Länge von zwei Takten, wobei das Stop-Bit über die volle Periode High-Pegel besitzt. Das Parity-Bit erweitert das Byte zu einer geraden Anzahl (Even) von gesetzten Bits. Damit wird die Datenintegrität geprüft. Der TSIC™ sendet alle 100 ms einen Messwert. Da der Sensor weniger als 100 µA Strom zieht, kann man den VCC Pin direkt von einem Mikrocontroller-Ausgang treiben und damit die Meßwertübertragung softwareseitig ein- bzw. ausschalten. Dabei sollte jedoch berücksichtigt werden, daß der erste Meßwert nach dem Anlegen der Spannung erst nach etwa 65-85 ms erfolgt.
Beschaltung
Der Temperatur-Sensor ist einfach zu beschalten. Das Datenblatt [2] empfiehlt möglichst dicht am IC ein RC-Glied anzuschalten um Störungen durch das Controller-Netzteil zu reduzieren.
Temperatur-Auflösung
Der TSIC™ hat einen Meßbereich von -50° C bis 150° C, umfaßt also insgesamt 200°. Der Meßwert wird in einem 11-Bit langem Wort geliefert. Das entspricht einem linearen Wertebereich von 0-2048. Daher muß das Ergebnis nach folgender Formel umgerechnet werden, um die Temperatur zu erhalten:
bzw.
Für die Umrechnung des Meßwertes wird also eine Multiplikation und eine Division bzw. eine Multiplikation mit Gleitkommazahl benötigt. Beides ist für einen Mikrocontroller mit begrenztem Speicher eine große Herausforderung. Um das mit vertretbarem Aufwand umsetzen zu können, muß die Formel etwas umgestellt werden. Zuerst wird der Bruch gekürzt:
Häufig genügt es, Temperaturen über 0° C zu messen, dann kann der Wertebereich des Meßwertes verkleinert werden indem der Offset (50° = 512) vor der Berechnung abgezogen wird. Weiterhin soll die Temperaturauflösung von 0,1° erhalten bleiben, was eine Erweiterung um den Faktor 10 erfordert. Es ergibt sich dann folgende Berechnungsformel:
In Software ist das schon sehr viel leichter handhabbar. Die Subtraktion besteht nur aus zwei Befehlen. Dann erfolgt eine 16-Bit-Multiplikation. Die anschließende Division durch eine Potenz von 2 kann leicht durch eine Rechtsverschiebung realisiert werden. Bei dieser Vorgehensweise wird keine Genauigkeit durch überflüssige Rundungen der Zwischenergebnisse eingebüßt. Lediglich bei der finalen Division gehen ein paar Nachkommastellen verloren, was aber tolerierbar ist.
Software
Es gibt zwei grundsätzliche Möglichkeiten, die Messwerte eines TSIC™ zu erfassen:
- On-Demand
- diese Methode hält den TSIC™ abgeschaltet und stößt eine Messung manuell an, indem der TSIC™ über einen Ausgangs-Pin per Software mit Spannung versorgt und dann in einer Polling-Schleife auf den Meßwert gewartet wird. Dies hat den Vorteil, daß der Mikrocontroller nicht durch eine Messung unterbrochen wird. Nachteilig ist jedoch, daß eine solche Messung etwa 90 ms in Anspruch nimmt, da der TSIC™ die erste Messung erst nach etwa 65-85 ms liefert und eine Messung ca. 2 ms dauert. Der Controller ist während dieser Zeit beschäftigt und kann keine anderen Dinge tun. Interrupts sollten während der Bearbeitung abgeschaltet werden. Da der Sensor bei der ersten Messung seine Betriebstemperatur noch nicht erreicht hat, sollte man mehrere Messungen durchführen und dann den Mittelwert bilden, was zusammen einige 100 ms in Anspruch nehmen kann.
- Interrupt-gesteuert
- diese Methode ist die bessere Wahl, da der Controller hier im Slave-Modus die Daten empfangen kann, wenn sie gesendet werden. Es muß nicht gewartet werden und die einzelnen Bits kommen genau „getimed“ am Controller an und können direkt verarbeitet werden. Allerdings ist die Verarbeitung etwas aufwändiger und der Controller muß mindestens mit 4 MHz getaktet werden.
Im Folgenden wird auf die erste Methode nicht weiter eingegangen. Der Controller wird so konfiguriert, daß er einen externen INT0- oder INT1-Interrupt auf der fallenden Flanke des TSIC™-Signals auslöst. Damit bekommen wir jedes Bit des Sensors frei Haus geliefert, wenn es verfügbar ist. Um den Verarbeitungsstatus über die einzelnen ISR Aufrufe zu persistieren, ist ein Status-Byte definiert und in einem General-Purpose IO Register abgelegt, was ein Byte im SRAM spart und einen schnelleren Zugriff ermöglicht. In der ISR wissen wir also immer, welches der 20 Bits gerade verarbeitet werden soll. Abbildung 4 zeigt den Aufbau des Status-Bytes.
Die einzelnen Bitpositionen bedeuten:
- A – Active Flag
- Wird beim ersten Start Bit gesetzt und zeigt eine laufende Verarbeitung an. Es ist während der gesamten Verarbeitung gesetzt und wird erst mit dem letzten Bit zurück gesetzt
- V – Valid Measurement
- wird gesetzt, wenn die Verarbeitung fehlerfrei durchgelaufen ist und ein gültiger Meßwert verfügbar ist. Dieses Bit muß vom Programm abgefragt werden, bevor auf den Meßwert zugegriffen wird
- H – High-Byte Flag
- Da der Aufbau beider Bytes identisch ist, muß die ISR wissen, welches Byte gerade decodiert wird.
- P – Process-Step
- In diesen beiden Bits wird der nächste Schritt aus der Verarbeitungs-Sequenz gespeichert. Die Sequenz ist für jedes Byte durch das Format festgelegt (START-DATA-PARITY). Zusammen mit dem High-Byte Flag und dem Bitzähler, ist das zu verarbeitende Bit eindeutig identifiziert.
- B – Bitcounter
- die letzten drei Bits dienen als Zähler für das Bit, daß gerade verarbeitet wird (7..0)
Die sequentielle Abfolge der Verarbeitung ist simpel. Jeder Schritt weiß, welcher der nächste ist und aktualisiert das Control-Status Register entsprechend.
Im ersten Schritt (START) erfolgt die Initialisierung des Prozesses. Dazu wird die Frequenz des Sensors mit einer Zählschleife ermittelt. Dieser Wert wird zur Initialisierung der Warteschleife für folgende ISR Aufrufe genutzt. Er wird in einem weiteren GPIOR persistent abgelegt.
Dann wird das Control-Status Register initialisiert und der Messwert gelöscht. Die DATA-Phase wird für jedes Byte genau acht mal durchlaufen. Der Bitzähler im Control-Status Register wird dazu von 7 bis 0 herabgezählt und identifiziert damit gleichzeitig das Bit und dessen Position im Ergebnis-Byte. Nur wenn das gelesene Signal-Bit = 1 ist, wird das Bit an der entsprechenden Position im Ergebnis gesetzt. Nicht gesetzte Bits werden nicht verarbeitet.
Ist der Zähler auf 0 zurück gezählt worden, wird das Control-Status Register aktualisiert und auf den nächsten Schritt gesetzt. Nun erfolgt die Verarbeitung des Parity-Bits für das decodierte Ergebnis-Byte. Das Parity-Bit erweitert das gelesene Datenbyte und es wird geprüft, ob zusammen eine gerade Anzahl gesetzter Bits vorhanden ist.
Ist dies der Fall, dann wird das Control-Status Register beim High-Byte auf den nächsten Schritt (START/STOP) gestellt und das High-Byte Flag gelöscht. Schlägt der Parity-Check fehl, dann wird die Messung verworfen und die Verarbeitung abgebrochen. Das geschieht durch die Löschung des Control-Status Registers und einer Warteschleife von 2 ms. Schließlich werden noch alle wartenden Interrupts gelöscht. Bis zur nächsten Messung steht dann kein gültiger Meßwert zur Verfügung.
Als nächstes folgt das START/STOP Bit, welches lediglich eine Aktualisierung des Control-Status Registers bewirkt. Es wird auf den nächsten Prozess-Schritt (DATA) gesetzt.
Die Verarbeitung des Low-Datenbytes des Meßwertes erfolgt analog dem High-Byte, außer daß die Bits nun in das Low-Byte geschoben werden. Nach dem letzten Bit wird der Prozess-Schritt wieder auf PARITY gesetzt. Auch für das Low-Byte wird nun wieder ein Parity-Check durchgeführt, der im Falle eines Fehlschlags wieder zur Verwerfung des Messwertes und der Beendigung der Verarbeitung führt. Ist die Prüfung in Ordnung, wird nun aus dem empfangenen Messwert der Temperaturwert errechnet.
Abschließend wird noch das Aktiv-Flag gelöscht um zu signalisieren, daß die Verarbeitung abgeschlossen ist und das Valid Flag gesetzt, sodaß die gemessene Temperatur weiter verarbeitet werden kann. In Abbildung 6 ist die gesamte ISR als Ablauf-Flußdiagramm dargestellt. Es zeigt den detaillierten Aufbau und zeigt, wie die Daten in den einzelnen Schritten verarbeitet werden.
Timings
TSIC™ Frequenz | 8000 | Hz |
Pulslänge | 125 | µs |
tSTROBE | 62 | µs |
CPU-Clock | 4 | MHz |
Delay Counter | 58 | |
Delay | 247 | clks |
Delay | 62 | µs |
Pfad | clks | µs |
---|---|---|
Start | < 301 | < 75 |
Data | < 355 | < 89 |
Parity (High) | < 384 | < 96 |
Parity (Low) | < 657 | < 164 |
Parity (invalid) | 8408 | 2102 |
Start/Stop | 300 | 75 |
Der Beispiel-Code ist in AVR-Assembler geschrieben. Es ist sinnvoll, daß zumindest die ISR ein kontrolliertes Laufzeitverhalten aufweist, was nur mit Assembler realisierbar ist, damit sichergestellt ist, daß ein Durchlauf abgeschlossen ist, bevor der TSIC™ das nächste Bit schickt.
Da die Verarbeitung eines Bits immer mit einer Warteschleife von ca. 60 µs beginnt (tSTROBE), bleiben für die Verarbeitung eines Prozess-Schrittes maximal nur weitere 60 µs. Das setzt selbst in Assembler einen Prozessortakt von mindestens 4 MHz voraus. Wird der Code in C geschrieben, wird der Code trotz Optimierung nicht effizient genug sein. Auf Grund der kritischen Anforderungen sollte in diesem Fall eine Optimierungs-Option gewählt werden, die auf schnelle Ausführung optimiert. Zur Sicherheit ist dann auch ein Prozessortakt von mindestens 8 MHz zu wählen.
Tabelle 1 zeigt die Ausführungszeiten der einzelnen ISR-Durchläufe des hier vorgestellten Beispiel-Codes bei einem CPU-Takt von 4 MHz. Die Zeiten enthalten die Warteschleife und liegen alle unter 100 µs. Die beiden Ausreißer in der Parity-Phase sind unkritisch, da dies jeweils das letzte Bit der Sequenz ist (Ausgang). Die langen Zeiten sind entweder so gewollt (invalidate) oder resultieren aus der Messwert/Temperatur Umrechnung, die am Ende der Verarbeitung durchgeführt wird. Bei den Warteschleifen soll noch darauf hingewiesen werden, daß der Aufruf einer ISR ebenso wie der Rücksprung jeweils 4 Prozessor-Takte benötigen. Zusammen mit der Sicherung der Register sind das nach dem Auftreten der fallenden Flanke 13 Takte, bis die ISR produktiven Code ausführen kann. Für die Laufzeit der ISR sind also insgesamt 26 Takte für den Startup/Cleanup Code zu berücksichtigen.
Die Zählschleife der Frequenzmessung verbraucht für jeden Durchlauf 4 Takte, hat also eine Auflösung von 1 µs. Damit der gezählte Wert für die Warteschleife verwendet werden kann, verbraucht auch diese pro Durchlauf 4 Takte. Da sowohl bei Zählen als auch beim Warten der Startup-Code der ISR durchlaufen ist, kann der Zählerwert direkt für die Initialisierung der Warteschleife verwendet werden. Er liegt je nach Frequenz des Sensors bei ca. 58.
Listings
; ============================================================================
; Temperature Controller with TSIC (INT1 ISR) (AS)
;
; MCU ATtiny2313
; Clock 4.0 MHz
;
; Copyright (c) by Juergen Werner, Koeln 2012
; ============================================================================
#include <avr/io.h>
#include "common.h"
signal = 17
tmp = 16
cnt = 18
mwl = 17
mwh = 18
pck = 17
; global definition of measurement value (uint16)
.comm measurement, 2
.section .text
;== ---------------------------------------------------------------------------
;== ISR INT1 (serves falling edges on PD2)
;== ---------------------------------------------------------------------------
.global INT1_vect
INT1_vect:
push signal
push tmp
push cnt
in tmp,_SFR_IO_ADDR(SREG)
push tmp
; check if this is the start edge (active flag is low)
sbis _SFR_IO_ADDR(ZACWIRE_CONTROL), ZW_ACTIVE_FLAG
rjmp init ; not active, goto initializing block
; tstrobe delay (preloop 15 clocks, one cycle 4 clocks)
in signal, _SFR_IO_ADDR(DELAY_PRESET)
dloop: dec signal ; decrement (1 clk)
nop ; we need 4 clocks per loop
brne dloop ; loop until 0 (2 clks)
; get bit from signal pin and save it in signal register
sbic _SFR_IO_ADDR(ZACWIRE_PIN), ZW_SIGNAL_PIN
ldi signal, 1 ; if skipped signal is 0
; processing is already active, check processing steps
; check DATA
in tmp, _SFR_IO_ADDR(ZACWIRE_CONTROL) ; get control structure
andi tmp, PROCMSK ; isolate processing step
cpi tmp, DATA ; check DATA
brne party ; isn't, goto next check
; DATA (bit processing)
; get bitcounter decrement and save into control structure
in tmp, _SFR_IO_ADDR(ZACWIRE_CONTROL)
mov cnt, tmp ; save bitcounter in cnt
andi cnt, BITMASK ; isolate
dec cnt ; counting from 7...0 (init 0)
andi cnt, BITMASK ; isolate (because of overflow)
andi tmp, ~(BITMASK) ; clear cnt area in control struct
or tmp, cnt ; insert new bit counter value
out _SFR_IO_ADDR(ZACWIRE_CONTROL), tmp ; update control structure
; check if actual bit is set, then skip bit processing
tst signal
breq ckcnt ; continue with bit counter check
; signal is set, update measurement value
mov tmp, cnt ; copy bit counter
tst tmp ; check if 0 (last bit - LSB)
bloop: breq ckhbt ; last bit
lsl signal ; otherwise left shift to bit pos
dec tmp ; shift counter
rjmp bloop ; shift loop
ckhbt: ; select actual processing byte
sbis _SFR_IO_ADDR(ZACWIRE_CONTROL), ZW_HIGH_BYTE
rjmp lowbt
highbt: ; actual processing high byte
lds tmp, (measurement + 1) ; get high byte from memory
or tmp, signal ; set bit
sts (measurement + 1), tmp ; save high byte
rjmp ckcnt
lowbt: ; actual processing low byte
lds tmp, (measurement + 0) ; get low byte from memory
or tmp, signal ; set bit
sts (measurement + 0), tmp ; update low byte
; falling through
ckcnt: ; finalize bit processing with check of bit counter
tst cnt
brne exit ; not null, end here, wait for next bit
; bitcounter is 0 - byte complete, init next step (parity)
in tmp, _SFR_IO_ADDR(ZACWIRE_CONTROL) ; get control structure
andi tmp, ~(PROCMSK) ; isolate processing step
ori tmp, PARITY ; set next step to parity
out _SFR_IO_ADDR(ZACWIRE_CONTROL), tmp ; update
rjmp exit ; finish data bit processing
party: ; check process step is PARITY ?
cpi tmp, PARITY ; check if actual step is parity
brne start ; no data, no parity, goto start block
; start parity bit processing here
rcall check_parity ; check parity
brcc par0
rcall invalidate ; reset and ignore the rest
rjmp exit
par0: ; parity check was ok ...
sbis _SFR_IO_ADDR(ZACWIRE_CONTROL), ZW_HIGH_BYTE ; check highbyte
rjmp par2 ; no, check low byte
par1: ; processing high byte parity
in tmp, _SFR_IO_ADDR(ZACWIRE_CONTROL) ; get control structure
andi tmp, ~(PROCMSK | (1<<ZW_HIGH_BYTE)) ; clear step an highbyte
out _SFR_IO_ADDR(ZACWIRE_CONTROL), tmp ; save control structure
rjmp exit
par2: ; processing low byte prarity, finish tsic processing here (last step)
rcall calculate ; calculate measurement value (adjust)
cbi _SFR_IO_ADDR(ZACWIRE_CONTROL), ZW_ACTIVE_FLAG ; reset activ
sbi _SFR_IO_ADDR(ZACWIRE_CONTROL), ZW_VALID_FLAG ; set valid flag
rjmp exit
start: ; start bit received - only between high- and low-byte
; initizing processing of second byte
in tmp, _SFR_IO_ADDR(ZACWIRE_CONTROL) ; get control structure
andi tmp, ~(PROCMSK) ; clear processing step area
ori tmp, DATA ; set next step to data
out _SFR_IO_ADDR(ZACWIRE_CONTROL), tmp ; save structure
rjmp exit
init: ; init waiting for rising edge and save for later delay loops
clr cnt ; clear counter
init0: ; loop for counting needs 4 clocks
inc cnt ; increment delay counter
sbis _SFR_IO_ADDR(ZACWIRE_PIN), ZW_SIGNAL_PIN ; check signal
rjmp init0 ; jump loop if cleared
dec cnt ; adjust
out _SFR_IO_ADDR(DELAY_PRESET), cnt ; save preset
; first edge control inactive, initialize tsic processing sequence
; set active flag, reset valid flag, set highbyte flag and first step
ldi tmp, (1<<ZW_ACTIVE_FLAG) | (1<<ZW_HIGH_BYTE) | (PROCMSK & DATA)
out _SFR_IO_ADDR(ZACWIRE_CONTROL), tmp ; update structure
eor tmp, tmp
sts (measurement + 0), tmp ; clear measurement value (low)
sts (measurement + 1), tmp ; clear measurement value (high)
; falling through
exit: ; exit isr
pop tmp
out _SFR_IO_ADDR(SREG), tmp
pop cnt
pop tmp
pop signal
reti
;== ---------------------------------------------------------------------------
;== void calculate(void) - local function
;==
;== calculation of measurement value from TSIC
;== T = ((MW - 511) * 1000) / 1024
;==
;== @return modifies measurement value in memory
;== @destroys mwh, mwl, tmp
;== ---------------------------------------------------------------------------
calculate:
push r0
push r1
push r2
push r3
lds mwh, (measurement + 1) ; get row measurementment (high part)
lds mwl, (measurement) ; get row measurementment (low part)
subi mwl, 0xFF ; first expression (MW - 511)
sbci mwh, 0x01
clr r3 ; prepare product destination (r3:r2:r1:r0)
clr r2
ldi tmp, 125 ;
mov r0, tmp
clr r1
ldi tmp, 16 ; load bit counter (will shift 16 times)
lsr r1 ; first shift right (product low word)
ror r0
cmulxa:
brcc cmulxb ; if right byte was 1 (carry set)
add r2, mwl ; add measurementment value to product
adc r3, mwh
cmulxb: ; otherwise just shift whole product right
ror r3
ror r2
ror r1
ror r0
dec tmp ; decrement bit counter to process next bit
brne cmulxa ; repeat 16 times
ldi tmp, 7 ; div / 128 equal to right shift 7 times (log2(128))
cdivxa:
ror r2 ; shift whole product ( /2 )
ror r1
ror r0
dec tmp ; 7 times => / 128
brne cdivxa
sts (measurement + 1), mwh ; save calculated temperature (high part)
sts (measurement), mwl ; save calculated temperature (low part)
pop r3
pop r2
pop r1
pop r0
ret
;== -------------------------------------------------------------------------
;== uint8 check_parity(uint8 pck) - local function
;==
;== this method checks the parity of the decoded byte
;==
;== @param parity bit in pck (signal)
;== @return 0 if ok, otherwise 1 in pck
;== @destroys tmp
;== -------------------------------------------------------------------------
check_parity:
; pck = signal contains the received parity bit (initial value)
sbis _SFR_IO_ADDR(ZACWIRE_CONTROL), ZW_HIGH_BYTE ; check highbyte
lds tmp, (measurement + 0) ; get low byte
sbic _SFR_IO_ADDR(ZACWIRE_CONTROL), ZW_HIGH_BYTE ; check highbyte
lds tmp, (measurement + 1) ; get low byte
ploop: tst tmp ; check if bits are set
breq pexit ; no, break here
lsr tmp ; get next bit in carry
brcc ploop ; carry set, add bit
inc pck ; add 1 to result
rjmp ploop ; next bit
pexit: ; parity check completed, finalize result (even parity)
lsr pck ; result to carry
ret
;== ---------------------------------------------------------------------------
;== void invalidate(void) - local function
;==
;== if wrong result, stop processing here and synchonize by waiting 2ms
;== will reset active flag and valid flag
;==
;== @destroys tmp, cnt
;== ---------------------------------------------------------------------------
invalidate:
; delay 2 ms
; inner loop will need exactly 1002 clocks
ldi cnt, INVALIDATE_DELAY ; init outer loop
outlp: ldi tmp, 250 ; init inner loop
innlp: dec tmp ; count back
nop ; one clock
brne innlp ; loop
dec cnt ; count back outer loop
brne outlp ; outer loop
; reset processing control structure
clr tmp ; clear control structure
out _SFR_IO_ADDR(ZACWIRE_CONTROL), tmp ; save structure
; clear all waiting interrupt requests
ldi tmp, (1<<INTF1) ; (re)set INT1 Flag
out _SFR_IO_ADDR(EIFR), tmp ; by writing 1 to GIFR
ret
.end
/******************************************************************************/
/* Common Header File contains definitions used in all Files */
/* */
/* Author: Juergen Werner */
/* Created: 14.03.2010 */
/* Last modified: 25.08.2012 */
/* Version: 1.1 */
/* Copyright (c) by Trimension, Cologne */
/******************************************************************************/
#ifndef COMMON_H_
#define COMMON_H_
#include <avr/io.h>
// === MCU Speed Definition ===
#ifndef F_CPU
#define F_CPU 4000000 // processor clock frequency
#warning F_CPU not set - redefined
#endif
// ----- TSIC ISR definitions
#define INVALIDATE_DELAY (2 * (F_CPU / 1000000))
#define ZACWIRE_CONTROL GPIOR0 // processing control structure register
#define ZW_ACTIVE_FLAG GPIOR07 // processing active mark
#define ZW_VALID_FLAG GPIOR06 // processing inactiv and valid measurement value
#define ZW_HIGH_BYTE GPIOR05 // internal, processing highbyte
#define DELAY_PRESET GPIOR1 // contains calculated TSTROBE preset
#define BITMASK 0x07 // internal, bitcounter in processing control structure
#define PROCMSK 0x18 // internal, step marker in processing contr. structure
#define DATA 0x08 // next step data bit decoding
#define PARITY 0x10 // next step parity bit processing
// TSIC Port definitions
#define ZACWIRE_PIN PIND
#define ZW_SIGNAL_PIN PD3 // IN - sensor input signal
#endif /* COMMON_H_ */
Quellverweise
- IST AG, Schweiz – Produktbeschreibung – TSIC™ Produktbeschreibung und Datenblatt
- IST AG, Schweiz – ZACWIRE™ Protokoll – ZACWIRE™ Digital Output – Application Notes