豆皮 - STM32开发板入门教程(三) - SysTick 定时器 (原创)

发布: 2008-10-23 17:08 | 作者: littleworm | 来源: StmFans思蜕盟 OPELC 自由电子联盟


豆皮 - STM32开发板入门教程(三) - SysTick 定时器 (原创)


版权所有 STMFANS 原创,转载请保留出处

http://www.stmfans.com/bbs/viewthread.php?tid=1069&page=1&extra=page%3D1




OK  下面继续做偶们的SysTick定时器咯  呵呵

本教程的主角是:SysTick  




通常实现Delay(N)函数的方法为:

for(i = 0; i <= x; i ++);

         x  ---  对应于 对应于N 毫秒的循环值




对于STM32系列微处理器来说,执行一条指令只有几十个ns,进行for循环时,要实现N毫秒的x值非常大,而且由于系统频率的宽广,很难计算出延时N毫 秒的精确值。针对STM32微处理器,需要重新设计一个新的方法去实现该功能,以实现在程序中使用Delay(N)。




Cortex-M3的内核中包含一个SysTick时钟。SysTick 为一个24位递减计数器,SysTick设定初值并使能后,每经过1个系统时钟周期,计数值就减1。计数到0时,SysTick计数器自动重装初值并继续计数,同时内部的COUNTFLAG标志会置位,触发中断(如果中断使能)。

在STM32的应用中,使用Cortex-M3 内核的SysTick作为定时时钟,设定每一毫秒产生一次中断,在中断处理函数
  里对N减一,在Delay(N)函数中循环检测N是否为0,不为0则进行循环等待;若为0则关闭SysTick时钟,退出函数。


注: 全局变量TimingDelay    必须定义为volatile

          延迟时间将不随系统时钟频率改变。



外部晶振为8MHz,9倍频,系统时钟为72MHz,SysTick的最高频率为9MHz(最大为HCLK/8),在这个条件下,把SysTick 效验值设置成9000,将SysTick 时钟设置为9MHz, 就能够产生1ms的时间基值,即SysTick产生1ms的中断。




使用ST的函数库使用systick的方法
1、调用SysTick_CounterCmd() 失能SysTick计数器
2、调用SysTick_ITConfig () 失能SysTick中断
3、调用SysTick_CLKSourceConfig() 设置SysTick时钟源。

4、调用SysTick_SetReload() 设置SysTick重装载值。
5、调用SysTick_ITConfig ()     使能SysTick中断
6、调用SysTick_CounterCmd() 开启SysTick计数器



SysTick   配置函数

/*******************************************************************************
* Function Name  : SysTick_Config
* Description    : Configures SysTick
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
//SysTick设置
void SysTick_Config(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);
}



Delay_Ms  延迟一毫秒函数

/*******************************************************************************
* Function Name  : Delay_Ms
* Description    : Inserts a delay time.
* Input          : nTime: specifies the delay time length, in milliseconds.
* Output         : None
* Return         : None
*******************************************************************************/
void Delay_Ms(u32 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);
}



TimingDelayMs_Decrement    中断调用函数

/*******************************************************************************
* Function Name  : TimingDelayMs_Decrement
* Description    : Decrements the TimingDelay variable.
* Input          : None
* Output         : TimingDelay
* Return         : None
*******************************************************************************/
void TimingDelay_Decrement(void)
{
    if (TimingDelay != 0x00)
    {
      TimingDelay--;
    }
}



SysTickHandler  中断进入函数

/*******************************************************************************
* Function Name  : SysTickHandler
* Description    : This function handles SysTick Handler.
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
void SysTickHandler(void)
{
  TimingDelay_Decrement();
}


NVIC_Configuration 中断向量表配置

/*******************************************************************************
* Function Name  : NVIC_Configuration
* Description    : Configures NVIC and Vector Table base location.
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
void NVIC_Configuration(void)
{
#ifdef  VECT_TAB_RAM
  /* Set the Vector Table base location at 0x20000000 */
  NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x0);
#else  /* VECT_TAB_FLASH  */
  /* Set the Vector Table base location at 0x08000000 */
  NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0);
#endif
}




完整工程在附件里

敬请继续关注 豆皮的的教程会逐步推出



[ 本帖最后由 littleworm 于 2008-11-24 12:23 编辑 ]

WORM_SysTick.rar
(2008-10-24 10:06:12, Size: 228 KB, Downloads: 449)

WORM_SysTick_520.rar
(2008-11-24 12:23:55, Size: 244 KB, Downloads: 617)

aleyn (2008-10-23 17:21:12)
jasonjee (2008-10-23 21:10:57)
不错,支持
lvhaian (2008-10-24 09:18:19)
继续顶,呵呵!
好帖子怎能不顶。
binglin (2008-10-25 09:57:28)
支持
yunfei7370 (2008-10-26 07:57:23)
不错,支持
yunfei7370 (2008-10-26 16:46:35)
好!支持1
kbgyzp (2008-10-27 17:08:36)
这个定时器函数岂不只能调用一次啊,调多了就乱逃了
lostgb (2008-11-01 22:43:38)
写的很详细,支持一下
supermouse88 (2008-11-04 10:53:39)
学习一下啊
easworld2k (2008-11-05 15:35:26)
都要调用ST的库的啊
littleworm (2008-11-05 16:31:48)

QUOTE:

原帖由 easworld2k 于 2008-11-5 15:35 发表
都要调用ST的库的啊
呵呵 一般的应用 直接调用库 做起来比较方便啊

如果速度性能要求比较高  那就抛弃库裸奔 也是可以的啊 呵呵
beeqer (2008-11-08 09:39:50)
谢谢,鼎立支持
ddllxxrr (2008-11-09 07:07:28)
好东东支持下
cy_aries (2008-11-12 08:54:12)
这个定时器比较方便!
jiayushu (2008-11-14 20:14:50)
谢谢,下载看看
wjmcu (2008-11-17 18:42:06)
谢谢,下载看看
archsb (2008-11-18 08:57:10)
怎么都这么有才呢。真是高手
yayongzhang (2008-11-18 15:22:39)
个人就是实现精确定时,用处不大,因为还是靠查询,别的用途还没有想到?不知理解的是否正确?
littleworm (2008-11-18 15:30:27)

QUOTE:

原帖由 yayongzhang 于 2008-11-18 15:22 发表
个人就是实现精确定时,用处不大,因为还是靠查询,别的用途还没有想到?不知理解的是否正确?
不是很理解你说的 呵呵  
不一定非要使用查询啊
可以使用中断里面判断的方式啊
isd2560 (2008-11-24 10:48:06)
娃哈哈,好东东