STM32中使用systick时钟进行延时的中断与非中断两种方法

发布时间:2024-11-21 04:59

《中医诊断学》:系统学习中医病症判断和诊断方法 #生活技巧# #健康生活方式# #健康生活方式书籍# #中医养生书籍#

一、第一种方法是进入内核中断的方式

#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、控制算法结合

随便看看