首先介绍一下74HC595工作原理
不同厂家不同的型号的74HC595,它的符号命名会有所不同,但引脚规则是统一适用的,下面按我自己理解总结一下。
如下图:
13引脚:OE串行数据输入端使能端,低电平有效,接低电平/跳线帽接地。
11引脚:上升沿到达时(SRCLK由0变1),从最高位开始依次输出8位数据。
12引脚:RCLK为输出存储器锁存时钟线,只需记住当RCLK由0到1,即上升沿到达(产生一个正脉冲)时,进来的8位数据分别从1~7引脚输出。实现串行信号----->并行信号。
14引脚:相当于搬运工,串行数据输入;
10引脚:主复位,低电平有效,实验时将它接高电平。
脑字还是懵懵的?似懂非懂?那换一种通俗点的解释:
就像做冰糖葫芦,假设1串冰糖葫芦有8个枣(命名为0~7号),当11引脚上升沿到达时,拿出0号枣准备往棍子最底端串,即串行输入。
当12引脚上升沿到达时,0号枣被送往棍子下方第0个位置,14引脚代表将枣送入的那股推力(手),即搬运工的作用。
当8个枣(实验中指8位二进制数中的0和1)全部被串行输入到木棍上时。每个枣被依次串入的间隔时间就是上升沿之间的延迟,用两个_nop_();函数表示
等8个枣全部被串入时,即做完一串冰糖葫芦,传输完成,吃冰糖葫芦当然是横着吃(串转并)(有谁竖着吃…跳过此步>_>),最后一个吃到的就是第0号串入的枣,即串入的0–7号枣,对应"吃"/输出的7----0号枣。
这下应该清楚了74HC595“串入” “并出”的概念吧
例如:点亮左上角第一个二极管:DPh高电平,P0^7低电平
#include "reg51.h" //注意这里使用“reg52.h"可能会出现重复定义错误,因为52.h中已定义过RCLK
#include
typedef unsigned int u16;
typedef unsigned char u8;
sbit SRCLK=P3^6;
sbit RCLK=P3^5;
sbit SER=P3^4;
u8 ledduan[]={0x38,0x44,0x42,0x21,0x42,0x44,0x38,0x00};//每一列的7~0二极管状态
u8 ledwei[]={0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe};//第1列到第8列位选
void delay(u16 i)
{
while(i--);
}
void Hc595SendByte(u8 dat)
{
u8 a;
SRCLK=0;
RCLK=0;
for(a=0;a<8;a++) //重复发送ledduan[i]中的段码,使每一列对应二极管亮
{
SER=dat>>7; //从最高位开始发送
dat<<=1; //左移依次左移1位,发送次高位,
SRCLK=1; //0-1,上升沿到达,发送一位数据(段码中的1位二进制值)
_nop_();
_nop_(); // 内置延时函数
SRCLK=0; //初始化SRCLK,重回低电平,为下一个上升沿输入做准备
}
RCLK=1; //RCLK从0到1,上升沿到达,输出前面接收的段码数据
_nop_();
_nop_();
RCLK=0; //初始化RCLK,重回低电平,为下一个上升沿输出做准备
}
void main()
{
u8 i;
while(1)
{
P0=0x7f;
for(i=0;i<8;i++)
{
P0=ledwei[i]; //位选
Hc595SendByte(ledduan[i]); //发送段选数据
delay(100); //时间足够短,视觉暂留
Hc595SendByte(0x00); //消//消隐,将dat置回初值隐
}
}
}
#include "reg51.h" //注意这里使用“reg52.h"可能会出现重复定义错误,因为52.h中已定义过RCLK
#include
typedef unsigned int u16;
typedef unsigned char u8;
sbit SRCLK=P3^6;
sbit RCLK=P3^5;
sbit SER=P3^4;
u8 ledduan[]={0x99,0x5a,0x3c,0xff,0xff,0x3c,0x5a,0x99};//每一列的二极管状态
u8 ledwei[]={0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe};//第1列到第8列
void delay(u16 i)
{
while(i--);
}
void Hc595SendByte(u8 dat)
{
u8 a;
SRCLK=0;
RCLK=0;
for(a=0;a<8;a++)//重复发送ledduan[i]中的段码,使每一列对应二极管亮
{
SER=dat>>7; //从最高位开始发送
dat<<=1; //左移依次左移1位,发送次高位,
SRCLK=1; //0-1,上升沿到达,发送一位数据(段码中的1位二进制值)
_nop_();
_nop_(); // 内置延时函数
SRCLK=0; //初始化SRCLK,重回低电平,为下一个上升沿输入做准备
}
RCLK=1; //RCLK从0到1,上升沿到达,输出前面接收的段码数据
_nop_();
_nop_();
RCLK=0; //初始化RCLK,重回低电平,为下一个上升沿输出做准备
}
void main()
{
u8 i;
while(1)
{
for(i=0;i<8;i++)
{
P0=ledwei[i];
Hc595SendByte(ledduan[i]);
delay(200); //时间足够短,则图像看起来就是一个完整的图案
Hc595SendByte(0x00);//消隐,将dat置回初值
}
}
}
若发现错误,欢迎指出,共同进步,谢谢!