文档章节

嵌入式软件之定时器的设计

爱吃冰红茶
 爱吃冰红茶
发布于 2014/01/03 14:21
字数 1190
阅读 190
收藏 5

这是真正意义上的第一篇自己写的博客,以前的都是copy的,后来发现这有很多弊病,所以果断全部给delete了!

不说废话了,正式开始!

前段时间,跟着项目做智能家居里的一部分工作,里面有写一个定时器,今天就专门来说说这个!

一说到定时器,估计很多人都第一个想到的是用alarm来做,这个是没问题的,我最初所用的方法也是用的是alarm,但是由于项目要求是在一个进程内控制多个设备的定时开关机(我设计的是16个),于是用alarm就会觉得力有不逮了!

先来看看用alarm吧!一个进程只能有一个 闹钟时间,如果在调用alarm之前已设置过闹钟时间,则任何以前的闹钟时间都被新值所代替。在最初用alarm时,我是先写一个控制设备开关机的函数 setPowerOnOff,然后当alarm的时间到了之后,系统会发出一个SIGALRM信号,我再用调用signal函数,使得系统接收到这个信号 时就调用setPowerOnOff函数,但是问题出来了,当我alarm倒计时还没结束时,我再次设置定时开关机,假设刚才设置的是1号机,现在我设置 2号机,那么系统就会清除之前的1号机alarm,而采用2号机的定时时间重新alarm,那么一号机就被这样被抛弃了!

于是换了个方法,通过开辟一个线程来维护一个结构体:

我先声明一个结构体:

typedef struct intervaltime
{
    int hour;
    int min;
    int sec;
}IntervalTime;                                      //时间格式

typedef struct Timing
{
    int devid[16];                               //16台设备的id
    IntervalTime timeOn[16];             //定时开机时间
    IntervalTime timeOff[16];             //定时关机时间
    int OnState[16];                           //定时开机状态位
    int OffState[16];                           //定时关机状态位
}timing;

在维护这个结构体之前,我们还需要写一个获取当前系统时间的函数,代码如下:

struct tm *ipp_sac_getNowTime()
{
    time_t rawtime;
    struct tm *systime;
    time(&rawtime);
    systime = localtime(&rawtime);
    return systime;
}

前面两部分代码都很简单,也就不多说什么了。

在声明结构体时,我们可以看到,此定时器只是需要时、分、秒,其余的天,月什么的 我们都没去考虑,当然如果说非要用的话,也不是什么难事。我的方法是比较传统的方法,通过比较当前系统时间和设置的定时时间是否相等,以及相应的开关机状 态位,来判断在什么时候执行什么样的操作。在我跟的这个项目里,用户端发送的是一个倒计时给我,所以我需要先将这个倒计时转化为一个我们平时所看到的系统 时间的格式:

struct tm *timeinfo;
    timeinfo = ipp_sac_getNowTime();
        static timing TimingPowerOnOff;

    //当前系统时间加上设置的定时关机时间,即为系统将要执行关机动作的时间。
    TimingPowerOnOff.devid[deviceid] = deviceid;
    TimingPowerOnOff.timeOff[deviceid].hour = timeinfo->tm_hour + time.hour;
    TimingPowerOnOff.timeOff[deviceid].min = timeinfo->tm_min + time.minute;
    TimingPowerOnOff.timeOff[deviceid].sec = timeinfo->tm_sec + time.sec;
        //当时,分达到24和60时,则需要如下的处理:
    if(TimingPowerOnOff.timeOff[deviceid].min > 59)
    {
        TimingPowerOnOff.timeOff[deviceid].min = TimingPowerOnOff.timeOff[deviceid].min - 60;
        TimingPowerOnOff.timeOff[deviceid].hour = TimingPowerOnOff.timeOff[deviceid].hour + 1;
    }

    if(TimingPowerOnOff.timeOff[deviceid].hour > 23)
    {
        TimingPowerOnOff.timeOff[deviceid].hour = TimingPowerOnOff.timeOff[deviceid].hour - 24;
    }

时间处理好了,接下来我们就只需要判断当前时间是否等于设置的时间就行了,以前设置的是定时开机还是定时关机,设置定时开关机状态就是0和1的问题,就不多说了。

while(1)
    {
        int tmp;
        struct tm *nowTimeInfo;
        nowTimeInfo = ipp_sac_getNowTime();

        for(tmp = 0;tmp < 16;tmp++)
        {
            if(TimingPowerOnOff.timeOff[tmp].hour ==  nowTimeInfo->tm_hour && TimingPowerOnOff.timeOff[tmp].min == nowTimeInfo->tm_min)
            {
                if(TimingPowerOnOff.OffState[tmp] == 1)
                {
                    mcu_sac_setPower(tmp,POWER_OFF);     //mcu_sac_setPower即为触发设备开关机的函数,此处就不列代码了。POWER_OFF = 1;
                    TimingPowerOnOff.OffState[tmp] = 0;
                }
            }

            if(TimingPowerOnOff.timeOn[tmp].hour ==  nowTimeInfo->tm_hour && TimingPowerOnOff.timeOn[tmp].min == nowTimeInfo->tm_min)
            {
                if(TimingPowerOnOff.OnState[tmp] == 1)
                {
                    mcu_sac_setPower(tmp,POWER_ON);  //POWER_ON = 0;
                    TimingPowerOnOff.OnState[tmp] = 0;
                }
            }
        }
        sleep(60);                 //虽然我声明的时间类型的有秒,但是实际项目里我没用到,所以这里就加了个sleep(60),让它每隔一分钟循环一次。
    }

到这里,定时器就设计好了,但是同时值得注意的是,我是开辟了一个线程来做定时器这个功能的,只是代码里我没有把那部分给列举出来而已;当然,如果整个进程只是跑一个定时器,线程神马的就可以不用了,这看个人喜好啦!

第一篇博客就算搞定啦,虽然定时器这个很简单,我说的估计也不仔细,但是不积跬步无以至千里,一切慢慢来吧!


© 著作权归作者所有

共有 人打赏支持
爱吃冰红茶
粉丝 2
博文 4
码字总数 4471
作品 0
绵阳
程序员
私信 提问
嵌入式系统watchdog详解

嵌入式系统的工作常会受到外界电磁场的干扰,造成程序的跑飞,而陷入死循环,程序的正常运行被打断,会造成整个系统的陷入停滞状态,发生不可预料的后果,所以需要对嵌入式系统运行状态进行实...

songkai320
2017/12/25
0
0
NIOS2随笔——uCOS-II实时操作系统

1. 概述 本设计采用NIOS2 32位处理器,实现uCOS-II实时操作系统的使用,实现两个任务同时运行,一个LED闪烁,一个串口打印。硬件平台采用ETree的开发板(某宝提供),如下图所示: 2. uCOS-II...

shugenyin
2017/10/03
0
0
C语言嵌入式系统编程修炼之屏幕操作

这是我13年前创作和发表在互联网上的文章,这么多年过去了,这篇文章仍然在到处传播。现在贴回Linuxer公众号。 全文目录: C语言嵌入式系统编程修炼之道——背景篇 C语言嵌入式系统编程修炼之...

jus3ve
2017/12/30
0
0
嵌入式学习:嵌入式硬件和软件详解

在嵌入式开发中,是分为硬件部分和软件部分的,大多数的初学者对于嵌入式的硬件和软件之间的区别不是很了解,所以今在这里就和大家具体说说嵌入式硬件和软件详解,大家可以参考一下。 图片来...

IT范儿
2017/11/18
0
0
STM32学习笔记(一)基本了解、芯片内部资源与外观说明

什么是STM32? 新的基于ARM内核的32位MCU系列 内核为ARM公司为要求高性能、低成本、低功 耗的嵌入式应用专门设计的Cortex-M内核 标准的ARM架构 优点超前的体系结构 极高的性能: 主流的Corte...

arrowyl
03/22
0
0

没有更多内容

加载失败,请刷新页面

加载更多

新手也能看懂,消息队列其实很简单

该文已加入开源项目:JavaGuide(一份涵盖大部分Java程序员所需要掌握的核心知识的文档类项目,Star 数接近 16k)。地址:https://github.com/Snailclimb/JavaGuide. 本文内容思维导图: 消息...

阿里云官方博客
19分钟前
1
0
如何在Chrome浏览器中启动deviceready事件(尝试调试phonegap项目)?

我正在开发PhoneGap应用程序,我希望能够在Chrome中调试它,而不是在电话上调试。但是,我在onGetReady()函数中初始化我的代码,该函数在PhoneGap触发“deviceready”事件时触发。由于Chr...

kisshua
今天
9
0
nginx中部署vue打包后的静态文件

如何在nginx中部署静态资源就不描述了, 请看我的这篇博客 将vue脚手架项目打包后的静态文件放到nginx上, 发现有个问题, 即url上有#, 怎么去掉这个#呢. 1 项目中router的mode 路由的mode要为h...

克虏伯
今天
13
0
JS容易理解错误的地方

在这端代码执行的末尾,你会不会hi变量回事函数中的hi了?你会不会认为这不是按引用传递了? 对值传递和引用传递产生质疑了? 1 var hi = {};2 function sayHello(hi) { ...

器石_
今天
9
0
Java开发学习--MongoDB

之前只学过sql,第一次使用非关系型数据库。以前对于关系型数据库与非关系型数据库的概念很模糊,通过这次的学习对这两者有了一个清晰的概念。 主键 在MongoDB中,主键名叫"_id",如果在生成...

微笑向暖wx
今天
6
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部