其他分享
首页 > 其他分享> > 基于通用定时器的PWM波形生成

基于通用定时器的PWM波形生成

作者:互联网

今天终于写到PWM了,关于PWM是什么我这里不再赘述,下面我们来看看通用定时器的PWM模式吧!
脉冲宽度调制模式可以产生一个由TIMx_ARR寄存器确定频率、由TIMx_CCRx寄存器确定占空比的信号。ARR是啥?可以简单记为从0数到ARR(向上计数)或从ARR数到0(向下计数),我们的TIM是16位的,所以ARR取值范围是0~65535。CCR则是当CNT(计数器的值)小于CCR是为1或者0,具体取决于PWM模式和输出极性。
我们再仔细看看输出模式,有边沿对齐和中央对齐,用的便是计数器的向上计数、向下计数和中央对齐模式。
image

上图是下图为TIMx_ARR=8时边沿对齐的向上计数的PWM波形实例。大家看各个CCR配置下的OCXREF即可。在这个模式中,有效电平是从复位后立刻生效的,到CNT不再小于CCR为止,应该很好理解吧。注意,在向下计数模式中产生无法占空比为0的波形。


image
image

上图给出了一些中央对齐的PWM波形的例子

使用中央对齐模式的提示:

下面就是编程环节了

先想想我们需要配置一些什么东西?我们要输出波形到逻辑分析仪就要配置GPIO,有时候还得重映射就要配置AFIO,PWM功能要配置时钟和PWM的两个结构体,一个是ARR和CCR,还有一个是输出信号的模式的配置。下面我们就开始吧!

点击查看代码
void TIM4_CH1_PWM_Init(u16 per,u16 psc)
{
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
	TIM_OCInitTypeDef TIM_OCInitStructure;
	GPIO_InitTypeDef GPIO_InitStructure;
	
	/* 开启时钟 */
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4,ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
	
	/*  配置GPIO的模式和IO口 */
	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_12;
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;//复用推挽输出
	GPIO_Init(GPIOD,&GPIO_InitStructure);
	
	GPIO_PinRemapConfig(GPIO_Remap_TIM4,ENABLE);//改变指定管脚的映射	
	
	TIM_TimeBaseInitStructure.TIM_Period=per;   //自动装载值
	TIM_TimeBaseInitStructure.TIM_Prescaler=psc; //分频系数
	TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1;
	TIM_TimeBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up; //设置向上计数模式
	TIM_TimeBaseInit(TIM4,&TIM_TimeBaseInitStructure);	
	
	TIM_OCInitStructure.TIM_OCMode=TIM_OCMode_PWM1;
	TIM_OCInitStructure.TIM_OCPolarity=TIM_OCPolarity_Low;
	TIM_OCInitStructure.TIM_OutputState=TIM_OutputState_Enable;
	TIM_OC1Init(TIM4,&TIM_OCInitStructure); //输出比较通道1初始化
	
	TIM_OC1PreloadConfig(TIM4,TIM_OCPreload_Enable); //使能TIMx在 CCR1 上的预装载寄存器
	TIM_ARRPreloadConfig(TIM4,ENABLE);//使能预装载寄存器
	
	TIM_Cmd(TIM4,ENABLE); //使能定时器

重映射了为什么是这个引脚呢?这就要去看中文参考手册的8.3.7定时器复用功能重映射章节了

下面是主函数的内容

点击查看代码
int main()
{
	u16 i=0;  
	u8 fx=0;
	SysTick_Init(72);
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);  //中断优先级分组 分2组
	LED_Init();
	TIM4_CH1_PWM_Init(500,72-1); //频率是2Kh
	
	while(1)
	{
		
		if(fx==0)
		{
			i++;
			if(i==300)
			{
				fx=1;
			}
		}
		else
		{
			i--;
			if(i==0)
			{
				fx=0;
			}
		}
		TIM_SetCompare1(TIM4,i);  //i值最大可以取499,因为ARR最大值是499.
		LED1=!LED1;
		delay_ms(100);	
	}
}

切记,在更换输出通道或定时器时一点要更改想要的函数以及变量,例如
TIM_SetCompare1(TIM4,i);
在换为TIM3,CH2时应该为
TIM_SetCompare2(TIM3,i);
其他的函数如上设置就可以了。

标签:ARR,定时器,波形,TIM4,TIMx,TIM,GPIO,PWM
来源: https://www.cnblogs.com/CottonTAT/p/16456282.html