PDA

View Full Version : Trying to use CGRAM of LCD with PIC16F877A



mcbeasleyjr
- 5th November 2011, 05:31
All,

I am trying to find a way to create custom characters using the CGRAM of a 20x4 LCD. I've been trying to browse online and I've only located ASM examples. I can't completely understand ASM so I'd much rather write it in PBP. I have the LCD wired to PORTB of my PIC16F877A MCU. I've listed my define's as shown in the code below.


DEFINE OSC 20 ' Define 20MHz Oscillator
DEFINE LCD_RSREG PORTB ' Set LCD Register Select port
DEFINE LCD_RSBIT 1 ' Set LCD Register Select bit - pin 4 of LCD
DEFINE LCD_RWREG PORTB ' Set LCD Read Write port
DEFINE LCD_RWBIT 2 ' Set LCD Read Write bit - pin 5 of LCD
DEFINE LCD_EREG PORTB ' Set LCD Enable port
DEFINE LCD_EBIT 3 ' Set LCD Enable bit - pin 6 of LCD
DEFINE LCD_DREG PORTB ' Set LCD Data port
DEFINE LCD_DBIT 4 ' Set starting bit (0 or 4) if 4-bit bus
DEFINE LCD_BITS 4 ' 4-bit LCD data bus - pins 11 - 14 of LCD
DEFINE LCD_LINES 4 ' Set number of lines on LCD
DEFINE LCD_COMMANDUS 2000 ' Set command delay time in us
DEFINE LCD_DATAUS 50 ' Set data delay time in us


Now, I have no problem with sending messages to my LCD.


MAIN:
LCDOUT $FE, 1
LCDOUT $FE, 2
LCDOUT $FE, $0C
LCDOUT "Testing my 20x4"
LCDOUT $FE, $C0
LCDOUT "LCD project."
LCDOUT $FE, $94
LCDOUT "Built By:"
LCDOUT $FE, $D4
LCDOUT "Me"
PAUSE 3000
GOTO MAIN

However, I've designed a "logo", if you will, that I would like to display on the LCD. I know that I want to use the 5x8 dot format but I'm not sure how to do this in PBP. Nor am I certain of how to write to the CGRAM addresses that need to be written to in order to display the characters that I'm trying to create. Can anyone provide an example PBP code to help me with this?

Thanks in advance....

mackrackit
- 5th November 2011, 09:55
http://www.picbasic.co.uk/forum/showthread.php?t=242&highlight=custom+characters
(http://www.picbasic.co.uk/forum/showthread.php?t=242&highlight=custom+characters)
http://www.picbasic.co.uk/forum/showthread.php?t=2598

mcbeasleyjr
- 5th November 2011, 20:03
Thank you for your response... I've looked at the two links that you posted and I understand now how to write the data to the CGRAM registers. How though, do I tell the LCD a specific location to display the created character? I've attached a jpeg of how I want to display these 5x7s. As you can see, the top left of the I starts in the 3rd character location of the first line. So I need to figure out first how to write that to CGRAM and then how to display it in that particular location. I'm hoping that I can write one location of CGRAM, display it, then overrite that location to display something different in a different location. Any thoughts? If anyone has an idea of how I can get my LCD to properly display what I have attached, I would greatly appreciate any of your help with this.

Thanks again in advance.

mackrackit
- 5th November 2011, 20:52
You must not have read the whole thread.
http://www.picbasic.co.uk/forum/showthread.php?t=242&p=46027#post46027

mcbeasleyjr
- 6th November 2011, 02:08
Mackrackit,

You were right again sir... I missed that part lower down. I discovered that what I was trying to do would not work because it would require 12 locations rather than 8. So I changed it a little and had it display a spade instead. I'm posting my code below in case you want to play with it or something. Once again I thank you for your help.


'************************************************* ***************
'* Name : LCDTEST.BAS *
'* Author : Morris C. Beasley, Jr. *
'* Notice : Copyright (c) 2011 Morris C. Beasley, Jr. *
'* : All Rights Reserved *
'* Date : 7/30/2011 *
'* Version : 1.0 *
'* Notes : *
'* : *
'************************************************* ***************
DEFINE OSC 20 ' Define 20MHz Oscillator

DEFINE LCD_RSREG PORTB ' Set LCD Register Select port
DEFINE LCD_RSBIT 1 ' Set LCD Register Select bit - pin 4 of LCD
DEFINE LCD_RWREG PORTB ' Set LCD Read Write port
DEFINE LCD_RWBIT 2 ' Set LCD Read Write bit - pin 5 of LCD
DEFINE LCD_EREG PORTB ' Set LCD Enable port
DEFINE LCD_EBIT 3 ' Set LCD Enable bit - pin 6 of LCD
DEFINE LCD_DREG PORTB ' Set LCD Data port
DEFINE LCD_DBIT 4 ' Set starting bit (0 or 4) if 4-bit bus
DEFINE LCD_BITS 4 ' 4-bit LCD data bus - pins 11 - 14 of LCD
DEFINE LCD_LINES 4 ' Set number of lines on LCD
DEFINE LCD_COMMANDUS 2000 ' Set command delay time in us
DEFINE LCD_DATAUS 50 ' Set data delay time in us

DEFINE ADC_BITS 10 ' Defines number of adc bits (o - 255 output)
DEFINE ADC_CLOCK 3 ' ADC clock speed
DEFINE ADC_SAMPLEUS 1 ' How often the adc samples inputs
PAUSE 1000

'************************************************* ******************************
' List the programmable CGRAM locations. They are commented out because they *
' are used as reference only. All should know that commands are sent to the *
' LCD by sending an $FE followed by the command itself. In this situation, the*
' command is going to be the CGRAM address. For example, LCDOUT $FE, $40 is *
' writing to the 0 location of CGRAM. There are 8 locations in total (0-7). *
' That command is followed by the 8 bytes representing each row in the matrix. *
' In a 5x8 matrix, the 3 MSB are not used, therefore, xxxLLLLL is your byte, *
' where x is not used and L is the logic of which you wish that box to be. *
' As an example, the following command darkens an entire matrix at the given *
' location: LCDOUT $FE,$40,$1F,$1F,$1F,$1F,$1F,$1F,$1F,$1F. The first byte *
' is the top line while the last byte is the bottom line. *
' Constants are created to indicate the beginning of each line on a 20x4 LCD. *
'************************************************* ******************************
'LOCATION 0 = $40 = 64
'LOCATION 1 = $48 = 72
'LOCATION 2 = $50 = 80
'LOCATION 3 = $58 = 88
'LOCATION 4 = $60 = 96
'LOCATION 5 = $68 = 104
'LOCATION 6 = $70 = 112
'LOCATION 7 = $78 = 120
ROW1 CON 128 '$80 - LINE 1
ROW2 CON 192 '$C0 - LINE 2
ROW3 CON 148 '$94 - LINE 3
ROW4 CON 212 '$D4 - LINE 4

BATVOLTAGE VAR WORD ' Variable for battery voltage
BAT_DIGIT VAR BYTE ' Variable for voltage digits before decimal
BAT_DEC VAR BYTE ' Variable for voltage digits after decimal
ADCON1 = %10000010 ' ADC configuration
TRISA = %11111111 ' Configure PortA
TRISB = %00000000 ' Configure PortB

MAIN:
LCDOUT $FE, 1 'Clear the display
LCDOUT $FE, 2 'Turn the cursor off
LCDOUT $FE,$40,$00,$00,$00,$00,$00,$04,$0E,$1F 'Writes top of spade to CGRAM address 0
LCDOUT $FE,$48,$01,$03,$07,$0F,$1F,$1F,$1F,$1F 'Write upper left of spade to CGRAM address 1
LCDOUT $FE,$50,$1F,$1F,$1F,$1F,$1F,$1F,$1F,$1F 'Write upper center of spade to CGRAM address 2
LCDOUT $FE,$58,$10,$18,$1C,$1E,$1F,$1F,$1F,$1F 'Write upper right of spade to CGRAM address 3
LCDOUT $FE,$60,$1F,$0F,$07,$00,$00,$01,$03,$07 'Write lower left of spade to CGRAM address 4
LCDOUT $FE,$68,$1F,$1F,$0E,$0E,$1F,$1F,$1F,$1F 'Write lower center of spade to CGRAM address 5
LCDOUT $FE,$70,$1F,$1E,$1C,$00,$00,$10,$18,$1C 'Write lower right of spade to CGRAM address 6

LCDOUT $FE, ROW1+2, 0
LCDOUT $FE, ROW1+5, "ISH ELECTRONICS"
LCDOUT $FE, ROW2+1, 1
LCDOUT $FE, ROW2+2, 2
LCDOUT $FE, ROW2+3, 3
LCDOUT $FE, ROW2+11, "BY"
LCDOUT $FE, ROW3+1, 4
LCDOUT $FE, ROW3+2, 5
LCDOUT $FE, ROW3+3, 6
LCDOUT $FE, ROW3+9, "MORRIS"
LCDOUT $FE, ROW4+9, "BEASLEY"
PAUSE 2000
GOSUB CHECK_VOLTAGE
PAUSE 100

GOTO MAIN

CHECK_VOLTAGE:
ADCIN 0, BATVOLTAGE ' Store the 10-bit conversion in variable
BAT_DIGIT = (BATVOLTAGE * 5) / 1000
BAT_DEC = (BATVOLTAGE * 5) - (BAT_DIGIT * 1000)
LCDOUT $FE, ROW1+2, 0
LCDOUT $FE, ROW1+5, " VOLTAGE "
LCDOUT $FE, ROW2+1, 1
LCDOUT $FE, ROW2+2, 2
LCDOUT $FE, ROW2+3, 3
LCDOUT $FE, ROW2+5, " MEASURED "
LCDOUT $FE, ROW3+1, 4
LCDOUT $FE, ROW3+2, 5
LCDOUT $FE, ROW3+3, 6
LCDOUT $FE, ROW3+5, " AT "
LCDOUT $FE, ROW4+5, DEC BAT_DIGIT, ".", DEC BAT_DEC, "DC Volts"
PAUSE 2000
RETURN