STM32输出比较

这个输出比较模式理解起来还是有点打脑壳的,但理解了也挺简单的。

对输出比较的理解分成两部分来解释:

一、原理

二、在STM32上实现:

       1)硬件上的配置

        2)中断服务程序的编写实现

一、原理

        示意图就像上面画的,一开始我设置输出高电平,设置ARR为最大oxff。第一次时设置CCR为50000,当到了50000我进入中断使状态翻转并且使CCR的值加30000,因为寄存器是16位数据肯定溢出。最后CCR的数值是50000+30000-65536=14464。那么当计数器计数到了14464时,我又进入中断,使状态翻转并且将CCR的值加50000。。。那么它的频率就是1/计数80000的时间,占空比为50000/80000。

二、在32上实现

    1)调用库函数进行配置

void Pwm_Init()
{
	  GPIO_InitTypeDef GPIO_InitStructure;
	  TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
	  TIM_OCInitTypeDef  TIM_OCInitStructure;
	  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);//GPIO配置
		
	  TIM_TimeBaseStructure.TIM_Period =0xffff;//设置ARR为最大
	  TIM_TimeBaseStructure.TIM_Prescaler =71;//设置分频系数,这样记一次数的时间为1/1MHz=1us
	  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;//设置增计数模式
	  TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);//载入

	  TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_Toggle;//设置每次进入中断为电平翻转模式
	  TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;//输出开
	  TIM_OCInitStructure.TIM_Pulse = 0;//设置最初CCR为0,这样一配置完就进去中断服务程序
	  TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;//设置最开始的电平为高电平
	  TIM_OC1Init(TIM3, &TIM_OCInitStructure);//载入寄存器

 TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Disable); //这里就是参考手册里说的禁用预装载寄存器
 TIM_ITConfig(TIM3, TIM_IT_CC1 , ENABLE);//开中断
	  TIM_Cmd(TIM3,ENABLE);//使能
	  
	  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); //配置中断
	
}

     2)中断服务程序编写

#define tim3ch1p 100  //频率单位hz
#define tim3ch1z 70   //占空比单位%

void TIM3_IRQHandler ()
{
   u16 ch2p=1000000/tim3ch1p;//1us*CCR=1/100,10^(-6)*CCR=10^(-2),CCR=10^(-2)/10^(-6)=10^6/10^2
   u16 ch2z=ch2p*tim3ch1z/100;
   u16 ccr=0;
   static u8 tim3flag=0;
	if(TIM_GetITStatus(TIM3, TIM_IT_CC1))
	{
		ccr=TIM_GetCapture1(TIM3);//读取当前CCR的值
		if(tim3flag)
			TIM_SetCompare1(TIM3, ccr+ch2p-ch2z);		 
		else
			 TIM_SetCompare1(TIM3,ccr+ch2z);
		
		tim3flag^=1;//不断取反
		
		TIM_ClearITPendingBit(TIM3, TIM_IT_CC1);
	}
	
}
int main(void)
{
	Pwm_Init();
	while(1);
}

用KEIL的虚拟示波器可以看看输出是否对的。

发布了13 篇原创文章 · 获赞 10 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/lblmlms/article/details/89391144