|
|
View previous topic :: View next topic |
Author |
Message |
saroch
Joined: 06 Oct 2004 Posts: 8
|
cannot use PIC16F877 with LCD |
Posted: Fri Oct 08, 2004 11:23 pm |
|
|
I'm using PIC16F877 with crystal 20MHz
and connect it to LCD with the following pin outs
RB4-RB7 --> D4-D7
RB0 --> E
RB1 --> RS
RB2 --> RW
and connect Vo (brightness) to ground without variable resistor
here is my code :
Code: |
#include <16F877.H>
#fuses XT, NOWDT, NOPROTECT, BROWNOUT, PUT, NOLVP
#use delay(clock = 20000000)
#include <lcd.c>
void main()
{
char a[11]="teststring";
lcd_init();
while(TRUE)
{
lcd_gotoxy(1,1);
printf(lcd_putc,"%s",a);
delay_ms(500);
}
}
|
but it doesn't work
i don't know why it is
thanks in advance |
|
|
saroch
Joined: 06 Oct 2004 Posts: 8
|
|
Posted: Fri Oct 08, 2004 11:25 pm |
|
|
here is my LCD.C
Code: |
As defined in the following structure the pin connection is as follows:
// B0 enable
// B1 rs
// B2 rw
// B3 bus_rw 0= gate external bus
// B4 D4
// B5 D5
// B6 D6
// B7 D7
//
// LCD pins D0-D3 are not used and PIC B3 is not used.
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; // nu // The bits are allocated from
BOOLEAN bus_rw; // low order up. ENABLE will
int data : 4; // be pin B0.
} lcd;
// bus_rw controls drive state of
// extern bus through 74125
// 0 gates bus
#byte lcd = 6 // This puts the entire structure
// on to port B (at address 6)
#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.
// changed following to make RB2 always input -- bit for init mode
STRUCT lcd_pin_map const LCD_WRITE = {0,0,1,0,0}; // For write mode all pins are out
STRUCT lcd_pin_map const LCD_READ = {0,0,1,0,15}; // For read mode data pins are in
byte lcd_read_bus() {
byte low,high;
set_tris_b(LCD_READ);
lcd.bus_rw = 0; // gate bus
delay_cycles(1);
low = lcd.data;
lcd.bus_rw = 1; // block bus
delay_cycles(1);
set_tris_b(LCD_WRITE);
return(low);
}
void lcd_send_nibble( byte n ) {
lcd.enable = 1;
delay_cycles(1);
lcd.data = n;
delay_us(2);
lcd.enable = 0;
}
void lcd_send_byte( byte address, byte n ) {
// address: 0=command, 1=data
lcd.enable = 0;
lcd.rs = address;
delay_cycles(1);
lcd_send_nibble(n >> 4);
lcd_send_nibble(n & 0xf);
delay_us(2);
}
void lcd_init() {
byte i;
set_tris_b(0xff); // all inputs
lcd.bus_rw = 1; // block bus
delay_cycles(2);
lcd.rs = 0;
lcd.enable = 0;
set_tris_b(LCD_WRITE);
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;
// y = line; 1 = 1st line, 2 = 2nd
if(y==1)
address=0;
else
address=lcd_line_two;
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;
}
}
#if 0
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);
}
#endif
|
|
|
|
Ttelmah Guest
|
|
Posted: Sat Oct 09, 2004 6:27 am |
|
|
Obvious comment, is are you sure your display supports having the bias voltage taken to GND?. This voltage adjusts the contrast, not the 'brightness', and on most displays a voltage below about 0.4v, makes the display invisible. The behaviour does vary between display makes. It may simply be that you cannot see the data on the display.
Best Wishes |
|
|
Mark
Joined: 07 Sep 2003 Posts: 2838 Location: Atlanta, GA
|
|
Posted: Sat Oct 09, 2004 9:33 am |
|
|
Why are you using a 74125?? Doesn't this prevent you from reading from the LCD? Why not drive the LCD directly? Your biggest problem is that the LCD is busy and that you are not waiting until it is ready. Refer to the CCS driver file LCD.C to see what I mean. Without this, you are going to have to add delays at just the right spots. Search the forum, I am sure others have done this. Personally I would never do it. It doesn't make for a very robust system IMHO. Also, if you are using a 20MHz osc then don't use XT in the fuses, use HS instead. |
|
|
saroch
Joined: 06 Oct 2004 Posts: 8
|
|
Posted: Sat Oct 09, 2004 11:38 am |
|
|
Quote: | Why are you using a 74125?? |
I'm not using 74125. I use only PIC and LCD ???
Quote: | if you are using a 20MHz osc then don't use XT in the fuses, use HS instead. |
I'm using #fuses HS instead but it still doesn't work !!!
pls help me |
|
|
Mark
Joined: 07 Sep 2003 Posts: 2838 Location: Atlanta, GA
|
|
Posted: Sat Oct 09, 2004 10:26 pm |
|
|
Then use the CCS lcd.c file
Code: |
#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);
}
|
|
|
|
saroch
Joined: 06 Oct 2004 Posts: 8
|
|
Posted: Sun Oct 10, 2004 2:59 am |
|
|
Got it !!
thanks very much for your help |
|
|
|
|
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
|