Hola
Pues, estoy que
con las interrupciones.
Recientemente me toco trabajar con unos display de 7 segmentos y tube el inconveniente de que si hacia la muestra de datos como subfuncion, dependia mucho del tiempo que duren otras funciones, si tomaban mucho tiempo, se veria un parpadeo en los displays.
Decidi utilizar la interrupcion del Timer0 para hacer la rutina de muestra de datos a travez de los displays cada 1mS aproximadamente.
El codigo que muestro es simple la verdad
.... muestro en un display el voltaje de 0 a 5 y en el otro un valor entre 0 y 99.
#include<18F442.h>
#device adc=8
#fuses XT, NOPROTECT, NOLVP
#use delay(clock=4M)
#define uni_p pin_d2
#define dec_p pin_d3
#define uni_t pin_c4
#define dec_t pin_c5
#define A PIN_B3
#define B PIN_B4
#define C PIN_B5
#define D PIN_B6
#define E PIN_B7
#define F PIN_B2
#define G PIN_B1
#define dp pin_d7
#define on output_high
#define off output_low
const float resolucion = 0.1961;
const float pc = 0.3921;
int8 ints_timer0 = 0;
int8 value_1 = 0, value_2 = 0, dato_1 = 0, dato_2 = 0;
int8 unidades_p = 0, decenas_p = 0, unidades_t = 0, decenas_t = 0;
void display (char numero)//display numero////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
{
switch (numero)
{
case 1 : off(b);off(c);on(a);on(d);on(e);on(f);on(g); break;
case 2 : OFF(A);OFF(B);ON(C);OFF(D);OFF(E);ON(F);OFF(G); break;
case 3 : off(a);off(b);off(c);off(d);off(g);on(e);on(f); break;
case 4 : off(b);off(c);off(f);off(g);on(a);on(d);on(e); break;
case 5 : off(a);off(f);off(g);off(c);off(d);on(b);on(e); break;
case 6 : off(a);off(f);off(e);off(d);off(c);off(g);on(b); break;
case 7 : off(a);off(b);off(c);on(d);on(e);on(f);on(g); break;
case 8 : off(a);off(b);off(c);off(d);off(e);off(f);off(g); break;
case 9 : off(a);off(b);off(c);off(f);off(g);on(e);on(d); break;
case 0 : off(a);off(b);off(c);off(d);off(e);off(f);on(g); break;
case 't':off(d);off(e);off(f);off(g);on(b);on(c);on(a); break;
case 'a':off(a);off(b);off(c);off(e);off(f);off(g);on(d); break;
default: on(a);on(b);on(c);on(d);on(e);on(f);on(g); break;
}
}
int8 int2bcd (int8 data)//int2bcd/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
{
int nibh;
int nibl;
nibh=data/10;
nibl=data-(nibh*10);
return((nibh<<4)|nibl);
}
#int_TIMER0
void Timer0_isr(void)
{
++ ints_timer0;
dato_1 = int2bcd(value_1);
dato_2 = int2bcd(value_2);
if(ints_timer0==1)
{
off(dec_t);
on(dp);
unidades_p = dato_1 & 0x0F;
display(unidades_p);
on(uni_p);
}
if(ints_timer0==2)
{
off(uni_p);
decenas_p = (dato_1>>4) & 0x0F;
display(decenas_p);
on(dec_p);
}
if(ints_timer0==3)
{
off(dec_p);
unidades_t = dato_2 & 0x0F;
display(unidades_t);
on(uni_t);
}
if(ints_timer0==4)
{
off(uni_t);
decenas_t = (dato_2>>4) & 0x0F;
display(decenas_t);
on(dec_t);
off(dp);
ints_timer0 = 0;
}
}
void main (void)
{
setup_adc(ADC_CLOCK_DIV_16);
setup_adc_ports(AN0_AN1_AN3);
setup_timer_1(T1_DISABLED);
setup_timer_0(RTCC_8_BIT | RTCC_DIV_4 | RTCC_INTERNAL);
enable_interrupts(INT_TIMER0);
enable_interrupts(GLOBAL);
off(uni_t);
off(dec_t);
off(dec_p);
off(uni_p);
on(dp);
while(true)
{
set_adc_channel(0);
delay_us(10);
value_1 = pc * read_adc();
set_adc_channel(1);
delay_us(10);
value_2 = resolucion * read_adc();
//delay_ms(1000);
}
}
El HW esta definido de tal manera que coincide con la tarjeta que tengo montada, pero para cambiarla es solo cambiar los pines. El delay al final es para actualizar el dato cada segundo...si se hubiera hecho el despliegue como funcion .... los display se hubieran quedado apagados ...
Bueno muchachos, comparto cada experiencia que paso, y me emociono cada vez mas pensando en lo que se puede aprender aqui
Saludos
PD// Anexo la simulacion en proteus