4位元七段顯示器控制

使用4位元七段顯示器時,通常透過com1~com4依次顯示每個位元的數字,利用高速掃描、視覺暫留來實現。

int seg[8] = {15, 16, 17, 18, 19, 21, 22, 23};
// 對應的接腳 { a,  b,  c,  d,  e,  f,  g, dp}
int data[]= {0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x27,0x7F,0x67,0x00};
// 顯示的數字 { 0  ,  1 ,  2 ,  3 ,  4 ,  5 ,  6 ,  7 ,  8 ,  9 ,全滅}
int com[4] = {25, 26, 27, 14};
// 對應的接腳 {com1,com2,com3,com4}

void setup() {
  // 初始化七段顯示器a~g、dp接腳
  for(int i=0; i<=7; i++)
  {
    pinMode(seg[i], OUTPUT);
    digitalWrite(seg[i],0);   // 全滅
  }
  // 初始化七段顯示器com1~com4接腳
  for(int i=0; i<=3; i++)
  {
    pinMode(com[i], OUTPUT);
    digitalWrite(com[i],0);   // 全滅    
  }
}

void loop() {
  showdata(9); // 千位數
  // ------ 掃瞄碼 ------
  digitalWrite(com[0],1);
  digitalWrite(com[1],0);
  digitalWrite(com[2],0);
  digitalWrite(com[3],0);
  // --------------------
  delay(1);

  showdata(8); // 百位數
  // ------ 掃瞄碼 ------
  digitalWrite(com[0],0);
  digitalWrite(com[1],1);
  digitalWrite(com[2],0);
  digitalWrite(com[3],0);
  // --------------------
  delay(1);

  showdata(7); // 十位數
  // ------ 掃瞄碼 ------
  digitalWrite(com[0],0);
  digitalWrite(com[1],0);
  digitalWrite(com[2],1);
  digitalWrite(com[3],0);
  // --------------------
  delay(1);

  showdata(6); // 個位數
  // ------ 掃瞄碼 ------
  digitalWrite(com[0],0);
  digitalWrite(com[1],0);
  digitalWrite(com[2],0);
  digitalWrite(com[3],1);
  // --------------------
  delay(1);
}

void showdata(int x)
{
  for(int i=0; i<7; i++)
  digitalWrite(seg[i],bitRead(data[x],i));
}

若定義一個位元掃瞄的陣列digit[ ],並將每個位元的掃瞄碼利用bitRead函式取出,可得到下列結果:

int seg[8] = {15, 16, 17, 18, 19, 21, 22, 23};
// 對應的接腳 { a,  b,  c,  d,  e,  f,  g, dp}
int data[]= {0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x27,0x7F,0x67,0x00};
// 顯示的數字 { 0  ,  1 ,  2 ,  3 ,  4 ,  5 ,  6 ,  7 ,  8 ,  9 ,全滅}
int com[4] = {25, 26, 27, 14};
// 對應的接腳 {com1,com2,com3,com4}
int digit[4] = {   8  ,   4  ,   2  ,   1  };
// 位元掃瞄     {"1000","0100","0010","0001"};

void setup() {
  // 初始化七段顯示器a~g、dp接腳
  for(int i=0; i<=7; i++)
  {
    pinMode(seg[i], OUTPUT);
    digitalWrite(seg[i],0);   // 全滅
  }
  // 初始化七段顯示器com1~com4接腳
  for(int i=0; i<=3; i++)
  {
    pinMode(com[i], OUTPUT);
    digitalWrite(com[i],0);   // 全滅    
  }
}

void loop() {
  showdata(9); // 千位數
  // --------------- 掃瞄碼 ---------------
  digitalWrite(com[0],bitRead(digit[0],3));
  digitalWrite(com[1],bitRead(digit[0],2));
  digitalWrite(com[2],bitRead(digit[0],1));
  digitalWrite(com[3],bitRead(digit[0],0));
  // --------------------------------------
  delay(1);

  showdata(8); // 百位數
  // --------------- 掃瞄碼 ---------------
  digitalWrite(com[0],bitRead(digit[1],3));
  digitalWrite(com[1],bitRead(digit[1],2));
  digitalWrite(com[2],bitRead(digit[1],1));
  digitalWrite(com[3],bitRead(digit[1],0));
  // --------------------------------------
  delay(1);

  showdata(7); // 十位數
  // --------------- 掃瞄碼 ---------------
  digitalWrite(com[0],bitRead(digit[2],3));
  digitalWrite(com[1],bitRead(digit[2],2));
  digitalWrite(com[2],bitRead(digit[2],1));
  digitalWrite(com[3],bitRead(digit[2],0));
  // --------------------------------------
  delay(1);

  showdata(6); // 個位數
  // --------------- 掃瞄碼 ---------------
  digitalWrite(com[0],bitRead(digit[3],3));
  digitalWrite(com[1],bitRead(digit[3],2));
  digitalWrite(com[2],bitRead(digit[3],1));
  digitalWrite(com[3],bitRead(digit[3],0));
  // --------------------------------------
  delay(1);
}

void showdata(int x)
{
  for(int i=0; i<7; i++)
  digitalWrite(seg[i],bitRead(data[x],i));
}

可以將每個位元的掃瞄碼改成scan()副程式:

int seg[8] = {15, 16, 17, 18, 19, 21, 22, 23};
// 對應的接腳 { a,  b,  c,  d,  e,  f,  g, dp}
int data[]= {0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x27,0x7F,0x67,0x00};
// 顯示的數字 { 0  ,  1 ,  2 ,  3 ,  4 ,  5 ,  6 ,  7 ,  8 ,  9 ,全滅}
int com[4] = {25, 26, 27, 14};
// 對應的接腳 {com1,com2,com3,com4}
int digit[4] = {   8  ,   4  ,   2  ,   1  };
// 位元掃瞄     {"1000","0100","0010","0001"};

void setup() {
  // 初始化七段顯示器a~g、dp接腳
  for(int i=0; i<=7; i++)
  {
    pinMode(seg[i], OUTPUT);
    digitalWrite(seg[i],0);   // 全滅
  }
  // 初始化七段顯示器com1~com4接腳
  for(int i=0; i<=3; i++)
  {
    pinMode(com[i], OUTPUT);
    digitalWrite(com[i],0);   // 全滅    
  }
}

void loop() {
  showdata(9); // 千位數
  scan(0);     // 掃瞄碼
  delay(1);

  showdata(8); // 百位數
  scan(1);     // 掃瞄碼
  delay(1);

  showdata(7); // 十位數
  scan(2);     // 掃瞄碼
  delay(1);

  showdata(6); // 個位數
  scan(3);     // 掃瞄碼
  delay(1);
}

void showdata(int x)
{
  for(int i=0; i<7; i++)
  digitalWrite(seg[i],bitRead(data[x],i));
}

void scan(int x)
{
  for(int i=0; i<4; i++)    
  digitalWrite(com[i],bitRead(digit[x],3-i));
}

若定義num[ ]陣列用來存放每個位元要顯示的數值,可得到下列結果:

int seg[8] = {15, 16, 17, 18, 19, 21, 22, 23};
// 對應的接腳 { a,  b,  c,  d,  e,  f,  g, dp}
int data[]= {0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x27,0x7F,0x67,0x00};
// 顯示的數字 { 0  ,  1 ,  2 ,  3 ,  4 ,  5 ,  6 ,  7 ,  8 ,  9 ,全滅}
int com[4] = {25, 26, 27, 14};
// 對應的接腳 {com1,com2,com3,com4}
int digit[4] = {   8  ,   4  ,   2  ,   1  };
// 位元掃瞄     {"1000","0100","0010","0001"};
int num[4] = {0, 0, 0, 0};
// 各位元數值 {千,百,十,個}

void setup() {
  // 初始化七段顯示器a~g、dp接腳
  for(int i=0; i<=7; i++)
  {
    pinMode(seg[i], OUTPUT);
    digitalWrite(seg[i],0);   // 全滅
  }
  // 初始化七段顯示器com1~com4接腳
  for(int i=0; i<=3; i++)
  {
    pinMode(com[i], OUTPUT);
    digitalWrite(com[i],0);   // 全滅    
  }
}

void loop() {
  num[0] = 9;
  num[1] = 8;
  num[2] = 7;
  num[3] = 6;

  showdata(num[0]); // 千位數
  scan(0);
  delay(1);

  showdata(num[1]); // 百位數
  scan(1);
  delay(1);

  showdata(num[2]); // 十位數
  scan(2);
  delay(1);

  showdata(num[3]); // 個位數
  scan(3);
  delay(1);
}

void showdata(int x)
{
  for(int i=0; i<7; i++)
  digitalWrite(seg[i],bitRead(data[x],i));
}

void scan(int x){
  for(int i=0; i<4; i++)    
  digitalWrite(com[i],bitRead(digit[x],3-i));
}

以後要顯示4個位元的數字,可直接指定num[ ]陣列的內容,並呼叫showNum()副程式即可。

int seg[8] = {15, 16, 17, 18, 19, 21, 22, 23};
// 對應的接腳 { a,  b,  c,  d,  e,  f,  g, dp}
int data[]= {0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x27,0x7F,0x67,0x00};
// 顯示的數字 { 0  ,  1 ,  2 ,  3 ,  4 ,  5 ,  6 ,  7 ,  8 ,  9 ,全滅}
int com[4] = {25, 26, 27, 14};
// 對應的接腳 {com1,com2,com3,com4}
int digit[4] = {   8  ,   4  ,   2  ,   1  };
// 位元掃瞄     {"1000","0100","0010","0001"};
int num[4] = {0, 0, 0, 0};
// 各位元數值 {千,百,十,個}

void setup() {
  // 初始化七段顯示器a~g、dp接腳
  for(int i=0; i<=7; i++)
  {
    pinMode(seg[i], OUTPUT);
    digitalWrite(seg[i],0);   // 全滅
  }
  // 初始化七段顯示器com1~com4接腳
  for(int i=0; i<=3; i++)
  {
    pinMode(com[i], OUTPUT);
    digitalWrite(com[i],0);   // 全滅    
  }
}

void loop() {
  num[0] = 9;   // 千位
  num[1] = 8;   // 百位
  num[2] = 7;   // 十位
  num[3] = 6;   // 個位 
  showNum();
}

void showdata(int x)
{
  for(int i=0; i<7; i++)
  digitalWrite(seg[i],bitRead(data[x],i));
}

void scan(int x){
  for(int i=0; i<4; i++)    
  digitalWrite(com[i],bitRead(digit[x],3-i));
}

void showNum()
{
  for(int i=0; i<4; i++)
  {
    showdata(num[i]); 
    scan(i);
    delay(1);  
  }
}

若要將一個數值轉換到各別位元儲存於陣列,可參考下列轉換:

  count = 2468;
  num[0] = count / 1000 % 10;   // 千位 2468 / 1000 = 2, 2 % 10 = 2
  num[1] = count / 100 % 10;    // 百位 2468 / 100 = 24, 24 % 10 = 4
  num[2] = count / 10 % 10;     // 十位 2468 / 10 = 246, 246 % 10 = 6
  num[3] = count % 10;          // 個位 2468 % 10 = 8

註: / 代表除法運算(預設為整數運算),% 代表取餘數運算

作業練習:

  1. 開機後,4位元七段顯示器顯示0000。
  2. 每按一下按鈕開關,可開始或停止計數(每0.001秒加1,在0000~9999之間循環)。
  3. 長按按鈕開關,計數器重置為0000。
  4. 七段顯示器的狀態必須同步顯示在監看視窗上。
  5. 請完成實體接線。