La segunda interrupción no funciona en MSP430

0

EnesteproyectoquierocontrolarelmotordeCCconeltecladonumérico.cuandopresionounbotónporprimeravez,funcionacorrectamente,perocuandopresionounbotónsegundaoterceravez,noreaccionaypermaneceelbotónquepresionéprimero.

Aquíestáelcódigo:

#include"io430.h"
#include "in430.h"

#define ileri BIT0
#define geri BIT1

void main(void)
{
  WDTCTL = WDTPW + WDTHOLD;

  DCOCTL=CALDCO_1MHZ;
  BCSCTL1=CALBC1_1MHZ;

  P1OUT = 0x00;
  P1DIR = 0x0F;
  P2OUT  = 0x00;
  P2DIR &= ~BIT0;
  P2IE   = BIT0;
  P2IFG  = 0x00;

  _BIS_SR(GIE);

  for(;;);
}

#pragma vector=PORT2_VECTOR
__interrupt void P2_ISR(void)
{


 if((P1IN && 0xF0) == BIT5+BIT6+BIT7) 
 {P1OUT =BIT0;P2IFG  = 0x00;}

 if(((P1IN && 0xF0)== BIT6+BIT7) && (P1IN && BIT5) == 0)
 {P1OUT =ileri+BIT2;}


P2IFG  = 0x00;

} cuando presiono un botón aleatorio e interrumpo la habilitación por ej. if(P1IN == BIT5+BIT6+BIT7) =1 y así P1OUT =0X01; . Está bien, no hay problema, pero si presiono otro botón, la segunda interrupción no funciona. Aunque if((P1IN == BIT6+BIT7) && P1IN!= BIT5) =1 , no puedo hacer P1OUT= ileri+BIT2 .

¿Podrías ayudarme por favor?

    
pregunta Ali AKÇAKMAK

1 respuesta

2

P1IN lee el estado de todo P1, no solo los pines configurados para la entrada. Una vez que cualquiera de p1.0-3 se establece en la lógica 1, P1IN también incluirá esos bits. Ejemplo:

If P1.5-P1.7 are high, P1IN = 0b11100000
And you set P1.0 high, P1OUT = 0b00000001
Then read P1IN again, P1IN = 0b11100001

Básicamente, necesitas enmascarar P1IN cuando lo pruebas en tus sentencias if.

if ( (P1IN & 0xF0) == BIT5+BIT6+BIT7) {P1OUT =BIT0;}

Por ejemplo:

P1.1, P1.5, and P1.6 are high, P1IN = 0b01100001
Bitwise And P1IN and 0xF0 aka 0b11110000 to mask the bits you don't want 
you get 0b01100001 & 0b11110000 = 0b01100000 aka 0x60
BIT5 = 0b00100000, BIT6 = 0b01000000, BIT7 = 0b10000000
Added together, that's 0b11100000 aka 0xE0
So you are testing if 0x60 equals 0xE0, which it does not.

Por eso, tu segunda sentencia if también falla. Si P1IN! = BIT5, será verdadero a menos que P1IN solo sea igual a 0b00100000.

Dado que el mm74c922 es un codificador simple, que genera 16 estados conocidos en binario, en 4 pines, nunca necesita meterse con ese tipo de prueba no igual o doble prueba.

Puedes probar BIT5 + BIT6 + BIT7 o BIT6 + BIT7, y ambos nunca serán verdaderos al mismo tiempo, ya que estas son pruebas absolutas.

Una forma más sencilla es simplemente usar el operador de desplazamiento a la derecha a nivel de bits >> para la prueba, y luego comparar con la salida real del mm74c922. El >> toma un valor y lo mueve a la derecha x número de bits. Todos los bits que se desplazan se pierden, en este caso se ocultan. En este caso, si cambia a la derecha en 4 significa que pierde el mordisco inferior y el mordisco superior se convierte en el mordisco inferior.

Remember how BIT5+BIT6+BIT7 =  0b11100000 = 0xE0?
Shifted right by 4, it becomes 0b00001110 aka 0x0E aka 14!
BIT6+BIT7 = 0b11000000 shifted by 4 is 0b1100 aka 0xC aka 12!

if ( (P1IN >> 4) == 14) {P1OUT = BIT0;}
if ( (P1IN >> 4) == 12) {P1OUT = ileri+BIT2;}

Finalmente, dado que hay 16 (solo 12 utilizados) estados conocidos, una instrucción de cambio es mejor que un grupo de declaraciones if.

switch (P1IN >> 4) {
     case 1:
      //do something when var equals 1
      break;
    case 2:
      //do something when var equals 2
      break;
    default: 
      // if nothing else matches, do the default
      // default is optional
}

Aquí hay un buen tutorial sobre operadores bitwise enlace

    
respondido por el Passerby

Lea otras preguntas en las etiquetas