Code
{******************************************************************** Harry ***}
{* Schrittmotorsteuerung *}
{* Display 128x64 OLED SSD1306 *}
{* Endschalter Kanal 1: C,2 und C,3 Kanal 2: C,4 und C,5 *}
{* Fusstaster C,6 und C,7 *}
{* DIP-Schalter Kanal 1: 1-4 --> B3-B0 *}
{* Kanal 2: 1-4 --> B4-B7 *}
{* Motor 1 Enable D,1 *}
{* Motor 2 Enable D,3 *}
{* Motortakt D,2 *}
{* MotorDir D,0 *}
{* *}
{* *}
{* *}
{* *}
{******************************************************************************}
Program SMS;
{$NOSHADOW}
{ $WG} {global Warnings off}
Device = xmega128A4U, VCC=3.3; // könnte auch mit einem XMega64A4U funktionieren,
// aber ich würde es nicht probieren ;-)
Define_Fuses
Override_Fuses;
ProgMode = PDI;
ProgFuses = true;
FuseBits5 = [BodAct1,BodLevel1,BodLevel2]; // 2.8V
// BOD level 0 falling VCC 1.62V ohne BodLevelx
// BOD level 1 falling VCC 1.8V BodLevel0
// BOD level 2 falling VCC 2.0V BodLevel1
// BOD level 3 falling VCC 2.2V BodLevel0 & 1
// BOD level 4 falling VCC 2.4V BodLevel2
// BOD level 5 falling VCC 2.6V BodLevel0 & 2
// BOD level 6 falling VCC 2.8V BodLevel1 & 2
// BOD level 7 falling VCC 3.0V BodLevel0 & 1 & 2
Import SysTick, TWI_C, LCDGraphic, ADC_A, SwitchPort_G, StepPort;
From System import LongWord, LongInt;
From LCDGraphic import CharSet; // block CharSet, pixels}
Define
OSCtype = int32MHz,
PLLmul = 4,
prescB = 1,
prescC = 1;
SysTick = 10; // msec
StackSize = $0100, iData;
FrameSize = $0100, iData;
TWIPrescC = TWI_BR400;
LCDGraphic = 128, 64, 8; {x-pix, y-pix, accesswidth}
LCDgraphMode = column, iData;
DefCharSet = 'Graphchars.pchr'; {FileName}
GViewports = 1, iData; {logical ViewPorts, scalings}
TGraphStr = 16; {Graphic Text String Length}
ADCrefA = Ref100; // ADC-Referenz 1.00V intern
ADCprescA = 512,12; // Prescaler 256, 12-Bit resolution
ADCchansA = [0..7];
SwitchPort_G = [ES11 , PinC,2] // EndSchalter 1 Port 1
[ES12 , PinC,3] // EndSchalter 1 Port 2
[ES21 , PinC,4] // EndSchalter 2 Port 1
[ES22 , PinC,5] // EndSchalter 2 Port 2
[FT1 , PinC,6] // FussTaster 1
[FT2 , PinC,7] // FussTaster 2
, %11000000; // entspricht nicht Portbelegung!
PolarityP_G = $C0; //
Debounce = 3;
StepMinFreq = 100;
StepMaxFreq = 5000;
StepTimer = Timer_C0;
StepType = UserPort;
StepPort = PortD.2, PortD.0;
Uses udpGraphText; // Unit für 3x5 und 5x5 Text
Implementation
{$IDATA}
Const
{------------------------------------------------------------------------------}
{ Type Declarations }
Type
{------------------------------------------------------------------------------}
Const
TText : Array[0..7] of String[6] = ('maxSpd','Rotati',
'Accele','bkRota',
' ----',' ----',
' ----',' ----');
EText : Array[0..7] of String[2] = ('%','Tn','ms','Tn','--','--','--','--');
{------------------------------------------------------------------------------}
{ Var Declarations }
{$IDATA}
Var
M1En[@PortD,1] : Bit; // Motor 1 Enable high-aktiv
M2En[@PortD,3] : Bit; // Motor 2 Enable high-aktiv
PreSet : Array[0..7] of Integer; // ADC-Werte
PS0 : AVFilter[0..15] of Integer;
DIPS : Array[0..7] of Boolean; // DIP-Schalter On=1
Switch : Array[0..5] of Boolean; // EndSchalter On=1
{--- Display-Funktionen Start -------------------------------------------------}
{ functions }
Procedure WriteLCD(Arg:Byte;IsData:Boolean);
Begin
If IsData=true
then
TWIOutC($3C,$40,Arg); // data
else
TWIOutC($3C,$80,Arg); // command
EndIf;
End WriteLCD;
Procedure GraphInit;
Begin
mDelay(100);
WriteLCD($AE,false); // display off
WriteLCD($D5,false); // set osc division
WriteLCD($80,false); //
WriteLCD($A8,false); // multiplex ratio
WriteLCD($3F,false); // duty=1/32
WriteLCD($D3,false); // set vertical shift by COM
WriteLCD($00,false); //
WriteLCD($8D,false); // set charge pump enable
WriteLCD($14,false); // $10=disable
WriteLCD($20,false); // set memory addressing mode
WriteLCD($02,false); // page addressing mode $02
WriteLCD($C8,false); // COM scan direction/vertical mirror
WriteLCD($DA,false); // set COM pins
WriteLCD($12,false); //
WriteLCD($81,false); // contrast control
WriteLCD($A0,false); // 0-255
WriteLCD($21,false); // set column address
WriteLCD($00,false); // start
WriteLCD($7F,false); // end
WriteLCD($22,false); // set address of display data RAM
WriteLCD($00,false); // start
WriteLCD($7F,false); // end
WriteLCD($40,false); // set display start line
WriteLCD($00,false); // set lower column address
WriteLCD($10,false); // set higher column address
WriteLCD($B0,false); // set page address
WriteLCD($A1,false); // set segment remap/horizontal mirror
WriteLCD($A6,false); // normal/$A7=inverse
WriteLCD($D9,false); // set pre-charge period
WriteLCD($1F,false); //
WriteLCD($DB,false); // set vcomh
WriteLCD($20,false); //
WriteLCD($AF,false); // display on
mDelay(50);
End GraphInit;
{$D-}
UserDevice GraphIOS(Cmd: Byte; Arg: Byte);
Begin
If cmd = 0
then
WriteLCD($02,false); // Column 0 --> RAM $02
WriteLCD($10,false);
WriteLCD($B0+Arg,false);
else
WriteLCD(Arg,true);
EndIf;
End GraphIOS;
{$D+}
Procedure SetContrast(co:Byte);
Begin
WriteLCD($81,false); // contrast control
WriteLCD(co,false); // 0-255
End SetContrast;
Procedure SetInverse(inv:Boolean);
Begin
If inv=true
then
WriteLCD($A7,false); // inverse
else
WriteLCD($A6,false); // normal
EndIf;
End SetInverse;
Procedure MirrorH(mir:Boolean); // mirror horizontal
Begin
If mir=true
then
WriteLCD($A0,false); // mirrored
else
WriteLCD($A1,false); // normal
EndIf;
End MirrorH;
Procedure MirrorV(mir:Boolean); // mirror vertical
Begin
If mir=true
then
WriteLCD($C0,false); // mirrored
else
WriteLCD($C8,false); // normal
EndIf;
End MirrorV;
{--- Display-Funktionen Ende --------------------------------------------------}
{--- Startsequenz/Initalisierungen Start --------------------------------------}
Procedure InitPorts; // Ports konfigurieren
Begin // DDRx: 0=Eingang / 1=Ausgang
DDRA:= %00000000; // Trimmer2: 1 2 3 4 Trimmer2: 1 2 3 4
DDRB:= %00000000; // nc nc nc nc Sw1: 1 2 3 4
PortB:=%00000000; // xxx xxx xxx xxx Sw1: 1 2 3 4
DDRC:= %00000000; // FT; Ö S ES2: 2 1 ES1: 2 1 | SCL SDA
DDRD:= %00001111; // Sw2: 4 3 2 1 SMEn2 SMClk SMEn1 SMDir
PortD:=%00000000; //
End InitPorts;
Procedure Start;
Begin
MirrorH(false);
MirrorV(false);
SetInverse(false);
SetContrast($40);
gClrScr(0);
gSetTextMode(wmSetPix);
gSetTextBkGnd(bkTransp);
gSetTextJustify(alHorCenter, alVertTop);
gDispRefresh;
gDrawString(32,-2,2,2,TxtRot0,'SMS');
gDrawString(32,14,2,1,TxtRot0,'V1.0');
gDrawString(22,55,1,1,TxtRot0,'(C)2021');
gDrawString(47,27,3,3,TxtRot0,'C');
gDrawString(53,41,3,3,TxtRot0,'H');
gDispRefresh;
mDelay(5000);
gSetTextBkGnd(bkNormal);
gSetTextJustify(alHorLeft, alVertTop);
gClrScr(0);
gDispRefresh;
End Start;
{--- Startsequenz/Initalisierungen Ende ---------------------------------------}
//UserDevice StepperIOS(cw:boolean);
// Begin
// End StepperIOS;
Procedure ShowPreSet;
Var Counter : Byte;
Begin
gDrawString(106,-2,1,1,TxtRot0,'ADC');
For Counter:=0 to 7 do
PreSet[Counter]:=Integer(GetADCA(7-Counter)) SHR 2;
chDraw5x5(105,(Integer(Counter)*7)+10,TxtRot0,IntToStr(PreSet[Counter]:4:'0'));
EndFor;
End ShowPreSet;
Procedure ShowDIPS;
Var Counter : Byte;
Begin
gDrawString(90,-2,1,1,TxtRot0,'Sw');
For Counter:=0 to 7 do
If Counter in [0..3]
then
DIPS[Counter]:=not Bit(PinB,3-Counter);
else
DIPS[Counter]:=not Bit(PinD,Counter);
EndIf;
If DIPS[Counter]=true
then
chDraw5x5(95,(Integer(Counter)*7)+10,TxtRot0,'1');
else
chDraw5x5(95,(Integer(Counter)*7)+10,TxtRot0,'0');
EndIf;
EndFor;
End ShowDIPS;
Procedure ShowSwitch;
Var Counter : Byte;
Begin
gDrawString(-2,-2,1,1,TxtRot0,'PE');
Switch[0]:=Inp_Raise_G(ES11);
Switch[1]:=Inp_Raise_G(ES12);
Switch[2]:=Inp_Raise_G(ES21);
Switch[3]:=Inp_Raise_G(ES22);
Switch[4]:=Inp_Raise_G(FT1);
Switch[5]:=Inp_Raise_G(FT2);
SwitchPort_G_Clear;
For Counter:=0 to 5 do
If Switch[Counter]=true
then
Case Counter of
0..1:chDraw5x5(2,(Integer(Counter)*7)+10,TxtRot0,'1');|
2..3:chDraw5x5(2,(Integer(Counter+5)*7)+10,TxtRot0,'1');|
4..5:chDraw5x5(2,(Integer(Counter-1)*7)+10,TxtRot0,'1');|
EndCase;
else
Case Counter of
0..1:chDraw5x5(2,(Integer(Counter)*7)+10,TxtRot0,'0');|
2..3:chDraw5x5(2,(Integer(Counter+4)*7)+10,TxtRot0,'0');|
4..5:chDraw5x5(2,(Integer(Counter-1)*7)+10,TxtRot0,'0');|
EndCase;
EndIf;
EndFor;
End ShowSwitch;
Procedure ShowText;
Var Counter : Byte;
Begin
For Counter:=0 to 7 do
chDraw3x5(48,(Integer(Counter)*7)+10,TxtRot0,EText[Counter]);
chDraw3x5(62,(Integer(Counter)*7)+10,TxtRot0,TText[Counter]);
EndFor;
End ShowText;
{------------------------------------------------------------------------------}
{ Main Program }
{$IDATA}
Begin
EnableInts($87);
GraphInit;
Start;
Loop
ShowPreSet;
ShowDIPS;
ShowSwitch;
ShowText;
gDispRefresh;
mDelay(200);
Endloop;
End SMS.
Das ist so übrigens nicht compilierbar, weil UserDevice SteppIOS fehlt. Das dürfte aber bei definiertem Clock-/Dir-Port nicht sein und bei alten Projekten mit Mega644 geht es auch.