![](/media/cache/img/default_profile.jpg.50x50_q85.jpg)
CQ_KIT_Ver1_5
Dependencies: mbed RateLimiter BLDCmotorDriverCQ_KIT_Ver1_5
X_NUCLEO_IHM07M1/SPN7Driver.cpp@6:0eec4b6e94ba, 2016-10-17 (annotated)
- Committer:
- avilei
- Date:
- Mon Oct 17 15:17:28 2016 +0000
- Revision:
- 6:0eec4b6e94ba
- Parent:
- 5:3290e8857120
- Child:
- 7:022c306baeb9
Add comments
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 | 2:4ae769d0b112 | 35 | #include "mbed.h" |
avilei | 2:4ae769d0b112 | 36 | #include "SPN7Driver.h" |
avilei | 2:4ae769d0b112 | 37 | |
avilei | 3:4c71d3475814 | 38 | typedef enum { |
avilei | 3:4c71d3475814 | 39 | ST_BLDC_LOW = 0, |
avilei | 3:4c71d3475814 | 40 | ST_BLDC_HIGH, |
avilei | 3:4c71d3475814 | 41 | ST_BLDC_OFF |
avilei | 3:4c71d3475814 | 42 | } st_bldc_status_t; |
avilei | 3:4c71d3475814 | 43 | |
avilei | 6:0eec4b6e94ba | 44 | /**************************************************************************/ |
avilei | 6:0eec4b6e94ba | 45 | /** |
avilei | 6:0eec4b6e94ba | 46 | @brief Constructor |
avilei | 6:0eec4b6e94ba | 47 | * @param pIN1 Logic input pin IN1 of L6230 chip |
avilei | 6:0eec4b6e94ba | 48 | * @param pIN2 Logic input pin IN2 of L6230 chip |
avilei | 6:0eec4b6e94ba | 49 | * @param pIN3 Logic input pin IN3 of L6230 chip |
avilei | 6:0eec4b6e94ba | 50 | * @param pEN1 Enable channel pin EN1 of L6230 chip |
avilei | 6:0eec4b6e94ba | 51 | * @param pEN2 Enable channel pin EN2 of L6230 chip |
avilei | 6:0eec4b6e94ba | 52 | * @param pEN3 Enable channel pin EN3 of L6230 chip |
avilei | 6:0eec4b6e94ba | 53 | * @param pH1 Hall sensor pin for phase #1 (A) of X-NUCLEO-IHM07M1 |
avilei | 6:0eec4b6e94ba | 54 | * @param pH2 Hall sensor pin for phase #2 (B) of X-NUCLEO-IHM07M1 |
avilei | 6:0eec4b6e94ba | 55 | * @param pH3 Hall sensor pin for phase #3 (Z) of X-NUCLEO-IHM07M1 |
avilei | 6:0eec4b6e94ba | 56 | * @param pFault Fault LED pin of X-NUCLEO-IHM07M1 |
avilei | 6:0eec4b6e94ba | 57 | */ |
avilei | 6:0eec4b6e94ba | 58 | /**************************************************************************/ |
avilei | 2:4ae769d0b112 | 59 | SPN7Driver::SPN7Driver(PinName pIN1, PinName pIN2, PinName pIN3, |
avilei | 2:4ae769d0b112 | 60 | PinName pEN1, PinName pEN2, PinName pEN3, |
avilei | 2:4ae769d0b112 | 61 | PinName pH1, PinName pH2, PinName pH3, |
avilei | 2:4ae769d0b112 | 62 | PinName pFault) : |
avilei | 2:4ae769d0b112 | 63 | BLDCmotorDriver(pIN1, pIN2, pIN3, |
avilei | 2:4ae769d0b112 | 64 | pEN1, pEN2, pEN3, |
avilei | 2:4ae769d0b112 | 65 | pH1, pH2, pH3, |
avilei | 2:4ae769d0b112 | 66 | pFault) |
avilei | 2:4ae769d0b112 | 67 | { |
avilei | 2:4ae769d0b112 | 68 | // The BLDCmotorDriver class was implemented for half-bridge drivers |
avilei | 2:4ae769d0b112 | 69 | // so the pin names may be misleading when referring to the L6230 chip. |
avilei | 3:4c71d3475814 | 70 | // Get pointers to each input pin and call them IN[x] (logic input) |
avilei | 2:4ae769d0b112 | 71 | // to be consistent with the terminology used in the L6230 documentation. |
avilei | 3:4c71d3475814 | 72 | PwmOut* IN[3] = {&GH_A, &GH_B, &GH_C}; |
avilei | 3:4c71d3475814 | 73 | |
avilei | 2:4ae769d0b112 | 74 | // Set the switching period of the INx logic input pins (PWM driven) |
avilei | 3:4c71d3475814 | 75 | for (int i = 0; i < 3; i++) { |
avilei | 3:4c71d3475814 | 76 | IN[i]->period(switchingPeriod); |
avilei | 3:4c71d3475814 | 77 | } |
avilei | 2:4ae769d0b112 | 78 | |
avilei | 2:4ae769d0b112 | 79 | // Set the step commutation function (triggered by the Hall sensors) |
avilei | 2:4ae769d0b112 | 80 | H1.rise(this, &SPN7Driver::commutation); |
avilei | 2:4ae769d0b112 | 81 | H2.rise(this, &SPN7Driver::commutation); |
avilei | 2:4ae769d0b112 | 82 | H3.rise(this, &SPN7Driver::commutation); |
avilei | 2:4ae769d0b112 | 83 | H1.fall(this, &SPN7Driver::commutation); |
avilei | 2:4ae769d0b112 | 84 | H2.fall(this, &SPN7Driver::commutation); |
avilei | 2:4ae769d0b112 | 85 | H3.fall(this, &SPN7Driver::commutation); |
avilei | 2:4ae769d0b112 | 86 | } |
avilei | 2:4ae769d0b112 | 87 | |
avilei | 6:0eec4b6e94ba | 88 | /**************************************************************************/ |
avilei | 6:0eec4b6e94ba | 89 | /** |
avilei | 6:0eec4b6e94ba | 90 | @brief Set duty cycle for motor control |
avilei | 6:0eec4b6e94ba | 91 | * @param dc duty cycle value (positive for clockwise spin) |
avilei | 6:0eec4b6e94ba | 92 | */ |
avilei | 6:0eec4b6e94ba | 93 | /**************************************************************************/ |
avilei | 4:3f63eed73ad1 | 94 | void SPN7Driver::setDutyCycle(float dc) { |
avilei | 4:3f63eed73ad1 | 95 | if (dc >= -1 && dc <= 1) { |
avilei | 4:3f63eed73ad1 | 96 | ticker.attach(this, &SPN7Driver::commutation, sampleTime); |
avilei | 4:3f63eed73ad1 | 97 | tempDutyCycle = dc; |
avilei | 4:3f63eed73ad1 | 98 | } else { |
avilei | 4:3f63eed73ad1 | 99 | coast(); |
avilei | 4:3f63eed73ad1 | 100 | } |
avilei | 4:3f63eed73ad1 | 101 | } |
avilei | 4:3f63eed73ad1 | 102 | |
avilei | 2:4ae769d0b112 | 103 | // 6-step phase commutation |
avilei | 3:4c71d3475814 | 104 | void SPN7Driver::commutation() |
avilei | 3:4c71d3475814 | 105 | { |
avilei | 3:4c71d3475814 | 106 | // The BLDCmotorDriver class was implemented for half-bridge drivers |
avilei | 3:4c71d3475814 | 107 | // so the pin names may be misleading when referring to the L6230 chip. |
avilei | 3:4c71d3475814 | 108 | // Get pointers to each input pin and call them IN[x] (logic input) |
avilei | 3:4c71d3475814 | 109 | // to be consistent with the terminology used in the L6230 documentation. |
avilei | 3:4c71d3475814 | 110 | PwmOut* IN[3] = {&GH_A, &GH_B, &GH_C}; |
avilei | 3:4c71d3475814 | 111 | // Get pointers to each enable pin and call them ENx (enable channel) |
avilei | 3:4c71d3475814 | 112 | // to be consistent with the terminology used in the L6230 documentation. |
avilei | 3:4c71d3475814 | 113 | DigitalOut* EN[3] = {&GL_A, &GL_B, &GL_C}; |
avilei | 3:4c71d3475814 | 114 | |
avilei | 2:4ae769d0b112 | 115 | // 1--X--0--0--X--1 |
avilei | 2:4ae769d0b112 | 116 | // X--1--1--X--0--0 |
avilei | 3:4c71d3475814 | 117 | // 0--0--X--1--1--X |
avilei | 3:4c71d3475814 | 118 | st_bldc_status_t tab[6][3] = { |
avilei | 3:4c71d3475814 | 119 | {ST_BLDC_HIGH, ST_BLDC_OFF, ST_BLDC_LOW}, |
avilei | 3:4c71d3475814 | 120 | {ST_BLDC_OFF, ST_BLDC_HIGH, ST_BLDC_LOW}, |
avilei | 3:4c71d3475814 | 121 | {ST_BLDC_LOW, ST_BLDC_HIGH, ST_BLDC_OFF}, |
avilei | 3:4c71d3475814 | 122 | {ST_BLDC_LOW, ST_BLDC_OFF, ST_BLDC_HIGH}, |
avilei | 3:4c71d3475814 | 123 | {ST_BLDC_OFF, ST_BLDC_LOW, ST_BLDC_HIGH}, |
avilei | 3:4c71d3475814 | 124 | {ST_BLDC_HIGH, ST_BLDC_LOW, ST_BLDC_OFF}, |
avilei | 3:4c71d3475814 | 125 | }; |
avilei | 2:4ae769d0b112 | 126 | |
avilei | 2:4ae769d0b112 | 127 | dutyCycle = rl.out(tempDutyCycle); |
avilei | 2:4ae769d0b112 | 128 | currentSector = getSector(); |
avilei | 2:4ae769d0b112 | 129 | |
avilei | 3:4c71d3475814 | 130 | if (dutyCycle == 0) { |
avilei | 3:4c71d3475814 | 131 | // Stop the motor |
avilei | 2:4ae769d0b112 | 132 | coast(); |
avilei | 3:4c71d3475814 | 133 | return; |
avilei | 2:4ae769d0b112 | 134 | } |
avilei | 2:4ae769d0b112 | 135 | |
avilei | 3:4c71d3475814 | 136 | // Move to next sector (i.e. commute phase) |
avilei | 3:4c71d3475814 | 137 | if (dutyCycle > 0 ) { |
avilei | 3:4c71d3475814 | 138 | // Move forward |
avilei | 3:4c71d3475814 | 139 | currentSector++; |
avilei | 3:4c71d3475814 | 140 | if(currentSector > 5) currentSector = 0; |
avilei | 3:4c71d3475814 | 141 | } else { |
avilei | 3:4c71d3475814 | 142 | // Move backward |
avilei | 3:4c71d3475814 | 143 | currentSector--; |
avilei | 3:4c71d3475814 | 144 | if(currentSector < 0) currentSector = 5; |
avilei | 3:4c71d3475814 | 145 | } |
avilei | 3:4c71d3475814 | 146 | |
avilei | 3:4c71d3475814 | 147 | // Get the absolute value of the duty cycle for the PWM |
avilei | 3:4c71d3475814 | 148 | float d = (dutyCycle > 0) ? dutyCycle : -dutyCycle; |
avilei | 3:4c71d3475814 | 149 | |
avilei | 3:4c71d3475814 | 150 | // Update the logic inputs and the enable pins |
avilei | 3:4c71d3475814 | 151 | for (int i = 0; i < 3; i++) { |
avilei | 3:4c71d3475814 | 152 | *EN[i] = (tab[currentSector][i] == ST_BLDC_OFF) ? 0 : 1; |
avilei | 3:4c71d3475814 | 153 | *IN[i] = (tab[currentSector][i] == ST_BLDC_HIGH) ? d : 0; |
avilei | 3:4c71d3475814 | 154 | } |
avilei | 2:4ae769d0b112 | 155 | } |