Sử dụng "State Machine" trong lập trình nhúng - Part 1

Sử dụng "State Machine" trong lập trình nhúng

      Mình có tìm hiểu và tích lũy được một chút về sử dụng State Machine trong Lập trình nhúng. Một loạt bài viết của mình về State Machine sẽ giới thiệu cho những người mới bắt đầu về cách sử dụng State Machine qua các ví dụ cơ bản.

      Đây là một ví dụ đơn giản về sử dụng State Machine để xử lý các sự kiện trong Lập trình nhúng mbed.
      Chúng ta có 3 nút nhấn button, khi các button này được thực hiện sự kiện "nhấn" (pressed) sẽ được hiển thị qua 3 Led trên mạch.


#include "mbed.h"
 
/* Various states */
typedef enum tState 
{ 
  STATE_A,
  STATE_B,
  STATE_C 
} tState;
 
/* Variables */
tState       state;       /* Current state */
char         trigger;     /* Bit set to indicate which button triggers */
 
InterruptIn  button1(p5); /* interrupt for button 1 at pin 5 */
InterruptIn  button2(p6); /* interrupt for button 1 at pin 6 */
InterruptIn  button3(p7); /* interrupt for button 1 at pin 7 */
BusOut       task(LED1, LED2, LED3, LED4);
 
/* Interrupt handlers when buttons is pressed */
void int_button1() {trigger |= 0x01;}  
void int_button2() {trigger |= 0x02;}
void int_button3() {trigger |= 0x04;}
 
/* task to be executed during each state transition */
void do_task(int n) {task = n; wait(2.0);}
 
void sleep(void) {__WFI();} /* Power-saving sleeping mode */
 
 
int main() 
{
  /* Enable pull-down resistor for each button */
  button1.mode(PullDown);
  button2.mode(PullDown);
  button3.mode(PullDown);
  
  /* Assign ISR to each button */
  button1.rise(&int_button1);
  button2.rise(&int_button2);
  button3.rise(&int_button3);
  
  /* initial the state machine */
  state = STATE_A;
  do_task(STATE_A);
  
  while(1) 
  {
    /* While I am not triggered, sleep */
    while (!trigger)
      sleep();
    
    /* I am awake now. Check which button has triggered*/
    switch (state)
    {
      //////////////////////////////////////////////////////////////////
      case STATE_A:  ///////////////////////////////////////////////////
      //////////////////////////////////////////////////////////////////
        if (trigger & 0x01/* Button 1 down */
        {
          do_task(1);
          state = STATE_B; /* Transit to STATE_B */
        }
        trigger = 0/* Ignore other triggers in this state */
        break;
 
      //////////////////////////////////////////////////////////////////
      case STATE_B:  ///////////////////////////////////////////////////
      //////////////////////////////////////////////////////////////////
        if (trigger & 0x01/* Button 1 down */
        {
          do_task(2);
          state = STATE_A;
        }
        if (trigger & 0x02/* Button 2 down */
        {
          do_task(3);
          /* Remain in the same state */
        }
        if (trigger & 0x04/* Button 3 down */
        {
          do_task(4);
          state = STATE_C;
        }
        trigger = 0/* Ignore other triggers in this state */
        break;
 
      //////////////////////////////////////////////////////////////////
      case STATE_C:  ///////////////////////////////////////////////////
      //////////////////////////////////////////////////////////////////
        if (trigger & 0x04/* Button 3 down */
        {
          do_task(5);
          state = STATE_A;
        }
        break;
    } /* while (!trigger) */
  } /* while (1) */
}

Còn nữa,....

No comments

Powered by Blogger.