蓝桥杯嵌入式 - 比较输出PWM

 STM32的PWM输出模式只能输出同频率不同占空比的方波,而在前几届比赛有考到输出不同频率不同占空比方波的情况。而STM32定时器的比较输出模式可以做到。
 而比赛不会考到很多理论上的东西,所以直接贴代码了。

一、初始化部分

  1. 计算周期
CCR1_Val = 1000000/p1;
CCR2_Val = 1000000/p2;
CCR1_duty = d1*CCR1_Val/100;
CCR2_duty = d2*CCR2_Val/100;

 因为后面时钟分频后为1MHz,所以计算周期直接用1000000。
2. 时钟

RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA |RCC_APB2Periph_AFIO, ENABLE);

 我们用TIM3的1、2通道,所以开启TIM3、GPIOA时钟。
2. GPIO初始化

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);

 这里记得服用推挽输出。

  1. NVIC初始化
NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
  1. TimeBase初始化
TIM_TimeBaseStructure.TIM_Period = 0xffff;
TIM_TimeBaseStructure.TIM_Prescaler = 71;
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_CounterMode = 0;
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);

 TIM_Period 填充为最大,0xffff,对时钟72分频,得到1MHz的时钟。
5. 输出初始化

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);

TIM_OCInitStructure.TIM_Pulse = CCR2_Val;
TIM_OC2Init(TIM3, &TIM_OCInitStructure);
TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Disable);
  1. 使能
TIM_Cmd(TIM3, ENABLE);
TIM_ITConfig(TIM3, TIM_IT_CC1 | TIM_IT_CC2 , ENABLE);

二、中断
 这里要特别感谢 马一飞 学长,根据他的博客才实现了这个功能。

void TIM3_IRQHandler(void)
{
	if (TIM_GetITStatus(TIM3, TIM_IT_CC1) != RESET)
	{
		TIM_ClearITPendingBit(TIM3, TIM_IT_CC1 );
		capture = TIM_GetCapture1(TIM3);
		if(flag_1)
			TIM_SetCompare1(TIM3, capture + CCR1_duty );
		else
			TIM_SetCompare1(TIM3, capture + CCR1_Val - CCR1_duty);
		flag_1 = (flag_1 + 1)%2;	
	}

	if (TIM_GetITStatus(TIM3, TIM_IT_CC2) != RESET)
	{
		TIM_ClearITPendingBit(TIM3, TIM_IT_CC2 );
		capture = TIM_GetCapture2(TIM3);
		if(flag_2)
			TIM_SetCompare2(TIM3, capture + CCR2_duty );
		else
			TIM_SetCompare2(TIM3, capture + CCR2_Val - CCR2_duty);
		flag_2 = (flag_2 + 1)%2;
	}
}

最后
 比赛时时候这个代码可以在库例程的 OCToggle 里面进行复制呀~~~~~~~~~~

猜你喜欢

转载自blog.csdn.net/qq_40344307/article/details/89599817