17. STM32. Програмування STM32F103. Watchdog
Сторожові таймери (Watchdog) існують для того, щоб у разі зависання програми мікроконтролера його (мікроконтролер) можна було перезавантажити. STM32 мають два watchdog. Їх звати IWDG і WWDG. IWDG - незалежний ("I" - Independent), доступний повсякчас. WWDG - більш обмежений ("W" - Window). Робота watchdog проста - якщо Ви його завели у своєму господарстві (налаштували і запустили), тоді треба його періодично годувати (скидати лічильник). Якщо лічильник не обновляти певний час, watchdog вважає, що з мікроконтролером щось не так і перезавантажує його. Це головна ідея watchdog. Тепер розглянемо їх детальніше і розберемо, у чому різниця між IWDG і WWDG.
IWDG - Independent Watchdog
Independent - незалежний Watchdog. IWDG тактується від окремого, вбудованого у мікроконтролера, генератора низької частоти. Дивись: 4. STM32. Програмування STM32F103. Тактування.Ініціалізація IWDG виконується наступним чином:
- Вмикається LSI (40 kHz) (генератор низької частоти, яким тактується IWDG)
- Вмикається доступ до регістрів IWDG
- Налаштовується дільник вхідної частоти
- Встановлюється лічильник (від 0 до 0x0FFF)
- Вмикається IWDG
#include "stm32f10x.h"
#include "stm32f10x_gpio.h"
#include "stm32f10x_rcc.h"
#include "stm32f10x_iwdg.h"
#include "misc.h"
int main(void)
{
int i;
/* Initialize Leds mounted on STM32 board */
GPIO_InitTypeDef GPIO_InitStructure;
/* Initialize LED which connected to PC13, Enable the Clock*/
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
/* Configure the GPIO_LED pin */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOC, &GPIO_InitStructure);
/* Disable LED */
GPIO_SetBits(GPIOC, GPIO_Pin_13);
/* delay */
for(i=0;i<0x100000;i++);
/* Enable the LSI OSC */
RCC_LSICmd(ENABLE);
/* Wait till LSI is ready */
while (RCC_GetFlagStatus(RCC_FLAG_LSIRDY) == RESET)
{}
/* Enable Watchdog*/
IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable);
IWDG_SetPrescaler(IWDG_Prescaler_4); // 4, 8, 16 ... 256
IWDG_SetReload(0x0FFF);//This parameter must be a number between 0 and 0x0FFF.
IWDG_ReloadCounter();
IWDG_Enable();
/* Enable LED */
GPIO_ResetBits(GPIOC, GPIO_Pin_13);
while (1)
{
//IWDG_ReloadCounter();
}
}
Оскільки IWDG тактується від власного генератора, він спрацює навіть у тому випадку, якщо від мікроконтролера відвалиться джерело тактування, наприклад кварц. Якщо при старті контролера програма перевіряє наявність джерела тактування, контролер зможе згенерувати відповідне повідомлення чи перейти на інше джерело тактування, а не просто повиснути.
WWDG - Window Watchdog
На відмінність від IWDG, WWDG тактується частотою, якою тактується мікроконтролер. Вірніше сказати, частота тактування WWDG дорівнює частоті PCLK1 (частота на виході APB1), поділена на постійний дільник 4096. Таким чином можна сказати, що робота WWDG синхронізована з роботою програми мікроконтролера.До чого тут Window? Для WWDG можна налаштувати "вікно" (проміжок часу), у яке треба обновляти лічильник watchdog. Не раніше і не пізніше. Тобто, якщо WWDG обновити раніше або пізніше, ніж очікувалось, буде виконано перезавантаження мікроконтролера. Ця властивість використовується не тільки для контролю зависання програми, а ще для контролю несанкціонованих переходів. Наприклад, якщо з будь-яких причин була пропущена важлива процедура. Саме занадто малий час між подіями і може стати сигналом того, що критична процедура не була виконана.
У WWDG є особливість - лічильник працює у діапазоні від 127 до 64. Тобто, він рахує вниз від зазначеного числа до 64. Для того, щоб налаштувати вікно, нам треба щоб WindowValue було менше за початкове значення лічильника. Наприклад, ми встановили WindowValue = 90, а лічильник 120. WWDG починає зменшувати лічильник від 120 до 64. І, якщо ми перезапишемо лічильник раніше, ніж він дорахує до 90, відбудеться перезавантаження мікроконтролера, бо ми не попали у вікно.
Якщо WindowValue рівна або більша за лічильник, тоді WWDG працює як звичайний watchdog.
Ініціалізація WWDG виконується наступним чином:
- Вмикається тактування WWDG
- Налаштовується дільник вхідної частоти
- Встановлюється вікно (від 64 до 127)
- Встановлюється лічильник (від 64 до 127) і вмикається WWDG
- Вмикається і налаштовується переривання, якщо потрібно
#include "stm32f10x.h"
#include "stm32f10x_gpio.h"
#include "stm32f10x_rcc.h"
#include "stm32f10x_wwdg.h"
int main(void)
{
int i;
/* Initialize Leds mounted on STM32 board */
GPIO_InitTypeDef GPIO_InitStructure;
/* Initialize LED which connected to PC13, Enable the Clock*/
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
/* Configure the GPIO_LED pin */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOC, &GPIO_InitStructure);
/* Disable LED */
GPIO_SetBits(GPIOC, GPIO_Pin_13);
/* delay */
for(i=0;i<0x100000;i++);
/* Enable Watchdog*/
RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG,ENABLE);
WWDG_DeInit();
WWDG_SetPrescaler(WWDG_Prescaler_8);
WWDG_SetWindowValue(0x7F);
WWDG_Enable(0x5F);
/* Enable LED */
GPIO_ResetBits(GPIOC, GPIO_Pin_13);
while (1)
{
//WWDG_SetCounter(0x5F);
}
}
Для WWDG можна налаштувати обробку переривання. Наприклад, нам потрібно зберегти якісь дані перед перезавантаженням. Або виконати якісь процедури і вирішити чи дійсно треба перезавантажити мікроконтролер чи дозволити йому працювати далі. Якщо скинути прапор WWDG функцією WWDG_ClearFlag() перезавантаження не відбудеться.
Приклад:
#include "stm32f10x.h"
#include "stm32f10x_gpio.h"
#include "stm32f10x_rcc.h"
#include "stm32f10x_wwdg.h"
#include "misc.h"
void WWDG_IRQHandler(void) {
int i;
WWDG_ClearFlag(); //This function reset flag WWDG->SR and cancel the resetting
WWDG_SetCounter(100);
/* Toggle LED which connected to PC13*/
GPIOC->ODR ^= GPIO_Pin_13;
}
int main(void)
{
/* Initialize Leds mounted on STM32 board */
GPIO_InitTypeDef GPIO_InitStructure;
/* Initialize LED which connected to PC13, Enable the Clock*/
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
/* Configure the GPIO_LED pin */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOC, &GPIO_InitStructure);
/* Disable LED */
GPIO_SetBits(GPIOC, GPIO_Pin_13);
/* Enable Watchdog*/
RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG,ENABLE);
WWDG_DeInit();
WWDG_SetPrescaler(WWDG_Prescaler_8); //1, 2, 4, 8
WWDG_SetWindowValue(127); // 64...127
WWDG_Enable(100);
WWDG_EnableIT();
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = WWDG_IRQn; /*WWDG interrupt*/
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);/* NVIC initialization*/
while (1)
{
}
}
Пам`ятка
WWDG тактується частотою: (PCLK1/4096)/WWDG_PrescalerІнтервал до перезавантаження розраховується як: T = 1000 / PCLK1 * 4096 * WWDG_Prescaler * (Counter - 63) мс Наприклад: T = 1000 / 8000000 * 4096 * 1 * (120-63) = 29.184 мс
Інтервал, після якого можна обновляти лічильник WWDG, розраховується як: t = 1000 / PCLK1 * 4096 * WWDG_Prescaler * (Counter - WindowValue) мс Наприклад: t = 1000 / 8000000 * 4096 * 1 * (120-80) = 20.48 мс
Бажаю успіхів!
Дивись також:
- 1. STM32. Програмування STM32F103. Тестова плата. Прошивка через UART та через ST-Link
- 2. STM32. Програмування. IDE для STM32
- 3. STM32. Програмування STM32F103. GPIO
- 4. STM32. Програмування STM32F103. Тактування
- 5. STM32. Програмування STM32F103. USART
- 6. STM32. Програмування STM32F103. NVIC
- 7. STM32. Програмування STM32F103. ADC
- 8. STM32. Програмування STM32F103. DMA
- 9. STM32. Програмування STM32F103. TIMER
- 10. STM32. Програмування STM32F103. TIMER. Захоплення сигналу
- 11. STM32. Програмування STM32F103. TIMER. Encoder
- 12. STM32. Програмування STM32F103. TIMER. PWM
- 13. STM32. Програмування STM32F103. EXTI
- 14. STM32. Програмування STM32F103. RTC
- 15. STM32. Програмування STM32F103. BKP
- 16. STM32. Програмування STM32F103. Flash
- 17. STM32. Програмування STM32F103. Watchdog
- 18. STM32. Програмування STM32F103. Remap
- 19. STM32. Програмування STM32F103. I2C Master
- 20. STM32. Програмування STM32F103. I2C Slave
- 21. STM32. Програмування STM32F103. USB
- 22. STM32. Програмування STM32F103. PWR
- 23. STM32. Програмування STM32F103. Option bytes
- 24. STM32. Програмування STM32F103. Bootloader
- STM32. Скачати приклади
- System Workbench for STM32 Інсталяція на Ubuntu
- Keil uVision5 – IDE для STM32
- IAR Workbench – IDE для STM32
- Керування безколекторним двигуном постійного струму (BLDC) за допомогою STM32
- Керування PMSM за допомогою STM32
Недавні записи
- Text to speech. Українська мова
- LCD Display ST7567S (IIC)
- Розпізнавання мови (Speech recognition)
- Selenium
- Комп'ютерний зір (Computer Vision)
- Деякі думки про точність вимірювань в електроприводі
- Датчики Холла 120/60 градусів
- Модуль драйверів напівмосту IGBT транзисторів
- Драйвер IGBT транзисторів на A316J
- AS5600. Варіант встановлення на BLDC мотор
Tags
docker sensors rtc led timer wifi remap sms css websocket mongodb bme280 rfid bluetooth esp8266 nodemcu bkp piezo bmp280 i2c mpu-6050 encoder examples avr brushless ngnix nvic displays bldc java-script pmsm barometer pwm lcd ethernet stm32 raspberry-pi capture usart gpio exti atmega meteo solar smd dma adc eeprom eb-500 flask python ssd1306 uart options flash mpx4115a html gps st-link 3d-printer servo dc-dc foc git books battery hih-4000 watchdog dht11 web tim programmator ssd1331 mpu-9250 usb rs-232 motor max1674 soldering
Архіви