{**************************************************************}
program WS2300_Slave;
{ S.Taborek - Beginn: 28.02.2005}
{ Modul für die Verbindung zur Wetterstation WS2300}
{ Stand : 22.05.2005}
{ Stand : 03.06.2005}
{**************************************************************}
{$NOSHADOW}
Device = mega8, VCC=4.8;
(*
Define_Fuses
LockBits0 = [];
FuseBits0 = [CKSEL0, CKSEL1, CKSEL3, SUT0, BODEN];
FuseBits1 = [];
ProgMode = SPI; *)
Import SysTick, RTclock, SerPort, TWINet;
From System Import random, longword, Processes;
Define
ProcClock = 16000000; {Hertz}
SysTick = 10; {msec}
StackSize = $0096, iData;
FrameSize = $0064, iData;
Scheduler = iData;
//
SerPort = 2400, Stop1; {Baud, StopBits|Parity}
RxBuffer = 32, iData;
TxBuffer = 32, iData;
//
TWInetMode = Slave;
TWInode = $03; {default address in slave mode}
TWIpresc = TWI_BR100; {Bitrate}
TWIframe = 54, iData; {buffer/packet size}
TWIframeBC = 4; {Broadcast Frame size}
//
RTClock = iData, DateTime;{Time, DateTime}
RTCsource = SysTick;
//uses Unit_Types;
Implementation
{$IDATA}
{--------------------------------------------------------------}
{ Type Declarations }
type
TReply = array[0..31]of Byte;
TRAMDATENRec = Record
Rec_jj : byte; //1
Rec_mm : byte; //2
Rec_dd : byte; //3
Rec_hh : byte; //4
Rec_mi : byte; //5
//..........................
TempInn : Integer; //6..7 1
TempOut : Integer; //8..9 2
HumidityOut : Word; //10..11 3
WindSpeed : word; //12..13 4
WindDir : Word; //14..15 5
AirPressRel : Word; //16..17 6
DewPoint : Word; //18..19 7
RainTotal : Word; //20..21 8
OkBits : Byte; //22 für Werte 1..8
//...........................
CRS : Byte; //23
end;
// folgener Record muss in Größe gleich dem TRAMSaveRec sein!
TRAMContrRec = Record
RecStart_jj : byte; //1
RecStart_mm : byte; //2
RecStart_dd : byte; //3
RecStart_st : byte; //4
RecStart_mi : byte; //5
RecSize : byte; //6
MAX_DevNr : byte; //7
SaveZyk : byte; //8
Akt_WrSnr : word; //9..10
Last_RdPC : word; //11..12 letzter DS an PC
Last_AnzPC : word; //13..14
IdentCode : word; //15..16
voll : boolean; //17
d : byte; //18
MasterStatus : byte; //19
WSS_SlvStatus : byte; //20
RAM_SlvStatus : byte; //21
LCD_Slvstatus : byte; //22
CRS : byte; //23
end;
TRAM_DS = array[1..sizeOf(TRAMDATENRec)] of byte;
// da RAM-Wetterdaten und Ctrl-Daten gleich groß sind,
// wird TRAM_DS auch als TRAM_CDS verwendet
TTime1 = array[1..3{4}] of byte;
//.................................................
// folgender Record darf die Größe von TWIframe nicht übersteigen!!
// Der Record enthält alle Messwerte der Wetterstation - auch jene,
// die nicht im RAM archiviert werden.
TWSTSlaveDS = Record
cmd : byte; //1
Time : TTime1; //2..4 4
Date : TTime1; //5..7
TempInnen : Integer; //8..9
TempAussen : Integer; //10..11
HumidityInn : word; //12..13
HumidityOut : word; //14..15
WindFlag : byte; //16
WindCode : Byte; //17
WindSpeed : word; //18..19
WindDir : array[1..7]of byte;//20..26
AirPressRel : Word; //27..28
Rain1H : word; //29..30
RainTotal : word; //31..32
DewPoint : word; //33..34
Reserve : byte; //35
WSSensorExt : byte; //36
MW_Status : word; //37..38 für alle MW
WSConnErr : word; //39..40
Last_RdPC : word; //41..42
MasterStatus : byte; //43 >> LED s
WSS_Slv_Status : byte; //44
RAM_Slv_Status : byte; //45
LCD_Slv_status : byte; //46
RAMCapacity : longword; //47..50
r1 : longword;
end;
// folgender Record darf die Größe von TWIframe nicht übersteigen!!
TRAMSlaveRec = Record
cmd : byte; //1
qui : byte; //2
Akt_WrSnr : word; //3..4
CtrlDS : TRAMContrRec; //Controldaten 5..28
WetterDS : TRAMDATENRec; //Wetterdaten 29..51
r1 : longword;
end;
{--------------------------------------------------------------}
{ Const Declarations }
const
BroadCNode : byte = $00;
MasterNode : byte = $02;
WSTSlvNode : byte = $03;
RAMSlvNode : byte = $04;
LCDSlvNode : byte = $05;
BatSlvNode : byte = $06;
const
FM24C_Adr : byte = $50; // Moduladr. im Datenblatt: 10100000b
SlvTimeOut : byte = 20; // 20x SysTick = 200msec
TxFrameSize : byte = sizeOf(TWSTSlaveDS);
TxLCDFrameSize : byte = SizeOf(TWSTSlaveDS);
TimeoutLimit : byte = 230; // für Timeoutüberwachg. der ser.Schnittst.
CRAM_ZykTime : byte = 10; // Anzahl Minuten bis Speicherung
const
RAMCtrlCode : word = $abcd;
RAM_MAX_DevNr : byte = 3; // 0..3 für Anzahl FM24C256
RAMDevCapacit : word = 32768; // Bytes pro Device
RAMRecSize : byte = sizeOf(TRAMDATENRec);
RAMDS_proDev : word = RAMDevCapacit div word(RAMRecSize);
RAM_MAX_Snr : word = ((RAM_MAX_DevNr + 1)* RAMDS_proDev) -1; //
RAMContrDSAdr : word = 0; // Datensatzadresse für Control-Daten
//-----------------------------
ClearBuffer : byte = $01; // broadcast for Slv to clear Rx state
cmd_01 : byte = $01;
cmd_02 : byte = $04;
cmd_03 : byte = $15;
cmd_04 : byte = $17;
cmd_05 : byte = $19;
cmd_06 : byte = $31;
cmd_07 : byte = $43;
cmd_08 : byte = $07;
cmd_09 : byte = $13;
qui_01 : byte = $A1;
qui_02 : byte = $A4;
qui_03 : byte = $A7;
qui_04 : byte = $A9;
kenng1 : byte = $37;
kenng2 : byte = $32;
kenng3 : byte = $31;
kenng4 : byte = $33;
kenng5 : byte = $35;
kenng6 : byte = $36;
kenng8 : byte = $38;
kenng9 : byte = $A2;
kenngA : byte = $AA;
kenngB : byte = $BB;
kenngC : byte = $CC;
// es folgen Messwert-Kennzeichnungen:
CTempInn : word = 1;
CTempOut : word = 2;
CHumyInn : word = 4;
CHumyOut : word = 8;
CWindFlag : word = 16;
CWindCode : word = 32;
CWindSpd : word = 64;
CWindDir : word = 128;
CAirPress : word = 256;
CRain1H : word = 512;
CRainTot : word = 1024;
CDewPoint : word = 2048;
CWSSensExt : word = 4096;
{--------------------------------------------------------------}
{--------------------------------------------------------------}
{ Type Declarations }
type
T4nibble = array[1..4] of byte;
// TReply = array[0..31]of Byte;
TStr10 = String[10];
TWS_Zug = array[1..2] of word;
TWS_REQ = array[1..5] of byte;
tWSRxRec = record
Cmd : byte;
ww : word;
stM : tStr10;
end;
{--------------------------------------------------------------}
{ Const Declarations }
const
// TxFrameSize : byte = sizeOf(TWSTSlaveDS);
// TimeoutLimit :byte = 160; //für Timeoutüberwachung
pot10 : array[1..6]of longword = (1, 10, 100, 1000, 10000, 100000);
UHRZEIT :TWS_Zug = ($200,06);
DATUM :TWS_Zug = ($23B,11);
TEMPERATURE_INN :TWS_Zug = ($346,3);
TEMPERATURE_OUT :TWS_Zug = ($373,3);
DEWPOINT :TWS_Zug = ($3CE,7);
HUMIDITY_INN :TWS_Zug = ($3FB,2);
HUMIDITY_OUT :TWS_Zug = ($419,2);
RAIN_1H :TWS_Zug = ($4B4,6);
// RAIN_24H :TWS_Zug = ($497,6);
RAIN_TOTAL :TWS_Zug = ($4D2,8);
// SENSOREXT : TWS_Zug = ($54D,1);
WIND :TWS_Zug = ($527,6);
REL_DRUCK :TWS_Zug = ($5E2,5);
RainTotClear :TWS_Zug = ($4D1,7);
{--------------------------------------------------------------}
{ Var Declarations }
{$IDATA}
var
NetRxRec[@TWIrxBuff] : tWSRxRec;
NetTxRec[@TWItxBuff] : TWSTSlaveDS;
TxDS :TWSTSlaveDS;
tick_min :boolean;
tick_std :boolean;
ret :boolean;
wsconnect :boolean;
nib :T4nibble;
bcnt :byte;
dd_cnt :byte;
WSReply :TReply;
wsContr :byte;
w :word;
iw :integer;
lw :longint;
c,i,j,h :byte;
RTC_Sync :boolean;
RTC_DCF :boolean; // true nach der ersten Synchronisation
st, mi, se :byte;
zeit1 :array[1..3] of byte;
dd, mm, jj :byte;
date1 :array[1..3] of byte;
WScon_cnt :word;
WScon_err :word;
WSqui_err :word;
WSprs_err :word;
WStio_err :word;
SLcon_cnt :word;
SLcon_err :word;
SLqui_err :word;
SLprs_err :word;
SLtio_err :word;
{--------------------------------------------------------------}
{ functions }
{==============================================================}
procedure RTC_Lesen;
{==============================================================}
begin
disableints;
se := RTCGetSecond;
mi := RTCGetMinute;
st := RTCGetHour;
dd := RTCGetDay;
mm := RTCGetMonth;
jj := RTCGetYear;
enableints;
// den Sendepuffer nur mit gesicherten Daten füllen:
if RTC_DCF then // erste Sync am Tag schon erfolgt?
zeit1[1] := st;
zeit1[2] := mi;
zeit1[3] := se;
date1[1] := dd;
date1[2] := mm;
date1[3] := jj;
else
for i := 1 to 3 do
zeit1[i] := 90;
date1[i] := 90;
endfor;
endif;
end;
{==============================================================}
Process RxMasterFrame(40, 80 : iData);
{==============================================================}
// cmd=1 bedeutet, dass der Slave die Wetterdaten senden soll
begin
WaitSema(TWIrxSEMA);
if NetRxRec.cmd = cmd_01 then
RTC_Lesen; // für Zeitstempel füllt zeit1 und date1
TxDS.Time := zeit1;
TxDS.Date := date1;
TxDS.cmd := cmd_09;
NetTxRec := TxDS; // Daten übergeben
mdelay(100);
TWItxFrame(02, TxFrameSize); // Senden
TXDS.MW_Status := 0; // Vorbereitung der neuen Sendung
endif;
TWIRXCLEAR; //
end;
{--------------------------------------------------------------}
Process RxBroadcastFrame(40, 80 : iData);
{--------------------------------------------------------------}
begin
WaitSema(TWIbroadcastSema);
case TWIbroadcastCMD of
ClearBuffer : TWIrxClear; // remove deadlocks
TWItxClear;
|
endcase;
end;
{==============================================================}
procedure RTCtickSecond; // CallBack from RTCclock
begin
end;
procedure RTCtickMinute; // CallBack from RTCclock
begin
tick_min := true;
end;
procedure RTCtickHour; // CallBack from RTCclock
begin
tick_std := true;
end;
{==============================================================}
procedure RTC_Uhr_Stellen(std_, mi_, se_:byte);
{==============================================================}
begin
disableints;
RTCsetSecond(se_);
RTCsetMinute(mi_);
RTCsetHour(std_);
enableints;
RTC_DCF := true; // wird täglich 1 mal zurückgesetzt
end;
{==============================================================}
procedure RTC_Datum_Stellen(dd_, mm_, jj_:byte);
{==============================================================}
begin
disableints;
RTCsetDay(dd_);
RTCsetMonth(mm_);
RTCsetYear(jj_);
enableints;
end;
{==============================================================}
procedure InitPorts;
{==============================================================}
begin
// DDRB:= %00000010;
end InitPorts;
{--------------------------------------------------------------}
procedure SIOPufferLeeren;
{--------------------------------------------------------------}
begin
while serstat do
mdelay(10);
c := serinp; //Puffer leeren
endwhile;
end;
{--------------------------------------------------------------}
function WS2300SendByte(sbf, ebf:byte; qb:boolean):boolean;
{--------------------------------------------------------------}
var cnt:byte;
// wenn qb=true, dann wird das Quittungsbyte geprüft
begin
ret :=false;
mdelay(13);
serout(sbf);
cnt := 0;
repeat
if cnt > 0 then
mdelay(18);
endif;
inc(cnt);
until (serstat)or(cnt = TimeoutLimit); // max 2sec
if (cnt < TimeoutLimit) then
c := serinp; // lesen der Schnittstelle
if (c = ebf) or (not qb) then // erwartete Quittung
ret :=true;
else
// inc(WSqui_err);
endif;
else
// inc(WStio_err);
endif;
Return(ret);
end;
{--------------------------------------------------------------}
procedure WS2300_Reset;
{--------------------------------------------------------------}
begin
WS2300SendByte($06, $02, false);
WS2300SendByte($06, $02, false); //Reset WS
end;
{--------------------------------------------------------------}
function WS2300Connected:boolean;
{--------------------------------------------------------------}
var i1:byte;
v:boolean;
begin
mdelay(200);
i1 := 0;
// es werden 3 Verbindungsversuche gemacht:
repeat
if i1 > 0 then
mdelay(2500); // warten vor dem nächsten Versuch
// inc(WScon_err);
endif;
SIOPufferLeeren;
inc(i1);
v := WS2300SendByte($06, $02, true);
until v or(i1 = 3{max_v});
if v then
// inc(WScon_cnt);
TxDS.WSS_Slv_Status := TxDS.WSS_Slv_Status or 1;
return(true);
else
WS2300_Reset;
WScon_cnt := 0; // ?
TxDS.WSS_Slv_Status := TxDS.WSS_Slv_Status and %11111110;
return(false);
endif;
end;
{--------------------------------------------------------------}
procedure WordToNibbles(w:word);
{--------------------------------------------------------------}
begin
nib[1] := hi(w) shr 4;
nib[2] := hi(w) and $0F;
nib[3] := lo(w) shr 4;
nib[4] := lo(w) and $0F;
end;
{--------------------------------------------------------------}
function WS2300Lesen(z:TWS_Zug):TReply;
{--------------------------------------------------------------}
var bcnt,cnt1,i1,j1, sb, qb:byte;
adr, sum :word;
// Abbruch der Funktion mit WSReply[0]=0 bedeutet, dass die Daten
// nicht oder nicht ungestört empfangen wurden
begin
adr := z[1];
bcnt:= byte(z[2]);
WSReply[0] := 0; // Anzahl der empfangenen Bytes
// zuerst prüfen, ob WS2300 angeschlossen und bereit:
if not wsconnect then
if (not WS2300Connected) then
wsconnect := false;
return(WSReply);
else
wsconnect := true;
endif;
else
SIOPufferLeeren;
endif;
//
WordToNibbles(adr); //die Adr in Nibbles wandeln
// 4 Adress-Nibble werden gesendet von hi nach lo
for j1 := 1 to 4 do
sb := $82 + (nib[j1] * 4);
qb := ($10 *(j1 -1))+ nib[j1];
if not WS2300SendByte(sb, qb, true) then
wsconnect := false;
return(WSReply); // Abbruch mit WSReply[0]=0
endif;
endfor;
// nun folgt das Lesekommando:
sb := bcnt * 4 + $C2; // Anfordern der gewünschten Zahl Bytes
qb := $30 + bcnt;
if not WS2300SendByte(sb, qb, true) then
wsconnect := false;
return(WSReply); // Abbruch, mit WSReply[0]=0
endif;
//
// nun Datenblock der Länge bcnt und ein Prüfbyte auslesen:
i1 := 0;
j1 := 0;
repeat
inc(i1);
inc(j1);
cnt1 := 0;
repeat
if cnt1 > 0 then
mdelay(8);
endif;
inc(cnt1);
until (serstat)or(cnt1 = TimeOutLimit);
if (cnt1 < TimeOutLimit) then
WSReply[j1] := serinp; // Lesen von WS
inc(j1); // 2.Stelle freilassen für Nibble-Code
else
//Timeout
inc(WStio_err);
wsconnect := false;
return(WSReply); // Abbruch, mit WSReply[0]=0
endif;
until (i1 = bcnt + 1)or(cnt1 > TimeOutLimit);
//
if (cnt1 > TimeOutLimit) then
wsconnect := false;
return(WSReply); //Abbruch, mit WSReply[0]=0
endif;
// das letzte empfangene Byte ist das Summenbyte
//........................
// nun die Prüfsumme kontrollieren:
sum := 0;
j1 := 1;
for i1 := 1 to bcnt do
sum := sum + word(WSReply[j1]);
inc(j1,2);
endfor;
sum := sum and $00FF; //relevant ist nur der lo-Teil
if (sum <> word(WSReply[(2 * bcnt) + 1])) then // Prüfsumme falsch
inc(WSprs_err);
return(WSReply); //Abbruch, mit WSReply[0]=0
else
endif;
// jedes Byte enthält im hi- und lo-Teil eine Dezimalziffer
//
// Daten in Nibbles wandeln:
j := 1;
for i1 := 1 to bcnt do
h := WSReply[j];
WSReply[j] := h and $0F;
WSReply[j+1] := h shr 4;
j := j + 2;
endfor;
WSReply[0] := bcnt; // Anzahl der gelesenen Bytes
return(WSReply);
end;
{--------------------------------------------------------------}
function DCFZeitLesen:boolean;
{--------------------------------------------------------------}
var ret:boolean;
begin
ret := false;
WSReply := WS2300Lesen(Uhrzeit);
// in WSReply steht: SE,SZ,ME,MZ,HE,HZ
if (WSReply[0] > 0) then
se := (WSReply[1] + WSReply[2]*10);
mi := (WSReply[3] + WSReply[4]*10);
st := (WSReply[5] + WSReply[6]*10);
//
WSReply := WS2300Lesen(Datum);
if (WSReply[0] > 0) then
dd := (WSReply[6] + WSReply[7]*10); //dd
mm := (WSReply[8] + WSReply[9]*10); //mm
jj := (WSReply[10] + WSReply[11]*10); //jj
ret := true;
endif;
endif;
if ret then
TxDS.WSS_Slv_Status := TxDS.WSS_Slv_Status or 2;
else
TxDS.WSS_Slv_Status := TxDS.WSS_Slv_Status and %11111101;
endif;
Return(ret);
end;
{--------------------------------------------------------------}
function WertHolen(z:TWS_Zug):boolean;
{--------------------------------------------------------------}
// ...das alles und mehr, weil der 8KB ROM nicht reicht
begin
h := 0;
repeat
mdelay(400);
WSReply := WS2300Lesen(z);
inc(h);
until (WSReply[0] > 0) or (h > 3);
return(WSReply[0] > 0);
end;
{--------------------------------------------------------------}
function TemperaturLesen(z:TWS_Zug):integer;
{--------------------------------------------------------------}
begin
if WertHolen(z) then
// temperatur = ((nib4*10 + nib3), nib2) -30
// der gelesene Wert wird mit 10 multipliziert zurückgegeben
w := word(WSReply[4])* 100 + (word(WSReply[3])* 10) +
word(WSReply[2]);
return(integer(w) - 300); // -30 Grad ist Grenzwert
else
return(-1000);
endif;
end;
{--------------------------------------------------------------}
function BCDWert(WSR:TReply; anz:byte):longint;
{--------------------------------------------------------------}
var lw_:longint;
begin
lw_ := 0;
for i := 1 to anz do
lw_ := lw_ + longint(WSR[i]) * longint(pot10[i]);
endfor;
{lw_ := longint(WSR[6]) * 100000 + longint(WSR[5]) * 10000 +
longint(WSR[4]) * 1000 + longint(WSR[3]) * 100 +
longint(WSR[2]) * 10 + longint(WSR[1]); }
return(lw_);
end;
{--------------------------------------------------------------}
procedure WS2300DatenPuffern(nr:byte);
{--------------------------------------------------------------}
(* 1 TempInnen : Integer;
2 TempAussen : Integer;
3 HumidityInn : Word;
4 HumidityOut : Word;
5 WindFlag : byte;
6 WindCode : Byte;
7 WindSpeed : word;
8 WindDir : array[1..7]of byte;
9 AirPressRel : Word;
10 Rain1H : word;
11 RainTotal : word;
12 DewPoint : Word;
13 Reserve : byte;
14 WSSensorExt : byte; *)
begin
//
//Das Byte MW_Status gibt dem RAM_Slave bekannt, welche Werte neu
//gemessen wurden, damit nicht alte Messwerte wieder in die Mittel-
//wertberechnung übernommen werden.
//Das Byte wird zurückgesetzt unmittelbar nach dem die Werte an den
//Master gesendet wurden.
case nr of
1: // Temperaturwerte sind mit 10 multipliziert
TXDS.TempInnen := TemperaturLesen(TEMPERATURE_INN);
TXDS.MW_Status := CTempInn;
TXDS.TempAussen := TemperaturLesen(TEMPERATURE_OUT);
TXDS.MW_Status := TXDS.MW_Status or CTempOut;
|
2: if WertHolen(HUMIDITY_INN) then
TXDS.HumidityInn := word(BCDWert(WSReply, 2) * 10);
TXDS.MW_Status := TXDS.MW_Status or CHumyInn;
else
TXDS.HumidityInn := 254;
endif;
|
3: if WertHolen(HUMIDITY_OUT) then
TXDS.HumidityOut := word(BCDWert(WSReply, 2) * 10);
TXDS.MW_Status := TXDS.MW_Status or CHumyOut;
else
TXDS.HumidityOut := 254;
endif;
|
4: if WertHolen(REL_DRUCK) then
//WS-Wert ist BCD-codiert:
//Wert ist mit 10 multipliziert hPa
TXDS.AirPressRel := word(BCDWert(WSReply, 5));
TXDS.MW_Status := TXDS.MW_Status or CAirPress;
else
TXDS.AirPressRel := 5;
endif;
|
5: if WertHolen(Wind) then
TXDS.WindFlag := WSReply[1];
TXDS.WindCode := WSReply[2];
//------Windgeschwindigkeit----------
// WS_Wert ist binär-codiert: !!! (nicht BCD)
//Wert ist mit 10 multipliziert m/sec
w := word(WSReply[5])* 256 + word(WSReply[4])* 16 + word(WSReply[3]);
if w <> 510 then //Fehler der WS2300
TXDS.WindSpeed := w;
TXDS.MW_Status := TXDS.MW_Status or CWindSpd;
endif;
//-------Windrichtungen: 1-6---------
for i := 6 to 11 do
TXDS.WindDir[i-5] := WSReply[i]; // aktuelle Richtungen
endfor;
TXDS.MW_Status := TXDS.MW_Status or CWindDir;
else
TXDS.WindFlag := 7; //Störung
TXDS.WindCode := 7;
TXDS.WindSpeed := 9999;
TXDS.WindDir[1] := 254;
endif;
|
6: if WertHolen(DEWPOINT) then
//WS_Wert ist BCD-codiert:
TXDS.DewPoint := word(BCDWert(WSReply, 6)); // ??????
TXDS.MW_Status := TXDS.MW_Status or CDewPoint; //12
else
TXDS.DewPoint := $E1F1;
endif;
|
7: if WertHolen(RAIN_1H) then
//WS_Wert ist BCD-codiert:
//Wert ist ist 100 multipliziert
TXDS.Rain1H := word(BCDWert(WSReply, 6));
TXDS.MW_Status := TXDS.MW_Status or CRain1H; // 10
else
TXDS.Rain1H := $9FF0;
endif;
|
//
8: if WertHolen(RAIN_Total) then
//WS_Wert ist BCD-codiert:
//Wert ist ist 100 multipliziert
lw := (BCDWert(WSReply, 6)); // lw falls irgendwann Rain > word-bereich
TXDS.RainTotal := word(lw);
TXDS.MW_Status := TXDS.MW_Status or CRainTot; //11
//
if lw >= 50000 then //nie mehr als 500mm Regen messen, sonst reset
WSReply := WS2300Lesen(RainTotClear); //Reset-Commando
//es muss auf 4D8 bis 4E1 der Zeit-Datensatz geschrieben werden !!! fehlt
noch
endif;
else
TXDS.RainTotal := $FFF0; //65520
endif;
|
(* // ROM reichte nicht
9: if WertHolen(SENSOREXT) then
TXDS.WSSensorExt := WSReply[1];
TXDS.MW_Status := TXDS.MW_Status or CWSSensExt;
else
TXDS.WSSensorExt := 254;
endif;
| *)
endcase;
TxDS.WSconnerr := WScon_err;
//TxDS.WSQuitErr := WSqui_err;
end;
{--------------------------------------------------------------}
procedure InitVar;
{--------------------------------------------------------------}
begin
tick_std := true;
tick_min := true;
WScon_cnt := 10;
WSqui_err := 0;
WSprs_err := 0;
RTC_Sync := false;
dd_cnt := 60; // stehen lassen
TXDS.MW_Status := 0;
end;
{--------------------------------------------------------------}
{ Main Program }
{$IDATA}
begin
InitPorts;
InitVar;
EnableInts;
//.......................
TWIadrMask:= $FF;
Priority(main_proc, 2);
Start_Processes;
TWIrxClear; // erst nach Start_Processes !
TWItxClear;
//
WS2300_Reset;
RTC_Sync := false;
RTC_DCF := false;
repeat
if DCFZeitLesen then // Uhrzeit und Datum aus WS2300
RTC_DCF := true;
else
mdelay(1000);
endif;
until RTC_DCF; // wenn DCF-Zeit gelesen, dann RTC_Sync = true
//================Hauptschleife=================
loop
inc(wsContr);
if wsContr > 9 then //max-case
wsContr := 0;
endif;
WS2300DatenPuffern(wsContr);
if tick_min then
tick_min := false;
if tick_std then
tick_std := false;
if (dd <> dd_cnt) and (RTC_sync) then
dd_cnt := dd;
RTC_DCF := false; // wird in RTC_Uhr_Stellen true
endif;
if DCFZeitLesen then
RTC_Sync := true;
RTC_Uhr_Stellen(st, mi, se);
RTC_Datum_Stellen(dd, mm, jj);
else
RTC_Sync := false;
tick_std := true;
endif;
endif;
endif;
mdelay(2005);
endloop;
end WS2300_Slave.