版权声明:本文为小生原创,转载请注明出处,好吗好的,善哉善哉!!! https://blog.csdn.net/u010650845/article/details/82188315
1.BB一下
原子哥的Delay延时函数,在没有使用OS的情况下,没有使用SysTick中断,而笔者希望通过该中断记录系统时间
- 不使用OS,使用SysTick中断
- 不使用OS,不使用SysTick中断
- 使用OS,使用SysTick中断
2.BB完了,上代码
2.1.不使用OS,使用SysTick中断
#define SYSTICK_INT_MS 500 /* 定义 SysTick 定时器 1/SYSTICK_INT_MS秒中断一次 */
static u8 fac_us=0;
static u16 fac_ms=0;
static u32 _tickMs = 0;
void SysTick_Handler(void)
{
_tickMs+=2;/*1/SYSTICK_INT_MS=2ms */
}
/* 获取系统时间 */
u32 get_systemMs(void){
return _tickMs;
}
/*
**************************************************
** desc : 延时函数初始化
** sysClk : 系统时钟频率
** note : SysTick的时钟频率是系统时钟频率的1/8
**************************************************
*/
void delay_init(u8 sysClk ){
u32 reload;
SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);/* 选择外部时钟 */
fac_us=sysClk/8; /* fac_us个时钟数1us */
reload=sysClk/8;
reload*=1000000/SYSTICK_INT_MS; /* 根据delay_ostickspersec设定溢出时间 */
/* reload为24位寄存器,最大值:16777216,在168M下,约合0.7989s左右 */
fac_ms=1000/SYSTICK_INT_MS; /* 最小延时单位 */
SysTick->CTRL|=SysTick_CTRL_TICKINT_Msk;/* 开启SysTick中断 */
SysTick->LOAD=reload; /* 每1/delay_ostickspersec秒中断一次 */
SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk; /* 开启SYSTICK */
}
/*
***********************************************
** desc : us 延时函数
** nus : 0~204522252(最大值即2^32/fac_us)
***********************************************
*/
void delay_us(u32 nus){
u32 ticks;
u32 told,tnow,tcnt=0;
u32 reload=SysTick->LOAD;
ticks=nus*fac_us; /* 需要的节拍数 */
told=SysTick->VAL; /* 当前 SysTick 计数值 */
while(1){
tnow=SysTick->VAL;
if(tnow!=told){
if(tnow<told)
tcnt+=told-tnow;
else
tcnt+=reload-tnow+told;
told=tnow;
if(tcnt>=ticks) /* 时间超过/等于要延迟的时间,则退出.*/
break;
}
};
}
/*
***********************************************
** desc : ms 延时函数
** nus : 0~204522(最大值即2^32/fac_us/1000)
***********************************************
*/
void delay_ms(u32 nms){
delay_us( nms*1000 );
#if 0
u32 time = get_systemMs();
while(1){
if( get_systemMs()-time>nms )
break;
}
#endif
}
2.2.不使用OS,不使用SysTick中断
static u8 fac_us=0;
static u16 fac_ms=0;
void delay_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_xms(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;
}
void delay_ms(u32 nms){
u8 repeat=nms/540;
u16 remain=nms%540;
while(repeat)
{
delay_xms(540);
repeat--;
}
if(remain)delay_xms(remain);
}
2.3.使用OS,使用SysTick中断
static u8 fac_us=0;
static u16 fac_ms=0;
static u32 _tickMs = 0;
void SysTick_Handler(void){
if( OSRunning==TRUE){
OSIntEnter();
OSTimeTick();
OSIntExit();
}
_tickMs+=2;//OS_TICKS_PER_SEC=500
}
u32 get_systemMs(void){
return _tickMs;
}
void delay_init(u8 sysClk){
u32 reload;
SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);
fac_us=sysClk/8;
reload=sysClk/8;
reload*=1000000/OS_TICKS_PER_SEC;
fac_ms=1000/OS_TICKS_PER_SEC;
SysTick->CTRL|=SysTick_CTRL_TICKINT_Msk;
SysTick->LOAD=reload;
SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk;
}
void delay_us(u32 nus)
{
u32 ticks;
u32 told,tnow,tcnt=0;
u32 reload=SysTick->LOAD;
ticks=nus*fac_us;
OSSchedLock();
told=SysTick->VAL;
while(1)
{
tnow=SysTick->VAL;
if(tnow!=told)
{
if(tnow<told)tcnt+=told-tnow;
else tcnt+=reload-tnow+told;
told=tnow;
if(tcnt>=ticks)break;
}
};
OSSchedUnlock();
}
void delay_ms(u16 nms)
{
if(OSRunning==TRUE)
{
if(nms>=fac_ms)
{
OSTimeDly(nms/fac_ms);
}
nms%=fac_ms;
}
delay_us((u32)(nms*1000));
}