51单片机入门学习 第七天

提示:今天是学习51单片机的第七天,以下就是今天的笔记(我买的是普中的开发板,学习笔记是根据普中的视频进行学习)   前面我们学习了案件和矩阵,矩阵的使用方法有行线反转法,今天学习IO口的扩展使用74H595芯片,另外学习点阵。


目录

IO 扩展(串转并)-74HC595

1.74HC595 芯片介绍

2.硬件设计

3.软件设计

LED 点阵实验

1.LED 点阵介绍

2.硬件设计 

3.软件设计


IO 扩展(串转并)-74HC595

在前面实验中,我们是直接使用单片机IO口控制外围设备,从LED流水灯到动态数码管显示,可以看到这些外围设备已经占据了很多的 IO 口,而 51 单片机 IO 口非常有限,如果想要连接更多外围设备,此时可以通过 IO 扩展来实现。我们就来介绍另外一种 IO 口扩展方式-串转并,使用的芯片是 74HC595。开 发板板载 1 个 74HC595 芯片,仅需单片机 3 个 IO 口即可扩展 8 个,如果需要还 可以将 2 个 74HC595 级联扩展出 16 个 IO,这就实现用少数 IO 资源控制多个设备。

1.74HC595 芯片介绍

2.硬件设计

3.软件设计

1.74HC595 芯片介绍

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

 芯片管脚及功能说明如下: 上面两张都是 74HC595 芯片管脚图,左侧的 1 脚是 QB, 而右侧芯片的 1 脚是 Q1,左侧芯片的 11 脚是 SCK,而右侧芯片的 11 脚是 SH_CP, 还有很多其他管脚不一样,其实这个都没有什么,每个人在绘制芯片管脚图时命 名可能不一样而已,看一个芯片重点是管脚功能。

15 和 1 到 7 脚 QA--QH:并行数据输出
9 脚 QH 非:串行数据输出
10 脚 SCLK 非( MR) : 低电平复位引脚
11 脚 SCK( SHCP) : 移位寄存器时钟输入
12 脚 RCK( STCP) : 存储寄存器时钟输入
13 脚 G 非( OE) : 输出有效
14 脚 SER( DS) : 串行数据输入

4HC595 是具有 8 位移位寄存器(注意在此时是一位一位的移动,先移动高位,高位往下走,在移动地位)和一个存储器,三态输出功能。移位寄存器 和存储器是单独的时钟。数据在 SCK 的上升沿输入,在 RCK 的上升沿进入到存 储器中。如果两个时钟连在一起,则移位寄存器总是比存储器早一个脉冲。移位寄存器有一个串行输入(DS),和一个串行输出(Q7 非),和一个异步的低电 平复位,存储寄存器有一个并行 8 位的,具有三态的总线输出,当 MR 为高电 平,OE 为低电平时,数据在 SHCP 上升沿进入移位寄存器,在 STCP 上升沿输 出到并行端口。

2.硬件设计

(1)8*8LED 点阵模块 (2)74HC595 模块

 上图中可以看出,74HC595 需要用到的控制管脚 SER、RCLK、SRCLK 直接连 接到 51 单片机的 P3.4-P3.6 IO 口上,输出端则是直接连接到 LED 点阵模块的行 端口上,即为 LED 发光二极管的阳极,LED 点阵的列则为发光二极管的阴极。 要想控制 LED 点阵,可以将单片机管脚按照 74HC595 芯片的通信时序要求来传输数据,这样即可控制 LED 点阵的行数据。根据 LED 发光二极管导通原理,当阳极为高电平,阴极为低电平则点亮,否则熄灭。因此通过单片机 P0 口可控制 点阵列,74HC595 可控制点阵行。

3.软件设计

通过 74HC595 模块控制 LED 点阵以一行循环滚动显示。

#include "reg52.h"
typedef unsigned int u16; //对系统默认数据类型进行重定义
typedef unsigned char u8;
//定义 74HC595 控制管脚
sbit SRCLK=P3^6; //移位寄存器时钟输入
sbit RCLK=P3^5; //存储寄存器时钟输入
sbit SER=P3^4; //串行数据输入
#define LEDDZ_COL_PORT P0 //点阵列控制端口

u8 ghc595_buf[8]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};

void delay_10us(u16 ten_us)
{
while(ten_us--);
}

void delay_ms(u16 ms)
{
u16 i,j;
for(i=ms;i>0;i--)
for(j=110;j>0;j--);
}

void hc595_write_data(u8 dat)
{
u8 i=0;
for(i=0;i<8;i++)//循环 8 次即可将一个字节写入寄存器中
{
SER=dat>>7;//优先传输一个字节中的高位
dat<<=1;//将低位移动到高位
SRCLK=0;
delay_10us(1);
SRCLK=1;
delay_10us(1);//移位寄存器时钟上升沿将端口数据送入寄存器中
}
RCLK=0;
delay_10us(1);
RCLK=1;//存储寄存器时钟上升沿将前面写入到寄存器的数据输出
}

void main()
{
u8 i=0;
LEDDZ_COL_PORT=0x00;//将 LED 点阵列全部设置为 0,即 LED 阴极为低电平
while(1)
{
for(i=0;i<8;i++)
{
hc595_write_data(0x00);//消除前面寄存器缓存数据
hc595_write_data(ghc595_buf[i]);//写入新的数据
delay_ms(500);//延时 500ms
}
}
}

首先定义好 74HC595 控制管脚,以及点阵列控制口,代码中重新定义了一个 ms 级延时函数 delay_ms,该函数与前面 delay_10us 类似,都是利用循环占用 CPU 起到延时效果。然后又定义了 74HC595 的控制函数 hc595_write_data,该函数完全按照 74HC595 的通信时序要求编写,主要要注意的是 74HC595 是先传输字节的高位后传输低位,所以需要将字节低位移动到高位 传输,在传输数据时,要注意移位寄存器时钟和存储寄存器时钟的先后顺序,将 要写入的数据先传输到 74HC595 寄存器中,即在准备好每位数据时要将 SRCLK 进行一个上升沿变化,此时即可将数据传输到寄存器内,待循环 8 次即一个字节 传输到寄存器中时,就可以来一个存储时钟上升沿,此时就可以将 74HC595 寄存 器中的数据全部一次传输到 595 端口输出。最后就是在 main 函数中调用 74HC595 的控制函数,将实验中要实现的效果数据写入进去,从而控制 LED 点阵的阳极, 而阴极由 P0 口控制,默认初始化时已经设置为 0,也就是说只要 595 输出高电 平,那么对应的行就会点亮。

另外要想使用多个74HC595管脚OH接下一个芯片的SER,把写入寄存器函数的参数写入多个,在进行多个for循环,写入的时候最高位会一直写入最后一个连接芯片的底部就是寄存器的高位。最后控制的时候根据原理图进行操作控制就行。


LED 点阵实验

前面了解过静态数码管和动态数码管显示,其中动态数码管是 一种应用非常多的显示设备,除此之外还有很多应用广泛的显示装置,比如 LED 点阵屏其实都是对LED灯的控制。

1.LED 点阵介绍

2. 硬件设计

3.软件设计 

1.LED 点阵介绍

LED点阵是由发光二极管排列组成的显示器件,在我们日常生活的电器中随 处可见,被广泛应用于汽车报站器,广告屏等。

通常应用较多的是 8*8 点阵,然后使用多个 8*8 点阵可组成不同分辨率的 LED 点阵显示屏,比如 16*16 点阵可以使用 4 个 8*8 点阵构成。因此理解了 8*8LED 点阵的工作原理,其他分辨率的 LED 点阵显示屏都是一样的。这里以 8*8LED 点 阵来做介绍。其内部结构图如下所示: 8*8 点阵共由 64 个发光二极管组成,且每个发光二极管是放置在行线和列线 的交叉点上,当对应的某一行置 1 电平,某一列置 0 电平,则相应的二极管就亮; 如要将第一个点点亮,则 1 脚接高电平 a 脚接低电平,则第一个点就亮了;如果 要将第一行点亮,则第 1 脚要接高电平,而(a、b、c、d、e、f、g、h )这些 引脚接低电平,那么第一行就会点亮;如要将第一列点亮,则第 a 脚接低电平, 而(1、2、3、4、5、6、7、8)接高电平,那么第一列就会点亮。

2.硬件设计 

(1)8*8LED 点阵模块

(2)74HC595 模块

 74HC595 需要用到的控制管脚 SER、RCLK、SRCLK 直接连接到 51 单片机的 P3.4-P3.6 IO 口上,输出端则是直接连接到 LED 点阵模块的行端口上,即为 LED 发光二极管的阳极,LED 点阵的列则为发光二极管的阴极。 要想控制 LED 点阵,可以将单片机管脚按照 74HC595 芯片的通信时序要求来传输数据,这样即可控制 LED 点阵的行数据。根据 LED 发光二极管导通原理,当 阳极为高电平,阴极为低电平则点亮,否则熄灭。因此通过单片机 P0 口可控制 点阵列,74HC595 可控制点阵行。

3.软件设计

(1)在点阵屏上点亮一个点

#include "reg52.h"
typedef unsigned int u16; //对系统默认数据类型进行重定义
typedef unsigned char u8;
//定义 74HC595 控制管脚
sbit SRCLK=P3^6; //移位寄存器时钟输入
sbit RCLK=P3^5; //存储寄存器时钟输入
sbit SER=P3^4; //串行数据输入
#define LEDDZ_COL_PORT P0 //点阵列控制端口

void delay_10us(u16 ten_us)
{
while(ten_us--);
}

void hc595_write_data(u8 dat)
{
u8 i=0;
for(i=0;i<8;i++)//循环 8 次即可将一个字节写入寄存器中
{
SER=dat>>7;//优先传输一个字节中的高位
dat<<=1;//将低位移动到高位
SRCLK=0;
delay_10us(1);
SRCLK=1;
delay_10us(1);//移位寄存器时钟上升沿将端口数据送入寄存器中
}
RCLK=0;
delay_10us(1);
RCLK=1;//存储寄存器时钟上升沿将前面写入到寄存器的数据输出
}

void main()
{
u8 i=0;
LEDDZ_COL_PORT=0x7f;//将 LED 点阵左边第一列设置为 0,即 LED 阴极为低电平,其
余列为 1,即高电平
while(1)
{
hc595_write_data(0x80);//将 LED 点阵上边第一行设置为 1,即 LED 阳极为高
电平,其余行为 0,即低电平
}
}

(2)LED 点阵(显示数字)

使用文字取模器^__^

#include "reg52.h"
typedef unsigned int u16; //对系统默认数据类型进行重定义
typedef unsigned char u8;
//定义 74HC595 控制管脚
sbit SRCLK=P3^6; //移位寄存器时钟输入
sbit RCLK=P3^5; //存储寄存器时钟输入
sbit SER=P3^4; //串行数据输入
#define LEDDZ_COL_PORT P0 //点阵列控制端口
u8 gled_row[8]={0x00,0x7C,0x82,0x82,0x82,0x7C,0x00,0x00};//LED 点阵显示数字 0 的行数据
u8 gled_col[8]={0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe};//LED 点阵显示数字 0 的列数据

void delay_10us(u16 ten_us)
{
while(ten_us--);
}

void hc595_write_data(u8 dat)
{
u8 i=0;
for(i=0;i<8;i++)//循环 8 次即可将一个字节写入寄存器中
{
SER=dat>>7;//优先传输一个字节中的高位
dat<<=1;//将低位移动到高位
SRCLK=0;
delay_10us(1);
SRCLK=1;
delay_10us(1);//移位寄存器时钟上升沿将端口数据送入寄存器中
}
RCLK=0;
delay_10us(1);
RCLK=1;//存储寄存器时钟上升沿将前面写入到寄存器的数据输出
}

void main()
{
u8 i=0;
while(1)
{
for(i=0;i<8;i++)//循环 8 次扫描 8 行、列
{
LEDDZ_COL_PORT=gled_col[i];//传送列选数据
hc595_write_data(gled_row[i]);//传送行选数据
delay_10us(100);//延时一段时间,等待显示稳定
hc595_write_data(0x00);//消影
}
}
}

动态扫描和以前动态数码管代码相似。main 函数中主要是 在 while 循环内从上至下,从左至右不断扫描 8 行、列,即首先设置左边第一列有效(P0.7 输出低电平),其余列无效(P0.6-P0.0 输出高电平),然后通过 74HC595 输出该列对应的行数据,延时一段时间等待显示稳定,最后清除列对应的行数据,即消影。从整个流程下来与动态数码管显示程序是很相似。

(3)LED 点阵(显示图像)

使用文字取模器^__^

u8 gled_row[8]={0x38,0x7C,0x7E,0x3F,0x3F,0x7E,0x7C,0x38};//LED 点阵显示图像的行数据其余代码与显示数字完全一样

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值