硬件电路
TIMER1的输入捕获/输出比较端口配置成推挽复用功能。
MCU电路
波形转换电路
变量声明及定义
//中断优先级定义
#define TIM1_IT_PI 2
//TIMER1相关
extern u16 Phase_CNT; //输出波形相位
//PWM有关
#define PWM_PERIOD (72000/(PWM_FREQ/1000)) //4000
#define PWM_FREQ 18000 //PWM频率18000Hz
//起始相位=0度
//信号周期=360uS
//PWM周期=1uS
//脉冲个数=360
extern unsigned short tb_sine_360[]={
0,69,139,209,279,348,418,487,556,625,694,763,831,899,967,1035,
1102,1169,1236,1302,1368,1433,1498,1562,1626,1690,1753,1815,1877,1939,1999,2060,
2119,2178,2236,2294,2351,2407,2462,2517,2571,2624,2676,2727,2778,2828,2877,2925,
2972,3018,3064,3108,3152,3194,3236,3276,3316,3354,3392,3428,3464,3498,3531,3564,
3595,3625,3654,3682,3708,3734,3758,3782,3804,3825,3845,3863,3881,3897,3912,3926,
3939,3950,3961,3970,3978,3984,3990,3994,3997,3999,4000,3999,3997,3994,3990,3984,
3978,3970,3961,3950,3939,3926,3912,3897,3881,3863,3845,3825,3804,3782,3758,3734,
3708,3682,3654,3625,3595,3564,3531,3498,3464,3428,3392,3354,3316,3276,3236,3194,
3152,3108,3064,3018,2972,2925,2877,2828,2778,2727,2676,2624,2571,2517,2462,2407,
2351,2294,2236,2178,2119,2060,1999,1939,1877,1815,1753,1690,1626,1562,1498,1433,
1368,1302,1236,1169,1102,1035,967,899,831,763,694,625,556,487,418,348,
279,209,139,69,
0,69,139,209,279,348,418,487,556,625,694,763,831,899,967,1035,
1102,1169,1236,1302,1368,1433,1498,1562,1626,1690,1753,1815,1877,1939,1999,2060,
2119,2178,2236,2294,2351,2407,2462,2517,2571,2624,2676,2727,2778,2828,2877,2925,
2972,3018,3064,3108,3152,3194,3236,3276,3316,3354,3392,3428,3464,3498,3531,3564,
3595,3625,3654,3682,3708,3734,3758,3782,3804,3825,3845,3863,3881,3897,3912,3926,
3939,3950,3961,3970,3978,3984,3990,3994,3997,3999,4000,3999,3997,3994,3990,3984,
3978,3970,3961,3950,3939,3926,3912,3897,3881,3863,3845,3825,3804,3782,3758,3734,
3708,3682,3654,3625,3595,3564,3531,3498,3464,3428,3392,3354,3316,3276,3236,3194,
3152,3108,3064,3018,2972,2925,2877,2828,2778,2727,2676,2624,2571,2517,2462,2407,
2351,2294,2236,2178,2119,2060,1999,1939,1877,1815,1753,1690,1626,1562,1498,1433,
1368,1302,1236,1169,1102,1035,967,899,831,763,694,625,556,487,418,348,
279,209,139,69,
0,69,139,209,279,348,418,487,556,625,694,763,831,899,967,1035,
1102,1169,1236,1302,1368,1433,1498,1562,1626,1690,1753,1815,1877,1939,1999,2060,
2119,2178,2236,2294,2351,2407,2462,2517,2571,2624,2676,2727,2778,2828,2877,2925,
2972,3018,3064,3108,3152,3194,3236,3276,3316,3354,3392,3428,3464,3498,3531,3564,
3595,3625,3654,3682,3708,3734,3758,3782,3804,3825,3845,3863,3881,3897,3912,3926,
3939,3950,3961,3970,3978,3984,3990,3994,3997,3999,4000,3999,3997,3994,3990,3984,
3978,3970,3961,3950,3939,3926,3912,3897,3881,3863,3845,3825,3804,3782,3758,3734,
3708,3682,3654,3625,3595,3564,3531,3498,3464,3428,3392,3354,3316,3276,3236,3194,
3152,3108,3064,3018,2972,2925,2877,2828,2778,2727,2676,2624,2571,2517,2462,2407,
2351,2294,2236,2178,2119,2060,1999,1939,1877,1815,1753,1690,1626,1562,1498,1433,
1368,1302,1236,1169,1102,1035,967,899,831,763,694,625,556,487,418,348,
279,209,139,69,
0,69,139,209,279,348,418,487,556,625,694,763,831,899,967,1035,
1102,1169,1236,1302,1368,1433,1498,1562,1626,1690,1753,1815,1877,1939,1999,2060,
2119,2178,2236,2294,2351,2407,2462,2517,2571,2624,2676,2727,2778,2828,2877,2925,
2972,3018,3064,3108,3152,3194,3236,3276,3316,3354,3392,3428,3464,3498,3531,3564,
3595,3625,3654,3682,3708,3734,3758,3782,3804,3825,3845,3863,3881,3897,3912,3926,
3939,3950,3961,3970,3978,3984,3990,3994,3997,3999,4000,3999,3997,3994,3990,3984,
3978,3970,3961,3950,3939,3926,3912,3897,3881,3863,3845,3825,3804,3782,3758,3734,
3708,3682,3654,3625,3595,3564,3531,3498,3464,3428,3392,3354,3316,3276,3236,3194,
3152,3108,3064,3018,2972,2925,2877,2828,2778,2727,2676,2624,2571,2517,2462,2407,
2351,2294,2236,2178,2119,2060,1999,1939,1877,1815,1753,1690,1626,1562,1498,1433,
1368,1302,1236,1169,1102,1035,967,899,831,763,694,625,556,487,418,348,
279,209,139,69};
TIMER1的配置
void TIMER1_Configuration(void)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; //定时器基本结构体
TIM_OCInitTypeDef TIM_OCInitStructure; //输出比较结构体
NVIC_InitTypeDef NVIC_InitStructure; //定义中断配置结构体
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE); //TIM1时钟使能
//定时器时基配置
TIM_TimeBaseStructure.TIM_Prescaler = 0; //不进行预分频
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //递增计数
TIM_TimeBaseStructure.TIM_Period = (PWM_PERIOD-1); //计数周期
TIM_TimeBaseStructure.TIM_ClockDivision = 0; //设置Tdts
TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;
TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);
//输出比较结构体配置
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //比较值越大输出越大
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //输出使能
TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Disable; //输出反相不使能
TIM_OCInitStructure.TIM_Pulse = 0; //初次比较值
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low; //输出极性
TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_Low; //输出极性
TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set; //刹车后呈高电平
TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCNIdleState_Set;//刹车后呈高电平
TIM_OC1Init(TIM1, &TIM_OCInitStructure); //PWM输出
TIM_OC2Init(TIM1, &TIM_OCInitStructure); //PWM输出
TIM_OC3Init(TIM1, &TIM_OCInitStructure); //PWM输出
TIM_OC4Init(TIM1, &TIM_OCInitStructure); //PWM输出
//开启自动重装功能
TIM_OC1PreloadConfig(TIM1, TIM_OCPreload_Enable); //自动重装功能 关闭直接写入OC1寄存器。开启的话要溢出后写入
TIM_OC2PreloadConfig(TIM1, TIM_OCPreload_Enable); //自动重装功能 关闭直接写入OC2寄存器。开启的话要溢出后写入
TIM_OC3PreloadConfig(TIM1, TIM_OCPreload_Enable); //自动重装功能 关闭直接写入OC2寄存器。开启的话要溢出后写入
TIM_OC4PreloadConfig(TIM1, TIM_OCPreload_Enable); //自动重装功能 关闭直接写入OC2寄存器。开启的话要溢出后写入
//中断允许
TIM_ITConfig(TIM1, TIM_IT_Update, ENABLE); //允许溢出中断
//开启相应的矢量中断使能
NVIC_InitStructure.NVIC_IRQChannel = TIM1_UP_IRQChannel; //TIM1_CC_IRQChannel;//TIM1_TRG_COM_IRQChannel;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = TIM1_IT_PI;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
TIM_Cmd(TIM1, ENABLE); //打开定时器
//TIM1 Main Output Enable
TIM_CtrlPWMOutputs(TIM1, ENABLE);
}
TIMER1溢出中断
void TIM1_UP_IRQHandler(void)
{
u32 i;
if(TIM_GetITStatus(TIM1, TIM_IT_Update) != RESET)
{
TIM_ClearITPendingBit(TIM1, TIM_IT_Update);
i=(u32)tb_sine_360[Phase_CNT]; //查表0-4000
TIM_SetCompare1(TIM1, i); //A相 产生SPWM波形
TIM_SetCompare4(TIM1, i); //N相 产生SPWM波形
i=(u32)tb_sine_360[Phase_CNT+60]; //查表0-4000
TIM_SetCompare2(TIM1, i); //B相 产生SPWM波形
i=(u32)tb_sine_360[Phase_CNT+120]; //查表0-4000
TIM_SetCompare3(TIM1, i); //C相 产生SPWM波形
switch(Phase_CNT) //由于需要双极性的SPWM波,所以把单极性的SPWM波转换成双极性的,并设置A、B、C三相的相位差为120度
{
case 0: //A相、N相反相
B_PS1 = 0;
B_PS4 = 0;
Phase_CNT++;
break;
case 59: //C相反相
B_PS3 = 1;
Phase_CNT++;
break;
case 119: //B相反相
B_PS2 = 0;
Phase_CNT++;
break;
case 179: //A相、N相反相
B_PS1 = 1;
B_PS4 = 1;
Phase_CNT++;
break;
case 239: //C相反相
B_PS3 = 0;
Phase_CNT++;
break;
case 299: //B相反相
B_PS2 = 1;
Phase_CNT++;
break;
default:
Phase_CNT++;
if(Phase_CNT > 360)
{
Phase_CNT = 0;
OSSemPost(Phase_ev); //激活一次相位任务
// 这里是用的是OS系统邮箱,可以利用标志位执行一个周期后要做的事情
}
break;
}
}
}