如何根据 C 中的状态机生成单个脉冲?
How to gererate a single pulse depending on a state machne in C?
我想编写一个 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 上的代码 运行 修改,因此它会根据某些逻辑发生变化。
似乎无法做到这一点。一些指导将不胜感激
您需要一个稍微更强大的状态机,它可以执行进入操作。
假设
- 状态机在脉冲时盲目是可以的
- 循环中的变量
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;
}
}
您只需为每个状态的状态更改和操作实现少量逻辑,如下所示:
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,...
}
简化开关示例
switch( state ) {
case 1:
case 2:
usleep(1000);
break;
case 0:
case 3:
/* pulse high */
usleep(1000);
/* pulse low */
}
更多是可能的,但可能不值得,让编译器自己解决。
我想编写一个 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 上的代码 运行 修改,因此它会根据某些逻辑发生变化。
似乎无法做到这一点。一些指导将不胜感激
您需要一个稍微更强大的状态机,它可以执行进入操作。
假设
- 状态机在脉冲时盲目是可以的
- 循环中的变量
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;
}
}
您只需为每个状态的状态更改和操作实现少量逻辑,如下所示:
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,...
}
简化开关示例
switch( state ) {
case 1:
case 2:
usleep(1000);
break;
case 0:
case 3:
/* pulse high */
usleep(1000);
/* pulse low */
}
更多是可能的,但可能不值得,让编译器自己解决。