Pantech.AI

“How to Interface the servo motor with 8051 “

Servo Motor

A servo motor is an electric device designed for precise control of angular rotation, making it ideal for applications where accuracy is crucial, such as controlling a robotic arm.

The motor includes control circuitry to manage the motor shaft’s precise positioning, operating as a closed-loop system. The servo motor’s rotation angle is regulated by a PWM (Pulse Width Modulation) signal, where adjusting the PWM width allows control over the angle and direction of rotation.

For more information on servo motors and their use, refer to the “Servo Motor” section in the sensors and modules category.

Generating PWM using 8051

The SG90 servo has a practical duty cycle range for achieving rotation from -90° to +90°, which differs slightly from the ideal.

  • At approximately 0.54ms (2.7% duty cycle), the servo shaft reaches -90°.
  • At around 1.4ms (7% duty cycle), the shaft is positioned at 0° (neutral).
  • At approximately 2.4ms (12% duty cycle), the shaft reaches +90°.

To control the servo motor within this -90° to +90° range, a 50Hz PWM waveform with a duty cycle varying from about 0.54ms to 2.4ms is required. This PWM signal can be generated using the Timer in an 8051 microcontroller.

Connecting SG90 Micro Servo Motor with 8051

Example

Now, let’s program the AT89S52 microcontroller to generate a 50Hz PWM signal for controlling a servo motor’s rotation between -90° and +90°.

In this example, PWM is generated on the P2.0 pin of the 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);
    }
}

Leave a Comment

Your email address will not be published. Required fields are marked *