CQ_KIT_Ver1_5
Dependencies: mbed RateLimiter BLDCmotorDriverCQ_KIT_Ver1_5
Diff: X_NUCLEO_IHM07M1/SPN7Driver.cpp
- Revision:
- 3:4c71d3475814
- Parent:
- 2:4ae769d0b112
- Child:
- 4:3f63eed73ad1
diff -r 4ae769d0b112 -r 4c71d3475814 X_NUCLEO_IHM07M1/SPN7Driver.cpp --- a/X_NUCLEO_IHM07M1/SPN7Driver.cpp Wed Oct 12 13:15:03 2016 +0000 +++ b/X_NUCLEO_IHM07M1/SPN7Driver.cpp Thu Oct 13 15:48:50 2016 +0000 @@ -35,6 +35,12 @@ #include "mbed.h" #include "SPN7Driver.h" +typedef enum { + ST_BLDC_LOW = 0, + ST_BLDC_HIGH, + ST_BLDC_OFF +} st_bldc_status_t; + // FIXME: add doxygen SPN7Driver::SPN7Driver(PinName pIN1, PinName pIN2, PinName pIN3, @@ -48,16 +54,14 @@ { // The BLDCmotorDriver class was implemented for half-bridge drivers // so the pin names may be misleading when referring to the L6230 chip. - // Get a reference of each input pin and call them INx (logic input) + // 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& IN1 = GH_A; - PwmOut& IN2 = GH_B; - PwmOut& IN3 = GH_C; - + PwmOut* IN[3] = {&GH_A, &GH_B, &GH_C}; + // Set the switching period of the INx logic input pins (PWM driven) - IN1.period(switchingPeriod); - IN2.period(switchingPeriod); - IN3.period(switchingPeriod); + 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); @@ -69,114 +73,61 @@ } // 6-step phase commutation -// -// Positive dutycycle: +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}; + // 1--X--0--0--X--1 // X--1--1--X--0--0 -// 0--0--X--1--1--X -// -// Negative dutycycle: -// 1--1--X--0--0--X -// 0--X--1--1--X--0 -// X--0--0--X--1--1 -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 a reference of each input pin and call them INx (logic input) - // to be consistent with the terminology used in the L6230 documentation. - PwmOut& IN1 = GH_A; - PwmOut& IN2 = GH_B; - PwmOut& IN3 = GH_C; - // Get a reference of each enable pin and call them ENx (enable channel) - // to be consistent with the terminology used in the L6230 documentation. - DigitalOut& EN1 = GL_A; - DigitalOut& EN2 = GL_B; - DigitalOut& EN3 = GL_C; +// 0--0--X--1--1--X + st_bldc_status_t tab[6][3] = { + {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}, + {ST_BLDC_OFF, ST_BLDC_LOW, ST_BLDC_HIGH}, + {ST_BLDC_HIGH, ST_BLDC_LOW, ST_BLDC_OFF}, + }; dutyCycle = rl.out(tempDutyCycle); currentSector = getSector(); - if (dutyCycle > 0 ) { - // Positive dutycycle - currentSector++; - - if(currentSector > 5) currentSector = 0; - - switch(currentSector) { - case 0: - EN1 = 1; IN1 = dutyCycle; - EN2 = 0; IN2 = 0; - EN3 = 1; IN3 = 0; - break; - case 1: - EN1 = 0; IN1= 0; - EN2 = 1; IN2 = dutyCycle; - EN3 = 1; IN3 = 0; - break; - case 2: - EN1 = 1; IN1 = 0; - EN2 = 1; IN2 = dutyCycle; - EN3 = 0; IN3 = 0; - break; - case 3: - EN1 = 1; IN1 = 0; - EN2 = 0; IN2 = 0; - EN3 = 1; IN3 = dutyCycle; - break; - case 4: - EN1 = 0; IN1 = 0; - EN2 = 1; IN2 = 0; - EN3 = 1; IN3 = dutyCycle; - break; - case 5: - EN1 = 1; IN1 = dutyCycle; - EN2 = 1; IN2 = 0; - EN3 = 0; IN3 = 0; - break; - } - } else if (dutyCycle < 0) { - // Negative dutycycle - currentSector--; - - if(currentSector < 0) currentSector = 5; - - switch(currentSector) { - case 0: - EN1 = 1; IN1 = 0; - EN2 = 0; IN2=0; - EN3 = 1; IN3 = -dutyCycle; - break; - case 1: - EN1 = 0; IN1=0; - EN2 = 1; IN2 = 0; - EN3 = 1; IN3 = -dutyCycle; - break; - case 2: - EN1 = 1; IN1 = -dutyCycle; - EN2 = 1; IN2 = 0; - EN3 = 0; IN3= 0; - break; - case 3: - EN1 = 1; IN1 = -dutyCycle; - EN2 = 0; IN2 = 0; - EN3 = 1; IN3 = 0; - break; - case 4: - EN1 = 0; IN1= 0; - EN2 = 1; IN2 = -dutyCycle; - EN3 = 1; IN3 = 0; - break; - case 5: - EN1 = 1; IN1 = 0; - EN2 = 1; IN2 = -dutyCycle; - EN3 = 0; IN3=0; - break; - } - - } else { + if (dutyCycle == 0) { + // Stop the motor coast(); + return; } + // Move to next sector (i.e. commute phase) + if (dutyCycle > 0 ) { + // Move forward + currentSector++; + if(currentSector > 5) currentSector = 0; + } else { + // Move backward + currentSector--; + if(currentSector < 0) currentSector = 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 + //printf("Commutation sector %d\n\r", currentSector); + for (int i = 0; i < 3; i++) { + *EN[i] = (tab[currentSector][i] == ST_BLDC_OFF) ? 0 : 1; + *IN[i] = (tab[currentSector][i] == ST_BLDC_HIGH) ? d : 0; +/* + int ena = (tab[currentSector][i] == ST_BLDC_OFF) ? 0 : 1; + float inp = (tab[currentSector][i] == ST_BLDC_HIGH) ? d : 0; + printf("EN[%d] = %d, IN[%d] = %f\n\r", i, ena, i, inp); +*/ + } }