【问题标题】:Programming a ripple counter in C with JK flip flops使用 JK 触发器用 C 语言编写纹波计数器
【发布时间】:2014-01-13 18:30:03
【问题描述】:

我决定尝试用 C 语言编写触发器。我尝试过 D 和 JK 触发器(还没有预设和清除部分)。

我正在测试通过级联它们是否可以让它们产生一个简单的 4 位纹波计数器。在编写我的代码并运行它之后,它似乎产生了一些非常奇怪的结果,形式如下:

时钟:01010101010101010101

OuA:01100110011001100110

OuB:01000100010001000100

OuC:01111000011110000111

密码:01010000010100000101

其中 Clk 是输入时钟,OuA 是输出 A、OuB、输出 B 等。如您所见,OuA 和 OuC 的开关比似乎有点可接受,但 B 和 D 看起来真的很奇怪!

我的代码是:

#include <stdio.h>
#include <stdlib.h>

void DFF(int Clk, int D, int *Q, int *NQ)
{
    if(Clk)
    {
        *Q = D;
        *NQ = !*Q;
    }
}

void JKF(int Clk, int J, int K, int *Q, int *NQ)
{
    if(Clk&J&(!K))
    {
        *Q = 1;
        *NQ = 0;
    }
    if(Clk&K&(!J))
    {
        *Q = 0;
        *NQ = 1;
    }
    if(Clk&J&K)
    {
        *Q = *NQ;
        *NQ = !*Q;
    }
}

int main()
{
    FILE *fptr;
    const int Len = 20;
    int Clk = 1, ClkA[Len];
    int n, OA[Len], OB[Len], OC[Len], OD[Len];
    int Q = 0, NQ = 1;
    int Q2 = 0, NQ2 = 1;
    int Q3 = 0, NQ3 = 1;
    int Q4 = 0, NQ4 = 1;

    for(n=0; n<Len; n++)
    {
        Clk^=1;

        JKF(Clk, 1, 1, &Q, &NQ);
        JKF(Q, 1, 1, &Q2, &NQ2);
        JKF(Q2, 1, 1, &Q3, &NQ3);
        JKF(Q3, 1, 1, &Q4, &NQ4);

        ClkA[n] = Clk;
        OA[n] = Q;
        OB[n] = Q2;
        OC[n] = Q3;
        OD[n] = Q4;
    }

    fptr = fopen("c:/ff.txt", "w");

    fprintf(fptr, "Clk: ");
    for(n = 0; n<Len; n++) fprintf(fptr, "%d", ClkA[n]);
    fprintf(fptr, "\nOuA: ");
    for(n = 0; n<Len; n++) fprintf(fptr, "%d", OA[n]);
    fprintf(fptr, "\nOuB: ");
    for(n = 0; n<Len; n++) fprintf(fptr, "%d", OB[n]);
    fprintf(fptr, "\nOuC: ");
    for(n = 0; n<Len; n++) fprintf(fptr, "%d", OC[n]);
    fprintf(fptr, "\nOuD: ");
    for(n = 0; n<Len; n++) fprintf(fptr, "%d", OD[n]);

    fclose(fptr);

    return 0;
}

我对清晰度表示歉意,我知道它可能不是特别有效,但有人可以澄清一下输出发生了什么吗?

干杯!

【问题讨论】:

    标签: c counter flip flip-flop


    【解决方案1】:

    稍微改进的版本....

    #include <stdio.h>
    #include <stdlib.h>
    
    typedef struct _JKFF
    {
        int clk;
        int q;
        int nq;
    }JKFF;
    
    
    void JKFFn(int Clk, int J, int K, _JKFF * jkff)
    {
        if ((Clk != jkff->clk) && !Clk)
        {   //Triggering FF on the falling edge
            if(J& (!K))
            {
                jkff->q = 1;
            }
            if(K &(!J))
            {
                jkff->q = 0;
            }
            if(J & K)
            {
                jkff->q = !jkff->q;
            }
            jkff->nq = !jkff->q;
        }
        jkff->clk = Clk;
    }
    
    
    int main()
    {
        FILE *fptr;
        const int Len = 80;
        int Clk = 1, ClkA[Len];
        int n, OA[Len], OB[Len], OC[Len], OD[Len];
    
        _JKFF jkff[4];
        memset(jkff, 0, sizeof(jkff));
    
        for(n=0; n<Len; n++)
        {
            Clk^=1;
    
            JKFFn(Clk, 1, 1, &jkff[0]);
            JKFFn(jkff[0].q, 1, 1, &jkff[1]);
            JKFFn(jkff[1].q, 1, 1, &jkff[2]);
            JKFFn(jkff[2].q, 1, 1, &jkff[3]);
    
            ClkA[n] = Clk;
            OA[n] = jkff[0].q;
            OB[n] = jkff[1].q;
            OC[n] = jkff[2].q;
            OD[n] = jkff[3].q;
        }
    
        fptr = fopen("ff.txt", "w");
    
        fprintf(fptr, "Clk: ");
        for(n = 0; n<Len; n++) fprintf(fptr, "%d", ClkA[n]);
        fprintf(fptr, "\nOuA: ");
        for(n = 0; n<Len; n++) fprintf(fptr, "%d", OA[n]);
        fprintf(fptr, "\nOuB: ");
        for(n = 0; n<Len; n++) fprintf(fptr, "%d", OB[n]);
        fprintf(fptr, "\nOuC: ");
        for(n = 0; n<Len; n++) fprintf(fptr, "%d", OC[n]);
        fprintf(fptr, "\nOuD: ");
        for(n = 0; n<Len; n++) fprintf(fptr, "%d", OD[n]);
    
        fclose(fptr);
    
        return 0;
    }
    

    【讨论】:

    • 这太完美了,干杯!也很好地介绍了如何使用结构。谢谢。
    【解决方案2】:

    根据函数JKF的实现,是电平触发而不是边沿触发。

    时钟:010

    OuA:011

    OuB:010

    在第三次时钟转换时,OuA 仍为“1”。 因此 JKF(Q, 1, 1, &Q2, &NQ2);将 OuB 切换为逻辑 0。

    在JKF函数实现中,必须考虑时钟的转换,而不是时钟的当前级别。

    作为一种简单的补救措施,可以对 for 循环进行如下更改以将时钟转换考虑在内。

    for(n=0; n<Len; n++)
    {
        Clk^=1;
    
        JKF(Clk, 1, 1, &Q, &NQ);
        if (n > 0)
        {
            if (OA[n -1] != Q)
            {
                JKF(Q, 1, 1, &Q2, &NQ2);
            }
    
            if (OB[n -1] != Q2)
            {
                JKF(Q2, 1, 1, &Q3, &NQ3);
            }
    
            if (OC[n -1] != Q3)
            {
                JKF(Q3, 1, 1, &Q4, &NQ4);
            }
        }
        else
        {
            JKF(Q, 1, 1, &Q2, &NQ2);
            JKF(Q2, 1, 1, &Q3, &NQ3);
            JKF(Q3, 1, 1, &Q4, &NQ4);
        }
    
    
        ClkA[n] = Clk;
        OA[n] = Q;
        OB[n] = Q2;
        OC[n] = Q3;
        OD[n] = Q4;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多