Студопедия
Случайная страница | ТОМ-1 | ТОМ-2 | ТОМ-3
АрхитектураБиологияГеографияДругоеИностранные языки
ИнформатикаИсторияКультураЛитератураМатематика
МедицинаМеханикаОбразованиеОхрана трудаПедагогика
ПолитикаПравоПрограммированиеПсихологияРелигия
СоциологияСпортСтроительствоФизикаФилософия
ФинансыХимияЭкологияЭкономикаЭлектроника

Міністерство освіти і науки, молоді та спорту України



Міністерство освіти і науки, молоді та спорту України

Дружківський технікум ДДМА

 

 

Наукова робота

За темою: «Використання об’єктно-орієнтованого програмування у керуванні нестандартним периферійним обладнанням»

 

 

Роботу виконав:

Студент гр. 1РПЗ-10

Погорілий В.В.

 

м. Дружківка 2013р.

На сьогоднішній день наука у галузі електроніки та комп’ютерної техніки стрімко рухається вперед. З кожним днем апаратне забезпечення та елементні бази застарівають і не задовольняють сучасних потреб. У даній науковій роботі представлено як можна ефективно використовувати застаріле апаратне забезпечення комп’ютерів та що корисного можна зробити із периферійних пристроїв комп’ютера, які вийшли з ладу.

Продовжуючи тему, примітимо, що останнім часом дедалі рідше і рідше використовується паралельний порт комп’ютера LPT, за допомогою якого здійснювався зв’язок між комп’ютером та такими периферійними пристроями як принтери, сканери, ксерокси та ін..

Якщо подивитись на принтер чи сканер з іншої сторони, то ці пристрої сміливо можна назвати верстатами з ЧПУ, де пристроєм програмного управління у них виступає комп’ютер. Але ці «верстати» дуже вузькоспеціалізовані. Та якщо, використавши деталі комп’ютерної периферії, яка вийшла з ладу, або ж модель дуже застаріла, переробивши електричну схему управління на потрібну та використати застарілу модель комп’ютера, який буде виступати пристроєм програмного управління, то отримаємо у кінцевому результаті невеликий верстат, у даному випадку свердлильно-фрезерний. Написати для нього програму управління із інтуїтивно-зрозумілим інтерфейсом та використовувати у навчальному процесі або ж у виробничому.

Щоб зрозуміти принцип роботи верстату і як програма керує ним, коротко розглянемо LPT-порт комп’ютера.

LPT-порт – це паралельний порт. Управління паралельним портом розділяється на два етапи - попереднє конфігурування (Setup) апаратних засобів порту і поточне (оперативне) перемикання режимів роботи прикладним або системним ПО. Оперативне перемикання можливо тільки в межах режимів, дозволених при конфігуруванні. Цим забезпечується можливість узгодження апаратури з ПО і блокування помилкових перемиканні, викликаних некоректними діями програми. Конфігурування LPT-порту залежить від його виконання. Порт, розташований на платі розширення (Мультикарта), встановлюється в слот ISA або ISA + VLB, конфігурується джамперами на самій платі. Порт на системній платі конфігурується через BIOS Setup.



Конфігуруванню підлягають наступні параметри:

Базова адреса - 3BCh, 378h або 278h. При ініціалізації BIOS перевіряє наявність портів за адресами саме в цьому порядку і, відповідно, привласнює виявленим портам логічні імена LPT1, LPT2, LPT3. Адреса 3BCh має адаптер порту, розташований на платі MDA або HGC. Більшість портів за умовчанням конфігуруються на адресу 378h і можуть перемикатися на 278h.

Використовувана лінія запиту переривання: для LPT - IRQ7, для LPT2 - IRQ5. Традиційно переривання від принтера не використовуються, і цей дефіцитний ресурс можна заощадити. Однак при використанні швидкісних режимів ЕСР (або Fast Centronics) робота через переривання може помітно підвищити продуктивність і знизити завантаження процесора.

Використання каналу DMA для режимів ЕСР і Fast Centronics - дозвіл і номер каналу DMA (за замовчуванням - 3).

Режими роботи порту:

SPP, PS / 2, Fast Centronics, ЕРР, ЕСР + ЕРР.

Із цих режимів роботи порту у курсовому проекті використовується ЕСР + ЕРР, бо він задовольняє усі необхідні потреби.

ЕСР + ЕРР - те ж, що і ЕСР, але запис в ECR коду режиму 100 переводить порт в ЕРР.

Призначення сигналів порту наведені у таблиці 1.

 

Таблиця 1 – Призначення сигналів порту

№ контакту

Адреса

1/0

сигнал

Призначення у верстаті

 

37Аh

1/0

Data Strobe

Управління основним рухом

 

378h

1/0

Data 0

Управління кроковим двигуном

 

378h

1/0

Data 0

 

378h

1/0

Data 0

 

378h

1/0

Data 0

 

378h

1/0

Data 0

Управління

Координатою Х

 

378h

1/0

Data 0

 

378h

1/0

Data 0

Управління координатою У

 

378h

1/0

Data 0

 

379h

 

Acknowledge

Датчик початку координати Х

 

379h

 

Busy

Датчик кінця координати Х

 

379h

 

Paper Out

Датчик початку координати У

 

379h

 

Select

Датчик кінця координати У

 

37Аh

1/0

Auto feed

Датчик підключення порту

 

379h

 

Error

GND

 

37Аh

1/0

Init

--

 

37Аh

1/0

Select Input

--

18-25

GND

-

GND

GND

 


Керування верстатом здійснюється через електричну схему (мал. 1), принцип дії якої полягає у роботі транзисторних ключів.

Мал. 1. Принципіальна схема управління верстатом.

 

Усі електронні компоненти, які були використані у даній електричній схемі наведені у таблиці 2.

Розглянувши відомості про LPT-порт та електричну схему керування верстатом, перейдемо до програми управління, написаної на мові програмування високого рівня С++, використовуючи класи та наслідування.

 

 

Таблиця 2. Використані електронні компоненти.

Програма дозволяє при мінімальному апаратному забезпеченні комп’ютера забезпечувати максимальну роботу верстату, не прив’язана до якоїсь певної операційної системи та не приводить до її збоїв.

Код програми складається із шести бібліотек. Розглянемо коротко кожну.

«Menus.h»

 

#include <stdio.h>

#include <iostream.h>

#include <stdlib.h>

#include <conIO.h>

#include <graphics.h>

#include <dos.h>

#include <string.h>

#include "Help.h"

int x11=0;

int x22=0;

int act=1;

int rr=0;

int en=0;

int i, j;

int q,Max_length_string=0,e,Kolvo_space;;

int Vozvrat;

int ONS=0;

int PONS=0;

struct Mas_Strok

{char *str;};

struct one

{Mas_Strok mas[20];};

one ons[10];

//function "item not selected"//

void no(char *pp)

{textcolor(YELLOW);

textbackground(BLUE);

cprintf("%s",pp);}

//function "item is selected"//

void yes(char *ps)

{textcolor(RED);

textbackground(WHITE);

cprintf("%s",ps);

textcolor(YELLOW);

textbackground(BLUE);}

//Realize printing on screen menu//

//Paint_Menu(max_string_length,Kolvo_strok,act)//

//---------------------------------------------//

////////function "painting menu"/////////////////

void Paint_Menu(int x1,int x2,char *qp, int a, int b, int c,int ONS)

{int q, e, i, Kolvo_space;

char *Stroka_1;

Stroka_1=qp;

i=0;

window(x1,x2,a+2+x1-1,b+3+x2-1);

clrscr();

textbackground(BLUE);

textcolor(YELLOW);

putch(201);

for(e=0;e<a;e++)

putch(205);

putch(187);

for(i=0;i<b;i++)

{putch(186);

if(i!=c-1)

no(ons[ONS].mas[i].str);

if(i==c-1)

yes(ons[ONS].mas[i].str);

if(strlen(ons[ONS].mas[i].str)<a)

{Kolvo_space=a-strlen(ons[ONS].mas[i].str);

for(e=0;e<Kolvo_space;e++)

cprintf(" "); }

putch(186);}

putch(200);

for(e=0;e<a;e++)

putch(205);

putch(188);}

//function realize menu//

int Menu(int x1, int x2, char *Stroka, int Kolvo_strok,int ONS)

{int i,j;

int q,Max_length_string=0,e,Kolvo_space;;

char *Stroka_1;

//Realize string interpretation//

Help objHelp;

clrscr();

x11=x1;

x22=x2;

Stroka_1=Stroka;

i=0;

ons[ONS].mas[i].str=strtok(Stroka_1,"^");

while(Stroka_1!=NULL)

{ons[ONS].mas[i].str=Stroka_1;

i++;

Stroka_1=strtok(NULL,"^");}

j=i;

for (q=0;q<10;q++)

for (i=0;i<Kolvo_strok;i++)

{if(strlen(ons[ONS].mas[i].str)>Max_length_string)

Max_length_string=strlen(ons[ONS].mas[i].str);}

Paint_Menu(x11,x22,Stroka,Max_length_string, Kolvo_strok, act, ONS);

//event loop//

rr=getch();

if(rr==80)

{act++;

if(act>Kolvo_strok)

act=1;

Paint_Menu(x11,x22,Stroka, Max_length_string, Kolvo_strok, act, ONS);}

if(rr==72)

{act--;

if(act<1)act=Kolvo_strok;

Paint_Menu(x11,x22,Stroka, Max_length_string, Kolvo_strok, act,ONS);}

if(rr==13)

{Vozvrat=act;

act=1;

return Vozvrat;}

if (rr==59)

{PONS=act;

act=1;

objHelp.Help_1(PONS,ONS);}

if (rr==27)

clrscr();} //End of "Menu"//

У цій бібліотеці описана реалізація малювання меню та виклик довідки по кожному з пунктів.

Мал. 2. Меню користувача

Довідка викликається загальноприйнятою клавішею F1 (мал.3).

Мал. 3. Виклик довідки по підпункту Програмне управління ► Введення дій

 

Довідки до кожного з підпунктів описані у бібліотеці «Help.h».

 

class Winp

{protected:

int chh;

int pc;

protected:

void Wind()

{window(39,1,80,10);

textbackground(BLUE);

textcolor(WHITE);}

protected:

void Windo()

{chh=getch();

window(39,1,80,10);

clrscr();

textbackground(BLUE);}

protected:

void Wind_1()

{window(1,1,80,10);

textbackground(BLUE);

textcolor(WHITE);}

protected:

void Windo_1()

{chh=getch();

window(1,1,80,10);

clrscr();

textbackground(BLUE);}};

class Help: protected Winp

{public:

void Help_1(int punct, int menu)

{Wind();

pc=punct;

if (menu==0)

{if(pc==1)

{cprintf("Данный пункт вызывает подменю программного управления станком,");

cprintf(" процедур подготовки станка к работе");

Windo();}

if(pc==2)

{cprintf("Данный пункт вызывает процедуру управления станком вручную,");

cprintf(" в режиме реального времени с помощью клавиатуры");

Windo();}

if(pc==3)

{cprintf("Данный пункт позволяет работать со станком с помощью");

cprintf(" готовых тех. процессов, описаных в текстовых файлах");

Windo();}

if(pc==4)

{cprintf("Выход из программы");

Windo();}}

if (menu==1)

{if(pc==1)

{cprintf("Ввод названия тех.. процесса");

Windo();}

if(pc==2)

{cprintf("Выход");

Windo();}

if(pc==3)

{cprintf("Нет справки по данному пункту");

Windo();}

if(pc>3)

{Wind();}}

if (menu==2)

{if(pc==1)

{cprintf("Нажмите ENTER, чтобы войти в подменю ввода тех. процесса");

Windo();}

if(pc==2)

{cprintf("Нажмите ENTER, чтобы посмотреть недавно введенный тех. процесс");

Windo();}

if(pc==3)

{cprintf("Нажмите ENTER, чтобы программа начала выполнять действия, описанные в вашем тех. процессе");

Windo();}

if(pc==4)

{cprintf("Отвод стола в нулевую точку");

Windo();}

if(pc>4)

{cprintf("Выход");

Windo();}}}

public:

void Help_2()

{Wind_1();

cprintf("Вы находитесь в ручном управлении станком");

cprintf(" Для управления используются следующие клавиши,");

cprintf(" расположенные на малой клавиатуре:");

cprintf(" 6 Х+; 4 Х-; 2 У-; 8 У+; 1 Х-У-; 3 Х-У+; 7 Х+У-; 9 Х+У+;");

cprintf(" Для включения двигателя со сверлом нажмите ENTER;");

cprintf(" Для выключения сверла нажмите DELETE;");

cprintf(" Для передвижения сверла вверх-вниз ");

cprintf(" используйте клавиши F11 и F12 соответственно");

Windo_1();}};

 

Найважливішою бібліотекою є «Step_Eng.h». У ній описана передача даних у порт.

 

class Step_Engine

{ public:

void Up_Engine()

{outport(0x378,8); delay(4);

outport(0x378,0); delay(0);

outport(0x378,4); delay(4);

outport(0x378,0); delay(0);

outport(0x378,2); delay(4);

outport(0x378,0); delay(0);

outport(0x378,1); delay(4);

outport(0x378,0); delay(0);}

 

void Down_Engine()

{outport(0x378,1); delay(4);

outport(0x378,0); delay(0);

outport(0x378,2); delay(4);

outport(0x378,0); delay(0);

outport(0x378,4); delay(4);

outport(0x378,0); delay(0);

outport(0x378,8); delay(4);

outport(0x378,0); delay(0);

}}; // END CLASS STEP_ENGINE //

//AUXILIARY FUNCTIONS//

class DC_Engine: public Step_Engine

{ protected:

void Stop(int Bit)

{outport(0x378,0); delay(1);

outport(0x378,Bit); delay(125);

outport(0x378,0);

window(1,1,80,25);

clrscr();

cprintf("„®бвЁЈ­гв Єа © бв®«! ЋвўҐ¤ЁвҐ бв®«ў ­г«Ґўго в®зЄг Ё Є®а४⭮ ўўҐ¤ЁвҐ вҐе­ЁзҐбЄЁ© Їа®жҐбб.");

getch();

clrscr();}

void DC_X_plus()

{//if(inportb(0x379)==151)

//Stop(128);

outport(0x378,64);

delay(4);

outport(0x378,0);}

void DC_X_minus()

{//if(inportb(0x379)==167)

//Stop(64);

outport(0x378,128);

delay(4);

outport(0x378,0);}

void DC_Y_plus()

{//if(inportb(0x379)==143)

//Stop(16);

outport(0x378,32);

delay(4);

outport(0x378,0);}

void DC_Y_minus()

{//if(inportb(0x379)==199)

//Stop(32);

outport(0x378,16);

delay(4);

outport(0x378,0);}

void Nonstandard(int Byte)

{outport(0x378,Byte);

delay(4);

outport(0x378,0);}

void DC_X_plus_hand(int dela)

{//if(inportb(0x379)==151)

//Stop(128);

outport(0x378,64);

delay(dela);

outport(0x378,0);}

void DC_X_minus_hand(int dela)

{//if(inportb(0x379)==167)

//Stop(64);

outport(0x378,128);

delay(dela);

outport(0x378,0);}

void DC_Y_plus_hand(int dela)

{//if(inportb(0x379)==143)

//Stop(16);

outport(0x378,32);

delay(dela);

outport(0x378,0);}

void DC_Y_minus_hand(int dela)

{//if(inportb(0x379)==199)

//Stop(32);

outport(0x378,16);

delay(dela);

outport(0x378,0);}

void Nonstandard_hand(int Byte,int dela)

{outport(0x378,Byte);

delay(dela);

outport(0x378,0);}

private:

int count;

protected:

//THIS FUNCTION DESCRIBES DRILLING PROCESS//

void Drill()

{for (count=0;count<90;count++)

{Down_Engine();

if (count==25)

outport(0x37a,0);}

for (count=0;count<90;count++)

{Up_Engine();

if (count==70)

outport(0x37a,1);}

outport(0x378,0);} // END function "DRILL" //

}; // END CLASS DC_ENGINE //

class Traning

{private:

int count;

int datch;

public:

void Null_Point()

{for (count=0;count<100;count++)

{//datch=inportb(0x379);

outport(0x378,16); delay(100);

if(inportb(0x379)==199 || inportb(0x379)==198)

{outport(0x378,0);delay(1);

outport(0x378,32);delay(165);

outport(0x378,0);break;}}delay(1);

for (count=0;count<100;count++)

{// datch=inportb(0x379);

outport(0x378,128); delay(100);

if(inportb(0x379)==151 || inportb(0x379)==150)

{outport(0x378,0);delay(1);

outport(0x378,64);delay(130);

outport(0x378,0);break;}}} // END FUNCTION "NULL_POINT"

void Extreme_Point()

{for (count=0;count<100;count++)

{//datch=inportb(0x379);

outport(0x378,32); delay(100);

if(inportb(0x379)==167 || inportb(0x379)==166)

{outport(0x378,0);delay(1);

outport(0x378,16);delay(165);

outport(0x378,0);break;}}

delay(1);

for (count=0;count<100;count++)

{ //datch=inportb(0x379);

outport(0x378,64); delay(100);

if(inportb(0x379)==143 || inportb(0x379)==142)

{outport(0x378,0);delay(1);

outport(0x378,128);delay(165);

outport(0x378,0);break;

}}} // END FUNCTION "EXTREME_POINT" //

}; // END CLASS "TRAINING" //

 

По назві класів та методів можна зрозуміти що вони роблять. Наприклад клас «Step_Engine» описує управління кроковим двигуном, його метод «Down_Engine» описує управління кроковим двигуном для опускання супорту, а «Up_Engine» підняття супорту. Обидва методі використовують функції стандартної бібліотеки «conio.h» -- outport(int Adress, int Byte) та delay(int Time). Функція outport() посилає у LPT-порт значення регістру «DATA», адреса «DATA» 0x378. Функція delay() задає затримку. В залежності від того, якою буде затримка буде змінюватись швидкість руху супорта та момент: менша затримка – вище швидкість переміщення, але менший момент; більша затримка – нижче швидкість переміщення, але більший момент. Клас «DC_Engine» описує управління двигунами постійного струму для переміщення столу по координатам та свердління. Клас «DC_Engine» є нащадком класу «Step_Engine», бо використовує у своєму методі «Drill» методи батьківського класу для переміщення супорту. У методах переміщення столу також використовуються стандартні функції outport() і delay(). Але тут затримка впливає не тільки на швидкість і момент двигунів, але і на точність верстату. Клас «Traning» містить методи підготовки верстату до роботи, а саме автоматичне переміщення столу у нульову точку, автоматичне переміщення столу для закріплення інструменту і заготовки. У цьому класі з’являється нова функція бібліотеки «conio.h» -- int inportb(int Adress). Ця функція не задає значення порту, а бере його. Але беремо мі його не з регістру «DATA», а з регістру «CONTROL», з адресою 0х379. Отже inportb(), опитуючи регістр «CONTROL», дозволяє працювати з датчиками переміщення, розміщених на цьому регістрі. Згадаємо принципіальну схему (мал. 1), на ній зображені перемикачі SA1-SA4, вони і є датчиками (мал. 4). Якщо кнопка датчика не натиснута, то значення байту «CONTROL» не змінюється і всі його виводи з’єднані із заземленням, але ж якщо кнопка буде натиснута, то значення «CONTROL» змінюється в залежності від того, якому виводу відповідає датчик.

Мал. 4. Зовнішній вигляд та конструктивні особливості перемикачів

 

Наступна бібліотека «Files.h» відповідає за зчитування технічних процесів із текстових файлів (мал. 5). Це потрібно для того, щоб не набирати знову і знову однотипні технічні процеси.

 

class Files

{protected:

struct DATAS

{int x1;

int x2;

int y1;

int y2;

int Z;};

DATAS Dataf[50];

int doom,Counter1,Counter2;

struct Strings

{char koord;

char znak;

int mm;};

Strings Struct[50];

char* stt;

public:

Files()

{Counter1=0;

Counter2=0;

doom=0;

for(int j=0;j<50;j++)

{Dataf[j].x1=0;

Dataf[j].x2=0;

Dataf[j].y1=0;

Dataf[j].y2=0;

Dataf[j].Z=0;}}

public:

FILE *file;

void process1()

{window(60,1,80,4);

clrscr();

putch(214);

for (int kk=0;kk<19;kk++)

putch(196);

putch(183);

putch(186);

for (kk=0;kk<19;kk++)

{putch(0);}

putch(186);

putch(211);

for(kk=0;kk<19;kk++)

putch(196);

putch(189);

window(61,2,79,3);

for (kk=0;kk<19;kk++)

{delay(150);

putch(177);}}

void Init_File()

{cprintf("Введите название файла - ");

gets(stt);}

void Read_File()

{Init_File();

Files();

file=fopen(stt,"r");

while (!feof(file))

{fscanf(file,"%c%c%i\n",&Struct[Counter1].koord,&Struct[Counter1].znak,&Struct[Counter1].mm);

if (Struct[Counter1].koord=='x' && Struct[Counter1].znak=='+')

Dataf[Counter2].x1=Struct[Counter1].mm;

if (Struct[Counter1].koord=='x' && Struct[Counter1].znak=='-')

Dataf[Counter2].x2=Struct[Counter1].mm;

if (Struct[Counter1].koord=='y' && Struct[Counter1].znak=='+')

Dataf[Counter2].y1=Struct[Counter1].mm;

if (Struct[Counter1].koord=='y' && Struct[Counter1].znak=='-')

Dataf[Counter2].y2=Struct[Counter1].mm;

if (Struct[Counter1].koord=='d' && Struct[Counter1].znak=='r')

Dataf[Counter2].Z=1;

if (Struct[Counter1].koord=='e' && Struct[Counter1].znak=='n')

Counter2++;

Counter1++;}

fclose(file);

doom=Counter2;}

void Write_File(int Doom)

{Init_File();

file=fopen(stt,"w");

j=0;

while (j<Doom)

{if(Dataf[j].x1!=0)

fprintf(file,"x+%i\n",Dataf[j].x1);

if(Dataf[j].x2!=0)

fprintf(file,"x-%i\n",Dataf[j].x2);

if(Dataf[j].y1!=0)

fprintf(file,"y+%i\n",Dataf[j].y1);

if(Dataf[j].y2!=0)

fprintf(file,"y-%i\n",Dataf[j].y2);

if(Dataf[j].Z!=0)

fprintf(file,"dr0\n");

fprintf(file,"en0\n");

j++;}

fclose(file);}

printf("x+_%i x-_%i y+_%i y-_%i Z_%i\n", Dataf[i].x1, Dataf[i].x2, Dataf[i].y1, Dataf[i].y2, Dataf[i].Z);}}};

 

Для простоти зчитування та написання технічних процесів зроблено шифрування, віддалено схоже на міжнародне кодування ISO 7bit. Наприклад запис у текстовому файлі «х+12» буде означати для програми, що треба перемістити стіл по координаті Х у позитивному напрямку на 12 міліметрів, а запис виду «dr0» означатиме, що у даній точці треба зробити отвір. Технічний процес розділений на блоки, які закінчуються ключовим записом «en0». Не можна, наприклад, написати у технічному процесі наступне: «x+12 x+21 х-10 у+2 dr0 en0», бо однотипні переміщення «х+12» і «х+21» повинні бути у різних блоках. Правильно буде записати так: «х+12 en0 x+21 x-10 y+2 dr0 en0». Також треба примітити, що кожна дія пишеться з нової строки, для простоти і зручності зчитування. Якщо ж технічний процес(ТП) був введений у самій програмі, то після виконання всіх дій користувачеві буде запропоновано зберегти ТП у текстовому файлі (мал. 6), після чого користувач введе назву текстового файлу, у який треба записати його ТП. Після цього програма створить у папці, де знаходиться програма, файл та зашифрує ТП у вище описаній системі.

 

Мал. 5. Зчитування технічного процесу з текстового файлу

 

Мал. 6. Запис технічного процесу у текстовий файл

 

Наступна бібліотека класів «Stanok.h»

Ця бібліотека забезпечує введення технічних процесів у програмі, перегляд їх, переклад міліметрів у дискети, взаємозв’язок різних підменю програми.

#include "menus.h"

#include "step_eng.h"

#include <math.h>

#include "Files.h"

class Processing: public DC_Engine, public Files

{protected:

struct Dat

{int x1;

int x2;

int y1;

int y2;

int Z;};

Dat Data[50], D[50];

int cot;

int Kolvo_cot;

private:

int array_x1[50];

int array_x2[50];

int array_y1[50];

int array_y2[50];

int array_Z[50];

float Discret_X, Discret_Y;

public:

char *CHAR;

Processing(): cot(0), Kolvo_cot(0)

{int clear;

for(clear=0;clear<50;clear++)

{Data[clear].x1=0;

Data[clear].x2=0;

Data[clear].y1=0;

Data[clear].y2=0;

Data[clear].Z=0;

array_x1[clear]=0;

array_x2[clear]=0;

array_y1[clear]=0;

array_y2[clear]=0;

array_Z[clear]=0;

Discret_X=0.85;

Discret_Y=0.35;}}

protected:

void Input_Data(int cot)

{int count1,count2,count3;

int rm;

while (rm!=6)

{count1=Menu(40,1,"Перемещение по Х+^Перемещение по Х-^Перемещение по У+^перемещение по У-^Сверление^выход",6,3);

switch (count1)

{case 1:

window(1,1,10,5);

cscanf("%i",&Data[cot].x1);

continue;

case 2:

window(1,1,10,5);

cscanf("%i",&Data[cot].x2);

continue;

case 3:

window(1,1,10,5);

cscanf("%i",&Data[cot].y1);

continue;

case 4:

window(1,1,10,5);

cscanf("%i",&Data[cot].y2);

continue;

case 5:

window(1,1,10,5);

cscanf("%i",&Data[cot].Z);

continue;

case 6:clrscr();rm=6;}}

window(50,1,70,5);

clrscr();

textbackground(BLUE);

textcolor(WHITE);}

protected:

void Conversion(float D_X, float D_Y)

{int index;

Discret_X=D_X;

Discret_Y=D_Y;

for(index=0;index<Kolvo_cot;index++)

{array_x1[index]=floor(Data[index].x1/Discret_X);

array_x2[index]=floor(Data[index].x2/Discret_X);

array_y1[index]=floor(Data[index].y1/Discret_Y);

array_y2[index]=floor(Data[index].y2/Discret_Y);

array_Z[index]=Data[index].Z;}}

protected:

void Print_Data()

{for(cot=0;cot<Kolvo_cot;cot++)

{cprintf("x+ %i ",Data[cot].x1);

cprintf(" x- %i ",Data[cot].x2);

cprintf(" y+ %i ",Data[cot].y1);

cprintf(" y- %i ",Data[cot].y2);

cprintf(" Drill %i ",Data[cot].Z);

cprintf("\n");}

getch();}

protected:

void Print_data()

{for(cot=0;cot<Kolvo_cot;cot++)

{cout << "x+ "<<Data[cot].x1;

cout << " x- "<<Data[cot].x2;

cout << " y+ "<<Data[cot].y1;

cout << " y- "<<Data[cot].y2;

cout << " Drill "<<Data[cot].Z<<endl;}}

protected:

void Nachalo()

{int counter;

int index;

Conversion(0.332, 0.3919);

for (counter=0; counter<Kolvo_cot; counter++)

{for (index=0; index<array_x1[counter]; index++)

{DC_X_plus();

if (inportb(0x379)==143)

{Stop(128);

Processing::Processing();

break;}}

for (index=0; index<array_x2[counter]; index++)

{DC_X_minus();

if (inportb(0x379)==151)

{Stop(64);

Processing::Processing();

break;}}

for (index=0; index<array_y1[counter]; index++)

{DC_Y_plus();

if (inportb(0x379)==167)

{Stop(16);

Processing::Processing();

break;}}

for (index=0; index<array_y2[counter]; index++)

{DC_Y_minus();

if (inportb(0x379)==199)

{Stop(32);

Processing::Processing();

break;}}

if(array_Z[counter]==1)

Drill();}

window(1,1,80,25);

clrscr();

textbackground(BLUE);

textcolor(WHITE);

cprintf("Выполнено!");

delay(1000);

clrscr();

cprintf("Записать этот алгоритм действий в текстовый файл? y/n");

gets(CHAR);

if (CHAR[0]=='y' || CHAR[0]=='Y')

{for(int ppp=0;ppp<Kolvo_cot;ppp++)

{Dataf[ppp].x1=Data[ppp].x1;

Dataf[ppp].x2=Data[ppp].x2;

Dataf[ppp].y1=Data[ppp].y1;

Dataf[ppp].y2=Data[ppp].y2;

Dataf[ppp].Z=Data[ppp].Z;}

Write_File(Kolvo_cot);

cprintf("Подождите, идет запись...");

process1();

delay(1000);

window(1,1,80,11);

clrscr();

textbackground(BLUE);

textcolor(WHITE);

cprintf("Записано!");

Processing::Processing();} else

Processing::Processing();}};

class Get_Menu: public Processing

{protected:

int Sub_Menu_2()

{int rpm=0;

int roma=0;

int ch=0;

do

{roma=Menu(1,1,"Ввод действий^Вывод действий на экран^Выполнение введенных действий^Отвод стола в нулевую точку^Отвод стола для крепления заготовки^Выход",6,2);

switch(roma)

{case 1:

Input_Data(Kolvo_cot);

Kolvo_cot++;

clrscr();

continue;

case 2:

{clrscr();

window(0,0,0,0);

clrscr();

textbackground(BLUE);

textcolor(WHITE);

Print_data();

getch();

window(1,1,80,25);

clrscr();

textbackground(BLUE);

textcolor(YELLOW);

cprintf("_");

continue;}

case 3:

{window(1,1,80,25);

clrscr();

cprintf("Пожалуйста подождите, идет обработка данных...");

delay(100);

process1();

window(1,1,80,25);

clrscr();

Nachalo();

getch();

continue;}

case 4:

{Traning object_Traning;

object_Traning.Null_Point();

window(50,3,70,6);

clrscr();

textbackground(BLUE);

textcolor(WHITE);

cprintf("Стол в нулевой точке. Все прошло отлично.");

delay(3000);

getch();

continue;}

case 5:

{Traning object_Traning;

object_Traning.Extreme_Point();}

case 6:rpm=6;}} while(rpm!=6);

return rpm;}

int Sub_Menu_1()

{int rpm=0;

int roma=0;

int ch=0;

do

{roma=Menu(20,5,"Ввод названия Тех.Процесса^Возврат",2,1);

switch(roma)

{case 1:

{clrscr();

window(1,1,80,11);

clrscr();

textbackground(BLUE);

textcolor(WHITE);

Read_File();

Kolvo_cot=doom;

cprintf("Идет извлечение данных, подождите...");

delay(1000);

process1();

for(int Counter3=0;Counter3<Kolvo_cot;Counter3++)

{Data[Counter3].x1=Dataf[Counter3].x1;

Data[Counter3].x2=Dataf[Counter3].x2;

Data[Counter3].y1=Dataf[Counter3].y1;

Data[Counter3].y2=Dataf[Counter3].y2;

Data[Counter3].Z=Dataf[Counter3].Z;}

window(1,1,80,25);

clrscr();

cprintf("Записано!");

getch();

continue; }

case 2:rpm=6;}} while(rpm!=6);

return rpm;}

int Sub_Menu_0()

{int rm=0;

int p=0;

int rom=0;

int ch=0;

do

{rom=Menu(1,1,"Программное управление^Ручное управление^Готовый тех.процесс^Выход",4,0);

outport(0x378,0);

switch(rom)

{case 1:

{p=Sub_Menu_2();

if(p==6)

continue;

p=0;}

case 2:

{clrscr();

window(1,1,80,25);

clrscr();

textbackground(BLUE);

textcolor(WHITE);

Hand object_Hand;

object_Hand.Hand_Control();

getch();

continue; }

case 3:

p=Sub_Menu_1();

if(p==6)

continue;

p=0;

case 4:rm=3;}} while (rm!=3);

return rm;}};

class my:public Get_Menu

{ public:

void General_Function()

{int index=0;

do

{index=Sub_Menu_0();

}while(index!=3);}};

 

Клас «Processing» є найважливішим. Його метод «Input_Data» забезпечує введення технічного процесу блоками у самій програмі у підпункті Програмне управління ► Введення дій (мал. 7). Метод «Conversion» описує переклад величини, яку користувач вводить (міліметри) у дискети. Це потрібно тому, що за один крок стіл переміщується не рівно на міліметр. Від правильно підібраних значень дискретів також залежить точність верстату.

Мал. 7. Програмне управління ► Введення дій

 

Метод «Print_Data» описує виведення на екрані у вигляді таблиці набраного технічного процесу (мал. 8).

Мал. 8. Виведення технічного процесу на екран

 

Наступний метод «Nachalo» виконує дії, описані користувачем у технічному процесі. Виконуються дії блоками, як і вводилися, постійно перевіряючи стан датчиків на той випадок, якщо користувач написав некоректний технічний процес і стіл у якомусь із напрямків дійшов до краю. Якщо ж це все ж таки сталося, то програма зупиняє роботу верстату і виводить попередження на екран.

І остання бібліотека «Hand.h». Вона описує ручне управління верстатом у режимі реального часу (мал. 9).

Мал. 9. Режим ручного управління

 

 

#include "stanok_1.h"

//CLASS OF MANUAL CONTROL//

class Hand: protected DC_Engine

{ private:

int chn;

void Get_Window(char *process)

{window(1,4,23,6); clrscr();

cprintf("Текущая операция: %s",process);}

void Get_Window_1()

{window(1,4,23,6);

clrscr();}

public:

int dela;

Hand():chn(0)

{dela=3;}

void Hand_Control()

{Help objectHelp;

while (chn!=27)

{window(1,1,20,3);

clrscr();

cout << "F1 - Вызов справки"<<endl<<"ESC - Выход";

chn=getch(); //POLL KEYS//

if (chn==72)

{DC_Y_plus_hand(dela);

Get_Window("Y+");}

if (chn==80)

{DC_Y_minus_hand(dela);

Get_Window("Y-");}

if (chn==75)

{DC_X_minus_hand(dela);

Get_Window("X-");}

if (chn==77)

{DC_X_plus_hand(dela);

Get_Window("X+");}

if (chn==71)

{Nonstandard_hand(160,dela);

Get_Window("X+ Y-");}

if (chn==73)

{Nonstandard_hand(96,dela);

Get_Window("X+ Y+");}

if (chn==79)

{Nonstandard_hand(144,dela);

Get_Window("X- Y-");}

if (chn==81)

{Nonstandard_hand(80,dela);

Get_Window("X- Y+");}

if (chn==43)

{dela++;

if (dela>20) dela=20;}

if (chn==45)

{dela--;

if (dela<2) dela=3;}

if (chn==60)

{outport(0x37a,0);}

if (chn==61)

{outport(0x37a,1);}

if (chn==59)

objectHelp.Help_2(); //HELP TOPICS//

if (chn==133)

{Up_Engine();

Get_Window("UP");}

if (chn==134)

{Down_Engine();

Get_Window("DOWN");}}

Get_Window_1();

clrscr();

Hand::Hand(); //CONSTRUCTOR CALL//}};

Ручне управління здійснюється через натискання клавіш клавіатури і обробкою їх кодів програмою через метод «Hand_Control» класу «Hand» (мал. 10).

Мал. 10. Довідка по ручному управлінню

 

Назва дії, яку виконує верстат виводиться на екран (мал. 11).

Мал. 11. Виведення на екран дій у ручному режимі управління.

 

 


Висновок

 

У цій науковій роботі ми розглянули як і де окрім стандартних ситуацій та задач можна використовувати об’єктно-орієнтоване програмування. Також розглянули принципи та особливості програмування LPT-порту на мові високого рівня С++. Верстат, приведений у даній науковій роботі (мал. 12), не є єдиним прикладом нестандартного периферійного обладнання. Це може бути що завгодно: роботи, світломузикальні пристрої, верстати інших типів, та багато іншого. Програма, описана у цій науковій роботі дала «друге життя» ксероксам та принтерам, які давно вийшли з ладу. Але скільки ще такого застарілого обладнання, якому так само можна дати друге життя, використовуючи знання у об’єктно-орієнтованому програмуванні та електроніці. Якщо описаний проект розширити та впровадити, як промислову галузь, то можна декілька вирішити проблему з утилізацією старих комп’ютерів та периферії та використовувати такі нестандартні пристрої у побуті, використовуючи любий комп’ютер з LPT-портом, не завдаючи шкоди ні комп’ютеру, ні операційній системі.


Список використаної літератури

 

  1. «Паралельні інтерфейси». http://phys.csu.ru/maelab/_frames/_lpt_1.htm
  2. «Об’єктно-орієнтоване програмування на С++» Р. Лафоре, «Питер», 2004-923с.

 


Дата добавления: 2015-09-29; просмотров: 22 | Нарушение авторских прав




<== предыдущая лекция | следующая лекция ==>
Что легче и проще – созидать с нуля, не имея ничего за пазухой, или разрушать то, что кажется тебе чуждым и непонятным? | Библиотека Московской школы политических исследований 1 страница

mybiblioteka.su - 2015-2024 год. (0.205 сек.)