www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Anfänger AVR RS-Flipflop nachbilden


Autor: Alex (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo zusammen,
wollte mal hören, ob das so ok ist. Im Simulator scheint es zu 
funktionieren.
//Initialisation
void init(void)
  {
  DDRB  = 0b11111100;
  PORTB = 0b00000011; //Pull Up
  }

int main(void)
  {
  
  init();
  
  //Main Loop
  while (1)
    {
    //RS-Flip Flop
    if (bit_is_set (PINB,PB0) && bit_is_clear (PINB,PB1))
      {
      PORTB |= (1 << PB7) | (1 << PB6);
      }
    if (bit_is_set (PINB,PB1))
      {
      PORTB &= ~((1 << PB7) | (1 << PB6));
      }
    }
  
  return 0;
  }

Autor: Michael H. (michael_h45)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Alex schrieb:
    if (bit_is_set (PINB,PB0) && bit_is_clear (PINB,PB1))
Lässt eine race condition zu, weil du PINB 2 mal einliest. Wenn sich 
PINB während der Zeit zwischen den Einlese-Vorgängen ändert, stimmt das 
Ergebnis nicht mehr.
Richtig wäre, PINB in einer Variable zu puffern und diese auswerten.
    if (bit_is_set (PINB,PB1))
Was passiert, wenn beide if-Abfragen wahr sind? Wird das Verhalten 
wirklich richtig abgebildet?

Autor: Martin H. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Man kanns auch übertreiben. Das oben wird durchaus für den 
normalgebrauch funktionieren. Bedenke, er/sie ist Anfänger. Da kommts 
selten auf so extreme Timings an.

Ich hätte es allerdings auch anders geschrieben:
   unint8_t buffer=0;

   while (1) {
       //RS-Flip Flop
       buffer = PINB;
       if ( buffer & PB1 )
           PORTB &= ~((1 << PB7) | (1 << PB6));
       else if ( buffer & PB0 )
           PORTB |= (1 << PB7) | (1 << PB6);
    }

Ist kürzer und für meine Augen übersichtlicher.
Man könnte auch
    switch( PINB & (PB0 | PB1) ) {
        case PB1:
            ; //reset
            break;
        case PB0:
            ; //set
            break;
    }
einbauen, das müsste es mMn auch tun, ich persönlich mag aber die 
if-else Konstruktion viel lieber!

lg Martin

Autor: Alex (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Vielen Dank für die Antworten.
#define F_CPU  3680000

#include <avr/io.h>
#include <util/delay.h>

void init(void)
  {
  DDRB  = 0b11111100;
  }

int main(void)
  {
  uint8_t buffer=0;
  init();

  while (1) 
    {
    
         //RS-Flip Flop
         buffer=PINB;
      if ( buffer & ( 1 << PB0 ) & !(buffer & ( 1 << PB1 ) ) ) 
      {
        PORTB = 0xFF;
      }
      if ( buffer & ( 1 << PB1 ) ) 
      {
        PORTB = 0x00;
      }

    }
       
   return 0;
   }
Ist das jetzt brauchbarer?
Gruß
Alex

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.