|
~: Main Program for motion control in C language :~
#include<reg51.h>
#include <string.h>
sbit rs = P3^7; // rs pin of LCD
sbit en = P3^5; // en pin of LCD
sbit rw = P3^6; // rw pin of LCD
sbit b = P0^7; // busy flag
sbit stp=P2^5; // stop indicator
sbit spd=P2^6; // RPM change indicator
sbit rcv=P2^7; // byte received indicator
unsigned int f=0,d,r,c=0;
unsigned char data d1,d2,d3;
void writecmd(unsigned char a);// function initializations
void writedata(unsigned char b);
void busy(void);
void writestr(unsigned char *s);
void send(void);
void dely(void);
void rotate(void);
void delay(int);
void spdinc(void);
void spddec(void);
void display(unsigned int);
void recv(void) interrupt 4 // serial interrupt function
{
rcv = 1; // indication
RI=0; // clear receive flag
c++; // count received digits
if(c==1) d1=SBUF; // store them one by one
else if(c==2) d2=SBUF;
else if(c==3) // when all three received
{
d3=SBUF;
c=0; // reset count
writecmd(0xC0);
writestr("Current RPM= "); // display "current RPM"
writedata(d1); // and display all bytes one by one
writedata(d2);
writedata(d3);
}
rcv = 0;
}
void spdinc() // increase RPM
{
spd=1; // indication
dely(); // debounce delay
if(d>5) // decrease delay till it becomes
{
d=d-5; // minimum
r=1250/d; // calculate RPM
writecmd(0x80); // display it as "set RPM"
writestr("set RPM = ");
display(r);
}
else if(d==5) // if delay is minimum
{
writecmd(0x80);
writestr("maximum RPM "); // display message
}
}
void spddec (void) // decrease RPM
{
spd=1; // indication
dely(); // debounce delay
if(d<45) // increase delay till it becomes
{
d=d+5; // maximum
r=1250/d; // calculate RPM
writecmd(0x80);
writestr("set RPM = "); // display it as "set RPM"
display(r);
}
else if(d==45) // if delay is maximum
{
writecmd(0x80);
writestr("minimum RPM "); // display message
}
}
void delay(int c)
{
int k;
TL0 = 0x17; // load timer with 64535
TH0 = 0xFC;
TR0 = 1; // start timer
for(k=0;k<c;k++) // count no of overflows
{
while(TF0==0); // timer will overflow after 1 ms
TF0 = 0; // clear timer overflow flag
TL0 = 0x17; // and reload timer till desire delay
TH0 = 0xFC; // is complete
}
TR0 = 0; // stop timer
}
void rotate() // rotate motor
{
while(P1==0xFF) // till any key is not pressed
{
P2=0x11; // apply pulse sequence
delay(d); // with desire delay
P2=0x12;
delay(d);
P2=0x04;
delay(d);
P2=0x08;
delay(d);
}
}
void display(unsigned int z) // display ASCII char on LCD
{
int z1,a,ASCII[3]; // convert decimal no into ASCII
if(z>=100) // if its 3 digit number
{
a=2;
while(z>10) // till it is greater then 10
{
z1=z%10; // separate its all digits
ASCII[a]=z1+0x30; // and convert it into ASCII
z=z/10;
a--;
}
ASCII[0]=z+0x30;
}
Else // if its 2 digit number
{
z1=z%10; // separate both digits
ASCII[2]=z1+0x30; // convert them into ASCII
z=z/10;
ASCII[1]=z+0x30;
ASCII[0]=0x30;// display first digit as ‘0’
}
writedata(ASCII[0]); // display all three digits
writedata(ASCII[1]);
writedata(ASCII[2]);
}
void dely(void) // key debounce delay
{
unsigned int x,y;
for(x=0;x<100;x++)
for(y=0;y<1000;y++);
}
void writecmd(unsigned char a) // send command to LCD
{
busy(); // check busy flag
rs = 0; // clear rs to select command register
rw = 0; // clear rw pin
P0 = a; // send command
en = 1; // strobe display
en = 0;
}
void writedata(unsigned char b) // send data to LCD
{
busy(); // check busy flag
rs = 1; // set rs to select data register
rw = 0; // clear rw pin
P0 = b; // send data
en = 1; // strobe display
en = 0;
}
void busy() // check busy flag
{
en = 0; // disable LCD
P0 = 0xFF; // consider P0 as input
rs = 0; // select data register
rw = 1; // read LCD
while(b==1) // loop till busy flag is 1
{
en=0;
en=1;
}
en=0; // disable LCD
}
void writestr(unsigned char *s) // write message string on LCD
{
unsigned char l,i;
l = strlen(s); // get length of message
for(i=1;i<l;i++)
{
writedata(*s); // send all the char one by one
s++;
}
}
void main()
{
TMOD = 0x21; // initialize timer and counter
SCON=0x40; // initialize serial communication
TH1=0xF3; // set baud rate to 9.6 KBPs
TL1=0xF3;
TR1=1; // start timer
IE=0x90; // enable serial interrupt
REN=1; // enable reception
P2=0x00; // P2 and P0 as output
P0=0x00;
writecmd(0x3C); // initialize LCD
writecmd(0x0E);
writecmd(0x01); // clear LCD memory and home cursor
d=25; // set 50 RPM initially
r=1250/d;
writecmd(0x80);
writestr("set RPM = "); // display message
display(r); // and RPM
begn:stp=1; // stop indication
P1=0xFF;
while(P1==0xFF); // wait until is pressed
loop:switch(P1)
{
case 0xFE:
dely();
P1=0xFF;
f=1; // set the flag and
rotate(); // start rotating motor
break;
case 0xFD:
P2=0x00; // stop the motor and
f=0; // reset the flag
dely();
break;
case 0xFB:
spdinc(); // increase RPM
P1=0xFF;
if(f==1) rotate();// if motor is rotating
break; // keep continue
case 0xF7:
spddec(); // decrease RPM
P1=0xFF;
if(f==1) rotate();// if motor is rotating
break; // keep continue
}
if(f==1) goto loop; // if motor is stop wait for
else goto begn; // key press
}
|