gg

Dependencies:   mbed MPU6050 RateLimiter test Math

Revision:
8:7efca5258efb
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/X_NUCLEO_IHM07M1/SPN7Driver.cpp	Fri Mar 06 05:58:45 2020 +0000
@@ -0,0 +1,162 @@
+/* mbed Microcontroller Library
+* Copyright (c) 2006-2016 ARM Limited
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*     http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+/**
+  ******************************************************************************
+  * @file    SPN7Driver.cpp 
+  * @author  STMicroelectronics
+  * @brief   Implementation of SPN7Driver class
+  ******************************************************************************
+  * @copy
+  *
+  * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
+  * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
+  * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
+  * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
+  * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
+  * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
+  *
+  * <h2><center>&copy; COPYRIGHT 2016 STMicroelectronics</center></h2>
+  */ 
+
+// This example is based on the BLDCmotorDriver motor control library
+// by the TVZ Mechatronics Team, University of Applied Sciences Zagreb,
+// Professional Study in Mechatronics:
+// https://developer.mbed.org/teams/TVZ-Mechatronics-Team/code/BLDCmotorDriver/
+
+#include "mbed.h"
+#include "SPN7Driver.h"
+
+typedef enum {
+    ST_BLDC_LOW = 0,
+    ST_BLDC_HIGH,
+    ST_BLDC_OFF
+} st_bldc_status_t;
+
+/**************************************************************************/
+/**
+    @brief  Constructor
+     * @param pIN1     Logic input pin IN1 of L6230 chip
+     * @param pIN2     Logic input pin IN2 of L6230 chip
+     * @param pIN3     Logic input pin IN3 of L6230 chip
+     * @param pEN1     Enable channel pin EN1 of L6230 chip
+     * @param pEN2     Enable channel pin EN2 of L6230 chip
+     * @param pEN3     Enable channel pin EN3 of L6230 chip
+     * @param pH1      Hall sensor pin for phase #1 (A) of X-NUCLEO-IHM07M1
+     * @param pH2      Hall sensor pin for phase #2 (B) of X-NUCLEO-IHM07M1
+     * @param pH3      Hall sensor pin for phase #3 (Z) of X-NUCLEO-IHM07M1
+     * @param pFault   Fault LED pin of X-NUCLEO-IHM07M1
+*/
+/**************************************************************************/
+SPN7Driver::SPN7Driver(PinName pIN1, PinName pIN2, PinName pIN3,
+                       PinName pEN1, PinName pEN2, PinName pEN3,
+                       PinName pH1,  PinName pH2,  PinName pH3,
+                       PinName pC1, PinName pC2, PinName pC3,
+                       PinName pFault) :
+                        BLDCmotorDriver(pIN1, pIN2, pIN3,
+                                        pEN1, pEN2, pEN3,
+                                        pH1,  pH2,  pH3,
+                                        pC1,  pC2,  pC3,
+                                        pFault)
+{
+    // The BLDCmotorDriver class was implemented for half-bridge drivers
+    // so the pin names may be misleading when referring to the L6230 chip.
+    // Get pointers to each input pin and call them IN[x] (logic input)
+    // to be consistent with the terminology used in the L6230 documentation.
+    PwmOut* IN[3] = {&GH_A, &GH_B, &GH_C};
+
+    // Set the switching period of the INx logic input pins (PWM driven)
+    for (int i = 0; i < 3; i++) {
+        IN[i]->period(switchingPeriod);
+    }    
+    
+    // Set the step commutation function (triggered by the Hall sensors)
+    H1.rise(this, &SPN7Driver::commutation);
+    H2.rise(this, &SPN7Driver::commutation);
+    H3.rise(this, &SPN7Driver::commutation);
+    H1.fall(this, &SPN7Driver::commutation);
+    H2.fall(this, &SPN7Driver::commutation);
+    H3.fall(this, &SPN7Driver::commutation);    
+}
+
+/**************************************************************************/
+/**
+    @brief  Set duty cycle for motor control
+     * @param dc       duty cycle value (>0 clockwise; <0 anti-clockwise)
+*/
+/**************************************************************************/
+void SPN7Driver::setDutyCycle(float dc) {
+    if (dc >= -1 && dc <= 1) {
+        ticker.attach(this, &SPN7Driver::commutation, sampleTime);
+        tempDutyCycle = dc;
+    } else {
+        coast();
+    }
+}
+
+// six-step phase commutation
+void SPN7Driver::commutation()
+{    
+    // The BLDCmotorDriver class was implemented for half-bridge drivers
+    // so the pin names may be misleading when referring to the L6230 chip.
+    // Get pointers to each input pin and call them IN[x] (logic input)
+    // to be consistent with the terminology used in the L6230 documentation.
+    PwmOut* IN[3] = {&GH_A, &GH_B, &GH_C};
+    // Get pointers to each enable pin and call them ENx (enable channel)
+    // to be consistent with the terminology used in the L6230 documentation.
+    DigitalOut* EN[3] = {&GL_A, &GL_B, &GL_C};
+
+    st_bldc_status_t tab[6][3] = {
+                            {ST_BLDC_OFF, ST_BLDC_LOW, ST_BLDC_HIGH},
+                            {ST_BLDC_HIGH, ST_BLDC_LOW, ST_BLDC_OFF},
+                            {ST_BLDC_HIGH, ST_BLDC_OFF, ST_BLDC_LOW},
+                            {ST_BLDC_OFF, ST_BLDC_HIGH, ST_BLDC_LOW},
+                            {ST_BLDC_LOW, ST_BLDC_HIGH, ST_BLDC_OFF},
+                            {ST_BLDC_LOW, ST_BLDC_OFF, ST_BLDC_HIGH},
+                            };
+
+    dutyCycle = rl.out(tempDutyCycle);
+    int sector = getSector();
+
+    if (dutyCycle == 0) {
+        // Stop the motor
+        coast();
+        return;
+    }
+    
+    // Move to next sector (i.e. commute phase)
+    if (dutyCycle > 0 ) {
+         // Clockwise spinning
+         
+         // The rows of the phase status table are offset by one when spinning
+         // clockwise so we need to increment the current sector by two steps
+         sector = (sector + 2) % 6;
+         
+    } else {
+        // Anti-clockwise spinning
+        sector--;
+        if(sector < 0) sector = 5;
+    }
+    
+    // Get the absolute value of the duty cycle for the PWM
+    float d = (dutyCycle > 0) ? dutyCycle : -dutyCycle;
+    
+    // Update the logic inputs and the enable pins
+    for (int i = 0; i < 3; i++) {
+         *EN[i] = (tab[sector][i] == ST_BLDC_OFF) ? 0 : 1;
+         *IN[i] = (tab[sector][i] == ST_BLDC_HIGH) ? d : 0;
+    }    
+}