TENMSMask*/
/*@}*//*endofgroupCMSIS_CM3_SysTick*/
与systick相关的寄存器的说明
voidSysTick_CLKSourceConfig(uint32_tSysTick_CLKSource)
作用:
选择systick的时钟源,AHB时钟或AHB的8分频
默认使用的是AHB时钟,即72MHz
函数说明:
/**
*@brief ConfigurestheSysTickclocksource.
*@param SysTick_CLKSource:
specifiestheSysTickclocksource.
* Thisparametercanbeoneofthefollowingvalues:
* @argSysTick_CLKSource_HCLK_Div8:
AHBclockdividedby8selectedasSysTickclocksource.
* @argSysTick_CLKSource_HCLK:
AHBclockselectedasSysTickclocksource.
*@retvalNone
*/
voidSysTick_CLKSourceConfig(uint32_tSysTick_CLKSource)
{
/*Checktheparameters*/
assert_param(IS_SYSTICK_CLK_SOURCE(SysTick_CLKSource));
if(SysTick_CLKSource==SysTick_CLKSource_HCLK)
{
SysTick->CTRL|=SysTick_CLKSource_HCLK;
}
else
{
SysTick->CTRL&=SysTick_CLKSource_HCLK_Div8;
}
}
Systick时钟源的定义:
/**@defgroupSysTick_clock_source
*@{
*/
#defineSysTick_CLKSource_HCLK_Div8 ((uint32_t)0xFFFFFFFB)//将控制状态寄存器的第二位置0,即用外部时钟源
#defineSysTick_CLKSource_HCLK ((uint32_t)0x00000004)//将控制状态寄存器的第二位置1,即用内核时钟
#defineIS_SYSTICK_CLK_SOURCE(SOURCE)(((SOURCE)==SysTick_CLKSource_HCLK)||\
((SOURCE)==SysTick_CLKSource_HCLK_Div8))
Systick定时时间的设定:
重装载值=systick时钟频率(Hz)X想要的定时时间(S)
如:
时钟频率为:
AHB的8分频;AHB=72MHz那么systick的时钟频率为72/8MHz=9MHz;要定时1秒,则
重装载值=9000000X1=9000000;
定时10毫秒
重状态值=9000000X0.01=90000
Systick的中断处理函数,
在startup_stm32f10x_hd.s启动文件中有定义。
DCD SysTick_Handler ;SysTickHandler
根据需要直接编写中断处理函数即可:
VoidSysTick_Handler(void)
{;}
注意:
如果在工程中,加入了stm32f10x_it.c,而又在主函数中编写中断函数,则会报错。
因为在stm32f10x_it.c文件中,也有这个中断函数的声明,只是内容是空的。
/**
*@brief ThisfunctionhandlesSysTickHandler.
*@param None
*@retvalNone
*/
voidSysTick_Handler(void)
{
}
中断优先级的修改
在调用SysTick_Config(uint32_tticks)之后,调用voidNVIC_SetPriority(IRQn_TypeIRQn,uint32_tpriority)。
这个函数在core_cm3.h头文件中。
具体内容如下:
/**
*@brief Setthepriorityforaninterrupt
*
*@param IRQn Thenumberoftheinterruptforsetpriority
*@param priority Theprioritytoset
*
*Setthepriorityforthespecifiedinterrupt.Theinterrupt
*numbercanbepositivetospecifyanexternal(devicespecific)
*interrupt,ornegativetospecifyaninternal(core)interrupt.
*
*Note:
Theprioritycannotbesetforeverycoreinterrupt.
*/
static__INLINEvoidNVIC_SetPriority(IRQn_TypeIRQn,uint32_tpriority)
{
if(IRQn<0){
SCB->SHP[((uint32_t)(IRQn)&0xF)-4]=((priority<<(8-__NVIC_PRIO_BITS))&0xff);}/*setPriorityforCortex-M3SystemInterrupts*/
else{
NVIC->IP[(uint32_t)(IRQn)]=((priority<<(8-__NVIC_PRIO_BITS))&0xff); } /*setPriorityfordevicespecificInterrupts */
}
下面以一个实例来说明:
利用systick来实现以1秒的时间间隔,闪亮一个LED指示灯,指示灯接在GPIOA.8,低电平点亮。
#include"stm32f10x.h"
//函数声明
voidGPIO_Configuration(void);//设置GPIOA.8端口
u32t;//定义一个全局变量
intmain(void)
{
//SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);
SysTick_Config(9000000);
SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);
GPIO_Configuration();
while
(1);
}
//GPIOA.8设置函数
voidGPIO_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStruct;//定义一个端口初始化结构体
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);//打开GPIOA口时钟
GPIO_InitStruct.GPIO_Mode=GPIO_Mode_Out_PP;//设置为推挽输出
GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;//设置输出频率50M
GPIO_InitStruct.GPIO_Pin=GPIO_Pin_8;//指定第8脚
GPIO_Init(GPIOA,&GPIO_InitStruct);//初始化GPIOA.8
GPIO_SetBits(GPIOA, GPIO_Pin_8);//置高GPIOA.8,关闭LED
}
//systick中断函数
voidSysTick_Handler(void)
{
t++;
if(t>=1)
{
if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_8)==1)
{GPIO_ResetBits(GPIOA,GPIO_Pin_8);}
}
if(t>=2)
{
if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_8)==0)
{GPIO_SetBits(GPIOA,GPIO_Pin_8);}
t=0;
}
}
模拟后的结果
1、8分频后结果
2、直接调用SysTick_Config(9000000);即不分频的结果,间隔为1/8=0.125s
总结:
1、要使用systick定时器,只需调用SysTick_Config(uint32_tticks)函数即可,
自动完成了,重装载值的装载,时钟源选择,计数寄存器复位,中断优先级的设置(最低),开中断,开始计数的工作。
2、要修改时钟源调用SysTick_CLKSourceConfig(uint32_tSysTick_CLKSource)。
3、要修改中断优先级调用
voidNVIC_SetPriority(IRQn_TypeIRQn,uint32_tpriority)
应用说明:
1、因systick是一个24位的定时器,故重装值最大值为2的24次方=16777215,
要注意不要超出这个值。
2、systick是cortex_m3的标配,不是外设。
故不需要在RCC寄存器组打开他的时钟。
3、每次systick溢出后会置位计数标志位和中断标志位,计数标志位在计数器重装载后被清除,而中断标志位也会随着中断服务程序的响应被清除,所以这两个标志位都不需要手动清除。
4、采用使用库函数的方法,只能采用中断的方法响应定时器计时时间到,如要采用查询的方法,那只能采用设置systick的寄存器的方法,具体操作以后再做分析。