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

Help PIC 16F876 And LCD 16X2
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
Rosmaninho



Joined: 16 Jan 2011
Posts: 23

View user's profile Send private message

Help PIC 16F876 And LCD 16X2
PostPosted: Sun Feb 27, 2011 12:09 pm     Reply with quote

Hi i'm trying to write a program, very simple program:

Code:
 
#include <16F876A.h>
#include <lcd.c>
#device adc=8

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES                       
#use delay(clock=20000000)




void main()
{

   setup_adc_ports(NO_ANALOGS);
   setup_adc(ADC_OFF);
   setup_spi(FALSE);
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
   setup_timer_1(T1_DISABLED);
   setup_timer_2(T2_DISABLED,0,1);
   setup_comparator(NC_NC_NC_NC);
   setup_vref(VREF_LOW|-2);
   
lcd_init();
delay_ms(5);   // <----- delays
lcd_putc("\f"); //Clear display
delay_ms(5);
lcd_gotoxy(1,1);
delay_ms(5);
lcd_putc("Champ");  // you want to send this to the lcd only once

while(TRUE)
{

// LCD Display //

delay_ms(1000);
}
   
   while(1)
   printf(lcd_putc, "\f Testing LCD     ");
   

}


And when i Compile the program, it give me Error in Source File, LCD.C


1 Errors, 0 Warnings.
Code:
Error[12]   C:\Program Files\PICC\drivers\lcd.c 106 : Undefined identifier  -- set_tris_lcd


Can anyone give me a help?
temtronic



Joined: 01 Jul 2010
Posts: 9229
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Mon Feb 28, 2011 8:48 am     Reply with quote

You may have a bad lcd.c file as there is no set_lcd_tris in my copy of lcd.c
Rosmaninho



Joined: 16 Jan 2011
Posts: 23

View user's profile Send private message

PostPosted: Mon Feb 28, 2011 9:48 am     Reply with quote

That's what i think...

I already change the LCD source file, to "LCD420.c" that was at PICC too, and I resolve it...

Thanks....
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon Feb 28, 2011 1:23 pm     Reply with quote

Quote:
You may have a bad lcd.c file as there is no set_lcd_tris in my copy of lcd.c

It's in lcd.c in vs. 4.119. The Examine32 text search program gives
these results:
Quote:

c:\program files\picc\drivers\lcd.c

#define set_tris_lcd(x) set_tris_b(x)

set_tris_lcd(LCD_INPUT_MAP);
set_tris_lcd(LCD_OUTPUT_MAP);
set_tris_lcd(LCD_OUTPUT_MAP);
set_tris_lcd(LCD_OUTPUT_MAP);



Quote:

I already change the LCD source file, to "LCD420.c" that was at PICC too, and I resolve it...

It may work, but the lcd.c driver is the best one to use for a 16x2 LCD.



Quote:
when i Compile the program, it give me Error in Source File, LCD.C

You forgot to put in the #include line for lcd.c. You need to add the line
shown in bold below:
Quote:

#include <16F876A.h>
#include <lcd.c>
#device adc=8

#FUSES NOWDT //No Watch Dog Timer
#FUSES
#use delay(clock=20000000)


#include <lcd.c>

void main()
{

Also you are missing your oscillator fuse. I suspect this is a Proteus project.
Rosmaninho



Joined: 16 Jan 2011
Posts: 23

View user's profile Send private message

PostPosted: Mon Feb 28, 2011 4:40 pm     Reply with quote

This is my "LCD.C"

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) Configurar as portas para o LCD, Alterado por Tony a 27-02-2011
#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);
}



I'm not finding the problem, the message:
Code:

Error[12]   C:\Program Files\PICC\drivers\lcd.c 93 : Undefined identifier  -- set_tris_lcd
[/code]
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon Feb 28, 2011 4:44 pm     Reply with quote

What port on the PIC is the LCD connected to ? Is it Port D, or Port B ?

Post a list of the connections between the LCD pins and the PIC pins.
Or post your Proteus schematic on a free image hosting service, and
then post a link to it.
Rosmaninho



Joined: 16 Jan 2011
Posts: 23

View user's profile Send private message

PostPosted: Mon Feb 28, 2011 5:39 pm     Reply with quote

Is connected at port B
http://www.e-rosmaninho.com/tese/my.jpg
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon Feb 28, 2011 5:54 pm     Reply with quote

I didn't notice that you had lcd.c included just below the PIC include line.
It's better if you put it in the location that I show below. But anyway, to
use PortB, you need to add the #define statement for 'use_portb_lcd' just
above the #include line for lcd.c, as shown below in bold:
Quote:

#include <16F876A.h>
#device adc=8
#FUSES HS, NOWDT
#use delay(clock=20000000)

#define use_portb_lcd TRUE
#include <lcd.c>


void main()
{
Rosmaninho



Joined: 16 Jan 2011
Posts: 23

View user's profile Send private message

PostPosted: Mon Feb 28, 2011 6:17 pm     Reply with quote

Thanks, it's working with this last help...
Rosmaninho



Joined: 16 Jan 2011
Posts: 23

View user's profile Send private message

PostPosted: Fri Apr 22, 2011 4:09 pm     Reply with quote

hi again.... i'm trying to test the program but the display seems to be dead. don't give me one sign of working....

in proteus, it works....

DISPLAYTECH 162B
LCD connections:

pin 1 -- Resistor---- +5v
pin 2 -- GND
pin 3 -- GND
pin 4 -- 5V
pin 5 -- 5V
pin 6 -- RB1
pin 7 -- RB2
pin 8 -- RB0
pin 9 -- NC
pin 10 NC
pin 11-- NC
pin 12 --NC
pin 13 RB4
pin 14 RB5
pin 15 RB6
pin 16 RB7

can you confirm if that's all ok?


this is my code:
Code:

#include <16F876A.h>
#device adc=8
#FUSES NOWDT                    //No Watch Dog Timer
#use delay(clock=20000000)
#define use_portb_lcd TRUE
#include <lcd.c>

//  Variaveis de Apoio
int a;
int b;
int c;

// Guarda Valor do ADC
float valor;

void main()
{
lcd_init();
set_adc_channel(0);
setup_adc(  ADC_CLOCK_INTERNAL  );
setup_port_a(ALL_ANALOG); // se port a to all analoges
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
setup_comparator(NC_NC_NC_NC);
setup_vref(VREF_LOW|-2);
set_tris_c (0b1111111); //0 - inputs | 1 - outputs


// Inicialização do Display
//lcd_init();
delay_ms(50);   // <----- delays
lcd_putc("\f "); //Clear display
delay_ms(50);
lcd_gotoxy(1,1);
delay_ms(50);
a=0;


// Publicidade
lcd_gotoxy(0,0);
lcd_putc( "\f E. Rosmaninho");
lcd_putc("\n Versao V0.1");
delay_ms(50);
lcd_gotoxy(1,0);
lcd_putc("\b Date 01/03/2011");
delay_ms(50);
lcd_gotoxy(1,0);
lcd_putc("\b Programmer: Tony    ");
delay_ms(50);
valor=0;






while (1) {

   // 1ª Leitura
   delay_ms( 50 );// SCAN TIME PAUSe, desactivado para ser mais rápido na simulação
   lcd_putc( "\f");
   valor = read_adc();
   valor= (2/10.24)*valor;

  // Termoestato Electrónico
   If (valor < 23 )
   {
       output_high(pin_C0);                     // Liga Aquecimento
       b=1; // Variável auxiliar aquecimento
       c=0; // Variável auxiliar alarme
       lcd_gotoxy(1,1);
       printf(lcd_putc,"Set Point: 25 C");
       lcd_gotoxy(1,2);
       printf(lcd_putc,"\nTemp: %.1fC\n", valor);
       delay_ms(100);}


   If (valor > 23 && valor < 27 && b==1 ) // A Aguardar que atinja a temperatura de desligar
   {
       lcd_gotoxy(1,1);
       printf(lcd_putc,"Set Point: 25 C");
       lcd_gotoxy(1,2);
       printf(lcd_putc,"\n Temp: %.1fC", valor);
       c=0;
delay_ms(100);
    }


   If (valor > 23 && valor < 27 && b==0 ) // Em espera para voltar a ligar
   {
       lcd_gotoxy(1,1);
       printf(lcd_putc,"Set Point: 25 C");
       lcd_gotoxy(1,2);
       printf(lcd_putc,"\nTemp: %.1fC\n", valor);
       output_low(pin_C1);
       c=0;
       delay_ms(100);} // Desliga o alarme



   If (valor > 27 && valor <40 && c==0) // Desliga o aquecimento
      {output_low(pin_C0);
      b=0;
      lcd_gotoxy(1,1);
      printf(lcd_putc,"Set Point: 25 C");
      lcd_gotoxy(1,2);
      printf(lcd_putc,"\nTemp: %.1fC\n", valor);
      delay_ms(100);}




    If (valor > 27 && valor <40 && c==1) // Vem de uma situação de alarme
      {output_low(pin_C0);
      b=0;
      lcd_gotoxy(1,1);
      printf(lcd_putc, "  !! ALARME !!  ");
      lcd_gotoxy(1,2);
      printf(lcd_putc,"\nTemp: %.1fC\n", valor);
      delay_ms(100);}



   while (valor > 40 ) // situação de alarme
   {
        valor = read_adc();
        valor= (2/10.24)*valor;
        output_low(pin_C0);
        output_high(pin_C1);
        b=0;
        c=1;
        lcd_gotoxy(1,1);
        printf(lcd_putc, "  !! ALARME !!  ");
        lcd_gotoxy(1,2);
        printf(lcd_putc,"\nTemp: %.1fC", valor);
        delay_ms(10);};

   }
}



in theory works... in the practice no :( is possible LCD burned?

regards
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Fri Apr 22, 2011 4:21 pm     Reply with quote

Quote:
in proteus, it works....

Proteus doesn't care about a lot of things that are important in real hardware.

Quote:
#FUSES NOWDT

Where is your oscillator fuse ? HS is needed.

Quote:
lcd_gotoxy(0,0);

The coordinates origin for the lcd.c driver is (1,1).
This is stated, right in the instructions at top of the driver file. Example:
Quote:
//// lcd_gotoxy(x,y) Set write position on LCD (upper left is 1,1)


Code:
pin 1 -- Resistor---- +5v
pin 2 -- GND
pin 3 -- GND
pin 4 -- 5V
pin 5 -- 5V
pin 6 -- RB1
pin 7 -- RB2
pin 8 -- RB0
pin 9 -- NC
pin 10 NC
pin 11-- NC
pin 12 --NC
pin 13 RB4
pin 14 RB5
pin 15 RB6
pin 16 RB7


There are at least two different pinouts for the 162B LCD.
In this one, pins A and K are on pins 15 and 16:
http://www.displaytech-us.com/pdf/FullSpecs/S162B-v11.pdf
In this one, they are on pins 1 and 2:
http://www.astlab.hu/pdfs/162b-series-lcd.pdf
Which one is correct ?
My advice is, get a different brand of LCD than DisplayTech. Get one
that has consistent documentation, where the pinouts are always the same.

Also I just noticed that you're using PortB, but you didn't do the changes
that I said in a previous post. Same with the HS fuse. So I guess I'm done with this.
Rosmaninho



Joined: 16 Jan 2011
Posts: 23

View user's profile Send private message

PostPosted: Fri Apr 22, 2011 4:33 pm     Reply with quote

i'm using the second one, the backlight switch in pin1 and 2
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Fri Apr 22, 2011 4:42 pm     Reply with quote

You have the Vo pin connected to +5v. That's the LCD contrast pin.
According to the data sheet, it should be set to approximately .2 to .5 volts.
If you set it to +5v, the LCD won't display properly.
Quote:

pin 1 -- Resistor---- +5v
pin 2 -- GND
pin 3 -- GND
pin 4 -- 5V
pin 5 -- 5V
pin 6 -- RB1
pin 7 -- RB2
pin 8 -- RB0
pin 9 -- NC
pin 10 NC
pin 11-- NC
pin 12 --NC
pin 13 RB4
pin 14 RB5
pin 15 RB6
pin 16 RB7

Also, if you have an ICD programmer connected to the board, the LCD
won't work. The ICD uses pins B6 and B7.
Rosmaninho



Joined: 16 Jan 2011
Posts: 23

View user's profile Send private message

PostPosted: Fri Apr 22, 2011 5:04 pm     Reply with quote

Sorry, what's a ICD programmer?

the PIN 5 I connect to GND, and the display already show anything....


its all ON
Rosmaninho



Joined: 16 Jan 2011
Posts: 23

View user's profile Send private message

PostPosted: Fri Apr 22, 2011 5:16 pm     Reply with quote

I see something like this in the 2 lines:

http://bp2.blogger.com/_27zDbRTyMD8/SGmGZ5Yk3UI/AAAAAAAAAMI/oCK_p6PsMkg/s1600-h/29062008227.jpg
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