基于CORDIC的三相SPWM
时间: 2023-05-24 09:06:58 浏览: 171
基本原理:
正弦波PWM技术(SPWM)是一种广泛应用于电力电子变频技术中的一种调制技术。 通过使用高速逻辑器件和高精度数字信号处理器,相位准确性高且死区时间小,从而使输出电压具有更高的精度和更好的波形质量。
CORDIC(坐标旋转数字计算器)是一种常见的数字信号处理算法,用于计算极坐标到直角坐标的旋转所需的参数,并可以快速计算三角函数。在这里,我们使用CORDIC实现三相SPWM。
实现步骤:
1.对于三相SPWM,需要计算出每个相位的正弦值。因此,我们需要使用CORDIC算法计算每个角度的正弦值。C语言代码示例如下:
```
double cordic_sin(double angle){
int i;
double val = angle;
double temp, sin_val=0;
for (i = 0; i < ITER; i++){
if (val < 0)
temp = y[i+ITER] + x[i+ITER];
else
temp = y[i] - x[i];
if (val < 0)
val += atan[i+ITER];
else
val -= atan[i];
sin_val += temp;
}
return sin_val;
}
```
2. 然后,我们需要确定每个角度对应的占空比,即每个正弦值的比率可以提供SPWM。采用固定占空比所需的角度按以下公式计算:
```
duty_cycle = ((cordic_sin(angle) + 1) / 2) * 255;
```
3.一旦确定了每个角度的占空比,我们就可以将其分配给单个PWM周期中的对应时间段。三相SPWM具有6个PWM周期,其中每个周期包含一个半周期(即扫描角度从0到180度的角度范围)。每个半周期中,每个电流的PWM输出被分配到以下四个时间:
| 时间 | A相(U) | B相(V) | C相(W) |
| --- | --- | --- | --- |
| 1 | ON | OFF | OFF |
| 2 | ON | ON | OFF |
| 3 | OFF | ON | OFF |
| 4 | OFF | ON | ON |
| 5 | OFF | OFF | ON |
| 6 | ON | OFF | ON |
三相SPWM的C语言代码示例如下:
```
void SPWM_output(double ang){
uint8_t duty_cycle_A, duty_cycle_B, duty_cycle_C;
// 计算角度的正弦值并确定占空比
duty_cycle_A = ((cordic_sin(ang) + 1) / 2) * 255;
duty_cycle_B = ((cordic_sin(ang + 120) + 1) / 2) * 255;
duty_cycle_C = ((cordic_sin(ang + 240) + 1) / 2) * 255;
// 根据占空比设置PWM输出
if(duty_cycle_A > PWM_PERIOD){
duty_cycle_A = PWM_PERIOD;
}
if(duty_cycle_B > PWM_PERIOD){
duty_cycle_B = PWM_PERIOD;
}
if(duty_cycle_C > PWM_PERIOD){
duty_cycle_C = PWM_PERIOD;
}
if(duty_cycle_A == 0){
PWM_High = 0;
}
else if(duty_cycle_A == PWM_PERIOD){
PWM_High = PWM_PERIOD;
}
else{
PWM_High = duty_cycle_A;
}
if(duty_cycle_B == 0){
PWM_Middle = 0;
}
else if(duty_cycle_B == PWM_PERIOD){
PWM_Middle = PWM_PERIOD;
}
else{
PWM_Middle = duty_cycle_B;
}
if(duty_cycle_C == 0){
PWM_Low = 0;
}
else if(duty_cycle_C == PWM_PERIOD){
PWM_Low = PWM_PERIOD;
}
else{
PWM_Low = duty_cycle_C;
}
//在预定时间输出PWM
HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_1);
HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_3);
HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_2);
HAL_Delay(5);
HAL_TIM_PWM_Stop(&htim2, TIM_CHANNEL_1);
HAL_TIM_PWM_Stop(&htim3, TIM_CHANNEL_3);
HAL_TIM_PWM_Stop(&htim3, TIM_CHANNEL_2);
return;
}
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim){
if(htim->Instance == TIM4){
// 基准时钟(1ms)
tick++;
if(tick == 5){
SPWM_output(angle);
angle += deg2rad(1);
if(angle >= PI){
angle -= 2*PI;
}
tick = 0;
}
}
}
```
阅读全文