☛ 功能說明

使用一個按鍵開關控制四位七段顯示器上、下計數。 每按一下按鍵開關,顯示器的狀態會改變,即原先上數改變為下數,原先下數改變為上數。

☛ 使用材料

Arduino UNO R3 開發板 × 1、按鍵開關 × 1、電阻 220Ω × 8、電阻 10KΩ × 4、PNP電晶體 2N3906 × 4、四位共陽極七段顯示器 SH5461BS × 1。

☛ 電路圖及麵包板接線圖

☛ 程式碼

int i;                                                //顯示器位數
int j;                                                //顯示器段數
int count=0;                                          //計數值
int number;                                           //計數值
int keyData;                                          //按鍵值
int numKeys=0;                                        //按鍵次數
const int debounceDelay=20;                           //開關穩定所需要的時間 20ms
unsigned long time=0;                                 //計數
const byte num[10] =                                  //0~9 顯示碼
      { B11000000, B11111001, B10100100, B10110000, B10011001,
        B10010010, B10000010, B11111000, B10000000, B10010000 };
const int seg[]={ 2,3,4,5,6,7,8,9 };                  //顯示器各段 abcdefgp 數位接腳
const int digit[]={ 10,11,12,13 };                    //顯示器共點 D1~D4 數位接腳
const int sw=14;

void setup()
{
     pinMode(sw,INPUT_PULLUP);                        //設定數位接腳 14 為輸入上拉模式
     for(i=0;i<8;i++)
         pinMode(seg[i],OUTPUT);                      //設定數位接腳 2~9 為輸出模式
     for(i=0;i<4;i++)
     {
         pinMode(digit[i],OUTPUT);                    //設定數位接腳 10~13 為輸出模式
         digitalWrite(digit[i],HIGH);                 //關閉掃描信號
     }
}

void loop()
{
     keyData=digitalRead(sw);                         //讀取按鍵
     if(keyData==LOW)                                 //按下按鍵?
     {
        delay(debounceDelay);                         //消除機械彈跳
        while(digitalRead(sw)==LOW)                   //按鍵尚未放開
              ;                                       //等待按鍵放開
        numKeys++;                                    //記錄按鍵次數
     }
     number=count;                                    //顯示計數值
     for(i=3;i>=0;i--)                                //四位顯示器
     {
         for(j=0;j<8;j++)                             //每位顯示器有 abcdefgp 八段
         {
             if(bitRead(num[number%10],j))            //段位元資料為 1?
                digitalWrite(seg[j],HIGH);            //設定段狀態為 HIGH
             else                                     //段位元資料為 0
                digitalWrite(seg[j],LOW);             //設定段狀態為 LOW
         }
         digitalWrite(digit[i],LOW);                  //致能 Di 位數顯示器
         delay(5);                                    //延遲 5ms
         digitalWrite(digit[i],HIGH);                 //除能 Di 位數顯示器
         number=number/10;                            //下一位數
         if(millis()-time>=1000)                      //已經過 1 秒
         {
            time=millis();                            //儲存時間
            if(numKeys%2==0)                          //按鍵次數為偶數?
            {
               count++;                               //計數值加 1
               if(count>9999)                         //計數值大於 9999?
                  count=0;                            //重新設定計數值為 0000
            }
            else                                      //按鍵次數為奇數
            {
               count--;                               //計數值減 1
               if(count<0)                            //計數值小於 0
                  count=9999;                         //重新設定計數值為 9999
            }
         }
     }
}

 
☛ 練習

⑴ 設計 Arduino 程式,使用按鍵開關控制顯示器閃爍上、下數。 每按一下按鍵開關,顯示器的狀態會改變,若原先上數則改變為下數,原先下數則改變為上數。

int i;                                                //顯示器位數
int j;                                                //顯示器段數
int count=0;                                          //計數值
int number;                                           //計數值
int keyData;                                          //按鍵值
int numKeys=0;                                        //按鍵次數
const int debounceDelay=20;                           //開關穩定所需要的時間 20ms
unsigned long time=0;                                 //計數
const byte num[10] =                                  //0~9 顯示碼
      { B11000000, B11111001, B10100100, B10110000, B10011001,
        B10010010, B10000010, B11111000, B10000000, B10010000 };
const int seg[]={ 2,3,4,5,6,7,8,9 };                  //顯示器各段 abcdefgp 數位接腳
const int digit[]={ 10,11,12,13 };                    //顯示器共點 D1~D4 數位接腳
const int sw=14;

void setup()
{
     pinMode(sw,INPUT_PULLUP);                        //設定數位接腳 14 為輸入上拉模式
     for(i=0;i<8;i++)
         pinMode(seg[i],OUTPUT);                      //設定數位接腳 2~9 為輸出模式
     for(i=0;i<4;i++)
     {
         pinMode(digit[i],OUTPUT);                    //設定數位接腳 10~13 為輸出模式
         digitalWrite(digit[i],HIGH);                 //關閉掃描信號
     }
}

void loop()
{
     keyData=digitalRead(sw);                         //讀取按鍵
     if(keyData==LOW)                                 //按下按鍵?
     {
        delay(debounceDelay);                         //消除机械弹跳
        while(digitalRead(sw)==LOW)                   //按鍵尚未放開
              ;                                       //等待按鍵放開
        numKeys++;                                    //記錄按鍵次數
     }
     number=count;                                    //顯示計數值
     numDisplay();
     delay(100);
     numClose();
     if(millis()-time>=1000)                          //已經過 1 秒
     {
        time=millis();                                //儲存時間
        if(numKeys%2==0)                              //按鍵次數為偶數?
        {
           count++;                                   //計數值加 1
           if(count>9999)                             //計數值大於 9999?
              count=0;                                //重新設定計數值為 0000
        }
        else                                          //按鍵次數為奇數
        {
           count--;                                   //計數值減 1
           if(count<0)                                //計數值小於 0
              count=9999;                             //重新設定計數值為 9999
        }
     }
}

void numDisplay()                                     //顯示數值副程式
{
     for(i=3;i>=0;i--)                                //四位顯示器
     {
         for(j=0;j<8;j++)                             //每位顯示器有 abcdefgp 八段
         {
             if(bitRead(num[number%10],j))            //段位元資料為 1?
                digitalWrite(seg[j],HIGH);            //設定段狀態為 HIGH
             else                                     //段位元資料為 0
                digitalWrite(seg[j],LOW);             //設定段狀態為 LOW
         }
         digitalWrite(digit[i],LOW);                  //致能 Di 位數顯示器
         delay(5);                                    //延遲 5ms
         digitalWrite(digit[i],HIGH);                 //除能 Di 位數顯示器
         number=number/10;                            //下一位數
     } 
}

void numClose()                                       //除能四位七段顯示器副程式
{
     for(i=0;i<4;i++)                                 //除能 Di 位數顯示器
         digitalWrite(digit[i],HIGH);
}

 

⑵ 設計 Arduino 程式,使用按鍵開關控制顯示器。 每按一下按鍵開關,顯示器的狀態會改變,若原先上數則改變為顯示「H」、「E」、「L」、「P」,原先顯示「H」、「E」、「L」、「P」則改變為上數。

int i;                                                //顯示器位數
int j;                                                //顯示器段數
int count=0;                                          //計數值
int number;                                           //計數值
int keyData;                                          //按鍵值
int numKeys=0;                                        //按鍵次數
const int debounceDelay=20;                           //開關穩定所需要的時間 20ms
unsigned long time=0;                                 //計數
const byte num[10] =                                  //0~9 顯示碼
      { B11000000, B11111001, B10100100, B10110000, B10011001,
        B10010010, B10000010, B11111000, B10000000, B10010000 };
const byte help[4]=                                   //HELP 顯示碼
      { B10001001, B10000110, B11000111, B10001100 };
const int seg[]={ 2,3,4,5,6,7,8,9 };                  //顯示器各段 abcdefgp 數位接腳
const int digit[]={ 10,11,12,13 };                    //顯示器共點 D1~D4 數位接腳
const int sw=14;

void setup()
{
     pinMode(sw,INPUT_PULLUP);                        //設定數位接腳 14 為輸入上拉模式
     for(i=0;i<8;i++)
         pinMode(seg[i],OUTPUT);                      //設定數位接腳 2~9 為輸出模式
     for(i=0;i<4;i++)
     {
         pinMode(digit[i],OUTPUT);                    //設定數位接腳 10~13 為輸出模式
         digitalWrite(digit[i],HIGH);                 //關閉掃描信號
     }
}

void loop()
{
     keyData=digitalRead(sw);                         //讀取按鍵
     if(keyData==LOW)                                 //按下按鍵?
     {
        delay(debounceDelay);                         //消除機械彈跳
        while(digitalRead(sw)==LOW)                   //按鍵尚未放開
              ;                                       //等待按鍵放開
        numKeys++;                                    //記錄按鍵次數
     }
     number=count;                                    //顯示計數值

     if(numKeys%2==0)                                 //按鍵次數為偶數?
        numDisplay();                                 //顯示數值
     else
        helpDisplay();                                //顯示 HELP
        
     if(millis()-time>=1000)                          //已經過 1 秒
     {
        time=millis();                                //儲存時間
        count++;                                      //計數值加 1
        if(count>9999)                                //計數值大於 9999?
           count=0;                                   //重新設定計數值為 0000
     }
}

void numDisplay()                                     //顯示數值副程式
{
     for(i=3;i>=0;i--)                                //四位顯示器
     {
         for(j=0;j<8;j++)                             //每位顯示器有 abcdefgp 八段
         {
             if(bitRead(num[number%10],j))            //段位元資料為 1?
                digitalWrite(seg[j],HIGH);            //設定段狀態為 HIGH
             else                                     //段位元資料為 0
                digitalWrite(seg[j],LOW);             //設定段狀態為 LOW
         }
         digitalWrite(digit[i],LOW);                  //致能 Di 位數顯示器
         delay(5);                                    //延遲 5ms
         digitalWrite(digit[i],HIGH);                 //除能 Di 位數顯示器
         number=number/10;                            //下一位數
     } 
}

void helpDisplay()                                    //顯示 HELP 副程式
{
     for(i=3;i>=0;i--)                                //四位顯示器
     {
         for(j=0;j<8;j++)                             //每位顯示器有 abcdefgp 八段
         {
             if(bitRead(help[i],j))                   //段位元資料為 1?
                digitalWrite(seg[j],HIGH);            //設定段狀態為 HIGH
             else                                     //段位元資料為 0
                digitalWrite(seg[j],LOW);             //設定段狀態為 LOW
         }
         digitalWrite(digit[i],LOW);                  //致能 Di 位數顯示器
         delay(5);                                    //延遲 5ms
         digitalWrite(digit[i],HIGH);                 //除能 Di 位數顯示器
     }   
}