STM32中 Systick问题 while(SysTick_Config(SystemFrequency / 1000)); 是什么意思,实现什么功能,求大神

作者&投稿:兴制 (若有异议请与网页底部的电邮联系)
stm32中Delay()函数延时的时间是怎么计算的?~

单片机编程过程中经常用到延时函数,最常用的莫过于微秒级延时delay_us(
)和毫秒级delay_ms(
)。1.普通延时法这个比较简单,让单片机做一些无关紧要的工作来打发时间,经常用循环来实现,不过要做的比较精准还是要下一番功夫。下面的代码是在网上搜到的,经测试延时比较精准。//粗延时函数,微秒
void delay_us(u16 time)
{
u16 i=0;
while(time--)
{
i=10; //自己定义
while(i--) ;
}
}
//毫秒级的延时
void delay_ms(u16 time)
{
u16 i=0;
while(time--)
{
i=12000; //自己定义
while(i--) ;
}
}2.SysTick 定时器延时CM3 内核的处理器,内部包含了一个SysTick
定时器,SysTick 是一个24 位的倒计数定时器,当计到0 时,将从RELOAD
寄存器中自动重装载定时初值。只要不把它在SysTick
控制及状态寄存器中的使能位清除,就永不停息。SysTick 在STM32
的参考手册里面介绍的很简单,其详细介绍,请参阅《Cortex-M3 权威指南》。
这里面也有两种方式实现:a.中断方式
如下,定义延时时间time_delay,SysTick_Config()定义中断时间段,在中断中递减time_delay,从而实现延时。
volatile unsigned long time_delay; //
延时时间,注意定义为全局变量
//延时n_ms
void delay_ms(volatile unsigned long nms)
{
//SYSTICK分频--1ms的系统时钟中断
if (SysTick_Config(SystemFrequency/1000))
{
while (1);
}
time_delay=nms;//读取定时时间
while(time_delay);
SysTick->CTRL=0x00; //关闭计数器
SysTick->VAL =0X00; //清空计数器
}
//延时nus
void delay_us(volatile unsigned long nus)
{
//SYSTICK分频--1us的系统时钟中断
if (SysTick_Config(SystemFrequency/1000000))
{
while (1);
}
time_delay=nus;//读取定时时间
while(time_delay);
SysTick->CTRL=0x00; //关闭计数器
SysTick->VAL =0X00; //清空计数器
} //在中断中将time_delay递减。实现延时void
SysTick_Handler(void)
{
if(time_delay)
time_delay--;

《如何从STM32F10xxx固件库V2.0.3升级为STM32F10xxx标准外设库V3.0.0》一文中的“3.3.2 SysTick”讲到:

在标准外设库中移除了SysTick的驱动,因此用户必须调用CMSIS定义的函数。
CMSIS只提供了一个SysTick设置的函数,替代了STM32原有SysTick驱动的全部函数。
SysTick_Config(uint32_t ticks);
该函数设置了自动重载入计数器(LOAD)的值,SysTick IRQ的优先级,复位了计数器(VAL)的值,开始计数并打开SysTick IRQ中断。SysTick时钟默认使用系统时钟。
下面的例程为使用固件库V2.0.3进行SysTick设置:
/* Select the HCLK Clock as SysTick clock source (72MHz) */
SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK);
/* SysTick end of count event each 1ms with input clock equal to 72MHz (HCLK) */
SysTick_SetReload(72000);
/* Enable SysTick interrupt */
SysTick_ITConfig(ENABLE);
下面的例程为使用标准外设库V3.0.0进行SysTick设置:
/* Setup SysTick Timer for 1 msec interrupts */
if (SysTick_Config(SystemFrequency / 1000)) /* SystemFrequency is defined in “system_stm32f10x.h” and equal to HCLK frequency */
{
/* Capture error */
while (1);
}

2.0库函数延时代码
/*初始化时钟*/
void Init_SysTick(void)
{
/* Disable SysTick Counter */
SysTick_CounterCmd(SysTick_Counter_Disable);

/* Disable the SysTick Interrupt */
SysTick_ITConfig(DISABLE);

/* Configure HCLK clock as SysTick clock source */
SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);

/* SysTick interrupt each 1000 Hz with HCLK equal to 72MHz */
SysTick_SetReload(9000);

/* Enable the SysTick Interrupt */
SysTick_ITConfig(ENABLE);
}

/*延时1ms函数*/
__IO uint32_t TimingDelay;
void delay_ms(__IO uint32_t nTime)
{
/* Enable the SysTick Counter */
SysTick_CounterCmd(SysTick_Counter_Enable);

TimingDelay = nTime;

while(TimingDelay != 0);

/* Disable SysTick Counter */
SysTick_CounterCmd(SysTick_Counter_Disable);

/* Clear SysTick Counter */
SysTick_CounterCmd(SysTick_Counter_Clear);
}

/*stm32f10x_it.c中的void SysTick_Handler(void)函数改为*/
extern __IO uint32_t TimingDelay;
void SysTick_Handler(void)
{
if (TimingDelay != 0x00)
{
TimingDelay--;
}
}

/*用法,延时1秒*/
delay_ms(1000);

3.5库函数延时代码
/*初始化时钟*/
void Init_SysTick(void)
{
if(SysTick_Config(SystemCoreClock / 1000)) //注意:3.5库中 SystemFrequency 被 SystemCoreClock 取代。
while(1);
}

/*延时1ms函数*/
__IO uint32_t TimingDelay;
void delay_ms(__IO uint32_t nTime)
{
TimingDelay = nTime;
while(TimingDelay != 0);
}

/*stm32f10x_it.c中的void SysTick_Handler(void)函数改为*/
extern __IO uint32_t TimingDelay;
void SysTick_Handler(void)
{
if (TimingDelay != 0x00)
{
TimingDelay--;
}
}

/*用法,延时1秒*/
delay_ms(1000);

static __INLINE uint32_t SysTick_Config(uint32_t ticks)
{
if (ticks > SYSTICK_MAXCOUNT) return (1); /* Reload value impossible */

SysTick->LOAD = (ticks & SYSTICK_MAXCOUNT) - 1; /* set reload register */
NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1); /* set Priority for Cortex-M0 System Interrupts */
SysTick->VAL = (0x00); /* Load the SysTick Counter Value */
SysTick->CTRL = (1 << SYSTICK_CLKSOURCE) | (1<<SYSTICK_ENABLE) | (1<<SYSTICK_TICKINT); /* Enable SysTick IRQ and SysTick Timer */
return (0); /* Function successful */
}
这是这个函数的定义,在core_cm3.h里面,是有返回值的,如果你设置的SystemFrequency / 1000不符合该函数要求就会返回1,这样这个while循环是跳不出的,一直在循环,只有你设置的值符合要求,程序才能跳出循环继续执行,这句话一般在SysTick_Config(SystemCoreClock / 1000);这句之后,上面这句已经配置好Systick的定时时间为1ms,紧接着 while(SysTick_Config(SystemFrequency / 1000)); 是判断你配置的定时频率是否可以实现,如果可以就继续往下执行,如果不可以就一直停在这里。(大哥,悬赏分都不给,我已经说得很详细了)

xydsy ,说得太好了,我最近也在做这方面!


怀宁县18320496235: stm32关于系统滴答定时器(systick) -
亓善泌淋: 你在中断处理函数中调用延时函数.是可以的.关键这个延时函数不可以使用到别的中断.stm32在中断处理中只能同时处理一个中断.如果该中断不处理完.即使有别的高级别中断产生也不会执行处理函数.你说你在你的延时函数中使用了systemtick,在你EXTI0_1_IRQHandler执行的时候,systemtick的中断处理不能执行.你的系统计时也不会增加,就导致你的延时函数永远等不到结束.如果你一定要延时的话,可以使用空循环.

怀宁县18320496235: STM32中 Systick问题 while(SysTick - Config(SystemFrequency / 1000)); 是什么意思,实现什么功能,求大神 -
亓善泌淋: static __INLINE uint32_t SysTick_Config(uint32_t ticks) {if (ticks > SYSTICK_MAXCOUNT) return (1); /* Reload value impossible */ SysTick->LOAD = (ticks & SYSTICK_MAXCOUNT) - 1; /* set reload register */NVIC_SetPriority (SysTick_IRQn, ...

怀宁县18320496235: STM32单片机Systick问题 -
亓善泌淋: const unsigned long System_Clock = 72MHz SysTick->LOAD = System_Clock /8000; //---这里,请注意 CTRL的第3位,即BIT2,如果为0, //----则表示把系统时钟分8频,如果为1,则表示 //----Systick的时钟为系统时钟 //----如果分8频,则除以...

怀宁县18320496235: 求助,STM32定时器3开启后SysTick延时不准 -
亓善泌淋: systick定时器有两个可选的时钟源,一个是外部时钟源(STCLK,等于HCLK/8),另一个是内核时钟(FCLK,等于HCLK).假若你选择内核时钟,并将HCLK频率设置为72MHz的话,系统时钟周期为1/(72M);systick有一个24位的递减计数器...

怀宁县18320496235: STM32的Systick设置问题:
亓善泌淋: 这是设置SysTick 定时器的一个初始化函数,具体解析如下:void SysTInit(void){SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);//SysTick时钟源为AHB时钟除以8SysTick_SetReload(9000);//SysTick重装载值为9000SysTick_ITConfig(ENABLE);//使能SysTick中断NVIC_SystemHandlerPriorityConfig(SystemHandler_SysTick, 0, 0);//设置优先级为0组0级SysTStop();}

怀宁县18320496235: STM32外部无法调用Systick - Config() -
亓善泌淋: 这个不需要调用,系统内定的一定要初始化stick中断,因为好多的hal对象都依赖于这个stick.

怀宁县18320496235: STM32问题 -
亓善泌淋: 不可以,寄存器是32位的,只有SysTick->CTRL&=0Xfffffffb可以保证其余的28位不会被改变,如果用SysTick->CTRL&=0Xfb,高24位全部都清零了.

怀宁县18320496235: STM32如何使用Systic(库函数) -
亓善泌淋: systick的中断是系统开辟了的 对于他的配置建议看下core_m3.h里面的SysTick_Config(uint32_t ticks)这个函数 调用这个函数以后 初始化状态就是 使用AHB ticks的值为VAL,也就是计数的滴答值,这个值减到了0就会中断,同时VAL值重新装填 还有 调用了函数以后,默认是开启了滴答计时器,所以要在调用函数之后关闭计时器,在要用的时候开启.对于滴答的开启与关闭是用寄存器做的

怀宁县18320496235: STM32 v3固件库编写SYSTICK,不报错,不进入中断,请大牛指点! -
亓善泌淋: 所有的中断函数都在启动汇编文件中声明了都是一些弱定义,说的白一点就是中断向量表,编译后把你定义的中断函数地址填进去.要用哪个中断直接重定义那个中断函数即可.stm32f10x_it.c只是官方自己为了整齐重新写的一个C

怀宁县18320496235: STM32的SysTick - >CTRL 理解 -
亓善泌淋: 就是你去读取该寄存器位后会被硬件清零. 打个类似的生活实例吧.比方 老师抽屉里有份试卷,不给你看 时你去看了,那该试卷就得作废,相当清零.该试卷不得再用.呵呵

本站内容来自于网友发表,不代表本站立场,仅表示其个人看法,不对其真实性、正确性、有效性作任何的担保
相关事宜请发邮件给我们
© 星空见康网