Máquina de Estados con C

Page 1

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. 2. 3. 4. 5. 6.

Realizar una definición typedef de un enum para definir cada estado. Una variable del tipo enum del paso uno para definir el estado siguiente. Crear un ciclo while infinito para ejecutar cada estado. Se debe definir el estado inicial de la máquina. Un switch para ejecutar el estado siguiente estado. 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: Configuration

Description: Configure device I/O, LCD, etc.

Check Sensors

Check sensors state (Core)

Count Up Count Down Update Data

Increment counter Decrement counter Update data on LCD

Input: None SEN_IN == 1 SEN_OUT == 1 (SEN_IN or SEN_OUT) != 1 None None None

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

Next State Check Sensors Count Up Count Down Check Sensors Update Data Update Data Check Sensors


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 #define SEN_OUT #define SEN_IN_OpenIn() #define SEN_OUT_OpenIn()

PORTAbits.RA4 PORTAbits.RA5 OpenInRA4(); WPUA4Enable() OpenInRA5(); WPUA5Enable()

// Declare states using an enumerator typedef enum { CONFIGURATION, CHECK_SENSORS, COUNT_UP, COUNT_DOWN, UPDATE_DATA } STATES; void main(void){ STATES NextState; u16 Counter; s8 CounterString[6]; OSCCONbits.IRCF = 0b110; OSCTUNEbits.SPLLEN = 1;

// Declare NextState has STATES // Counter // Counter converted to string // Poscaler selected to 8 MHz // 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); if(SEN_IN == 1){ while(SEN_IN == 1); NextState = COUNT_UP; } else{ NextState = CHECK_SENSORS; } } else if(SEN_OUT == 1){ Waitmsx(50); if(SEN_OUT == 1){ while(SEN_OUT == 1); NextState = COUNT_DOWN; } else{ NextState = CHECK_SENSORS; } } else{ NextState = CHECK_SENSORS; } break; case COUNT_UP: Counter++; // Increment counter NextState = UPDATE_DATA; break;

// Wait for noise // Wait until sensor is released

// Wait for noise // Wait until sensor is released

case COUNT_DOWN: Counter--; // Decrement counter NextState = UPDATE_DATA; break; case UPDATE_DATA: sprintf(&CounterString[0],"%.5hu",Counter); 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()

// Convert Counter to string


Por: Omar Gurrola 4. Simulaci贸n, pruebas y correcciones pertinentes: 4.1. Simulaci贸n con Proteus ISIS:

3/28/13

http://www.proprojects.wordpress.com

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


Issuu converts static files into: digital portfolios, online yearbooks, online catalogs, digital photo albums and more. Sign up and create your flipbook.