[学习笔记]STM32F1 SYSTICK 滴答定时器(寄存器、标准库、HAL库)

目录

0. 博主理解:

1. 实验内容及步骤:

2. 硬件说明

3. 寄存器说明

3.1 SysTick的时钟和使能:

3.2 SysTick重装载数值寄存器:

3.3 SysTick的中断优先级:

3.4 SysTick的中断函数:

4. 程序设计(寄存器)

5. 程序设计(标准库)

6. 程序设计(HAL库)

7. 实验结果

8. 源码下载


 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)

[学习笔记]STM32F1 SYSTICK 滴答定时器(寄存器、标准库、HAL库)

       主要说明寄存器的第二位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)

[学习笔记]STM32F1 SYSTICK 滴答定时器(寄存器、标准库、HAL库)

       在本实验中设置SysTick为10ms定时器,因为上一步中选择的时钟源为内核时钟(1=AHB=72M),以此当重装载值为720000时,倒计时到0的时间就为10ms。

       STK_LOAD = 720000;

3.3 SysTick的中断优先级:

       配置SysTick的中断优先级与外部中断优先级的寄存器不一样,严格来说SysTick的优先级为异常优先级。其寄存器如下所示

       系统异常优先级寄存器阵列(地址:0xE000_ED18 - 0xE000_ED23,SHPRx)

[学习笔记]STM32F1 SYSTICK 滴答定时器(寄存器、标准库、HAL库)

       本实验中配置SysTick的中断优先级为15,即优先级最低。

       SHPR12 = 15<<4; (因为高四位才是配置优先级的有效位,所以要左移四位)

3.4 SysTick的中断函数:

       在startup_stm32f10x_hd.s中可以找到SysTick的中断函数为SysTick_Handler

[学习笔记]STM32F1 SYSTICK 滴答定时器(寄存器、标准库、HAL库)

       实验中需要定时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的配置函数了,如下所示

[学习笔记]STM32F1 SYSTICK 滴答定时器(寄存器、标准库、HAL库)

        其配置方式与我们寄存器配置的方式一样,就不详细讲解了。

       输入参数为重装载的值,即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”。

[学习笔记]STM32F1 SYSTICK 滴答定时器(寄存器、标准库、HAL库)

8. 源码下载

        源码下载

上一篇:单片机学习(十二)1-Wire通信协议和DS18B20温度传感器


下一篇:20210708双端队列实现链表的倒序