有没有大神在单片机中写过类似PLC定时器的函数

2019-07-15 16:47发布

一般单片机中定时器资源有限,而PLC中却有几千个定时器,据说里面的定时器也是由一个基础的衍生出来的,有没有烧友研究过在单片机中一次搞出几十个定时器,同时类似PLC中条件成立定时,条件不成立复位,并且有输出的函数?坐等大神。。。
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
8条回答
andy_wsj
2019-07-16 10:48
lydy123 发表于 2015-6-28 01:23
请问定时器复位和入口的判断如何处理?结构体中的两个函数能否详细讲解下?

定时器的复位?是用户定时器的复位吧,这个需要自己实现,其实就是初始化结构体的状态变量,但是不能清除入口函数和重装载值,其他的都可以清除,定时器的入口就是一个函数指针而已,时间到了就去执行那个函数就好了。
结构体里面只有一个函数指针,就是pFun,这个函数是用户定义的,例如在用户使用的时候定义了一个10ms执行一次的函数UserTimer1

void UserTimer1( void *arg )
{
        struct  user_str something = ( struct  user_str *)arg;
        if( something  == NULL )
               retrun;
.....
         /*
         do something
        */
.....
}
假设这个函数就是每10ms执行一次,按前面的定义,最多可以定义1024个这样的函数

但这个函数需要按时间执行,需要注册到成为一个入口
代码类似于
.....
#define TIMER1    1
#define TIME_10MS  10
struct  user_str para = {0};

....
ret = TimerRegister(TIMER1, UserTimer1,  TIME_10MS, (void *)para);
if( ret == FALSE )
{
     return ret;
}

StartTimer(TIMER1);
....

这就是我前几天提到的需要实现一个注册的接口和一个开始的接口
上面的意思就是把函数 UserTimer1注册到那1024个里面的第一个,周期是10ms,带一个参数para,para可以是任意结构体,前提是 UserTimer1能够处理这个结构体即可

于是乎就有两个接口函数,需要实现:
int TimerRegister( int  timer,  void (*pFun)(voi *), unsigned int time_ms, void *arg )
{
         PLC_Timer *pTimer = NULL;

         pTimer  = GetTimerNode(timer);   //获取timer的节点,如果使用动态内存分配可以是使用malloc
         if( pTimer == NULL )
                return FALSE;

        pTimer->pFun = pFun;                  //设定用户入口
        pTimer->Ticks = time_ms * 1000;   //假设硬件1us产生一次中断  
        pTimer->Para = arg;                      //用户的参数
       。。。。。
        return TRUE;
}

void StartTimer( int  timer)
{
         PLC_Timer *pTimer = NULL;

         pTimer  = GetTimerNode(timer);  
         if( pTimer == NULL )
                return FALSE;
        pTimer->Flag = ENABLE;   //使能这个节点事件,时间到了就执行 pTimer->pFun指向的UserTimer1
.........
}

说道这里,基本都已经说得很清楚了,有开始函数,必然有结束函数,有注册函数,那就还要实现注销函数入口等等....
代码是我随手敲的,只提供思路,正式用还需要考虑可重入,上下文切换,加一些锁的机制保证数据安全等
但是在单片机里面使用的话,这些因素较少,考虑中断与应用的可重入性就可以了

一周热门 更多>