CQ_KIT_Ver1_5
Dependencies: mbed RateLimiter BLDCmotorDriverCQ_KIT_Ver1_5
X_NUCLEO_IHM07M1/SPN7Driver.cpp@8:9a6444df4256, 2016-10-18 (annotated)
- Committer:
- avilei
- Date:
- Tue Oct 18 10:28:09 2016 +0000
- Revision:
- 8:9a6444df4256
- Parent:
- 7:022c306baeb9
- Child:
- 11:0120619cdfb7
Remove negative dutycycle
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
avilei | 2:4ae769d0b112 | 1 | /* mbed Microcontroller Library |
avilei | 2:4ae769d0b112 | 2 | * Copyright (c) 2006-2016 ARM Limited |
avilei | 2:4ae769d0b112 | 3 | * |
avilei | 2:4ae769d0b112 | 4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
avilei | 2:4ae769d0b112 | 5 | * you may not use this file except in compliance with the License. |
avilei | 2:4ae769d0b112 | 6 | * You may obtain a copy of the License at |
avilei | 2:4ae769d0b112 | 7 | * |
avilei | 2:4ae769d0b112 | 8 | * http://www.apache.org/licenses/LICENSE-2.0 |
avilei | 2:4ae769d0b112 | 9 | * |
avilei | 2:4ae769d0b112 | 10 | * Unless required by applicable law or agreed to in writing, software |
avilei | 2:4ae769d0b112 | 11 | * distributed under the License is distributed on an "AS IS" BASIS, |
avilei | 2:4ae769d0b112 | 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
avilei | 2:4ae769d0b112 | 13 | * See the License for the specific language governing permissions and |
avilei | 2:4ae769d0b112 | 14 | * limitations under the License. |
avilei | 2:4ae769d0b112 | 15 | */ |
avilei | 2:4ae769d0b112 | 16 | |
avilei | 2:4ae769d0b112 | 17 | /** |
avilei | 2:4ae769d0b112 | 18 | ****************************************************************************** |
avilei | 2:4ae769d0b112 | 19 | * @file SPN7Driver.cpp |
avilei | 2:4ae769d0b112 | 20 | * @author STMicroelectronics |
avilei | 2:4ae769d0b112 | 21 | * @brief Implementation of SPN7Driver class |
avilei | 2:4ae769d0b112 | 22 | ****************************************************************************** |
avilei | 2:4ae769d0b112 | 23 | * @copy |
avilei | 2:4ae769d0b112 | 24 | * |
avilei | 2:4ae769d0b112 | 25 | * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS |
avilei | 2:4ae769d0b112 | 26 | * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE |
avilei | 2:4ae769d0b112 | 27 | * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY |
avilei | 2:4ae769d0b112 | 28 | * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING |
avilei | 2:4ae769d0b112 | 29 | * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE |
avilei | 2:4ae769d0b112 | 30 | * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. |
avilei | 2:4ae769d0b112 | 31 | * |
avilei | 2:4ae769d0b112 | 32 | * <h2><center>© COPYRIGHT 2016 STMicroelectronics</center></h2> |
avilei | 2:4ae769d0b112 | 33 | */ |
avilei | 2:4ae769d0b112 | 34 | |
avilei | 7:022c306baeb9 | 35 | // This example is based on the BLDCmotorDriver motor control library |
avilei | 7:022c306baeb9 | 36 | // by the TVZ Mechatronics Team, University of Applied Sciences Zagreb, |
avilei | 7:022c306baeb9 | 37 | // Professional Study in Mechatronics: |
avilei | 7:022c306baeb9 | 38 | // https://developer.mbed.org/teams/TVZ-Mechatronics-Team/code/BLDCmotorDriver/ |
avilei | 7:022c306baeb9 | 39 | |
avilei | 2:4ae769d0b112 | 40 | #include "mbed.h" |
avilei | 2:4ae769d0b112 | 41 | #include "SPN7Driver.h" |
avilei | 2:4ae769d0b112 | 42 | |
avilei | 3:4c71d3475814 | 43 | typedef enum { |
avilei | 3:4c71d3475814 | 44 | ST_BLDC_LOW = 0, |
avilei | 3:4c71d3475814 | 45 | ST_BLDC_HIGH, |
avilei | 3:4c71d3475814 | 46 | ST_BLDC_OFF |
avilei | 3:4c71d3475814 | 47 | } st_bldc_status_t; |
avilei | 3:4c71d3475814 | 48 | |
avilei | 6:0eec4b6e94ba | 49 | /**************************************************************************/ |
avilei | 6:0eec4b6e94ba | 50 | /** |
avilei | 6:0eec4b6e94ba | 51 | @brief Constructor |
avilei | 6:0eec4b6e94ba | 52 | * @param pIN1 Logic input pin IN1 of L6230 chip |
avilei | 6:0eec4b6e94ba | 53 | * @param pIN2 Logic input pin IN2 of L6230 chip |
avilei | 6:0eec4b6e94ba | 54 | * @param pIN3 Logic input pin IN3 of L6230 chip |
avilei | 6:0eec4b6e94ba | 55 | * @param pEN1 Enable channel pin EN1 of L6230 chip |
avilei | 6:0eec4b6e94ba | 56 | * @param pEN2 Enable channel pin EN2 of L6230 chip |
avilei | 6:0eec4b6e94ba | 57 | * @param pEN3 Enable channel pin EN3 of L6230 chip |
avilei | 6:0eec4b6e94ba | 58 | * @param pH1 Hall sensor pin for phase #1 (A) of X-NUCLEO-IHM07M1 |
avilei | 6:0eec4b6e94ba | 59 | * @param pH2 Hall sensor pin for phase #2 (B) of X-NUCLEO-IHM07M1 |
avilei | 6:0eec4b6e94ba | 60 | * @param pH3 Hall sensor pin for phase #3 (Z) of X-NUCLEO-IHM07M1 |
avilei | 6:0eec4b6e94ba | 61 | * @param pFault Fault LED pin of X-NUCLEO-IHM07M1 |
avilei | 6:0eec4b6e94ba | 62 | */ |
avilei | 6:0eec4b6e94ba | 63 | /**************************************************************************/ |
avilei | 2:4ae769d0b112 | 64 | SPN7Driver::SPN7Driver(PinName pIN1, PinName pIN2, PinName pIN3, |
avilei | 2:4ae769d0b112 | 65 | PinName pEN1, PinName pEN2, PinName pEN3, |
avilei | 2:4ae769d0b112 | 66 | PinName pH1, PinName pH2, PinName pH3, |
avilei | 2:4ae769d0b112 | 67 | PinName pFault) : |
avilei | 2:4ae769d0b112 | 68 | BLDCmotorDriver(pIN1, pIN2, pIN3, |
avilei | 2:4ae769d0b112 | 69 | pEN1, pEN2, pEN3, |
avilei | 2:4ae769d0b112 | 70 | pH1, pH2, pH3, |
avilei | 2:4ae769d0b112 | 71 | pFault) |
avilei | 2:4ae769d0b112 | 72 | { |
avilei | 2:4ae769d0b112 | 73 | // The BLDCmotorDriver class was implemented for half-bridge drivers |
avilei | 2:4ae769d0b112 | 74 | // so the pin names may be misleading when referring to the L6230 chip. |
avilei | 3:4c71d3475814 | 75 | // Get pointers to each input pin and call them IN[x] (logic input) |
avilei | 2:4ae769d0b112 | 76 | // to be consistent with the terminology used in the L6230 documentation. |
avilei | 3:4c71d3475814 | 77 | PwmOut* IN[3] = {&GH_A, &GH_B, &GH_C}; |
avilei | 3:4c71d3475814 | 78 | |
avilei | 2:4ae769d0b112 | 79 | // Set the switching period of the INx logic input pins (PWM driven) |
avilei | 3:4c71d3475814 | 80 | for (int i = 0; i < 3; i++) { |
avilei | 3:4c71d3475814 | 81 | IN[i]->period(switchingPeriod); |
avilei | 3:4c71d3475814 | 82 | } |
avilei | 2:4ae769d0b112 | 83 | |
avilei | 2:4ae769d0b112 | 84 | // Set the step commutation function (triggered by the Hall sensors) |
avilei | 2:4ae769d0b112 | 85 | H1.rise(this, &SPN7Driver::commutation); |
avilei | 2:4ae769d0b112 | 86 | H2.rise(this, &SPN7Driver::commutation); |
avilei | 2:4ae769d0b112 | 87 | H3.rise(this, &SPN7Driver::commutation); |
avilei | 2:4ae769d0b112 | 88 | H1.fall(this, &SPN7Driver::commutation); |
avilei | 2:4ae769d0b112 | 89 | H2.fall(this, &SPN7Driver::commutation); |
avilei | 2:4ae769d0b112 | 90 | H3.fall(this, &SPN7Driver::commutation); |
avilei | 2:4ae769d0b112 | 91 | } |
avilei | 2:4ae769d0b112 | 92 | |
avilei | 6:0eec4b6e94ba | 93 | /**************************************************************************/ |
avilei | 6:0eec4b6e94ba | 94 | /** |
avilei | 6:0eec4b6e94ba | 95 | @brief Set duty cycle for motor control |
avilei | 8:9a6444df4256 | 96 | * @param dc duty cycle value |
avilei | 6:0eec4b6e94ba | 97 | */ |
avilei | 6:0eec4b6e94ba | 98 | /**************************************************************************/ |
avilei | 4:3f63eed73ad1 | 99 | void SPN7Driver::setDutyCycle(float dc) { |
avilei | 8:9a6444df4256 | 100 | if (dc >0 && dc <= 1) { |
avilei | 4:3f63eed73ad1 | 101 | ticker.attach(this, &SPN7Driver::commutation, sampleTime); |
avilei | 4:3f63eed73ad1 | 102 | tempDutyCycle = dc; |
avilei | 4:3f63eed73ad1 | 103 | } else { |
avilei | 4:3f63eed73ad1 | 104 | coast(); |
avilei | 4:3f63eed73ad1 | 105 | } |
avilei | 4:3f63eed73ad1 | 106 | } |
avilei | 4:3f63eed73ad1 | 107 | |
avilei | 2:4ae769d0b112 | 108 | // 6-step phase commutation |
avilei | 3:4c71d3475814 | 109 | void SPN7Driver::commutation() |
avilei | 3:4c71d3475814 | 110 | { |
avilei | 3:4c71d3475814 | 111 | // The BLDCmotorDriver class was implemented for half-bridge drivers |
avilei | 3:4c71d3475814 | 112 | // so the pin names may be misleading when referring to the L6230 chip. |
avilei | 3:4c71d3475814 | 113 | // Get pointers to each input pin and call them IN[x] (logic input) |
avilei | 3:4c71d3475814 | 114 | // to be consistent with the terminology used in the L6230 documentation. |
avilei | 3:4c71d3475814 | 115 | PwmOut* IN[3] = {&GH_A, &GH_B, &GH_C}; |
avilei | 3:4c71d3475814 | 116 | // Get pointers to each enable pin and call them ENx (enable channel) |
avilei | 3:4c71d3475814 | 117 | // to be consistent with the terminology used in the L6230 documentation. |
avilei | 3:4c71d3475814 | 118 | DigitalOut* EN[3] = {&GL_A, &GL_B, &GL_C}; |
avilei | 3:4c71d3475814 | 119 | |
avilei | 2:4ae769d0b112 | 120 | // 1--X--0--0--X--1 |
avilei | 2:4ae769d0b112 | 121 | // X--1--1--X--0--0 |
avilei | 3:4c71d3475814 | 122 | // 0--0--X--1--1--X |
avilei | 3:4c71d3475814 | 123 | st_bldc_status_t tab[6][3] = { |
avilei | 3:4c71d3475814 | 124 | {ST_BLDC_HIGH, ST_BLDC_OFF, ST_BLDC_LOW}, |
avilei | 3:4c71d3475814 | 125 | {ST_BLDC_OFF, ST_BLDC_HIGH, ST_BLDC_LOW}, |
avilei | 3:4c71d3475814 | 126 | {ST_BLDC_LOW, ST_BLDC_HIGH, ST_BLDC_OFF}, |
avilei | 3:4c71d3475814 | 127 | {ST_BLDC_LOW, ST_BLDC_OFF, ST_BLDC_HIGH}, |
avilei | 3:4c71d3475814 | 128 | {ST_BLDC_OFF, ST_BLDC_LOW, ST_BLDC_HIGH}, |
avilei | 3:4c71d3475814 | 129 | {ST_BLDC_HIGH, ST_BLDC_LOW, ST_BLDC_OFF}, |
avilei | 3:4c71d3475814 | 130 | }; |
avilei | 2:4ae769d0b112 | 131 | |
avilei | 2:4ae769d0b112 | 132 | dutyCycle = rl.out(tempDutyCycle); |
avilei | 2:4ae769d0b112 | 133 | currentSector = getSector(); |
avilei | 2:4ae769d0b112 | 134 | |
avilei | 3:4c71d3475814 | 135 | if (dutyCycle == 0) { |
avilei | 3:4c71d3475814 | 136 | // Stop the motor |
avilei | 2:4ae769d0b112 | 137 | coast(); |
avilei | 3:4c71d3475814 | 138 | return; |
avilei | 2:4ae769d0b112 | 139 | } |
avilei | 2:4ae769d0b112 | 140 | |
avilei | 3:4c71d3475814 | 141 | // Move to next sector (i.e. commute phase) |
avilei | 3:4c71d3475814 | 142 | if (dutyCycle > 0 ) { |
avilei | 3:4c71d3475814 | 143 | // Move forward |
avilei | 3:4c71d3475814 | 144 | currentSector++; |
avilei | 3:4c71d3475814 | 145 | if(currentSector > 5) currentSector = 0; |
avilei | 3:4c71d3475814 | 146 | } else { |
avilei | 3:4c71d3475814 | 147 | // Move backward |
avilei | 3:4c71d3475814 | 148 | currentSector--; |
avilei | 3:4c71d3475814 | 149 | if(currentSector < 0) currentSector = 5; |
avilei | 3:4c71d3475814 | 150 | } |
avilei | 3:4c71d3475814 | 151 | |
avilei | 3:4c71d3475814 | 152 | // Get the absolute value of the duty cycle for the PWM |
avilei | 3:4c71d3475814 | 153 | float d = (dutyCycle > 0) ? dutyCycle : -dutyCycle; |
avilei | 3:4c71d3475814 | 154 | |
avilei | 3:4c71d3475814 | 155 | // Update the logic inputs and the enable pins |
avilei | 3:4c71d3475814 | 156 | for (int i = 0; i < 3; i++) { |
avilei | 3:4c71d3475814 | 157 | *EN[i] = (tab[currentSector][i] == ST_BLDC_OFF) ? 0 : 1; |
avilei | 3:4c71d3475814 | 158 | *IN[i] = (tab[currentSector][i] == ST_BLDC_HIGH) ? d : 0; |
avilei | 3:4c71d3475814 | 159 | } |
avilei | 2:4ae769d0b112 | 160 | } |