STM32驱动舵机(附例程)

本文详细解释了STM32 PWM模式中ARR(预装载周期)和PSC(预分频系数)的作用,通过实例说明如何计算定时器周期和频率,并展示了如何使用TIM8驱动舵机,通过调整ARR和PSC实现不同角度的PWM波形输出。
摘要由CSDN通过智能技术生成

一、PWM__Mode:

当计数值小于CRR寄存器值时输出为有效电平,而有效电平要根据OCXInit来设置,设置的有效电平为高则当CNT值小于设置的CRR寄存器值时输出有效电平高电平,当CNT值大于设置的CRR寄存器值时输出有效电平低电平;

二、为什么PWM模式下要设置arr(period)和psc(prescaler)呢?

        首先,ARR对应于预装载值,打个比方,当为向上计数时,计数器计数到CNT=ARR时,溢出并重新计数,所以可称ARR的值为预装载周期(此周期是在分频系数PSC下对应的周期);

        其次,PSC是预分频系数,就是将机器周期的频率进行分频,STM32F407在倍频前对应的时钟频率是84MHZ, 假如,ARR=499(0~499=500)、PSC=83(0~83=84),此时有,机器周期对应的是1/84000000(单位是s,M对应的是十的六次方),分频系数是psc=83+1=84,分频后的频率为84/84=1MHZ,对应的周期为1/1000000(由式子84/84000000得来,也就是一个时钟周期【C51里面,一个时钟周期对应12个机器周期,STM32可以自己设置而已】);

        好啦,到这里就好理解了。ARR是预装载值,PSC是预分频系数,在分频系数的分频之下,每一个装载值,对应的一个时钟周期为84/84000000,故定时器的定时实间为 ARR*PSC/(84MHz)=500*84/84000000s=0.0005s,频率也就是1/0.0005=2000Hz

        顺便提一下,ARR可理解为计数周期,这个周期代表一次定时器溢出的计数周期,即计数达到此值时就会溢出,是在PSC分频系数下得到的机器周期对应的频率下计数的周期间。

 例:在STM32F103VET6上的舵机驱动程序(270°舵机)。

舵机参数:

 程序设计思路:

         PWM初始化arr为20000,psc为72,计算的定时器周期为0.02秒,定时器频率为50hz,同时计数频率则为1M,计数周期为1us,最大计数周期为20000,servo函数里,直接更改ccr寄存器,在pwm模式设置下(pwm模式一和pwm模式二,其中一个是当CNT值小于ccr值时为高电平、大于时为低电平,另一个模式则相反),设置对应的ccr寄存器值为500起,对应pwm波形500us,500+2000/270*pwm,pwm取值0~270,得到输出有效脉宽电平500~2500us  对应 0°~270°。

(其他型号舵机驱动原理相同,如180°对应的ARR寄存器取值为500+2000/180*pwm,pwm取值0~180)

初始化程序:

/**********************************************/
//舵机初始化配置,TIM8的四个通道输出四路舵机
/**********************************************/
extern int s1_c,s2_c,s3_c,s4_c;	//记录上一次舵机角度值
void servo_Configuration1(void)	 //舵机初始化
{
	GPIO_InitTypeDef GPIO_InitStructrue;
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructrue;
	TIM_OCInitTypeDef TIM_OCInitStructrue;

	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM8 , ENABLE);


	GPIO_InitStructrue.GPIO_Mode=GPIO_Mode_AF_PP;
	GPIO_InitStructrue.GPIO_Pin	=GPIO_Pin_6|GPIO_Pin_7|GPIO_Pin_8|GPIO_Pin_9;
	GPIO_InitStructrue.GPIO_Speed =	GPIO_Speed_50MHz;
	GPIO_Init(GPIOC, &GPIO_InitStructrue);

	TIM_TimeBaseInitStructrue.TIM_ClockDivision=0;
	TIM_TimeBaseInitStructrue.TIM_CounterMode=TIM_CounterMode_Up;
	TIM_TimeBaseInitStructrue.TIM_Period=19999;
	TIM_TimeBaseInitStructrue.TIM_Prescaler=71;
	TIM_TimeBaseInit(TIM8,&TIM_TimeBaseInitStructrue);

	TIM_OCInitStructrue.TIM_OCMode=TIM_OCMode_PWM1;
	TIM_OCInitStructrue.TIM_OCPolarity=TIM_OCPolarity_High;
	TIM_OCInitStructrue.TIM_OutputState=TIM_OutputState_Enable;

	TIM_OCInitStructrue.TIM_Pulse=0;

	TIM_OC1Init(TIM8,&TIM_OCInitStructrue);
	TIM_OC1PreloadConfig(TIM8,TIM_OCPreload_Disable);


	TIM_OC2Init(TIM8,&TIM_OCInitStructrue);
	TIM_OC2PreloadConfig(TIM8,TIM_OCPreload_Disable);	


	TIM_OC3Init(TIM8,&TIM_OCInitStructrue);
	TIM_OC3PreloadConfig(TIM8,TIM_OCPreload_Disable);		

	TIM_OC4Init(TIM8,&TIM_OCInitStructrue);
	TIM_OC4PreloadConfig(TIM8,TIM_OCPreload_Disable);	

	TIM_CtrlPWMOutputs(TIM8,ENABLE);	//MOE 主输出使能	
	TIM_ARRPreloadConfig(TIM8,DISABLE);
	TIM_Cmd(TIM8,ENABLE);	
}

舵机角度控制程序:

/*************************************/
//TIM8的四路舵机输出,servo1、servo2、servo3和servo4
/*************************************/

void servo1(int pwm)    //pwm是设定的角度,这里pwm有效值0~270,下同
{
	if ((pwm >= 0)&&(pwm<=270))
	{		
		TIM8->CCR1= 500 + (2000/270)*pwm;
	}
	else 
	{                               /*****/
		if(pwm <0)                //限定角度最小0°,最大270°。下同。
		{TIM8->CCR1 =  500;}        /****/
		else
		{	TIM8->CCR1 =  2500;}
	}
	s1_c = pwm;
} 
void servo2(int pwm)
{
	if ((pwm >= 0)&&(pwm<=270))
	{
		TIM8->CCR2 = 500 + (2000/270)*pwm;
	}
	else 
	{
		if(pwm <0)
		{TIM8->CCR2 =  500;}
		else
		{	TIM8->CCR2 =  2500;}
	}
		s2_c = pwm;
} 


void servo3(int pwm)
{
	if ((pwm >= 0)&&(pwm<=270))
	{
		TIM8->CCR3 = 500 + (2000/270)*pwm;
	}
	else 
	{
		if(pwm <0)
		{TIM8->CCR3 =  500;}
		else
		{	TIM8->CCR3 =  2500;}
	}
	s3_c = pwm;

} 

void servo4(int pwm)
{
	if ((pwm >= 0)&&(pwm<=270))
	{
		TIM8->CCR4 = 500 + (2000/270)*pwm;
	}
	else 
	{
		if(pwm <0)
		{TIM8->CCR4 =  500;}
		else
		{	TIM8->CCR4 =  2500;}
	}
		s4_c = pwm;

}

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值