8051
AVR
EZLab
PIC
80C196KC
DSP
ARM
VHDL
마이크로마우스
로봇축구
Battle 로봇
로봇대회
휴먼로봇
Embeded Linux
HW/SW 강좌
RTOS
 
 

5. 시리얼 통신제어 방법

 

  이론을 먼저 공부하고, 예제로 PIC(PIC16C73B 혹은 PIC16F84)끼리 서로 통신해서 I/O 포트에 DISPLAY 더 나아가 LCD에 DISPLAY하는 것 까지 해보는 것이 저의 목표입니다. 일단은 I/O 포트에 DISPLAY하는 것까지 하고 다음 강좌에 LCD에 대해 알아본 후 계속되는 예제로 PIC끼리 통신해서 LCD에 통신한 문자를 표시하는 것까지 해 봅시다. 이론은 인터넷상에서 RS232 강좌를 퍼온 글이므로 본 강좌와 약간은 관계가 없을 수도 있습니다. 이해하시기 바라고 참고자료로 활용하시기 바랍니다.

1. 시리얼 통신이란?

    "시리얼 통신"이란 일반적으로 컴퓨터 기기를 접속하는 방법의 하나로, 접속하는 선의 수를 삭감하고, 또한 원거리까지 신호를 보낼 수 있도록 한 방식을 말한다. 이때 신호가 1비트마다 시리얼(직렬)로 보내지기 때문에 시리얼 통신이라 부른다.


2. 퍼스널컴퓨터와의 접속

    여기서는 통신 접속 상대방을 퍼스널컴퓨터로 한다. 그러나, 이 시리얼 통신의 접속은 표준화되어 있으며, "RS-232C"라 부르고 있는데, 대부분의 퍼스널컴퓨터나 모뎀이 이 규격에 따르고 있기 때문에 같은 방법으로 접속할 수 있다.
    이 접속에는 "25핀 DSUB 커넥터"나 "9핀 미니 DSUB 커넥터"라 부르는 커넥터가 일반적으로 사용되고 있으므로, 그것을 전제로 설명한다. 저는 보통 9핀 DSUB 커넥터를 사용합니다. 2번, 3번, 5번만 연결해도 되더라구요. 안되면 4번 5번을 서로 단락 시킵니다.

     

    커넥터의 핀 번호와 신호 및 간이적인 사용법은 아래 표와 같다.

미니DSUB
커넥터

25핀
DSUB

신호 명칭

간단한 사용법

1

8

CD(Data Carrier Detect)

입력, 사용하지 않는다

2

3

RD(Receive Data)

입력, 상대방 TD에 접속

3

2

TD(Transmit Data)

출력, 상대방 RD에 접속

4

20

DTR(Data Terminal Ready)

출력, 사용하지 않는다

5

7

SG(Signal Ground)

그라운드, 상대방 SG에 접속

6

6

DSR(Data Set Ready)

입력, 사용하지 않는다

7

4

RTS(Request to Send)

출력, 상대방 CTS와 접속

8

5

CTS(Clear to Send)

입력, 상대방 RTS와 접속

9

22

RI(Ring Indicate)

입력, 사용하지 않는다

 

 

3. 시리얼 통신 제어 프로그램의 구성

      여기서 소개하는 통신용 프로그램은 타이머 인터럽트를 사용하고 있다. 이 인터럽트를 사용함으로써 각 비트의 신호를 기다리고 있는 동안, 컴퓨터에는 다른 작업을 시킬 수 있다. 따라서, 통신을 하면서 다른 일을 하려는 경우, 예를 들면 표시를 하거나 모터를 동작시키는 일이 가능해진다.
    전체는 3개의 프로그램 모듈과 하나의 변수 정의 부분으로 구성되어 있다.

    여기서 약간 연구되어 있는 것은 우선 스타트 비트의 인터럽트가 들어왔다면, 확인하기 위해 10μs 기다린 다음, 다시 한번 입력을 읽어들여 보고, 같은 신호였다면 스타트 비트로 간주한다.
    다르면 노이즈로 인터럽트가 들어온 것으로 간주하여 무시하고, 다음 스타트 비트의 인터럽트를 기다린다.
    확실히 스타트 비트를 받아들였다면 다음의 타이머는 1.5비트분의 시간으로 스타트한다.
    그리고 time up의 인터럽트가 들어오면 데이터로 입력을 읽어들인다. 이것으로 틀림없이 확실한 데이터를 읽어들이게 된다. 이하, 1비트분 시간의 타이머로 계속한다.


4. 통신속도용 파라메터

    (1) 통신속도용 파라미터


      통신속도를 가변으로 하기 위해 2개의 파라미터를 사용하고 있다. 그 값을 구하는 방법은 아래와 같이 한다.
      우선, 통신속도로부터 1비트의 펄스폭을 구한다. 다음에 마이크로컴퓨터의 클록으로 그것을 나누어 카운터의 값을 구한다(1카운트는 4클록분). 그리고 그 카운트값을 실현하는 prescaler와 TMR0의 값을 구한다.
      아래 표는 실제의 예이며, 클록은 10MHz의 경우이다.

       

    BaudRate

    PulseWidth

    Counter

    prescale

    TMR0(BITTMR)

    width

    300bps

    3333.33usec

    8333

    64(5)

    130(7E)

    3328usec

    1200

    833.33

    2083

    16(3)

    130(7E)

    832

    2400

    416.67

    1041

    8(2)

    128(80)

    409

    4800

    208.33

    521

    4(1)

    124(84)

    198

    9600

    104.17

    260

    2(0)

    122(86)

    99

 

 

5. 실험내용

1) 목적

  CCS-C사의 PCM 컴파일러를 이용하여 RS232C 통신하는 방법을 익힌다.

또한, PIC 내부의 USART( RS232C )를 이용하지 않고 소프트웨어적으로 하는 방법을 익힌다. 이렇게 함으로서 USART가 없는 예를 들어 5X 계열, 6X 계열 등에서 소프트웨어적으로 RS232C를 구현하여 개발시 단가를 줄이는데 그 목적이 있다.

만일 개발시 꼭 RS232C를 하드웨어적으로 해야한는 경우는 게시판에 글을 올려 주세여~~

 

2) 방법

  다음의 회로도에서 보는 바와 같이 PIC와 PIC의 RB0를 서로 연결합니다. RB0 포트를 통해 PIC는 서로 RS232C 통신을 한다. 물론 프로토콜을 RS232C 모듈에서 하는 것이 아니라 소프트웨어적으로 만들어 준는 겁니다.

  

 

         

 

 

3) 프로그램

  프로그램은 PIC16C73B용으로 코딩했습니다. 헤더파일은 제가 게시판에 올린 것으로만 해야 합니다. 만일 74나, 84로 해보시고 싶은 분은 #include " "문에서 바꾸어 주시면 되구요. 물론 헤더파일은 게시판에 올리겠습니다. 따라서 게시판에 올린 헤더파일은 73B, 74B, 84 모두 올리겠습니다.

                                         [RS232C 송신(TX) 프로그램 ]

#include "H_16C73B.h"
#use delay(clock=4000000)
#use rs232(baud=4800, xmit=pin_b0, rcv=pin_b1)

void main(void)
{
        char rcv_value;

        TRISB = 0x00;
        PORTB = 0x00; // 포트 초기화

        while(1) {

                // 문자 'A'를 RS232 포트( RB0 )로 보낸다.

                putc('A'); delay_ms(1000);

        }
}

 

                                         [RS232C 수신(RX) 프로그램 ]

#include "H_16C73B.h"
#use delay(clock=4000000)
#use rs232(baud=4800, xmit=pin_b1, rcv=pin_b0)

#define         LED     RB7
#define         ON      1
#define         OFF     0

void main(void)
{
        char rcv_value;

        TRISB = 0x0f;
        PORTB = 0x00; // 포트 초기화

        while(1) {
                // RS232포트 즉, rb0로 들어도는 데이터 감지
                // -> kbhit()함수( 메뉴얼 참조 )
                if( kbhit() ) {
                        // getc()함수는 메뉴얼 참조  
                        rcv_value = getc();

                        // 받은 값이 문자 'A'이면 RB7의 LED를 ON 시키고
                        // 'A'가 아니면 RB7의 LED를 OFF 시킨다.
                        if( rcv_value == 'A' ) { LED = ON;  }
                        else                        { LED = OFF; }
                }
        }
}

 

4) 프로그램 설명

 송신( MCU_TX )쪽에서는 문자 'A'를 1초에 한번씩 보내고 수신( MCU_RX )쪽에서는 문자 'A'가 들어오면 RB7에 5[V]를 보내어 LED를 켜고 다른 DATA가 들어오면 LED를 OFF 시킨다.




상호 : (주) 로보블럭 사업자등록번호:214-86-56219 통신판매업신고19-2544 대표: 신대섭 전화:(02)2679-8556 Fax :(02)2679-8557
본사 : 경기도 부천시 원미구 약대동 부천 테크노파크 401동 502호     서울사무소 : 서울시 영등포구 문래동 4가 8-1 4층
Copyright(C) 2004, (주) 로보블럭 시스템즈 All Rights Reserved E-Mail : WebMaster