目录
7.SYSTICK 滴答定时器
0. 博主理解:
SysTick就是一个定时器,只不过这个定时器是属于Cortex-M3内核中的(就是说所有的M3内核的芯片都有这个定时器),起到兼容的作用。这个定时器通常用于操作系统的“心跳”;在裸机中通常用其充当延时作用。
1. 实验内容及步骤:
实验内容:
通过SysTick滴答定时器实现每隔1S钟,串口输出“1S SysTick”
步骤:
1.配置SysTick控制及状态寄存器(选择时钟源、使能SysTick、使能中断);
2.配置SysTick重装载数值寄存器(装入倒计时的值);
3.配置SysTick的中断优先级;
4.配置SysTick的中断函数。
2. 硬件说明
无。
3. 寄存器说明
参考“STM32F10xxx Cortex-M3编程手册-英文版”,“Cortex-M3权威指南(中文)”
3.1 SysTick的时钟和使能:
配置SysTick控制及状态寄存器(地址:0xE000_E010)(STK_CTRL)
主要说明寄存器的第二位CLKSOURCE,0=AHB/8;1=AHB
在本实验中设置Systick定时器,选择时钟源为内核时钟(1=AHB=72M),使能Systick和SysTick异常请求(即中断)。
STK_CTRL = 0x0007;
3.2 SysTick重装载数值寄存器:
SysTick每次都会从重装载值开始减,减到0是就会产生异常,并且重新将重装载寄存器的值装到计数器里面,以此循环。建议产生中断的值不要太短,太短会导致系统频繁进入中断,增加CPU的负担。这里我们设置重装载的值为10ms。
SysTick重装载寄存器(地址:0xE000_E014,STK_LOAD)
在本实验中设置SysTick为10ms定时器,因为上一步中选择的时钟源为内核时钟(1=AHB=72M),以此当重装载值为720000时,倒计时到0的时间就为10ms。
STK_LOAD = 720000;
3.3 SysTick的中断优先级:
配置SysTick的中断优先级与外部中断优先级的寄存器不一样,严格来说SysTick的优先级为异常优先级。其寄存器如下所示
系统异常优先级寄存器阵列(地址:0xE000_ED18 - 0xE000_ED23,SHPRx)
本实验中配置SysTick的中断优先级为15,即优先级最低。
SHPR12 = 15<<4; (因为高四位才是配置优先级的有效位,所以要左移四位)
3.4 SysTick的中断函数:
在startup_stm32f10x_hd.s中可以找到SysTick的中断函数为SysTick_Handler
实验中需要定时1S,而SysTick的定时器为10ms,因此进入100次中断时,则代表以及定时了1S。定义一个变量初始值为100,进入一次中断就减1,最后减到0时,则代表以及定时了1S,再进行相应的操作。
4. 程序设计(寄存器)
源码: 这里是帅选了关键部分,详细看源码。
#define SysTick_FCLK_10ms 720000
#define SET_SYS_IP(IRQx,pp) SCB->SHP[((uint32_t)(IRQx) & 0xF)-4]= pp<<4 //设置异常优先级
u16 systick_1s=100;
//SYSTICK初始化
void Systick_Config(void)
{
//重装载值
SysTick->LOAD = SysTick_FCLK_10ms;
SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | //使用内部时钟72M
SysTick_CTRL_TICKINT_Msk | //开启中断
SysTick_CTRL_ENABLE_Msk; //使能Systick
SET_SYS_IP(SysTick_IRQn,15);
}
void SysTick_Handler()
{
if(systick_1s!=0)
systick_1s--;
}
/**********************main***************************/
//主函数
int main(void)
{
SET_NVIC_GROUP(NVIC_PriorityGroup_4); //中断组4
Systick_Config(); //初始化SysTick定时器
………(省略)
USART1_Config(115200); //串口1配置115200
while (1)
{
………(省略)
if(systick_1s == 0) //判断是否到1S
{
systick_1s = 100; //重新赋值1S
USART1_Sends((u8*)"1S SysTick\r\n");
}
}
}
5. 程序设计(标准库)
在core_cm3.h文件中已经有SysTick的配置函数了,如下所示
其配置方式与我们寄存器配置的方式一样,就不详细讲解了。
输入参数为重装载的值,即720000(10ms Systick中断)
中断函数和主函数部分与寄存器的一致。
源码:这里是帅选了关键部分,详细看源码。
#define SysTick_FCLK_10ms 720000
//主函数
int main(void)
{
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4); //设置中断优先组4
………(省略)
SysTick_Config(SysTick_FCLK_10ms);
USART1_Config(); //串口1配置115200
while (1)
{
………(省略)
if(systick_1s == 0)
{
systick_1s = 100; //重新赋值1S
USART1_Sends((u8*)"1S SysTick\r\n");
}
}
}
void SysTick_Handler()
{
if(systick_1s!=0)
systick_1s--;
}
6. 程序设计(HAL库)
在HAL中,SysTick的配置函数与标准库的一致,在core_cm3.h文件中。
源码:这里是帅选了关键部分,详细看源码。
#define SysTick_FCLK_10ms 720000
u16 systick_1s=100;
void SysTick_Handler()
{
if(systick_1s!=0)
systick_1s--;
}
/*********************main函数*****************************/
int main(void)
{
HAL_Init();
SystemClock_Config();
SysTick_Config(SysTick_FCLK_10ms); //设置SysTick定时器10ms
LED_GPIOX_Config(); //LED初始化
KEY_EXTI_Config(); //按键中断初始化
USART1_Config(); //串口1配置115200
printf("SysTick_Test\r\n");
while (1)
{
if(systick_1s == 0) //判断1S
{
systick_1s = 100; //重新赋值1S
USART1_Sends((u8*)"1S SysTick\r\n");
}
}
}}
7. 实验结果
串口助手每隔1S就会输出“1S SysTick”。