我一直在用C语言开发一个控制软件我决定花
一段时间后,我将在将来开发的其他程序(某种类型的库)中使用通用功能块我的软件从应用的角度分为两大部分一部分是控制部分
(PI控制器、调制器、锁相环等)第二个是逻辑
部件(应用程序的有限状态机等)逻辑部分处理逻辑信号这些信号由逻辑门和触发器的软件实现来处理我的目标是实现一些软件版本的振荡器我指的是一些功能块,它能够产生0到1之间的振荡,在它的输出端有规定的周期和占空比原则上,我可以在一个程序中有几个这样的振荡器所以我有
决定以如下方式实现振荡器振荡产生是由一个函数完成的,振荡器的每个实例都是由先前定义的结构实例实现的该结构主要包括振荡周期、占空比和振荡器执行周期,即放置振荡器实例的RTOS任务的执行周期基于振荡周期和任务执行周期产生振荡函数
void OSC(uint32_t output, Osc_t *p){
// p->T is the task execution period in ms
// p->period is the desired oscillations period in ms
// p->counter is the internal state of the oscillator
p->delay_count = (uint16_t)((p->period)/(2*p->T));
if(++(p->counter) >= p->delay_count){
p->counter = 0;
NegLogicSignal(output);
}
}
}
下面是包含单个振荡器实例状态的结构
typedef struct{
float period; // period of the oscillations (ms)
float T; // function execution period (ms)
uint16_t counter; // initial number of execution periods
uint16_t delay_count; // number of execution periods corresponding to half
// period
}Osc_t;
振荡器功能的用法如下
Debug_LED_Oscillator_state.T = 1; // T = 1 ms
Debug_LED_Oscillator_state.period = 500; // period 0.5 s = 500 ms
OSC(LDbgLedOsc, &Debug_LED_Oscillator_state);
我的问题是我必须把我的振荡器放在最快的任务中(执行周期为1毫秒的任务)
因为我无法在另一个任务中实现周期500 ms(半周期250 ms),因为我的其他任务有500 ms的不适当执行周期(20 ms和100 ms,即250/20=12.5-不是整数值,250/100=2.5-也不是整数值)问题是,我在另一个任务中拥有应用程序逻辑的其余部分。
预期用途是产生LED闪烁模式的逻辑信号问题是,我必须将振荡器移到逻辑上不同的任务,只是因为我无法在逻辑上适当的任务中实现所需的定时精度(因为商半周期/执行周期的非整数值)我正在考虑不同的实现方法,使振荡器能够在逻辑上完成适当的任务,并达到所需的定时精度。
我想到了下面的解决办法我将定义一组全局变量(uint16_t Timer_1ms、uint16_t Timer_5ms等)这些全局变量将在最高优先级任务(在我的情况下是任务1毫秒)中递增我将重新定义OSC功能
void OSC(uint32_t output, Osc_t *p){
float act_time;
taskENTER_CRITICAL();
switch(p->timer_type){
case TMR_1MS:
act_time = Timer_1ms;
break;
case TMR_5MS:
act_time = Timer_5ms;
break;
}
taskEXIT_CRITICAL();
if(p->init){
SetLogicSignal(output);
switch(p->timer_type){
case TMR_1MS:
p->delta = ((p->period)/(2*1*p->T));
break;
case TMR_5MS:
p->delta = ((p->period)/(2*5*p->T));
break;
}
p->stop_time = (act_time + p->delta);
p->init = FALSE;
}
if(act_time >= (p->stop_time)){
NegLogicSignal(output);
p->stop_time = (act_time + p->delta);
}
}
和振荡器结构
// oscillator state
typedef struct{
float period; // period of the oscillations (ms)
float T; // function execution period (ms)
float delta; // half_period in timer counts
float stop_time; // timer counts when to negate the output
BOOL init; // force initialization of the timer
timer_e timer_type;
}Osc_t;
我试过这个解决方案,但它似乎不起作用有人知道为什么吗提前谢谢你的建议。
最佳答案
当您使用软截止时间执行任务时,RTOS的线程非常有用软期限意味着如果执行延迟,系统不会失败在您的情况下,振荡器有一个硬期限,例如,如果占空比的脉宽调制不精确和稳定的电机将不会有理想的恒定角速度在这种情况下,您必须使用MCU的可用定时器/计数器外围设备。
您可以设置一个定时器,在给定的时间间隔内中断CPU,并在ISR(中断服务程序)中切换输出使用这种方法,时间计数的负载从CPU转移到计时器外围,允许精确的振荡输出和其他任务的平滑执行。
您不清楚使用的是哪个rto或MCU/CPU,但它们都有定时器/计数器外围设备如果不直接从RTOS支持,请查看CPU供应商数据表。
关于c - C语言中振荡器的软件实现,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/45717653/