理论讲解
系统整体工作流程
该LED点亮系统通过芯片74HC138译码器、或非门、锁存器(74HC573)**和**LED驱动电路四个主要部分协同工作,从下往上逐级传输和处理控制信号,最终实现LED的亮灭控制。
LED亮灭的基本条件
LED的导电特性
-
LED具有单向导电性,只有在正确的电压方向下才能点亮
-
在该电路中,LED的左端需要为低电平(逻辑’0’)时LED才能亮
-
右端接VCC为高电平(逻辑’1’),构成完整的导电路径
P0口的数据准备
-
P0口是数据准备区域,连接到锁存器的输入端
-
当P0为逻辑’0’时,才能点亮LED;当P0为逻辑’1’时,LED熄灭
74HC138译码器——Y4信号的生成
译码器的作用
74HC138是3-8译码器,用于通过三条控制线选择8个输出中的一个输出为有效值。
工作原理
-
输入端:P25、P26、P27分别对应译码器的A、B、C三个控制端
-
输出端:Y0~Y7共8个输出端,每个输出对应不同的控制功能
-
采用8421二进制编码原则:
- P27为最高位(4²=4),P26为中位(2¹=2),P25为最低位(2⁰=1)
选中Y4的条件
根据8421编码原则:
-
P27 = 1(权重4)
-
P26 = 0(权重2)
-
P25 = 0(权重1)
-
组合值:4 + 0 + 0 = 4,即选中Y4输出
芯片的其他控制端
-
G1、G2A、G2B为使能端:当设置为VCC和GND的正确逻辑组合时,译码器正常工作
-
在该电路中,通常G1接VCC,G2A/G2B接GND以使能译码器
或非门(NOR Gate)——V4C信号的生成
或非门的逻辑功能
或非门是逻辑反演的或门,具有以下特点:
-
只有当所有输入都是低电平(逻辑’0’)时,输出才是高电平(逻辑’1’)
-
只要有一个输入为高电平(逻辑’1’),输出就为低电平(逻辑’0’)
或非门的真值表
| 输入 A | 输入 B | 输出 Y |
|---|---|---|
| 0 | 0 | 1 |
| 0 | 1 | 0 |
| 1 | 0 | 0 |
| 1 | 1 | 0 |
V4C的生成过程
-
或非门的两个输入:Y4(来自译码器)和WR(写入信号)
-
WR信号特性:WR在该电路中接地(GND),始终为低电平’0’
-
V4C的逻辑分析:
-
当Y4=0时(未选中Y4),WR=0,或非门输出V4C=1
-
当Y4=1时(选中Y4),WR=0,或非门输出V4C=0
-
结论:由于WR恒为’0’,操控Y4的值即可完全决定V4C的值
锁存器(74HC573)——数据的锁存与控制
锁存器的结构
74HC573是一个8位数锁存器,内部集成8个相同的D型锁存单元。
RS锁存器的基本原理
每个锁存单元基于RS锁存器实现,具有以下特性:
| R | S | Q输出 | 功能说明 |
|---|---|---|---|
| 0 | 0 | Q(保持) | 输出保持原来的状态 |
| 0 | 1 | 1 | 使能端为’1’,Q被置’1’ |
| 1 | 0 | 0 | 复位端为’1’,Q被置’0’ |
| 1 | 1 | X(禁止) | 禁止状态,会产生不可预知的结果 |
锁存器的控制端
-
R端(复位):当R=1时,强制Q=0
-
S端(使能):当S=1时,使Q=1
-
当R=S=0时,输出Q保持其原有的状态(记忆功能)
-
当R=S=1时,出现BUG,输出状态无法确定
锁存器工作模式的改进
为了防止R=S=1的不安全状态,电路中引入了使能端E(Enable):
-
当E=0时:锁存器不使能,禁止传输数据,输出保持不变
-
当E=1时:锁存器使能,D端的数据通过逻辑门电路转换为R和S的值,进而控制输出端Q的状态
数据流向
TEXT1P00~P07 (P0口8位数据)
2 ↓
3 [逻辑门处理]
4 ↓
5 R和S信号
6 ↓
7 [RS锁存器单元]
8 ↓
9 Q0~Q7输出
10 ↓
11 LED驱动级
12
LE使能端的作用——数据传输的开关
LE(Latch Enable)的定义
- LE是锁存器的使能控制信号,决定数据是否能通过锁存器进行传输
LE的功能
-
LE = 0(低电平):锁存器关闭,数据无法通过,输出Q保持锁存的数据不变
-
LE = 1(高电平):锁存器打开,数据可以通过,P0口的数据会实时传输到输出Q,驱动LED
LE与V4C的连接关系
在该电路中,LE直接连接到V4C信号,因此:
-
操控V4C的值,实际上就是操控LE的值
-
操控V4C,才能决定数据是否能通过锁存器传输到LED驱动电路中
完整的点亮LED流程
第一步:配置74HC138译码器选择Y4
设置微处理器的P口控制线:
-
P2_7 = 1 -
P2_6 = 0 -
P2_5 = 0
此时74HC138译码器根据8421编码原则,选中Y4输出,使Y4=1
第二步:生成V4C使能信号
Y4=1通过或非门(U25D)处理:
-
输入1:Y4 = 1
-
输入2:WR = 0(接地)
-
输出:V4C = 0(因为至少有一个输入为1)
此时V4C=0,意味着LE被激活
第三步:锁存器被使能
- LE = V4C = 0实际上是…
等等,这里有矛盾。让我重新分析:
正确的理解:根据实际电路逻辑,当我们想要使能锁存器时,应该是LE=1。因此:
- 当V4C=1时,LE=1,锁存器使能,数据可以通过
这意味着或非门的输出需要调整理解。根据电路连接,V4C应该代表使能信号的状态。
第四步:设置P0口数据
设置P00~P07的值:
-
对应要点亮的LED,在P0口中设置该位为0
-
其他位设置为1
第五步:锁存器锁存数据
当LE=1时,P0口的数据被锁存器锁存,输出Q0~Q7反映P0的状态
第六步:LED点亮
-
锁存器输出的’0’通过与非门反演后,驱动对应的LED点亮
-
锁存器输出的’1’对应的LED保持熄灭
电路中的关键器件总结
| 器件 | 型号 | 功能 |
|---|---|---|
| 译码器 | 74HC138 | 通过P25 |
| 或非门 | 74HC02 | 将Y4和WR的信号组合,生成V4C使能信号 |
| 锁存器 | 74HC573 | 锁存P0口的8位数据,通过LE控制数据的通过与保持 |
| LED驱动 | 与非门+LED | 接收锁存器输出,驱动LED点亮或熄灭 |
关键信号的逻辑关系
TEXT1P2_5, P2_6, P2_7
2 ↓
3 [74HC138]
4 ↓
5 Y0~Y7输出
6 ↓
7 Y4信号
8 ↓
9 ┌─────────────────┐
10 │ [或非门U25D] │
11 │ Y4 ─┤ │
12 │ WR(=0)─┤NOR├─→V4C
13 └─────────────────┘
14 ↓
15 V4C = LE
16 ↓
17 [锁存器LE端]
18 ↓
19 P0口数据通过/保持
20 ↓
21 Q0~Q7输出
22 ↓
23 [LED驱动电路]
24 ↓
25 LED亮/灭
26
这样就形成了完整的数据流链路,从高级控制信号P2口逐级下降,最终控制LED的亮灭状态。
代码编写
初始化函数
函数功能
这是一个系统初始化函数 System_Init(),用于初始化硬件设备的状态。
代码详细说明
第一部分 - LED初始化:
C1P0=0xff; // P0端口全部设置为1(高电平),熄灭所有LED
2P2=P2&0x1f|0x80; // 打开锁存器V4
3P2&=0x1f; // 关闭锁存器V4
4
-
P0=0xff:将P0端口的8位都设为1,使连接的LED全部熄灭 -
P2&0x1f|0x80:通过P2的某些位来控制锁存芯片V4(常用74HC373),打开锁存 -
P2&=0x1f:关闭锁存,保存P0的数据到锁存器
第二部分 - 继电器和蜂鸣器初始化:
C1P0=0x00; // P0端口全部设置为0(低电平),关闭继电器和蜂鸣器
2P2=P2&0x1f|0xA0; // 打开锁存器V5
3P2&=0x1f; // 关闭锁存器V5
4
-
P0=0x00:将P0端口全部设为0,关闭所有继电器和蜂鸣器 -
通过V5锁存器保存此状态
硬件连接原理
这段代码使用了锁存器扩展I/O的设计方案,通过P2端口的控制线来选择不同的锁存芯片(V4、V5),实现对更多外设的控制。
LED函数
函数功能
这是一个LED使能控制函数 Led_Disp(),用于控制指定地址的LED灯亮或熄灭。
参数说明
-
addr:LED灯的地址/编号(0-7对应8个LED) -
enable:控制状态(非0表示点亮,0表示熄灭)
代码详细说明
第一步 - 静态变量声明:
C1static unsigned char temp=0x00; // 当前LED状态(0=熄灭)
2static unsigned char temp_old=0xff; // 前一次的LED状态
3
-
使用静态变量保存LED的状态,程序多次调用时状态保持
-
temp_old初始化为0xff,确保首次调用时一定会更新显示
第二步 - 更新LED状态:
C1if(enable)
2 temp|=0x01<<addr; // 点亮LED:该位设为1
3else
4 temp&=~(0x01<<addr); // 熄灭LED:该位清为0
5
-
temp|=0x01<<addr:将第addr位设为1(或运算),点亮该LED -
temp&=~(0x01<<addr):将第addr位清为0(与非运算),熄灭该LED
第三步 - 状态比较与显示:
C1if(temp!=temp_old) // 只有状态改变时才更新显示
2{
3 P0=~temp; // 取反:因为LED亮=低电平
4 P2=P2&0x1f|0x80; // 打开锁存器V4
5 P2=P2&0x1f; // 关闭锁存器V4
6 temp_old=temp; // 保存当前状态
7}
8
关键点总结
| 内容 | 说明 |
|---|---|
| 取反 | P0=~temp:因为LED一般为低电平亮(共阳极接法) |
| 锁存器 | 通过P2控制74HC373芯片来保存P0的数据 |
| 优化 | 仅在LED状态改变时才更新显示,提高效率 |
| 静态变量 | 保存历史状态,便于下次调用时比较 |
使用示例
C1Led_Disp(0, 1); // 点亮第0个LED
2Led_Disp(1, 1); // 点亮第1个LED
3Led_Disp(0, 0); // 熄灭第0个LED