AVR microcontroller scans 4X4 matrix keyboard and digital tube display program

Publisher:MeshulunLatest update time:2015-05-12 Source: 51hei Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere
/*

          program name : keyboard ;
     Function description: Scan 16 keys (4X4) and display the key values ​​on the digital tube (two digits);
 
     Key points: When scanning the keys, a relatively complex two for() loop nested
     scanning scheme is used, which greatly reduces the amount of program. The loop nesting scheme made me entangled for a long time.
 The key values ​​are 0~9, up, down, left, right, confirm, and clear;
 
  Experience: Another milestone, tears are running... I seem to have become a code god...;
  Experimental time: About 14 hours (2 hours per day X7 days); 
 
 
 Completion time: 2013-11-19 23:58:22
 
*/
#include
#include

#define uint8 unsigned char //macro definition of 8-bit data type;
#define uint16 unsigned int //macro definition of 16-bit data type;

 

          // 0 , 1 , 2 , 3 , 4 , 5 , 6 , 
uint8 ak[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,
        // 7 , 8 , 9 , up , down , left , right ;
            0x07,0x7f,0x6f,0x62 ,0x54,0x21,0x0c};
uint8 ge=8,shi=8 ,si=0;

void bit(uint8 h) //digital tube bit selection enable function;
{
   PORTB|=0X02; //digital tube bit selection set to 1 (transparent state);
   if(h==0)
    {
PORTB&=0XFD; //clear (latch state);
}
}


void dat(uint8 u) //digital tube data enable function;   
{
   PORTB|=0X01;   
   if(u==0)
   {
     PORTB&=0XFE;
   }
}

void buzz(uint8 k) //Buzzer function;
{
   if(k==0)
    {
 PORTC&=~(0X80);
}
      else PORTC|=0X80;

}


void delay(uint8 j) //1=1000 counting cycles;
{
   uint16 h=0;
   while(j--)
    {
for(h=0;h<1000;h++);
}
}


void mega16() //Initialize each IO port;
{

  DDRA=0XFF; //PA output;
  DDRB=0XFF; //PB output;
  PORTA=0X00; //PA output all 0;
  delay(1); //Delay, 1000 counting cycles;
  bit(0); //Common cathode of digital tube all zero;
  PORTA=0X3F; //The digital tube data port loads data and displays 0;
  PORTB=1<<2; //Turn on the LED running light;
  dat(0); //Latch the digital tube data port data, eight digital tubes display 0;

  delay(30); //delay;   
  DDRD=0X0F; //PD port high four bits input, fourth bit output;
  PORTD=0XFF; //PD input port internal pull-up, output port outputs all 1;
  DDRC=0XFF; //PC port full output mode;
  PORTC=0X00; //PC port outputs all zero;
}

void led()
{
   static uint8 g=0;
   
PORTA=0Xff; //When inputting display data to the digital tube, all common cathodes must be set to 1 first,
         //otherwise the digital tube will be shadowed;
bit(0); //Eight digital tubes have common cathodes set to 1 (low level is valid);
   switch(g)
{ case 0: PORTA=ak[ge] ;dat(0);PORTA=0XFE;break;//digital tube ones;
  case 1: PORTA=ak[shi];dat(0);PORTA=0XFD;break; //digital tube tens;
  default: break; //otherwise...
}
      bit(0);
       g++;
            if(g==2)
{
  g=0;
}
}

[page]

shu(uint8 c)
{
          if(c<=2) {c++;} //1~3;
else if(c==3) {ge=10;shi=10; return 0;} //up;
     else if (c==11){ge=c ; shi=c; return 0;} //bottom;
else if(c==7) {ge=12,shi=12; return 0;} //left;
else if (c==15) {ge=13,shi=13; return 0;} //right;
else if(c==13){return 0;} //enter confirmation; ;
else if(c==14) {ge=0; shi=0; return 0;} //Clear;
else if((c>=8)&&(c<=10)){c-=1;} //7~9;
else if (c==12){ge=0;return 0;}
else { ;} //4~6;
 
 ge=c; shi=0;       
    
 
    
 

}


 key()
{    
    uint8 i=0 ,y=0,temp=0x10 ,v=0,ke=0 ,en[]={0xfe,0xfd,0xfb,0xf7};
// temp is used to detect whether a key is pressed in each row; en array is a four-column detection;             
    
for(v=0;v<4;v++) //v plus one represents a column detection;
{  
 PORTD=en[v]; //Detect four columns;
 temp=0x10;        
for(y=0;y<4;y++) //y plus one represents a key detection in a column;
{
if((PIND&temp)==0) //If a key is pressed, enter;
 {  
    for(i=0;i<250;i++){led();} //Debounce delay and scan digital tube;
if((PIND&temp)==0) //Confirm again that a key is pressed;
{
   buzz(1); //Buzzer on;
for(i=0;i<200;i++){led();} //Beeping delay;
for(i=0;i<200;i++){led();} //Beeping delay;
buzz(0); //Buzzer off;             
   
//==============Generate key value part================
if(v==1)y+=3; //Detect the second line; //
else if(v==2)y+=6; //Detect the third line; //
else if(v==3)y+=9; //Detect the fourth line; //
 else {;} //Detect the first line; //
ke=v+y; //Generate key value; //
//===========================================
shu(ke); // Send key value;
    while((PIND&temp)==0)led(); //Wait for the button to pop up;
  for(i=0;i<250;i++){led();} //Wait;
   while((PIND&temp)==0)led(); //Confirm again whether the button pops up;
  
  
  return 0; //End function;
}
                               
    
 }  
 
  temp=temp<<1; //Move left to detect the next button;
 
 }
        
           
     }
   
}


void main(void)
{
 

     mega16(); //Initialize each IO port;
buzz(1); //Buzzer on;
delay(15); //Delay 15,000 counting cycles;
buzz(0); //Buzzer off;
PORTA=0xff; //Load all 1s;
bit(0); //Latch all 1 data in the common cathode of the digital tube (digital tube off); 
delay(15); //Delay 15,000 counting cycles;
 
while(1)
 {
    led(); //Scan the digital tube;  
key(); //Scan the keyboard;
          
 
  } 
}
 

Reference address:AVR microcontroller scans 4X4 matrix keyboard and digital tube display program

Previous article:AVR microcontroller 8-bit timer LED accurate 1 second flashing program
Next article:AVR MCU external interrupt triggered water lamp program

Latest Microcontroller Articles
  • Download from the Internet--ARM Getting Started Notes
    A brief introduction: From today on, the ARM notebook of the rookie is open, and it can be regarded as a place to store these notes. Why publish it? Maybe you are interested in it. In fact, the reason for these notes is ...
  • Learn ARM development(22)
    Turning off and on interrupts Interrupts are an efficient dialogue mechanism, but sometimes you don't want to interrupt the program while it is running. For example, when you are printing something, the program suddenly interrupts and another ...
  • Learn ARM development(21)
    First, declare the task pointer, because it will be used later. Task pointer volatile TASK_TCB* volatile g_pCurrentTask = NULL;volatile TASK_TCB* vol ...
  • Learn ARM development(20)
    With the previous Tick interrupt, the basic task switching conditions are ready. However, this "easterly" is also difficult to understand. Only through continuous practice can we understand it. ...
  • Learn ARM development(19)
    After many days of hard work, I finally got the interrupt working. But in order to allow RTOS to use timer interrupts, what kind of interrupts can be implemented in S3C44B0? There are two methods in S3C44B0. ...
  • Learn ARM development(14)
  • Learn ARM development(15)
  • Learn ARM development(16)
  • Learn ARM development(17)
Change More Related Popular Components

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

About Us Customer Service Contact Information Datasheet Sitemap LatestNews


Room 1530, 15th Floor, Building B, No.18 Zhongguancun Street, Haidian District, Beijing, Postal Code: 100190 China Telephone: 008610 8235 0740

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号