|
|
View previous topic :: View next topic |
Author |
Message |
Guest
|
PICDEM 2 plus with new pinout for LCD |
Posted: Wed Jan 17, 2007 11:59 am |
|
|
Hello,
Just got in a new PICDEM2PLUS 2006 board, in which they have upgraded to a Rohs compliant LCD. In doing so it they have changed the pinout to the LCD using only PORTD as listed below. I am trying to modify the current LCD driver to work with this new LCD. The first step i took was changing the struct overlay as follows to meet the new board requirement.
DB4 = RD0
DB5 = RD1
DB6 = RD2
DB7 = RD3
RS = RD4
RW = RD5
E = RD6
Code: |
struct lcd_pin_map {
int data : 4;//rd0-rd3
BOOLEAN rs; //rd4
BOOLEAN rw; //rd5
BOOLEAN enable; //rd6
BOOLEAN unused; //rd7
} lcd; |
it looks like i can leave the tris pin map constants the same. After these changes the lcd will still not intialize. After looking at the asm lcd driver it looks like the setup up bytes are completely different from what they used to be. below is old and new
OLD LCD INIT:
Code: | LCDInit
clrf PORTA
banksel TRISA ;configure control lines
bcf LCD_E_DIR
bcf LCD_RW_DIR
bcf LCD_RS_DIR
movlw b'00001110'
banksel ADCON1
movwf ADCON1
movlw 0xff ; Wait ~15ms @ 20 MHz
banksel COUNTER
movwf COUNTER
movlw 0xFF
banksel delay
movwf delay
call DelayXCycles
decfsz COUNTER, F
goto $-3
movlw b'00110000' ;#1 Send control sequence
movwf temp_wr
bcf STATUS,C
call LCDWriteNibble
movlw 0xff ;Wait ~4ms @ 20 MHz
movwf COUNTER
movlw 0xFF
movwf delay
call DelayXCycles
decfsz COUNTER, F
goto $-3
movlw b'00110000' ;#2 Send control sequence
movwf temp_wr
bcf STATUS,C
call LCDWriteNibble
movlw 0xFF ;Wait ~100us @ 20 MHz
movwf delay
call DelayXCycles
movlw b'0011000' ;#3 Send control sequence
movwf temp_wr
bcf STATUS,C
call LCDWriteNibble
;test delay
movlw 0xFF ;Wait ~100us @ 20 MHz
movwf delay
call DelayXCycles
movlw b'00100000' ;#4 set 4-bit
movwf temp_wr
bcf STATUS,C
call LCDWriteNibble
call LCDBusy ;Busy?
movlw b'00101000' ;#5 Function set
movwf temp_wr
call i_write
movlw b'00001101' ;#6 Display = ON
movwf temp_wr
call i_write
movlw b'00000001' ;#7 Display Clear
movwf temp_wr
call i_write
movlw b'00000110' ;#8 Entry Mode
movwf temp_wr
call i_write
movlw b'10000000' ;DDRAM addresss 0000
movwf temp_wr
call i_write
; movlw b'00000010' ;return home
; movwf temp_wr
; call i_write
return
GLOBAL LCDInit |
NEW LCD INIT:
Code: | LCDInit
banksel TRISD
bcf TRISD,7
banksel PORTD
bsf PORTD,7
call Delay30ms
clrf PORTA
banksel TRISA ;configure control lines
bcf LCD_E_DIR
bcf LCD_RW_DIR
bcf LCD_RS_DIR
movlw b'00001110'
banksel ADCON1
movwf ADCON1
movlw 0xff ; Wait ~15ms @ 20 MHz
banksel COUNTER
movwf COUNTER
movlw 0xFF
banksel delay
movwf delay
call DelayXCycles
decfsz COUNTER, F
goto $-3
;0x02------------------
; movlw b'00110000' ;#1 Send control sequence
movlw b'00100000' ;#1 Send control sequence
movwf temp_wr
bcf STATUS,C
call LCDWriteNibble
movlw 0xff ;Wait ~4ms @ 20 MHz
movwf COUNTER
movlw 0xFF
movwf delay
call DelayXCycles
decfsz COUNTER, F
goto $-3
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;28---2
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; movlw b'00110000' ;#2 Send control sequence
movlw b'00100000' ;#2 Send control sequence
movwf temp_wr
bcf STATUS,C
call LCDWriteNibble
movlw 0xFF ;Wait ~100us @ 20 MHz
movwf delay
call DelayXCycles
;28--08
; movlw b'0011000' ;#3 Send control sequence
movlw b'10000000'
movwf temp_wr
bcf STATUS,C
call LCDWriteNibble
;test delay
movlw 0xFF ;Wait ~100us @ 20 MHz
movwf delay
call DelayXCycles
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;0C--0
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; movlw b'00100000' ;#4 set 4-bit
movlw b'00000000' ;#4 set 4-bit
movwf temp_wr
bcf STATUS,C
call LCDWriteNibble
;0x0C
movlw b'11000000' ;#4 set 4-bit
movwf temp_wr
bcf STATUS,C
call LCDWriteNibble
call Delay1ms
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;0x01
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; movlw b'00100000' ;#4 set 4-bit
movlw b'00000000' ;#4 set 4-bit
movwf temp_wr
bcf STATUS,C
call LCDWriteNibble
;0x01
movlw b'00010000' ;#4 set 4-bit
movwf temp_wr
bcf STATUS,C
call LCDWriteNibble
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
call LongDelay ;2ms
call LongDelay ;2ms
call LongDelay ;2ms
call LongDelay ;2ms
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;0x02
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
movlw b'00000000' ;#4 set 4-bit
movwf temp_wr
bcf STATUS,C
call LCDWriteNibble
;0x02
movlw b'00100000' ;#4 set 4-bit
movwf temp_wr
bcf STATUS,C
call LCDWriteNibble
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; rcall LCDBusy ;Busy?
call LongDelay ;2ms
call LongDelay ;2ms
call LongDelay ;2ms
call LongDelay ;2ms
call LongDelay ;2ms
call LongDelay ;2ms
call LongDelay ;2ms
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; call LCDBusy ;Busy?
;
; movlw b'00101000' ;#5 Function set
; movwf temp_wr
; call i_write
;
; movlw b'00001101' ;#6 Display = ON
; movwf temp_wr
; call i_write
;
; movlw b'00000001' ;#7 Display Clear
; movwf temp_wr
; call i_write
;
; movlw b'00000110' ;#8 Entry Mode
; movwf temp_wr
; call i_write
;
; movlw b'10000000' ;DDRAM addresss 0000
; movwf temp_wr
; call i_write
; movlw b'00000010' ;return home
; movwf temp_wr
; call i_write
movlw 0x4E
movwf temp_wr
call LCDBusy
bsf STATUS, C
call LCDWrite
call Delay1ms
return
GLOBAL LCDInit |
At this point I am not sure why there are many more configuration bytes being sent to the LCD, Is it a non-standara Hitachi LCD?? Has anyone implemented a working LCD driver for this LCD?? I guess its probably a an easy by changing and adding values to the LCD_INIT_STRING ?? Any input would be great!
Thanks |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed Jan 17, 2007 12:07 pm |
|
|
Try this driver in the Code Library. Change the pin list at the top of the
driver to fit the new PicDem2-Plus board. This will allow you to test if
the board is working.
http://www.ccsinfo.com/forum/viewtopic.php?t=24661 |
|
|
Guest
|
|
Posted: Wed Jan 17, 2007 12:20 pm |
|
|
I used the flex friver updation to correct pins as followw, and get the same results, it appears as if it is not initializing (light bars on first line).
Code: | #define LCD_DB4 PIN_D0
#define LCD_DB5 PIN_D1
#define LCD_DB6 PIN_D2
#define LCD_DB7 PIN_D3
#define LCD_RS PIN_D4
#define LCD_RW PIN_D5
#define LCD_E PIN_D6 |
By looking at the differences in the 2 assembly lcd init files, old to new, does it appear to you that the problem might be in the lcd init setup bytes?? |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed Jan 17, 2007 12:38 pm |
|
|
Download the manual for the new version of the board:
http://ww1.microchip.com/downloads/en/DeviceDoc/PICDEM_2_Plus_Users_Guide_51275c.pdf
It shows that they have added a power control pin for the LCD on pin D7
of the PIC. You have to set pin D7 to a logic high level to turn on the LCD.
To implement this, create a new constant called LCD_POWER and
put it with the other LCD #define statements at the start of the driver.
Then add a statement to set the power pin to a high level at the
beginning of the lcd_init() function. Example:
Quote: |
#define LCD_POWER PIN_D7
//----------------------------
void lcd_init(void)
{
int8 i;
output_high(LCD_POWER);
output_low(LCD_RS);
#ifdef USE_LCD_RW
output_low(LCD_RW);
#endif
output_low(LCD_E);
delay_ms(15); |
|
|
|
Mark
Joined: 07 Sep 2003 Posts: 2838 Location: Atlanta, GA
|
|
Posted: Wed Jan 17, 2007 2:09 pm |
|
|
I like to do it like this:
Code: |
struct lcd_pin_map
{
int data : 4;//rd0-rd3
BOOLEAN rs; //rd4
BOOLEAN rw; //rd5
BOOLEAN enable; //rd6
BOOLEAN power; //rd7
} lcd;
|
and access it like this:
You will also have to make sure the tris map has bit 7 as an output. |
|
|
fvnktion
Joined: 27 Jun 2006 Posts: 39
|
|
Posted: Wed Jan 17, 2007 3:16 pm |
|
|
Thanks much, that did the trick. Its been fun reading your guy's code and learning oodles from it (PCM and Mark). Here is the driver with modifications that works for the new PICDEM2 PLUS board (Rhos LCD)
Cheers and thanks again
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. ////
///////////////////////////////////////////////////////////////////////////
// Un-comment the following define to use port B
// #define use_portb_lcd TRUE
struct lcd_pin_map {
int data : 4;//rd0-rd3
BOOLEAN rs; //rd4
BOOLEAN rw; //rd5
BOOLEAN enable; //rd6
BOOLEAN power; //rd7
} 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_power PIN_D7
#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};
struct lcd_pin_map const LCD_READ = {15,0,0,0,0};
//reads data pins to see if busy, high data bit(rd3) high if busy, poll rd3
BYTE lcd_read_byte() {
BYTE low=0,high=0;
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>> 4);
lcd_send_nibble(n & 0xf);
}
void lcd_init() {
BYTE i;
lcd.power = TRUE;
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);
} |
|
|
|
mindstorm88
Joined: 06 Dec 2006 Posts: 102 Location: Montreal , Canada
|
|
Posted: Tue Feb 06, 2007 7:07 pm |
|
|
fvnktion wrote: | Here is the driver with modifications that works for the new PICDEM2 PLUS board (Rhos LCD)
|
Are you sure ?? few errors and missing stuff!!!! , Can you repost it ???
Thanks |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Feb 06, 2007 7:57 pm |
|
|
He didn't disable HTML when he posted it. That's the reason. |
|
|
Guest
|
|
Posted: Thu Feb 08, 2007 11:51 am |
|
|
Sorry about that, here is the code with html disabled at posting. By the way my version LCD is OCULAR OM16214.
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. ////
///////////////////////////////////////////////////////////////////////////
// Un-comment the following define to use port B
// #define use_portb_lcd TRUE
struct lcd_pin_map {
int data : 4;//rd0-rd3
BOOLEAN rs; //rd4
BOOLEAN rw; //rd5
BOOLEAN enable; //rd6
BOOLEAN power; //rd7
} 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_power PIN_D7
#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};
struct lcd_pin_map const LCD_READ = {15,0,0,0,0};
//reads data pins to see if busy, high data bit(rd3) high if busy, poll rd3
BYTE lcd_read_byte() {
BYTE low=0,high=0;
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;
lcd.power = TRUE;
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);
}
|
|
|
|
andrewz
Joined: 13 Nov 2010 Posts: 1
|
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19515
|
|
Posted: Sat Nov 13, 2010 10:29 am |
|
|
Er. What language is this bulletin board for?.
CCS C.
Does this answer your question?.
Best Wishes |
|
|
|
|
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
|