ATMEGA

11월 1일 ATMEGA

박잡스 2010. 11. 1. 08:58
윈도우기반 직렬통신 프로그래밍

Virtual Serial Port Driver 설치
(Eltima Software Virtual Serial Port Driver 6.0.1.115)

장치관리자 에서 사용가능한 포트 확인

(Eltima Software Virtual Serial Port Driver 6.0.1.115)에서
Manage ports에서연결하고자하는포트를선택한후
Add pair버튼누르면왼편의Virtual ports에표시됨

장치관리자에서 추가된 포트를 확인할 수 있다



윈도우의 보조프로 그램인 하이퍼 터미널을 이용해서 가상 포트를 열수가 있다.






단방향 직렬 통신 프로그램 

송신부

#include <stdio.h>
#include <windows.h>

int main(void)
{
  char szPort[15]; //포트명을 저장할 변수
  wsprintf(szPort, "COM%d",2); //COM2가 변수 szPort에 들어감


  HANDLE m_hComm = NULL;
  m_hComm = CreateFile(szPort,      /*통신포트 열기 CreateFile 파일이나 입출력 장치를 연다. 
                    대표적인 입출력 장치로는 파일, 파일 스트림, 디렉토리, 물리적인 디스크, 
                    볼륨, 콘솔 버퍼, 테이브 드라이브, 파이프 등이 있다. 
                    이 함수는 각 장치를 제어할 수 있는 handle(핸들)을 반환한다.*/
 

    GENERIC_READ | GENERIC_WRITE,/*dwDesiredAccess 접근 방법을 명시하기 위해서 사용한다. 
                  일반적으로 GENERIC_READ, GENERIC_WRITE 혹은 
                  GENERIC_READ|GENERIC_WRITE를 사용한다. 만약 0을 사용하면, 
                  장치를 직접 접근하는 대신 속성을 얻기위한 요청을 한다.*/

    0,/*dwShareMode 개체의 공유 방식을 지정한다. 0을 지정하면 공유할 수 없는 상태가 되고, 
      핸들이 닫히기 전까지 다른 열기는 실패하게 된다.*/

    NULL,/*lpSecurityAttributes*/
    OPEN_EXISTING,/*dwCreationDisposion파일이 존재하면 연다. 만약 파일이나 장치가 
            존재하지 않으면, 에러 코드로 ERROR_FILE_NOT_FOUND (2)를 설정한다.*/

    FILE_ATTRIBUTE_NORMAL,NULL);/*dwFlagsAndAttributes 파일의 기타 속성을 지정한다. 
                  FILE_ATTRIBUTE_NORMAL은 다른 속성을 가지지 않는다.*/


  if(m_hComm == INVALID_HANDLE_VALUE)
  {
    printf("(!) failed to create a Comm Device file");
    return FALSE;
  }


  DCB dcb; //DCB에는 시리얼 포트를 통한 데이터 통신시 필요한 환경 설정 정보가 저장됩니다.
          //장치 컨트롤 블록(DCB)
               
  dcb.DCBlength = sizeof(DCB);
  GetCommState(m_hComm, &dcb);//포트 설정불러오기 

  dcb.BaudRate = 9600//통신 포트 설정
  dcb.ByteSize = 8;
  dcb.Parity = 0;
  dcb.StopBits = 0;

  SetCommState(m_hComm, &dcb); //포트 설정 완료후 set시킴

  OVERLAPPED osWrite; //osWrite 정보 초기화 OVERLAPPED -비동기 I/O 정보를 담고있다.
  osWrite.Offset = 0;
  osWrite.OffsetHigh = 0;
  osWrite.hEvent = CreateEvent(NULL,TRUE,FALSE,NULL); //이벤트 설정


  char buf[100]={'\0',}; //배열 초기화
  while(1)
  {
    printf("숫자입력: ");
    scanf("%s",buf);
    WriteFile(m_hComm,buf,strlen(buf),NULL,&osWrite);/*데이터 Write
    WriteFile( idComDev, lpByte, dwBytesToWrite, &dwBytesWritten, &osWrite ) ;
    첫번째 인자는 파일 핸들러이고, 두 번째 인자는 써야 할 데이터, 세 번째 인자는 
    써야 할 바이트의 수, 네 번째 인자는 써야 할 바이트수가 들어 있는 번지, 다섯 번
    째 인자는 구조체 인자*/

    Sleep(1000);
    if(strcmp(buf,"-1")==0/*strcmp는 2개의 문자열을 비교하는 함수이며, 
                문자열의 길이가 크고 작음을 비교하는 것이 아니라 
                첫번째 문자부터 차례로 바이트의 크기를 비교합니다.*/

    {
      printf("프로그램 종료!\n");
      break;
    }
  
  }
  CloseHandle(m_hComm); //시리얼 포트 파일을 닫는다.

  return 0;
}




수신부

#include <stdio.h>
#include <windows.h>

int main(void)
{
  char szPort[15];
  wsprintf(szPort, "COM%d",5);


  HANDLE m_hComm = NULL;
  m_hComm = CreateFile(szPort,
    GENERIC_READ | GENERIC_WRITE,
    0,NULL,OPEN_EXISTING,
    FILE_ATTRIBUTE_NORMAL,NULL);

  if(m_hComm == INVALID_HANDLE_VALUE)
  {
    printf("(!) failed to create a Comm Device file");
    return FALSE;
  }


  DCB dcb;
  dcb.DCBlength = sizeof(DCB);

  GetCommState(m_hComm, &dcb);

  dcb.BaudRate = 9600;
  dcb.ByteSize = 8;
  dcb.Parity = 0;
  dcb.StopBits = 0;

  SetCommState(m_hComm, &dcb);

  OVERLAPPED osRead;
  osRead.Offset = 0;
  osRead.OffsetHigh = 0;
  osRead.hEvent = CreateEvent(NULL,TRUE,FALSE,NULL);
  
  
  
  while(1)
  {
    char buf[100]={'\0'}; //배열 초기화
    ReadFile(m_hComm,buf,sizeof(buf),NULL,&osRead); //sizeof 로 읽을 파일의 크기 설정
    printf("recv:%s\n",buf);
    Sleep(1000);
    if(strcmp(buf,"-1")==0)
    {
      printf("프로그램 종료!\n");
      break;
    }
  }

  CloseHandle(m_hComm);

  return 0;
}