STM32 clock tree analysis, STM32 CLOCK tree details, STM32 F103 clock tree details, IWDG – independent watchdog, clock, timer to play so long MCU, this time finally understand! Note: SYSTICK system tick timer, talk about THE STM32F10X chip SYSTICK system clock timer

Hardware: STM32F107VC(Cortex-M3)

Software: Keil μVision4, JLINK

I. Introduction of timer

1. Basic concepts of timers

A timer counts pulse signals with fixed periods, such as the peripheral clock (APB) inside the MCU.

A counter counts pulse signals with fixed or unfixed cycles, such as external pulse signals introduced by the I/O pins of the MCU.

Therefore, timers and counters are essentially counters, and timers are a special case of counters.

2. STM32 timer family

3. The clock tree

In order to achieve low power consumption, STM32 is designed with perfect functions to form a complex clock system, called clock tree. Knowing the clock tree, you will understand the source of the clock signal when using each peripheral. Enables the clock of the peripheral function to be self-configurable. Because STM32 has so many peripherals, which vary from project to project, controllable clock can reduce product power consumption. All peripherals must have a clock signal set before they can be used.

AHB is the abbreviation of Advanced High Performance Bus. It is a “system Bus”. AHB is mainly used to connect high-performance modules such as CPU, DMA and DSP. The AHB system is composed of master module, slave module and Infrastructure. The transmission on the whole AHB bus is sent by the master module and responded by the slave module.

APB stands for Advanced Peripheral Bus, which is a Peripheral Bus. APB is mainly used for the connection between low-bandwidth peripherals, such as UART, 1284, etc. Its bus architecture does not support multiple master modules like AHB. The only master module in APB is the APB bridge. Further down, APB2 is responsible for AD, I/O, advanced TIM, serial port 1; APB1 is responsible for DA, USB, SPI, I2C, CAN, serial 2345, ordinary TIM.

Both are buses and conform to the AMBA specification. The AMBA on-chip bus launched by ARM company has been favored by IP developers and SoC system integrators, and has become a popular industrial standard on-chip architecture. The AMBA specification mainly includes AHB system bus and APB peripheral bus.

1) Four clock sources for STM32

External clock:

  • High Speed External clock (HSE) : an External clock source with a crystal oscillator frequency range of 4 to 16MHz. Generally, 8MHz crystal oscillator is used.
  • Low Speed External (LSE) : an External clock source that provides the real-time clock module with 32.768KHz.

Internal clock:

  • High Speed Internal clock (HSI, High Speed Internal) : generated by the Internal RC oscillator, the frequency is 8MHz, but unstable, the clock frequency accuracy is poor, can be directly used as the system clock or after 2 frequency division as PLL input
  • Low Speed Internal clock (LSI, Low Speed Internal) : generated by the Internal RC oscillator, also mainly supplied to the real-time clock module, with a frequency of about 40KHz.

2) Take the most commonly used high-speed external clock (HSE) as an example

  • Clock source 2 two external pins OSC_OUT and OSC_IN are connected to both ends of an 8-meter crystal oscillator.
  • The 8M clock encounters the first divider PLLXTPRE, which is the first node behind HSE, regardless of frequency.
  • The clock comes to PLL Source Mux. The clock signals can be input as external high speed clock (HSE) and internal high speed clock (HSI). Choose HSE.
  • Then the signal goes to PLL, which has frequency doubling effect. We select frequency doubling factor (PLL Mul), which can be 2,3… 14,15,16. We’re going for 9 octaves. The clock signal is now 8*9=72M.
  • Enter the system clock source and select HSE (8M), HSI (8M) and PLL CLK (72M) after frequency doubling. PLL CLK is selected as the system clock, and the system clock is 72M.
  • The system clock (SYSCLK) came to the AHB preassigned frequency, coefficient of optional frequency division: 1,2,4,8,16,32,64,128,256,512. Choose regardless of frequency, directly to mount low speed peripherals (APB1) PCLK1 and mount high speed peripherals (APB2) PCLK2.
  • The maximum frequency of PCLK1 low-speed peripheral clock is 36M, so the minimum frequency division is 2. The maximum frequency of the PCLK2 high speed peripheral clock is 72M, which can be selected as non-frequency.

HSE was also chosen because the external clock is more stable and accurate, providing maximum clock frequency to SYSCLK and maximizing CPU performance through frequency doubling.

3) System clock SYSCLK

System clock SYSCLK is the clock source for most components of STM32. It can be PLL output, HSI or HSE (PLL frequency doubling to 72Mhz is used in general programs). Before selecting the clock source, pay attention to determine whether the target clock source has stable oscillation. Max=72MHz, it is divided into 2 channels:

Route 1 is sent to I2S2CLK and I2S3CLK used by I2S2 and I2S3; The other 1 channel is divided by AHB divider (1-512) and then sent to the following 8 modules for use:

① Send SDIOCLK clock to SDIO.

② Send FSMCCLK clock to FSMC.

③ Send HCLK clock for AHB bus, kernel, memory and DMA.

(4) Send the System timer clock (SysTick) to the Cortex after passing 8.

⑤ Send the Cortex’s idle running clock FCLK directly.

⑥ Send to APB1 divider. APB1 divider can choose 1, 2, 4, 8, 16 frequency dividers, its output one way for APB1 peripherals (PCLK1, maximum frequency 36MHz), the other way to timer (Timer2-7)2, 3, 4 frequency doublers for use. The frequency multiplier can choose 1 or 2 frequency doubling, clock output for timer 2, 3, 4, 5, 6, 7 use.

⑦ Send to APB2 divider. APB2 divider can choose 1, 2, 4, 8, 16 frequency dividers, one of the output for APB2 peripherals (PCLK2, maximum frequency 72MHz), the other way to timer (Timer1, Timer8)1, 2 frequency doublers. The frequency doubler can choose 1 or 2 frequency doubler, and the clock output is used by timer 1 and timer 8. In addition, the APB2 divider has one output for the ADC divider. After the divider, the ADCCLK clock is sent to the ADC module for use. ADC divider can be selected as 2, 4, 6, 8.

⑧ after 2 frequency division, send to SDIO AHB interface for use (HCLK/2).

4) Users can configure the frequency of AHB bus, high-speed APB2 bus and low-speed APB1 bus through multiple predividers.

  • The maximum frequency in the AHB and APB2 domains is 72MHZ.

  • The maximum allowable frequency in the APB1 domain is 36MHZ.

  • The clock frequency of the SDIO port is fixed to HCLK/2.

  • The 40kHz LSI is used by the independent watchdog IWDG and can also be selected as the clock source for the real-time clock RTC.

  • Real-time clock The RTC clock source can also be the LSE or HSE 128-division clock source.

  • The clock source of the RTC is selected by RTCSEL[1:0].

  • STM32 has a USB module with full speed function, and its serial interface engine requires a clock source with a frequency of 48MHz. The clock source can be obtained only from the PLL output. The clock source can be 1.5 or 1. That is, if the USB module needs to be used, PLL must be enabled and the clock frequency must be set to 48MHz or 72MHz.

  • STM32 can also select a PLL output of 2-division, HSI, HSE, or system clock SYSCLK output to the MCO pin (PA8).

5) Enable control of clock output

To use a module, enable the corresponding clock first. Note that the timer doubler has a value of 1 when the APB is 1, otherwise it has a value of 2.

Devices connected to APB1(low-speed peripherals) include: power port, backup port, CAN, USB, I2C1, I2C2, UART2, UART3, SPI2, window watchdog, Timer2, Timer3, and Timer4. Note that while the USB module requires a separate 48MHz clock signal, it should not be the clock for the USB module to work on, but only the clock for the serial interface engine (SIE) to use. USB module working clock should be provided by APB1.

Devices connected to APB2(high speed peripherals) are: GPIO_A-E, USART1, ADC1, ADC2, ADC3, TIM1, TIM8, SPI1, AFIO.

2. SysTick System Timer

1. Definition of SysTick

SysTick is a 24-bit system tick timer. It provides automatic overload and overflow interrupt functions. All microcontrollers based on the Cortex_M3 processor can obtain certain time interval by using this timer. This timer is dedicated to real-time operating systems and can also be used as a standard decrement counter.

The SysTick timer is bound to the NVIC and is used to generate SysTick exceptions (exception number: 15). The Cortex-M3 processor contains a SysTick timer, so all Cortex-M3 chips have this timer, SysTick can be used for fast porting cortex-M3 chips, the software in different Cortex-M3 chips porting work greatly simplified.

It has the following characteristics:

  • 24 bit decrement counter
  • Automatic reloading function
  • A maskable interrupt is generated when the counter is 0
  • Programmable clock source

The clock source of the system timebase timer is from the AHB bus. The frequency is equal to AHB frequency and AHB/8. It can be an internal clock (FCLK, the free-running clock on the Cortex) or an external clock (SYSCLK signals on the Cortex processor).

2. SysTick

In a single-task reference program, because its architecture determines the serialization of the tasks it performs, a real-time operating system (RTOS) is used. Because RTOS processes tasks in a parallel architecture, the collapse of a single task does not affect the entire system. Users may then design their applications based on RTOS for reliability reasons. SYSTICK exists to provide the necessary clock beats to provide a rhythmic “heartbeat” for RTOS task scheduling.

All controllers based on the ARM Cortex_M3 kernel come with SysTick timer, which makes it easy to transfer programs between different devices. One of the first things to do with an RTOS is port it to the developer’s hardware platform, which is made easier by SYSTICK.

In addition to serving the operating system, the SysTick timer can also be used as an alarm to measure the time. When the processor is halted during debugging, the SysTick timer will also be halted.

3. Structure diagram of SysTick

In the figure, it shows that the system metronome timer has four related registers. Knowing the contents of these four registers, you can master the working principle of the system metronome timer.

In core_cm3.h, four registers of SysTick are defined, which are control and state register SysTick_CTRL, reload value register SysTick_LOAD, current count value register SysTick_VAL and correction value register SysTick_CALIB.

typedef struct { __IO uint32_t CTRL; / *! < SysTick Control and Status Register */ __IO uint32_t LOAD; / *! < SysTick Reload Value Register */ __IO uint32_t VAL; / *! < SysTick Current Value Register */ __I uint32_t CALIB; / *! < SysTick Calibration Register */ } SysTick_Type;Copy the code

Stm32f10x.h defines the address and name of each of SysTick’s four registers.

/******************************************************************************/ /* */ /* SystemTick */ /* */ /******************************************************************************/ /***************** Bit definition for SysTick_CTRL register *****************/ #define SysTick_CTRL_ENABLE ((uint32_t)0x00000001) /*! < Counter enable */ #define SysTick_CTRL_TICKINT ((uint32_t)0x00000002) /*! < Counting down to 0 pends the SysTick handler */ #define SysTick_CTRL_CLKSOURCE ((uint32_t)0x00000004) /*! < Clock source */ #define SysTick_CTRL_COUNTFLAG ((uint32_t)0x00010000) /*! < Count Flag */ /***************** Bit definition for SysTick_LOAD register *****************/ #define SysTick_LOAD_RELOAD ((uint32_t)0x00FFFFFF) /*! < Value to load into the SysTick Current Value Register when the counter reaches 0 */ /***************** Bit definition for SysTick_VAL register ******************/ #define SysTick_VAL_CURRENT ((uint32_t)0x00FFFFFF) /*! < Current value at the time the register is accessed */ /***************** Bit definition for SysTick_CALIB register ****************/ #define SysTick_CALIB_TENMS ((uint32_t)0x00FFFFFF) /*! < Reload value to use for 10ms timing */ #define SysTick_CALIB_SKEW ((uint32_t)0x40000000) /*! < Calibration value is not exactly 10 ms */ #define SysTick_CALIB_NOREF ((uint32_t)0x80000000) /*! < The reference clock is not provided */Copy the code

1) Control and status registersSysTick_CTRL

The specific meanings of each digit are as follows:

Bit 0: ENABLE, Systick ENABLE bit

Bit 1: TICKINT, Systick interrupt enable bit

2nd place: CLKSOURCE, Systick clock source choice

Bit 16: COUNTFLAG, Systick count comparison flag, interrupt flag of the Systick system timer

2) Reload the value registerSysTick_LOAD

Systick is a decrement timer. When the timer decays to zero, the value in the overloaded register is reloaded and continues decrement. **SysTick_LOAD** Overloaded register is a 24-bit register with a maximum count of 0xFFFFFF.

3) Current count registerSysTick_VAL

4) Calibrate the positive registerSysTick_CALIB

To use the Systick timer, simply call the SysTick_Config(Uint32_t ticks) function, which is defined in core_cm3.h as follows:

/* SysTick constants */ #define SYSTICK_ENABLE 0 /* Config-Bit to start or stop the SysTick Timer */ #define SYSTICK_TICKINT 1 /* Config-Bit to enable or disable the SysTick interrupt */ #define SYSTICK_CLKSOURCE 2 /* Clocksource  has the offset 2 in SysTick Control and Status Register */ #define SYSTICK_MAXCOUNT ((1<<24) -1) /* SysTick MaxCount */  /** * @brief Initialize and start the SysTick counter and its interrupt. * * @param uint32_t ticks is the number of ticks between two interrupts * @return none * * Initialise the system tick timer and its interrupt and start the * system tick timer / counter in free running mode to generate * periodical interrupts. */ static __INLINE uint32_t SysTick_Config(uint32_t ticks) { if (ticks > SYSTICK_MAXCOUNT) return (1); /* Reload value impossible */ // The Reload value must be less than 0XFF FFFF because this is a 24-bit decrement counter, SysTick->LOAD = (ticks & SYSTICK_MAXCOUNT) -1; SysTick->LOAD = (ticks & SYSTICK_MAXCOUNT) -1; /* set reload register */ / set NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) -1); /* Set Priority for cortex-m0 System Interrupts */ / SysTick->VAL = (0x00); /* Load the SysTick_VAL Counter Value */ / Load the SysTick_VAL Counter Value to any Value, such as 0, clear the CURRENT Value, and clear the SysTick_CTRL COUNTFLAG; SysTick->CTRL = (1 << SYSTICK_CLKSOURCE) | (1<<SYSTICK_ENABLE) | (1<<SYSTICK_TICKINT); /* Enable SysTick IRQ and SysTick Timer */ /1 << SYSTICK_CLKSOURCE =1 <<2 Select the system clock as the ticks timer clock source //1<<SYSTICK_ENABLE (1) <<0 (ENABLE=1) to start the ticks timer. //1<<SYSTICK_TICKINT (1) <<1 (TICKINT) =1. Open system cadence timer Timing interrupt return (0); /* Function successful */ } #endifCopy the code

Uint32_t SysTick_Config(uint32_t ticks) Used to define static convergent functions.

Uint32_t ticks if (ticks > SYSTICK_MAXCOUNT) return (1); SYSTICK_MAXCOUNT is the macro constant 0xFF FFFF. This is because the system timer is a 24-bit decrement counter with a maximum value of 0xFF FFFF. Therefore, when the if result is true, the value of ticks exceeded the maximum value of the system timer.

SysTick->LOAD = (ticks & SYSTICK_MAXCOUNT) -1; SysTick->LOAD = (ticks & SYSTICK_MAXCOUNT) -1; Assign the initial value of the ticks minus 1 to the LOAD register (SysTickLOAD).

Line 3 NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) -1); Call the CMSIS library function NVIC_SetPriority to set the priority of the abnormal cadence timer to 15.

SysTick->VAL = (0x00); Writing 0 to the VAL register (SysTick_VAL) causes the value inside the LOAD to be loaded into the VAL register.

Line 5 SysTick – > CTRL = (1 < < SYSTICK_CLKSOURCE) | | (1 < < SYSTICK_ENABLE) (1 < < SYSTICK_TICKINT); Select the system clock as the clock source of the system cadence timer, start the system cadence timer, and enable the interrupt of the system cadence timer, where the macro constants SysTick_CLKSOURCE, SysTick_TICKINT, and SysTick_ENABLE are (1<<2), (1<<1), and (1<<0) respectively.

Use of SysTick is summarized as follows:

  • To use the Systick timer, simply callSysTick_Config(uint32_t ticks)Function can, function automatically complete: reload value of the load, clock source selection, count register reset, interrupt priority setting (minimum), open interrupt, start counting work.
  • To modify the clock source callSysTick_CLKSourceConfig(uint32_t SysTick_CLKSource), can also be based onSysTick_Config()The default setting FCLK is not changed.
  • To modify the interrupt priority callvoid NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority)

SysTick application description:

  • Because systick is a 24-bit timer, the maximum reinstallation value is 2 to the 24th power =16, 777, 215.
  • Systick is standard with Cortex_M3, not a peripheral. There is no need to turn on its clock in the RCC register group.
  • The count flag bit and interrupt flag bit are set after each Systick overflow. The count flag bit is cleared after the counter is reloaded, and the interrupt flag bit is cleared with the interrupt service program’s response, so neither of these flag bits need to be cleared manually.
  • Using the library function method, can only use the interrupt method to respond to the timer time, if you want to use the method of query, that can only use the systick register setting method, specific operation can refer to the STM32 system tick timer.

4. Use SysTick

Systick timer is a 24-bit decrement counter. When the initial value is set and enabled, it will decrease each system clock period counter by 1. When the count reaches 0, the initial value of the time will be automatically reloaded from the RELOAD register. It never stops as long as it doesn’t clear the enable bit in the SysTick control and status registers.

If (SysTick_Config(SystemFrequency / 1000));

The configured clock uses 72MHz as the system clock, so it takes 1/72mhz for the counter to decrease each time. Assuming that our initial value of the counter is 72000, then the time for the counter to decrease to 0 each time passes by (1/72m) * 72000 = 0.001, that is, 1ms. (Can be understood as: 72MHz clock frequency, then it represents 1s count 72000000 times (cycle number), then 1ms count 72000000 times, so the count value is 72000000)

void SysTick_Configuration(void)
{
  /* SysTick interrupt each 250ms with counter clock equal to 9MHz */
  if (SysTick_Config((SystemFrequency/8) / 4))
  { 
    /* Capture error */
    while (1);
  }

  /* Select HCLK/8 as SysTick clock source */
  SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);
}
Copy the code

      

When SystemFrequency is 72MHz, SystemFrequency/8=9MHz. The decreasing frequency of the system timebase timer is set to 9MHz/4. The clock source of the counter is AHB/8=9MHz, so it takes 1/9mhz for the counter to decrease once, so every time the counter decreases to 0, after (1/9m) * 9M/4 = 0.25, that is, 250ms.

For other examples, when the system clock is 72MHz, the decreasing frequency of the system timebase timer is set to 9MHz. Under this condition, the initial value of the system timer is set to 90,000, and the time base value of 10ms is generated. If the interrupt is enabled, the interrupt of 10ms is generated.

5. Specific examples of SysTick

Example program from ulRM3-NMA Experimental Instruction manual 0.97.doc program 23-SysTick system timer.

In the experiment, a Systick interrupt is generated every 1ms, and the nTime of Delay(U32ntime) Delay function is reduced by one in the interrupt processing function of Systick. When Delay(U32ntime) detects that nTime has been reduced to 0, the function exits the loop, thus realizing Delay. Every time a certain delay time will be reversed LED state, so as to achieve the board D5~D8 flashing.

The main function main.c looks like this:

#include "main.h" /* Private typedef -----------------------------------------------------------*/ /* Private define ------------------------------------------------------------*/ /* Private macro -------------------------------------------------------------*/ /* Private variables ---------------------------------------------------------*/ GPIO_InitTypeDef GPIO_InitStructure; static __IO uint32_t TimingDelay; /* Private function prototypes -----------------------------------------------*/ void Delay(__IO uint32_t nTime); /* Private functions ---------------------------------------------------------*/ int main(void) { /* Setup the microcontroller system. Initialize the Embedded Flash Interface, initialize the PLL and update the SystemFrequency variable. */ SystemInit(); /* Initialize the LCD */ STM3210C_LCD_Init(); /* Clear the LCD */ LCD_Clear(White); /* Set the LCD Text Color */ LCD_SetTextColor(Black); printf(" STM3210C-EVAL \n"); printf(" systemtick usage"); /* Initialize Leds mounted on STM3210X-EVAL board */ STM_EVAL_LEDInit(LED1); STM_EVAL_LEDInit(LED2); STM_EVAL_LEDInit(LED3); STM_EVAL_LEDInit(LED4); /* Turn on LED1 and LED3 */ STM_EVAL_LEDOn(LED1); STM_EVAL_LEDOn(LED3); /* Setup SysTick Timer for 1 msec interrupts */ if (SysTick_Config(SystemFrequency / 1000)) { /* Capture error */ while (1); } while (1) { /* Toggle LED2 and LED4 */ STM_EVAL_LEDToggle(LED2); STM_EVAL_LEDToggle(LED4); printf("\n--delay 500ms"); /* Insert 500 ms delay */ Delay(500); /* Toggle LED1 and LED3 */ STM_EVAL_LEDToggle(LED1); STM_EVAL_LEDToggle(LED3); printf("\n++delay 1000ms"); /* Insert 1000 ms delay */ Delay(1000); } } /** * @brief Inserts a delay time. * @param nTime: specifies the delay time length, in milliseconds. * @retval None */ void Delay(__IO uint32_t nTime) { TimingDelay = nTime; while(TimingDelay ! = 0); } /** * @brief Decrements the TimingDelay variable. * @param None * @retval None */ void TimingDelay_Decrement(void) { if (TimingDelay ! = 0x00) { TimingDelay--; }}Copy the code

Stm32f10x_it. c interrupt service function SysTick_Handler:

void SysTick_Handler(void)
{
  TimingDelay_Decrement();
}
Copy the code

Iii. Independent Watchdog (IWDG)

1. The IWDG profile

The STM32F10x has two built-in watchdog peripherals that provide a high degree of security, accurate timing and flexible application. All watchdog peripherals (standalone or Windows) are used to detect and resolve failures caused by software failure. When the timer reaches a given timeout value, the watchdog triggers an interrupt or restart of the system. The independent watchdog is timed by its own special low speed clock (32KHZ), so it can operate normally even when the master clock is not working. The Windows watchdog clock is segmented from the APB1 clock and has a configurable programmable timing window that detects abnormal late or early application behavior.

The independent watchdog is a 12-bit decrement counter that generates a reset signal, IWDG_RESET, when the counter goes from a certain value to zero. If the counter is refreshed before it reaches zero, no reset signal is generated. The watchdog function is powered by the VDD voltage domain and can work in stop mode and standby mode.

2. IWDG functional block diagram analysis

① Independent watchdog clock

Independent watchdog clock is provided by independent RC oscillator LSI, even if the master clock fails it is still effective, very independent. The frequency of LSI is generally between 30 and 60KHZ, with a certain drift depending on the temperature and the working environment. Generally, 40KHZ is used. Therefore, the timing time of the independent watchdog must be very accurate, and only applies to the occasions with low requirements on time accuracy.

② Counter clock

The clock of the decrement counter is obtained by LSI through an 8-bit predivider. We can operate the predivider register IWDG_PR to set the dividing factor. The dividing factor can be: [4,8,16,32,64,128,256,256], dividing factor =4 * 2^PRV, counter clock CK_CNT= 40/ (4 * 2^PRV), a counter clock, the counter is reduced by one.

For example, PRV=3, frequency divider =4 * 2^PRV=4 * 2^3=32, exactly corresponding to PR[2:0]=011 in IWDG_PR.

(3) counter

The independent watchdog counter is a 12-bit decrement counter with a maximum value of 0XFFF. When the counter reaches 0, a reset signal is generated :IWDG_RESET, which restarts the program. If the counter is refreshed before it reaches 0, no reset signal is generated. The action of refreshing the counter is commonly known as feeding the dog.

④ Reload register IWDG_RLR

The reload register is a 12-bit register that holds the value to be flushed to the counter. This value determines the overflow time of the independent watchdog, ranging from 0 to 0XFFF. Tout = (4 * 2^ PRV) /40 * RLV = (divider factor /40) * RLV, in ms, PRV is the value of the predivider register and RLV is the value of the reloaded register.

⑤ Key value register

The key value register IWDG_KR can be said to be a control register of an independent watchdog. There are three main control methods. Writing the following three different values to this register has different effects.

Starting the watchdog by writing 0XCCC to the key-value register is a software startup method. Once the independent watchdog is started, it cannot be turned off and can only be turned off by resetting.

⑥ Status register

The status register SR is valid only at bits 0: PVU and 1: RVU. These bits can only be operated by hardware, not software. RVU: The reloading value of the watchdog counter is updated. If the hardware is set to “1”, the reloading value is being updated and will be cleared by the hardware after the update. PVU: The watchdog predivision value is updated. The hardware 1 indicates that the predivision value is being updated. When the update is complete, the hardware will clear it. So the reload register/predivision register can only be updated when RVU/PVU is equal to 0.

3. The IWDG operation

If the count reaches zero, a reset occurs, but the program avoids the reset by constantly rewriting the count against the watchdog counter in Systick’s interrupt handler. Otherwise, this causes the independent watchdog count to zero and the program to reset (run from scratch).

4. The IWDG experiment

Example program from ulRM3-NMA Experimental Instruction Manual 0.97.doc Example program 17- Independent watchdog timer.

This example program is used to demonstrate the periodic feeding of dogs in systick interrupt service program. The watchdog timeout is 280 milliseconds. Systick generates interrupts every 250 ms. In the interrupt service routine, light up D6 (pin PD13) and overload the independent watchdog counter so that the system does not generate watchdog reset. The GPIO port connected to the USER button (pin PB9) is set so that the external interrupt input generates an interrupt at each falling edge. In the interrupt controller of the system, this external interrupt generated by GPIO has a higher priority than Systick. This is used to simulate a program error in the external interrupt service routine: when the interrupt service routine is triggered by pressing the USER button, the interrupt suspend bit is not cleared. Therefore, the interrupt service routine will continue to execute, and the Systick interrupt service routine will not execute properly, which causes the watchdog to reset. After the system is reset, it will check the reset status. If the reset is caused by the watchdog, the LCD will display it. D5 (pin PD7) will also be lit.

The main function main.c looks like this:

Timeout = (frequency divider /40) * RLV = (32/40) *350=280ms

/* Includes ------------------------------------------------------------------*/ #include "stm32f10x.h" #include "stm3210c_eval_lcd.h" #include "stm32_eval.h" #include <stdio.h> ErrorStatus HSEStartUpStatus; void SysTick_Configuration(void); int main(void) { /* Setup the microcontroller system. Initialize the Embedded Flash Interface, initialize the PLL and update the SystemFrequency variable. */ SystemInit(); /* Initialize the LCD */ STM3210C_LCD_Init(); /* Clear the LCD */ LCD_Clear(White); /* Set the LCD Text Color */ LCD_SetTextColor(Black); printf(" STM3210C-EVAL \n"); printf(" How to use IWDG \n"); /* Initialize LED1 and Key Button mounted on STM3210X-EVAL board */ STM_EVAL_LEDInit(LED1); STM_EVAL_LEDInit(LED2); STM_EVAL_PBInit(Button_KEY, Mode_EXTI); /* Configure SysTick to generate an interrupt each 250ms */ SysTick_Configuration(); /* 1 bits for pre-emption priority and 3 bits for subpriority */ NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1); /* Set Button EXTI Interrupt priority to 0 (highest) */ NVIC_SetPriority(KEY_BUTTON_EXTI_IRQn, NVIC_EncodePriority (NVIC_GetPriorityGrouping (), 0, 0)); /* Set SysTick interrupt vector Preemption Priority to 1 */ NVIC_SetPriority(SysTick_IRQn, NVIC_EncodePriority (NVIC_GetPriorityGrouping (), 1, 0)); /* Check if the system has resumed from IWDG reset */ / If (RCC_GetFlagStatus(rCC_IWdGRST)! = RESET) {/* IWDGRST flag set */ * Turn on LED1 */ / LED1 on STM_EVAL_LEDOn(LED1); Printf ("RESET from IWDG\n"), /* Clear RESET flags */ / RCC_ClearFlag(); } else {/* IWDGRST flag is not set */ * Turn off LED1 */ / LED1 not bright STM_EVAL_LEDOff (LED1); printf("normal reset\n"); } /* IWDG timeout equal to 280 ms (the timeout may vary due to LSI frequency dispersion) */ / the timeout period = (octavium factor /40) * RLV = (32/40) *350=280ms /* Enable write access to IWDG_PR and IWDG_RLR Registers */ / Enable the PR and RLR registers to be written IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable); IWDG_SetPrescaler(IWDG_Prescaler_32); IWDG_Prescaler_32; /* Set counter reload value to 349 */ / Set counter reload value to 349; IWDG_ReloadCounter(); /* Reload IWDG counter */ printf("Press USER to kill IWDG reload! \n"), /* Enable IWDG (the LSI oscillator will be enabled by Hardware) */ / Enable IWDG IWDG_Enable(); while (1) {} } /** * @brief Configures SysTick to generate an interrupt each 250ms. * @param None * @retval None */ void  SysTick_Configuration(void) { /* SysTick interrupt each 250ms with counter clock equal to 9MHz */ if (SysTick_Config((SystemFrequency/8) / 4)) { /* Capture error */ while (1); } /* Select HCLK/8 as SysTick clock source */ SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8); }Copy the code

Stm32f10x_it. c interrupt service function EXTI9_5_IRQHandler:

void EXTI9_5_IRQHandler(void) { if (EXTI_GetITStatus(KEY_BUTTON_EXTI_LINE) ! /* Turn off LED2 */ STM_EVAL_LEDOn(LED2); printf("kill IWDG!!!" ); /* As KEY_BUTTON_EXTI_LINE pending bit is not cleared, the CPU will execute indefinitely this ISR and when the IWDG counter reaches 00h the IWDG reset occurs */ } }Copy the code

Stm32f10x_it. c interrupt service function SysTick_Handler:

void SysTick_Handler(void)
{
  /* Reload IWDG counter */
  IWDG_ReloadCounter();

  /* Toggle LED2 */
  STM_EVAL_LEDToggle(LED2);
}
Copy the code

5. The functions used

1) NVIC_PriorityGroupConfig

2) NVIC_GetPriorityGrouping

3) NVIC_EncodePriority

4) NVIC_SetPriority

5) RCC_GetFlagStatus

6) RCC_ClearFlag

7) IWDG_WriteAccessCmd

8) IWDG_SetPrescaler

9) IWDG_SetReload

10) IWDG_ReloadCounter

11) IWDG_Enable