직렬 통신 정보

데이터 통신을 위해 직렬 포트를 사용하는 것은 통신 분야에서 중요한 위치를 차지합니다. RS232-RS485를 사용하여 데이터 신호를 수집하고 전송하는 것은 VC 프로그래밍의 또 다른 인기 주제입니다. 직렬 통신은 통신 소프트웨어에 널리 사용됩니다. 전화, 팩스, 비디오 등 다양한 제어가 가능합니다. 다양한 개발 도구 중에서 VC는 강력하고 유연하며 Microsoft의 지원이 가장 큽니다. 따라서 하드웨어 작업과 관련된 일반적인 통신 프로그래밍에서는 VC가 개발 도구로 가장 권장됩니다. 그러나 산업용 제어 직렬 통신은 대부분의 제어 주변 장치가 16진수 데이터(BYTE 형식)를 전송하기 때문에 일반적인 직렬 통신 프로그램과 다릅니다. 따라서 프로그램의 실행 안정성을 향상시키기 위해 통신을 위한 프로그램을 작성합니다. BYTE 유형의 데이터는 무시될 수 있습니다.

현재 널리 사용되는 두 가지 직렬 통신 방법이 있습니다. 하나는 Microsoft에서 제공하는 CMSCOMM 컨트롤을 사용하여 통신하는 것이지만 이제 많은 프로그래머는 이 방법을 포기해야 한다고 생각합니다. 두 번째는 프로그래밍에 WINAPI 함수를 사용하는 것입니다. 이러한 종류의 프로그래밍은 가장 어렵고 많은 API 기능을 마스터해야 합니다. 세 번째는 CSerial 클래스 등과 같이 현재 네트워크에서 제공되는 일부 직렬 통신 컨트롤을 사용하여 작성하는 것입니다.

프로그램 구현:

많은 프로젝트의 개발과 실습을 통해 직렬 포트 개발에 WIN API 기능을 사용하면 프로그래머에게 많은 제어권을 부여할 수 있으며 프로그램 운영 또한 매우 안정적입니다. 그래서 시리얼 포트에 연결되어 있는 함수들을 캡슐화해서 각 프로젝트에서 호출했는데 효과는 비교적 좋았습니다. 이제 여러분에게 도움이 되는 다양한 함수와 호출 방법을 나열하겠습니다.

1. 시리얼 포트 설정 관련 작업

#define MAXBLOCK 2048

#define XON 0x11

#define XOFF 0x13

BOOL SetCom(HANDLE & m_hCom, const char *m_sPort, int BaudRate, int Databit, CString parity, CString stopbit)

{

COMMTIMEOUTS TimeOuts; /직렬 포트 출력 시간 초과 설정

DCB dcb; ///포트와 일치하는 장치

m_hCom=CreateFile(m_sPort, GENERIC_READ | GENERIC_WRITE, 0, NULL,

OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,

NULL); // 중첩 모드에서 직렬 포트 열기

if(m_hCom==INVALID_HANDLE_VALUE)

{

AfxMessageBox("직렬 포트 부분 설정, 직렬 포트 열기 실패"); ////중복 비동기 통신(INVALID_HANDLE_VALUE) 함수가 실패했습니다.

return FALSE;

}

SetupComm(m_hCom, MAXBLOCK, MAXBLOCK); //버퍼 설정

memset(amp; TimeOuts) , 0, sizeof(TimeOuts));

TimeOuts.ReadIntervalTimeout=MAXDWORD; // 간격 시간 초과를 최대로 설정하고 총 시간 초과를 0으로 설정하면 ReadFile이 즉시 반환되고 작업이 완료됩니다.

p>

TimeOuts.ReadTotalTimeoutMultiplier=0; //읽기 시간 계수

TimeOuts.ReadTotalTimeoutConstant=0; //읽기 시간 상수

TimeOuts.WriteTotalTimeoutMultiplier=50; timeout= 시간 계수 * 시간 상수를 읽고 쓰는 데 필요한 문자 수

TimeOuts.WriteTotalTimeoutConstant=2000; //WriteComm 멤버 함수에서 쓰기 시간 제한을 지정하려면 쓰기 시간 제한을 설정하세요.

SetCommTimeouts(m_hCom, amp; TimeOuts); //GetOverlappedResult 함수의 대기 시간*/

if(!GetCommState(m_hCom, amp; dcb)) ////직렬 포트 개방 모드, 포트, 보드 포트와 일치하는 속도 및 장치

{

AfxMessageBox("GetCommState Failed")

return FALSE; >

dcb.fParity =TRUE; //패리티 허용

dcb.fBinary=TRUE;

if(parity=="NONE")

dcb.Parity=NOPARITY ;

if(parity=="ODD")

dcb.Parity=ODDPARITY;

if(parity=="EVEN" )

dcb.Parity=EVENPARITY;

if(stopbit=="1")//전송 속도 설정

dcb.StopBits=ONESTOPBIT;

//if(stopbit=="0")//전송 속도 설정

// dcb.StopBits=NONESTOPBIT;

if(stopbit== "2")/ /전송 속도 설정

dcb.StopBits=T

WOSTOPBITS;

BOOL m_bEcho=FALSE; ///

int m_nFlowCtrl=0

BOOL m_bNewLine=FALSE; > dcb.BaudRate=BaudRate; // 전송 속도

dcb.ByteSize=Databit; // 바이트당 비트

// 하드웨어 흐름 제어 설정

dcb

dcb.fInX=dcb.fOutX=m_nFlowCtrl==2;

dcb.XonChar=XON

dcb.XoffChar=XOFF; p> p>

dcb.XonLim=50;

TRUE; ///com 통신 포트 설정

else

{

AfxMessageBox("직렬 포트가 열렸습니다. 설정에 실패했습니다.");

return FALSE

}

}

2. 직렬 포트 읽기 작업:

int ReadCom(HANDLE hComm, BYTE inbuff [], DWORD&nBytesRead, int ReadTime)

{

DWORD lrc ; ///수직 중복 검사

DWORD endtime; /// /////jiesuo

static OVERLAPPED ol;

int numCount=0; //읽기 횟수 제어

DWORD dwErrorMask, nToRead

COMSTAT comstat; Offset=0; ///파일 시작을 기준으로 한 바이트 오프셋

ol.OffsetHi

gh=0; ///데이터 전송을 시작하는 바이트 오프셋의 상위 단어로, 파이프 및 통신 중에 호출 프로세스에서 무시할 수 있습니다.

ol.hEvent=NULL; ///이벤트 식별, 데이터 전송 완료 시 신호 상태로 설정

ol.hEvent=CreateEvent(NULL, TRUE, FALSE, NULL);

endtime=GetTickCount() ReadTime; //GetTickCount()는 처음부터 현재 시점까지 시스템이 소요한 시간(밀리초)을 검색합니다.

for(int i=0; ilt ; 2000; i )

inbuff[i]=0;

Sleep(ReadTime);

ClearCommError(hComm, amp; dwErrorMask, amp; comstat) ;

nToRead=min(2000, comstat.cbInQue)

if(int(nToRead)lt; 2)

루프 이동;

if(!ReadFile(hComm, inbuff, nToRead, & nBytesRead, & ol))

{

if((lrc=GetLastError())==ERROR_IO_PENDING)

{

//////////////////

endtime=GetTickCount() ReadTime //GetTickCount; () 검색 시스템이 이 지점에 도달하는 데 걸린 시간(밀리초)

while(!GetOverlappedResult(hComm, amp; ol, amp; nBytesRead, FALSE))//이 함수는 다음의 결과를 검색합니다. 중첩된 작업

{

if(GetTickCount()gt; endtime)

break; > }

}

1을 반환합니다.

루프: 0을 반환합니다.

}

3. 직렬 포트 명령

int WriteCom(HANDLE hComm, BYTE Outbuff[], int size, int bWrite[])

{

DWORD nBytesWrite, endtime, lrc ;

정적 OVERLAPPED ol;

DWORD dwErrorMask, dwError;

COMSTAT comstat;

ol.hEvent=CreateEvent(NULL, TRUE , FALSE, NULL);

ol.Offset=0

ol.Of

fsetHigh=0;

ol.hEvent=NULL; ///이벤트를 식별합니다. 데이터 전송이 완료되면 신호 상태로 설정합니다.

ClearCommError(hComm, amp; dwErrorMask, amp ; comstat)

if(!WriteFile(hComm, Outbuff, size, & nBytesWrite, & ol))

{

if(( lrc =GetLastError())==ERROR_IO_PENDING)

{

endtime=GetTickCount() 1000;

while(!GetOverlappedResult(hComm, amp; ol, amp ;nBytesWrite, FALSE))

{

dwError=GetLastError();

if(GetTickCount()gt;endtime)

{

AfxMessageBox("직렬 포트에 쓰는 시간이 너무 깁니다. 현재 직렬 포트 송신 버퍼의 데이터 수가 비어 있습니다.")

break

}

if(dwError=ERROR_IO_INCOMPLETE)

continue; //완전히 읽히지 않은 경우 일반 반환 결과

else

{

// 오류가 발생했습니다. 복구를 시도하세요!

ClearCommError(hComm, amp; dwError, amp; comstat)

중단

}

}

}

}

FlushFileBuffers(hComm)

PurgeComm(hComm, PURGE_TXCLEAR)

bWrite=0; p>

p>

return 1;

}

4. 호출 방법은 매우 간단하며 직렬 포트 매개변수만 설정하면 됩니다.

예:

BOOL Main_OpenCom()//COM 설정

{

int Boundrate=9600 //전송 속도

CString StopBits="1"; //정지 비트

int DataBits=8; //데이터 비트

CString Parity="ODD"; > CString m_Port="COM1";

return SetCom(m_hCom1, m_Port, Boundrate, DataBits, Parity, StopBits)

}

void Main( )

{

int SIZE;

DWORD BytestoRead=52*Count 6; //11바이트 필요

int BWRITE [2] ;

int ReadTime=2000;

BYTE 아웃버프[12]={0xff, 0x00, 0xea, 0xff, 0xea, 0xff, 0, 0, 0, 0, 0, 0 };

SIZE=sizeof(Outbuff);

WriteCom(m_hCom, Outbuff, SIZE, BWRITE)

ReadCom(m_hCom, m_Inbuff, BytestoRead, ReadTime );

//Xiangyin의 압축 풀기 처리 수행

}

上篇: 충전보 어느 브랜드가 좋을까요? 下篇: 미디어 학생 노트북
관련 내용