máquina de estados con c

7
Por: Omar Gurrola 3/28/13 http://www.proprojects.wordpress.com Máquiná de Estádos con C Finite Máchine Státe (FSM) La máquina de estados es un paradigma o arquitectura de programación que se utiliza para resolver algunos tipos de problemas, principalmente donde se interactúa software con hardware (maquinas). Existen diferentes tipos de máquinas de estados por lo que la estructura del software puede cambiar dependiendo del problema a resolver. Algunas de las ventajas que ofrecen son: Mejora el diseño del software. Código más fácil de entender, depurar y modificar. Flujo más organizado. Se puede cambiar el orden de la secuencia sin mucha dificultad. Se puede repetir más de una vez un evento. Se puede terminar el programa inmediatamente sin esperar al final de la secuencia. Este tema lo conocí por las clases de programación con LabVIEW Sesión #8, lo cual me llevo a investigar más y tratar de utilizarlo en el desarrollo de firmware para microcontroladores utilizando el lenguaje C. Al principio parecía complicado pero ya viendo los ejemplos me di cuenta que lo único que se puede complicar es el análisis del problema y el desarrollo del diagrama de estados, pero una vez teniendo bien plasmado eso implementarlo es muy sencillo. Uno de los documentos que más me gusto por la forma tan profesional y sencilla de explicar este tema fue de http://www.i-micro.com/pdf/articulos/Maquina_edos.pdf gracias a ellos puede entenderlo fácilmente. Para resolver un problema con una máquina de estados debemos: 1. Lo primero es analizar el problema a resolver para extraer los estados por los que puede pasar el dispositivo, al igual que las entradas y salidas. 2. Diseño del algoritmo (pseudocódigo, diagrama de flujo, tabla de estados, diagrama de estados, etc.). 3. Implementar el algoritmo en software. 4. Simulación, pruebas y correcciones pertinentes. Para utilizar una de las máquinas de estados en C se puede realizar de la siguiente manera: 1. Realizar una definición typedef de un enum para definir cada estado. 2. Una variable del tipo enum del paso uno para definir el estado siguiente. 3. Crear un ciclo while infinito para ejecutar cada estado. 4. Se debe definir el estado inicial de la máquina. 5. Un switch para ejecutar el estado siguiente estado. 6. Dentro de cada case el código a ejecutar del caso y la evaluación para determinar el siguiente caso.

Upload: dragoon-micromar

Post on 22-Mar-2016

221 views

Category:

Documents


1 download

DESCRIPTION

Como implementar una maquina de estados sencilla en C

TRANSCRIPT

Por: Omar Gurrola 3/28/13 http://www.proprojects.wordpress.com

Má quiná de Estádos con C Finite Máchine Státe (FSM)

La máquina de estados es un paradigma o arquitectura de programación que se utiliza para resolver algunos tipos de

problemas, principalmente donde se interactúa software con hardware (maquinas). Existen diferentes tipos de

máquinas de estados por lo que la estructura del software puede cambiar dependiendo del problema a resolver.

Algunas de las ventajas que ofrecen son:

Mejora el diseño del software.

Código más fácil de entender, depurar y modificar.

Flujo más organizado.

Se puede cambiar el orden de la secuencia sin mucha dificultad.

Se puede repetir más de una vez un evento.

Se puede terminar el programa inmediatamente sin esperar al final de la secuencia.

Este tema lo conocí por las clases de programación con LabVIEW Sesión #8, lo cual me llevo a investigar más y tratar de

utilizarlo en el desarrollo de firmware para microcontroladores utilizando el lenguaje C.

Al principio parecía complicado pero ya viendo los ejemplos me di cuenta que lo único que se puede complicar es el

análisis del problema y el desarrollo del diagrama de estados, pero una vez teniendo bien plasmado eso implementarlo

es muy sencillo.

Uno de los documentos que más me gusto por la forma tan profesional y sencilla de explicar este tema fue de

http://www.i-micro.com/pdf/articulos/Maquina_edos.pdf gracias a ellos puede entenderlo fácilmente.

Para resolver un problema con una máquina de estados debemos:

1. Lo primero es analizar el problema a resolver para extraer los estados por los que puede pasar el dispositivo, al

igual que las entradas y salidas.

2. Diseño del algoritmo (pseudocódigo, diagrama de flujo, tabla de estados, diagrama de estados, etc.).

3. Implementar el algoritmo en software.

4. Simulación, pruebas y correcciones pertinentes.

Para utilizar una de las máquinas de estados en C se puede realizar de la siguiente manera:

1. Realizar una definición typedef de un enum para definir cada estado.

2. Una variable del tipo enum del paso uno para definir el estado siguiente.

3. Crear un ciclo while infinito para ejecutar cada estado.

4. Se debe definir el estado inicial de la máquina.

5. Un switch para ejecutar el estado siguiente estado.

6. Dentro de cada case el código a ejecutar del caso y la evaluación para determinar el siguiente caso.

Por: Omar Gurrola 3/28/13 http://www.proprojects.wordpress.com typedef enum { STATE_0, STATE_1, STATE_2, . . STATE_N } STATES; void main(void){ STATES NextState; NextState = STATE_0; while(true){ switch(NextState){ case STATE_0: // Code to run when STATE_0 ... // Select NextState if(X == Y) NextState = STATE_1; else NextState = STATE_N; break; case STATE_1: ... break; ... case STATE_N: ... break; case default: // When the selected State has not defined show an error... break; }; } }

Procedamos a realizar un ejemplo.

Problema:

Se desea realizar un dispositivo que cuente cuantas personas se encuentran dentro de una sala de conferencias.

Supóngase que hay una puerta de entrada y otra diferente de salida, cada una con un sensor infrarrojo que cambia de 0

-> 1 al pasar una persona. No considere situaciones extraordinarias ni casos especiales.

1. Análisis del problema.

1.1. Entradas: Dos sensores infrarrojos (diodo infrarrojo y fototransistor) que pasan a 1 cuando pasa una persona

por la puerta.

1.2. Salidas: Un LCD HD44780 16x02 con la cuenta de personas que se encuentran en la sala.

1.3. Solución:

Se utilizara un uC PIC18F14K50 para implementar la FSM.

Para solucionar el problema se utilizara un contador de 16b (Suponiendo que la sala tiene un cupo máximo

de personas) que incrementara cada vez que se active el sensor de entrada y decrementara cada vez

que se active el sensor de salida, con esto mantendremos la cuenta de las personas en la sala.

Por ser un problema tan sencillo se utilizara polling en lugar de interrupciones para revisar cambio en los

sensores y solo se contara cuando el bit regrese a cero (La persona paso por completo).

No se entrada en detalles sobre el manejo del LCD, ya que solamente utilizaremos la librería.

Por: Omar Gurrola 3/28/13 http://www.proprojects.wordpress.com

2. Diagrama de estados.

2.1. Tabla de estados:

State: Description: Input: Next State

Configuration Configure device I/O, LCD, etc. None Check Sensors

Check Sensors Check sensors state (Core)

SEN_IN == 1 Count Up

SEN_OUT == 1 Count Down

(SEN_IN or SEN_OUT) != 1 Check Sensors

Count Up Increment counter None Update Data

Count Down Decrement counter None Update Data

Update Data Update data on LCD None Check Sensors

2.2. Diagrama de estados:

3. Implementación del algoritmo:

main.c /* * Copyright (c) 2011-2013, http://www.proprojects.wordpress.com * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: * * 1.- Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * 2.- Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT

Por: Omar Gurrola 3/28/13 http://www.proprojects.wordpress.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /********************************************************************************** * Author: Omar Gurrola * Site: http://www.proprojects.wordpress.com * Processor: PIC18 * Compiler: C18 v3.45 * File Name: main.c * Description: Main program * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * Rev. Date Comment * 1.0 04/01/12 Initial version * 1.1 01/29/13 Remove ISR prototipes, they are declared in hid_bl.h *********************************************************************************/ /** INCLUDES *******************************************************/ #include <p18f14k50.h> #include "pic18f14k50_cbits.h" #include "pic18f14k50_io.h" #include "stdvars.h" #include "wait.h" #include "HD44780-STP.h" #include <stdio.h> /** PROTOTYPES *****************************************************/ /** VARIABLES ******************************************************/ /** DECLARATIONS ***************************************************/ #pragma code // Forces the code below this line to be put into the code section (Memory Adress >= 0x'REMDIR'02A) /** Interrupt Service Routines (ISR)********************************/ #pragma interrupt HighPriorityISR void HighPriorityISR (void){ //Check which interrupt flag caused the interrupt. //Service the interrupt //Clear the interrupt flag //Etc. } //This return will be a "retfie fast", since this is in a #pragma interrupt section #pragma interruptlow LowPriorityISR void LowPriorityISR (void){ //Check which interrupt flag caused the interrupt. //Service the interrupt //Clear the interrupt flag //Etc. } //This return will be a "retfie", since this is in a #pragma interruptlow section // Aplication Defines #define SEN_IN PORTAbits.RA4 #define SEN_OUT PORTAbits.RA5 #define SEN_IN_OpenIn() OpenInRA4(); WPUA4Enable() #define SEN_OUT_OpenIn() OpenInRA5(); WPUA5Enable() // Declare states using an enumerator typedef enum { CONFIGURATION, CHECK_SENSORS, COUNT_UP, COUNT_DOWN, UPDATE_DATA } STATES; void main(void){ STATES NextState; // Declare NextState has STATES u16 Counter; // Counter s8 CounterString[6]; // Counter converted to string OSCCONbits.IRCF = 0b110; // Poscaler selected to 8 MHz OSCTUNEbits.SPLLEN = 1; // PLLx4 Enable System FQ = 32 MHz NextState = CONFIGURATION; // Initial STATE while(true){ // The Finite State Machsine (FSM) switch(NextState){ case CONFIGURATION: // Configure SWX IO Ports SEN_IN_OpenIn(); SEN_OUT_OpenIn();

Por: Omar Gurrola 3/28/13 http://www.proprojects.wordpress.com // Configure LCD lcd_initialize(); lcd_goto(1,1); lcd_write_pgm(" People Inside: "); lcd_goto(2,1); lcd_write_pgm(" 00000 "); // Initialize Counter Counter = 0; NextState = CHECK_SENSORS; break; case CHECK_SENSORS: // Check SWX if(SEN_IN == 1){ Waitmsx(50); // Wait for noise if(SEN_IN == 1){ while(SEN_IN == 1); // Wait until sensor is released NextState = COUNT_UP; } else{ NextState = CHECK_SENSORS; } } else if(SEN_OUT == 1){ Waitmsx(50); // Wait for noise if(SEN_OUT == 1){ while(SEN_OUT == 1); // Wait until sensor is released NextState = COUNT_DOWN; } else{ NextState = CHECK_SENSORS; } } else{ NextState = CHECK_SENSORS; } break; case COUNT_UP: Counter++; // Increment counter NextState = UPDATE_DATA; break; case COUNT_DOWN: Counter--; // Decrement counter NextState = UPDATE_DATA; break; case UPDATE_DATA: sprintf(&CounterString[0],"%.5hu",Counter); // Convert Counter to string lcd_goto(2,6); lcd_write(&CounterString[0]); NextState = CHECK_SENSORS; break; default: lcd_clear(); lcd_goto(1,1); lcd_write_pgm("ERROR!!!"); lcd_goto(2,1); lcd_write_pgm("UNKNOWN STATE!!!"); while(true); // Lock forever break; } } // end while } // end main()

Por: Omar Gurrola 3/28/13 http://www.proprojects.wordpress.com 4. Simulación, pruebas y correcciones pertinentes:

4.1. Simulación con Proteus ISIS:

4.2. Prototipo: Como no cuento con los diodos infrarrojos y los fototransistores utilizare interruptores en su lugar.

Por: Omar Gurrola 3/28/13 http://www.proprojects.wordpress.com

Referencias

Microchip, “PIC18F/LF1XK50 Data Sheet”, 2010,

http://ww1.microchip.com/downloads/en/DeviceDoc/41350E.pdf

Ing. Eric López Pérez, “Maquinas de Estado”, 2013

http://www.i-micro.com/pdf/articulos/Maquina_edos.pdf

Bennet Gedan, “Finite State Machine Matrix-Style C Implementation”, 2008

http://www.gedan.net/2008/09/08/finite-state-machine-matrix-style-c-implementation/

Mari Carmen Othero Vidal, “Diagrama de Estado”, 2013

http://caceros.docentes.upbbga.edu.co/I2012/SIM_I2012/laboratorios/lab1/Diagramas_estado.PDF