stm32 产生 spwm 波
通过 stm32 可以输出 3 对互补 spwm 波,以一对互补 spwm 波为例,另外还可以通过 Keil 自带的 logic
analyzer 查看 PORTA、B 的波形,很直观的仿真结果,可以帮助调试!
产生 2 路互补 spwm 波,管脚为 PA8 和 PB13,GPIO 初始化函数如下:
SPWM 产生原理是规则采样法:ton = Tc*(1 + m*sin(w*ti))/2,通过 PC 计算出来,供单片机以
后查找表,缺点是波形有点失真;
void PWM_GOIO_INIT(void)
{
GPIO_InitTypeDef GPIO_InitStructure;/*允许总线 CLOCK,在使用 GPIO 之前必须允许相应端的时钟.
从 STM32 的设计角度上说,没被允许的端将不接入时钟,也就不会耗能,
这是 STM32 节能的一种技巧,*/
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
/* PA8 9 10 TIM1 PWM 输出端口*/
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //50M 时钟速度
GPIO_Init(GPIOA, &GPIO_InitStructure);
/* PB13 14 15 是 TIM1_PWM 波的互补输出*/
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;//GPIO_Mode_Out_OD; /必须选择
GPIO_Mode_AF_PP,AF_PPAF_OD 仿真无
/ //波形,可能实际
需要上拉吧!AF 代表复用的意思
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //50M 时钟速度
GPIO_Init(GPIOB, &GPIO_InitStructure);
}
高级定时器 TIM1 设置如下:
void TIM_Configuration(void)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
/* TIM1 clock enable */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);
TIM_TimeBaseStructure.TIM_Period = 3600; //最大 65535 //
TIM_TimeBaseStructure.TIM_Prescaler = 1; //36M72M 经过 3 分频
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);/* Channel 1 Configuration in PWM mode */
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //PWM 模式 2
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //正向通道有效
TIM_OCInitStructure.TIM_OutputNState =
TIM_OutputNState_Enable;//TIM_OutputNState_Disable;//反向通道无效
TIM_OCInitStructure.TIM_Pulse = 20000;//CCR1_Val; //占空时间
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //输出极性
TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High; //互补端的极性,如果为 Low,则
PA8 PB13 两路输出一致
TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set;
TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Reset;
TIM_OC1Init(TIM1,&TIM_OCInitStructure); //通道 1
TIM_OC1PreloadConfig(TIM1, TIM_OCPreload_Enable);//Disable ????
/* TIM1 counter enable */
TIM_Cmd(TIM1,ENABLE);
/* TIM2 Main Output Enable */
TIM_CtrlPWMOutputs(TIM1,ENABLE);/* TIM IT enable */
TIM_ITConfig(TIM1, TIM_IT_Update, ENABLE);
}
//定时器中断函数
void TIM1_UP_IRQHandler(void)
{
static int i = 0;
CCR1_Val = 1800 + m * tab[i];//确定为正数
TIM_SetCompare1(TIM1, CCR1_Val);
TIM_ClearITPendingBit(TIM1, TIM_IT_Update);
i++;
if(i == 200)
i = 0;
}
volatile float m = 0.8;//调制波幅值
volatile uint16_t CCR1_Val = 0;
const int16_t tab[] = { //sin 值表扩大 1800 倍
28,84,141,197,253,309,365,420,474,529,
583,636,688,740,791,842,891,940,988,1035,
1080,1125,1169,1211,1252,1292,1331,1368,1404,1439,
1472,1504,1534,1563,1590,1616,1640,1662,1683,1702,
1720,1736,1750,1762,1773,1782,1789,1794,1798,1799,
1799,1798,1794,1789,1782,1773,1762,1750,1736,1720,
1702,1683,1662,1640,1616,1590,1563,1534,1504,1472,
1439,1404,1368,1331,1292,1252,1211,1169,1125,1080,
1035,988,940,891,842,791,740,688,636,583,
529,474,420,365,309,253,197,141,84,28,
-29,-85,-142,-198,-254,-310,-366,-421,-475,-530,
-584,-637,-689,-741,-792,-843,-892,-941,-989,-1036,
-1081,-1126,-1170,-1212,-1253,-1293,-1332,-1369,-1405,-1440,
-1473,-1505,-1535,-1564,-1591,-1617,-1641,-1663,-1684,-1703,
-1721,-1737,-1751,-1763,-1774,-1783,-1790,-1795,-1799,-1800,
-1800,-1799,-1795,-1790,-1783,-1774,-1763,-1751,-1737,-1721,
-1703,-1684,-1663,-1641,-1617,-1591,-1564,-1535,-1505,-1473,
-1440,-1405,-1369,-1332,-1293,-1253,-1212,-1170,-1126,-1081,
-1036,-989,-941,-892,-843,-792,-741,-689,-637,-584,
-530,-475,-421,-366,-310,-254,-198,-142,-85,-29,
};
Void main(void)
{
RCC_Configuration();
PWM_IO_INIT();
TIM_Configuration();
NVIC_Configuration();
USART_Configuration();
While(1)
{
}
}
以下是仿真结果: