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
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
- Popular Resources
- Popular amplifiers
- Learn ARM development(16)
- Learn ARM development(17)
- Learn ARM development(18)
- Embedded system debugging simulation tool
- A small question that has been bothering me recently has finally been solved~~
- Learn ARM development (1)
- Learn ARM development (2)
- Learn ARM development (4)
- Learn ARM development (6)
Professor at Beihang University, dedicated to promoting microcontrollers and embedded systems for over 20 years.
- LED chemical incompatibility test to see which chemicals LEDs can be used with
- Application of ARM9 hardware coprocessor on WinCE embedded motherboard
- What are the key points for selecting rotor flowmeter?
- LM317 high power charger circuit
- A brief analysis of Embest's application and development of embedded medical devices
- Single-phase RC protection circuit
- stm32 PVD programmable voltage monitor
- Introduction and measurement of edge trigger and level trigger of 51 single chip microcomputer
- Improved design of Linux system software shell protection technology
- What to do if the ABB robot protection device stops
- CGD and Qorvo to jointly revolutionize motor control solutions
- CGD and Qorvo to jointly revolutionize motor control solutions
- Keysight Technologies FieldFox handheld analyzer with VDI spread spectrum module to achieve millimeter wave analysis function
- Infineon's PASCO2V15 XENSIV PAS CO2 5V Sensor Now Available at Mouser for Accurate CO2 Level Measurement
- Advanced gameplay, Harting takes your PCB board connection to a new level!
- Advanced gameplay, Harting takes your PCB board connection to a new level!
- A new chapter in Great Wall Motors R&D: solid-state battery technology leads the future
- Naxin Micro provides full-scenario GaN driver IC solutions
- Interpreting Huawei’s new solid-state battery patent, will it challenge CATL in 2030?
- Are pure electric/plug-in hybrid vehicles going crazy? A Chinese company has launched the world's first -40℃ dischargeable hybrid battery that is not afraid of cold
- Prize-giving event | NI helps you design a more reliable data acquisition system
- MSP430 clock system
- Op amp biasing
- 【Homemade】OLED ultra-thin downloader
- 【BK7231N】Tuya Development Board Evaluation 1-System Development Environment Construction
- Touch MCU YS65F805 Data Sheet
- The simplest air purifier
- Wireless Charging Technology
- DSP interrupt PIE controller
- Unveiling IoT security solutions: Microsoft Azure Sphere