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 = 9MHzfac_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; //¼Ç¼ÓжàÉÙ¸öÕûµÄ540msu16 remain = nms % 540; //¼Ç¼ÓжàÉÙ¸ö²»¹»540mswhile(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