AN2039 Firmware Implementation


Peripherals Code Generated Using the Microchip Code Configurator (MCC) All the firmware for I/O, Timer1, ADC, PWM, Flash memory and I2C peripherals has been created and initialized using the free MPLAB Code Configurator (MCC) software. The system setup also uses the MCC
software. The entire firmware was developed using the MPLAB® X IDE. The use of the MCC software is highly recommended, since the firmware created is tested and well documented. The initialization and the user routines for each peripheral are modular and in case the user wants to use another larger or smaller PIC16F1XXX device, the re-creation of peripheral routines is very simple and takes very little time. Using the MCC, the code for all the peripherals will be automatically generated and placed in the MPLAB X project. The Adding a Timer explanation shows a step-by-step process for using the MCC to generate code for Timer1 as a brief example.

I2C Slave Interrupt Firmware

The I2C Slave Interrupt Firmware has also been created using MCC. MCC firmware has a built in example of serial EEPROM communication. The Modifying MCC created I2C Slave Interrupt details the setup using MCC to modify and incorporate the slave I2C used in the Power Sequencer program. This method is quick and very easy to use without any prior knowledge or setup details on the I2C protocol or function.


User Application

All code has been written in state machine format. The code for the PM modules is in the file app.c. The code for the ADC, Flash, Key and System is in the respective files appAdc.c, appFlash.c, appKey.c and appSys.c files. The definitions and the variables used are defined in app.h. The entire application code is state-machine based, where each task is defined as a series of states. For example, there is a state machine for the ADC, for each PM module, for Flash Memory and for the overall system. The *main.c program is very simple, as shown.

void main(void) 
 //All state machines are initialized at the start

//In an infinite loop each state machine is run one after another
 while (1)
  for (MI=1;MI < AllModules;MI++)

Modules 1 to 4 correspond to the PMs 1 to 4. Module 0 is designated to run a state machine which monitors the input voltage.

Each Initialize routine initializes the module or the system or the peripheral. On the other hand, each task is a state machine which runs the tasks for the application PM modules 0 to 4, the ADC, KEY, Flash Memory and the overall system.

Parameter Structure for Each Module

Each Power Module is assigned a set of parameters which are defined in “app.h”.

The parameters are:

  • State – which defines the state in which each module is in at a given moment in time.
    The 8 states are:
    • Init – The Initial state of the Module
    • On – Module is in the ON state
    • Off – Module is in the OFF state
    • Start – Module is turned ON
    • Starting – Module rise-time is taken into account when turning ON
    • Stop – Module is turned OFF
    • UpdatePWM – Module output voltage level is adjust by adjusting thePWM
    • ErrorChecking – Module output voltage level is checked to be within error limits
  • NormalUVL, NormalOVL, MarginUVL, MarginOVL – OverVoltageLimit and UnderVoltageLimit for Normal and Margin voltages. These variables are used and maintained for error checking. They are 8 bit unsigned value and they can be modified by the user.
  • ADC – Unsigned 16-bit value to maintain 16 counts of 10-bit ADC values.
  • PWMValue – 10 bit PWM duty cycle value used in the specific PWM used with the Module.
  • ADCValue – 8-bit average value of ADC over 16 counts of 10-bit values. This value is compared with the limit voltage values and checked for any errors.
  • anChannel – ADC channel number assigned to Module.
  • OnTime and OffTime – 14-bit value in mS for the start and stop time for each module
  • TurnOn – bit value to indicate if the module is turned on.

All parameters are defined in a typedef struct and an array of this struct is defined as:


The appmData[ 1] is for Module 1… appmData[4] is for module 4.
appmData[0] is kept for Input Voltage.

All the states and parameters are not necessarily relevant for the Input Voltage.
i.e. appmData[3].PWMValue – corresponds to the 10-bit Duty cycle value of the PWM used for Module # 3.

Apart from creating this structure, each module has an Initialize routine and a Tasks routine defined as :


Where x is a value 0 to 4.

By creating this structure and the associated functions for each module, it now becomes very easy for the user to increase or decrease the number of module used in the application. If the number of modules required is 3 then decrease the number of elements by 1 (from 4 to 3). One Initialize and Tasks functions can also be deleted. However, if we need to increase the number of modules by 1 to 5, then the number of elements in the array needs to increased( from 4 to 5). A copy and paste of one additional Initialize and Tasks routine will be needed and the appropriate parameters adjusted to reflect the new module #5.

Adding a Code Module is an example of how to add one additional Module #4 in the application.

ADC Routine and Voltage Measurement

The ADC routine essentially runs thru and sample the voltage of each module 0 to 4. Module 0, as mentioned earlier, corresponds to the Input Voltage, which always gets monitored for a failure. A failure of the Input Voltage also causes a shutdown. No retries will be attempted.

The 10-bit ADC routine samples each voltage 16 times and then uses the averaged 8-bit value to check for an error or adjustment of the margin voltage. In this Application, the Voltage reference is 5.0V or Vdd of the system. Using 5.0V as a voltage reference will work fine when sampling and converting 1.8V, 2.5V and 3.3V Modules. However for the 5.0V module and the input voltage, a resistor divider is needed to bring the full voltage range within the 5.0V reference voltage. The resistor divider factor for the 5.0V Module is 0.55 and the Input voltage divide factor is 0.239. Users will have to use these values during the calculation of the Under and Over voltage limit values and define them appropriately in the header files. This is especially required if the user decides to use values other than those used in this application note.

ADC State Machine States

The ADC state machine states are:

  • Init – Initializes the ADC converter
  • Sample – In this state, the ADC channel is assigned and a 1mSec Sampling time, is allowed before the conversion is started.
  • Convert – The convert command is given and the ADC conversion is started
  • Done – a check to see if the conversion is done, if yes then the converted value is added and if all 16 samples have been taken the appropriate module state is assigned for a PWM update and voltage check.
  • Next – In this state, the next module is assigned to the ADC and the whole process is repeated.

The ADC state machine is always running. A designated Module voltages is only checked if that module is turned ON or in the ON State. Otherwise only the Input Voltage is checked. Once a module is turned ON, it is always checked.

Key State Machine

The Key state machine has the following states:

  • Init – Initializes the State machine
  • High – when the key is at the default high state, a check for a key press (0 volts) is done
  • Low – when the key is in the pressed state, a check for a release (5 volts) is done
  • Debounce – in this state a delay of 20 mS is executed then a check for a high or low state is done

The Key state machine insures the proper functioning of the key press switch S1. If the system is OFF, a key-press will turn the system ON. If the system is ON, a key-press will turn the system OFF.

SYS State Machine

The SYS state machine manages the overall functioning of the system. In particular it manages failure modes during startup. If a startup failure occurs, then automatic re-starts are executed as defined by the user in the Retry parameter. The APP_SYS_Tasks() routine makes sure that all the retry attempts are executed. If all retry attempts are exhausted, the system will shut down and a fault condition will result. The user must then clear the system using a serial command on the i2C interface or a button on the GUI. Any failure mechanism must be fixed to prevent another failure during startup. The system will not restart until the reset command is executed or a power down reset is done.

The SYS states are:

  • Init: Initialize state for SYS
  • ON: State when the system is ON
  • OFF: State when the system is OFF
  • Starting: State when the system is starting up
  • Stopping: State when the system is shutting down
  • Fault: State when a system fault has occurred

Flash State Machine

The default parameters are saved in Flash Memory of the PIC16F1509. The Flash PM storage location, starts at 0x1f80 and the parameters are saved sequentially for each module.
The default parameters for each Module are:

  • Start time
  • Stop time
  • Normal Under Voltage limit
  • Normal Over Voltage limit
  • Margin Under Voltage limit
  • Margin Over Voltage limit
  • PWM DutyCycle
  • Apart from these 28 parameters( 4 x 7), the System parameters are also saved:
  • Vin Under Voltage limit
  • Vin Over Voltage limit
  • Number of retries

The user can use the GUI or serial command to change the value of these parameters. These values have to be “burnt” on to Flash Memory by the user, using the “Burn Flash” button on the GUI or the serial command: 0x10, 0xAB. Once they are burnt, they become the new default values. The file “” defines all the default values and locations in Flash PM.

20th Annual
Microchip MASTERs Conference 2016
Register now - Deadline: July 29

JW Marriott Desert Ridge Resort-Phoenix, AZ

© 2016 Microchip Technology, Inc.
Information contained on this site regarding device applications and the like is provided only for your convenience and may be superseded by updates. It is your responsibility to ensure that your application meets with your specifications. MICROCHIP MAKES NO REPRESENTATIONS OR WARRANTIES OF ANY KIND WHETHER EXPRESS OR IMPLIED, WRITTEN OR ORAL, STATUTORY OR OTHERWISE, RELATED TO THE INFORMATION, INCLUDING BUT NOT LIMITED TO ITS CONDITION, QUALITY, PERFORMANCE, MERCHANTABILITY OR FITNESS FOR PURPOSE. Microchip disclaims all liability arising from this information and its use. Use of Microchip devices in life support and/or safety applications is entirely at the buyer's risk, and the buyer agrees to defend, indemnify and hold harmless Microchip from any and all damages, claims, suits, or expenses resulting from such use. No licenses are conveyed, implicitly or otherwise, under any Microchip intellectual property rights.