搜尋此網誌

2013/01/20

14-1 計時中斷的延伸題


14-1 計時中斷延伸題:電壓表

1. 相關知識

本範例主要是運用本文中使用到的計時中斷,讓中斷負責顯示陣列Data[]的內容,而主迴圈程式負責讀入A0的電壓值,並轉換個別數值至Data[]中,方便計時中斷顯示。

2. 電路圖

(1)電路圖

圖1 四位元多工顯示器電路
圖2 Arduino與多工顯示器的連接

(2)配線圖


3. 程式碼

/*  數位電壓表:採用四位元多工掃描
    可將A0端測得的電壓顯示在四位元七段顯示器上
    可顯示的數值為0.000V~5.000V
*/

#include <FlexiTimer2.h>
#include <Time.h> 

const int seg7[] = { 11, 10, 9, 8, 7, 6, 5, 4 };  // 七段控制腳陣列,對應a~g段+小數點
const int scan[] = { 13, 12, 3, 2 };           // 掃描端控制腳陣列,千,百,十,個
const byte V = A0;

char TAB[]={ 0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x27,0x7F,0x67,0 };  // 七節顯示器編碼表 0~9
volatile char scan_line = 0;         // 記錄掃描線位置的變數(中斷用)
int ii;
// 顯示的數字
volatile byte Data[4];
unsigned int voltage;

// the setup routine runs once when you press reset:
void setup() {                
  for (ii=0; ii<8; ii++) {  // 初始化指定的數位腳位為輸出模式
     pinMode(seg7[ii], OUTPUT);
  }
  for (ii=0; ii<4; ii++) {
     pinMode(scan[ii], OUTPUT);  // 初始化scan[ii]腳位為輸出模式
     digitalWrite(scan[ii], LOW); // 掃描端電晶體 OFF
  }
  FlexiTimer2::set(5, 1.0/1000, flash); // 每 5ms 呼叫一次 flash
  FlexiTimer2::start();          // 啟動計時中斷
}

// the loop routine runs over and over again forever:
void loop() {
  voltage=map(analogRead(V),0,1023,0,4500);
  SetNumber(voltage);
  delay(100);
}

// 計時中斷程式,每次執行時處理1位數
void flash()
{
  digitalWrite(scan[scan_line], LOW);
  scan_line=(scan_line+1) % 4;
  if (scan_line==0)    // 若是千位數其小數點要亮,故需加上0x80
    OutPort(0x80+TAB[Data[scan_line]]);
  else
    OutPort(TAB[Data[scan_line]]);
  digitalWrite(scan[scan_line], HIGH);
}

// 將指定值顯示在七段顯示器上,最低位元為a,依序為 abcdefg+小數點
void OutPort(byte dat) {
    for (ii=0; ii<8; ii++)
        digitalWrite(seg7[ii], bitRead(dat, ii));
}

// 將欲顯示的數字 number 存入顯示陣列 Data 中
void SetNumber(unsigned long temp) {
  for (ii=3; ii>=0; ii--) {
    Data[ii]=temp % 10;
    temp=temp/10;
  }
}

4. 成果影片

沒有留言: