proj_pls/Sources/gpio_state_machine.c
2020-11-01 20:32:34 +01:00

146 lines
3.2 KiB
C

/*
* Ukazkovy program pro Programovani mikropocitacu
* Blikani LED ovladane pomoci tlacitka - stavovy automat.
* Vyuziva "vysokourovnovych" funkci jako pinWrite a pinRead.
* Tyto funkce jsou obsazeny v ovladaci drv_gpio.
*
*
*/
#include "MKL25Z4.h"
#include "drv_gpio.h"
// Prototypy funkci definovanych nize
void delay(void);
void led_update_state(void);
/* A4 */
#define SWITCH_PIN (4)
/* E5 */
#define SV1_PIN (5)
/* D3 */
#define H1_PIN (3)
/* C16 */
#define H2_PIN (16)
/* D2 */
#define H3_PIN (2)
static int i = 0;
void init(void);
static inline int is_key_pressed(int pin);
// Stavy, ve kterych se muze nachazet LED
typedef enum { LED_VYPNUTA, LED_BLIKA, } LED_state;
LED_state stav_led = LED_VYPNUTA;
int main(void)
{
GPIO_Initialize();
// Nastavit pin pro LED jako vystup
pinMode(LD3, OUTPUT);
// Piny pro tlacitka jako vstup
pinMode(SW1, INPUT);
pinMode(SW2, INPUT);
// Zapsat na pin log. 1, tim LED zhasne.
pinWrite(LD3, HIGH);
// Cekame na stisk tlacitek a podle toho ovladame LED
while(1)
{
// Testujeme tlacitka a podle toho aktualizujeme stav programu
led_update_state();
// Podle aktualniho stavu provedeme prislusnou akci
switch (stav_led)
{
case LED_VYPNUTA:
pinWrite(LD3, HIGH); // zhasneme LED (i opakovane)
delay(); // pockame chvili, at netestujeme stisk tlacitka zbytecne casto
break;
case LED_BLIKA:
pinWrite(LD3, LOW); // rozsvitit
delay();
pinWrite(LD3, HIGH); // zhasnout
delay();
break;
}
// TODO: kod pro stav BLIKA je sice takto srozumitelny, ale dlouho trva
// nez se znovu otestuje tlacitko. Zkuste kratce stisknout SW2; nekdy se
// blikani nezastavi...
// Dokazete program upravit tak, aby se tlacitko testovalo casteji?
}
/* Never leave main */
return 0;
}
void init(void)
{
// Enable clock for ports A, B, C, D, E
SIM->SCGC5 |= (SIM_SCGC5_PORTA_MASK | SIM_SCGC5_PORTB_MASK |
SIM_SCGC5_PORTC_MASK | SIM_SCGC5_PORTD_MASK | SIM_SCGC5_PORTE_MASK );
// Set pin function to GPIO
PORTA->PCR[SWITCH_PIN] = PORT_PCR_MUX(1);
PORTE->PCR[SV1_PIN] = PORT_PCR_MUX(1);
PORTD->PCR[H1_PIN] = PORT_PCR_MUX(1);
PORTC->PCR[H2_PIN] = PORT_PCR_MUX(1);
PORTD->PCR[H3_PIN] = PORT_PCR_MUX(1);
// Set pin direction
PTE->PDDR |= (1 << SV1_PIN); // SV1 is output - valve 1
// Hx are inputs (sensors)
PTD->PDDR &= ~(1 << H1_PIN);
PTC->PDDR &= ~(1 << H2_PIN);
PTD->PDDR &= ~(1 << H3_PIN);
// pull-ups are not needed.
}
/* Return 1 if the switch on given pin is pressed, 0 if not pressed. */
static inline int is_key_pressed(int pin)
{
if ((PTA->PDIR & (1 << pin)) == 0) {
return 1;
} else {
return 0;
}
}
// Aktualizuje stav LED
void led_update_state(void)
{
// Pokud je stisknuto tlacitko, menime stav
// Pokud je stisknuto SW1...
if ( pinRead(SW1) == LOW )
stav_led = LED_BLIKA; // ...stav bude blikani
// Pokud je stisknuto tlacitko SW2...
if ( pinRead(SW2) == LOW )
stav_led = LED_VYPNUTA; // ...stav bude zhasnuto
}
/* delay
* Jednoducha cekaci funkce - busy wait
* */
void delay(void)
{
unsigned long n = 700000L;
while ( n-- )
;
}
////////////////////////////////////////////////////////////////////////////////
// EOF
////////////////////////////////////////////////////////////////////////////////