# Sensor de temperatura con LM35 y PIC18F4550



## Juano861 (Abr 24, 2012)

Buenas Tengo un problemita en el codigo del pic.18f4550 en el proteus me funciona pero me esta mostrando la mitad de la cantidad que deberia mostrar. me explico en la entrada con el LM35 tengo por decirles 30 grados que a su vez en voltaje serian 300mV y este me deberia mostrar en los displays 30...correcto, entonces lo que me esta mostrando es un 15. 
yo creo q el error lo tengo aqui....... agradezco la ayuda...


;CONFIGURACION DEL CONVERTIDOR A/D

    MOVLW    B'00001110'    ;BIT5/4 = 00 REFERENCIA 0-5V; BIT3/2/1/0 = 1110 AN0 ANALOGICO, RESTO DIGITAL.
    MOVWF    ADCON1
    MOVLW    B'00000000'    ;BIT5/4/3/2 = 0000 CANAL 0 (AN0) SELEC; BIT1 = 0 CONV. PARADA; BIT0 = 0 A/D DESACTIVADO.
    MOVWF    ADCON0
    MOVLW    B'00001001'    ;BIT7 = 0 JUST. IZQUIERDA; BIT5/4/3 = 001 tAD=fOSC/8; BIT2/1/0 = 001 2tAD. 
    MOVWF    ADCON2

    BSF    ADCON0,ADON    ;ACTIVAR CONVERTIDOR A/D


----------



## rachelies (Abr 25, 2012)

Prueba a poner a 1 el bit 7 del ADCON2


----------



## chuu (Nov 28, 2012)

hola a todos en el foro soy nuevo en esto de la programación y encontré un programa para sensor de temperatura pero con pic16f877a y yo tengo el pic18f4550 y quise modificarlo para este pic pero me marca error en una entrada analógica y no se si me falta algo les agradecería mucho que le echen un vistazo a mi programa y me puedan ayudar, esta en rojo marcado el error que me marca estoy haciendo en pic c compiler... gracias espero su respuesta...


```
#include <18f4550.h>       //PIC A USAR
#device adc=8              //Usa resolución de 8 bits
#include <math.h>          //PARA OPERACIONES MATEMATICAS
#use delay(clock=48000000)     //CRISTAL A UTILIZAR
#include <LCD.c>           //CONTROLADOR DEL LCD
#fuses INTRC, NOWDT, NOPUT, NOMCLR, NOBROWNOUT, NOLVP, NOCPD, NOPROTECT,HSPLL
#build(reset=0x02000,interrupt=0x02008)
#org 0x0000,0x1FFF {}
void main()
{

// VARIABLES A USAR

int8 temp1;
float temp;

lcd_init();                       //INICIALIZA EL LCD
lcd_putc(" CONTROL TEMPERATURA"); //IMPRIME EN PANTALLA
lcd_gotoxy(7,2);                  //COLOCA EL CURSOR EN COLUMNA 7 FILA 2
lcd_putc("ON - OFF");             //IMPRIME EN PANTALLA
delay_ms(5000);                   //ESPERA 5 SEGUNDOS
lcd_putc("\f");                   //LIMPIA PANTALLA

while(1)
   {
      setup_adc(ADC_CLOCK_INTERNAL);
      Setup_adc_ports([COLOR=Red]RA0_ANALOGO[/COLOR]);          //PONE PUERTO RA0 ANALOGO
      set_adc_channel(0);                   // INDICA EL PIN A LEER RA0
      delay_us(20);        
      temp1=read_adc();                     //LEE EL VALOR DEL PIN
      temp=(temp1*0.01960784314*100);       //CONVIERTE EL VALOR LEIDO DE HEXA AL REAL el numero 0.01960784314 viene de dividir (5/255) y el resultado se multiplica por 100 para alcanzar 150 grados
      lcd_gotoxy(1,1);                      //COLOCA EL CURSOR EN COLUMNA 1 FILA 1
      lcd_putc("TEMPERATURA ACTUAL...");    //IMPRIME EN PANTALLA                                        
      lcd_gotoxy(4,2);                      //COLOCA EL CURSOR EN COLUMNA 4 FILA 2
      printf(lcd_putc," T= %2.2f C",temp);  //MUESTRA EN EL LCD EL VALOR DE TEMPERATURA
      delay_ms (1);


         if(temp>40){
            output_high(pin_b0);            //SI LA EMPERATURA ES MENOR O IGUAL A 40ºC MANDA UN 1 AL PIN BO         
                  }
         else{
            output_low(pin_b0);             //DE LO CONTRARIO MANDA UN 0 AL PIN B0 
             }

   }//fin while

}//fin main
```


----------



## D@rkbytes (Nov 28, 2012)

chuu dijo:


> me marca error en una entrada analógica y no se si me falta algo


Esto...
Setup_adc_ports(RA0_ANALOGO);          //PONE PUERTO RA0 ANALOGO
Cámbialo por esto...
setup_adc_ports(AN0);          //PONE PUERTO RA0 ANALOGO

Suerte.


----------



## chuu (Nov 28, 2012)

muchas gracias D@rkbytes si me sirvio gracias por tu ayuda.... saludos


----------



## chuu (Nov 29, 2012)

una pregunta mas le quiero hacer una arreglo al programa en el cual esta que a los 30 °C se encienda una señal pero quiero ponerle que a por ejemplo a los 25 se apague esa señal, lo intente hacer pero no he podido encontrar la manera correcta ya que lo hice por medio de tiempo pero el problema es que si no se llega a enfriar o se llegue y entonces se armaría un relajo y pues quisiera hacerlo mejor hacer en intervalos.... gracias espero alguna respuesta.... Marque en rojo donde yo hice los cambios para hacerlo por tiempo, pero ahora quisiera que se apague la señal a los 25°c....




```
#include <18f4550.h>       //PIC A USAR
#device adc=8              //Usa resolución de 8 bits
#include <math.h>          //PARA OPERACIONES MATEMATICAS
#use delay(clock=48000000)     //CRISTAL A UTILIZAR
#include <LCD.c>           //CONTROLADOR DEL LCD
#fuses INTRC, NOWDT, NOPUT, NOMCLR, NOBROWNOUT, NOLVP, NOCPD, NOPROTECT,HSPLL
#build(reset=0x02000,interrupt=0x02008)
#org 0x0000,0x1FFF {}
void main()
{

// VARIABLES A USAR

int8 temp1;
float temp;

lcd_init();                       //INICIALIZA EL LCD
lcd_putc(" CONTROL TEMPERATURA"); //IMPRIME EN PANTALLA
lcd_gotoxy(7,2);                  //COLOCA EL CURSOR EN COLUMNA 7 FILA 2
lcd_putc("ON - OFF");             //IMPRIME EN PANTALLA
delay_ms(5000);                   //ESPERA 5 SEGUNDOS
lcd_putc("\f");                   //LIMPIA PANTALLA

while(1)
   {
      setup_adc(ADC_CLOCK_INTERNAL);
      Setup_adc_ports(AN0);          //PONE PUERTO RA0 ANALOGO
      set_adc_channel(0);                   // INDICA EL PIN A LEER RA0
      delay_us(20);        
      temp1=read_adc();                     //LEE EL VALOR DEL PIN
      temp=(temp1*0.01960784314*100);       //CONVIERTE EL VALOR LEIDO DE HEXA AL REAL el numero 0.01960784314 viene de dividir (5/255) y el resultado se multiplica por 100 para alcanzar 150 grados
      lcd_gotoxy(1,1);                      //COLOCA EL CURSOR EN COLUMNA 1 FILA 1
      lcd_putc("TEMPERATURA ACTUAL...");    //IMPRIME EN PANTALLA                                        
      lcd_gotoxy(4,2);                      //COLOCA EL CURSOR EN COLUMNA 4 FILA 2
      printf(lcd_putc," T= %2.2f C",temp);  //MUESTRA EN EL LCD EL VALOR DE TEMPERATURA
      delay_ms (1);


         [COLOR=Red]if(temp>40){[/COLOR]
          [COLOR=Red]  output_high(pin_b0);[/COLOR]            //SI LA TEMPERATURA ES MENOR O IGUAL A 40ºC MANDA UN 1 AL PIN BO         
                  }
        [COLOR=Red] else{[/COLOR]
          [COLOR=Red]  output_low(pin_b0); [/COLOR]            //DE LO CONTRARIO MANDA UN 0 AL PIN B0 
             }

   }//fin while

}//fin main
```


----------



## D@rkbytes (Nov 29, 2012)

chuu dijo:


> ahora quisiera que se apague la señal a los 25°c....


Saludos.

Adjunto tu programa con lo que creo que es lo que quieres hacer.

Suerte.


----------



## chuu (Nov 29, 2012)

gracias D@rkytes ya lo hice igual pero en el primer if no le coloque el else q pusiste abajo y me funciono bien gracias por tu ayuda....





D@rkbytes dijo:


> Saludos.
> 
> Adjunto tu programa con lo que creo que es lo que quieres hacer.
> 
> Suerte.



gracias por toda la ayuda dada por aca, ahora he querido meterle unos botones con los cuales pueda controlar las los rangos de temperatura como un tipo menu en donde solo ocupe 4 botones uno para subir otro para bajar, seleccionar y cancelar, algo asi quiero hacer adjunto una imagen donde vi, algo asi como lo que quiero hacer pero no se que cambiarle al programa y ni idea de como meterle un menu que me haga eso tambien va el circuito en proteus que hice pero le faltarian los botones garcias por la ayuda espero pronto respuesta...saludos


este es el link de donde saque la imagen
http://www.pablin.com.ar/electron/circuito/mc/termost/index.htm


```
#include <18f4550.h>       //PIC A USAR
#device adc=8              //Usa resolución de 8 bits
#include <math.h>          //PARA OPERACIONES MATEMATICAS
#use delay(clock=48000000)     //CRISTAL A UTILIZAR
#include <LCD.c>           //CONTROLADOR DEL LCD
#fuses INTRC, NOWDT, NOPUT, NOMCLR, NOBROWNOUT, NOLVP, NOCPD, NOPROTECT,HSPLL
#build(reset=0x02000,interrupt=0x02008)
#org 0x0000,0x1FFF {}
void main()
{

// VARIABLES A USAR

int8 temp1;
float temp;


lcd_init();                       //INICIALIZA EL LCD
lcd_putc("CONTROL TEMPERATURA"); //IMPRIME EN PANTALLA
lcd_gotoxy(0,2);                  //COLOCA EL CURSOR EN COLUMNA 0 FILA 2
lcd_putc("ON - OFF");             //IMPRIME EN PANTALLA
delay_ms(3000);                   //ESPERA 3 SEGUNDOS
lcd_putc("\f");                   //LIMPIA PANTALLA

while(1)
   {
      setup_adc(ADC_CLOCK_INTERNAL);
      setup_adc_ports(AN0);                  //PONE PUERTO RA0 ANALOGO
      set_adc_channel(0);                   // INDICA EL PIN A LEER RA0
      delay_us(20);        
      temp1=read_adc();                     //LEE EL VALOR DEL PIN
      temp=(temp1*0.01960784314*100);       //CONVIERTE EL VALOR LEIDO DE HEXA AL REAL el numero 0.01960784314 viene de dividir (5/255) y el resultado se multiplica por 100 para alcanzar 150 grados
      lcd_gotoxy(1,1);                      //COLOCA EL CURSOR EN COLUMNA 1 FILA 1
      lcd_putc("TEMP.ACTUAL...");           //IMPRIME EN PANTALLA                                        
      lcd_gotoxy(1,2);                      //COLOCA EL CURSOR EN COLUMNA 1 FILA 2
      printf(lcd_putc," T=%2.2f C",temp);  //MUESTRA EN EL LCD EL VALOR DE TEMPERATURA
      delay_ms (100);


         if(temp>30){
            output_high(pin_b0);            //SI LA EMPERATURA ES MAYOR A 30ºC MANDA UN 1 AL PIN BO                     
                  }
         if(temp<=27){
            output_low(pin_b0);             //SI LA TEMPERATURA ES IGUAL O MENOR A 25°C MANDA UN 0 AL PIN B0
         
             }     
   } //fin while
   
} //fin main
```


----------



## Basalto (Nov 29, 2012)

Algo así como esto. No conozco la estructura de CSS, pero creo que la idea queda clara.


#include <18f4550.h>       //PIC A USAR #device adc=8              //Usa resolución de 8 bits #include <math.h>          //PARA OPERACIONES MATEMATICAS #use delay(clock=48000000)     //CRISTAL A UTILIZAR #include <LCD.c>           //CONTROLADOR DEL LCD #fuses INTRC, NOWDT, NOPUT, NOMCLR, NOBROWNOUT, NOLVP, NOCPD, NOPROTECT,HSPLL #build(reset=0x02000,interrupt=0x02008) #org 0x0000,0x1FFF {} void main() {  // VARIABLES A USAR  int8 temp1; float temp;
int8 tempmax=30; int8 tempmin=27; bit maxpin; bit minpin;

lcd_init();                       //INICIALIZA EL LCD lcd_putc("CONTROL TEMPERATURA"); //IMPRIME EN PANTALLA lcd_gotoxy(0,2);                  //COLOCA EL CURSOR EN COLUMNA 0 FILA 2 lcd_putc("ON - OFF");             //IMPRIME EN PANTALLA delay_ms(3000);                   //ESPERA 3 SEGUNDOS lcd_putc("\f");                   //LIMPIA PANTALLA  while(1)    {       setup_adc(ADC_CLOCK_INTERNAL);       setup_adc_ports(AN0);                  //PONE PUERTO RA0 ANALOGO       set_adc_channel(0);                   // INDICA EL PIN A LEER RA0       delay_us(20);               temp1=read_adc();                     //LEE EL VALOR DEL PIN       temp=(temp1*0.01960784314*100);       //CONVIERTE EL VALOR LEIDO DE HEXA AL REAL el numero 0.01960784314 viene de dividir (5/255) y el resultado se multiplica por 100 para alcanzar 150 grados       lcd_gotoxy(1,1);                      //COLOCA EL CURSOR EN COLUMNA 1 FILA 1       lcd_putc("TEMP.ACTUAL...");           //IMPRIME EN PANTALLA                                               lcd_gotoxy(1,2);                      //COLOCA EL CURSOR EN COLUMNA 1 FILA 2       printf(lcd_putc," T=%2.2f C",temp);  //MUESTRA EN EL LCD EL VALOR DE TEMPERATURA       delay_ms (100);  if (pin_c0==1 and maxpin==0){  tempmax++;
}

if (pin_c1==1 and minpin==0){  tempmin++;
}
maxpin=pin_c0;
minpin=pin_c1;

 if(temp>tempmax){             output_high(pin_b0);            //SI LA EMPERATURA ES MAYOR A 30ºC MANDA UN 1 AL PIN BO                                        }          if(temp<=tempmin){             output_low(pin_b0);             //SI LA TEMPERATURA ES IGUAL O MENOR A 25°C MANDA UN 0 AL PIN B0                        }         } //fin while     } //fin main


----------



## chuu (Nov 29, 2012)

Basalto dijo:


> Algo así como esto. No conozco la estructura de CSS, pero creo que la idea queda clara.
> 
> 
> #include <18f4550.h>       //PIC A USAR #device adc=8              //Usa resolución de 8 bits #include <math.h>          //PARA OPERACIONES MATEMATICAS #use delay(clock=48000000)     //CRISTAL A UTILIZAR #include <LCD.c>           //CONTROLADOR DEL LCD #fuses INTRC, NOWDT, NOPUT, NOMCLR, NOBROWNOUT, NOLVP, NOCPD, NOPROTECT,HSPLL #build(reset=0x02000,interrupt=0x02008) #org 0x0000,0x1FFF {} void main() {  // VARIABLES A USAR  int8 temp1; float temp;
> ...



hola amigo según yo así lo hice con el programa q*ue* me pasaste pero no se estoy bien ya que no me simula y no se en q*ue* este mal espero y me puedas ayudar necesito algo como lo de la imagen que esta más arriba y que me salga un menú en el display para poner intervalos... bueno realmente no se si así sea como me lo pasaste pero no me lo logro simular gracias espero tu respuesta...


----------



## Basalto (Nov 30, 2012)

chuu dijo:


> hola amigo según yo así lo hice con el programa q*ue* me pasaste pero no se estoy bien ya que no me simula y no se en q*ue* este mal espero y me puedas ayudar necesito algo como lo de la imagen que esta más arriba y que me salga un menú en el display para poner intervalos... bueno realmente no se si así sea como me lo pasaste pero no me lo logro simular gracias espero tu respuesta...



Como dije no conozco la sintaxis que se utiliza en CSS, por lo que es normal que no  funcione. Lo que te intento transmitir es idea de como se podría hacer.

Falta esto también para reducir las variables de la temperatura.

if (pin_c2==1 and maxpin2==0){
if (tempmax!=tempmin){ tempmax--};
}

if (pin_c3==1 and minpin3==0){ tempmin--;
}


----------



## chuu (Nov 30, 2012)

ok gracias pero el problema que yo igual no se como hacer el programa para colocarle los pulsadores y que guarde datos no se que librerías utilizar o si se utilizan librerías soy novato en verdad apenas y les entiendo a los programas y p*ue*s yo tengo un programa de termostato donde la temperatura mínima es de 27  y la máxima es de 30, estos parámetros los cambio mediante el programa que es el siguiente; pero me gustaría añadirle unos pulsadores para cambiar valores de temperaturas, pero no se la programación, si alguien me puede ayudar...




```
#include <18f4550.h>       //PIC A USAR
#device adc=8              //Usa resolución de 8 bits
#include <math.h>          //PARA OPERACIONES MATEMATICAS
#use delay(clock=48000000)     //CRISTAL A UTILIZAR
#include <LCD.c>           //CONTROLADOR DEL LCD
#fuses INTRC, NOWDT, NOPUT, NOMCLR, NOBROWNOUT, NOLVP, NOCPD, NOPROTECT,HSPLL
#build(reset=0x02000,interrupt=0x02008)
#org 0x0000,0x1FFF {}
void main()
{

// VARIABLES A USAR

int8 temp1;
float temp;


lcd_init();                       //INICIALIZA EL LCD
lcd_putc("CONTROL TEMPERATURA"); //IMPRIME EN PANTALLA
lcd_gotoxy(0,2);                  //COLOCA EL CURSOR EN COLUMNA 0 FILA 2
lcd_putc("ON - OFF");             //IMPRIME EN PANTALLA
delay_ms(3000);                   //ESPERA 3 SEGUNDOS
lcd_putc("\f");                   //LIMPIA PANTALLA

while(1)
   {
      setup_adc(ADC_CLOCK_INTERNAL);
      setup_adc_ports(AN0);                  //PONE PUERTO RA0 ANALOGO
      set_adc_channel(0);                   // INDICA EL PIN A LEER RA0
      delay_us(20);        
      temp1=read_adc();                     //LEE EL VALOR DEL PIN
      temp=(temp1*0.01960784314*100);       //CONVIERTE EL VALOR LEIDO DE HEXA AL REAL el numero 0.01960784314 viene de dividir (5/255) y el resultado se multiplica por 100 para alcanzar 150 grados
      lcd_gotoxy(1,1);                      //COLOCA EL CURSOR EN COLUMNA 1 FILA 1
      lcd_putc("TEMP.ACTUAL...");           //IMPRIME EN PANTALLA                                        
      lcd_gotoxy(1,2);                      //COLOCA EL CURSOR EN COLUMNA 1 FILA 2
      printf(lcd_putc," T=%2.2f C",temp);  //MUESTRA EN EL LCD EL VALOR DE TEMPERATURA
      delay_ms (100);


         if(temp>30){
            output_high(pin_b0);            //SI LA EMPERATURA ES MAYOR A 30ºC MANDA UN 1 AL PIN BO                     
                  }
         if(temp<=27){
            output_low(pin_b0);             //SI LA TEMPERATURA ES IGUAL O MENOR A 25°C MANDA UN 0 AL PIN B0
         
             }     
   } //fin while
   
} //fin main
```

Me interesaría poder regular esos parámetros desde unos pulsadores, pero es que no tengo ni idea de como hacerlo... necesito ayuda, os lo agradezco mucho....


ahora encontré este programa y mas o menos le entiendo pero no se que cambiarle o agregarle al mi programa para hacer esos cambios, este programa es para un reloj y esas mismas funciones las quiero para mi programa pero no se que hay que poner o quitar. Les agradecería mucho la ayuda.

```
#include <16f88.h>
#use delay(clock=8MHz)
#use fast_io(all)
#fuses MCLR,NOPUT,INTRC_IO,NOWDT,NOBROWNOUT


#define Tec1   PIN_B0
#define Tec2   PIN_B1
#define Tec3   PIN_B2
#define Tec4   PIN_B3   //Pines del PIC correspondientes a cada tecla.

#define Nada   0  
#define Mas    1     // valores validos para Flag
#define Menos  2  

int Segs;            // Segundos.
int Minu;            // Minutos.
int Hora;            // Hora.
int Tmp;             // Temporal.
int Tecla;           // Tecla pulsada.
int anTecla;         // Tecla pulsada en la comprobación anterior
int Tiempo;          // Tiempo transcurrido desde la ultima comprobacion
                     // de teclado.
int CuantoTiempo;    // Cuanto tiempo debe esperar para la
                     // proxima comprobacion.
int Flag;            // Flag para incrementar o decrementar
                     // el valor deseado.
int Set;             // Flag para seleccionar el valor a cambiar.

void main(){
   
   setup_oscillator(OSC_8MHz);
   
   set_tris_a(0);                // Puerto A como salida
   set_tris_b(0b00001111);       // Puerto B<7:4> salida B<3:0> entradas
   
   // Inicio Variables
   anTecla=255;
   Set=0;
   Hora=0;
   Minu=0;
   Segs=0;  
   
   
   do{   
   
      Tecla=0;
      if (input(Tec1))Tecla=1;        // Comprueba que pulsador se activó
      if (input(Tec2))Tecla=2;        // y lo guarda en Tecla
      if (input(Tec3))Tecla=3;
      if (input(Tec4))Tecla=4;        
      
      if (++Tiempo>CuantoTiempo||Tecla!=anTecla) {  // Incrementa el
                              // tiempo transcurrido, Si se pasa de
                              // CuantoTiempo o cambia el estado de
                              // de las teclas con respecto a la
                              // iteracion anterior.
Flag=Nada;                    // Limpia el flag
            
         if(Tecla!=0){                 // Si hay una tecla pulsada
            if(Tecla!=anTecla){        // si la tecla es la primera
                                       // vez que se pulsa.
               CuantoTiempo=100;       // establece el tiempo de
                                       // espera en 100.               
               if(Tecla==1){           // Si se pulsó la tecla 1
                  if(++Set>3) Set=1;   // Avanza el flag para setear
                                       // segs/minu/hora
               }
               if(Tecla==4) Set=0;     // Se pulsó la tecla 4, desactiva
                                       // el modo configuración
            
            }else{                     // Si no es la primera vez que se
                                       // pulsa la tecla
               CuantoTiempo=30;        // la próxima comprobación la
                                       // hará en menos tiempo.
            }
            
            if(Tecla==2) Flag=Menos;   // Si la tecla pulsada es la 2
                                       // flag de decremento
            if(Tecla==3) Flag=Mas;     // y si es la 3 flag de incremento
         }
         
         
         if (Set!=0){                  // Si está en modo configuración
            
            if(Set==1) Tmp=Segs;       // Si se está configurando los
                                       // segundos Segs a temporal
            if(Set==2) Tmp=Minu;       // lo mismo si está configurando
                                       // los minutos
            if(Set==3) Tmp=Hora;       // o la hora
            
            if (Flag==Menos){          // si el flag es de decremento
               if(--Tmp>200)Tmp=59;    // le resta 1 al temporal si es
                                       // menor a 0 pasa a 59
               if(Set==3&&Tmp==59)Tmp=23;// Si está configurando las
                                       // horas el limite es 23
            }
            
            if (Flag==Mas){            // Si el flag es de incremento
               if(++Tmp>59)Tmp=0;      // Incrementa el temporal y si
                                       // se pasa de 59 vuelve a 0
               if(Set==3&&Tmp>23)Tmp=0;// Si configura las horas y
                                       // se pasa de 23 vuelve a 0
            }
            
            if(Set==1) Segs=Tmp;
            if(Set==2) Minu=Tmp;       // Guarda el valor temporal
            if(Set==3) Hora=Tmp;       // en donde corresponda...
         }      
         anTecla=Tecla;                // Almacena la tecla pulsada
                                       // para la próxima 
         Tiempo=0;                     // iteración, Tiempo a 0 para
                                       // volver a contar el tiempo
            
      }
      delay_ms(5);   // Entre iteración e iteración espera 5 ms que
                     // multiplicado por CuantoTiempo, es el tiempo
                     // que tarda en reaccionar a las pulsaciones y
                     // cuanto tarda en avanzar cuando se mantiene
                     // pulsado un botón.
     
   }while(true);
}
```


----------



## rubencho987 (Dic 9, 2012)

Buenas a todos no llevo mucho tiempo en el tema, pero espero que les sea de aporte el siguiente código hecho en assembler para detectar la temperatura del sensor LM35 y ser mostrado en una LCD 16X4 utilizando PIC18F4550


```
LIST P=18F4550
 INCLUDE <P18F4550.INC> 
;***Comienzo a definir variables***

; Oscilador utilizado 4MHz.-
; ************************************************
ByteAlto    equ 0x20    ; Registro para guardar Byte alto de la conversion.-
ByteBajo    equ 0x21    ; Regsitro para guardar Byte bajo de la conversion.-
Contador    equ 0x22    ; registro utilizado en demora.-
ASCII_H EQU 0x2B
ASCII_M EQU 0x2C
ASCII_L EQU 0x2D
HEXADECIMAL EQU 0x23    ;GUARDA EL DATOS DEL SENSOR
NUMASCCII   EQU 0x24    ;RESULTADO DE CONVERSION HEX A ASCCII

CONTA1       EQU    0124H
CONTA2       EQU    0125H
CONTA3       EQU    0126H
; ************************************************
            org     0x00
            GOTO CONFIPIC
INICIO
            CALL MENSAJE
PROCESO
            bsf     STATUS,5  ; Banco 1
            movlw   0x8E        ; Justificado a la derecha, Fosc/8, RA0 analógico, VDD, VSS.-
            movwf   ADCON1
            bcf     STATUS,5  ; Banco 0
            movlw   0x41        ; Fosc/8, Canal 0, módulo habilitado.-
            movwf   ADCON0
            call    Demora_20us ; Demora de adquision.-
            bsf     ADCON0,GO
Espera
            btfsc   ADCON0,GO   ; Espera a que termine conversion.-
            goto    Espera
            movf    ADRESH,0   ; Movemos resultado de la conversion.-
            addwf ADRESH,0
            CALL Hex_Ascii    
            CALL MOSTRAR_TEMPERATURA
            ;BSF PORTB,2
            bsf     STATUS,5  ; Banco 1
            movf    ADRESL,0
            ;movwf   ByteBajo
            bcf     STATUS,5  ; Banco 0.-
            bsf     ADCON0,ADON ; Apago modulo de conversion.-
    
             GOTO PROCESO
    ;**** Demora ****
Demora_20us
            movlw   0x05 ;
            movwf   Contador ; Iniciamos contador1.-
Repeticion
            decfsz  Contador,1 ; Decrementa Contador1.-
            goto    Repeticion ; Si no es cero repetimos ciclo.-
            return              ; Regresa de la subrutina.-
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;; RUTINA PARA CONVERTIR HEX ASCCII ;;;;;;;;;;;;;;;;;;;;;;;

Hex_Ascii      ;cargar en W el dato hex

            movwf HEXADECIMAL 
            clrf ASCII_H ;Para BCD D'0'
            clrf ASCII_M ;Para BCD D'0'
            clrf ASCII_L ;Para BCD D'0'

Centenas    movlw D'100' ;D'100' --> W
            subwf HEXADECIMAL,0 ;HEXADECIMAL - D'100' --> W
            btfss STATUS,C ;¿ HEXADECIMAL es menor que D'100' ?
            goto Decenas ;Si
            movwf HEXADECIMAL ;Salva el resto
            incf ASCII_H,F ;Incrementa el contador de centenas BCD
            goto Centenas ;Vuelve por otros D'100'

Decenas        movlw D'10' ;D'10' --> W
            subwf HEXADECIMAL,0 ;HEXADECIMAL - D'10' --> W
            btfss STATUS,C ;¿ HEXADECIMAL es menor que D'10' ?
            goto Unidades ;Si
            movwf HEXADECIMAL ;Salva el resto
            incf ASCII_M,F ;Incrementa el contador de decenas BCD
            goto Decenas ;Vuelve por otros D'10'

Unidades    movf HEXADECIMAL,0 ;El resto pertenece
            movwf ASCII_L ;a las unidades BCD
            clrf HEXADECIMAL ;Pone a cero el registro HEXADECIMAL
            
Bcd_A_Ascii    movlw H'30' ;H'30' --> W
            iorwf ASCII_L,F ;Convierte de BCD a ASCII    
            iorwf ASCII_M,F ;Convierte de BCD a ASCII

            movf ASCII_H,F ;ASCII_H --> F
            btfsc STATUS,Z ;? ASCII_H es D'00' ?
            goto Espacio ;Si
            movlw H'30' ;H'30' --> W
            iorwf ASCII_H,F ;Convierte de BCD a ASCII
            return ;Retorna
 
Espacio
            movlw '0' ;A' ' --> W
            movwf ASCII_H ;A' ' --> ASCII_H
            return ;Retorna

;**********************************************************************
;     MOSTRAR MENSAJE DE BIENVENIDA
;**********************************************************************
MENSAJE
                NOP
                   MOVLW        038H         ; Inicio LCD a 8 bits, 2 linea            
                  CALL      CONTROL
                MOVLW     0CH          ; sentido giro 0000 0101 
                CALL      CONTROL 
                MOVLW     01H                         
                CALL      CONTROL      ; Limpia todo el display  y retorna el cursor a la posicion de inicio de LCD ... 
                CALL      RETARDO     ; Tiempo prudencial para que la lcd ermnie la instruccion anterior der borrado ...


                MOVLW     " "          
                CALL      DATO
                MOVLW     " "          
                CALL      DATO
                MOVLW     " "         
                CALL      DATO
                MOVLW     "B"          
                CALL      DATO    
                MOVLW     "I"          
                CALL      DATO 
                MOVLW     "E"         
                CALL      DATO    
                MOVLW     "N"          
                CALL      DATO          
                MOVLW     "V"          
                CALL      DATO    
                MOVLW     "E"         
                CALL      DATO           
                MOVLW     "N"         
                CALL      DATO    
                MOVLW     "I"         
                CALL      DATO                
                MOVLW     "D"          
                CALL      DATO    
                MOVLW     "O"          
                CALL      DATO    
                MOVLW     "S"          
                CALL      DATO                
                MOVLW     " "          
                CALL      DATO    
                MOVLW     " "         
                CALL      DATO
;************ SEGUNDA LINEA **************************
                MOVLW     " "          
                CALL      DATO
                MOVLW     " "          
                CALL      DATO
                MOVLW     " "         
                CALL      DATO
                MOVLW     " "          
                CALL      DATO    
                MOVLW     "R"          
                CALL      DATO 
                MOVLW     "U"         
                CALL      DATO    
                MOVLW     "B"          
                CALL      DATO          
                MOVLW     "E"          
                CALL      DATO    
                MOVLW     "N"         
                CALL      DATO           
                MOVLW     "C"         
                CALL      DATO    
                MOVLW     "H"         
                CALL      DATO                
                MOVLW     "O"          
                CALL      DATO    
                MOVLW     " "          
                CALL      DATO    
                MOVLW     " "          
                CALL      DATO                
                MOVLW     " "          
                CALL      DATO    
                MOVLW     " "         
                CALL      DATO
;************ TERCER LINEA **************************
                MOVLW     " "          
                CALL      DATO
                MOVLW     " "          
                CALL      DATO
                MOVLW     " "         
                CALL      DATO
                MOVLW     " "          
                CALL      DATO    
                MOVLW     " "          
                CALL      DATO 
   
                MOVLW     " "          
                CALL      DATO          
                MOVLW     "2"          
                CALL      DATO    
                MOVLW     "0"         
                CALL      DATO           
                MOVLW     "1"         
                CALL      DATO    
                MOVLW     "2"         
                CALL      DATO 
                MOVLW     " "         
                CALL      DATO                
                MOVLW     " "          
                CALL      DATO    
                MOVLW     " "          
                CALL      DATO    
                MOVLW     " "          
                CALL      DATO                
                MOVLW     " "          
                CALL      DATO    
                MOVLW     " "         
                CALL      DATO
                   CALL RETARDO
                  CALL RETARDO
                   CALL RETARDO
                  CALL RETARDO
                CALL RETARDO
                CALL RETARDO
                CALL RETARDO
                CALL RETARDO
                   
                MOVLW     01H                         
                CALL      CONTROL      ; Limpia todo el display  y retorna el cursor a la posicion de inicio de LCD ... 
                  
                CALL      RETARDO     ; Tiempo prudencial para que la lcd ermnie la instruccion anterior der borrado ...

                MOVLW     "T"          
                CALL      DATO    
                MOVLW     "E"          
                CALL      DATO 
                MOVLW     "M"          
                CALL      DATO    
                MOVLW     "P"          
                CALL      DATO  
                MOVLW     " "          
                CALL      DATO  
                MOVLW     "="          
                CALL      DATO  
                MOVLW     " "          
                CALL      DATO 
                MOVLW     B'10001100'                         
                CALL      CONTROL      ; POSICIONA EL CURSOR EN UNA CIERTA POSICION
  
                MOVLW     0xDF            ;envia el simbolo de grados celsius
                CALL      DATO    
                MOVLW     'C'
                CALL      DATO
              RETURN

;**********************************************************************
;**********************************************************************
; MOSTRAR TEMPERATURA
;**********************************************************************
MOSTRAR_TEMPERATURA
                 NOP
                MOVLW     B'10001000'                         
                CALL      CONTROL        
                
                movf     ASCII_H,0 ;envia las centenas de temperatura
                CALL      DATO    
                movf ASCII_M,0   ;envia las decenas de temperatura
                CALL      DATO    
                movf ASCII_L,0  ;envia las unidades de temperatura
                CALL      DATO    
                MOVLW     " "    
                CALL      DATO 
                CALL RETARDO

              RETURN

;**********************************************************************
;**********************************************************************
; CONTROL LCD 
;**********************************************************************
CONTROL          BCF         PORTA,1        ; RS =  0 Control
                   BSF         PORTA,2        ; E    =  1 Habilito LCD ...
                   NOP
                   NOP
                  NOP
                 MOVWF    PORTD            ; Saca dato puerto B
                 CALL     RETARDO1
                 CALL     RETARDO1
                 BCF      PORTA,2        ; E   =  0    Desabilito LCD ...
                 RETURN
;**********************************************************************
; DATO  LCD 
;**********************************************************************
DATO             BSF         PORTA,1        ; RS =  1   Dato    
                  BSF         PORTA,2        ; E    =  1 Habilito LCD ...
             
                  MOVWF    PORTD            ; Saca dato puerto B
                 CALL     RETARDO1
                 BCF      PORTA,2        ; E   =  0    Desabilito LCD ...
                 RETURN     
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;**********************************************************************
; RETARDO1        TIEMPO DE WRITE Y READ DE DATO PARA LCD MODIFAMOS 019-025-30
;**********************************************************************
RETARDO1          MOVLW      0C8H
                  MOVWF      CONTA2         ;cargo el registro CONTA1 con AAh
CICLO22           MOVLW      01H    
                  MOVWF      CONTA3         ;cargo el registro CONTA1 con 01h

CICLO11           DECFSZ     CONTA3,1          ;decrementa el contenido CONTA3
                  GOTO       CICLO11            
            
                  DECFSZ     CONTA2,1          ;decrementa el contenido CONTA2
                  GOTO       CICLO22  
                  RETURN  
;**********************************************************************
; RETARDO
;**********************************************************************

RETARDO             MOVLW  0FFH                ;CARGAMOS EN EL REGISTRO DE TRABAJO EN FF  UN DECREMENTO
                MOVWF  CONTA1            ;LO MEVEMOS AL REGISTRO DE PROPOCITO GENERAL CONTA 1
CICLO3          MOVLW  0FFH                ;CARGA EN EL REGISTRO DE TRABAJO FF PARA UN DECREMENTO
                MOVWF  CONTA2            ;LO MEVEMOS A LA ETIQUETA 
CICLO2          MOVLW  01H                ;CARGA EN EL REGISTRO DE TRABAJO PARA UN DECREMENTO
                MOVWF  CONTA3            ;LO MUEVE AL REGISTRO
CICLO1          DECFSZ CONTA3,1                ;DECREMENTA EL REGISTRO Y DEJA EL RESULTADO EN ESE REGISTRO
                GOTO   CICLO1                ;SI EL DECREMENTO ES CERO SALTA A LA ETIQUETA
                DECFSZ CONTA2,1            ;DECREMENTA
                GOTO   CICLO2            ;SIEL DECREMENTO ES CERO SALTA
                DECFSZ CONTA1,1            ;DECREMENTA
                GOTO   CICLO3            ;SI ES CERO SALTA
                RETURN                    ;RETORNA



;**********************************************************************
;******************** CONFIGURACION PIC *******************************
;**********************************************************************

CONFIPIC    
            NOP
            BANKISEL 0F00H
            CLRF PORTB            ;LIMPIAMOS EL PUERTO
            CLRF LATB            ;UNIDAD DE MEMORIA DE LOS PUERTOS
            MOVLW b'00000000'   ;pone el puerto b como salida
            MOVWF TRISB            ;MOSTRAMOS POR EL PUERTO B
            CLRF PORTB
            
            ;CLRF PORTA,1
            ;CLRF PORTA,2
    
            CLRF PORTD            ;LIMPIAMOS EL PUERTO
            CLRF LATD            ;UNIDAD DE MEMORIA DE LOS PUERTOS
            MOVLW b'00000000'   ;pone el puerto b como salida
            MOVWF TRISD            ;MOSTRAMOS POR EL PUERTO D
            CLRF PORTD



;*********************************************************************           
            CLRF     PORTA 
            CLRF     LATA 
            MOVLW    0Fh
            MOVWF    ADCON1 
            MOVLW    07h
            MOVWF    CMCON 
            MOVLW    00h 
            MOVWF    TRISA
            
            BSF      PORTA,2
            CALL     RETARDO
            BCF      PORTA,2
            CALL     RETARDO
            BSF      PORTA,2
            CALL     RETARDO
            GOTO INICIO
            
    END
```
 Programa realizado por Rubén Sánchez. El cual muestra en una LCDx4 la temperatura que recibe de un sensor de temperatura análogo "LM35" implementado en un "PIC18F4550". 

En la parte de abajo adjunto un archivo llamado LM35.rar donde se encuentra el archivo de proteus y el código.


----------



## Marydany (Ene 22, 2013)

Buenos Días estoy realizando un pequeño proyecto usando PIC18F4550 Un controlador de temperatura usando LM35 con salida a display que comando puedo usar para que oscile entre 15 y 20°c como tal aquí les dejo el programa ya me dio el conversor 



```
;PRUEBA DEL CONVERTIDOR

    LIST        P=18F4550
    #INCLUDE    <P18F4550.INC>
    ORG    0X0000
    GOTO    INICIO
    ORG    0X0008
    RETFIE    
    ORG    0X0018
    RETFIE

;DECLARACION DE REGISTROS GENERALES
    
BINARIO        EQU    0X0A1
BCD_H        EQU    0X0A2
BCD_M        EQU    0X0A3
BCD_L        EQU    0X0A4
FC4H        EQU    0x0B1
FC3H        EQU    0X0B2

;CONFIGURACION DE PUERTOS

        INICIO
        CLRF    TRISD
        CLRF    PORTD
        CLRF    TRISC
        CLRF    PORTC

;CONFIGURACION DEL ADC

        MOVLW    B'00111110'
        MOVWF    ADCON1
        MOVLW    B'00000001'
        MOVWF    ADCON0
        MOVLW    B'00010100'
        MOVWF    ADCON2
    
;PROGRAMA PRINCIPAL

        PRINCIPAL
        BSF    ADCON0,GO_DONE
BUCLE        BTFSC    ADCON0,GO_DONE
        GOTO    BUCLE
        MOVFF    ADRESH,BINARIO
        CALL    BINTOBCD
        GOTO    PRINCIPAL

BINTOBCD    ;MOVWF    BINARIO
        CLRF    BCD_L
        CLRF    BCD_M
        CLRF    BCD_H

CENTENA        MOVLW    .100
        SUBWF    BINARIO,W
        BTFSS    STATUS,C
        GOTO    DECENA
        MOVWF    BINARIO
        INCF    BCD_H,F
        GOTO    CENTENA

DECENA        MOVLW    .10
        SUBWF    BINARIO,W
        BTFSS    STATUS,C
        GOTO    UNIDAD
        MOVWF    BINARIO
        INCF    BCD_M,F
        GOTO    DECENA

UNIDAD        MOVF    BINARIO,W
        MOVWF    BCD_L
        CLRF    BINARIO
        MOVFF    BCD_M,PORTC
        MOVFF    BCD_L,PORTD
        RETURN
        END
```


----------



## Xander1493 (Abr 14, 2015)

Hola*.* *H*e probado y simulado tanto en proteus como en físico el programa del amigo rubencho987 y el 99% sale okay, pero solo un pequeño problema, es que al cabo de pasar un tiempo de 4 a 5 minutos de simulación en proteus o prueba en físico, el PIC se resetea solo y se comien*z*a a ejecutar de nuevo el programa*.*
*L*es agradecería mucho si alguien me pudiera decir por *qué* ocurre eso y como podría solucionarlo*.*

*D*e antemano, muchas gracias.


----------



## D@rkbytes (Abr 14, 2015)

Seguramente se eso se debe a que ese programa no tiene la palabra de configuración.
Entonces por defecto queda activo el fuse WDT (Watchdog Timer) y eso provocará un reset en el PIC cuando este timer se desborde.

Aparte, si no se incluye o no se configura de forma correcta la palabra de configuración, el PIC no trabajará a la frecuencia requerida.


----------

