Programming/8051

8051( 중급 7부 - RS485 )

청솔1 2009. 11. 29. 14:01

8051( 중급 7부 - RS485 )


5월중으로 RS-485 에 대한 강좌를 해드리기로 했는데 겨우 하드웨어에 대한것만 하고 이제야 소프트 웨어에 대한 자료를 만듬다.
RS-485는 Multi Drop 방식으로 두가닥의 실선에 송수신을 해야 하기 때문에 Simplex 방식으로 통신을 한다고 지난 강좌에서 말씀 드렸슴다.
또한 1 대 n 개소와의 통신을 해야하기 때문에 각각의 컨트롤러는 고유의 I.D. 를 가져야 함다.

통신을 하는 방법에는 LAN 구성 방식처럼 star 방식이나 token-ring 방식등을 사용할 수도 있지만 그렇게 구현하려면 소프트웨어적인 부담이 상당히 많슴다.

그래서 마이컴 간의 RS-485 통신을 하는데 있어서는 Host 1대와 복수의 Slave를 두고 Host에서 polling하는 방식의 통신을 제일 많이 사용할검다.
평상시에 Host는 순차적으로 각 Slave 컨트롤러를 조회를 하는검다. 그리고 어떤 이벤트가 생겨났을때는 순서를 무시하고 해당 컨트롤러를 제어 할수도 있고 아니면 시간적으로 부담이 없다면 순서에 입각해서 이벤트가 생겨났을때 만들어둔 제어 명령어를 전달 하는 방식으로 통신을 하면 됨다.

쉽게 풀어서 설명을 한다면

 "갑동이 나와라 오버!"
"갑동이 나왔다 오버! 별다른 상황엄따!"

"을동이 나와라 오버!"
"을동이 나왔다 오버! 나도 이상엄따!"

"길동이 나와라 오버!"
"길동이 나왔다 오버! 우리집에 손님이 있다! 좀 바쁘니 다음에 애기 하자! 오버!"

하는 식으로 무전기로 대화를 한다고 생각을 하면 가장 비슷한 방법일것이다.
노파심 삼아 애기 하지만 일반 무전기는 핸드폰과 틀림다.
자신이 애기 할때는 수신을 하지 못함다. 자신이 송신을 종료해야만 수산을 할수 있슴다.
만일 상대방이 송신중에 자신도 송신을 하게 되면 서로 수신을 하지 못하는 상황에 봉착함다.

제 삼자가 들으면 양쪽의 신호를 들을수도 있겠지만 양쪽 모두를 전혀 수신 못하는 경우도 있슴다.

마찬가지로 RS-485는 Simplex 방식으로 통신을 하므로 무전기로 대화를 나누는 상황과 거의 같슴다.

그러므로 Host에서 polling을 할때는 각 Slave가 응답할수 있는 시간 여유를 항상 두어야  함다.

만일 어떤 오류에 의해서 해당 Slave가 응답을 하지 않으면 미리 정해둔 Slave의 응답 시간 동안은 수신이 안이루어 지더라도 그냥 standby 함다.


 "갑동이 나와라 오버!"
 "..................." [ 갑동이가 응답하지 않음. 미리 정해둔 시간만큼 대기 ]

 "을동이 나와라 오버!"
 "을동이 나왔다 오버! 별 이상엄따!"

그리고 시리얼 통신을 할때에는 ASCII code에 의한 통신 방식을 권함다.
ASCII code상의 제어 문자들을 그대로 활용키 위해 16진값을 송신을 경우에도 한바이트의 16진수 값을 두바이트의 ASCII 문자로 변환하여 송신 하고 수신측에서 다시 16진값으로 환원시켜 사용하는 방식을 말함다.


 송신해야할 16진 데이터     : 0x4e
 ASCII code로 변환한 데이터 : "4E" = 0x34 0x45
 송신해야할 16진 데이터     : 0x03
 ASCII code로 변환한 데이터 : "03" = 0x30 0x33

두번째의 경우 만일 16진 데이터 그 자체로 송신을 하면 ASCII 제어 문자인 ETX( 0x03 )과 충돌함다.
그러므로 16진 데이터를 송신코자 할때는 위와 같이 ASCII code로 변환하여 송신하면 이러한 충돌을 예방할수 있슴다.

RS-485 통신 제어시 중요한 점이 하나 있슴다. 바로 송수신 전환 딜레이 타임 문제임다.
SN75176의 2번과 3번핀을 묶어서 TXEN( TX Enable ) 신호를 사용시 수신에서 송신 전환시 1~2 Bit time 정도의 딜레이가 필요함다.

 ( 이부분에 대한 정확한 자료를 찾으려 했으나 현재 찾지 못하고 있슴다. )
또한 송신에서 수신으로 전환시에도 모든 데이터가 송신 되었는지 확인한 다음에 전환을 해야 하는데
이때도 역시 1~2 Bit time 정도의 딜레이가 필요함다.

통신 속도가 가변되는 경우 일일히 딜레이 타임을 계산해서 딜레이 시키는건 번거롭슴다.
해서 산적은 아예 의미 없는 Space 문자( 0x20 )을 문자열 선두와 말미에 삽입을 해서 통신을 하곤 함다.

이경우 RS-485 라인을 모니터링 해 보면 어떤 경우에는 Space 문자가 정상 수신 되는 경우도 있고 어떨때는 엉뚱한 값으로 바뀌어 있는 경우가 있슴다.

이점이 송수신 전환시 딜레이 타임이 필요한 이유임다.

<XMP>#define ASCII_hex( c ) ( ( c > 64 ) ? ( c - 55 ) : ( c - 48 ) ) unsigned char HEX_ascii_high( unsigned char c ) { unsigned char temp; temp = c & 0xf0; temp >>= 4; if( temp > 9 ) return temp + 55; else return temp + 48; } unsigned char HEX_ascii_low( unsigned char c ) { unsigned char temp; temp = c & 0x0f; if( temp > 9 ) return temp + 55; else return temp + 48; } void COM1_puts_sum( xdata unsigned char *str ) { int i; unsigned char chk; chk = 0; for(i=0;str[ i ] != 0;i++) chk ^= str[ i ]; /* check sum 구하기 */ while( Tx_ready1 == 0 );</XMP>

    /* RS-485 IC를 수신에서 송신으로 전환 직후 interval을 주기 위해 의미없는 space를 송신 */
    TXEN = 0;                           
    SBUF = ' ';
<XMP> Tx_ready1 = 0; for(i=0;str[ i ] != 0;i++) { while( Tx_ready1 == 0 ); Tx_ready1 = 0; SBUF = str[ i ]; } while( Tx_ready1 == 0 ); Tx_ready1 = 0; SBUF = HEX_ascii_high( chk ); /* 미리 구해놓은 check sum 값이 16진수이므로 */ /* ASCII 값으로 변환( 상위 니블 ) */ while( Tx_ready1 == 0 ); Tx_ready1 = 0; SBUF = HEX_ascii_low( chk ); /* 하위 니블을 ASCII 값으로 변환 */ while( Tx_ready1 == 0 );</XMP>

    /* RS-485 IC를 송신에서 수신으로 전환하기 직전에 interval을 주기 위해 의미없는 space를 송신 */
    SBUF = ' ';
    Tx_ready1 = 0;
    while( Tx_ready1 == 0 );
    TXEN= 1;
<XMP> } </XMP>


그리고 RS-485 통신을 하는 경우에는 여러대의 마이컴이 한 회선을 공유 하기 때문에 각각의 마이컴은 고유 아이디를 가져야 함다.
보통은 마이컴 회로상에 DIP SW를 두어 그 스위치 값에 의해 아이디를 가질수 있도록 하거나 EEPROM을 갖는 경우에는

그곳에 자신의 아이디를 보유 할수 있도록 만들어 줌다.

또한 통신 프로토콜을 설정해야 함다.
기존의 RS-485 장비에서 데이터를 빼어 쓰는 경우에는 기존의 PROTOCOL을 분석해서 그 사용방법에 따라야 함다.

그러지 아니하고 새로이 프로토콜을 만들어 사용해야 하는 경우에는 몇가지 점을 유념 해야함다.

산적이 MODEM 통신이나 RS-485 통신에서 주로 많이 사용한 방법은 다음과 같슴다.
chk1과 chk2는 위의 루틴상에서 보여주듯이 STX에서 ETX까지의 모든 문자를 XOR 취한 다음 ASCII 두 바이트로 바꾼 값임다.

1. 첫번째 방법

STX 수신아이디 command data ... ETX chk1 chk2


수신아이디가 Host가 아닌 경우에는 Host가 Slave에 송신한 경우이고
수신아이디가 Host인 경우에는 Slave가 Host의 요구에 응답한 경우로 간주 함다.

2. 두번째 방법

STX 수신아이디 송신아이디 command data ... ETX chk1 chk2


이 경우에는 수신처와 송신처를 확실히 구분하는 방법임다.
그래서 경우에 따라서는 Slave가 또 다른 Slave에 데이터를 송신할수도 있슴다.

3. data의 길이가 유동적인 경우

STX 수신아이디 송신아이디 command length data ... ETX chk1 chk2


command는 주로 한바이트의 ASCII 문자로 사용하고 그에 따른 data 길이가 변동되었을때를 대비하여
length로 데이터 길이에 대한 정보를 보내주는 방법임다.

 

 

<< 전자기기 개발 --- 건강기기, 통신기기,각종 전자회로 개발, PCB ARTWORK >>