Autor Tema: Interrupción RB en HiTech.  (Leído 2846 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado micro_pepe

  • Moderadores
  • DsPIC30
  • *****
  • Mensajes: 3206
Interrupción RB en HiTech.
« en: 02 de Abril de 2011, 16:54:24 »
Estoy a punto de tirar la toalla con HiTech, para una interrupción por cambio en el puerto B, se supone que se debe poner el bit RBIE a 1, y en la atención de la interrupción borrar el flag y leer el puerto B ¿No?

Bien, se trata de leer un teclado con esta interrupción, y compartir el puerto con el display. Poniendo el display en otro puerto funciona, aunque cada vez que pulso una tecla la interrupción se produce dos veces. Pero compartiendo el puerto salta continuamente sin pulsar ninguna tecla.

Pongo el codigo por si me podeis echar una mano:

Código: [Seleccionar]
//  Ejemplo de configuracion y utilizacion
#include <htc.h>
#include <stdlib.h>
#include "pic168xa.h"

__CONFIG(WDTDIS & HS & UNPROTECT);

#define _XTAL_FREQ 8000000 // Cristal 8MHz
#define LcdControlPort PORTB // Uso el puerto A para los bits de control
#define LcdRWBit 1 // El bit 0 del puerto A para RW
#define LcdRSBit 0 // El bit 0 del puerto A para RS
#define LcdENBit 2 // El bit 0 del puerto A para EN
#define LcdDataPort  PORTB // Uso el puerto B para los datos
#define LcdD4 4 // Solo utilizar para protocolo de 4 Bits

#include "SuperLcd.C" // Incluimos nuestra libreria

#define TRUE 1
#define FALSE 0
/**************************************************************************************/
/*                      VARIABLES                                                     */
unsigned char Tecla;
unsigned char PuertoB;
/**************************************************************************************/
char const CharactersCGRAM[64]={0,0,0,0,0,0,0,0x1F,
0,0,0,0,0,0,0x1F,0x1F,
0,0,0,0,0,0x1F,0x1F,0x1F,
0,0,0,0,0x1F,0x1F,0x1F,0x1F,
0,0,0,0x1F,0x1F,0x1F,0x1F,0x1F,
0,0,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,
0,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,
0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F};
/**************************************************************************************/
// Guarda en la CGRAM el caracter en el banco seleccionado.-
// <Caracter> es la dirección de la primer fila del caracter a enviar.-
void vLcdWriteCgram(unsigned char Bank,char Character){
unsigned char AddressBank,i;
 
AddressBank=0x40 + 0x08*Bank;
WriteByteLcd(AddressBank,0);
// Cargamos los 8 registros.-
for(i=0;i<8;i++){
WriteByteLcd(CharactersCGRAM[Character + i],1);
}
WriteByteLcd(0x80,0); // Se da por terminada la escritura.-
}
/**************************************************************************************/
// Incializa Memoria CGRAM.-
void vLcdInitCgram(void){
unsigned char j;

for(j=0;j<8;j++){
vLcdWriteCgram(j,j*8);   
}
}
/**************************************************************************************/
unsigned char LeerTeclado(void){

}
/**************************************************************************************/
void EnableInterrupcionesGlobal(unsigned char a){
//a = true-->habilitadas. a = false-->desabilitadas.

GIE = a;

}

/**************************************************************************************/
void interrupt intsrv(void){

if(RBIF && RBIE){

Tecla --;//LeerTeclado();
RBIF = 0;//Borramos el flag de interrupcion.
PuertoB = PORTB;
}

}
/**************************************************************************************/
void ConfiguracionINTCON(void){

GIE = 0;
PEIE = 0;
T0IE = 0;
INTE = 0;
RBIE = 1;
T0IF = 0;
INTF = 0;
RBIF = 0;

}
/**************************************************************************************/
void main(void)
{

  const char * pantalla = "Mundo";
  char texto[10];

  ConfiguracionINTCON();

  EnableInterrupcionesGlobal(FALSE);

  InitLcd();
  GotoxyLcd (1,1);
  WriteStrLcd ("Hola"); // escribe en la primer linea la palabra Hola
  GotoxyLcd (1,2);
  WriteStrLcd (pantalla); // escribe en la segunda linea la palabra apuntada por la variable pantalla

  vLcdInitCgram();

  GotoxyLcd (1,4);
  WriteCharLcd(0);
  WriteCharLcd(1);
  WriteCharLcd(2);
  WriteCharLcd(3);
  WriteCharLcd(4);
  WriteCharLcd(5);
  WriteCharLcd(6);
  WriteCharLcd(7);
 
 
do{
EnableInterrupcionesGlobal(FALSE);
TRISB = 0;
GotoxyLcd (1,3);
itoa(texto,Tecla,10);
WriteStrLcd(texto);
TRISB = 0b11111000;
PORTB = 0b11111000;
PuertoB = PORTB;
EnableInterrupcionesGlobal(TRUE);
__delay_ms(333);


}while(TRUE);
}
Se obtiene más en dos meses interesandose por los demás, que en dos años tratando de que los demás se interesen por ti.

新年快乐     的好奇心的猫死亡

Desconectado AngelGris

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 2480
Re: Interrupción RB en HiTech.
« Respuesta #1 en: 02 de Abril de 2011, 17:41:43 »
  Tranquilo micro_pepe no tires la toalla que Hitech es un lindo compilador  :)
 
  Dejame que busque algún ejemplo, o que lo vuelva a hacer, porque estoy seguro que lo he simulado y funcionaba bien.
 
De vez en cuando la vida
nos besa en la boca
y a colores se despliega
como un atlas

Desconectado Suky

  • Moderador Local
  • DsPIC33
  • *****
  • Mensajes: 6758
Re: Interrupción RB en HiTech.
« Respuesta #2 en: 02 de Abril de 2011, 17:58:06 »
Hola!

1º Es normal que la interrupción ocurra 2 veces, pues pulsas y sueltas, o sea 2 cambios de estado en RB4-RB7  ;-)
2º Si no afecta al funcionamiento puede que sea adecuado agregar una demora de 20ms para el anti-rebote y recién testear si es una pulsación valida.
3º Un esquema de como lo estas conectando puede ser de ayuda para entender lo que pasa.


Saludos!
No contesto mensajes privados, las consultas en el foro

Desconectado AngelGris

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 2480
Re: Interrupción RB en HiTech.
« Respuesta #3 en: 02 de Abril de 2011, 23:40:38 »
  Acabo de simular este programa para un PIC16F876A y funciona bien

Código: C
  1. #include <htc.h>
  2.  
  3.   __CONFIG (WDTDIS & LVPDIS & HS);
  4.  
  5. #define PIC_CLK     10000000
  6. #define _XTAL_FREQ  10000000
  7.  
  8. #define LcdDataPort    PORTB
  9. #define LcdControlPort PORTB
  10. #define LcdENBit       0
  11. #define LcdRSBit       1
  12. #define LcdRWBit       2
  13. #define LcdD4          4
  14. #include "SuperLcd.c"
  15.  
  16. #define KeyInPort  PORTB
  17. #define KeyOutPort PORTB
  18. #define PHONE
  19. #define OutD0      1
  20. #define InD0       4
  21. #define PULLUP
  22. #include "Teclados.c"
  23.  
  24. bit pulsaron;
  25.  
  26. void interrupt isr(void)
  27. {
  28.   if (RBIF == 1)
  29.   {
  30.     pulsaron = 1;
  31.     PORTB = PORTB;
  32.     RBIF = 0;
  33.   }
  34. }
  35.  
  36. void main(void)
  37. {
  38.   char TeclaPulsada;
  39.  
  40.   TRISB = 0b11110000;
  41.   PORTB = 0;
  42.   TRISA = 0;
  43.   CMCON = 7;      // deshabilito los comparadores
  44.   ADON = 0;       // apago el ADC
  45.   ADCON1 = 0x87;  // entradas como digitales
  46.   InitLcd();
  47.   WriteStrLcd("   Bienvenido   ");
  48.   RBIF = 0;       // borro el flag de interrupcion por cambio de estado
  49.   RBIE = 1;       // habilito interrupcion por cambio de estado
  50.   GIE = 1;        // habilito interrupciones globales
  51.   while (1)
  52.   {
  53.     if (pulsaron == 1)            // si hubo interrupcion por cambio de estado
  54.     {
  55.       __delay_ms (15);            // antirebote
  56.       if ((PORTB & 0xF0) != 0xF0) // si sigue habiendo tecla presionada...
  57.       {
  58.         RBIE = 0;                 // deshabilito interrupcion por cambio de estado
  59.         TeclaPulsada = GetKey();  // leo la tecla presionada
  60.         while ((PORTB & 0xF0) != 0xF0); // espero hasta soltar la tecla
  61.         GotoxyLcd (1,2);
  62.         if (TeclaPulsada != 0) WriteCharLcd (TeclaPulsada); // muestro la tecla en el LCD
  63.         PORTB = PORTB;            // leo el puerto para eliminar la desigualdad
  64.         RBIF = 0;                 // borro el flag
  65.         RBIE = 1;                 // habilito la interrupcion por cambio de estado
  66.       }
  67.       pulsaron = 0;              // borro mi flag de cambio de estado
  68.     }
  69.   }
  70. }

  Verás que hay un while después de leer la tecla pulsada y eso está así para asegurarme que no siga el programa mientras haya alguna tecla presionada. Es para evitar que se pueda producir algún cortocircuito al querer enviar datos al LCD.
  De todas maneras el riesgo sigue estando ya que si al comienzo (en el momento de escribir "Bienvenido") se presiona alguna tecla se puede producir un corto. Habría que buscar una forma de protección sobre el teclado para que no pueda provocar dicho conflicto.

  Te adjunto una imagen del conexionado que utilicé.

EDITO: acabo de sacar el while mencionado anteriormente y modificado el circuito agregando 3 resistencias de 1K al teclado para evitar los cortos y simulándolo en Proteus funcionó bien. Adjunto el nuevo circuito
« Última modificación: 03 de Abril de 2011, 09:29:12 por AngelGris »
De vez en cuando la vida
nos besa en la boca
y a colores se despliega
como un atlas

Desconectado micro_pepe

  • Moderadores
  • DsPIC30
  • *****
  • Mensajes: 3206
Re: Interrupción RB en HiTech.
« Respuesta #4 en: 03 de Abril de 2011, 14:12:03 »
OK, muchas gracias, ya está funcionando. El esquema que estaba usando es muy similar al segundo que puso AngelGris, solo que compartia el pin del enable del display con un pin del teclado, y de esa manera no funciona.

Saludos.
Se obtiene más en dos meses interesandose por los demás, que en dos años tratando de que los demás se interesen por ti.

新年快乐     的好奇心的猫死亡

Desconectado AngelGris

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 2480
Re: Interrupción RB en HiTech.
« Respuesta #5 en: 03 de Abril de 2011, 14:59:10 »
  Justamente yo no comparto dicho pin, para evitar que se habilite el display erróneamente.
De vez en cuando la vida
nos besa en la boca
y a colores se despliega
como un atlas

Desconectado Palomino86

  • PIC16
  • ***
  • Mensajes: 180
Re: Interrupción RB en HiTech.
« Respuesta #6 en: 03 de Abril de 2011, 22:00:01 »
Les dejo un link que les ayudara a comprender la interrupción por cambio de estado.

Espero y les sea de gran ayuda.

Saludos


http://www.cursomicros.com/mod2/c05_07_interrupcion_cambio_portb.html
Lo que no me destruye, me fortalece

Desconectado Suky

  • Moderador Local
  • DsPIC33
  • *****
  • Mensajes: 6758
Re: Interrupción RB en HiTech.
« Respuesta #7 en: 03 de Abril de 2011, 23:32:01 »
  Justamente yo no comparto dicho pin, para evitar que se habilite el display erróneamente.

Es que es lo único que habilita al LCD para recibir o enviar datos, y si lo colocas con un pulsador  :z) jejeje!
No contesto mensajes privados, las consultas en el foro