INTERRUPCIÓN EXTERNA AVR PCINTO, PCINT1, ..., PCINT23
En los pines del microcontrolador AVR nombrados como PCINT0, PCINT1, hasta PCINT23 se pueden producir interrupciones por cambio de estado en estos pines, esto es si pasan de un alto a un bajo o si pasan de un bajo a un alto, no se tienen otras opciones como en el caso visto para la interrupción externa AVR INT0 e INT1 en donde se tiene hasta 4 opciones que se pueden elegir por programa.
Los pines PCINT0, PCINT1, hasta PCINT23 se encuentran formando grupos correspondientes a los puertos en los que se encuentran, en el atmega88 del PCINT0 a PCINT7 forman un grupo en el puerto B, del PCINT8 a PCINT14 forman otro grupo en el puerto C y del PCINT16 a PCINT23 forman un grupo en el puerto D, no cuenta con el PCINT15 ya que el puerto C solo tiene 8 pines.
La habilitación de la interrupción externa avr en este caso es mediante un solo bit común a un grupo de pines, si alguno de los pines de algún grupo provoca una interrupción, este pondrá a 1 un bit común al grupo, que es usado para detectar que se ha producido una interrupción externa AVR por alguno de los pines de ese grupo.Para habilitar la interrupción externa AVR para los grupos de pines, se utiliza el registro de control de interrupción por cambio de estado PCICR; además deben estar habilitadas las interrupciones globales, lo cual en el XC8 se hará con la instrucción sei(), como se comentó aquí.
Los bits 7 a 3 no se utilizan por lo que se les suele poner a 0, al poner a 1 el bit 2 se habilita la interrupción externa AVR por cambio de estado para el grupo de pines del PCINT16 al PCINT23, al poner a 1 el bit 1 se habilita la interrupción externa AVR por cambio de estado para el grupo de pines del PCINT8 al PCINT14, al poner a 1 el bit 0 se habilita la interrupción externa AVR por cambio de estado para el grupo de pines del PCINT0 a PCINT7.
Para detectar en que grupo de pines está el pin por el que se provocó la interrupción por cambio de estado se tiene el registro PCIFR.
Para detectar la interrupción externa AVR provocada por alguno de los pines del PCINT16 al PCINT23 el bit2 se pone a cero, si por alguno de estos pines ocurre una interrupción por cambio de estado, el bit2 se pondrá automáticamente a 1, para volver a detectar una interrupción por alguno de estos pines, dentro de la rutina de interrupciones se tendrá que poner nuevamente el bit2 a 0, cuando se utiliza la rutina de interrupciones con el AVR, este bit se pone a 0 automáticamente.
Para detectar la interrupción externa avr provocada por alguno de los pines del PCINT8 al PCINT14 el bit1 se pone a cero, si por alguno de estos pines ocurre una interrupción por cambio de estado, el bit1 se pondrá automáticamente a 1, para volver a detectar una interrupción por alguno de estos pines, dentro de la rutina de interrupciones se tendrá que poner nuevamente el bit1 a 0, cuando se utiliza la rutina de interrupciones con el AVR, este bit se pone a 0 automáticamente.
Para detectar la interrupción externa AVR provocada por alguno de los pines del PCINT0 al PCINT7 el bit0 se pone a cero, si por alguno de estos pines ocurre una interrupción por cambio de estado, el bit0 se pondrá automáticamente a 1, para volver a detectar una interrupción por alguno de estos pines, dentro de la rutina de interrupciones se tendrá que poner nuevamente el bit0 a 0, cuando se utiliza la rutina de interrupciones con el AVR, este bit se pone a 0 automáticamente.
Para elegir que pines de los grupos de pines serán utilizados para provocar una interrupción externa AVR se cuentan con 3 registros:
El registro PCMSK2, es usado para elegir que pines del grupo PCINT16 al PCINT23 serán utilizados para provocar una interrupción externa avr por cambio de estado, si el bit2 del registro PCICR se a puesto a 1 y están habilitadas las interrupciones globales, entonces al poner a 1 el bit correspondiente al pin que se quiera utilizar, se habilitará el uso de ese pin para provocar una interrupción externa AVR, si el bit se deja a 0 entonces el pin no será utilizado para provocar interrupciones.
El registro PCMSK1, es usado para elegir que pines del grupo PCINT8 al PCINT14 serán utilizados para provocar una interrupción externa avr por cambio de estado, si el bit1 del registro PCICR se a puesto a 1 y están habilitadas las interrupciones globales, entonces al poner a 1 el bit correspondiente al pin que se quiera utilizar, se habilitará el uso de ese pin para provocar una interrupción externa AVR, si el bit se deja a 0 entonces el pin no será utilizado para provocar interrupciones.
El registro PCMSK0, es usado para elegir que pines del grupo PCINT0 al PCINT7 serán utilizados para provocar una interrupción externa avr por cambio de estado, si el bit0 del registro PCICR se a puesto a 1 y están habilitadas las interrupciones globales, entonces al poner a 1 el bit correspondiente al pin que se quiera utilizar, se habilitará el uso de ese pin para provocar una interrupción externa AVR, si el bit se deja a 0 entonces el pin no será utilizado para provocar interrupciones.
Rutinas de interrupción externa avr PCINT0 a PCINT23 en C/C++ en el XC8
Si se utiliza la interrupción externa AVR PCINT0 a PCINT7, la rutina de interrupción se realizará dentro de la siguiente función:
ISR(PCINT0_vect){
//tareas a realizar dentro de la rutina de interrupción de PCINT0 a PCINT7
}
Si se utiliza la interrupción externa AVR PCINT8 a PCINT14, la rutina de interrupción se realizará dentro de la siguiente función:
ISR(PCINT1_vect){
//tareas a realizar dentro de la rutina de interrupción de PCINT8 a PCINT14
}
Si se utiliza la interrupción externa AVR PCINT16 a PCINT23, la rutina de interrupción se realizará dentro de la siguiente función:
ISR(PCINT2_vect){
//tareas a realizar dentro de la rutina de interrupción de PCINT16 a PCINT23
}
Interrupción externa AVR PCINT0 a PCINT23
Se hará un ejemplo para la interrupción externa AVR por el pin PCINT23, se le hará llegar una señal que cambiará su estado entre altos y bajos con la ayuda de un fotorresistor, cuando se ilumine el fotorresistor su resistencia disminuirá y al pin PCINT23 le llegará un alto, cuando el fotorresistor no se ilumine su resistencia será alta y al pin PCINT23 le llegará un bajo. Se programará para que al ocurrir la interrupción externa AVR por cambio de estado en este pin, cada vez que se produzca la interrupción se cambiará el estado del pin PB0 lo que será visible mediante un led. El circuito utilizado es el que se muestra en la imagen.
El programa realizado en el XC8 para el uso de la interrupción externa AVR PCINTx, siguiendo el procedimiento comentado aquí es el siguiente:
#define F_CPU 20000000UL
#include <avr/io.h>
#include <avr/interrupt.h> //libreria necesaria para utilizar las interrupciones
int main(void) {
DDRB|=(1<<0);//pin PB0 como salida para el led que cambia de estado
PORTB&=~(1<<0);//el led se incia apagado
cli();//deshabilita todas las interrupciones, esto se hace por si acaso
PCMSK2|=(1<<7);//se elige que se utilizará el pin PCINT23 para detectar
//interrupciones por cambio de estado
PCICR|=(1<<2);//habilita la interrupcion externa por cambio de estado en el grupo
//en el que está el pin PCINT23
PCIFR=0b00000000;//su bit 2 a 0 para detectar las interrupciones en PCINT23
//al producirse la interrupción por cambio de estadp este bit se pondrá a 1
//en la rutina ISR se pondrá nuevamente a 0 automaticamente
//este paso no es necesario ya que siempre se incia a 0, pero se hace
//por si acaso
sei();//habilita las interrupciones globales
while (1) {
//en este ejemplo no se hará nada aquí, todo se hará por interrupción INT0
}
}
ISR(PCINT2_vect){//rutina cuando se produzca una interrupción externa PCINT23
PORTB^=(1<<0);//cada vez que ocurre la interrupción el pin PB0 cambia de estado
//visible por medio del led
}
Esperamos de todo corazón ser de vuestra ayuda, no olviden suscribirse al canal de mrelberni, darle me gusta a los vídeos, compartirlos, que de esa manera nos ayudan a continuar, desde ya muchas gracias.
Publicar un comentario