Usando múltiples interrupciones externas en PIC

9

He usado PIC16F877 ( hoja de datos ) para varios proyectos. Para una sola interrupción de cambio de pin externo, puede usar PORTB0 interrupt. Pero ahora necesito soportar 8 interrupciones de cambio de pin externo independientes, en un solo circuito.

En la hoja de datos dice que hay 15 interrupciones en PIC16F877 , pero supongo que se cuentan, incluidas las interrupciones por desbordamiento del temporizador, etc. que son inútiles en este caso.

Esto es lo que dice la hoja de datos sobre INTCON register.

¿Puedo tener 4 interrupciones independientes usando bit0, RBIF ? Representa cambio en PB7:PB4 . ¿Cómo puedo identificar qué pin ha cambiado, es leyendo el valor del puerto en la rutina de interrupción?

¿Incluso tengo respuestas positivas a las anteriores, necesito 8 interrupciones? por supuesto, todavía puedo usar INTE , para PORTB0 cambio. Entonces 4 + 1 = 5 , pero ¿qué pasa con otros 3? (Sin embargo, como todos los 8 eventos de interrupción son del mismo tipo, la cosa 4 + 1 + 3 = 8 parece fea, ¿no?)

No se esperan otras tareas pesadas del microcontrolador que monitorean 8 pines. (Hablando de las otras tareas, tendrá que mantener un conjunto de variables de contador separadas y, con frecuencia, transmitir unos 4 bytes a la PC en serie)

Cualquier sugerencia es bienvenida. Incluso si se trata de cambiar el microcontrolador por uno más adecuado (pero eh ... no me digas que se vaya de PIC s).

    
pregunta Codenamed SC

3 respuestas

3

Este es un pseudocódigo para explicar una idea. Utiliza un O exclusivo para determinar qué pines han cambiado y llamará a sus diferentes manejadores dentro de la única interrupción RBIE. Dependiendo de la importancia de la aplicación, es posible que desee comprobar cómo maneja el PIC situaciones como el 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();
}
    
respondido por el PeterJ
1

Esa parte solo tiene 4 interrupciones de cambio de pin y algunas otras que puedes configurar en los bordes seleccionados. Una estrategia sería detectar un cambio en el valor de 8 bits externamente, y luego interrumpir el desajuste. Eso se complica con el hardware, pero es exactamente lo que usted desea.

Los parámetros importantes que no ha indicado son la rapidez con la que necesita responder a un cambio de pin y el tiempo mínimo que un cambio de pin persistirá para que sea válido. Dependiendo de las respuestas, puede realizar una encuesta basada en una interrupción regular del firmware. El 16F877 puede ejecutarse a una velocidad de instrucción de 5 MHz, y la verificación de un cambio solo tomaría unas pocas instrucciones. Digamos que configuras 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, puede ejecutar la interrupción mucho más lentamente.

    
respondido por el Olin Lathrop
1

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 cambios de entrada / salida en paralelo de 8 bits como "74HC165N", entonces solo tendrá que leer los datos de ese Shift Register después de que haya aumentado 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 fácil de expandir y que utilizará no más de 5 pines, y si agrega un sistema de control de direcciones (MUX, LATCH, ...), solo necesitará un pino para la notificación de interrupción y otros pines se pueden reutilizar en diferentes momentos para diferentes recursos;)

    
respondido por el Eli Oulman

Lea otras preguntas en las etiquetas