¦þ¹ ¼³¾Šł
¦þ¹ ¼³¾Šł
¦þ¹ ¼³¾Šł
Create successful ePaper yourself
Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.
Êîäèíã<br />
C/C++: ÐÀÁÎÒÀÅÌ Ñ COM-ÏÎÐÒÎÌ<br />
Íèêîëàé «GîrluM» Àíäðååâ (gorlum@real.xakep.ru)<br />
Âõîäèò è<br />
Âûõîäèò....<br />
Ðàáîòàåì ñ COM-ïîðòîì<br />
Äàâíûì-äàâíî, âî âðåìåíà ñòàðîãî äîáðîãî DOS`à, ðàáîòàòü ñ õàðäâàðîì áûëî ãîðàçäî ïðîùå.<br />
Âçÿòü, íàïðèìåð, óïðàâëåíèå êîììóíèêàöèîííûìè ïîðòàìè. Ïðîãðàììû òîãäà èñïîëüçîâàëè<br />
ïðåðûâàíèÿ è îáùàëèñü ñ óñòðîéñòâàìè íàïðÿìóþ (ýòî áûëî íàñòîÿùåå ðàçäîëüå<br />
âèðìåéêåðàì). Ñ òåõ ïîð ìíîãîå ïåðåìåíèëîñü. Íà ñìåíó ÄÎÑó ïðèøëè âèíäû, à ñ íèìè è<br />
íîâûå ïðàâèëà. Òåïåðü ïðîãðàììû, ðàáîòàþùèå â Windows, îáùàþòñÿ ñ óñòðîéñòâîì íå íàïðÿìóþ,<br />
à ÷åðåç ñïåöèàëüíûå WinAPI ôóíêöèè. Âîò ýòè ñàìè WinAPI ôóíêöèè ìû ñåãîäíÿ è<br />
áóäåì èçó÷àòü. Ðàçáåðåì ðàáîòó ñ COM-ïîðòîì, à â êà÷åñòâå ïðèìåðà íàïèøåì ïðîñòåíüêóþ<br />
òåðìèíàëüíóþ ïðîãðàììó äëÿ ìîäåìà ñ ïðîñòûì è êðàñèâûì ãðàôè÷åñêèì èíòåðôåéñîì.<br />
Íèêîëàé "GorluM" Àíäðååâ (gorlum@real.xakep.ru)<br />
Ðàáîòàåì êàê ñ ôàéëîì<br />
Ñàìà ñèñòåìà äðàéâåðîâ, äà è âèíäîâ â öåëîì, ïîçâîëÿåò ðàáîòàòü ñ êîììóíèêàöèîííûìè<br />
ïîðòàìè (íå òîëüêî COM, íî è LPT) êàê ñ îáûêíîâåííûìè ôàéëàìè. Òî åñòü äëÿ<br />
ýòîãî áóäóò èñïîëüçîâàòüñÿ òå æå ôóíêöèè, ÷òî è ïðè ðàáîòå ñ ôàéëàìè. Âîò êàê ýòî<br />
ðåàëèçóåòñÿ. Äëÿ íà÷àëà âçàèìîäåéñòâèÿ ñ ïîðòîì íåîáõîäèìî ïîëó÷èòü åãî õýíäë ïðè<br />
ïîìîùè ôóíêöèè CreateFile. Ïðè÷åì ïàðàìåòðû òî÷íî òàêèå æå, êàê è ïðè ðàáîòå ñ<br />
ôàéëàìè, òîëüêî â ïîëå èìåíè ôàéëà ìû ñòàâèì èìÿ ïîðòà - "COM1", "COM2" è ò.ï.:<br />
HANDLE hCom =<br />
CreateFile("COM1",GENERIC_READ|GENERIC_WRITE,0,0,OPEN_EXISTING,0,0);<br />
Äëÿ äðóãèõ ïðèëîæåíèé äðàéâåð ïîðòà ïîëó÷èò ñòàòóñ "çàíÿòûé", è â ïåðåìåííîé<br />
hCom îêàæåòñÿ HANDLE ïîðòà. Òåïåðü ìû ìîæåì ðàáîòàòü ñ íèì ïðè ïîìîùè äâóõ<br />
api-ôóíêöèé: ReadFile è WriteFile. Íàïðèìåð, äëÿ òîãî ÷òîáû ïîñëàòü â ïîðò ñòðîêó<br />
buffer, íåîáõîäèìî ñäåëàòü ñëåäóþùåå:<br />
WriteFile(hCom, buffer, strlen(buffer), &n, 0);<br />
 ïåðâîì ïàðàìåòðå ýòîé ôóíêöèè ìû ïåðåäàåì õýíäë ïîðòà, äàëåå óêàçàòåëü íà<br />
ñòðîêó, îáúåì ïîñûëàåìûõ áàéò, çàòåì óêàçàòåëü íà ïåðåìåííóþ òèïà DWORD, â êîòîðóþ<br />
çàíåñåòñÿ êîëè÷åñòâî ïîñëàííûõ áàéò, è óêàçàòåëü íà overlapped-áóôåð (îí<br />
íàì íå íóæåí, ïîýòîìó ïðîñòî ïåðåäàåì íîëü).<br />
À âîò ÷òî íåîáõîäèìî ñäåëàòü, ÷òîáû ïðî÷èòàòü èç ïîðòà ñòðîêó äëèíîé â 6 ñèìâîëîâ:<br />
ReadFile(hCom, &buffer, 6, &n, 0);<br />
Ó ýòîé ôóíêöèè åñòü îäèí íþàíñ. Ïðè çàïóñêå îíà æäåò ïîÿâëåíèÿ çàäàííîãî êîëè÷åñòâà<br />
áàéò â ïîðòó. Åñëè ïðèõîäèò ìåíüøå îæèäàåìîãî, òî ôóíêöèÿ ïðîñòî íå âåðíåò óïðàâëåíèÿ<br />
ïðîãðàììå è áóäåò äîæèäàòüñÿ îñòàâøèõñÿ áàéò. ×òîáû óáðàòü òàêèå "çàâèñàíèÿ"<br />
èç ïðîãðàììû, ìû ìîæåì ñäåëàòü ñëåäóþùåå: â öèêëå ÷èòàòü ïî îäíîìó áàéòó èç<br />
ïîðòà è òîò÷àñ æå åãî âûâîäèòü. Íî â òî æå âðåìÿ ó íàñ íå ïîëó÷èòñÿ îäíîâðåìåííî ïèñàòü<br />
â ïîðò è ñ÷èòûâàòü. À âûõîä èç ñëîæèâøèéñÿ ñèòóàöèè ïðîñò! Íàì íàäî ñîçäàòü ïîòîê,<br />
òî åñòü ôóíêöèþ, ðàáîòàþùóþ ïàðàëëåëüíî ñ îñíîâíîé ïðîãðàììîé, â êîòîðûé ìû<br />
è ïîìåñòèì íàø öèêë ÷òåíèÿ. Äëÿ ýòîãî ìû îïðåäåëèì ôóíêöèþ è äîáàâèì â íåå öèêë:<br />
DWORD __stdcall ReadThread(LPVOID param){<br />
// ... òóò öèêë ÷òåíèÿ<br />
}<br />
À óæå èç ìåéíîâîé ôóíêöèè çàïóñòèì ïðè ïîìîùè WinAPI íàø ïîòîê:<br />
HANDLE hThread = CreateThread(0, 0, ReadThread, (LPVOID)0, 0, 0);<br />
È âðîäå áû âñå çàìå÷àòåëüíî: â îäíîì ïîòîêå ó íàñ èäåò ÷òåíèå è âûâîä, â äðóãîì<br />
(ãëàâíîì) - ìû ââîäèì äàííûå è ïîñûëàåì èõ â ïîðò. Íî òóò êðîåòñÿ åùå îäíà ïðîáëåìà.<br />
Íàì íåëüçÿ îäíîâðåìåííî ÷èòàòü è ïîñûëàòü äàííûå! Òî åñòü â òî âðåìÿ, ïîêà<br />
èç ïîðòà íè÷åãî íå ïðèøëî, è ReadFile ñïîêîéíî æäåò ñâîåãî áàéòèêà, ìû íå ìîæåì<br />
ïîñëàòü äàííûå. Êàê æå áûòü Ïðîñòî ïðåæäå ÷åì îòïðàâèòü óæå ââåäåííûå äàííûå,<br />
ìû êèëëàíåì ïîòîê. Óáüåì, ïîøëåì, à çàòåì ñíîâà ñîçäàäèì. È òàê êàæäûé ðàç,<br />
êîãäà çàõîòèì ïîñëàòü ÷òî-ëèáî â ïîðò. Óáèâàòü ïîòîê ìû áóäåì ïðè ïîìîùè ôóíêöèè<br />
TerminateThread, â ïåðâîì ïàðàìåòðå êîòîðîé ïåðåäàäèì óêàçàòåëü íà ïîòîê<br />
(hThread), à âî âòîðîì - êîä çàâåðøåíèÿ (0). Âûãëÿäèò âñå ýòî òàê:<br />
86<br />
// Óáèâàåì íèòü ÷òåíèÿ äàííûõ<br />
TerminateThread(hThread,0);<br />
// Îòïðàâëÿåì òåêñò<br />
WriteFile(hCom, writebuffer, strlen(writebuffer), &n1, 0);<br />
// Çàíîâî ñîçäàåì ïîòîê<br />
hThread = CreateThread(0, 0, ReadThread, (LPVOID)hwnd, 0, 0);<br />
Ïàðàìåòðû ïîðòà<br />
×èòàòü è ïèñàòü ìû íàó÷èëèñü :). Òåïåðü íàì íàäî íàó÷èòüñÿ ìåíÿòü ïàðàìåòðû ïîðòà.<br />
Ýòî ìîæíî ñäåëàòü â device manager, çàéäÿ â ñâîéñòâà óñòðîéñòâà, à ìîæíî è èç<br />
ñâîåé ïðîãðàììû. Âñå ïàðàìåòðû ïîðòà áóäóò õðàíèòüñÿ â îãðîìíîé ñòðóêòóðå ïîä<br />
íàçâàíèåì DCB. Âîò åå îñíîâíûå çíà÷åíèÿ:<br />
BaudRate - ñêîðîñòü ïîðòà. Ìîæåò ïðèíèìàòü çíà÷åíèÿ CBR_9600, CBR_19200,<br />
CBR_38400 è ò.ä.<br />
ByteSize - ðàçìåð áàéòà, âàðüèðóåòñÿ îò 4 äî 8. Íàì íåîáõîäèìî 8.<br />
Parity - ÷åòíîñòü. Íàì îíà íå íóæíà, ïîýòîìó ïðèñâàèâàåì defined-çíà÷åíèå NOPARITY.<br />
StopBits - ñòîïîâûå áèòû, ó íàñ - ONESTOPBIT.<br />
Ëåïèì êíîïêè<br />
Äëÿ òîãî ÷òîáû îòðåäàêòèðîâàòü ïàðàìåòðû, èõ íàäî ñíà÷àëà ïîëó÷èòü. Ïîýòîìó ìû<br />
âîñïîëüçóåìñÿ ôóíêöèåé GetCommState: â ïåðâîì àðãóìåíòå ïåðåäàåòñÿ õýíäë ïîðòà,<br />
à âî âòîðîì - ïåðåìåííàÿ òèïà ñòðóêòóðû DCB. Ïîñëå âûïîëíåíèÿ ôóíêöèè<br />
ñòðóêòóðà áóäåò çàïîëíåíà òåêóùèìè óñòàíîâêàìè ïîðòà. Òåïåðü ìû ìîæåì ñìåëî<br />
ðåäàêòèðîâàòü ëþáîé èç íèõ. Ïîñëå ðåäàêòèðîâàíèÿ ïàðàìåòðîâ èõ, åñòåñòâåííî,<br />
íàäî ñîõðàíèòü. Äëÿ ýòîãî ñîçäàíà ôóíêöèÿ SetCommState. Âîò òàê âûãëÿäèò êîä ðåêîíôèãóðàöèè<br />
â íàøåé ïðîãðàììå:<br />
DCB dcb;<br />
GetCommState(hCom, &dcb);<br />
dcb.BaudRate = CBR_57600;<br />
dcb.ByteSize = 8;<br />
dcb.Parity = NOPARITY;<br />
dcb.StopBits = ONESTOPBIT;