Uso de múltiples interrupciones externas en PIC

9

He usado PIC16F877( hoja de datos ) para varios proyectos. Para una interrupción de cambio de pin externo, puede usar PORTB0interrupción. 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 INTCONregistro.

ingrese la descripción de la imagen aquí

¿Puedo tener 4 interruptores independientes usando bit 0, 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 recibo respuestas positivas a las anteriores, ¿necesito 8 interrupciones? Por supuesto que todavía puedo usar INTE, para el PORTB0cambio. Entonces 4 + 1 = 5, pero ¿qué pasa con los otros 3? (Sin embargo 4 + 1 + 3 = 8, dado que los 8 eventos de interrupción son del mismo tipo, la cosa parece fea, ¿no?)

No se esperan otras tareas pesadas del microcontrolador que no sean monitorear 8 pines. (Hablando de las otras tareas, tendrá que mantener un conjunto de variables de contador separadas y con frecuencia transmitir aproximadamente 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 uh ... no me digas que me aleje de PICs).

Codificado SC
fuente
2
Sin usar interrupciones, puede supervisar los pines en el programa principal. Pero eso no es perfecto. Como alternativa, puedes optar por Arduino. Aunque no es PIC, es bastante simple, lo comprenderá fácilmente ya que ya está familiarizado con los PIC.
Anubis
1
Si usa la interrupción RBIE, puede almacenar el valor anterior cada vez y un XOR para encontrar lo que ha cambiado. Debería ser bastante rápido de ejecutar.
PeterJ
@ PeterJ no entendí bien eso. ¿Qué valor de búfer?
Codenamed SC
@PeterJ genial! esperando ...
Codenamed SC
1
Una forma es usar una compuerta externa de 8 entradas (como la 74LS30 en los viejos tiempos) para combinar las señales externas en un pin de interrupción. Como el 74 (HC) 30 es una puerta NAND, necesitaría todas las entradas altas en el estado de reposo; también necesitarían estar conectadas a los pines del puerto para que pueda identificar qué interrupciones estaban activas al leer el puerto.
Brian Drummond el

Respuestas:

3

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 la única interrupción de 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();
}
PeterJ
fuente
Lo entiendo, gracias! pero esa no es la respuesta exacta que estoy buscando. De esa manera, puede monitorear RB7:RB4solo 4 pines. Pero estoy pidiendo una forma de monitorear 8 pines. ¿cualquier sugerencia?
Codenamed SC
Supongo que hay una razón por la que no puedes usar RB0 - RB7. ¿Lo anterior debería funcionar? De lo contrario, realmente no puedo pensar en una manera, si la activación del código rápidamente no es vital, podría usar el estilo de código anterior en una interrupción del temporizador (o solo el bucle principal).
PeterJ
Para ese PIC, si necesita usar interrupciones para hacer esto, el truco XOR en RB4: RB7, y cuatro interrupciones para el RB0: RB3 es el camino a seguir. Si no necesita la interrupción, solo sondee todo el puerto en su código, o use una interrupción de temporizador para manejar la encuesta si necesita una frecuencia de muestreo difícil
Scott Seidman
and four interrupts for the RB0:RB3? PIC16F877 no admite interrupciones para RB1:RB3, ¿eh?
Codenamed SC
Había extrañado eso en la hoja de datos, suponía que cubría todo el puerto. Pero vi su otro comentario una vez por segundo, así que creo que sería mejor ejecutar esto en su bucle principal. Con las interrupciones, tendrá que ocuparse de la actualización de las variables en cualquier momento durante la ejecución y cómo manejar los cambios de pin mientras se ejecuta la interrupción. Realmente parece que lo complicará sin ganancia real. La única excepción en la que podría pensar es si quisieras usar Wake from Sleep en la interrupción, en cuyo caso necesitarías hardware MUX.
PeterJ
1

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, luego interrumpir el desajuste. Eso se vuelve complicado 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 qué tiempo mínimo persistirá un cambio de pin para que sea válido. Dependiendo de las respuestas, puede realizar una encuesta en función de una interrupción regular en el firmware. El 16F877 puede ejecutarse a una velocidad de instrucción de 5 MHz, y buscar 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 velocidad de interrupción sería de 100 kHz y el período de 10 µs. Por supuesto, el código de primer plano todavía 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,

Olin Lathrop
fuente
Perdón por los detalles que faltan. Como la tasa de respuesta esperada once per secondserá 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 se eleva por encima de un cierto valor, se deben transmitir cuatro bytes USARTa la PC. Luego restablezca el valor del contador relevante a cero. Simple como eso. Supongo que la opción de votación irá bien, ¿verdad?
Codificado SC
2
Una vez por segundo ! Entonces, ¿para qué son las agonizantes interrupciones? Esto se hace fácilmente con encuestas periódicamente. ¿Cuál es el problema entonces?
Olin Lathrop
um ... pensé que sería mejor ya que hay 8 de ellos y además, la respuesta no se puede predecir (pero se puede suponer que ese valor es el mínimo). ¡Oye! la gente puede cometer errores, cierto ... :(
Codenamed SC
1

Puede usar la compuerta NAND de 8 entradas como lo menciona @Brian Drummond para aumentar una interrupción sobre el pin INT y también conectar sus fuentes de interrupción al registro de desplazamiento de entrada paralela / salida de 8 bits como "74HC165N", por lo que necesitará simplemente leer los datos de ese Registro de turnos después de que se disparó 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 usará no más de 5 pines, y si agrega un sistema de control de dirección (MUX, LATCH, ...), solo necesitará un pino para la notificación de interrupción y otros pines pueden reutilizarse en diferentes momentos para diferentes recursos;)

Eli Oulman
fuente