hola, un saludo a todo el foro.
Intento visualizar la temperatura en un LCD de un proyecto ya hecho del libro "Compilador C CCS y simulador PROTEUS para microcontroladores PIC" y no funciona.
El libro viene con un cd donde viene el programa en c y el programa ya compilado (.hex) para cargarlo directamente en el pic. Tengo varios problemas.
-Aunque ya viene compilado, intento compilarlo yo para poderlo editar posteriormente y me sale el siguiente error:
Error 12 "c:\"archivodeprograma\PICC\drivers\lcd.c" line 91(29,30) undefined identifier -- set_tris_d
Error 12 "c:\"archivodeprograma\PICC\drivers\lcd.c" line 103(30,31) undefined identifier -- set_tris_d
Error 12 "c:\"archivodeprograma\PICC\drivers\lcd.c" line 133(28,29) undefined identifier -- set_tris_d
Da error la propia libreria que viene con el programa PCWHD Compiler
-Cargo el archivo .hex que viene en el cd en el pic para visualizar en el LCD y no sale nada. Solo se pone en negro la primera linea en el LCD
el conexionado del pic16f876 con el LCD es el siguiente
B0 enable
B1 rs
B2 rw
B4 D4
B5 D5
B6 D6
B7 D7
-Eso si, en la simulacion con el Proteus si que funciona.
Mis dudas son como puedo hacer para que al compilar el programa la libreria lcd.c no de error y como puedo hacer para visualizar en el display y no me salga la linea negra en el LCD.
Gracias de antemano.
Programa del termometro
#include "16f876.h"
#device adc=10
#fuses XT,NOWDT
#use delay(clock=4000000)
#include <math.h> //Necesaria para los cálculos matemáticos
#include <lcd.c>
void main() {
float tv,tr,temp,y; //Variables de ecuación
int16 value;
lcd_init();
// setup_port_a( ALL_ANALOG );
// setup_adc( ADC_CLOCK_INTERNAL );
// set_adc_channel( 0 );
delay_us(10);
do {
value = Read_ADC();
tv = 5.0 * value / 1024.0;
tr = tv * 10000.0 / (5.0 - tv);
y = log(tr/20000.0);
y = (1.0/298.15) + (y *(1.0/4050.0));
temp=1.0/y;
temp = temp -273.15;
printf(lcd_putc,"\nT = %04.2fC", temp);
} while (TRUE);
}
Libreria del LCD extraida del programa PCWHD Compiler lcd.c
//// 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 use_portb_lcd
//#locate lcd = getenv("sfr:PORTB") // This puts the entire structure over the port
#ifdef __pch__
#locate lcd = 0xf81
#else
#locate lcd = 6
#endif
#define set_tris_lcd(x) set_tris_b(x)
#else
//#locate lcd = getenv("sfr:PORTD") // This puts the entire structure over the port
#ifdef __pch__
#locate lcd = 0xf83
#else
#locate lcd = 8
#endif
#define set_tris_lcd(x) set_tris_d(x)
#endif
#ifndef lcd_type
#define lcd_type 2 // 0=5x7, 1=5x10, 2=2 lines
#endif
#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);
}
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);
}