☛ 功能说明

利用一个电话键盘控制 10 个 LED ( L0 ~ L9 ) 的状态。当按下数字 0 ~ 9 时,LED 相对编号 L0 ~ L9 的状态改变,例如按一下按键 0 时,L0 亮,再按一下按键 0 时,L0 暗。

☛ 使用材料

Arduino UNO R3  开发板 × 1、电阻 220Ω × 10、红色 LED × 10、薄膜按键键盘 ( 4 × 4 ) × 1。

☛ 电路图及面包板接线图

☛ 程式码

int i,j,k;                                        //电话键盘第 i 行,第 j 列及第 k 个 LED
int ledStatus[10];                                //LED 状态
const int numCols=4;                              //电话键盘总行数
const int numRows=4;                              //电话键盘总列数
const int debounceDelay=20;                       //按键开关稳定所需时间
const int led[]={10,11,12,13,14,15,16,17,18,19};  //LED 数位接脚
const int col[]={6,7,8,9};                        //电话键盘行的数位接脚
const int row[]={2,3,4,5};                        //电话键盘列的数位接脚
const int keyMap[numRows][numCols]=               //4 × 4 电话键盘的按键定义
          { {1,2,3,12},                           //按键 1、2、3、A
            {4,5,6,13},                           //按键 4、5、6、B
            {7,8,9,14},                           //按键 7、8、9、C
            {10,0,11,15} };                       //按键 *、0、#、D

void setup()
{
     for(i=0;i<numCols;i++)
     {
         pinMode(col[i],OUTPUT);                  //设定键盘行接脚为输出
         digitalWrite(col[i],HIGH);               //所有行接脚为 HIGH
     }
     for(j=0;j<numRows;j++)
     {
         pinMode(row[j],INPUT);                   //设定键盘列接脚为输入
         digitalWrite(row[j],HIGH);               //开启所有列接脚的内部上拉电阻
     }
     for(k=0;k<10;k++)
     {
         pinMode(led[k],OUTPUT);                  //设定所有 LED 接脚为输出
         digitalWrite(led[k],LOW);                //设定所有 LED 皆不亮
         ledStatus[k]=LOW;                        //设定所有 LED 状态皆为 LOW
     }
}

void loop()
{
     int key=getKey();                            //读取按键状态

     if(key>=0 && key<=9)                         //按下 0 ~ 9 键?
     {
        ledStatus[key]=!ledStatus[key];           //改变相同编号的 LED 状态
        digitalWrite(led[key],ledStatus[key]);    //设定相同编号的 LED 状态
     }
}

int getKey()
{
  int i,j;
  int key=-1;                                     //按键 k=-1,代表未按下任何按键

  for(i=0;i<numCols;i++)
  {
      digitalWrite(col[i],LOW);                   //扫描第 i 行
      for(j=0;j<numRows;j++)                      //检测每一列的按键是否已经被按下
      {
        if(digitalRead(row[j])==LOW)              //按键已经被按下?
        {
           delay(debounceDelay);                  //消除按键的机械弹跳不稳定现象
           while(digitalRead(row[j])==LOW)        //等待按键放开
                 ;
           key=keyMap[j][i];                      //储存按键值
        }
      }
      digitalWrite(col[i],HIGH);                  //除能行扫描
  }
  return(key);                                    //传回按键值
}

 

 

☛ 练习

㈠ 设计 Arduino 程式,使用 4×4 电话键盘控制 10 个 LED 的状态。当按下数字 0~9 时,LED 相对编号 L0~L9 的状态改变,例如按一下按键 0 时,L0 闪烁,再按一下按键 0 时,L0 暗。

int i,j,k;                                        //电话键盘第 i 行,第 j 列及第 k 个 LED
int ledStatus[10];                                //LED 状态
const int numCols=4;                              //电话键盘总行数
const int numRows=4;                              //电话键盘总列数
const int debounceDelay=20;                       //按键开关稳定所需时间
const int led[]={10,11,12,13,14,15,16,17,18,19};  //LED 数位接脚
const int col[]={6,7,8,9};                        //电话键盘行的数位接脚
const int row[]={2,3,4,5};                        //电话键盘列的数位接脚
const int keyMap[numRows][numCols]=               //4 × 4 电话键盘的按键定义
          { {1,2,3,12},                           //按键 1、2、3、A
            {4,5,6,13},                           //按键 4、5、6、B
            {7,8,9,14},                           //按键 7、8、9、C
            {10,0,11,15} };                       //按键 *、0、#、D

void setup()
{
     for(i=0;i<numCols;i++)
     {
         pinMode(col[i],OUTPUT);                  //设定键盘行接脚为输出
         digitalWrite(col[i],HIGH);               //所有行接脚为 HIGH
     }
     for(j=0;j<numRows;j++)
     {
         pinMode(row[j],INPUT);                   //设定键盘列接脚为输入
         digitalWrite(row[j],HIGH);               //开启所有列接脚的内部上拉电阻
     }
     for(k=0;k<10;k++)
     {
         pinMode(led[k],OUTPUT);                  //设定所有 LED 接脚为输出
         digitalWrite(led[k],LOW);                //设定所有 LED 皆不亮
         ledStatus[k]=LOW;                        //设定所有 LED 状态皆为 LOW
     }
}

void loop()
{
     int key=getKey();                            //读取按键状态

     if(key>=0 && key<=9)                         //按下 0 ~ 9 键?
     {
        ledStatus[key]=!ledStatus[key];           //改变相同编号的 LED 状态
     }
     displayLED();                                //显示各个 LED 状态
}

int getKey()
{
  int i,j;
  int key=-1;                                     //按键 k=-1,代表未按下任何按键

  for(i=0;i<numCols;i++)
  {
      digitalWrite(col[i],LOW);                   //扫描第 i 行
      for(j=0;j<numRows;j++)                      //检测每一列的按键是否已经被按下
      {
        if(digitalRead(row[j])==LOW)              //按键已经被按下?
        {
           delay(debounceDelay);                  //消除按键的机械弹跳不稳定现象
           while(digitalRead(row[j])==LOW)        //等待按键放开
                 ;
           key=keyMap[j][i];                      //储存按键值
        }
      }
      digitalWrite(col[i],HIGH);                  //除能行扫描
  }
  return(key);                                    //传回按键值
}

void displayLED()                                 //显示各个 LED 副程式
{
     for(i=0;i<10;i++)                            //扫描各个 LED 的显示状态值
     {
         if(ledStatus[i]==HIGH)                   //显示状态值为 HIGH,该相对位置的 LED 闪烁
            digitalWrite(led[i],HIGH);
         delay(10);                               //延迟 10ms
         digitalWrite(led[i],LOW);
     }
}