开篇先说一句废话····
本旺名字叫萨摩耶,,Please 叫我旺财,,,哈哈,招财进宝嘛!
74HC595
8位串行输入/输出或者并行输出移位寄存器,具有高阻关断状态
- 8位串行输入
- 8位串行或者并行输出
- 存储状态寄存器
这个芯片有什么用?怎么用?
说直白点就是,这玩意可以把你要发送的一个8位字节数据给你一位一位发出去,比如你要控制八个LED的亮灭,只需要将它们共阴极连接,将八个阳极接在这个芯片的并行输出引脚上,控制这个发送数据,即可点亮对应的LED,发现了吧,这个功能和P2口(本单片机P2口连接八个LED)的功能一样,也可以说就是I/O口的拓展。
它有四个比较重要的引脚, 一个是移位寄存器时钟输入CRCLK;一个是存储寄存器时钟输入RCLK;一个是输入有效OE(低电平有效);一个是串行输入SER。 其他引脚的接法或者用法可以参考74HC595芯片的数据手册。
这是引脚说明,原理图如下:
如上图,要想74HC595可以使用,对应单片机就是8X8点阵可以点亮,OE是能引脚必须接地(低电平有效),所以操作这个之前必须先把单片机上的8X8点阵附近有个接线帽连接正确。
阅读数据手册,可以读出,先通过修改移位寄存器时钟输入SRCLK将要发的八字节发送到串行输入SER,此过程需要循环八次(一位一位的发),最后在给存储寄存器RCLK上升沿把串行输入SER的数据输出出去
操作步骤:
此过程循环八次
- 拉低SRCLK
- 把数据的最高位发送给SER
- 数据左移一位(为次高位发送做准备)
- 延时一小会(两个_nop_()即可)
- 拉高SRCLK
最后只需要:
- 拉低RCLK
- 延时一小会(两个_nop_()即可)
- 拉高RCLK(上升沿输出数据)
注意的就是因为要把八字节数据发送出去,此函数需要一个形参–>数据
代码如下:
void SendByte(u8 date){
u8 i,temp;
temp=date;
for(i=0;i<8;i++){
SRCLK=0; //移位寄存器时钟输入
SER=temp>>7;//串行输入
temp<<=1;
_nop_();
_nop_();
SRCLK=1;
}
RCLK=0; //存储寄存器时钟输入
_nop_();
_nop_();
RCLK=1;
}
8X8点阵
8X8点阵就是把LED组合起来,想要点亮某一个LED点亮,只需要它的正极拉高,负极拉低,只是这次通过一个P0口和这个74HC595来控制而已,原理其实是简单的。
原理图如下:
比如想要让第一行第一列LED亮,就需要Dph为1(高电平),P0^7为0(低电平)。
对于74HC595而言,置一点亮 ,(Dpa–>Dph)想要让哪一行亮,让对应的DpX置一即可;对于P0口而言,清零点亮 ,(P0^0–>P0 ^7),想要让那一列亮,让对应的P0 ^X置零即可。
- 先声明两个数组来存放8X8点阵行(74HC595)数据和列(P0口)数据
- 循环8次(行和列对应输出)
循环体:- 将列数组数据赋给P0口
- 通过发送字节函数将行数组数据发送出去
- 延时1ms左右
- 消影(发送字节函数发送0x00,74HC595清零熄灭)
8X8点阵显示数字‘0’
代码如下:
#include "reg51.h" //52.h中RCLK重定义
#include "intrins.h"
typedef unsigned char u8;
typedef unsigned int u16;
sbit SRCLK=P3^6;
sbit RCLK=P3^5;
sbit SER=P3^4;
//这个可以画个图,计算出这两个数组
u8 hang[]={0x00,0x00,0x3c,0x42,0x42,0x42,0x3c,0x00}; //控制行的亮灭(置一亮)
u8 lie[]={0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe}; //控制列的亮灭(清零亮)
void Delay(u16 i) //11.0592MHz 1ms
{
while(i--){
unsigned char i, j;
_nop_();
i = 2;
j = 199;
do
{
while (--j);
} while (--i);
}
}
//发送字节函数
void SendByte(u8 date){
u8 i,temp;
temp=date;
for(i=0;i<8;i++){
SRCLK=0;
SER=temp>>7;
temp<<=1;
_nop_();
_nop_();
SRCLK=1;
}
RCLK=0;
_nop_();
_nop_();
RCLK=1;
}
void main()
{
u8 i;
while(1){
for(i=0;i<8;i++){
P0=lie[i];
SendByte(hang[i]);
Delay(1);
SendByte(0x00);
}
}
}
- 注意
其实这个8X8点阵动态扫描和数码管动态显示差不多,可以借鉴一番。