Create Your First Motor Control Application Using MPLAB® Harmony v3: Step 5

Last modified by Microchip on 2023/11/15 12:52

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.cmcapp.cq14.cmcapp.hq14.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.cq14.cmcapp.hq14.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-clicking on Source Files > Add Existing Item….

add source file

add sourcefile1

add sourcefile2

Back to top

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

add headerfile

add headerfile1add headerfile2


Back to top

Verify all the files are included properly, as follows:

completion view

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

Back to top

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 Code Configurator (MCC)) + 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 MCC is 2399. Therefore, the macro defined in userparams.h should be "period value" + 1 = 2400.

Setting motor control PWM frequency Chart

Setting motor specific parameters

​ Setting motor specific parameters chart

Back to top

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.

Code Example 1

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

hall and commutation pattern relation for long Hurst and small Hurst motors Table

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.

Example Commutation Table

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

Example Commutation Table

Back to top

The mcapp.h file 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.

Code Example 2

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

Back to top

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.

Back to top

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

Clockwise direction Hall pattern

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

Anti-Clockwise direction Hall pattern

Back to top

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.

Code Example 3

Back to top

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

Code Example 4

Back to top

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

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.

Back to top

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

Real-time physical quantities equation

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.

Back to top

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!

Back to top