Example application for X-NUCLEO-IHM07M1 board connected to a 3-phase brushless motor with Hall sensors.

Dependencies:   BLDCmotorDriver RateLimiter mbed

Fork of HelloWorld_IHM07M1 by Antonio Vilei

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers SPN7Driver.cpp Source File

SPN7Driver.cpp

Go to the documentation of this file.
00001 /* mbed Microcontroller Library
00002 * Copyright (c) 2006-2016 ARM Limited
00003 *
00004 * Licensed under the Apache License, Version 2.0 (the "License");
00005 * you may not use this file except in compliance with the License.
00006 * You may obtain a copy of the License at
00007 *
00008 *     http://www.apache.org/licenses/LICENSE-2.0
00009 *
00010 * Unless required by applicable law or agreed to in writing, software
00011 * distributed under the License is distributed on an "AS IS" BASIS,
00012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00013 * See the License for the specific language governing permissions and
00014 * limitations under the License.
00015 */
00016 
00017 /**
00018   ******************************************************************************
00019   * @file    SPN7Driver.cpp 
00020   * @author  STMicroelectronics
00021   * @brief   Implementation of SPN7Driver class
00022   ******************************************************************************
00023   * @copy
00024   *
00025   * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
00026   * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
00027   * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
00028   * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
00029   * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
00030   * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
00031   *
00032   * <h2><center>&copy; COPYRIGHT 2016 STMicroelectronics</center></h2>
00033   */ 
00034 
00035 // This example is based on the BLDCmotorDriver motor control library
00036 // by the TVZ Mechatronics Team, University of Applied Sciences Zagreb,
00037 // Professional Study in Mechatronics:
00038 // https://developer.mbed.org/teams/TVZ-Mechatronics-Team/code/BLDCmotorDriver/
00039 
00040 #include "mbed.h"
00041 #include "SPN7Driver.h"
00042 
00043 typedef enum {
00044     ST_BLDC_LOW = 0,
00045     ST_BLDC_HIGH,
00046     ST_BLDC_OFF
00047 } st_bldc_status_t;
00048 
00049 /**************************************************************************/
00050 /**
00051     @brief  Constructor
00052      * @param pIN1     Logic input pin IN1 of L6230 chip
00053      * @param pIN2     Logic input pin IN2 of L6230 chip
00054      * @param pIN3     Logic input pin IN3 of L6230 chip
00055      * @param pEN1     Enable channel pin EN1 of L6230 chip
00056      * @param pEN2     Enable channel pin EN2 of L6230 chip
00057      * @param pEN3     Enable channel pin EN3 of L6230 chip
00058      * @param pH1      Hall sensor pin for phase #1 (A) of X-NUCLEO-IHM07M1
00059      * @param pH2      Hall sensor pin for phase #2 (B) of X-NUCLEO-IHM07M1
00060      * @param pH3      Hall sensor pin for phase #3 (Z) of X-NUCLEO-IHM07M1
00061      * @param pFault   Fault LED pin of X-NUCLEO-IHM07M1
00062 */
00063 /**************************************************************************/
00064 SPN7Driver::SPN7Driver(PinName pIN1, PinName pIN2, PinName pIN3,
00065                        PinName pEN1, PinName pEN2, PinName pEN3,
00066                        PinName pH1,  PinName pH2,  PinName pH3,
00067                        PinName pFault) :
00068                         BLDCmotorDriver(pIN1, pIN2, pIN3,
00069                                         pEN1, pEN2, pEN3,
00070                                         pH1,  pH2,  pH3,
00071                                         pFault)
00072 {
00073     // The BLDCmotorDriver class was implemented for half-bridge drivers
00074     // so the pin names may be misleading when referring to the L6230 chip.
00075     // Get pointers to each input pin and call them IN[x] (logic input)
00076     // to be consistent with the terminology used in the L6230 documentation.
00077     PwmOut* IN[3] = {&GH_A, &GH_B, &GH_C};
00078 
00079     // Set the switching period of the INx logic input pins (PWM driven)
00080     for (int i = 0; i < 3; i++) {
00081         IN[i]->period(switchingPeriod);
00082     }    
00083     
00084     // Set the step commutation function (triggered by the Hall sensors)
00085     H1.rise(this, &SPN7Driver::commutation);
00086     H2.rise(this, &SPN7Driver::commutation);
00087     H3.rise(this, &SPN7Driver::commutation);
00088     H1.fall(this, &SPN7Driver::commutation);
00089     H2.fall(this, &SPN7Driver::commutation);
00090     H3.fall(this, &SPN7Driver::commutation);    
00091 }
00092 
00093 /**************************************************************************/
00094 /**
00095     @brief  Set duty cycle for motor control
00096      * @param dc       duty cycle value (>0 clockwise; <0 anti-clockwise)
00097 */
00098 /**************************************************************************/
00099 void SPN7Driver::setDutyCycle(float dc) {
00100     if (dc >= -1 && dc <= 1) {
00101         ticker.attach(this, &SPN7Driver::commutation, sampleTime);
00102         tempDutyCycle = dc;
00103     } else {
00104         coast();
00105     }
00106 }
00107 
00108 // six-step phase commutation
00109 void SPN7Driver::commutation()
00110 {    
00111     // The BLDCmotorDriver class was implemented for half-bridge drivers
00112     // so the pin names may be misleading when referring to the L6230 chip.
00113     // Get pointers to each input pin and call them IN[x] (logic input)
00114     // to be consistent with the terminology used in the L6230 documentation.
00115     PwmOut* IN[3] = {&GH_A, &GH_B, &GH_C};
00116     // Get pointers to each enable pin and call them ENx (enable channel)
00117     // to be consistent with the terminology used in the L6230 documentation.
00118     DigitalOut* EN[3] = {&GL_A, &GL_B, &GL_C};
00119 
00120     st_bldc_status_t tab[6][3] = {
00121                             {ST_BLDC_OFF, ST_BLDC_LOW, ST_BLDC_HIGH},
00122                             {ST_BLDC_HIGH, ST_BLDC_LOW, ST_BLDC_OFF},
00123                             {ST_BLDC_HIGH, ST_BLDC_OFF, ST_BLDC_LOW},
00124                             {ST_BLDC_OFF, ST_BLDC_HIGH, ST_BLDC_LOW},
00125                             {ST_BLDC_LOW, ST_BLDC_HIGH, ST_BLDC_OFF},
00126                             {ST_BLDC_LOW, ST_BLDC_OFF, ST_BLDC_HIGH},
00127                             };
00128 
00129     dutyCycle = rl.out(tempDutyCycle);
00130     int sector = getSector();
00131 
00132     if (dutyCycle == 0) {
00133         // Stop the motor
00134         coast();
00135         return;
00136     }
00137     
00138     // Move to next sector (i.e. commute phase)
00139     if (dutyCycle > 0 ) {
00140          // Clockwise spinning
00141          
00142          // The rows of the phase status table are offset by one when spinning
00143          // clockwise so we need to increment the current sector by two steps
00144          sector = (sector + 2) % 6;
00145     } else {
00146         // Anti-clockwise spinning
00147         sector--;
00148         if(sector < 0) sector = 5;
00149     }
00150     
00151     // Get the absolute value of the duty cycle for the PWM
00152     float d = (dutyCycle > 0) ? dutyCycle : -dutyCycle;
00153     
00154     // Update the logic inputs and the enable pins
00155     for (int i = 0; i < 3; i++) {
00156          *EN[i] = (tab[sector][i] == ST_BLDC_OFF) ? 0 : 1;
00157          *IN[i] = (tab[sector][i] == ST_BLDC_HIGH) ? d : 0;
00158     }    
00159 }