He usado PIC16F877
( hoja de datos ) para varios proyectos. Para interrupciones de cambio de un solo pin externo, puede usar PORTB0
interrupt. Pero ahora necesito admitir 8 interrupciones de cambio de pin externas independientes, en un solo circuito.
En la hoja de datos dice que hay 15 interrupciones PIC16F877
, pero supongo que se cuentan, incluidas las interrupciones de desbordamiento del temporizador, etc., que son inútiles en este caso.
Esto es lo que dice la hoja de datos sobre el INTCON
registro.
¿Puedo tener 4 interrupciones independientes usando bit0, RBIF
? Representa el cambio en PB7:PB4
. ¿Cómo puedo identificar qué pin cambió, es leyendo el valor del puerto en la rutina de interrupción?
Incluso si obtengo respuestas positivas a lo anterior, ¿necesito 8 interrupciones? por supuesto que todavía puedo usar INTE
, para PORTB0
cambiar. Entonces 4 + 1 = 5
, pero ¿qué pasa con los otros 3? (Sin embargo, como los 8 eventos de interrupción son del mismo tipo, la 4 + 1 + 3 = 8
cosa parece fea, ¿no?)
No se esperan otras tareas pesadas del microcontrolador aparte de monitorear 8 pines. (Hablando de las otras tareas, tendrá que mantener un conjunto de variables de contador separadas y con frecuencia transmitir alrededor de 4 bytes a la PC en serie)
Cualquier sugerencia es bienvenida. Aunque se trate de cambiar el microcontrolador por uno más adecuado (pero eh.. no me digas que me aleje de PIC
s).
Este es un pseudocódigo C para explicar una idea. Utiliza un OR exclusivo para determinar qué pines han cambiado y llamará a sus diferentes controladores dentro de una interrupción RBIE. Dependiendo de cuán crítica sea la aplicación, es posible que desee verificar cómo el PIC maneja situaciones como un cambio de puerto mientras se ejecuta la interrupción para asegurarse de que no se perderá ningún evento.
int old_port_b;
void isr_handler()
{
int new_port_b, changed_pins;
new_port_b = read_port_b();
changed_pins = new_port_b ^ old_port_b;
if (changed_pins | 1)
rb0_hander();
if (changed_pins | 2)
rb1_hander();
// ... etc
old_port_b = new_port_b;
}
int main()
{
old_port_b = read_port_b();
enable_interrupt();
}
RB7:RB4
4 pines. Pero estoy pidiendo una forma de monitorear 8 pines. ¿cualquier sugerencia?and four interrupts for the RB0:RB3
? PIC16F877 no admite interrupciones para RB1:RB3
, ¿eh?Esa parte solo tiene 4 interrupciones de cambio de pin y algunas otras que puede configurar en los bordes seleccionados. Una estrategia sería detectar un cambio en el valor de 8 bits externamente y luego interrumpir si no coincide. Eso se complica en el hardware, pero será exactamente lo que quieres.
Los parámetros importantes que no ha indicado son qué tan rápido necesita responder a un cambio de pin y cuánto tiempo mínimo persistirá un cambio de pin para que sea válido. Según las respuestas, puede sondear en función de una interrupción regular en el firmware. El 16F877 puede funcionar a una velocidad de instrucción de 5 MHz, y verificar si hay un cambio solo requeriría unas pocas instrucciones. Digamos que configura la interrupción cada 50 instrucciones. Eso dejaría una buena parte del tiempo del procesador al código de primer plano. La tasa de interrupción sería de 100 kHz y el período de 10 µs. Por supuesto, el código de primer plano aún necesita ver el indicador de cambio y hacer algo al respecto, por lo que el tiempo de respuesta será de más de 10 µs, pero no ha dicho nada sobre lo que debe hacer cuando se detecta un cambio. Si esto solo necesita responder en tiempo humano,
once per second
será suficiente. Cuando se detecta un cambio de pin (solo un borde, digamos ascendente), se debe incrementar un contador (variable). En el bucle principal, tiene que monitorear los valores del contador y cuando uno supera cierto valor, se deben transmitir cuatro bytes a través USART
de la PC. Luego reinicie el valor del contador relevante a cero. Simple como eso. Supongo que la opción de sondeo irá bien, ¿verdad?Puede usar la puerta NAND de 8 entradas como lo menciona @Brian Drummond para elevar una interrupción sobre el pin INT y también conectar sus fuentes de interrupción al registro de desplazamiento de entrada en paralelo/salida en serie de 8 bits como "74HC165N", entonces necesitará simplemente leer los datos de ese registro de desplazamiento después de que aumentó la interrupción y eso le dará la información sobre su fuente de interrupción real ... puede que no sea la forma más rápida, pero es fácil de expandir y no usará más de 5 pines, y si agrega un sistema de control de direcciones (MUX, LATCH,...), solo necesitará un pin para la notificación de interrupción y otros pines se pueden reutilizar en diferentes momentos para diferentes recursos;)
Anubis
PedroJ
SC con nombre en código
SC con nombre en código
usuario_1818839
kenny
olin lathrop
SC con nombre en código
Pranjal Saxena