Hallo,
ich habe ein Problem mit der Kommunikation PC <--> AVR. Und zwar ein Vertändnisproblem. Vielleicht kann mir jemand den richtigen Ansatz zeigen.
Ein PC schickt sreille an den AVR ein Komanndo. Der AVR arbeitet das Komanndo ab. Nun möchte ich, während der AVR das aktuelle Kommando abarbeitet, ein weiteres Kommando schicken. In meinem Beispiel ein Art "Not-Aus".
Genau geht es darum, das eine Achse per Schrittmotor getrieben wird und zum Besipiel die Referenzfaht macht. Die Referenzfahrt mache ich im Groben so.
repeat
StepOneCW;
medelay(3);
until PINX.X=false;
Jetzt kann ich den RXRDY-Interrupt benutzen, um trotz der repeat-until Schleife Zeichen zu Empfangen, dann ein Flag zu setzten. Und dieses Flag in der Referenzfahrtschleife ständig abfragen:
repeat
StepOneCW;
medelay(3);
if FLAGNOTAUS then ...
until PINX.X=false;
Hier noch die Routine für Interruptempfang:
Interrupt RXRDY;
begin
asm;
in _ACCA, UDR1;
sts %.RXchar, _ACCA;
ENDASM;
serout(RXchar); //echo zum Debuggen
if CommFlag = StartChar then //Vorher schon gültiges Startzeichen empfangen?
inc(CommPointer); // dann im Buffer ablegen
RecvBuffer[CommPointer]:= RXchar;
if (CommPointer = 5) then //Bufferende erreicht?
if RecvBuffer[CommPointer] = '#' then //Endezeichen empfangen?
CommFlag:= Received; //Ja, Empfangsflag setzen
else //Buffer voll und letzten Zeichen ist kein
CommFlag:= NoChar; //Endezeichen, also wieder von vorn
endif; // if RecvBuffer[CommPointer] = 35
endif; //if (CommPointer = 5) then
else
case RXChar of
'z' :
CommPointer:= 1;
CommFlag:= StartChar;
RecvBuffer[CommPointer]:= 'z';
|
'x' :
CommPointer:= 1;
CommFlag:= StartChar;
RecvBuffer[CommPointer]:= 'x';
|
's' :
CommPointer:= 1;
CommFlag:= StartChar;
RecvBuffer[CommPointer]:= 's';
|
'e' :
CommPointer:= 1;
CommFlag:= StartChar;
RecvBuffer[CommPointer]:= 'e';
|
endcase;
endif; //if CommFlag = StartChar then
if CommFlag = Received then
cmdb1:= ord(RecvBuffer[2]);
cmdb2:= ord(RecvBuffer[3]);
cmdb3:= ord(RecvBuffer[4]);
cmdb4:= 0;
endif;
end;
Eine andere Variante wäre, die Referenzfahrt und den Empfang der Zeichen als Process zu schreiben:
Waitpipe(RXBuffer);
if NOTAUS then suspend(Referenzfahrt);
Die zentralen Fragen:
Was davon ist der richtige Weg?
Oder gibt es noch eine bessere Alternative?
Ich danke ganz herzlich für Eure Geduld und den Zeitaufwand!
Viele Grüße
Rolf
ich habe ein Problem mit der Kommunikation PC <--> AVR. Und zwar ein Vertändnisproblem. Vielleicht kann mir jemand den richtigen Ansatz zeigen.
Ein PC schickt sreille an den AVR ein Komanndo. Der AVR arbeitet das Komanndo ab. Nun möchte ich, während der AVR das aktuelle Kommando abarbeitet, ein weiteres Kommando schicken. In meinem Beispiel ein Art "Not-Aus".
Genau geht es darum, das eine Achse per Schrittmotor getrieben wird und zum Besipiel die Referenzfaht macht. Die Referenzfahrt mache ich im Groben so.
Code
repeat
StepOneCW;
medelay(3);
until PINX.X=false;
Jetzt kann ich den RXRDY-Interrupt benutzen, um trotz der repeat-until Schleife Zeichen zu Empfangen, dann ein Flag zu setzten. Und dieses Flag in der Referenzfahrtschleife ständig abfragen:
Code
repeat
StepOneCW;
medelay(3);
if FLAGNOTAUS then ...
until PINX.X=false;
Hier noch die Routine für Interruptempfang:
Code
Interrupt RXRDY;
begin
asm;
in _ACCA, UDR1;
sts %.RXchar, _ACCA;
ENDASM;
serout(RXchar); //echo zum Debuggen
if CommFlag = StartChar then //Vorher schon gültiges Startzeichen empfangen?
inc(CommPointer); // dann im Buffer ablegen
RecvBuffer[CommPointer]:= RXchar;
if (CommPointer = 5) then //Bufferende erreicht?
if RecvBuffer[CommPointer] = '#' then //Endezeichen empfangen?
CommFlag:= Received; //Ja, Empfangsflag setzen
else //Buffer voll und letzten Zeichen ist kein
CommFlag:= NoChar; //Endezeichen, also wieder von vorn
endif; // if RecvBuffer[CommPointer] = 35
endif; //if (CommPointer = 5) then
else
case RXChar of
'z' :
CommPointer:= 1;
CommFlag:= StartChar;
RecvBuffer[CommPointer]:= 'z';
|
'x' :
CommPointer:= 1;
CommFlag:= StartChar;
RecvBuffer[CommPointer]:= 'x';
|
's' :
CommPointer:= 1;
CommFlag:= StartChar;
RecvBuffer[CommPointer]:= 's';
|
'e' :
CommPointer:= 1;
CommFlag:= StartChar;
RecvBuffer[CommPointer]:= 'e';
|
endcase;
endif; //if CommFlag = StartChar then
if CommFlag = Received then
cmdb1:= ord(RecvBuffer[2]);
cmdb2:= ord(RecvBuffer[3]);
cmdb3:= ord(RecvBuffer[4]);
cmdb4:= 0;
endif;
end;
Eine andere Variante wäre, die Referenzfahrt und den Empfang der Zeichen als Process zu schreiben:
Code
Waitpipe(RXBuffer);
if NOTAUS then suspend(Referenzfahrt);
Die zentralen Fragen:
Was davon ist der richtige Weg?
Oder gibt es noch eine bessere Alternative?
Ich danke ganz herzlich für Eure Geduld und den Zeitaufwand!
Viele Grüße
Rolf