├── LICENSE ├── README.md ├── svpwm.c └── svpwm.h /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Serhii Yatsenko 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # C-library with implementation of the Space-Vector PWM generation technique 2 | 3 | This embedded C-library for MCUs provides the 3-phase duty cycle generation by Space Vector Pulse Width Modulation (SVPWM) technique. [More about SVPWM technique here](https://www.switchcraft.org/learning/2017/3/15/space-vector-pwm-intro). 4 | 5 | * Project structure 6 | * README.md - current file 7 | * LICENSE - file with license description 8 | * svpwm.h - C-header file with user data types and function prototypes 9 | * svpwm.c - C-source file with firmware functions 10 | 11 | # HowToUse (example) 12 | 13 | // let it the MCU's hardware counter compare registers is: CCR0, CCR1, CCR2 14 | 15 | #include "svpwm.h" 16 | 17 | // updatable voltages in Alpha-Beta coordinates: 18 | float NewAlphaVoltage, NewBetaVoltage; 19 | 20 | // 1st step: create and initialize the global variable of user data structure 21 | tSVPWM sSVPWM = SVPWM_DEFAULTS; 22 | 23 | // 2nd step: do some settings 24 | sSVPWM.enInType = AlBe; // set the input type 25 | sSVPWM.fUdc = 537.0f; // set the DC-Link voltage in Volts 26 | sSVPWM.fUdcCCRval = 255; // set the Max value of counter compare register which equal to DC-Link voltage 27 | 28 | // 3rd step: Next code must be executed every time a new calculation of duty cycles is needed 29 | sSVPWM.fUal = NewAlphaVoltage; // set a new value of voltage Alpha 30 | sSVPWM.fUbe = NewBetaVoltage; // set a new value of voltage Beta 31 | sSVPWM.m_calc(&sSVPWM); // call the SVPWM duty cycles calculation function 32 | CCR0 = sSVPWM.fCCRA; // update the duty cycle value in CCR0 33 | CCR1 = sSVPWM.fCCRB; // update the duty cycle value in CCR1 34 | CCR2 = sSVPWM.fCCRC; // update the duty cycle value in CCR2 35 | 36 | # License 37 | 38 | [MIT](./LICENSE "License Description") 39 | -------------------------------------------------------------------------------- /svpwm.c: -------------------------------------------------------------------------------- 1 | /** 2 | *********************************************************************************** 3 | * @file svpwm.c 4 | * @author Serhii Yatsenko [royalroad1995@gmail.com] 5 | * @version V1.0 6 | * @date May-2020 7 | * @brief This file provides firmware function for implementation the SVPWM - 8 | * Space-Vector Pulse Width Modulation for power electronics application 9 | *********************************************************************************** 10 | * @license 11 | * 12 | * MIT License 13 | * 14 | * Permission is hereby granted, free of charge, to any person obtaining a copy 15 | * of this software and associated documentation files (the "Software"), to deal 16 | * in the Software without restriction, including without limitation the rights 17 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 18 | * copies of the Software, and to permit persons to whom the Software is 19 | * furnished to do so, subject to the following conditions: 20 | * 21 | * The above copyright notice and this permission notice shall be included in all 22 | * copies or substantial portions of the Software. 23 | * 24 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 25 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 26 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 27 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 28 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 29 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 30 | * SOFTWARE. 31 | * 32 | *********************************************************************************** 33 | */ 34 | 35 | /* Includes -----------------------------------------------------------------------*/ 36 | #include "svpwm.h" 37 | 38 | /* Private typedef ----------------------------------------------------------------*/ 39 | /* Private define -----------------------------------------------------------------*/ 40 | #define M_Pi 3.1415926535897f // float type of Pi constant value 41 | #define M_Pi_3 (M_Pi/3.0f) 42 | 43 | /* Private constants --------------------------------------------------------------*/ 44 | 45 | /** 46 | * @brief Matrix with cell indices in a time intervals table for SVPWM duty cycle 47 | * calculation technique 48 | */ 49 | const uint8_t au8PermuataionMatrix[6][3] = 50 | { 51 | { 1, 2, 0 }, 52 | { 3, 1, 0 }, 53 | { 0, 1, 2 }, 54 | { 0, 3, 1 }, 55 | { 2, 0, 1 }, 56 | { 1, 0, 3 } 57 | }; 58 | 59 | /* Private macro ------------------------------------------------------------------*/ 60 | /* Private variables --------------------------------------------------------------*/ 61 | /* Private function prototypes ----------------------------------------------------*/ 62 | /* Private functions --------------------------------------------------------------*/ 63 | 64 | /** 65 | * @brief SVPWM calculation function. This function calculates three values of 66 | * duty cycle to generate a three-phase voltage vector with amplitude - 67 | * ptSVPWM->fUs and angle - ptSVPWM->fAngRad. 68 | * @param ptSVPWM: pointer to user data structure with type "tSVPWM". 69 | * @retval None 70 | */ 71 | void tSVPWM_calc(tSVPWM* ptSVPWM) 72 | { 73 | uint8_t u8Sector; 74 | float fMaxUs, fScaledUs, fBeta, fTb1, fTb2, afTi[4]; 75 | 76 | fMaxUs = ptSVPWM->fUdc * (1.0f/sqrtf(3.0f)); 77 | 78 | switch(ptSVPWM->enInType) 79 | { 80 | case AlBe: 81 | ptSVPWM->fUs = hypotf(ptSVPWM->fUbe, ptSVPWM->fUal); 82 | ptSVPWM->fAngRad = atan2f(ptSVPWM->fUbe, ptSVPWM->fUal); 83 | break; 84 | 85 | case UsAng: 86 | ptSVPWM->fUs = fabsf(ptSVPWM->fUs); 87 | break; 88 | 89 | default: return; 90 | } 91 | 92 | if(ptSVPWM->fUs > fMaxUs) ptSVPWM->fUs = fMaxUs; 93 | 94 | fScaledUs = ptSVPWM->fUs/fMaxUs; 95 | 96 | ptSVPWM->fAngRad += M_Pi; 97 | 98 | u8Sector = (uint8_t)(ptSVPWM->fAngRad * (1.0f/M_Pi_3)); 99 | 100 | fBeta = ptSVPWM->fAngRad - M_Pi_3 * u8Sector; 101 | 102 | fTb1 = fScaledUs * sinf(M_Pi_3 - fBeta); 103 | fTb2 = fScaledUs * sinf(fBeta); 104 | 105 | afTi[0] = (1.0f - fTb1 - fTb2)*0.5f; 106 | afTi[1] = fTb1 + fTb2 + afTi[0]; 107 | afTi[2] = fTb2 + afTi[0]; 108 | afTi[3] = fTb1 + afTi[0]; 109 | 110 | ptSVPWM->fCCRA = ptSVPWM->fUdcCCRval * afTi[au8PermuataionMatrix[u8Sector][0]]; 111 | ptSVPWM->fCCRB = ptSVPWM->fUdcCCRval * afTi[au8PermuataionMatrix[u8Sector][1]]; 112 | ptSVPWM->fCCRC = ptSVPWM->fUdcCCRval * afTi[au8PermuataionMatrix[u8Sector][2]]; 113 | } 114 | 115 | /*********************************** END OF FILE ***********************************/ 116 | -------------------------------------------------------------------------------- /svpwm.h: -------------------------------------------------------------------------------- 1 | /** 2 | *********************************************************************************** 3 | * @file svpwm.h 4 | * @author Serhii Yatsenko [royalroad1995@gmail.com] 5 | * @version V1.0 6 | * @date May-2020 7 | * @brief This file contains the type definition of data structure and function 8 | * prototypes for implementation the SVPWM - Space-Vector Pulse Width 9 | * Modulation 10 | *********************************************************************************** 11 | * @license 12 | * 13 | * MIT License 14 | * 15 | * Permission is hereby granted, free of charge, to any person obtaining a copy 16 | * of this software and associated documentation files (the "Software"), to deal 17 | * in the Software without restriction, including without limitation the rights 18 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 19 | * copies of the Software, and to permit persons to whom the Software is 20 | * furnished to do so, subject to the following conditions: 21 | * 22 | * The above copyright notice and this permission notice shall be included in all 23 | * copies or substantial portions of the Software. 24 | * 25 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 26 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 27 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 28 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 29 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 30 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 31 | * SOFTWARE. 32 | * 33 | *********************************************************************************** 34 | */ 35 | 36 | /* Define to prevent recursive inclusion ------------------------------------------*/ 37 | #ifndef __SVPWM_H__ 38 | #define __SVPWM_H__ 39 | 40 | #ifdef __cplusplus 41 | extern "C" { 42 | #endif 43 | 44 | /* Includes -----------------------------------------------------------------------*/ 45 | #include 46 | #include 47 | 48 | /* Exported types -----------------------------------------------------------------*/ 49 | 50 | /** 51 | * @brief SVPWM module data input type 52 | */ 53 | typedef enum 54 | { 55 | AlBe = 0x00U, // Alpha-Beta component input 56 | UsAng = 0x01U // Magnitude-Angle component input 57 | } tInType; 58 | 59 | /** 60 | * @brief "SVPWM Module" data structure 61 | */ 62 | typedef struct sSVPWM 63 | { 64 | // Inputs: 65 | tInType enInType; // SVPWM module data input type 66 | float fUdc; // DC Link voltage, Volts 67 | float fUdcCCRval; // Counter compare register value which is 68 | // equivalent to full DC Link voltage 69 | // enInType == AlBe: 70 | float fUal; // Alpha input, Volts 71 | float fUbe; // Beta input, Volts 72 | // enInType == UsAng: 73 | float fUs; // Magnitude input, Volts (enInType == UsAng) 74 | float fAngRad; // Angle input, Rad (enInType == UsAng) 75 | // Outputs: 76 | float fCCRA; // Counter compare register A value 77 | float fCCRB; // Counter compare register B value 78 | float fCCRC; // Counter compare register C value 79 | // Functions: 80 | void (*m_calc)(struct sSVPWM*); // Pointer to SVPWM calculation function 81 | } tSVPWM; 82 | 83 | /* Exported constants -------------------------------------------------------------*/ 84 | 85 | /** 86 | * @brief Initialization constant with defaults for user variables 87 | * with "tSVPWM" type 88 | */ 89 | #define SVPWM_DEFAULTS { \ 90 | .enInType = AlBe, \ 91 | .fUal = 0.0f, \ 92 | .fUbe = 0.0f, \ 93 | .fUs = 0.0f, \ 94 | .fAngRad = 0.0f, \ 95 | .fUdc = 0.0f, \ 96 | .fUdcCCRval = 0.0f, \ 97 | .fCCRA = 0.0f, \ 98 | .fCCRB = 0.0f, \ 99 | .fCCRC = 0.0f, \ 100 | .m_calc = tSVPWM_calc \ 101 | } 102 | 103 | /* Exported macro -----------------------------------------------------------------*/ 104 | /* Exported functions -------------------------------------------------------------*/ 105 | 106 | /* SVPWM Duty Cycles calculation function prototype ********************************/ 107 | void tSVPWM_calc(tSVPWM*); 108 | 109 | #ifdef __cplusplus 110 | } 111 | #endif 112 | 113 | #endif /* __SVPWM_H__ */ 114 | 115 | /*********************************** END OF FILE ***********************************/ 116 | --------------------------------------------------------------------------------