1 Star 12 Fork 7

MilkLi / 单片机软件定时器

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
贡献代码
同步代码
取消
提示: 由于 Git 不支持空文件夾,创建文件夹后会生成空的 .keep 文件
Loading...
README
MIT

单片机软件定时器

介绍

本软件定时器实现了一个向下计数自动重装载的定时器。时基通过一个硬件定时器确定。不含有任何与底层MCU相关代码,可以移植到任何嵌入式平台。定时器回调函数的运行可以在中断中,或者在主函数while循环中执行。可以使用提供的各种API函数,来修改定时器的计数值、重装载值,运行次数。可以开启或关闭单个软件定时器。

使用说明

  1. 需要确定时基,一般由一个硬件定时器提供,将SoftwareTimer_Tick()函数放入定时器中断服务函数下。
   //stm32平台1ms定时器生成1s的时基的中断服务函数
   void TIM1_UP_IRQHandler(void)
   {
       static uint16_t TimesCounter_ms = 0;
       if (TIM_GetITStatus(TIM1, TIM_IT_Update))
       {
           TimesCounter_ms++;
           TIM_ClearITPendingBit(TIM1, TIM_IT_Update);
           if (TimesCounter_ms >= 1000)
           {
               TimesCounter_ms = 0;
               SoftwareTimer_Tick();
           }
       }
   }
  1. 使用SoftwareTimer_Init()函数初始化一个软件定时器。
    //这里初始化了两个软件定时器,重装载2,计数值分别为0,1,循环无限次
    //可以实现SW1_callback、SW2_callback两个回调函数前后依次运行
    SoftwareTimer_Init(0, 0, 2, SW1_callback, FOREVER);
    SoftwareTimer_Init(1, 1, 2, SW2_callback, FOREVER);
  1. 将SoftwareTimer_Loop()函数放到想要回调函数运行的位置
    //这里把SoftwareTimer_Loop放到了主函数while循环中,回调函数会在这里被调用。
    int main(void)
    {
        while(1)
        {
            SoftwareTimer_Loop();
        }
    }

使用注意

本定时器定时时长与选择硬件定时器周期、所使用的MCU平台相关(C51类单片机、ARM类单片机)。在相同平台下,时基越大则定时时间越长;不同平台下计数值所使用的位数不同,如STC15单片机(C51类)中long型数据类型长度为4个字节,int型为2个字节;而在STM32F103中(ARM类)中,int型、long型均为4个字节。本质上来说,此软件定时器是一个软件计数器计数的最大次数与两次计数的最长时间最终都是由底层MCU来决定。

要注意的是,单个软件定时器任务要按照编写中断服务函数的原则来编写,尽量不要使用过长的延时。如果一定要使用软件延时,可以将此延时通过状态机机制实现。单个定时器任务的运行时间最好不要超过定时器时基长度。

存在的问题

在STC8A8k64S4A12单片机上出现了,软件定时器任务多次调用的问题。表现的现象是,在设置的时间点出现连续调用两次软件定时器任务的情况。具体原因未知,故请不要将定时上报的通讯任务使用在本定时器中,对于一些时序要求不严的定时采集传感器数据的任务使用本定时器影响不大。如果在使用中对您的开发造成了困扰,本人表示非常的抱歉。OTZ.....

问题可能的解决方式,再后面对此上述问题进一步研究时,发现如果使用函数嵌套后会出现上述问题。在对SofwareTimer_Loop()函数进行封装后,发现出现了上述问题,如果在main()函数中直接调用则不会出现,原因未+知。所以请尽可能的直接调用SofwareTimer_Loop()这个函数,如果为了代码规范可以使用宏定义的方式实现。

经过进一步测试,通过查看C51里的map文件发现了两个函数中for循环中的计数变量,使用的一个地址。但是其中一个循环计数变量在中断中被使用。这就可能导致在主函数运行的函数中循环计数变量数据被破坏(C51里的优化会将不同函数中的局部变量使用相同的地址,,PS:稍微有点坑啊~)。在STM32中由于有堆栈所以不会出现在C51类单片机中的问题。

经过大约一年的测试,整个程序运行良好。已经应用在了各类传感器采集类项目、控制器计时任务以及各种功能的实现。基本可以替换项目中需要用到延时的地方。

最后,这个代码在我本人的项目中已经类似于系统的存在,其实可以认为这是一个时间片轮询系统。所有创建的定时器都可以认为是这个系统中的任务,只不过没有上下文切换,抢占balabala这么一说。

MIT License Copyright (c) 2021 MilkLi Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

简介

软件定时器。适合于嵌入式裸机程序中使用的软件定时器,可以有效的解决STM32、51类单片机硬件定时器不足的问题。 展开 收起
C
MIT
取消

发行版

暂无发行版

贡献者

全部

近期动态

加载更多
不能加载更多了
C
1
https://gitee.com/milkli/mcu-software-timer.git
git@gitee.com:milkli/mcu-software-timer.git
milkli
mcu-software-timer
单片机软件定时器
master

搜索帮助