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
SPN7Driver.cpp
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>© 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 }
Generated on Sat Jul 16 2022 22:03:49 by 1.7.2