文档章节

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

爱吃冰红茶
 爱吃冰红茶
发布于 2014/01/03 14:21
字数 1190
阅读 188
收藏 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
STM32学习笔记(一)基本了解、芯片内部资源与外观说明

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

arrowyl
03/22
0
0
嵌入式系统在机器人视觉中的应用.doc

来,基于机器视觉的智能机器人在工业等各个领域中得到了广泛的应用.本文针对应用中遇到的一些问题,提出了将机器视觉与嵌入式系统相结合的思想.开发了一种通用的嵌入式系统平台,进行操作系统...

文艺小青年
2017/06/28
0
0

没有更多内容

加载失败,请刷新页面

加载更多

中秋快乐!!!

HiBlock
24分钟前
0
0
Node安装教程

1、安装最新版的node 2、设置相关目录(以D盘为例) 分别建立目录:D:\node,D:\node\node-globa,D:\node\node-cache 命令行输入: // 设置npm国内镜像 npm config set registry https://re...

Mohan710
52分钟前
3
0
中国发布域名系统基础软件 “红枫”

9月12日消息,域名工程中心(英文缩写 ZDNS)发布了宣称自主开发的域名系统基础软件 “红枫(Maple DNS)”。 9月12日消息,域名工程中心(英文缩写 ZDNS)发布了宣称自主开发的域名系统基础软...

问题终结者
今天
3
0
Shell编程(分发系统介绍、expect远程登录、expect远程执行命令、expect传递参数)

分发系统介绍expect 分发系统expect即分发脚本,是一种脚本语言;通过他可以实现传输,输入命令(上线代码) 应用场景:业务越来越大,网站app,后端,编程语言是php,所以就需要配置lamp或者...

蛋黄_Yolks
今天
2
0
Java Http请求工具类

public static String httpPost(String source, String params) {URL url = null;HttpURLConnection conn = null;OutputStream os = null;String ret = null;try {......

yuewawa
今天
3
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部