欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

单片机三个引脚控制16路流水灯

程序员文章站 2022-06-10 14:23:27
我们先来看下最终的效果 我们先用单片机按照74HC595手动分解的例子,来实现我们想要的结果。 首先,我们让16个LED灯交叉亮起来 代码部分: int STCP_Pin = 4; int SHCP_Pin = 6; int DS_Pin = 5; void setup () { pinMode(S ......

我们先来看下最终的效果
单片机三个引脚控制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);    
  }
}

运行效果
单片机三个引脚控制16路流水灯
然后我们再把代码简化一下,使其看起来更简洁,实用

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灯亮的效果
单片机三个引脚控制16路流水灯

然后我们连贯起来搞个流水的灯玩玩

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); 
}

最终的流水灯实验效果
单片机三个引脚控制16路流水灯
单片机三个引脚控制16路流水灯
当然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的效果
单片机三个引脚控制16路流水灯
单片机三个引脚控制16路流水灯

总结:

1、复杂的功能,深入分解后背后的原理其实还是挺简单的;

2、我们绝大部分时候都在造“*“,殊不知更优秀的“*”已经造好了;知晓“*”的由来,然后造出更优秀的“*”给自己用也是单片机学习路上的一项重要技能。