Servo Motor Interfacing with 8051

Servo Motor

Servo Motor with wire connector
Servo Motor

A servo motor is an electric device used for precise control of angular rotation. It is used where precise control is required, like in the case of control of a robotic arm.

  • It consists of a suitable motor with control circuitry for precise position control of the motor shaft.
  • It is a closed-loop system.
  • The rotation angle of the servo motor is controlled by applying a PWM signal to it.
  • By varying the width of the PWM signal, we can change the rotation angle and direction of the motor.

For more information about Servo Motor and how to use it, refer to the topic Servo Motor in the sensors and modules section.

 

Generating PWM using 8051

SG90 servo has a practical duty cycle time for -90° to +90 rotation that is different from ideal.

At ~0.54ms (2.7% duty cycle) we get shaft position at -90° of its rotation.

At ~1.4ms (7% duty cycle) we get shaft position at 0° (neutral) of its rotation.

At ~2.4ms (12% duty cycle) we get shaft position at +90° of its rotation.

 

To control the servo motor in between -90° to +90° rotation. We need to generate a PWM waveform of 50Hz with duty cycle variation from ~0.54ms to ~2.4ms. We can generate PWM using Timer in 8051.

 

Connecting SG90 Micro Servo Motor with 8051

Servo Motor Interface with 8051
Servo Motor Interface with 8051

 

Example

Now let’s program AT89S52 to generate 50Hz PWM to control Servo Motor in the angle between -90° to +90° rotation.

Here we have generated PWM on the P2.0 pin of AT89S52.

Servo Motor Controlling using 8051

#include <reg52.h>
#include <intrins.h>

/* Define value to be loaded in timer for PWM period of 20 milli second */
#define PWM_Period 0xB7FE

sbit Servo_Motor_Pin = P2^0;

unsigned int ON_Period, OFF_Period, DutyCycle;

/* Function to provide delay of 1ms at 11.0592 MHz */
void delay(unsigned int count)
{
    int i,j;
    for(i=0; i<count; i++)
			for(j=0; j<112; j++);
}

void Timer_init()
{
	TMOD = 0x01;		/* Timer0 mode1 */
	TH0 = (PWM_Period >> 8);/* 20ms timer value */
	TL0 = PWM_Period;
	TR0 = 1;		/* Start timer0 */
}

/* Timer0 interrupt service routine (ISR) */
void Timer0_ISR() interrupt 1	
{
	Servo_Motor_Pin = !Servo_Motor_Pin;
	if(Servo_Motor_Pin)
	{
		TH0 = (ON_Period >> 8);
		TL0 = ON_Period;
	}	
	else
	{
		TH0 = (OFF_Period >> 8);
		TL0 = OFF_Period;
	}	
			
}

/* Calculate ON & OFF period from duty cycle */
void Set_DutyCycle_To(float duty_cycle)
{
	float period = 65535 - PWM_Period;
	ON_Period = ((period/100.0) * duty_cycle);
	OFF_Period = (period - ON_Period);	
	ON_Period = 65535 - ON_Period;	
	OFF_Period = 65535 - OFF_Period;
}

int main()
{
   EA  = 1;		/* Enable global interrupt */
   ET0 = 1;         	/* Enable timer0 interrupt */
   Timer_init();
   while(1)
    {
	Set_DutyCycle_To(2.7);/* 0.54ms(2.7%) of 20ms(100%) period */
	delay(1000);
	Set_DutyCycle_To(7);/* 1.4ms(7%) of 20ms(100%) period */
	delay(1000);
	Set_DutyCycle_To(12);/* 2.4ms(12%) of 20ms(100%) period */
	delay(1000);
    }
}

 


Components Used

Servo Motor MG995
Servo Motor MG995
1
8051 AT89c51
8051 AT89c51
1

Downloads

8051_Servo_Motor_Keil_Project Download
8051_Servo_Control_Proteus_Simulation Download
Ad