Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[18.189.180.76] |
|
Сообщ.
#1
,
|
|
|
Устройство USB-UART cp2102 рабочее. Позволяет программировать прибор, и через него идет считывание данных с прибора через программы-мониторы портов. Но в программе на Delphi не проходит команда SetCommState(Com_Port_Handle, DCB), а GetCommState(Com_Port_Handle, DCB) возвращает все нули. Устройства USB-UART на других микросхемах (например, CH340G) с этой программой работают. В чем может быть проблема?
|
Сообщ.
#2
,
|
|
|
Что значит "не проходит команда SetCommState" ?
|
Сообщ.
#3
,
|
|
|
Если делаю цикл
While Result = false do begin SetCommState(Com_Port_Handle, DCB) ; Result := SetCommState(Com_Port_Handle, DCB); end ; то зависает именно на CP2102. На CH340G все проходит, параметры порта устанавливаются. |
Сообщ.
#4
,
|
|
|
А зачем цикл? Всегда достаточно было одного раза. Что GetLastError сообщает?
Устанавливаемые параметры порта совпадают с теми, что используют другие программы (которые работают)? |
Сообщ.
#5
,
|
|
|
С одного раза не зависает, но и ничего в CP2102 не устанавливает (а в CH340G устанавливает). GetCommState(Com_Port_Handle, DCB) возвращает все нули. GetLastError дает нуль. Параметры, используемые другими программами, неизвестны, но я их довольно много перебрал, все глухо. А на других микросхемах и с одного раза все ставится нормально, и параметры меняю как угодно.
|
Сообщ.
#6
,
|
|
|
В терминале все работает и там и там?
|
Сообщ.
#7
,
|
|
|
Если использую готовые программы-мониторы портов, все работает, данные считываются.
|
Сообщ.
#8
,
|
|
|
Значит ищи ошибку, перепроверь параметры DCB. Запись байт в порт проходит нормально под отладчиком? Если в терминале работает, должно и у тебя в коде.
Добавлено Попробуй portmon. |
Сообщ.
#9
,
|
|
|
И чтение и запись идет нормально через другие программы, устройство рабочее. Параметры DCB на последний момент:
DCB.BaudRate := CBR_9600 ; // DCB.Parity := EVENPARITY ; DCB.Parity := NOPARITY; // DCB.ByteSize := 7 ; DCB.ByteSize := 8 ; DCB.StopBits := ONESTOPBIT ; // DCB.XonLim := 0 ; // DCB.XoffLim := 255 ; // DCB.XonChar := 11 ; // DCB.XoffChar := 13 ; // DCB.StopBits := TWOSTOPBITS ; 9600, NOPARITY, 8 бит, 1 стоп-бит - вроде бы ничего необычного. Ни один параметр даже по отдельности не устанавливается. Без предварительной установки GetCommState(Com_Port_Handle, DCB) возвращает все нули изначально (с другими микросхемами не так). |
Сообщ.
#10
,
|
|
|
Попробуй задержку перед GetCommState поставить. Вызвать его повторно с задержкой.
|
Сообщ.
#11
,
|
|
|
Portmon порт на CP2102 обнаруживает (COM10 как и везде), но активности из под Delphi никакой нет (на других микросхемах и портах что-то пишет).
Добавлено Задержка ничего не дает. |
Сообщ.
#12
,
|
|
|
А терминал соответственно портмон активность показывает? Функция открытия порта как отрабатывает?
|
Сообщ.
#13
,
|
|
|
Может Handle неправильный? Код такой:
procedure TfMT_30.OpenComPort ; {--------------Установить параметры COM-порта--------------------} begin if (Com_Port_Handle = 0) then begin Com_Port_Handle:= CreateFile( pchar(Port_Name), GENERIC_READ or GENERIC_WRITE, //FILE_SHARE_READ, 0, // Not shared nil, // No security attributes OPEN_EXISTING, //CREATE_NEW, //OPEN_EXISTING, // 0, // FILE_FLAG_OVERLAPPED, FILE_ATTRIBUTE_READONLY, 0 // No template ) ; end ; if (Com_Port_Handle = INVALID_HANDLE_VALUE) then begin eReady.Text := 'Ошибка' ; exit ; end ; end ; Хотя ошибки при работе не выдает. |
Сообщ.
#14
,
|
|
|
В коде я имею в виду.
Добавлено Вместо FILE_ATTRIBUTE_READONLY поставь 0 перед GetCommState что-то вроде этого попробуй dcb.DCBlength = sizeof(DCB); |
Сообщ.
#15
,
|
|
|
Portmon на CP2102 вообще ничего не показывает.
|
Сообщ.
#16
,
|
|
|
А и вот еще что, хорошо бы перед GetCommState обнулить dcb, как это в дельфи тебе виднее
Добавлено Цитата Igor_Muhin @ Portmon на CP2102 вообще ничего не показывает. И терминал при этом отрабатывает? Добавлено В CreateFile последний параметр в nil поставь Добавлено Если активности нет, по идеи ты сюда должен свалить eReady.Text := 'Ошибка' ; потому как порт не открылся |
Сообщ.
#17
,
|
|
|
Вместо FILE_ATTRIBUTE_READONLY 0 ничего не дает.
dcb.DCBlength = sizeof(DCB); ничего не дает. Portmon активности никакой не показывает. Зато после всех манипуляций и порты на других микросхемах стали вести себя так же. Добавлено Ну, да: if (Com_Port_Handle = INVALID_HANDLE_VALUE) then begin eReady.Text := 'Ошибка' ; exit ; end ; Но ошибки, получается нет, т. е. Handle правильный. |
Сообщ.
#18
,
|
|
|
Хорошо, верни в CreateFile как было, а со структурой dcb
сначала ее обнуляешь, потом присваиваешь длину, потом вызов getCommState и нули? Добавлено Если в терминале работает, ну не знаю. Можно посмотреть в сторону таймаутов COMMTIMEOUTS CommTimeOuts; CommTimeOuts.ReadIntervalTimeout := 0xFFFFFFFF; CommTimeOuts.ReadTotalTimeoutMultiplier := 0; CommTimeOuts.ReadTotalTimeoutConstant := TIMEOUT; CommTimeOuts.WriteTotalTimeoutMultiplier := 0; CommTimeOuts.WriteTotalTimeoutConstant := TIMEOUT; SetCommTimeouts(m_Handle, &CommTimeOuts) |
Сообщ.
#19
,
|
|
|
Таймауты пока отключены. Вернулся назад, выполняю только процедуру открытия порта CreateFile и процедуру закрытия. Для CP2102 Portmon никакой активности вообще не показывает, для других микросхем и портов минимальная активность в три строчки имеется. Только что-то этот Portmon систему портит, порты как бы остаются после их изъятия, некоторые становятся неправильным оборудованием, вплоть до жесткий диск стал несистемным. Возможно, все-таки где-то на уровне CreateFile что-то идет не так.
Добавлено Когда в CreateFile задаю имя порта как Pchar('\\.\'+ Port_Name) вместо Pchar(Port_Name), то Portmon активность для CP2102 показывает, GetCommState и SetCommState вроде бы тоже работают, т. е. вроде бы пока процесс пошел. А что такое здесь это '\\.\' и что оно дает? Добавлено Получается что вместо COM10 надо записать \\.\COM10? |
Сообщ.
#20
,
|
|
|
Igor_Muhin, ter_nk_
M Используем тег [code] для добавления текста программы в пост! Устное предупреждение! Читаем правила! |
Сообщ.
#21
,
|
|
|
В общем, когда задаю в CreateFile имя порта как Pchar('\\.\'+ Port_Name) вместо Pchar(Port_Name), где Port_Name = 'COM10' (получается программно), то порт на CP2102 (действительно COM10 по диспетчеру устройств) устанавливается нормально и даже уже удается иногда прочитать правильные числа с прибора. Зачем нужна добавка '\\.\', пока не понял. Только Portmon при использовании для контроля портит дело, приходится перезагружать компьютер.
|
Сообщ.
#22
,
|
|
|
Цитата Igor_Muhin @ В общем, когда задаю в CreateFile имя порта как Pchar('\\.\'+ Port_Name) вместо Pchar(Port_Name), где Port_Name = 'COM10' (получается программно), то порт на CP2102 (действительно COM10 по диспетчеру устройств) устанавливается нормально и даже уже удается иногда прочитать правильные числа с прибора. Зачем нужна добавка '\\.\', пока не понял. Только Portmon при использовании для контроля портит дело, приходится перезагружать компьютер. Там где порт больше девятого надо '\\.\' ставить. При открытии файла где длина пути больше 255 тоже надо добавлять "абсолютный" путь. |
Сообщ.
#23
,
|
|
|
Понятно, спасибо. А корректно этот префикс к именам первых портов (COM1-COM9) тоже добавлять для простоты? Я пока ко всем добавляю, вроде бы работает.
|
Сообщ.
#24
,
|
|
|
Цитата Igor_Muhin @ Понятно, спасибо. А корректно этот префикс к именам первых портов (COM1-COM9) тоже добавлять для простоты? Я пока ко всем добавляю, вроде бы работает. Не обязательно добавлять. Я кстати не знал, что выше 9 надо добавлять, в дотнетовском проекте когда делал, у меня было до фига ком-портов и все работало. |
Сообщ.
#25
,
|
|
|
> корректно этот префикс к именам первых портов (COM1-COM9) тоже добавлять для простоты?
Да, корректно. (Это UNC-нотация) |
Сообщ.
#26
,
|
|
|
Igor_Muhin после CreateFile() и настройки порта CP2102 обязательно поставь задержку перед передачей данных. Сталкивался с некоторым такими девайсами (завит от настроения производителя) которые не воспринимали начальную посылку данных.
|
Сообщ.
#27
,
|
|
|
та же проблема. 1 в 1.
|