Форум программистов, компьютерный форум, киберфорум
Микроконтроллеры
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.74/39: Рейтинг темы: голосов - 39, средняя оценка - 4.74
3 / 3 / 0
Регистрация: 03.05.2010
Сообщений: 116

Аппаратно-программная реализация считывателей БСК MF-RW-USB (старых и новых годов выпуска)

24.07.2012, 23:40. Показов 8580. Ответов 34
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Всем доброе время суток!

Есть два считывателя БКС MF-RW-USB разных годов выпуска!
Оба считывателя собраны на PIC с той лишь разницей, что старый имеет FTDI, а новый напрямую смотрит контроллером PIC18F4550 на USB и тут начинаются проблемы!

Проблемы:
1. Тот, который с FTDI не может эмулировать нажатия клавиатуры (это стало ясно после общения со службой поддержки)
2.Тот, который с FTDI считанную информацию выкидывает в не читабельном формате (по мнению службя поддержки в BIN коде)
3. из-за не возможности подключения того, который с FTDI в качестве эмулятора клавиатуры, программа которая установленна сейчас его просто не видит, да и вся база с кодами карт записана в не читаемом формате.

Собственно вопрос в следующем:
1. Как узнать в каком формате выли сделаны запись старым считывателем.
2. Есть ли возможность заставить новый стивыатель выкидывать информацию в формате старого считывателя?
3. Как можно реализовать возможность эмуляции клавиатуры старым считывателем без изменения кода отдачи. Если такая возможность есть то, на каком уровне это можно реализовать (изменение прошивки, доработка драйверов или еще как)

Полный состав микросхем обоих считывателей выложе завтра

Всем заранее огромное спасибо!
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
24.07.2012, 23:40
Ответы с готовыми решениями:

Программная vs аппаратно-программная реализация функционала
Ребят, здравствуйте Немного запутался. В чем разница между программной и аппаратно-программной реализации функции в сетевом устройстве. ...

Аппаратная и программная реализация старых консолей?
Мне хотелось бы узнать, какой фундамент знаний и навыков я должен иметь/освоить для погружения в данную тему. Я самостоятельно вот уже...

Вывести список самых новых и самых старых машин для каждой из стоянок,с указанием их владельцев и года выпуска
"В районном обществе автолюбителей имеются сведения об N автомобилях.О каждой машине известно:фамилия владельца,год выпуска и номер...

34
 Аватар для raxper
10237 / 6615 / 498
Регистрация: 28.12.2010
Сообщений: 21,154
Записей в блоге: 1
01.08.2012, 09:40
Студворк — интернет-сервис помощи студентам
нет, не связана . А по первому:
BodyLen длина дополнительных данных для команды
0
3 / 3 / 0
Регистрация: 03.05.2010
Сообщений: 116
01.08.2012, 18:21  [ТС]
Неа, не разобраться...

Delphi
1
function W_IO(Address, Cmd: char; BodyLen: integer; const CmdBody; var ReplyLen: integer; var ReplyBuffer): char;
Параметры:
Address адрес считывателя (0..3F)
Cmd команда
BodyLen длина дополнительных данных для команды
CmdBody буфер, содержащий дополнительные данные
ReplyLen длина данных, полученных от считывателя
ReplyBuffer буфер, в который будут помещены полученные данные.
При вызове функции в ReplyLen должен быть записан размер области памяти, отведенной под Reply-
Buffer. На выходе в ReplyLen будет записана длина фактически полученных данных.
Возвращаемое значение – код возврата, см. раздел «Константы» REPLY_XXXXX.


Получается: (мысли в слух)
Ret:= W_IO(#$1, #$10, 0, '', RL, Event); // $10 - читать самое старое событие

#$1, - Cmd команда
#$10, - CmdBody буфер, содержащий дополнительные данные
0, - Так и не разобрался кто это
'', - ReplyBuffer буфер, в который будут помещены полученные данные.
RL, - ReplyLen длина данных, полученных от считывателя
Event - некое событие, так понимаю берется из библиотеки

Если все так, то где BodyLen: integer; - в каком направлении искать?

Добавлено через 25 минут
Хотя судя по примеру в доках, то запрос выглядит так

Ret:= W_IO(#$3F, #$10, 0, '', RL, Event); // $10 - читать самое старое событие

#$3F, - Адрес ридера
#$10, - Cmd команда
0, - Так и не разобрался кто это
'', - ReplyBuffer буфер, в который будут помещены полученные данные.
RL, - ReplyLen длина данных, полученных от считывателя
Event - некое событие, так понимаю берется из библиотеки
Но даже тут нет BodyLen: integer;

еще в доках есть
Методы расчета контрольной суммы кадра:
  1. CHECK_NONE 0х00 Не проверять контрольную сумму кадра
  2. CHECK_SUM 0х01 Использовать суммирование (1 байт)
  3. CHECK_CRC16 0х02 Использовать CRC16 (2 байта)
  4. CHECK_FCS 0х03 Использовать FCS (2 байта)

Структура TProtocolInfo
Структура используется для управления различными параметрами протокола обмена данными при
работе с различными моделями устройств.
  1. DisableAddress BOOLEAN Размер структуры, байт
  2. CheckMode INTEGER Режим проверки контрольной суммы

Следующие типы данных являются членами структуры TLogInfo и предназначены для хранения nullterminated
строк, используемых для настройки внешнего вида протокола обмена данными.
Типы данных
  1. TPathStr Массив из MAX_PATH символов
  2. TFmtStr Массив из 64 символов
  3. TmarkStr Массив из 20 символов

Скажите пожалуйста, где они используются и как ими перировать???
0
 Аватар для raxper
10237 / 6615 / 498
Регистрация: 28.12.2010
Сообщений: 21,154
Записей в блоге: 1
01.08.2012, 19:11
0, - Так и не разобрался кто это
Address адрес считывателя (0..3F)
Cmd команда
BodyLen длина дополнительных данных для команды
CmdBody буфер, содержащий дополнительные данные
ReplyLen длина данных, полученных от считывателя
ReplyBuffer буфер, в который будут поме
===================

Скажите пожалуйста, где они используются и как ими перировать???
c.5, с.6, с.7 'Prox232_DLL.pdf':

Delphi
1
2
3
4
W_SetLogParams(LogCfgPtr: PLogInfo); 
W_GetLogParams(LogCfgPtr: PLogInfo); 
W_SetProtocolParams(ProtocolInfoPtr: PProtocolInfo); 
W_GetProtocolParams(ProtocolInfoPtr: PProtocolInfo);
0
3 / 3 / 0
Регистрация: 03.05.2010
Сообщений: 116
01.08.2012, 20:48  [ТС]
Так, если я все правильно понял, то сейчас обмен с ридером идет без подсчета контрольных сумм, а для того, чтобы все запросы были с контрольными суммами, необходимо включить эту возможность.
Как я понял, это делается через:
Функция W_SetProtocolParams: установка параметров протокола обмена
procedure W_SetProtocolParams(ProtocolInfoPtr: PProtocolInfo);
Для этого необходимо:
1. Описать структуру
Delphi
1
2
3
4
5
type
TProtocolInfo = record
DisableAddress: BOOLEAN;
CheckMode: INTEGER;
end;
2. Выводим указатель
Delphi
1
PProtocolInfo = ^ TProtocolInfo;
3. Задаем описание
Delphi
1
W_SetProtocolParams: procedure(ProtocolInfoPtr: PProtocolInfo); stdcall;
4. Подключаем
Delphi
1
W_SetProtocolParams:= LinlProc('W_SetProtocolParams');
А вот дальше я в тупике.....
Понял только, что в консантах необходимо прописать, что используем метод FCS
CHECK_FCS 0х03
Если я правильно понимаю, то примерно должно быть так.
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
procedure TForm1.SetProtocolParams;
const
CHECK_FCS= #$03;
var
PPar: TProtocolInfo;
begin
PPar:= ; // Вот с этим я и не могу разобраться, но если эту строку не прописывать,
//то в запросе получается следующее
// Запрос без W_SetProtocolParams  - FD 3F 30 40 AF FE
// Запрос с   W_SetProtocolParams  - FD 31 40 39 E2 FE
 W_SetProtocolParams(@t)
end;
Тоесть, если можно заметить, то 40 переехало на свое место, но после него должен быть еще 1 байт, который я найти не могу.
Запрос без W_SetProtocolParams - FD 3F 30 40 AF FE
Запрос с W_SetProtocolParams - FD 31 40 39 E2 FE

А это так, для аналитики дел
Запрос без W_SetProtocolParams
FD 3F 39 40 B8 FE
FD 3F 3A 40 B9 FE
FD 3F 3B 40 BA FE
FD 3F 3C 40 BB FE


Запрос с W_SetProtocolParams
FD 3D 40 99 4B FE
FD 3E 40 F1 61 FE
FD 3F 40 29 78 FE
FD 40 40 25 0B FE


Но в любом ватианте 1 байта не хватает.
Вот такие пироги....
0
3 / 3 / 0
Регистрация: 03.05.2010
Сообщений: 116
07.08.2012, 05:07  [ТС]
Значит так
Добавил
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
........
procedure SetProtocolParams;
procedure Read;
........
 
  type
  TProtocolInfo = record
  DisableAddress: BOOLEAN;
  CheckMode: INTEGER;
  end;
  PProtocolInfo = ^ TProtocolInfo;
 
var
PPar: TProtocolInfo;
W_SetProtocolParams: procedure(ProtocolInfoPtr: PProtocolInfo); stdcall;
......
 
//В  const запихал все коды ответы оборудованием
// Коды ошибок при работе с портом
//и Методы расчета контрольной суммы кадра
 
procedure TMain.FormCreate(Sender: TObject);
begin
W_SetProtocolParams:= LinkProc('W_SetProtocolParams');
.....
end;
 
procedure TMain.SetProtocolParams;
begin
 W_SetProtocolParams(@t)
end;
 
procedure TMain.Read;
begin
 W_SetPortParams(@t); // Установка параметров порта
 SetProtocolParams;  // Установка параметров протакола 
begin
 Ret:= W_IO(#$3F, #$03, 0,'', RL, Event); // Запрос (управление энергопотреблением)
 if Ret = REPLY_ACK then
   memo1.Lines.Add('Данные получены')
else
  memo1.Lines.Add('Ошибка');
 end;
  end;
Из procedure TMain.SetParams; убрал строку W_SetPortParams(@t); и поместил ее в procedure TMain.Read;

Теперь при нажатии на кнопку запросы отправляются верно, но
Если запрос такой Ret:= W_IO(#$3F, #$03, 0,'', RL, Event); то все замечательно,
а если запрос такой Ret:= W_IO(#$3F, #$00, 0,'', RL, Event); то при первом нажатии на кнопку запрос выполняется, а при повторном, программа вываливается в ошибку, я так понимаю. что это из-за того, что программа не приняла то, что было отправленно ридером при первом запросе.

Собственно пока вопроса 2
1. Как принять данные с порта
2. Так и не разобрался что необходимо сделать для того, чтобы выполнить запрос сдополнительными параметрами.
Запрос на чтение карты - 45 00

Сейчас можно выполнить запросы только
00 - Чтение параметров
03 - управление энергопотреблением
22 - Сброс накачки
23 - Выключение накачки
43 - Halt
Все остальные состоят из 4 сиволов.
0
 Аватар для raxper
10237 / 6615 / 498
Регистрация: 28.12.2010
Сообщений: 21,154
Записей в блоге: 1
07.08.2012, 09:19
Сейчас можно выполнить запросы только
00 - Чтение параметров
03 - управление энергопотреблением
22 - Сброс накачки
23 - Выключение накачки
43 - Halt


Так и не разобрался что необходимо сделать для того, чтобы выполнить запрос сдополнительными параметрами.
Запрос на чтение карты - 45 00
запрос на чтение карты 0х20 без дополнительных параметров.

1. Как принять данные с порта
либо анализируя ответ W_IO, либо работая с виртуальным COM-портом напрямую без PROX232, формируя и разбирая пакеты запросов-ответов самому. Есть неплохая оберточка над WinAPI вызовами для работы с COM-портом - COMM32 (for Delphi).
0
3 / 3 / 0
Регистрация: 03.05.2010
Сообщений: 116
07.08.2012, 12:42  [ТС]
Цитата Сообщение от raxp Посмотреть сообщение
запрос на чтение карты 0х20 без дополнительных параметров.
ХМ, если отправить запрос 20, то получаю в ответ - "02 - Получен сигнал NACK2 (неверная команда)".
а если отправить 45 00, то в ответ приходит - "00 - Команда выполнена успешно., 04 00 88 E5 E3 F0 0C"

А по повду Comm32? я знаю, просто еще не совсем догнал как ей читать с порта, но сейчас разбераюсь!
0
 Аватар для raxper
10237 / 6615 / 498
Регистрация: 28.12.2010
Сообщений: 21,154
Записей в блоге: 1
07.08.2012, 14:28
...запустите W_Term, выберите команду - 20 (считывание метки), отследите что она посылает сниффером и что приходит в ответ.

А по повду Comm32? я знаю, просто еще не совсем догнал как ей читать с порта
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
  public
    { Public declarations }
 
    procedure rec(Sender:TObject; Buffer: pointer; BufferLength: Word);
  end;
 
 
uses Comm32;
 
 
{ ----------------------------------------- }
{ ТЕСТ СЫРЫХ ЗАПРОСОВ БЕЗ PROX232.DLL }
{ ----------------------------------------- }
const  brate: array [1..10] of integer = (1200, 2400, 4800, 9600, 19200, 38400, 57600, 115200, 128000, 256000);
       cmprt: array [1..14] of string = ('COM1','COM2','COM3','COM4','COM5','COM6','COM7','COM8','COM9','COM10','COM11','COM12','COM13','COM14');
 
var  com: Tcomm32;
 
procedure TForm1.FormCreate(Sender: TObject);
var i: integer;
begin
 
 // --------------------------------------------------
 decimalseparator:= '.';
 // динамическое создание COMM32
 com:= Tcomm32.Create(self);
 com.OnReceiveData:= rec;
 
 // настройки порта
 com.BaudRate:= 9600; // скорость
 com.StopBits:= 1;    // стоп-бит
 com.Bits    := 8;    // кол-во
 com.CommPort:= 'COM2'; // номер порта
 
 com.StartComm 
end;
 
 
procedure TForm1.FormDestroy(Sender: TObject);
begin
 com.StopComm;
 com.free
end;
 
 
type tb = array[1..255] of Char;  //Определяем символьный массив
     pb = ^tb;
     TDataByte = array of word;
 
var buf: array of byte;
    id_kadr: integer;
    crc: byte;
 
procedure TForm1.rec(Sender:TObject; Buffer: pointer; BufferLength: Word);
var PX : pb;
    i  : integer;
    str: string;
begin
 PX:= buffer; str:='';
 
 // ЛОГГИРОВАНИЕ ==============================================================
 for i:= 1 to BufferLength do begin
  str:= str +inttohex(ord(PX^[i]), 2) + ' ';
 end; 
 memo1.Lines.Add(str);
 
 // РАЗБОР КОДОГРАММЫ ===========================
 // Кадр ответа считывателя компьютеру
 //
 // Стартовое условие 1 0xFD
 // Адрес 1 0x00
 // Идентификатор кадра 1  Повторение идентификатора кадра компьютера.
 // Код команды 1  Повторение кода команды компьютера.
 // Данные команды  ХХ  Зависит от команды.
 // Контрольная сумма 1  С поля «Адрес» до поля «Данные»
 // Стоповое условие 1 0xFE
 // ===========================================================================
 
 // При разборе кадра следует придерживаться следующих правил:
 if (ord(PX^[1])= $FD) and // cтартовое условие обладает наивысшим приоритетом
    (ord(PX^[7])= $FE) and // cтоповое условие обладает вторым уровнем приоритета
    (ord(PX^[2])= $1)      // адрес обладает третьим уровнем приоритета
  then begin
 
 
  // Байтстаффинг обладает четвертым уровнем приоритета. Ошибка байтстаффинга в процессе
  // разбора потока есть основание для отбрасывания всего потока до следующего стартового
  // условия.
 
  // Разбор кадра начинается с проверки минимально допустимой длины кадра (длина кадра без поля
  // данных) и его контрольной суммы (ищется как смещение от стопового условия). Все остальные
  // поля ищутся как смещения от стартового условия.
 
 end;
 
 
 
 // end РАЗБОР КОДОГРАММЫ ==================
 
end;
0
3 / 3 / 0
Регистрация: 03.05.2010
Сообщений: 116
07.08.2012, 20:15  [ТС]
Я так понимаю, что для использования Comm32 нужно отказаться от Prox232.dll.

Цитата Сообщение от raxp Посмотреть сообщение
...запустите W_Term, выберите команду - 20 (считывание метки), отследите что она посылает сниффером и что приходит в ответ.
При отправке 20 терминал возвращает "Ответ 02 - Получен сигнал NACK2 (неверная команда)"

Запрос:07.08.2012 20:12:30.30664 (+611.4844 seconds)
FD B2 20 9B 27 FE
Ответ:07.08.2012 20:12:30.30664 (+0.0000 seconds)
FD B2 2A 02 67 04 FE

При отправке 45 00 терминал возвразает "Ответ 00 - Команда выполнена успешно., Данные 04 00 88 E5 E3 F0 0C"

Запрос:07.08.2012 20:13:31.96664 (+9.3438 seconds)
FD B5 45 00 ED 4D FE
Ответ:07.08.2012 20:13:31.96664 (+0.0000 seconds)
FD B5 45 04 00 88 E5 E3 F0 0C 6A C8 FE
0
 Аватар для raxper
10237 / 6615 / 498
Регистрация: 28.12.2010
Сообщений: 21,154
Записей в блоге: 1
07.08.2012, 21:17
При отправке 20 терминал возвращает "Ответ 02 - Получен сигнал NACK2 (неверная команда)"

Запрос:07.08.2012 20:12:30.30664 (+611.4844 seconds)
FD B2 20 9B 27 FE
Ответ:07.08.2012 20:12:30.30664 (+0.0000 seconds)
FD B2 2A 02 67 04 FE
в настройках протокола W_Term.exe метод расчета CRC какой стоит?

Я так понимаю, что для использования Comm32 нужно отказаться от Prox232.dll.
именно, PROX232 для запроса и чтения каждый раз открывает и закрывает порт, то есть занимает его на время запрос-ответа. При использовании COMM32 вы можете поступать точно также, а можете продолжать монопольно использовать порт все время.
0
3 / 3 / 0
Регистрация: 03.05.2010
Сообщений: 116
07.08.2012, 22:04  [ТС]
Вот скрины Работа прогаммы в разных режимах
Миниатюры
Аппаратно-программная реализация считывателей БСК MF-RW-USB (старых и новых годов выпуска)   Аппаратно-программная реализация считывателей БСК MF-RW-USB (старых и новых годов выпуска)   Аппаратно-программная реализация считывателей БСК MF-RW-USB (старых и новых годов выпуска)  

Аппаратно-программная реализация считывателей БСК MF-RW-USB (старых и новых годов выпуска)  
0
mrBotsman
27.09.2012, 13:49
подскажите, пожалуйста, где можно взять все команды для работы считывателя с карточками mifare.
на сайте prox.ru в документации есть описание только базовых команд (очень неполный список)
в службу техподдержки обратился, но пока ответа нет.
пишу на VB6, общаться с MF-RW-USB получается через COM-порт.
хотелось-бы узнать у Firmwares'a - получилось работать со считывателем?
3 / 3 / 0
Регистрация: 03.05.2010
Сообщений: 116
07.10.2012, 06:42  [ТС]
mrBotsman, Со считывателем с тех пор так и не занимался - был в отпуске, а потом разгребал завалы на работе.
Если еще нужна инфорация по считывателям, то пишите в личку и я отправлю Вам все, что у меня есть по этому поводу.

Добавлено через 5 часов 50 минут
Значит такое дело!

Если запрос выполнить следующим образом, то он выполняется корректно и ридер скидывает данные.
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
procedure TMain.Read;
 const
 otvet='Есть ответ от ридера...';
 bat = #$00;
 REPLY_OK = #$00;
 REPLY_ACK = #$55;
 REPLY_NACK6 = #$06;
var
  Ret: char;
  RL: integer;
  Event: TEvent;
begin
 Ret := W_IO(#$1, #$45, length(bat), '00', RL, Event);
 if Ret = REPLY_OK then
 memo1.Lines.Add(otvet);
end;
Но теперь мне не принять данные.
Усли я правильно понял, то судя по мануалу ответ от ридера принимается примерно в таком же виде как и запрос, но мне его не сформировать.

Следовательно вопрос:
как получить ответ от ридера и вывести его в Memo.
0
3 / 3 / 0
Регистрация: 03.05.2010
Сообщений: 116
09.10.2012, 18:20  [ТС]
Исправил зпрос на

Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
procedure TMain.Read;
begin
 Ret := W_IO(#$1, #$00, 0, '', ReplyLen, ReplyBuffer);
 
if Ret = REPLY_OK then begin
 Edit1.Text:='Команда выполнена успешно, получены данные';
 Edit2.Text:=(ReplyBuffer);
end;
if Ret= REPLY_ACK then begin
 Edit1.Text:='Получен ответ ACK';
 Edit2.Text:=(ReplyBuffer);
end;
if Ret= REPLY_NACK6 then begin
 Edit1.Text:='Получен ответ NACK6';
 Edit2.Text:=(ReplyBuffer);
end;
 end;
Теперь получается следующее
При первом запросе В Edit1 вписывает "Команда выполнена успешно, получены данные", что и дожно быть в связи с тем, что запрос выполняется успешно.
В Edit2 Вписывает 1.
При второй попытке запроса происходит все тоже самое, но программа выдае ошибку.

Как необходимо правильно составить запрос для того, чтобы Получить данные из ReplyBuffer и вписать в Edit2 в том виде, в котором они получены от считывателя?
Миниатюры
Аппаратно-программная реализация считывателей БСК MF-RW-USB (старых и новых годов выпуска)  
0
3 / 3 / 0
Регистрация: 03.05.2010
Сообщений: 116
16.10.2012, 20:37  [ТС]
Уважаемый raxp, скажите пожалуйста, что не так, вылетает "access violation at address" при работе прогаммы?

Вот весь код.
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
unit Unit1;
 
interface
 
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, SyncObjs;
 
type
  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    Button3: TButton;
    Edit1: TEdit;
    Edit2: TEdit;
    function LinkProc(ProcName: string):Pointer;
    procedure FormCreate(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure Button3Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;
 
  type
  PComInfo = ^ TComInfo;
  TComInfo = record
  RecordSize: DWORD; // Размер структуры, байт
  Port: BYTE; // Номер порта. 1 - COM1 и т.д.
  BaudRate: DWORD; // Скорость обмена
  WaitPortTimeout: DWORD; // Время ожидания доступности порта, мс
  ReadTotalTimeout: DWORD; // Время ожидания ответа считывателя, мс
  ReadNextByteTimeout: DWORD; // Время ожидания поступления очередного
                              // байта при условии, что обнаружено начало
                              // валидного кадра, мс.
  end;
 
  type
  PProtocolInfo = ^ TProtocolInfo;
  TProtocolInfo = record
  DisableAddress: BOOLEAN; // Размер структуры, байт
  CheckMode: INTEGER; // Режим проверки контрольной суммы
  end;
var
  Form1: TForm1;
// набор импортируемых функций
  W_SetPortParams: procedure(PortCfgPtr: PComInfo); stdcall;
  W_SetProtocolParams: procedure(ProtocolInfoPtr: PProtocolInfo); stdcall;
  W_IO: function(Address, Cmd: char;
                 BodyLen: integer;
                 const CmdBody;
                 var ReplyLen: integer;
                 var ReplyBuffer): char; stdcall;
  LibHandle: THandle;
 
  implementation
 
  {$R *.dfm}
 
{ TForm1 }
 
{ TForm1 }
 
function TForm1.LinkProc(ProcName: string): Pointer;
begin
  result:= GetProcAddress(LibHandle,PChar(ProcName));
end;
 
// Подключаем DLL....
procedure TForm1.FormCreate(Sender: TObject);
begin
  LibHandle:= LoadLibrary('dll/ProX232.dll');
  W_SetPortParams:= LinkProc('W_SetPortParams');
  W_SetProtocolParams:= LinkProc('W_SetProtocolParams');
  W_IO:= LinkProc('W_IO');
end;
 
// Устанавливаем параметры порта и создаем подключение....
procedure TForm1.Button1Click(Sender: TObject);
var
  t: TComInfo;
begin
  t.Port:= 3;
  t.BaudRate:= 115200;
  t.WaitPortTimeout:= 200;
  t.ReadTotalTimeout:= 100;
  t.ReadNextByteTimeout:= 50;
  t.RecordSize:= 21; // dword = 4 байтам
  W_SetPortParams(@t)
 end;
 
 // Устанавливаем параметры протакола....
procedure TForm1.Button2Click(Sender: TObject);
var
  Prot: TProtocolInfo;
begin
  Prot.DisableAddress:=true; // Размер структуры, байт
  Prot.CheckMode:=03; // Режим проверки контрольной суммы
  W_SetProtocolParams(@Prot)
end;
 
// Формирем и отправляем запрос....
procedure TForm1.Button3Click(Sender: TObject);
// Описываем константы....
Const
  REPLY_OK = #$0;
  REPLY_ACK = #$55;
var
// Выводим переменные....
  Ret:Char;
  ReplyLen:integer;
  ReplyBuffer:Pointer;
begin
//определяем размер буфера и выделяем под него память....
  ReplyLen:=255;
  ReplyBuffer:=GetMemory(ReplyLen);
// Формируем и отправляем запрос....
  Ret := W_IO(#$1, #$00, 0, '', ReplyLen, ReplyBuffer);
 if Ret = REPLY_OK then
begin
// Выводим ответ от считывателя...
  Edit1.Text:='Команда выполнена успешно, получены данные';
  Edit2.Text:=PChar(ReplyBuffer);
end;
// Освобождаем память...
  FreeMemory(ReplyBuffer);
end;
 
end.
Все бы ничего, но получается попытка доступа к тому, чего нет, а к чему??
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
16.10.2012, 20:37

Вывести список самых новых и самых старых машин для каждой из стоянок,с указанием их владельцев и года выпуска
"В районном обществе автолюбителей имеются сведения об N автомобилях.О каждой машине известно:фамилия владельца,год выпуска и номер...

Получить сведения обо всех владельцах автомашин марки «мерседес», белого цвета, последних трех годов выпуска
Автомобиль характеризуется названием (маркой), годом выпуска, цветом, номером, именем владельца. Получить сведения обо всех владельцах...

KERNELBASE.dll в старых играх играх 2013 годов и позднее
в любых приложениях русифицированных и нет

Реализация деления аппаратно
Здраво Уважаемые форумчане , в процессе учебы возникла задание разработать аппаратное деление двух 3-х разрядных чисел 6/3, читал книги, но...

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


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
35
Ответ Создать тему
Новые блоги и статьи
Вангую, что это не пройдёт модерацию, и на неделе я запущу свой сервер.
Hrethgir 19.07.2026
Эта публикация сейчас в песочнице и ждёт приглашения. https:/ / habr. com/ ru/ sandbox/ 295048/ начало и оглавление - Как «пернатого» заставить осваивать новые горизонты опыта через масштабирование. . .
сукцессия 33. открытые вопросы от клауде
anaschu 19.07.2026
"Что накопилось за эту часть А — тринадцать правок, из которых шесть пришли из ваших вопросов и каждая оказалась реальной ошибкой, а не калибровкой: односторонний симбиоз, отсутствующий листопад,. . .
32 сукцессия
anaschu 19.07.2026
сукцессия 28‑мерное ядро стабилизировано Коллеги, фиксирую разбор инженерных правок и их изоморфную проекцию на экономику, меметику и половой отбор. Модель теперь не «подкручивает» сходимость —. . .
сукцессия 31: модель микоризы - это модель ещё нескольких явлений, социальных и экономических
anaschu 18.07.2026
Теория «Всего»: апдейт v1. 1. 2 — 28‑мерное ядро стабилизировано Коллеги, фиксирую разбор инженерных правок и их изоморфную проекцию на экономику, меметику и половой отбор. Модель теперь не. . .
сукцессия 30. Массив проверяющих друг друга моделей
anaschu 18.07.2026
Архитектура сети взаимопроверяющих моделей микоризной сукцессии (v2. 0) Развитие тензорного ОДУ-ядра и создание кросс-платформенного калибровочного полигона Уважаемые коллеги! В продолжение. . .
Грибы - это женщины, деревья - это мужчины. Анти инь янь для союза мужчины и женщины.
anaschu 18.07.2026
ГЛАВНЫЙ НАУЧНО-ФИЛОСОФСКИЙ ВЫВОД: Сексуально-Репродуктивный Капитализм против Государства Моногамии Коллеги, мы вышли на финишную прямую 20-мерного ОДУ-моделирования вековой сукцессии (ветка. . .
Текстовый слайдер с нумерацией страниц и кроссбраузерность.
russiannick 18.07.2026
Один мой друг написал текстовый слайдер с нумерацией страниц. Сегодня я расскажу как он умудрился подружить его с кроссбраузерностью. Очевидно сложно угодить с шириной каждому браузеру. Один крадет. . .
Грибы - это мемы, дерево - это человек. Применение микоризной модели к теории меметики Докинза.
anaschu 18.07.2026
Меметический изоморфизм теории «всего»: Грибная сукцессия как модель эволюции идей Докинза Базовый код системы ОДУ микоризной сукцессии описывает не просто биологию, а универсальную. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru