This article has participated in the Denver Nuggets Creators Camp 3 “More Productive writing” track, see details: Digg project | creators Camp 3 ongoing, “write” personal impact.

preface

Timers, as the name implies, are used for timing, but in addition to timing, we can also use the timer’s counting characteristics to evolve other interesting functions (such as motor speed control). But before we do that, let’s take a look at how timers work.

This paper gives an overview of

1. Basic concept of timer

1.1. Counting width

This refers to the number of digits of the counter. For example, the count bit of Systick timer in CM3 kernel has 24 bits, that is, the maximum count value is 224-1 = 16,777,215. Let’s say Systick has a count width of 24.

1.2. Working mode

Timer is human design, and design is free. Since you specify the range of values for counting, we can count from 0 to 16,777,215, and we can count from 16,777,215 to 0, right? So this leads to the concept of working mode:

  • Counting up: count from 0 to 16,777,215
  • Count down: from 16,777,215 to 0

There is no essential difference between the two models. However, some timers may not give us developers the freedom to operate, limiting the count only to up or down.

1.3 counting cycle

Now that we have defined the range of counting, what is the time period between counting from 1 to 2, and counting from 2 to 3? How do we keep the counting period constant?

The question is really simple… Use the clock! The pulse of a clock is easily determined. Then we can implement counting cycles directly using the clock, i.e. :


T C N T = 1 f C l k S o u r c e T_{CNT} = \frac{1}{f_{ClkSource}}\qquad

1.4. Counting duration

What? Just said the counting period, can you give me the counting period now? What thing?

Oh, this guy is for interruption.

We started with the count width, which determines the maximum count we can take. But it just determines the maximum number of values that we can take, CNT, short for count, which is up to us. Depending on the requirements of the project, you can take as many as you want. That is:


t = C N T x T C N T T = x T_ CNT {} CNT

When the count up or down reaches CNT times, the count overflows and triggers a timer interrupt. What does this interrupt do? Don’t worry, we’ll talk about it later.

1.5. Reload the counter

We just said that when the count up or down reaches CNT times, a timer interrupt is triggered. So how does the counter continue to time after the interrupt ends? Very simple, design a special control of the detection count of the state of the module, when the count value reached our specified CNT, reset the timer, let it count again OK.

This reset operation, commonly known as the reload counter, can be controlled by manipulating the relevant registers.

1.6. Simple timer model

According to the above information, we can build the timer model as follows:

Second, the Systick

2.1, introduction to

SysTick – System timer is a peripheral that belongs to the CM3 kernel and is embedded in NVIC. Also known as the tick timer, because it only needs a simple counting function.

The system timer is a 24bit down-counting counter (PS: only down-counting here) with a count time of 1/SYSCLK.

Because SysTick is a peripheral of the CM3 kernel, all microcontrollers based on the CM3 kernel have this

System timer, so that the software in CM3 MCU can be easily transplanted. System timers are generally used in operating systems to generate time bases and maintain the heartbeat of the operating system.

(The above is from the information of wildfire, cut and revised.)

2.2 Systick Application and configuration process

2.2.1 Register groups for Systick

For Systick, there are four registers that control it:

  • CTRL: SysTick control and status register
  • LOAD: SysTick Reloads the value register
  • VAL: SysTick current value register
  • CALIB: SysTick calibration value register

Given what we saw in the previous section, it should be easy to understand why these registers appear. Also, if we need to operate registers directly, we generally only need to operate the first three registers. Of course, we usually use the firmware library directly now.

For Systick applications, we are generally directly used to implement the delay function, to achieve accurate delay.

2.2.1 Implementation principle of delay function

As we know from the previous introduction, when the value of the counter reaches our specified CNT, an interrupt is generated.

We can define a variable Delaytime. Delaytime– is handled on every interrupt. In the delay function, we only need to pass the time we want to delay to Delaytime, and determine whether Delaytime is 0.

2.2.2, configuration,

To do this, we simply call the library function Systick_Config() provided by the firmware library.

This function only requires us to pass in the value of the counter, which greatly simplifies the operation steps.

So what are the general incoming arguments? Take STM32F10X series as an example, the system clock is generally 72Mhz, because the microcontroller executes instructions at the microsecond level, so we generally set an interrupt time as 1ms, that is, the general parameter transmission is 72000.

2.3. Code Examples

Only speak principle does not speak application example is play rascal…

Here I use the wildfire guide to achieve 1s of LED flashing as an example.

Complete project code: My_Github

2.3.1. Main function

#include "stm32f10x.h"
#include "stm32f10x_it.h"
#include "led.h"
u8 state;
int main(void)
{
	SysTick_Config(72000);
	Led_Init();
	Led_Control(Led_All,OFF);
	while(1)
	{
        Led_Control(Led_All,state);
		Delay_ms(1000);
		state ^=1; }}Copy the code

2.3.2 Interrupt service function

u32 Delaytime;
void Delay_ms(u32 time)
{
	Delaytime = time;
	while(Delaytime);
}
void SysTick_Handler(void)
{
	Delaytime--;
}
Copy the code

The resources

Zero Dead Angle STM32 — F103 Guide

CM3 Authoritative Guide CnR2