Programowanie timera dla zegarka ez430 chronos

ez430 to zegarek zaprojektowany na bazie procesora o wyjątkowo niskim poborze mocy firmy Texas Instruments. Moją pierwszą poważną modyfikacją jego kodu źródłowego było wyposażenie go w timer, odliczający czas „w dół”, w przedziale 23 godziny ÷ 1 minuta – do zera. W poprzednim wpisie pisałem o usunięciu pewnych elementów menu, wydłużeniu czasu alarmu i podświetlenia. Po zapoznaniu się ze środowiskiem programistycznym, oswojeniu się z nowym językiem i zapoznaniu się z kodem zegarka przyszła kolej na napisanie czegoś nowego. Od razu pomyślałem o dodaniu funkcji timera, narzędzia bardzo często wykorzystywanego w kuchni.

Opis działania:

Timer wyświetla się na dolnej linii wyświetlacza, po dacie. Domyślnie po uruchomieniu ustawione są następujące wartości. 0 godzin, 10 minut i 1 sekunda. Timer można rozróżnić od stopera dzięki obecności ikony „record” wyświetlanej cały czas, gdy menu jest aktywne, a migającej podczas odliczania. Uruchomienie timera następuje po przyciśnięciu prawego, dolnego przycisku. Po wyzerowaniu się timera, włącza się alarm – na zasadach identycznych jak budzik. Jego czas trwania można zmieniać, modyfikując ALARM_ON_DURATION w pliku alarm.h.

Wciśnięciu przycisku start/stop na wyzerowanym timerze powoduje powrót do wartości domyślnych. Dowolny czas w przedziale 23h 59min – 1min można zaprogramować przytrzymując lewy dolny przycisk. Wejście do trybu programowania powoduje wyzerowanie sekund.

Projekt powstał w środowisku Code Composer Studio, wersja 5.2.1. Wykorzystałem kompilator msp430_5.2.1. Do posta załączam archiwum ze zmienionymi plikami, oraz skompilowany kod źródłowy w formacie TI-TXT, do zaprogramowania bezprzewodowo przez Chronos Control Center.

Moduł timera powstał na bazie stopera, a nazywa się „eggtimer”. Nowe pliki to ‚eggtimer.c’ oraz ‚eggtimer.h’ – należy je wgrać do podfoldera logic. Dodatkowo należy dokonać kilku zmian w plikach źródłowych:

Wywołanie przerwania co sekundę

Wykorzystałem timer zegara, który generuje przerwania dokładnie co jedną sekundę. Należy dodać wywołanie funkcji obniżającej licznik timera co sekundę do pliku timer.c

#include "ps.h"
#include "display.h"

// logic
#include "clock.h"
#include "battery.h"
#include "stopwatch.h"
#include "eggtimer.h"
#include "alarm.h"
#include "altitude.h"
#include "display.h"
// Enable IE
TA0CCTL0 |= CCIE;

// Add 1 second to global time
clock_tick();

eggtimer_tick();

// Set clock update flag
display.flag.update_time = 1;

plik main.c

Konieczne jest załączenie pliku .c z modułem timera oraz jego zresetowanie podczas uruchamiania urządzenia.

#include "stopwatch.h"
#include "eggtimer.h"
#include "battery.h"
// Reset stopwatch
reset_stopwatch();

// Reset eggtimer
reset_eggtimer();

// Reset altitude measurement
reset_altitude_measurement();

Wyświetlacz – display.h

W tym pliku konieczne jest zadeklarowanie flagi, informującej o konieczności odświeżenia wyświetlacza podczas pracy timera

        u16 update_alarm : 1;           // 1 = Alarm time was updated
        u16 update_acceleration : 1;    // 1 = Acceleration data was updated
        u16 update_eggtimer : 1;		// 1 = timer was updated
    } flag;
    u16 all_flags;                      // Shortcut to all display flags (for reset)
} s_display_flags;

Menu, czyli menu.c i menu.h

W menu.h po prostu należy zadeklarować fakt istnienia elementu menu:

extern const struct menu menu_L2_Date;
extern const struct menu menu_L2_Stopwatch;
extern const struct menu menu_L2_Eggtimer;
extern const struct menu menu_L2_Battery;

W menu.c należy dokonać więcej zmian:

  • W linii 61 wstawić include dla pliku timera: #include "eggtimer.h"
  • Następnie zadeklarować funkcję eggtimer_display():
    u8 update_eggtimer(void)
    {
        return (display.flag.update_eggtimer);
    }
    
  • Na koniec zadeklarować pełny obiekt reprezentujący element menu, z odpowiednimi odwołaniami do funkcji:
        FUNCTION(display_date),           // display function
        FUNCTION(update_date),            // new display data
        &menu_L2_Eggtimer,
    };
    
    // Line2 - eggtimer
    const struct menu menu_L2_Eggtimer = {
        FUNCTION(sx_eggtimer),           // direct function
        FUNCTION(mx_eggtimer),           // sub menu function
        FUNCTION(display_eggtimer),      // display function
        FUNCTION(update_eggtimer),       // new display data
        &menu_L2_Stopwatch,
    };
    // Line2 - Stopwatch
    const struct menu menu_L2_Stopwatch = {
    

Główne pliki timera – eggtimer.c oraz eggtimer.h

Należy napisać kilka słów zwłaszcza o pliku nagłówkowym: eggtimer.h. Zawiera on definicje trzech stałych, które określają domyslne wartości timera – początkowe oraz po wyzerowaniu. Oznaczone one są nazwami EGGTIMER_DEF_HOURS, EGGTIMER_DEF_MINUTES oraz EGGTIMER_DEF_SECONDS. Można je swobodnie modyfikować. Wszystkie funkcje są opisane szerzej w pliku eggtimer.c, w odpowiednich komentarzach.

extern void reset_eggtimer(void);
extern void start_eggtimer(void);
extern void stop_eggtimer(void);
extern u8 is_eggtimer(void);
extern u8 is_eggtimer_empty(void);
extern void eggtimer_tick(void);
extern void eggtimer_decrement(u8 id);

// Menu functions
extern void display_eggtimer(u8 line, u8 update);
extern void sx_eggtimer(u8 line);
extern void mx_eggtimer(u8 line);
// *************************************************************************************************
// Defines section

#define EGGTIMER_DEF_HOURS	(0)
#define EGGTIMER_DEF_MINUTES	(10)
#define EGGTIMER_DEF_SECONDS	(1)

// *************************************************************************************************
// Global Variable section
struct egg
{
    u8 running:1; //timer pracuje
    u8 visible:1; //timer jest widoczny
    u8 toggle:1;
    u8 empty:1; //timer jest wyzerowany
    u8 hours; //godziny
    u8 minutes; //minuty
    u8 seconds; //sekundy
};
extern struct egg sEgg;

Pobierz zmienione pliki oraz skompilowany kod.

Gdyby kod nie działał, proszę o feedback w komentarzu.

Udostępnij:Share on FacebookEmail this to someoneWykop!Share on Google+Print this pageShare on TumblrTweet about this on Twitter

Dodaj komentarz

Twój adres email nie zostanie opublikowany.