如何根据C中的状态机生成单个脉冲?
Posted
技术标签:
【中文标题】如何根据C中的状态机生成单个脉冲?【英文标题】:How to gererate a single pulse depending on a state machne in C? 【发布时间】:2017-12-28 10:32:00 【问题描述】:我想编写一个 c 代码来生成一个脉冲,但我似乎无法围绕逻辑来实现它。我来自强大的 Verilog 背景并且知道如何在 verilog 中执行此操作(使用 xor 查找状态变化并使用该脉冲,如果需要,通过多次注册它随着时间的推移拉伸它)
我应该如何在 C 中做到这一点?我想做类似的事情
while(1)
switch(state)
case 0: // generate single pulse
case 1: // dont generate
case 2: // dont gererate
case 3: // generate single pulse
usleep(1000) // I want a 1ms pulse
状态由运行在 FPGA 上的代码修改,因此它会根据某些逻辑而改变。 似乎无法做到这一点。一些指导将不胜感激
【问题讨论】:
"pulse" 是什么意思?什么样的“脉冲”。想要脉搏什么? 您可以在一个循环中切换为高电平,然后在下一个循环中切换为低电平,例如通过使用状态 4“脉冲”。 单脉冲作为默认低电平的信号,但当某些情况发生时,高电平和低电平时间 = 说 1 毫秒 @Yunnosch 我尝试了类似“if(signal=0) signal =1; else signal = 0”的方法,但只要该状态稳定,就会产生多个脉冲 您需要提供更多上下文。使用您显示的代码,“进入操作”之类的东西是不可能的。请尝试提供更接近minimal reproducible example 的内容。朝着合适的强大状态机迈出的一步是维护一个“statebefore”变量。 【参考方案1】:你需要一个稍微强大一点的状态机,它可以执行进入操作。
假设
状态机在脉冲时失明是可以的 变量state
在您的循环内发生变化(例如,可能是易失性的并且可能从 ISR 更新)
或状态在循环内以某种方式更新(存在伪代码)
您在聊天中表示您可以控制变量 state
何时更改。这很重要。要么使用从伪代码行调用的轮询函数updatestate()
;或者以某种方式确保变量不会在 // enter protection ...
和 // leave protection ...
之间发生变化。
但是,状态机仍会因之间的更改而失明,尤其是在usleep(1000);
期间。如果这是一个问题,您需要明显更复杂的机制。
伪代码提案:
// somewhere before
volatile int state = 0; // somehow changing within the loop
int statecopy = 0;
int statebefore = state,
while(1)
// updatestate(); // if that is necessary
// Note that the state machine is blind for changes to state
// between executions of these initial lines.
// I.e. changes are noticed only when executing the update above
// or the critical section below this comment. (depending on how
// the variable state changes.
// enter protection for critical section
statebefore = statecopy;
statecopy = state;
// leave protection for critical section
switch(statecopy )
case 0: // generate single pulse
if (statecopy != statebefore)
// switch high
usleep(1000); // I want a 1ms pulse
// switch low
break;
case 1: // dont generate
break;
case 2: // dont gererate
break;
case 3: // generate single pulse
if (statecopy != statebefore)
// switch high
usleep(1000); // I want a 1ms pulse
// switch low
break;
default:
break;
【讨论】:
【参考方案2】:您只需要为每个状态的状态更改和操作实现少量逻辑,如下所示:
int state = 0;
while(1)
switch(state)
case 0: // generate single pulse
start_pulse();
usleep(1000);
stop_pulse();
break;
case 1: // dont generate , wait 1ms?
usleep(1000);
break;
case 2: // dont generate, wait 1ms?
usleep(1000);
break;
case 3: // generate single pulse
start_pulse();
usleep(1000);
stop_pulse();
break;
state = (state+1)%3; // next state: 0, 1, 2, 3, 0, 1, 2,...
【讨论】:
【参考方案3】:为了简化开关示例
switch( state )
case 1:
case 2:
usleep(1000);
break;
case 0:
case 3:
/* pulse high */
usleep(1000);
/* pulse low */
更多是可能的,但可能不值得,让编译器弄清楚。
【讨论】:
以上是关于如何根据C中的状态机生成单个脉冲?的主要内容,如果未能解决你的问题,请参考以下文章