• 1
  • 2

Oživujeme tlačidlá #2

. .

Článok, ktorý poukazuje na fungovanie a zostavenie tlačidiel 2

 

 

Doporučené preštudovať: Oživujeme tlačidlá #1



V minulej časti som ukázal základné spôsoby práce so spínačmi.
V tomto článku navrhnem ešte pár príkladov použitia tlačidiel.

Budem vychádzať z použitia univerzálneho modulu, ktorý som uverejnil v minulom článku Oživujeme tlačidlá #1 a navrhnem len funkcie vychužívajúce jadro modulu.

Pri návrhu budem pracovať s niekoľkými LEDs zapojenými na registry PORTB a portoch RB1-2-3-7.

Schéma zapojenia:




switchers.h


struct _switch_ {
    struct __attribute__ ((packed)) {
       struct __attribute__ ((packed)) {
          volatile unsigned int *Port;
          volatile unsigned int *Tris;
             }Direct;
       struct __attribute__ ((packed)) {
          int * Pins;
          int pin_size;
          int Pin;
            }Config;
         }Switch;

    struct __attribute__ ((packed)) {
       struct __attribute__ ((packed)) {
          volatile unsigned int *Port;
          volatile unsigned int *Tris;
             }Direct;
       struct __attribute__ ((packed)) {
          int * Pins;
          int pin_size;
          int Pin;
            }Config;
         }Leds;

    struct __attribute__ ((packed)) {
       int i;
       int count;
       bool is_activate;
          }Tmp;
}SW;


void Switch_Config(void)
{
   int switch_array[]={0};
   int led_array[]={1,2,3,7};

   int err,err2 = 564;

   if (*SW.Switch.Direct.Port == PORTA && PORTA != __No__Used__ && TRISA != __No__Used__)
     { SW.Switch.Direct.Tris = uintptr &TRISA; err=0; }
   if (*SW.Switch.Direct.Port == PORTB && PORTB != __No__Used__ && TRISB != __No__Used__)
     { SW.Switch.Direct.Tris = uintptr ⧍ err=0; }
   if (*SW.Switch.Direct.Port == PORTC && PORTC != __No__Used__ && TRISC != __No__Used__)
     { SW.Switch.Direct.Tris = uintptr &TRISC; err=0; }
   if (*SW.Switch.Direct.Port == PORTD && PORTD != __No__Used__ && TRISD != __No__Used__)
     { SW.Switch.Direct.Tris = uintptr &TRISD; err=0; }
   if (*SW.Leds.Direct.Port == PORTA && PORTA != __No__Used__ && TRISA != __No__Used__)
     { SW.Leds.Direct.Tris = uintptr &TRISA; err2=0; }
   if (*SW.Leds.Direct.Port == PORTB && PORTB != __No__Used__ && TRISB != __No__Used__)
     { SW.Leds.Direct.Tris = uintptr ⧍ err2=0; }
   if (*SW.Leds.Direct.Port == PORTC && PORTC != __No__Used__ && TRISC != __No__Used__)
     { SW.Leds.Direct.Tris = uintptr &TRISC; err2=0; }
   if (*SW.Leds.Direct.Port == PORTD && PORTD != __No__Used__ && TRISD != __No__Used__)
     { SW.Leds.Direct.Tris = uintptr &TRISD; err2=0; }

   if(err==0)
    {
       SW.Switch.Config.pin_size = sizeof(switch_array)/sizeof(int);
       SW.Switch.Config.Pins = malloc(SW.Switch.Config.pin_size);

       for (SW.Tmp.i=0; SW.Tmp.i<SW.Switch.Config.pin_size; SW.Tmp.i++)
           {
              SW.Switch.Config.Pins[SW.Tmp.i] = switch_array[SW.Tmp.i];
           }

       for (SW.Tmp.i = 0; SW.Tmp.i < SW.Switch.Config.pin_size; SW.Tmp.i++)
           {
              Init_Port(*SW.Switch.Direct.Port,SW.Switch.Config.Pins[SW.Tmp.i],"digital");
              Config_IN(*SW.Switch.Direct.Tris,SW.Switch.Config.Pins[SW.Tmp.i]);
           }
    }

   if(err2==0)
    {
       SW.Leds.Config.pin_size = sizeof(led_array)/sizeof(int);
       SW.Leds.Config.Pins = malloc(SW.Leds.Config.pin_size);

       for (SW.Tmp.i=0; SW.Tmp.i<SW.Leds.Config.pin_size; SW.Tmp.i++)
           {
              SW.Leds.Config.Pins[SW.Tmp.i] = led_array[SW.Tmp.i];
           }

       for (SW.Tmp.i=0; SW.Tmp.i < SW.Leds.Config.pin_size; SW.Tmp.i++)
           {
              Init_Port(*SW.Leds.Direct.Port,SW.Leds.Config.Pins[SW.Tmp.i],"digital");
              Config_OUT(*SW.Leds.Direct.Tris,SW.Leds.Config.Pins[SW.Tmp.i]);
              Bit_Clr(*SW.Leds.Direct.Port,SW.Leds.Config.Pins[SW.Tmp.i]);
           }
    }

   if(err==0&&err2==0)
    {
       SW.Tmp.count = 0;
       SW.Tmp.is_activate = false;
    }
}

void Switch_Leds1(void)
{
   if((Get_Switch(*SW.Switch.Direct.Port,SW.Switch.Config.Pins[0])) !=0 )
    {
       while((Get_Switch(*SW.Switch.Direct.Port,SW.Switch.Config.Pins[0])) !=0)
              {
              }
       Delay_ms(12);
       if(SW.Tmp.count < SW.Leds.Config.pin_size)
        {
           Bit_Set(*SW.Leds.Direct.Port,SW.Leds.Config.Pins[SW.Tmp.count]);
           SW.Tmp.count++;
        }
    }
}

void Switch_Leds2(void)
{
   if((Get_Switch(*SW.Switch.Direct.Port,SW.Switch.Config.Pins[0])) !=0 )
    {
       while((Get_Switch(*SW.Switch.Direct.Port,SW.Switch.Config.Pins[0])) !=0)
              {
              }
       Delay_ms(12);
       if(SW.Tmp.count < SW.Leds.Config.pin_size)
        {
           Bit_Set(*SW.Leds.Direct.Port,SW.Leds.Config.Pins[SW.Tmp.count]);
        } else
             {
                for(SW.Tmp.i=0; SW.Tmp.i < SW.Leds.Config.pin_size; SW.Tmp.i++)
                    {
                       Bit_Clr(*SW.Leds.Direct.Port,SW.Leds.Config.Pins[SW.Tmp.i]);
                    }
                SW.Tmp.count=-1;
              }
        SW.Tmp.count++;
    }
}

void Switch_Leds3(void)
{
   if((Get_Switch(*SW.Switch.Direct.Port,SW.Switch.Config.Pins[0])) !=0 )
    {
       while((Get_Switch(*SW.Switch.Direct.Port,SW.Switch.Config.Pins[0])) !=0)
              {
              }
       Delay_ms(12);
       if(SW.Tmp.count < SW.Leds.Config.pin_size && SW.Tmp.is_activate == false)
        {
           Bit_Set(*SW.Leds.Direct.Port,SW.Leds.Config.Pins[SW.Tmp.count]);
           SW.Tmp.count++;
         } else
              {
                 SW.Tmp.is_activate = true;
                 SW.Tmp.count--;
                 Bit_Clr(*SW.Leds.Direct.Port,SW.Leds.Config.Pins[SW.Tmp.count]);
                 if(SW.Tmp.count <= 0)
                  {
                     SW.Tmp.is_activate = false;
                  }
               }
     }
}
 




main.c

#include "config_diall.h"
#include "switchers.h"
#include "header_words.h"

char *PageSys(void)
{
   return "0x21";
}


int main(void)
{
   SW.Switch.Direct.Port = uintptr &PORTB;
   SW.Leds.Direct.Port = uintptr &PORTB;
   Switch_Config();

   while(1)
          {
             Switch_Leds3();
          }
}
 



Popis metod


Stisknutiami rozsvieť

Metoda Switch_Leds1() zaznamenáva stlačenie tlačidla, pričom pri každom stlačení rozsvieti postupne každú LED diodu definovanú v dočasnom poli v Switch_Config().
Po rozsvietení všetkých LED metoda na ďalšie stláčanie nereaguje a LEDs sú rozsvietené.

                                                                  

 


Stisknutiami rozsvieť a opakuj

Metoda Switch_Leds2() zaznamenáva stláčanie spínača a ako metoda Switch_Leds1() ich postupne rozsviecuje. Po rozsvietení poslednej LED sa pri ďalšom stlačení všetky zhasnú a znovu sa začína rozsviecovať od prvej. Metoda cyklicky opakuje funkcionalitu stláčaní.

                                                

 


Stisknutiami rozsvieť a od konca zhasni

Metoda Switch_Leds3() pri každom stlačení postupne rozsvieti všetky definované LEDs. V okamihu rozsvietenia poslednej LED diody, začne pri stláčaní zhasínať LEDs od konca.