CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

PIC16F873A with LCD 16x4
Goto page 1, 2  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
Guest








PIC16F873A with LCD 16x4
PostPosted: Sun Nov 16, 2008 7:17 am     Reply with quote

Dear friends

i am working with pic16F873 and LCD device MC1604B-SBLW (16x4). I have tried the FlexLCD 4x20 driver from PCM Programer. But i've got no success. I have change all adresses but it does not work. Can somebody help me? should i post my code ?
Rohit de Sa



Joined: 09 Nov 2007
Posts: 282
Location: India

View user's profile Send private message Visit poster's website

PostPosted: Sun Nov 16, 2008 10:11 am     Reply with quote

Quote:
should i post my code
Umm, yes. Only if you post code, will we be able to help you out. Code and a circuit description, please. Also, have you worked with LCDs before? A 2x16 LCD, maybe?

Rohit
FvM



Joined: 27 Aug 2008
Posts: 2337
Location: Germany

View user's profile Send private message

PostPosted: Sun Nov 16, 2008 11:27 am     Reply with quote

You can try to change addresses, if the some characters aren't displayed at their correct location. If you don't get display operation at all, it's not a matter of line addresses, rather than of basic display connection. The said device is a Hitachi compatible LCD, it should work with this driver.
deniska_gus



Joined: 11 Jul 2006
Posts: 42
Location: Minden, Germany

View user's profile Send private message

PostPosted: Sun Nov 16, 2008 1:20 pm     Reply with quote

Thank you for your answer. I have worked with PIC16F877A and 2x16 LCD. It was very fine. But now i have PIC16F873a and i can not get it working.

So, here is the driver( by PCM Programmer):
Code:

// Flex_LCD416.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_DB4   PIN_B4
#define LCD_DB5   PIN_B5
#define LCD_DB6   PIN_B6
#define LCD_DB7   PIN_B7

#define LCD_RS    PIN_C4
#define LCD_RW    PIN_C5
#define LCD_E     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 0x10
#define LCD_LINE_4_ADDRESS 0x50

// 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


And now the test application also by PCM Programmer
Code:

#include <16F873A.H>
#fuses HS, NOWDT, NOPROTECT, BROWNOUT, PUT, NOLVP, NOCPD
#use delay(clock = 20000000)
#include "Flex_LCD416.c"

//===================================
void main()
{
int8 i;
int8 b1, b2, b3, b4;
setup_adc_ports (NO_ANALOGS);
delay_ms(50);

// The lcd_init() function should always be called once,
// near the start of your program.
lcd_init();

// Clear the LCD.
printf(lcd_putc, "\f");
delay_ms(500);


while(1)
  {
   // Test the clear screen and newline commands.
   // Also test that we can write to all 4 lines.
   printf(lcd_putc, "\fIts the 1st line");
   printf(lcd_putc, "\nIts the 2nd line");
   printf(lcd_putc, "\nIts the 3rd line");
   printf(lcd_putc, "\nAnd the 4th line");
   delay_ms(3000);

   // Test some additional characters.
   printf(lcd_putc, "\fABCDEFGHIJKLMNOP");
   printf(lcd_putc, "\nabcdefghijklmnop");
   printf(lcd_putc, "\n1234567890123456");
   printf(lcd_putc, "\n!@#$^&*(){}[]:;<");
   delay_ms(3000);

   // Clear the LCD.
   printf(lcd_putc, "\f");
   delay_ms(500);

   // Test that lcd_gotoxy() works.  Go to each of
   // the four corners and put a number in each one,
   // in a clockwise direction, starting with the upper
   // left corner.
   lcd_gotoxy(4, 2);       
   printf(lcd_putc, "Put a number in");   
   lcd_gotoxy(4, 3);       
   printf(lcd_putc, "each corner.");   
   lcd_gotoxy(1, 1);       
   printf(lcd_putc, "1");   
   lcd_gotoxy(16, 1);
   printf(lcd_putc, "2");   
   lcd_gotoxy(16, 4);
   printf(lcd_putc, "3");
   lcd_gotoxy(1, 4);       
   printf(lcd_putc, "4");   
   delay_ms(3000);

// Read the character that was written in each corner
// of the LCD and display it.   This tests the lcd_getc()
// function.   
// The following test can only be done if we can read
// from the LCD.  If the RW pin is not used, then the
// LCD is in write-only mode, and we can't do this test.
// The #ifdef statement will prevent the code from
// being compiled, in that case.

#ifdef USE_RW_PIN   
   // Test if lcd_getc() can read
   // a byte from each corner.
   b1 = lcd_getc(1,1);   
   b2 = lcd_getc(16,1);
   b3 = lcd_getc(16,4);
   b4 = lcd_getc(1,4);   
   lcd_gotoxy(1, 1);       
   printf(lcd_putc, "\fRead these bytes\n");
   printf(lcd_putc, "from the 4 corners:\n\n");
   printf(lcd_putc, "     %c %c %c %c", b1, b2, b3, b4);       
   delay_ms(3000);
#endif

   // Type some characters and backspace over them.
   printf(lcd_putc, "\fType characters and\n");
   printf(lcd_putc,   "backspace over them.");
   delay_ms(2000);

   // Go to end of 2nd line.
   lcd_gotoxy(16, 2);

   // Backspace over 2nd line.
   for(i = 0; i < 1; i++)
      {
       printf(lcd_putc," \b\b");
       delay_ms(150);
      }

   // Go to end of first line.               
   lcd_gotoxy(16, 1);

   // Backspace over first line.
   for(i = 0; i < 16; i++)
      {
       printf(lcd_putc," \b\b");
       delay_ms(150);
      }         

  }   

}


@FvM

Danke für Ihre Hilfe. Nun, die Pinbelegung ist so wie im Treiber angegeben ist. Ich glaube dass, das auch das Problem ist. Ich hatte früher 16F877 mit 2x16 zum Laufen gebracht. Bei diesem Controller habe ich damals PortD genutzt.Bei diesm Controller bin ich momentan ratlos.


Last edited by deniska_gus on Mon Nov 17, 2008 1:07 pm; edited 1 time in total
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sun Nov 16, 2008 1:24 pm     Reply with quote

For those working on this problem, this page has links to the data sheets:
http://uk.farnell.com/everbouquet/mc1604b-sblw/lcd-module-alphanumeric-16x4/dp/9449086



----
Edit: Fixed link


Last edited by PCM programmer on Mon Nov 17, 2008 1:03 pm; edited 1 time in total
deniska_gus



Joined: 11 Jul 2006
Posts: 42
Location: Minden, Germany

View user's profile Send private message

PostPosted: Sun Nov 16, 2008 1:54 pm     Reply with quote

I don't know. I have changed the addresses, but it's dead. :-(
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sun Nov 16, 2008 3:40 pm     Reply with quote

Quote:
but it's dead


1. Have you been able to make this 16F873A board do anything ?
Have you tried to make an LED blinking program for this board ?
Does it work ?

2. Is the LCD blank, or does it show black squares ?

3. Post a list of the wire connections between the PIC pins and the
LCD pins. Post the actual pin numbers (not just the signal names).

4. Post a description of the contrast circuit connected to LCD.

5. Measure the contrast voltage with a meter and post it.
deniska_gus



Joined: 11 Jul 2006
Posts: 42
Location: Minden, Germany

View user's profile Send private message

PostPosted: Mon Nov 17, 2008 12:48 pm     Reply with quote

Well,
1) Yes, i have let the led blinking. Its no problem.
2) The LCD is blank. It don't shows any changes if i turn the PIC on or off.
3) The connection between PIC and LCD:

LCD<------------------------------->PIC
1 ground
2 +5V
3 contrast voltage comes from the middle of 10k pot.
4 RS<------------------------------->16 PIN C4
5 RW<------------------------------->17 PIN C5
6 E <-------------------------------->18 PIN C6
7,8,9,10 are not connected
11 DB4<------------------------------> 25 PIN B4
12 DB5<------------------------------->26 PIN B5
13 DB6<------------------------------->27 PIN B6
14 DB7<-------------------------------->28 PIN B7
15 - Backlight
16 +Backlight

4) i have realized it with a 10k pot. The middle pin goes to the pin 3 of LCD. The other both to +5V and ground.

5) With this 10k pot i can make voltage between +5V and GND.

I hope you can understand my description. My englich is not good.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon Nov 17, 2008 1:07 pm     Reply with quote

Quote:
4 RS<------------------------------->16 PIN C4
5 RW<------------------------------->17 PIN C5
6 E <-------------------------------->18 PIN C6
7,8,9,10 are not connected
11 DB4<------------------------------> 25 PIN B4
12 DB5<------------------------------->26 PIN B5
13 DB6<------------------------------->27 PIN B6
14 DB7<-------------------------------->28 PIN B7

The listing above shows the control signals are on port C.
But your #define statements (shown below) from your
previously posted code have got them on port B:
Quote:

#define LCD_DB4 PIN_B4
#define LCD_DB5 PIN_B5
#define LCD_DB6 PIN_B6
#define LCD_DB7 PIN_B7

#define LCD_RS PIN_B4
#define LCD_RW PIN_B5
#define LCD_E PIN_B6
deniska_gus



Joined: 11 Jul 2006
Posts: 42
Location: Minden, Germany

View user's profile Send private message

PostPosted: Mon Nov 17, 2008 1:09 pm     Reply with quote

Yes, i have found this foul and changed this, but LCD has no function
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon Nov 17, 2008 1:13 pm     Reply with quote

Quote:
5) With this 10k pot i can make voltage between +5V and GND.

What is the voltage on the contrast pin ? You should adjust the pot
so that voltage is about 0.5 volts. Measure the voltage with a meter
to make sure that it is 0.5v.
deniska_gus



Joined: 11 Jul 2006
Posts: 42
Location: Minden, Germany

View user's profile Send private message

PostPosted: Mon Nov 17, 2008 1:17 pm     Reply with quote

Ok, its done. 0,5V

I have seen, the LCD gets 2 fields with black squares. ( Can you understand me?) I mean, the second and the last line are black and the other both not. Is it ok, or is my LCD dead.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon Nov 17, 2008 1:21 pm     Reply with quote

If you get black squares, the LCD is probably not being initialized correctly.

You are using pins B6 and B7 for the LCD. Do you have a debugger or
programmer connected to the board ? It uses those pins.
deniska_gus



Joined: 11 Jul 2006
Posts: 42
Location: Minden, Germany

View user's profile Send private message

PostPosted: Mon Nov 17, 2008 1:28 pm     Reply with quote

No, i have not any programmer or debugger, that is connected with the board. Thank you very much, PCM Programmer, for your help, but i think i will buy another PIC (16F877)tomorrow and i will test it with your original driver and code. This problem is to high for me, you understand.
deniska_gus



Joined: 11 Jul 2006
Posts: 42
Location: Minden, Germany

View user's profile Send private message

PostPosted: Mon Nov 17, 2008 1:49 pm     Reply with quote

My LCD has a controller SPLC780D. If you could look the datasheet of them on the page 11. It is a description from 4-Bit Interface for this controller.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page 1, 2  Next
Page 1 of 2

 
Jump to:  
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