C suli 7 - Impulzusok, multivibrátorok

2016-10-27

 

A kapcsolásunkat egy újabb LED-del egészítjük ki.

Emlékeztetőül az ATmega8 bekötése:

Impulzusok kezelésére szolgálnak a multivibrátornak nevezett áramkörök. Három fajtájuk van, az astabil, a bistabil, és a monostabil. Az astabil multivibrátor folyamatosan billeg a két állapota között. Az alábbi program felváltva fogja a két LED-et villogtatni. Azt is bemutatom, hogy egyszerűbb programokat hogyan lehet úgy megírni, hogy nem szükségesek mellé kommentek (szerintem). Ezt az áramkört használják lámpák villogtatására.


/*******************************************************************************
*
*   Author       -  Kiraly Tibor
*                   http://www.tkiraaly.hu
*   Date         -  2016.10.25.
*   Chip         -  ATmega8
*   Compiler     -  avr-gcc
*
*   c_suli_7_1.c
*   Astabil multivibrator, ket LED-et villogtatasa felvaltva
*
*******************************************************************************/

#define F_CPU  4 MHZ

#include "tkiraaly_atmega8.h"
#include <util/delay.h>

#define  LED1_KIMENET    PB0_OUTPUT
#define  LED1_BE         PB0_0
#define  LED1_KI         PB0_1

#define  LED2_KIMENET    PB1_OUTPUT
#define  LED2_BE         PB1_0
#define  LED2_KI         PB1_1


int main( void) 
{
   LED1_KI;
   LED2_KI;
   LED1_KIMENET;
   LED2_KIMENET;
   for(;;)
   {
      LED1_BE;
      LED2_KI;
      _delay_ms( 500);
      LED1_KI;
      LED2_BE;
      _delay_ms( 500);
   }
}

A bistabil multivibrátort az egyik bemenetére adott impulzussal az egyik állapotába lehet billenteni, míg a másik bementére adott impulzussala másik állapotába. Az alábbi program ha azt érzékeli, hogy lenyomjuk az A gombot, akkor a LED1 fog világítani, ha a B gombot, akkor pedig átvált a LED2-re. Ezzel az áramkörrel lehet kapcsolót pergésmentesíteni, vagy öntartó kapcsolást készíteni.


/*******************************************************************************
*
*   Author       -  Kiraly Tibor
*                   http://www.tkiraaly.hu
*   Date         -  2016.10.25.
*   Chip         -  ATmega8
*   Compiler     -  avr-gcc
*
*   c_suli_7_2.c
*   Bistabil multivibrator
*
*******************************************************************************/

#define F_CPU  4 MHZ

#include "tkiraaly_atmega8.h"

#define  LED1_KIMENET    PB0_OUTPUT
#define  LED1_BE         PB0_0
#define  LED1_KI         PB0_1

#define  LED2_KIMENET    PB1_OUTPUT
#define  LED2_BE         PB1_0
#define  LED2_KI         PB1_1

#define  A_FELHUZAS      PD1_PULLUP
#define  A_GOMB          PD1_RD == 0

#define  B_FELHUZAS      PD5_PULLUP
#define  B_GOMB          PD5_RD == 0


int main( void) 
{
   LED1_KI;
   LED2_KI;
   LED1_KIMENET;
   LED2_KIMENET;
   A_FELHUZAS;
   B_FELHUZAS;
   for(;;)
   {
      if ( A_GOMB)
      {
         LED1_BE;
         LED2_KI;
      }
      if ( B_GOMB)
      {
         LED1_KI;
         LED2_BE;
      }
   }
}

A monostabil multivibrátor a bemenetére érkező impulzus hatására átbillen, majd az időzítéstől függően visszabillen. Ilyen áramkört alkalmaznak folyosók világításának vezérlésekor is.


/*******************************************************************************
*
*   Author       -  Kiraly Tibor
*                   http://www.tkiraaly.hu
*   Date         -  2016.10.25.
*   Chip         -  ATmega8
*   Compiler     -  avr-gcc
*
*   c_suli_7_3.c
*   Bistabil multivibrator
*
*******************************************************************************/

#define F_CPU  4 MHZ

#include "tkiraaly_atmega8.h"
#include <util/delay.h>

#define  LED1_KIMENET    PB0_OUTPUT
#define  LED1_BE         PB0_0
#define  LED1_KI         PB0_1

#define  A_FELHUZAS      PD1_PULLUP
#define  A_GOMB          PD1_RD == 0


int main( void) 
{
   LED1_KI;
   LED1_KIMENET;
   A_FELHUZAS;
   for(;;)
   {
      if ( A_GOMB)
      {
         LED1_BE;
         _delay_ms( 2000);
         LED1_KI;
      }
   }
}

Most egy olyan áramkört is készítünk, amivel két játékos versenyez, ki nyomta meg előbb a gombot? Nem a makróimmal oldottam meg a feladatot, mert így egy időben kérdezzük le mindkét gombot. A while ciklusban találkozunk egy új elemmel. A C lehetőséget ad arra is, hogy egyszerre több változónak adjuk ugyanazt az értéket. Ezt látjuk itt is. Kiolvassuk a PIND regisztert. Mivel a gombok LOW aktívak, negáljuk a kiolvasott bájtot, kimaszkoljuk a kapcsolók bitjeit, és ezt eltároljuk az a változóba, majd továbbadjuk a while-nak is vizsgálatra. A while ciklus mindaddig fut, amíg valamelyik gombot le nem nyomják, vagyis amíg ez az érték 0. Azután kijelezzük melyik gombot nyomták meg, majd 2 másodperc várakozás után mindkét LED-et kikapcsoljuk.


/*******************************************************************************
*
*   Author       -  Kiraly Tibor
*                   http://www.tkiraaly.hu
*   Date         -  2016.10.25.
*   Chip         -  ATmega8
*   Compiler     -  avr-gcc
*
*   c_suli_7_4.c
*   Ki nyomta le elobb?
*
*******************************************************************************/

#define F_CPU  4 MHZ

#include "tkiraaly_atmega8.h"
#include <util/delay.h>

#define  LED1_KIMENET    PB0_OUTPUT
#define  LED1_BE         PB0_0
#define  LED1_KI         PB0_1

#define  LED2_KIMENET    PB1_OUTPUT
#define  LED2_BE         PB1_0
#define  LED2_KI         PB1_1

#define  A_FELHUZAS      PD1_PULLUP
#define  A_GOMB          PD1_RD == 0

#define  B_FELHUZAS      PD5_PULLUP
#define  B_GOMB          PD5_RD == 0


int main( void) 
{
   unsigned char a;
   LED1_KI;
   LED2_KI;
   LED1_KIMENET;
   LED2_KIMENET;
   A_FELHUZAS;
   B_FELHUZAS;
   for(;;)
   {
      while( ( a= (~PIND) & 0B00100010) == 0);   // olvasas, negalas, maszkolas, tarolas, varakozas gombnyomasra
      if ( a & 0B00000010) LED1_BE;              // A gomb eseten
      if ( a & 0B00100000) LED2_BE;              // B gomb eseten
      _delay_ms( 2000);                          // eredmeny kijelzes 2 sec
      LED1_KI;                                   // eredmeny torlese
      LED2_KI;
   }
}