国产MCU学习Day3——CW32F030C8T6: Systick定时器(滴答定时器)精解

发布于:2025-06-29 ⋅ 阅读:(17) ⋅ 点赞:(0)

每日更新教程,评论区答疑解惑,小白也能变大神!"

目录

CW32F030C8T6 Systick定时器概述

Systick寄存器配置

InitTick函数

案例一.实现100MS程序块

关键点说明


 

CW32F030C8T6 Systick定时器概述

SysTick定时器可用作标准的下行计数器,是一个24位向下计数器,有自动重新装载能力

可屏蔽系统中断发生器。Cortex-M0+处理器内部包含了一个简单的定时器,所有基于M0+内核的控制器都带有SysTick定时器,这样就方便了程序在不同的器件之间的移植。

SysTick定时器可用于操作系统,提供系统必要的时钟节拍,为操作系统的任务调度提供一个有节奏的“心跳”。

SysTick定时器设定初值并使能之后,每经过1个系统时钟周期,计数值就减1,减到0时,SysTick计数器自动重新装载初值并继续计数,同时内部的COUNTFLAG标志位被置位,触发中断(前提开启中断)。


Systick寄存器配置

关键寄存器包括:

  1. CTRL:控制寄存器

    • Bit 2: CLKSOURCE(时钟源选择,0=HCLK/8,1=内核时钟)
    • Bit 1: TICKINT(中断使能,1=计数到0时触发中断)
    • Bit 0: ENABLE(定时器使能)
  2. LOAD:重载值寄存器

    • 写入24位初始值,决定定时周期。
  3. VAL:当前值寄存器

    • 读取当前计数值,写入任意值会清零计数器。
  4. CALIB:校准寄存器(通常无需修改)

InitTick函数

  • 主要作用是初始化SysTick定时器,确保它能够在指定的频率(通过uwTickFreq定义)产生中断,并配置中断的优先级。

函数说明

  • __WEAK关键字表明这是一个弱定义函数,意味着如果在其他地方有同名的强定义函数,那么会优先使用强定义版本。这通常用于提供默认的实现,允许用户在需要时替换或扩展功能。
  • 参数HclkFreq是系统时钟频率,单位是Hz(赫兹),用于计算SysTick的重载值。
  • SysTick_Config函数配置SysTick定时器,使其在每个uwTickFreq Hz频率下产生中断。uwTickFreq是你希望的SysTick中断频率,单位是Hz。
  • HclkFreq / (1000U / uwTickFreq)计算每次中断间隔对应的SysTick重载值。HclkFreq是48MHz,且希望每毫秒产生一次中断(即uwTickFreq=1000Hz),则计算结果为48。
  • 如果SysTick_Config返回值大于0,表示配置失败(例如,因为请求的中断频率超过SysTick的最大支持频率),则函数直接返回,不继续执行后续配置。
  • 这部分代码尝试设置SysTick中断(SysTick_IRQn)的优先级为TICK_INT_PRIORITY。__NVIC_PRIO_BITS定义了可以设置的优先级位数,如果TICK_INT_PRIORITY的值有效(即小于最大优先级数),则使用NVIC_SetPriority函数设置优先级。
  • 如果TICK_INT_PRIORITY超出允许范围,则函数同样提前返回,不更改中断优先级。

 

     

    案例一.实现100MS程序块


    时钟与SysTick初始化

    __IO uint32_t uwTick;
    uint32_t uwTickPrio   = (1UL << __NVIC_PRIO_BITS); /* Invalid PRIO */
    TickFreqTypeDef uwTickFreq = TICK_FREQ_DEFAULT;  /* 1KHz */
    
    
    RCC_HSI_Enable(RCC_HSIOSC_DIV2);       //启用HSI时钟,分频系数为2(输出24MHz)
    InitTick(24000000);                    //基于24MHz时钟源初始化SysTick计时器
    

    GPIO配置

    CW_SYSCTRL->AHBEN_f.GPIOB = 1;         //使能GPIOB的AHB总线时钟
    GPIO_InitTypeDef GPIO_InitStruct;      //定义GPIO初始化结构体
    GPIO_InitStruct.Pins = GPIO_PIN_8 | GPIO_PIN_9;  //选择PB8和PB9引脚
    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;      //设置为推挽输出模式
    GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;         //设置输出速度为高速
    GPIO_Init(CW_GPIOB, &GPIO_InitStruct); //应用配置到GPIOB
    PB08_SETLOW();                         //初始化PB8为低电平
    PB09_SETLOW();                         //初始化PB9为低电平
    

    主循环逻辑

    cnt = GetTick();                       //记录当前系统时间(单位:毫秒)
    while (1)
    {
        if ((GetTick() - cnt) > 100)       //检查是否达到100ms间隔
        {
            cnt = GetTick();               //更新计时基准
            PB08_TOG();                    //翻转PB8电平状态
            PB09_TOG();                    //翻转PB9电平状态
        }
    }
    

    SysTick中断处理函数

    void SysTick_Handler(void)
    {
        /* USER CODE BEGIN SysTick_IRQn */
        uwTick += uwTickFreq;              //递增系统时间计数器(需确保uwTickFreq已定义)
        /* USER CODE END SysTick_IRQn */
    }
    
    • uwTick:全局变量,记录系统运行时间。
    • uwTickFreq:定义为每次中断的时间增量(如1毫秒)。

    关键点说明

    1. 硬件依赖:移植时仔细核对GPIO端口。
    2. 实际行为:代码操作的是PB8/PB9。
    3. 重载值不得超过24位最大值(0xFFFFFF)。