|
|
View previous topic :: View next topic |
Author |
Message |
treitmey
Joined: 23 Jan 2004 Posts: 1094 Location: Appleton,WI USA
|
PICDEM 2 PLUS LCD |
Posted: Wed Jun 02, 2004 7:46 am |
|
|
The following are two sources of code library for PICDEM 2 PLUS lcd.
http://www.ccsinfo.com/forum/viewtopic.php?t=20182
http://www.ccsinfo.com/forum/viewtopic.php?t=24661
I have opted to remove the original code that I posted.
I had used a delay_cycles() statment which then makes the code dependant
on the clock freq. #use delay(clock=xx)
Change this to a delay_ms(xx) or delay_us(xx) for stable code with ANY clock.
Last edited by treitmey on Fri May 16, 2008 8:12 am; edited 6 times in total |
|
|
cxiong
Joined: 09 Sep 2003 Posts: 52
|
|
Posted: Mon Nov 22, 2004 12:54 pm |
|
|
I have modified the above code to use on PORTD to control the LCD. I did modified the PICDEM2 plus board as follow:
Cut trace and add jumper RS ---- > RD2 of PICDEM2 Plus (org. this pin connected to RA3)
Cut trace and add jumper R/W --- > RD1 of PICDEM2 plus (org. this pin connected to RA2)
Cut trace and add jumper E ------ > RD0 of PICDEM2 plus (org. this pin connected to RA1).
I did the above modification due to I need to free more Analog channel on PORTA.
I modified the PICDEM2_LCD.C as follow:
Code: |
///////////////////////////////////////////////////////////////////////////
//// PICDEM2_LCD.C ////
//// Driver for common PICDEM2 PLUS 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 ////
//// ////
///////////////////////////////////////////////////////////////////////////
#define use_PICDEM2_lcd TRUE
#if defined use_PICDEM2_lcd
#define lcd_en PIN_D0 //It was PIN_A1
#define lcd_rw PIN_D1 //It was PIN_A2
#define lcd_rs PIN_D2 //It was PIN_A3
#define lcd_type 2 // 0=5x7, 1=5x10, 2=2 lines
#define lcd_line_two 0x40 // LCD RAM address for the second line
#define d_cycle 1
#endif
void lcd_send_nibble( BYTE n ) {
n=n&0x0f; //Strip off the top 4 bits.. This only sends bit 3:0
output_d(n);
delay_cycles(d_cycle);
output_high(lcd_en);
delay_us(20);
output_low(lcd_en);
}
BYTE lcd_read_byte() {
BYTE low,high;
output_high(lcd_rw);
delay_cycles(d_cycle);
output_high(lcd_en);
delay_cycles(d_cycle);
high = input_d(); //using d0:d3 for 4 bit data bus
output_low(lcd_en);
delay_cycles(d_cycle);
output_high(lcd_en);
delay_us(1);
low = input_d(); //using d0:d3 for 4 bit data bus
output_low(lcd_en);
return((high<<4) | low);
}
void lcd_send_byte( BYTE A0, BYTE n ) { //A0: 0=instruction, 1=Data
output_low(lcd_rs);
while ( bit_test(lcd_read_byte(),7) ) ; // wait until busy flag is low
if (A0==0){ output_low(lcd_rs);} //0=Instruction and 1=Data
if (A0==1){output_high(lcd_rs);} //0=Instruction and 1=Data
delay_cycles(d_cycle);
output_low(lcd_rw);
delay_cycles(d_cycle);
output_low(lcd_en);
lcd_send_nibble(n >> 4);
lcd_send_nibble(n & 0xf);
}
void lcd_init() {
BYTE const LCD_INIT_STRING[4] = {0x20 | (lcd_type << 2), 0xc, 1, 6};
// These bytes need to be sent to the LCD for initialization.
BYTE i;
//fprintf(debug,"Init!!\n\r");
output_low(lcd_rs);
output_low(lcd_rw);
output_low(lcd_en);
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 Data;
if(y!=1)
Data=lcd_line_two;
else
Data=0;
Data+=x-1;
lcd_send_byte(0,0x80|Data);
}
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
output_high(lcd_rs);
value = lcd_read_byte();
output_low(lcd_rs);
return(value);
}
|
I recompile the same code with the new modified driver and it does not
work. What else do I need to do in the driver in order for it to work?
Please help..... |
|
|
Mark
Joined: 07 Sep 2003 Posts: 2838 Location: Atlanta, GA
|
|
Posted: Mon Nov 22, 2004 12:59 pm |
|
|
Well, RD0-RD3 is used as the data bus for the LCD! So that's why it doesn't work. Make sense? |
|
|
cxiong
Joined: 09 Sep 2003 Posts: 52
|
|
Posted: Mon Nov 22, 2004 1:37 pm |
|
|
Now I change to pin 27, 28, and 29 which is RD4, RD5, RD6. and remodified the software as follow:
Code: |
#define use_PICDEM2_lcd TRUE
#if defined use_PICDEM2_lcd
#define lcd_en PIN_D4 //Pin 27 uP //It was PIN_A1
#define lcd_rw PIN_D5 //pin 28 uP //It was PIN_A2
#define lcd_rs PIN_D6 //pin 29 uP //It was PIN_A3
#define lcd_type 2 // 0=5x7, 1=5x10, 2=2 lines
#define lcd_line_two 0x40 // LCD RAM address for the second line
#define d_cycle 1
#endif
|
I only see a cursor flashing on the LCD.
Is there any else wrong? |
|
|
Mark
Joined: 07 Sep 2003 Posts: 2838 Location: Atlanta, GA
|
|
Posted: Mon Nov 22, 2004 11:21 pm |
|
|
Try this code:
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,1997 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. ////
////////////////////////////////////////////////////////////////////////////
// This structure is overlayed onto the data ports so that you may use
// whatever ports you desire
struct lcd_pin_map
{
int unusedA; // portA is not used
int unusedB; // portB is not used
int unusedC; // portC is not used
int data : 4; // lower nibble of portD is used for data lines
BOOLEAN enable; // PinD4
BOOLEAN rw; // PinD5
BOOLEAN rs; // PinD6
BOOLEAN dummy; // PinD7 is not used
} lcd;
#if defined(__PCH__)
#locate lcd = 0xF80
#else
#locate lcd = 5
#endif
struct lcd_tris_map
{
int unusedA; // portA is not used
int unusedB; // portB is not used
int unusedC; // portC is not used
int data : 4; // lower nibble of portD is used for data lines
int control : 3;
BOOLEAN dummy; // PinD7 is not used
} lcdtris;
#if defined(__PCH__)
#locate lcdtris = 0xF92
#else
#locate lcdtris = 0x85
#endif
#define set_tris_lcd(x) lcdtris.data = (x); lcdtris.control = 0;
#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.
#define LCD_WRITE 0 // For write mode all pins are out
#define LCD_READ 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);
lcd.rs=1;
value = lcd_read_byte();
lcd.rs=0;
return(value);
}
|
|
|
|
cxiong
Joined: 09 Sep 2003 Posts: 52
|
|
Posted: Tue Nov 23, 2004 7:15 am |
|
|
Thanks...
It works fine. |
|
|
vnkieuphong
Joined: 23 Jun 2005 Posts: 1 Location: Da Nang Viet Nam
|
PICDEM 2 Plus |
Posted: Thu Jun 23, 2005 1:32 am |
|
|
hi..
I think you have done the code to PICDEM 2 Plus....
Can help me show the wrong of my code for display voltage using PIC16F76...
here....PIC16F76
void voltmeter()
{
int8 AD_Result,temp;
while(!input(PIN_B0)); // while RB0, S3 is pressed. S3 and RB0
//LEDshare the same portb pin.
lcd_putc("\n RB0 = Exit ");
// setup_adc(ADC_CLOCK_INTERNAL);
setup_port_A(ALL_ANALOG); //A0 A1 A3 are analog - Ref=Vdd
setup_adc(ADC_CLOCK_INTERNAL);
set_adc_channel(0);
set_tris_B(0x00); //PortB output
set_tris_A(0x01); // A0 is an input pin
while(1)
{
delay_ms(25);
AD_Result= read_adc();
temp = ( AD_Result *5)/255;
printf(lcd_putc"'%f", float(temp)); //display AD_result on LCD
if (exit())
{
while (INPUT(PIN_B0) == 0); // We need to stay here until RB0 is released, or we'll jump right into the next menu option.
lcd_gotoxy( 1, 1 );
lcd_putc(" Voltmeter "); // Get the prompt back up for when we're out.
lcd_putc("\nRA4=Next RB0=Now");
return;
}
}
} |
|
|
snow
Joined: 05 Jul 2005 Posts: 2
|
Re: PICDEM 2 PLUS LCD driver source code. |
Posted: Tue Jul 05, 2005 5:03 am |
|
|
I would like to use the LCD on a PICDEM 2 PLUS with 16F876.
I modified the above code
Code: |
\lcd>diff PICDEM2_LCDorg.C PICDEM2_LCD.C
33c33
< output_d(n);
---
> output_b(n);
46c46
< high = input_d(); //using d0:d3 for 4 bit data bus
---
> high = input_b(); //using b0:b3 for 4 bit data bus
51c51
< low = input_d(); //using d0:d3 for 4 bit data bus
---
> low = input_b(); //using b0:b3 for 4 bit data bus
58c58
< while ( bit_test(lcd_read_byte(),7) ) ; // wait until busy flag is low
---
> // while ( bit_test(lcd_read_byte(),7) ) ; // wait until busy flag is low
|
and wrote the following code.
Code: |
#include <16F876.h>
#fuses HS,NOWDT,NOPROTECT,PUT,BROWNOUT,NOLVP
#use delay(CLOCK = 20000000)
#include <PICDEM2_LCD4776.c>
void main()
{
lcd_init();
while(1)
{
lcd_gotoxy(1,1);
printf(lcd_putc,"Hello, World!");
delay_ms(100);
}
}
|
But no characters show up on the LCD with J6 is off.
Please tell me what is wrong. |
|
|
Mark
Joined: 07 Sep 2003 Posts: 2838 Location: Atlanta, GA
|
|
Posted: Tue Jul 05, 2005 6:35 am |
|
|
If you use the code that I posted, it will work. I tested it before I posted it. |
|
|
snow
Joined: 05 Jul 2005 Posts: 2
|
|
Posted: Thu Jul 07, 2005 3:56 am |
|
|
Thanks Mark, it works fine!
My modification this time is
Code: |
lcd2>diff LCDDorg.c LCDD.c
32,39c32,37
< int unusedA; // portA is not used
< int unusedB; // portB is not used
< int unusedC; // portC is not used
< int data : 4; // lower nibble of portD is used for data lines
< BOOLEAN enable; // PinD4
< BOOLEAN rw; // PinD5
< BOOLEAN rs; // PinD6
< BOOLEAN dummy; // PinD7 is not used
---
> BOOLEAN dummy0; // PinA0 is not used
> BOOLEAN enable; // PinA1
> BOOLEAN rw; // PinA2
> BOOLEAN rs; // PinA3
> int dummy : 4; // PinA4:A7 are not used
> int data : 4; // lower nibble of portB is used for data lines
49,54c47,50
< int unusedA; // portA is not used
< int unusedB; // portB is not used
< int unusedC; // portC is not used
< int data : 4; // lower nibble of portD is used for data lines
< int control : 3;
< BOOLEAN dummy; // PinD7 is not used
---
> BOOLEAN dummy0; // PinA0 is not used
> int control : 3; // lower nibble of portA is used for command lines
> int dummy : 4; // PinA3:A7 are not used
> int data : 4; // lower nibble of portB is used for data lines
|
and the code is,
Code: |
#include <16F876.h>
#fuses HS,NOWDT,NOPROTECT,PUT,BROWNOUT,NOLVP
#use delay(CLOCK = 20000000)
#include <LCDD.c>
void main()
{
lcd_init();
while(1)
{
lcd_gotoxy(1,1);
printf(lcd_putc,"Hello,");
lcd_gotoxy(1,2);
printf(lcd_putc,"World!");
delay_ms(100);
}
}
|
J6 is off.
RB0 and RD0, RB1 and RD1, RB2 and RD2, RB3 and RD3 are connected for each by jumbers.
I'm awful glad! |
|
|
chingB
Joined: 29 Dec 2003 Posts: 81
|
|
Posted: Sat Aug 06, 2005 6:49 am |
|
|
I modify the code of Mark without using the #locate built-in preprocessor of the CCS compiler which is not supported with other PICmicro C-compilers.
Rather I use the method in C memory-mapped I/O.
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,1997 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. ////
////////////////////////////////////////////////////////////////////////////
// This structure is overlayed onto the data ports so that you may use
// whatever ports you desire
struct lcd_pin_map
{
int unusedA; // portA is not used
int unusedB; // portB is not used
int unusedC; // portC is not used
int data : 4; // lower nibble of portD is used for data lines
BOOLEAN enable; // PinD4
BOOLEAN rw; // PinD5
BOOLEAN rs; // PinD6
BOOLEAN dummy; // PinD7 is not used
} lcd;
#if defined(__PCH__)
#define lcd ((struct lcd_pin_map *)0xF80)
#else
#define lcd ((struct lcd_pin_map *)0x05)
#endif
struct lcd_tris_map
{
int unusedA; // portA is not used
int unusedB; // portB is not used
int unusedC; // portC is not used
int data : 4; // lower nibble of portD is used for data lines
int control : 3;
BOOLEAN dummy; // PinD7 is not used
} lcdtris;
#if defined(__PCH__)
#define lcdtris ((struct lcd_tris_map *)0xF92)
#else
#define lcdtris ((struct lcd_tris_map *)0x85)
#endif
#define set_tris_lcd(x) lcdtris->data = (x); lcdtris->control = 0;
#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.
#define LCD_WRITE 0 // For write mode all pins are out
#define LCD_READ 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);
lcd->rs=1;
value = lcd_read_byte();
lcd->rs=0;
return(value);
}
|
|
|
|
KevinMonk
Joined: 08 Aug 2005 Posts: 5
|
|
Posted: Tue Aug 09, 2005 3:09 am |
|
|
Why do I get a Error128 on line 31: A #device required before this line when I try compiling this code.
???
total newbie - Day 2. Got cwph, IDE and ICD2 installed yesterday. |
|
|
Mark
Joined: 07 Sep 2003 Posts: 2838 Location: Atlanta, GA
|
|
Posted: Tue Aug 09, 2005 6:29 am |
|
|
Most likely because you are using MPLAB and have added multiple source files to the project. For the CCS compiler, you can only have one source file listed. The other files must be included in the main source file. Search the General Discussion forum for tons of info on this. |
|
|
KevinMonk
Joined: 08 Aug 2005 Posts: 5
|
|
Posted: Tue Aug 09, 2005 9:10 am |
|
|
Works for me now.
Thanks. |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|