Section 7_SysTick系统定时器

1.SysTick定时器介绍

SysTick定时器也叫SysTick滴答定时器,它是Cortex-M4内核的一个外设,被嵌入在 NVIC 中。它是一个24 位向下递减的定时器,每计数一次所需时间为1/SYSTICK,SYSTICK是系统定时器时钟,它可以直接取自系统时钟,还可以通过系统时钟8分频后获取。当定时器计数到0时,将从LOAD 寄存器中自动重装定时器初值,重新向下递减计数,如此循环往复。如果开启SysTick中断的话,当定时器计数到0,将产生一个中断信号。因此只要知道计数的次数就可以准确得到它的延时时间。

2.SysTick定时器寄存器

(1)CTRL寄存器

CTRL是SysTick定时器的控制及状态寄存器。其相应位功能如下:
在这里插入图片描述

(2)LOAD寄存器

LOAD是SysTick定时器的重装载数值寄存器。其相应位功能如下:在这里插入图片描述

(3)VAL寄存器

VAL是SysTick定时器的当前数值寄存器。其相应位功能如下:在这里插入图片描述

(4)CALIB寄存器

CALIB是SysTick定时器的校准数值寄存器。其相应位功能如下:在这里插入图片描述

3.SysTick定时器配置步骤

SysTick定时器的操作可以分为 4 步:
(1)设置SysTick定时器的时钟源。
(2)设置SysTick定时器的重装初始值(如果要使用中断的话,就将中断使能打开)。
(3)清零SysTick定时器当前计数器的值。
(4)打开SysTick定时器。

4.函数

SysTick_Init()函数:
void SysTick_Init(u8 SYSCLK)
{
 	SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8); //函数在misc.c
	fac_us=SYSCLK/8;						//SYSCLK的8分频 保存1us所需的计数次数
	fac_ms=(u16)fac_us*1000;				//每个ms需要的systick时钟数   
}
delay_us()函数:
void delay_us(u32 nus)                      //不能大于2的24次方/21  798000
{		
	u32 temp;	    	 
	SysTick->LOAD=nus*fac_us; 				//时间加载	  		 
	SysTick->VAL=0x00;        				//清空计数器  
	SysTick->CTRL|=0x01 ;                   //开始倒数                     
	do
	{
		temp=SysTick->CTRL;                              
	}while((temp&0x01)&&!(temp&(1<<16)));	//等待时间到达   
	SysTick->CTRL&=~0x01; //关闭计数器                     
	SysTick->VAL =0X00;       				//清空计数器    
}
delay_nms()函数:
void delay_nms(u16 nms)                     //798
{	 		  	  
	u32 temp;		   
	SysTick->LOAD=(u32)nms*fac_ms;			//时间加载(SysTick->LOAD为24bit)
	SysTick->VAL =0x00;           			//清空计数器
	SysTick->CTRL|=0x01 ; //开始倒数 
	do
	{
		temp=SysTick->CTRL;
	}while((temp&0x01)&&!(temp&(1<<16)));	//等待时间到达   
	SysTick->CTRL&=~0x01; //关闭计数器
	SysTick->VAL =0X00;     		  		//清空计数器	  	    
} 
delay_ms()函数:
void delay_ms(u16 nms)
{	 	 
	u8 repeat=nms/540;		//这里用540,是考虑到某些客户可能超频使用,                                           
						    //比如超频到248M的时候,delay_nms最大只能延时541ms左右了
	u16 remain=nms%540;                      
	while(repeat)                            
	{
		delay_nms(540);                      
		repeat--;
	}
	if(remain)delay_nms(remain);            
} 

在这里插入图片描述

5.编程

1.在Public创建两个文件

SysTick.h

#ifndef _SysTick_H
#define _SysTick_H

#include "system.h"

void SysTick_Init(u8 SYSCLK);
void delay_ms(u16 nms);
void delay_us(u32 nus);



#endif

SysTick.c

#include "SysTick.h"

static u8  fac_us=0;							//us延时倍乘数			   
static u16 fac_ms=0;							//ms延时倍乘数

/*******************************************************************************
* 函 数 名         : SysTick_Init
* 函数功能		   : SysTick初始化,SYSTICK的时钟固定为AHB时钟的1/8
* 输    入         : SYSCLK:系统时钟频率
* 输    出         : 无
*******************************************************************************/
void SysTick_Init(u8 SYSCLK)
{
 	SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8); 
	fac_us=SYSCLK/8;						//SYSCLK的8分频 保存1us所需的计数次数
	fac_ms=(u16)fac_us*1000;				//每个ms需要的systick时钟数   
}								    

/*******************************************************************************
* 函 数 名         : delay_us
* 函数功能		   : us延时,
* 输    入         : nus:要延时的us数
					注意:nus的值,不要大于798915us(最大值即2^24/fac_us@fac_us=21)
* 输    出         : 无
*******************************************************************************/
void delay_us(u32 nus)
{		
	u32 temp;	    	 
	SysTick->LOAD=nus*fac_us; 				//时间加载	  		 
	SysTick->VAL=0x00;        				//清空计数器
	SysTick->CTRL|=0x01 ; //开始倒数 	 
	do
	{
		temp=SysTick->CTRL;
	}while((temp&0x01)&&!(temp&(1<<16)));	//等待时间到达   
	SysTick->CTRL&=~0x01; //关闭计数器
	SysTick->VAL =0X00;       				//清空计数器 
}

/*******************************************************************************
* 函 数 名         : delay_nms
* 函数功能		   : ms延时,
* 输    入         : nms:要延时的ms数
					注意:nms的值,SysTick->LOAD为24位寄存器,
					不要大于0xffffff*8*1000/SYSCLK
					对168M条件下,nms<=798ms 
* 输    出         : 无
*******************************************************************************/
void delay_nms(u16 nms)
{	 		  	  
	u32 temp;		   
	SysTick->LOAD=(u32)nms*fac_ms;			//时间加载(SysTick->LOAD为24bit)
	SysTick->VAL =0x00;           			//清空计数器
	SysTick->CTRL|=0x01 ; //开始倒数 
	do
	{
		temp=SysTick->CTRL;
	}while((temp&0x01)&&!(temp&(1<<16)));	//等待时间到达   
	SysTick->CTRL&=~0x01; //关闭计数器
	SysTick->VAL =0X00;     		  		//清空计数器	  	    
}

/*******************************************************************************
* 函 数 名         : delay_ms
* 函数功能		   : ms延时,
* 输    入         : nms:要延时的ms数 0~65535
* 输    出         : 无
*******************************************************************************/
void delay_ms(u16 nms)
{	 	 
	u8 repeat=nms/540;		//这里用540,是考虑到某些客户可能超频使用,
							//比如超频到248M的时候,delay_nms最大只能延时541ms左右了
	u16 remain=nms%540;
	while(repeat)
	{
		delay_nms(540);
		repeat--;
	}
	if(remain)delay_nms(remain);
} 
2.编写main.c

main.c

/*******************************************************************************
* 实 验 名		 : SysTick系统定时器
* 实验说明       : 
* 连接方式       : 
* 注    意		 : SysTick驱动程序在SysTick.c内
*******************************************************************************/

#include "system.h"
#include "SysTick.h"
#include "led.h"

/*******************************************************************************
* 函 数 名         : main
* 函数功能		   : 主函数
* 输    入         : 无
* 输    出         : 无
*******************************************************************************/
int main()
{
	SysTick_Init(168);
	LED_Init();
	while(1)
	{
		led1=0;
		led2=1;
		delay_ms(500);  //精确延时500ms
		led1=1;
		led2=0;
		delay_ms(500);  //精确延时500ms
	}
3.添加misc.c防止报错

在这里插入图片描述

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值