Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
диплом2015.docx
Скачиваний:
84
Добавлен:
26.03.2016
Размер:
722.99 Кб
Скачать

4.2 Разработка программного обеспечения

Программное обеспечение разработано в среде MS Visual C++ 6.0. Для работы с базами данных использовано средство RDE Apollo OLE DB.

Данная программа предназначена для автоматизированного учета шкафов и компрессоров в цехе на постах сборки и пайки посредством считывания штриховых кодов с технологических этикеток.

Программа обрабатывает поступающую информацию с учетных точек, проверяет корректность принятых данных, регистрирует в базах данных, выводит результаты обработки в окно главной формы.

Поступление информации происходит через COM порт, поэтому для работы необходимо его открыть. При открытии последовательного порта необходимо установить настройки порта для корректной его работы. Для открытия порта используем функцию CSerial::Open(). В этой функции устанавливаем все настройки и собственно с помощью функции CreateFile открываем последовательный порт.

Для корректной работы порта используется структура DCB, которая содержит большинство настроек порта.

Основными параметрами DCB структуры, которые необходимо указать, являются[5]:

– DCBlength – размер самой структуры DCB. Задает длину, в байтах, структуры DCB. Используется для контроля корректности структуры при передаче ее адреса в функции настройки порта;

– BaudRate – скорость передачи данных. Возможно указание любого значения, однако установленная скорость будет кратна скорости 115200. Дело в том, что в самой микросхеме порта есть два регистра, являющиеся непосредственно предделителем и делителем. Соответственно, при записи в делитель "1" – скорость будет 115200, "2" – 57600, "3" – 38400, "4" – 28800 и т.д. Устанавливаем скорость работы равной 9600.

– Parity — определяет выбор схемы контроля четности. Данное поле должно содержать одно из следующих значений:

а) EVENPARITY (2) дополнение до четности;

б) MARKPARITY (3) бит четности всегда 1;

в) NOPARITY (0) бит четности отсутствует;

г) ODDPARITY (1) дополнение до нечетности;

д) SPACEPARITY (4) бит четности всегда 0;

В нашем случае выбираем вариант в) – бит чётности отсутствует.

– StopBits – определяет количество стоповых бит. Поле может принимать следующие значения:

а) ONESTOPBIT (0) один стоповый бит;

б) ONE5STOPBIT (1) полтора стоповых бита;

в) TWOSTOPBIT (2) два стоповых бита;

В нашем случае выбираем вариант а) – один стоповый бит.

– ByteSize – определяет число информационных бит в передаваемых и принимаемых байтах. Запрещенные значения:

а) 5 в комбинации с StopBits=TWOSTOPBITS;

б) 6,7,8 в комбинации с StopBits=ONE5STOPBITS.

В нашем случае выбираем 8 информационных бит.

DCB в качестве параметров имеют функции GetCommState и SetCommState. Функции необходимы для чтения/записи структуры DCB порта.

Для определения таймаутов выполнения функции чтения и записи COM порта используется структура COMMTIMEOUTS.

Поля структуры TCOMMTIMEOUTS имеют следующее назначение[5]:

– ReadIntervalTimeout – максимальный временной промежуток (в мсек.), допустимый между двумя принимаемыми байтами. Если интервал между двумя последовательными байтами превысит заданное значение, операция чтения ReadFile завершается с возвратом всех данных из приемного буфера. Нулевое значение данного поля означает, что данный тайм-аут не используется. Комбинация:

ReadIntervalTimeout := 0xFFFFFFFF;

ReadTotalTimeoutMultiplier := 0;

ReadTotalTimeoutConstant := 0;

приводит к тому, что функция ReadFile возвращает немедленно все имеющиеся байты в приемном буфере.

– ReadTotalTimeoutMultiplier – задает множитель (в мсек.), используемый для вычисления общего тайм-аута операции чтения. Для каждой операции чтения данное значение умножается на количество запрошенных для чтения байт;

– ReadTotalTimeoutConstant – задает константу (в мсек.), используемую для вычисления общего тайм-аута операции чтения. Для каждой операции чтения данное значение плюсуется к результату умножения ReadTotalTimeoutMultiplier на количество запрошенных для чтения байт. Нулевое значение полей ReadTotalTimeoutMultiplier и ReadTotalTimeoutConstant означает, что общий тайм-аут для операции чтения не используется;

– WriteTotalTimeoutMultiplier – задает множитель (в мсек.), используемый для вычисления общего тайм-аута операции записи. Для каждой операции записи данное значение умножается на количество записываемых байт;

– WriteTotalTimeoutConstant – задает константу (в мсек.), используемую для вычисления общего тайм-аута операции записи. Для каждой операции записи данное значение прибавляется к результату умножения WriteTotalTimeoutMultiplier на количество записываемых байт. Нулевое значение полей WriteTotalTimeoutMultiplier и WriteTotalTimeoutConstant означает, что общий тайм-аут для операции записи не используется.

Для чтения и записи таймаутов используются GetCommTimeouts и SetCommTimeouts соответственно.

Для закрытия порта используется функция CSerial::Close(). Где с помощью CloseHandle закрывается COM порт.

Для ожидания прихода байт в порт используется функция CSerial::ReadDataWaiting().

Функция CSerial::ReadData() используется для чтения данных с последовательного порта.

Важным моментом в работе данной программы является проверка и запись считанного штрих-кода в таблицу. Для открытия таблицы используется функция CApollo::Open(). Для закрытия – CApollo::CloseAll(). Для запроса и записи данных используется стандартные функции средства RDE Apollo OLE DB, соответственно sx_Query и для записи - sx_Append, sx_PutString, sx_Commit.

Класс Serial (Serial.h)

#define FC_DTRDSR 0x01

#define FC_RTSCTS 0x02

#define FC_XONXOFF 0x04

#define ASCII_BEL 0x07

#define ASCII_BS 0x08

#define ASCII_LF 0x0A

#define ASCII_CR 0x0D

#define ASCII_XON 0x11

#define ASCII_XOFF 0x13

class CSerial

{

public:

CSerial();

~CSerial();

BOOL Close( void );

BOOL Open( int nPort = 1, int nBaud = 9600);

BOOL IsOpened( void ){ return( Opened ); }

int GetData( void *, int );

int ReadDataWaiting( void );

BOOL ClearBuffer( void );

int ReadData( void *, int );

OVERLAPPED OverlappedRead;

protected:

HANDLE Port;

BOOL Opened;

CRITICAL_SECTION CriticalSection;

};

Класс Serial (Serial.cpp)

#include "stdafx.h"

#include "com_port.h"

#include "Serial.h"

#ifdef _DEBUG

#undef THIS_FILE

static char THIS_FILE[]=__FILE__;

#define new DEBUG_NEW

#endif

CSerial::CSerial()

{

InitializeCriticalSection(&CriticalSection);

memset( &OverlappedRead, 0, sizeof( OVERLAPPED ) );

Port = NULL;

Opened = FALSE;

}

CSerial::~CSerial()

{

Close();

DeleteCriticalSection(&CriticalSection);

}

BOOL CSerial::Open(int nPort, int nBaud) ;функция, открывающая

COM порт

{

if( Opened ) return( TRUE );

char szPort[15];

DCB dcb;

wsprintf( szPort, "\\\\.\\COM%d", nPort );

Port = CreateFile( szPort, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL );

if(( Port == NULL ) || ( Port == INVALID_HANDLE_VALUE )) return( FALSE );

memset( &OverlappedRead, 0, sizeof( OVERLAPPED ) );

COMMTIMEOUTS CommTimeOuts; ;определяем таймауты

выполнения функции чтения и записи

CommTimeOuts.ReadIntervalTimeout = 0xFFFFFFFF;

CommTimeOuts.ReadTotalTimeoutMultiplier = 0;

CommTimeOuts.ReadTotalTimeoutConstant = 0;

CommTimeOuts.WriteTotalTimeoutMultiplier = 0;

CommTimeOuts.WriteTotalTimeoutConstant = 5000;

SetCommTimeouts( Port, &CommTimeOuts );

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

dcb.DCBlength = sizeof( DCB ); ;устанавливаем

настройки последовательного порта

GetCommState( Port, &dcb );

dcb.BaudRate = nBaud;

dcb.Parity = 0;

dcb.StopBits = 0;

dcb.ByteSize = 8;

if( !SetCommState( Port, &dcb ) ||

!SetupComm( Port, 10000, 10000 ) ||

OverlappedRead.hEvent == NULL )

{

DWORD dwError = GetLastError();

if( OverlappedRead.hEvent != NULL ) CloseHandle( OverlappedRead.hEvent );

CloseHandle( Port );

return( FALSE );

}

Opened = TRUE;

return( Opened );

}

BOOL CSerial::Close() ;функция, закрывающая

COM порт

{

if( !Opened || Port == NULL ) return( TRUE );

if( OverlappedRead.hEvent != NULL ) CloseHandle( OverlappedRead.hEvent );

CloseHandle( Port );

Opened = FALSE;

Port = NULL;

return( TRUE );

}

int CSerial::GetData(void *buffer, int limit)

{

EnterCriticalSection(&CriticalSection);

DWORD dwBytesNum;

dwBytesNum = ReadData(buffer, limit);

LeaveCriticalSection(&CriticalSection);

return dwBytesNum;

}

BOOL CSerial::ClearBuffer() ;функция очистки

буфера порта

{

if( !Opened || Port == NULL ) return( FALSE );

if(!PurgeComm(Port, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR)) return( FALSE );

return TRUE;

}

int CSerial::ReadDataWaiting() ;функция ожидания

данных

{

if( !Opened || Port == NULL ) return( 0 );

DWORD dwErrorFlags;

COMSTAT ComStat;

ClearCommError( Port, &dwErrorFlags, &ComStat );

return( (int) ComStat.cbInQue );

}

int CSerial::ReadData(void *buffer, int limit) ;функция чтения данных

с порта

{

if( !Opened || Port == NULL ) return( 0 );

BOOL bReadStatus;

DWORD dwBytesRead, dwErrorFlags;

COMSTAT ComStat;

ClearCommError( Port, &dwErrorFlags, &ComStat );

if( !ComStat.cbInQue ) return( 0 );

dwBytesRead = (DWORD) ComStat.cbInQue;

if( limit < (int) dwBytesRead ) dwBytesRead = (DWORD) limit;

bReadStatus = ReadFile( Port, buffer, dwBytesRead, &dwBytesRead, &OverlappedRead );

if( !bReadStatus ){

if( GetLastError() == ERROR_IO_PENDING ){

WaitForSingleObject( OverlappedRead.hEvent, 2000 );

return( (int) dwBytesRead );

}

return( 0 );

}

return( (int) dwBytesRead );

}

Класс Apollo (Apollo.h)

#include "sde61.h"

class CApollo

{

public:

BOOL Open(char* , char *, short);

void CloseAll();

CApollo();

virtual ~CApollo();

};

Класс Apollo (Apollo.cpp)

#include "stdafx.h"

#include "com_port.h"

#include "Apollo.h"

#ifdef _DEBUG

#undef THIS_FILE

static char THIS_FILE[]=__FILE__;

#define new DEBUG_NEW

#endif

CApollo DbApollo;

CApollo::CApollo()

{

sx_SetStringType(1);

sx_SetDeleted(TRUE);

sx_SetLockTimeout(5);

sx_SetSoftSeek(FALSE);

sx_ErrorLevel(ERRLEVEL_NONE);

CloseAll();

}

CApollo::~CApollo()

{

CloseAll();

}

BOOL CApollo::Open(char* name, char* alias, short mode)

{ ;функция, открывающая

таблицу

sx_ErrorLevel(ERRLEVEL_NONE);

BOOL result = TRUE;

int ret = 0;

int i = 0; ;счетчик попыток

if (sx_WorkArea((PBYTE)alias) != 0)

return TRUE;

sx_SetLockTimeout(3);

if (ret == 0)

{

while ((ret==0)&&(i<5))

{

ret = sx_Use((PBYTE)name, (PBYTE)alias, mode, SDEFOX);

i++;

}

if (ret == 0)

result = FALSE;

}

return result;

}

void CApollo::CloseAll() ;функция, закрывающая

таблицу

{

sx_CloseAll();

}

Основная программа

#include "stdafx.h"

#include "com_port.h"

#include "com_portDlg.h"

#include "Serial.h"

#include <time.h>

#include <string.h>

#include<stdlib.h>

#ifdef _DEBUG

#define new DEBUG_NEW

#undef THIS_FILE

static char THIS_FILE[] = __FILE__;

#endif

HANDLE reader;

bool but=false;

char count;

char count1[255]; ;буфер данных

char dateStr[100]; ;буфер даты

char timeStr[100];

CSerial comport;

bool func(CListBox *List) ;функция потока

{

char a[255];

CApollo CAp;

if (CAp.Open("test.dbf","test",0)==0)

{

AfxMessageBox("ошибка при открытии таблицы");

return false;

}

while(1) ;запускаем бесконечный

цикл

{

if (comport.ReadDataWaiting())

{

comport.GetData(&count, 20);

fflush(stdin);

wsprintf(a, "NAME = '%s'", &count);

if (sx_Query((PBYTE)a)==0)

{

sx_Append();

sx_PutString((PBYTE)"NAME", (PBYTE)&count);

_strdate( dateStr );

_strtime( timeStr );

strcat(count1, dateStr);

strcat(count1, " ");

strcat(count1, timeStr);

sx_PutString((PBYTE)"DATE", (PBYTE)count1);

sx_Commit();

List->AddString(&count);

}

else

{

AfxMessageBox("данный штрих код был уже считан");

}

}

count=NULL;

count1[255]=NULL; ;очистка буфера данных

dateStr[100]=NULL; ;очистка буфера даты

timeStr[100]=NULL;

memset( &comport.OverlappedRead, 0, sizeof(OVERLAPPED) );

comport.ClearBuffer();

Sleep(500);

}

CAp.CloseAll();

comport.Close();

return 0;

}

void CCom_portDlg::OnButton1()

{

if (!but)

{

GetDlgItem(IDC_BUTTON1)->SetWindowText("STOP");

but=true;

}

else

{

GetDlgItem(IDC_BUTTON1)->SetWindowText("START");

but=false;

return;

}

if(comport.Open())

{

AfxMessageBox(" порт успешно открыт ");

reader = CreateThread(NULL, 0,(LPTHREAD_START_ROUTINE)func,&m_list, 0, NULL);

}

else

{

AfxMessageBox(" ошибка при открытии порта ");

GetDlgItem(IDC_BUTTON1)->SetWindowText("START");

but=false;

}

return;

}

void CCom_portDlg::OnOK()

{

comport.Close();

CDialog::OnOK();

}

void CCom_portDlg::OnCancel()

{

comport.Close();

CDialog::OnCancel();

}