Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
int8 x; // Declaramos el valor de X como byte, se corresponder con los 8 LEDs de salida.
int8 enc; // Se almacenar el valor actual de RA0 y RA1, hasta la siguiente comparacin.
int8 aux; // Se almacenar el valor anterior de RA0 y RA1, hasta la siguiente comparacin.
while (true)
{
aux=enc; // Igualamos 'AUX' y 'ENC' para luego comparar cuando cambie 'ENC'.
enc=porta & 3; // Aislamos RA0 y RA1 como un nmero de 2 bits y se carga en la variable 'ENC'.
Este lector de encoder usa la interrupcin externa RB0/INT. Cuando se produce un cambio de
estado en la patilla RB0/INT, el micro deja lo que estaba haciendo y saltar a un procedimiento de
forma inmediata. Terminado ese procedimiento vuelve al programa principal.
Funciona de la siguiente manera: Podemos hacer que la interrupcin se active con un flanco de
subida o de bajada, esto es programable modificando el registro INTEDG. Cuando ocurre una
interrupcin por flanco de subida hemos de programar la siguiente interrupcin para que se active
por flanco de bajada e incrementamos el contador si RB1 est a 1. Y viceversa, si ocurre una
interrupcin por flanco de bajada hemos de programar la siguiente interrupcin por flanco de
subida y decrementamos el contador si RB1 est a 1.
Una cosa muy buena que tiene esta forma de funcionar es que mientras el PIC no recibe
interrupciones (RB0/INT en este caso) puede dedicarse a hacer otra cosa, como por ejemplo,
calcular velocidades y cosas as. Como contrapartida, las interrupciones tienen un problema, y es
que si intentas hacer comunicaciones por el puerto serie, podra perturbar los tiempos de
temporizacin que rige la comunicacin y hacer que falle. Adems, recomiendo que cuando se
use la interrupcin RB0/INT no se use otras interrupciones (sea internas o externas), porque si ha
de contar, esas otras interrupciones puede impedir el contaje.
#include <16F876A.h>
#FUSES NOWDT, XT, PUT, NOPROTECT, NODEBUG, NOBROWNOUT, NOLVP, NOCPD, NOWRT
#use delay(clock=4000000)
#ZERO_RAM
#byte porta = 0x05 // Asignamos PortA (No lo usamos).
#byte portb = 0x06 // Asignamos PortB (Usamos RB0 y RB1).
#byte portc = 0x07 // Asignamos PortC (8 salidas a LED).
// ------ Variable Global ------
int8 x=0; //Declaramos el valor de X como byte, es decir, 8 bits.
// ---------- Interrupcin ----------
#INT_EXT
void IntRB0()
{
if (bit_test(portb,0)) // Si RB0 se ha puesto a 1 (flanco de subida),
{
ext_int_edge(H_TO_L); //entonces activar la interrupcin flanco bajada.
if (bit_test(portb,1)) // Si RB1 est 1,
{
x++; // entonces incrementar el contador X.
}
}
else // Si RB0 se ha puesto a 0 (flanco de bajada),
{
ext_int_edge(L_TO_H); //entonces activar la interrupcin flanco subida.
if (bit_test(portb,1)) // Si RB1 est 1,
{
x--; // entonces decrementar el contador X.
}
}
}
// ---------- Programa Principial ----------
void main()
{
port_b_pullups(FALSE);
setup_adc_ports(NO_ANALOGS);
setup_adc(ADC_CLOCK_DIV_2);
setup_spi(SPI_SS_DISABLED);
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
setup_comparator(NC_NC_NC_NC);
setup_vref(FALSE);
While (true)
{
portc = x; //El valor de X sale por el puerto C, 8 LED de salida.
}
}
PIC Encoder con un 18F4550.
Funciona de la siguiente manera: Podemos hacer que la interrupcin se active con un flanco de
subida o de bajada, esto es programable modificando el registro INTEDG. Cuando ocurre una
interrupcin por flanco de subida hemos de programar la siguiente interrupcin para que se
active por flanco de bajada e incrementamos el contador si RB1 est a 1. Y viceversa, si ocurre
una interrupcin por flanco de bajada hemos de programar la siguiente interrupcin por flanco
de subida y decrementamos el contador si RB1 est a 1. cuenta los pulsos de forma muy
eficiente.
Los PICs 18F2455 y 18F2550 no tienen puerto D, tendras que hacer la salida a los LED a
travs del puerto A (sin olvidar poner una resistencia de RA4 a positivo porque es salida con
colector abierto). En este caso slo tendramos 6 bits en vez de 8 pero para ver el
funcionamiento de conteo es suficiente.
En principio el programa est configurado para un cristal de 4MHz pero como en este ejercicio
no usamos el USB puedes usar el cristal que desees mientras est en el rango de 4 a 20MHz,
porque no se utiliza temporizaciones ni nada parecido.
While (True)
{
PortD = x; // El valor de X sale por el Puerto D a los 8 LED.
}
}