Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

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.

Latest threads

Back
Top