//--------------------------------------------------------------
#ifndef Unit2H
#define Unit2H
//--------------------------------------------------------------#include <Classes.hpp>
//--------------------------------------------------------------class Executing: public TThread
{
private:
protected:
void __fastcall Execute();
public:
bool end;
__fastcall Executing(bool CreateSuspended);
};
//--------------------------------------------------------------#endif
//--------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "Unit1.h"
#include "Unit2.h"
#include <stdio.h>
#include "ProgExchCl_b.h"
#include "Udevices.h"
#define SecondLevelNodeAccess Form1->XMLDocument1->DocumentElement->ChildNodes
#define ThirdLevelNodeAccess(a) Form1->XMLDocument1->DocumentElement->ChildNodes->GetNode(a)->ChildNodes
#define FourthLevelNodeAccess(a, b) Form1->XMLDocument1->DocumentElement->ChildNodes->GetNode(a)->ChildNodes->GetNode(b)->ChildNodes
char received_data[255];
PModule Module; // массив модулей
PCorrection Correction; // массив исправлений
HANDLE m_Disp = NULL; // для монитора
int wrtd, // для функции mWrite
cor_count; // количество исправлений
TCom* ComPort; // порт
//--------------------------------------------------------------
void __fastcall msg(char *str)//сообщение для монитора
{
if(!mWrite(m_Disp, (AnsiString(str)+AnsiString("\n\r")).c_str(), strlen(str)+2, &wrtd));
}
void __fastcall logmsg(AnsiString mes)//сообщение в поле мемо
{
Form1->LogText->Lines->Add(mes);
}
//--------------------------------------------------------------char __fastcall DeviceOrModule(AnsiString Parameter, int* item_index) // определить что было передано с начальными параметрами: прибор или модуль и выдать порядковый номер нужного тега.
{
int i, all_nodes;
// ищем прибор
all_nodes = SecondLevelNodeAccess->GetCount(); // количество тегов второго уровня
for (i = 0; i < all_nodes; i++) {
if(AnsiString(SecondLevelNodeAccess->GetNode(i)->Attributes[WideString("name")]) == Parameter){
*item_index = i;
return 1;
}
}
// если прибор не найден, ищем модуль в теге default
all_nodes = SecondLevelNodeAccess->FindNode("default")->ChildNodes->GetCount(); // количество тегов третьего уровня в теге default
for (i = 0; i < all_nodes; i++) {
if(AnsiString(SecondLevelNodeAccess->FindNode("default")->ChildNodes->GetNode(i)->Text) == Parameter){
*item_index = i;
return 2;
}
}
return 0;
}
//--------------------------------------------------------------
void __fastcall GetModuleList(AnsiString Parameter, PModule* ModuleList, int item_index, int* modules_counter) // получение списка модулей входящих в состав прибора
{
int i, j, k, p, all_modules, version_count;
AnsiString mes;
*modules_counter = ThirdLevelNodeAccess(item_index)->GetCount(); // количество модулей в приборе
*ModuleList = new TModule[*modules_counter]; // выделяем память под массив модулей
for (i = 0; i < *modules_counter; i++) { // заполняем поля name и baseaddress
if(cor_count)
{
for(j = 0; j < cor_count; j++) {
if (AnsiString(ThirdLevelNodeAccess(item_index)->GetNode(i)->GetNodeValue()) == Correction[j].name) {
(*ModuleList)[i].name = Correction[j].new_name;
break;
}
else (*ModuleList)[i].name = AnsiString(ThirdLevelNodeAccess(item_index)->GetNode(i)->GetNodeValue());
}
}
else (*ModuleList)[i].name = AnsiString(ThirdLevelNodeAccess(item_index)->GetNode(i)->GetNodeValue());
(*ModuleList)[i].baseaddress = StrToInt(ThirdLevelNodeAccess(item_index)->GetNode(i)->Attributes[WideString("baseaddress")]);
}
// LOG->Add(AnsiString());
// активизация dll со списком модулей
Form1->XMLDocument1->FileName = "module_list.xml";
Form1->XMLDocument1->Active = true;
all_modules = SecondLevelNodeAccess->GetCount(); // сколько всего модулей в базе
for (i = 0; i < *modules_counter; i++) {
for (j = 0; j <= all_modules; j++) { // заполняем поля version
if (j >= all_modules) { // не нашли модуль (ошибка в файле с исправлениями)
mes = AnsiString("Не найден модуль ") + (*ModuleList)[i].name;
MessageBox(NULL, mes.c_str(), "Ошибка", MB_ICONERROR | MB_OK);
break;
}
if ((*ModuleList)[i].name == AnsiString(ThirdLevelNodeAccess(j)->GetNode(0)->GetNodeValue())) {
(*ModuleList)[i].version_count = ThirdLevelNodeAccess(j)->GetCount() - 1;
for (k = 0; k < (*ModuleList)[i].version_count; k++) {
(*ModuleList)[i].version[k] = new TVersion;
(*ModuleList)[i].version[k]->address = StrToInt(FourthLevelNodeAccess(j, k+1)->GetNode(0)->NodeValue);
(*ModuleList)[i].version[k]->value = StrToInt(FourthLevelNodeAccess(j, k+1)->GetNode(1)->NodeValue);
(*ModuleList)[i].version[k]->type = StrToInt(FourthLevelNodeAccess(j, k+1)->GetNode(2)->NodeValue);
(*ModuleList)[i].version[k]->description = AnsiString(ThirdLevelNodeAccess(j)->GetNode(k+1)->Attributes[WideString("description")]);
}
break;
}
}
// LOG->Add(ModuleList[i].name + AnsiString(" ") + ModuleList[i].baseaddress);
}
}
//--------------------------------------------------------------
void __fastcall GetModule(AnsiString Parameter, PModule* ModuleList, int item_index) // получаем информацию для одного модуля
{
int i, j, all_modules;
*ModuleList = new (TModule);
(*ModuleList)[0].name = AnsiString(Form1->XMLDocument1->DocumentElement->ChildNodes->FindNode("default")->ChildNodes->GetNode(item_index)->GetNodeValue());
(*ModuleList)[0].baseaddress = StrToInt(Form1->XMLDocument1->DocumentElement->ChildNodes->FindNode("default")->ChildNodes->GetNode(item_index)->Attributes[WideString("baseaddress")]);
Form1->XMLDocument1->FileName = "module_list.xml";
Form1->XMLDocument1->Active = true;
all_modules = SecondLevelNodeAccess->GetCount();
for (i = 0; i <= all_modules; i++) {
if (i >= all_modules) {
MessageBox(NULL, "Модуль не был найден. Версия недоступна", "Error", MB_ICONERROR | MB_OK);
break;
}
if ((*ModuleList)[0].name == AnsiString(ThirdLevelNodeAccess(i)->GetNode(0)->GetNodeValue())) {
(*ModuleList)[0].version_count = ThirdLevelNodeAccess(i)->GetCount() - 1;
for (j = 0; j < (*ModuleList)[0].version_count; j++) {
(*ModuleList)[0].version[j] = new TVersion;
(*ModuleList)[0].version[j]->address = StrToInt(FourthLevelNodeAccess(i, j+1)->GetNode(0)->NodeValue);
(*ModuleList)[0].version[j]->value = StrToInt(FourthLevelNodeAccess(i, j+1)->GetNode(1)->NodeValue);
(*ModuleList)[0].version[j]->type = StrToInt(FourthLevelNodeAccess(i, j+1)->GetNode(2)->NodeValue);
(*ModuleList)[0].version[j]->description = AnsiString(ThirdLevelNodeAccess(i)->GetNode(j+1)->Attributes[WideString("description")]);
}
break;
}
}
/* LOG->Add((*ModuleList)[0].name + AnsiString(" ") + (*ModuleList)[0].baseaddress);
for (i = 0; i < (*ModuleList)[0].version_count; i++) {
LOG->Add((*ModuleList)[0].version[i]->address);
LOG->Add((*ModuleList)[0].version[i]->value);
LOG->Add((*ModuleList)[0].version[i]->type);
} */
}
//--------------------------------------------------------------
unsigned int _fastcall get_version(unsigned int BaseAddress, unsigned int type) // считываем версию с модуля
{
unsigned short i, j;
unsigned short SHsum; // контрольная сумма
unsigned char* pTarget = new unsigned char[10];
unsigned char* pReceived;
unsigned short MessageSize = 6;
unsigned int version;
ComPort = new TCom("COM2", 115200);
i = ComPort->link_on();
if(i) {
MessageBox(NULL, AnsiString(i).c_str(), "Ошибка инициализации порта", MB_OK);
return 0;
}
pTarget[0]= 0x31;
pTarget[1]=(unsigned char)(MessageSize); //младший байт
pTarget[2]=(unsigned char)(MessageSize>>8); //старший байт
pTarget[3] = 0x04;
pTarget[4] = (unsigned char) type;
*(int*)(pTarget + 0x05) = BaseAddress;
version = 0;
SHsum=0x0;
for (i=3; i<=8; i++){SHsum+=pTarget[i];} //подсчёт КС
// MessageBox(NULL, AnsiString(SHsum).c_str(), "Контрольная сумма", MB_OK);
pTarget[9]=(unsigned char)(SHsum);//младший байт
pTarget[10]=(unsigned char)(SHsum>>8);//старший байт
ComPort->write(pTarget, 3+MessageSize+2);
delete [] pTarget;
Sleep(100);
i = ComPort->read();
if(i>0)
{
// MessageBox(NULL, AnsiString(i).c_str(), "Принято байт", MB_OK);
pReceived = ComPort->get_receiver_ptr(); //считываем полученное значение
if (pReceived[0]!= 0x55 || pReceived[1]!= 0xAA) {
MessageBox(NULL, pReceived, "Ошибка", MB_OK);
return 0;
}
// наложение масок
switch (type) {
case 1:
version = (unsigned int) (*(char*)(pReceived + 5))&0x000000FF;
break;
case 2:
version = (unsigned int) (*(short*)(pReceived + 5))&0x0000FFFF;
break;
case 4:
version = (unsigned int) *(int*)(pReceived + 5);
break;
default:
version = (unsigned int) (*(short*)(pReceived + 5))&0x0000FFFF;
break;
}
}
ComPort->link_off();
return version;
}
__fastcall Executing::Executing(bool CreateSuspended)// конструктор
: TThread(CreateSuspended)
{
end = false; // метка окончания = ложно
}
//--------------------------------------------------------------
int __fastcall get_correction(PCorrection* CorrectionList) // обработка файла исправлений
{
int i = 0;
int j = 0;
int n = 0;
int correction_counter = 0; // количество исправлений
FILE* CorrectFilePtr; // файл с исправлениями
char tempchar = ' ';
char* tempFile; //массив под файл с сиправлениями
char control_buff[20]; // массив знаков препинания
if ((CorrectFilePtr = fopen("corrections.txt","r")) == NULL) {
return 0;
}
// узнаем размер файла и выделяем временный массив под файл
fseek(CorrectFilePtr,0L,SEEK_END);
n = ftell(CorrectFilePtr);
fseek(CorrectFilePtr,0L,SEEK_SET);
tempFile = new char[n];
//исправляем возможные ошибки пунктуации
while(tempchar == '\n' || tempchar == ' '){
tempchar = fgetc(CorrectFilePtr);
}
tempFile[0] = tempchar;
i = 1;
while (1){
tempchar = fgetc(CorrectFilePtr);
if(tempchar == '\n'){
continue;
}
if(tempchar == ' '){
continue;
}
if(tempchar == '='){
control_buff[j] = tempchar;
j++;
}
if(tempchar == ';'){
control_buff[j] = tempchar;
correction_counter++;
j++;
}
if(tempchar == EOF){
tempFile[i] = tempchar;
control_buff[j] = tempchar;
break;
}
tempFile[i] = tempchar;
i++;
}
//правильно ли расставлены знаки припенания
for (i = 0; i <= j; i++){
if(control_buff[i] == '='){
if(control_buff[i+1]!= ';'){
logmsg("В файле корректировки обнаружена ошибка. Корректировки учтены не будут33");
return 0;
}
}
if(control_buff[i] == ';'){
if(!(control_buff[i+1] == '=' || control_buff[i+1] == EOF)){
logmsg("В файле корректировки обнаружена ошибка. Корректировки учтены не будут331");
return 0;
}
}
}
// MessageBox(NULL, tempFile,"Пpочитано",MB_OK);
*CorrectionList = new TCorrection[correction_counter];
//заполянем массив исправлений
tempchar = 0;
i = 0;
n = 0;
while (tempchar!= EOF) {
while(tempFile[i]!= '=') {
(*CorrectionList)[n].name += tempFile[i++];
}
// (*CorrectionList)[n].name[j] = '\0';
i++;
while(tempFile[i]!= ';') {
(*CorrectionList)[n].new_name += tempFile[i++];
}
// (*CorrectionList)[n].new_name[j] = '\0';
n++;
tempchar = tempFile[++i];
}
/* for (j = 0; j < correction_counter; j++) {
MessageBox(NULL, (*CorrectionList)[j].name,"",MB_OK);
MessageBox(NULL, (*CorrectionList)[j].new_name,"",MB_OK);
} */
delete [] tempFile;
fclose(CorrectFilePtr);
return correction_counter;
}
//--------------------------------------------------------------void __fastcall Executing::Execute()
{
CoInitialize(NULL);
char item_type;
DWORD res;
char received_data[255];
unsigned int received_version = 0;
AnsiString mes;
int i, j, index, modules_counter, all_modules, p, param_num;
int error = 0;
if(!FileExists("device_list.xml")){
MessageBox(NULL, "Файл device_list.xml не был найден ", "Ошибка", MB_ICONERROR | MB_OK);
PostMessage(Form1->Handle, WM_CLOSE, 0,0);
return;
}
if(!FileExists("module_list.xml")){
MessageBox(NULL, "Файл module_list.xml не был найден ", "Ошибка", MB_ICONERROR | MB_OK);
PostMessage(Form1->Handle, WM_CLOSE, 0,0);
return;
}
// обработка входных параметров
if (ParamCount() == 0) {
MessageBox(NULL, "Не было передано ни одного параметра!", "Ошибка", MB_ICONERROR | MB_OK);
PostMessage(Form1->Handle, WM_CLOSE, 0,0);
return;
}
// получить управление над функциями библиотеки ProgExchCl.dll
res = ProgExchCl_LoadLibrary();
if(res!= 0x0)
{
sprintf(received_data, "Ошибка %d при обращении к библиотеке \"ProgExchCl.dll\".", res);
MessageBox(NULL, received_data, "Ошибка", MB_OK);
}
//открытие канала выдачи данных на экран
sprintf(received_data, "PipeDisplay%d", GetCurrentProcessId());
res = mOpen(received_data, &m_Disp);
if(res == 0x0)
{
// перевести вывод в режим отладочной (0x01 0x02) или отчетной (0x01 0x01) информации
received_data[0] = 0x01; received_data[1] = 0x01;
res = mWrite(m_Disp, received_data, 2, &wrtd);
if(res!= 0x0)
{
sprintf(received_data, "Ошибка %d при переводе вывода в режим отладочной информации", res);
MessageBox(NULL, received_data, "Ошибка", MB_OK);
logmsg(received_data);
}
Form1->WindowState = wsMinimized;
}
else {
sprintf(received_data, "Ошибка %d при открытии канала выдачи данных на экран", res);
logmsg(AnsiString(received_data));
logmsg(AnsiString("Режим автономной работы"));
Form1->WindowState = wsNormal;
}
cor_count = get_correction(&Correction);
// открытие XML-файла
Form1->XMLDocument1->FileName = "device_list.xml";
Form1->XMLDocument1->Active = true;
item_type = DeviceOrModule(ParamStr(1), &index);
// получение списка модулей входящих в состав прибора
if (item_type == 0){
MessageBox(NULL, "Прибор или модуль не был найден", "Ошибка", MB_ICONERROR | MB_OK);
PostMessage(Form1->Handle, WM_CLOSE, 0,0);
return;
}
if (item_type == 1) {
GetModuleList(ParamStr(1), &Module, index, &modules_counter);
if(index == -1) {
PostMessage(Form1->Handle, WM_CLOSE, 0,0);
return;
}
mes = AnsiString("Проверка версии прибора: ") + ParamStr(1);
}
if (item_type == 2) {
GetModule(ParamStr(1), &Module, index);
if(index == -1) {
PostMessage(Form1->Handle, WM_CLOSE, 0,0);
return;
}
mes = AnsiString("Проверка версии модуля: ") + ParamStr(1);
modules_counter = 1;
}
msg(" ");
msg(" ");
msg(mes.c_str());
logmsg(mes.c_str());
// перевести вывод в режим отладочной (0x01 0x02) или отчетной (0x01 0x01) информации
received_data[0] = 0x01; received_data[1] = 0x02;
res = mWrite(m_Disp, received_data, 2, &wrtd);
if(res!= 0x0)
{
// sprintf(received_data, "Ошибка %d при переводе вывода в режим отладочной информации", res);
// MessageBox(NULL, received_data, "Ошибка", MB_OK);
}
// вывод результатов тестирования по каждому модулю
for (i = 0; i < modules_counter; i++) {
// название модуля
msg(" ");
msg(Module[i].name.c_str());
logmsg(" ");
logmsg(Module[i].name.c_str());
for (j = 0; j < Module[i].version_count; j++) {
received_version = get_version((unsigned int) (Module[i].baseaddress + Module[i].version[j]->address), Module[i].version[j]->type);
// если версии совпадают, то НОРМА, если не совпадают, то НЕНОРМА
if(received_version == Module[i].version[j]->value){
mes =AnsiString(" ") + Module[i].version[j]->description + AnsiString(" 0x") + IntToHex((int) Module[i].version[j]->value, Module[i].version[j]->type) + AnsiString(":HOPMA ");
msg(mes.c_str());
logmsg(mes.c_str());
}
else {
mes =AnsiString(" ") + Module[i].version[j]->description + AnsiString(" 0x") + IntToHex((int) received_version, Module[i].version[j]->type) + AnsiString(":HEHOPMA ") + AnsiString("(должно быть 0x") + IntToHex((int) Module[i].version[j]->value, Module[i].version[j]->type) + AnsiString(")");
msg(mes.c_str());
logmsg(mes.c_str());
error+=1;
}
}
}
// перевести вывод в режим отладочной (0x01 0x02) или отчетной (0x01 0x01) информации
received_data[0] = 0x01; received_data[1] = 0x01;
res = mWrite(m_Disp, received_data, 2, &wrtd);
if(res!= 0x0)
{
// sprintf(received_data, "Ошибка %d при переводе вывода в режим отчетной информации", res);
// MessageBox(NULL, received_data, "Ошибка", MB_OK);
}
// общий результат тестирования
if(error) {
msg(" ");
msg("Результат: НЕНОРМА");
logmsg(" ");
logmsg("Результат: НЕНОРМА");
}
else {
msg(" ");
msg("Результат: НОРМА");
logmsg(" ");
logmsg("Результат: НОРМА");
}
// освобождаем динамически выделенную память
if (item_type == 1) {
delete [] Module;
}
else delete Module;
delete [] Correction;
if(mClose!= NULL)
{
// отключить каналы обмена
mClose(m_Disp);
}
ProgExchCl_FreeLibrary();
CoUninitialize();
PostMessage(Form1->Handle, WM_CLOSE, 0,0);
}
//--------------------------------------------------------------
#ifndef Unit1H
#define Unit1H
//--------------------------------------------------------------#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
#include <msxmldom.hpp>
#include <XMLDoc.hpp>
#include <xmldom.hpp>
#include <XMLIntf.hpp>
//--------------------------------------------------------------
typedef struct _SVersion{
unsigned int address; //адрес регистра версии
unsigned int value; //считанное значение версии
unsigned int type; //разрядность версии
AnsiString description;//описание версии
} TVersion,* PVersion;
typedef struct _SModule{
AnsiString name; //имя модуля
unsigned int baseaddress; //базовый адрес модуля
int version_count;//количество версий у модуля
PVersion version[10]; //массив версий модуля
} TModule,* PModule;
typedef struct _SCorrection{
AnsiString name;
AnsiString new_name;
} TCorrection,* PCorrection;
class TForm1: public TForm
{
__published: // IDE-managed Components
TXMLDocument *XMLDocument1;
TMemo *LogText;
void __fastcall FormActivate(TObject *Sender);
void __fastcall FormClose(TObject *Sender, TCloseAction &Action);
private: // User declarations
public: // User declarations
__fastcall TForm1(TComponent* Owner);
};
//--------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//--------------------------------------------------------------
#endif
//--------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "Unit1.h"
#include "Unit2.h"
#include <stdio.h>
//--------------------------------------------------------------#pragma package(smart_init)
#pragma resource "*.dfm"
Executing *Thread;
TForm1 *Form1;
tagMSG lpMsg;
//--------------------------------------------------------------__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//--------------------------------------------------------------
void __fastcall TForm1::FormActivate(TObject *Sender)
{
Thread = new Executing(FALSE); // запускаем поток
}
//--------------------------------------------------------------
void __fastcall TForm1::FormClose(TObject *Sender, TCloseAction &Action)
{
Thread->WaitFor();
delete (Thread);
}
//--------------------------------------------------------------
//---------------------------------------------------------------------------
#ifndef UdevicesH
#define UdevicesH
#include <classes.hpp>
//#include "U_MK_pipe.h"
#include <Mask.hpp>
//--------------------------------------------------------------// Абстрактный класс, реализующий базовые функции любого устройства
class TDevFather: public TObject
{
__published:
private: // User declarations
protected:
bool active;
char receiver[0x1000];//априорно выделено 4кб буфера, приготовлены для отправки классу монитору
int receiver_size;//размер реально принятых байт в буфере
public:
virtual __fastcall TDevFather();
virtual __fastcall ~TDevFather();
virtual int __fastcall link_on();
virtual int __fastcall link_off();
//функции для работы с мостом в целях ввода/вывода
//чтение из буфера устройтва
virtual int __fastcall scan();//Возвращает признак состояния устройства
virtual int __fastcall read();//Если положительное число, то это число пинятых байт, если отрицательное, то это код ошибки
virtual char* __fastcall get_receiver_ptr();//
//отправить данные
virtual int __fastcall write(char* chs, int size);//передача символов/байтов на устройство
//запись в буфер
//virtual int __fastcall add_to_sender(char* chs, int size);//передача символов/байтов в передающий буфер
};
//--------------------------------------------------------------
class TCom: public TDevFather
{
__published:
private: // User declarations
protected:
AnsiString comname;
int baudrate;
HANDLE com_hndl;
DCB st_dcb;
public:
virtual __fastcall TCom(char* comname, int baudrate);
virtual __fastcall ~TCom();
int __fastcall link_on();
int __fastcall link_off();
//функции для работы с мостом в целях ввода/вывода
//чтение из буфера устройтва
int __fastcall scan();//Возвращает признак состояния устройства
int __fastcall read();//Если положительное число, то это число пинятых байт, если отрицательное, то это код ошибки
//virtual char* __fastcall get_receiver_ptr();// метод наследуется без изменения
//отправить данные
virtual int __fastcall write(char* chs, int size);//передача символов/байтов на устройство
//запись в буфер
//virtual int __fastcall add_to_sender(char* chs, int size);//передача символов/байтов в передающий буфер
void __fastcall set_comname(AnsiString comname);
void __fastcall set_baudrate(int baudrate);
AnsiString __fastcall get_comname();
int __fastcall get_baudrate();
};
//--------------------------------------------------------------#endif
//--------------------------------------------------------------
#pragma hdrstop
#include <Forms.hpp>
#include <Mask.hpp>
#include "Udevices.h"
//--------------------------------------------------------------__fastcall TDevFather::TDevFather(){}
//--------------------------------------------------------------__fastcall TDevFather::~TDevFather(){}
//--------------------------------------------------------------int __fastcall TDevFather::link_on()
{ return 0; }
//--------------------------------------------------------------int __fastcall TDevFather::link_off()
{ return 0; }
//-------------------------------------------------------------- //функции для работы с мостом
int __fastcall TDevFather::scan()//Возвращает признак состояния устройства
{
//
return receiver_size;
}
//---------------------------------------------------------------------------
int __fastcall TDevFather::read()//Если положительное число, то это число принятых байт, если отрицательное, то это код ошибки
{
//
return receiver_size;
}
//---------------------------------------------------------------------------
char* __fastcall TDevFather::get_receiver_ptr()//
{
return receiver;
}
//---------------------------------------------------------------------------
int __fastcall TDevFather::write(char* chs, int size)
{
return size;
}
//---------------TCom-------------------------------------------__fastcall TCom::TCom(char* comname, int baudrate)
{
//
TCom::comname=comname; //="COM1";
TCom::baudrate=baudrate; //=115200;
active=false;
}
//--------------------------------------------------------------__fastcall TCom::~TCom()
{
//
if(active)
{
link_off();
}
}
//--------------------------------------------------------------int __fastcall TCom::link_on()
{
//
if (!active)
{
com_hndl=CreateFile(comname.c_str(), GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0);
if (com_hndl == INVALID_HANDLE_VALUE)
{
//MessageBoxA(0,"Invalid handle value","Simple_COM", MB_OK);
active=false;
return -1;
}
//настройка параметров соединения
st_dcb.DCBlength= sizeof(DCB);
st_dcb.Parity=NOPARITY; //NOPARITY, ODDPARITY, MARKPARITY, EVENPARITY
st_dcb.StopBits=ONESTOPBIT; //ONESTOPBIT, ONE5STOPBITS, TWOSTOPBITS
st_dcb.ByteSize=8; //4-8
st_dcb.BaudRate=baudrate; //CBR_115200
SetCommState(com_hndl, &st_dcb);
if (com_hndl == INVALID_HANDLE_VALUE)
{
//MessageBoxA(0,"Invalid handle value","Simple_COM", MB_OK);
active=false;
return -1;
}
SetupComm(com_hndl, 40000, 40000);//размеры банков
if (com_hndl == INVALID_HANDLE_VALUE)
{
//MessageBoxA(0,"Invalid handle value","Simple_COM", MB_OK);
active=false;
return -1;
}
SetCommMask(com_hndl,EV_RXCHAR);
if (com_hndl == INVALID_HANDLE_VALUE)
{
//MessageBoxA(0,"Invalid handle value","Simple_COM", MB_OK);
active=false;
return -1;
}
active=true;
};
if (!active)
{
return -1;
}else{
return 0;
}
}
//--------------------------------------------------------------int __fastcall TCom::link_off()
{
//
if (active)
{
active=false;
CloseHandle(com_hndl);
return 0;
}
else
{
active=false;
return -1;
}
}
//--------------------------------------------------------------int __fastcall TCom::scan()//Возвращает признак состояния устройства
{
COMSTAT st;
unsigned long Err;
if (active)
{
if (ClearCommError(com_hndl, &Err, &st))
{
return st.cbInQue;
}
else
{
//MessageBoxA(0,"Com scan error","Simple_COM", MB_OK);
return -1;
}
}
else
{
return 0;
}
}
//--------------------------------------------------------------int __fastcall TCom::read()//Если положительное число, то это число пинятых байт, если отрицательное, то это код ошибки
{
COMSTAT st;
unsigned long Err;
unsigned long readed_bytes;
//
readed_bytes=0;
if (active)
{
if (ClearCommError(com_hndl, &Err, &st))
{
if ((Err & CE_BREAK)>0)
{
//MessageBoxA(0,"Com read error: CE_BREAK","Simple_COM", MB_OK);
return -2;
}
if (0x1000>st.cbInQue)
{
if (! ReadFile(com_hndl, receiver, st.cbInQue, &readed_bytes, NULL))
{
//MessageBoxA(0,"Com read error: ReadFile 1","Simple_COM", MB_OK);
return -3;
}
}
else
{
if (! ReadFile(com_hndl, receiver, 0x1000, &readed_bytes, NULL))
{
//MessageBoxA(0,"Com read error: ReadFile 2","Simple_COM", MB_OK);
return -4;
}
}
}
else
{
//MessageBoxA(0,"0шибка сканирования устройства COM","Simple_COM", MB_OK);
}
}
return (int)readed_bytes;
}
//--------------------------------------------------------------int __fastcall TCom::write(char* chs, int size)
{
unsigned long sended;
//
sended=0;
if (! WriteFile(com_hndl, chs, (unsigned long)size, &sended, NULL))
{//ошибка
//MessageBoxA(0, "Ошибка передачи данных", "Simple_COM", MB_OK);
return -1;
}
return (int)sended;
}
//--------------------------------------------------------------
void __fastcall TCom::set_comname(AnsiString comname){}
void __fastcall TCom::set_baudrate(int baudrate){}
AnsiString __fastcall TCom::get_comname()
{//
return comname;
}
//--------------------------------------------------------------int __fastcall TCom::get_baudrate()
{//
return baudrate;
}