C++Builder Programming Forum
C++Builder  |  Delphi  |  FireMonkey  |  C/C++  |  Free Pascal  |  Firebird
볼랜드포럼 BorlandForum
 경고! 게시물 작성자의 사전 허락없는 메일주소 추출행위 절대 금지
C++빌더 포럼
Q & A
FAQ
팁&트릭
강좌/문서
자료실
컴포넌트/라이브러리
메신저 프로젝트
볼랜드포럼 홈
헤드라인 뉴스
IT 뉴스
공지사항
자유게시판
해피 브레이크
공동 프로젝트
구인/구직
회원 장터
건의사항
운영진 게시판
회원 메뉴
북마크
볼랜드포럼 광고 모집

C++빌더 Q&A
C++Builder Programming Q&A
[23920] Re:Re:Re: ,간단한 소스와 주석
김시환 [] 2451 읽음    2003-01-28 02:00
저도 이게 오래된 프로그램이고 처음으로 제어했던 PLC라 소스가 좀 지저분 합니다.

지금보면 정말 한심한 소스인데  전체 소스는 회사 규정상 보내 드릴 수 없고

전송 부분과 수신 부분의 일부만 소스를 올렸습니다.



#define ENQ  0x05
#define ACK  0x06
#define NAK  0x15
#define EOT  0x04
#define ETX  0x03

void TMain::Input_Send(void)   // I/O 포트에 대한 값을 읽어들이기 위한 함수
{
    byte ch[25] ;

    ch[0]=ENQ; ch[1]=0x30; ch[2]=0x30; ch[3]='R';   ch[4]='S';
    ch[5]='S'; ch[6]=0x30; ch[7]=0x32; ch[8]=0x30;  ch[9]=0x35;
    ch[10]='%';ch[11]='P'; ch[12]='W'; ch[13]=0x30; ch[14]=0x31 ;
    ch[15]=0x30;  ch[16]=0x35;
    ch[17]='%';ch[18]='P'; ch[19]='W'; ch[20]=0x30; ch[21]=0x33 ;
    ch[22]=EOT ;

    CommPort->SendData(ch,sizeof(ch)) ;
}
//---------------------------------------------------------------------------
void TMain::Analog_Send(void)  // 아날로그 값을 읽기 위한 함수
{
    byte ch[41] ;

    ch[0]=ENQ; ch[1]=0x30; ch[2]=0x30; ch[3]='R';   ch[4]='S';
    ch[5]='S'; ch[6]=0x30; ch[7]=0x34;
    ch[8]=0x30;  ch[9]=0x36;
    ch[10]='%';ch[11]='D'; ch[12]='W'; ch[13]=0x31; ch[14]=0x31 ; ch[15]=0x32 ;
    ch[16]=0x30;  ch[17]=0x36;
    ch[18]='%';ch[19]='D'; ch[20]='W'; ch[21]=0x31; ch[22]=0x31 ; ch[23]=0x33 ;
    ch[24]=0x30;  ch[25]=0x36;
    ch[26]='%';ch[27]='D'; ch[28]='W'; ch[29]=0x31; ch[30]=0x31 ; ch[31]=0x34 ;
    ch[32]=0x30;  ch[33]=0x36;
    ch[34]='%';ch[35]='D'; ch[36]='W'; ch[37]=0x31; ch[38]=0x31 ; ch[39]=0x35 ;
    ch[40]=EOT ;

    CommPort->SendData(ch,sizeof(ch)) ;
}

//  위의 두 함수에서 배열값을 제가 함수에서 지정했는데 고정된 값이기 때문에
헤더에 정의 하던가 아니면 별도의 모듈에서 static 전역으로 설정해서 사용하는 것이
좋을 것입니다.

예)   static byte analog[41] = {--------} ;     아날로그값 Read  포맷
      static byte IO_Read[25] = {----------} ;  I/O Read 포맷
      byte IO_Write[20] = {--------} ;          I/O Write 포맷(값이 변경됨으로 static를 선언하지 않음)

      이런 것인데 이상하게 빌더에서는 이런
      형태로 초기화가 안되더군요.. 그래서 부득이 위의 함수와 같이 무식한 방법을
      사용했습니다.  

void TMain::Out_send(int temp)    //  I/O 포트를 제어하기 위한 함수
{
    byte ch[20] ;
    byte tempA,tempB ;

    ch[0]=ENQ ; ch[1]=0x30; ch[2]=0x30; ch[3]=0x57; ch[4]=0x53;
    ch[5]=0x53; ch[6]=0x30; ch[7]=0x31; ch[8]=0x30; ch[9]=0x35;
    ch[10]=0x25; ch[11]=0x50; ch[12]=0x57; ch[13]=0x30; ch[14]=0x34 ;

    switch(temp)
    {
      case 0 : output = output | 0x80 ;  // Analog Active
               break ;
                   :
                   :
                   :  
               break ;
      case 13: output = output | 0x01 ;  // 진공주입기 ON
               break ;
      case 14: output = output & 0xfe ;  // 진공주입기 OFF
               break ;
    }

    tempA = output >> 4 ;
    tempB = output & 0x0f ;

    ch[15] = 0x30 ;
    ch[16] = 0x30 ;

    ch[17] = HexToAsc(tempA) ;
    ch[18] = HexToAsc(tempB) ;
    ch[19] = EOT ;

    CommPort->SendData(ch,sizeof(ch)) ;
}


위의 3 함수는 PLC 의 프로토콜과 관련된 함수 입니다.
저도 오래된데가 메뉴얼이 없어 위의 데이타 포맷의 각 값들의 의미를
모르겠습니다.

아마 메뉴얼에서 위와 비슷한 포맷의 프로토콜의 찾아 분석해 보시면
아실 것입니다.

void __fastcall TMain::Timer1Timer(TObject *Sender)
{
    if(send==true)
    {
      Input_Send() ;
      send = false ;
    }
    else
    {
      Analog_Send() ;
      send = true ;
    }
}


위의 함수는 타이머에서 아날로그 값과 I/O  를 번갈아 가며 읽어들이기 위한 것입니다.


void __fastcall TMain::CommPortReceiveData(TObject *Sender,
      Pointer DataPtr, int DataSize)
{
    char* data = new char[DataSize+1] ;

    strncpy(data,(char*)DataPtr,DataSize) ;  // Data Copy to work buffer

    if(send==false)                          // I/O 포트값을 전송했을 경우 들어오는 데이타
    {
      if(data[0] == ACK && data[20] == ETX )   // ACK 에서 시작해서 ETX 로 끝나는 데이타 페키지
      {
        byte *temp = new byte[8] ;
        temp[0] = AscToHex(data[10]) ;
        temp[1] = AscToHex(data[11]) ;
        temp[2] = AscToHex(data[12]) ;
        temp[3] = AscToHex(data[13]) ;
        temp[4] = AscToHex(data[16]) ;
        temp[5] = AscToHex(data[17]) ;
        temp[6] = AscToHex(data[18]) ;
        temp[7] = AscToHex(data[19]) ;
        Display(temp) ;
        delete[] temp ;
      }
    }

    else           // 아날로그값을 읽기위해 전송한 후 들어오는 데이타
    {
      if(data[0] == ACK && data[32] == ETX)  
      {
        short *value = new short[4]   ;
        value[0] = 0xfff0 | AscToHex(data[10]) ;
        value[0] <<= 4 ;
        value[0] = value[0] | AscToHex(data[11]) ;
        value[0] <<= 4 ;
        value[0] = value[0] | AscToHex(data[12]) ;
        value[0] <<= 4 ;
        value[0] = value[0] | AscToHex(data[13]) ;

        위의 내용은 아날로그 값은 4바이트 되어있음을 나타냄 
                          :
                          :
                          :

        value[3] = 0xfff0 | AscToHex(data[28]) ;
        value[3] <<= 4 ;
        value[3] = value[3] | AscToHex(data[29]) ;
        value[3] <<= 4 ;
        value[3] = value[3] | AscToHex(data[30]) ;
        value[3] <<= 4 ;
        value[3] = value[3] | AscToHex(data[31]) ;

        Display_Analog(value) ;
        delete[] value ;
      }
    }
    CommPort->FlushBuffers(true,true) ;
    delete[] data ;
}



+ -

관련 글 리스트
23915 [질문] PLC 와 PC간의 시리얼 통신하기 위한 가장 기본적인 사항은 뭔가요? 강영준 4254 2003/01/27
23916     Re:[질문] PLC 와 PC간의 시리얼 통신하기 위한 가장 기본적인 사항은 뭔가요? 김시환 3449 2003/01/27
23917         Re:Re:답변 감사 합니다. 강영준 1463 2003/01/28
23920             Re:Re:Re: ,간단한 소스와 주석 김시환 2451 2003/01/28
23937                 Re:Re:Re:Re: ,간단한 소스와 주석 강영준 1364 2003/01/28
23933                 Re:Re:Re:Re: 김시환님 ~~~~ 무리 해봐도.. 방법을 모르겠네요.. 젠장... 강영준 1488 2003/01/28
Google
Copyright © 1999-2015, borlandforum.com. All right reserved.