Modem_init or Comm*
- From
- Henry Tabunkin (2:5054/39)
- To
- Timur Shemsedinov
- Date
- 2002-05-05T04:06:26Z
- Area
- SU.WINDOWS.NT.PROG
Приветствую вас уважаемый(-ая)(-ое), Timur!
Как-то 23 Apr 02 в аккурат в 21:55, некто Timur Shemsedinov отписал к All на вот такую занятную тему как "Modem_init or Comm*":
TS> Киньте, если имеете, пpимеpчик инициализации модема, желательно чеpез,
TS> WinApi т.е. CreateFile, Comm* На асме я когда-то пpогpаммиpовал
TS> микpосхему чеpез поpты, но тут же ж под NT по pучкам надают, так что
TS> интеpесует как установить: - скоpость обмена - четность - битов в
TS> байте - стоповых битов А вообще будет великолепно, если есть пpимеp с
TS> CreateEvent для чтения данных с поpта в отдельном тpеде, посаженном на
TS> событие. Если я пpавильно понял, как это в винде культуpно делать?
Есть паpа соpцов.
1. За 100% pаботоспособность пеpвого файла не pучаюсь, ибо его _желательно_
попpавить под свои нужды, но общее напpавление там достаточно веpное.
(Я его как-то пользовал как "темплейт")
2. Вопpосы к автоpу исходного письма (а шапке)
№1.
=== Cut ===
// Open_Comport
// -------------
// Opens a communications port for use.
//
// Returns: Handle number if successful, else 0
//
// Comport = Communications port to open (ie. 1, 2, 3, 4, ... 255)
// BaudRate = Desired baud rate (ie, 110, 300, 600, 1200, 2400, 4800, 9600,
19200, ...)
//
HANDLE Open_Comport (DWORD Comport, DWORD BaudRate)
{
HANDLE DriverHandle;
char Com_Name[10];
DWORD DCB_Baud_Rate;
DCB Our_DCB;
//
// Range check the Comport number
//
if (Comport > 255) {
return INVALID_HANDLE_VALUE;
}
//
// Make a COMPORT name from a number
//
sprintf(Com_Name, "COM%i", Comport);
//
// Convert the Baud Rate to the Com library define for the DCB
//
switch (BaudRate) {
case 110:
DCB_Baud_Rate = 110;
break;
case 300:
DCB_Baud_Rate = CBR_300;
break;
case 600:
DCB_Baud_Rate = CBR_600;
break;
case 1200:
DCB_Baud_Rate = CBR_1200;
break;
case 2400:
DCB_Baud_Rate = CBR_2400;
break;
case 4700:
DCB_Baud_Rate = CBR_4800;
break;
case 9600:
DCB_Baud_Rate = CBR_9600;
break;
case 19200:
DCB_Baud_Rate = CBR_19200;
break;
case 38400:
DCB_Baud_Rate = CBR_38400;
break;
case 57600:
DCB_Baud_Rate = CBR_57600;
break;
case 115200:
DCB_Baud_Rate = CBR_115200;
break;
default:
return INVALID_HANDLE_VALUE;
}
//
// Open a channel to the Comport - This example DOES NOT use overlapped
I/O
// Since the benefits of overlapped I/O are few, we suggest not using
it.
//
DriverHandle = CreateFile (Com_Name, GENERIC_READ | GENERIC_WRITE,
0, NULL, OPEN_EXISTING, 0, NULL);
//
// Do we have a valid handle? (If not, the driver probably isn't loaded)
//
if (DriverHandle == INVALID_HANDLE_VALUE) {
return (DriverHandle);
} else {
//
// The SetupComm() function establishes the Transmit and Receive
// buffer sizes.
//
SetupComm (DriverHandle, 1024, 1024);
//
// Obtain the current DCB structure. this can be saved away for
restore after
// the application is done using the Comport
//
GetCommState (DriverHandle, &Our_DCB);
//
// Fill in the DCB structure with our own settings.
//
Our_DCB.BaudRate = DCB_Baud_Rate;
Our_DCB.fParity = 0;
Our_DCB.fOutxCtsFlow = 0;
Our_DCB.fOutxDsrFlow = 0;
Our_DCB.fDtrControl = DTR_CONTROL_ENABLE;
Our_DCB.fDsrSensitivity = FALSE;
Our_DCB.fTXContinueOnXoff = 0;
Our_DCB.fOutX = 0;
Our_DCB.fInX = 0;
Our_DCB.fErrorChar = 0;
Our_DCB.fNull = 0;
Our_DCB.fRtsControl = RTS_CONTROL_DISABLE;
Our_DCB.fAbortOnError = 0;
Our_DCB.ByteSize = 8;
Our_DCB.Parity = NOPARITY;
Our_DCB.StopBits = ONESTOPBIT;
//
// Configure the comport with our new DCB
//
SetCommState (DriverHandle, &Our_DCB);
//
// Setup a mask that allows us to tell if the port is done
transmitting
// the current buffer of data
//
SetCommMask (DriverHandle, EV_TXEMPTY);
}
return DriverHandle;
}
// Close_Comport
// -------------
// Closes a communications port previously opened
// Returns: TRUE on success, FALSE on failure
// DriverHandle = Handle returned on Open_Comport() call
int Close_Comport (HANDLE DriverHandle)
{
//
// Sanity check on the Handle
//
if ((DriverHandle == 0) || (DriverHandle == INVALID_HANDLE_VALUE)) {
return FALSE;
}
//
// Close the communications port
//
CloseHandle (DriverHandle);
return TRUE;
}
//
// Write_Comport
// -------------
// Writes a buffer of data out the RS232 commmunications port
//
// Returns: TRUE on success, FALSE on failure
//
// DriverHandle = Handle returned on Open_RS232() call
// NumBytes = Number of bytes to send
// Buffer = Buffer of data to send
int Write_Comport (HANDLE DriverHandle, DWORD NumBytes, void *Buffer)
{
DWORD BytesWritten;
// DWORD EvtMask;
// BOOL status;
//
// Sanity check on the Handle
//
if ((DriverHandle == 0) || (DriverHandle == INVALID_HANDLE_VALUE)) {
return FALSE;
}
//
// Some devices may require setting RTS or DTR to specific states prior
to
// tranmission of data
//
EscapeCommFunction (DriverHandle, SETRTS);
//
// Output the data to the Comport
//
// status = WriteFile (DriverHandle, Buffer, NumBytes, &BytesWritten, 0);
WriteFile (DriverHandle, Buffer, NumBytes, &BytesWritten, 0);
//
// If you want, use the WaitCommEvent() function to wait for the
// data Transmission to complete
//
// WaitCommEvent(DriverHandle, &EvtMask, NULL);
//
// Some devices may require clearing RTS or DTR to after transmission of
data
//
EscapeCommFunction (DriverHandle, CLRRTS);
return TRUE;
}
//
// Read_Comport
// -------------
// Reads data received on the RS232 communications port
//
// Returns: TRUE on success, FALSE on failure
//
// DriverHandle = Handle returned on Open_RS232() call
// BytesRead = Number of bytes read by the ReadFile() function
// BufferSize = Size of Buffer in bytes
// Buffer = Data buffer that holds received data
//
int Read_Comport (HANDLE DriverHandle, DWORD *BytesRead, DWORD BufferSize,
void *Buffer)
{
COMSTAT Our_Comstat;
DWORD Com_Errors, BytesToRead;
//
// Sanity check on the Handle
//
if ((DriverHandle == 0) || (DriverHandle == INVALID_HANDLE_VALUE)) {
return FALSE;
}
//
// By far the most efficient way to input Comport data is the following:
// ---------------------------------------------------------------------
// A) See how much data is present
// B) Read exactly that amount of data
//
// Note: It is possible to ask for more data than is present, but the
ReadFile()
// function call will not return until that amount of data has
been received.
// Some programs will request more data and establish a timeout
using the
// SetCommTimeouts() function to return from the ReadFile()
function when
// not enough data has been receive. Although this may work, it is
inefficient
// and generally works like crap. For everyone's sake, use the
technique above
// and handle your own timeout in applications code.
//
// Check the Input buffer
//
ClearCommError (DriverHandle, &Com_Errors, &Our_Comstat);
//
// ReadFile() only if there is data.
//
if (Our_Comstat.cbInQue > 0) {
//
// Make sure we do not overrun the Buffer
//
if (Our_Comstat.cbInQue > BufferSize) {
BytesToRead = BufferSize;
} else {
BytesToRead = Our_Comstat.cbInQue;
}
//
// Read the data, no (NULL) Overlapped I/O
//
ReadFile(DriverHandle, Buffer, BytesToRead, BytesRead, NULL);
} else {
*BytesRead = 0;
}
return TRUE;
}
=== Cut ===
№2.
=== Cut ===
═ RU.VISUAL.CPP (2:5054/45.7) ═════════════════════════════════ RU.VISUAL.CPP ═
Msg : 487 of 861 -476 +516
From : Dmitry A. Semenets 2:5020/400 17 Jan 01 12:40:09
To : All 18 Jan 01 07:11:09
Subj : Re: команды модему
═══════════════════════════════════════════════════════════════════════════════
From: "Dmitry A. Semenets" <alta@atm-lan.com.ua>
> Написал как-то Dmitry A. Semenets к All следующие строки:
> >> Необходимо используя API функции работы с портами посылать команды
> >> модему типа ATZ|и в таком роде. Куда копать?
> DS> Посылать прямо в порт соответсвующую комманду прямо в чистом виде,
> DS> ждать ответа (OK).
> Вот именно это меня и интересует.Если нетрудно пару строк кода.
> Я пробавал CreateFile...WriteFile.
В принципе - правильно. Но настаивать параметры порта тоже нужно. Попробуй
следующий код.
================= CUT ======================
// Opening Comm Port
// Используется асинхронный ввод/вывод
hFile=CreateFile("COM2", GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
FILE_FLAG_OVERLAPPED, NULL);
if (hFile == INVALID_HANDLE_VALUE)
{
Report("CreateFile");
return 1;
};
DCB dcb;
char buffer[70];
// Set Comm port params
// Получаем оригинальные параметры.
if (!GetCommState(hFile, &dcb))
{
nRetCode=1;
Report("GetCommState");
goto exit_app;
};
// Здесь настраиваем свои параметры. Остальные остаются оригинальными.
if (!BuildCommDCB("baud=19200 parity=N data=8 stop=1", &dcb))
{
nRetCode=1;
Report("BuildCommDCB");
goto exit_app;
};
if (!SetCommState(hFile, &dcb))
{
nRetCode=1;
Report("SetCommState");
goto exit_app;
};
=============== end CUT =================
функция Report выводит информацию об ошибке. Далее как обычно WriteFile,
ReadFile.
Может быть в конце каждой комманды нужно ставить конец строки.
-+- ifmail v.2.15dev5
+ Origin: Svit Online (post does not reflect views of Golden Tele (2:5020/400)
=== Cut ===
До следующего коннекта!
the Hunter.
[39 кошек] [HoM&M] [Metal Music] [No Smoking]
--- Not yet implemented
* Origin: -=<{\/\_ Видеть звуки... слышать звезды... _/\/}>=- (2:5054/39)