【问题标题】:How to gererate a single pulse depending on a state machne in C?如何根据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”变量。

标签: c logic pulse


【解决方案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 */
      }
      

      更多是可能的,但可能不值得,让编译器弄清楚。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-10-30
        • 2013-10-12
        • 2012-04-01
        相关资源
        最近更新 更多