368 lines
8.4 KiB
C++
368 lines
8.4 KiB
C++
// Ukazka odezvy programu
|
|
//
|
|
// Ocekavane chovani:
|
|
// Pri stisku tlacitka se spusti efekt, kdy blikaji postupne LED,
|
|
// Po uvolneni tlacitka LED zhasnou. Tedy blikani trva po dobu stisku tlacitka.
|
|
//
|
|
// Ukazano je postupne vylepsovani odezvy programu - aby program rychleji reagoval na
|
|
// uvolneni tlacitka. Verzi programu zvolte nize v #define VERSION
|
|
//
|
|
// Posledni zmena: 30.10.2020
|
|
///////////////////////////////////////////////
|
|
#include <iostream>
|
|
#include "simul_kl25z.h"
|
|
|
|
using namespace std;
|
|
|
|
//#include "MKL25Z4.h"
|
|
//#include "drv_gpio.h"
|
|
//#include "drv_systick.h"
|
|
#include <stdbool.h> // kvuli typu bool
|
|
|
|
|
|
|
|
#define SWITCH_PRESSED (1)
|
|
#define SWITCH_NOT_PRESSED (0)
|
|
|
|
#define KEY SW1
|
|
#define LED1 LD1
|
|
#define LED2 LD2
|
|
#define LED3 LD3
|
|
#define BLINK_DELAY 1000
|
|
|
|
// Prototypy funkci
|
|
void init(void);
|
|
int switch1_read(void);
|
|
void delay_debounce(void);
|
|
void LED_control(bool d1, bool d2, bool d3);
|
|
|
|
// Verze 4
|
|
// Program je vylepsen rozdelenim na jednotlive ulohy - tasky.
|
|
// Z pohledu odezvy je chovani stejne jako u verze 3, ale struktura programu je
|
|
// prehlednejsi a snadneji by se rozsiroval o dalsi cinnosti.
|
|
|
|
// Stavy programu
|
|
#define ST_LED1_ON 1
|
|
#define ST_LED2_ON 2
|
|
#define ST_LED3_ON 3
|
|
#define ST_OFF 4
|
|
#define ST_LED1_WAIT 5
|
|
#define ST_LED2_WAIT 6
|
|
#define ST_LED3_WAIT 7
|
|
|
|
// globalni promenna pro stav tlacitka SW1
|
|
bool SW1_pressed;
|
|
/* we'll do blinking, but not by default, values are -1/1 */
|
|
int blinkingpls = -1;
|
|
|
|
// Prototypy funkci
|
|
void TaskSwitches(void);
|
|
void TaskEffect(void);
|
|
void TaskL1(void);
|
|
void TaskL2(void);
|
|
void TaskL3(void);
|
|
|
|
int main(void) {
|
|
// inicializace ovladace pinu a delay
|
|
init();
|
|
|
|
while (1) {
|
|
|
|
TaskSwitches();
|
|
//TaskEffect();
|
|
TaskL1();
|
|
TaskL2();
|
|
TaskL3();
|
|
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
// Uloha, ktera se stara o obsluhu tlacitek
|
|
void TaskSwitches(void)
|
|
{
|
|
if (switch1_read() == SWITCH_PRESSED) {
|
|
SW1_pressed = true;
|
|
/* ignoring the legacy option above, when pressing the button the value of either
|
|
* 1 or -1 is multiplied by -1 resulting in the value assigned back to the variable
|
|
* being - again - either 1 or -1 (meaning the opposite of the one before) creating
|
|
* an easily switchable thingy
|
|
*/
|
|
blinkingpls *= -1;
|
|
} else {
|
|
SW1_pressed = false;
|
|
}
|
|
}
|
|
|
|
// Uloha, ktera se stara o blikani LED
|
|
void TaskEffect(void) {
|
|
// Stav totoho tasku.
|
|
// Promenna je static, aby si uchovala hodnotu mezi volanimi teto funkce,
|
|
// tj. aby nezanikla na konci funkce
|
|
static int state = ST_LED1_ON;
|
|
|
|
static uint32_t waitStart; // cas, kdy se rozvitila LED, musi byt static!
|
|
uint32_t currentTime; // aktualni cas, pomocna promenna
|
|
|
|
// Uloha efekt LED se provadi jen pri stisknutem tlacitku
|
|
if (SW1_pressed) {
|
|
switch (state) {
|
|
|
|
case ST_LED1_ON:
|
|
// Rozsvitit LED, ulozit aktualni cas a prejit do stavu cekani na
|
|
// uplynuti casu svitu teto LED.
|
|
LED_control(true, false, false);
|
|
waitStart = SYSTICK_millis();
|
|
state = ST_LED1_WAIT;
|
|
break;
|
|
|
|
case ST_LED1_WAIT:
|
|
// Kontrola jestli uz ubehlo dost casu abychom rozsvitili dalsi LED
|
|
// a pokud ano, prechod na dalsi stav
|
|
currentTime = SYSTICK_millis();
|
|
if (currentTime - waitStart >= BLINK_DELAY)
|
|
state = ST_LED2_ON;
|
|
break;
|
|
|
|
case ST_LED2_ON:
|
|
LED_control(false, true, false);
|
|
waitStart = SYSTICK_millis();
|
|
state = ST_LED2_WAIT;
|
|
break;
|
|
|
|
case ST_LED2_WAIT:
|
|
currentTime = SYSTICK_millis();
|
|
if (currentTime - waitStart >= BLINK_DELAY)
|
|
state = ST_LED3_ON;
|
|
break;
|
|
|
|
case ST_LED3_ON:
|
|
LED_control(false, false, true);
|
|
waitStart = SYSTICK_millis();
|
|
state = ST_LED3_WAIT;
|
|
break;
|
|
|
|
case ST_LED3_WAIT:
|
|
currentTime = SYSTICK_millis();
|
|
if (currentTime - waitStart >= BLINK_DELAY)
|
|
state = ST_LED1_ON;
|
|
break;
|
|
|
|
} // switch
|
|
} else {
|
|
// zhasnout LED pokud neni stisknuto tlacitko
|
|
LED_control(false, false, false);
|
|
state = ST_LED1_ON; // reset stavu tasku
|
|
}
|
|
|
|
} // TaskEffect
|
|
|
|
|
|
/////////////////////////////////
|
|
// Doba svitu/zhasnuti zelene LED
|
|
#define GREEN_ON_DELAY 200
|
|
#define GREEN_OFF_DELAY 700
|
|
/* as per the requirements */
|
|
#define L1_ON_DELAY 500
|
|
#define L1_OFF_DELAY 500
|
|
#define L2_ON_DELAY 200
|
|
#define L2_OFF_DELAY 650
|
|
#define L3_ON_DELAY 800
|
|
#define L3_OFF_DELAY 300
|
|
|
|
void TaskL1() {
|
|
static enum {
|
|
ST_LED_ON,
|
|
ST_ON_WAIT,
|
|
ST_LED_OFF,
|
|
ST_OFF_WAIT
|
|
|
|
} state = ST_LED_ON;
|
|
|
|
static uint32_t start_time;
|
|
if (blinkingpls > 0) {
|
|
|
|
switch (state) {
|
|
|
|
case ST_LED_ON:
|
|
pinWrite(LED1, LOW);
|
|
start_time = SYSTICK_millis();
|
|
state = ST_ON_WAIT;
|
|
break;
|
|
|
|
case ST_ON_WAIT:
|
|
if (SYSTICK_millis() - start_time >= L1_ON_DELAY)
|
|
state = ST_LED_OFF;
|
|
break;
|
|
|
|
case ST_LED_OFF:
|
|
pinWrite(LED1, HIGH);
|
|
start_time = SYSTICK_millis();
|
|
state = ST_OFF_WAIT;
|
|
break;
|
|
|
|
case ST_OFF_WAIT:
|
|
if (SYSTICK_millis() - start_time >= L1_OFF_DELAY)
|
|
state = ST_LED_ON;
|
|
break;
|
|
} // switch
|
|
} else {
|
|
/* turn the LED off and reset its state */
|
|
pinWrite(LED1, HIGH);
|
|
state = ST_LED_ON;
|
|
}
|
|
}
|
|
|
|
void TaskL2() {
|
|
static enum {
|
|
ST_LED_ON,
|
|
ST_ON_WAIT,
|
|
ST_LED_OFF,
|
|
ST_OFF_WAIT
|
|
|
|
} state = ST_LED_ON;
|
|
|
|
static uint32_t start_time;
|
|
if (blinkingpls > 0) {
|
|
|
|
switch (state) {
|
|
|
|
case ST_LED_ON:
|
|
pinWrite(LED2, LOW);
|
|
start_time = SYSTICK_millis();
|
|
state = ST_ON_WAIT;
|
|
break;
|
|
|
|
case ST_ON_WAIT:
|
|
if (SYSTICK_millis() - start_time >= L2_ON_DELAY)
|
|
state = ST_LED_OFF;
|
|
break;
|
|
|
|
case ST_LED_OFF:
|
|
pinWrite(LED1, HIGH);
|
|
start_time = SYSTICK_millis();
|
|
state = ST_OFF_WAIT;
|
|
break;
|
|
|
|
case ST_OFF_WAIT:
|
|
if (SYSTICK_millis() - start_time >= L2_OFF_DELAY)
|
|
state = ST_LED_ON;
|
|
break;
|
|
} // switch
|
|
} else {
|
|
/* turn the LED off and reset its state */
|
|
pinWrite(LED2, HIGH);
|
|
state = ST_LED_ON;
|
|
}
|
|
}
|
|
|
|
void TaskL3() {
|
|
static enum {
|
|
ST_LED_ON,
|
|
ST_ON_WAIT,
|
|
ST_LED_OFF,
|
|
ST_OFF_WAIT
|
|
|
|
} state = ST_LED_ON;
|
|
|
|
static uint32_t start_time;
|
|
if (blinkingpls > 0) {
|
|
|
|
switch (state) {
|
|
|
|
case ST_LED_ON:
|
|
pinWrite(LED3, LOW);
|
|
start_time = SYSTICK_millis();
|
|
state = ST_ON_WAIT;
|
|
break;
|
|
|
|
case ST_ON_WAIT:
|
|
if (SYSTICK_millis() - start_time >= L3_ON_DELAY)
|
|
state = ST_LED_OFF;
|
|
break;
|
|
|
|
case ST_LED_OFF:
|
|
pinWrite(LED3, HIGH);
|
|
start_time = SYSTICK_millis();
|
|
state = ST_OFF_WAIT;
|
|
break;
|
|
|
|
case ST_OFF_WAIT:
|
|
if (SYSTICK_millis() - start_time >= L3_OFF_DELAY)
|
|
state = ST_LED_ON;
|
|
break;
|
|
} // switch
|
|
} else {
|
|
/* turn the LED off and reset its state */
|
|
pinWrite(LED3, HIGH);
|
|
state = ST_LED_ON;
|
|
}
|
|
}
|
|
|
|
|
|
// Pomocne funkce
|
|
|
|
// inicializace
|
|
void init()
|
|
{
|
|
SYSTICK_initialize();
|
|
|
|
GPIO_Initialize();
|
|
|
|
pinMode(SW1, INPUT_PULLUP);
|
|
pinMode(LED1, OUTPUT);
|
|
pinMode(LED2, OUTPUT);
|
|
pinMode(LED3, OUTPUT);
|
|
pinMode(LED_GREEN, OUTPUT);
|
|
pinWrite(LED1, HIGH);
|
|
pinWrite(LED2, HIGH);
|
|
pinWrite(LED3, HIGH);
|
|
pinWrite(LED_GREEN, HIGH);
|
|
|
|
|
|
}
|
|
|
|
// Ovladani LED - parametr true znamena rozsvitit prislusnou LED, false zhasnout.
|
|
void LED_control(bool d1, bool d2, bool d3)
|
|
{
|
|
pinWrite(LED1, !d1);
|
|
pinWrite(LED2, !d2);
|
|
pinWrite(LED3, !d3);
|
|
}
|
|
|
|
/*
|
|
switch1_read
|
|
Cte stav tlacitka SW1 s osetrenim zakmitu.
|
|
Vraci SWITCH_NOT_PRESSED pokud tlacitko neni stisknuto,
|
|
SWITCH_PRESSED pokud je stisknuto.
|
|
|
|
Reads and debounces switch SW1 as follows:
|
|
1. If switch is not pressed, return SWITCH_NOT_PRESSED.
|
|
2. If switch is pressed, wait for about 20 ms (debounce),
|
|
then:
|
|
if switch is no longer pressed, return SWITCH_NOT_PRESSED.
|
|
if switch is still pressed, return SWITCH_PRESSED.
|
|
*/
|
|
int switch1_read(void)
|
|
{
|
|
int switch_state = SWITCH_NOT_PRESSED;
|
|
if ( pinRead(SW1) == LOW )
|
|
{
|
|
// tlacitko je stisknuto
|
|
|
|
// debounce = wait
|
|
SYSTICK_delay_ms(50);
|
|
|
|
// znovu zkontrolovat stav tlacitka
|
|
if ( pinRead(SW1) == LOW )
|
|
{
|
|
switch_state = SWITCH_PRESSED;
|
|
}
|
|
}
|
|
// vratime stav tlacitka
|
|
return switch_state;
|
|
}
|
|
|
|
|