/* 리눅스에서 시리얼 제어 하기 (출처 : http://2mr.mju.ac.kr/zbxe/) */
#include <termios.h> // 터미널 제어 해더파일
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/signal.h>
#include <sys/types.h>
#define BAUDRATE B38400 // 38400 baudrate
#define MODEMDEVICE "/dev/ttyS0" // 시리얼 포트 정의 (ttyS0 : com1, ttyS1 : com2)
#define TRUE 1
#define FALSE 0
main()
{
int fd,i,stop;
int res;
struct termios oldtio, newtio;
unsigned char buf[255];
unsigned char recieve;
/* 시리얼 장치 open */
fd = open(MODEMDEVICE, O_RDWR | O_NOCTTY | O_NDELAY);
if(fd<0)
{
perror(MODEMDEVICE);
exit(-1);
}
/* file descriptor를 비동기로 만든다 */
fcntl(fd, F_SETFL, FASYNC);
/* 현재 포트 플래그를 oldtio에 저장 */
tcgetattr(fd, &oldtio);
/* 포트 플래그를 세팅 */
/*
c_cflag(제어 모드 플래그)
BAUDRATE : 전송 속도
CRTSCTS : 하드웨어 흐름 제어 (시리얼 케이블이 모든 핀에 연결되어 있을 경우 사용
HUPCL : 마지막 프로세스가 장치를 닫은 후에 접속을 닫음
CS8 : 8bit data (no parity, 1 stopbit)
CLOCAL : Local connectio. 모뎀 제어를 안함
CREAD : 수신을 가능하게 함
*/
newtio.c_cflag = BAUDRATE | CS8 | CLOCAL | CREAD;
/*
c_iflag(입력 모드 플래그)
IGNBRK : 입력에서 break 조건을 무시
BRKINT : IGNBRK가 설정되면 break에서 SIGINT를 생성
INLCR : 입력에서 NL을 CR로 변환
IGNCR : 입력에서 CR을 무시
ICRNL : IGNCR이 설정되지 않으면 입력에서 CR을 NL로 변환
*/
newtio.c_iflag = IGNPAR | ICRNL;
/*
c_oflag(출력 모드 플래그)
onLCR : 출력에서 NL을 CR-NL로 맵핑
OCRNL : 출력에서 CR을 NL로 맵핑
ONLRET : CR을 출력하지 않음
*/
newtio.c_oflag = 0;
/*
c_lflag(지역 모드 플래그)
ISIG : INTR, QUIT, SUSP 문자가 수신될 때 각각 SIGINT, SIGQUIT, SIGSTP을 생성
ICANON : 정규 모드를 사용
ECHO : 입력 문자를 출력으로 반향
ECHONL : ECHO가 설정되지 않더라도 정규 모드에서 NL문자를 반향
*/
newtio.c_lflag = 0;
/*
c_cc[](제어 문자)
밑의 설정 빼고는 default로 설정되어 있음(참고파일 : sys/ttydefaults.h)
*/
newtio.c_cc[VMIN] = 1; // 1 문자 받을때까지 blocking
newtio.c_cc[VTIME] = 0; // 문자 사이의 delay 0
/* 포트를 초기화 */
tcflush(fd, TCIFLUSH);
/* 포트를 세팅 */
tcsetattr(fd, TCSANOW, &newtio);
for(i=0;i<255;i++)
buf[i] = 0;
stop = FALSE;
while(1)
{
res = read(fd, &recieve, 1); // 읽기 시작. recieve변수에 데이터가 들어옴.
// 데이터 갯수를 res변수로 리턴
if(res < 1)
printf("read error!\n");
switch(recieve)
{
case 0:
buf[0] = 0x11;
if(write(fd, buf, 1) < 1) // 쓰기 시작. buf배열의 데이터가 출력.
printf("write error!\n"); // 출력된 데이터의 갯수가 리턴됨
break;
case 1:
buf[0] = 0x22;
if(write(fd, buf, 1) < 1)
printf("write error!\n");
break;
case 2:
buf[0] = 0x33;
if(write(fd, buf, 1) < 1)
printf("write error!\n");
break;
case 3:
buf[0] = 0xff;
if(write(fd, buf, 1) < 1)
printf("write error!\n");
stop = TRUE;
break;
default:
break;
}
if(stop == TRUE)
break;
}
tcsetattr(fd, TCSANOW, &oldtio); //처음 설정으로 다시 세팅
close(fd); //시리얼 포트를 닫음
}
'IT_Programming > System Programming' 카테고리의 다른 글
[Linux] 데몬 생성 함수 / IPC (0) | 2009.11.12 |
---|---|
[펌] ARM Developer Suite(ADS) 1.2 에서 C 코드와 ASM 코드 섞어 쓰기 (0) | 2009.10.07 |
GDB를 이용한 디버깅 (0) | 2009.05.26 |
Gcc Complie & Linking (0) | 2009.05.19 |
[Linux] 데몬 프로세스 만들기 (1) | 2008.01.25 |