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.

This site uses Akismet to reduce spam. Learn how your comment data is processed.