SysTick定时器定义:
SysTick
是一个 24 位的倒计数定时器,当计到
0
时,将从
RELOAD
寄存器中自动重装载定时初值。只要不把它在 SysTick 控制及状态寄存器中的使能位清除,就永不停息。
SysTick定时器分类:
SysTick定时器工作过程:
SysTick Control and Status Register(控制及状态寄存器)
SysTick Reload Value Register(重装载值寄存器)
SysTick Current Value Register(当前值寄存器)
时钟频率
delay.c
#include "delay.h"
//ÀûÓÃϵͳµÎ´ð¶¨Ê±£¬±àдµÄÑÓʱº¯Êý
static u8 fac_us=0; //usÑÓʱ±¶³ËÊý
static u16 fac_ms=0; //msÑÓʱ±¶³ËÊý
/****************************************************************************
* Ãû ³Æ: delay_init()
* ¹¦ ÄÜ£ºÑÓʱº¯Êý³õʼ»¯
* Èë¿Ú²ÎÊý£ºÎÞ
* ·µ»Ø²ÎÊý£ºÎÞ
* ˵ Ã÷£º
****************************************************************************/
void delay_init(void)
{
SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);
//Ϊϵͳ¶¨Ê±Æ÷Ñ¡ÔñʱÖÓΪ HCLK 8·ÖƵ 72MHz / 8 = 9MHz
fac_us = SYSCLK / 8;
//΢ÃëµÄ±¶³ËÊý = 72 / 8 = 9
//X * fac_us¾ÍÏ൱ÓÚÓÐX¸ö΢Ãî
fac_ms = (u16)fac_us * 1000;
//ÿ¸ömsÐèÒªµÄsystickʱÖÓÊý(1ms = 1000us),ËùÒÔfac_us*1000
//X * fac_ms¾ÍÏ൱ÓÚÓÐX¸öºÁÃî
}
/****************************************************************************
* Ãû ³Æ: void delay_us(u32 nus)
* ¹¦ ÄÜ£ºÑÓʱnus
* Èë¿Ú²ÎÊý£ºÒªÑÓʱµÄ΢ÃëÊý
* ·µ»Ø²ÎÊý£ºÎÞ
* ˵ Ã÷£ºnusµÄÖµ,²»Òª´óÓÚ1864135us
****************************************************************************/
/*
ͨ¹ýÏà¹ØÊÖ²áÎÒÃÇÁ˽⵽,±¸·ÝÖµ¼Ä´æÆ÷ºÍµ±Ç°Öµ¼Ä´æÆ÷µÄÖµ×î´óΪ16M - 1
ÎÒÃǵÄ΢Ã뼶µÄÑÓʱº¯ÊýµÄ±¶³ËÊýΪ9ËùÒÔ16M - 1 / 9 = 1864135
*/
void delay_us(u32 nus)
{
u32 midtime; //±£´æ¼Ä´æÆ÷µÄ״̬
SysTick->LOAD = nus * fac_us; //ʱ¼ä¼ÓÔØ(Ï൱ÓÚÓÐnus¸ö΢Ãî)
SysTick->VAL = 0x00; //Çå¿Õ¼ÆÊýÆ÷
SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk; //ʹÄÜϵͳ¶¨Ê±Æ÷¼ÆÊý
do
{
midtime = SysTick->CTRL;
}
while((midtime & 0x01) && !(midtime & (1 << 16)));//µÈ´ýʱ¼äµ½´ï
SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk; //¹Ø±Õ¼ÆÊýÆ÷
SysTick->VAL = 0X00; //Çå¿Õ¼ÆÊýÆ÷
}
/****************************************************************************
* Ãû ³Æ: void delay_xms(u16 nms)
* ¹¦ ÄÜ£ºÑÓʱnms
* Èë¿Ú²ÎÊý£ºÒªÑÓʱµÄºÁÃîÊý
* ·µ»Ø²ÎÊý£ºÎÞ
* ˵ Ã÷£ºSysTick->LOADΪ24λ¼Ä´æÆ÷,ËùÒÔ,×î´óÑÓʱΪ: nms<=0xffffff*8*1000/SYSCLK
¶Ô9MÌõ¼þÏÂ,nms<=1864ms
****************************************************************************/
void delay_xms(u16 nms)
{
u32 midtime;
SysTick->LOAD = (u32)nms*fac_ms; //ʱ¼ä¼ÓÔØ(SysTick->LOADΪ24bit)
SysTick->VAL = 0x00; //Çå¿Õ¼ÆÊýÆ÷
SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk; //¿ªÊ¼µ¹Êý
do
{
midtime = SysTick->CTRL;
}
while((midtime & 0x01) && !(midtime & (1 << 16)));//µÈ´ýʱ¼äµ½´ï
SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk; //¹Ø±Õ¼ÆÊýÆ÷
SysTick->VAL = 0X00; //Çå¿Õ¼ÆÊýÆ÷
}
/****************************************************************************
* Ãû ³Æ: void delay_ms(u16 nms)
* ¹¦ ÄÜ£ºÑÓʱnms
* Èë¿Ú²ÎÊý£ºÒªÑÓʱµÄºÁÃîÊý
* ·µ»Ø²ÎÊý£ºÎÞ
* ˵ Ã÷£ºnms:0~65535
****************************************************************************/
void delay_ms(u16 nms)
{
u8 repeat = nms / 540; //¼Ç¼ÓжàÉÙ¸öÕûµÄ540ms
u16 remain = nms % 540; //¼Ç¼ÓжàÉÙ¸ö²»¹»540ms
while(repeat)
{
delay_xms(540);
repeat--;
}
if(remain)delay_xms(remain);
}
delay.h
#ifndef __DELAY_H
#define __DELAY_H
#include "stm32f10x_conf.h"
#define SYSCLK 72
typedef uint32_t u32;
typedef uint16_t u16;
typedef uint8_t u8;
void delay_init(void);
void delay_ms(u16 nms);
void delay_us(u32 nus);
#endif