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)

Grzegorz Kamiński: Historia pewnej płytki krzemowej 300 mm (12”)
Analiza rynku sztucznej inteligencji: firmy o największym wzroście przychodów z AI w 2026 roku
I-7520 – izolowany konwerter RS-232/RS-485 



