메뉴 바로가기

서브메뉴 바로가기

본문 바로가기

logo

묻고 답하기
일반
2008.01.22 17:44

RS485 통신 방법

조회 수 23,123 추천 수 0 댓글 3
?

단축키

Prev이전 문서

Next다음 문서

위로 아래로 댓글로 가기 인쇄 쓰기 목록
?

단축키

Prev이전 문서

Next다음 문서

위로 아래로 댓글로 가기 인쇄 쓰기 목록
?
  • WhiteAT 2008.01.23 09:52
    1. 속도
        일반적으로 사용하는 9600bps 로 통신을 한다면,
        1초에 약 100바이트를 보내게 됩니다.
         즉 1바이트를 보내는데 10mS 가 소요됩니다.

        5바이트 이상의 데이터를 보낸다면 50mS 안에 응답을 완료하기 힘들겁니다.


    2. (무조건) RX는 인터럽트로 처리해야 하고요....
        (다른 루틴 처리하다 데이터를 잃을 경우가 생길수 있기 때문에)
         Tx 는 while로 처리하면 될듯합니다.

        circular Queue 를 사용하여 RX데이터를 처리하면 간단합니다.
        즉, 데이터를 RX인터럽트로 받어 Q에 넣고, 수시로 수신된 데이터의 갯수를 체크하고, RX 데이터를 검사하는 겁니다.
        여기에서 응답해야 하는 패킷을 들어 왔을 경우에는 바로 응답을 보내지 않고, 플래그를 하나 만들어서, SET 하고,
        while()의 TX함수에서 그 플래그가 SET되어 있는 경우에 응답해주면 될겁니다.



    간단하게 구조를 보면 아래처럼 될겁니다.

    RX인터럽트(){
        큐에 보관....
    }

    TX함수(){  // 딜레이 타이머를 지정하지 않음
        데이터를 보내야 하면 => 데이터를 보내라.
    }

    RX데이터분석함수(){ // 딜레이 타이머를 지정하지 않음
         큐에 분석할 만한 데이터의 수가 있는가? 그렇지 않다면 그냥 나감.
         큐에 헤더, 데이터등의 패킷이 유효한가? 그렇지 않다면 (노이즈이기 때문에) 큐를 초기화 하고 나감
         패킷을 분석하여 TX 를 하겠다는 플래그 SET,  큐 초기화    
    }

    while(){
      TX함수();
      기타함수들();
      RX데이터분석함수();
    }
      
  • WhiteAT 2008.01.24 09:56
    1.
    TX 내부에 delay()를 직접 주는 거는 위험요소가 될수 있습니다.

    TX함수()에 딜레이가 필요하면.. 타이머를 써야 할듯합니다.
    (처음부터 힘들게 작업하신게  delay 를 직접 사용하지 않는 구조를 사용하지 않으려는 거였잖아요^^)


    void Tx(void) {
      if( next_tiimer > 0) return;
      if(!보낼데이터가 있는가?) return;

      if(tx_step ==0) {
        //통신칩 register 세팅
       write_reg(xxxx);
       write_reg(xxxx);
       write_reg(xxxx);
       write_reg(xxxx);
       write_reg(xxxx);
       tx_step++;
       next_tiimer = 1200; //
      }
     else if(tx_step==1) {
         // Main while에서 받은 값을 tx 버퍼 큐에 쓴다.
        Write_Data(ui8Z85_TBuf[tx_data_cnt]); 
           tx_data_cnt++;
           if(tx_data_cnt >= 14){u8tx_step = ??;} 
       }
      next_tiimer = 1; // 데이터를 보낸후에는 딜레이가 필요없다.
    }
    // 통신칩을 초기화 한후에는 1200딜레이를 가진후 TX를 하게 됩니다.


    2. RX분석 함수에 TX함수를 직접 넣으면 다른 함수에 영향을 줄수도 있습니다.
       TX 하는데 시간이 많이 소요되 때문에 분리해서 하시는게 좋을거 같습니다.
        (TX 인터럽트를 사용해서 보내는 것도 좋은 방법입니다.)


    3. 8Mhz로 9600 으로 (PC와) 통신을 해보셨나요?
       제 경험으로 9600bps로도 통신이 잘 안되고, 데이터 시트에도 에러율이 높게 나와 있습니다.

       시리얼통신((482,232 등)의 통신이 중요한 시스템이라면, 11.0592 같은 통신용 크리스탈을 사용하시는게 좋습니다.





  • WhiteAT 2008.01.25 10:11

    1.
    네이버에서 검색해보니 http://krdic.naver.com/search.nhn?query_euckr=%C0%C0%B4%E4%BD%C3%B0%A3

    응답이 시작되기까지 걸리는 시간이라고 하네요.^^.
    50mS 면 충분한 시간일듯 합니다..

    2. TX함수에서 송신시에는 그냥 연속으로 데이터를 보내세요.
         TX 인터럽트를 사용하지 않고 한 바이트씩 나눠서 보내면, 수신측에서 연속으로 오는 데이터가 아니라서 노이즈로 판단할수도 있습니다.
        ( 저도 개인적으로 이 부분(TX)을 인터럽트로 처리하는 방법으로 변경해야 하는데, 아직 별 문제가 없고, 귀차니즘 때문에 그냥 사용합니다.^^)

    void Tx(void) {

      if(tx_step ==0) {
        //통신칩 register 세팅
       write_reg(xxxx);
       tx_step++;
      }
     else if(tx_step==1) {
         // Main while에서 받은 값을 tx 버퍼 큐에 쓴다.
        Write_Data(ui8Z85_TBuf[tx_data_cnt]); 
           tx_data_cnt++;
           if(tx_data_cnt >= 14){u8tx_step = 3;}
     
        for(i = 0;i<14;i++)   //  데이터는 연속으로 보내야....
              Send Data;
        tx_step = 3;
        timer = 1900;;  // 딜레이도 여기에 주는게...

       }
      else if(tx_step==3) { //Rx 를 위한 세팅..
          
          delay(1900);  // 여기도 delay가 있었네요. -.-'
          
          tx_data_cnt  = 0;
          tx_step =0;
        
          Write_reg(0x21); //Rx 수신대기를 위한 칩 세팅 -- 그렇다면 이 부분도 인터럽트 루틴에 넣는 것이 좋을까요?..
          Write_reg(0x3e);
          Write_reg(0x92);
          Write_reg(0x23);
          ...........................
          Write_reg(0x02);
        }
    }

    3.
    PC 와 통신을 해보라고 말한거는, 꼭 PC와 통신 하라는 뜻이 아니고요^^
    AVR이 8Mhz일 때 9600bps 이상일 경우 통신이 잘 안되기 때문에 그 보레이트에서 에러가 없는지 확인해보시라는 뜻이었습니다.^^ (이건 괜히 급하게 언급했나 보네요ㅡㅡ;)


    4.
    RX 인터럽트는 주기가 필요하지 않습니다.
    데이터가 수신되는 즉시 걸리는 루틴입니다.

    RX 인터럽트 루틴에서는 큐에 데이터를 넣기만 하고요

    interrupt [USART0_RXC] void usart0_rx_isr(void)
    {
     char status,uart_data;
     status=UCSR0A;
     uart_data = UDR0;   /* Read receive data */
     //  putchar1('4');
     if ((status & (FRAMING_ERROR | PARITY_ERROR | DATA_OVERRUN))==0)
     {          
      if (structRX0Info.rx_wr_index1 >= RX_BUFFER_SIZE1-1) structRX0Info.rx_wr_index1=0;
      structRX0Info.rx_buffer[structRX0Info.rx_wr_index1]=uart_data;
      structRX0Info.rx_wr_index1++; 
     };
    }



    데이터 분석 함수에서는 데이터를 분석만 하면 됩니다.
    TX()// 즉 데이터 분석 함수에서는
    큐에 저장된 데이터를 하나씩 꺼내와서 분석만 하면 될겁니다.

    INT16S getchar0(void){
     INT16S iReturnValue = -1;
     #asm("cli")
     if( structRX0Info.rx_rd_index1 >= structRX0Info.rx_wr_index1){
       structRX0Info.rx_rd_index1 = 0;
       structRX0Info.rx_wr_index1 = 0;
      iReturnValue = -1;
     }else{
      if(structRX0Info.rx_rd_index1 >= RX_BUFFER_SIZE1-1){
       structRX0Info.rx_rd_index1 = 0;
      }
      iReturnValue = structRX0Info.rx_buffer[structRX0Info.rx_rd_index1];
      structRX0Info.rx_rd_index1++;
     }
     return iReturnValue;
    }
    
    
    
    
    Tx(){ 
     iRxData=getchar0(); // 큐에 데이터가 있는지 확인
    while (0<= iRxData && iRxData<=255 )  // 
     {
          하나씩 꺼내서 분석...
          패킷이 일치하면 tx_flag = on;
            
     }
    
    }
    




     


  1. VC++ RS232C통신 및 Log data 수집

    Date2009.04.04 Category :일반 Reply1
    Read More
  2. [MFC]키보드 입력 관련 질문입니다.

    Date2009.02.03 Category :일반 Reply1
    Read More
  3. 어제 테트리스에 댓글 달았던 학생입니다

    Date2008.12.13 Category :일반 Reply2
    Read More
  4. 테트리스 소스에 대한 질문이있습니다.

    Date2008.12.12 Category :일반 Reply1
    Read More
  5. 기술자료실에 127번 글에서 질문있습니다..

    Date2008.12.01 Category :일반 Reply1
    Read More
  6. 문제 답변 쫌 부탁드려요~ ^^

    Date2008.11.09 Category :일반
    Read More
  7. 조언 부탁드립니다. 필드에서 지적 받은건데요..

    Date2008.06.13 Category :일반
    Read More
  8. c++구조체와 함수를사용해서 성적표만들기2

    Date2008.05.29 Category :일반 Reply1
    Read More
  9. c++구조체와 함수를사용해서 성적표만들기

    Date2008.05.29 Category :일반 Reply1
    Read More
  10. mfc 테트리스 질문이요~

    Date2008.05.15 Category :일반 Reply1
    Read More
  11. RS485 통신 방법

    Date2008.01.22 Category :일반 Reply3
    Read More
  12. 함수인자를 구조체 변수나 구조체 주소로 받는 것.

    Date2008.01.14 Category :일반 Reply2
    Read More
  13. 인터럽트 루틴을 메인으로 빼고자 하는데 가능할 지요?

    Date2008.01.09 Category :일반 Reply12
    Read More
  14. LED 깜빡 거림.

    Date2008.01.08 Category :일반 Reply8
    Read More
  15. IAR 컴파일러 환경에서 AVR128 Timer1 인터럽터 구현이 안되요..

    Date2008.01.04 Category :일반 Reply2
    Read More
목록
Board Pagination Prev 1 2 3 4 Next
/ 4