单片机三个引脚控制16路流水灯
我们先来看下最终的效果
我们先用单片机按照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、我们绝大部分时候都在造“轮子“,殊不知更优秀的“轮子”已经造好了;知晓“轮子”的由来,然后造出更优秀的“轮子”给自己用也是单片机学习路上的一项重要技能。