LinkedIn YouTube Facebook
Szukaj

Wstecz
Artykuły

Precyzyjne opóźnienia w połączeniu z trybami oszczędzania energii w STM32, część 2

List. 9. Program testowy umieszczony w pliku main.c

#include "clock.h"
#include "delay.h"
#include "key.h"
#include "out.h"
#include "sleep.h"
 
#define HSI_MHZ    8
#define HCLK_MHZ   72
// #define SUPPLY_CURRENT
// #define USLEEP_TIME 1
// #define MSLEEP_TIME 1
#define HSI_DELAY  (HSI_MHZ  * 1000000)
#define HCLK_DELAY (HCLK_MHZ * 1000000)
 
int main() {
  AllPinsDisable();
  OutConfigure();
  KeyConfigure();
 
  LED1on();
  Delay(HSI_DELAY);
  error_check(ClockConfigure(HCLK_MHZ), 1);
  error_check(SleepConfigure(HCLK_MHZ), 2);
  LED1off();
 
  #ifdef SUPPLY_CURRENT
    USleep(65535);
    LED1on();
    Delay(HCLK_DELAY);
    LED1off();
    MSleep(8000);
    LED1on();
    Delay(HCLK_DELAY);
    LED1off();
    Sleep(12);
    LED1on();
    Delay(HCLK_DELAY);
    /* Dioda przestaje świecić po wejściu w tryb czuwania. */
    Standby(16);
    /* Program nigdy tu nie dochodzi. */
    error_check(-1, 3);
  #else
    for (;;) {
      FREQon();
      #ifdef USLEEP_TIME
        USleep(USLEEP_TIME);
      #endif
      #ifdef MSLEEP_TIME
        MSleep(MSLEEP_TIME);
      #endif
      FREQoff();
      #ifdef USLEEP_TIME
        USleep(USLEEP_TIME);
      #endif
      #ifdef MSLEEP_TIME
        MSleep(MSLEEP_TIME);
      #endif
    }
  #endif
}

Na listingu 9 zamieszczono przykładowy program główny. Częstotliwość w MHz taktowania rdzenia i liczników ustawiamy za pomocą stałej HCLK_MHZ. Rodzaj testu wybieramy za pomocą makrodefinicji:

#define SUPPLY_CURRENT
#define USLEEP_TIME 1
#define MSLEEP_TIME 1

Pobór prądu zasilania możemy mierzyć, definiując stałą SUPPLY_CURRENT. Zakomentowanie tej definicji umożliwia pomiar czasu opóźnień mikrosekundowych i milisekundowych. Na wyjściu FREQ pojawia się wtedy sygnał o częstotliwości będącej w przybliżeniu połową odwrotności opóźnienia zadanego definicjami USLEEP_TIME i MSLEEP_TIME. Jeśli zdefiniowana jest stała  USLEEP_TIME, to w pętli wywoływana jest dwukrotnie funkcja USleep z argumentem równym tej stałej. Analogicznie jeśli zdefiniowana jest stała MSLEEP_TIME, to w pętli wywoływana jest dwukrotnie funkcja MSleep z argumentem równym tej stałej. W czasie pierwszego wywołania każdej z tych funkcji na wyjściu FREQ jest poziom wysoki, a w czasie drugiego – poziom niski. Jeśli żadna z tych stałych nie jest zdefiniowana, mierzymy częstotliwość iteracji „pustej” pętli, bez funkcji opóźniających. Zmierzony czas opóźnienia obliczamy jako połowę różnicy miedzy okresem iteracji pętli z funkcjami opóźniającymi a okresem iteracji pętli bez funkcji opóźniających. Sposób pracy regulatora 1,8 V w trybie zatrzymania wybieramy za pomocą stałej PWR_REGULATOR_MODE zdefiniowanej w pliku sleep.c, co zostało omówione w pierwszej części artykułu.
Aby skompilować przykład, potrzebny jest jeszcze plik nagłówkowy delay.h zawierający sygnaturę funkcji Delay, która została przedstawiona na początku pierwszej części artykułu. W pliku delay.c należy umieścić jej implementację, a w pliku out.c – implementacje funkcji, których sygnatury są na listingu 6. Ponadto Standard Peripheral Library wymaga obecności pliku stm32f10x_conf.h, który w naszym przypadku zawiera tylko puste makro:

#define assert_param(expr) ((void)0)