|
|
|
|
'**************************************************************** '* Name : CF320240.BAS * '* Author : Jack Smith * '* Notice : Copyright (c) 2006 Jack R. Smith * '* : All Rights Reserved * '* Date : 1/31/2006 * '* Version : 1.0 * '* Notes : Started 31 Jan 2006 * '* : * '**************************************************************** // // LCD INFORMATION & CONNECTION // ---------------------------- // Library assumes a CrystalFontz 320x240 graphic LCD is connected to the PIC. // CFAG320240C Series LCD. Factory-shipped with jumper JM in 6800 compatibility mode. This is OK //Connections are: // LCD Pin Fcn PIC Pin LCD Pin Fcn PIC Pin // 1 GND -- 11 DB4 PortD.4 // 2 +5V -- 12 DB5 PortD.5 // 3 Vo -- 13 DB6 PortD.6 // 4 E PortE.0 14 DB7 PortD.7 // 5 R/W PortE.1 15 CS PortA.5 // 6 A0 PortE.2 16 RES PortA.1 // 7 DB0 PortD.0 17 Vee -- // 8 DB1 PortD.1 18 Frame -- [to ground] // 9 DB2 PortD.2 19 unused -- // 10 DB3 PortD.3 20 unused -- // // LCD Pin 3 to wiper of 20k POT. One end off pot to +5V, other end to Vee (pin 17) // Pot adjusts contrast. Vee outputs ~ -20V from on-board power inverter // // Program demonstrates how to initialize the LCD and display text and graphics // with display screen for panadapter display.
'-------------- Module CF320240 '-------------- Include "string.bas"Include "usart.bas"Include "globalconst.bas"Include "utils.bas"Include "math.bas"Public Const GLCD_Width = 320, //dimensions of LCD display GLCD_Height = 240,GLCD_CharWidth = 8, //built-in character generator dimensions GLCD_CharHeight = 8, //ditto GLCD_TextAdr = $0000, //text memory GLCD_GrAdr = GLCD_Width * GLCD_Height / 64,GLCD_GrAdrEnd = GLCD_GrAdr + (GLCD_Width * GLCD_Height), GLCD_CR = GLCD_Width / 8 - 1, GLCD_CMD_SYSTEM = $40, // General system settings GLCD_CMD_SLEEP = $53, // Enter into standy mode GLCD_CMD_DISP_OFF = $58, // Turn the display off GLCD_CMD_DISP_ON = $59, // Turn the display on GLCD_CMD_SCROLL = $44, // Setup text and graphics address regions GLCD_CMD_CSR_FORM = $5D, // Set cursor size GLCD_CMD_CSRDIR_RIGHT = $4C, // Cursor moves right after write to display memory GLCD_CMD_CSRDIR_LEFT = $4D, // Cursor moves left after write to display memory GLCD_CMD_CSRDIR_UP = $4E, // Cursor moves up after write to display memory GLCD_CMD_CSRDIR_DN = $4F, // Cursor moves down after write to display memory GLCD_CMD_CGRAM_ADDR = $5C, // Configure character generator RAM address GLCD_CMD_HDOT_SCR = $5A, // Set horizontal scroll rate GLCD_CMD_OVERLAY = $5B, // Configure how layers overlay GLCD_CMD_SET_CSR_ADDR = $46, // Set the cursor address GLCD_CMD_GET_CSR_ADDR = $47, // Read the cursor address GLCD_CMD_DISPLAY_WRITE = $42, // Write to display memory GLCD_CMD_DISPLAY_READ = $43, // Read from display memory MemLength = GLCD_Width * GLCD_Height / 8, // memory required for full graphics// = 9600 bytes PageAStart = $0960, // start of memory for Graphics Page A PageAEnd = PageAStart + MemLength - 1,PageBStart = PageAStart + MemLength, 'memory required for full graphics PageBEnd = PageBStart + MemLength -1, 'page B end CheckVal = %10101010, 'for writing to see if have problems CheckAdr = PageBEnd + 256 'with loss of synchronization// error check data port, then set default - user option will override... #if IsOption(CLF_DATA) And Not IsValidPort(CLF_DATA) Or IsOption(CLF_DATA@) #error CLF_DATA, "Invalid option. DATA must be a valid MCU port name."#endif #option CLF_DATA = PORTD// error check data access, then set default - user option will override... #if IsOption(CLF_ACCESS) And Not IsValidPortPin(CLF_ACCESS) #error CLF_ACCESS, "Invalid option. ACCESS must be a valid MCU port pin."#endif #option CLF_ACCESS = PORTE.2// error check RW, then set default - user option will override... #if IsOption(CLF_RW) And Not IsValidPortPin(CLF_RW) #error CLF_RW, "Invalid option. RW must be a valid MCU port pin."#endif #option CLF_RW = PORTE.1// error check ENABLE, then set default - user option will override... #if IsOption(CLF_ENABLE) And Not IsValidPortPin(CLF_ENABLE) #error CLF_ENABLE, "Invalid option. ENABLE must be a valid MCU port pin."#endif #option CLF_ENABLE = PORTE.0// error check CS, then set default - user option will override... #if IsOption(CLF_CS) And Not IsValidPortPin(CLF_CS) #error CLF_CS, "Invalid option. CS must be a valid MCU port pin."#endif #option CLF_CS = PORTA.5// error check RESET, then set default - user option will override... #if IsOption(CLF_RESET) And Not IsValidPortPin(CLF_RESET) #error CLF_RESET, "Invalid option. RESET must be a valid MCU port pin."#endif #option CLF_RESET = PORTA.1// port and pin assignments... Private Dim DatPort As CLF_DATA, // LCD Data bus (DB0..DB7) is connected to PortD A0 As CLF_ACCESS.CLF_ACCESS@, // A0 sets data destination. A0=1 control / A0=0 memory RW As CLF_RW.CLF_RW@, // Read/Write direction. R/W = 0 is write to LCD, R/W=1 read from LCD E As CLF_ENABLE.CLF_ENABLE@, // E=enable in 6800 mode. Serves as a strobe CS As CLF_CS.CLF_CS@, // Chip select -- CS=0 is selected CS=1 is disabled RES As CLF_RESET.CLF_RESET@ // RES = Reset. Normally RES=1 but take it to 0 for initialization'Subroutine Initialize. 'Purpose: Set up ports for I/O and perform RESET on LCD 'Call Initialize before doing anything to the LCD '----------------------- Public Sub Initialize()'----------------------- CMCON = %00000111 // must disable comparators to read with PortD TRISD = $00 //all Ports D & E are output// Must use ADCON1 to set PortA pins to mixed digital/analog 'ADCON1 = %10001111 // A0 is analog input rest of PortA are digitial // V+ref = AN3 for %1111 ADCON1 = %00011110 'for PIC18F4620 ONLY TRISE = $00 // Set all PortE pins for output. Also disable D slave TRISA = %00001001 // Still must set PortA digital pins for Output// Don't forget AN3 must also be an INPUT RES = %1 //RST = HIGH for operation CS = %1 //CS = HIGH - chip is unselected E = %1 //E = High - exact status unimportant at the moment RW = %1 //WR = HIGH - also unimportant at the moment A0 = %0 //A0 = Low - not important now CS = %0 //Chip select is active LOW - set to 0 to enable LCD DelayMS(10)RES = %0 //accomplish reset via low DelayMS(5) //3 ms minimum, so we'll wait a bit longer for safety RES = %1 //take high to end reset and restore function to normal DelayMS(10) //time for reset to take effect RW = %0 //R/w = 0 to permit writing to the LCDEnd Sub // Initialize
'Returns the high byte of pValue. pValue can be a constant '----------------------------------------- Public Function Hi(pValue As Word) As Byte '----------------------------------------- Hi = pValue.Byte1End Function
'Returns the high byte of pValue. pValue can be a constant '----------------------------------------- Public Function Lo(pVaLUE As Word) As Byte '----------------------------------------- Lo = pValue.Byte0End Function
'Subroutine WriteCtrl writes a control byte to the LCD 'Call with the byte to be written. Assumes E is set low upon entry '------------------------------------- Public Sub WriteCtrl(CtrlByte As Byte) '------------------------------------- DatPort = CtrlByte //assert data on bus - give it time to settle ASMNOP NOP End ASM A0 = %1 //SET A0 -- this determines that the data is intrepreted as control by LCD ASMNOP NOP End ASM CS = %0 //CLEAR CS ASMNOP NOP End ASM E = %1 //SET E -- data is read on falling edge of E. ASM // E must be high at least 120ns NOPNOP NOP End ASM E = %0 //CLEAR E -- here's the falling edge ASM // E must be high at least 120ns NOPNOP NOP End ASM CS = %1 //SET CS ASMNOP NOP End ASM End Sub // WriteCtrl
'Subroutine WriteCtrl writes a control byte to the LCD 'Call with the byte to be written. Assumes E is set low upon entry 'Only difference between WriteCtrl and WriteData is value of A0 'Public Inline Sub WriteData(DataByte as Byte) '------------------------------------- Public Sub WriteData(DataByte As Byte) '------------------------------------- ASMNOP NOP End ASM DatPort = DataByte //assert data on bus - give it time to settle ASMNOP NOP End ASM A0 = %0 //CLEAR A0 -- this determines that the data is intrepreted as data by LCD ASMNOP NOP End ASM CS = %0 //CLEAR CS ASMNOP NOP End ASM E = %1 //SET E -- data is read on falling edge of E. ASM // E must be high at least 120ns NOPNOP NOP End ASM E = %0 //CLEAR E -- here's the falling edge ASM // E must be high at least 120ns NOPNOP NOP End ASM CS = %1 //SET CS ASMNOP NOP End ASM End Sub // WriteData
'Function ReadData reads the LCD's databus and returns the byte read. Data 'address is previously set via a set cursor command '--------------------------------- Public Inline Function ReadData() As Byte '--------------------------------- PortD = $00TRISD = $FF // set data port for input ASMNOP NOP End ASM E = %0 ASM NOP NOP End ASM CS = %0 //CLEAR CS to activate chip ASMNOP NOP End ASM RW = %1 // Read from LCD ASMNOP NOP End ASM A0 = %1 ASM NOP NOP End ASM E = %1 Result = PortD // use a read as a delay statement Result = PortDResult = PortD Result = PortD // delay is required to let LCD bus xfer data E = %0ASM NOP NOP End ASM RW = %0 // Restore data bus direction for writing to LCD ASMNOP NOP End ASM A0 = %0 ASM NOP NOP End ASM TRISD = $00 // reset data port for output ASMNOP NOP End ASM PortD = $00 ASM NOP NOP NOP End ASM CS = %1 //SET CS ASMNOP NOP End ASM End Function 'Returns the current Cursor Address '----------------------------------- Public Function GetCursAdr() As Word '----------------------------------- WriteCtrl(GLCD_CMD_GET_CSR_ADDR)Result.Byte0 = ReadData Result.Byte1 = ReadData End Function 'sub CursMem moves the cursor to the memory address MemStart. Remember that the cursor is 'the starting LCD memory address for read/write. The cursor auto increments as defined by 'another parameter setting, cursor direction. 'Call with the starting memory address as a WORD variable 'Public Inline sub CursMem(MemStart as Word) '----------------------------------- Public Sub CursMem(MemStart As Word) 'positions cursor to MemStart'----------------------------------- WriteCtrl(GLCD_CMD_SET_CSR_ADDR) // command - next two bytes are Low/High bytes of memory start WriteData(MemStart.Byte0) // send in sequence LOW BYTE then WriteData(MemStart.Byte1) // the HIGH BYTE{ While MemStart <> GetCursAdr WriteCtrl(GLCD_CMD_SET_CSR_ADDR) // check for correct cursor start adr WriteData(MemStart.Byte0) WriteData(MemStart.Byte1) WEND } End Sub // CursMem
'Subroutine ClearTextMem writes blanks (spaces) into all text memory '------------------------ Public Sub ClearTextMem() '------------------------ Dim m As Word // loop counter to go through text memory CursMem(GLCD_TextAdr) // Position cursor to start of text memory at $0000 WriteCtrl(GLCD_CMD_DISPLAY_WRITE) // Set to write to display memory For m = 1 To (30 * 40) // Text memory corresponds to 30 rows WriteData(" ") // of 40 characters per row using built-in Next 'm // character gen 5 x 7 using 8x8 cells CursMem(GLCD_TextAdr) // good practice to reset cursor to startEnd Sub // subroutine ClearTextMem
'Subroutine ClearGraphicMem clears the graphics memory by writing $00 to the 'memory bytes representing one graphics page, starting at Where. '---------------------------------------- Public Sub ClearGraphicMem(Where As Word) '---------------------------------------- Dim m As Word // loop counter to go through text memory CursMem(Where) // start of graphic memory = .2400 << REV to named constant>> WriteCtrl(GLCD_CMD_DISPLAY_WRITE) // Set to write to display memory// Graphics memory set up similarly to For m = 0 To MemLength-1 // text memory except each row is 1 pixel tall. WriteData($00) // hence one page is 240 pixels tall * 40 bytes wide Next 'm // total memory in Crystalfontz LCD is 32 K so clear// some extra memory while we are at it CursMem(GLCD_TextAdr) // reset cursor to start of text memoryEnd Sub // subroutine ClearGraphicMem
'Subroutine TextOut writes a text string of maximum 'length 30 at coordinates Row,Col. Used to put the status value report up 'If COl > 40, then program auto-centers the text '-------------------------------------------------------- Public Sub TextOut(s As String, Col As Byte, Row As Byte) '-------------------------------------------------------- Dim MemLoc As Word, n As Byte //USART.Write("Into Text Out",13)//USART.Write("Str Len: ",DecToStr(Length(s)),9,"Str: ",s,13) // look for auto-centering value If Col > 39 Then // if Col > 40 then auto-center the string Col = (40 - Length(s))/2EndIf If Row > 29 Then Row = 0 EndIf // text memory starts at $0000. Organized in MemLoc = Row * 40 + Col // continous strip with wraparound.// [0000][0001]...[0039] ROW 0 (top of LCD) CursMem(MemLoc) // [0040][0041] ...[0079] ROW 1// ... // [1160[1161] ... [1199] BOTTOM ROW // [ ] values are decimal memory addresses // above code calculates mem address for ROW/COL // and then sets cursor to that mem address WriteCtrl(GLCD_CMD_DISPLAY_WRITE) // command to write to LCD memory If (Length(s) >= 1) And (Length(s) < 41) ThenFor n = 0 To Length(s)-1 // only give command 1 time for sequence WriteData(s(n)) // cursor auto advances Next 'n // so we write the text one letter at a time EndIf //USART.Write("Row ",DecToStr(Row),9,// "Col ",DecToStr(Col),9, // "Str Len: ",DecToStr(Length(s)),9, // "Str: ",s,13) End Sub 'Subroutine TextOut
'Subroutine FastDrawBox draws a 8x10 graticule on the screen at right side 'the box is 240 x 240 pixels. Where defines PageA or PageB memory area 'FastDrawBox is revised to remove conditional tests '------------------------------------ // Graticule has solid line box Public Sub FastDrawBox(Where As Word) // with solid dividers at 50%'------------------------------------ // other dividers are . . . . . Dim // layout is 8 x 10 divisions n,l As Byte,m As Word, Ind(6) As Byte Ind(0) = 1 Ind(1) = 2 Ind(2) = 3 Ind(3) = 5 Ind(4) = 6 Ind(5) = 7 //draw vertical lines first For n = 0 To 10 Step 5 // First put on vertical lines For l = 0 To 232 // For 10 divisions, need 11 lines m = Where + 9 + l*40 // Display area is 240 pixels, so lines m = m + Byte(3*n) // are 24 pixels apart. Memory indexes WriteCtrl(GLCD_CMD_SET_CSR_ADDR) //jumps by 40 bytes per display line WriteData(m.Byte0) // see SED1335 data sheet for more info WriteData(m.Byte1) // setup memory index a/k/a cursor adr WriteCtrl(GLCD_CMD_DISPLAY_WRITE)WriteData(%00000001) // write solid lines Next 'l // each byte, as a byte represents a horizontal line Next 'n For n = 1 To 9 // First put on vertical lines For l = 0 To 232 Step 4 // For 10 divisions, need 11 lines m = Where + 9 + l*40 // Display area is 240 pixels, so lines m = m + Byte(3*n) // are 24 pixels apart. Memory indexes WriteCtrl(GLCD_CMD_SET_CSR_ADDR) //jumps by 40 bytes per display line WriteData(m.Byte0) // see SED1335 data sheet for more info WriteData(m.Byte1) // setup memory index a/k/a cursor adr WriteCtrl(GLCD_CMD_DISPLAY_WRITE)WriteData(%00000001) // write solid lines Next 'l // each byte, as a byte represents a horizontal line Next 'n// now draw horizontal lines First draw 6 horizontal dotted lines For l = 0 To 5 'Start of memory is function of X & Y m = Where + 10 + Word(Ind(l)*1160) '+10 starts at 80 pixesl from left WriteCtrl(GLCD_CMD_SET_CSR_ADDR) 'point cursor to starting point WriteData(m.Byte0) 'load starting point WriteData(m.Byte1) '' WriteCtrl(GLCD_CMD_DISPLAY_WRITE) 'lines are 8*(1+(39-10)) pixels wide For n = 10 To 39 ' WriteData(%10001000) 'these intermediate lines are dotted Next 'm Next 'l For l = 0 To 8 Step 4m = Where + 10 + Word(l*1160) //need 9 lines for 8 divisions WriteCtrl(GLCD_CMD_SET_CSR_ADDR)WriteData(m.Byte0) WriteData(m.Byte1) //graphics memory starts at 0x960 = .2400 WriteCtrl(GLCD_CMD_DISPLAY_WRITE) // now write the lines For n = 10 To 39 // others are dotted. WriteData($FF) // solid line is $FF Next 'm Next 'lEnd Sub
'Initialize and set up various registers in the LCD control board 'Need to go back and replace some hard coding with defined constants '---------------------- Public Sub InitDisplay() '---------------------- WriteCtrl(GLCD_CMD_SYSTEM) // Execute System Set Instruction WriteData($30) // Control byte sets internal char gen. See 8.2.1 of DS WriteData($87) // FX -- horizontal char size. See 8.2.1.7 WriteData($07) // FY -- vertical char size - 1 WriteData($27) // C/R. Bytes per line horizintally - 1. 320/8 = .40 = $28 WriteData($42) // TC/R. Complicated - provides overscan idle time see DS WriteData(GLCD_Height-1) // LF -- height of frame in lines -1. $EF = 239 WriteData($28) // APL -- low byte of AP. AP = horizontal address of virtual WriteData($00) // screen. APH is high byte. See Fig 8 in DS WriteCtrl(GLCD_CMD_SCROLL) // sets scroll address and lines per scroll block WriteData($00) // SAD 1 Low - start of text memory WriteData($00) // SAD 1 High WriteData(GLCD_Height-1) // SL 1 $EF=.239 WriteData(Lo(PageAStart)) // SAD 2 Low - start of graphic memory WriteData(Hi(PageAStart)) // SAD 2 High - start at $0960 = 2400 WriteData(GLCD_Height-1) // SL 2 $EF=.239 WriteData(Lo(PageBStart)) // SAD 3 Low WriteData(Hi(PageBStart)) // SAD 3 High WriteData(00) // SAD 4 Low WriteData(00) // SAD 4 High WriteCtrl(GLCD_CMD_HDOT_SCR) // allow screen to scroll by pixels WriteData($00) // set to zero pixels for now WriteCtrl(GLCD_CMD_OVERLAY) // how text and graphics layers are combined WriteData($00) // set to Priority OR L1 > L2 > L3 $03 WriteCtrl(GLCD_CMD_DISP_OFF) // command for screen on/off WriteData($14) // turns screen off WriteCtrl(GLCD_CMD_CSR_FORM) // select cursor size and shape WriteData($07) // cursor width = 8 pixels (7+1) WriteData($87) // cursor height is 8 pixels & block style WriteCtrl(GLCD_CMD_DISP_ON) // command for screen on/off WriteData($14) // turn screen on, layers 1 & 2 ON WriteCtrl(GLCD_CMD_CSRDIR_RIGHT) // set cursor to increment to right CursMem(GLCD_TextAdr) // tidy up with cursor at start of text// ClearGraphicMem(PageAStart) // clear the graphics memory // ClearGraphicMem(PageBStart) // both dispay pages // ClearTextMem //clear text memory End Sub // Subroutine InitDisplay
'RefreshRegs re-writes the minimum set of registers necessary to 'fix the register trashing observed '---------------------- Public Sub RefreshRegs(WhereA, WhereB As Word) '---------------------- WriteCtrl(GLCD_CMD_SYSTEM) // Execute System Set Instruction WriteData($30) // Control byte sets internal char gen. See 8.2.1 of DS WriteData($87) // FX -- horizontal char size. See 8.2.1.7 WriteData($07) // FY -- vertical char size - 1 WriteData($27) // C/R. Bytes per line horizintally - 1. 320/8 = .40 = $28 WriteData($42) // TC/R. Complicated - provides overscan idle time see DS WriteData(GLCD_Height-1) // LF -- height of frame in lines -1. $EF = 239 WriteData($28) // APL -- low byte of AP. AP = horizontal address of virtual WriteData($00) // screen. APH is high byte. See Fig 8 in DS WriteCtrl(GLCD_CMD_SCROLL) // sets scroll address and lines per scroll block WriteData($00) // SAD 1 Low - start of text memory WriteData($00) // SAD 1 High WriteData(GLCD_Height-1) // SL 1 $EF=.239 WriteData(WhereA.Byte0) // SAD 2 Low - start of graphic memory WriteData(WhereA.Byte1) // SAD 2 Low - start of graphic memory WriteData(GLCD_Height-1) // SL 2 $EF=.239 WriteData(WhereB.Byte0) // SAD 2 Low - start of graphic memory WriteData(WhereB.Byte1) // SAD 2 Low - start of graphic memory WriteData(00) // SAD 4 Low WriteData(00) // SAD 4 High WriteCtrl(GLCD_CMD_HDOT_SCR) // allow screen to scroll by pixels WriteData($00) // set to zero pixels for now'needed WriteCtrl(GLCD_CMD_OVERLAY) // how text and graphics layers are combined WriteData($00) // set to Priority OR L1 > L2 > L3 $03 WriteCtrl(GLCD_CMD_DISP_OFF) // command for screen on/off WriteData($14) // turns screen off WriteCtrl(GLCD_CMD_CSR_FORM) // select cursor size and shape WriteData($07) // cursor width = 8 pixels (7+1) WriteData($87) // cursor height is 8 pixels & block style WriteCtrl(GLCD_CMD_DISP_ON) // command for screen on/off WriteData($14) // turn screen on, layers 1 & 2 ON WriteCtrl(GLCD_CMD_CSRDIR_RIGHT) // set cursor to increment to rightEnd Sub // Subroutine RefreshRegs
'Write a pixel to the LCD at location X,Y. If mode = true then clear '------------------------------------------------------------------------ Public Sub PutPixel(x As Word, y As Word, Mode As Boolean, Where As Word) '------------------------------------------------------------------------ Dim MemAdr As Word, Offset As Byte, temp As Byte If x > 319 Then x = 319 EndIf //If y > 239 Then y = 239 EndIf If y > 239 Then y = 0 EndIfMemAdr = Where + y * 40 + x/8 Offset = x - ((x/8) * 8) WriteCtrl(GLCD_CMD_SET_CSR_ADDR) WriteData(MemAdr.Byte0) WriteData(MemAdr.Byte1) WriteCtrl(GLCD_CMD_DISPLAY_READ) temp = ReadData() If Mode Then temp = temp Or (%10000000 >> Offset) Else temp = temp And (%01111111 >> Offset) EndIf WriteCtrl(GLCD_CMD_SET_CSR_ADDR) WriteData(MemAdr.Byte0) WriteData(MemAdr.Byte1) WriteCtrl(GLCD_CMD_DISPLAY_WRITE) WriteData(temp) // fixEnd Sub 'Subroutine VLine draws a vertical line at X position X, between Ystart and 'Yend. Mode defines line or erase line. True = line, false = erase line '------------------------------------------------------------------------- Public Sub VLine(x As Word, ystart As Byte, yend As Byte, Mode As Boolean, Where As Word) '------------------------------------------------------------------------- Dim i, istart,iend As Byte 'used in indexing If yend > ystart Then 'need to determine direction to write data istart = ystartiend = yend 'this code sets istart to the lower of Else 'ystart and yend. iend is then set to the istart = yend 'greatere of ystart and yend iend = ystartEndIf For i = istart To iend 'to draw the vertical line, just write the PutPixel(x,i,Mode, Where) 'pixels to the screen NextEnd Sub 'Subroutine HLine draws a horizontal line at position X, between X and 'Xend. Mode defines line or erase line. True = line, false = erase line '------------------------------------------------------------------------- Public Sub HLine(xstart As Word, y As Word, xend As Word, Mode As Boolean, Where As Word) '------------------------------------------------------------------------- Dim i, istart,iend As Word 'used in indexing If xend > xstart Then 'need to determine direction to write data istart = xstartiend = xend 'this code sets istart to the lower of Else 'ystart and yend. iend is then set to the istart = xend 'greater of xstart and xend iend = xstartEndIf For i = istart To iend PutPixel(i,y,Mode, Where) Next 'iEnd Sub
'----------------------------------------- Public Sub Box(x1,y1,x2,y2 As Word, Mode As Boolean, Where As Word) '----------------------------------------- HLine(x1,y1,x2,Mode,Where)HLine(x1,y2,x2,Mode,Where) VLine(x1,y1,y2,Mode,Where) VLine(x2,y1,y2,Mode,Where) End Sub
'Checkerboard writes a block checkerboard to graphics memory page 2 '------------------------------------------------------- Public Sub Checkerboard(Where As Word, pDispMode As Bit) '------------------------------------------------------- Dim i,j,k As Word, Fore,Back As Byte If pDispMode = %1 Then Fore = $FF Back = $00 Else Fore = $00 Back = $FF EndIf CursMem(Where) WriteCtrl(GLCD_CMD_DISPLAY_WRITE) For i = 0 To GLCD_Height-1 For j = 0 To (GLCD_Width / 8) -1 If (i.bit3 = %0) And (j Mod 2 = 0) Then WriteData(Fore) ElseIf (i.bit3 = %1) And(j Mod 2 = 1) Then WriteData(Fore) Else WriteData(Back) EndIf Next 'j Next 'iEnd Sub 'Draws a box or erases a box around text string of length Len with the 'text written at positions x & y. Mode is true/false for write/erase 'where defines the display page. Since box has margins from text, won't work 'at extreme edges of the display '------------------------------------------------------------------ Public Sub TextBox(x,y,Len As Word, Mode As Boolean, Where As Word) '------------------------------------------------------------------ Dim x1,x2,y1,y2 As Word ' coordinates of box to be drawn x1 = 8*x - 2 ' Apply border of 2 pixels around x2 = x1 + 8*len + 2 ' the text on all sides y1 = 8*y - 2 ' must leave blanks to avoid over printing y2 = y1 + 10 ' also can't be at screen edge on any side Box(x1,y1,x2,y2,Mode,Where)End Sub '---------------------------------------- Public Sub SetDisplayPage(pValue As Word) '---------------------------------------- WriteCtrl(GLCD_CMD_SCROLL) // sets scroll address and lines per scroll block WriteData($00) // SAD 1 Low - start of text memory WriteData($00) // SAD 1 High WriteData(GLCD_Height-1) // SL 1 $EF=.239 WriteData(pValue.Byte0) // SAD 2 Low - start of graphic memory WriteData(pValue.Byte1) // SAD 2 High - start at $0960 = 2400 WriteData(GLCD_Height-1) // SL 2 $EF=.239 WriteData($00) // SAD 3 Low WriteData($00) // SAD 3 High WriteData($00) // SAD 4 Low WriteData($00) // SAD 4 HighEnd Sub
'exchanges values of X & Y '------------------------------------- Private Sub Swap(ByRef x,y As Integer) '------------------------------------- If x <> y Thenx = x Xor y y = x Xor y x = x Xor y EndIf End Sub
'----------------------------------------------------------------------- Public Sub Line(x0,y0,x1,y1 As Integer,pMode As Boolean, pWhere As Word) '----------------------------------------------------------------------- 'Based on Bresenham's algoritm Dim Steep As Boolean, DeltaX,DeltaY As Integer, Error,DeltaErr As Integer, x,y,ystep As Integer {'fudge to get 1 pixel shift If x0 > 1 Then x0 = x0-1 EndIf If x1 > 1 Then x1 = x1-1 EndIf } Steep = abs(y1-y0) > abs(x1-x0)If Steep Then Swap(x0,y0) Swap(x1,y1) EndIf If x0 > x1 Then Swap(x0,x1) Swap(y0,y1) EndIf DeltaX = x1-x0 DeltaY = abs(y1-y0) Error = 0 DeltaErr = DeltaY y = y0 If y0 < y1 Then ystep = 1 Else ystep = -1 EndIf For x = x0 To x1 If Steep Then PutPixel(y,x,pMode,pWhere) Else PutPixel(x,y,pMode,pWhere) EndIf Error = Error + DeltaErr If 2*Error >= DeltaErr Then y = y + yStep Error = Error - DeltaX EndIf Next End Sub '------------------- Public Sub StartUp() '------------------- Initialize // set up ports and reset the LCD DelayMS(500) // Take it slow at the start. InitDisplay // Initialize registers in LCD control board ClearGraphicMem(PageAStart)ClearGraphicMem(PageBStart) ClearTextMem // clear text memory to make room for new messagesEnd Sub End
|