在平时我们针对裸机进行开发不使用RTOS的时候,有时候需要使用到简单的线程调度,如果使用硬件定时器实现的话,可能会受到硬件本身定时器资源的限制,这时候我们可以使用SysTick实现软件定时器。
软件定时器是用程序模拟出来的定时器,可以由一个硬件定时器模拟出成千上万个软件定时器,这样程序在需要使用较多定时器的时候就不会受限于硬件资源的不足,这是软件定时器的一个优点,即数量不受限制。
SysTick俗称嘀嗒定时器,是Cortex内核自带的组件,它是一个24位的递减计数器,用户仅需掌握ARM的CMSIS软件提供的一个函数SysTick_Config即可,原代码如下:
- /* ################################## SysTick function ############################################ */
- /** \ingroup CMSIS_Core_FunctionInterface
- \defgroup CMSIS_Core_SysTickFunctions SysTick Functions
- \brief Functions that configure the System.
- @{
- */
- #if (__Vendor_SysTickConfig == 0)
- /** \brief System Tick Configuration
- The function initializes the System Timer and its interrupt, and starts the System Tick Timer.
- Counter is in free running mode to generate periodic interrupts.
- \param [in] ticks Number of ticks between two interrupts.
- \return 0 Function succeeded.
- \return 1 Function failed.
- \note When the variable <b>__Vendor_SysTickConfig</b> is set to 1, then the
- function <b>SysTick_Config</b> is not included. In this case, the file <b><i>device</i>.h</b>
- must contain a vendor-specific implementation of this function.
- */
- __STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks)
- {
- if ((ticks - 1) > SysTick_LOAD_RELOAD_Msk) return (1); /* Reload value impossible */
- SysTick->LOAD = ticks - 1; /* set reload register */
- NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1); /* set Priority for Systick Interrupt */
- SysTick->VAL = 0; /* Load the SysTick Counter Value */
- SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk |
- SysTick_CTRL_TICKINT_Msk |
- SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */
- return (0); /* Function successful */
- }
函数的形参表示内核时钟多少个周期后触发一次Systick定时中断,比如形参配置为如下数值。 -- SystemCoreClock / 1000 表示定时频率为 1000Hz, 也就是定时周期为 1ms。 -- SystemCoreClock / 500 表示定时频率为 500Hz, 也就是定时周期为 2ms。 -- SystemCoreClock / 2000 表示定时频率为 2000Hz, 也就是定时周期为 500us。
本次实验中使用软定时器实现了两个线程调度函数,其中第一个线程实现了按键扫描的功能,第二个线程实现了板载LED流水灯的功能,main函数如下:
该工程中已经将软件定时器编写成了驱动文件,便于移植和使用,主要文件为soft_timer.c和soft_timer.h文件,在Keil工程中添加源文件后的目录如下:
使用时需要在SysTick中断处理函数中添加软定时器刷新函数:
接下来使用时进行硬件定时器初始化和中断优先级配置和:
最后就是软件定时器的创建和回调函数编写:
本实验最后实现了LED流水灯和按键扫描两个线程的调度:
本工程完整源码如下:
[payamount]2.00[/payamount]
[pay]
MM32L0xx.rar
(2.85 MB, 下载次数: 1)
[/pay]
|