This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

KEYPAD INTERFACING TO MSP430F2370

Other Parts Discussed in Thread: MSP430F2370

Hello All,

                   I am new to MSP430 microcontroller,& using CCS-v4 as a compiler.I am interfacing MSP430F2370 with keypad.

I tried out with following code in C,but i get garbage values while simulating it in Labcenter's Proteus VSM.Please

Please analyse what wrong with following code & if not Please anyone help me for interfacing keypad with MSP430F2370

 

#include<MSP430f2370.h>

unsigned char x;

void delay(int v)
    {
        while(v!=0)v--;
    }
 
unsigned char key(void)
  {
    unsigned char x;
    P1DIR|=0X0F;
    P1OUT=0XFE;              //make row 0 as 0
   
    switch(P1IN & 0xF0)                    //scan for column
   {
    case 0xE0:    x=0;                           //0xE0:make column 0 as 0
                            break;

    case 0xD0:     x=1;                         //0xD0:make column 1 as 0
                             break;

    case 0xB0:     x=2;                         //0xB0:make column 2 as 0

                            break;


    case 0x70:     x=3;                         //0x70:make column 3 as 0
               
                           break;


    default: P1OUT=0xFD;                   //make next row as 0
   
              switch(P1IN & 0xF0)
              {
              case 0xE0: x=4;
                                   break;


              case 0xD0: x=5;
                           
                                  break;
              case 0xB0: x=6;
                         
                                  break;
              case 0x70: x=7;
                       
                                   break;
              default: P1OUT=0xFB;
                      
                       switch(P1IN & 0xF0)
                       {
                         case 0xE0: x=8;
                                    
                                             break;
                         case 0xD0: x=9;
                                    
                                             break;
                         case 0xB0: x=10;
                                    
                                              break;
                         case 0x70: x=11;
                                    
                                             break;
                         default: P1OUT=0xF7;
                        
                                switch(P1IN & 0xF0)
                                {
                                 case 0xE0: x=12;
                                            
                                                      break;
                                 case 0xD0: x=13;
                                        
                                                     break;
                                 case 0xB0: x=14;
                                            
                                                     break;
                                 case 0x70: x=15;
                                            
                                                      break;
                                }
                       }
              }
   }

   return (x);
}
 
 
unsigned char keyj(void)
    {
      unsigned char x;
      P1DIR|=0X0F;
      P1OUT=0XF0;
      x=(P1IN & 0XF0);
      return(x); 
    } 

#pragma vector=PORT1_VECTOR
__interrupt void p1int(void)
        {
        if(keyj()!=0X00)
           {
           delay(200);  
               if(keyj()!=0X00)
                 {
                    P4OUT=key();
                  
                  }
            }
         P1OUT=0XF0;
         P1IFG=0X00;
        }

void main(void)
{
  WDTCTL = WDTPW + WDTHOLD;  /*   // Stop WDT */
 
 
   P4DIR=0XFF;
   P4OUT=0X00;
  
   P1DIR=0X0F;
   P1OUT=0XF0;
  
   P1IES|=0X0F;
   P1IE|=0XF0;
  
   _EINT();  /*/ Enable interrupts   */
 
  while(1)
  {
 
     LPM0;                  
    _NOP();  
  
  }
}

  • First, your delay isn't a delay. The compiler will see that the parameter v (which is completely local) is neither used inside the loop (so the compiler might just set it to the loop end condition) nor afterwards (so it can be discarded completely) and maybe the function itself is inlined because of its small content (read:nothing), so it may turn out faster than a single NOP.

    If you want a reliable delay, either use timers (that's what they are made for) or use the __delay_cycles() compiler intrinsic, which will generate code that takes exactly the given number of MCLK cycles.

    Then your code is overly complex.

    When the ISR is called, you know that there was a high-to-low transition. No need to check it. You can test the IFG flag(s) to heck which one it was.
    Anyway, it's better to start a timer in the port ISR and disable the port interrupt. So when the timer expires, you check for the current (debounced) state of the port pins and re-enable the port interrupt.

    Doing a busy-wainting delay inside an ISR is waste of processor power (you could do better things in the meantime) or energy (you could sleep in LPM instead).

    Your code to determine the pressed key is wasting space and time too. And it does not cope well if two buttons are pressed simultaneously (three pressed buttons will generate a fourth alias keypress, but two can be detected safely)

    What you can do next is to generate a 4*16 table which holds the key to report based on which output line is set low and what input value is read. Then do a for-loop to set the 4output bits and get the result form the table, or just a sequence of 4 P1OUT/P1IN lines. (the for loop is better because you can exit it if the result from the table is !=255 which means a pressed key has been found). It allows you to easily give one button preference over another, or generate a virtual button number for two simultaneously pressed buttons. Whatever you want.

    In any case, you should enable the pullup resistors for the input pins. Else you might get any input value for an input pin if no button is pressed in its row.

    Then there is superfluous code: You reconfigure P1DIR and P1OUT on several places with values they already have at this point.

    One last thing: the _NOP behind entering LPM doe snot server well for a breakpoint. The breakpoint will be hit before LPM is entered (the instruction is fetched in the same clock cycle as the LPM is activated).

    Besides all that, I don't see what's wrong with your current code. It might not be optimal, but it should work. But I don' t know the attached hardware, nor do I know the simulator.

**Attention** This is a public forum