Elementy biblioteki:
Tak naprawdę cała biblioteka będzie się składała z jednej funkcji, która na podstawie podanych zmiennych głównych będzie odpowiednio inicjować układ czuwający.
Poniżej przedstawiam plik nagłówkowy .h:
#ifndef WATCHDOG_H #define WATCHDOG_H 60 #include "stm32f4xx.h" //Reset systemu jest wywolywany co okreslony czas //zdefiniowany wedlug wybranej zmiennej. #define CzasPrze_10ms 1 #define CzasPrze_250ms 2 #define CzasPrze_500ms 3 #define CzasPrze_1s 4 #define CzasPrze_2s 5 #define CzasPrze_4s 6 #define CzasPrze_8s 7 //Ustawienie dzielnika: //Wartosc binarna: 000 #define Dzielnik_4 0x00 //Wartosc binarna: 001 #define Dzielnik_8 0x01 //Wartosc binarna: 010 #define Dzielnik_16 0x02 //Wartosc binarna: 011 #define Dzielnik_32 0x03 //Wartosc binarna: 100 #define Dzielnik_64 0x04 //Wartosc binarna: 101 #define Dzielnik_128 0x05 //Wartosc binarna: 110 #define Dzielnik_256 0x06 void IWDGKonfiguracjaReg(uint16_t wartosc, uint8_t dzielnik); void IWDGKonfiguracja(uint16_t wartosc, uint8_t dzielnik) ; #endif
Teraz kolej na plik zawierający główną funkcję. Prezentuje się on następująco:
#include "STM32F4_Watchdog.h" void IWDGKonfiguracjaReg(uint16_t wartosc, uint8_t dzielnik) { //Zezwolenie na zapis do rejestrów IWDG_PR oraz IWDG_RLR IWDG->KR = 0x5555; //Ustawienie watrtosci poczatkowej if (wartosc == CzasPrze_10ms) { IWDG->RLR = 10; IWDG->PR = Dzielnik_32; } else if (wartosc == CzasPrze_250ms) { IWDG->RLR = 255; IWDG->PR = Dzielnik_32; } else if (wartosc == CzasPrze_500ms) { IWDG->RLR = 511; IWDG->PR = Dzielnik_32; } else if (wartosc == CzasPrze_1s) { IWDG->RLR = 1023; IWDG->PR = Dzielnik_32; } else if (wartosc == CzasPrze_2s) { IWDG->RLR = 2047; IWDG->PR = Dzielnik_32; } else if (wartosc == CzasPrze_4s) { //Maksymalna wartosc jaka mozna wprowadzic //do tego rejestru IWDG->RLR = 4095; IWDG->PR = Dzielnik_32; } else if (wartosc == CzasPrze_8s) { IWDG->RLR = 1023; IWDG->PR = Dzielnik_256; } else { IWDG->RLR = wartosc; IWDG->PR = dzielnik; } //Przeladowanie wybranej konfiguraci IWDG->KR = 0xAAAA; //Wlaczenie watchdoga oraz sygnalu taktujacego LSI IWDG->KR = 0xCCCC; } void IWDGKonfiguracja(uint16_t wartosc, uint8_t dzielnik) { //Zezwolenie na zapis do rejestrów IWDG_PR oraz IWDG_RLR (0x5555) IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable); //Ustawienie watrtosci poczatkowej if (wartosc == CzasPrze_10ms) { //IWDG_SetReload(0xA); IWDG_SetReload(10); IWDG_SetPrescaler(IWDG_Prescaler_32); } else if (wartosc == CzasPrze_250ms) { //IWDG_SetReload(0xFF); IWDG_SetReload(255); IWDG_SetPrescaler(IWDG_Prescaler_32); } else if (wartosc == CzasPrze_500ms) { //IWDG_SetReload(0x1FF); IWDG_SetReload(511); IWDG_SetPrescaler(IWDG_Prescaler_32); } else if (wartosc == CzasPrze_1s) { //IWDG_SetReload(0x3FF); IWDG_SetReload(1023); IWDG_SetPrescaler(IWDG_Prescaler_32); } else if (wartosc == CzasPrze_2s) { //IWDG_SetReload(0x7FF); IWDG_SetReload(2047); IWDG_SetPrescaler(IWDG_Prescaler_32); } else if (wartosc == CzasPrze_4s) { //Maksymalna wartosc jaka mozna wprowadzic //do tego rejestru //IWDG_SetReload(0xFFF); IWDG_SetReload(4095); IWDG_SetPrescaler(IWDG_Prescaler_32); } else if (wartosc == CzasPrze_8s) { //IWDG_SetReload(0x3FF); IWDG_SetReload(1023); IWDG_SetPrescaler(IWDG_Prescaler_32); } else { IWDG_SetReload(wartosc); IWDG_SetPrescaler(dzielnik); } //Przeladowanie wybranej konfiguraci IWDG_ReloadCounter(); //Wlaczenie watchdoga oraz sygnalu taktujacego LSI IWDG_Enable(); }
W głównej części zawarłem dwa sposoby inicjalizacji pracy watchdoga na rejestrach, oraz z wykorzystaniem bibliotek API.
Czas minimalny oraz maksymalny jaki będzie resetowanie mikrokontrolera oraz jego odświeżenie należy obliczyć z następujących danych wzorów:
W głównym programie należy pamiętać o zainicjowaniu funkcji watchdoga, sprawdzeniu czy praca się od resetu wywołanego przez układ czuwający, oraz o przeładowaniu licznika. Pozostałe elementy są należy umieszczać według potrzeby.
//Warunek sprawdzajacy czy system zaczal prace po wykorzystaniu resetu //przez uklad czuwajacy, Jezeli tak to wejscie w petle if (RCC_GetFlagStatus(RCC_FLAG_IWDGRST) != RESET) { //Wyczyszczenie flagi resetu RCC_ClearFlag(); //Petla opózniajaca for (i=0;i<10000000;i++); } . . IWDGKonfiguracjaReg(); . . IWDG_ReloadCounter(); . .