C通过计时器触发任何功能作为单触发功能
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C通过计时器触发任何功能作为单触发功能相关的知识,希望对你有一定的参考价值。
我已经为轮式编带机构建了一个大型程序。我遇到某些功能的时间问题。
在某些方面,我不得不等待像气缸这样的东西。
它可以在某些点发生,即函数立即执行而不是在设置的间隔之后执行。它很少发生,但它可能是令人讨厌的。可能发生的是,车轮在录制之前意外地从机器中滚出。
最重要的是,我还为每个单拍功能使用了一个2字节的软件定时器,它可以更高效。
我现在在做什么:我触发一个在X时间后调用的函数
triggerOneshot(TWO,300);
void triggerOneshot(int C, int I) // sets the interval for the one-shot timer and selects which function is to be fired.
{
counter1[C] = counter;
interval1[C] = I;
oneshot_bool[C] = 1;
}
我不断打电话:
void updateTimers()
{
for(j=0;j<8;j++) {
if(oneshot_bool[j] == 1) {
if((counter - counter1[j]) >= interval1[j] ) {
oneshot_bool[j] = 0;
fireOneshot(j); } } }
}
定时器ISR保持递增“计数器”。当时间到了,我做:
void fireOneshot(byte s) // this function contains all one-shot timed events.
{
switch(s) { // selector
case ONE: oneshotFunction1(); break;
case TWO: oneshotFunction2(); break;
case THREE: oneshotFunction3(); break;
case FOUR: oneshotFunction4(); break;
case FIVE: oneshotFunction5(); break;
case SIX: oneshotFunction6(); break;
case SEVEN: oneshotFunction7(); break;
case EIGHT: oneshotFunction8(); break; }
}
所有这些单一功能的主体都包含一个独特的例程。
void oneshotFunction1()
{
if(airPressureSensor == 1) {
applicatorUp = 1;
applicatorDown = 0;
automatic = 1;
message_set = 0;
setapos(1,15);clreol();// deletes error message
stop_bool = 1;
start_bool = 1; }
else {
lamp_bool = 1;
automatic = IDLE;
greenLamp = 0;
start_bool = 0;
Estop_bool = 0;
mainRelay = 0; }
}
我可以同时使用这些单打,但我从来没有需要它。
我想要什么,不知道如何是以下。我想调用triggerOneshot并传递2个争论,时间和任何自定义函数而不是数字。现在我只能使用我为这些oneshot事件开发的特定函数(void oneshotFunction1())。但是我希望能够使用我拥有的每一个函数并将其解析为对于onehot事件的争论。我不知道如何实现这一点。
首先是
void (*const fireOneshot[]) (void) = {
oneshotFunction1,
oneshotFunction2,
oneshotFunction3,
oneshotFunction4,
oneshotFunction5,
oneshotFunction6,
oneshotFunction7,
oneshotFunction8,
};
你可以打电话给fireOneshot[j]()
(到目前为止测试)。
(未在此处测试)
使用void (*const fireShot) (int i, char c);
你可以用fireShot
分配变量foo
任意函数void foo(int, char)
和签名fireshot = foo
,并通过fireShot(7,3)
调用它。
触发器可能是
typedef uint16_t WORD;
struct Trigger {
void (*function)(int arg1, Foo * pointer);
int fx_arg1;
Foo * fx_arg2;
WORD countdown;
} my_trigger;
struct Trigger * ptrigger;
然后可以通过设置这样的触发器
my_trigger.funtion = my_generic_shot;
my_trigger.fx_arg1 = 08;
my_trigger.fx_arg2 = p_current_foo;
my_trigger.countdown = 300;
当倒计时到期时,请致电
my_trigger.function(my_trigger.fx_arg1, my_trigger.fx_arg2);
或者
ptrigger->function(ptrigger->fx_arg1, ptrigger->fx_arg2);
(测试会发现的错别字除外)。
类似的答案,但让我提供另一个例子如下。
// oneshot event handler prototype; you can modify as you want
typedef int (*eventhandler_t)(uint32_t counter, void * context);
typedef struct {
uint32_t timeout;
eventhandler_t handler;
void *context;
bool triggered;
//... even you can define further
} eventDS_t;
#define MAX_EVENTDS 10
eventDS_t _eventDS_list[MAX_EVENTDS]; // you can implement with linked list as well
unsigned int _eventDS_size = 0;
// You'd better implement this part with binary tree to search faster the handler with interval
int regHandler(uint32_t timeout, eventhandler_t func, void *context) {
if (_eventDS_size < MAX_EVENTDS && func != NULL) {
_eventDS_list[_eventDS_size].timeout = counter + timeout;
_eventDS_list[_eventDS_size].handler = func;
_eventDS_list[_eventDS_size].context = context;
_eventDS_list[_eventDS_size].triggered = false;
_eventDS_size++;
return 0; // success
}
return -1; // error
}
void updateTimer() {
for (unsigned int i = 0; i < _eventDS_size; i++) {
if (!_eventDS_list[i].triggered &&
_eventDS_list[i].timeout >= counter) {
_eventDS_list[i].handler(counter, _eventDS_list[i].context);
_eventDS_list[i].triggered = true;
}
}
}
int fireOneshot(uint32_t counter, void * context) {
//.... something else what you want
return 0;
}
int main(int argc, char *argv[]) {
struct myData {
int a, b;
} data;
// somewhere in your main codes, you can call regHandler() to register the hanlder
regHandler(100, fireOneshot, (void*)&data);
regHandler(200, fireTwoshot, (void*)&data);
//.... as you want
return 0;
}
_eventDS_list[_eventDS_size].timeout = counter + timeout;
和_eventDS_list[i].timeout >= counter
是一个严重的错误。
它没有考虑到qazxsw poi在232个单位时间内溢出。 (注意232毫秒= = 7个星期远离有缺陷的情况)。
以上是关于C通过计时器触发任何功能作为单触发功能的主要内容,如果未能解决你的问题,请参考以下文章
如何在Xamarian iOS应用程序中单击按钮后X秒触发事件?