1.SysTick寄存器结构
SYSTICK 寄存器结构,SysTick_TypeDeff,在文件“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; // 72/8=9M=9*2^20(>20个位,所以u32) nus*=nTime; //nTime微妙共需动作次数 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); } } }
原文地址:http://whatever957.blog.51cto.com/6835003/1627476