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
Недавні записи
- Розпізнавання мови (Speech recognition)
- Selenium
- Комп'ютерний зір (Computer Vision)
- Деякі думки про точність вимірювань в електроприводі
- Датчики Холла 120/60 градусів
- Модуль драйверів напівмосту IGBT транзисторів
- Драйвер IGBT транзисторів на A316J
- AS5600. Варіант встановлення на BLDC мотор
- DC-DC для IGBT драйверів ізольований 2 W +15 -8 вольт
- U-FOC - Векторне керування безколекторними моторами
Tags
esp8266 examples adc usart rfid eb-500 soldering lcd stm32 raspberry-pi python mongodb gps mpu-9250 sensors led hih-4000 foc ngnix wifi servo sms ethernet bldc 3d-printer bluetooth mpx4115a web pmsm options remap solar timer bme280 mpu-6050 avr docker flash bkp capture gpio uart meteo i2c usb rtc encoder programmator ssd1306 battery displays java-script barometer watchdog eeprom flask websocket pwm dht11 motor ssd1331 piezo smd brushless atmega books css git st-link dc-dc html nodemcu dma nvic rs-232 exti tim bmp280 max1674
Архіви