SED1520
This library supports a 122 x 32 GLCD with the SED1520 controller. The GLCD is a monochrome display and is commonly available. The library is intended for use with the standard Swordfish GLCD library (GLCD.bas). This will allow use of proportional fonts, bitmap images and vector graphics.
The library is included below. Use with the GLCD library requires an addition to the GLCD library itself. However, this has already been done for you. You do not need to add the module code shown below to the user library folder. Just do one of the following:
- For licenced users, run the on-line update facility.
- For SE users, download the latest release (version 1.2.0.8 and above - Library Revision B).
This will update the GLCD library and add the new SED1520 library.
Note that the library assumes that the RST pin of the display is left disconnected. In addition, the CS1 and CS2 pins are sometimes labelled E1 and E2 and the RS pin is labelled A0.
Below are two images of the display in use - the first shows the use of Rectangle() and proportional fonts, the second also shows the use of bitmap images with SetImage() for the buttons.
It is a useful exercise to compare this libary to the standard Swordfish KS0108 driver library - this shows how easy it is to adapt an existing library for use with a new controller. The development of this driver did not take more than around five hours.
SED1520 Graphics Driver
Sample Code
Device = 18F452 Clock = 20 #option GLCD_MODEL = SED1520 Include "Graphics.bas" Include "GLCD.bas" Include "Tahoma.bas" Include "Bitmaps.bas" SetFont(Tahoma) Font.Style = fsNormal TextAlign = taCenter Cls WriteStr(60,4,"- SWORDFISH SED1520 -") SetImage(0,19,BtnOK) SetImage(83,19,BtnCancel)
SED1520 Module
{ **************************************************************************** * Name : SED1520.BAS * * Author : S Wright * * Notice : Copyright (c) 2006 S Wright * * : All Rights Reserved * * Date : 03/11/2006 * * Version : 1.0 * * Notes : * * : * **************************************************************************** } Module SED1520 // import the graphics module... #define GLCD_PIXEL_01 #define GLCD_COLOR_01 #define GLCD_XY_08 Include "Graphics.bas" Include "System.bas" // default module options - user options can override these values... #option GLCD_DATA = PORTD // data port #option GLCD_RS = PORTC.0 // RS pin (control or data) #option GLCD_RW = PORTC.1 // RW pin (read or write) #option GLCD_CS1 = PORTC.2 // chip select #option GLCD_CS2 = PORTC.3 // chip select #option GLCD_ASPECT_RATIO = 110 // aspect ratio, smaller number will squeeze y for GLCD circles and box #option GLCD_INIT_DELAY = 100 // initialisation delay (ms) // validate data port... #if IsOption(GLCD_DATA) #if Not IsValidPort(GLCD_DATA) #error GLCD_DATA, "Invalid option. DATA must be a valid port name." #endif #ifdef GLCD_DATA@ Then #error GLCD_DATA@, "Invalid option. DATA port cannot be a single bit value." #endif #endif // validate RS pin... #if IsOption(GLCD_RS) And Not IsValidPortPin(GLCD_RS) #error GLCD_RS, "Invalid option. RS must be a valid port pin." #endif // validate RW pin... #if IsOption(GLCD_RW) And Not IsValidPortPin(GLCD_RW) #error GLCD_RW, "Invalid option. RW must be a valid port pin." #endif // validate CS1 pin... #if IsOption(GLCD_CS1) And Not IsValidPortPin(GLCD_CS1) #error GLCD_CS1, "Invalid option. CS1 must be a valid port pin." #endif // validate CS2 pin... #if IsOption(GLCD_CS2) And Not IsValidPortPin(GLCD_CS2) #error GLCD_CS2, "Invalid option. CS2 must be a valid port pin." #endif // validate initialisation delay... #if IsOption(GLCD_INIT_DELAY) #if Not (GLCD_INIT_DELAY in (0 to 1000)) #error GLCD_INIT_DELAY, "Invalid option. GLCD initialize delay must be between 0 and 1000 (ms)." #endif #endif // now create Data TRIS... #option _GLCD_DATA_TRIS = GetTRIS(GLCD_DATA) // GLCD width and height... Public Const GLCDWidth = 122, GLCDHeight = 32 // x, y position... Public Dim Pos As TPosition // left or right controller Dim Side As Byte // SED1520 commands... Const cmdOn = $AF, // turn on display cmdOff = $AE, // turn off display cmdStaticOff = $A4, // turn static drive off cmdDutyCycle = $A9, // set duty cycle to 1/32 cmdReset = $E2, // reset display cmdSetADC = $A0, // set ADC cmdRMWDisable = $EE, // disable read-modify-write cmdRMWEnable = $E0, // enable read-modify-write cmdDisplayStartLine = $C0, cmdPage = $B8, cmdColumn = $00, GLCDDelay = GLCD_INIT_DELAY // port and pin settings, these are brought into // the program by using the above options... Dim Data As GLCD_DATA, // data in (PORT) TRISData As _GLCD_DATA_TRIS, // data TRIS RS As GLCD_RS.GLCD_RS@, // RS pin (control or data) RW As GLCD_RW.GLCD_RW@, // RW pin (read or write) CS1 As GLCD_CS1.GLCD_CS1@, // chip1 select CS2 As GLCD_CS2.GLCD_CS2@ // chip2 select { **************************************************************************** * Name : GLCDData (PRIVATE) * * Purpose : Switch to GLCD data mode * **************************************************************************** } Inline Sub GLCDData() RS = 1 End Sub { **************************************************************************** * Name : GLCDInst (PRIVATE) * * Purpose : Switch to GLCD instruction mode * **************************************************************************** } Inline Sub GLCDInst() RS = 0 End Sub { **************************************************************************** * Name : GLCDRead (PRIVATE) * * Purpose : Set GLCD to read mode * **************************************************************************** } Inline Sub GLCDRead() RW = 1 End Sub { **************************************************************************** * Name : GLCDWrite (PRIVATE) * * Purpose : Set GLCD to write mode * **************************************************************************** } Inline Sub GLCDWrite() RW = 0 End Sub { **************************************************************************** * Name : WaitForIdle (PRIVATE) * * Purpose : Block further GLCD access until signalled ready. * **************************************************************************** } Sub WaitForIdle() Dim Timeout As Byte CS1 = Side.Bits(0) // CS high for left or ... CS2 = Side.Bits(1) // right sides (or both) Timeout = $FF GLCDInst // instruction data GLCDRead // read mode TRISData = $FF // set data bus to input Repeat ClrWDT Dec(Timeout) Until (Data.7 = 0) Or (Timeout = 0) CS1 = 0 CS2 = 0 End Sub { **************************************************************************** * Name : SetData (PRIVATE) * * Purpose : Write a data byte to GLCD * * : pSide: %01 = Left, %10 = Right, %11 = Both * **************************************************************************** } Sub SetData(pData As Byte) WaitForIdle // block until not busy GLCDData // access display RAM data GLCDWrite // write mode CS1 = Side.Bits(0) // CS high for left or ... CS2 = Side.Bits(1) // right sides (or both) TRISData = $00 // set data bus to output Data = pData // write to the bus DelayUS(2) CS1 = 0 // latch data to GLCD CS2 = 0 DelayUS(2) End Sub { **************************************************************************** * Name : Command (PRIVATE) * * Purpose : Write a command byte to GLCD * * : pSide: %01 = Left, %10 = Right, %11 = Both * **************************************************************************** } Sub Command(pCommand As Byte) WaitForIdle // block until not busy GLCDInst // instruction mode GLCDWrite // write mode CS1 = Side.Bits(0) // CS high for left or ... CS2 = Side.Bits(1) // right sides (or both) TRISData = $00 // set data bus to output Data = pCommand // write to the bus DelayUS(2) CS1 = 0 // latch data to GLCD CS2 = 0 DelayUS(2) End Sub { **************************************************************************** * Name : GetData (PRIVATE) * * Purpose : Read byte from GLCD * * : pSide: %01 = Left, %10 = Right, %11 = Both * **************************************************************************** } Function GetData() As Byte Command(cmdRMWEnable) WaitForIdle // block until not busy CS1 = Side.Bits(0) // CS high for left or ... CS2 = Side.Bits(1) // right sides (or both) GLCDData // access display RAM data GLCDRead // read mode CS1 = 0 CS2 = 0 DelayUS(2) TRISData = $FF // set data bus to input CS1 = Side.Bits(0) // CS high for left or ... CS2 = Side.Bits(1) // right sides (or both) DelayUS(2) Result = Data // get the data CS1 = 0 CS2 = 0 DelayUS(2) Command(cmdRMWDisable) End Function { **************************************************************************** * Name : SetPosition (PRIVATE) * * Purpose : Set GLCD x and y positions * **************************************************************************** } Sub SetPosition() Dim xPos As Byte If Pos.x < 61 Then // find x position for left or right controller xPos = Pos.x Side = %01 Else xPos = Pos.x - 61 Side = %10 EndIf Command(cmdColumn Or xPos) // set x position Command(cmdPage Or Pos.y) // set y position End Sub { **************************************************************************** * Name : WriteByte * * Purpose : Write a byte at x, page * **************************************************************************** } Public Sub WriteByte(pValue As Byte) SetPosition SetData(pValue) End Sub { **************************************************************************** * Name : ReadByte * * Purpose : Read a byte at x, page * **************************************************************************** } Public Function ReadByte() As Byte SetPosition GetData Result = GetData End Function { **************************************************************************** * Name : SetPixel * * Purpose : Set pixel at pixel location x,y * **************************************************************************** } Public Sub SetPixel(pX, pY As Byte) Dim YBit As Byte Dim Pixel As Byte If (pX < GLCDWidth) And (pY < GLCDHeight) Then YBit = 1 << (pY Mod 8) Pos.y = pY / 8 Pos.x = pX SetPosition GetData Pixel = GetData // pen is white... If Pen.Color = 0 Then If Pen.Mode = pmCopy Then YBit = Not YBit Pixel = Pixel And YBit EndIf // pen is black... Else // pen copy or merge... If Pen.Mode <> pmXOR Then Pixel = Pixel Or YBit // pen XOR Else If (Pixel And YBit) = 0 Then Pixel = Pixel Or yBit Else yBit = Not yBit Pixel = Pixel And YBit EndIf EndIf EndIf SetPosition SetData(Pixel) EndIf End Sub { **************************************************************************** * Name : GetPixel * * Purpose : Return pixel colour at pixel position x, y * **************************************************************************** } Public Function GetPixel(pX, pY As Byte) As TColor Dim Pixel As Byte Pos.y = pY / 8 Pos.x = pX SetPosition GetData Pixel = GetData >> (pY Mod 8) Result = Pixel.0 End Function { **************************************************************************** * Name : Cls * * Purpose : Clear the GLCD screen * **************************************************************************** } Public Sub Cls() Dim x, y As Byte Side = %11 Command(cmdOff) y = 0 Repeat Command(cmdPage Or y) x = 0 Repeat Command(cmdColumn Or x) SetData($00) Inc(x) Until x > 60 Inc(y) Until y > 3 Command(cmdOn) End Sub { **************************************************************************** * Name : Initialize * * Purpose : Configure the GLCD before use * **************************************************************************** } Sub Initialize() Pos.x = 0 Pos.y = 0 DelayMS(GLCDDelay) // start up delay, allow GLCD to settle Output(RS) Output(RW) Output(CS1) // screen (1) Output(CS2) // screen (2) Side = %01 Repeat Command(cmdOn) Command(cmdStaticOff) Command(cmdDutyCycle) Command(cmdReset) Command(cmdSetADC) Command(cmdRMWDisable) Command(cmdDisplayStartLine) // set start position to top-left Command(cmdPage) Command(cmdColumn) Inc(Side) Until Side > %10 CS1 = 0 CS2 = 0 End Sub // configure the module Initialize