Three methods of STM32 delay function--best to master the Third Kind

Source: Internet
Author: User
Tags reset volatile

The time delay function is often used in the process of MCU programming, the most commonly used is microsecond delay delay_us () and millisecond level Delay_ms ().

1. General Delay method

This is relatively simple, let the single-chip microcomputer do some unimportant work to pass the time, often with the loop to achieve, but to do more accurate or to the next effort. The following code is searched on the Internet, the test delay is more accurate.

Coarse delay function, microseconds
void Delay_us (U16 time)
{
U16 I=0;
while (time--)
{
i=10; Define Yourself
while (i--);
}
}
Millisecond-delay
void Delay_ms (U16 time)
{
U16 I=0;
while (time--)
{
i=12000; Define Yourself
while (i--);
}
}

2.SysTick Timer delay

CM3 Core processor, the internal contains a SysTick timer, SysTick is a 24-bit countdown timer, when counted to 0 o'clock, will automatically reload the timing initial value from the reload register. As long as the enable bits in the Systick control and status register are not removed, it will never cease. SysTick in STM32 's reference manual is simple and detailed, please refer to the CORTEX-M3 authoritative guide.

There are two ways to achieve this:

A. Mode of interruption

As below, define the delay time Time_delay,systick_config () defines the break time period, decrements the Time_delay in the interrupt, thus realizes the delay.
volatile unsigned long time_delay; Delay time, note defined as global variable
Delay N_ms
void Delay_ms (volatile unsigned long NMS)
{
System clock interrupt for Systick crossover--1ms
if (Systick_config (systemfrequency/1000))
{

while (1);
}
time_delay=nms;//Read Timing Time
while (Time_delay);
systick->ctrl=0x00; Turn off counters
Systick->val =0x00; Empty counter
}
Delay NUS
void Delay_us (volatile unsigned long NUS)
{
System clock interrupt for Systick crossover--1us
if (Systick_config (systemfrequency/1000000))
{

while (1);
}
time_delay=nus;//Read Timing Time
while (Time_delay);
systick->ctrl=0x00; Turn off counters
Systick->val =0x00; Empty counter
}

Decrements the Time_delay in the interrupt. Implementation delay

void Systick_handler (void)
{
if (Time_delay)
time_delay--;
}

B. Non-disruptive mode

The main imitation of the atom of the "STM32 Incomplete handbook". The clock of the SYSTICK is fixed at 1/8 of the HCLK clock, where we choose the internal clock source 72M, so the SYSTICK clock is 9M, that is, the SYSTICK timer decreases at 9M frequency. The SysTick consists of 4 registers, including CTRL, LOAD, VAL, calib, etc.

Systick->ctrl

Bit segment

Name

Type

Reset Value

Describe

16

Countflag

R

0

If the Systick is 0 after the last reading of the register, the bit is 1, and if the bit is automatically zeroed

2

Clksource

RW

0

0: External clock source 1: Internal clock

1

Tickint

RW

0

0: Reduced to 0 no action; 1: Reduced to 0 generates Systick exception request

0

ENABLE

RW

0

Systick timer Enable bit

Systick-> LOAD

Bit segment

Name

Type

Reset Value

Describe

23:0

RELOAD

RW

0

Reduced to 0 o'clock reload value

Systick-> VAL

Bit segment

Name

Type

Reset Value

Describe

23:0

Current

RW

0

Returns the current inverted count value on read, writes the zero, and clears the COUNTFLAG flag in the Systick control and status register

Systick-> Calib is not commonly used, we can not use it here, it is not introduced.

The procedure is as follows, the equivalent of query method.

//Imitation atomic delay, do not enter systic interrupt
void Delay_us (u32 nus)
{
 u32 temp;
 systick->load = 9*nus;
 systick->val=0x00;//Empty counter
 systick->ctrl=0x01;//enable, minus Zero is no action, take external clock source
 do
 {
  temp=systick->ctrl;//reads the current inverted count value
 }while (temp&0x01) && (! ( temp& (1<<16)));//wait time arrives
     SysTick->CTRL=0x00;//Close counter
     systick->val =0x00; Empty counter
}
void Delay_ms (U16 nms)
{
 u32 temp;
 systick->load = 9000*nms;
  systick->val=0x00;//Empty counter
 systick->ctrl=0x01;//enable, minus Zero is no action, take external clock source
 do
 {
  temp=systick->ctrl;//reads the current inverted count value
 }while ((temp&0x01) && (!) ( temp& (1<<16)));//wait time arrives
    SysTick->CTRL=0x00;//Close counter
     systick->val =0x00; Empty counter
}

Three ways have pros and cons, the first way is easy to understand, but not very precise. The second way to use the library function, writing simple, because of the existence of interrupts, not conducive to other interrupts call this delay function. The third way to directly operate the register, it looks more cumbersome, in fact, it is not difficult, at the same time overcome the shortcomings of the above two ways, personal feeling more useful.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.