• No results found

Integrating a state machine with existing code

In document LPCXpresso v7 User Guide (Page 110-115)

18. Red State : Software state machine tutorial

18.4. Integrating a state machine with existing code

We now have our completed state machine. Next we need to generate the C code for the state machine and hook it up to the existing code which turns LEDs on and off and handles external interrupts.

The state machine is updated by calling its dispatch function with inputs and outputs. The name of the dispatch function can be set in the State Machine Settings panel. Its default name is ledState_dispatch for this example. The inputs and outputs for the state machine

are defined by two structs in the main header file (e.g. ledState.h).

18.4.1 Editing

main

The main function in main_ledflash.c contains a while loop which increments a variable.

We will be replacing the content of that while loop with a call to the dispatch function. First, we need to set up the inputs and outputs. The input struct will be a global variable whose type is defined in ledState.h. Add the ledState.h header file to main_ledflash.c.

#include "ledState.h"

Then enter the following before the main function call:

pf_inputs input; // global access to the input

Next, we initialize the inputs between initializing the LEDs and the start of the while loop. Also, add the local output struct and initialize it by calling the dispatch function with the

reset signal set to 1. This reset will set the current state to the initial state and fill the output

with their preload values.

// initialise the inputs and outputs: input.buttonPushed = 0;

input.reset = 1;

pf_outputs out;

ledState_dispatch(input, &out); input.reset = 0;

Replace the body of the while loop with a call to the delay function and the call to the dispatch function:

while(1) {

short_delay(10); // slow it down ledState_dispatch(input, &out); i++;

}

18.4.2 Generating the state machine code

We now need to generate the code for the dispatch function. With the state machine editor selected, press the Generate Code button in the State Table panel. This should add four files to your project. The names of these files are defined in the State Machine Settings panel. By default you should have the following files:

• ledState.h — Header file for the logic of the state machine.

• ledState.c — The logic of the state machine. Contains the dispatch function and the

input and output data structures.

• ledState_actions.c — The functions that are called by the state machine.

The ledState_actions.c file is initially empty. It can be filled with the required template

functions by pressing the Generate Action C Template button in the Actions panel or by right-clicking in the State Machine editor window and selecting Generate Action

Template.

Warning

Generate Action Template will overwrite any existing content in your

ledState_actions.c file as well as regenerating the other three files.

You are expected to edit the ledState_actions.c file. The other files are regenerated each

time you press the Generate Code button. You are strongly advised not to edit these other files, as your changes will get overwritten.

18.4.3 Editing the actions C file

Press the Generate Action C Template button to make the function bodies for the action functions. The LedFlash example contains the leds.h and leds.c files which contain code

for turning on and off the LEDs. Include the leds.h in the ledState_actions.c file.

#include "leds.h"

The LEDs can be turned on by the function led_on(int) and off using led_off(int) passing

it a reference to the LED as the parameter. The LEDs are identified by the constants defined in leds.h, see Table 18.2.

Table 18.2. The LED ids

Constant Representation

LED_3 Red

LED_2 Yellow

LED_5 Green

LED_4 Walk Sign

Note that the unusual ordering of the LEDs is due to their layout on the RDB board. Enter the appropriate calls for turning the LEDs on and off in the function bodies.

/* Action: GreenOff */ void act_GreenOff() {

led_off (LED_5); // green led }

/* Action: GreenOn */ void act_GreenOn() {

led_on (LED_5); // green led }

/* Action: RedOff */ void act_RedOff() {

led_off (LED_3); // Red }

...

18.4.4 Accessing the outputs

The output variables are stored in a struct defined in the ledState.h file. Its name is of

the form prefix_outputs, where prefix is defined in the State Machine Settings view.

A pointer to the output struct is passed to the dispatch function. From within the action functions you can get this pointer by calling the prefix_getOutput() function. We use this

pointer to increment the timer value:

/* Action: incTimer */ void pf_incTimer() {

pf_outputs * out = pf_getOutput(); out->timer++;

}

18.4.5 Setting inputs in interrupt handlers

The state machine will now happily sit in its Green state. Now we need to hook up an external

interrupt so that the state machine knows when a pedestrian has pushed a button. We use code imported from the RDB1768cmsis2_ExtInt project — the eint0.c and eint0.h files. This

code is included in our base project.

Include the eint0.h header file in the main_ledflash.c file.

#include "eint0.h"

Next add the following line to initialize the interrupt immediately after the LEDs have been initialized.

// Setup External Interrupt 0 for RDB1768 ISP button EINT0_init();

In the eint0.c file replace the #include "leds.h" with #include "ledState.h". Declare input

as an extern global with the following line:

extern pf_inputs input;

Replace the call to leds_invert() from the EINT0_IRQHandler() in the eint0.c file with

input.buttonPushed = 1;

Now when the ISP button on the board is pressed, the buttonPushed input will be set to 1.

Finally we need to have it reset to 0 after the dispatch function has processed the event.

This reset is accomplished by setting the buttonPushed input to 0 after the dispatch function

is called. Place the following line after the call to ledState_dispatch() in the while loop in

the main function:

18.4.6 Running on the target

Now the traffic lights are ready to be deployed to the target. Switch to the C/C++ perspective and choose Debug 'RDB1768...' from the Quickstart Panel.

The LED beside the LCD will light up when this example is running on the RDB1768 board. Pressing the button labeled ISP (between the Ethernet socket and the LCD) makes the LEDs change in the traffic light sequence — see Figure 18.15.

Figure 18.15. The LEDs on the RDB1768 board.

18.4.7 Other examples

Be sure to check out other examples in the RedState examples folder. The project

RDB1768cmsis2_RedStateTrafficLCD shows how the same state machine can be used with

In document LPCXpresso v7 User Guide (Page 110-115)

Related documents