Professional Documents
Culture Documents
*/
/*** Including header files for C-Programming and 8051 Microcontroller Register
***/
#include <stdio.h>
#include <reg51.h>
int i,C,C1,COUNT=16,PrintVAL,col;
char PRNTC;
char* LINE1 ="NS=
NA=
";// NS denotes SetSpeed, NA denotes ActualSpeed (
in RPM)
char* LINE2 ="E=
DC=
";// E denotes Error, DC denotes Duty cycle (in pe
rcentage)
char* POINTER;
sbit led = P3^2;
ndow
// *****************************************************************************
// ***************************** MAIN PROGRAM ******************************
// *****************************************************************************
void main()
{
LCD();
led = 0;
REFRESH1();
POINTER = LINE1;
PrintLine();
REFRESH2();
POINTER = LINE2;
PrintLine();
TMOD = 0x51;
er
TON = 10*Duty;
TOFF =10*(100-Duty);
for(C1=0;C1<500;C1++)
{
MotorDrive = 1;
for(C=0;C<TON;C++)
MotorDrive = 0;
for(C=0;C<TOFF;C++)
}
REFRESH6();
PrintVAL = Duty;
PrintDec();
while(1) // Endless while loop.
{
MandC();
}
}
/*********** END of the MAIN Program ***************/
//***************************************************************
//**********************Previously Used Functions*************************
//***************************************************************
LCD() // Control Commands to configure and clear the LCD
{
P0 = 0XFF;
P1 = 0XFF;
P20=0;
//clear R/W
P21=0;
//clear RS
P22=0;
//clear EN
P0 = 0X30;
WRITE1();
P0 = 0X30;
WRITE1();
P0 = 0X38;
WRITE1();
P0 = 0X08;
WRITE1();
P0 = 0X03;
WRITE1();
P0 = 0X06;
WRITE1();
P0 = 0X0C;
WRITE1();
P0 = 0X80;
WRITE1();
CLRLCD();
}
WRITE1() // Send command to the LCD (WRITE CYCLE ROUTINE)
{
P20=0;
P21=0;
//MAKE RS,R/W,EN LOW
P22=0;
P22=0;
P22=1;
//MAKE EN HIGH
DELAY1();
P22=0;
P22=0;
P20=1;
P20=1;
// MAKE R/W HIGH
P20=0;
P20=0;
DELAY1();
}
DELAY1() // EN Pulse Width
{
for(C=0;C<2000;C++);
}
DELAY2()
{
for(C=0;C<500;C++);
}
DELAY3()
{
for(C=0;C<100;C++)
{
for(C=0;C<300;C++) ;
}
}
PRINTC() // Display a character on LCD
{
P0=PRNTC;
P21=1; //MAKE RS HIGH
P22=1; //MAKE EN HIGH
DELAY1(); //EN PULSE WIDTH
P22=0; //MAKE EN LOW
P20=1; //MAKE R/W HIGH
P21=0; //MAKE RS LOW
P20=0; //MAKE R/W LOW
P22=0;
}
REFRESH1() // Select First Line on LCD
{
P0=0X80;
WRITE1();
P20=0;
}
REFRESH2() // Select Second Line on LCD
{
P0=0XC0;
WRITE1();
P20=0;
}
REFRESH3() // Select First Line on LCD
{
P0=0X83;
WRITE1();
P20=0;
}
REFRESH4() // Select Second Line on LCD
{
P0=0X8C;
WRITE1();
P20=0;
}
REFRESH5() // Select Second Line on LCD
{
P0=0XC2;
WRITE1();
P20=0;
}
REFRESH6() // Select Second Line on LCD
{
P0=0XCC;
WRITE1();
P20=0;
}
/**************** *************/
CLRLCD() // Clear the LCD Display for Next page
{
P0=0X01;
WRITE1();
P20=0;
}
PrintDec() // Prints upto 4-digit decimal number
{
int D4,D31,D3,D21,D2,D1,A4,A3,A2,A1;
//***************** Decimal Value Extraction ******************/
D4 = PrintVAL/1000; // Most significant decimal digit
D31 = PrintVAL%1000;
D3 = D31/100; // Next significant decimal digit
D21 = D31%100;
D2 = D21/10; // Next significant decimal digit
D1 = D21%10; // Least significant decimal digit
//**********Decimal to ASCII Conversion ***************/
A4 = D4+48;
PRNTC = A4;
PRINTC();
A3 = D3+48;
PRNTC = A3;
PRINTC();
A2 = D2+48;
PRNTC = A2;
PRINTC();
A1 = D1+48;
PRNTC = A1;
PRINTC();
}
PrintLine() // Display one LINE (16 characters) of text
{
for (col=0;col<12;col++) // COUNT set to 16
{
PRNTC=*POINTER;
PRINTC();
POINTER++;
}
}
/////////////////////////////////////////////////////////////////////
//****************************************************************
// *************************** NEW Function*****************************
//****************************************************************
MandC()
{
int ActualSpeed,SetSpeed,Error,K;// Speed and control parameters
int CPH,CPL;
// Count values for HIGH and LOW durations of th
e PWM output
// Choose CPH + CPL = 2560, giving PWM time period TPWM = 2560/(11MHz/12) = 2.8
ms approx.
int T1Gate,PulseCount,countC;
// Count Encoder pulses by Timer1, Gated through a time window T1Gate in the ran
ge 1-5 sec,
// generated by counting PWM pulses for a count PulseCount = T1Gate/TPWM = 358*T
1Gate)
SetSpeed = 1500;
in the range 900-4500)
K = 10;
n the range 1-20)
CPH = Duty/10;
//
pulse = 256*CPH
CPL = 10 - CPH;
//
pulse = 256*CPL
T1Gate = 3;
//
the range 1-5)
PulseCount = 358*T1Gate;//
MotorDrive = 0;
// Low interval of PWM starts
TR0 = 1;
// Start Timer 0
while(!TF0);
// Checking Timer0 flag register if it i
s not equal to 1
TR0 = 0;
// If TF0 = 1 stop the timer
TF0 = 0;
// Clear the Timer0 Flag bit for the nex
t PWM cycle
}
/****************************** Measure speed**********************************/
TR1 = 0;
// Stop Timer1 to hold measured value
ActualSpeed = 15*(256*TH1 + TL1)/T1Gate; // Speed in RPM = 15*Encoder pu
lse frequency
/******************** Compute, Update PWM Duty cycle and Display ***************
*/
Error = (ActualSpeed - SetSpeed)/(SetSpeed/100);//Percentage error in sp
eed
Duty = Duty - Error/K;
// Correction made in Duty cycle
// Restricting Duty cycle in the range of (10%-90%)
if(Duty>90)
{
Duty=90;
}
if(Duty<10)
{
Duty=10;
}
/////// Print Set Speed(NS) and Actual Speed (NA)
REFRESH3();
PrintVAL = SetSpeed;
PrintDec();
REFRESH4();
PrintVAL = ActualSpeed;
PrintDec();
/// Check and Print Error (E)
REFRESH5();
if(Error<0)
{
Error = Error * -1;
PRNTC = 45;
PRINTC();
PrintVAL = Error;
PrintDec();
Error = Error * -1;
}
else
{
PRNTC = 32;
PRINTC();
PrintVAL = Error;
PrintDec();
}
// Print Space