View previous topic :: View next topic |
Author |
Message |
AD76XYZ
Joined: 18 Jun 2012 Posts: 19
|
20x4 LCD Flex driver error |
Posted: Sun Jul 01, 2012 10:48 pm |
|
|
I got this driver for 20x4 lcd module. But it gives lot of error.
Please help me.
Code: |
// Flex_LCD420.c
// These pins are for my Microchip PicDem2-Plus board,
// which I used to test this driver.
// An external 20x4 LCD is connected to these pins.
// Change these pins to match your own board's connections.
#define LCD_RS_PIN PIN_C0
#define LCD_RW_PIN PIN_C1
#define LCD_ENABLE_PIN PIN_C2
#define LCD_DATA4 PIN_C3
#define LCD_DATA5 PIN_C4
#define LCD_DATA6 PIN_C5
#define LCD_DATA7 PIN_C6
/*
// To prove that the driver can be used with random
// pins, I also tested it with these pins:
#define LCD_DB4 PIN_D4
#define LCD_DB5 PIN_B1
#define LCD_DB6 PIN_C5
#define LCD_DB7 PIN_B5
#define LCD_RS PIN_E2
#define LCD_RW PIN_B2
#define LCD_E PIN_D6
*/
// If you want only a 6-pin interface to your LCD, then
// connect the R/W pin on the LCD to ground, and comment
// out the following line. Doing so will save one PIC
// pin, but at the cost of losing the ability to read from
// the LCD. It also makes the write time a little longer
// because a static delay must be used, instead of polling
// the LCD's busy bit. Normally a 6-pin interface is only
// used if you are running out of PIC pins, and you need
// to use as few as possible for the LCD.
#define USE_RW_PIN 1
// These are the line addresses for most 4x20 LCDs.
#define LCD_LINE_1_ADDRESS 0x00
#define LCD_LINE_2_ADDRESS 0x40
#define LCD_LINE_3_ADDRESS 0x14
#define LCD_LINE_4_ADDRESS 0x54
// These are the line addresses for LCD's which use
// the Hitachi HD66712U controller chip.
/*
#define LCD_LINE_1_ADDRESS 0x00
#define LCD_LINE_2_ADDRESS 0x20
#define LCD_LINE_3_ADDRESS 0x40
#define LCD_LINE_4_ADDRESS 0x60
*/
//========================================
#define lcd_type 2 // 0=5x7, 1=5x10, 2=2 lines(or more)
int8 lcd_line;
int8 const LCD_INIT_STRING[4] =
{
0x20 | (lcd_type << 2), // Set mode: 4-bit, 2+ lines, 5x8 dots
0xc, // Display on
1, // Clear display
6 // Increment cursor
};
//-------------------------------------
void lcd_send_nibble(int8 nibble)
{
// Note: !! converts an integer expression
// to a boolean (1 or 0).
output_bit(LCD_DB4, !!(nibble & 1));
output_bit(LCD_DB5, !!(nibble & 2));
output_bit(LCD_DB6, !!(nibble & 4));
output_bit(LCD_DB7, !!(nibble & 8));
delay_cycles(1);
output_high(LCD_E);
delay_us(2);
output_low(LCD_E);
}
//-----------------------------------
// This sub-routine is only called by lcd_read_byte().
// It's not a stand-alone routine. For example, the
// R/W signal is set high by lcd_read_byte() before
// this routine is called.
#ifdef USE_RW_PIN
int8 lcd_read_nibble(void)
{
int8 retval;
// Create bit variables so that we can easily set
// individual bits in the retval variable.
#bit retval_0 = retval.0
#bit retval_1 = retval.1
#bit retval_2 = retval.2
#bit retval_3 = retval.3
retval = 0;
output_high(LCD_E);
delay_us(1);
retval_0 = input(LCD_DB4);
retval_1 = input(LCD_DB5);
retval_2 = input(LCD_DB6);
retval_3 = input(LCD_DB7);
output_low(LCD_E);
delay_us(1);
return(retval);
}
#endif
//---------------------------------------
// Read a byte from the LCD and return it.
#ifdef USE_RW_PIN
int8 lcd_read_byte(void)
{
int8 low;
int8 high;
output_high(LCD_RW);
delay_cycles(1);
high = lcd_read_nibble();
low = lcd_read_nibble();
return( (high<<4) | low);
}
#endif
//----------------------------------------
// Send a byte to the LCD.
void lcd_send_byte(int8 address, int8 n)
{
output_low(LCD_RS);
#ifdef USE_RW_PIN
while(bit_test(lcd_read_byte(),7)) ;
#else
delay_us(60);
#endif
if(address)
output_high(LCD_RS);
else
output_low(LCD_RS);
delay_cycles(1);
#ifdef USE_RW_PIN
output_low(LCD_RW);
delay_cycles(1);
#endif
output_low(LCD_E);
lcd_send_nibble(n >> 4);
lcd_send_nibble(n & 0xf);
}
//----------------------------
void lcd_init(void)
{
int8 i;
lcd_line = 1;
output_low(LCD_RS);
#ifdef USE_RW_PIN
output_low(LCD_RW);
#endif
output_low(LCD_E);
// Some LCDs require 15 ms minimum delay after
// power-up. Others require 30 ms. I'm going
// to set it to 35 ms, so it should work with
// all of them.
delay_ms(35);
for(i=0 ;i < 3; i++)
{
lcd_send_nibble(0x03);
delay_ms(5);
}
lcd_send_nibble(0x02);
for(i=0; i < sizeof(LCD_INIT_STRING); i++)
{
lcd_send_byte(0, LCD_INIT_STRING[i]);
// If the R/W signal is not used, then
// the busy bit can't be polled. One of
// the init commands takes longer than
// the hard-coded delay of 50 us, so in
// that case, lets just do a 5 ms delay
// after all four of them.
#ifndef USE_RW_PIN
delay_ms(5);
#endif
}
}
//----------------------------
void lcd_gotoxy(int8 x, int8 y)
{
int8 address;
switch(y)
{
case 1:
address = LCD_LINE_1_ADDRESS;
break;
case 2:
address = LCD_LINE_2_ADDRESS;
break;
case 3:
address = LCD_LINE_3_ADDRESS;
break;
case 4:
address = LCD_LINE_4_ADDRESS;
break;
default:
address = LCD_LINE_1_ADDRESS;
break;
}
address += x-1;
lcd_send_byte(0, 0x80 | address);
}
//-----------------------------
void lcd_putc(char c)
{
switch(c)
{
case '\f':
lcd_send_byte(0,1);
lcd_line = 1;
delay_ms(2);
break;
case '\n':
lcd_gotoxy(1, ++lcd_line);
break;
case '\b':
lcd_send_byte(0,0x10);
break;
default:
lcd_send_byte(1,c);
break;
}
}
//------------------------------
#ifdef USE_RW_PIN
char lcd_getc(int8 x, int8 y)
{
char value;
lcd_gotoxy(x,y);
// Wait until busy flag is low.
while(bit_test(lcd_read_byte(),7));
output_high(LCD_RS);
value = lcd_read_byte();
output_low(LCD_RS);
return(value);
}
#endif
|
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sun Jul 01, 2012 11:34 pm |
|
|
I note that you don't post your PIC, or anything else. Also, you don't
tell us what errors you got. We are not mind-readers.
Are you aware that you must have a test program that calls the functions
in the Flex driver ? You can't just drop the flex driver into MPLAB and
press the compile button. Of course you will get errors in that case.
You must have a test program which has the #include for the PIC, #fuses
and #use delay(), and main(), etc. This is all shown in the post that
you copied that code from. |
|
|
AD76XYZ
Joined: 18 Jun 2012 Posts: 19
|
Sorry |
Posted: Mon Jul 02, 2012 12:17 am |
|
|
Hi,
Sorry for not giving the detailed info.
Here is the info.
PIC16F886 running on internal OSC at 4MHz.
4x3 keypad at portB (B7-B1)
16x2 LCD on portc
All work properly when I use CCS's LCD.C driver which is for 16x2 LCD. But when I include Flex_LCD420.C (After removing LCD.C) am getting lot of error like.
Undefined Identifier for below.
LCD_DB4
LCD_DB5
LCD_DB6
LCD_DB7
LCD_E
LCD_RW
LCD_RS
Here is mine code in which I include Flex_LCD420.C
Code: |
// I have define LCD pins as per requirment.
#define LCD_RS_PIN PIN_C0
#define LCD_RW_PIN PIN_C1
#define LCD_ENABLE_PIN PIN_C2
#define LCD_DATA4 PIN_C3
#define LCD_DATA5 PIN_C4
#define LCD_DATA6 PIN_C5
#define LCD_DATA7 PIN_C6
#define LED PIN_A0
#include "D:\PROJECTS\CodeLock\Files\CCS_C\CodeLock.h"
#include "D:\PROJECTS\CodeLock\Files\CCS_C\Flex_LCD420.C"
#include "D:\PROJECTS\CodeLock\Files\CCS_C\kbd4x3.c"
int i;
void main()
{
setup_adc_ports(NO_ANALOGS|VSS_VDD);
setup_adc(ADC_CLOCK_DIV_2);
setup_spi(SPI_SS_DISABLED);
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
setup_ccp1(CCP_OFF);
setup_comparator(NC_NC_NC_NC);// This device COMP currently not supported by the PICWizard
setup_oscillator(OSC_4MHZ);
// TODO: USER CODE!!
char k;
char word1,word2,word3,word4;
lcd_init();
kbd_init();
lcd_putc("Test");
lcd_putc("\nTest2\n");
lcd_putc("\nTest3");
delay_ms(3000);
lcd_putc("\f");
lcd_putc("\nTest4");
lcd_putc("\nCode Lock");
delay_ms(3000);
lcd_putc("\f");
lcd_putc("\nEnter Four Digit");
lcd_putc("\nPassword\n");
while(TRUE)
{
//k=kbd_getc();
//if (k!=0)
}
}
|
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Jul 02, 2012 12:52 am |
|
|
Quote: | #define LCD_RS_PIN PIN_C0
#define LCD_RW_PIN PIN_C1
#define LCD_ENABLE_PIN PIN_C2
#define LCD_DATA4 PIN_C3
#define LCD_DATA5 PIN_C4
#define LCD_DATA6 PIN_C5
#define LCD_DATA7 PIN_C6
|
These #define constants in bold above are not part of the 20x4 Flex driver.
Look at the sample #defines in the Flex driver code:
http://www.ccsinfo.com/forum/viewtopic.php?t=28268
Use the same #define constants that it uses. |
|
|
AD76XYZ
Joined: 18 Jun 2012 Posts: 19
|
Same problem |
Posted: Mon Jul 02, 2012 1:13 am |
|
|
Thanks for reply.
My 20x4 LCD is on portc thats the reason I define port C pins.
Just sake of experiment I included that Flex_LCD420.C driver in mine code and compiled but still I got those errors. Now I have not edited any part of the file just include in my code. |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9229 Location: Greensville,Ontario
|
|
Posted: Mon Jul 02, 2012 6:16 am |
|
|
Well I'm confused...
you first say you're using a 4x20 LCD driver, then say you've got a 16 x 2 LCD, then say you've got a 4x20 LCD.....
If you are really using a 2 x 16 LCD there is the 'flex' driver for it that works. trying to use the 4 x 20 driver may not work with all 2 x 16 LCD due to memory mapping/commands of the LCD itself.
So.. please tell us which LCD you really are using.
Also show us your simple 'hello world' main test program that you've compiled that doesn't work. |
|
|
AD76XYZ
Joined: 18 Jun 2012 Posts: 19
|
temtronic, confused!!! |
Posted: Mon Jul 02, 2012 11:08 am |
|
|
Hi,
I mean, I used 16x2 LCD module in same ckt and it work with LCD.C driver, but when I connect 20x4 LCD module and included LCD420.C driver which I got from this CCS forum, when I compiled I got said errors. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Jul 02, 2012 11:36 am |
|
|
You are confusing the various LCD drivers. They are not compatible.
The CCS drivers are included with the compiler and are in this directory:
c:\program files\picc\drivers\
CCS drivers:
lcd.c
lcd420.c
The Code library drivers do not come with the CCS compiler.
They are on this webpage:
http://www.ccsinfo.com/forum/viewforum.php?f=2
Code Library drivers:
Flex_lcd.c
Flex_LCD420.c
You can not mix together these drivers, or pieces of the drivers.
You can not use constants in #define statements from the CCS drivers
with the Flex drivers. |
|
|
AD76XYZ
Joined: 18 Jun 2012 Posts: 19
|
How to send k's value to function? |
Posted: Mon Jul 02, 2012 11:41 am |
|
|
See this code.
Code: |
unsigned char *k;
count=0;
do
{
k = kbd_getc();
save_digit(&k);
}
while(count<=3);
|
After k=kbd_getc(), k will contain the key value, now I want to send this key value to a function save_digit(), so the way I written is right or any other way there. Please guide. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Jul 02, 2012 11:43 am |
|
|
You just switched the topic. I'm out of here. |
|
|
AD76XYZ
Joined: 18 Jun 2012 Posts: 19
|
To PCM Programmer |
Posted: Mon Jul 02, 2012 11:44 am |
|
|
No no, I am not mixing two or more LCD driver. At a time only one I included in main file. The standard LCD.C driver works perfectly but the driver for 4x20 which I got from this forum is giving errors. |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9229 Location: Greensville,Ontario
|
|
Posted: Mon Jul 02, 2012 1:38 pm |
|
|
I strongly suggest you start ALL over again, delete everything you've done and if you want a 4x20 LCD, build that circuit, use ONE of the two 4x20 LCD drivers (I'd use the flex version).
Now FULLY test it with the traditional 'Hello World' program.
ONCE you're satisfied it works THEN add new features (like your keyboard routines).
Until you are 100% happy with the LCD do NOT proceed with other functions as you cannot prove it's the new code or a 'glitch' in the LCD code!!
Also do not add more topics inside a topic. IE do not ask for KPD code within an LCD topic.
hth
jay |
|
|
Mike Walne
Joined: 19 Feb 2004 Posts: 1785 Location: Boston Spa UK
|
|
Posted: Tue Jul 03, 2012 2:04 am |
|
|
Quote: | Posted: Mon Jul 02, 2012 5:41 pm Post subject: How to send k's value to function?
--------------------------------------------------------------------------------
See this code.
Code:
unsigned char *k;
count=0;
do
{
k = kbd_getc();
save_digit(&k);
}
while(count<=3);
After k=kbd_getc(), k will contain the key value, now I want to send this key value to a function save_digit(), so the way I written is right or any other way there. Please guide. | You've already got a thread going on this.
You think you know what you're doing but you're confusing everyone else by changing LCD's and topic.
Do as temtronic suggests:-
(1) Start with a clean sheet.
(2) Tackle each section ONE at time.
(3) FULLY test each section BEFORE moving on the the next.
When you're stuck, come back, someone will try to help, if you follow the CCS forum guidelines.
Mike |
|
|
|