Create your first Motor Control Application using MPLAB® Harmony v3: Step 5

Step 5: Add Application Code to Project

The application is already developed and is available in the files mcapp.c and q14.c under the < unzip mc_bldc_block_commutation>/firmware/src folder.

The application files mcapp.c and q14.c contain the application logic. They also contain placeholders that you will populate with the necessary code in the next step.

  • Go to the < unziped mc_bldc_block_commutation >/firmware/src folder and copy the pre-developed main.c , mcapp.c, q14.c, mcapp.h, q14.h, and userparams.h files.
  • Paste and replace (over-write) the files of your project available at <your project folder>/firmware/src with the copied files.
  • Add the application files mcapp.c, q14.c, mcapp.h, q14.h, and userparams.h to your project as shown below.


Navigate to MPLAB® X IDE and add the pre-developed files mcapp.c and q14.c to your project by right click on Source files > Add Existing Item….



Add mcapp.h, q14.h, and userparams.h to the project by right clicking on
Header Files > Add Existing Item….



Verify all the files are included properly, as follows:


The following steps will explain each function in the predeveloped application files.


The userparams.h file has all user-defined parameters for the application.

The motor specific parameters, board-specific parameters, and application parameter macros must be updated in the software for optimal control of the BLDC motor. The following section briefly describes the motor and application-specific parameters used in the project.

Setting motor control PWM frequency

PWM frequency is set by configuring the timer period of TCC0 in terms of TCC0 clock counts. This frequency needs to be communicated to other sections in the algorithm by defining the "Period Value" (set in MPLAB Harmony Configurator) + 1 as a macro in userparams.h.

For example, in order to achieve a PWM frequency of 25 kHz in edge aligned mode with peripheral clock frequency of 60 MHz, the period value defined in MHC is 2399. Therefore, the macro defined in userparams.h should be "period value" + 1 = 2400.


Setting motor specific parameters



Hall pattern and commutation patterns are defined in the mcapp.c file.

HALL_ARRAY [16] array contains the hall pattern for both the directions - the first eight entries are for clockwise direction, and the next eight entries are for anti-clockwise direction.

COMMUTATION_ARRAY [16] array contains the commutation pattern corresponding to the hall pattern - the first eight entries are for clockwise direction, and the next eight entries are for anti-clockwise direction.


The table below gives the hall and commutation pattern relation for long Hurst and small Hurst motors.


Example Commutation:

The entry in the commutation array for V+W- is 0x4075.

This is given in terms of the Pattern Enable register TCC_PATT.

Pattern value configuration for V+W- is 0x40. This means the low side switch of Phase W is continuously ON.


Pattern enable configuration is 0x75. Pattern output is disabled for Phase V high side switch where PWM will be applied as per speed command.



mcapp.h is included and MCAPP_Start(void) function is called inside the main() function.

This function calls all the callback functions, enables ADC, and starts TCC0 and TC0 Timers.


At this state, the application waits for start switch S2 to be pressed.


If the start switch is pressed, EIC_START_STOP_InterruptHandler(uintptr_t context) gets triggered and starts the motor by calling Motor_Start().

void EIC_START_STOP_InterruptHandler(uintptr_t context)
   /* Motor state (Start/Stop) toggled for every event on switch (S2) */
   Motor_StateParams.switchState ^= 1;

    if(1U == Motor_StateParams.switchState)
        Motor_StateParams.stateRun = 1;

        Motor_StateParams.stateRun = 0;

   /* Indicates the motor start */

LED0 (D2) glows to indicate motor is started.


The Motor_Start(void) function reads initial HALL values through Hall pins directly and updates the next commutation to the TCC0 Pattern register. It identifies the next Hall and commutation pattern based on the motor direction.

Default Motor Direction is Clockwise. If Direction SWITCH S3 is pressed, application will trigger the EIC_FORWARD_REVERSE_InterruptHandler(uintptr_t context) handler and changes the motor direction.

void EIC_FORWARD_REVERSE_InterruptHandler(uintptr_t context)

    /* Direction can be changed only when motor is stopped*/
        /* Motor direction (Forward/ Reverse) is changed for every event on switch (S3) */
        Motor_StateParams.direction ^= 1;

            Motor_StateParams.directionOffset = 0;
            Motor_StateParams.directionOffset = 8;

        /* Indicates the motor reverse direction */


Direction toggle command is accepted only when the motor is stationary.

LED1(D17) glows to indicate the motor is running in reverse direction.

Below are commutation patterns and state machines for both clockwise and anti-clockwise direction.

Clockwise Direction:


If the current Hall pattern is 3, the forced commutation pattern will be 0x4076, which corresponds to the next Hall pattern 1.

Anti-Clockwise Direction:



Every Hall Pattern change will create Velocity Interrupt in PDEC. Hence, application will trigger PDEC_VLC_InterruptHandler(PDEC_HALL_STATUS status, uintptr_t context) for each hall change.

In this handler, current hall sensor values read from PDEC_HALLPatternGet() function are compared with estimated next hall pattern value. If they are the same, it forces the next commutation pattern to the TCC0 Pattern register.



TC1 measures the time elapsed between two consecutive hall edges. These values are moving window averaged in this handler.



In between, TC0_1ms_InterruptHandler(TC_TIMER_STATUS status, uintptr_t context) will trigger for each 1ms.

ADC0 reads the output voltage of the potentiometer, which determines the current speed. Minimum motor speed, maximum speed, and current speed all can be controlled and managed within this 1ms handler.

Speed Calculation:

  • T – Time taken for one transition
  • Pole Pairs- Number of pole pairs available in the Motor
  • Value "6" denotes six transitions for one electrical cycle

PI controller is used to regulate the motor speed. PI controller function pi_lib_calculate (picontrol_type* piPtr) is available in the q14.c file.


This example project uses q14 format to represent the real-time physical quantities as follows:


The real value range of voltage, current, and speed are chosen as independent base quantities for deriving the range of other physical quantities. The independent base quantities are determined by considering the electrical constraints of the MCLV2 development board and the motor used.


If START/STOP switch S2 is pressed again, Motor_Stop(void) will be called. This function will make all motor control parameters to their initial state. This stops the motor and LED0 will be turned off.

You are now ready to build the code!

Next Step >

© 2020 Microchip Technology, Inc.
Notice: ARM and Cortex are the registered trademarks of ARM Limited in the EU and other countries.
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.