Написание программы, позволяющей работать с вольтметром через персональный компьютер, страница 3

Заголовок – последовательность символов для идентификации прибора, который отвечает. Вид заголовка ANSWxx, где xx – адрес прибора.

Строка сообщения от прибора – результат измерения, текущее состояние в формате строки программных данных о занятости/ошибке.

Идентификатор конца посылки – символы с кодами <0dh> и <0ah>.

Таблица 2. Возвращаемые сообщения.

Сообщение от прибора

Комментарий

Error 0

Смещение нуля АЦП больше нормы (в ответ на запуск или в режиме Talk Only)

Error 1

Переполнение приемного буфера строки (строка программных данных более 20 символов)

Error 2

Неверные программные данные

Error 3

Неоднозначность запуска (при использовании запуска приход очередной команды запуска)

Error 4

Внешнее смещение при вычисление ХХ больше нормы ( в ответ на команду N1 или в режиме Talk Only)

Error 5

Деление на нуль при калибровке (в ответ на команду Cxxxx или в режиме Talk Only при нулевом результате измерения)

Error 6

Ошибка записи в EEPROM при калибровке (в ответ на команду Cxxxx или в режиме Talk Only)

Error 7

Ошибка при передаче данных от PIC – частотомеру (в ответ на запуск или в режиме Talk Only)

Error 8

Ошибка при чтение данных от PIC – частотомеру (в ответ на запуск или в режиме Talk Only)

Error 9

Отсутствие сигнала EOC (End of Convert ion) об окончание измерения АЦП или PIC – частотомера (в ответ на запуск или в режиме Talk Only)

BUSY…

Прибор занят исполнением запуска, вычислением внешних смещений или калибровкой.

Интерфейс программы.

Перед началом работы нужно выбрать номер порта, на который подключен вольтметр; скорость передачи данных и установить параметры порта (посылка длиной 8 бит, без паритета, 1 стоп-бит, выбранная скорость) кнопкой “Послать”.

Для начала измерений нужно выбрать нужный тумблер с необходимым диапазоном (панель управления находится справа).

Все отсылаемые посылки к прибору проходят через верхнее окошко редактирования строки.

В случае, если среди принимаемых данных программа обнаружит результаты измерения она немедленно их зарисует.

Рисунок 1. Главное окно программы.

Дополнительное окно для определения размера области вывода информации и параметров вывода.

Рисунок 2. Параметры вывода.

Листинг программы: (вырезки важных мест из текста программы).

Структура для работы с портом.

typedef struct _PORT_READ_STRUCT

{    CWnd* w1; // Указатель на окно

CWnd* w2; // Указатель на принятую строку

HANDLE h_com; // указатель на СОМ порт

int read_time_out; //

HANDLE hMutex1; // Мьютекс

bool IsMutex1;

} PORT_READ_STRUCT, *PPORT_READ_STRUCT;

Процедура открытия СОМ порта.

void COscillographDlg::OnCbnSelchangeCombo1()

{             CString str;

str.Format("COM%d",port.GetCurSel()+1);

// Закрываем предыдущий порт

if (PRTh1.h_com!=NULL){CloseHandle(PRTh1.h_com);}

// Открываем выбранный порт

PRTh1.h_com = CreateFile( str, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING,

FILE_FLAG_OVERLAPPED, 0);

if (PRTh1.h_com == INVALID_HANDLE_VALUE)

{             PRTh1.h_com = NULL;

CString sm;

sm.Format("Не могу открыть порт COM%d",port.GetCurSel()+1);

MessageBox(sm);}

}

Процедура записи данных в порт.

void COscillographDlg::OnBnClickedButton1()

{

OVERLAPPED osWrite = {0};

DWORD dwWritten;

BOOL fRes;

UpdateData(TRUE);

str_send = str_send_inside;

UpdateData(FALSE);

DWORD len;

if (is_null.GetCheck() == BST_CHECKED) len = str_send_inside.GetLength()+2;

else len = str_send_inside.GetLength()+1;

char* Buf = new TCHAR[len];

_tcscpy(Buf, str_send_inside);

if (is_null.GetCheck() == BST_CHECKED)

{          Buf[str_send_inside.GetLength()] = 0x0d;

Buf[str_send_inside.GetLength()+1] = 0x0a;}  

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

if (osWrite.hEvent == NULL) MessageBox("Error creating overlapped event handle.");

else                   

if (PRTh1.h_com!=NULL)

{            if (!WriteFile(PRTh1.h_com, Buf, len, &dwWritten, &osWrite))

{            if (GetLastError() != ERROR_IO_PENDING)

{             // WriteFile failed, but it isn't delayed. Report error and abort.

fRes = FALSE;

}

else

{             // Write is pending.

if (!GetOverlappedResult(PRTh1.h_com, &osWrite, &dwWritten, TRUE))