1.分析原理图
最好自己先去查查138以及ULN2003的使用方法,我这里直接讲思路。
由上图我们可以看到如果138输入ABC=101,则输出Y5=0,此时若WR通过跳线帽接地则Y5C=1
,于是573(U9)处于输出跟随输入P0状态,此时若P06=1,则573输出Q7=1,ULN2003输入IN7=1,但是由于ULN2003输入后芯片内部先经过非门在输入到达林顿管,所以输出OUT7=0,蜂鸣器响。然后我们再改变138输入ABC的值使Y5=1,则573进入锁存状态,此时无论P0口为任何值,蜂鸣器都会一直响。
在这里我遇到一个很奇怪的问题:如果在573(U9)锁存的时候ABC=000,573(U6)不知道为啥会解锁。但是我用ABC=110去锁存就不会出现这个情况。理论上用只要用ABC =000~110去锁存都可以啊,为什么用000去锁存就会短暂出现一些不定态时U6解锁呢,后面试试换一颗138试试吧
2.封装代码
//1打开 0关闭
void Set_Beep(bit Status)
{
//选中蜂鸣器所在573
P25=1;P26=0;P27=1; //74HC138-->Y5=0,else=1-->Y5C=1,else=0
P06=Status; //ULN2003输入经过非门送入达林顿管,低电平有效
P25=1;P26=1;P27=0;//锁存数据
}
void Set_Relay(bit Status)
{
//选中蜂鸣器所在573
P25=1;P26=0;P27=1; //74HC138-->Y5=0,else=1-->Y5C=1,else=0
P04=Status; //ULN2003输入经过非门送入达林顿管,低电平有效
P25=1;P26=1;P27=0;//锁存数据
}
这里我也发现一个小问题,如果上次的P0口状态已经改变了,假如现在运行Set_Beep(),那在解锁后,输出会立即跟随输入,那继电器的状态就会改变,所以我觉得这里需要用全局变量来暂存旧的状态,这是修改过后的代码:
#include "BeepRelay.h"
bit Beep_Status=0; //初始关闭
bit Relay_Status=0; //初始关闭
//1打开 0关闭
void Set_Beep(bit Status)
{
//选中蜂鸣器所在573
P25=1;P26=0;P27=1; //74HC138-->Y5=0,else=1-->Y5C=1,else=0
P04=Relay_Status; //使继电器保持原状态
P06=Status; //ULN2003输入经过非门送入达林顿管,低电平有效
Beep_Status=Status; //记录蜂鸣器状态
P25=1;P26=1;P27=0;//锁存数据
}
void Set_Relay(bit Status)
{
//选中蜂鸣器所在573
P25=1;P26=0;P27=1; //74HC138-->Y5=0,else=1-->Y5C=1,else=0
P06=Beep_Status;
P04=Status; //ULN2003输入经过非门送入达林顿管,低电平有效
Relay_Status=Status;
P25=1;P26=1;P27=0;//锁存数据
}