Y por fin le damos una vuelta de tuerca al Tema de Capturar el ancho de un pulso ...
Por indicación del amigo filth ampliamos lo que hemos visto en
Midiendo un pulso. 1ª Parte. Tiempo en Alto con INTEXT y en
Midiendo un pulso. 2ª Parte. Tiempo en Alto con INTCCP.
En ambas hemos utilizado la técnica de recoger el valor de TMR1 cuando ocurre o la interrupción externa por RB0 o la interrupcion CCP, sea en el flanco de caída, sea en el de subida. Con los valores de ambos flancos y simplemente restando el uno del otro tenemos el valor del ancho del pulso.
Hay otra manera de hacer exactamente lo mismo utilizando una tercera fuente de interrupción de los PIC's: Utilizando la
intetrrupción por cambio de estado de RB04:7A.- Conceptos involucrados:Los conceptos son exactamente los mismos que los descritos en las parte anteriores por lo que os ruego que consultéis si os es necesario:
Midiendo un pulso. 1ª Parte y/o
2ª Parte.B.- Técnica a Aplicar:La
interrupción por Cambio de Estado de los pines 4 a 7 del PORTB es una interrupción muy socorrida aunque
algo falta de precisición. No dispone como en nuestros anteriores ejemplos INTEXT e INTCCP de la posibilidad de pre-programar el flanco que deseamos que dispare la Petición de Servicio de Interrupción (
ISR).
Aunque esta interrupción, a la que a partir de aquí llamaremos
INTRB, afecta en principio a los bits desde el 4 hasta el 7 del PORTB, solo lo hará efectivamente a aquellos que esten
configurados como de entrada, que hayamos programado con el TRIS a 1.
Al dispararse la interrupción solo sabemos que
uno o mas de estos pines ha cambiado de estado. Nada mas, ni nada menos.
Por ello es
imprescindible al usar
INTRB que vayamos recogiendo sobre una variable estática de un byte los
cambios sucesivos que se van produciendo para poder
comparar en el momento de recibir la interrupción el estado
actual del PORTB con el inmediatamente
anterior.
Así si el bit correspondiente al pin que estamos utilizando para nuestra medición del pulso es igual
en el estado actual que en el anterior
no tenemos cambio en el pulso y además no ha sido éste pin el responsable de disparar la interrupción.
Si el estado
anterior era bajo y el actual es alto estamos ante el
flanco de subida de nuestro pulso y además es él quien ha producido el disparo de la interrupción.
Si por el contrario el estado
anterior del pin era alto y ahora es bajo entonces acabamos de detectar el
flanco de bajada de nuestro pulso, y por supuesto también ha sido él el responsable de disparar la interrupción INTRB.
Con esta información realizaremos exactamente igual que en los ejemplos anteriores: guardamos el valor de TMR1 tras el flanco de subida y tras el de bajada, realizamos la correspondiente resta entre ambos valores y transmitimos los resultados.
C.- Implementación en C:Para
configurar inicialmente nuestra interrupción INTRB debemos hacer que nuestro pin, en este caso el 4, sea de entrada, y habilitaremos las interrupciones necesarias con:
set_tris_b(0b00010000); // Habilito como entrada RB7 para interrupción RB
enable_interrupts(int_rb);
enable_interrupts(global);
Nuestra
rutina ISR para INTRB quedaría como sigue:
int estado_portb_anterior=0;
int estado_portb_actual=0;
...
#int_rb
void handle_rb_int(){
estado_portb_actual=input_b();
if ((!bit_test(estado_portb_anterior,4))&&(bit_test(estado_portb_actual,4)))
{
hay_flanco_de_bajada=0;
}
if(hay_flanco_de_bajada!=0){ // He recibido Flanco de Subida
t1=get_timer1(); // Guardo en t1 el valor de TMR1 al Flanco de Subida
} else { // He recibido Flanco de Bajada
t2=get_timer1(); // Guardo en t2 el valor de TMR1 al Flanco de Bajada
set_timer1(0); // Reinicio TMR1
if(flagHayDatos==0){ // Si los datos anteriores han sido procesados ...
flagHayDatos=1; // Indico que ya hay nuevos datos de flancos para calcular
}
}
}
El resto de la implementación en C de esta Técnica es identica a la mostrada en
Midiendo un pulso. 1ª Parte. Tiempo en Alto con INTEXT y
Midiendo un pulso. 2ª Parte. Tiempo en Alto con INTCCPBueno, y esto es todo por hoy amigos.
Mañana, más.