51单片机:IO口扩展,74HC595芯片,8*8点阵

我们在之前的学习中,都是通过IO口直接控制板子上的外围器件:LED、数码管等。如果想要连接更多的外围设备,就需要通过扩展IO来实现。(74HC595芯片

目录

I O扩展原理:

74HC595芯片:

LED 8*8点阵

1.静态点亮(静态数码管)

2.动态显示(动态数码管)

I O扩展原理:

SER、SRCLK、RCLK这3个IO输入口对应控制右侧8个输出端口(DPa--DPh).第九个QH’是串行输出端口。注意:这个QH’串行输出对应着左侧的SER串行输入端口,是74HC595芯片IO扩展的关键所在。这个串行输出端口会连接下一个74HC595芯片的串行输入端口(SER),这样又可以扩展8个输出端口。依次连接下去,就会拓展很多的输出端口。

74HC595芯片:

74HC595 是一个 8 位串行输入、并行输出的位移缓存器,其中并行输出为三态输出(即高电平、低电平和高阻抗)。

OE: 打开使能              带上横线的意思:输入低电平这个芯片才能工作

        所以要保证用跳线帽将OE(第二个)和地(第三个)短接。

SER(P34):串行数据输入管脚         

        数据从SER口排着队依次进入。

SRCLK(P36):移位寄存器的时钟输入

        数据从SER口排着队等待进入,这个管脚打开数据往里走一点,打开数据往里走一点,打开数据往里走一点........给高电平一下,输入一个位(bit) ;给高电平一下,输入一个位(bit)。

RCLK(P35):存储计时器时钟的输入引脚

        把刚才输入的8位数据,给存储起来。使用:给高电平一下,把移位寄存器中的8位数据一次性转存到存储时钟当中。

下面就要编写74HC595的写数据的程序

根据上面描述,先用for循环把数据暂存到8位移位寄存器当中,然后把移位寄存器中的8位数据一次性转存到存储时钟当中即可。

程序:

/******************定义74HC595管脚************************/

sbit rclk=P3^5;
sbit SRCLK=P3^6;
sbit SER=P3^4;

void HC595_write(uchar dat)//74HC595芯片的写数据
{
	uchar i;
	
	for(i=0;i<8;i++)//先把数据暂存到8位移位寄存器当中
	{
		SER=dat>>7;//把最高位的数值赋给SER串行输入端口
		dat<<=1;//把dat数据的次高位移至最高位
		SRCLK=0;
		Delay10us();//进行一个微小的延时	
		SRCLK=1;//对高低电平进行转换,每置一次高电平,数据就往里传输一位。
		Delay10us();	
	}
	//把移位寄存器中的8位数据一次性转存到存储时钟当中
	rclk=0;
	Delay10us();//进行一个微小的延时		
	rclk=1;//置为高电平才开始工作
}

LED 8*8点阵

  在51单片机上,我们通过74HC595来扩展了一个LED8*8点阵,在使用点阵的时候,要保证OE(第二个)跳线帽和地(第三个)短接。

  点阵中,每一引出的是放光二极管的阳极,在高电平下点亮

  例如DPh置为高电平,第一行就被点亮。

  每一引出的是放光二极管的阴极,由P0口控制,在低电平下点亮

1.静态点亮(静态数码管)

程序:点亮8*8点阵的左上角的灯

让第一列置0,第一行置1即可。

/**********************点亮左上角第一个点*****************/
/*
#include <reg52.h>
#include "intrins.h"

#define uchar unsigned char
#define uint unsigned int

/******************对LED灯进行定义*********************

sbit LED1=P2^0;
sbit LED2=P2^1;

/******************定义38译码器的输入管脚*******************

sbit LSA=P2^2;   //对单个管脚进行定义用sbit
sbit LSB=P2^3;
sbit LSC=P2^4;
//#define SMG_duanxuan   P0//对整个P0端口进行定义 用宏定义
                         //是对整个段选端口进行定义

/******************定义74HC595管脚************************

sbit rclk=P3^5;
sbit SRCLK=P3^6;
sbit SER=P3^4;
#define LEDdz_lie   P0//LED点阵的列都定义在P0端口处

uchar LEDdz_hang[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};
        //LED点阵从最下面一行依次到最上面一行点亮

void Delayms(uint ms);//1毫秒延时
void Delay10us();		//@11.0592MHz
void HC595_write(uchar dat);
void LED_DZ_work();

void main()
{
	while(1)
	{
		LED_DZ_work();
	}
}

void LED_DZ_work()
{
	LEDdz_lie=0X7F;//让列输出低电平才能点亮。
	HC595_write(0X80);//把行显示的数据传给74HC595芯片
}

void HC595_write(uchar dat)//74HC595芯片的写数据
{
	uchar i;
	
	for(i=0;i<8;i++)//先把数据暂存到8位移位寄存器当中
	{
		SER=dat>>7;//把最高位的数值赋给SER串行输入端口
		dat<<=1;//把dat数据的次高位移至最高位
		SRCLK=0;
		Delay10us();//进行一个微小的延时	
		SRCLK=1;//对高低电平进行转换,每置一次高电平,数据就往里传输一位。
		Delay10us();	
	}
	//把移位寄存器中的8位数据一次性转存到存储时钟当中
	rclk=0;
	Delay10us();//进行一个微小的延时		
	rclk=1;//置为高电平才开始工作
}

void Delayms(uint ms)//1毫秒延时
{
	uint i,j;
	for(i=ms;i>0;i--)
	for(j=114;j>0;j--);
}

void Delay10us()		//@11.0592MHz
{
	unsigned char i;

	_nop_();
	i = 25;
	while (--i);
}

2.动态显示(动态数码管)

其原理类似于动态数码管的显示,从第一列开始逐列进行扫描,这一行如果显示就把要显示的灯置高电平。

这里我们用到一个文字取模工具,新建一个8*8的图像之后,可以在模拟动画里面放大图像。用鼠标建立自己想显示的图像。然后点击参数设置,将字节倒序选项取消选中,取模方式选择纵向取模,其余选项默认,点击确定。之后点击取模方式,选择C51格式,就可得到每一列的行方向上的数据。

例如:取模数字0、

第一列的每一行都不需要显示,所以全部置为低电平,第二列中需要显示的那一行置为高电平即可。

0x00,0x7C,0x82,0x82,0x82,0x7C,0x00,0x00,

/***************************显示数字图像*******************/
/*
#include <reg52.h>
#include "intrins.h"

#define uchar unsigned char
#define uint unsigned int

/******************对LED灯进行定义*********************

sbit LED1=P2^0;
sbit LED2=P2^1;

/******************定义38译码器的输入管脚*******************

sbit LSA=P2^2;   //对单个管脚进行定义用sbit
sbit LSB=P2^3;
sbit LSC=P2^4;
//#define SMG_duanxuan   P0//对整个P0端口进行定义 用宏定义
                         //是对整个段选端口进行定义

/******************定义74HC595管脚************************

sbit rclk=P3^5;
sbit SRCLK=P3^6;
sbit SER=P3^4;
#define LEDDZ_lie   P0//LED点阵的列都定义在P0端口处

uchar LEDdz_hang[]={0x00,0x7C,0x82,0x82,0x82,0x7C,0x00,0x00};
        //LED点阵显示数字0  通过文字取模软件获取
uchar LEDdz_lie[]={0X7F,0XBF,0XDF,0XEF,0XF7,0XFB,0XFD,0XFE};
        //LED点阵逐列扫描

void Delayms(uint ms);//1毫秒延时
void Delay10us();		//@11.0592MHz
void HC595_write(uchar dat);
void LED_DZ_work();

void main()
{
	while(1)
	{
		LED_DZ_work();
	}
}

void LED_DZ_work()
{
	uchar i=0;
	
	for(i=0;i<8;i++)
	{
		LEDDZ_lie=LEDdz_lie[i];//让列输出低电平才能点亮
		                       //逐列扫描,让每一列都点亮
		HC595_write(LEDdz_hang[i]);//把行显示的数据传给74HC595芯片
		HC595_write(0X00);//消隐
	}
}

void HC595_write(uchar dat)//74HC595芯片的写数据
{
	uchar i;
	
	for(i=0;i<8;i++)//先把数据暂存到8位移位寄存器当中
	{
		SER=dat>>7;//把最高位的数值赋给SER串行输入端口
		dat<<=1;//把dat数据的次高位移至最高位
		SRCLK=0;
		Delay10us();//进行一个微小的延时	
		SRCLK=1;//对高低电平进行转换,每置一次高电平,数据就往里传输一位。
		Delay10us();	
	}
	//把移位寄存器中的8位数据一次性转存到存储时钟当中
	rclk=0;
	Delay10us();//进行一个微小的延时		
	rclk=1;//置为高电平才开始工作
}

void Delayms(uint ms)//1毫秒延时
{
	uint i,j;
	for(i=ms;i>0;i--)
	for(j=114;j>0;j--);
}

void Delay10us()		//@11.0592MHz
{
	unsigned char i;

	_nop_();
	i = 25;
	while (--i);
}

文字取模软件链接:

      链接:https://pan.baidu.com/s/1uzVLQSOg3LqM7g7yVxT-qA?pwd=x6la 
      提取码:x6la

  • 1
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值