Haz una pregunta
  Foros de Electrónica » Diseño digital » Microcontroladores y sistemas embebidos
Foros Registrarse ¿Olvidaste tu contraseña?

Temas similares

27/07/2011 #1


Mi primer proyecto. Crono-termostato, 16f876, lcd 16x2. Ayuda!!
Hola, soy nuevo en el foro. Quisiera compartir con vosotros un proyecto que estoy desarrollando, o al menos intentándolo. Llevo un par de meses liado con esto y por fin he conseguido que coja forma.

Se trata de un crono-termostato con curvas de temperatura ajustables mediante una interfaz lcd de 16x2. Está escrito en CCS utilizando un 16f876. Ahora estoy intentando hacerlo funcionar en el hardware. El diseño del esquemático y PCB los estoy haciendo en proteus. El sensor de temperatura originalmente es un LM35, aunque tengo aquí un par de lm335 que encontré en una tienda de mi localidad. No sé cual usaré en el diseño definitivo.

Os agradecería toda ayuda posible para terminarlo, me está trayendo muchos dolores de cabeza y ya se ha convertido en un reto personal conseguirlo. No seáis demasiado duros con los fallos que habré cometido, que seguro los hay. Es mi primera incursión en el mundo de la programación / electrónica así que podéis considerarme un completo novato.

Tengo varios problemas, pero el que me está trayendo de cabeza es el lcd. No hay manera de hacer que muestre algún carácter en pantalla. He leído que es un problema común y que los tiempos de espera son críticos para que funcionen correctamente, pero probe en una protoboard de montar el circuito y a aumentar los delays con muchas combinaciones y no conseguí hacerlo funcionar, ni en modo 4 ni 8 bits. Hice muchísimas pruebas hasta quemar el lcd al cablearlo mal en una de ellas, momento en el cual aparque el hardware para acabar el código hasta ahora que me toca pelearme de nuevo con el.

Ayer me llego un lcd nuevo y probé la primera versión de la pcb, pero esta vez acabé quemando el pic. No sé muy bien que paso, el micro parecía responder ya que la rutina de leds al comienzo se realizaba correctamente, pero no se veía nada en el lcd. Tan solo la primera línea llena de cuadros negros. Al cabo de varias pruebas empezó a oler a quemado, no sé cómo se quemo el pic pero sospecho que fue un corto al dejar algunas patitas de los componentes sin cortar en la parte posterior de la pcb.

En fin, os pego el código del programa junto con el esquemático y layout, a ver si alguien puede hacerme ver la luz al final del túnel. Perdonad si no está muy ordenado. También subo algunas fotos pero no tienen demasiada calidad.

Muchas gracias, un saludo


Código PHP:
//************************ Directivas para el compilador ***********************

#include <16f876.h>                      //PIC utilizado
#device *=16
#device adc=10
#fuses XT, NOWDT, PUT, NOPROTECT, NOBROWNOUT, NOLVP, NOCPD, NOWRT, NODEBUG//16F876
#use delay (clock=4000000)                 //Oscilador a 4Mhz
//#use delay (clock=20000000)                //Oscilador a 20Mhz
#include "lcd_16F876_delay.h"                   //Libreria LCD con delay
//#include "lcd_16F876.h"                           //Libreria LCD
#include "internal_eeprom.c"

#define rele 56
#define zumbador 57
#define pulsador_menu 42
#define pulsador_enter 43
#define pulsador_menos 44
#define pulsador_mas 45
#define LED1 61
#define LED2 60
#define LED3 59
#define LED4 58

#byte PORTA=0xD80                         //Dirección Puerto A
#byte PORTB=0xD81                         //Dirección Puerto B
#byte PORTC=0xD82                         //Dirección Puerto C
//#use fast_io(a)                           //Optimiza E/S del Puerto A
//#use fast_io(b)                           //Optimiza E/S del Puerto B
//#use fast_io(c)                           //Optimiza E/S del Puerto C

//******************************************************************************
//************************ Definición de funciones *****************************
//******************************************************************************

   
void leds(void);
   
void lcd_mensaje_inicial(void);
   
void lcd_mensaje_secundario(void);
   
void termostato (void);
   
void termometro (void);
   
void crono_termostato (void);
   
void tiempo1(void);
   
void crono1 (void);
   
void crono2 (void);
   
void crono3 (void);
   
void crono4 (void);
   
//******************************************************************************
//************************* Declaración de constantes:**************************
//******************************************************************************

const char mensaje[]= {   "For UAV construction"}; //Mensaje en movimiento
   
   
byte const N_Ints=30;    // Numero de interrupciones para 1 Segundo 4Mhz
//byte const N_Ints=150;     // Numero de interrupciones para 1 Segundo 20Mhz
byte const N_Ints2=500;  // Numero de interrupciones timer #2
   
//******************************************************************************
//*************************** Variables para timer0 ****************************
//******************************************************************************

char C_Ints=0;                         // Contador de Interrupciones ocurridas
char C_Ints2=2;
char Flag=0;                           // Flag que cambia cada NInterrupciones
char K=0;                              // Estado anterior del Flag
unsigned int segundos=00,minutos=00,horas=00//Variables contador cronómetro
unsigned long int segundos_completos;

//******************************************************************************
//************* Declaración de variables para curvas de temperatura*************
//******************************************************************************
unsigned int modo 1;
unsigned int16 Time1=5Time2=5Time3=5Time4=50;//Duración de curvas en minutos 
unsigned int8 Td1=20Td2=40Td3=20Td4=5;       //Temperatura deseada curvas

unsigned int temp_calculada;      //Temp deseada en cada momento de la curva       
unsigned int temp_actual;    //Temperatura actual calculada desde el sensor
unsigned int temp_inicio;         //Temperatura al inicio del ciclo      
unsigned int magnitud_rampa;      //Cantidad de grados a aumentar en cada curva
unsigned long int duracion_rampa//Duracion curva de temperatura en minutos

float Tc 0.0;  //  Variable en coma flotante para calcular rampa temperatura

int16 valor_sensor//        Valor descargado del sensor temperatura
   
//******************************************************************************
//********************* Bucle interrupciones (Timer 0)**************************
//******************************************************************************

#int_RTCC                 //  Interrupción por desbordamiento
void RTCC_isr() {         // del TIMER0 RTCC. Usado para reloj

   
if(++C_Ints==N_ints){
   
C_Ints=0x00;
   ++
segundos_completos;
      if(++
segundos>59){
      
segundos=0;
         if(++
minutos>59){
         
minutos=0;
            if(++
horas>23){
            
horas=0;
            }
         }
      }
   }
}

//*****************************************************************************
//********************* Bucle interrupciones (Timer 2)**************************
//******************************************************************************

#int_timer2
void timer2_isr() // TIMER2
{     
set_adc_channel);     
valor_sensor Read_ADC();           //Timer 2 usado para leer y actualizar 
temp_actual = (valor_sensor/2); //      temperatura del sensor
}

//******************************************************************************
//*************************** Programa principal *******************************
//******************************************************************************

void main() 
{

   
set_tris_A(0x3F);          //Establece puerto como entrada (3F : 6 pines)
   
set_tris_B(0x00);          //Establece puerto como salida 
   
set_tris_C(0x00);          //Establece puerto como salida
   #use fast_io(a)                           //Optimiza E/S del Puerto A
   #use fast_io(b)                           //Optimiza E/S del Puerto B
   #use fast_io(c)                           //Optimiza E/S del Puerto C


   
setup_counters(RTCC_INTERNAL,RTCC_DIV_128); // TIMER0: Clock Interno, Presescaler 128,una RTCC cada 33.3 milisegundos.
   
setup_timer_2 (T2_DIV_BY_161255); 
   
set_timer2 (0);
   
enable_interrupts(INT_RTCC);     // Habilito Interrupción RTCC
   
enable_interrupts(INT_TIMER2);   // Habilito Interrupción Timer2
   
enable_interrupts(global);       // Habilito Interrupciones Globalmente
   
setup_adc_ports(AN0);            // Puerto A0 analogico para LM35
   
setup_adcADC_CLOCK_INTERNAL ); // Reloj interno
   
set_adc_channel);
   
delay_us(10);

/*
   write_int16_eeprom (0x00, Time1);//   Almacena en la eeprom interna el
   write_int16_eeprom (0x08, Time2);//    valor definido en las variables
   write_int16_eeprom (0x10, Time3);//        de tiempo y temperatura
   write_int16_eeprom (0x18, Time4);//     Usar para reinicializar eeprom.

   write_eeprom (0x04, Td1);
   write_eeprom (0x0C, Td2);
   write_eeprom (0x14, Td3);
   write_eeprom (0x1C, Td4);
*/
   
Time1 read_int16_eeprom (0x00);   //Cargo variables de tiempo y temperatura
   
Td1   read_eeprom (0x04);         //   con los valores almacenados en 
   
Time2 read_int16_eeprom (0x08);   //     la eeprom interna del PIC
   
Td2   read_eeprom (0x0C);
   
Time3 read_int16_eeprom (0x10);
   
Td3   read_eeprom (0x14);
   
Time4 read_int16_eeprom (0x18);
   
Td4   read_eeprom (0x1C);

//******************************************************************************
//************************ Selección de FUNCIONES: *****************************
//******************************************************************************

   
output_low(rele);                                      //Inicializa LCD a mano
   
leds ();      //Rutina LEDS
   
delay_ms(100);
   
lcd_init();Delay_ms(100);                       //Inicializa LCD
   
lcd_mensaje_inicial();                          //Mensaje 01
   
lcd_mensaje_secundario();
   
while(
1)
{
switch(
modo)
{
case 
1//modo configuración
While(modo==1)
{
   if(
modo==1)
   {
   
output_low(LED3);
   
termometro();
   }
   if(
modo==1)
   { 
   
output_low(rele);
   
termostato();
   }
   if(
modo==1)
   {
   
output_low(rele);
   
crono_termostato();
   }
}

case 
2//modo ejecucion
   
if (modo==2)
   {
   
tiempo1();
   }
      else
      {
      
modo=1
      break;
      }
   if(
modo==2)
   {
   
output_low(LED3);
   
output_low(LED4);
   
crono1();
   }
      else
      {
      
modo=1
      break;
      }
   if(
modo==2)
   {
   
crono2();   
   }
      else
      {
      
modo=1
      break;
      }
   if(
modo==2)
   {
   
crono3();   
   }
      else
      {
      
modo=1
      break;
      }
   if(
modo==2)
   {
   
crono4();
   }
      else
      {
      
modo=1;
      break;
      }

   default:
   break;
}
}

}
      
//******************************************************************************
//******************************************************************************

//******************************************************************************
//******************************** FUNCIONES: **********************************
//******************************************************************************


void leds (void)                       //Inicialización leds 
{
   
int x=0;

   
output_high(zumbador);       
   
Delay_ms(100);
   
output_low(zumbador);
   
      for (
x=0x<7x++){
         
output_high(LED1);
         
output_high(LED2);
         
output_low (LED3); 
         
output_low (LED4);
         
delay_ms(300);

         
output_low(LED1);
         
output_low(LED2);
         
output_high (LED3); 
         
output_high (LED4);
         
delay_ms(300);
         ++
x;
         }
         
      
output_low (LED3);
      
output_low (LED4);
      
delay_ms(1000);

}         

void lcd_mensaje_inicial(void)         //Mensaje inicial
{      

   
output_high(Zumbador);       
   
Delay_ms(100);
   
output_low(Zumbador);
   
delay_ms(100);
         
   
Lcd_putc"\f");                 //Limpio lcd
   
lcd_gotoxy(4,1);
   
Lcd_putc ("mi nombre");      
   
delay_ms(10);
   
lcd_gotoxy(4,2);
   
Lcd_putc"empresa");
   
delay_ms(1000);
   
Lcd_putc"\f");                 //Limpio lcd   

}

void lcd_mensaje_secundario (void) {   //Mensaje secundario
         
   
output_high(zumbador);       
   
delay_ms(100);
   
output_low(zumbador);
   
delay_ms(300);
         
   
lcd_putc"\f");                 //Limpio lcd
   
lcd_gotoxy(1,1);                 
   
lcd_putc ("Departamento UAV");    
   
delay_ms(10);                  
      
   
lcd_gotoxy(1,2);                
   
lcd_putc"Termostato  v.01");    //Escribo...
   
delay_ms(2000);                 
   
lcd_putc"\f");                 //Limpio lcd
   
delay_ms (300);
}


void termometro (void)
{

output_high(LED1);
modo=2;

Lcd_putc"\f");                 //Limpio lcd
   
do{
      
      
lcd_gotoxy(4,1);
      
lcd_putc ("Termometro");
      
lcd_gotoxy(5,2);
      
printf(lcd_putc,"Temp: %02d     "temp_actual);
      if (
input(pulsador_menu)){delay_ms(300);modo=1;}
    }
  While(
modo==2);
}
void termostato (void){output_low(LED1);output_high(LED2);
Lcd_putc"\f");                 //Limpio lcd
temp_calculada=temp_actual;
int x=1;
   while(
input(pulsador_enter)!=1)
   {
      
lcd_gotoxy(4,1);
      
printf(lcd_putc,"Termostato");
      
lcd_gotoxy(5,2);
      
printf(lcd_putc,"Activar?");
      if (
input(pulsador_menu)){delay_ms(300);modo=1;return;}
      if (
input(pulsador_enter)){modo=1;x=2;}
   }

Lcd_putc"\f");                 //Limpio lcd
  
   
if (x==2)
   
output_high(LED4);
      
x=1;
      do{
      
lcd_gotoxy(1,1);
      
printf(lcd_putc,"Temp  actual:%02d          "temp_actual);
      
lcd_gotoxy(1,2);
      
printf(lcd_putc,"Temp deseada:%02d         "temp_calculada);
      
      if(
temp_calculada>temp_actual){output_high(rele);}
      else {
output_low(rele);}   
       
      if (
input(pulsador_menu)){delay_ms(300);modo=1;return;}
      if (
input(pulsador_menos)){--Temp_calculada;}
      if (
input(pulsador_mas)){++Temp_calculada;}
   
      }while(
input(pulsador_menu)!=1);
      
modo=1;
      
output_low(LED4);
      return;
   
   }

void crono_termostato (void){
      
output_low(LED2);
      
output_high(LED3);
      
Lcd_putc"\f");                 //Limpio lc
   
do{
      
lcd_gotoxy(1,1);
      
Lcd_putc ("Crono-termostato");      
      
delay_ms(10);
      
lcd_gotoxy(5,2);
      
Lcd_putc"Activar?");
      if (
input(pulsador_menu)){delay_ms(300);modo=1;return;}
      if (
input(pulsador_enter)){modo=2;return;}
      
   }
   While(
modo!=2);
}

void tiempo1 (void){
output_high(LED4);
   
Lcd_putc"\f");                 //Limpio lcd
do{
   
lcd_gotoxy(1,1);
   
printf(lcd_putc,"Time1:%luMinutos         " Time1);   
   
lcd_gotoxy(1,2);
   
printf(lcd_putc,"Temp :%02d Grados   " Td1); 

   if (
input(pulsador_menu)){modo=1; return;}
   if (
input(pulsador_menos)){Time1 Time1-5write_int16_eeprom (0x00Time1);}
   if (
input(pulsador_mas)){Time1 Time1+5write_int16_eeprom (0x00Time1);}
 }while(
input(pulsador_enter)!=1);
  

   
Lcd_putc"\f");                 //Limpio lcd
do{
   
lcd_gotoxy(1,1);
   
printf(lcd_putc,"Time :%luMinutos         " Time1);   
   
lcd_gotoxy(1,2);
   
printf(lcd_putc,"Temp1:%02d Grados   " Td1); 
   
   if (
input(pulsador_menu)){modo=1; return;}
   if (
input(pulsador_enter)){delay_ms(50);break;}
   if (
input(pulsador_menos)){Td1--, write_eeprom (0x04Td1);}
   if (
input(pulsador_mas)){Td1++, write_eeprom (0x04Td1);}
  
 }while(
input(pulsador_enter)!=1);
  

   
Lcd_putc"\f");                 //Limpio lcd
do{
   
lcd_gotoxy(1,1);
   
printf(lcd_putc,"Time2:%luMinutos         " Time2);   
   
lcd_gotoxy(1,2);
   
printf(lcd_putc,"Temp :%02d Grados   " Td2); 
   
   if (
input(pulsador_menu)){modo=1; return;}
   if (
input(pulsador_enter)){delay_ms(50);break;}
   if (
input(pulsador_menos)){Time2=Time2-5write_int16_eeprom (0x08Time2);}
   if (
input(pulsador_mas)){Time2=Time2+5write_int16_eeprom (0x08Time2);}

 }while(
input(pulsador_enter)!=1);
  

   
Lcd_putc"\f");                 //Limpio lcd
do{
   
lcd_gotoxy(1,1);
   
printf(lcd_putc,"Time :%luMinutos         " Time2);   
   
lcd_gotoxy(1,2);
   
printf(lcd_putc,"Temp2:%02d Grados   " Td2); 
   
   if (
input(pulsador_menu)){modo=1; return;}
   if (
input(pulsador_enter)){delay_ms(50);break;}
   if (
input(pulsador_menos)){Td2--, write_eeprom (0x0CTd2);}
   if (
input(pulsador_mas)){Td2++, write_eeprom (0x0CTd2);}

 }while(
input(pulsador_enter)!=1);
  

   
Lcd_putc"\f");                 //Limpio lcd
do{
   
lcd_gotoxy(1,1);
   
printf(lcd_putc,"Time3:%luMinutos         " Time3);   
   
lcd_gotoxy(1,2);
   
printf(lcd_putc,"Temp :%02d Grados   " Td3); 

   if (
input(pulsador_menu)){modo=1; return;}
   if (
input(pulsador_enter)){delay_ms(50);break;}
   if (
input(pulsador_menos)){Time3=Time3-5write_int16_eeprom (0x10Time3);}
   if (
input(pulsador_mas)){Time3=Time3+5write_int16_eeprom (0x10Time3);}

 }while(
input(pulsador_enter)!=1);
  

   
Lcd_putc"\f");                 //Limpio lcd
do{
   
lcd_gotoxy(1,1);
   
printf(lcd_putc,"Time :%luMinutos         " Time3);   
   
lcd_gotoxy(1,2);
   
printf(lcd_putc,"Temp3:%02d Grados   " Td3); 

   if (
input(pulsador_menu)){modo=1; return;}
   if (
input(pulsador_enter)){delay_ms(50);break;}
   if (
input(pulsador_menos)){Td3--, write_eeprom (0x14Td3);}
   if (
input(pulsador_mas)){Td3++, write_eeprom (0x14Td3);}

 }while(
input(pulsador_enter)!=1);

   
Lcd_putc"\f");                 //Limpio lcd
do{
   
lcd_gotoxy(1,1);
   
printf(lcd_putc,"Time4:%luMinutos         " Time4);   
   
lcd_gotoxy(1,2);
   
printf(lcd_putc,"Temp :%02d Grados   " Td4); 

   if (
input(pulsador_menu)){modo=1; return;}
   if (
input(pulsador_enter)){delay_ms(50);break;}
   if (
input(pulsador_menos)){Time4=Time4-5write_int16_eeprom (0x18Time4);}
   if (
input(pulsador_mas)){Time4=Time4+5write_int16_eeprom (0x18Time4);}

 }while(
input(pulsador_enter)!=1);
  

   
Lcd_putc"\f");                 //Limpio lcd
do{
   
lcd_gotoxy(1,1);
   
printf(lcd_putc,"Time :%luMinutos         " Time4);   
   
lcd_gotoxy(1,2);
   
printf(lcd_putc,"Temp4:%02d Grados   " Td4); 

   if (
input(pulsador_menu)){modo=1; return;}
   if (
input(pulsador_menu)){delay_ms(50);break;}
   if (
input(pulsador_menos)){Td4--, write_eeprom (0x1CTd4);}
   if (
input(pulsador_mas)){Td4++, write_eeprom (0x1CTd4);}
   
 }while(
input(pulsador_enter)!=1);
  
modo=2;break;
}

void crono1 (void){

minutos 0;
segundos 0;
segundos_completos =0;
temp_inicio=temp_actual;  //Temperatura al inicio del ciclo   
output_low(LED3);
output_high(LED1);
Lcd_putc"\f");                 //Limpio lcd

While(segundos_completos<=Time1*60)
{
   If(
Td1>=temp_inicio)
   {
      
magnitud_rampa = (float)Td1 temp_inicio;//total de grados a aumentar
      
duracion_rampa Time1*60;                //Duracion rampa 1 en segundos
      
float Dv1;
      
Dv1=(float)Magnitud_rampa/Duracion_rampa// Dv1 = Division1
      
Tc=0;
      
Tc = (float)Dv1*segundos_completos;
      
temp_calculada = (float) Tc temp_inicio;
      
lcd_gotoxy(1,1);
      
printf(lcd_putc,"Temp:%02d %02d:%02d:%02d     "temp_actual,horas,minutos,segundos);   
      
lcd_gotoxy(1,2);
      
printf(lcd_putc,"Calc:%02d C1:Td.%02d      "temp_calculada,Td1);
      if(
segundos>=59){Lcd_putc"\f");}
      if(
minutos>=59){Lcd_putc"\f");}
      if(
horas>=23){Lcd_putc"\f");}

      if(
temp_calculada>temp_actual){output_high(rele);}
      else {
output_low(rele);}
      if (
input(pulsador_menu)){modo=1;return;}
      if (
input(pulsador_enter)){break;}
      if (
input(pulsador_menos)){if(Td1>01){--Td1;}}
      if (
input(pulsador_mas)){if(Td1<99){++Td1;}}
   }

   Else If(
Td1<=temp_inicio){
      
         
magnitud_rampa = (float) temp_inicio Td1;//total de grados a disminuir
         
duracion_rampa Time1*60;                 //Duracion rampa 1 en segundos
         
float Dv1;
         
Dv1=(float)Magnitud_rampa/Duracion_rampa// Dv1 = Division1
         
Tc = (float)Dv1*segundos_completos;
         
temp_calculada = (float) temp_inicio Tc;
         
lcd_gotoxy(1,1);
         
printf(lcd_putc,"Temp:%02d %02d:%02d:%02d     "temp_actual,horas,minutos,segundos);     
         
lcd_gotoxy(1,2);
         
printf(lcd_putc,"Calc:%02d C1:Td.%02d      "temp_calculada,Td1);

         if(
segundos>=59){Lcd_putc"\f");         }
            if(
minutos>=59){Lcd_putc"\f");            }
               if(
horas>=23){Lcd_putc"\f");               }
   
   if (
input(pulsador_menu)){termometro();}
       if(
temp_calculada>temp_actual){output_high(rele);}
       else {
output_low(rele);}    
      
   if (
input(pulsador_menu)){modo=1;return;}
   if (
input(pulsador_enter)){break;}
   if (
input(pulsador_menos)){if(Td1>01){--Td1;}}
   if (
input(pulsador_mas)){if(Td1<99){++Td1;}}
   }
   }
}

void crono2 (void){

output_low(LED1);
output_high(LED2);
Segundos_completos=0;
While(
segundos_completos<=Time2*60){

   If(
Td2>=Td1)
   {
   
magnitud_rampa = (float)Td2 Td1;      //Cantidad total de grados a aumentar
   
duracion_rampa Time2*60;     
   
float Dv1;
   
Tc=0;
   
Dv1=(float)Magnitud_rampa/Duracion_rampa// Dv1 = Division1
   //Tc=(float) Tc + Td1;
   
Tc = (float)Dv1*segundos_completos;
   
temp_calculada = (float) Tc Td1;

   
lcd_gotoxy(1,1);
   
printf(lcd_putc,"Temp:%02d %02d:%02d:%02d     "temp_actual,horas,minutos,segundos);     
   
lcd_gotoxy(1,2);
   
printf(lcd_putc,"Calc:%02d C2 Td.%02d      "temp_calculada,Td2);
   if(
segundos>=59){Lcd_putc"\f");}
   if(
minutos>=59){Lcd_putc"\f");}
   if(
horas>=23){Lcd_putc"\f");}
 
   if(
temp_calculada>temp_actual){output_high(rele);}
   else {
output_low(rele);}
      if (
input(pulsador_menu)){modo=1;return;}
   if (
input(pulsador_enter)){break;}
   if (
input(pulsador_menos)){if(Td2>01){--Td2;}}
   if (
input(pulsador_mas)){if(Td2<99){++Td2;}}
   }

   Else If(
Td2<=Td1)
   {
      
magnitud_rampa = (float) Td1-Td2;   //Cantidad total de grados a disminuir
      
duracion_rampa Time2*60;     
      
float Dv1 1.0;
      
Dv1=(float)Magnitud_rampa/Duracion_rampa// Dv1 = Division1
      
Tc = (float)Dv1*segundos_completos;
      
temp_calculada = (float) Td1-Tc;

      
lcd_gotoxy(1,1);
      
printf(lcd_putc,"Temp:%02d %02d:%02d:%02d     "temp_actual,horas,minutos,segundos);     
      
lcd_gotoxy(1,2);
      
printf(lcd_putc,"Calc:%02d C2 Td.%02d      "temp_calculada,Td2);
      if(
segundos>=59){Lcd_putc"\f");}
      if(
minutos>=59){Lcd_putc"\f");}
      if(
horas>=23){Lcd_putc"\f");}
      
      if(
temp_calculada>temp_actual){output_high(rele);}
      else {
output_low(rele);}
      if (
input(pulsador_menu)){modo=1;return;}
      if (
input(pulsador_enter)){break;}
      if (
input(pulsador_menos)){if(Td2>01){--Td2;}}
      if (
input(pulsador_mas)){if(Td2<99){++Td2;}}
   }

}
}

void crono3 (void){

output_low(LED2);
output_high(LED3);

Segundos_completos=0;

While(
segundos_completos<Time3*60){
   If(
Td3>=Td2)
   {
      
magnitud_rampa = (float)Td3 Td2;  //Cantidad total de grados a aumentar
      
duracion_rampa Time3*60;     
      
float Dv1;
      
Dv1=(float)Magnitud_rampa/Duracion_rampa//     Dv1 = Division1
      
Tc = (float)Dv1*segundos_completos;
      
temp_calculada = (float) Tc Td2;
      
lcd_gotoxy(1,1);
      
printf(lcd_putc,"Temp:%02d %02d:%02d:%02d     "temp_actual,horas,minutos,segundos);     
      
lcd_gotoxy(1,2);
      
printf(lcd_putc,"Calc:%02d C3 Td.%02d      "temp_calculada,Td3);
      if(
segundos>=59){Lcd_putc"\f");}
      if(
minutos>=59){Lcd_putc"\f");}
      if(
horas>=23){Lcd_putc"\f");}
      if(
temp_calculada>temp_actual){output_high(rele);}
         else {
output_low(rele);}
      if (
input(pulsador_menu)){modo=1;return;}
      if (
input(pulsador_enter)){break;}
      if (
input(pulsador_menos)){if(Td3>01){--Td3;}}
      if (
input(pulsador_mas)){if(Td3<99){++Td3;}}
   }

   Else If(
Td3<=Td2)
   {
      
magnitud_rampa = (float) Td2-Td3;   //Cantidad total de grados a disminuir
      
duracion_rampa Time3*60;     
      
float Dv1 1.0;
      
Dv1=(float)Magnitud_rampa/Duracion_rampa//     Dv1 = Division1
      
Tc = (float)Dv1*segundos_completos;
      
temp_calculada = (float) Td2-Tc;
      
lcd_gotoxy(1,1);
      
printf(lcd_putc,"Temp:%02d %02d:%02d:%02d     "temp_actual,horas,minutos,segundos);     
      
lcd_gotoxy(1,2);
      
printf(lcd_putc,"Calc:%02d C3 Td.%02d      "temp_calculada,Td3);
      if(
segundos>=59){Lcd_putc"\f");}
      if(
minutos>=59){Lcd_putc"\f");}
      if(
horas>=23){Lcd_putc"\f");}            
      if(
temp_calculada>temp_actual){output_high(rele);}
         else {
output_low(rele);}
      if (
input(pulsador_menu)){modo=1;return;}      
      if (
input(pulsador_enter)){break;}
      if (
input(pulsador_menos)){if(Td3>01){--Td3;}}
      if (
input(pulsador_mas)){if(Td3<99){++Td3;}}
   }
}
}

void crono4 (void){

output_low(LED3);
output_high(LED4);

Segundos_completos=0;
   
   While(
segundos_completos<Time4*60)
   {
      If(
Td4>=Td3)
      {
      
magnitud_rampa = (float)Td4 Td3;  //Cantidad total de grados a aumentar
      
duracion_rampa Time4*60;     
      
float Dv1;
      
Dv1=(float)Magnitud_rampa/Duracion_rampa//     Dv1 = Division1
      
Tc = (float)Dv1*segundos_completos;
      
temp_calculada = (float) Tc Td3;
      
lcd_gotoxy(1,1);
      
printf(lcd_putc,"Temp:%02d %02d:%02d:%02d     "temp_actual,horas,minutos,segundos);     
      
lcd_gotoxy(1,2);
      
printf(lcd_putc,"Calc:%02d C4 Td.%02d      "temp_calculada,Td4);
      if(
segundos>=59){Lcd_putc"\f");}
      if(
minutos>=59){Lcd_putc"\f");}
      if(
horas>=24){Lcd_putc"\f");}
      
      if(
temp_calculada>temp_actual){output_high(rele);}
      else {
output_low(rele);}
      if (
input(pulsador_enter)){break;}
      if (
input(pulsador_menu)){modo=1;break;}
      if (
input(pulsador_menos)){if(Td4>01){--Td4;}}
      if (
input(pulsador_mas)){if(Td4<99){++Td4;}}
      }
      Else If(
Td4<=Td3)
      {
      
magnitud_rampa = (float) Td3-Td4;  //Cantidad total de grados a disminuir
      
duracion_rampa Time4*60;     
      
float Dv1 1.0;
      
Dv1=(float)Magnitud_rampa/Duracion_rampa//     Dv1 = Division1
      
Tc = (float)Dv1*segundos_completos;
      
temp_calculada = (float) Td3-Tc;

      
lcd_gotoxy(1,1);
      
printf(lcd_putc,"Temp:%02d %02d:%02d:%02d     "temp_actual,horas,minutos,segundos);     
      
lcd_gotoxy(1,2);
      
printf(lcd_putc,"Calc:%02d C4 Td.%02d      "temp_calculada,Td4);
      if(
segundos>=59){Lcd_putc"\f");}
      if(
minutos>=59){Lcd_putc"\f");}
      if(
horas>=23){Lcd_putc"\f");}

      if(
temp_calculada>temp_actual){output_high(rele);}
      else {
output_low(rele);}
      if (
input(pulsador_menu)){modo=1;break;}
      if (
input(pulsador_enter)){break;}
      if (
input(pulsador_menos)){if(Td4>01){--Td4;}}
      if (
input(pulsador_mas)){if(Td4<99){++Td4;}}
      }
   }

output_low(rele);
minutos 0;
segundos 0;
segundos_completos =0;
int Temp_end;
Temp_end=temp_actual;
Lcd_putc"\f");
Output_low(LED4);
Segundos_completos=0;
   While(
TRUE)
   {
      
lcd_gotoxy(1,1);
      
printf(lcd_putc,"Fin %02d:%02d:%02d %02dc      "horas,minutos,segundos,Temp_end);     
      
lcd_gotoxy(5,2);
      
printf(lcd_putc,"Deseada: %02dc         "Td4);
      if (
input(pulsador_menu)){modo=1;break;}
      

   }

}

//******************************************************************************
//***************************** FIN DE PROGRAMA ********************************
//****************************************************************************** 
Olvidaba los adjuntos
28/07/2011 #2


Hola,
tengo una version de proteus distinta al tuyo por lo tanto no puedo abrir el archivo que pusiste, podrias exportar el circuito como grafico y ponerlo para poder ver el circuito.
Ademas podrias poner el programa completo con los include incluidos, sino, no lo puedo probar.

Saludos
28/07/2011 #3


Aqui tienes:

Libreria original ccs:

Código:
#bit lcd_enable = 7.7
//#bit lcd_rw = 7.1 //Desabilitar para poner a masa RW
#bit lcd_rs = 7.6
#byte lcd_a = 7 //portc
#byte lcd_b = 6 //portb


#define LCD_LINEA2 0x40 // Direccion de memoria para la segunda linea
#define LCD_DATO 1
#define LCD_COMANDO 0

#define LCD_CLEAR 0x01
#define LCD_HOME 0x02

#define LCD_DISPLAY_OFF 0x08
#define LCD_DISPLAY_ON 0x0f
#define LCD_CURSOR_ON 0x0E
#define LCD_CURSOR_BLINK 0x0F

#define LCD_CURSOR_SHIFT_RIGHT 0x10
#define LCD_CURSOR_SHIFT_LEFT 0x14
#define LCD_DISPLAY_SHIFT_RIGHT 0x18
#define LCD_DISPLAY_SHIFT_LEFT 0x1C


int lcd_leer()
{
int valor;

//set_tris_c(0x00);
set_tris_b(0xFF);

//lcd_rw = 1;
delay_ms(5);
lcd_enable = 1;
delay_ms(5);
valor = lcd_b;
delay_ms (5);
lcd_enable = 0;
delay_ms (5);

set_tris_b(0x00);
delay_ms (5);
return valor;
}


void lcd_enviar(int dir, int valor)
{
//set_tris_c(0x00);
//set_tris_b(0x00);

lcd_rs = 0;
while( bit_test(lcd_leer(),7) );
lcd_rs = dir;


//lcd_rw = 0;
delay_ms(10);
lcd_enable = 0;
lcd_b = valor;
delay_ms(10);
lcd_enable = 1;
delay_ms(50);
lcd_enable = 0;
delay_ms(10);
}


void lcd_init()
{
int i;
delay_ms (40);
set_tris_c(0x00);
set_tris_b(0x00);

lcd_enable = 0;
delay_ms(1);
//lcd_rw = 0;
lcd_rs = 0;
delay_ms(40);


for(i=0; i<3; i++)
{
lcd_enviar(LCD_COMANDO,0x38);
delay_ms(25);
lcd_enviar(LCD_COMANDO,LCD_DISPLAY_ON);
delay_ms(25);
lcd_enviar(LCD_COMANDO,0x06);
delay_ms(25);
lcd_enviar(LCD_COMANDO,LCD_CLEAR);
delay_ms(25);
lcd_enviar(LCD_COMANDO,LCD_HOME);
delay_ms(400);
}
}

void lcd_gotoxy( byte x, byte y) {
byte dir;

if(y!=1)
dir=LCD_LINEA2;
else
dir=0;
dir+=x-1;
lcd_enviar(LCD_COMANDO,0x80|dir);
delay_ms(50);
}


void lcd_putc( char c) {switch (c) {
case '\f' : lcd_enviar(LCD_COMANDO,0x01);
delay_ms(50);
break;
case '\n' : lcd_gotoxy(1,2); break;
delay_ms(50);
case '\b' : lcd_enviar(LCD_COMANDO,0x10); break;
delay_ms(50);
default : lcd_enviar(LCD_DATO,c); break;

delay_ms(500);
}
}
Esta es la versión con delays, le he aumentado de manera significativa todos los que había y incluso añadido alguno adicional. Va tan lenta que en la simulación se muestran los caracteres uno a uno aun así en el hardware no funciona.

Código:
 #bit lcd_enable = 7.7
//#bit lcd_rw = 7.1 //Desabilitar para poner a masa RW
#bit lcd_rs = 7.6
#byte lcd_a = 7 //portc
#byte lcd_b = 6 //portb


#define LCD_LINEA2 0x40 // Direccion de memoria para la segunda linea
#define LCD_DATO 1
#define LCD_COMANDO 0

#define LCD_CLEAR 0x01
#define LCD_HOME 0x02

#define LCD_DISPLAY_OFF 0x08
#define LCD_DISPLAY_ON 0x0C
#define LCD_CURSOR_ON 0x0E
#define LCD_CURSOR_BLINK 0x0F

#define LCD_CURSOR_SHIFT_RIGHT 0x10
#define LCD_CURSOR_SHIFT_LEFT 0x14
#define LCD_DISPLAY_SHIFT_RIGHT 0x18
#define LCD_DISPLAY_SHIFT_LEFT 0x1C


int lcd_leer()
{
int valor;

set_tris_c(0x00);
set_tris_b(0xFF);

//lcd_rw = 1;
delay_us(150);
lcd_enable = 1;
delay_us(100);
valor = lcd_b;
delay_us (50);
lcd_enable = 0;
delay_us (50);

set_tris_b(0x00);
delay_us (50);
return valor;
}


void lcd_enviar(int dir, int valor)
{
set_tris_c(0x00);
set_tris_b(0x00);

lcd_rs = 0;
while( bit_test(lcd_leer(),7) );
lcd_rs = dir;


//lcd_rw = 0;
delay_ms(1);
lcd_enable = 0;
lcd_b = valor;
delay_ms(1);
lcd_enable = 1;
delay_ms(1);
lcd_enable = 0;
delay_ms(1);
}


void lcd_init()
{
int i;
delay_ms (40);
set_tris_c(0x00);
set_tris_b(0x00);

lcd_enable = 0;
delay_ms(1);
//lcd_rw = 0;
lcd_rs = 0;
delay_ms(40);


for(i=0; i<3; i++)
{
lcd_enviar(LCD_COMANDO,0x38);
delay_ms(25);
}
lcd_enviar(LCD_COMANDO,LCD_DISPLAY_ON);
delay_ms(1);
lcd_enviar(LCD_COMANDO,0x06);
delay_ms(1);
lcd_enviar(LCD_COMANDO,LCD_CLEAR);
delay_ms(1);
lcd_enviar(LCD_COMANDO,LCD_HOME);
delay_ms(1);
}


void lcd_gotoxy( byte x, byte y) {
byte dir;

if(y!=1)
dir=LCD_LINEA2;
else
dir=0;
dir+=x-1;
lcd_enviar(LCD_COMANDO,0x80|dir);
delay_ms(5);
}


void lcd_putc( char c) {
switch (c) {
case '\f' : lcd_enviar(LCD_COMANDO,0x01);
delay_ms(50);
break;
case '\n' : lcd_gotoxy(1,2); break;
case '\b' : lcd_enviar(LCD_COMANDO,0x10); break;
default : lcd_enviar(LCD_DATO,c); break;
}
}
Y la librería para trabjar con la eeprom:

Código PHP:
#ifndef INTERNAL_EEPROM_UTILITIES
#define INTERNAL_EEPROM_UTILITIES

// Used to adjust the address range
#ifndef INT_EEPROM_ADDRESS
#define INT_EEPROM_ADDRESS  int8
#endif

////////////////////////////////////////////////////////////////////////////////
//// Internal EEPROM Functions
////////////////////////////////////////////////////////////////////////////////

// Purpose:    Write one bit to internal eeprom
// Inputs:     1) An eeprom address
//             2) The bit position (LSB == 0)
//             3) The bit to write
// Outputs:    None
void write_int1_eeprom(INT_EEPROM_ADDRESS addressint8 bitPositionint1 data)
{
   
int8 stored_data;

   
stored_data read_eeprom(address);

   if(
data)
   {
      
bit_set(stored_databitPosition);
   }
   else
   {
      
bit_clear(stored_databitPosition);
   }

   
write_eeprom(addressstored_data);
}


// Purpose:    Read one bit from internal eeprom
// Inputs:     1) An eeprom address
//             2) The bit position (LSB == 0)
// Outputs:    The bit read from internal eeprom
int1 read_int1_eeprom(INT_EEPROM_ADDRESS addressint8 bitPosition)
{
   return 
bit_test(read_eeprom(address), bitPosition);
}


// Purpose:    Write a 16 bit number to internal eeprom
// Inputs:     1) An eeprom address
//             2) The 16 bit number to write to internal eeprom
// Outputs:    None
void write_int16_eeprom(INT_EEPROM_ADDRESS addressint16 data)
{
   
int8 i;

   for(
02; ++i)
   {
     
write_eeprom(address i, *((int8 *)(&data) + i));
   }
}


// Purpose:    Read a 16 bit number from internal eeprom
// Inputs:     An eeprom address
// Outputs:    The 16 bit number read from internal eeprom
int16 read_int16_eeprom(INT_EEPROM_ADDRESS address)
{
   
int8  i;
   
int16 data;

   for(
02; ++i)
   {
     *((
int8 *)(&data) + i) = read_eeprom(address i);
   }

   return(
data);
}


// Purpose:    Write a 32 bit integer to internal eeprom
// Inputs:     1) An eeprom address
//             2) The 32 bit number to write to internal eeprom
// Outputs:    None
void write_int32_eeprom(INT_EEPROM_ADDRESS addressint32 data)
{
   
int8 i;

   for(
04; ++i)
   {
     
write_eeprom(address i, *((int8 *)(&data) + i));
   }
}


// Purpose:    Read a 32 bit integer from internal eeprom
// Inputs:     An eeprom address
// Outputs:    The 32 bit integer read from internal eeprom
int32 read_int32_eeprom(INT_EEPROM_ADDRESS address)
{
   
int8  i;
   
int32 data;

   for(
04; ++i)
   {
     *((
int8 *)(&data) + i) = read_eeprom(address i);
   }

   return 
data;
}


// Purpose:    Write a floating point number to internal eeprom
// Inputs:     1) An eeprom address. Four eeprom locations will be used.
//             2) The floating point number to write to internal eeprom
// Outputs:    None
void write_float_eeprom(INT_EEPROM_ADDRESS addressfloat data)
{
   
int8 i;

   for(
04; ++i)
   {
     
write_eeprom(address i, *((int8 *)(&data) + i));
   }
}


// Purpose:    Read a floating point number from internal eeprom
// Inputs:     An eeprom address
// Outputs:    The floating point number read from the internal eeprom
float read_float_eeprom(INT_EEPROM_ADDRESS address)
{
   
int8 i;
   
float data;

   for(
04; ++i)
   {
     *((
int8 *)(&data) + i) = read_eeprom(address i);
   }

   return 
data;
}

#endif 
Por último el esquemático:
Archivos Adjuntos
Tipo de Archivo: rar Esquemático en JPG.rar (339,3 KB (Kilobytes), 33 visitas)
28/07/2011 #4


OK, veremos el tema del display
29/07/2011 #5


Sería una gran ayuda, gracias por el interés
29/07/2011 #6


Hola, simule el lcd en proteus y funciona bien, en esta parte no deberias tener problemas.
Te muestro una imagen para que veas.


esta probado con el codigo original de ccs.
29/07/2011 #7


No me habré explicado bien, en proteus lo tengo funcionando todo bien.

El problema lo tengo al hacerlo funcionar en el hardware real, no hay manera de que muestra algo por pantalla.

Adjunto datasheet del LCD que estoy usando por si sirve de algo:

http://www.farnell.com/datasheets/653676.pdf

Un saludo
29/07/2011 #8


Bueno, revisa todas las tensiones del micro la vdd y la mclr y trata de ver si oscila y tambien la del lcd talvez haya alguna soldadura o conexion que no esta bien

Fijate si las conexiones RS E y RW se conectan como dice el esquema, no puedo identificar bien estas conexiones con las fotos del impreso.
29/07/2011 #9


El programa creo que corre bien en el micro. Esto lo se porque he añadido en diferentes partes del programa la orden de encender un led y funciona. El oscilador también está funcionando y las tensiones son correctas, medido con osciloscopio. Por cierto en el esquemático hay un error, a mclr en realidad le tengo puesta una R de 10k a 5v.

Estoy convencido de que es problema de código, por lo que he leído sospecho de la librería. El pcb que he construido coincide con el esquemático de proteus y las conexiones están todas correctas. También probé de hacer funcionar el lcd con un 16f84 en una protoboard y tuve el mismo problema.

Saludos

Las conexiones RS, RW y E están bien, las tengo tal y como lo has simulado en proteus.
29/07/2011 #10


ok, voy a comparar las librerias con unas mias que funcionan bien y te comento.
04/08/2011 #11


Hola

Ya tengo un PIC para sustituir al que se quemó pero estoy probandolo y no hay manera de hacer que funcione en la placa.. Estoy bastante desesperado :enfadado: He invertido ya cientos de horas en esto y me encuentro parado por culpa del maldito LCD.

Esta mañana hice un pequeño programita que mostrase algo en la pantalla sin mas parafernalia, para simplificar todo al máximo y tampoco me funciona.

Ricber ¿pudiste mirar lo de las librerías? Agradecería mucho si alguien tiene una que funcione o me puede encaminar hacia una solución..

Muchras gracias
Saludos,
04/08/2011 #12


Perdona que te prometi lo de las librerias, se me olvido, las estoy viendo ahora pero son para c18 que es el compilador de microchip para la serie 18F....

Podria hacer el fin de semana una prueba en mi placa de pruebas, pero tiene otro micro
asi que si el codigo se adapta hago una prueba
05/08/2011 #13


Muchas gracias ricber, de todos modos....

YA FUNCIONA!! :apla uso:

Estoy super contento!!

Cambié de librería, he puesto la flex_lcd. Ya la había probado y no me fue bien, pero tras aumentarle un poco los delay funciono!! Llevo meses y muchas horas para hacer andar el lcd, ya estaba desesperado hasta el punto de creer que no iba a conseguirlo :enfadado: De todos modos he aprendido bastante en el proceso así que no es todo malo.

Moraleja, alejarse de la librería del CCS!!! Solo funciona en proteus por algún motivo. Sospecho que puede ser por tener la linea RW a masa o por no respetar el orden de pines indicado en la misma aunque la verdad no lo sé, ni me importa. No la quiero ver mas! jajaja

Ahora a arreglar varios bugs que han aparecido, ajustar los filtros RC y añadir algun delay antes de construir la PCB definitiva

Un saludo
05/08/2011 #14


Bueno te aplaudimos entonces.
Respuesta
¿Tienes una mejor respuesta a este tema? ¿Quieres hacerle una pregunta a nuestra comunidad y sus expertos? Registrate

Foros de Electrónica » Diseño digital » Microcontroladores y sistemas embebidos

Powered by vBulletin® Version 3.8.4
Copyright ©2000 - 2017, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO ©2011, Crawlability, Inc.