51单片机STC 89C52RC进阶 – 两片74HC595D串联实现跑马灯

芯片概述(回忆)

STC 89C52RC电气特性

管脚定义

51单片机STC 89C52RC进阶 – 两片74HC595D串联实现跑马灯_第1张图片

管脚符号 管脚序号 管脚含义 备注
T2/P1.0 ~ P1.7 1 ~ 8 带内部上拉电阻的8位双向I/O口 可输入或输出数据。同时可做定时器/计数器2的的外部技术输入(P1.0/T2)和触发输入(P1.1/T2EX)
RST 9 复位输入 用来完成单片机单片机的复位初始化操作
RXD/P3.0 10 串行输入口 使用USB转TTL下载器烧写程序时,此接口一般接下载器的TXD引脚
TXD/P3.1 11 串行输出口 使用USB转TTL下载器烧写程序时,此接口一般接下载器的RXD引脚
INTO/P3.2 12 外部中断口0
INT1/P3.3 13 外部中断口1
TO/P3.4 14 定时器0的外部输入
T1/P3.5 15 定时器1的外部输入
WR/P3.6 16 外部数据存储器写选通
RD/P3.7 17 外部数据存储器读选通
XTAL2 18 振荡器反相放大器的输入端
XTAL1 19 振荡器反相放大器和内部时钟发生电路的输入端
VSS 20 接地(GND)端
P2.0/A8 ~ P2.7/A15 21 ~ 28 带内部上拉电阻的8位双向I/O端口 可输入或输出数据
PSEN 29 外ROM读选通信号 在访问片外程序存储器时,此端输出负脉冲作为存储器读选通信号
ALE/PROG 30 地址锁存允许/片内EPROM编程脉冲 ALE:用来锁存P0口送出的低8位地址 PROG:片内有EPROM的芯片,在EPROM编程期间,此引脚输入编程脉冲
EA 31 访问外部程序存储器控制信号 为了执行内部程序指令,应该接电源正极
P0.0/AD0 ~ P0.7/AD7 32 ~ 39 漏极开路的8位双向I/O口 可输入或输出数据
VCC 40 电源正极输入 接电源正极

补充表格注释:
51单片机STC 89C52RC进阶 – 两片74HC595D串联实现跑马灯_第2张图片

74HC595和74HC595D 电气特性

管脚定义(左:74HC595D 右:74HC595)

51单片机STC 89C52RC进阶 – 两片74HC595D串联实现跑马灯_第3张图片

管脚符号 管脚序号 管脚含义 备注
QA 15 8位并行数据输出 分别接8颗独立的LED发光二极管
QB 1
QC 2
QD 3
QE 4
QF 5
QG 6
QH 7
GND 8 接地端 接树莓派的GND引脚
Vcc 16 电源正极输入 接树莓派的5V电源正极引脚
SI 14 串行数据输入 控制数据的输入。一般接树莓派定义好的GPIO引脚来接收树莓派的高低电平数据
G 13 输出使能控制端 是否要将数据输出到QA~QH引脚上
RCK 12 存储寄存器(锁存器)时钟输入 是否要将移位寄存器中的数据拷贝到存储寄存器(锁存器)中。一般接树莓派定义好的GPIO引脚来接收树莓派的数据实现上升沿
SCK 11 移位寄存器时钟输入 决定何时把SI引脚的数据存入移位寄存器中。一般接树莓派定义好的GPIO引脚来接收树莓派的数据实现上升沿
SCLR 10 移位寄存器清零输入 决定是否要重置所有的寄存器到初始状态。
QH’ 9 串行数据输出 接下一个74HC595D的SI引脚实现串联

补充表格注释:
51单片机STC 89C52RC进阶 – 两片74HC595D串联实现跑马灯_第4张图片

电路图

完整电路图

51单片机STC 89C52RC进阶 – 两片74HC595D串联实现跑马灯_第5张图片
以下三张图分别是在面包板上搭建好的完整电路、最小系统+74HC595D串联电路和LED等阵列电路。

51单片机STC 89C52RC进阶 – 两片74HC595D串联实现跑马灯_第6张图片

电路图分析

整体来看,从右到左,电路可分为三大部分:STC
89C52RC最小系统电路、74HC595D级联电路和LED发光二极管阵列电路。

完整电路连接分析表
STC 89C52RC最小系统电路部分
源芯片名称 源芯片管脚符号 /管脚序号 连接到的目标芯片名称 连接到的目标芯片管脚符号 /管脚序号 接法解释 备注
STC 89C52RC RST / 9 10uF铝电解电容和10K电阻 最小系统必需
STC 89C52RC XTAL2 / 18 11.0592MHz晶振和30pF瓷片电容 最小系统必需
STC 89C52RC XTAL1 / 19 11.0592MHz晶振和30pF瓷片电容 最小系统必需
STC 89C52RC VSS / 20 电源 电源负极/GND 为STC 89C52RC提供电源回路
STC 89C52RC EA / 31 电源 电源正极 让STC 89C52RC从内部读取程序执行
STC 89C52RC VCC / 40 电源 电源正极 为STC 89C52RC提供工作电源
74HC595D级联电路部分
源芯片名称 源芯片管脚符号 /管脚序号 连接到的目标芯片名称 连接到的目标芯片管脚符号 /管脚序号 接法解释 备注
第一片74HC595D QB / 1 红色LED阵列 第二排阵列正极 驱动红色LED阵列的第二排LED
第一片74HC595D QC / 2 红色LED阵列 第三排阵列正极 驱动红色LED阵列的第三排LED
第一片74HC595D QD / 3 红色LED阵列 第四排阵列正极 驱动红色LED阵列的第四排LED
第一片74HC595D QE / 4 绿色LED阵列 第一排阵列正极 驱动绿色LED阵列的第一排LED
第一片74HC595D QF / 5 绿色LED阵列 第二排阵列正极 驱动绿色LED阵列的第二排LED
第一片74HC595D QG / 6 绿色LED阵列 第三排阵列正极 驱动绿色LED阵列的第三排LED
第一片74HC595D QH / 7 绿色LED阵列 第四排阵列正极 驱动绿色LED阵列的第四排LED
第一片74HC595D GND / 8 电源 电源负极 为第一片74HC595D提供电源回路
第一片74HC595D QH’ / 9 第二片74HC595D SI / 14 串联下一片74HC595D
第一片74HC595D SCLR / 10 STC 89C52RC P1.5 / 6 灵活控制LED的亮灭
第一片74HC595D SCK / 11 STC 89C52RC P1.4 / 5 控制何时将SI引脚上输入的串行数据移动到移位寄存器中
第一片74HC595D RCK / 12 STC 89C52RC P1.3 / 4 控制何时将移位寄存器中的数据拷贝到存储寄存器(锁存器)中
第一片74HC595D G / 13 STC 89C52RC P1.6 / 7 控制QA~QH是否输出数据
第一片74HC595D SI / 14 STC 89C52RC P1.2 / 3 输入串行数据
第一片74HC595D QA / 15 红色LED阵列 第一排阵列正极 驱动红色LED阵列的第一排LED
第一片74HC595D Vcc / 16 电源 电源正极 为74HC595D提供工作电源
第二片74HC595D QB / 1 黄色LED阵列 第二排阵列正极 驱动黄色LED阵列的第二排LED
第二片74HC595D QC / 2 黄色LED阵列 第三排阵列正极 驱动黄色LED阵列的第三排LED
第二片74HC595D QD / 3 黄色LED阵列 第四排阵列正极 驱动黄色LED阵列的第四排LED
第二片74HC595D QE / 4 蓝色LED阵列 第一排阵列正极 驱动蓝色LED阵列的第一排LED
第二片74HC595D QF / 5 蓝色LED阵列 第二排阵列正极 驱动蓝色LED阵列的第二排LED
第二片74HC595D QG / 6 蓝色LED阵列 第三排阵列正极 驱动蓝色LED阵列的第三排LED
第二片74HC595D QH / 7 蓝色LED阵列 第四排阵列正极 驱动蓝色LED阵列的第四排LED
第二片74HC595D GND / 8 电源 电源负极 为第二片74HC595D提供电源回路
第二片74HC595D QH’ / 9 如没有第三片74HC595D则不连
第二片74HC595D SCLR / 10 STC 89C52RC P1.5 / 6 灵活控制LED的亮灭 和第一片74HC595D连接位置一致
第二片74HC595D SCK / 11 第一片74HC595D SCK / 11 控制何时将SI引脚上输入的串行数据移动到移位寄存器中
第二片74HC595D RCK / 12 第一片74HC595D RCK / 12 控制何时将移位寄存器中的数据拷贝到存储寄存器(锁存器)中
第二片74HC595D G / 13 STC 89C52RC P1.6 / 7 控制QA~QH是否输出数据 和第一片74HC595D连接位置一致
第二片74HC595D SI / 14 第一片74HC595D QH’ / 9 输入串行数据
LED发光二极管阵列电路部分
比较简单,按电路图连接即可,不再赘述

表格注释补充:
51单片机STC 89C52RC进阶 – 两片74HC595D串联实现跑马灯_第7张图片
51单片机STC 89C52RC进阶 – 两片74HC595D串联实现跑马灯_第8张图片

跑马灯程序

完整程序

执行C程序后,会看到16排LED发光二极管依次循环亮灭,行如流水。

程序:

https://gitee.com/stevejrong1024/festive-lantern.git

文件:

labs/lab2.c

基础知识

  1. 十进制数转换二进制数:

十进制整数转换为二进制整数采用"除2取余,逆序排列"法。具体做法是:用2整除十进制整数,可以得到一个商和余数;再用2去除商,又会得到一个商和余数,如此进行,直到商为小于1时为止,然后把先得到的余数作为二进制数的低位有效位,后得到的余数作为二进制数的高位有效位,依次排列起来。

例:十进制数255转换二进制数为多少?
答:

  1. 形如“0x”这样的表示法为十六进制的表示法。十六进制一般用数字0到9和字母A到F(或a~f)表示,其中A~F(或a~f)表示10~15,这些称作十六进制数字。

  2. 十六进制数转换十进制数:
    16进制数的第0位的权值为16的0次方,第1位的权值为16的1次方,第2位的权值为16的2次方……

例:十六进制数 0x80、0xff、0xfe 转换十进制数分别为多少?
答:
51单片机STC 89C52RC进阶 – 两片74HC595D串联实现跑马灯_第9张图片

  1. 两个十进制数进行按位与运算:
    按位与就是将两个数字或字符串,转换为二进制数之后,其中的每一位进行运算最后得出的一个新的二进制结果,将这个新得出的二进制数转换为十进制数,即为最终答案
    按位与的运算规则:
    两个要进行按位与运算的数字都转为二进制数后,每一位进行比较。若当前位中,两者的值都等于1,则新生成的二进制数中,此位的值就写为1,否则此位写0

例:十进制数7和十进制数9进行按位与运算,结果为多少?
答:

5. 循环左移运算:
在二进制表示法下,循环将位于二进制数最左边的一位移动到二进制数最右边,构成新的二进制数的操作。

例:十进制数1,左移一位后,结果为多少?
答:
51单片机STC 89C52RC进阶 – 两片74HC595D串联实现跑马灯_第10张图片
在C语言中,没有现成的库能实现循环左移,使用一下自定义方法可实现循环左移:

/**
 * 循环左移
 *
 * @param sourceData 原始数据
 * @param bit 原始数据的位数。可选值:8、16、32
 * @param step 移动位数
 * @return
 */
int circularLeft(int sourceData, int bit, int step) {
    return (sourceData << step) | (sourceData >> (bit - step));
}
  1. 可能用到的数字,其十进制、十六进制和二进制表示法大全:
十进制数 十六进制表示法 二进制表示法 备注
1 0x01 0000 0001
2 0x02 0000 0010
4 0x04 0000 0100
8 0x08 0000 1000
16 0x10 0001 0000
32 0x20 0010 0000
64 0x40 0100 0000
128 0x80 1000 0000
  • 仔细观察二进制表示法中,值1的位置。从表格第一行的十进制数字1开始,到表格最后一行的十进制数字128结束,二进制数中的值1,从最右边逐位移动到了最左边。
    这也就是为什么跑马灯程序中,main方法里的初始值要设置成0x01了,因为这表示第一片QA引脚接入的第一排红色LED先点亮
  1. 两片74HC595D串联以后,16位的二进制数与74HC595D管脚的对应位置关系
    对应了关系,也就表明一个二进制数可以精确到单独控制74HC595D的每一个并行输出引脚,是否输出数据。即可以精确地控制16排LED发光二极管,每一排的亮灭**
二进制位数位置 二进制数位置列举 对应74HC595D片 对应管脚符号 /管脚序号 备注
第16位 0000 0000 0000 0001 第一片 QA / 15 即当给SI引脚输入0000 0000 0000 0001二进制数据后,红色LED阵列的第一排LED会亮起,剩余15排LED都熄灭
第15位 0000 0000 0000 0010 第一片 QB / 1 即当给SI引脚输入0000 0000 0000 0010二进制数据后,红色LED阵列的第二排LED会亮起,剩余15排LED都熄灭
第14位 0000 0000 0000 0100 第一片 QC / 2 以此类推
第13位 0000 0000 0000 1000 第一片 QD / 3 以此类推
第12位 0000 0000 0001 0000 第一片 QE / 4 以此类推
第11位 0000 0000 0010 0000 第一片 QF / 5 以此类推
第10位 0000 0000 0100 0000 第一片 QG / 6 以此类推
第9位 0000 0000 1000 0000 第一片 QH / 7 以此类推
第8位 0000 0001 0000 0000 第二片 QA / 16 以此类推
第7位 0000 0010 0000 0000 第二片 QB / 1 以此类推
第6位 0000 0100 0000 0000 第二片 QC / 2 以此类推
第5位 0000 1000 0000 0000 第二片 QD / 3 以此类推
第4位 0001 0000 0000 0000 第二片 QE / 4 以此类推
第3位 0010 0000 0000 0000 第二片 QF / 5 以此类推
第2位 0100 0000 0000 0000 第二片 QG / 6 以此类推
第1位 1000 0000 0000 0000 第二片 QH / 7 以此类推
  1. 适用于频率为11.0529MHz,精确延时的C语言方法:
void delay(unsigned int n) {  
int i, j;  
for (i = n; i \> 0; i--)  
for (j = 110; j \> 0; j--);  
}

程序分析

完整程序中已包含详尽注释,不再赘述。
重在理解以下几点:

  1. 为什么通过数据的移位操作就能控制74HC595D每个并行输出引脚的数据输出
  2. main()方法中,每次while循环结束前为什么要循环左移,不循环左移行吗?
  3. send_data()方法每一步的执行逻辑是什么样的,执行到每一步之后,输入到SI引脚的二进制数据分别是什么?

根据注释一步步分析下来以后,就能很清楚的知道程序是如何精确控制每一个并行输出引脚的了。

你可能感兴趣的:(硬件,单片机,嵌入式)