專(zhuān)注電子技術(shù)學(xué)習(xí)與研究
當(dāng)前位置:單片機(jī)教程網(wǎng) >> MCU設(shè)計(jì)實(shí)例 >> 瀏覽文章

AVR單片機(jī)掃描4X4矩陣鍵盤(pán)并數(shù)碼管顯示程序

作者:huqin   來(lái)源:本站原創(chuàng)   點(diǎn)擊數(shù):  更新時(shí)間:2014年02月26日   【字體:

 /*
          program name :   keyboard ;
     功能描述 :  掃描16個(gè)按鍵(4X4),并把鍵值顯示在數(shù)碼管上(兩位);
 
     要點(diǎn) :  在掃描按鍵時(shí)運(yùn)用了比較復(fù)雜的兩個(gè)for()循環(huán)嵌套式
     掃描方案,大大減少了程序量,循環(huán)嵌套方案讓我糾結(jié)了好久,
 鍵值有0~9,上,下,左,右,確認(rèn),清零;
 
  體會(huì):  又一個(gè)里程碑,淚奔啊...我似乎成了 代碼男神  啊...;
  實(shí)驗(yàn)用時(shí):  約等于14小時(shí)(每天2小時(shí)X7天);
 
 
 完成時(shí)間: 2013-11-19 23:58:22
 
*/
#include <iom16v.h>
#include <macros.h>

#define uint8  unsigned char      //宏定義8位數(shù)據(jù)類(lèi)型;
#define uint16 unsigned int       //宏定義16位數(shù)據(jù)類(lèi)型;

 

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

void bit(uint8 h)    //數(shù)碼管位選使能函數(shù);
{
   PORTB|=0X02;   //數(shù)碼管位選置1(透明狀態(tài));
   if(h==0)
    {
PORTB&=0XFD;   //清零(鎖存狀態(tài));
}
}


void dat(uint8 u)   //數(shù)碼管數(shù)據(jù)使能函數(shù);  
{
   PORTB|=0X01;  
   if(u==0)
   {
     PORTB&=0XFE;
   }
}

void buzz(uint8 k)    //蜂鳴器函數(shù);
{
   if(k==0)
    {
 PORTC&=~(0X80);
}
      else  PORTC|=0X80;

}


void delay(uint8 j)          //1=1000個(gè)計(jì)數(shù)周期;
{
   uint16  h=0;
   while(j--)
    {
for(h=0;h<1000;h++);
}
}


void mega16()       //初始化各個(gè)IO口;
{

  DDRA=0XFF;    //PA輸出;
  DDRB=0XFF;    //PB輸出;
  PORTA=0X00;   //PA 輸出全0;
  delay(1);     //延時(shí)一下,1000個(gè)計(jì)數(shù)周期;
  bit(0);          //數(shù)碼管共陰極全零;
  PORTA=0X3F;    //數(shù)碼管數(shù)據(jù)口裝載數(shù)據(jù)顯示0;
  PORTB=1<<2;    //打開(kāi)led流水燈燈;
  dat(0);        //鎖存數(shù)碼管數(shù)據(jù)口數(shù)據(jù),八個(gè)數(shù)碼管顯示0;

  delay(30);    //延時(shí)一下;  
  DDRD=0X0F;   //PD口高四位輸入,第四位輸出;
  PORTD=0XFF;  //PD輸入口內(nèi)部上拉,輸出口輸出全1;
  DDRC=0XFF;   //PC口全部輸出模式;
  PORTC=0X00;   //PC口輸出全零;
}

void led()
{
   static uint8 g=0;
  
PORTA=0Xff;  //向數(shù)碼管輸入顯示數(shù)據(jù)時(shí),必先將共陰極全部置一,
         //否則數(shù)碼管會(huì)出現(xiàn)陰影;
bit(0);     //八個(gè)數(shù)碼管共陰極置一(低電平有效);
   switch(g)
{  case 0:  PORTA=ak[ge] ;dat(0);PORTA=0XFE;break;//數(shù)碼管個(gè)位;
  case 1:  PORTA=ak[shi];dat(0);PORTA=0XFD;break; //數(shù)碼管十位;
  default: break;   //否則...
}
      bit(0);
       g++;
            if(g==2)
{
  g=0;
}
}

 

shu(uint8 c)
{
          if(c<=2) {c++;}  //1~3;
else if(c==3) {ge=10;shi=10; return 0;}   //上;
     else if(c==11){ge=c ; shi=c; return 0;}   //下;
else if(c==7) {ge=12,shi=12; return 0;}   //左;
else if(c==15) {ge=13,shi=13; return 0;}   //右;
else if(c==13){return 0;}      //enter 確認(rèn);  ;
else if(c==14){ge=0; shi=0;  return 0;}  //清零;
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用于檢測(cè)每一行某個(gè)鍵是否按下; en數(shù)組是四列檢測(cè);            
   
for(v=0;v<4;v++)     //v每加一代表檢測(cè)一列;

 PORTD=en[v];     //檢測(cè)四列;
 temp=0x10;       
for(y=0;y<4;y++)    //y每加一,代表檢測(cè)一列中的一個(gè)按鍵;
{
if((PIND&temp)==0)    //如果有鍵被按下,進(jìn)入;
 { 
    for(i=0;i<250;i++){led();}   //去抖延時(shí)并且掃描數(shù)碼管;
if((PIND&temp)==0)        //再次確認(rèn)有鍵被按下;
{
   buzz(1);      //蜂鳴器開(kāi);
for(i=0;i<200;i++){led();}   //鳴響延時(shí);
for(i=0;i<200;i++){led();}   //鳴響延時(shí);
buzz(0);      //蜂鳴器關(guān);            
  
//===============生成鍵值部分================
if(v==1)y+=3;       //檢測(cè)到第二行;        //
else if(v==2)y+=6;  //檢測(cè)到第三行;        //
else if(v==3)y+=9;  //檢測(cè)到第四行;        //
 else {;}          //檢測(cè)到第一行;        //
ke=v+y;    //生成鍵值;                     //
//===========================================
shu(ke);    // 發(fā)送鍵值;
    while((PIND&temp)==0)led();   //等待按鍵彈起;
  for(i=0;i<250;i++){led();}    //等待一下;
   while((PIND&temp)==0)led();   //再次確認(rèn)一下按鍵是否彈起;
 
 
  return 0;    //結(jié)束函數(shù);
}
                              
   
 } 
 
  temp=temp<<1;  //左移一下代表檢測(cè)下一個(gè)按鍵;
 
 }
       
          
     }
  
}


void main(void)
{
 

     mega16();  //初始化各個(gè)IO口;
buzz(1);   //蜂鳴器開(kāi);
delay(15); //延時(shí)1.5萬(wàn)計(jì)數(shù)周期;
buzz(0);   //蜂鳴器關(guān);
PORTA=0xff;   //載入全1;
bit(0);       //把全1數(shù)據(jù)鎖存在數(shù)碼管共陰極(數(shù)碼管滅);
delay(15);   //延時(shí)1.5萬(wàn)計(jì)數(shù)周期;
 
while(1)
 {
    led();  //掃描數(shù)碼管; 
key();  //掃描鍵盤(pán);
         
 
  }
}
 

關(guān)閉窗口

相關(guān)文章