Hola,
He realizado programa para controlar la temperatura dentro de un rango programable y visualizarla en un display, con Mplab y el complilador HI-TECH. El programa funciona bien pero para mejorarlo he pensado en introducirle el rango de temperatura mediante dos potenciometros (max y min) en vez de con microinterruptores. Y aqui es donde me he atascado, ¿deberia usar los modulos CCP? Alguna sugerencia por favor. El código es el siguiente, esta todo comentado, en el word está descrito el montaje y qué hace este programa:
#include<pic1687x.h>
unsigned char x=1; //para el switch (inicializa y actualiza max y min)
unsigned int temp,tempmin,tempmax,t; //variables en hexadec y t (retardo conversor).
unsigned int templcd,tempminlcd,tempmaxlcd; //variables en decimal para enviar al lcd.
unsigned int rangmin,rangmax; //variables en Hex para enviar al lcd de los interrup
unsigned char hexadec(unsigned char hex); //Pasa a decimal
void iniciar_lcd(void); //Inicial el LCD
void lcd_control(unsigned int valor); //Control del LCD
void prueba(void);
void prueba2(void);
void rango(void); //Datos y texto para el LCD
void prueba3(void);
void prueba4(void);
void error(void);
void lcd_dato(unsigned int dato);
unsigned int i; //Para el retardo funciones
//*****************MAIN**************
void main(void){
TRISB=0x00; //Salida
TRISE=0x00; //salida
TRISC=0xFF; //Entrada digital
TRISD=0xFF; //Entrada digital
TRISA =0x01; //Salida D y RA0 en Analogico
PORTA=0x00; //Salida digital a 0
PORTC=0x00; //Temp minima del rango a 0
PORTD=0x00; //Temp max del rango a 0
PORTE=0x00; //Inicializo a 0
PORTB=0x00;
OPTION=0x80;
INTCON=0xC0;
ADCON1=0x8E; //Justifico a la der
ADCON0=0x81;
templcd=tempminlcd=tempmaxlcd=37; //37dec=25hex Temp defecto
ADIE=1; //Habilitamos interrupt
ADGO=1; //Empezamos conversión
while(1);
} //MAIN
//*************Interrupcion del conversor A/D*****************
void interrupt convertir (void){
if(ADIF){ // si ha terminado la conversión
ADIF=0;
temp=(ADRESH<<8)+ADRESL; //Justifico a la derecha
temp=temp>>1; //Divido entre dos para buscar la paridad de la escala
templcd=hexadec(temp); //A decimal
rangmin=PORTC; //Rangos de temperatura introducidos
rangmax=PORTD;
iniciar_lcd();
lcd_control(0x80); //Pone el mensaje en la 1ª fila
prueba(); //Envia al LCD
//para ver la Tmax y la Tmin que coge la sonda*/////////////
//switch(x){
// case 1:
// if(templcd>tempminlcd) {tempminlcd=templcd;}x++;
// break; //Solo podrá entrar una vez
//
// case 2:
// if(templcd<tempmaxled) {tempmaxlcd=templcd;}x++;
// break; //Solo podrá entrar una vez
//
// case 3:
// if (templcd<tempminlcd) { tempminled=templcd; }
// x++;break;
//
//
// case 4:
// if(templed>tempmaxled) { tempmaxlcd=templcd; x=3;
// break;
//
// } //Switch********************
//lcd_control(0xC0) //mensaje en la 2ª fila
// prueba2(); //visualiza la max y min de la sonda
//rango(); //visualiza la max(PORTD) y la min(PORTC) introducida
//Al principio los led están en ON
if (templcd<PORTC){ //si la T actual es menor que la que introducimos
if (PORTC>PORTD){ //Si la Tª min rango>Tmax rango=>Error
lcd_control(0x80); //Primera fila del lcd
error(); //Rango mal introducido
RA1=1; //apaga led calor xq hay error en rango
}
else{
lcd_control(0x80); //fila 1 lcd
RA1=0; //apago led calor RA1
prueba3(); //mostramos calor en el lcd
}
}
if(templcd>PORTD){ //Si la T > q la introducida
if(PORTC>PORTD){ //Si la T min rango> T max rango=>Error
lcd_control(0x80); //Primera fila del lcd
error(); //Rango mal introducido
RA2=1; //apaga led frio xq hay error en rango
}
else{
lcd_control(0x80); //fila 1 lcd
RA2=0; //apago led RA2
prueba4(); //mostramos frio en el lcd
}
}
//********para volver a encender led RA1 y RA2********+
if (templcd<=PORTD){ //Si la T <= max introducida
RA2=1; //enciende led frio
}
if (templcd>=PORTC){ //Si la T >= min introducida
RA1=1; //enciende led calor
}
//*********************
for(t=0;t<5000;t++); //retardo para volver a activar el conversor
ADGO=1;
} //IF DE adif
} //Interrupt
//****************FUNCIONES************************
unsigned char hexadec (unsigned char hex)
{ unsigned char x,y;
x=hex/0x0A;
x=x<<4;
y=hex%0x0A;
return(x+y);
}
//*****************
void iniciar_lcd(void){
PORTB=0x0E; //inicia lcd
RE0=1; //active ENABLE
for(i=0;i<=100;i++); //retardo
RE0=0; //Desactiva ENABLE
for(i=0;i<=100;i++); //retardo
PORTB=0x3C;
RE0=1; //ENABLE
for(i=0;i<=100;i++); //retardo
RE0=0;
for(i=0;i<=100;i++); //retardo
return;
}
void lcd_control(unsigned int valor){
RE2=0; //RS=0
for(i=0;i<=100;i++); //retardo
PORTB=valor; //PORTB=0x80 a 1ª linea
for(i=0;i<=100;i++); //retardo
RE0=1; //ENABLE
for(i=0;i<=100;i++); //retardo
RE0=0; //ENABLE
for(i=0;i<=100;i++); //retard
return;
}
void prueba(void){ //T a enviat + texto
lcd_dato('A');
lcd_dato('C');
lcd_dato('T');
lcd_dato('U');
lcd_dato('A');
lcd_dato('L');
lcd_dato(':');
lcd_dato(0x30|(templcd & (0xF0))>>4 ); //D7-D4=0011.D3-D0=templcd&(0xF0);
lcd_dato(0x30|(templcd & (0x0F))); //D7-D4=0011.D3-D0=templcd&(0x0F);
lcd_dato(' ');
lcd_dato(' ');
lcd_dato(' ');
lcd_dato(' ');
lcd_dato(' ');
lcd_dato(' ');
}
void prueba2(void){ //
lcd_dato('M');
lcd_dato('A');
lcd_dato('X');
lcd_dato(':');
lcd_dato( 0x30|(tempmaxlcd & (0xF0))>>4 );//D7-D4=0011.D3-D0=templcd&(0xF0);
lcd_dato( 0x30|(tempmaxlcd & (0x0F))); //D7-D4=0011.D3-D0=templcd&(0x0F);
lcd_dato('M');
lcd_dato('I');
lcd_dato('N');
lcd_dato(':');
lcd_dato(0x30|(tempminlcd & (0xF0))>>4 );//D7-D4=0011.D3-D0=templcd&(0xF0);
lcd_dato(0x30|(tempminlcd & (0x0F))); //D7-D4=0011.D3-D0=templcd&(0x0F);
lcd_dato(' ');
}
void prueba3(void){ //
lcd_dato('A');
lcd_dato('C');
lcd_dato('T');
lcd_dato('U');
lcd_dato('A');
lcd_dato('L');
lcd_dato( 0x30|(templcd & (0xF0))>>4 ); //D7-D4=0011.D3-D0=templcd&(0xF0);
lcd_dato( 0x30|(templcd & (0x0F))); //D7-D4=0011.D3-D0=templcd&(0x0F);
lcd_dato(' ');
lcd_dato('C');
lcd_dato('A');
lcd_dato('L');
lcd_dato('O');
lcd_dato('R');
lcd_dato(' ');
lcd_dato(' ');
}
void prueba4(void){ //texto y temperatura envia LCD
lcd_dato('A');
lcd_dato('C');
lcd_dato('T');
lcd_dato('U');
lcd_dato('A');
lcd_dato('L');
lcd_dato( 0x30|(templcd & (0xF0))>>4 ); //D7-D4=0011.D3-D0=templcd&(0xF0);
lcd_dato( 0x30|(templcd & (0x0F))); //D7-D4=0011.D3-D0=templcd&(0x0F);
lcd_dato(' ');
lcd_dato('F');
lcd_dato('R');
lcd_dato('I');
lcd_dato('O');
lcd_dato(' ');
lcd_dato(' ');
}
void rango(void){
lcd_dato('M');
lcd_dato('A');
lcd_dato('X');
lcd_dato(':');
lcd_dato( 0x30|(rangmax & (0xF0))>>4 ); //D7-D4=0011.D3-D0=templcd&(0xF0);
lcd_dato( 0x30|(rangmax & (0x0F))); //D7-D4=0011.D3-D0=templcd&(0x0F);
lcd_dato(' ');
lcd_dato(' ');
lcd_dato(' ');
lcd_dato('M');
lcd_dato('I');
lcd_dato('N');
lcd_dato(':');
lcd_dato( 0x30|((rangmin & (0xF0))>>4 )); //D7-D4=0011.D3-D0=templcd&(0xF0);
lcd_dato( 0x30|(rangmin & (0x0F))); //D7-D4=0011.D3-D0=templcd&(0x0F);
lcd_dato(' ');
}
void error(void){ //Actual y error
lcd_dato('A');
lcd_dato('C');
lcd_dato('T');
lcd_dato('U');
lcd_dato('A');
lcd_dato('L');
lcd_dato(':');
lcd_dato(0x30|(templcd & (0xF0))>>4 ); //D7-D4=0011.D3-D0=templcd&(0xF0);
lcd_dato(0x30|(templcd & (0x0F))); //D7-D4=0011.D3-D0=templcd&(0x0F);
lcd_dato(' ');
lcd_dato('E');
lcd_dato('R');
lcd_dato('R');
lcd_dato('O');
lcd_dato('R');
lcd_dato(' ');
lcd_dato(' ');
}
void lcd_dato(unsigned int dato){ //Envia al LCD
RE2=1; //rs=1; lee dato
for(i=0;i<=100;i++); //retardo
PORTB=dato;
for(i=0;i<=100;i++); //retardo
RE0=1;
for(i=0;i<=100;i++); //retard
RE0=0;
for(i=0;i<=100;i++); //retard
return;
}