Hallo,
bei dem neuen Update bekomme ich einen Fehler beim Mega32 nicht aber beim Mega2651.
gruß
wom
program UST4_485a;
{$NOSHADOW}
{ $WG} {global Warnings off}
Device = mega32, VCC=5;
Define_Fuses
Override_Fuses;
COMport = USB2;
LockBits0 = [];
FuseBits0 = [BODEN, BODLEVEL];
FuseBits1 = [CKOPT];
FuseBits2 = [];
ProgMode = SPI;
Import SysTick,WatchDog,SysLEDblink,ADCPort,SerPort1,TickTimer;
From SysLEDblink Import LEDmessage, FlashOnce, FastBlink; // these are options
From System Import LongWord;
Define
ProcClock = 8000000; {Hertz}
SysTick = 10; {msec}
WatchDog = msec2000; {presc = 7}
StackSize = $0064, iData;
FrameSize = $0064, iData;
TickTimer = Timer1;
ADCchans = 4, iData;
ADCpresc = 128;
SysLEDblink = 3; {30*SysTick = 300msec}
SysLEDBlink0 = PortD, 7, low; {LEDon = high level}
SysLEDBlink1 = PortC, 3, low; {LEDon = high level}
SerPort1 = 38400, Stop1, timeout; {Baud, StopBits|Parity}
SerCtrl1 = PortD, 2, positive; {control line for RS485 driver}
RxBuffer1 = 32, iData;
TxBuffer1 = 32, iData;
Implementation
{$IDATA}
{ Type Declarations }
Type
tRTC = Record
Second : Byte;
Minute : Byte;
Hour : Byte;
Weekday : Byte;
Date : Byte;
Month : Byte;
Year : Byte;
End;
tEcoMod = Record
Err : Boolean;
Adr : Byte;
Comand : Byte;
RxData : String[32];
TxData : String[32];
End;
tVB = Record
Info : Byte;
Timer : Byte;
VS : Boolean;
VT : Boolean;
SKOff : Boolean;
RKAkt : Word;
RKSW : Word;
End;
{--------------------------------------------------------------}
{ Const Declarations }
Const
cErrTime[$7FFD] : Byte = 240; // Zeit in Sec. ab wann ein Telegramm Error ausgelößt wird
cADAkt [$7FFC] : Byte = 4;
cResTime[$7FFB] : Byte = 10; // Zeit in Sec. ab der ein Neustart durchgeführt wird
cRolTime[$7FFA] : Byte = 10; // Zeit in Sec.
RelOn : Boolean = True;
RelOff : Boolean = False;
LEDOff : Boolean = True;
LEDOn : Boolean = False;
Tx : Boolean = True;
Rx : Boolean = False;
{--------------------------------------------------------------}
{ Var Declarations }
{$IDATA}
var
ADAkt : Boolean;
Rel1[@PortC,7] : Bit;
Rel2[@PortC,6] : Bit;
Rel3[@PortC,5] : Bit;
Rel4[@PortC,4] : Bit;
VT1_LED [@PortB,0] :Bit;
VT2_LED [@PortB,2] :Bit;
VT3_LED [@PortB,3] :Bit;
VT4_LED [@PortB,4] :Bit;
VT1 [@PinD,3] :Bit;
VT2 [@PinD,4] :Bit;
VT3 [@PinD,5] :Bit;
VT4 [@PinD,6] :Bit;
NR0 [@PinD,4] :Bit;
NR1 [@PinD,5] :Bit;
NR2 [@PinD,6] :Bit;
NR3 [@PinD,7] :Bit;
EcoMod : tEcoMod;
RTC : tRTC;
ErrTime : Byte;
AdrSW[@PinA] : Byte;
USTAdr : Byte;
ResetTime : Byte;
RelRoll : Byte;
ADTimer : Byte;
PollStop : Boolean;
VB : Array [0..3] OF tVB;
// ADMin : Array [0..3] Of Word;
VTStatus : Byte;
Err,x,CH : Byte;
ModADR : String[2];
Timer1 : SysTimer;
WW : Array [0..1] Of Word;
{$EEPROM}
Var
eVB : Array [0..1] OF tVB;
{$IDATA}
{--------------------------------------------------------------}
{--------------------------------------------------------------}
Procedure TestModul;
Begin
Rel1:=RelOn;
VT1_LED:=LEDOn;
mDelay(300);
Rel1:=RelOff;
VT1_LED:=LEDOff;
Rel2:=RelOn;
VT2_LED:=LEDOn;
mDelay(300);
Rel2:=RelOff;
VT2_LED:=LEDOff;
Rel3:=RelOn;
VT3_LED:=LEDOn;
mDelay(300);
Rel3:=RelOff;
VT3_LED:=LEDOff;
Rel4:=RelOn;
VT4_LED:=LEDOn;
mDelay(300);
Rel4:=RelOff;
VT4_LED:=LEDOff;
Rel1:=RelOn;
Rel2:=RelOn;
Rel3:=RelOn;
Rel4:=RelOn;
End;
{--------------------------------------------------------------}
{ SW1 = 1 ON = 0 Off = 1 +-+-+-+-+ }
{ SW2 = 2 ON = 0 Off = 1 |_|_|_|_| }
{ SW3 = 4 ON = 0 Off = 1 |X|X|X|X| = $00 }
{ SW4 = 8 ON = 0 Off = 1 +-+-+-+-+ }
{--------------------------------------------------------------}
Procedure LeseModADR;
Begin
USTAdr:=ADRSW And $F0;
USTAdr:=USTAdr SHR 4;
USTAdr:=USTAdr xor $0F;
Inc(USTAdr);
End;
{--------------------------------------------------------------}
{ Modul initialisieren }
{--------------------------------------------------------------}
procedure InitPorts;
Var
x : Byte;
begin
PollStop:=True;
DDRA := DDRA And %11110000; // Output=1 Input=0
PortA := %11110000;
DDRB := DDRB Or %00011101; // Output=1 Input=0
DDRC := %11111111; // Output=1 Input=0
PortC := %11111111; // Output=1 Input=0
DDRD := %10000100; // Output=1 Input=0
VT1_LED :=LEDOff;
VT2_LED :=LEDOff;
VT3_LED :=LEDOff;
VT4_LED :=LEDOff;
If cADAkt=0 Then ADAkt:=False; Else ADAkt:=True; EndIf;
ADTimer:=0;
VB[0].VT:=False;
VB[1].VT:=False;
VB[0].VS:=True;
VB[1].VS:=True;
VT1_LED :=LEDOff;
VT2_LED :=LEDOff;
VT3_LED :=LEDOff;
VT4_LED :=LEDOff;
ErrTime:=0;
SetSysTimer(Timer1,100);
PollStop:=False;
RelRoll:=cRolTime;
LeseModADR;
TestModul;
end InitPorts;
{--------------------------------------------------------------}
{ Senden der Daten mit länge (DLen) über RS485 mit Zeit }
{--------------------------------------------------------------}
Procedure Send485;
Var
ASCII : String[32];
Begin
Ser_Enable1 (true); // Baustein auf Ausgabe setzen
FlushBuffer (TxBuffer); // Transmittspeicher löschen
uDelay(20); // auf Treiber warten zur Sicherhit
ASCII:=':'+EcoMod.TxData+#13+#10; // Datentelegramm bilden
For CH:=1 To Length(ASCII) Do // Telegramm als Einzelzeichen ausgeben
SerOut1(Ord(ASCII[CH])); // ein Zeichen ausgeben
EndFor;
uDelay(10); // Sicherheitshalber warten bis alles übertragen ist
Ser_Enable1 (False); // Baustein auf Input setzen
End;
{------------------------------------------------------------------}
{ messen der RK Eingänge 1/2 und ablegen in Speicher und Telegramm }
{------------------------------------------------------------------}
Procedure PollRK;
Var
VT,xTime,ADx: Byte;
Begin
EnableInts;
VTStatus:=$00;
If (VT1=False) Then
SetBit(VTStatus,0,True);
Else
SetBit(VTStatus,0,False);
EndIf;
If (VT2=False) Then
SetBit(VTStatus,1,True);
Else
SetBit(VTStatus,1,False);
EndIf;
If (VT3=False) Then
SetBit(VTStatus,2,True);
Else
SetBit(VTStatus,2,False);
EndIf;
If (VT4=False) Then
SetBit(VTStatus,3,True);
Else
SetBit(VTStatus,3,False);
EndIf;
{ messen der RK Eingänge 1..4 und ablegen in Speicher }
ADx:=1;
Repeat
// 50A => 2,5V
VB[ADx-1].RKAkt:=GetADC(ADx);
uDelay(5);
If VB[ADx-1].RKAkt=GetADC(ADx) Then
If VB[ADx-1].RKAkt>10 Then
SetBit(VTStatus,ADx-1,True);
EndIf;
EndIf;
Inc(ADx);
Until ADx>4;
VT1_LED:=Bit(VTStatus,0) XOR $FF;
VT2_LED:=Bit(VTStatus,1) XOR $FF;
VT3_LED:=Bit(VTStatus,2) XOR $FF;
VT4_LED:=Bit(VTStatus,3) XOR $FF;
End;
{--------------------------------------------------------------}
{ Setzen der RK Konfiguration pro Kanal über Telegramm }
{--------------------------------------------------------------}
Procedure SetModRKConf;
Var
xASCII : String[3];
ModKanal : Byte;
Begin
ModKanal:=Ord(EcoMod.RxData[6])-48;
If ModKanal in [0..1] then
xASCII:=EcoMod.RxData[7]+EcoMod.RxData[8]+EcoMod.RxData[9];
VB[ModKanal].RKSW:=HexToInt(xASCII);
EcoMod.TxData:='99';
Else
EcoMod.TxData:='90';
EndIf;
End;
{--------------------------------------------------------------}
{--------------------------------------------------------------}
Procedure SendModRKConf;
Var
xASCII : String[10];
Flag,ModKanal : Byte;
Begin
EcoMod.TxData:='FFFFFFFFFF';
ModKanal:=Ord(EcoMod.RxData[6])-48;
If ModKanal in [0..1] then
xASCII:=IntToHex(VB[ModKanal].RKSW);
xASCII:=xASCII+IntToHex(VB[ModKanal].RKAkt);
Flag:=0;
If VB[ModKanal].VT Then Flag:=Flag + $02; EndIf;
If VB[ModKanal].VS Then Flag:=Flag + $01; EndIf;
xASCII:=xASCII+ByteToHex(Flag);
EcoMod.TxData:=xASCII;
EndIf;
End;
{--------------------------------------------------------------}
{ Setzen der Ausgänge Rel1/2 über Telegramm }
{--------------------------------------------------------------}
Procedure LoadSetVS;
Var
xASCII : String[1];
xVB : Byte;
TelByte : String[2];
TelWord : String[4];
Begin
EnableInts; // interrupts freigeben
xASCII:=EcoMod.RxData[6];
VB[0].Info:=HexToInt(xASCII);
xASCII:=EcoMod.RxData[7];
VB[1].Info:=HexToInt(xASCII);
xASCII:=EcoMod.RxData[8];
VB[2].Info:=HexToInt(xASCII);
xASCII:=EcoMod.RxData[9];
VB[3].Info:=HexToInt(xASCII);
If (VB[0].Info>=8) Or (VB[0].Info=0) Or (VB[0].Info=1) Then
Rel1:=RelOn;
VB[0].VS:=True;
SetBit(VTStatus,4,True);
Else
Rel1:=RelOff;
VB[0].VS:=False;
SetBit(VTStatus,4,False);
EndIF;
If (VB[1].Info>=8) Or (VB[1].Info=0) Or (VB[1].Info=1) Then
Rel2:=RelOn;
VB[1].VS:=True;
SetBit(VTStatus,5,True);
Else
Rel2:=RelOff;
VB[1].VS:=False;
SetBit(VTStatus,5,False);
EndIF;
If (VB[2].Info>=8) Or (VB[2].Info=0) Or (VB[2].Info=1) Then
Rel3:=RelOn;
VB[2].VS:=True;
SetBit(VTStatus,6,True);
Else
Rel3:=RelOff;
VB[2].VS:=False;
SetBit(VTStatus,6,False);
EndIF;
If (VB[3].Info>=8) Or (VB[3].Info=0) Or (VB[3].Info=1) Then
Rel4:=RelOn;
VB[3].VS:=True;
SetBit(VTStatus,7,True);
Else
Rel4:=RelOff;
VB[3].VS:=False;
SetBit(VTStatus,7,False);
EndIF;
{ Telegramminhalt }
{ |1|23| |4 |567 |8 |9AB |C |D | }
{ |:|MODNr||VBStatusH[1]|RK1H[234]|VBStatusL[1]|RK2H[234]|CR|LF| }
{ StatusH = Bit 3..0 Zustand VS }
{ RKAkr1 = Bit 12..0 Wert der AD1-RK Messung }
{ StatusL = Bit 7..4 Zustand VT }
{ RKAkr2 = Bit 12..0 Wert der AD2-RK Messung }
TelWord:=IntToHex(VB[0].RKAkt);
TelByte:=ByteToHex(VTStatus);
TelWord[1]:=TelByte[2];
EcoMod.TxData:=ByteToHex(USTAdr)+TelWord;
TelWord:=IntToHex(VB[1].RKAkt);
TelWord[1]:=TelByte[1];
EcoMod.TxData:=EcoMod.TxData+TelWord+IntToHex(VB[2].RKAkt)+IntToHex(VB[3].RKAkt);
End;
{--------------------------------------------------------------}
{ Lessen der COM-Schnittstelle und Telegramm erkennen }
{--------------------------------------------------------------}
Function ReadEcoModTel:Boolean;
Var
Daten : Boolean;
Begin
If SerInp_TO1 (CH,1) Then
If CH<>$3A Then Return(False); EndIf;
EndIf;
EcoMod.RxData:=Char(CH);
Repeat
If SerInp_TO1 (CH,2) Then
If CH in [$30..$46] Then
EcoMod.RxData:=EcoMod.RxData+Char(CH);
EcoMod.Err:=False;
EndIf;
Else
EcoMod.Err:=True;
EndIf;
Until (CH=10) Or (EcoMod.Err);
SysLEDflashOnce (1); // b= 0..7 LED number
ModADR:=Char(EcoMod.RxData[2])+Char(EcoMod.RxData[3]);
EcoMod.Adr:=HexToInt(ModADR);
If EcoMod.Adr=USTAdr Then
ModADR:=Char(EcoMod.RxData[4])+Char(EcoMod.RxData[5]);
EcoMod.Comand:=HexToInt(ModADR);
Return(True);
Else
Return(False);
EndIf;
Return(False);
End;
{--------------------------------------------------------------}
{--------------------------------------------------------------}
Procedure NotProgramm;
Begin
Dec(RelRoll);
If RelRoll=0 Then
If ResetTime=0 Then
System_Reset;
Else
Dec(ResetTime);
EndIf;
RelRoll:=cRolTime;
If RelRoll>4 Then RelRoll:=1; EndIf;
Case RelRoll Of
1 : Rel1:=RelOn;Rel2:=RelOff;Rel3:=RelOff;Rel4:=RelOff;|
2 : Rel1:=RelOff;Rel2:=RelOn;Rel3:=RelOff;Rel4:=RelOff;|
3 : Rel1:=RelOff;Rel2:=RelOff;Rel3:=RelOn;Rel4:=RelOff;|
4 : Rel1:=RelOff;Rel2:=RelOff;Rel3:=RelOff;Rel4:=RelOn;|
EndCase;
Inc(RelRoll);
EndIf;
End;
{--------------------------------------------------------------}
{ Haptprogramm }
{--------------------------------------------------------------}
{ Main Program }
{$IDATA}
begin
InitPorts;
WatchDogStart;
EnableInts;
SetSysTimer(Timer1,100);
FlushBuffer (TxBuffer);
FlushBuffer (RxBuffer);
RTC.Second:=0;
VTStatus:=0;
ErrTime:=cErrTime;
LeseModADR;
loop
PollStop:=False;
WatchDogTrig;
EnableInts;
If IsSysTimerZero(Timer1) Then
SetSysTimer(Timer1,50);
SysLEDflashOnce (1);
LeseModADR;
WatchDogTrig;
Inc(ADTimer);
If ADTimer>59 Then ADTimer:=0; EndIf;
If ErrTime=0 Then
NotProgramm;
ErrTime:=0;
Else
Dec(ErrTime);
EndIf;
PollRK;
EndIf;
Ser_Enable (False);
If SerStat Then
ErrTime:=cErrTime;
If ReadEcoModTel Then
SysLEDflashOnce (0);
EcoMod.TxData:='';
ErrTime:=cErrTime;
ResetTime:=cResTime;
Case EcoMod.Comand Of
$02 : EcoMod.TxData:=ByteToHex(USTAdr)+'99';|
$03 : EcoMod.TxData:=ByteToHex(VTStatus);|
$04 : LoadSetVS;|
$06 : SetModRKConf;|
$07 : SendModRKConf;|
$09 : System_Reset;|
EndCase;
If EcoMod.TxData<>'' Then
Send485;
mDelay(6);
EndIf;
EndIf;
EndIf;
endloop;
end UST4_485a.
bei dem neuen Update bekomme ich einen Fehler beim Mega32 nicht aber beim Mega2651.
gruß
wom
Code
program UST4_485a;
{$NOSHADOW}
{ $WG} {global Warnings off}
Device = mega32, VCC=5;
Define_Fuses
Override_Fuses;
COMport = USB2;
LockBits0 = [];
FuseBits0 = [BODEN, BODLEVEL];
FuseBits1 = [CKOPT];
FuseBits2 = [];
ProgMode = SPI;
Import SysTick,WatchDog,SysLEDblink,ADCPort,SerPort1,TickTimer;
From SysLEDblink Import LEDmessage, FlashOnce, FastBlink; // these are options
From System Import LongWord;
Define
ProcClock = 8000000; {Hertz}
SysTick = 10; {msec}
WatchDog = msec2000; {presc = 7}
StackSize = $0064, iData;
FrameSize = $0064, iData;
TickTimer = Timer1;
ADCchans = 4, iData;
ADCpresc = 128;
SysLEDblink = 3; {30*SysTick = 300msec}
SysLEDBlink0 = PortD, 7, low; {LEDon = high level}
SysLEDBlink1 = PortC, 3, low; {LEDon = high level}
SerPort1 = 38400, Stop1, timeout; {Baud, StopBits|Parity}
SerCtrl1 = PortD, 2, positive; {control line for RS485 driver}
RxBuffer1 = 32, iData;
TxBuffer1 = 32, iData;
Implementation
{$IDATA}
{ Type Declarations }
Type
tRTC = Record
Second : Byte;
Minute : Byte;
Hour : Byte;
Weekday : Byte;
Date : Byte;
Month : Byte;
Year : Byte;
End;
tEcoMod = Record
Err : Boolean;
Adr : Byte;
Comand : Byte;
RxData : String[32];
TxData : String[32];
End;
tVB = Record
Info : Byte;
Timer : Byte;
VS : Boolean;
VT : Boolean;
SKOff : Boolean;
RKAkt : Word;
RKSW : Word;
End;
{--------------------------------------------------------------}
{ Const Declarations }
Const
cErrTime[$7FFD] : Byte = 240; // Zeit in Sec. ab wann ein Telegramm Error ausgelößt wird
cADAkt [$7FFC] : Byte = 4;
cResTime[$7FFB] : Byte = 10; // Zeit in Sec. ab der ein Neustart durchgeführt wird
cRolTime[$7FFA] : Byte = 10; // Zeit in Sec.
RelOn : Boolean = True;
RelOff : Boolean = False;
LEDOff : Boolean = True;
LEDOn : Boolean = False;
Tx : Boolean = True;
Rx : Boolean = False;
{--------------------------------------------------------------}
{ Var Declarations }
{$IDATA}
var
ADAkt : Boolean;
Rel1[@PortC,7] : Bit;
Rel2[@PortC,6] : Bit;
Rel3[@PortC,5] : Bit;
Rel4[@PortC,4] : Bit;
VT1_LED [@PortB,0] :Bit;
VT2_LED [@PortB,2] :Bit;
VT3_LED [@PortB,3] :Bit;
VT4_LED [@PortB,4] :Bit;
VT1 [@PinD,3] :Bit;
VT2 [@PinD,4] :Bit;
VT3 [@PinD,5] :Bit;
VT4 [@PinD,6] :Bit;
NR0 [@PinD,4] :Bit;
NR1 [@PinD,5] :Bit;
NR2 [@PinD,6] :Bit;
NR3 [@PinD,7] :Bit;
EcoMod : tEcoMod;
RTC : tRTC;
ErrTime : Byte;
AdrSW[@PinA] : Byte;
USTAdr : Byte;
ResetTime : Byte;
RelRoll : Byte;
ADTimer : Byte;
PollStop : Boolean;
VB : Array [0..3] OF tVB;
// ADMin : Array [0..3] Of Word;
VTStatus : Byte;
Err,x,CH : Byte;
ModADR : String[2];
Timer1 : SysTimer;
WW : Array [0..1] Of Word;
{$EEPROM}
Var
eVB : Array [0..1] OF tVB;
{$IDATA}
{--------------------------------------------------------------}
{--------------------------------------------------------------}
Procedure TestModul;
Begin
Rel1:=RelOn;
VT1_LED:=LEDOn;
mDelay(300);
Rel1:=RelOff;
VT1_LED:=LEDOff;
Rel2:=RelOn;
VT2_LED:=LEDOn;
mDelay(300);
Rel2:=RelOff;
VT2_LED:=LEDOff;
Rel3:=RelOn;
VT3_LED:=LEDOn;
mDelay(300);
Rel3:=RelOff;
VT3_LED:=LEDOff;
Rel4:=RelOn;
VT4_LED:=LEDOn;
mDelay(300);
Rel4:=RelOff;
VT4_LED:=LEDOff;
Rel1:=RelOn;
Rel2:=RelOn;
Rel3:=RelOn;
Rel4:=RelOn;
End;
{--------------------------------------------------------------}
{ SW1 = 1 ON = 0 Off = 1 +-+-+-+-+ }
{ SW2 = 2 ON = 0 Off = 1 |_|_|_|_| }
{ SW3 = 4 ON = 0 Off = 1 |X|X|X|X| = $00 }
{ SW4 = 8 ON = 0 Off = 1 +-+-+-+-+ }
{--------------------------------------------------------------}
Procedure LeseModADR;
Begin
USTAdr:=ADRSW And $F0;
USTAdr:=USTAdr SHR 4;
USTAdr:=USTAdr xor $0F;
Inc(USTAdr);
End;
{--------------------------------------------------------------}
{ Modul initialisieren }
{--------------------------------------------------------------}
procedure InitPorts;
Var
x : Byte;
begin
PollStop:=True;
DDRA := DDRA And %11110000; // Output=1 Input=0
PortA := %11110000;
DDRB := DDRB Or %00011101; // Output=1 Input=0
DDRC := %11111111; // Output=1 Input=0
PortC := %11111111; // Output=1 Input=0
DDRD := %10000100; // Output=1 Input=0
VT1_LED :=LEDOff;
VT2_LED :=LEDOff;
VT3_LED :=LEDOff;
VT4_LED :=LEDOff;
If cADAkt=0 Then ADAkt:=False; Else ADAkt:=True; EndIf;
ADTimer:=0;
VB[0].VT:=False;
VB[1].VT:=False;
VB[0].VS:=True;
VB[1].VS:=True;
VT1_LED :=LEDOff;
VT2_LED :=LEDOff;
VT3_LED :=LEDOff;
VT4_LED :=LEDOff;
ErrTime:=0;
SetSysTimer(Timer1,100);
PollStop:=False;
RelRoll:=cRolTime;
LeseModADR;
TestModul;
end InitPorts;
{--------------------------------------------------------------}
{ Senden der Daten mit länge (DLen) über RS485 mit Zeit }
{--------------------------------------------------------------}
Procedure Send485;
Var
ASCII : String[32];
Begin
Ser_Enable1 (true); // Baustein auf Ausgabe setzen
FlushBuffer (TxBuffer); // Transmittspeicher löschen
uDelay(20); // auf Treiber warten zur Sicherhit
ASCII:=':'+EcoMod.TxData+#13+#10; // Datentelegramm bilden
For CH:=1 To Length(ASCII) Do // Telegramm als Einzelzeichen ausgeben
SerOut1(Ord(ASCII[CH])); // ein Zeichen ausgeben
EndFor;
uDelay(10); // Sicherheitshalber warten bis alles übertragen ist
Ser_Enable1 (False); // Baustein auf Input setzen
End;
{------------------------------------------------------------------}
{ messen der RK Eingänge 1/2 und ablegen in Speicher und Telegramm }
{------------------------------------------------------------------}
Procedure PollRK;
Var
VT,xTime,ADx: Byte;
Begin
EnableInts;
VTStatus:=$00;
If (VT1=False) Then
SetBit(VTStatus,0,True);
Else
SetBit(VTStatus,0,False);
EndIf;
If (VT2=False) Then
SetBit(VTStatus,1,True);
Else
SetBit(VTStatus,1,False);
EndIf;
If (VT3=False) Then
SetBit(VTStatus,2,True);
Else
SetBit(VTStatus,2,False);
EndIf;
If (VT4=False) Then
SetBit(VTStatus,3,True);
Else
SetBit(VTStatus,3,False);
EndIf;
{ messen der RK Eingänge 1..4 und ablegen in Speicher }
ADx:=1;
Repeat
// 50A => 2,5V
VB[ADx-1].RKAkt:=GetADC(ADx);
uDelay(5);
If VB[ADx-1].RKAkt=GetADC(ADx) Then
If VB[ADx-1].RKAkt>10 Then
SetBit(VTStatus,ADx-1,True);
EndIf;
EndIf;
Inc(ADx);
Until ADx>4;
VT1_LED:=Bit(VTStatus,0) XOR $FF;
VT2_LED:=Bit(VTStatus,1) XOR $FF;
VT3_LED:=Bit(VTStatus,2) XOR $FF;
VT4_LED:=Bit(VTStatus,3) XOR $FF;
End;
{--------------------------------------------------------------}
{ Setzen der RK Konfiguration pro Kanal über Telegramm }
{--------------------------------------------------------------}
Procedure SetModRKConf;
Var
xASCII : String[3];
ModKanal : Byte;
Begin
ModKanal:=Ord(EcoMod.RxData[6])-48;
If ModKanal in [0..1] then
xASCII:=EcoMod.RxData[7]+EcoMod.RxData[8]+EcoMod.RxData[9];
VB[ModKanal].RKSW:=HexToInt(xASCII);
EcoMod.TxData:='99';
Else
EcoMod.TxData:='90';
EndIf;
End;
{--------------------------------------------------------------}
{--------------------------------------------------------------}
Procedure SendModRKConf;
Var
xASCII : String[10];
Flag,ModKanal : Byte;
Begin
EcoMod.TxData:='FFFFFFFFFF';
ModKanal:=Ord(EcoMod.RxData[6])-48;
If ModKanal in [0..1] then
xASCII:=IntToHex(VB[ModKanal].RKSW);
xASCII:=xASCII+IntToHex(VB[ModKanal].RKAkt);
Flag:=0;
If VB[ModKanal].VT Then Flag:=Flag + $02; EndIf;
If VB[ModKanal].VS Then Flag:=Flag + $01; EndIf;
xASCII:=xASCII+ByteToHex(Flag);
EcoMod.TxData:=xASCII;
EndIf;
End;
{--------------------------------------------------------------}
{ Setzen der Ausgänge Rel1/2 über Telegramm }
{--------------------------------------------------------------}
Procedure LoadSetVS;
Var
xASCII : String[1];
xVB : Byte;
TelByte : String[2];
TelWord : String[4];
Begin
EnableInts; // interrupts freigeben
xASCII:=EcoMod.RxData[6];
VB[0].Info:=HexToInt(xASCII);
xASCII:=EcoMod.RxData[7];
VB[1].Info:=HexToInt(xASCII);
xASCII:=EcoMod.RxData[8];
VB[2].Info:=HexToInt(xASCII);
xASCII:=EcoMod.RxData[9];
VB[3].Info:=HexToInt(xASCII);
If (VB[0].Info>=8) Or (VB[0].Info=0) Or (VB[0].Info=1) Then
Rel1:=RelOn;
VB[0].VS:=True;
SetBit(VTStatus,4,True);
Else
Rel1:=RelOff;
VB[0].VS:=False;
SetBit(VTStatus,4,False);
EndIF;
If (VB[1].Info>=8) Or (VB[1].Info=0) Or (VB[1].Info=1) Then
Rel2:=RelOn;
VB[1].VS:=True;
SetBit(VTStatus,5,True);
Else
Rel2:=RelOff;
VB[1].VS:=False;
SetBit(VTStatus,5,False);
EndIF;
If (VB[2].Info>=8) Or (VB[2].Info=0) Or (VB[2].Info=1) Then
Rel3:=RelOn;
VB[2].VS:=True;
SetBit(VTStatus,6,True);
Else
Rel3:=RelOff;
VB[2].VS:=False;
SetBit(VTStatus,6,False);
EndIF;
If (VB[3].Info>=8) Or (VB[3].Info=0) Or (VB[3].Info=1) Then
Rel4:=RelOn;
VB[3].VS:=True;
SetBit(VTStatus,7,True);
Else
Rel4:=RelOff;
VB[3].VS:=False;
SetBit(VTStatus,7,False);
EndIF;
{ Telegramminhalt }
{ |1|23| |4 |567 |8 |9AB |C |D | }
{ |:|MODNr||VBStatusH[1]|RK1H[234]|VBStatusL[1]|RK2H[234]|CR|LF| }
{ StatusH = Bit 3..0 Zustand VS }
{ RKAkr1 = Bit 12..0 Wert der AD1-RK Messung }
{ StatusL = Bit 7..4 Zustand VT }
{ RKAkr2 = Bit 12..0 Wert der AD2-RK Messung }
TelWord:=IntToHex(VB[0].RKAkt);
TelByte:=ByteToHex(VTStatus);
TelWord[1]:=TelByte[2];
EcoMod.TxData:=ByteToHex(USTAdr)+TelWord;
TelWord:=IntToHex(VB[1].RKAkt);
TelWord[1]:=TelByte[1];
EcoMod.TxData:=EcoMod.TxData+TelWord+IntToHex(VB[2].RKAkt)+IntToHex(VB[3].RKAkt);
End;
{--------------------------------------------------------------}
{ Lessen der COM-Schnittstelle und Telegramm erkennen }
{--------------------------------------------------------------}
Function ReadEcoModTel:Boolean;
Var
Daten : Boolean;
Begin
If SerInp_TO1 (CH,1) Then
If CH<>$3A Then Return(False); EndIf;
EndIf;
EcoMod.RxData:=Char(CH);
Repeat
If SerInp_TO1 (CH,2) Then
If CH in [$30..$46] Then
EcoMod.RxData:=EcoMod.RxData+Char(CH);
EcoMod.Err:=False;
EndIf;
Else
EcoMod.Err:=True;
EndIf;
Until (CH=10) Or (EcoMod.Err);
SysLEDflashOnce (1); // b= 0..7 LED number
ModADR:=Char(EcoMod.RxData[2])+Char(EcoMod.RxData[3]);
EcoMod.Adr:=HexToInt(ModADR);
If EcoMod.Adr=USTAdr Then
ModADR:=Char(EcoMod.RxData[4])+Char(EcoMod.RxData[5]);
EcoMod.Comand:=HexToInt(ModADR);
Return(True);
Else
Return(False);
EndIf;
Return(False);
End;
{--------------------------------------------------------------}
{--------------------------------------------------------------}
Procedure NotProgramm;
Begin
Dec(RelRoll);
If RelRoll=0 Then
If ResetTime=0 Then
System_Reset;
Else
Dec(ResetTime);
EndIf;
RelRoll:=cRolTime;
If RelRoll>4 Then RelRoll:=1; EndIf;
Case RelRoll Of
1 : Rel1:=RelOn;Rel2:=RelOff;Rel3:=RelOff;Rel4:=RelOff;|
2 : Rel1:=RelOff;Rel2:=RelOn;Rel3:=RelOff;Rel4:=RelOff;|
3 : Rel1:=RelOff;Rel2:=RelOff;Rel3:=RelOn;Rel4:=RelOff;|
4 : Rel1:=RelOff;Rel2:=RelOff;Rel3:=RelOff;Rel4:=RelOn;|
EndCase;
Inc(RelRoll);
EndIf;
End;
{--------------------------------------------------------------}
{ Haptprogramm }
{--------------------------------------------------------------}
{ Main Program }
{$IDATA}
begin
InitPorts;
WatchDogStart;
EnableInts;
SetSysTimer(Timer1,100);
FlushBuffer (TxBuffer);
FlushBuffer (RxBuffer);
RTC.Second:=0;
VTStatus:=0;
ErrTime:=cErrTime;
LeseModADR;
loop
PollStop:=False;
WatchDogTrig;
EnableInts;
If IsSysTimerZero(Timer1) Then
SetSysTimer(Timer1,50);
SysLEDflashOnce (1);
LeseModADR;
WatchDogTrig;
Inc(ADTimer);
If ADTimer>59 Then ADTimer:=0; EndIf;
If ErrTime=0 Then
NotProgramm;
ErrTime:=0;
Else
Dec(ErrTime);
EndIf;
PollRK;
EndIf;
Ser_Enable (False);
If SerStat Then
ErrTime:=cErrTime;
If ReadEcoModTel Then
SysLEDflashOnce (0);
EcoMod.TxData:='';
ErrTime:=cErrTime;
ResetTime:=cResTime;
Case EcoMod.Comand Of
$02 : EcoMod.TxData:=ByteToHex(USTAdr)+'99';|
$03 : EcoMod.TxData:=ByteToHex(VTStatus);|
$04 : LoadSetVS;|
$06 : SetModRKConf;|
$07 : SendModRKConf;|
$09 : System_Reset;|
EndCase;
If EcoMod.TxData<>'' Then
Send485;
mDelay(6);
EndIf;
EndIf;
EndIf;
endloop;
end UST4_485a.