/* 作業名稱:HW02_SPI_74595_2x7段_Button
使用按鈕配合外部中斷,按下按鈕可以改變7段顯示器顯示的數字上/下數的方向
使用IC 74595配合UNO的SPI介面以及函式庫, 完成上次作業一樣的結果
學號:A1252003 姓名:周育均
*/
#include <SPI.h>
const byte seg7_digit[10]={
//abcdefgh
B11111100, //數字0
B01100000, //數字1
B11011010, //數字2
B11110010, //數字3
B01100110, //數字4
B10110110, //數字5
B10111110, //數字6
B11100100, //數字7
B11111110, //數字8
B11110110}; //數字9
#define Button 2 //指定按鈕開關的接腳,接到UNO的D2
#define LED1_pin 8 //指定LED1為個位數,接到UNO的D8
#define LED2_pin 9 //指定LED2為十位數,接到UNO的D9
#define SS 10 //指定74HC595的pin 12 STCP,接到UNO的D10
volatile int cnt=0; //使用在ISR的計數值變數
volatile unsigned long now, pre=0; //使用在ISR的時間變數
int num=0; //設定變數num為LED顯示的數字
boolean flag=1; //設定變數flag為判斷數字上/下數的方向
void setup()
{
pinMode(Button, INPUT_PULLUP); //設定Button接腳,並啟用內建的上拉電阻
pinMode(SS, OUTPUT); //sets the digital pin 10 as output
pinMode(LED2_pin, OUTPUT); //sets the digital pin 9 as output
pinMode(LED1_pin, OUTPUT); //sets the digital pin 8 as output
digitalWrite(LED2_pin, HIGH); //sets the digital pin 9 HIGH, LED2十位數字OFF
digitalWrite(LED1_pin, HIGH); //sets the digital pin 8 HIGH, LED1個位數字OFF
SPI.begin(); //Initializes the SPI bus by setting SCK, MOSI, and SS to outputs, pulling SCK and MOSI low, and SS high.
//按下按鈕(pin 2),執行外部中斷,下緣觸發
attachInterrupt(digitalPinToInterrupt(2),my_ISR,FALLING);
}
void loop()
{
if(flag==1) //利用flag判斷數字上/下數的方向
{ //若flag等於1就往上計數
num++; //num等於num+1
num=num%100; //num等於num除以100的餘數
}
else //flag不等於1就往下計數
{
if(num>0) //判斷數字是否為正/負數
{
num--; //num等於num-1
}
else //若為負數就跳到99往下計數
{
num=99; //若數到0就跳到99往下計數
}
}
int n2, n1;
n2=num/10; //十位數字
n1=num%10; //個位數字
//修正後的版本, 比較不會有殘影
for(int d=0; d<5; d++) //重覆執行次數作為數字計數的延遲時間,比較不會有殘影
{
digitalWrite(LED1_pin, HIGH); //LED1個位數字OFF
digitalWrite(SS, LOW); //當SS(STCP)=0時,放入設定值
SPI.transfer(seg7_digit[n2]); //更新下一位數字的8bit狀態,n2為十位數字
digitalWrite(SS, HIGH); //當SS(STCP)=1時,設定值就會被推入storage register中
digitalWrite(LED2_pin, LOW); //LED2十位數字ON
delay(50);
digitalWrite(LED2_pin, HIGH); //LED2十位數字OFF
digitalWrite(SS, LOW); //LOW to HIGH Transition
SPI.transfer(seg7_digit[n1]); //更新下一位數字的8bit狀態,n1為個位數字
digitalWrite(SS, HIGH);
digitalWrite(LED1_pin, LOW); //LED1個位數字ON
delay(50);
}
}
void my_ISR() //按下按鈕執行外部中斷
{
//now = millis(); //取得現在的時間
//if ((now-pre)>200) //去除按鍵彈跳,大於200ms
{
flag=!flag;
}
//pre = now;
}
/*
void setup()
{
pinMode(SS, OUTPUT);
pinMode(d1, OUTPUT);
pinMode(d0, OUTPUT);
digitalWrite(d1, HIGH);
digitalWrite(d0, HIGH);
SPI.begin();
}
void loop()
{
digitalWrite(d0, HIGH); //d0個位數字OFF
digitalWrite(SS, LOW);
SPI.transfer(seg7_digit[1]); //更新下一位數字的8bit狀態
digitalWrite(SS, HIGH);
digitalWrite(d1, LOW); //d1十位數字ON
delay(50);
digitalWrite(d1, HIGH); //d1 十位數字OFF
digitalWrite(SS, LOW);
SPI.transfer(seg7_digit[0]); //更新下一位數字的8bit狀態
digitalWrite(SS, HIGH);
digitalWrite(d0, LOW); //d0個位數字ON
delay(50);
}
*/