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. Тестовая плата. Прошивка через последовательный порт и через 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
RCC_LSICmd(DISABLE);
Додати коментар
Недавні записи
- 🇺🇦 FOC Board STM32F103RB 🧩
- STM32 Motor control SDK - керування оборотами мотора за допомогою потенціометра 📑
- Flask✙Gunicorn✙Nginx➭😎
- STM32 Motor control SDK - програмне керування обертам мотора
- STM32 Motor control SDK - як створити перший проект
- Vue SVG. Приклад побудови живого параметричного креслення
- Вимірювання моменту мотора
- Vue SVG - компонент. Приклад 📑
- Flask + Vue 🏁 Финальный пример 🏁
- Flask, CORS, JSON-файл. Пример#6
Tags
bldc brushless stm32 motor web html css flask atmega foc git java-script pmsm raspberry-pi python websocket mongodb esp8266 nodemcu st-link tim timer docker ngnix programmator ssd1331 ssd1306 wifi uart meteo bme280 bmp280 i2c gps mpu-6050 mpu-9250 sensors 3d-printer options usb barometer remap watchdog flash eeprom rtc bkp encoder pwm servo capture examples dma adc nvic usart gpio books battery dc-dc sms max1674 avr lcd dht11 piezo rs-232 rfid solar exti bluetooth eb-500 displays ethernet led smd soldering mpx4115a hih-4000
Архіви