我們先來看下最終的效果
我們先用微控制器按照74HC595手動分解的例子,來實現我們想要的結果。
首先,我們讓16個LED燈交叉亮起來
程式碼部分:
int STCP_Pin = 4;
int SHCP_Pin = 6;
int DS_Pin = 5;
void setup ()
{
pinMode(STCP_Pin,OUTPUT);
pinMode(SHCP_Pin,OUTPUT);
pinMode(DS_Pin,OUTPUT);
}
// 我們先讓16個燈交叉亮
void loop()
{
while(1)
{
digitalWrite(STCP_Pin, LOW);
// 1
digitalWrite(SHCP_Pin, LOW);
digitalWrite(DS_Pin, LOW);
digitalWrite(SHCP_Pin, HIGH);
// 2
digitalWrite(SHCP_Pin, LOW);
digitalWrite(DS_Pin, HIGH);
digitalWrite(SHCP_Pin, HIGH);
// 3
digitalWrite(SHCP_Pin, LOW);
digitalWrite(DS_Pin, LOW);
digitalWrite(SHCP_Pin, HIGH);
// 4
digitalWrite(SHCP_Pin, LOW);
digitalWrite(DS_Pin, HIGH);
digitalWrite(SHCP_Pin, HIGH);
// 5
digitalWrite(SHCP_Pin, LOW);
digitalWrite(DS_Pin, LOW);
digitalWrite(SHCP_Pin, HIGH);
// 6
digitalWrite(SHCP_Pin, LOW);
digitalWrite(DS_Pin, HIGH);
digitalWrite(SHCP_Pin, HIGH);
// 7
digitalWrite(SHCP_Pin, LOW);
digitalWrite(DS_Pin, LOW);
digitalWrite(SHCP_Pin, HIGH);
// 8
digitalWrite(SHCP_Pin, LOW);
digitalWrite(DS_Pin, HIGH);
digitalWrite(SHCP_Pin, HIGH);
// 9
digitalWrite(SHCP_Pin, LOW);
digitalWrite(DS_Pin, LOW);
digitalWrite(SHCP_Pin, HIGH);
// 10
digitalWrite(SHCP_Pin, LOW);
digitalWrite(DS_Pin, HIGH);
digitalWrite(SHCP_Pin, HIGH);
// 11
digitalWrite(SHCP_Pin, LOW);
digitalWrite(DS_Pin, LOW);
digitalWrite(SHCP_Pin, HIGH);
// 12
digitalWrite(SHCP_Pin, LOW);
digitalWrite(DS_Pin, HIGH);
digitalWrite(SHCP_Pin, HIGH);
// 13
digitalWrite(SHCP_Pin, LOW);
digitalWrite(DS_Pin, LOW);
digitalWrite(SHCP_Pin, HIGH);
// 14
digitalWrite(SHCP_Pin, LOW);
digitalWrite(DS_Pin, HIGH);
digitalWrite(SHCP_Pin, HIGH);
// 15
digitalWrite(SHCP_Pin, LOW);
digitalWrite(DS_Pin, LOW);
digitalWrite(SHCP_Pin, HIGH);
// 16
digitalWrite(SHCP_Pin, LOW);
digitalWrite(DS_Pin, HIGH);
digitalWrite(SHCP_Pin, HIGH);
digitalWrite(STCP_Pin, HIGH);
}
}
執行效果
然後我們再把程式碼簡化一下,使其看起來更簡潔,實用
int STCP_Pin = 4;
int SHCP_Pin = 6;
int DS_Pin = 5;
void setup ()
{
pinMode(STCP_Pin,OUTPUT);
pinMode(SHCP_Pin,OUTPUT);
pinMode(DS_Pin,OUTPUT);
digitalWrite(STCP_Pin, LOW);
}
void loop()
{
unsigned char LED_Data;
while(1)
{
LED_Data = 0xAA;
// 第一個8位
digitalWrite(STCP_Pin, LOW);
for(int i=0; i<8; i++)
{
if(LED_Data&0x80){ digitalWrite(DS_Pin, HIGH);}
else { digitalWrite(DS_Pin, LOW); }
digitalWrite(SHCP_Pin, LOW);
digitalWrite(SHCP_Pin, HIGH);
LED_Data <<=1;
}
// 第二個8位
LED_Data = 0xAA;
for(int i=0; i<8; i++)
{
if(LED_Data&0x80){ digitalWrite(DS_Pin, HIGH);}
else { digitalWrite(DS_Pin, LOW); }
digitalWrite(SHCP_Pin, LOW);
digitalWrite(SHCP_Pin, HIGH);
LED_Data <<=1;
}
digitalWrite(STCP_Pin, HIGH);
delay(1000);
}
}
我們稍微改變下,讓LED燈按照我們的意思工作,封裝一下函式,然後讓中間四個燈亮起來
int STCP_Pin = 4;
int SHCP_Pin = 6;
int DS_Pin = 5;
void HC595_Write(unsigned char data1, unsigned char data2);
void setup ()
{
pinMode(STCP_Pin,OUTPUT);
pinMode(SHCP_Pin,OUTPUT);
pinMode(DS_Pin,OUTPUT);
}
void loop()
{
unsigned char LED_Data1 = 0x03;
unsigned char LED_Data2 = 0xC0;
while(1)
{
HC595_Write(LED_Data1, LED_Data2);
delay(1000);
}
}
void HC595_Write(unsigned char data1, unsigned char data2)
{
// 第一個8位
digitalWrite(STCP_Pin, LOW);
for(int i=0; i<8; i++)
{
if(data1&0x80){ digitalWrite(DS_Pin, HIGH);}
else { digitalWrite(DS_Pin, LOW); }
digitalWrite(SHCP_Pin, LOW);
digitalWrite(SHCP_Pin, HIGH);
data1 <<=1;
}
// 第二個8位
for(int i=0; i<8; i++)
{
if(data2&0x80){ digitalWrite(DS_Pin, HIGH);}
else { digitalWrite(DS_Pin, LOW); }
digitalWrite(SHCP_Pin, LOW);
digitalWrite(SHCP_Pin, HIGH);
data2 <<=1;
}
digitalWrite(STCP_Pin, HIGH);
}
中間四個LED燈亮的效果
然後我們連貫起來搞個流水的燈玩玩
int STCP_Pin = 4;
int SHCP_Pin = 6;
int DS_Pin = 5;
unsigned char LED_Data1[8] = { 0x01, 0x02, 0x04, 0x08,
0x10, 0x20, 0x40, 0x80};
unsigned char LED_Data2[8] = { 0x01, 0x02, 0x04, 0x08,
0x10, 0x20, 0x40, 0x80};
void HC595_Write(unsigned char data1, unsigned char data2);
void setup ()
{
pinMode(STCP_Pin,OUTPUT);
pinMode(SHCP_Pin,OUTPUT);
pinMode(DS_Pin,OUTPUT);
}
void loop()
{
while(1)
{
for(int i=0; i<8; i++)
{
HC595_Write(0x00, LED_Data1[i]);
delay(1000);
}
for(int i=0; i<8; i++)
{
HC595_Write( LED_Data2[i], 0x00);
delay(1000);
}
}
}
void HC595_Write(unsigned char data1, unsigned char data2)
{
// 第一個8位
digitalWrite(STCP_Pin, LOW);
for(int i=0; i<8; i++)
{
if(data1&0x80){ digitalWrite(DS_Pin, HIGH);}
else { digitalWrite(DS_Pin, LOW); }
digitalWrite(SHCP_Pin, LOW);
digitalWrite(SHCP_Pin, HIGH);
data1 <<=1;
}
// 第二個8位
for(int i=0; i<8; i++)
{
if(data2&0x80){ digitalWrite(DS_Pin, HIGH);}
else { digitalWrite(DS_Pin, LOW); }
digitalWrite(SHCP_Pin, LOW);
digitalWrite(SHCP_Pin, HIGH);
data2 <<=1;
}
digitalWrite(STCP_Pin, HIGH);
}
最終的流水燈實驗效果
當然arduino本身自帶了移位函式,同樣可以達到效果
int STCP_Pin = 4;
int SHCP_Pin = 6;
int DS_Pin = 5;
unsigned char LED_Data1[8] = { 0x01, 0x02, 0x04, 0x08,
0x10, 0x20, 0x40, 0x80};
unsigned char LED_Data2[8] = { 0x01, 0x02, 0x04, 0x08,
0x10, 0x20, 0x40, 0x80};
void setup ()
{
pinMode(STCP_Pin,OUTPUT);
pinMode(SHCP_Pin,OUTPUT);
pinMode(DS_Pin,OUTPUT);
}
void loop()
{
for(int a=0; a<8; a++)
{
digitalWrite(STCP_Pin,LOW);
shiftOut(DS_Pin,SHCP_Pin,MSBFIRST,LED_Data1[a]);
shiftOut(DS_Pin,SHCP_Pin,MSBFIRST,0x00);
digitalWrite(STCP_Pin,HIGH);
delay(500);
}
for(int a=0; a<8; a++)
{
digitalWrite(STCP_Pin,LOW);
shiftOut(DS_Pin,SHCP_Pin,MSBFIRST,0x00);
shiftOut(DS_Pin,SHCP_Pin,MSBFIRST,LED_Data2[a]);
digitalWrite(STCP_Pin,HIGH);
delay(500);
}
}
流水的延時500ms的效果
總結:
1、複雜的功能,深入分解後背後的原理其實還是挺簡單的;
2、我們絕大部分時候都在造“輪子“,殊不知更優秀的“輪子”已經造好了;知曉“輪子”的由來,然後造出更優秀的“輪子”給自己用也是微控制器學習路上的一項重要技能。