LinuxForum.Fans
Тема

Личный опыт: Как я решил проблему бита четности Space и Mark

Автор: Sidor_Luty 1 сообщений 1427 просмотров
#103039

Описание проблемы.
Есть сеть RS-485 со множеством приборов. Мастер - только компьютер. Адрес и конец обмена выдаются с нулевым битом четности (Space), а обмен ведется с единичным битом четности (Mark). Корректность данных и команд контролируется контрольной суммой в конце команды от мастера и в конце данных от прибора. Есть исходники программ на Delphi. Очень легко все перевел на Lazarus в Windows. Получиласть такая же графическая оболочка, как и на Delphi (немного с построеним графиков заморочки были, т.к. компонент TChart сильно от дельфийского отличается). Но в итоге - практически аналогичная программа под Windows. Затевалось это все для портирования в Linux. И тут .... ЗАСАДА!!! В стандартном варианте Synaser для Linux ПРОСТО НЕЛЬЗЯ сделать бит четности Space/Mark. Никак!!!

Решение.
Начал рыть интернет. Наткнулся на статью Томаса Лочматтера "Linux and MARK/SPACE Parity" http://www.lothosoft.ch/thomas/libmip/markspaceparity.php Хорошо, думаю, путь понятен. Теперь надо надыбать конкретные биты во флаге c_cflag. Ну, с #define CMSPAR 010000000000 - понятно, переводим восьмеричное в hex и все. А вот с битами PARENB PARODD опять была засада - поиск #define PARODD (#define PARENB) давал такое количество вариантов, что голова кругом шла. Пришлось все варианты перепробовать. И вот окончательный результат

text

uses 
... SynaSer, SynaUtil, SynaFPC, ....

const

CMSPAR= $40000000; { mark or space (stick) parity } PARENB= $00000100; { enable parity on output } PARODD= $00000200; { use odd parity if set, else even }

type ... procedure ParitySpace; procedure ParityMark; ...

var ser: TBlockSerial; ... ...

implementation

procedure TForm1.ParitySpace; {SPACE parity is selected by} begin ser.TermiosStruc.c_cflag:= ser.TermiosStruc.c_cflag or CMSPAR or PARENB; ser.TermiosStruc.c_cflag:= ser.TermiosStruc.c_cflag and (Not PARODD); ser.SetCommState; end;

procedure TForm1.ParityMark; {MARK parity is selected by} begin ser.TermiosStruc.c_cflag:= ser.TermiosStruc.c_cflag or CMSPAR or PARENB or PARODD; ser.SetCommState; end; ...

По окончании работы с программой не забывайте в FormCloseQuery сбрасывать бит CMSPAR.

text

  ser.TermiosStruc.c_cflag:= ser.TermiosStruc.c_cflag and (Not CMSPAR);

Проверено - работает замечательно!

Войдите или зарегистрируйтесь, чтобы ответить.