树莓派论坛
直播中

京五环以外

10年用户 3188经验值
擅长:EMC/EMI设计
私信 关注
[经验]

用8位移位寄存器74HC595扩展RPi的GPIO接口

本帖最后由 京五环以外 于 2014-9-12 09:52 编辑

      (本文来自转载)

       解决一下论坛发烧友们的老大难问题。

       树莓派的GPIO接口数目有限,驱动一个步进电机需要占用4个, 一个显示屏也要占4个, 传感器输入至少需要一个,多玩几个外设后接口就不够用了。如果接口可以复用就可以让树莓派驱动更多的外设了,本文讨论如何使用74HC595集成电路芯片来扩展树莓派的GPIO接口。


芯片介绍

       SN74HC595N是德州仪器公司生产的集成电路芯片,是一个8位串行输入变串行输出或并行输出移位寄存器,具有高阻关断,高电平和低电平三态输出。在IO扩充上,可以最多串联15片,也就是高达120个IO扩充。


      接口的常用命名方式有以下两种:


控制流程
       如果要在8个引脚输出01010101
       1、将Pin 14(DS, SER)置为高电平(1);
       2、将Pin 11 (SH_CP, SRCLK))做高低电平切换,形成一个脉冲信号,这个信号会将数据从移位寄存器C1移动到下一个移位寄存器C2,。。。
       3、接着将Pin 14设为低电平(0),再将Pin 11做1->0的脉冲变化,将数据继续往下移,依次类推直到8位都输入完成;
       4、将Pin 12(ST_CP, RCLK)做1->0的脉冲,将8位数据一次并行输出。

       如果要串联多片,由上一片的Pin 9接到下一片的Pin 14即可,这样输入16 bit后,再向Pin 12输入一个1->0的脉冲,16 bit会并行输出。
       如果要一次清除所有数据,将Pin 10设为低电平后,再向Pin 12输入一个1->0的脉冲即可;
下面我们使用一片74HC595来同时控制8个发光二极管的状态,只需要占用树莓派的3个GPIO;否则的话,则需要占用8个。如果需要同时控制16个发光二极管,则可以通过串联两个74HC595来实现。


所需材料
       74HC595  一个
       面包板  一个
       跳线  14根
       发光二极管  8个
       300欧姆电阻  8个


引脚连接
  • 596 Pin 14 -> Raspberry Pi GPIO4
  • 596 Pin 12 -> Raspberry Pi GPIO5
  • 596 Pin 11 -> Raspberry Pi GPIO6

代码
  • #include
  • #include
  • int SER   = 4;
  • int RCLK  = 5;
  • int SRCLK = 6;
  • unsigned char LED[8]={0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80};
  • void SIPO(unsigned char byte);
  • void pulse(int pin);
  • void init() {
  •     pinMode(SER, OUTPUT);
  •     pinMode(RCLK, OUTPUT);
  •     pinMode(SRCLK, OUTPUT);
  •     digitalWrite(SER, 0);
  •     digitalWrite(SRCLK, 0);
  •     digitalWrite(RCLK, 0);   
  • }
  • void delayMS(int x) {
  •   usleep(x * 1000);
  • }
  • int main (void)
  • {
  •     if (-1 == wiringPiSetup()) {
  •         printf("Setup wiringPi failed!");
  •         return 1;
  •     }   
  •     init();
  •     int i;
  •     while(1) {  
  •       for(i = 0; i < 8; i++)
  •       {
  •        SIPO(LED);
  •        pulse(RCLK);
  •        delayMS(50);
  •        printf(" i = %d", i);
  •       }
  •       printf("n");
  •       delayMS(500); // 500 ms
  •       
  •       for(i = 7; i >= 0; i--)
  •       {
  •        SIPO(LED);
  •        pulse(RCLK);
  •        delayMS(50);
  •        printf(" i = %d", i);
  •       }
  •       delayMS(500); // 500 ms
  •     }
  •     usleep(1000);
  •     digitalWrite(RCLK, 1);
  • }
  • void SIPO(unsigned char byte)
  • {
  •     int i;
  •     for (i=0;i<8;i++)
  •     {
  •         digitalWrite(SER,((byte & (0x80 >> i)) > 0));
  •         pulse(SRCLK);
  •     }
  • }
  • void pulse(int pin)
  • {
  •     digitalWrite(pin, 1);
  •     digitalWrite(pin, 0);
  • }


[color=rgb(51, 102, 153) !important]复制代码

       编译执行上面的代码后可以看到LED从左到有一次依次点亮后灭掉,再反向点亮一遍,循环执行,有点像钟摆的效果。
Pin 13还有高阻关断的第三态输出功能。
      


回帖(3)

王林广

2015-4-13 20:48:31
好,顶!!!!!!!
举报

kaicheng230

2015-11-10 15:40:32
这个好!!!!!!!!!1
举报

prophet000

2015-11-13 21:04:21
嗯,这方法单片机也用
举报

更多回帖

发帖
×
20
完善资料,
赚取积分