Search   
Home  Print View  

 

P112

Branch Content

Framework

What we call "framework" is a skeleton written in assembly that you must complete with your application specific code. The framework takes care of common tasks such as debouncing GPI readings and handling hardware interrupts. This section explains some details you must understand to make effective use of the framework.

The source is made of the following files:

    macros.h  (framework)
    p112.h    (framework)
    p112.asm  (framework)
    user.h    (User)
    init.asm  (User)
    user.asm  (User)
    timers.inc(User, optional)
    uart.inc  (User, optional)

Header files (.h) contains definitions only while .asm and .inc files implement the logic. As a user, you will only concern with the files indicated as (User) in the list above. Those marked as (User, optional) may or may not interest you depending on your application.

More on this in section "Writing your code".

FLAGS variable

Defined in p112.h is a variable named FLAGS. As the name suggests, this variable is used bitwise to indicate various status. The framework uses only two of these flags (also defined in p112.h):

   F_GPI_READY --> bit 0
   F_VT0_BUSY  --> bit 1

As a user, you are free to use the remaining bits for your own purposes.

MACROS

File macros.h contains all macros used by the framework. Your code will also make use of those macros so it worth to take a look to that file.

Some macros are generic and serve no purpose other than facilitate coding; this is the case of macro SELECT_BANK, for example. Also, a series of "traditional branch" macros are defined to get around the cumbersome PIC instructions btfsc, btfss. Those are: JZ, JNZ, JC, JNC.

There also are framework specific macros such as VTIMER and START_VTIMER. We will cover those later in this manual.

Interrupts Handling

Interrupts occurs when the Real Timer Tmr0 times out and when the UART has a complete byte available for reading. The framework handles those interrupts for you as following:

Registers STATUS and W are saved to the stack and global interrupts are disabled. Then, the source of the interrupt is identified. If it came from the Real Timer, subroutine ISR_Tmr0 is called; if it came from the UART, subroutine ISR_UART is called. These routines in turn make they ways to call user subroutines. More on this in section "Writing your code".

On return, registers STATUS and W are restored from the stack and global interrupts are enabled back.

Virtual Timers

The framework initializes the microcontroller's real timer Tmr0 to interrupt every one millisecond. Based on this "tick", various "virtual timers" are updated (decremented) by the interrupt service routine.

Unlike real timers, virtual timers are implemented in firmware. Each virtual timer consists of:

   COUNT variable
   VALUE literal
   BUSY flag

The BUSY flag resides in variable FLAGS; it is set while the virtual timer is counting, cleared after timeout. The VALUE literal expresses the count in milliseconds. The COUNT variable is decremented by the Tmr0 interrupt service routine until it reaches zero.

To start the virtual timer, the COUNT variable is loaded with the VALUE constant and the BUSY flag is set. This is done by macro START_VTIMER defined in macros.h. The BUSY flag is automatically cleared by the framework on timeout.

Using virtual timers in user code is as simple as running the START_TIMER macro to start it, then keep watching the BUSY flag for time out.

The framework implements one virtual timer (VT0) used for GPI debouncing. As a user, you can create and manage your own virtual timers. More on this in section "Writing your code".

GPI reading and debouncing

Reading and debouncing GPIs is handled by routine ReadGPI which is called continuously in the Main Loop. As a user, your only concern about whether flag F_GPI_READY (bit 0 of variable FLAGS) is set indicating that GPI reading is stable (debounced).

The ReadGPI routine works as following:

All GPIs are read at once from ports PORTA and PORTB. Literals GPIO_CFG_A and GPIO_CFG_B are used to mask GPOs. This is important to know because those literals are defined in user code (file user.h).

Values read from the ports are stored in temporary variables and virtual timer VT0 is started. As a consequence of this, flag F_VT0_BUSY (bit 1 of variable FLAGS) is set indicating that VT0 is counting.

When the ReadGPI routine is called again in the Main Loop, it returns immediately as this routine checks the F_VT0_BUSY flag. If set, it does nothing, just returns.

VT0 time out occurs 10 milliseconds later causing the F_VT0_BUSY flag to clear. The next time ReadGPI is called from the Main Loop, GPIs are read again from PORTA and PORTB, then compared with previos values. If they match, flag F_GPI_READY is set completing the job. If not, the new values are stored in temporary variables again and VT0 is started to give it another try.

This process is tried three times. If no two consecutives reading can be obtained, the alarm LED is turned on and reading is aborted all together.

Alarm codes and the ALM LED

The ADDR configuration jumpers

Serial Port (RS485/422)

Online Manuals -- this software is based on Help Books running at melissa