首先要了解74HC595这个芯片:74HC595是一个8位串行输入、平行输出的位移缓存器:平行输出为三态输出。
这个芯片各个引脚的功能及工作原理如下:
Q0--Q7: 八位并行输出端,可以直接控制数码管的8个段。(用于接LED灯)
Q7': 级联输出端。将它接下一个595的DS端。(可以实现级联)
DS: 串行数据输入端,级联的话接上一级的Q7'。
74595的控制端说明:
/MR(10脚): 低电平时将移位寄存器的数据清零。通常我将它接Vcc。
SH_CP(11脚):上升沿时数据寄存器的数据移位。Q0->Q1->Q2-->Q3-->...-->Q7;下降沿移位寄存器数据不变。(脉冲宽度:5V时,大于几十纳秒就行了。我通常都选微秒级)
ST_CP(12脚):上升沿时移位寄存器的数据进入数据存储寄存器,下降沿时存储寄存器数据不变。通常我将ST_CP置为低电平,当移位结束后,在ST_CP端产生一个正脉冲(5V时,大于几十纳秒就行了。我通常都选微秒级),更新显示数据。
/OE(13脚): 高电平时禁止输出(高阻态)。如果单片机的引脚不紧张,用一个引脚控制它,可以方便地产生闪烁和熄灭效果。比通过数据端移位控制要省时省力。(所以实现流水灯时应接入高电平,用于接地)
要看懂该芯片的时序图。高处为高电平,低处为低电平。便于理解各个引脚的作用。
我所实现流水灯的代码为:
#include<reg51.h> #include<intrins.h> int i; sbit SRCLK=P3^6;对应于图中的ST_CP引脚(注:芯片的引脚名称经常变化,但是功能是不变的) sbit RCLK=P3^5; //对应于MR (这三条语句是他们连在单片机的位置) sbit SER=P3^4; //对应于SH_CP引脚 void Hc595SendByte(unsigned char dat) // 函数名:Hc595SendByte 函数功能:向74HC595发送一个字节的数据。输入输出:无 { unsigned char a; SRCLK=0; // 将两个引脚置于低电平 RCLK=0; for(a=0;a<8;a++) // 发送8位数 { SER=dat>>7; //通过数据的移位实现流水。从最高位开始发送数据。右移七位 dat<<=1; // SRCLK=1; _nop_(); ////延时函数,系统自带 _nop_(); SRCLK=0; // 发送时序 RCLK=1; _nop_(); _nop_(); RCLK=0; } } void main() { unsigned char ledNum; ledNum=0xfe; // 灯全灭 while(1) { Hc595SendByte(ledNum); ledNum=_crol_(ledNum,1); for(i=30000;i>0;i--); } }
工作原理:
74HC595为串行输入,8位并行输出.&0x80 的用途就是将最高位取出来,然后SH_CP来一个上升沿,写入到串行。DS=(a<<i)&0x80 的用途就是,依次取出 a 的每一位,并输入到串行。最后,ST_CP 来一个上升沿,数据写到寄存器。
for(i=0;i<8;i++)
{
DS=(a<<i) & 0x80;
}
a = 0000 0110 ;
当 i = 0 , a << i 就是 00000110 (a<<i) & 0x80 等于 0
当 i = 1 , a << i 就是 00001100 0
当 i = 2 , a << i 就是 00011000 0
当 i = 3 , a << i 就是 00110000 0
当 i = 4 , a << i 就是 01100000 0
当 i = 5 , a << i 就是 11000000 1
当 i = 6 , a << i 就是 10000000 1
当 i = 7 , a << i 就是 00000000 (a<<i) & 0x80 等于 0
就是依次取出了 a = 0000 0110 它的值(该数据取值0x70的时候也可以实现这一功能)
{
DS=(a<<i) & 0x80;
}
a = 0000 0110 ;
当 i = 0 , a << i 就是 00000110 (a<<i) & 0x80 等于 0
当 i = 1 , a << i 就是 00001100 0
当 i = 2 , a << i 就是 00011000 0
当 i = 3 , a << i 就是 00110000 0
当 i = 4 , a << i 就是 01100000 0
当 i = 5 , a << i 就是 11000000 1
当 i = 6 , a << i 就是 10000000 1
当 i = 7 , a << i 就是 00000000 (a<<i) & 0x80 等于 0
就是依次取出了 a = 0000 0110 它的值(该数据取值0x70的时候也可以实现这一功能)
电路连接图如下: