一、引言
介绍
Systick定时器是一种专用于ARM Cortex-M系列微控制器的系统定时器,旨在提供一个简单、标准化的方式来生成时间间隔。它通常用于操作系统的时基,也可以用于延时、定时事件和周期性任务等。Systick定时器由一个24位的递减计数器组成,能够自动重装载,从而实现精确的定时功能。该定时器由内核提供,具有较高的集成度和使用简便的特点。
工作原理
Systick定时器的工作原理基于一个递减计数器,该计数器每接收到一个时钟信号就减1。当计数器的值递减到0时,会自动重装载一个预设值,并触发一次中断。通过设置计数器的初始值和时钟源,可以精确控制中断的发生频率。典型的使用场景包括每1毫秒触发一次中断,用于系统时基计数或周期性任务调度。在中断服务程序中,用户可以执行需要定时的操作,从而实现对时间的精确控制。
二、代码
1.main.c
Systick定时器初始化设置一个定时中断,每1微秒触发一次中断,在主循环中,用延时函数延时10ms,每10ms timercount就会+1,10ms时灯亮,100ms时灯灭,并将计时清零。循环往复,实现LED每1s亮0.9s灭0.1s
#include "stm32f10x.h"
#include "LED.h"
#include "systick.h"
static uint16_t timecount;
int main(void)
{
LED_Init();
systick_Init();
/* 清零时间计数 */
timecount=0;
while (1)
{
/* 延时10ms */
Delay_ms(10);
/* 每10ms计数值增加1 */
timecount++;
/* 计数到10,延时时间为100ms */
if(timecount==10)
{
LED1_ON();
}
/* 计数到100,延时时间为1s */
if(timecount==100)
{
LED1_OFF();
/* 清零时间计数 */
timecount=0;
}
}
}
2.systick.c
systick_Init()初始化配置Systick定时器,每1微秒触发一次中断,然后关闭定时器
Delay_us(__IO u32 nTime)将延时时间赋值给全局变量TimingDelay,然后使能Systick定时器,等待计时器计数为0,即完成延时
TimingDelay_Decrement()是定时器中断处理函数,用于在Systick中断函数SysTick_Handler()(见4.其他)
中调用,每次计时器计数非零时,将计数值减1
具体请见代码旁的注释
#include "systick.h"
static __IO u32 TimingDelay;
//初始化配置系统滴答定时器 SysTick
void systick_Init(void)
{
/* SystemFrequency / 1000 1ms中断一次
* SystemFrequency / 100000 10us中断一次
* SystemFrequency / 1000000 1us中断一次
*/
if (SysTick_Config(SystemCoreClock / 1000000))
{
/* Capture error */
while (1);
}
/* 关闭系统滴答定时器:初始化先不用开启,等需要延时时才开启定时器 */
SysTick->CTRL &= ~ SysTick_CTRL_ENABLE_Msk;
}
/**
* 函数功能: us延时程序
* 输入参数: nTime:延时时间
* 返 回 值: 无
* 说 明:无
*/
void Delay_us(__IO u32 nTime)
{
TimingDelay = nTime;
/* 使能滴答定时器 */
SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk;
while(TimingDelay != 0);
/* 关闭系统滴答定时器 */
SysTick->CTRL &= ~ SysTick_CTRL_ENABLE_Msk;
}
/**
* 函数功能: 获取节拍程序
* 输入参数: 无
* 返 回 值: 无
* 说 明:在 SysTick 中断函数 SysTick_Handler()调用
*/
void TimingDelay_Decrement(void)
{
if (TimingDelay != 0x00)
{
TimingDelay--;
}
}
3.systick.h
#ifndef __SYSTICK_H__
#define __SYSTICK_H__
#include <stm32f10x.h>
#define Delay_ms(x) Delay_us(1000*x) //单位ms
void systick_Init(void);
void TimingDelay_Decrement(void);
void Delay_us(__IO u32 nTime);
#endif
4.其他
1.LED.c跟之前一样不用改
2.还需要在stm32f10x_it.c的文件的 SysTick_Handler(){}中加上TimingDelay_Decrement();
加完后别忘了在文件开头引用头文件#include "systick.h"
当Systick定时器每次计数到0时,会触发Systick定时器中断,进入该中断服务程序。在这个中断服务程序中,调用了TimingDelay_Decrement()
函数,用于实现延时功能
void SysTick_Handler(void)
{
TimingDelay_Decrement();//这句代码是新加上去的
}
三、实验结果
作业四
四、总结
这次作业让我更好地了解了Systick定时器,在老师给的代码基础上进行修改,顺利完成了本次作业,锻炼了我的动手实践能力,拓展了专业知识,令我受益匪浅