hat nicht viel gebracht. Ich habe das Programm erheblich reduziert. Bisher habe ich einiges versucht aber nichts bringt was. FloatToStr bringt gelegentlich Fehler (so ca. 1 bei 15 Übertragungen). Den i2c Treiber habe ich schon verworfen, der macht auch Probleme wenn der Baustein nicht vorhanden ist. Bisher habe ich über Jahre mit dem atmega 2651 keinerlei Probleme. Habe aber auf die RTC Funktion verzichtet.
Die Unterlagen geben hier keine hinweise. Was aber passiert wenn ich andere Teile noch benutze wie z.B. ModBus-RTU ??
PS: auf die Processes/Tasks habe ich bisher verzichtet. Wenn man die Werte z.B. über einen RS485 Interface überträgt gibt es keinerlei Probleme.
Code
program MINI3_X1;
{$NOWATCHDOGAUTO}
{$NOSHADOW}
{$WG}
Device = xmega256A3BU;
{$BOOTRST $20000} {Reset Jump to $20000}
//{$BootApplication} // $20000
Define_Fuses
Override_Fuses;
NoteBook = D;
COMport = USB;
ProgMode = PDI;
LockBits0 = [BLBB0, BLBB1, LB0, LB1]; // protect boot and app against read back
FuseBits0 = [];
FuseBits1 = [];
FuseBits2 = [BootRst]; // mandatory !!
FuseBits5 = [BODACT0, BodLevel0, BodLevel1, BodLevel2];
Import SysTick,WatchDog, SerPortD0, SerPortE0, SerPortF0, SerPortC0;
Import UserPort, TWI_E, TickTimer, ADC_A;
Import SerPortCDC;
From System Import Processes, Tasks;
From System Import Float,LongWord,Traps;
Define
// XMega USB must use the internal 32MHz OSC. So the system must use the 2MHz OSC
OSCtype = int2MHz,
PLLmul = 16, // bei int2MHz und PLLmul 10 = 20MHz
prescB = 1,
prescC = 1;
SysTick = 10, User; // msec
StackSize = $0128, iData;
FrameSize = $0128, iData;
WatchDog = msec2000; {2048msec}
// optional
Scheduler = iData;
TaskStack = $80, iData;
TaskFrame = $100;
// IDATA1 = $5FC0;
USBmanufact = 'EcoTron'; // max 31 bytes
USBprodName = 'Serial CDC-USB'; // "
USBpid = $05FE;
USBvid = $BCDE;
USBprodRel = 203;
USBcurrent = 100;
SerPortCDC = TimeOut;
RxBufferCDC = 64, iData;
TxBufferCDC = 64, iData;
{----------------------------- init AD-Wandler -----------------------------}
ADCrefA = REF100;
ADCprescA = 128,12;
ADCchansA = [0..2];
TWIprescE = TWI_BR100;
UserPort = 65535;
{ RTC-CPU-Uhr intern }
TickTimer = Timer_C0; // use Timer_C0 and no PortPin
// RS485
SerPortC0 = 38400, Stop1, timeout; {Baud, StopBits|Parity}
SerCtrlC0 = PortD, 4, positive;
RxBufferC0 = 40, iData;
TxBufferC0 = 100, iData;
// RS485
SerPortD0 = 38400, Stop1, timeout; {Baud, StopBits|Parity}
SerCtrlD0 = PortD, 4, positive;
RxBufferD0 = 40, iData;
TxBufferD0 = 100, iData;
// RS485
SerPortE0 = 38400, Stop1, timeout; {Baud, StopBits|Parity}
SerCtrlE0 = PortE, 4, positive;
RxBufferE0 = 40, iData;
TxBufferE0 = 100, iData;
// RS485
SerPortF0 = 38400, Stop1, timeout; {Baud, StopBits|Parity}
SerCtrlF0 = PortF, 1, positive;
RxBufferF0 = 40, iData;
TxBufferF0 = 100, iData;
Uses uXmega_CDC;
Implementation
{$IDATA}
{------------------------------------------------------------------------------}
{ Type Declarations }
Type
{--------------------------------------------------------------}
{ Const Declarations }
Const
// this constant must be the same as in the Main app
DownLoaderID : word = $1234; // mandatory constant
{--------------------------------------------------------------}
{ Var Declarations }
Var
Timer1 : SysTimer;
StopSysTic : Boolean;
PollLED [@PortR,1] : Bit; // Poll-LED
SysLED [@PortR,0] : Bit; // Poll-LED
USBOk[@pinB,3] : Bit;
USBOffline : Boolean;
ADIn : Word;
{$IDATA}
{$NoSave} // standard register save is sufficient
{--------------------------------------------------------------}
{--------------------------------------------------------------}
Interrupt TCD0_INTOVF;
begin
ASM: CALL System.$INTERRUPT_SYSTICK_USER;
end;
{--------------------------------------------------------------}
{--------------------------------------------------------------}
Procedure onTickTimer; // onTickTimer(SaveAllRegs);SaveAllRegs not necessary here
begin
ASM: CALL System.$INTERRUPT_SYSTICK_USER;
end;
{--------------------------------------------------------------}
{--------------------------------------------------------------}
{$NoSave} // standard register save is sufficient
(* for a UserDevice the following 3 function must be implemented *)
UserDevice UsrDevIni;
begin
end;
{--------------------------------------------------------------}
{--------------------------------------------------------------}
UserDevice UsrDevInp (adr : word) : byte;
var
ERR,IC : Byte;
EEByte : Byte;
begin
EnableInts($87);
IC:=$50; // mandory for USB_ControlJob
If Adr>=32768 Then Inc(IC); EndIf;
If TWIOutE(IC,adr) Then
Err:=50;
Repeat
Dec(Err);
Until TWIInpE(IC,EEByte) Or (Err=0);
If Err=0 Then Return($ff); Else Return(EEByte); EndIf;
EndIf;
end;
{--------------------------------------------------------------}
{--------------------------------------------------------------}
UserDevice UsrDevOut (adr : word; outp : byte);
var
ERR,IC : Byte;
begin
EnableInts($87); // mandory for USB_ControlJob
IC:=$50; // mandory for USB_ControlJob
If Adr>=32768 Then Inc(IC); EndIf;
If TWIOutE(IC,adr,outp) Then
Err:=50;
Repeat
Dec(Err);
Until (TWIStatE(IC)) Or (Err=0);
EndIf;
End;
{--------------------------------------------------------------}
{--------------------------------------------------------------}
Procedure OnSysTick;
Begin
// Dec(I2CTiOut);
End;
{--------------------------------------------------------------}
{ Initialisieren der CPU }
{--------------------------------------------------------------}
Procedure InitPorts;
Begin
DDRR := DDRR Or %00000011; // Output=1 Input=0
DDRA := DDRA And %11111000; // Output=1 Input=0
PollLED:=True;
SysLED :=False;
End;
{--------------------------------------------------------------}
{ Init System und Ports }
{ Ports DDR = Output=1 Input=0 }
{--------------------------------------------------------------}
Procedure InitSystem;
Begin
InitPorts;
WatchDogStart;
End;
{==============================================================================}
{--------------------------------------------------------------}
{--------------------------------------------------------------}
Procedure WriteLnUSB(xASCII:String[40]);
Begin
If USBOk=False Then Return; EndIf;
FlushBuffer(TxBufferCDC);
If CDCportValid Then
WriteLn(SerOutCDC,xASCII);
EndIf;
End;
{==============================================================================}
Procedure PollSystem;
Var
xFL : Float;
ASCII : String[40];
Begin
PollLED:=True;
// PollAlle_UST2_485;
// WriteLn(SerOutC0,FloatToStr(ADVdc[1]:8:2:'0')+' '+IntToStr(ADIn[1]));
lock(self);
ADIn:=GetAdcA(1);
xFL:=(Float(ADIn)*0.1);
unlock(self);
SetSerEnable(UsartF0, true);
WriteLn(SerOutF0,FloatToStr(xFL)+' '+IntToStr(ADIn));
SetSerEnable(UsartF0, False);
ASCII:=FloatToStr(xFL);
WriteLnUSB(ASCII+' '+IntToStr(ADIn));
// Case RTC.Second And $01 Of
// 0 : Send_Systemdaten;|
// EndCase;
PollLED:=False;
End;
{--------------------------------------------------------------}
{--------------------------------------------------------------}
{ Main Program }
{$IDATA}
begin
InitSystem;
SysLED:=True;
EnableInts($87); // mandory for USB_ControlJob
TickTimerTime(10000); // 10000usec = 10msec
TickTimerStart;
USBOffline:=True;
PollLED:=False;
SetSysTimer(Timer1,50);
StopSysTic:=False;
loop
SysLED:=False;
If USBOk Then
If USBOffline Then
CDCopenPort; // Open&Connect CDC Port
USBOffline:=False;
SysLED:=True;
EndIf;
Else
SysLED:=True;
System_Reset;
EndIf;
If StopSysTic=False Then
If IsSysTimerZero(Timer1) Then
SetSysTimer(Timer1,50);
WatchDogTrig;
PollSystem;
EndIf;
EndIf;
endloop;
CDCclosePort;
end.