Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
lab1-2.doc
Скачиваний:
1
Добавлен:
01.07.2025
Размер:
488 Кб
Скачать
☆

1.3. Програма роботи

Використовуючи одну з мов об’єктно-орієнтованого програмування (наприклад Builder) написати програму для прийому та передачі даних через СОМ-порт.

1.4. Обладнання та програмне забезпечення

1.4.1. Персональний комп’ютер.

1.4.2. Одна з мов об’єктно-орієнтованого програмування.

1.5. Порядок виконання роботи

1.5.1. Перш за все, необхідно запустити сердовище Borland C++ Builder. Для цього зазвичай необхідно зайти в меню ПУСК → Программы → Borland C++ Builder 6 → C++ Builder 6 (рис. 5)

Рис. 5. Запуск C++ Builder із головного меню.

1.5.2. Після запуску середовища перед нами з’явиться 5 вікон:

  • Головне меню середовища (рис. 6)

Рис. 6. Головне меню середовища.

  • Вікно дерева об’єктів (рис.7)

Рис. 7. Вікно дерева об’єктів.

  • Вікно подій (рис. 8)

Рис. 8. Вікно подій.

  • Вікно з макетом форми програми, яку ми розробляємо (рис. 9)

Рис. 9. Форма програми.

  • Вікно з текстовим редактором, який призначений для написання коду програм додатку (рис. 10)

Рис. 10. Редактор для програмування.

4.5.3. Переіменуємо заголовок основної форми програми. Для цього перейдемо у вікно Object Inspector, в полі Caption введемо «СОМ-порт» (рис.11).

Рис. 11. Назва заголовку форми.

4.5.4. Перейдемо до розробки графічного інтерфейсу. Для забезпечення можливості налаштування параметрів послідовного порту вручну необхідно розташувати графічні елементи TEdit, TLabel, TButton, приблизно так як показано на рисунку 12.

Рис. 12. Вікно налаштування послідовног порту.

В конструкторі форми напишемо слідуючи код, який буде ініціалізувати графічний інтерфейс:

AnsiString SpeedValues[14];

SpeedValues[0]="300";

SpeedValues[1]="600";

SpeedValues[2]="1200";

SpeedValues[3]="2400";

SpeedValues[4]="4800";

SpeedValues[5]="9600";

SpeedValues[6]="14400";

SpeedValues[7]="19200";

SpeedValues[8]="38400";

SpeedValues[9]="56000";

SpeedValues[10]="57600";

SpeedValues[11]="115200";

SpeedValues[12]="128000";

SpeedValues[13]="256000";

for(int i=0; i<14; ++i)

{

Form1->CBSpeed1->Items->Add(SpeedValues[i]);

}

Form1->CBSpeed1->Text = SpeedValues[5];

AnsiString Parity[5];

Parity[0]="Чет";

Parity[1]="Нечет";

Parity[2]="Нет";

Parity[3]="Маркер";

Parity[4]="Пробел";

for(int i=0; i<5; ++i)

{

Form1->CBParity1->Items->Add(Parity[i]);

}

Form1->CBParity1->Text = Parity[2];

AnsiString StopBits[3];

StopBits[0] = "1";

StopBits[1] = "1.5";

StopBits[2] = "2";

for(int i=0; i<3; ++i)

{

Form1->CBStopBit1->Items->Add(StopBits[i]);

}

Form1->CBStopBit1->Text = StopBits[0];

AnsiString DataBits[5];

DataBits[0] = "4";

DataBits[1] = "5";

DataBits[2] = "6";

DataBits[3] = "7";

DataBits[4] = "8";

for(int i=0; i<5; ++i)

{

Form1->CBDataBit1->Items->Add(DataBits[i]);

}

Form1->CBDataBit1->Text = DataBits[4];

Form1->LStatus1->Caption = "Порт COM1 не ініціалізований";

4.5.5. Запрограмуємо кнопку «Ініціалізувати порт». Під ініціалізацією порту розуміємо наступне:

- визначення кількості наявних в системі послідовних портів (процедура описана на 7 – 8 сторінці методичних вказівок);

- реалізація алгоритму вибору необхідного вільного порту;

- отримання дескриптора порту за допомогою функції CreateFile (описана на сторінці 8 методичних вказівок);

- перевірка правильності отриманого дескриптору (необхідно перевірити чи не є дескриптор порту рівним INVALID_HANDLE_VALUE, якщо так, то необхідно прийняти відповідні міри по звершенню роботи програми, та інформуванні користувача);

- налаштувати порт використовуючи структуру DCB (процедура описана на 12 сторінці методичних вказівок);

- виконати очищення черги послідовного порту за допомогою функції PurgeComm (13 сторінка).

Перед тим як писати даний код, в заголовочному файлі форми, в розділі public, необхідно розмітити слідуючий рядок:

HANDLE hPort1;

Повністю код буде виглядати наступним чином (приблизно):

TRegistry *Reg = new TRegistry;

TStringList *Ts = new TStringList;

AnsiString port;

AnsiString SpeedValue;

AnsiString DataBits;

AnsiString Parity;

AnsiString StopBits;

DCB dcb;

Reg->RootKey = HKEY_LOCAL_MACHINE;

AnsiString key = "HARDWARE\\DEVICEMAP\\SERIALCOMM";

Reg->OpenKey(key,false);

Reg->GetValueNames(Ts);

port = Ts[0];

SpeedValue = Form1->CBSpeed1->Text;

DataBits = Form1->CBDataBit1->Text;

Parity = Form1->CBParity1->Text;

StopBits = Form1->CBStopBit1->Text;

hPort1 = CreateFile(port.c_str(),GENERIC_READ|

GENERIC_WRITE,0,NULL,OPEN_EXISTING,

FILE_FLAG_OVERLAPPED,NULL);

if (port == "COM1")

{

if ((hPort1 == INVALID_HANDLE_VALUE)||

(hPort1 == NULL))

{

MessageBox(NULL,"Помилка ініціалізаці COM1","Помилка",MB_ICONERROR);

return;

}

if (!GetCommState(hPort1,&dcb))

{

MessageBox(NULL,"Помилка отримання пораметрів COM1","Помилка",MB_ICONERROR);

return;

}

}

if (SpeedValue=="110") dcb.BaudRate=CBR_110;

if (SpeedValue=="300") dcb.BaudRate=CBR_300;

if (SpeedValue=="600") dcb.BaudRate=CBR_600;

if (SpeedValue=="1200") dcb.BaudRate=CBR_1200;

if (SpeedValue=="2400") dcb.BaudRate=CBR_2400;

if (SpeedValue=="4800") dcb.BaudRate=CBR_4800;

if (SpeedValue=="9600") dcb.BaudRate=CBR_9600;

if (SpeedValue=="14400") dcb.BaudRate=CBR_14400;

if (SpeedValue=="19200") dcb.BaudRate=CBR_19200;

if (SpeedValue=="38400") dcb.BaudRate=CBR_38400;

if (SpeedValue=="56000") dcb.BaudRate=CBR_56000;

if (SpeedValue=="57600") dcb.BaudRate=CBR_57600;

if (SpeedValue=="115200") dcb.BaudRate=CBR_115200;

if (SpeedValue=="128000") dcb.BaudRate=CBR_128000;

if (SpeedValue=="265000") dcb.BaudRate=CBR_256000;

if (DataBits=="4") dcb.ByteSize=4;

if (DataBits=="5") dcb.ByteSize=5;

if (DataBits=="6") dcb.ByteSize=6;

if (DataBits=="7") dcb.ByteSize=7;

if (DataBits=="8") dcb.ByteSize=8;

if (Parity=="Чет") dcb.Parity=EVENPARITY;

if (Parity=="Нечет") dcb.Parity=MARKPARITY;

if (Parity=="Нет") dcb.Parity=NOPARITY;

if (Parity=="Маркер") dcb.Parity=ODDPARITY;

if (Parity=="Пробел") dcb.Parity=SPACEPARITY;

if (StopBits=="1") dcb.StopBits=0;

if (StopBits=="1.5") dcb.StopBits=1;

if (StopBits=="2") dcb.StopBits=2;

if (port == "COM1")

{

if (!SetCommState(hPort1,&dcb))

{

MessageBox(NULL,"помилка встановлення параметрів COM1","Помилка",MB_ICONERROR);

return;

}

if (!PurgeComm(hPort1,PURGE_TXCLEAR | PURGE_RXCLEAR))

{

MessageBox(NULL,"Помилка очищення черги COM1","Помилка",MB_ICONERROR);

return;

}

Form1->LStatus1->Caption="Порт COM1 ініціалізовано";

}

4.5.6 Далі необхідно запрограмувати кнопку для деініціалізації послідовного порту (кнопка «Деініціалізувати порт»). Суть деініціалізації полягає в скиданні дескриптора відкритого порта. Код приведений нижче:

if (port == "COM1")

{

CloseHandle(hPort1);

Form1->LStatus1->Caption="Порт COM1 деініціалізовано";

}

4.5.7. Перейдемо до реалізації процедури запису/зчитування даних з порта. Для цього спочатку реалізуємо графічний інтерфейс користувача, який надасть змогу проводити дану процедуру. Розмістимо та скомпонуємо (на вибір програміста) наступні елементи графічного інтерфейсу на формі програми: TMemo (даний елемент слугуватиме для відображення даних отриманих з СОМ-порту), TEdit (даний елмент слугуватиме для введення даних, які будуть передаватись через послідовний порт), а також 2 елемента TButton (елементи управління процесом прийому та передачі).

4.5.8. Реалізуємо тепер програмно процедуру запису/зчитування (детально вона описана на сторінці 15-17 методичних матеріалів). Для організації зчитування даних з послідовного порту необхідно виконати наступні дії:

- перевести порт в режим прийому функцією SetCommMask;

- виконати процедуру зчитування за допомогою функці ReadFile.

Повністю даний код буде виглядати наступним чином ( записати необхідно в вікно редактора коди, яке відкриється коли 2чі клацнути мишкою по елементи TButton, який керує зчитуванням даних з порту):

if (!SetCommMask (hPort1, EV_RXCHAR))

{

ShowMessage("ПОМИЛКА ВСТАНОВЛЕННЯ МАСКИ ПОРТУ");

};

COMSTAT CommStat;

DWORD dwError;

DWORD dwRead;

BYTE *Buf;

OVERLAPPED OverRead;

int i;

AnsiString STR;

OverRead.hEvent = CreateEvent(NULL, True, False, NULL);

if (OverRead.hEvent == Null)

{ShowMessage("Помилка при спробі зчитування порту");}

if(!ClearCommError(hPort1,&dwError,&CommStat)) {

MessageBox(NULL,"Помилка очищення порта","Помилка",MB_ICONERROR);}

dwRead = CommStat.cbInQue;

if (dwRead > 0)

{

Buf = new BYTE[dwRead];

if (!ReadFile(hPort,Buf,dwRead,&dwRead,&OverRead))

{

MessageBox(NULL,"Помилка читання порта","Помилка",MB_ICONERROR);

}

// В chReadBuff знаходяться прочитані байти

// Далі йде обробка отриманих байтів

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

{

STR=STR+char(Buf[i]);/* IntToStr(short(Buf[i])) + " "; */

}

Form1->Memo1->Lines->Add(STR);

delete Buf;

}

//тут Memo1 – об’єкт TMemo який слугує для відображення даних отриманих з СОМ-порта.

Процедура запису даних з порту схожа за принципом до зчитування, відмінність полягає в використанні функції WriteFile.

BYTE chWriteBuff[1024];

OVERLAPPED Sync;

DWORD dwWrite;

AnsiString str_buf;

int i;

str_buf = Edit1->Text;//.c_str()-48;

for(i=0;i<str_buf.Length();i++)

{

chWriteBuff[i]=char(str_buf[i+1]);

}

Sync.hEvent=CreateEvent(NULL,TRUE,FALSE,NULL);

if (Sync.hEvent==NULL)

{

ShowMessage("ПОМИЛКА СТВОРЕННЯ ПОДІЇ");

};

if (!WriteFile(hPort1, &chWriteBuff,str_buf.Length(), &dwWrite, &Sync))

{

if (GetLastError()!=ERROR_IO_PENDING)

{

ShowMessage("ПОМИЛКА ЗАПИСУ ДАНИХ");

}

}

1.5.9. Сворений проект необхідно відкомпілювати і запустити на виконання. Для компіляції модуля необхідно вибрати пункт меню Project | Compile Unit (або натиснути на клавіші Alt-F9). Цей метод зручний для віднаходження синтаксичних помилок в написаному коді, і відбуваєтсья без запуску програми в режим виконання. Для того щоб запустити програму не в середовищі програмування необхідно її зібрати, для цього виконують команду Project | Build. Для відлагодження внутрішніх помилок в програмі, які пов’язані з синтаксисом програми, а з логікою і внутрішньою організацією алгоритму, зручно запускати програму з середовища розробки, для цього слугує пункт меню Run | Run (F9), в даному режимі можна переглядати стан змінних програми, викликати відладник, ставити контрольні точки в коді, а також переглядати асемблер ний код програми.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]