Energia单片机实验-饮水机模拟

一、要求分析

    利用状态机程序思想,使用MSP-EXP430F5529 Launchpad板卡实现以下模拟饮水机的功能。

    饮水机是我们生活中常见的家用设备。假设一个简易的饮水机有两个按键:童锁按键[PUSH1]热水按键[PUSH2]

    按键功能说明: 1.童锁按键: ① 平时“童锁按键”处于锁定状态[RED_LED初始化条件],长按“童锁按键”3秒后进入解锁状态[长按PUSH1事件]; ② 如果“童锁按键”处于解锁状态,3秒内没有按下“热水按键”,“童锁按键”回到锁定状态[闲置PUSH2事件]。 2.热水按键: ①“童锁按键”处于锁定状态时,按下“热水按键”不起作用(不放水)[无用限制条件]; ② “童锁按键”处于解锁状态时,单击“热水按键”(按键释放有效)进入放水状态,开 始放水[松开PUSH2事件]; ③ 处于放水状态时,双击“热水按键”(按键释放有效),停止放热水,“童锁按键” 回到锁定状态[松开PUSH2事件]; ③ 处于放水状态时,按“童锁按键”不起作用[放水时童锁一定解锁,按童锁键是为了解锁,本身成立]。 ④在解锁状态时,长按“热水按键”超过3秒不放,不会自动回到“锁定状态”,按“童锁按键”也不起作用。[这里的长按具有迷惑性,根据前面其他描述,恢复锁定状态的条件是通过PUSH2未按下时作出闲置响应,但是按下了PUSH2后,PUSH2处于按击状态,不用考虑恢复锁定的问题] 。请设计程序,模拟饮水机的工作PUSH1为“童锁按键”,PUSH2为“热水按键”;锁定状态红 色LED亮,解锁状态红色LED灭;放水状态绿色LED亮。

二、完整代码 (仅供参考!!!)

#include "Timer.h"
int ChildLockState=0; //童锁状态,0锁定,1解锁
int ChildLockButtonState=0;  //童锁按键(PUSH1)状态,0闲置,1短按,2长按
int WaterState=0; // 放水状态,0不放水,1放水
int WaterButtonState=0;  //热水按键(PUSH2)状态,0闲置,1单击/双击[通过两次松开间隔判断](不区分短按/长按)
int LastClButton=1;
int CurClButton=1;
int LastWButton=1;
int CurWButton=1;

int ClCnt=0; //童锁按键长按计时器
int WCnt_Empty=0; //热水按键闲置计数器

int DoubleFlag=0;
int DoubleCnt=0;


void setup() {
   pinMode(PUSH1,INPUT_PULLUP);
   pinMode(PUSH2,INPUT_PULLUP);
   pinMode(RED_LED,OUTPUT);
   pinMode(GREEN_LED,OUTPUT);
   digitalWrite(RED_LED,HIGH); //初始童锁锁定,红色LED亮
   digitalWrite(GREEN_LED,LOW); //初始处于未放水状态,绿色LED灭
   SetTimer(irsTimer,20);  //设置定时中断计时器,中断周期为20ms
   Serial.begin(9600);
}

void loop() {

}

void irsTimer()
{
    if(DoubleFlag) DoubleCnt++;
  int ClButton=0; //童锁按键瞬时状态,0无改变,1按下,2松开
  int WButton=0;  //热水按键瞬时状态,0无改变,1按下,2松开
  //按键消抖,检测按键变化(1、童锁;2、热水按键)
  //1、检测童锁按键变化
  CurClButton=digitalRead(PUSH1);
  if(CurClButton!=LastClButton)
  {
    if(CurClButton==LOW)   ClButton=1;
    else  ClButton=2;
  }

  //2.检测热水按键变化
  CurWButton=digitalRead(PUSH2);
  if(CurWButton!=LastWButton)
  {
    if(CurWButton==LOW)   WButton=1;
    else  WButton=2;
  }

  //检测按键状态
  //检测童锁按键状态
  switch(ChildLockButtonState)
  {
     case 0:
       if(ClButton==1) 
       {
        ChildLockButtonState=1; //若按下按键,切换为短按状态
        ClCnt=0;
       }
       break;
       

     case 1:
       if(ClButton==2)
       {
         ChildLockButtonState=0; //若松开按键,切换为闲置状态
         ClCnt=0;
       }
       else if(ClButton==0)  //如果按键状态未改变,则开始计数
       {
          ClCnt++;
          if(ClCnt>=150)   //3s/20ms=150
          {
            ChildLockButtonState=2; //达到计数门限,切换为长按状态
             ClCnt=0;
          }
       }
       break;
       
      case 2: 
     //长按童锁时,解锁童锁(不放水状态时)
    if(ClButton==0){
      ChildLockState=1;  
      ChildUnlocked();
      WCnt_Empty=0;
    }
     
     if(ClButton==2) {
      ChildLockButtonState=0;
     }
      break;

  }


  switch(WaterButtonState) 
  {
    case  0:
    if(WButton==0)
    {
     if(WaterState==0&&ChildLockState==1)
     {
      Serial.println(WCnt_Empty);
      WCnt_Empty++; 
      if (WCnt_Empty>=150)
      {
          WCnt_Empty=0;
         ChildLockState=0;  //3s未按热水按键,锁定童锁
         ChildLocked();
      }
     }
    }
      

      if(WButton==1)
        WaterButtonState=1;  //若按下按键,切换为短按状态
    break;
     
    case 1:
      if(WButton==2) //完整短按一次热水按键,若童锁已解锁则放水
      {
          //区分单击和双击
        
         if(!DoubleFlag||DoubleCnt>15) //单击事件处理
         {
             if(!DoubleFlag) DoubleFlag=1;
             if(ChildLockState==1&&WaterState==0)
             {
                  WaterState=1;
                  InWater();
             }    
             DoubleCnt=0;//计时器归零
         }
          else{ //双击事件处理
              if(ChildLockState==1&&WaterState==1)
              {
                  ChildLockState=0;
                  ChildLocked();
                  WaterState=0;
                  NoWater();
              }
              DoubleCnt=0;
          }
       
        
        WaterButtonState=0;
        WCnt_Empty=0;
      }
      break;
          
      case 2:

  }

  LastClButton=CurClButton;
  LastWButton=CurWButton;

}

void NoWater()
{
  digitalWrite(GREEN_LED,LOW);
}

void InWater()
{
  digitalWrite(GREEN_LED,HIGH);
}

void ChildLocked()
{
   digitalWrite(RED_LED,HIGH);
}

void ChildUnlocked()
{
  digitalWrite(RED_LED,LOW);
}

  • 6
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值