Вы находитесь на странице: 1из 6

Angle control source code avr

#include <avr/io.h>
#include <util/delay.h>
#include <string.h>

//////////////// variable
declarations////////////////////////////

unsigned int angle=0,new_angle,set_angle=0,num_of_pulses,


rotate_reverse_flag=0;

///////////// function to send data to


LCD//////////////////////////

void senddata(unsigned char data)


{
_delay_ms(2); // wait for LCD to be ready
PORTD=(1<<PD0); // for data rs=1
PORTC=data; // put data byte on data-bus
PORTD=(1<<PD0)|(1<<PD1); // give strobe to En pin
PORTD=(1<<PD0)|(0<<PD1);
}

//////////////////// function to send command to


LCD////////////////

void sendcmd(unsigned char cmd)


{
_delay_ms(2); // wait for LCD to be ready
PORTD=(0<<PD0); // for data rs=0
PORTC=cmd; // put command byte on data-bus
PORTD=(1<<PD1); // give strobe to En pin
PORTD=(0<<PD1);
}

///////////// function to send string to LCD


//////////////////////
void printstr(unsigned char *s)
{
uint8_t l,i;
l = strlen(s); // get the length of string
for(i=0;i<l;i++)
{
senddata(*s); // write every char one by one
s++;
}
}

///////////////// function to display angle value on


LCD///////////////

void display_value(unsigned int t)


{
unsigned int t1,a;
unsigned char asci[3];
if(t>=100) // for angle in 3 digit
{
a=2;
while(t>=10) // separate all 3 digits
{
t1=t%10; // one by one
asci[a]=t1+0x30; // convert them into ASCII
t=t/10; // store them in array
a--;
}
asci[0]=t+0x30; // first digit of angle
}
else // for angle in2 digits
{
t1=t%10; // separate both digits
asci[2]=t1+0x30; // convert them in to ASCII
t=t/10;
asci[1]=t+0x30;
asci[0]=0x20; // take first digit as space
}
sendcmd(0xC0);
senddata(asci[0]); // send all digits one by one to
senddata(asci[1]); // LCD
senddata(asci[2]);
printstr(" deg ");
}

//////////////// function to initialize LCD


/////////////////////////
void lcd_init()
{
sendcmd(0x3E); // configure LCD dot pattern
sendcmd(0x0E); // LCD screen on cursor on
sendcmd(0x01); // clear LCD memory and home cursor
sendcmd(0x80); // set cursor to 1st line 1st column
printstr("Set Motor Angle:"); // display message
}

//////////////// function to increase angle by 15


//////////////////
void inc_angle()
{
if(angle<345) angle+=15; // increase angle till 345 degree
display_value(angle); // display new angle value
new_angle = angle; // update new angle value
}

////////////// function to decrease angle by 15 ////////////////


void dec_angle()
{
if(angle>0) angle-=15; // decrease angle till 0 degree
display_value(angle); // display new angle value
new_angle = angle; // update new angle value
}

///////////////// function to rotate motor till desire angle


//////////
void rotate_motor()
{
int i;
if(new_angle>set_angle) // if new entered angle is larger
{
num_of_pulses = (new_angle-set_angle) / 15; // set number of
rotate_reverse_flag=0; // pulses and clear flag to rotate
// motor CCW
}
else // if new entered angle is smaller
{
num_of_pulses = (set_angle-new_angle) / 30; // set number
rotate_reverse_flag=1; // of pulses and set flag to rotate
// motor CW
}
if(rotate_reverse_flag==0) // check if flag is clear
{
for(i=0;i<num_of_pulses;i++) // generate pulse sequence to
{ // rotate motor CCW
PORTB = 0x01;
_delay_ms(100);
PORTB = 0x02;
_delay_ms(100);
PORTB = 0x04;
_delay_ms(100);
PORTB = 0x08;
_delay_ms(100);
}
}
else // else if flag is set
{
for(i=0;i<num_of_pulses;i++) // generate pulse sequence to
{
PORTB = 0x08; // rotate motor CW
_delay_ms(100);
PORTB = 0x04;
_delay_ms(100);
PORTB = 0x02;
_delay_ms(100);
PORTB = 0x01;
_delay_ms(100);
}
}
set_angle = new_angle; // save angle value

/////////////////// main function starts here


/////////////////////////
int main(void)
{
DDRC=0xFF; // PORTB, PORTC and PORTD as
DDRD=0xFF; // an output ports
DDRB=0x0F;
DDRA=0x00; // PORT A as an input port
PORTC=0x00;
PORTD=0x00;
PORTB=0x0F;
lcd_init(); // initialize LCD
display_value(angle); // display angle as 0 degree
loop:while(PINA==0xF0); // loop until no button is pressed
switch(PINA) // when button is pressed
{
case 0xF1: // if 1st button is pressed
inc_angle(); // increment angle by 15 degree
_delay_ms(200); // key debounce delay
break; // get out of loop
case 0xF2: // same as above
dec_angle();
_delay_ms(200);
break;
case 0xF4: // for 3rd key
rotate_motor(); // rotate motor
break;
}
goto loop; // continuous loop
}
Software Logic
The software logic is based on how to rotate stepper motor at set angle every time. Motor rotation directly depends
upon its step resolution. The motor step resolution is 3.75o/ pulse. That means for each pulse applied – motor rotates
for 3.75o only. But it is required to give 4 pulses in sequence to all four motor coils. So motor will rotate 3.75 o × 4 =
15o. Thus we can rotate motor in multiples of 15o like 30o, 45o, 60o, 75o ......

The logic is to find out how many number of pulses should be applied to motor so that it can rotate till desire angle
value. So to do this, every time when user selects rotation angle, the number of pulses to be applied to motor is
found from the equation given below

Number of pulses = 4 × (new set angle value – previous set angle value) / 15

e.g. lets take previously set angle value was 45o and new set angle value is 75o. That means actually the motor has
to rotate for 30o. Putting values in above equation

Number of pulses = 4 × (75-45) / 15 = 8

So motor rotates for 8 × 3.75o = 30o

If new set angle value is lesser than previous set angle value then subtraction will be reversed and motor also rotates
in reverse (CW) direction.

Software Program

Program is written in C language. It’s compiled and simulated using AVR studio software. Complete program is made
up of different functions.

Senddata() function sends 1 byte data to LCD on its data bus

sendcommand() function sends 1 byte command to LCD on its data bus

printstr() function displays message or string on LCD

inc_angle() function increments angle by 15o and displays on LCD


dec_angle() function decrements angle by 15o and displays on LCD

display_value() function takes integer angle value as input. Convert its all digits into ASCII and displays it as angle
value on LCD

lcd_init() function configures and initializes LCD

rotate_motor function rotates stepper motor CW or CCW as per entered angle value till motor reaches that angle
position.