Laboratorul 08 - Timing & Timere

Timere Arduino

Platforma Ardunio utilizează microcontrollere din familia Atmel megaAVR, ce conțin un număr de timere hardware:

  • Modelul ATmega328, disponibil pe Arduino Uno, are 3 timere (timer0 - timer2), dintre care unul pe 16 biți
  • Modelul ATmega2560, disponbil pe Arduino Mega, are 6 timere (timer0 - timer5), 4 dintre ele fiind pe 16 biți

În modul de lucru clasic, timer0 este utilizat de funcțiile delay(), millis() și micros(). În plus, timerele controlează și pinii PWM ai plăcuțelor Arduino.

Timerele pot fi modificate manual, în funcție de comportamentul dorit, prin regiștrii corespunzători. Pentru a găsi acești regiștri și biții ce trebuie modificați, trebuie să consultați documentația microcontroller-ului. De exemplu, pentru ATmega328, documentația poate fi găsită aici. La pagina 74 puteți găsi informații despre timer-ul pe 8 biți și regiștrii acestuia.

Software Timer API

Timerele menționate anterior sunt hardware, iar utilizarea lor nu este cea mai facilă. FreeRTOS simplifică acest lucru, printr-un API specializat în crearea de timere software. Aceste timere sunt mai ușor de utilizat, întrucât funcționează ca o punte între programator și circuitele electronice. Pe lângă bilbioteca FreeRTOS, trebuie inclusă în proiect și biblioteca timers.h

În documentația FreeRTOS, informații despre acest API se găsesc începând cu pagina 253.

1. Crearea unui timer

Pentru a crea un timer software, este utilizată funcția TimerHandle_t xTimerCreate( const char *pcTimerName, const TickType_t xTimerPeriod, const UBaseType_t uxAutoReload, void * const pvTimerID, TimerCallbackFunction_t pxCallbackFunction );, care se apelează pentru un element de tipul TimerHandle_t. Parametrii funcției sunt:

  • *pcTimerName - Un nume atribuit timer-ului
  • xTimerPeriod - Numărul de cicli de ceas după care timer-ul va expira
  • uxAutoReload - Specificăm dacă timer-ul va expira după perioada xTimerPeriod sau va fi automat rearmat
  • pvTimerID - un număr care să identifice în mod unic timer-ul
  • pxCallbackFunction - funcția ce va fi apelată la expirarea timer-ului, dacă este necesară

Pentru orice valoare diferită de NULL întoarsă de funcție, timer-ul a fost creat cu succes

Parametrul xTimerPeriod definește numărul de cicli de ceas. Pentru a converti timpul din milisecunde în cicli de ceas, utilizați funcția pdMS_TO_TICKS()

Exemplu:

#include <Arduino_FreeRTOS.h>
#include <timers.h>
 
// Declarare element de tipul TimerHandle_t
TimerHandle_t xTimer;
 
void setup()
{
// Creare timer cu numele "Timer", care expiră la fiecare 100ms și apelează funcția vTimerCallback
xTimer =  xTimerCreate("Timer", pdMS_TO_TICKS(100), pdTRUE, ( void * ) 0, vTimerCallback );
 
if( xTimer == NULL)
{
  // Timer-ul nu a fost creat
}
else
{
 // Timer creat cu succes
}
}
 
// Declarare funcție ce va fi apelată la epirarea timer-ului. Necesită TimerHandle_t ca parametru pentru a recunoaște timer-ul care a apelat funcția
void vTimerCallback( TimerHandle_t X )
{
...
}

2. Start/Stop/Reset

După crearea timer-ului, acesta trebuie pornit. Funcțiile utile pornirii, opririi sau resetării unui timer sunt:

  • xTimerStart( TimerHandle_t xTimer, TickType_t xTicksToWait ) - setează timer-ul specificat ca parametru ca activ . Al doilea parametru specifică timpul maxim de procesare a comenzii de către task-ul ce gestionează timerele
  • xTimerStop( TimerHandle_t xTimer, TickType_t xTicksToWait ) - setează timer-ul specificat ca parametru ca inactiv
  • xTimerReset( TimerHandle_t xTimer, TickType_t xTicksToWait ) - resetează timer-ul specificat ca parametru
  • xTimerDelete( TimerHandle_t xTimer, TickType_t xTicksToWait ) - șterge timer-ul specificat ca parametru

Un timer activ nu va porni atât timp cât scheduler-ul FreeRTOS nu este pornit, folosind funcția vTaskStartScheduler();

Exemplu:

// Declarare element de tipul TimerHandle_t
TimerHandle_t xTimer;
 
void setup()
{
// Creare timer cu numele "Timer", care expiră la fiecare 10ms și apelează funcția vTimerCallback
xTimer =  xTimerCreate("Timer", pdMS_TO_TICKS(10), pdTRUE, ( void * ) 0, vTimerCallback );
 
if( xTimer == NULL)
{
  // Timer-ul nu a fost creat
}
else
{
   // Timer creat cu succes. Se încearcă activarea acestuia. Se așteaptă maxim 10 cicli de ceas pentru a fi activat. 
   if( xTimerStart( xTimer, 10 ) != pdPASS )
   {
       Timer-ul nu poate fi setat ca ACTIV
   }
   else
   {
       Timer-ul a fost setat ca ACTIV
   }
}
 
// Pornire scheduler FreeRTOS. Timer-ul setat ca activ va începe să cronometreze din acest moment
vTaskStartScheduler();
}
 
 
...
 
//O altă funcție sau task din program
{
 // Se încearcă resetarea timer-ului
 if( xTimerReset( xTimer, 10 ) != pdPASS )
 {
    // Timer-ul nu a putut fi resetat
 }
 
 
...
 
 // Se încearcă inactivarea timer-ului
 if( xTimerStop( xTimer, 10 ) != pdPASS )
 {
    // Timer-ul nu a putut fi inactivat
 }
 
 
...
 
 // Se încearcă ștergerea timer-ului
 if( xTimerDelete( xTimer, 10 ) != pdPASS )
 {
    // Timer-ul nu a putut fi șters
 }
 
 
 
}

3. Alte funcții utile

  • xTimerGetExpiryTime( TimerHandle_t xTimer) - după cât timp (în cicli) va expira timer-ul activ specificat ca parametru?
  • pcTimerGetName( TimerHandle_t xTimer ) - care este numele timer-ului?
  • xTimerGetPeriod( TimerHandle_t xTimer ) - care este perioada timer-ului (parametrul xTimerPeriod specificat la crearea timer-ului)?
  • pvTimerGetTimerID( TimerHandle_t xTimer ) - care este ID-ul timer-ului?
  • vTimerSetTimerID( TimerHandle_t xTimer, void *pvNewID ) - specificare ID nou
  • xTimerIsTimerActive( TimerHandle_t xTimer ) - este timer-ul activ?
patr/laboratoare/08.txt · Last modified: 2022/02/17 09:47 by alexandru.ionita99
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0