STC单片机定时器0产生pwm控制舵机运动和调速

STC单片机定时器0产生pwm控制舵机运动和调速

  • 首先,要使用pwm控制舵机,就需要对舵机的转角和脉宽关系有所了解,下图为一个周期内脉冲的宽度变化,所 以我们只需要按照图示产生固定比例的pwm波形就可以简单的控制舵机的正反转。

List item

  • 我使用的是stc8a8k32s型号单片机,用的24M晶振,为了给主程序和其他串口中断留下工作时间,所以将定时器定时时间设置为50us产生一次中断,所以对应舵机正反转的高电平时间500~2500us来说,是产生10次到50次中断,总的周期为400次中断,也就是20ms。所以编程思路为在总共400次的周期里,只需要控制中断次数在10到50次之间产生高电平就能让舵机转动。
  • 对于舵机来说,需要的是对角度的精准控制和速度的可调,角度的控制在这篇文章就是将10到50次中断映射到舵机的全角度中,比如我使用的是270°舵机,所以就是对应270°角。对于舵机的调速来说,就是大角度的转动是靠小角度的堆积,并且在堆积中需要一定的延时,就可以完成对速度的调整,延时时间的控制就反映了舵机运动时间的快慢。
  • 这是对定时器0初始化,并且定时50us.
void Time0_Init(void)
{
		P0M1 &= 0xF7; P0M0 &= 0xF7;		//设置为准双向模式,内部弱上拉
		P0 |= 0x08;
		AUXR &= 0X7f; 		//定时器0为12T模式
		TMOD = 0X01;			//模式1
		TL0 = 0X9c;				//50us中断一次
		TH0 = 0XFF;
		TR0 = 1;
		ET0 = 1;
		EA = 1;
		pwm = 1;
}
  • 定时器0中断服务函数
void Time0Interrupt(void) interrupt 1
{	
		pwm_num++;		//pwm计数值
		TL0 =0X9c;		//时钟定时50us,所以重装值和初始化一致
		TH0 =0XFF;
		if(pwm_num<=angle)		//angle为主函数更改,用来和当前中断次数作比较
			pwm=1;
		else
			pwm=0;
		if(pwm_num>400)
		{
			pwm_num=0;
		}
}
  • 舵机角度转动和速度控制函数
void Servo_motion(unsigned int num,unsigned int speed)		//speend范围10-80 
{
		unsigned int ang;
		ang=(num/270.0)*40+10; //num为你需要转动的角度,然后算出在舵机整个角度范围内的比例,再乘以整个周期数就可以知道需要中断几次高电平,最后因为是10到50次中断为舵机的有效脉宽,所以加10次
		if(angle > ang)
		{
			while(angle>ang)	//如果舵机当前的角度大于我们希望到达的角度,就要依次做减法
			{
					angle-=1;
					Delay_ms(speed); //此处可以添加自己需要的延时时间,一般为100ms以内
			}
		}
		else
		{
				while(angle<ang)
				{
						angle+=1;
						Delay_ms(speed);
				}
		}
}
  • 主函数
int main(void)
{
	Time0_Init();
	angle=30;		//舵机初始角度设定,中断前30次为高电平,也就是135°
	while(1)
	{	
		Servo_motion(150,60);	//150°转动
		Servo_motion(200,60); //200°转动
	}
}
  • 对于最合适的舵机pwm来说,应当是1us中断一次,刚好对应500到2500us的脉宽时间,总共是中断20000次,对应20ms的周期,所以如果使用stm32系列,可以尝试此方法,然后不断修改定时器重载值就可以实现舵机的精准控制和速度调整,这里只是为了说明舵机的pwm调速的原理,使得对于舵机的角度把握并不是精准的。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值