Таджикистан, Душанбе, Таджикский Технический Университет (ТТУ), 2013 |
Программирование приложений в CE
Пример программы SerialIO, использующей вызовы В/В файлов ОС
Пример программы C++ читает последовательный ввод данных с COM2:, выводит каждый символ в консольном окне eBox, и отправляет его назад на вывод на COM2:.
Программа использует базовые функции API В/В файлов CE, такие как CreateFile, ReadFile, WriteFile, и CloseHandle для передачи данных в/из последовательного порта. В функции ModifyCommSettings используются вызовы API GetCommStatus и SetCommStatus для получения, модификации, и затем задания для порта COM скорости в бодах, числа битов данных, и вариантов квитирования. Вызов API SetCommTimeouts используется для задания задержек для операций последовательного чтения и записи. Его можно использовать для определения, что операция чтения должна подождать ввода символа или вернуть управление немедленно.
Вызов API WaitCommEvent используется для блокирования процесса, пока не появится входящий символ. Это более эффективно в терминах времени процессора и питания, чем постоянное циклическое повторение. SetCommEvent используется для определения, какой тип коммуникационного события будет запускать WaitCommEvent. Обычно основной процесс не будет блокироваться, и для чтения и записи последовательного порта будет использоваться поток. Так как основной процесс в этом примере только посылает данные назад, то поток не требуется.
Для просмотра последовательных данных последовательный null-модемный кабель соединяется из COM2: на eBox с неиспользуемым портом COM на настольном ПК системы разработки. Выполняя HyperTerminal или другую программу эмулятора терминала, соединитесь с портом COMx: на скорости 9600 бод, с 8 битами данных, без контроля четности, с 1 стоп битом, и без задания управления потоком.
Когда выполняется программа, она печатает заголовок, а затем каждый символ, введенный на клавиатуре настольного ПК посылается в устройство eBox, которое считывает символы, выводит их в консольном окне, и посылает символы назад. Так как они посылаются назад, они также выводятся в эмуляторе терминала. Ввод Ctrl-C в эмуляторе терминала заставляет eBox выйти из программы, а вызов CloseHandle освобождает порт COM для использования в других приложениях.
// SerialIO.cpp : Определяет точку входа для консольного приложения. // // Пример программы В/В файла через последовательный порт // // FOR DEMO: Соедините Ebox COM2: с ПК с помощью null-модемного кабеля // Выполните HyperTerminal на скорости 9600 бод, с 8 битами данных, 1 стоп // битом, без четности и без управления потоком #include "stdafx.h" BOOL ModifyCommSettings (HANDLE hComPort); HANDLE hSerial; int _tmain(int argc, TCHAR *argv[], TCHAR *envp[]) { DWORD cBytes_out, cBytes_in; DWORD dwMask; char cBuffer_out[] = "\f\n Hello Serial World! \n\r Type something and watch it echo back \n\r Ctrl C to exit \n\r"; TCHAR cBuffer_in[80]; // Выводит сообщение на консоль printf("\nOpening COM2: Serial Port - Type ctrl C on other device to exit\n\r"); // Откройте последовательный порт COM2: для чтения и записи // Примечание: COM1: обычно задается для отправки отладочной информации // В этом случае COM2: становится COM1: в ОС hSerial = CreateFile(_T("COM1:"), GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL); // Проверка ошибок открытия файла if (hSerial == INVALID_HANDLE_VALUE){ printf("file open errors\n"); Sleep(4000); return 0; } // Модифицируйте настройки порта Com (т.е., Baud Rate, #bits, parity и т.д.) if(!ModifyCommSettings (hSerial)){ printf("com port settings errors\n"); Sleep(4000); return 0; } // Запишите заголовок в последовательный порт. if (!WriteFile(hSerial, cBuffer_out, strlen(cBuffer_out), &cBytes_out, NULL)) { printf("file write errors\n"); Sleep(4000); return 0; } // Задаем маску коммуникационного события для WaitCommEvent для rxchar (получить символ) в буфер SetCommMask(hSerial, EV_RXCHAR | EV_ERR); cBuffer_in[0] = 0; // Считать символы, скопировать в консольное окно и Echo // Цикл, пока не будет нажато ctrl C while (cBuffer_in[0] != 0x03){ // Ожидаем символ в буфере ввода - события являются более эффективными, чем // цикл WaitCommEvent(hSerial, &dwMask, 0); cBytes_in = 1; // Цикл на тот случай, если более одного символа находится в буфере ввода // UART while (cBytes_in != 0){ // Эхо-считывание всех последовательных данных и вывод if (ReadFile(hSerial, cBuffer_in, 64, &cBytes_in, NULL)){ if (cBytes_in == 0) break; // Вывод эхо-считанных данных printf("%s",cBuffer_in, cBytes_in); // Эхо-Отправка символов отправителю if (!WriteFile(hSerial, cBuffer_in, cBytes_in, &cBytes_out, NULL)){ printf("\rfile write errors\n"); Sleep(4000); return 0; } } } } // Закрытие файла CloseHandle(hSerial); return 1; } // Функция для задания параметров порта COM BOOL ModifyCommSettings (HANDLE hComPort) { COMMTIMEOUTS ctos; DCB PortDCB; // Инициализация члена DCBlength. PortDCB.DCBlength = sizeof (DCB); // Получение информации DCB о настройках по умолчанию последовательного порта GetCommState (hSerial, &PortDCB); // Изменение настроек обычной структуры DCB для модификации настроек // последовательного порта. PortDCB.BaudRate = 9600; // Current baud PortDCB.fBinary = TRUE; // Binary mode; no EOF check PortDCB.fParity = TRUE; // Enable parity checking PortDCB.fOutxCtsFlow = FALSE; // No CTS output flow control PortDCB.fOutxDsrFlow = FALSE; // No DSR output flow control PortDCB.fDtrControl = DTR_CONTROL_ENABLE; // DTR flow control type PortDCB.fDsrSensitivity = FALSE; // DSR sensitivity PortDCB.fTXContinueOnXoff = TRUE; // XOFF continues Tx PortDCB.fOutX = FALSE; // No XON/XOFF out flow control PortDCB.fInX = FALSE; // No XON/XOFF in flow control PortDCB.fErrorChar = FALSE; // Disable error replacement PortDCB.fNull = FALSE; // Disable null stripping PortDCB.fRtsControl = RTS_CONTROL_ENABLE; // RTS flow control PortDCB.fAbortOnError = FALSE; // Do not abort reads/writes on error PortDCB.ByteSize = 8; // Number of bits/byte, 4-8 PortDCB.Parity = NOPARITY; // 0-4=no,odd,even,mark,space PortDCB.StopBits = ONESTOPBIT; // 0,1,2 = 1, 1.5, 2 // Конфигурирование настроек порта согласно новым спецификациям // структуры DCB. if (!SetCommState (hSerial, &PortDCB)){ printf("Unable to configure the serial port"); Sleep(4000); return false; } // Set read time outs ctos.ReadIntervalTimeout = MAXDWORD; ctos.ReadTotalTimeoutMultiplier = MAXDWORD; ctos.ReadTotalTimeoutConstant = 1; ctos.WriteTotalTimeoutMultiplier = 0; ctos.WriteTotalTimeoutConstant = 0; if(!SetCommTimeouts(hSerial, &ctos)){ printf("Unable to configure the serial port"); Sleep(4000); return false; } return true; }8.2.