Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Interfacing with C plus plus-programing communication with microcontrolers (K. Bentley, 2006)

.pdf
Скачиваний:
192
Добавлен:
12.08.2013
Размер:
3.18 Mб
Скачать

8 DRIVING MOTORS - DC & STEPPER 265

enum MOTORTYPE {UPFS, UPHS, BPFS, BPHS};

class StepperMotor : public Motor

{

private:

MOTORTYPE MotorType; unsigned char Switching[8]; int CycleIndex;

int MaxIndex;

public:

StepperMotor(MOTORTYPE motortype = UPFS, int baseaddress=0x378);

virtual void Forward(); virtual void Reverse(); virtual void Brake();

};

StepperMotor::StepperMotor(MOTORTYPE motortype,

int baseaddress): Motor(baseaddress)

{

MotorType = motortype; CycleIndex = 0;

switch(MotorType)

{

case UPFS: MaxIndex = 4; Switching[0] = 0x11; Switching[1] = 0x12; Switching[2] = 0x22; Switching[3] = 0x21; break;

case UPHS: MaxIndex = 8; Switching[0] = 0x01; Switching[1] = 0x11; Switching[2] = 0x10; Switching[3] = 0x12; Switching[4] = 0x02; Switching[5] = 0x22; Switching[6] = 0x20; Switching[7] = 0x21; break;

case BPFS: MaxIndex = 4; Switching[0] = 0x99;

266 8 DRIVING MOTORS - DC & STEPPER

Switching[1] = 0x69;

Switching[2] = 0x66;

Switching[3] = 0x96; break;

case BPHS: MaxIndex = 8; Switching[0] = 0x99; Switching[1] = 0x09; Switching[2] = 0x69; Switching[3] = 0x60; Switching[4] = 0x66; Switching[5] = 0x06; Switching[6] = 0x96; Switching[7] = 0x90;

}

}

void StepperMotor::Forward()

{

if(++CycleIndex == MaxIndex) CycleIndex = 0; WritePort0(Switching[CycleIndex]); delay(259-GetSpeed());

}

void StepperMotor::Reverse()

{

if(--CycleIndex == -1) CycleIndex = MaxIndex -1; WritePort0(Switching[CycleIndex]); delay(259-GetSpeed());

}

void StepperMotor::Brake()

{

switch(MotorType)

{

case UPFS: case UPHS: WritePort0(0x11); break;

case BPFS: case BPHS: WritePort0(0x99);

}

}

void main()

{

Motor *MotorPtr;

8 DRIVING MOTORS - DC & STEPPER 267

int Quit = 0;

key = 0;

unsigned char

int SpeedLock

= 1;

 

int Selection;

 

 

clrscr();

 

 

MOTOR MENU";

cout << endl << "

cout << endl << "

~~~~~~~~~~" << endl;

cout << "

1

DC Motor" << endl;

cout << "

2

UPFS" << endl;

cout << "

3

UPHS" << endl;

cout << "

4

BPFS" << endl;

cout << "

5

BPHS" << endl;

cout << "

6

QUIT" << endl;

cout << endl;

 

 

cout << "

Select the MOTOR Number: ";

cin >> Selection; switch(Selection)

{

case 1: MotorPtr = new DCMotor; break;

case 2: MotorPtr = new StepperMotor(UPFS); break;

case 3: MotorPtr = new StepperMotor(UPHS); break;

case 4: MotorPtr = new StepperMotor(BPFS); break;

case 5: MotorPtr = new StepperMotor(BPHS); break;

case 6: return;

default: cout << endl;

cout << " Unspecified Motor type...."; cout << " PRESS a key to END Program!"; getch();

exit(1); // Exits the program

}

if(MotorPtr == NULL)

{

cout << "Memory allocation failed " << endl; getch();

exit(1);

268 8 DRIVING MOTORS - DC & STEPPER

}

cout << "**********************************" << endl; cout << "* CONNECT BOARD POWER SUPPLY NOW *" << endl;

cout << "**********************************" << endl; cout << endl;

cout << " After connecting power,”;

cout << “ press a key to continue " << endl; getch();

while(!Quit)

{

key = peekb(0x40,0x17); // Read control key byte. if(key & 0x80) // Test Insert key ON (MSBit '1').

Quit = 1; // Exit the program.

else

{

//If both shift keys are released SpeedLock is

//released

if(!(key & 0x01) && !(key & 0x02)) SpeedLock = 0;

key &= 0x0F; // Filter out bits corresponding to // just SHIFT, ALT & CTRL keys.

switch(key)

{

case 0x04 : MotorPtr->Forward(); break;

case 0x08 : MotorPtr->Reverse(); break;

case 0x01 : if(!SpeedLock)

{

MotorPtr->SetSpeed(MotorPtr->GetSpeed()+4); SpeedLock = 1;

}

break;

case 0x02 : if(!SpeedLock)

8 DRIVING MOTORS - DC & STEPPER 269

{

MotorPtr->SetSpeed(MotorPtr->GetSpeed()-4); SpeedLock = 1;

}

break;

case 0x03 : MotorPtr->Brake(); break;

case 0x05 : if(!SpeedLock)

{

MotorPtr->SetSpeed(MotorPtr->GetSpeed()+4); SpeedLock = 1;

}

MotorPtr->Forward(); break;

case 0x06 : if(!SpeedLock)

{

MotorPtr->SetSpeed(MotorPtr->GetSpeed()-4); SpeedLock = 1;

}

MotorPtr->Forward(); break;

case 0x09 : if(!SpeedLock)

{

MotorPtr->SetSpeed(MotorPtr->GetSpeed()+4); SpeedLock = 1;

}

MotorPtr->Reverse(); break;

case 0x0B : if(!SpeedLock)

{

MotorPtr->SetSpeed(MotorPtr->GetSpeed()-4); SpeedLock = 1;

}

MotorPtr->Reverse(); break;

270 8 DRIVING MOTORS - DC & STEPPER

case 0x00 : MotorPtr->Off();

}

}

delete MotorPtr;

}

}

In our program that uses virtual functions, we were able to write the motor control portion as a generic module. This approach allows the program to bind the correct function to the object associated with the selected motor during program execution (late binding). Only after the user has selected the type of motor, will dynamic memory allocation and late binding take place to drive the motor. If the program had not used virtual functions, the programmer would need to provide extensive dedicated code to control each motor. This was seen in the modified main() function given in Listing 8-20.

The program that uses virtual functions to control the motors does not need dedicated motor control code for each type of motor. Instead, the code is independent of the specific motor type and will even work for motors that may be added to the hierarchy in the future. These benefits are the main advantages of using virtual functions and can also be seen as one of the greatest strengths of object-oriented programming.

8.8 Summary

This chapter presented the construction and operation of DC Motors and Stepper Motors. Various means of controlling these motors has also been described.

A class hierarchy was developed to represent all types of motor discussed at the beginning of the chapter. This was followed by a conceptual explanation of abstract classes and pure virtual functions. Class hierarchy’s and multiple inheritance were also explained. The need for a set of virtual destructors in a class hierarchy was also demonstrated. Unlike constructors, destructors can be virtual. These destructors are used to free an object’s dynamically allocated memory once the program no longer needs the object.

A generic program for all real motor classes of the hierarchy was developed and integrated into a main() function to demonstrate the concept and advantages of late binding. Keyboard controls were then incorporated into the program to improve control of motors when using the interface board.

8 DRIVING MOTORS - DC & STEPPER 271

8.9 Bibliography

Bergsman, P. , Controlling The World With Your PC, HighText Publications, San Diego, 1994.

Stiffler, K., Design with Microprocessors for Mechanical Engineers, McGrawHill, 1992.

PARKER HANNIFIN CORP, Positioning Control Systems and Drives, 19921993.

Lafore, R. Object Oriented Programming in MICROSOFT C++, Waite Group Press, 1992.

Wang, P.S., C++ with Object Oriented Programming, PWS Publishing, 1994. Borland, Borland C++ version 5, User’s Guide, Borland International, 1996.

Borland, Borland C++ version 5, Programmers Guide, Borland International, 1996.

Barton, J.J. and L.R. Nackman, Scientific and Engineering C++ - An Introduction with Advanced Techniques and Examples, Addison Wesley, 1994.

Stevens, A. Teach Yourself C++ Fifth Edition, MIS Press, 1997.

Schildt, H. Teach Yourself C++ Third Edition, Osborne/McGraw-Hill, 1998.

9

Program

Development

Techniques

Inside this Chapter

ξ

ξ

ξ

ξ

ξ

ξ

Developing programs – what is involved?

Efficient coding techniques.

Modular development approach.

Header Files.

Function files.

Project files and make files.

9.1 Introduction

So far we have learned how to develop efficient object-oriented programs where the emphasis has been on the program statements (source code). In this chapter we will learn how to plan a program using pseudo-code, organise its structure, and write the program so typographical errors can be kept to a minimum. The development process to produce modular programs will also be explained.

A modular program can be made by separating a lengthy single file program into a number of logical modules and then placing each module into its own dedicated file. This process greatly improves our ability to maintain our programs. Furthermore, it allows us to carry out modifications with greater ease and also promotes more efficient debugging of programs. An inevitable consequence of this modular approach is the multi-file program. We will learn how to create a multifile program from a number of source files and then generate a final executable file.

9.2 Efficient Coding Techniques

The word coding is used is used in this chapter and refers to the writing of programming statements. No coding should commence until a detailed plan for the program is established. This plan is written as a general worded discription known as pseudo-code. If we are writing an object-oriented program, the first step should be creating the object classes and the associated class hierarchy. Using an objectoriented approach tends to result in a program with good structure. Program development should be carried out in a number of manageable steps. At each of these steps the program (or the part of the program) coded to that point can be compiled and verified for errors.

Most editors used for programming provide cutting and pasting facilities for text editing. We can minimise typographical errors during the coding process by using text cutting and pasting operations. These typographical errors tend to be the cause of most compilation errors.

Pseudo-code

Using pseudo-code to outline the basic operation of an application can assist in its development. The following example demonstrates how pseudo-code is developed and used to generate program code.

Program description:

A crane is used to lift a weight from point A and move it to another point B. It is assumed that the crane uses three DC motors; one to lift/lower the load, another to move the load in the x direction, and the third motor to move the load in the y direction.

9 PROGRAM DEVELOPMENT TECHNIQUES 275

The pseudo-code is:

Enter coordinates for points A and B. Move the crane to point A.

Lift the load.

Move the crane to point B. Lower the load.

End.

We can translate this pseudo-code into a C++ object-oriented program. The following example program shows one implementation of a main() function that implements the pseudo-code:

void main()

 

 

 

{

//

Create

a Crane object.

Crane OurCrane;

Point a, b;

//

Create

two Point objects.

cout << “Enter coordinates of point A ”; cin >> a;

cout << endl << “Enter coordinates of point B ”; cin >> b;

OurCrane.MoveToPoint(a);

OurCrane.LiftLoad();

OurCrane.MoveToPoint(b);

OurCrane.LowerLoad();

}

This main() function uses a Point object. It also uses a Crane object and implies that MoveToPoint(), LiftLoad() and LowerLoad() be member functions of the Crane class. This operation requires two points and three motors; one motor lifts and lowers the load, one motor drives in the X direction and another motor drives in the Y direction.

The corresponding Point class would be as follows:

class Point

{

private: int X; int Y;

public:

Point();

Point(int x, int y); void SetX(int x);