На Ком порте висит модем, нужно записать в него Ат команду и получить отклик от него, точнее результат выполнения этой команды,. Послать команту просто:
HANDLE hCOM=CreateFile("COM1",GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
if (hCOM!=INVALID_HANDLE_VALUE){
ShowMessage("COM1 is open OK!");
DWORD nb;
OVERLAPPED ov;
//записываем команду
WriteFile(hCOM,"AT+CPBR=1",9,&nb,&ov);
//читаем результатв ch - хотя я незнаю здесь ли нужно это делать
char ch[10];
ReadFile(hCOM,ch,10,&nb,0);
ShowMessage(ch);
CloseHandle(hCOM);
}else
ShowMessage("Error Open " + edPort->Text);
Прошу поправить меня если я не прав, команды посылаются, а в ch пусто, что-то я делаю не так, а что??? Большое спасибо...
[C++] MSDN02.11.03 14:49 Автор: amirul <Serge> Статус: The Elderman
> hCOM=CreateFile("COM1",GENERIC_WRITE,0,NULL,OPEN_EXISTING,F > ILE_ATTRIBUTE_NORMAL,NULL); Для использования OVERLAPPED файл надо открывать с FILE_FLAG_OVERLAPPED.
> if (hCOM!=INVALID_HANDLE_VALUE){ > ShowMessage("COM1 is open OK!"); > > DWORD nb; > OVERLAPPED ov; > //записываем команду > WriteFile(hCOM,"AT+CPBR=1",9,&nb,&ov); А зачем вообще тут overlapped?
> Прошу поправить меня если я не прав, команды посылаются, а > в ch пусто, что-то я делаю не так, а что??? Большое > спасибо... В общем смотри в сторону SetCommMask/WaitCommEvent в частности и Platform SDK: Communication Functions вообще. Кроме того, советую заглянуть в пример работы с ком-портом все в том же MSDN-е. Алгоритм примерно следующий:
Записывается команда, ставится маска на EV_RXCHAR, ставится ожидание событий из порта, когда событие пришло - можно читать.
Ну смотри я сделал следующим образом, но как была строка пустой так и осталась...
HANDLE hCOM=CreateFile("COM1",GENERIC_WRITE | GENERIC_READ,0,NULL,OPEN_EXISTING,FILE_FLAG_OVERLAPPED,NULL);
if(hCOM!=INVALID_HANDLE_VALUE){
ShowMessage("COM1 is open OK!");
ShowMessage(ch);
CloseHandle(hCOM);
}else
ShowMessage("Error Open COM1");
Может я опять наглючил чтонибудь, хотя я непонял какого сообщания нужно ждать я просто ставлю время на WaitForSingleObject 100 мл сек если за это время объект не ответил, то выходим, а если всё нормально, то читам данные.
ЭТО правильно?
[C++] SetCommMask/WaitCommEvent03.11.03 11:09 Автор: amirul <Serge> Статус: The Elderman
> Ну смотри я сделал следующим образом, но как была строка > пустой так и осталась... > HANDLE hCOM=CreateFile("COM1",GENERIC_WRITE | > GENERIC_READ,0,NULL,OPEN_EXISTING,FILE_FLAG_OVERLAPPED,NULL > ); Странный ты, ей богу. Теперь указал FILE_FLAG_OVERLAPPED, но не используешь его :-))
> WriteFile(hCOM,"ATI2",edPort->Text.Length(),&nb,0); > if(WaitForSingleObject(hCOM,100) == WAIT_TIMEOUT){ > ShowMessage("Время кончилось..."); > return; > } Ладно. Не хочешь сам смотреть MSDN, покажу. Вот в точности пример оттуда:
HANDLE hCom;
OVERLAPPED o;
BOOL fSuccess;
DWORD dwEvtMask;
hCom = CreateFile( "COM1",
GENERIC_READ | GENERIC_WRITE,
0, // exclusive access
NULL, // no security attributes
OPEN_EXISTING,
FILE_FLAG_OVERLAPPED,
NULL
);
if (hCom == INVALID_HANDLE_VALUE)
{
// Handle the error.
}
// Set the event mask.
fSuccess = SetCommMask(hCom, EV_CTS | EV_DSR);
if (!fSuccess)
{
// Handle the error.
}
// Create an event object for use in WaitCommEvent.
o.hEvent = CreateEvent(
NULL, // no security attributes
FALSE, // auto reset event
FALSE, // not signaled
NULL // no name
);
assert(o.hEvent);
if (WaitCommEvent(hCom, &dwEvtMask, &o))
{
if (dwEvtMask & EV_DSR)
{
// To do.
}
if (dwEvtMask & EV_CTS)
{
// To do.
}
}
---
Единственное, что тебе надо исправить это тип события (EV_RXCHAR в твоем случае). Кроме того, гораздо правильнее было бы поставить SetCommTimeouts и сделать ReadFile (а не ждать хендл, при работе с COM портом это вообще практически никогда не делается)
> Может я опять наглючил чтонибудь, хотя я непонял какого > сообщания нужно ждать я просто ставлю время на > WaitForSingleObject 100 мл сек если за это время объект не > ответил, то выходим, а если всё нормально, то читам данные. > ЭТО правильно? Нет :-)))
Почитай MSDN все таки :-)
У меня вообще команда не доходит чтоли???03.11.03 23:36 Автор: CrazyPitbull Статус: Незарегистрированный пользователь
Может можно где посмотреть примеры терминала... Я посмотрел одной программкой, команды посылаются и выполняются. Но мне не сделать так, чтобы можно было послать программку (код уже показывал). Может где-нибудь можно посмотреть как это делается?
В MSDN-е полно примеров работы с портом04.11.03 15:09 Автор: amirul <Serge> Статус: The Elderman
> Может можно где посмотреть примеры терминала... Я > посмотрел одной программкой, команды посылаются и > выполняются. Но мне не сделать так, чтобы можно было > послать программку (код уже показывал). Может где-нибудь > можно посмотреть как это делается? Если не нравится MSDN, то наверное лучше воспользоваться билдеровской компонентой.
Хотя общая идея работы с com-портом: практически все что делается, делается после ожидания событий. В принципе хорошим вариантом будет даже запустить поток, который будет постоянно ждать event-ы, а потом запускать колбяки на каждый из них.
И всётаки почему мой код на работает?04.11.03 16:52 Автор: CrazyPitbull Статус: Незарегистрированный пользователь
> WriteFile(hCOM,"ATDT111111\xD",13,0,0); "ATDT111111\xD"
-это 11 символов \xD это один символ с кодом 13 - переволд строки. Для модема означает конец команды. Надо так
WriteFile(hCOM,"ATDT111111\xD",11,0,0);
Может это смешно, но всёравно не работает...04.11.03 01:17 Автор: CrazyPitbull Статус: Незарегистрированный пользователь
WriteFile(hCOM,"ATI2",edPort->Text.Length(),&nb,0);
а надо
WriteFile(hCOM,"ATI2\xD",5,&nb,0);
Вообще имхо если ты пишешь втебе билдере то есть хороший компонент обертка вокруг ком порта - ComDrv32. Халявный и с сырцами. Недостаток в том что не умеет открывать порты больше 4го но это легко фиксится благодаря сырцам. Да и 100мсек имхо маловато. Например ATZ может выполняться до пары секунд на некоторых модемах.
А что за компанент?03.11.03 23:30 Автор: CrazyPitbull Статус: Незарегистрированный пользователь
Линка внизу. Вот кстати мот тебе поможет... тут кусок одной моей проги - инициализация модема через CreateFile и потом инициализация этого ComDrv32 для работы если с модемом все ок.
void __fastcall TForm1::reinit(int index)
{
flags[index]|=1;
if(comms[index]->Connected())
{
sendcmd(index,postinit,0,300);
comms[index]->Disconnect();
}
//else
{
AnsiString cp="\\\\.\\COM"+(AnsiString)(index+1);
HANDLE f=CreateFile(cp.c_str(),GENERIC_READ|GENERIC_WRITE,0,0,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);
if(f==INVALID_HANDLE_VALUE)
{
ListView1->Items->Item[index]->Checked=false;
return;
}
CloseHandle(f);
comms[index]->Connect();
comms[index]->Disconnect();
f=CreateFile(cp.c_str(),GENERIC_READ|GENERIC_WRITE,0,0,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);
DWORD dw=0;
COMMTIMEOUTS cmto,cmt;
int er=GetCommTimeouts(f,&cmto);cmt=cmto;
cmt.WriteTotalTimeoutMultiplier=10;
cmt.WriteTotalTimeoutConstant=100;
char xxx[32];dw=0;
SetCommTimeouts(f,&cmt);
int n=0,xcon=1;
WriteFile(f,"\x0D",1,&dw,0);
Sleep(200);
ReadFile(f,xxx,32,&dw,0);
do
{
DWORD tmx=GetTickCount()+3000;
ZeroMemory(xxx,32);
WriteFile(f,"atz\x0D",4,&dw,0);
int x=0;
do
{
ReadFile(f,xxx+x,32,&dw,0);
}while((!strstr(xxx,"ERROR\x0D"))&&(!strstr(xxx,"OK\x0D"))&&(GetTickCount()<tmx));
n++;
}while((!strstr(xxx,"OK\x0D"))&&(n<2));
if(!strstr(xxx,"OK\x0D"))xcon=0;
else
{
n=0;
do
{
ZeroMemory(xxx,32);
DWORD tmx=GetTickCount()+3000;
WriteFile(f,"ate0\x0D",5,&dw,0);
do
{
ReadFile(f,xxx,32,&dw,0);
}while((!strstr(xxx,"ERROR\x0D"))&&(!strstr(xxx,"OK\x0D"))&&(GetTickCount()<tmx));
n++;
}while((!strstr(xxx,"OK\x0D"))&&(n<4));
};
SetCommTimeouts(f,&cmto);
CloseHandle(f);
if(!xcon)
{
ListView1->Items->Item[index]->Checked=false;
flags[index]&=~1;
return;
}
dtmfs[index]=rets[index]="";
rbacks[index]=0;
switch(hwhandshake)
{
case 1:comms[index]->ComPortHwHandshaking=hhRTSCTS;break;
default:comms[index]->ComPortHwHandshaking=hhNONE;
}
switch(swhandshake)
{
case 1:comms[index]->ComPortSwHandshaking=shXONXOFF;break;
default:comms[index]->ComPortSwHandshaking=shNONE;
}
switch(portspeed)
{
case 0 :comms[index]->ComPortSpeed=br110;break;
case 1 :comms[index]->ComPortSpeed=br300;break;
case 2 :comms[index]->ComPortSpeed=br1200;break;
case 3 :comms[index]->ComPortSpeed=br2400;break;
case 4 :comms[index]->ComPortSpeed=br4800;break;
case 5 :comms[index]->ComPortSpeed=br9600;break;
case 6 :comms[index]->ComPortSpeed=br14400;break;
case 7 :comms[index]->ComPortSpeed=br19200;break;
case 8 :comms[index]->ComPortSpeed=br38400;break;
case 9 :comms[index]->ComPortSpeed=br56000;break;
case 10:comms[index]->ComPortSpeed=br57600;break;
case 11:comms[index]->ComPortSpeed=br115200;break;
default:comms[index]->ComPortSpeed=br115200;
}