【发布时间】:2014-03-05 03:56:20
【问题描述】:
嘿,StackOverflow!
在下面的代码中,我有一个简单的状态机,它改变了一些外部照明设备的操作(正如 cmets 所暗示的那样)。通过按下连接到 GP1 的按钮改变状态。连接到 GP1 的电路是一个比较器去抖动电路,它将 VDD 与 0.6VDD 进行比较(我也尝试过 RC/二极管/施密特触发电路),然后强制信号 LO。在示波器上,当按钮被快速按下时,我们会看到一个干净的方波。
PIC10F200的当前(和不希望)行为如下:
- 开关被按下(状态 = 0)
- 状态机变量增量(状态 = 1)
- 照明转到案例 1,然后打开
- 照明至少持续一秒钟
- 灯光关闭
- 系统保持在此状态,直到再次按下按钮或 关机
问题是:为什么会这样?如果可能的话,我如何修复它,使单次按下按钮等同于单次状态增量,然后 PIC 会保持这种增量只要系统通电且按钮未再次启动?
#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 目前不稳定,我该如何做到这一点?
更新(2014-03-08):解决方案
需要设置以下设置,假设 GP0 是输出,GP2 是您的 T0CKI,并且您有一个在启动时将信号驱动到 LO 的开关。
TRIS = 0b111110;
OPTION = 0b11101111;
OPTION 的 0-3 位是否真正重要是一个判断调用,以及您是否选择使用 WDT 模块。
此外,按钮释放检测的实现是一种简单的计数器机制,在计数期间的任何时间点 GP2 为 LO 时都会重置。
if (TMR0 > 0)
{
while (count < 20)
{
if (!GPIObits.GP2) count = 0;
__delay_ms(10);
count++;
}
TMR0 = 0;
state++;
}
【问题讨论】:
-
那么gp1是按钮,gp0是led,gp2是什么?另外,按钮是如何工作的?一键(按下并释放)给 1,再点击 0?
-
是的,GP1 连接到按钮,GP0 连接 LED/EL 线驱动器 EN 端口(最终),GP2 是低频检测电路的输入(低音来自...响亮的音乐) ,尚未连接,因为我什至无法让状态机正常工作。该按钮是一个即时按钮,就像您在大多数廉价电子产品中找到的真正基本的按钮一样。因此,当它被按下时,触点被连接并且 VDD 进入比较器电路(LM324N 运算放大器)。
-
你为什么要用“状态”来做。你想要达到的目标很容易。您不需要使代码复杂化。
-
使用
state,我试图简单地在代码中标记的设备操作模式之间切换。以我目前对 PIC、XC8 的工作原理和 C 的了解,这是我能想到的完成这项任务的最简单方法。我完全愿意尝试不同的方法,除了汇编中的任何解决方案,因为改变语言不仅不能解决问题,它还引入了不必要的实现和支持复杂性。 -
你描述的是一个状态。按下按钮时。将来您可能想要添加其他内容,但现在它是一种状态。
if (!GPIObits.GP1){GPIObits.GP0 = 1; __delay_ms(1000); GPIObits.GP0 = 0;}
标签: c microcontroller pic microchip xc8