要想输出异相方波,就得先明白翻转的方式进行输出PWM波的方式是什么。Toggle(翻转)输出pwm的原理是:在计数器的计数值到TIMx->CCR1、2、3、4
时,对应的引脚的电平信号会翻转一次,下次计数器的值为TIMx->CCR1、2、3、4
时,对应的引脚会在翻转一次,如此下去,就会输出一个方波,且占空比是50%。
那么异相方波是什么:这里的异相不能是一个引脚输出的pwm波,必须要有两个方波来进行比价才有异相的说法;现在定时器3的通道1 输出一个方波,产生一个中断,那么在这个时候增加通道2的比较值,那么就会相对前一次产生的方波往后延迟,就不是同时发生,有一定的相位差;
这样写出现的波形的确是异相方波,但是在两个波形相位相差大于等于180°时,就会出现频率不一样,正在解决中、、、、、、
相位小于 180°
相位等于 180°
keil 4仿真图形
(2018/1/21)错误已解决,错误原因:直接在中断里设置得注意计数问题,我在OC1中断时改变了OC2的计数值,假设OC1 的翻转值是CCR1_Val + 500,那么在中断发生时马上改变OC2的计数值,
capture = TIM_GetCapture1(TIM3);//获取比较值
TIM_SetCompare1(TIM3, capture + CCR1_Val);//间隔CCR1_Val翻转一次
TIM_SetCompare2(TIM3,capture+200);//增加通道2 的比较值,比通道1的方波延缓200次计数
if (TIM_GetITStatus(TIM3, TIM_IT_CC2) != RESET)
{
TIM_ClearITPendingBit(TIM3, TIM_IT_CC2);
capture = TIM_GetCapture2(TIM3);
TIM_SetCompare2(TIM3, capture + CCR2_Val);//同时间隔CCR2_Val翻转一次电平
//CCR2_Val = CCR1_Val两个方波的频率相同
}
这样做的话,那么当capture+200
为capture+600
后,就会出现OC2的永远达不到计数值,一直不会翻转,这就会出现下面的图形:
相位大于 180°
下面是程序,通过固件库PWM_Toggle更改而成
这个程序的思想在中断服务函数里面,以及Toggle模式输出PWM波形
修改:
- 主函数调用初始化
- 滴答定时器定时更改相位(框架)
- 如下:
int main(void)
{
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
SysTick_Config(SystemCoreClock / 1000);
STM3210B_LCD_Init();
LED_Init();
PWM_Init();
LCD_Clear(White);
LCD_SetTextColor(Red);
LCD_SetBackColor(White);
LED_Control(LED0,1);
while(1)
{
// TIM_DeInit(TIM3);
if(flag==1)
{
flag = 0;
PWM_Init();//对于这道例程完全没必要更改,因为相位一直没有变化,这个只是个框架,在这之前更改相位就好
}
}
}
u16 TimingDelay;
u8 flag;
void SysTick_Handler(void)
{
static u8 num0 = 0;
TimingDelay--;
if(++num0==200)//200ms
{
num0 = 0;
flag = 1;
}
}
#include "pwm.h"
uint16_t CCR1_Val = 500;//
uint16_t CCR2_Val = 500;
u16 capture = 0;
void PWM_Init(void)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_AFIO, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
TIM_DeInit(TIM3);
TIM_TimeBaseStructure.TIM_Period = 65535;
TIM_TimeBaseStructure.TIM_Prescaler = 72;
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
/* Output Compare Toggle Mode configuration: Channel1 */
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_Toggle;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse = CCR1_Val;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low;
TIM_OC1Init(TIM3, &TIM_OCInitStructure);
TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Disable);
/* Output Compare Toggle Mode configuration: Channel2 */
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse =CCR2_Val + 600;//更改相位
TIM_OC2Init(TIM3, &TIM_OCInitStructure);
TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Disable);
/* TIM enable counter */
TIM_Cmd(TIM3, ENABLE);
/* Enable the TIM3 global Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
/* TIM IT enable */
TIM_ITConfig(TIM3, TIM_IT_CC1 | TIM_IT_CC2, ENABLE);
}
void TIM3_IRQHandler(void)
{
/* TIM3_CH1 toggling with frequency = 183.1 Hz */
if (TIM_GetITStatus(TIM3, TIM_IT_CC1) != RESET)
{
TIM_ClearITPendingBit(TIM3, TIM_IT_CC1 );
capture = TIM_GetCapture1(TIM3);
TIM_SetCompare1(TIM3, capture + CCR1_Val );//实现同频率翻转
}
/* TIM3_CH2 toggling with frequency = 366.2 Hz */
if (TIM_GetITStatus(TIM3, TIM_IT_CC2) != RESET)
{
TIM_ClearITPendingBit(TIM3, TIM_IT_CC2);
capture = TIM_GetCapture2(TIM3);
TIM_SetCompare2(TIM3, capture + CCR2_Val);
}
}
(2018/1/21 改 )