简介
SysTick 叫做系统滴答时钟、系统定时器,属于 Cortex-M4 内核中的一个外设(外围设备),它 24bit 向下递减 的计数器。
注意:
定时器的位数越多,定时时间更长。
通过计数值间接计算定时时间,不能像操作系统直接调用函数实现延时或定时功能。
系统定时器是24位,最大数值是(2^24 -1)
//系统定时器触发1KHz的中断,中断周期时间T= 1/f = 1000ms/1000=1ms
//系统定时器连接到PLL输出的168MHz时钟
//只要系统定时器进行168000000次计数,就是1秒时间的到达
//只要系统定时器进行168000次计数,就是1ms时间的到达
//只要系统定时器进行168次计数,就是1us时间的到达
SysTick_Config(SystemCoreClock/1000);
计算最大的定时时间
Tmax = 2^24 *1000ms/168000000 = 99.86ms。
初始化系统定时器,1S 内核触发 1000 次中断,说白了定时 1ms,能够成功
SysTick_Config(SystemCoreClock/1000);
初始化系统定时器,1S 内核触发 10 次中断,说白了定时 100ms,现象失败
SysTick_Config(SystemCoreClock/10);
初始化系统定时器,1S 内核触发 11 次中断,说白了定时 90.90ms,能够成功
SysTick_Config(SystemCoreClock/11);
总结:填写中断频率值不能小于11,否则定时时间不准确。
例
#include "stm32f4xx.h"
#include "sys.h"
static GPIO_InitTypeDef GPIO_InitStructe;
void deply_us(uint32_t t)
{
SysTick->CTRL = 0;//关闭系统定时器
SysTick->LOAD = 168*t-1;//给予计数值,决定延时时间,1微妙
SysTick->VAL = 0; //清空CTRL寄存器的count标志位,重新开始计数
SysTick->CTRL = 5; //使用的时钟源为系统时钟(168MHz是5,21MHz是1),开始工作
while((SysTick->CTRL & 0x00010000) ==0);//检测CTRL寄存器的count标志位是否置1,若置1,就代表计数完毕
SysTick->CTRL =0;
}
//最大值为99.8ms
void deply_ms(uint32_t t)
{
while(t--)
{
SysTick->CTRL = 0;
SysTick->LOAD = 168000-1;
SysTick->VAL = 0;
SysTick->CTRL = 5;
while((SysTick->CTRL & 0x00010000) == 0);
SysTick->CTRL = 0;
}
}
int main(void)
{
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF|RCC_AHB1Periph_GPIOE,ENABLE);
GPIO_InitStructe.GPIO_Pin = GPIO_Pin_9|GPIO_Pin_10;
GPIO_InitStructe.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructe.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructe.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_InitStructe.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_Init(GPIOF,&GPIO_InitStructe);
GPIO_InitStructe.GPIO_Pin = GPIO_Pin_13|GPIO_Pin_14;
GPIO_Init(GPIOE,&GPIO_InitStructe);
GPIO_SetBits(GPIOF,GPIO_Pin_9|GPIO_Pin_10);
GPIO_SetBits(GPIOE,GPIO_Pin_13|GPIO_Pin_14);
//系统定时器
SysTick_Config(SystemCoreClock/1000);
while(1)
{
}
}
void SysTick_Handler(void)
{
static uint32_t i=0;
static uint32_t j=0;
static uint32_t k=0;
static uint32_t l=0;
i++;
j++;
k++;
l++;
if(i==100)
{
i=0;
PFout(9) ^= 1;
}
if(j == 330)
{
j=0;
PFout(10) ^= 1;
}
if(k == 1500)
{
k=0;
PEout(13) ^= 1;
}
if(l == 2200)
{
l=0;
PEout(14) ^= 1;
}
}