stm32 uses the atomic delay function at the right time, and the main function delay fails

Publisher:糖三角Latest update time:2018-12-25 Source: eefocusKeywords:stm32 Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere

I recently discovered a phenomenon when I was working on something. I had never discovered it before, or I had never studied it carefully. I would like to share it with you.


When using the delay function of Atom Brother, I found that the delay function in the main function was invalid. It did not work. The following is a simple analysis of the whole process.


First directly on the code, a very simple example


int main(void)

{

 

delay_init(); //delay function initialization   

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //Set NVIC interrupt group 2: 2-bit preemption priority, 2-bit response priority

uart_init(115200); //Serial port initialized to 115200

  LED_Init(); //LED port initialization

UltrasonicWave_Configuration(); //IO port initialization

  TIM5_Cap_Init(0XFFFF,72-1); //Count at 1Mhz frequency 

        TIM7_Int_Init(99,7199); //10ms ultrasonic timing

        while(1)

{

LED1=!LED1;        

delay_us(50);

  delay_ms(1000);

        delay_ms(1000);

delay_ms(1000);

 

}


}


A level flip is performed in the main loop, and an LED light turns on and off.


But I found that the delay function was not executed and the LED kept flashing.


After debugging, I found that I had a delay function in a timer interrupt function, which caused the delay in the main function to fail.


void TIM7_IRQHandler(void)

{

if (TIM_GetITStatus(TIM7, TIM_IT_Update) != RESET) // is an update interrupt

{    

TIM_ClearITPendingBit(TIM7, TIM_IT_Update ); //Clear TIM7 update interrupt flag  

time_count++;

                switch (time_count)

{

case 1:

GPIO_SetBits(TRIG_PORT,TRIG_PIN_1); //Send high level >10US

        delay_us(20); //delay 20us

GPIO_ResetBits(TRIG_PORT,TRIG_PIN_1);

break;


case 2:

        GPIO_SetBits(TRIG_PORT,TRIG_PIN_2); //Send high level >10US

                          delay_us(20); //delay 20us

                          GPIO_ResetBits(TRIG_PORT,TRIG_PIN_2);

break;


case 3:

GPIO_SetBits(TRIG_PORT,TRIG_PIN_3); //Send high level >10US

                                delay_us(20); //delay 20us

                                GPIO_ResetBits(TRIG_PORT,TRIG_PIN_3);

break;


case 4:

GPIO_SetBits(TRIG_PORT,TRIG_PIN_4); //Send >10US high level

                                delay_us(20); //delay 20us

                                GPIO_ResetBits(TRIG_PORT,TRIG_PIN_4);

break;

}

if(time_count==4)

time_count=0;

}     

}


Because I actually need to operate 4 ultrasonic modules, I chose the delay function in a timer interrupt to perform the operation.


Later, it was discovered that this was also the reason for the delay in the main function.


Let's analyze it below


// Initialize delay function

//When using OS, this function will initialize the OS clock beat

//SYSTICK clock is fixed to 1/8 of HCLK clock

//SYSCLK: system clock

void delay_init()

{

#if SYSTEM_SUPPORT_OS //If OS support is required.

u32 reload;

#endif

SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8); //Select external clock HCLK/8

fac_us=SystemCoreClock/8000000; //1/8 of the system clock  

#if SYSTEM_SUPPORT_OS //If OS support is required.

reload=SystemCoreClock/8000000; //The number of counts per second is in K    

reload*=1000000/delay_ostickspersec; //Set overflow time according to delay_ostickspersec

//reload is a 24-bit register, with a maximum value of 16777216. At 72M, it takes about 1.86 seconds

fac_ms=1000/delay_ostickspersec; // represents the minimum unit that OS can delay    

 

SysTick->CTRL|=SysTick_CTRL_TICKINT_Msk; //Enable SYSTICK interrupt

SysTick->LOAD=reload; //Interrupt every 1/delay_ostickspersec seconds

SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk;    //开启SYSTICK    

 

#else

fac_ms=(u16)fac_us*1000; //Non-OS, represents the number of systick clocks required for each ms   

#endif

}


Delay initialization function, the clock of SysTick comes from the 8-frequency division of HCLK. The external crystal I use is 8M, and then multiplied to 72M, then the clock of SysTick is 9Mhz, that is, every time the SysTick counter VAL decreases by 1, it means that 1/9us has passed.


Delay function provided by Atom


void delay_us(u32 nus)

{

u32 temp;      

SysTick->LOAD=nus*fac_us; //Time loading Reload the register value and count down from this value

SysTick->VAL=0x00; // Clear the counter and clear the current register value to 0

SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk; //Start countdown   

do

{

temp=SysTick->CTRL;

}while((temp&0x01)&&!(temp&(1<<16))); //Wait for time to arrive   

SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk; //Turn off the counter

SysTick->VAL =0X00; //Clear the counter  

}

//Delay nms

//Note the range of nms

//SysTick->LOAD is a 24-bit register, so the maximum delay is:

//nms<=0xffffff*8*1000/SYSCLK

//SYSCLK is in Hz, nms is in ms

//Under 72M conditions, nms<=1864 

void delay_ms(u16 nms)

{     

u32 temp;    

SysTick->LOAD=(u32)nms*fac_ms; //Time loading (SysTick->LOAD is 24bit)

SysTick->VAL =0x00; //Clear the counter

SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk; //Start countdown  

do

{

temp=SysTick->CTRL;

}while((temp&0x01)&&!(temp&(1<<16))); //Wait for time to arrive   

SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk; //Turn off the counter

SysTick->VAL =0X00; //Clear the counter       


By viewing the SysTick control and status register 


The corresponding register names in the above figure are:


CTRL: Control and Status Register


LOAD : Reload value register


VAL: Current value register


CALIB: Calibration Register


In the main loop, execute the delay_ms(1000) function, convert the delay ms into the SysTick clock number, and then write it into the LOAD register. Then clear the current register VAL and start the countdown function. Wait until the countdown ends. At this time, enter the interrupt service function, execute the delay_us(20) function, convert the delay us into the SysTick clock number again, and then write it into the LOAD register. Then clear the current register VAL and start the countdown again.


When the interrupt is executed, the main function continues to execute, but the value in the LOAD register has been changed (changed by the delay function in the interrupt function) and is no longer the value originally calculated.


So the above situation will occur.


So, in the end I directly wrote a delay function similar to the one in 51 to solve this problem, although I think it is very low


Keywords:stm32 Reference address:stm32 uses the atomic delay function at the right time, and the main function delay fails

Previous article:stm32 strange bit assignment problem went wrong
Next article:stm32f103 study notes—— 05 Using SysTick to implement hardware delay

Recommended ReadingLatest update time:2024-11-15 07:35

STM32 cannot use IAR to download program
I created the project at first, and then the program was downloaded normally. I don't know why I downloaded the code myself, and then I couldn't download the code again. I followed the prompts to find the file FlashStm32f30x8.flash, but found that it was not in the IAR directory. I suspected that the IAR file was
[Microcontroller]
STM32 cannot use IAR to download program
Simple analysis of STM32 SysTick precise delay
When designing software, some have strict timing requirements, but simple delay functions cannot accurately delay --- STM32 has a system tick clock which is a good configuration --- ----The first part is---writing the initial value to the tick clock register, that is, decrementing according to the system frequency----
[Microcontroller]
STM32 USART DMA unknown length data reception and forwarding
Today, I finally realized that for data of unknown length, serial port 1 receives the command from the host computer, serial port 2 forwards the command to the module, and then receives the module data and sends it out through serial port 2. The entire serial port reception and transmission is completed by DMA, using
[Microcontroller]
STM32 TFT learning notes - brush characters
Host environment: Windows 7 SP1 Development environment: MDK5.14 Target board: ST NUCLEO-F303RE TFT model: 2.4 inches, with touch, SD card, 240*320 resolution, 260,000 colors Driver IC:ILI9325 ST library version: STM32Cube_FW_F3_V1.1.0 After brushing the picture, it is natural to want to brush the character experime
[Microcontroller]
stm32 pulse
There are two purposes for sending pulses: 1) speed control   2) position control The purpose of speed control is the same as analog quantity, so there is nothing to pay attention to The pulse sending method is PWM, which has a stable rate and takes up less resources. STM32 position control needs to obtain
[Microcontroller]
Detailed explanation of stm32 assertions
Recently, the company has not been busy, so I thought about enriching myself. I came across the "assertion mechanism" by chance, and I tried it carefully. I quickly recorded it down, also for the purpose of reviewing and learning new things, and then share it with you! First, let’s take a look at an application: (Th
[Microcontroller]
Detailed explanation of stm32 assertions
Causes and solutions for Flash download failed-Cortex-M3
First of all, this type of error is basically encountered by STM32 chips, and basically all of them use the JLINK emulator. In fact, the following methods may not necessarily help you solve the problem. We have not disclosed the real cause of the problem in this post. If you need to solve it, please contact the JLI
[Microcontroller]
Causes and solutions for Flash download failed-Cortex-M3
How to create a project template using the STM32_V3.5 firmware library
The preparations are as follows: 1: Download the firmware library of STM32_V3.5. Find it on the forum. There are many   2: Prepare Keil uVision4 software and install it on the computer.   3: Don’t bring a bench, just bring your head, because the bench can’t think.   start: 1: First, unzip the d
[Microcontroller]
How to create a project template using the STM32_V3.5 firmware library
Latest Microcontroller Articles
Change More Related Popular Components

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

About Us Customer Service Contact Information Datasheet Sitemap LatestNews


Room 1530, 15th Floor, Building B, No.18 Zhongguancun Street, Haidian District, Beijing, Postal Code: 100190 China Telephone: 008610 8235 0740

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号