51单片机——74HC595、LED点阵屏

目录

1.74HC595

[1.1 回顾](#1.1 回顾)

[1.2 概述](#1.2 概述)

[1.3 工作原理](#1.3 工作原理)

[1.4 硬件设计](#1.4 硬件设计)

[1.5 实验设计](#1.5 实验设计)

[2. LED点阵](#2. LED点阵)

[2.1 概述](#2.1 概述)

​编辑

[2.2 软件设计](#2.2 软件设计)

[2.2.1 点亮一个灯](#2.2.1 点亮一个灯)

[2.2.2 显示一个数字](#2.2.2 显示一个数字)


1.74HC595
1.1 回顾

前面动态数码管实验中提到 74HC138 拓展单片机 IO ,回顾:

"2个四位一体的数码管位选线有8根,但单片机IO资源有限

通常使用一种IO扩展芯片 ,如 74HC138,74HC164,74HC595

只需要用很少的单片机IO口就可扩展出8个控制口,通过级联方式甚至可以拓展更多IO口"

本篇介绍另外一种 IO口 拓展方式------串转并,使用的芯片是74HC595 芯片

1.2 概述

开发板板载一个 74HC595芯片,仅单片机3个IO口即可拓展8个IO口

如果需要还可以将2个74HC595级联拓展出16个IO,即可实现用少数 IO 口资源控制多个设备

74HC595是一个 8位 串行输入,并行输出的位移缓存器

并行输出为三态输出(高电平、低电平、高阻扛)

1.3 工作原理

下图左边均是芯片管脚图,但管脚命名不同,重在关注管脚功能即可

74HC595 具有一个八位移位寄存器、存储寄存器。移位寄存器和存储寄存器是单独的时钟。数据通过 14脚 上升沿输入,当 MR 为高电平、OE为低电平时,数据在 11脚 的上升沿(高电平)进入到 移位寄存器,再通过 12脚 的上升沿(高电平)移动到 存储寄存器,若需要级联,则通过 9脚 串行输出,14 脚 串行数据输入即可;否则直接通过 15和1-7脚 并行数据输出到外围设备即可;

1.4 硬件设计

下图,中间是 74HC595 芯片,右端为 LED 点阵

OE :**LED 点阵的 "驱动总开关"。**低电平允许芯片驱动点阵显示,高电平切断驱动以关闭显示或隔离信号

图中左侧标注为"J24",典型的跳线接口。黄色跳线帽连接1、2脚,OE引脚被拉低(低电平状态),黄色跳线帽连接2、3引脚,OE引脚被拉高(高电平状态);若不插跳线帽,OE 引脚悬空,可能导致输出不稳定

从图中可以看到,74HC595 需要用到的控制管脚连接单片机的 P34-P36 IO口,输出端连接LED点阵模块的行端口上,即为 LED发光二极管的阳极,单片机 P0口 控制点阵列

此外,数据是一位一位的传输到八位的移位寄存器,且从数据最高位开始移入,移位寄存器满八位之后,再一次性传输到存储寄存器

如 1001 0001 ,先将最高位 1 存入移位寄存器,再将 0 存入移位寄存器,如此类推,一直到最低位 1 也存入移位寄存器,移位寄存器满了之后,将数据一次性传输到存储寄存器。且最高位 1 对应 Dph,即 点阵屏第一行,次高位 0 对应 Dpg,即点阵屏第二行,如此类推

1.5 实验设计

通过74HC595控制LED点阵以行滚动方式循环显示

cpp 复制代码
//74HC595 控制 LED点阵逐行点亮
#include <at89c51RC2.h>
#include <intrins.h>

//简化类型名
typedef unsigned char u8;
typedef unsigned int u16;


//定义 74HC595 关键引脚
sbit SER = P3^4;      //串行数据输入
sbit RCLK_595 = P3^5; //存储寄存器输入:头文件中已经预定义了 RCLK
sbit SRCLK = P3^6;    //移位寄存器输入

//74HC595 串行输入数据
u8 hc595[] = {0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01};

/*延时函数:74HC595 对时钟信号的上升/下降沿有最小时间要求
如果时钟翻转太快,芯片来不及采样数据,会导致输出错误。*/
void Delay10us(u16 ms)	//@11.0592MHz
{
	unsigned char data i;

	while(ms--)
	{
		i = 2;
		while (--i);
	}
}

//串行数据输入--->并行数据输出
void hc595_write(u8 date)//date即要写入的字节数据
{
	u8 i = 0;
	for(i=0;i<8;i++)//1字节=8位,逐位传输8次
	{
		SER = date>>7;//先把最高位传输到SER引脚
		date <<= 1;   //下一位左移(去掉最高位,末位补0)到最高位
		
		//产生移位时钟脉冲
		SRCLK = 0;   //时钟拉低
		Delay10us(1);//稳定低电平(10us)
		SRCLK = 1;   //时钟拉高,上升沿触发,将 SER 数据传输到移位寄存器
		Delay10us(1);//稳定高电平
	}
	//产生存储时钟脉冲,触发数据输出
	RCLK_595 = 0;	//时钟拉低
	Delay10us(1);	//稳定低电平(10us)
	RCLK_595 = 1;	//时钟拉高,上升沿触发,将移位寄存器数据传输到存储寄存器
	Delay10us(1);   ////稳定高电平
	//之后,74HC595的 QA-QH 并行输出传入的8位数据,驱动LED点阵
}

void main()
{
	u8 i = 0;
	while(1)
	{
		//LED点阵阴极为低电平
		P0 = 0x00;
		for(i=0;i<8;i++)
		{	
			hc595_write(0x00);		//消影:"清空旧数据",避免LED余晖和视觉暂留导致的重影
			hc595_write(hc595[i]);	//输入串行数据
			Delay10us(20000);
			//延时作用:保持当前 LED 的点亮状态,但解决不了"切换瞬间的新旧数据叠加"
		}
	}
}
2. LED点阵
2.1 概述

LED点阵 是由发光二极管排列组成的显示器件,被广泛应用于汽车报站器、广告屏等

2.2 软件设计
2.2.1 点亮一个灯

要求:点亮 LED点阵 第一行第一列的灯

cpp 复制代码
//点亮LED点阵一个灯
#include <at89c51RC2.h>
#include <intrins.h>

//简化类型名
typedef unsigned char u8;
typedef unsigned int u16;


//定义 74HC595 关键引脚
sbit SER = P3^4;      //串行数据输入
sbit RCLK_595 = P3^5; //存储寄存器输入:头文件中已经预定义了 RCLK
sbit SRCLK = P3^6;    //移位寄存器输入

/*延时函数:74HC595 对时钟信号的上升/下降沿有最小时间要求
如果时钟翻转太快,芯片来不及采样数据,会导致输出错误。*/
void Delay10us(u16 ms)	//@11.0592MHz
{
	unsigned char data i;

	while(ms--)
	{
		i = 2;
		while (--i);
	}
}

//串行数据输入--->并行数据输出
void hc595_write(u8 date)//date即要写入的字节数据
{
	u8 i = 0;
	for(i=0;i<8;i++)//1字节=8位,逐位传输8次
	{
		SER = date>>7;//先把最高位传输到SER引脚
		date <<= 1;   //下一位左移(去掉最高位,末位补0)到最高位
		
		//产生移位时钟脉冲
		SRCLK = 0;   //时钟拉低
		Delay10us(1);//稳定低电平(10us)
		SRCLK = 1;   //时钟拉高,上升沿触发,将 SER 数据传输到移位寄存器
		Delay10us(1);//稳定高电平
	}
	//产生存储时钟脉冲,触发数据输出
	RCLK_595 = 0;	//时钟拉低
	Delay10us(1);	//稳定低电平(10us)
	RCLK_595 = 1;	//时钟拉高,上升沿触发,将移位寄存器数据传输到存储寄存器
	Delay10us(1);   ////稳定高电平
	//之后,74HC595的 QA-QH 并行输出传入的8位数据,驱动LED点阵
}

void main()
{
	while(1)
	{
		//LED点阵阴极为低电平
		P0 = 0x7f;
		//输入行数据
		hc595_write(0x80);	
	}
}
2.2.2 显示一个数字

要求:显示一个数字 0

想要在 LED点阵 上显示一个数字,需要知道哪些灯是熄灭的,哪些灯是点亮的,也就是需要获取对应的显示数据,将数字字符对应的显示数据通过 74HC595 发送到点阵的行或列就能显示数字字符

取字模软件可以方便地获取显示数据

显示图像各行对应的数据:0x00,0x00,0x3C,0x42,0x42,0x3C,0x00,0x00

第一、二列:没有灯需要点亮 ,所以行对应数据:0x00,0x00

第三列;第 3.4.5.6 行需要点亮,所以行对应数据:0011 1100: 0x3C

如此类推

实验代码与前面点亮一个灯的核心代码是一样的,重点要理解动态扫描

动态扫描:首先设置最左边第一列(P0^7)有效,即低电平,其余列为高电平,然后通过74HC595输出该列对应的行数据,延时一段时间等待显示稳定,最后清除列对应的行数据,即消影

cpp 复制代码
//LED点阵显示数字
#include <at89c51RC2.h>
#include <intrins.h>

//简化类型名
typedef unsigned char u8;
typedef unsigned int u16;


//定义 74HC595 关键引脚
sbit SER = P3^4;      //串行数据输入
sbit RCLK_595 = P3^5; //存储寄存器输入:头文件中已经预定义了 RCLK
sbit SRCLK = P3^6;    //移位寄存器输入

// 共阴点阵适配:字模用原数组(高电平有效)
u8 led_row[] = {0x00,0x00,0x3C,0x42,0x42,0x3C,0x00,0x00}; //LED点阵显示数字0的行数据
u8 led_col[] = {0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe}; //LED点阵显示数字0的列数据

/*延时函数:74HC595 对时钟信号的上升/下降沿有最小时间要求
如果时钟翻转太快,芯片来不及采样数据,会导致输出错误。*/
void Delay10us(u16 ms)	//@11.0592MHz
{
	unsigned char data i;

	while(ms--)
	{
		i = 2;
		while (--i);
	}
}

//串行数据输入--->并行数据输出
void hc595_write(u8 date)//date即要写入的字节数据
{
	u8 i = 0;
	for(i=0;i<8;i++)//1字节=8位,逐位传输8次
	{
		SER = date>>7;//先把最高位传输到SER引脚
		date <<= 1;   //下一位左移(去掉最高位,末位补0)到最高位
		
		//产生移位时钟脉冲
		SRCLK = 0;   //时钟拉低
		Delay10us(1);//稳定低电平(10us)
		SRCLK = 1;   //时钟拉高,上升沿触发,将 SER 数据传输到移位寄存器
		Delay10us(1);//稳定高电平
	}
	//产生存储时钟脉冲,触发数据输出
	RCLK_595 = 0;	//时钟拉低
	Delay10us(1);	//稳定低电平(10us)
	RCLK_595 = 1;	//时钟拉高,上升沿触发,将移位寄存器数据传输到存储寄存器
	Delay10us(1);   ////稳定高电平
	//之后,74HC595的 QA-QH 并行输出传入的8位数据,驱动LED点阵
}

void main()
{
	u8 i=0;
	while(1)
	{
		for(i=0;i<8;i++)
		{	
			P0 = led_col[i];        // 传送列数据
			hc595_write(led_row[i]);// 传送行数据
			Delay10us(40);          // 延时一段时间,等待显示稳定
			
			hc595_write(0x00);      // 消影
		}
	}
}
相关推荐
hazy1k2 小时前
ESP32基础-Socket通信 (TCP/UDP)
c语言·单片机·嵌入式硬件·网络协议·tcp/ip·udp·esp32
charlie1145141913 小时前
利用WSL + VSCode + ESP-IDF6开发ESP32系列单片机指南
ide·vscode·单片机·esp32·wsl·指南·工程
oshan20123 小时前
小华HC32L136K8TA 单片机通用定时器(五)
单片机·嵌入式硬件
qq_401700414 小时前
单片机电源电路设计常用芯片
单片机·嵌入式硬件
大侠课堂5 小时前
单片机经典面试题50道
arm开发·单片机·嵌入式硬件·mongodb
_infinite_6 小时前
STM32常用外设配置
stm32·单片机·嵌入式硬件
普中科技6 小时前
【普中STM32F1xx开发攻略--标准库版】-- 第 17 章 STM32 中断系统
stm32·单片机·嵌入式硬件·arm·中断系统·普中科技
资料,小偿8 小时前
4.1.1基于51单片机汇编语言出租车计价器可切换白天黑夜,可修改价格
汇编·51单片机·proteus
hazy1k14 小时前
ESP32 ESP32基础-WIFI_手机控制LED
c语言·stm32·单片机·嵌入式硬件·51单片机·esp32·实时音视频