STM32中使用systick时钟进行延时的中断与非中断两种方法
《中医诊断学》:系统学习中医病症判断和诊断方法 #生活技巧# #健康生活方式# #健康生活方式书籍# #中医养生书籍#
一、第一种方法是进入内核中断的方式#include "systick.h"
u32 TimingDelay;
void Delay_ms(__IO uint32_t nTime)
{
if (SysTick_Config(SystemCoreClock / 1000))
{
while (1);
}
TimingDelay = nTime;
while(TimingDelay != 0);
SysTick->CTRL = 0x00;
SysTick->VAL = 0x00;
}
void Delay_us(__IO uint32_t nTime)
{
if (SysTick_Config(SystemCoreClock / 1000000))
{
while (1);
}
TimingDelay = nTime;
while(TimingDelay != 0);
SysTick->CTRL = 0x00;
SysTick->VAL = 0x00;
}
void SysTick_Handler(void)
{
if (TimingDelay != 0x00)
{
TimingDelay--;
}
}
中断函数位置在
注意:使用这种延时方式在普通情况下是可以的,但是一旦在其他中断中调用此延时函数,便会使程序卡死,比如在按键外部中断中进行按键消抖延时。
void EXTI0_IRQHandler(void)
{
Delay_ms(10);
if(K0 == 1)
{
LED1 = ~LED1;
}
EXTI_ClearITPendingBit(EXTI_Line0);
}
触发中断进入延时函数后会死在 while(TimingDelay != 0); 这是因为 void SysTick_Handler(void) 函数是内核中断,内核将其中断优先级设置为最低,导致在外部中断函数里无法抢占执行,参数TimingDelay也就无法减小。
此内核中断优先级的设置在,比如将优先级设置为0后可以抢占使用,但是需注意调用延时函数的中断的优先级要小于systick所改的优先级,经实验是可行的。
static __INLINE uint32_t SysTick_Config(uint32_t ticks)
{
if (ticks > SysTick_LOAD_RELOAD_Msk) return (1);
SysTick->LOAD = (ticks & SysTick_LOAD_RELOAD_Msk) - 1;
NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1);
SysTick->VAL = 0;
SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk |
SysTick_CTRL_TICKINT_Msk |
SysTick_CTRL_ENABLE_Msk;
return (0);
}
二、第二种方法是无需进入内核中断的方式这种方式利用设置Systick时钟的重装载值,然后重装载值倒数完毕后会将SysTick->CTRL的位15置1,对该位进行判断便可知道延时完毕否。这种延时方式无需进入 void SysTick_Handler(void) 中断,在中断中使用也不怕优先级问题了,就不需要改内核文件了。这种方式虽然看起来有点繁琐,但是也不难理解。
#include "delay.h"
static u8 fac_us=0;
static u16 fac_ms=0;
void SysTick_Init(u8 SYSCLK)
{
SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);
fac_us=SYSCLK/8;
fac_ms=(u16)fac_us*1000;
}
void delay_us(u32 nus)
{
u32 temp;
SysTick->LOAD=nus*fac_us;
SysTick->VAL=0x00;
SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk ;
do
{
temp=SysTick->CTRL;
}while((temp&0x01)&&!(temp&(1<<16)));
SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk;
SysTick->VAL =0X00;
}
void delay_ms(u16 nms)
{
u32 temp;
SysTick->LOAD=(u32)nms*fac_ms;
SysTick->VAL =0x00;
SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk ;
do
{
temp=SysTick->CTRL;
}while((temp&0x01)&&!(temp&(1<<16)));
SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk;
SysTick->VAL =0X00;
}
总结:两种方法最好都能掌握,因为比如一些比赛中,内核文件是上锁修改不了的。另外中断中其实最好不要使用延时的,但是有时候似乎迫不得已,尽量少用而且不能延时太长吧。
网址:STM32中使用systick时钟进行延时的中断与非中断两种方法 https://www.yuejiaxmz.com/news/view/168031
相关内容
基于STM32的智能节能风扇的设计与实现一种基于STM32的智能家居控制系统
旅行中的时差反应
渐进式延时训练法
断桥铝门窗使用过程中如何保养
中医养生的意义与方法
STM32智能除湿系统的设计方案
中央空调如何使用?中央空调开关使用方法图解
基于STM32的宠物远程投喂和监测系统设计
基于STM32的智能交通灯控制系统设计与实现思路:LoRa、控制算法结合