Č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 &TRISB; 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 &TRISB; 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.