View previous topic :: View next topic |
Author |
Message |
buckeyes1997 Guest
|
problem with LCD and CCS driver |
Posted: Sun Nov 21, 2004 9:43 pm |
|
|
hello everyone
i am trying to use the included CCS lcd driver to make my 4x20 lcd module work. i am trying to use it in 4bit mode with a 16f84. the code compiles and doesnt give any errors, but it doesnt output characters or strings entered as
...
lcd_putc('A');
lcd_putc("hello");
.....
what could i be doing wrong?? also i am only using 6 lines and leaving the r/w pin low for writting always. i commented out the while() condition in the lcd program to keep from possibly getting stuck in a loop trying to read the r/w pin.
thanks everyone
matt |
|
|
Mark
Joined: 07 Sep 2003 Posts: 2838 Location: Atlanta, GA
|
|
Posted: Sun Nov 21, 2004 10:38 pm |
|
|
Quote: | what could i be doing wrong?? |
Quote: | i am only using 6 lines and leaving the r/w pin low for writting always. i commented out the while() condition |
What do you think that check is in there for?? |
|
|
buckeyes1997 Guest
|
i know |
Posted: Mon Nov 22, 2004 9:08 am |
|
|
i know the check is in there to use hardware to set the delays, but its easier for me to just delay the amount of time i need in software. that is why i commented them out and added some small delays that meet the timing paramaters given in the hitachi datasheet. but thanks for that great answer to my question.
what im really looking for is some bonehead thing i should check because im probably not setting up in the CCS compiler for my chip or something. point is i can run the third party lcd routine and it works (with the 6lines) but the included CCS routine does nothing. it never even initializes the display.
could someone post an example of what should be in main() to output a few characters to the lcd? perhaps im not calling the function properly.
i will post my code tonite to maybe help out. |
|
|
Mark
Joined: 07 Sep 2003 Posts: 2838 Location: Atlanta, GA
|
|
Posted: Mon Nov 22, 2004 10:27 am |
|
|
Post your code. |
|
|
buckeyes1997 Guest
|
my code attempt |
Posted: Mon Nov 22, 2004 5:32 pm |
|
|
here is my code for the main program as well as using a slightly modified lcd.c file.
Code: | #include "C:\Documents and Settings\Administrator\My Documents\microcontroller\piclcd\piclcd2.h"
#include <LCD.C>
#include <stdio.h>
#include <stddef.h>
void main()
{
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
lcd_init();
lcd_putc('a');
lcd_putc("hello world");
}
|
the modification to the lcd.c file was basically to comment out the conditionally statement that pended on the r/w pin of the pic since i dont provide access to this line. thanks guys for your help
matt |
|
|
Mark
Joined: 07 Sep 2003 Posts: 2838 Location: Atlanta, GA
|
|
Posted: Mon Nov 22, 2004 6:29 pm |
|
|
I don't see any device specified, no fuses, no clock....
You didn't post the LCD.c file you modified
You didn't post the piclcd2.h file. |
|
|
buckeyes1997 Guest
|
hmmm |
Posted: Mon Nov 22, 2004 6:53 pm |
|
|
thanks mark for replying so fast. im going to attach the files you mentioned here. also i think the device declaration is in the header file as well as the wdt etc.
do i need to use the pullup resisters for portB or do anything special to use them as outputs?? i set the port up as outputs using the project wizard. |
|
|
buckeyes Guest
|
oops |
Posted: Mon Nov 22, 2004 7:35 pm |
|
|
Code: | #include <16F84A.h>
#use delay(clock=4000000)
#fuses NOWDT,HS, PUT, NOPROTECT
|
Code: | ///////////////////////////////////////////////////////////////////////////
//// LCDD.C ////
//// Driver for common LCD modules ////
//// ////
//// lcd_init() Must be called before any other function. ////
//// ////
//// lcd_putc(c) Will display c on the next position of the LCD. ////
//// The following have special meaning: ////
//// \f Clear display ////
//// \n Go to start of second line ////
//// \b Move back one position ////
//// ////
//// lcd_gotoxy(x,y) Set write position on LCD (upper left is 1,1) ////
//// ////
//// lcd_getc(x,y) Returns character at position x,y on LCD ////
//// ////
///////////////////////////////////////////////////////////////////////////
//// (C) Copyright 1996,2003 Custom Computer Services ////
//// This source code may only be used by licensed users of the CCS C ////
//// compiler. This source code may only be distributed to other ////
//// licensed users of the CCS C compiler. No other use, reproduction ////
//// or distribution is permitted without written permission. ////
//// Derivative programs created using this software in object code ////
//// form are not restricted in any way. ////
///////////////////////////////////////////////////////////////////////////
// As defined in the following structure the pin connection is as follows:
// D0 enable
// D1 rs
// D2 rw
// D4 D4
// D5 D5
// D6 D6
// D7 D7
//
// LCD pins D0-D3 are not used and PIC D3 is not used.
// Un-comment the following define to use port B
#define use_portb_lcd TRUE
struct lcd_pin_map { // This structure is overlayed
BOOLEAN enable; // on to an I/O port to gain
BOOLEAN rs; // access to the LCD pins.
BOOLEAN rw; // The bits are allocated from
BOOLEAN unused; // low order up. ENABLE will
int data : 4; // be pin B0.
} lcd;
#if defined(__PCH__)
#if defined use_portb_lcd
#byte lcd = 0xF81 // This puts the entire structure
#else
#byte lcd = 0xF83 // This puts the entire structure
#endif
#else
#if defined use_portb_lcd
#byte lcd = 6 // on to port B (at address 6)
#else
#byte lcd = 8 // on to port D (at address 8)
#endif
#endif
#if defined use_portb_lcd
#define set_tris_lcd(x) set_tris_b(x)
#else
#define set_tris_lcd(x) set_tris_d(x)
#endif
#define lcd_type 2 // 0=5x7, 1=5x10, 2=2 lines
#define lcd_line_two 0x40 // LCD RAM address for the second line
BYTE const LCD_INIT_STRING[4] = {0x20 | (lcd_type << 2), 0xc, 1, 6};
// These bytes need to be sent to the LCD
// to start it up.
// The following are used for setting
// the I/O port direction register.
struct lcd_pin_map const LCD_WRITE = {0,0,0,0,0}; // For write mode all pins are out
struct lcd_pin_map const LCD_READ = {0,0,0,0,15}; // For read mode data pins are in
BYTE lcd_read_byte() {
BYTE low,high;
//set_tris_lcd(LCD_READ);
lcd.rw = 1;
delay_cycles(1);
lcd.enable = 1;
delay_cycles(1);
high = lcd.data;
lcd.enable = 0;
delay_cycles(1);
lcd.enable = 1;
delay_us(1);
low = lcd.data;
lcd.enable = 0;
// set_tris_lcd(LCD_WRITE);
return( (high<<4) | low);
}
void lcd_send_nibble( BYTE n ) {
lcd.data = n;
delay_cycles(1);
lcd.enable = 1;
delay_us(2);
lcd.enable = 0;
}
void lcd_send_byte( BYTE address, BYTE n ) {
lcd.rs = 0;
// while ( bit_test(lcd_read_byte(),7) ) ;
lcd.rs = address;
delay_cycles(1);
lcd.rw = 0;
delay_cycles(1);
lcd.enable = 0;
lcd_send_nibble(n >> 4);
lcd_send_nibble(n & 0xf);
}
void lcd_init() {
BYTE i;
// set_tris_lcd(LCD_WRITE);
lcd.rs = 0;
lcd.rw = 0;
lcd.enable = 0;
delay_ms(15);
for(i=1;i<=3;++i) {
lcd_send_nibble(3);
delay_ms(5);
}
lcd_send_nibble(2);
for(i=0;i<=3;++i)
lcd_send_byte(0,LCD_INIT_STRING[i]);
}
void lcd_gotoxy( BYTE x, BYTE y) {
BYTE address;
if(y!=1)
address=lcd_line_two;
else
address=0;
address+=x-1;
lcd_send_byte(0,0x80|address);
}
void lcd_putc( char c) {
switch (c) {
case '\f' : lcd_send_byte(0,1);
delay_ms(2);
break;
case '\n' : lcd_gotoxy(1,2); break;
case '\b' : lcd_send_byte(0,0x10); break;
default : lcd_send_byte(1,c); break;
}
}
char lcd_getc( BYTE x, BYTE y) {
char value;
lcd_gotoxy(x,y);
// while ( bit_test(lcd_read_byte(),7) ); // wait until busy flag is low
lcd.rs=1;
value = lcd_read_byte();
lcd.rs=0;
return(value);
}
|
|
|
|
buckeyes Guest
|
|
Posted: Mon Nov 22, 2004 7:38 pm |
|
|
// set_tris_lcd(LCD_WRITE);
it looks like this line should not be commented out and would cause it to not initialize right?? ill correct that and try it again |
|
|
Mark
Joined: 07 Sep 2003 Posts: 2838 Location: Atlanta, GA
|
|
Posted: Mon Nov 22, 2004 8:03 pm |
|
|
Code: | #fuses NOWDT,HS, PUT, NOPROTECT
|
should be
Code: | #fuses NOWDT,XT, PUT, NOPROTECT, NOLVP
|
You need to uncomment the setting of the tris.
Quote: | i know the check is in there to use hardware to set the delays, but its easier for me to just delay the amount of time i need in software. that is why i commented them out and added some small delays that meet the timing paramaters given in the hitachi datasheet. but thanks for that great answer to my question.
|
Where are those delays? |
|
|
buckeyes1997 Guest
|
hey mark |
Posted: Mon Nov 22, 2004 10:03 pm |
|
|
why do i want to use XT with a 4mhz oscillator? i was under the impression i needed to have the HS set for 4 and greater?
what is the lvp for in the fuses statement....i know it means low voltage programming but what would this be used for?
the delays i was refering to were in an earlier version of the file piclcd1.c/h. they werent much more than delaying several ms after each command to the lcd. the timing parameters are on the data sheet and several ms should be sufficient to free up the io pin. |
|
|
Mark
Joined: 07 Sep 2003 Posts: 2838 Location: Atlanta, GA
|
|
Posted: Mon Nov 22, 2004 11:05 pm |
|
|
Quote: | why do i want to use XT with a 4mhz oscillator? |
cause HS might not work. XT will.
Quote: | what is the lvp for in the fuses statement |
I said NOLVP cause you aren't using it and if ya mess with the LVP pin your PIC will go into the weeds! Gets people all the time.
Quote: | the delays i was refering to were in an earlier version of the file piclcd1.c/h. |
Do you think you might need them? It didn't work until I added a delay instead of the while |
|
|
buckeyes1997 Guest
|
just in case |
Posted: Tue Nov 23, 2004 6:59 pm |
|
|
hey guys i wanted to relate my findings with everyone.
i took care not to goto sleep after one pass of the software and it works.
the chip seems to run okay in HS mode with a 4mhz oscillator.
there is no LVP(NOLVP) directive in the 16f84a according to the software.
ill try this out on the LCD program and report back.
thanks
matt |
|
|
buckeyes1997 Guest
|
SUCCESS!!!!!!!!! |
Posted: Wed Nov 24, 2004 1:07 am |
|
|
okay guys i finally got the lcd working with the driver.
i am having another problem though. the lcd i have is a 4x20 character display and for some reason i can only seem to use two lines. the top 2 lines work and nothing ever gets written on the lines 3 and 4. im guessing its an initiallization setting but im clueless.
the lcd screen is the L2014. the datasheet is on the web.
any ideas how to use all 4 lines???
thanks a bunch guys hope im not annoying anyone by asking questions. |
|
|
Mark
Joined: 07 Sep 2003 Posts: 2838 Location: Atlanta, GA
|
|
Posted: Wed Nov 24, 2004 6:43 am |
|
|
Read the comments:
Code: | #define lcd_type 2 // 0=5x7, 1=5x10, 2=2 lines
#define lcd_line_two 0x40 // LCD RAM address for the second line
BYTE const LCD_INIT_STRING[4] = {0x20 | (lcd_type << 2), 0xc, 1, 6};
// These bytes need to be sent to the LCD
// to start it up.
|
Take a look at the gotoxy:
Code: | void lcd_gotoxy( BYTE x, BYTE y) {
BYTE address;
if(y!=1)
address=lcd_line_two;
else
address=0;
address+=x-1;
lcd_send_byte(0,0x80|address);
}
|
So we could change it a bit
Code: |
#define lcd_line_two 0x40 // LCD RAM address for the second line
#define lcd_line_three 0x14 // LCD RAM address for the third line
#define lcd_line_four 0x54 // LCD RAM address for the fourth line
void lcd_gotoxy( BYTE x, BYTE y) {
BYTE address;
switch (y)
{
case 2:
address=lcd_line_two;
break;
case 3:
address=lcd_line_three;
break;
case 4:
address=lcd_line_four;
break;
default:
address=0;
}
address+=x-1;
lcd_send_byte(0,0x80|address);
|
But now we have another problem that needs fixing:
Code: |
void lcd_putc( char c)
{
static BYTE currentline = 1;
switch (c)
{
case '\f':
currentline = 1;
lcd_send_byte(0,1);
delay_ms(2);
break;
case '\n':
if (currentline < 4)
currentline++;
lcd_gotoxy(1,currentline);
break;
case '\b':
lcd_send_byte(0,0x10);
break;
default:
lcd_send_byte(1,c);
break;
}
}
|
Here's a datasheet with the commands
http://www.electronic-engineering.ch/microchip/datasheets/lcd/the_lcd_data_sheet.pdf |
|
|
|