Autor Tema: Problema Sensor de temp y 3 displays  (Leído 6412 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado aripod

  • PIC16
  • ***
  • Mensajes: 170
Problema Sensor de temp y 3 displays
« en: 17 de Noviembre de 2008, 16:35:53 »
Estoy haciendo un sensor de temp con 3 displays y un 16f877a. El codigo es el siguiente:

Código: [Seleccionar]
#include <16f877a.h>            //pic a utilizar         
#fuses XT,NOWDT,NOPROTECT,PUT,NOLVP      //ordenes para el programador
#use delay (clock=4000000)         //Fosc=4Mhz


void mostrar(int temperatura);
float temperatura=0;
void main(void)
{
set_tris_b(0x00); 
set_tris_c(0x00);
output_low(pin_C0);
output_low(pin_C1);
output_low(pin_C2);

setup_adc_ports(NO_ANALOGS);
setup_adc_ports(RA0_ANALOG);
setup_adc(ADC_CLOCK_INTERNAL);
set_adc_channel(0); //Canal 0.
delay_ms(1);


while(1)
   {
mostrar(temperatura=read_adc()*(500/255));
   }
}


void mostrar(int temperatura)
{
int decenas=0, unidades=0, decimales=0;
int tab7seg[10]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x67};
while(temperatura>100)
   {
   temperatura=temperatura-100;
   decenas++;
   }

while(temperatura>10)
   {
   temperatura=temperatura-10;
   unidades++;
   }

while(temperatura>0)
   {
   temperatura=temperatura-1;
   decimales++;
   }

output_high(pin_C0);
output_b(tab7seg[decenas]);
delay_ms(5);
output_low(pin_C0);
delay_ms(5);   //VER SI PUEDEN SER MENORES O CERO.
output_high(pin_C1);
output_b(tab7seg[unidades]);
delay_ms(5);
output_low(pin_C1);
delay_ms(5);   //VER SI PUEDEN SER MENORES O CERO.
output_high(pin_C2);
output_b(tab7seg[decimales]);
delay_ms(5);
output_low(pin_C2);
delay_ms(5);   //VER SI PUEDEN SER MENORES O CERO.
}

La idea es que muestre la temp por los tres displays, DECENAS UNIDADES. DECIMALES, por eso en la conversion multiplico el dato por (500/255), para poder tener los tres digitos en un solo numero entero. Definitivamente algo esta mal porque poniendo valor en la RA0 que seria la temp me muestra cualquier valor.
El sensor me tira 100mv/°c. Dejo el archivo del proteus tambien....

Gracias por la ayuda!

Desconectado MLO__

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 4581
Re: Problema Sensor de temp y 3 displays
« Respuesta #1 en: 17 de Noviembre de 2008, 17:29:26 »
El papel lo aguanta todo

Desconectado aripod

  • PIC16
  • ***
  • Mensajes: 170
Re: Problema Sensor de temp y 3 displays
« Respuesta #2 en: 23 de Noviembre de 2008, 20:25:37 »
Volvi al codigo, tenia un problema con los tipos de las variables....declare float y anda bien. AHora estoy con lo de los 7 segs y la interrupcion,,,,nunca lo hice asi...gracias por el link...
Donde puedo conseguir informacion para aprender a utilizar las interrupciones para cualquier fin, no solo para mnostrar algo en los displays? Gracias!

Desconectado MLO__

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 4581
Re: Problema Sensor de temp y 3 displays
« Respuesta #3 en: 23 de Noviembre de 2008, 21:34:26 »
Hola.

Aqui en el foro hay muuuuuucha info sobre eso. Usa el buscador y listo.

Saludos
El papel lo aguanta todo

Desconectado aripod

  • PIC16
  • ***
  • Mensajes: 170
Re: Problema Sensor de temp y 3 displays
« Respuesta #4 en: 24 de Noviembre de 2008, 11:06:51 »
Suponiendo que quiero que haga algo la interrupcion cada 1ms, que pasa con lo del main? Se hacen las dos cosas, paralelamente digamos??

Desconectado MLO__

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 4581
Re: Problema Sensor de temp y 3 displays
« Respuesta #5 en: 24 de Noviembre de 2008, 20:59:41 »
Hola.

Las ISR son justamente para eso, el main se cumlple normalmente, al 1 milisegundo se interrumpe el codigo que se esta ejecutando y se atiende el servicio de interrupcion, hace lo que tiene que hacer y luego retorna a la parte del codigo donde se habia quedado antes de interrumpirse.

Saludos
El papel lo aguanta todo

Desconectado aripod

  • PIC16
  • ***
  • Mensajes: 170
Re: Problema Sensor de temp y 3 displays
« Respuesta #6 en: 29 de Noviembre de 2008, 20:18:45 »
Bueno, retomo el tema.....SI quiero hacer la interrupcion cada 1ms, y seguin la formula: T = (256 - precarga) * Preescaler * 4 / Fosc ; con Preescaler 256 y Fosc 4Mhz, precarga=252. Esto significa que necesito que empiece a contar desde 252 para que llegue a 255 asi se desborda cada 1ms?
Suponiendo que asi sea, dentro de #int_RTCC que es lo que tengo que hacer? Ver si se desbordo el timer0 y si asi paso ponerlo en 252....?

Desconectado MLO__

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 4581
Re: Problema Sensor de temp y 3 displays
« Respuesta #7 en: 30 de Noviembre de 2008, 14:07:45 »
Hola.

Cuando entra a la parte de #int_RTCC, es porque el timer ya se desbordo y por ende ya entro a la interrupcion. Si quieres que sea 1mS exacto deberias colocar dentro de la interrupcion set_timer(precarga), de esta manera vuelve a contar pero teniendo en cuenta el valor de la precarga, yo no lo hice asi ... no afectan mucho los 24uS que estan de extra en la visualizacion, pero si quieres bases de tiempo mas precisas entonces usa el set_timer(precarga) dentro de la int.

Código: CSS
  1. #int_TIMER0
  2. void display_isr(void)
  3. {
  4.  set_timer0(value);//value: valor calculado para el desborde
  5.  ....
  6. }

Saludos

El papel lo aguanta todo

Desconectado aripod

  • PIC16
  • ***
  • Mensajes: 170
Re: Problema Sensor de temp y 3 displays
« Respuesta #8 en: 03 de Diciembre de 2008, 09:57:50 »
Segun lo que entendi, el codigo deberia ser asi:

Código: [Seleccionar]
#include <16f877a.h>            //pic a utilizar         
#fuses XT,NOWDT,NOPROTECT,PUT,NOLVP      //ordenes para el programador
#use delay (clock=4000000)         //Fosc=4Mhz


void mostrar(long temperatura);
long temperatura=0;
void main(void)

set_tris_a(0x00); 
set_tris_b(0x00); 
set_tris_c(0x00);
set_tris_d(0x00);
output_low(pin_C0);
output_low(pin_C1);
output_low(pin_C2);

output_a(0x00);
output_b(0x00);
output_c(0x00);
output_d(0x00);

enable_interrupts(INT_RTCC);               // Habilito Interrupción RTCC.
setup_counters(RTCC_INTERNAL,RTCC_DIV_256);// TIMER0: Clock Interno, Presescaler 256.
set_timer0(252);

setup_adc_ports(NO_ANALOGS);
setup_adc_ports(RA0_ANALOG);
setup_adc(ADC_CLOCK_INTERNAL);
set_adc_channel(0); //Canal 0.



while(1)
   {
    temperatura=read_adc()*(100/51);
   }
}

#int_TIMER0
void Timer0_isr(void)
{
mostrar(temperatura);
set_timer0(252);
}

void mostrar(long temperatura)
{
int decenas=0, unidades=0, decimales=0;
int tab7seg[10]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x67};
while(temperatura>100)
   {
   temperatura=temperatura-100;
   decenas++;
   }

while(temperatura>10)
   {
   temperatura=temperatura-10;
   unidades++;
   }

while(temperatura>0)
   {
   temperatura=temperatura-1;
   decimales++;
   }

output_high(pin_C0);
output_b(tab7seg[decenas]);
delay_ms(5);
output_low(pin_C0);
delay_ms(5);   //VER SI PUEDEN SER MENORES O CERO.
output_high(pin_C1);
output_b(tab7seg[unidades]);
delay_ms(5);
output_low(pin_C1);
delay_ms(5);   //VER SI PUEDEN SER MENORES O CERO.
output_high(pin_C2);
output_b(tab7seg[decimales]);
delay_ms(5);
output_low(pin_C2);
delay_ms(5);   //VER SI PUEDEN SER MENORES O CERO.
}

Pero definitivamente entendi mal ya que no se prenden nunca los displays......esta claro que no entiendo bien que es lo ke hay que hacer cuando entra a la interrupcion. NO tengo que hacer ahi lo que quiero hacer y al salir poner el valor del TIMER0 en el valor de precarga??

Vi tu ejemplo MLO_ y por lo que entendi, todo lo que haces dentro de la interrupcion es lo que cada uno necesita para su necesidad?
« Última modificación: 03 de Diciembre de 2008, 10:12:01 por aripod »

Desconectado MLO__

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 4581
Re: Problema Sensor de temp y 3 displays
« Respuesta #9 en: 03 de Diciembre de 2008, 12:39:44 »
Hola.

No es bueno colocar delays tan largos en las interrupciones, mira que tu estas despelgando los datos cada 5mS dentro de la misma interrupcion que se desborda cada milisegundo.

Otra cosa: Las interrupciones debes definirlas antes del programa principal, no despues como tu las tienes definidas.

Saludos
El papel lo aguanta todo

Desconectado aripod

  • PIC16
  • ***
  • Mensajes: 170
Re: Problema Sensor de temp y 3 displays
« Respuesta #10 en: 03 de Diciembre de 2008, 14:00:17 »
Entonces kizas estoy yendo por mal camino. Mi idea es que se ejecute el main, pero cada 1ms salte a la interrupcion, haga el barrido de los displays y vuelva al main y siga haciendo sus cosas, y al 1ms vuelva a la interrupcion, todo esto dure lo ke dure la misma....

Desconectado MLO__

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 4581
Re: Problema Sensor de temp y 3 displays
« Respuesta #11 en: 03 de Diciembre de 2008, 14:31:45 »
Hola.

Lo que yo hago con la interrupcion es multiplexar los datos. Es decir: tengo 4 variables, unidades_var1, decenas_var1, unidades_var2 y decenas_var2, cada vez que entra a la interrupcion (cada 1.024 mS) despliego las variables.

Para la primera interrupcion del timer0, visualizo las unidades de la primera variable:


Para la siguiente interrupcion del timer0, visualizo las decenas de la primera variable:


Para la 3 interrupcion del timer0, visualizo las unidades de la segunda variable:


Para la 4 interrupcion del timer0, visualizo las decenas de la segunda variable y reinicio el contador de las interrupciones para que el proceso reinicie:


Dentro de la misma interrupcion lo que hago primero es pasar el valor de las variables a BCD, es decir si tengo el valor d56 en value_1 lo convierto en 0x56, para pasar primero el valor 6 (unidades) y luego el valor 5 (decenas)
Código: C#
  1. dato_1 = int2bcd(value_1);
  2.         dato_2 = int2bcd(value_2);

Y el valor de las variables las cargo en el programa principal:
Código: C#
  1. while(true)
  2.  {
  3.         set_adc_channel(0);
  4.         delay_us(10);
  5.         value_1 = pc * read_adc();
  6.         set_adc_channel(1);
  7.         delay_us(10);
  8.         value_2 = resolucion * read_adc();
  9.         //delay_ms(1000);
  10.  }

Espero te ayude la aclaracion -y no haberte enrredado mas-

Saludos
El papel lo aguanta todo

Desconectado aripod

  • PIC16
  • ***
  • Mensajes: 170
Re: Problema Sensor de temp y 3 displays
« Respuesta #12 en: 03 de Diciembre de 2008, 21:31:53 »
Entendi bien la idea, programe lo siguiente; pero no se prenden los displays......dejo el codigo y la simulacion:

Código: [Seleccionar]
#include <16f877a.h>            //pic a utilizar         
#fuses XT,NOWDT,NOPROTECT,PUT,NOLVP      //ordenes para el programador
#use delay (clock=4000000)         //Fosc=4Mhz

int decenas=0, unidades=0, decimales=0, interrupciones=1;
int tab7seg[10]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x67};
#int_TIMER0
void Timer0_isr(void)
{
switch(interrupciones)
{
case 1:
output_high(pin_C0);
output_b(tab7seg[decenas]);
delay_ms(5);
output_low(pin_C0);
delay_ms(5);   //VER SI PUEDEN SER MENORES O CERO.
interrupciones++;
break;

case 2:
output_high(pin_C1);
output_b(tab7seg[unidades]);
delay_ms(5);
output_low(pin_C1);
delay_ms(5);   //VER SI PUEDEN SER MENORES O CERO.
interrupciones++;
break;

default:
output_high(pin_C2);
output_b(tab7seg[decimales]);
delay_ms(5);
output_low(pin_C2);
delay_ms(5);   //VER SI PUEDEN SER MENORES O CERO.
interrupciones=1;
break;
}
set_timer0(252);
}

void conversion_bcd(long temperatura);
long temperatura=0;
void main(void)

set_tris_a(0x00); 
set_tris_b(0x00); 
set_tris_c(0x00);
set_tris_d(0x00);
output_low(pin_C0);
output_low(pin_C1);
output_low(pin_C2);

output_a(0x00);
output_b(0x00);
output_c(0x00);
output_d(0x00);

enable_interrupts(INT_RTCC);               // Habilito Interrupción RTCC.
setup_counters(RTCC_INTERNAL,RTCC_DIV_256);// TIMER0: Clock Interno, Presescaler 256.

setup_adc_ports(NO_ANALOGS);
setup_adc_ports(RA0_ANALOG);
setup_adc(ADC_CLOCK_INTERNAL);
set_adc_channel(0); //Canal 0.
set_timer0(252); //T = (256 - precarga) * Preescaler * 4 / Fosc --->>> precarga=252

while(1)
   {
    temperatura=read_adc()*(100/51);
conversion_bcd(temperatura);

   }
}


void conversion_bcd(long temperatura)
{
while(temperatura>100)
   {
   temperatura=temperatura-100;
   decenas++;
   }

while(temperatura>10)
   {
   temperatura=temperatura-10;
   unidades++;
   }

while(temperatura>0)
   {
   temperatura=temperatura-1;
   decimales++;
   }
}

Desconectado MLO__

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 4581
Re: Problema Sensor de temp y 3 displays
« Respuesta #13 en: 03 de Diciembre de 2008, 22:20:39 »
Hola.

Debes organizar un poco el codigo.
Código: C#
  1. setup_adc_ports(NO_ANALOGS);
  2. setup_adc_ports(RA0_ANALOG);
  3. setup_adc(ADC_CLOCK_INTERNAL);
  4. setup_counters(RTCC_INTERNAL,RTCC_DIV_256);// TIMER0: Clock Interno, Presescaler 256.
  5. set_adc_channel(0);     //Canal 0.
  6. set_timer0(252);        //T = (256 - precarga) * Preescaler * 4 / Fosc --->>> precarga=252
  7. enable_interrupts(INT_RTCC);               // Habilito Interrupción RTCC.
  8. enable_interrupts(GLOBAL);

Mira que te faltaba habilitar las interrupciones con enable_interrupts(GLOBAL).

De todas formas, revisa bien el codigo de tu interrupcion, no es la manera adecuada de multiplexar.

Saludos
El papel lo aguanta todo

Desconectado MLO__

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 4581
Re: Problema Sensor de temp y 3 displays
« Respuesta #14 en: 03 de Diciembre de 2008, 22:54:12 »
Seria mas o menos asi con un switch{ case : }:

Código: C#
  1. #include <16f877a.h>            //pic a utilizar          
  2. #fuses XT,NOWDT,NOPROTECT,PUT,NOLVP      //ordenes para el programador
  3. #use delay (clock=4000000)         //Fosc=4Mhz
  4.  
  5. int decenas=0, unidades=0, decimales=0, interrupciones=0;
  6. int tab7seg[10]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x67};
  7. long temperatura=0;
  8.  
  9. void decimal2bcd(long temp);
  10.  
  11. #int_TIMER0
  12. void Timer0_isr(void)
  13. {
  14.         decimales=0; unidades=0; decenas=0;
  15.         decimal2bcd(temperatura);//Paso el valor a BCD
  16.         switch(interrupciones)
  17.         {
  18.                 case 0: output_high(pin_c0);//Apago el habilitador de las decenas
  19.                                 output_b(tab7seg[decimales]);//Pongo el numero de los decimales
  20.                                 output_low(pin_c2);//Enciendo el habilitador de los decimales
  21.                                 break;
  22.  
  23.                 case 1: output_high(pin_c2);//Apago el habilitador de los decimales
  24.                                 output_b(tab7seg[unidades]);//Pongo el numero de las unidades
  25.                                 output_low(pin_c1);//Enciendo el habilitador de las unidades
  26.                                 break;
  27.  
  28.                 case 2: output_high(pin_c1);//Apago el habilitador de las unidades
  29.                                 output_b(tab7seg[decenas]);//Pongo el numero de las decenas
  30.                                 output_low(pin_c0);//Enciendo el habilitador de las decenas
  31.                                 interrupciones=0;//Inicializo la variable para el multiplexaje
  32.                                 break;                         
  33.         }
  34.         interrupciones++;//Aumento la variable para el multiplexaje
  35. }
  36.  
  37. void main(void)
  38. {  
  39.         setup_adc_ports(RA0_ANALOG);
  40.         setup_adc(ADC_CLOCK_INTERNAL);
  41.         setup_counters(RTCC_INTERNAL,RTCC_DIV_256);// TIMER0: Clock Interno, Presescaler 256.
  42.         set_adc_channel(0);     //Canal 0.
  43.         set_timer0(252);        //T = (256 - precarga) * Preescaler * 4 / Fosc --->>> precarga=252
  44.         output_high(pin_c0);
  45.         output_high(pin_c1);
  46.         output_high(pin_c2);
  47.         enable_interrupts(INT_RTCC);               // Habilito Interrupción RTCC.
  48.         enable_interrupts(GLOBAL);
  49.        
  50.         while(true)
  51.         {
  52.                 temperatura=read_adc()*(100/51);
  53.         }
  54. }
  55.  
  56. void decimal2bcd(long temp)
  57. {
  58.         while(temperatura>100)
  59.         {
  60.                 temperatura=temperatura-100;
  61.                 decenas++;
  62.         }
  63.  
  64.         while(temperatura>10)
  65.         {
  66.                 temperatura=temperatura-10;
  67.                 unidades++;
  68.         }
  69.  
  70.         while(temperatura>0)
  71.         {
  72.                 temperatura=temperatura-1;
  73.                 decimales++;
  74.         }
  75. }

De todas maneras compilalo por si acaso.

Saludos
El papel lo aguanta todo