D-Flipflop
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
}