STM32学习笔记(3):系统时钟和SysTick定时器
下面介绍一下STM32中的SysTick,它属于NVIC控制部分,一共有4个寄存器:
STK_CSR,0xE000E010:控制寄存器
STK_LOAD,0xE000E014:重载寄存器
STK_VAL,0xE000E018:当前值寄存器
STK_CALRB,0xE000E01C:校准值寄存器
首先看STK_CSR控制寄存器,有4个bit具有意义:
第0位:ENABLE,SysTick使能位(0:关闭SysTick功能,1:开启SysTick功能);
第1位:TICKINT,SysTick中断使能位(0:关闭SysTick中断,1:开启SysTick中断);
第2位:CLKSOURCE,SysTick时钟选择(0:使用HCLK/8作为时钟源,1:使用HCLK);
第3为:COUNTFLAG,SysTick计数比较标志,如果在上次读取本寄存器后,SysTick已经数到0了,则该位为1,如果读取该位,该位自动清零。
STK_LOAD重载寄存器:
Systick是一个递减的定时器,当定时器递减至0时,重载寄存器中的值就会被重装载,继续开始递减。STK_LOAD重载寄存器是个24位的寄存器最大计数0xFFFFFF。
STK_VAL当前值寄存器:
也是个24位的寄存器,读取时返回当前倒计数的值,写它则使之清零,同时还会清除在SysTick控制及状态寄存器中的COUNTFLAG标志。
STK_CALRB校准值寄存器:
其中包含着一个TENMS位段,具体信息不详。暂时用不到。
在MDK开发环境中,我们不必要非得去操作每一个寄存器,可以通过调用ST函数库中的函数来进行相关的操作,其步骤如下:
(1)调用SysTick_CounterCmd()失能SysTick计数器
(2)调用SysTick_ITConfig()失能SysTick中断
(3)调用SysTick_CLKSourceConfig()设置SysTick时钟源
(4)调用SysTick_SetReload()设置SysTick重装载值
(5)调用NVIC_SystemHandlerPriorityConfig()设置SysTick定时器中断优先级
(6)调用SysTick_ITConfig()使能SysTick中断
(7)在stm32f10x_it.c中SysTickHandler()下写中断服务函数。
(8)在需要的时候调用SysTick_CounterCmd()开启SysTick计数器
4.工程实现
根据以上描述,准备利用开发板上的LED灯做一个小实验,将第一个跑马灯的实验稍微改进一下,以1s精确延时的状态来顺序点亮LED灯,采用的定时器就是SysTick。
设计思路是先配置好系统的各个参数,然后设置SysTick定时器每1ms就进入一次中断,再定义一个全局变量作为定时长短的参数,然后将从延时函数中得到的参数赋值给这个全局变量,每进入一次中断,这个全局变量就减一次,直到减为0,才跳出延时函数。
1.配置系统时钟
void RCC_cfg()
{
//定义错误状态变量
ErrorStatus HSEStartUpStatus;
//将RCC寄存器重新设置为默认值
RCC_DeInit();
//打开外部高速时钟晶振
RCC_HSEConfig(RCC_HSE_ON);
//等待外部高速时钟晶振工作
HSEStartUpStatus = RCC_WaitForHSEStartUp();
if(HSEStartUpStatus == SUCCESS)
{
//设置AHB时钟(HCLK)为系统时钟
RCC_HCLKConfig(RCC_SYSCLK_Div1);
//设置高速AHB时钟(APB2)为HCLK时钟
RCC_PCLK2Config(RCC_HCLK_Div1);
//设置低速AHB时钟(APB1)为HCLK的2分频
RCC_PCLK1Config(RCC_HCLK_Div2);
//设置FLASH代码延时
FLASH_SetLatency(FLASH_Latency_2);
//使能预取指缓存
FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);
//设置PLL时钟,为HSE的9倍频8MHz * 9 = 72MHz
RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);
//使能PLL
RCC_PLLCmd(ENABLE);
//等待PLL准备就绪
while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);
//设置PLL为系统时钟源
RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
//判断PLL是否是系统时钟
while(RCC_GetSYSCLKSource() != 0x08);
}
//打开PB和PD用于点亮LED灯
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOD, ENABLE);
}
其中使用到了NVIC的函数,需要将stm32f10xR.lib加入到工程中。
2.配置SysTick定时器
void SysTick_cfg()
{
//设置失能SysTick定时器
SysTick_CounterCmd(SysTick_Counter_Disable);
//设置失能SysTick中断
SysTick_ITConfig(DISABLE);
//设置SysTick的时钟源为AHB时钟
SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK);
//设置重装载值,由于SysTick是AHB时钟,即72MHz,所以重装载值设置为72000,即每1ms重新装载一次
SysTick_SetReload(72000);
//设置SysTick定时器中断优先级
NVIC_SystemHandlerPriorityConfig(SystemHandler_SysTick, 1, 0);
//设置使能SysTick中断
SysTick_ITConfig(ENABLE);
}
3.编写延时函数
void Delay(u32 nTime)
{
TimingDelay = nTime;
//允许SysTick定时器
SysTick_CounterCmd(SysTick_Counter_Enable);
//循环等待定时时间到
while(TimingDelay != 0);
//禁止SysTick定时器
Sys
STM32学习笔记系统时钟SysTick定时 相关文章:
- Windows CE 进程、线程和内存管理(11-09)
- RedHatLinux新手入门教程(5)(11-12)
- uClinux介绍(11-09)
- openwebmailV1.60安装教学(11-12)
- Linux嵌入式系统开发平台选型探讨(11-09)
- Windows CE 进程、线程和内存管理(二)(11-09)