티스토리 뷰

embedded

RS-485 통신의 구현

fistful 2020. 12. 4. 17:03
반응형

Photo by Thomas Jensen on Unsplash

 

최근 RS-485 통신의 Slave 기기를 구현할 일이 있었다. (ATmega64 칩셋 이용) 이에 구현을 하며 얻은 정보를 정리해보려 한다.

 

RS-485 통신에 대하여

참고 링크: https://jusths.tistory.com/41

위키: https://www.wikiwand.com/en/RS-485

 

- 시리얼 통신 표준 중의 하나이다. 시리얼 통신 표준은 RS-232, RS-422, RS-485 등이 있다.

- RS-232 보다 거리에서 통신이 가능하고, RS-422 4 wire 보다 간편하다.

- Half-Duplex 이다. 양방향 통신이 가능하지만 한번에 방향만 가능하다는 말이다.

- 2 wire 쓰는데 4 wire 쓰면 Full-Duplex 가능하기는 하다.

- Half-Duplex 무전기, Full-Duplex 전화기라고 생각해도 되겠다.

- Master 하나에 Slave 32개까지 가능하다.

보통 어떻게 동작하는가?

1. Slave Rx, Master Tx 상태이다. Slave 들이 데이터를 받을 준비가 되어 있고, Master 보낼 준비가 되어 있는 상태라는 말이다.

2. Master 전체 Slave에게 broadcasting 수도 있고, 특정 Slave 지목하여 보낼 수도 있다.

  - 모든 Slave는 baud rate 을 9600 bps 로 변경해 라고 명령할 수도 있고

  - 24번 Slave는 현재 상황을 보고해 라고 명령할 있다는 것이다. 경우 모든 Slave 명령을 받는 것은 같지만 24 Slave 자신에게 명령임을 알고 응답하게 구현한다.

3. Master 특정 Slave 지목해서 데이터를 보내면 재빨리 Rx 모드로 전환한다. 명령을 하고 응답을 들을 있는 상태로 전환하는 것이다.

4. Slave Master 보낸 데이터를 받았다면, 전체 또는 자신에게 오는 데이터인지 확인 ,

5. 그에 대한 작업을 다음에, Rx에서 Tx 모드를 전환한 다음 Master에게 데이터를 전송한다.

6. Tx 전송이 완료된 것을 확인하면 다시 Master 보내는 데이터를 받을 있도록 Rx 모드로 전환한다. 부분이 중요한데 Tx 전송이 완료된 것을 확인하지 않고 Rx 변경하면 전송실패가 있는 것이다. 미리 스포일러를 한다면 TXC flag 비트를 보고 Tx 전송 완료를 확인한다.

 

이해 안되는 부분이 있을 있겠지만 일단 읽고나서 아래 내용을 다음에 다시 보면 이해가 것이다.

 

ATmega64 에서 어떻게 구현할 것인가?

 

칩셋 데이터 시트 다운로드 링크: https://datasheetspdf.com/pdf-file/956032/ATMELCorporation/ATmega64A/1

 

칩셋에서 RS-485 사용하려면 추가 칩셋이 필요하다. SP335ECR1-L 이다. RS-485 slave ATmega64 Rx, Tx 모드중 하나를 선택하려면 칩셋에 GPIO 신호를 보내주면 된다.

너무 세세하게 이야기를 하려 했더니 복잡해지고 지치는 부분이 있어서 개념 위주로 간략히 설명하겠다.

ATmega64 Register

레지스터 설정과 레지스터 내의 플래그(flag, 깃발) 비트들을 이용하여 작업들을 있다.

 

TXEN, RXEN

 

Tx, Rx 사용하려면 비트들을 1 설정해준다.

 

UDR(UART Data Register)

 

transmit buffer 역할이다.  우리가 보내려는 바이트들을 여기에 하나씩 넣어주면 Shift 레지스터가 비어 있으면 UDR Shift 레지스터로 옮겨진다.

그리고 Shift 레지스터에서 비트씩 실제 전송이 일어난다.

 

UDRE(Data Register Empty)

 

UDRE 비트가 1 되면 UDR 비었다(= Shift 레지스터로 전달완료) 것을 의미하며

다음 바이트를  UDR(transmit buffer) 있다는 말이다. 비면 1 되고, 채워지고 나서 Shift Register 옮겨가기 전까지는 0이다.

 

TXC(Transmit Complete)

 

RS-485 구현에서 이게 중요하다. Rx 모드이던 slave ATmega64 Tx 모드로 바뀌어 응답을 전송한 다음에 다시 Rx 모드가 되어야 하는데,

TCX 바로 타이밍을 알려주는 것이다.

 

The TXC Flag is useful in half-duplex communication interfaces (like the RS485 standard), where a transmitting application must enter Receive mode and free the communication bus immediately after completing the transmission.

 

RXC(Receive Complete)

 

안읽은 바이트가 있다는 말이다. 읽어가면 자동으로 RXC 0으로 clear 된다.

 

그리고 인터럽트들

이제 어떤 interrupt 사용하면 좋을 보자

 

RXCIE(Receive Complete Interrupt Enable)

 

transmit buffer 상응하는 receive buffer 역할을 하는 UDR 있다.

RXC 비트는 Receive 쪽의 Shift 레지스터를 통해 UDR 바이트가 쓰여지면 1 설정된다.

RXCIE 1 Enable 했다면, RXC 1 될때에 인터럽트가 발생한다.

 

흐름을 설명하자면

1) UDR 비어있다.

2) Shift 레지스터를 통해 UDR 바이트가 쓰여지면 RXC 1 설정되며 인터럽트가 발생한다.

3) 인터럽트 서비스 루틴에서는 UDR에서 바이트를 읽으면 RXC 다시 0 된다. 그러면 Shift 레지스터는 받은 바이트가 있을 때에 UDR 쓴다.

4) 2) 3) 반복하며 전체 데이터를 받게 된다.

 

UDRIE(USART Data Register Interrupt Enable)

 

Enable 시키면 UDR 비게 되면 인터럽트가 작동한다. , UDRE 1 되면 인터럽트가 동작하여 바이트를 있다는 것을 알려주며

다시 바이트를 UDR 써주면 UDRE 0으로 자동 clear 된다.

 

흐름을 설명하자면

1) UDR 비어있으며, 전송해야할 바이트들이 있다.

2) UDR 바이트를 쓰면 Shift 레지스터가 비어있을때에 UDR Shift 레지스터로 바이트가 옮겨간다.

3) UDR 비었으므로 UDRE 비트가 1 되며, UDR 인터럽트가 발생한다.

4) UDR ISR(인터럽트 서비스 루틴)에서 비어있는 UDR 다음 바이트를 써준다. 이렇게 2) 3) 4) 반복하며 전송 데이터를 모두 내보낸다.

6) 만약 데이터를 모두 전송한 것을 확인하려면 TXC 이용하면 된다. 이것은 UDR 비어있고, Shift 레지스터 역시 비어있다는 것을 의미한다.

 

 

TXCIE(Transmit Complete Interrupt Enable)

 

Shift Register 전체 프레임이 전송되고, transmit buffer 비면 인터럽트가 발생한다.

인터럽트가 발동하면 TXC 자동 클리어, 그게 아니라면 0으로 클리어해줘야 한다는 말도 있는데 이건 조금 틀린 표현으로 보인다.

 

1. 만약 TXC 1 되는 지켜보고 1 될때에 동작하게 구현한다면 동작후에 0으로 바꿔줘야 것이다.

2. 하지만 TXC 상태가 0에서 1, 혹은 1에서 0으로 바뀌는지만 체크하려면 굳이 매번 0으로 초기화할 필요가 없다.

3. 마지막으로 TXCIE 인터럽트를 이용한다면 더더욱 초기화 필요는 없다. 왜냐하면 Edge 변화할 때마다 인터럽트가 발생하기 때문이다.

 

최종 구현

 

1) 최초에는 Rx 모드로 있다가 RXC 비트로 발생하는 인터럽트로 들어오는 데이터를 받아낸다. , RS-485 master 보낸 패킷을 받는다.

2) 받으면 패킷을 해석하고 회신할 패킷을 준비한다. 준비가 되면 RS-485 Rx 에서 Tx 모드로 바꿔준다.

3) 최초 번은 UDR 바이트를 넣어주고 UDRIE 1 설정하여 인터럽트를 Enable 시켜준다.

4) 그리고 ISR(인터럽트 서비스 루틴)에서 남은 패킷들을 바이트씩 UDR 넣어준다.

5) TXC 인터럽트가 발생하면 master 에게 보내는 Tx 전송이 완료되었다는 것이다. 이제 Rx 모드로 전환하고 다시 대기한다.

반응형
댓글
  • 프로필사진 공개설정 안녕하세요 RS485에 대한 글 잘 읽었습니다.
    최종구현 부분에서 질문이 있습니다.

    3) 최초 한 번은 UDR에 한 바이트를 넣어주고 UDRIE를 1로 설정하여 인터럽트를 Enable 시켜준다.
    → 질문 : 최초 한 번은 UDR에 한바이트를 넣어준다고 하셨는데, 한바이트를 넣어주는 이유가 무엇인지요?? UDR에 어떤 DATA값이 있을지 몰라서 그 DATA값을 제거하기 위함인지요?? UDR0 = '\0' 을 넣어줘도 되나요??
    2021.10.25 10:08
  • 프로필사진 fistful 너무 오랜만에 보니 정확한 이유까지는 기억이 나지 않네요. 데이터시트를 보면 이유가 나올듯 한데 일단은 이렇게 써보시고 안되면 데이터시트를 점검해봐얄 듯 합니다 2021.10.25 12:35 신고
댓글쓰기 폼