Hatte vor Jahren etwas damit zu tun.
Hier der relevante Softwareteil.
Code
Device = Xmega32A4U, VCC = 3.3;
{ $BOOTRST $08000} {Reset Jump to $08000}
define_fuses
Override_Fuses;
NoteBook = D;
ProgMode = PDI;
COMport = USB;
Supply = 3.3, 100;
LockBits0 = [];
FuseBits0 = [];
FuseBits1 = [];
FuseBits2 = [];
FuseBits5 = [BodLevel0, BodLevel2];
ProgFlash = true; // or false – program Flash
ProgEEprom = false; // or false – program EEprom
Import SysTick, WatchDog, QDEC_C0, QDEC_C1, QDEC_D0, SerPortD0, SerPortD1, SPIdriver1, LCDPort, BeepPort, SwitchPort_G, ADC_A; // TickTimer,
From System import Processes, longword, longint, OEMcharSet;
From SysTick Import SystemTime16;
define
// The XMegas don't provide any Oscillator fuses.
// So the application must setup the desired values
// possible OSC types: extXTAL, extClock, ext32kHz, int32Khz, int2MHz, int32MHz
//>> CPU=32MHz, PeripherX4=32MHz, PeripherX2=32MHz
OSCtype = extXTAL = 7372800, PLLmul = 4, prescB = 1, prescC = 1;
SysTick = 10; {msec}
WatchDog = msec125; {presc = 3}
StackSize = $0100, iData;
FrameSize = $0100, iData;
Scheduler = iData;
// TickTimer = Timer_D1;
QDECphase_C0 = PortC, 0, 1; // Port, Phase0, Phase90 input pin
QDECevChan_C0 = 0; // main event on channel 0..1
QDECphase_C1 = PortC, 2, 3; // Port, Phase0, Phase90 input pin
QDECevChan_C1 = 2; // main event on channel 2..3
QDECphase_D0 = PortC, 4, 5; // Port, Phase0, Phase90 input pin
QDECevChan_D0 = 4; // main event on channel 4..5
LCDPort = LCDuserPort; // SPI_Soft
LCDrows = 2; // rows
LCDcolumns = 16; // columns per line
LCDtype = 66712;
// LCDBargraph1 = LCDport;
SPIdriver1 = PortB, 1, 0, 5, 3; // SCK, MOSI, MISO, SS
SPIorder1 = MSB;
SPIcPHA1 = 1;
SPIcPol1 = 1;
BeepPort = PortD, 0;
ADCrefA = REFextA; // extern reference, input pins at PortA
ADCprescA = 256, 8; // prescaler 256, resolution 8bits
ADCchansA = [1..4]; // 4 channels in use, using SysTick
SerPortD0 = 19200, Databit8, parEven, Stop1;
TxBufferD0 = 100, iData;
RxBufferD0 = 100, iData;
SerPortD1 = 19200, Databit8, parEven, Stop1; // Debugin
TxBufferD1 = 100, iData;
RxBufferD1 = 100, iData;
SwitchPort_G = [Wartezeit_Reset, PinE, 1], %00000010;
PolarityP_G = %00000010; // Polarity SwitchPort_G
Debounce = 3; // debounce alle 3 SysTicks
//--------------------------------------------------------------;
//--------------------------------------- pIncrementalGeber -----------------------------------------------------;
{$IDATA}
var
CASE_IncGeber : byte;
TimerIncGeber1 : SysTimer;
TimerIncGeber2 : SysTimer;
iIntensCounter : integer;
iDauerCounter : integer;
iWartezeitCounter : integer;
bIntensEncoderAktiv : Byte;
bDauerEncoderAktiv : Byte;
bWartezeitEncoderAktiv : Byte;
const
iIntLimitUnten : Integer = 10;
iIntLimitOben : Integer = 80;
iDauerLimitUnten : Integer = 1;
iDauerLimitOben : Integer = 30; // Sekunden
iWarteLimitUnten : Integer = 1;
iWarteLimitOben : Integer = 60; // Minuten
//--------------------------------------------------------------------------------------------;
procedure pIncrementalGeber;
begin
case CASE_IncGeber of
0 : QDECenable_C0(true); // Incrementalzähler freigeben.
QDECenable_C1(true);
QDECenable_D0(true);
// QDECclearpos_C0; // Incrementalzähler Reset.
// QDECclearpos_C1;
// QDECclearpos_D0;
SetSysTimer(TimerIncGeber1, ms50);
CASE_IncGeber:= 1;
|
1 : If iIntensCounter <> QDECgetPos_C0 div 2 Then
bIntensEncoderAktiv:= Ja;
EndIf;
iIntensCounter := QDECgetPos_C0 div 2;
If iIntensCounter < iIntLimitUnten Then // Incrementalzähler auf unteres Limit prüfen.
QDECsetPos_C0(iIntLimitUnten*2);
iIntensCounter:= iIntLimitUnten;
EndIf;
If iIntensCounter > iIntLimitOben Then // Incrementalzähler auf oberes Limit prüfen.
QDECsetPos_C0(iIntLimitOben*2);
iIntensCounter:= iIntLimitOben ;
EndIf;
CASE_IncGeber:= 2;
|
2 : If iDauerCounter <> QDECgetPos_C1 div 2 Then
bDauerEncoderAktiv:= Ja;
EndIf;
iDauerCounter := QDECgetPos_C1 div 2;
If iDauerCounter < iDauerLimitUnten Then // Incrementalzähler auf negativen Wert prüfen.
QDECsetPos_C1(iDauerLimitUnten*2);
iDauerCounter:= iDauerLimitUnten;
EndIf;
If iDauerCounter > iDauerLimitOben Then // Incrementalzähler auf positives Limit prüfen.
QDECsetPos_C1(iDauerLimitOben*2);
iDauerCounter:= iDauerLimitOben;
EndIf;
CASE_IncGeber:= 3;
|
3 : If iWartezeitCounter <> QDECgetPos_D0 div 2 Then
bWartezeitEncoderAktiv:= Ja;
EndIf;
iWartezeitCounter:= QDECgetPos_D0 div 2;
If iWartezeitCounter < iWarteLimitUnten Then // Incrementalzähler auf negativen Wert prüfen.
QDECsetPos_D0(iWarteLimitUnten*2);
iWartezeitCounter:= iWarteLimitUnten;
EndIf;
If iWartezeitCounter > iWarteLimitOben Then // Incrementalzähler auf positives Limit prüfen.
QDECsetPos_D0(iWarteLimitOben*2);
iWartezeitCounter:= iWarteLimitOben;
EndIf;
CASE_IncGeber:= 5;
|
5 : IF (IsSysTimerZero(TimerIncGeber2)) Then
IF eiIntensCounter <> iIntensCounter Then eiIntensCounter := iIntensCounter; EndIf;
IF eiDauerCounter <> iDauerCounter Then eiDauerCounter := iDauerCounter; EndIf;
IF eiWartezeitCounter <> iWartezeitCounter Then eiWartezeitCounter:= iWartezeitCounter; EndIf;
SetSysTimer(TimerIncGeber2, sec1);
EndIf;
CASE_IncGeber:= 10;
|
10 : IF (IsSysTimerZero(TimerIncGeber1)) Then
CASE_IncGeber:= 1;
EndIf;
|
endcase;
end pIncrementalGeber;
//--------------------------------------------------------------------------------------------;