Программирование счетчика пульсаций на C с JK-триггерами

Я решил попробовать программировать триггеры на C. У меня была попытка сделать триггер D и JK (пока без предустановленных и чистых секций).

Я проверяю, могу ли я, каскадируя их, заставить их производить простой 4-битный счетчик пульсаций. После написания моего кода и его запуска он, кажется, дает действительно странные результаты в виде:

Код: 01010101010101010101

УА: 01100110011001100110

УБ: 01000100010001000100

ОК: 01111000011110000111

Уд: 01010000010100000101

Где Clk — входной такт, OuA — выход A, OuB, выход B и т. д. Как видите, OuA и OuC кажутся несколько приемлемыми с соотношением on/off, но 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;
}

Я извиняюсь за ясность, и я знаю, что это, вероятно, не особенно эффективно, но может ли кто-нибудь прояснить, что происходит с выводами?

Ваше здоровье!


person Pyrohaz    schedule 26.12.2013    source источник


Ответы (2)


Согласно реализации функции JKF, она запускается по уровню, а не по фронту.

Код: 010

УА: 011

УБ: 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;
}
person Duleeka Gunatilake    schedule 26.12.2013

Немного улучшенная версия....

#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;
}
person Duleeka Gunatilake    schedule 26.12.2013
comment
Это было идеально, ура! Дает мне хорошее представление об использовании структур. Спасибо. - person Pyrohaz; 27.12.2013