#include <16F628A.h>
#FUSES NOWDT //No Watch Dog Timer
#FUSES INTRC //Internal RC Osc
#FUSES PUT //Power Up Timer
#FUSES PROTECT //Code protected from reads
#FUSES NOBROWNOUT //No brownout reset
#FUSES NOMCLR //Master Clear pin used for I/O
#FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOCPD
//#device adc=8//La resolución del módulo A/D es de 8 bits.
#use delay(int=4000000)
#byte PORTA = 5
char Decena,Unidad,TempBin,AuxBin,var=0,TempSeteo=37,Actualizar=1,TempAnterior=0,MostrarSeteo=0,Seteando=0,i=0;
int8 ValorADC=0;
#include <Display.c>
//#include <Display_Punto.c>
#include <1wire.c>
#include <1820.c>
#int_TIMER1
Void TIMER1_isr(void)
{
TempBin=ds1820_read();
AuxBin=TempBin%100;//Resto de la division por 100
Decena=AuxBin/10;
Unidad=AuxBin%10;
Mostrar_Numero();
//if(!(bit_test(PORTA,5)))
//{
//set_adc_channel(3);
//delay_us(20);
//ValorADC=read_adc();
//delay_ms(5);
//TempSeteo=(ValorADC/255)*43+37;
//AuxBin=TempSeteo%100;//Resto de la division por 100
//Decena=AuxBin/10;
//Unidad=AuxBin%10;
//}
set_timer1(0x0BDC);//set_timer1(0x0BDC);//carga del TMR
}
void main()
{
// setup_adc_ports(sAN3|VSS_VDD);
//setup_adc(ADC_CLOCK_INTERNAL);
//set_adc_channel(3);
//delay_ms(5);
setup_ccp1(CCP_OFF);
setup_comparator(NC_NC_NC_NC);
#use delay (clock=4000000) //Fosc=4Mhz
set_tris_b(0x00); //portb como salida
set_tris_a(0x38); //porta como Entrada
enable_interrupts(INT_TIMER1);
setup_timer_1 ( T1_INTERNAL | T1_DIV_BY_8); //
set_timer1(0x0BDC);//set_timer1(0x0BDC);//carga del TMR
enable_interrupts(GLOBAL); //activadas interrupciones
while(1){
Mostrar_Numero();
}
}Mostrar_Numero(void)
{
int Tabla7seg[10]={0xEE,0x82,0xDC,0xD6,0xB2,0x76,0x7E,0xC2,0xFE,0xF6}; //7seg hex 0-9
output_b(Tabla7seg[Unidad]); //muestra por portb digito 7 segmentos
output_a(0x01);
delay_ms(5);
output_a(0x00);
//--------------
output_b(Tabla7seg[Decena]); //muestra por portb digito 7 segmentos
output_a(0x02);
delay_ms(5);
output_a(0x00);
//-----------------
// output_b(Tabla7seg[Centena]); //muestra por portb digito 7 segmentos
// output_a(0x04);
//delay_ms(15);
//output_a(0x00);
}
En ves de cada ves que entras a la interrupcion mostras todos los numeros, trata de que cada ves que entras a la interrupcion mostrar 1 solo. Eso te va a llevar a una interrupcion mas rapida. Mostras 1, salis, entras y ahora mostras el otro, salis, entras a la interrupcion y comenzs de vuelta.Hola Killer, mi interrupcion esta calculada para que se de cada 500 ms, al poner un delay de unos ms en la interrupcion no afectaria ya que esta se da cada 500 ms de todas manera lo voy a sacar. El muestreo lo hago en la interrupcion y en el while porque sino me muestra solo la decena en el display, no es logico lo se pero, pero es asi y no se la razon.
Solo necesitas calcular de nuevo los valores cuando sea necesario ( suponete cada 100 veces que entra a la interrupcion - digamos cada 0.5s o 1s ). Trata de actualizarlos siempre cuando empeces el ciclo de muestra.
Nunca debes poner delays en la interrupcion, empecemos por ahi. Intenta hacerlo de la forma que te dije arriba. Y no se exactamente cuanto tiempo tiene tu timer pero trata de que sea menos.. que se produzca una interrupcion cada 10/25ms masomenos haciendo lo que dije al comienzo.
Y otra cosa, si tu interrupcion se encarga del display, no lo hagas tambien en el while.
Hola moe, como te ha dicho quita los delay de la interrupción ( y ser posible no los uses nunca una vez entres en el while(1)), deberías tener una tasa de refresco de unos 4ms y estas poniendo dos delay de 5ms osea un retarde de 10ms, además como también te han dicho, quita el refresco del display del while1 porque entonces esos 10ms son prácticamente continuos.gracias por responder, le voy a sacar la rutina de muestreo de la interrupcion, el tema no es que se vea con parpadeo es que se apaga periodicamente el display, con el codigo que paso a continuacion solo muestra las decenas y se apaga periodicamente
Par verlo bien sin parpadeos debes de refrescar cada 4ms y tienes 10ms, que además cuando se ejecutan con el while y salta la interrupción (si es que salta mientras esta en los delay) se pisan.
Un saludo
#include <16F628A.h>
#FUSES NOWDT //No Watch Dog Timer
#FUSES INTRC //Internal RC Osc
#FUSES PUT //Power Up Timer
#FUSES PROTECT //Code protected from reads
#FUSES NOBROWNOUT //No brownout reset
#FUSES NOMCLR //Master Clear pin used for I/O
#FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOCPD
//#device adc=8//La resolución del módulo A/D es de 8 bits.
#use delay(int=4000000)
#byte PORTA = 5
char Decena,Unidad,TempBin,AuxBin,var=0,TempSeteo=37,Actualizar=1,TempAnterior=0,MostrarSeteo=0,Seteando=0,i=0;
int8 ValorADC=0;
#include <Display.c>
//#include <Display_Punto.c>
#include <1wire.c>
#include <1820.c>
#int_TIMER1
Void TIMER1_isr(void)
{
TempBin=ds1820_read();
AuxBin=TempBin%100;//Resto de la division por 100
Decena=AuxBin/10;
Unidad=AuxBin%10;
set_timer1(0x0BDC);//set_timer1(0x0BDC);//carga del TMR
}
void main()
{
// setup_adc_ports(sAN3|VSS_VDD);
//setup_adc(ADC_CLOCK_INTERNAL);
//set_adc_channel(3);
//delay_ms(5);
setup_ccp1(CCP_OFF);
setup_comparator(NC_NC_NC_NC);
#use delay (clock=4000000) //Fosc=4Mhz
set_tris_b(0x00); //portb como salida
set_tris_a(0x38); //porta como Entrada
enable_interrupts(INT_TIMER1);
setup_timer_1 ( T1_INTERNAL | T1_DIV_BY_8); //
set_timer1(0x0BDC);//set_timer1(0x0BDC);//carga del TMR
enable_interrupts(GLOBAL); //activadas interrupciones
while(1){
Mostrar_Numero();
}
}
Hola Killer, mi interrupcion esta calculada para que se de cada 500 ms, al poner un delay de unos ms en la interrupcion no afectaria ya que esta se da cada 500 ms de todas manera lo voy a sacar. El muestreo lo hago en la interrupcion y en el while porque sino me muestra solo la decena en el display, no es logico lo se pero, pero es asi y no se la razon.
por otro lado si fijo los valores de las decenas y unidades con antelacion, el display las muestra sin parpadeos
gracias por responder, le voy a sacar la rutina de muestreo de la interrupcion, el tema no es que se vea con parpadeo es que se apaga periodicamente el display, con el codigo que paso a continuacion solo muestra las decenas y se apaga periodicamente
float ds1820_read()
{
int8 busy=0, temp1, temp2;
signed int16 temp3;
float result;
onewire_reset();
onewire_write(0xCC);
onewire_write(0x44);
while (busy == 0)
busy = onewire_read();
onewire_reset();
onewire_write(0xCC);
onewire_write(0xBE);
temp1 = onewire_read();
temp2 = onewire_read();
temp3 = make16(temp2, temp1);
result = (float) temp3 / 2.0; //Calculation for DS18S20 with 0.5 deg C resolution
// result = (float) temp3 / 16.0; //Calculation for DS18B20 with 0.1 deg C resolution
delay_ms(25);
return(result);
}
#include <16F88.h>
#FUSES NOWDT //No Watch Dog Timer
#FUSES INTRC //Internal RC Osc
#FUSES PUT //Power Up Timer
#FUSES PROTECT //Code protected from reads
#FUSES NOBROWNOUT //No brownout reset
#FUSES NOMCLR //Master Clear pin used for I/O
#FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOCPD
//#device adc=8//La resolución del módulo A/D es de 8 bits.
#use delay(int=4000000)
#byte PORTA = 5
char Decena=0,Unidad=0,TempBin,AuxBin,TempSeteo=37;
int8 ValorADC=0;
#include <Display.c>
#include <1wire.c>
#include <1820.c>
#int_TIMER1
Void TIMER1_isr(void)
{
set_timer1(0x0BDC);//set_timer1(0x0BDC);//carga del TMR
if((bit_test(PORTA,3)))TempBin=ds1820_read();
else TempBin=TempSeteo;
if(!(bit_test(PORTA,5)))
{
TempSeteo=TempSeteo+1;
if(TempSeteo==86)TempSeteo=30;
}
if(!(bit_test(PORTA,6)))
{
TempSeteo=TempSeteo-1;
if(TempSeteo==29)TempSeteo=85;
}
AuxBin=TempBin%100;//Resto de la division por 100
Decena=AuxBin/10;
Unidad=AuxBin%10;
}
void main()
{
setup_comparator(NC_NC_NC_NC);
#use delay (clock=4000000) //Fosc=4Mhz
set_tris_b(0x00); //portb como salida
set_tris_a(0x38); //porta como Entrada
enable_interrupts(INT_TIMER1);
setup_timer_1 ( T1_INTERNAL | T1_DIV_BY_4); //
set_timer1(0x0BDC);//set_timer1(0x0BDC);//carga del TMR
enable_interrupts(GLOBAL); //activadas interrupciones
while(1){
Mostrar_Numero();
}
}cual es el error en este codigo que no me permite dejarle el while a la rutina del ds1820?
El tema es que mientras se este ejecutando la rutina del ds1820 con el while el refresco no se va a hacer, por eso se apaga el display, cual seria la forma de evitar eso¿?
En ves de cada ves que entras a la interrupcion mostras todos los numeros, trata de que cada ves que entras a la interrupcion mostrar 1 solo. Eso te va a llevar a una interrupcion mas rapida. Mostras 1, salis, entras y ahora mostras el otro, salis, entras a la interrupcion y comenzs de vuelta.
Solo necesitas calcular de nuevo los valores cuando sea necesario ( suponete cada 100 veces que entra a la interrupcion - digamos cada 0.5s o 1s ). Trata de actualizarlos siempre cuando empeces el ciclo de muestra.
Nunca debes poner delays en la interrupcion, empecemos por ahi. Intenta hacerlo de la forma que te dije arriba. Y no se exactamente cuanto tiempo tiene tu timer pero trata de que sea menos.. que se produzca una interrupcion cada 10/25ms masomenos haciendo lo que dije al comienzo.
Y otra cosa, si tu interrupcion se encarga del display, no lo hagas tambien en el while.