MezData-Logo Creative Commons License 417 :AVR: Simulation von Digital-Schaltungen

Schlüsselwörter: SPS, Port, Mikrokontroller, C

Grundlagen

An den Port-Pins eines µC werden Taster und LED angeschlossen. Der µC soll die Funktion logischer Digital-Schaltungen simulieren. In der C-Umgebung kann nur auf die Gesammtheit aller Port-Bits zugegriffen werden, daher spielt das geschickte Bit-Maskieren hier eine grosse Rolle.

Vordefinierte Konstanten in den Include-Dateien

PortPinsDa sich die Adressen der Port-Register der verwendeten µC unterscheiden können und zur besseren Lesbarkeit des Quellcodes sind in den Include-Dateien des jeweiligen Kontrollers für jedes Register und jedes Bit entsprechende Bezeichnungen vordefiniert. Beispiel:

Priorität der Operatoren beachten

Siehe Ausdrücke und Operatoren. Bindungsstärke der Operatoren nimmt ab: ==,!= > & > ^ > | > && > ||

Beispiel für typischen Fehler: (PINB&3==3) wird so berechnet: (PINB&(3==3)) ergibt PINB&1. Daher Klammern setzen ((PINB&3)==3).

Boolsche Interpretation von nicht boolschen Ausdrücken in C

In C werden die Werte 0, 0.0, null als false interpretiert, alle anderen Werte, auch negative, als true.

Beispiel: Bei if ((PINB&3)!=0) kann C der Vergleich !=0 weg gelassen werden, if (PINB&3) führt zum selben Ergebnis.

Grundprinzip

Im ersten Lösungsquelltext ist eine Initalisierung (enspricht bei Arduino dem setup) und die Endlos-whileschleife (loop) enthalten, die weiteren Quelltexte enthalten nur noch den Inhalt der While-Scheife. Auch wurden Alternativen in der Darstellung der Werte vorgeschlagen: 0b00001000 = 8 = 0x08 = 1<<3

Und Baustein

#include <avr/io.h>  // Einbinden der Konstanten
int main(){          // Hauptprogramm DDRB = 0b00001000; // PB3 auf Ausgang //DDRB = 1<<PB3;
  while (1){         // Endlosschleife
    if((PINB&3)==3){ // PB0 & PB1 
      PORTB |= 8;    // PB3 <- 1 //PORTB |= 0b00001000;
    //PORTB |= 1<<PB3;  }
    else{
      PORTB &= ~8;    // PB3 <- 0 //PORTB &= 0b11110111;
    //PORTB &= ~(1<<PB3); } } }

and Lesen von PINB spricht alle Bits von PB an. Bei der Verarbeitung sind aber nur PB1 und PB0 relevant, die anderen Bits sollen ausgeblendet werden. Dies wird durch eine Und-Verknüpfung mit einer Maske erreicht, die alle unbeteiligten Bits ausblendet.

Maske: PINB & 0b11

Nach der Maskierung kann der Wert zwischen 0..3 liegen, der Und-Bausten soll beim Wert 3 eine 1 ausgeben, d.h. PB3 gesetzt werden sonst soll PB3 gelöscht werden.

Setzen   von PB3: PORTB |= 1<<PB3;       // 0b00001000

Löschen von PB3: PORTB &= ~(1<<PB3); // 0b11110111

 

Oder Baustein

or2
Quellcode [b2_or2.c]
if((PINB&3)!=0){ // PB0 | PB1
  PORTB |=8;   // PB3 <- 1
}
else{
  PORTB &=~8;   // PB3 <- 0
}
Zuerst die Maske bilden und dann mit dem Wert vergleichen,
bei dem das Oder nicht Eins sein soll.

SR-FlipFlop

rs-ff
Quellcode [b3_rsff.c]
if(PINB&2){    // PB1 = 1 ?
  PORTB &=~4;  // PB2 <- 0
}
else if(PINB&1){ // PB0 = 1 ?
  PORTB |=4;     // PB2 <- 1
}
Wegen der Rücksetzpriorität wird zuerst das R-Signal überprüft.

Taktflanken gesteuertes D-FF

dff-flanke
Quellcode [b4_dff-flanke.c]
byte merker=0; // merkerbyte
if(!merker && (PINB&2)){ // PB1 steigende Flanke
  if(PINB&1){ // PB2 <- PB0
    PORTB |=4;
  }
  else {
    PORTB &=~4;
  }
}
merker = PINB&2;
Im der Variablen merker wird der letzte Zustand des PB1 gemerkt,
um die steigende Flanke erkennen zu können.

Beispiele und Übungen

and3 Lösung anzeigen..
 
Oder und Xor Lösung anzeigen..
 
Und3 mit RS-FF Lösung anzeigen..
 
Nor RS-FF Lösung anzeigen..
 
Pegel D-FFr Lösung anzeigen..