Compiler Rev. 5.09.51
Mega328P
Hallo,
es geht um ein ganz einfaches RS485 Protokoll.
Es sollen einfach ein paar Bytes nicht umgewandelt in Strings und ohne irgendeinen weiteren Zusatz wie "carriage return" usw. übertragen werden.
Also nur "nackte" Bytes.
Es ist eine Revision einer alten Baugruppe, es muß so gemacht werden.
Im Beispielcode wäre mir am Liebsten die Pascal Variante (pRS485_Pascal) mit "SerOut".
Im Simulator geht's.
Nur in echt geht's nicht. Es erscheint kein 9. Datenbit auf dem Oszi.
Im Notfall auch die Assembler Variante (pRS485_Assembler).
Hoffe es ist soweit alles Aufschlußreich zum Nachvollziehen.
Danke
program RS485_Test_01;
{
Testprogrammcode wegen Fehlverhalten bei der Einstellung und nicht Übertragung des 9. Datenbits.
Datum: 16.02.2022
}
{$NOSHADOW}
{ $WG} {global Warnings off}
Device = mega328p, VCC=5;
{ $BOOTRST $03800} {Reset Jump to $03800}
Define_Fuses
Override_Fuses;
// NoteBook = A;
COMport = USB;
SPIclk = 2000000;
LockBits0 = [];
FuseBits0 = [CKSEL3, CKDIV8];
FuseBits1 = [BOOTSZ0, BOOTSZ1];
FuseBits2 = [BODLEVEL0, BODLEVEL1];
ProgMode = SPI;
Import SysTick, SerPort;
Define
ProcClock = 14745600; {Hertz}
SysTick = 1; {msec}
StackSize = 100, iData;
FrameSize = 100, iData;
SerPort = 76800, Stop1; {Baud, StopBits|Parity}
RxBuffer = 10, iData;
TxBuffer = 10, iData;
SerCtrl = PortD, 2, positive; {control line for RS485 driver}
Implementation
{ Var Declarations }
{$IDATA}
var
bMadress : Byte;
bX : Byte;
bZ : Byte;
CASE_loop : byte;
Timerloop : SysTimer8;
//--------------------------------------------------------------;
//--------------------------------------------------------------;
{ functions }
procedure InitPorts;
begin
PortD:= %0000 0000;
DDRD:= %0000 0100; // 1=Ausgang, 0=Eingang
end InitPorts;
//--------------------------------------------------------------;
procedure InitVariablen;
begin
bMadress:= 127; // Masteradresse
bX:= %1010 1010;
bZ:= %0101 0101;
end InitVariablen;
//--------------------------------------------------------------;
Procedure pRS485_Pascal;
begin
UCSR0B:= UCSR0B Or %0000 0101; // umschalten auf Adressbyte für Master mit 9 Bits, 9. Datenbit auf high
Ser_Enable (true); // RS Transceiver-IC auf senden schalten.
SerOut (bMadress);
Ser_Enable (false); // RS Transceiver-IC auf empfangen schalten
UCSR0B:= UCSR0B And %1111 1010; // umschalten auf Datenbyte mit 8 Bits
SerOut (bX);
SerOut (bZ);
End pRS485_Pascal;
//--------------------------------------------------------------;
// https://www.mikrocontroller.net/articles/AVR_ASM_Befehls%C3%BCbersicht
// https://www.mikrocontroller.net/attachment/highlight/269
Procedure pRS485_Assembler;
begin
UCSR0B:= UCSR0B Or %0000 0101; // umschalten auf Adressbyte für Master mit 9 Bits, 9. Datenbit auf high
Ser_Enable (true); // RS Transceiver-IC auf senden schalten.
ASM;
ldi r16, 127
out UDR1, r16
ENDASM;
Ser_Enable (false); // RS Transceiver-IC auf empfangen schalten
UCSR0B:= UCSR0B And %1111 1010; // umschalten auf Datenbyte mit 8 Bits
SerOut (bX);
SerOut (bZ);
End pRS485_Assembler;
//--------------------------------------------------------------;
//--------------------------------------------------------------;
{ Main Program }
{$IDATA}
begin
CLKPR:= %1000 0000; // Clock Prescaler Change Enable.
CLKPR:= %0000 0000; // Clock Prescale = 1.
InitPorts;
InitVariablen;
EnableInts;
loop
Case CASE_loop Of
0 : SetSysTimer(Timerloop, 100);
CASE_loop:= 1;
|
1 : IF IsSysTimerZero(Timerloop) Then
pRS485_Pascal;
// pRS485_Assembler;
CASE_loop:= 0;
EndIF;
|
EndCase;
endloop;
end RS485_Test_01.
Mega328P
Hallo,
es geht um ein ganz einfaches RS485 Protokoll.
Es sollen einfach ein paar Bytes nicht umgewandelt in Strings und ohne irgendeinen weiteren Zusatz wie "carriage return" usw. übertragen werden.
Also nur "nackte" Bytes.
Es ist eine Revision einer alten Baugruppe, es muß so gemacht werden.
Im Beispielcode wäre mir am Liebsten die Pascal Variante (pRS485_Pascal) mit "SerOut".
Im Simulator geht's.
Nur in echt geht's nicht. Es erscheint kein 9. Datenbit auf dem Oszi.
Im Notfall auch die Assembler Variante (pRS485_Assembler).
Hoffe es ist soweit alles Aufschlußreich zum Nachvollziehen.
Danke
Code
program RS485_Test_01;
{
Testprogrammcode wegen Fehlverhalten bei der Einstellung und nicht Übertragung des 9. Datenbits.
Datum: 16.02.2022
}
{$NOSHADOW}
{ $WG} {global Warnings off}
Device = mega328p, VCC=5;
{ $BOOTRST $03800} {Reset Jump to $03800}
Define_Fuses
Override_Fuses;
// NoteBook = A;
COMport = USB;
SPIclk = 2000000;
LockBits0 = [];
FuseBits0 = [CKSEL3, CKDIV8];
FuseBits1 = [BOOTSZ0, BOOTSZ1];
FuseBits2 = [BODLEVEL0, BODLEVEL1];
ProgMode = SPI;
Import SysTick, SerPort;
Define
ProcClock = 14745600; {Hertz}
SysTick = 1; {msec}
StackSize = 100, iData;
FrameSize = 100, iData;
SerPort = 76800, Stop1; {Baud, StopBits|Parity}
RxBuffer = 10, iData;
TxBuffer = 10, iData;
SerCtrl = PortD, 2, positive; {control line for RS485 driver}
Implementation
{ Var Declarations }
{$IDATA}
var
bMadress : Byte;
bX : Byte;
bZ : Byte;
CASE_loop : byte;
Timerloop : SysTimer8;
//--------------------------------------------------------------;
//--------------------------------------------------------------;
{ functions }
procedure InitPorts;
begin
PortD:= %0000 0000;
DDRD:= %0000 0100; // 1=Ausgang, 0=Eingang
end InitPorts;
//--------------------------------------------------------------;
procedure InitVariablen;
begin
bMadress:= 127; // Masteradresse
bX:= %1010 1010;
bZ:= %0101 0101;
end InitVariablen;
//--------------------------------------------------------------;
Procedure pRS485_Pascal;
begin
UCSR0B:= UCSR0B Or %0000 0101; // umschalten auf Adressbyte für Master mit 9 Bits, 9. Datenbit auf high
Ser_Enable (true); // RS Transceiver-IC auf senden schalten.
SerOut (bMadress);
Ser_Enable (false); // RS Transceiver-IC auf empfangen schalten
UCSR0B:= UCSR0B And %1111 1010; // umschalten auf Datenbyte mit 8 Bits
SerOut (bX);
SerOut (bZ);
End pRS485_Pascal;
//--------------------------------------------------------------;
// https://www.mikrocontroller.net/articles/AVR_ASM_Befehls%C3%BCbersicht
// https://www.mikrocontroller.net/attachment/highlight/269
Procedure pRS485_Assembler;
begin
UCSR0B:= UCSR0B Or %0000 0101; // umschalten auf Adressbyte für Master mit 9 Bits, 9. Datenbit auf high
Ser_Enable (true); // RS Transceiver-IC auf senden schalten.
ASM;
ldi r16, 127
out UDR1, r16
ENDASM;
Ser_Enable (false); // RS Transceiver-IC auf empfangen schalten
UCSR0B:= UCSR0B And %1111 1010; // umschalten auf Datenbyte mit 8 Bits
SerOut (bX);
SerOut (bZ);
End pRS485_Assembler;
//--------------------------------------------------------------;
//--------------------------------------------------------------;
{ Main Program }
{$IDATA}
begin
CLKPR:= %1000 0000; // Clock Prescaler Change Enable.
CLKPR:= %0000 0000; // Clock Prescale = 1.
InitPorts;
InitVariablen;
EnableInts;
loop
Case CASE_loop Of
0 : SetSysTimer(Timerloop, 100);
CASE_loop:= 1;
|
1 : IF IsSysTimerZero(Timerloop) Then
pRS485_Pascal;
// pRS485_Assembler;
CASE_loop:= 0;
EndIF;
|
EndCase;
endloop;
end RS485_Test_01.