最近在做一个逆变器项目,主控使用GD32E203,这是其中的SPWM生成正弦波的代码。
Timer2普通定时器配置
void Timer2_Config(void) // 50HZ SPWM
{
/* -----------------------------------------------------------------------
TIMER2 configuration: generate 3 PWM signals with 3 different duty cycles:
TIMER2CLK = SystemCoreClock / 72 = 1MHz, the PWM frequency is 62.5Hz.
----------------------------------------------------------------------- */
Timer2_GPIO_Init();
timer_oc_parameter_struct timer_ocinitpara;
timer_parameter_struct timer_initpara;
/* enable the TIMER clock */
rcu_periph_clock_enable(RCU_TIMER2);
/* deinit a TIMER */
timer_deinit(TIMER2);
/* initialize TIMER init parameter struct */
timer_struct_para_init(&timer_initpara);
/* TIMER2 configuration */
// timer_initpara.prescaler = 719; // 1KHZ prescaler = 719; period = 99;
timer_initpara.prescaler = 719; // 2KHZ prescaler = 359; period = 99;
timer_initpara.period = 99;
timer_initpara.alignedmode = TIMER_COUNTER_EDGE;
timer_initpara.counterdirection = TIMER_COUNTER_UP;
timer_initpara.clockdivision = TIMER_CKDIV_DIV1;
timer_initpara.repetitioncounter = 0;
timer_init(TIMER2, &timer_initpara);
/* initialize TIMER channel output parameter struct */
timer_channel_output_struct_para_init(&timer_ocinitpara);
/* configure TIMER channel output function */
timer_ocinitpara.outputstate = TIMER_CCX_ENABLE;
timer_ocinitpara.outputnstate = TIMER_CCXN_DISABLE;
timer_ocinitpara.ocpolarity = TIMER_OC_POLARITY_HIGH;
timer_ocinitpara.ocnpolarity = TIMER_OCN_POLARITY_HIGH;
timer_ocinitpara.ocidlestate = TIMER_OC_IDLE_STATE_LOW;
timer_ocinitpara.ocnidlestate = TIMER_OCN_IDLE_STATE_LOW;
timer_channel_output_config(TIMER2, TIMER_CH_0, &timer_ocinitpara);
timer_channel_output_config(TIMER2, TIMER_CH_1, &timer_ocinitpara);
// PB5 TIMER2_CH1,
timer_channel_output_pulse_value_config(TIMER2, TIMER_CH_1, 100);
timer_channel_output_mode_config(TIMER2, TIMER_CH_1, TIMER_OC_MODE_PWM0);
timer_channel_output_shadow_config(TIMER2, TIMER_CH_1, TIMER_OC_SHADOW_DISABLE);
// PB4 TIMER2_CH0,
timer_channel_output_pulse_value_config(TIMER2, TIMER_CH_0, 100);
timer_channel_output_mode_config(TIMER2, TIMER_CH_0, TIMER_OC_MODE_PWM0);
timer_channel_output_shadow_config(TIMER2, TIMER_CH_0, TIMER_OC_SHADOW_DISABLE);
/* auto-reload preload enable */
timer_auto_reload_shadow_enable(TIMER2);
// //启用定时器中断
timer_interrupt_flag_clear(TIMER2, TIMER_INT_FLAG_UP);
timer_interrupt_enable(TIMER2, TIMER_INT_UP);
/* TIMER2 counter enable */
timer_enable(TIMER2);
}
TImer2中断配置,主要是中断更新改变pwm占空比。
extern int8_t Nub;
extern int8_t Tim14_Ratio_CH0;
extern int8_t Tim14_Ratio_CH1;
int16_t spwm = 0;
uint64_t SPWM_Nub0[40] = { // 10个占空比
// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100,
100, 97, 92, 84, 74, 61, 48, 32, 28, 0, 0, 28, 32, 48, 61, 74, 84, 92, 97, 100};
uint64_t SPWM_Nub1[40] = { // 10个占空比
// 97, 86, 64, 34, 18, 18, 34, 64, 86, 97,
// 18, 34, 64, 86, 97, 97, 86, 64, 34, 18,
100, 97, 92, 84, 74, 61, 48, 32, 28, 0, 0, 28, 32, 48, 61, 74, 84, 92, 97, 100,
100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100};
// 中断服务函数
void TIMER2_IRQHandler(void)
{
if (SET == timer_interrupt_flag_get(TIMER2, TIMER_INT_FLAG_UP))
{
/* clear update interrupt bit */
timer_interrupt_flag_clear(TIMER2, TIMER_INT_FLAG_UP); // 清除更新中断位
if (spwm >= 0 && spwm < 40)
{
timer_channel_output_pulse_value_config(TIMER2, TIMER_CH_0, SPWM_Nub0[spwm]);
timer_channel_output_pulse_value_config(TIMER2, TIMER_CH_1, SPWM_Nub1[spwm]);
if (spwm >= 0 && spwm < 20)
{
timer_channel_output_pulse_value_config(TIMER14, TIMER_CH_0, 0); // 配置占空比
timer_channel_output_pulse_value_config(TIMER14, TIMER_CH_1, Tim14_Ratio_CH1);
}
else if (spwm >= 20 && spwm < 40)
{
timer_channel_output_pulse_value_config(TIMER14, TIMER_CH_0, Tim14_Ratio_CH0); // 配置占空比
timer_channel_output_pulse_value_config(TIMER14, TIMER_CH_1, 100);
}
++spwm;
}
else
{
spwm = 0;
}
}
}
使用python计算正弦波对应的pwm值
# coding=utf-8
import matplotlib.pyplot as plt
import numpy as np
import math
# 修改本变量可以更改点数
POINT_NUM = 20 #100个数
# 正弦函数放大倍数
MULTIPLE = 100 #占空比最大为99
# 正弦函数X取值范围
X_VALUE = math.pi
# POINT_NUM 个点
n = np.linspace(0, X_VALUE, POINT_NUM)
# 计算POINT_NUM个点的正弦值
a = map(math.sin, n)
r = []
d=0
for i in a:
temp = round(i*MULTIPLE)
# 得到序列
r.append(temp)
print(temp, end=",")
if (d + 1) % 20 == 0:
print("\n")
d+=1
#print(list(map(int, r)))
# 写入序列到文件
# with open("py_pwm_sinWave.c", 'w', encoding='gb2312') as f:
# print(list(map(int, r)), file=f)
# 绘图
plt.plot(n, r, "-o")
plt.show()