STM32学习笔记——使用SysTick定时器做延时

时间:2022-04-04 00:24:08

   开学了,无法再像假期一样能够一整天玩板了!好在这学期的课说少不少,说多也不多,每周也有十几大节。剩下的时间除去学生工作等一些七七八八的事情,间断着还是能看看教程玩玩板!越发发现《STM32菜鸟学习手册——啰嗦版》真是不错的入门教程,简单易懂。其他诸如《固件库手册》等等官方文件更是必不可少,可惜ST公司的网页找手册实在麻烦得很呐!

   这两天一直在看有关于系统嘀嗒时钟SysTick的文件,但由于3.5版的固件库较2.0版的库,已经将SysTick相关的驱动函数移除,用户要使用SysTick就必须改为调用CMSIS中的函数,而网上大多数的例程(包括《菜鸟学习手册》)使用的都是2.0的库,以至于在学习中遇到许多问题,程序编译总会出现问题。一般都是“无法找到与SysTick相关的函数,函数未定义”错误。因此,查找了许多文献才得以解决。

   SysTick定时器被捆绑在NVIC,用于产生SysTick异常(异常号:15)。主要应用于操作系统,作为“嘀嗒中断”维持操作系统“心跳”的节律。当然,SysTick定时器除了能服务于操作系统之外,还能用于其它目的:如作为一个闹铃,用于测量时间等。要注意的是,当处理器在调试期间被喊停(halt)时,则SysTick定时器亦将暂停运作。

1.SysTick寄存器:

寄存器

说明

地址

CTRL

SysTick控制和状态寄存器

0xE000E010

LOAD

Systick重装值寄存器

0xE000E014

VAL

Systick当前值寄存器

0xE000E018

CALIB

SysTick校准值寄存器

0xE000E01C

 

l       SysTick控制和状态寄存器(SysTick_CTRL

STM32学习笔记——使用SysTick定时器做延时STM32学习笔记——使用SysTick定时器做延时

    说明:

CLKSOURCE位:CM3允许为SysTick提供两个时钟源以供选择。第一个是内核的*运行时钟FCLK*表现在它不来自系统时钟HCLK,因此在系统时钟停止时FCLK也继续运行。第二个是一个外部的参考时钟。但是使用外部时钟时,因为它在内部是通过FCLK来采样的,因此其周期必须至少是FCLK的两倍(采样定理)。很多情况下芯片厂商都会忽略此外部参考时钟,因此通常不可用。

COUNTFLAG位:当SysTick定时器从1计到0时,它将把COUNTFLAG位置位;而下述方法可以清零之:

读取SysTick控制及状态寄存器(STCSR);

SysTick当前值寄存器(STCVR)中写任何数据。

 

l       SysTick重装值寄存器(SysTick_LOAD

STM32学习笔记——使用SysTick定时器做延时

   STM32学习笔记——使用SysTick定时器做延时

    说明:

   当计数器倒数至0时,使用SysTick_LOAD寄存器来指定载入“当前值寄存器”的初始值。初始值可以是10x00FFFFFF之间的任何值。


l       Systick当前值寄存器(SysTick_VAL

STM32学习笔记——使用SysTick定时器做延时

STM32学习笔记——使用SysTick定时器做延时

l       SysTick校准值寄存器(SysTick_CALIB)

STM32学习笔记——使用SysTick定时器做延时STM32学习笔记——使用SysTick定时器做延时


各寄存器示意图:

STM32学习笔记——使用SysTick定时器做延时 STM32学习笔记——使用SysTick定时器做延时

2.SysTick函数

3.0版以后的STM32固件库在标准外设库中移除了SysTick的驱动,因此用户必须调用CMSIS定义的函数。

CMSIS只提供了一个SysTick设置的函数,替代了STM32原有SysTick驱动的全部函数。

SysTick_Config(uint32_t ticks);

该函数设置了自动重载入计数器(LOAD)的值,SysTick IRQ的优先级,复位了计数器(VAL)的值,开始计数并打开SysTick IRQ中断。SysTick时钟默认使用系统时钟。

此外,还可以使用SysTick_CLKSourceConfig函数来改变时钟源,使用NVIC_SetPriority设置中断优先级(往后再深入)。

SysTick_CLKSourceConfig函数

函数名

SysTick_CLKSourceConfig

函数原型

SysTick_CLKSourceConfig(u32 SysTick_CLKSource)

行为描述

配置SysTick的时钟源

输入参数

SysTick_CLKSource:SysTick的时钟源

输出参数

返回值

前提条件

调用函数

 

SysTick_CLKSource允许值

SysTick_CLKSource

描述

SysTick_CLKSource_HCLK_Div8

SysTick时钟源为AHB时钟的1/8

SysTick_CLKSource_HCLK

SysTick时钟源为AHB时钟

 

:

选择1/8AHB时钟作为SysTick时钟源

SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);


3.例程

3.1 程序代码

本例程代码在点亮LED灯例程代码上做修改,使用SysTick定时延时,除延时外其他代码不变,与SysTick相关语句给予注释。

 

#include "stm32f10x.h"
void Delay(u32 nTime);//声明延迟函数
void GPIO_Configuration(void);
int main(void)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);
GPIO_Configuration();
while(SysTick_Config(SystemCoreClock/1000)!=0);//配置SysTick,装入初始值,装载值根据时钟源频率而定,72MHz时钟源则产生1ms中断需要装载值为(72000000/1000)
while(1)
{
GPIO_ResetBits(GPIOC,GPIO_Pin_7|GPIO_Pin_9);
GPIO_SetBits(GPIOC,GPIO_Pin_6|GPIO_Pin_8);
Delay(1000);
GPIO_ResetBits(GPIOC,GPIO_Pin_6|GPIO_Pin_8);
GPIO_SetBits(GPIOC,GPIO_Pin_7|GPIO_Pin_9);
Delay(1000);
GPIO_Write(GPIOC,0x0140);
Delay(1000);
GPIO_Write(GPIOC,0x0280);
Delay(1000);
}
}

void GPIO_Configuration(void)
{
GPIO_InitTypeDefGPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_6|GPIO_Pin_7|GPIO_Pin_8|GPIO_Pin_9;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;
GPIO_Init(GPIOC,&GPIO_InitStructure);
}

volatile u32 TimingDelay;//定义全局变量,其声明在stm32f10x_it.c中
void Delay(u32 nTime)//定义延迟函数
{
TimingDelay=nTime;//将延迟数赋予全局变量
while(TimingDelay!=0);
}

其中,在stm32f10x_it.c中:

extern volatile u32 TimingDelay; //声明全局变量
void SysTick_Handler(void)
{
TimingDelay--;
}

3.2 结果

编译烧入开发板后,LED等以1s的时间精确交替闪烁。

 

参考文献:

[1]JosephYiu,宋岩译.《Cortex-M3权威指南》[EB/OL].http://ishare.iask.sina.com.cn/f/11378333.html?retcode=0,2010-11-05/2012-09-09.

[2]ST.STM32固件库2.0.33.0版本的比较中文版》[EB/OL].http://ishare.iask.sina.com.cn/f/18297257.html?from=like2011-08-22/2012-09-09.

[3]Xxbing8.STM32_SysTick[EB/OL].http://hi.baidu.com/xxbing8/item/c99ea4f53f996ad042c36ab82012-06-14/2012-09-09.


data:20120909