久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

專注電子技術學習與研究
當前位置:單片機教程網 >> MCU設計實例 >> 瀏覽文章

AVR單片機矩陣鍵盤程序(2種方法)

作者:佚名   來源:本站原創   點擊數:  更新時間:2012年06月05日   【字體:

AVR矩陣鍵盤2種方法實現!

普通方法:

#include<iom16v.h>//
#include<macros.h>//
#define uchar unsigned char//
#define uint unsigned int//
#define setb(val,bitn) (val|=(1<<(bitn)))//設置某IO口某位為1
#define clr(val,bitn) (val&=~(1<<(bitn)))//設置某IO口某位為0
#define get(val,bitn) (val&(1<<(bitn)))//讀取某位狀態如if(get(PORTC,7))即判斷PC7口是否為1
#pragma data:code//數組存放位置
const table[]={
0xc0,0xf9,0xa4,0xb0,0x99,
0x92,0x82,0xf8,0x80,0x90,
0x88,0x83,0xc6,0xa1,0x86,
0x8e
};//共陽數碼管0--9代碼
uchar num,yin,temp;//鍵值碼及識別碼
void delay(uchar);//延時函數
void  disy();//顯示函數
void skk()
{
  for(yin=0;yin<2;yin++)
  {
   PORTD=0xfe;//將第一行置0,即檢測第一行
  temp=PIND;//將值給tem
  temp=temp&0xf0;//與0xf0與門一下,
  while(temp!=0xf0)//判斷是否為0xf0
  {
   delay(10);//延時
   temp=PIND;//將P1值再給tem
   temp=temp&0xf0;//將值再與門
   while(temp!=0xf0)//再次判斷是否為0xf0
   {
    temp=PIND;//確實按下了,將tem值裝回,以便下次判斷開關語句,否則沒有它對應的值,如原來是ee,如果再按下是第二個鍵就不是de了
    switch(temp)//開關語句
     {
      case 0xee:num=0;//與num值比較是否相等,如果相等就退出switch語句
      break;//退出switch語句
      case 0xde:num=1;//與num值比較是否相等,如果相等就退出switch語句
      break;//退出switch語句
      case 0xbe:num=2;//與num值比較是否相等,如果相等就退出switch語句
      break;//退出switch語句
      case 0x7e:num=3;//與num值比較是否相等,如果相等就退出switch語句
      break;//退出switch語句
     }
    while(temp!=0xf0)//松手判斷,以便退出以上兩個while
    {
     temp=PIND;//給temp賦值
     temp=temp&0xf0;//與門一下
    }
   }
  }
 }
 
  for(yin=0;yin<2;yin++)
      {
   PORTD=0xfd;//將第一行置0,即檢測第一行
  temp=PIND;//將值給tem
  temp=temp&0xf0;//與0xf0與門一下,
  while(temp!=0xf0)//判斷是否為0xf0
  {
   delay(10);//延時
   temp=PIND;//將P1值再給tem
   temp=temp&0xf0;//將值再與門
   while(temp!=0xf0)//再次判斷是否為0xf0
   {
    temp=PIND;//確實按下了,將tem值裝回,以便下次判斷開關語句,否則沒有它對應的值,如原來是ee,如果再按下是第二個鍵就不是de了
    switch(temp)//開關語句
     {
      case 0xed:num=4;//與num值比較是否相等,如果相等就退出switch語句
      break;//退出switch語句
      case 0xdd:num=5;//與num值比較是否相等,如果相等就退出switch語句
      break;//退出switch語句
      case 0xbd:num=6;//與num值比較是否相等,如果相等就退出switch語句
      break;//退出switch語句
      case 0x7d:num=7;//與num值比較是否相等,如果相等就退出switch語句
      break;//退出switch語句
     }
    while(temp!=0xf0)//松手判斷,以便退出以上兩個while
    {
     temp=PIND;//給temp賦值
     temp=temp&0xf0;//與門一下
    }
   }
  }
 }
 for(yin=0;yin<2;yin++)
      {
   PORTD=0xfb;//將第一行置0,即檢測第一行
  temp=PIND;//將值給tem
  temp=temp&0xf0;//與0xf0與門一下,
  while(temp!=0xf0)//判斷是否為0xf0
  {
   delay(10);//延時
   temp=PIND;//將P1值再給tem
   temp=temp&0xf0;//將值再與門
   while(temp!=0xf0)//再次判斷是否為0xf0
   {
    temp=PIND;//確實按下了,將tem值裝回,以便下次判斷開關語句,否則沒有它對應的值,如原來是ee,如果再按下是第二個鍵就不是de了
    switch(temp)//開關語句
     {
      case 0xeb:num=8;//與num值比較是否相等,如果相等就退出switch語句
      break;//退出switch語句
      case 0xdb:num=9;//與num值比較是否相等,如果相等就退出switch語句
      break;//退出switch語句
      case 0xbb:num=10;//與num值比較是否相等,如果相等就退出switch語句
      break;//退出switch語句
      case 0x7b:num=11;//與num值比較是否相等,如果相等就退出switch語句
      break;//退出switch語句
     }
    while(temp!=0xf0)//松手判斷,以便退出以上兩個while
    {
     temp=PIND;//給temp賦值
     temp=temp&0xf0;//與門一下
    }
   }
  }
 }
  for(yin=0;yin<2;yin++)
       {
   PORTD=0xf7;//將第一行置0,即檢測第一行
  temp=PIND;//將值給tem
  temp=temp&0xf0;//與0xf0與門一下,
  while(temp!=0xf0)//判斷是否為0xf0
  {
   delay(10);//延時
   temp=PIND;//將P1值再給tem
   temp=temp&0xf0;//將值再與門
   while(temp!=0xf0)//再次判斷是否為0xf0
   {
    temp=PIND;//確實按下了,將tem值裝回,以便下次判斷開關語句,否則沒有它對應的值,如原來是ee,如果再按下是第二個鍵就不是de了
    switch(temp)//開關語句
     {
      case 0xe7:num=12;//與num值比較是否相等,如果相等就退出switch語句
      break;//退出switch語句
      case 0xd7:num=13;//與num值比較是否相等,如果相等就退出switch語句
      break;//退出switch語句
      case 0xb7:num=14;//與num值比較是否相等,如果相等就退出switch語句
      break;//退出switch語句
      case 0x77:num=15;//與num值比較是否相等,如果相等就退出switch語句
      break;//退出switch語句
     }
    while(temp!=0xf0)//松手判斷,以便退出以上兩個while
    {
     temp=PIND;//給temp賦值
     temp=temp&0xf0;//與門一下
    }
   }
  }

 }
}
void main()
{
     DDRD|=0xff;//設置PB口為輸出
     PORTD|=0xff;//PB輸出為高電位
     DDRD&=0x0f;//設置高
     while(1)//大循環
     {
      skk();
 disy();//調用顯示子程序 
     }
}
void delay(uchar z)//延時子函數
{
 uchar x,y;
 for(x=100;x>0;x--)
 for(y=z;y>0;y--); 
}
void disy()//顯示子函數
{   
     DDRC=0xff;
     DDRB=0xff;
     PORTB=table[num];
     PORTC=0x00;
}

簡單方法:

#include<iom16v.h>
#include<macros.h>
#define uchar unsigned char
#define uint unsigned int
#pragma data:code//定義程序存在ROM里面
const table[]={
0xc0,0xf9,0xa4,0xb0,0x99,
0x92,0x82,0xf8,0x80,0x90,
0x88,0x83,0xc6,0xa1,0x86,
0x8e,0xff
};
/***********************************************/
/*******************延時子程序******************/
/***********************************************/
void delay(uchar z)
{
   uchar x,y;
  for(x=0;x<50;x++)
  for(y=0;y<z;y++);
}
/***********************************************/
/*******************顯示子程序******************/
/***********************************************/
void xian(uchar num)
{
  uchar i;
 PORTB=table[num];//十位
 PORTC=0x00;
}
/***********************************************/
/***************按鍵按下處理程序***************/
/***********************************************/
uchar key_press()
{
     uchar i;
     DDRD=0XFF;//設置PD口全為輸出
  PORTD=0XF0;//設置PD高四位為高電平,以便進行判斷
  DDRD=0X0F;//設置高4位為輸入,低4位為輸出
  i=PIND;//讀出IO口狀態
  if(i==0XF0)//如果它等于0XF0就執返回0
  {
    DDRD=0XFF;//將IO口值讀回來
    return 0;
  }
  else//否則它就執返回1
  {
    DDRD=0XFF;
    return 1;
  }
}
/***********************************************/
/***************按鍵鍵值處理程序***************/
/***********************************************/
uchar key_scan()
{
    uchar key,i=0X7F,j;//將變量I設置為01111111B
 if(key_press())//判斷按鍵是否被按下了
 {
      delay(10);//如果被按下了,消下抖
   if(key_press())//再次判斷下按鍵是否被按下了
   {
     do//先執行一次
  {
   i=(i<<1|i>>7);/*將變量I內容左移1位,11111110
   然后將I右移7位,11111110,即實現11111110
   11111101 11111011 11110111*/
   PORTD=i;//將移位后的值給PD口
   DDRD=0X0F;//將PD口高位設為輸入,低位設為輸出
   key=PIND;//將IO口高位值讀一下
   j=key&0XF0;//只需要讀高4位
    }
  while(j==0XF0);//如果按鍵沒有按下,則再執行上面的do語句
  while(key_press());//如果有按下則釋放一下
  switch(key)//確定有按鍵按下了就判斷下到底是哪個值
  {
          case 0xEE:
      key=0x0;
   break;
      case 0xDE:
      key=0x1;
   break;
      case 0xBE:
      key=0x2;
   break;
      case 0x7E:
      key=0x3;
   break;
      case 0xED:
      key=0x4;
   break;
      case 0xDD:
      key=0x5;
   break;
      case 0xBD:
      key=0x6;
   break;
     case 0x7D:
      key=0x7;
   break;
      case 0xEB:
      key=8;
   break;
      case 0xDB:
      key=9;
   break;
      case 0xBB:
      key=0xA;
   break;
      case 0x7B:
      key=0xB;
   break;
      case 0xE7:
      key=0xC;
   break;
      case 0xD7:
      key=0xD;
   break;
        case 0xB7:
      key=0xE;
   break;
      case 0x77:
      key=0xF;
   break;
  }
  }
  }
  return key;//返回按鍵值
}
/***********************************************/
/*******************主程序*********************/
/***********************************************/
void main()
{
   uchar ik=16;//定義局部變量
   DDRB=0xff;//設置PB口為輸出
  DDRC=0xff;//設置PC口為輸出
  while(1)
  {
     ik=key_scan();//將按鍵返回值給變量IK
     if(ik<16)//如果返回值小于16就在數碼管上顯示出來
   xian(ik); //調用顯示子程序
   else//如果返回值不小于16,就顯示黑屏
   xian(16);
  }
}

關閉窗口

相關文章

主站蜘蛛池模板: 午夜精品一区二区三区在线视频 | 毛片免费观看 | 国产成人精品午夜视频免费 | 91精品久久久 | 日韩精品区 | 国产一二区免费视频 | 色偷偷噜噜噜亚洲男人 | 亚洲欧美在线免费观看 | 欧美久久视频 | 久久er精品| 一区二区三区视频在线免费观看 | 国产精品我不卡 | 日本成人中文字幕 | 91精品国产一区二区三区 | 久久综合激情 | 久久亚洲经典 | 91视频三区 | 成人小视频在线观看 | 亚洲欧美日韩精品久久亚洲区 | 中文字幕在线免费 | 在线观看一区 | 狠狠涩| 中文字幕av一区 | 一区二区三区av | 精品国产一区探花在线观看 | 一级片免费视频 | 91在线精品一区二区 | 日韩精品在线一区 | av一区二区三区四区 | 天天夜夜人人 | 久久精品亚洲精品 | 少妇精品久久久久久久久久 | 综合国产在线 | 亚洲a在线视频 | 中文字幕一级 | 久久国产精品久久 | 在线国产一区二区三区 | 91国自视频| 日本 欧美 三级 高清 视频 | 国产精品免费视频一区 | 一级做a爰片性色毛片 |