|
#1
|
|||
|
|||
COM порт
Добрый вечер! Вот такая проблема: Написал модуль для работы с com портом к своей программе.
Код:
unit ComPort; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; const end_dannyh: ShortString = #90 + #3 + #85 + #90; // записываем в конец отправляемых данных var freq: integer; Nomer_RPU: ShortString; Nomer_COM_Porta: string; port : THandle; function initComport (Nomer_COM_Porta: AnsiString):THandle; procedure CloseComPort(Port: Thandle); procedure WriteComPort(Port: Thandle; freq: integer; Nomer_RPU: ShortString; Nomer_COM_Porta: AnsiString); // Задаем частоту и номер РПУ function ReadComPort (Port: Thandle): shortstring; implementation function initComport (Nomer_COM_Porta: AnsiString):THandle; var DCB: TDCB; CommTimeouts:TCommTimeouts; begin FillChar(dcb, SizeOf(dcb), 0); port := 0; port:= CreateFileA(PAnsiChar(Nomer_COM_Porta) ,GENERIC_READ or GENERIC_WRITE, 0, nil, OPEN_EXISTING, 0,0); if port = INVALID_HANDLE_VALUE then begin // Обнаружена ошибка, порт открыть не удалось exit; end; if Not GetCommState(port,dcb) then begin CloseHandle(port); // Ошибка при подключении параметров порта exit; end; GetCommState(port,DCB); {получаем текущее DCB} DCB.BaudRate:=CBR_9600; {устанавливаем скорость работы} DCB.Parity:=NOPARITY; {устанавливаем отсутствие проверки на четность} DCB.ByteSize:=8; {8 бит в передаваемом байте} DCB.StopBits:=OneStopBit; {одиночный стоп-бит} DCB.EvtChar:=chr(13); {вот собственно задаем символ для SetCommMask. В данном случае - возврат каретки} SetCommState(port,DCB); {ну теперь собственно прописываем исправленное DCB} if Not SetCommState(port,dcb) then begin CloseHandle(port); // Ошибка при установке параметров порта exit; end; GetCommTimeouts(Port, CommTimeouts); //получаем структуру CommTimeouts что бы не заполнять все вручную CommTimeouts.ReadIntervalTimeout :=MAXDWORD; //функция ReadFile возвращает CommTimeouts.ReadTotalTimeoutMultiplier := 0; //немедленно все имеющиеся CommTimeouts.ReadTotalTimeoutConstant := 0; //байты в приемном буфере CommTimeouts.WriteTotalTimeoutMultiplier := 0;//общий тайм-аут для CommTimeouts.WriteTotalTimeoutConstant := 0; //операции записи не используется. SetCommTimeouts(Port, CommTimeouts); //записываем измененную структуру result := port; end; procedure CloseComPort(Port: Thandle); begin CloseHandle(Port); {закрытие порта после завершения работы с ним} end; procedure WriteComPort(Port: Thandle; freq: integer; Nomer_RPU: ShortString; Nomer_COM_Porta: AnsiString); // Задаем частоту и номер РПУ var buf: ShortString; written: Cardinal; // Nomer_COM_Porta1: PAnsiChar; //j: Integer; //переменная для вывода передаваемого кода на экран begin if PAnsiChar(Nomer_COM_Porta) = 'COM1' then begin buf:= Nomer_RPU+format('F%0.7d',[freq])+end_dannyh;//получаем данные для отправки в виде F частота #3 end else begin freq:= Round(freq/100); buf:= format('F%0.5d',[freq])+#3;//получаем данные для отправки в виде F частота #3 end; WriteFile(Port,buf[1],Length(buf),Written,nil); //собственно отпавляем данные // Вывод передаваемого кода на экран------------------------------------------- // writeln(Nomer_COM_Porta); // for j := 1 to Length(buf) do // writeln( IntToStr(j) + '-' + IntToStr( ord(buf[j]) ) + ' ' + buf[j] ); // writeln; //----------------------------------------------------------------------------- end; function ReadComPort (Port: Thandle): shortstring; Var RCBuf:array [1..1024] of char; //Буфер данных для приема nToRead:Cardinal; //Число байт для чтения nRead:Cardinal; //Число прочитанных байт ComStat:TComStat; //состояние порта Errs:Dword; str: shortstring; begin FillChar( RCBuf, Sizeof(RCBuf), #0); //Обнуляем буфер данных для приема ClearCommError(Port,Errs,@ComStat); //считываем состояние порта nToRead:=ComStat.cbInQue; //считываем число байт для чтения из структуры ReadFile(Port,RCBuf,nToRead,nRead,nil); //считываем данные str := shortstring(RCBuf); Result:= str; end; end. В модуле есть такая строчка DCB.Parity:=NOPARITY; Мне нужно DCB.Parity:=evenPARITY; но тогда comport принимает не то что я посылаю в него. Comport все правильно принимает если стоит NOPARITY, но тогда не работает остальное железо. Что делать Последний раз редактировалось lmikle, 02.04.2013 в 22:42. |
#2
|
||||
|
||||
Цитата:
2) Почитать про COM-порт (RS232, протокол UART). 3) Разобраться, что значит это самое PARITY. 4) Понять, что формат посылки и приема должны совпадать, иначе данные будут другие или их не будет вовсе. (Считай, один человек пишет на немецком, а другой читает этот текст на английском. Буквы одинаковые, но данные будут совсем другие, или их не будет вовсе). 5) Переделать железо так, чтобы оно отправляло в нужном формате, или забить и использовать текущий формат приема на компе. jmp $ ; Happy End! The Cake Is A Lie. Последний раз редактировалось Bargest, 02.04.2013 в 21:21. |