XMEGA LCD-Grafik-Display mit UC1698 Controller

pvs-deck
PowerUser
Avatar
Gender:
Age: 53
Homepage: pvs-deck.de
Posts: 1341
Registered: 02 / 2009
Subject:

XMEGA LCD-Grafik-Display mit UC1698 Controller

 · 
Posted: 07.02.2018 - 00:26  ·  #1
Anbei eine Anpassung und Demo für einen UC1698 Grafik-LCD-Controller.

Code
program XMEGA_UC1698;
//
//   XMEGA und LCD-Grafik-Display 256 x 64 Punkte
//
//   RGB Grafik-Controller UC1698 über SPI an XMEGA
//
//   DEMO 7 Schnittstellencode für E-LAB / AVRco
//   User frei zu verwenden.
//
//   info(at)pvs-deck.de
//
//   Stand:  06.02.2018
//

{$NOSHADOW}
{ $WG}                     {global Warnings off}

Device = xmega256A3U, VCC = 3.3;
//Device = xmega128A1U, VCC = 3.3;

Define_Fuses
  Override_Fuses;
  NoteBook               = D;
  COMport                = USB;
  LockBits0              = [];
  FuseBits0              = [];
  FuseBits1              = [ WDPER0, WDPER3 ];   // Watchdog   0:3 / 0110 512CLK 0.512s

// 0=WDPER0
// 1=WDPER1
// 2=WDPER2
// 3=WDPER3

  FuseBits2              = [];                         // mandatory !!
  // Brown-out is obligatory with USB !!!
//  FuseBits5              = [BODACT0, BodLevel0, BodLevel1, BodLevel2];
  FuseBits5              = [BodLevel0,BodLevel2, BodAct0]; //  2.6V:

  ProgFlash = true; // or false – program Flash
  ProgEEprom= FALSE; // or false – program EEprom
  AutoRelease    = true; // or false – Release Target    // Wichtig für Programmierung über UPP !!

Import SysTick, SerPortD1, LCDGraphic, SPI_E;

//From System Import CharSet;
from LCDGraphic import CharSet;     {block CharSet, pixels}

Define
// XMega USB must use the internal 32MHz OSC. So the system must use the 2MHz OSC
//  OSCtype                = int2MHz, PLLmul = 16, prescB = 1, prescC = 1;
OSCtype                = int2MHz, PLLmul = 8, prescB = 1, prescC = 1;
//OSCtype = int32MHz, PLLmul=5, prescB=1, prescC=1, overdrive; // 40MHz
//  OSCtype = int32MHz, PLLmul=6, prescB=1, prescC=1, overdrive; // 48MHz
//OSCtype = int32MHz, PLLmul=7, prescB=1, prescC=1, overdrive; // 56MHz
//OSCtype = int32MHz, PLLmul=8, prescB=1, prescC=1, overdrive; //64MHz
  SysTick                = 10;                 // msec
  StackSize              = $0512, iData;
  FrameSize              = $0512, iData;
// SerPort D1
  SerPortD1 = 19200, Databit8,parNone, Stop1; {9600 Baud, 1Stopbit}
  RxBufferD1     = 100, iData;
  TxBufferD1     = 100, iData;

// LCD-Display-Daten
  LCDGraphic     = 256,64, 8;               { x-pix, y-pix, accesswidth        }
  LCDgraphMode   = readonly, iData;

// LCDgraphMode   = column, iData;
  DefCharSet     = 'Graphchars.pchr';
  GViewports     = 1, iData;                { logical ViewPorts, scalings      }
  TGraphStr      = 24;

// SPI_E
  SPIorderE        = MSB;
  SPImodeE         = 0; // Clock Phase and Polarity
  SPIprescE        = 0; // presc = 0..3 -> 4/16/64/128. Double speed optional
  SPI_SSE          = PortE, 4; // use this pin as SS chipselect


Implementation

{$IDATA}

{--------------------------------------------------------------}
{ Type Declarations }

 {--------------------------------------------------------------}
{ Const Declarations }
  // definitions for bitmap types
CONST
  elabbmp         : Array[1..(32*32 div 8)+2] of Byte = 'e-lab.pbmp';

{--------------------------------------------------------------}
{ Var Declarations }
{$IDATA}
var
  SerTimer      : SysTimer;
  WDITimer      : SysTimer;
  bTast0, bTast1,bTast2,bTast3 : boolean;

// IO Onboard
   HxIN_TAST0    [@PINA, 2 ] : bit;
   HxIN_TAST1    [@PINA, 1 ] : bit;
   HxIN_TAST2    [@PINA, 3 ] : bit;
   HxIN_TAST3    [@PINA, 4 ] : bit;
   HxDispData    [@PORTE, 2 ] : bit;

// LCD VARs
   bContrast_level : byte;
{--------------------------------------------------------------}
{ functions }

// Debug / Infoausgabe an Ser-Port
//
procedure DebugOut( OutStr : String[59] );
begin
  Writeln(SerOutD1,OutStr);
end; //Ende Debug Out

//--------------------------------------------------------------
// Daten an LCD/SPI schreiben BYTE
// bei DATA true, Daten-PIN an LCD-Controller setzen
//
Procedure WriteLCD(bData: Byte; DispData: Boolean);
  Begin
    If DispData
      then
        HxDispData:=TRUE; // Daten
      else
        HxDispData:=FALSE; // CMD
      EndIf;
    SPIOutByteE(bData);    // Daten über SPI senden
  End WriteLCD;

//--------------------------------------------------------------
// Daten an LCD/SPI schreiben WORD
// bei DATA true, Daten-PIN an LCD-Controller setzen
//
Procedure wWriteLCD(wData: WORD; DispData: Boolean);
  Begin
    If DispData
      then
        HxDispData:=TRUE; // Daten
      else
        HxDispData:=FALSE; // CMD
      EndIf;
    SPIOutWordE(wData);    // Daten über SPI senden
  End wWriteLCD;
  
//--------------------------------------------------------------
// LCD mit Schwarz füllen / Clear-Black
//
Procedure display_black;
var
ii : integer;
ij : integer;

begin
for ii:= 0 to 63 do // Zeilen
  for ij:= 0 to 128 do  //1byte data or 2 dot  120*2=240dot
    WriteLCD( $FF, true );
  endfor;
endfor;
end display_black;

//--------------------------------------------------------------
// LCD mit Weiss füllen / Clear-White
//
procedure display_white;
var
ii : integer;
ij : integer;

begin
for ii:= 0 to 63 do // Zeilen
  for ij:= 0 to 128 do  //1byte data or 2 dot  120*2=240dot
    WriteLCD( $00, true );
  endfor;
endfor;
end display_white;


//--------------------------------------------------------------
// Setze auf Spalte / Reihe
//
procedure display_address( DispSpalte : byte;  DispZeile : Byte);
var
 LSB : BYTE;
 MSB : BYTE;

begin
// Spalte/Col=0 to 263  Zeile/Row=0 to 63

// Displayspalte / Column address LSB
  LSB:= DispSpalte AND $0F;
   WriteLCD( $00 OR LSB, false );
// Displayspalte / Column address MSB
  MSB:= (DispSpalte AND $F0) SHR 4;
   WriteLCD( $10 OR MSB, false );

// Displayzeile / Row address LSB
  LSB:= DispZeile AND $0F;
   WriteLCD( $60 OR LSB, false );
// Displayzeile / Row address MSB
  MSB:= (DispZeile AND $F0) SHR 4;
   WriteLCD( $70 OR MSB, false );

end display_address;

//--------------------------------------------------------------
// turns 1byte B/W data to Displayformat
//
procedure DispBW2RGB( temp : byte);
var
temp1,temp2,temp3,temp4,temp5,temp6,temp7,temp8 : byte;
h11,h12,h13,h14,h15,h16,h17,h18,d1,d2,d3,d4 : byte;

begin
    temp1:=temp AND $80;
    temp2:=( temp AND $40) SHR 3; // >>3;
    temp3:=( temp AND $20) SHL 2; // <<2;
    temp4:=( temp AND $10) SHR 1; // >>1;
    temp5:=( temp AND $08) SHL 4; // <<4;
    temp6:=( temp AND $04) SHL 1; // <<1;
    temp7:=( temp AND $02) SHL 6; // <<6;
    temp8:=( temp AND $01) SHL 3; // <<3;

    h11:=temp1 OR (temp1 SHR 1) OR (temp1 SHR 2) OR (temp1 SHR 3);
    h12:=temp2 OR (temp2 SHR 1) OR (temp2 SHR 2) OR (temp2 SHR 3);
    h13:=temp3 OR (temp3 SHR 1) OR (temp3 SHR 2) OR (temp3 SHR 3);
    h14:=temp4 OR (temp4 SHR 1) OR (temp4 SHR 2) OR (temp4 SHR 3);
    h15:=temp5 OR (temp5 SHR 1) OR (temp5 SHR 2) OR (temp5 SHR 3);
    h16:=temp6 OR (temp6 SHR 1) OR (temp6 SHR 2) OR (temp6 SHR 3);
    h17:=temp7 OR (temp7 SHR 1) OR (temp7 SHR 2) OR (temp7 SHR 3);
    h18:=temp8 OR (temp8 SHR 1) OR (temp8 SHR 2) OR (temp8 SHR 3);

    d1:= h11 OR h12; d2:= h13 OR h14;
    d3:= h15 OR h16; d4:= h17 OR h18;
              // Schreibe aufbereitete Daten an Display
    WriteLCD(d1,true); WriteLCD(d2,true);
    WriteLCD(d3,true); WriteLCD(d4,true);
end DispBW2RGB;

//--------------------------------------------------------------
// Befehl Funktion für Software Reset Controller
// ACHTUNG Display-RAM wird nicht gelöscht, aber
// der Controller wird auf Grundeinstellungen gesetzt.
//
procedure LCDReset;
begin
  WriteLCD( $E2, false);
end LCDReset;


//--------------------------------------------------------------
// Display-Init
//
Procedure LCDInit;
  Begin
    MDelay(200);
    LCDReset;
    MDelay(100);
   //*power control*/
  WriteLCD($e9,false);      //Bias Ratio:1/10 bias
  WriteLCD($2b,false);      //power control set as internal power
  WriteLCD($24,false);      //set temperate compensation as 0%
  WriteLCD($81,false);      //electronic potentionmeter
        bContrast_level:= 0;
  WriteLCD(bContrast_level,false);

  //*display control*/
  WriteLCD($a4,false);      //all pixel off
  WriteLCD($a6,false);      //inverse display off

  //*lcd control*/
  WriteLCD($c4,false);      //Set LCD Maping Control (MY=1, MX=0)
  WriteLCD($a1,false);      //line rate
  WriteLCD($d1,false);      //rgb-rgb
  WriteLCD($d5,false);      //4k color mode
  WriteLCD($84,false);      //12:partial display control disable

  //*n-line inversion*/
  WriteLCD($c8,false);
  WriteLCD($10,false);      //enable NIV

  //*com scan fuction*/
  WriteLCD($da,false);      //enable FRC,PWM,LRM sequence

  //*window*/
  WriteLCD($f4,false);      //wpc0:column
  WriteLCD(0,false);          //start from 0
  WriteLCD($f6,false);      //wpc1
  WriteLCD(85,false);          //end:3*86=258

  WriteLCD($f5,false);      //wpp0:row
  WriteLCD($00,false);      //start from 0
  WriteLCD($f7,false);      //wpp1
  WriteLCD(63,false);          //end 128

  WriteLCD($f8,false);      //inside mode

  WriteLCD($89,false);      //RAM control

  //*scroll line*/
  WriteLCD($40,false);      //low bit of scroll line
  WriteLCD($50,false);      //high bit of scroll line

  WriteLCD($90,false);      //14:FLT,FLB set
  WriteLCD($00,false);

  //*partial display*/
  WriteLCD($85,false);      //12,set partial display control:on
  WriteLCD($f1,false);      //com end
  WriteLCD(63,false);          //64
  WriteLCD($f2,false);      //display start
  WriteLCD(0,false);        //0
  WriteLCD($f3,false);      //display end
  WriteLCD(63,false);          //64

   display_address(0,0);
        display_white;

  WriteLCD($ad,false);      //display on,select on/off mode.Green Enhance mode disable

        MDelay(200);
  End LCDInit;

//--------------------------------------------------------------
// GraphIOS
// Anpassung an das AVRco GraphSystem
//
UserDevice GraphIOS (cmd : byte; data : byte);
begin
// commands passed to user defined function "GraphIOS"
// cmd 0 set row address data = row
// cmd 1 write data byte data = content
 if cmd = 0 then
   display_address( 0, data);  // set row addr = data
 else
   DispBW2RGB( data );  // Bereite Daten auf und schreibe Daten an LCD
 endif;
end GraphIOS;


//--------------------------------------------------------------
// INIT Werte IOs
//
procedure InitPorts;
begin
//  PIN0CTRLA := %01011000; // pullup und INVERT
  PIN2CTRLA := %01011000; // pullup und INVERT
  DDRA.2:= 0;  // 0=EINGANG  1=Ausgang
//  PIN1CTRLA := %01011000; // pullup und INVERT
  PIN1CTRLA := %01011000; // pullup und INVERT
  DDRA.1:= 0;  // 0=EINGANG  1=Ausgang
//  PIN0CTRLA := %01011000; // pullup und INVERT
  PIN3CTRLA := %01011000; // pullup und INVERT
  DDRA.3:= 0;  // 0=EINGANG  1=Ausgang
//  PIN0CTRLA := %01011000; // pullup und INVERT
  PIN4CTRLA := %01011000; // pullup und INVERT
  DDRA.4:= 0;  // 0=EINGANG  1=Ausgang
//HxDispData
  DDRE.2:= 1;  // 0=EINGANG  1=Ausgang

end InitPorts;

//--------------------------------------------------------------
// Demoausgabe an das Display
//
Procedure Start;
  Begin
  display_address(0,0);
    gSetTextJustify(alHorLeft, alVertTop);
    gSetTextMode(wmSetPix);
    gSetTextBkGnd(bkTransp);
    gSetCharSetRam(false);
    gSetLineMode(wmXorPix);
    gDrawRect(0,0,254,63,$FF);
    gDrawString(3,3,2,2,TxtRot0,'0123456789');
    gDrawString(2,21,3,3,TxtRot0,'C');
    gDrawString(8,35,3,3,TxtRot0,'H');
    gDrawString(180,50,1,1,TxtRot0,'256x64 Pixel');
    gDrawString(45,27,1,1,TxtRot0,'Contr:UC1698');
    gDrawString(170,32,1,1,TxtRot0,'Rot0');
    gDrawString(170,32,1,1,TxtRot90,'Rot90');
    gDrawString(170,25,1,1,TxtRot180,'Rot180');
    gDrawString(170,25,1,1,TxtRot270,'Rot270');
    gDrawBitMap(212,2,@ELABbmp,wmSetPix);
    gFillRect(35,45,100,60,$FF);
    gDrawRect(55,40,120,55,$FF);
    gDrawCircle(140,38,13,$FF);
    gFillCircle(135,50,10,$FF);
    gSetTextBkGnd(bkNormal);
    gDispRefresh;
  End Start;

{--------------------------------------------------------------}
{ Main Program }
{$IDATA}

begin

InitPorts;
 EnableInts($87);
  LCDInit;
   MDelay(100);
    Start;

 DebugOut( 'System gestartet....');
  loop


// Taste 0
//
   if (HxIN_TAST0 AND not bTast0)then
    DebugOut('Taste 0: LCDInit;');
     bTast0:= true;
      LCDInit;
   endif;
   if (not HxIN_TAST0 AND bTast0)then
     bTast0:= false;
   endif;


// Taste 1
//
   if (HxIN_TAST1 AND not bTast1)then
    DebugOut('Taste 1: Start;');
      bTast1:= true;
       Start;
   endif;
   if (not HxIN_TAST1 AND bTast1)then
     bTast1:= false;
   endif;


// Taste 2
//
   if (HxIN_TAST2 AND not bTast2)then
   // DebugOut('Taste 2: gDrawLine');
      bTast2:= true;
       display_white;
   endif;
   if (not HxIN_TAST2 AND bTast2)then
     bTast2:= false;
   endif;


// Taste 3
//
   if (HxIN_TAST3 AND not bTast3)then
    DebugOut('Taste 3: ');
      bTast3:= true;
       LCDReset;
   endif;
   if (not HxIN_TAST3 AND bTast3)then
     bTast3:= false;
   endif;


 endloop;

end XMEGA_UC1698.
You must be logged in or your permissions are to low to see this Attachment(s).
Harry
Moderator
Avatar
Gender:
Location: zwischen Augsburg und Ulm
Age: 59
Posts: 2134
Registered: 03 / 2003
Subject:

Re: XMEGA LCD-Grafik-Display mit UC1698 Controller

 · 
Posted: 07.02.2018 - 07:21  ·  #2
Hi Thorsten,

sehr schön - danke. Hast du mal die Refresh-Zeit gemessen?

Gruss
Harry

PS: Wieso steht da CH? Müsste das nicht TD heißen ;) ?
pvs-deck
PowerUser
Avatar
Gender:
Age: 53
Homepage: pvs-deck.de
Posts: 1341
Registered: 02 / 2009
Subject:

Re: XMEGA LCD-Grafik-Display mit UC1698 Controller

 · 
Posted: 07.02.2018 - 09:09  ·  #3
Quote by Harry

PS: Wieso steht da CH? Müsste das nicht TD heißen ;) ?


Weil ich einfach die "Procedure Start();" von einem Deiner Display-Codes hier im Software-Forum genommen habe. Also ist es doch nur gerecht das ich das "CH" drinnen gelassen habe ;-) . Außerdem fand ich es ganz gut, da man da grob und schnell die wichtigsten Funktionen auf dem Display sieht ;-)

Thorsten

PS: Abgesehen davon hast Du mir auch viele Infos und Tipps zu der Umsetzung gegeben.
Harry
Moderator
Avatar
Gender:
Location: zwischen Augsburg und Ulm
Age: 59
Posts: 2134
Registered: 03 / 2003
Subject:

Re: XMEGA LCD-Grafik-Display mit UC1698 Controller

 · 
Posted: 07.02.2018 - 16:10  ·  #4
Hi Thorsten,

sorry wenn ich mich jetzt nochmal einmische, aber das könnte einfacher sein:
Code
Procedure DispBW2RGB(temp:Byte);
  Var d1,d2,d3,d4:Byte;
  Begin
    If Bit(temp,7) then d1:=%11111000; else d1:=0; EndIf;
    If Bit(temp,6) then d1:=d1 or %00000111; d2:=%11100000; else d2:=0; EndIf;
    If Bit(temp,5) then d2:=d2 or %00011111; EndIf;
  // das waren jetzt 3 Pixel=2 Byte
    .....
    WriteLCD(d1,true); WriteLCD(d2,true); 
    WriteLCD(d3,true); WriteLCD(d4,true); 
  End DispBW2RGB;

Was ich noch nicht so ganz verstanden habe: 2 Byte RGB sind 3 Pixel SW? Wenn ja, was ist dann mit dem übrigen 9. Pixel?

Gruss
Harry

.... vergessen: d1...4 müssen vorher auf 0 gesetzt werden evtl. bei der ersten Verwendung in der Proc im "else". Habs oben korrigiert.
pvs-deck
PowerUser
Avatar
Gender:
Age: 53
Homepage: pvs-deck.de
Posts: 1341
Registered: 02 / 2009
Subject:

Re: XMEGA LCD-Grafik-Display mit UC1698 Controller

 · 
Posted: 07.02.2018 - 19:36  ·  #5
Quote by Harry

Hi Thorsten,

sorry wenn ich mich jetzt nochmal einmische, aber das könnte einfacher sein:
Code
Procedure DispBW2RGB(temp:Byte);
  Var d1,d2,d3,d4:Byte;
  Begin
    If Bit(temp,7) then d1:=%11111000; else d1:=0; EndIf;
    If Bit(temp,6) then d1:=d1 or %00000111; d2:=%11100000; else d2:=0; EndIf;
    If Bit(temp,5) then d2:=d2 or %00011111; EndIf;
  // das waren jetzt 3 Pixel=2 Byte
    .....
    WriteLCD(d1,true); WriteLCD(d2,true); 
    WriteLCD(d3,true); WriteLCD(d4,true); 
  End DispBW2RGB;

Was ich noch nicht so ganz verstanden habe: 2 Byte RGB sind 3 Pixel SW? Wenn ja, was ist dann mit dem übrigen 9. Pixel?

Gruss
Harry

.... vergessen: d1...4 müssen vorher auf 0 gesetzt werden evtl. bei der ersten Verwendung in der Proc im "else". Habs oben korrigiert.

Hallo Harry,

1 Pixel sind 4 bit zum Controller, wenn ich den auf 4k Color umgeschaltet habe. War in der Anleitung etwas blöd geschrieben. Die Angabe mit dem 12 bzw. 16 BIT RGB-Werten, zeigt im Datenblatt nur die Verbindung zwischen LCD-Controller und dem LCD-Display. Das hat nichts mit der MCU zu tun. Die genaue Angabe fehlt hier im Datenblatt.

Ich habe absichtlich das ganze mit dem BIT-AND / -OR, SHL, SHR gemacht. Ich habe mal gelernt, das diese deutlich schneller abgearbeitet werden als IF / Bedingte-Abzweige.

Gruß
Thorsten
Selected quotes for multi-quoting:   0

Registered users in this topic

Currently no registered users in this section

The statistic shows who was online during the last 5 minutes. Updated every 90 seconds.
MySQL Queries: 14 · Cache Hits: 14   94   108 · Page-Gen-Time: 0.021593s · Memory Usage: 2 MB · GZIP: on · Viewport: SMXL-HiDPI