SinelaboreRT Header Logo

SinelaboreRT

As simple as possible, but not any simpler!

User Tools

Site Tools


wiki:examples:pic_tutorial

This is an old revision of the document!


Getting started with the PIC16F18446 and State Machines

This tutorial explains to use of state machines with the PIC16F18446 Curiosity Nano board. It provides 2k of RAM and 16k program memory. More than enought for this small tutorial.

Pre-requisites if you want to follow all steps yourself: - Java installation - MPLab X IDE - SinelaboreRT demo - Graphviz (for editing the state machine)

For this tutorial we will use just the push botton and the LED on the board. So you can follow it without any additional hardware required. The LED shall blink all the time. The frequency can be changed from slow to fast by pressing the button. Simple enough but sufficient to show all the key concepts we are going to use.

The PINs are allocated as shown in the next figure using the MPLAP X IDE pin manager. The 4MHz system clock and the 10ms Timer0 timer tick were also configured with the Resource Manager. I've not used this configurator before. But have to say that it is a very convinient way to setup the hardware. I would wish to have the same for the MSP430 μCs I also often use.

Step 1 - Deciding the system archtecture

For small sensor nodes it is usually sufficient use a main loop design. The main loop cycles endlessly and waits for events. Events are benefitially stored in an event queue. The queue is filled from timer events, other state machines (cooperating machines) or interrupt handlers. If events are available the state machine(s) are called from the main loop to process them.

In our little example events are sent from the keyboad interrupt and from a software timer module which is called regulary from the cyclic hardware timer. The following figure shows the system archtecture.

The below code snippets show the irq handlers and the main loop processing the evens.

// cyclic timer interrupt
void TMR0_IRQHandler(void){
    tick(); // if a timer has fired this function stores a timer event in the message queue
}
 
// keyboard interrupt
void SW0_IRQHandler(void){
    fifoPut(&fifo,evKey);
}
 
void main(void){
    ...
 
    while (1)
	{
        do {
            // check if there are one or more events in the queue.
            // if yes, process all events in the state machine
            retVal = fifoGet(&fifo, &bufVal);
            if (retVal != QUEUE_EMPTY) {
                sm(&instData, bufVal);
            }
        } while (retVal != QUEUE_EMPTY);
        __delay_ms(10U);
    }
}

Step 2 - Realizing the state machine

So far we have not seen how the state machine looks like. To realize this simple job just two evens are reqired. - evKey: Indicates that the user pressed the switch - evTimeout: Indicating that it is time to toggle the LED

The next figure shows the complete state machine:

evKey triggers the state transition from state Slow to state Fast or vice versa. Entering either state a new time out time is set.

This website uses cookies. By using the website, you agree with storing cookies on your computer. Also you acknowledge that you have read and understand our Privacy Policy. If you do not agree leave the website.More information about cookies

Leave your comments

, 2022/03/24 20:01, 2022/03/24 20:05
Hello Jonathan,

There are different possibilities. The most flexible is probably that you use a simple event queue per state machine. Then you check for each queue in the main loop if there is an event and then call the corresponding state machine.

An example of this approach is shown here: https://www.sinelabore.de/doku.php/wiki/news/02jan2015
The code example starts at "Weaving the state machines and the library part together”.

A simple implementation of a queue is also available on this page further down in the “lib” folder of the download. Or alternatively here: https://github.com/sinelabore/examples/tree/master/lib

If your machine has only view events (e.g. an irq handler implemented as SM) you can also instruct the code generator to generate the events represented as bits in a bitfield. Then a simple variable can store the events (bit set) for your state machine. But I think the queue based design is much more flexible. The relevant configuration parameter in the config file is: EventsAreBitCoded=yes

I send you the MPLAB files by separate mail.

Best regards,
Peter
, 2022/03/24 20:01, 2022/03/24 20:02
Hello,
I am evaluating your code generator for use with PIC24 controllers. I saw in Getting started with the PIC16F18446 and State Machines that you said "Use the example and expand it to learn. To receive a copy just send a mail."

Would it be possible to send me the MPLAB project for an example?

Also, I have a question about having several State Machines in the main loop. Do I have to worry about events being consumed by the wrong SM? How do I handle passing events to the correct SM?

Best Regards,
Jonathan Baize
wiki/examples/pic_tutorial.1556733966.txt.gz · Last modified: 2019/05/01 20:06 by pmueller

Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki