为什么此状态机不保持其状态? [英] Why does this state machine not maintain its state?

查看:112
本文介绍了为什么此状态机不保持其状态?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

嘿,StackOverflow!

Hey there StackOverflow!

在下面的代码中,我有一个简单的状态机,可以更改某些外部照明设备的操作(如注释所示).通过按下连接到GP1的按钮可以改变状态.连接到GP1的电路是一个比较器去抖动电路,将VDD与0.6VDD进行比较(我也尝试过RC/二极管/施密特触发电路),然后强制信号LO.在示波器上,当快速按下按钮时,我们会看到干净的方波.

In the following code I have a simple state machine that changes the operation of some external lighting device (as the comments imply). The state is changed via the pressing of the button connected to GP1. The circuit connected to GP1 is a comparator debouncing circuit that compares VDD to 0.6VDD (I've also tried an RC/diode/schmitt trigger circuit), which then forces the signal LO. On a scope, we see a clean square wave when the button is actuated rapidly.

PIC10F200 当前(和不受欢迎的)行为如下:

The current (and undesirable) behavior of the PIC10F200 is as follows:

  1. 按下开关(状态= 0)
  2. 状态机变量增量(状态= 1)
  3. 照明进入案例1,然后打开
  4. 照明至少持续一秒钟
  5. 灯光熄灭
  6. 系统保持此状态,直到再次按下按钮或 关闭电源
  1. Switch is pressed (state = 0)
  2. State machine variable increments (state = 1)
  3. Lighting goes to case 1, and turns on
  4. Lighting remains on for at least a second
  5. Lighting turns off
  6. System remains in this state until button is actuated again or powered off

问题是:为什么会这样?而且,如果可能的话,如何解决这个问题,使按一下按钮就等于一个状态增量,然后由PIC保持该状态增量.只要系统已通电且按钮没有再次致动?

The question is: Why does it behave like this? And how if possible, do I fix it such that a single press of the button equates to a single state increment, which the PIC then maintains for as long as the system is powered and the button is not actuated again?

#define SYS_FREQ        8000000L
#define FCY             SYS_FREQ/4
#define _XTAL_FREQ      4000000

/******************************************************************************/
/* User Global Variable Declaration                                           */
/******************************************************************************/


/******************************************************************************/
/* Main Program                                                               */
/******************************************************************************/

__CONFIG(MCLRE_ON & CP_OFF & OSC_IntRC);

void main(void)
{
    TRIS = 0b111110;

    unsigned char state = 0;

    while(1)
    {
        switch (state)
        {
            case 0: // IDLE/OFF
                if (GPIObits.GP0) GPIObits.GP0 = 0;
                break;
            case 1: // ON
                if (!GPIObits.GP0) GPIObits.GP0 = 1;
                break;
            case 2: // BLINK (slow)
                GPIObits.GP0 = !GPIObits.GP0;
                __delay_ms(100);
                break;
            case 3: // BLINK (fast)
                GPIObits.GP0 = !GPIObits.GP0;
                __delay_ms(50);
                break;
            case 4: // BEAT DETECT
                GPIObits.GP0 = GPIObits.GP2;
                break;
            default:
                state = 0;
                break;
        }

        if (!GPIObits.GP1)
        {
            __delay_ms(250);
            state++;
        }
    }
}

更新:由于对于我要使用此代码/系统完成的工作似乎有些困惑,因此请提供完整的上下文. PIC10F200 这个微控制器是用于电致发光(EL)线驱动器的整体电路板设计的一部分.微控制器通过将GP0连接到驱动器IC的EN端口来简单地控制是否启用驱动器电路. 系统具有四种操作模式,电线始终亮着,电线闪烁,电线闪烁速度更快,并且每当检测到低频跳动时电线就会闪烁(系统中的另一个电路) ). 从这些操作模式的过渡由要安装在PCB上的按钮开关(瞬时)控制.这使得上面代码中的state在按钮操作之间保持稳定.它当前不执行此操作,其行为如本文的原始部分所述.如问题标题所述,为什么state当前不稳定,我该如何做到?

UPDATE: Since there seems to be a little confusion as to what I am trying to accomplish with this code/system, lets provide the full context. This microcontroller, the PIC10F200 is part of an overall board design for an electroluminescent (EL) wire driver. The miconcontroller simply controls whether or not the driver circuit is enabled by connecting GP0 to the EN port of the driver IC. The system has four modes of operation, the wire is constantly on, the wire is blinking, the wire is blinking faster, and the wire blinks whenever a low-frequency beat is detected (another circuit in the system). The transition from these modes of operation is governed by a pushbutton (on momentarily) switch to be mounted on the PCB. This necessitates that state in the code above remains stable between button actuations. It currently does not do this and behaves as described in the original part of this post. As the question title states, why isn't state stable currently, and how do I make it so?

更新(2014-03-08):解决方案

需要设置以下设置,假设GP0是输出,GP2是您的T0CKI,并且您有一个开关,该开关在启动时将信号驱动到LO.

The following settings need to be set assuming GP0 is the output, GP2 is your T0CKI and you have a switch that drives the signal to LO when actuated.

TRIS = 0b111110;
OPTION = 0b11101111;

OPTION的位0-3是否真正重要取决于判断调用以及您是否选择使用WDT模块.

Whether or not bits 0-3 for OPTION really matter is a judgement call and whether or not you choose to use the WDT module.

此外,按钮释放检测的实现是一种简单的计数器机制,可在计数期间的任意时刻将GP2设为LO时复位.

Additionally, the implementation for the button release detection is a simple counter mechanism that resets upon GP2 being LO at any point during the count.

if (TMR0 > 0)
{
    while (count < 20)
    {
        if (!GPIObits.GP2) count = 0;
        __delay_ms(10);
        count++;
    }
    TMR0 = 0;
    state++;
}

推荐答案

您有硬件/软件设计问题!

You have a hardware/software design problem!

  1. 当您的程序处于延迟循环中时,您的按键没有 检查了!
  2. 您仅在按键事件上进行检查,但您还必须在按键上进行检查 释放.
  1. When your program is in delay loop than your key button is not checked!
  2. You are checking only on key press event, but you must also on key relase.

我的目的是可以将GP2(T0CKI)引脚代替GP1用于按键按钮.如果用作计数器TMR0输入,则此引脚具有施密特触发器输入.之后,将您的MCPU TMR0配置为带有GP2(T0CKI)引脚上的外部时钟的计数器.您还必须将T0SE位置1以配置计数器,该计数器将在T0CKI引脚上由高到低的跳变时递增. 在任何循环后的程序中,检查TMR0的内容是否大于0,并按下了该键. 等待几毫秒,然后检查键是否被释放(如果已释放),则增加state变量并清除TMR0内容.

My purpose is that you can use GP2 (T0CKI) pin instead GP1 for key buttom. This pin has schmitt trigger input if is used as counter TMR0 input. After that configure your MCPU TMR0 as counter with external clock on GP2 (T0CKI) pin. You must also set the T0SE bit to configure counter that will increment on high-to-low transition on the T0CKI pin. In program after any loop check the TMR0 content if biger than 0 the key was pressed. Wait some ms and check if key was relased if relased than increase the state variable and clear TMR0 content.

这篇关于为什么此状态机不保持其状态?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆