《 bitRead() 使用說明 》
bitRead(x, n)
x :要讀取的數字,如果輸入是10進位或16進位,會自動轉成2進位
n :要讀取的字元,0 代表最右邊的字元
void setup() {
// 例:七段顯示器欲顯示2,控制碼為 0101 1011(2進制碼) –> 0x5B(16進制碼)
// (dp) g f e d c b a
// x = 0 1 0 1 1 0 1 1 (0x5B)
int x = 0x5B;
Serial.begin(9600);
Serial.println(bitRead (x,0)); // bitRead (x,0) = 1 —> a
Serial.println(bitRead (x,1)); // bitRead (x,1) = 1 —> b
Serial.println(bitRead (x,2)); // bitRead (x,2) = 0 —> c
Serial.println(bitRead (x,3)); // bitRead (x,3) = 1 —> d
Serial.println(bitRead (x,4)); // bitRead (x,4) = 1 —> e
Serial.println(bitRead (x,5)); // bitRead (x,5) = 0 —> f
Serial.println(bitRead (x,6)); // bitRead (x,6) = 1 —> g
Serial.println(bitRead (x,7)); // bitRead (x,7) = 0 —> dp
}
void loop() {
}
原基本控制的程式碼:
int seg[8] = {15, 16, 17, 18, 19, 21, 22, 23};
// 對應的接腳 { a, b, c, d, e, f, g, dp}
void setup() {
for(int i=0; i<=7; i++)
{
pinMode(seg[i], OUTPUT);
}
}
void loop() {
// (dp)gfedcba
// 顯示0: 0011 1111(2進制碼) --> 0x3F(16進制碼)
digitalWrite(seg[0],1); // a
digitalWrite(seg[1],1); // b
digitalWrite(seg[2],1); // c
digitalWrite(seg[3],1); // d
digitalWrite(seg[4],1); // e
digitalWrite(seg[5],1); // f
digitalWrite(seg[6],0); // g
digitalWrite(seg[7],0); // dp
delay(1000);
// 顯示1: 0000 0110(2進制碼) --> 0x06(16進制碼)
digitalWrite(seg[0],0); // a
digitalWrite(seg[1],1); // b
digitalWrite(seg[2],1); // c
digitalWrite(seg[3],0); // d
digitalWrite(seg[4],0); // e
digitalWrite(seg[5],0); // f
digitalWrite(seg[6],0); // g
digitalWrite(seg[7],0); // dp
delay(1000);
}
可使用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 ,全滅}
void setup() {
// 初始化七段顯示器
for(int i=0; i<=7; i++)
{
pinMode(seg[i], OUTPUT);
}
}
void loop() {
// (dp)gfedcba
// 顯示0: 0011 1111(2進制碼) --> 0x3F(16進制碼)
digitalWrite(seg[0],bitRead(data[0],0)); // a
digitalWrite(seg[1],bitRead(data[0],1)); // b
digitalWrite(seg[2],bitRead(data[0],2)); // c
digitalWrite(seg[3],bitRead(data[0],3)); // d
digitalWrite(seg[4],bitRead(data[0],4)); // e
digitalWrite(seg[5],bitRead(data[0],5)); // f
digitalWrite(seg[6],bitRead(data[0],6)); // g
delay(1000);
// 顯示1: 0000 0110(2進制碼) --> 0x06(16進制碼)
digitalWrite(seg[0],bitRead(data[1],0)); // a
digitalWrite(seg[1],bitRead(data[1],1)); // b
digitalWrite(seg[2],bitRead(data[1],2)); // c
digitalWrite(seg[3],bitRead(data[1],3)); // d
digitalWrite(seg[4],bitRead(data[1],4)); // e
digitalWrite(seg[5],bitRead(data[1],5)); // f
digitalWrite(seg[6],bitRead(data[1],6)); // g
delay(1000);
}
進一步可將要顯示的數字改寫成副程式:
void showdata(int x)
{
for(int i=0; i<7; i++)
digitalWrite(seg[i],bitRead(data[x],i));
}
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 ,全滅}
void setup() {
// 初始化七段顯示器
for(int i=0; i<=7; i++)
{
pinMode(seg[i], OUTPUT);
}
}
void loop() {
showdata(0); // 顯示0
delay(1000);
showdata(1); // 顯示1
delay(1000);
}
void showdata(int x)
{
for(int i=0; i<7; i++)
digitalWrite(seg[i],bitRead(data[x],i));
}
作業練習:
- 開機後,七段顯示器顯示 8 和 dp (好壞測試),1秒後顯示0。
- 每按一下按鈕開關,可開始或停止計數(每秒加1,在0~9之間循環)。
- 長按按鈕開關,計數器歸 0。
- 七段顯示器的狀態必須同步顯示在監看視窗上。
- 在Wokwi網站上進行模擬,並完成實體接線。
參考範例:
//---------------------------------------------------------------------------
const int pb = 34; // 按鈕開關接腳
bool lastButtonState = HIGH; // 按鈕開關前一次的狀態
unsigned long lastDebounceTime = 0; // 按鈕開關前一次狀態改變時的millis()時間
int debounceDelay = 150; // 防彈跳預設的延遲時間
//---------------------------------------------------------------------------
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 ,全滅}
//---------------------------------------------------------------------------
bool startCount = 0; // (0:停止,1:開始)
int count = 0; // 計數器,初值為0
//---------------------------------------------------------------------------
unsigned long previousMillis = 0; // 前一次的millis()時間
const long interval = 1000; // 預設計時的時間
//---------------------------------------------------------------------------
void setup() {
//--------------------------------------------------
Serial.begin(9600); // 啟用串列埠監看視窗
//--------------------------------------------------
pinMode(pb, INPUT); // 初始化按鈕開關
//--------------------------------------------------
for(int i=0; i<=7; i++) // 初始化七段顯示器
{
pinMode(seg[i], OUTPUT);
}
//--------------------------------------------------
}
void loop() {
// ---------------------------------------------------------------------------------------------------------------
unsigned long currentTime = millis(); // 當前的millis()時間
bool buttonState = digitalRead(pb); // 當前的按鈕開關狀態:未按下(HIGH),按下(LOW)
// 若按鈕開關狀態發生變化,且超過防彈跳預設的延遲時間
if ((buttonState != lastButtonState) && (currentTime - lastDebounceTime) > debounceDelay)
{
// --------------------------------------------------------------------------------------
if (lastButtonState == HIGH && buttonState == LOW) // 若按鈕從未按下(HIGH)到按下(LOW)
{
// 按鈕按下時,想做的事
startCount = !startCount; // 取反相
if(startCount==0)
{
Serial.println("Stop."); // 印出停止狀態
}
else
{
Serial.println("Start count..."); // 印出開始計數狀態
}
}
else if (lastButtonState == LOW && buttonState == HIGH) // 若按鈕從按下(LOW)到未按下(HIGH)
{
// 按鈕放開時,想做的事
}
lastButtonState = buttonState; // 更新按鈕狀態
// --------------------------------------------------------------------------------------
lastDebounceTime = currentTime; // 更新前一次狀態改變時的millis()時間
}
// ---------------------------------------------------------------------------------------------------------------
// ---------------------------------------------------------------------------------------------------------------
unsigned long currentMillis = millis(); // 當前的millis()時間
if (currentMillis - previousMillis >= interval) // 若達到預設計時的時間
{
//---------------------------------------------------------------------
// 每經過一個interval的時間,要做的事
//---------------------------------------------------------------------
if(startCount == 1)
{
count = count + 1;
Serial.println(count);
}
//---------------------------------------------------------------------
previousMillis = currentMillis; // 更新前一次的millis()時間
}
// ---------------------------------------------------------------------------------------------------------------
}
void showdata(int x)
{
for(int i=0; i<7; i++)
digitalWrite(seg[i],bitRead(data[x],i));
}