4x4 Keypad & asm("nop")

Status
Not open for further replies.

Urahara

Member
Hi

Am trying to understand a C pgm (believe it is Hi-Tech's C) written for 16F877A to work with a 4x4 keypad. Within the scan subroutine, there is a statement that says asm("nop") with a comment saying it is for delay purpose. Is there a reason for using this statement instead of a "for" loop? Also, is this an interrupt-based scanning? This is supposedly the complete demo pgm I've gotten.

Code:
#include<pic.h>              //include MCU head file
 __CONFIG(0x1832);        
//THE configure of MCU,watchdog OFF,electrify delay OPEN,power down check OFF,
//LOW power programme OFF,encrypt,4M crystal HS surge.

 int  result;
 void  delay();              //delay function declare
 void  init();               //I/O PORT initialize function declare
 void  scan();               //key scan function declare
 void  display(int x);       //display function declare
//---------------------------------------------------
                             //main program  
void main()
{
  while(1)                   //circle work                        
    {                                                             
      init();                //call initialize subprogram         
      scan();                //call key scan subprogram           
      display(result);       //call result display subprogram     
    }
 }
 
//---------------------------------------------------
//initialize function
void init() 
 {
  ADCON1=0X07;                // set A PORT general I/O PORT                  
  TRISA=0X0f;                 //A PORT low 4 bits INPUT,high 4 bits OUTPUT    
  TRISC=0XF0;                 //C PORT high 4 bits INPUT,low 4 bits OUTPUT    
  TRISD=0X00;                 //set D PORT OUTPUT                             
  PORTA=0XFF;                                                                 
  PORTD=0XFF;                 //clear all display                             
 }

//---------------------------------------------------
//key scan program
void scan()
{
 PORTC=0XF7;                 //C3 OUTPUT low,the other 3 bits OUTPUT high                      
 asm("nop");                 //delay                                                           
 result=PORTC;               //read C PORT                                                     
 result=result&0xf0;         //clear low 4 bits                                                
 if(result!=0xf0)            //judge if high 4 bits all 1(all 1 is no key press)               
   {                                                                                           
     result=result|0x07;     //no,add low 4 bits 0x07 as key scan result                       
   }                                                                                           
 else                        //yes,change low 4 bits OUTPUT, judge if a key press again        
   {                                                                                           
   PORTC=0XFb;               //C2 OUTPUT low,the other 3 bits OUTPUT high                      
   asm("nop");               //delay                                                           
   result=PORTC;             //read C PORT                                                     
   result=result&0xf0;       //clear low 4 bits                                                
   if(result!=0xf0)          //judge if high 4 bits all 1(all 1 is no key press)               
     {                                                                                         
     result=result|0x0b;     //no,add low 4 bits 0x0b as key scan result                       
     }                                                                                         
   else                      //yes,change low 4 bits OUTPUT, judge if a key press again        
       {                                                                                       
       PORTC=0XFd;           //C1 OUTPUT low,the other 3 bits OUTPUT high                      
       asm("nop");           //delay                                                           
       result=PORTC;         //read C PORT                                                     
       result=result&0xf0;   //clear low 4 bits                                                
       if(result!=0xf0)      //judge if high 4 bits all 1(all 1 is no key press)               
        {                                                                                      
        result=result|0x0d;  //no,add low 4 bits 0x0d as key scan result                       
        }                                                                                      
       else                  //yes,change low 4 bits OUTPUT, judge if a key press again        
          {                                                                                    
          PORTC=0XFe;        //C0 OUTPUT low,the other 3 bits OUTPUT high                      
          asm("nop");        //delay                                                           
          result=PORTC;      //read C PORT                                                     
          result=result&0xf0;//clear low 4 bits                                                
          if(result!=0xf0)   //judge if high 4 bits all 1(all 1 is no key press)               
            {                                                                                  
             result=result|0x0e;//no,add low 4 bits 0x0e as key scan result                    
            }                                                                                  
          else               //yes,all key scan end,no key press,set no key press flag         
            {                                                                                  
             result=0xff;    //key scan result 0xff as no key press flag                       
            }   
          }      
      }
   }
 }

//----------------------------------------------------------
//display program
void   display(int x)
  {
   switch(result)                 
      {
       case 0xe7:
                 PORTD=0xf9;PORTA=0X2F;delay();PORTD=0xc0;PORTA=0X1F;delay();break;   //K10
       case 0xeb:
                 PORTD=0xf9;PORTA=0X2F;delay();PORTD=0xf9;PORTA=0X1F;delay();break;   //K11
       case 0xed:
                 PORTD=0xf9;PORTA=0X2F;delay();PORTD=0xa4;PORTA=0X1F;delay();break;   //K12
       case 0xee:
                 PORTD=0xf9;PORTA=0X2F;delay();PORTD=0xb0;PORTA=0X1F;delay();break;   //K13
       case 0xd7:
                 PORTD=0xf9;PORTA=0X2F;delay();PORTD=0x99;PORTA=0X1F;delay();break;   //K14
       case 0xdb:
                 PORTD=0xf9;PORTA=0X2F;delay();PORTD=0x92;PORTA=0X1F;delay();break;   //K15
       case 0xdd:
                 PORTD=0xf9;PORTA=0X2F;delay();PORTD=0X82;PORTA=0X1F;delay();break;   //K16
       case 0xde:
                 PORTD=0xf9;PORTA=0X2F;delay();PORTD=0XF8;PORTA=0X1F;delay();break;   //K17
       case 0xb7:
                 PORTD=0xf9;PORTA=0X2F;delay();PORTD=0X80;PORTA=0X1F;delay();break;   //K18
       case 0xbb:
                 PORTD=0xf9;PORTA=0X2F;delay();PORTD=0X90;PORTA=0X1F;delay();break;   //K19
       case 0xbd:
                 PORTD=0xa4;PORTA=0X2F;delay();PORTD=0xc0;PORTA=0X1F;delay();break;   //K20
       case 0xbe:
                 PORTD=0xa4;PORTA=0X2F;delay();PORTD=0xf9;PORTA=0X1F;delay();break;   //K21
       case 0x77:
                 PORTD=0xa4;PORTA=0X2F;delay();PORTD=0xa4;PORTA=0X1F;delay();break;   //K22
       case 0x7b:
                 PORTD=0xa4;PORTA=0X2F;delay();PORTD=0xb0;PORTA=0X1F;delay();break;   //K23
       case 0x7d:
                 PORTD=0xa4;PORTA=0X2F;delay();PORTD=0x99;PORTA=0X1F;delay();break;   //K24
       case 0x7e:
                 PORTD=0xa4;PORTA=0X2F;delay();PORTD=0x92;PORTA=0X1F;delay();break;   //K25
       case 0xff:
                 PORTD=0x8e;PORTA=0X2F;delay(); PORTD=0x8e; PORTA=0X1F; delay();      //no key press
      }
   }

//------------------------------------------------------------------
//delay program
void  delay()              //delay program 
    {
     int i;                 //define integer variable
     for(i=0x100;i--;);     //delay
    }

Finally, does anyone has a C18 code for a 4x4 keypad scanning? Hv searched but seems to be getting only assembly-based examples. I am trying to do one for a 18F4550.

Thks!
 
Within the scan subroutine, there is a statement that says asm("nop") with a comment saying it is for delay purpose.

It sits between a write and a read of the I/O port so it's most likely there to ensure that the levels on the port have settled before it reads the port.

Sort of variation on the known 'read-modify-write' issue with 12F/16F series PICs

It doesn't need anything more than a 'nop' instruction to space the write from the read. A 'for' loop would be overkill.
 
Last edited:
Status
Not open for further replies.
Cookies are required to use this site. You must accept them to continue using the site. Learn more…