|
|
View previous topic :: View next topic |
Author |
Message |
Rosmaninho
Joined: 16 Jan 2011 Posts: 23
|
Help PIC 16F876 And LCD 16X2 |
Posted: Sun Feb 27, 2011 12:09 pm |
|
|
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: 9246 Location: Greensville,Ontario
|
|
Posted: Mon Feb 28, 2011 8:48 am |
|
|
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
|
|
Posted: Mon Feb 28, 2011 9:48 am |
|
|
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
|
|
Posted: Mon Feb 28, 2011 1:23 pm |
|
|
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
|
|
Posted: Mon Feb 28, 2011 4:40 pm |
|
|
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
|
|
Posted: Mon Feb 28, 2011 4:44 pm |
|
|
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
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Feb 28, 2011 5:54 pm |
|
|
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
|
|
Posted: Mon Feb 28, 2011 6:17 pm |
|
|
Thanks, it's working with this last help... |
|
|
Rosmaninho
Joined: 16 Jan 2011 Posts: 23
|
|
Posted: Fri Apr 22, 2011 4:09 pm |
|
|
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
|
|
Posted: Fri Apr 22, 2011 4:21 pm |
|
|
Quote: | in proteus, it works.... |
Proteus doesn't care about a lot of things that are important in real hardware.
Where is your oscillator fuse ? HS is needed.
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
|
|
Posted: Fri Apr 22, 2011 4:33 pm |
|
|
i'm using the second one, the backlight switch in pin1 and 2 |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Fri Apr 22, 2011 4:42 pm |
|
|
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
|
|
Posted: Fri Apr 22, 2011 5:04 pm |
|
|
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
|
|
|
|
|
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
|