Cortex系统定时器--SysTick

1.SysTick寄存器结构 

SYSTICK 寄存器结构,SysTick_TypeDef,在文件“stm32f10x_map.h”中定义如下: 

typedef struct 
{
    vu32 CTRL; 
    vu32 LOAD; 
    vu32 VAL; 
    vuc32 CALIB; 
} SysTick_TypeDef;

SysTick 外设声明于文件“stm32f10x_map.h”: 

#define SCS_BASE ((u32)0xE000E000) 

#define SysTick_BASE (SCS_BASE + 0x0010) 

#ifndef DEBUG 

... 

#ifdef _SysTick 

#define SysTick ((SysTick_TypeDef *) SysTick_BASE) 

#endif /*_SysTick */ 

... 

#else /* DEBUG */ 

... 

#ifdef _SysTick 

EXT SysTick_TypeDef *SysTick; 

#endif /*_SysTick */ 

... 

#endif 

使用Debug模式时,初始化指针SysTick于文件“stm32f10x_lib.c”: 

#ifdef _SysTick 

SysTick = (SysTick_TypeDef *) SysTick_BASE; 

#endif /*_SysTick */ 

为了访问SysTick寄存器,, _SysTick必须在文件“stm32f10x_conf.h”中定义如下: 

#define _SysTick 


SysTic定时可应用与以下两个方面:

1).设置简单的延时,eg:led灯闪烁显示:

///MyTime.h

#ifndef __MYTIME_H__
#define __MYTIME_H__

#include "stm32f10x.h"

/****************************
*@Fun 定时延时
****************************/
void MySysTick_Init(void);
void MyDelay_us(u32 nTime);
void MyDelay_ms(u32 nTime);

#endif



///MyTime.c

#include "MyTime.h"

void MySysTick_Init(void)
{
	SysTick->CTRL &= ~0x01;        //失能SysTick定时器
	SysTick->CTRL &= ~(0x01<<1);   //失能中断响应(异常响应)
	SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);//设置系统时钟源
	
}
void MyDelay_us(u32 nTime)
{
	u32 nLastRead;
	u32 nus;   //1us时间内动作次数              
	nus = SystemCoreClock/8000000; //  72M/8M=9<2^4(只需4位,用u8即可)
	nus*=nTime; //nTime微妙共需动作次数(假设1000us(1ms),9*1000=9000<9*2^10(10个位即可),假设延时1000000us(1s),则9*1000000=9000000=9M<9*2^20(需要20个位)),所以nus最终用u32.
	SysTick->VAL = 0;       //清空当前值寄存器
	SysTick->LOAD = nus;    //重装载值寄存器
	SysTick->CTRL |= 0x01;  //使能定时器
	
	do
	{
		nLastRead = SysTick->CTRL;
	}while(nLastRead&0x01 && !(nLastRead&(1<<16))); //定时器使能状态 && SysTick->CTRL==0时满足条件
																									//当SysTick->CTRL == 1时,说明定时周期已到。
	SysTick->CTRL &= ~(0x01);    //失能定时器
	SysTick->LOAD = 0;
	SysTick->VAL = 0;
}
void MyDelay_ms(u32 nTime)
{
	u32 nLastRead;
	u16 nms;     //1ms动作次数
	nms = SystemCoreClock/8000;// 72M/8000=9000<9*2^10;(10个位即可)
	SysTick->VAL = 0;
	SysTick->LOAD = (u32)nms*nTime;
	SysTick->CTRL |= 0x01;
	
	do
	{
		nLastRead = SysTick->CTRL;
	}while(nLastRead&0x01 && !(nLastRead&(1<<16)));
	
	SysTick->CTRL &= ~0x01;
	SysTick->LOAD = 0;
	SysTick->VAL = 0;
}

///main.c

#include "stm32f10x_conf.h"
#include "MyTime.h"
int main(void)
{
	GPIO_InitTypeDef GPIO_InitStruct;
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
	
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
	GPIO_InitStruct.GPIO_Pin = GPIO_Pin_5;
	GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
	
	GPIO_Init(GPIOB,&GPIO_InitStruct);		
	
	while(1)
	{	  
		GPIO_SetBits(GPIOB,GPIO_Pin_5);
		MyDelay_ms(100);
		GPIO_ResetBits(GPIOB,GPIO_Pin_5);
                MyDelay_ms(100);
         }
 }


2).定时做某一动作,相当于定时器。

///MyTime.h

#ifndef __MYTIME_H__
#define __MYTIME_H__

#include "stm32f10x.h"

/*******************************
*@Fun 定时器
********************************/
void MySetTimer(u16 nSec);

#endif


///MyTime.c

void MySetTimer(u16 nSec)
{
	u16 ns;
	ns = SystemCoreClock/8;  //1s动作次数
	SysTick->CTRL &= ~0x01;
	SysTick->CTRL &= ~(0x01<<1);
	SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);
	SysTick->VAL = 0;
	SysTick->LOAD = (u32)nSec*ns;
	SysTick->CTRL |= 0x01;
}


///main.c

int main(void)
{
	GPIO_InitTypeDef GPIO_InitStruct;
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOE,ENABLE);
	
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
	GPIO_InitStruct.GPIO_Pin = GPIO_Pin_5;
	GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
	
	GPIO_Init(GPIOB,&GPIO_InitStruct);
	GPIO_Init(GPIOE,&GPIO_InitStruct);
	GPIO_SetBits(GPIOB,GPIO_Pin_5);
	GPIO_SetBits(GPIOE,GPIO_Pin_5);
		
	MySetTimer(10);
	while(1)
	{
		u32 nLastRead = SysTick->CTRL;
		if(nLastRead&0x01 && (nLastRead&(1<<16)))	//这里有个很奇怪的问题,如果用1 == nLastRead&(1<<16),则无法显示正确结果。。。。。	
		{
			//时间到
			GPIO_ResetBits(GPIOB,GPIO_Pin_5);			
		}
		else
		{
			GPIO_SetBits(GPIOB,GPIO_Pin_5);
		}
	}	
}


你可能感兴趣的:(SysTick,Cortex,系统定时器)