Liebe Avrler,
ich habe das Problem, dass eine kleine Karte mit Mega168 Prozessor, die wir in Massen einsetzen und immer perfekt funktionierte nun nicht mehr geht. Das Programm mit der Version 4.98 kompiliert geht gut. mit der 4.99.14 als auch 4.99.17 geht die TWI Kommunikation nicht mehr. Ich habe das Programm mal auf das nötigste zusammengestrichen. Wie gesagt mit 4.98 ok jetzt aber nicht. Nach einigen Sekunden beobachtet man das Lowgehen der SDA und SCL-Leitungen. Es kommt aber von vornherein keine Kommunikation zustande.
Hat jemand anderes auch TWIprobleme ?
program BDK02;
{ $ BOOTRST $00C00} {Reset Jump to $00C00}
{ $ NOSHADOW} // Sichert bei IRQs nur die benötigten Register.
{ $ NOSAVE} // bei dem nachfolgenden Irq werden nur die Register
// AccA, AccB, AccCLo, AccCHi & StatusReg gesichert.
{ $W+ Warnings} {Warnings off}
Device = mega168, VCC=5;
Import SysTick, TWIslave, SerPort;
From System Import Float;
Define
ProcClock = 8000000; {Hertz}
SysTick = 10, Timer0; {msec}
StackSize = $0084, iData;
FrameSize = $0084, iData;
SerPort = 9600, Stop1; {Baud, StopBits|Parity}
RxBuffer = 8, iData;
TxBuffer = 8, iData;
TWIbuffer = 10, iData;
TWIaddr = 02;
TWImode = HandShake;
Implementation
{$IDATA}
{--------------------------------------------------------------}
{ Type Declarations }
type
TStr30 = String[30];
TI2CBlock = Record
JI : LongInt;
JS : Byte;
Ky : Byte;
end;
{--------------------------------------------------------------}
{ Const Declarations }
Const CR : Char = #13;
LF : Char = #10;
{--------------------------------------------------------------}
{ Var Declarations }
{$IDATA}
var
LED[@PortB,1] : Bit;
F4[@PinB,0] : Bit; {Enter}
F1[@PinD,5] : Bit; {Escape}
cmd : byte;
I2CBlock : TI2CBlock;
I2CArr[@I2CBlock] : Array[0 .. 5] of byte;
JogInt[@I2CBlock] : LongInt;
JogShift[@I2CBlock+4] : Byte;
Taste[@I2CBlock+5] : Byte;
JogLimitArr : Array[0..8] of Byte; {Erlaubte Grenzen}
JogIntHi[@JogLimitArr] : LongInt;
JogINtLo[@JogLimitArr+4] : LongInt;
JogShiftHi[@JogLimitArr+8] : byte;
TOut : integer;
Value : LongInt;
idx : byte;
SaveT : Byte; {Zwischenspeicher zum Feststellen der Änderungen}
SaveJI : LongInt;
SaveJS : Byte;
{--------------------------------------------------------------}
{ functions }
{-------------------- Seriell --------------------------------------}
PROCEDURE SendString(S : TStr30);
VAR I : byte;
BEGIN
FOR I := 1 TO Length(S) DO SerOut(S[I]); endfor;
END;
PROCEDURE SendCR;
BEGIN
SerOut(CR);
SerOut(LF);
END;
Procedure InitPorts;
begin
DDRB := %00000010; {PB0: Taster F4, PB1: Led, PB2: SS PB3: MoSi, PB4: MiSo, PB4: Sck}
PortB := %00000001; {Led aus}
DDRD := %00000010; {PD7: Taster F3, PD6: F2, PD5: F1}
{PD4: JogDialC, PD3: JogButton, PD2:JogDialA, PD1:TxD, PD0: RxD}
PortD := %11100000;
end InitPorts;
FUNCTION AsmIsKey:Byte; {0: Keine, 1:esc, 8:enter, $10: JogButton gedrückt}
var b : byte;
begin
asm;
In _AccA, PinD;
In _AccB, PinB;
Com _AccB;
OrI _AccA,$17
Com _AccA;
RoR _AccB
RoR _AccA ; F4 F3 F2 F1 XX JB XX XX
LSR _AccA
LSR _AccA ; B7 B3 Cy
LSR _AccA ; 00 00 00 F4 F3 F2 F1 XX JB
BrCc NoJButton
OrI _AccA,$20;
NoJButton:
LSR _AccA
St Y, _AccA //Returnwert immer -> Y;
endAsm;
return(b);
end;
{--------------------------------------------------------------}
{ Main Program }
{$IDATA}
begin
InitPorts;
EnableInts;
TWIsetGC(true); {Reaktion auf Broadcasts (ADR0) enable;}
TWIsetslaveAddr(2); {Dieses Gerät hat Adresse 2}
SendString('BDK-02'); sendCR;
Taste := 0;
Repeat
until TWIsetRDY(true);
loop
If not TWIGetRdy then // wenn der Master via TWI gesendet hat
cmd := TWIGetCmd; // Kommando feststellen
Case cmd of
1: For idx:=0 to 5 do //für Änderung durch Jog-Dial:
I2CArr[idx] := TWIRXBUFFER[idx]; // Anfangswerte eintragen
EndFor; |
2: For idx:=0 to 5 do {*** Versenden ***}
TWITXBUFFER[idx]:=I2CArr[idx]; {Daten -> Sendepuffer}
EndFor;
TOut:=0;
repeat
inc(Tout);
until (TWIsetRDY(true) or (TOut>10000)); {Melde 'Bereit'}
TOut:=0;
repeat
inc(Tout);
until (TWIgetTXStat or (TOut>10000)); {Warte bis abgeholt ist}
|
3: for idx:=0 to 8 do {** Get Limits for Jogdial **}
JogLimitArr[idx] := TWIRXBUFFER[idx];
EndFor; |
endcase;
repeat until TWIsetRDY(true); // Wieder "Bereit" melden
endif;
If Cmd = 3 then
SendString('cmd:'+ByteToStr(Cmd)); SendCR;
SendString('JogIntHi'+LongToStr(JogIntHi)); SendCR;
SendString('JogIntLo'+LongToStr(JogIntLo)); SendCR;
SendString('JogShHi'+ByteToStr(JogShiftHi)); SendCR;
endif;
Taste:= AsmIsKey; // Tasten einlesen
if ( SaveT<>Taste) then
I2CBlock.JI := JogInt; // Werte zum Versenden ins Feld eintragen
I2CBlock.JS := JogShift;
I2CBlock.Ky := Taste;
SaveJI:=Jogint; // Werte merken für nächste Veränderung
SaveJS:=JogShift;
SaveT:= Taste;
for idx:= 0 to 5 do
TWITXBUFFER[idx]:= I2CArr[idx];
endfor;
endIf;
endloop;
end BDK02.
ich habe das Problem, dass eine kleine Karte mit Mega168 Prozessor, die wir in Massen einsetzen und immer perfekt funktionierte nun nicht mehr geht. Das Programm mit der Version 4.98 kompiliert geht gut. mit der 4.99.14 als auch 4.99.17 geht die TWI Kommunikation nicht mehr. Ich habe das Programm mal auf das nötigste zusammengestrichen. Wie gesagt mit 4.98 ok jetzt aber nicht. Nach einigen Sekunden beobachtet man das Lowgehen der SDA und SCL-Leitungen. Es kommt aber von vornherein keine Kommunikation zustande.
Hat jemand anderes auch TWIprobleme ?
Code
program BDK02;
{ $ BOOTRST $00C00} {Reset Jump to $00C00}
{ $ NOSHADOW} // Sichert bei IRQs nur die benötigten Register.
{ $ NOSAVE} // bei dem nachfolgenden Irq werden nur die Register
// AccA, AccB, AccCLo, AccCHi & StatusReg gesichert.
{ $W+ Warnings} {Warnings off}
Device = mega168, VCC=5;
Import SysTick, TWIslave, SerPort;
From System Import Float;
Define
ProcClock = 8000000; {Hertz}
SysTick = 10, Timer0; {msec}
StackSize = $0084, iData;
FrameSize = $0084, iData;
SerPort = 9600, Stop1; {Baud, StopBits|Parity}
RxBuffer = 8, iData;
TxBuffer = 8, iData;
TWIbuffer = 10, iData;
TWIaddr = 02;
TWImode = HandShake;
Implementation
{$IDATA}
{--------------------------------------------------------------}
{ Type Declarations }
type
TStr30 = String[30];
TI2CBlock = Record
JI : LongInt;
JS : Byte;
Ky : Byte;
end;
{--------------------------------------------------------------}
{ Const Declarations }
Const CR : Char = #13;
LF : Char = #10;
{--------------------------------------------------------------}
{ Var Declarations }
{$IDATA}
var
LED[@PortB,1] : Bit;
F4[@PinB,0] : Bit; {Enter}
F1[@PinD,5] : Bit; {Escape}
cmd : byte;
I2CBlock : TI2CBlock;
I2CArr[@I2CBlock] : Array[0 .. 5] of byte;
JogInt[@I2CBlock] : LongInt;
JogShift[@I2CBlock+4] : Byte;
Taste[@I2CBlock+5] : Byte;
JogLimitArr : Array[0..8] of Byte; {Erlaubte Grenzen}
JogIntHi[@JogLimitArr] : LongInt;
JogINtLo[@JogLimitArr+4] : LongInt;
JogShiftHi[@JogLimitArr+8] : byte;
TOut : integer;
Value : LongInt;
idx : byte;
SaveT : Byte; {Zwischenspeicher zum Feststellen der Änderungen}
SaveJI : LongInt;
SaveJS : Byte;
{--------------------------------------------------------------}
{ functions }
{-------------------- Seriell --------------------------------------}
PROCEDURE SendString(S : TStr30);
VAR I : byte;
BEGIN
FOR I := 1 TO Length(S) DO SerOut(S[I]); endfor;
END;
PROCEDURE SendCR;
BEGIN
SerOut(CR);
SerOut(LF);
END;
Procedure InitPorts;
begin
DDRB := %00000010; {PB0: Taster F4, PB1: Led, PB2: SS PB3: MoSi, PB4: MiSo, PB4: Sck}
PortB := %00000001; {Led aus}
DDRD := %00000010; {PD7: Taster F3, PD6: F2, PD5: F1}
{PD4: JogDialC, PD3: JogButton, PD2:JogDialA, PD1:TxD, PD0: RxD}
PortD := %11100000;
end InitPorts;
FUNCTION AsmIsKey:Byte; {0: Keine, 1:esc, 8:enter, $10: JogButton gedrückt}
var b : byte;
begin
asm;
In _AccA, PinD;
In _AccB, PinB;
Com _AccB;
OrI _AccA,$17
Com _AccA;
RoR _AccB
RoR _AccA ; F4 F3 F2 F1 XX JB XX XX
LSR _AccA
LSR _AccA ; B7 B3 Cy
LSR _AccA ; 00 00 00 F4 F3 F2 F1 XX JB
BrCc NoJButton
OrI _AccA,$20;
NoJButton:
LSR _AccA
St Y, _AccA //Returnwert immer -> Y;
endAsm;
return(b);
end;
{--------------------------------------------------------------}
{ Main Program }
{$IDATA}
begin
InitPorts;
EnableInts;
TWIsetGC(true); {Reaktion auf Broadcasts (ADR0) enable;}
TWIsetslaveAddr(2); {Dieses Gerät hat Adresse 2}
SendString('BDK-02'); sendCR;
Taste := 0;
Repeat
until TWIsetRDY(true);
loop
If not TWIGetRdy then // wenn der Master via TWI gesendet hat
cmd := TWIGetCmd; // Kommando feststellen
Case cmd of
1: For idx:=0 to 5 do //für Änderung durch Jog-Dial:
I2CArr[idx] := TWIRXBUFFER[idx]; // Anfangswerte eintragen
EndFor; |
2: For idx:=0 to 5 do {*** Versenden ***}
TWITXBUFFER[idx]:=I2CArr[idx]; {Daten -> Sendepuffer}
EndFor;
TOut:=0;
repeat
inc(Tout);
until (TWIsetRDY(true) or (TOut>10000)); {Melde 'Bereit'}
TOut:=0;
repeat
inc(Tout);
until (TWIgetTXStat or (TOut>10000)); {Warte bis abgeholt ist}
|
3: for idx:=0 to 8 do {** Get Limits for Jogdial **}
JogLimitArr[idx] := TWIRXBUFFER[idx];
EndFor; |
endcase;
repeat until TWIsetRDY(true); // Wieder "Bereit" melden
endif;
If Cmd = 3 then
SendString('cmd:'+ByteToStr(Cmd)); SendCR;
SendString('JogIntHi'+LongToStr(JogIntHi)); SendCR;
SendString('JogIntLo'+LongToStr(JogIntLo)); SendCR;
SendString('JogShHi'+ByteToStr(JogShiftHi)); SendCR;
endif;
Taste:= AsmIsKey; // Tasten einlesen
if ( SaveT<>Taste) then
I2CBlock.JI := JogInt; // Werte zum Versenden ins Feld eintragen
I2CBlock.JS := JogShift;
I2CBlock.Ky := Taste;
SaveJI:=Jogint; // Werte merken für nächste Veränderung
SaveJS:=JogShift;
SaveT:= Taste;
for idx:= 0 to 5 do
TWITXBUFFER[idx]:= I2CArr[idx];
endfor;
endIf;
endloop;
end BDK02.