锁存器触发器

发布时间:2023年12月29日

前言

本篇文章介绍触发器
触发器是这样一种电路实现,触发器有一个控制输入端和一个数据输入端,触发器的特点是可以保存数据输入的信息

  • 如果控制输入端设置为高电平,数据输入端的数据将会改变输出的数据
  • 否则,数据输入端不对输出数据产生影响

SR锁存器

SR锁存器是最简单的一类触发器,通过两个或非门实现,电路图如下:
在这里插入图片描述

我们再次给出或非门的输入输出逻辑关系:
输入 A 输入 B 输出 0 0 1 0 1 0 1 0 0 1 1 0 \begin{array}{|c|c|c|} \hline 输入A&输入B&输出\\ \hline 0&0&1\\ \hline 0&1&0\\ \hline 1&0&0\\ \hline 1&1&0\\ \hline \end{array} 输入A0011?输入B0101?输出1000??
SR锁存器的特点如下:

  • 默认 S = 0 S=0 S=0 R = 0 R=0 R=0 Q Q Q=0, Q  ̄ \overline{Q} Q?=1
  • 当第一次设置 S S S端为1时, Q Q Q=1, Q  ̄ \overline{Q} Q?=0
  • 然后再次断开 S S S的值不会影响 Q Q Q Q  ̄ \overline{Q} Q?的值
  • 如果设置 R R R端为1, Q Q Q=0, Q  ̄ \overline{Q} Q?=1
  • 然后再次断开 R R R的值不会影响 Q Q Q Q  ̄ \overline{Q} Q?的值

SR锁存器有两点需要注意:

  1. S = 0 S=0 S=0 R = 0 R=0 R=0时, Q Q  ̄ Q\overline{Q} QQ?维持之前的状态不变
  2. 不能同时设置 S = 1 S=1 S=1 R = 1 R=1 R=1,因为这个时候状态是不可预测的,这样SR锁存器就没有意义了。

SR锁存器可以简化为带有输入和输出标志的小框图:
在这里插入图片描述

SR锁存器最突出的特点在于,它可以记住哪个输入端的最终状态为 1。

触发器

触发器与锁存器的不同在于, 它除了置1、置0输人端以外,又增加了一个触发信号输人端。 只有当触发信号到来时,触发器才能按照输人的置 1、置0信号置成相应的状态,并保持下去。 我们将这个触发信号称为时钟信号(CLOCK),记作CLK。当系统中有多个触发器需要同时动作时,就可以用同一个时钟信号作为同步控制信号了

D型触发器

D型触发器由两个或非门组成的SR锁存器加上两个与门组成的逻辑电路
D型触发器有两个输入端:

  • 数据控制端,控制端可以看作是CLK
  • 数据输入端,数据输入端本来有两个,就是SR锁存器的S端和R端,但是在SR锁存器这一节中我们说过,SR都为0的话保持之前的状态不变,并且SR不能都为1,也就是说SR值一样的时候对我们没什么意义,我们需要的是记住数据输入端的状态,所以我们用一个输入输入端,通过添加一个反相器来引出SR端。参照下面的电路图

D型触发器的特点是:只有当数据控制端为高电平时,数据输入端的状态才会被保存
D型触发器比SR触发器复杂一些,电路图如下:
在这里插入图片描述

根据D型触发器的特点我们可以想到,D型触发器可以保存数据,就是当我需要保存输入数据的时候,只需要把控制端的时钟置成高位即可。并且时钟变为低位后,输入数据不会改变已经保存的数据。

下面列出D型触发器的状态值:

  • 时钟为1,数据端为1, Q Q Q=1, Q  ̄ \overline{Q} Q?=0
  • 时钟为1,数据端为0, Q Q Q=0, Q  ̄ \overline{Q} Q?=1
  • 时钟为0,数据端为1或者0, Q Q Q不变, Q  ̄ \overline{Q} Q?不变

关于D型触发器的思考:
D型触发器的特点决定了一个可能的情况,就是当时钟为1时,如果数据端的数据发生了改变,每次改变都会产生新的状态。对于某些情况而言,可能需要的仅仅是时钟切换到1时保存数据输入的值,然后不在改变。一个是区间,一个是即时,对于即时的改变,有一种新的触发器,叫做边沿触发器

边沿触发器

边沿触发器的特点:
只有当时钟从0跳变到1时,才会引起输出的改变。边沿触发器与D型触发器的区别在于,在D型触发器中,当时钟输入为0时, 数据端输入的任何改变都不会影响输出;而在边沿触发器中,当时钟输入为1时,数据端输入的改变也不会影响输出。只有在时钟输入从0变到1的瞬间,数据端的输入才会影响边沿触发器的输出

边沿触发器是由两个D型触发器连接而成的,电路图如下:
在这里插入图片描述

可以推导一下边沿触发器的规则:

  • 当CLK=0时,前面的D型触发器能保存数据端的数据,并且会一直保存最新的数据,后面的D型触发器因为CLK=0,不保存数据
  • 当CLK从0变成1时,前面的D型触发器关闭,输出的一直是最新的数据,后面的D型触发器打开,将前面的数据保存到 Q Q Q Q  ̄ \overline{Q} Q?
  • 当CLK保持1时,因为前面的D型触发器已经关闭,输出的一直是之前的数据,所以后面的D型触发器一直保存的是CLK从0变成1时的数据。
  • 当CLK从1变成0时,回到第一步。

最后给出锁存器触发器的C语言实现
可以参考Git地址

/**
 * sr锁存器的C语言实现
 * s:置位项
 * r:重置项
 * q:输入Q
 * q1:输出Q1
 */
extern void sr_lock(long s, long r,long *q,long *q1);

/**
 * D型触发器
 * clock:时钟输入
 * data:数据输入
 * q:输出Q
 * q1:输出Q1
 */
extern void d_trigger(long clock, long data,long *q,long *q1);

/**
 * 边沿触发器
 * clock:时钟输入
 * data:数据输入
 * q_0:前面的D型触发器的输出数据
 * q_1:前面的D型触发器的输出数据
 * q:输出Q
 * q1:输出Q1
 */
extern void b_trigger(long clock, long data,long *q_0,long *q_1,long *q,long *q1);
void sr_lock(long s, long r,long *q,long *q1)
{
    for(int i =0;i<sizeof(long)*8;i++)
    {
        // 输入都是0,状态不变
        if(((1<<i)&s) == 0 && ((1<<i)&r) == 0)
        {
            continue;
        }
        // 输入都是1,理论上要避免
        if(((1<<i)&s) != 0 && ((1<<i)&r) != 0)
        {
            continue;
        }
        // s==1 r==0
        if(((1<<i)&s) != 0)
        {
            (*q) |= 1<<i;
        }
        else// s==0 r==1
        {
            (*q) &= ~(1<<i);
        }
    }
    (*q1) = ~(*q);
}

void d_trigger(long clock, long data,long *q,long *q1)
{
    long in_1 = alu_and(clock, data, sizeof(long)*8);
    long in_2 = alu_and(clock, ~data, sizeof(long)*8);
    sr_lock(in_1,in_2,q,q1);
}

void b_trigger(long clock, long data,long *q_0,long *q_1,long *q,long *q1)
{
    d_trigger(~clock,data,q_0,q_1);
    long in_1 = alu_and(clock, *q_0, sizeof(long)*8);
    long in_2 = alu_and(clock, *q_1, sizeof(long)*8);
    sr_lock(in_1,in_2,q,q1);
}
文章来源:https://blog.csdn.net/b1049112625/article/details/135290330
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。