D-Flipflop

Bild1Knowhow:

Ein D-FF übernimmt bei der steigenden Flanke die Daten und speichert sie bis zur nächsten steigenden Flanke. Der Ausgang ist undefiniert bis eine steigende Flanke kommt oder über einen RESET-Eingang das FF rückgesetzt wird.

Daten und steigende Flanken am Clock sollen sich nicht gleichzeitig ändern, da sonst nicht sicher ist, welches Datum gespeichert wird.

/*
* d_flipflop.cpp kner2013

 * emulate a d type flipflop: on rising edge of clk store an output the input data;

   CLK = PB0, DATA = PB1, Q = PB7

 */

 

 

#include <avr/io.h>

#define PORT PORTB

#define DDR DDRB

#define CLKPIN 0

#define DATAPIN 1

#define QPIN 7

 

typedef enum {UNDEFINED, HIGH,LOW} logic_t;

 

void setup();

 

logic_t DFF(logic_t clk, logic_t data){

    static logic_t q = UNDEFINED;

    static logic_t oldClkLevel = UNDEFINED;

 

    if ((oldClkLevel == LOW) && (clk == HIGH)) {

        //rising edge

        q=data;

 

    }

    oldClkLevel = clk;

    return q;

}

 

int main(void)

{   logic_t ck = UNDEFINED;

    logic_t dat = UNDEFINED;

    logic_t q = UNDEFINED;

    setup();

    while(1)

    {

        //read input

        uint8_t in = PINB;

        ck =  in & (1<<CLKPIN)?HIGH:LOW;

        dat =  in & (1<<DATAPIN)?HIGH:LOW;

        q = DFF(ck,dat);                

        switch (q){

          case HIGH: PORT |= (1<<QPIN);  break;  

          case LOW : PORT &= ~(1<<QPIN); break;

          default  :PORT &= ~(1<<QPIN);   //LOW when undefined

        }

    }   

}

void setup(){

    DDR  = 0b10000000; //PB7 as output

    PORT = 0b01111111; //PB7=0; Pullups active on PB6..PB0

}