Thông báo

Collapse
No announcement yet.

Cần giúp đỡ về RS 485 network

Collapse
X
 
  • Lọc
  • Giờ
  • Show
Clear All
new posts

  • Cần giúp đỡ về RS 485 network

    Em có làm một project nhỏ là mạng RS 485, tuy nhiên em không làm phần cứng mà một người khác làm, em chỉ lập trình cho mạch thôi ( một modul Atmeg128 là master cái này còn làm nhiều việc khác nữa, một modul là Atmeg8 chỉ thu thập dữ liệu từ sensor và tham gia vào mạng 485 ). Mỗi modul chỉ có một con MAX485 và tất cả nối trên cùng một đường dây ( mạng đường thẳng ). Nếu một con truyền một con nhận thì không có vấn đề gì, nó hoạt động tốt, tuy nhiên em nâng cao nên một chút cho 2 modul truyền nhận 2 chiều và có đặt ID vào thì không chạy.
    Cái khó của em khi debug chương trình là phần cứng em không làm nên nếu lối ở phần cứng thì em bó tay, thứ hai là modul ATmeg128 thì có cổng RS232 truyền lên PC mình cũng dễ debug nhưng modul Atmega8 chẳng có dấu hiệu gì dù chỉ là 1 con Led sáng khi nhận được Message thành ra rất khó check lỗi.
    Thứ ba cũng vì kiến thức, kinh nghiệm có hạn.
    Em xin post lên phần chương trình của em ( nó không chạy), mọi người ai giúp em với ? nếu cho em biết lỗi ở đâu thì tốt quá hoặc cho em biết phải đọc cái gì để debug hoặc là kinh nghiệm debug hay cái gì đó ? cái này làm em điên đầu 3 tuần rồi mà chẳng có kết quả gì. Về phần cứng thì người khác vẽ em chưa xin phép được lên không dám post vì nó gồm nhiều cái khác.

  • #2
    Master complier : Codevison atmeg128 16Mhz)

    #include <mega128.h>
    #include <delay.h>
    #include <ctype.h>

    #define TRUE 1
    #define FALSE 0
    #define TX_MODE 1
    #define RX_MODE 0

    #define RS485_N0_DIR PORTD.7

    #define Address_Slave_1 '1'
    #define Message_Lenght 6
    #define Start_Lenght 3
    #define Check_Lenght 3
    unsigned char network_state;

    unsigned char Message[Message_Lenght]={'{','O','K',Address_Slave_1,'?','}'} ;
    unsigned char Start[Start_Lenght]={'{','{','{'};
    unsigned char Check[Check_Lenght]={'{','O','K'};

    #define RXB8 1
    #define TXB8 0
    #define UPE 2
    #define OVR 3
    #define FE 4
    #define UDRE 5
    #define RXC 7

    #define FRAMING_ERROR (1<<FE)
    #define PARITY_ERROR (1<<UPE)
    #define DATA_OVERRUN (1<<OVR)
    #define DATA_REGISTER_EMPTY (1<<UDRE)
    #define RX_COMPLETE (1<<RXC)

    // Get a character from the USART1 Receiver
    #pragma used+
    char getchar1(void)
    {
    char status,data;
    while (1)
    {
    while (((status=UCSR1A) & RX_COMPLETE)==0);
    data=UDR1;
    if ((status & (FRAMING_ERROR | PARITY_ERROR | DATA_OVERRUN))==0)
    return data;
    };
    }
    #pragma used-

    // Write a character to the USART1 Transmitter
    #pragma used+
    void putchar1(char c)
    {
    while ((UCSR1A & DATA_REGISTER_EMPTY)==0);
    UDR1=c;
    }
    #pragma used-

    // Standard Input/Output functions
    #include <stdio.h>


    void init_mC(void)
    {
    // Input/Output Ports initialization
    // Port A initialization
    // Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
    // State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
    PORTA=0x00;
    DDRA=0x00;

    // Port B initialization
    // Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
    // State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
    PORTB=0x00;
    DDRB=0x00;

    // Port C initialization
    // Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
    // State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
    PORTC=0x00;
    DDRC=0x00;

    // Port D initialization
    // Func7=Out Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
    // State7=0 State6=T State5=T State4=T State3=T State2=T State1=T State0=T
    PORTD=0x00;
    DDRD=0x80;

    // Port E initialization
    // Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
    // State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
    PORTE=0x00;
    DDRE=0x00;

    // Port F initialization
    // Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
    // State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
    PORTF=0x00;
    DDRF=0x00;

    // Port G initialization
    // Func4=In Func3=In Func2=In Func1=In Func0=In
    // State4=T State3=T State2=T State1=T State0=T
    PORTG=0x00;
    DDRG=0x00;

    // Timer/Counter 0 initialization
    // Clock source: System Clock
    // Clock value: Timer 0 Stopped
    // Mode: Normal top=FFh
    // OC0 output: Disconnected
    ASSR=0x00;
    TCCR0=0x00;
    TCNT0=0x00;
    OCR0=0x00;

    // Timer/Counter 1 initialization
    // Clock source: System Clock
    // Clock value: Timer 1 Stopped
    // Mode: Normal top=FFFFh
    // OC1A output: Discon.
    // OC1B output: Discon.
    // OC1C output: Discon.
    // Noise Canceler: Off
    // Input Capture on Falling Edge
    // Timer 1 Overflow Interrupt: Off
    // Input Capture Interrupt: Off
    // Compare A Match Interrupt: Off
    // Compare B Match Interrupt: Off
    // Compare C Match Interrupt: Off
    TCCR1A=0x00;
    TCCR1B=0x00;
    TCNT1H=0x00;
    TCNT1L=0x00;
    ICR1H=0x00;
    ICR1L=0x00;
    OCR1AH=0x00;
    OCR1AL=0x00;
    OCR1BH=0x00;
    OCR1BL=0x00;
    OCR1CH=0x00;
    OCR1CL=0x00;

    // Timer/Counter 2 initialization
    // Clock source: System Clock
    // Clock value: Timer 2 Stopped
    // Mode: Normal top=FFh
    // OC2 output: Disconnected
    TCCR2=0x00;
    TCNT2=0x00;
    OCR2=0x00;

    // Timer/Counter 3 initialization
    // Clock source: System Clock
    // Clock value: Timer 3 Stopped
    // Mode: Normal top=FFFFh
    // Noise Canceler: Off
    // Input Capture on Falling Edge
    // OC3A output: Discon.
    // OC3B output: Discon.
    // OC3C output: Discon.
    // Timer 3 Overflow Interrupt: Off
    // Input Capture Interrupt: Off
    // Compare A Match Interrupt: Off
    // Compare B Match Interrupt: Off
    // Compare C Match Interrupt: Off
    TCCR3A=0x00;
    TCCR3B=0x00;
    TCNT3H=0x00;
    TCNT3L=0x00;
    ICR3H=0x00;
    ICR3L=0x00;
    OCR3AH=0x00;
    OCR3AL=0x00;
    OCR3BH=0x00;
    OCR3BL=0x00;
    OCR3CH=0x00;
    OCR3CL=0x00;

    // External Interrupt(s) initialization
    // INT0: Off
    // INT1: Off
    // INT2: Off
    // INT3: Off
    // INT4: Off
    // INT5: Off
    // INT6: Off
    // INT7: Off
    EICRA=0x00;
    EICRB=0x00;
    EIMSK=0x00;

    // Timer(s)/Counter(s) Interrupt(s) initialization
    TIMSK=0x00;
    ETIMSK=0x00;

    // USART0 initialization
    // Communication Parameters: 8 Data, 1 Stop, No Parity
    // USART0 Receiver: On
    // USART0 Transmitter: On
    // USART0 Mode: Asynchronous
    // USART0 Baud Rate: 9600
    UCSR0A=0x00;
    UCSR0B=0x18;
    UCSR0C=0x06;
    UBRR0H=0x00;
    UBRR0L=0x67;

    // USART1 initialization
    // Communication Parameters: 8 Data, 1 Stop, No Parity
    // USART1 Receiver: On
    // USART1 Transmitter: On
    // USART1 Mode: Asynchronous
    // USART1 Baud Rate: 9600
    UCSR1A=0x00;
    UCSR1B=0x18;
    UCSR1C=0x06;
    UBRR1H=0x00;
    UBRR1L=0x67;

    // Analog Comparator initialization
    // Analog Comparator: Off
    // Analog Comparator Input Capture by Timer/Counter 1: Off
    ACSR=0x80;
    SFIOR=0x00;
    }

    void transmit_serial_data(void)
    {
    static unsigned char i;
    RS485_N0_DIR= TX_MODE;
    for(i=0;i< Start_Lenght;i++)
    {
    putchar(Start[i]);
    }
    for(i=0;i<Message_Lenght;i++)
    {
    putchar(Message[i]);
    }

    network_state = 'r';


    }

    unsigned char RX_Buffer[10];
    void receive_serial_data(void)
    {
    static unsigned char i = 0;
    static bit Frame_flag = FALSE;
    RS485_N0_DIR= RX_MODE;
    RX_Buffer[i]=getchar();
    if(RX_Buffer[i]==Check[i])
    {
    i++;
    if(i==3)
    {
    Frame_flag = TRUE;
    }
    }
    else
    {
    i=0;
    }
    if(Frame_flag)
    {

    network_state = 't';
    }


    }
    void serial_communication(void)
    {
    switch(network_state)
    {
    case 'r':
    {
    // Receive data.

    receive_serial_data();
    break;
    }


    case 't':
    {
    // Transmit data.

    transmit_serial_data();
    break;
    }

    default:
    break;
    }


    }

    // Declare your global variables here

    void main(void)
    {
    // Declare your local variables here


    init_mC();
    network_state = 't';
    while (1)
    {
    // Place your code here
    serial_communication();



    };
    }

    Comment


    • #3
      Slave Atmega8 8mhz )
      #include <mega8.h>
      #include <delay.h>

      #define TRUE 1
      #define FALSE 0
      #define TX_MODE 1
      #define RX_MODE 0
      #define RS485_DIR PORTC.0


      unsigned char network_state;

      // Standard Input/Output functions
      #include <stdio.h>

      void init_mC(void)
      {
      // Input/Output Ports initialization
      // Port B initialization
      // Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
      // State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
      PORTB=0x00;
      DDRB=0x00;

      // Port C initialization
      // Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=Out
      // State6=T State5=T State4=T State3=T State2=T State1=T State0=0
      PORTC=0x00;
      DDRC=0x01;

      // Port D initialization
      // Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
      // State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
      PORTD=0x00;
      DDRD=0x00;

      // Timer/Counter 0 initialization
      // Clock source: System Clock
      // Clock value: Timer 0 Stopped
      TCCR0=0x00;
      TCNT0=0x00;

      // Timer/Counter 1 initialization
      // Clock source: System Clock
      // Clock value: Timer 1 Stopped
      // Mode: Normal top=FFFFh
      // OC1A output: Discon.
      // OC1B output: Discon.
      // Noise Canceler: Off
      // Input Capture on Falling Edge
      // Timer 1 Overflow Interrupt: Off
      // Input Capture Interrupt: Off
      // Compare A Match Interrupt: Off
      // Compare B Match Interrupt: Off
      TCCR1A=0x00;
      TCCR1B=0x00;
      TCNT1H=0x00;
      TCNT1L=0x00;
      ICR1H=0x00;
      ICR1L=0x00;
      OCR1AH=0x00;
      OCR1AL=0x00;
      OCR1BH=0x00;
      OCR1BL=0x00;

      // Timer/Counter 2 initialization
      // Clock source: System Clock
      // Clock value: Timer 2 Stopped
      // Mode: Normal top=FFh
      // OC2 output: Disconnected
      ASSR=0x00;
      TCCR2=0x00;
      TCNT2=0x00;
      OCR2=0x00;

      // External Interrupt(s) initialization
      // INT0: Off
      // INT1: Off
      MCUCR=0x00;

      // Timer(s)/Counter(s) Interrupt(s) initialization
      TIMSK=0x00;

      // USART initialization
      // Communication Parameters: 8 Data, 1 Stop, No Parity
      // USART Receiver: On
      // USART Transmitter: On
      // USART Mode: Asynchronous
      // USART Baud Rate: 9600
      UCSRA=0x00;
      UCSRB=0x18;
      UCSRC=0x86;
      UBRRH=0x00;
      UBRRL=0x33;

      // Analog Comparator initialization
      // Analog Comparator: Off
      // Analog Comparator Input Capture by Timer/Counter 1: Off
      ACSR=0x80;
      SFIOR=0x00;

      }
      #define Respond_Lenght 5
      #define Start_Lenght 3
      #define Adress '1'
      unsigned char Respond[Respond_Lenght]={'{','O','K',Adress,'}'} ;
      unsigned char Start[Start_Lenght]={'{','{','{'};
      unsigned char Check[Adress]={'{','O','K'} ;

      void transmit_serial_data(void)
      {
      static unsigned char i;
      RS485_DIR = TX_MODE;
      for(i=0;i<Start_Lenght;i++)
      {
      putchar(Start[i]);
      }
      for(i=0;i<Respond_Lenght;i++)
      {
      putchar(Respond[i]);
      }


      network_state = 'r';

      }
      unsigned char RX_Buffer[10];
      void receive_serial_data(void)
      {

      static unsigned char i=0;
      static bit Frame_flag= FALSE;
      RS485_DIR = RX_MODE;

      RX_Buffer[i] = getchar() ;
      if(RX_Buffer[i]==Check[i])
      {
      i++;
      if(i==3)
      {
      Frame_flag = TRUE;
      }

      }
      else
      {
      i=0 ;
      }

      if(Frame_flag)
      {
      network_state = 't' ;
      }

      }
      void serial_communication(void)
      {
      switch(network_state)
      {
      case 'r':
      {
      // Receive data.

      receive_serial_data();
      break;
      }


      case 't':
      {
      // Transmit data.

      transmit_serial_data();
      break;
      }
      default:
      break;
      }


      }


      // Declare your global variables here

      void main(void)
      {
      // Declare your local variables here




      init_mC();
      network_state = 'r';
      while (1)
      {
      // Place your code here
      serial_communication();

      };
      }

      Comment


      • #4
        Hiện tượng như sau:
        + Em không cho nó truyền FRAME mối lần chỉ truyền 1 ký tứ bên nào nhận được thì truyền trở lại thôi ( nó đơn giản hơn code trên kia) thì master không nhận được gì nó dừng lại ở hàm getchar().
        + Nếu bên nào nhận được truyền lên khoảng 3, 4 ký tự thì nó nhận được nhưng có lần đúng có lần sai

        Mong mọi người giúp đỡ. Thanks for viewing .

        Comment


        • #5
          nhìn ct viết bằng c thì bó hand.mình chỉ dùng asm.
          nhưng theo như bạn nói mình nghĩ bạn sai ở chổ :giả sử khi con chủ truyền con tớ nhận thì khi nhận xong con tớ phải delay ít nhất bằng thời gian truyền 1 bit trước khi truyền lại cho con chủ.nếu nếu mạng truyền thông có 3 thành phần trở lên thì bạn phải dùng pp truyền thông đa xử lý( cần phân biệt rõ byte địa chỉ và byte dữ liệu). thân chào bạn!

          Comment


          • #6
            Trước tiên bạn phải đảm bảo hardware ko có vấn đề ( nếu truyền nhận 1 chiều qua lại OK thi chắc là ko có vấn đề)
            Ở cuối ha`m transmit thì bạn thêm delay khoảng 10ms.Lý do là sau khi thực hiện các lênh trong transmit thì bạn phải chờ 1 chút cho bộ đệm serial nó truyền cho xong. Chứ hiện tại code của bạn sau khi xong lênh transmit(DE=1) thi bạn chuyển ngay sang receive (RE=0) thì nó có thể chưa truyền hết dữ liệu. Đó cũng là lý do khi bạn truyền 3-4 char thì có lúc đúng có lúc sai. Nếu truyền thành công rồi thì bạn cân chỉnh lại giá trị delay cho tối ưu hơn

            Comment


            • #7
              Nguyên văn bởi zinix Xem bài viết
              Trước tiên bạn phải đảm bảo hardware ko có vấn đề ( nếu truyền nhận 1 chiều qua lại OK thi chắc là ko có vấn đề)
              Ở cuối ha`m transmit thì bạn thêm delay khoảng 10ms.Lý do là sau khi thực hiện các lênh trong transmit thì bạn phải chờ 1 chút cho bộ đệm serial nó truyền cho xong. Chứ hiện tại code của bạn sau khi xong lênh transmit(DE=1) thi bạn chuyển ngay sang receive (RE=0) thì nó có thể chưa truyền hết dữ liệu. Đó cũng là lý do khi bạn truyền 3-4 char thì có lúc đúng có lúc sai. Nếu truyền thành công rồi thì bạn cân chỉnh lại giá trị delay cho tối ưu hơn
              Đúng là phải thêm 1 delay thì mới có thể ổn định được.
              Theo tớ, bạn nên dùng ngắt truyền và ngắt nhận, một bộ đệm truyền và nhận sẽ được cấp phát (có thể tùy chỉnh được). Ngoài ra tốc độ truyền cực cao vì khi truyền sẽ không phải delay (kiểm tra bộ đệm truyền khi về 0 là đã truyền hết). Nếu dùng RS485 với 2 đường truyền và nhận riêng biệt thì sao nhỉ?

              Comment


              • #8
                bạn không post phần cứng nên cũng khó phân tích.
                ở đây có vài vấn đề:
                khi con master truyền chưa hết data thì mấy con slave đã chuyển sang chế độ truyền--> trùng bit-->lỗi.
                nếu trên mạng này bạn mắc nhiều hơn 1 slave mà không kiểm địa chỉ thì khi nhận được data mấy con slave này đều chuyển sang chế độ truyền-->trùng bit giữa 2 con slave nên master sẽ không nhận được đúng data.
                để giải quyết thì bạn cần đặt tất cả thiết bị ở chế độ nhận. trước khi muốn truyền data lên đường truyền thì cấn kiểm tra xem đường truyền có đang ở trạng thái rỗi hay không. (cái này thì phụ thuộc phần cứng. hình như con max485 có chân này thì phải, bạn kiểm tra datasheet giúp nhé).

                thân!

                Comment


                • #9
                  Nguyên văn bởi dt_love Xem bài viết
                  bạn không post phần cứng nên cũng khó phân tích.
                  ở đây có vài vấn đề:
                  khi con master truyền chưa hết data thì mấy con slave đã chuyển sang chế độ truyền--> trùng bit-->lỗi.
                  nếu trên mạng này bạn mắc nhiều hơn 1 slave mà không kiểm địa chỉ thì khi nhận được data mấy con slave này đều chuyển sang chế độ truyền-->trùng bit giữa 2 con slave nên master sẽ không nhận được đúng data.
                  để giải quyết thì bạn cần đặt tất cả thiết bị ở chế độ nhận. trước khi muốn truyền data lên đường truyền thì cấn kiểm tra xem đường truyền có đang ở trạng thái rỗi hay không. (cái này thì phụ thuộc phần cứng. hình như con max485 có chân này thì phải, bạn kiểm tra datasheet giúp nhé).

                  thân!
                  Không có chân ấy đâu bạn à.

                  Comment


                  • #10
                    Nguyên văn bởi mrcuongcon Xem bài viết
                    Không có chân ấy đâu bạn à.
                    uh.thanks mrcuongcon nhé. mình check lại rồi.
                    nếu vậy thì chắc phải dùng đến phần mềm kiểm tra chân RO để xác định trạng thái đường truyền (tuy nhiên nó sẽ trùng với mức logic 1 của data).
                    bạn thử dùng phương pháp này thử xem:
                    master truyền data xong, đặt timer để chờ timeout(thời gian này thì bạn cho bằng thời gian truyền của vài byte lớn hơn 2). nếu timer tràn mà không có data về thì xem như ko có tín hiệu trả lời từ slave, master sẽ tiếp tục gửi data để tìm slave nếu cần.
                    slave nhận data,check add nếu đúng thì nó sẽ đặt timer để chờ timeout(thời gian chờ lớn hơn thời gian truyền hết một byte). nếu nhận có data mới thì nó clear timer này.như vậy nếu timer tràn thì có nghĩa là đường truyền rỗi. lúc này nó chỉ việc gửi data trả về master.
                    tuy nhiên ở đây thì bạn phải đặt add cho mấy cái slave để tránh đụng data giữa chúng.

                    ở trên bạn nói là nếu chỉ truyền giữa 2 bộ thì giao tiếp bình thường.
                    chắc là bạn chưa đặt add cho slave, giờ bạn vẫn giữ 2 bộ đó trên mạch và đặt add cho slave. bạn điều khiển sao cho khi con master gửi đúng lệnh gọi nó thì nó mới trả lời.
                    tiếp tục bạn gỡ con slave này ra, gắn con slave khác vào, set add cho nó và cũng làm như trên. khi master đã gọi được add của 2 con này rồi thì bạn lắp luôn 3 cái vào và thử xem sao.

                    Comment


                    • #11
                      Nguyên văn bởi dt_love Xem bài viết
                      uh.thanks mrcuongcon nhé. mình check lại rồi.
                      nếu vậy thì chắc phải dùng đến phần mềm kiểm tra chân RO để xác định trạng thái đường truyền (tuy nhiên nó sẽ trùng với mức logic 1 của data).
                      bạn thử dùng phương pháp này thử xem:
                      master truyền data xong, đặt timer để chờ timeout(thời gian này thì bạn cho bằng thời gian truyền của vài byte lớn hơn 2). nếu timer tràn mà không có data về thì xem như ko có tín hiệu trả lời từ slave, master sẽ tiếp tục gửi data để tìm slave nếu cần.
                      slave nhận data,check add nếu đúng thì nó sẽ đặt timer để chờ timeout(thời gian chờ lớn hơn thời gian truyền hết một byte). nếu nhận có data mới thì nó clear timer này.như vậy nếu timer tràn thì có nghĩa là đường truyền rỗi. lúc này nó chỉ việc gửi data trả về master.
                      tuy nhiên ở đây thì bạn phải đặt add cho mấy cái slave để tránh đụng data giữa chúng.

                      ở trên bạn nói là nếu chỉ truyền giữa 2 bộ thì giao tiếp bình thường.
                      chắc là bạn chưa đặt add cho slave, giờ bạn vẫn giữ 2 bộ đó trên mạch và đặt add cho slave. bạn điều khiển sao cho khi con master gửi đúng lệnh gọi nó thì nó mới trả lời.
                      tiếp tục bạn gỡ con slave này ra, gắn con slave khác vào, set add cho nó và cũng làm như trên. khi master đã gọi được add của 2 con này rồi thì bạn lắp luôn 3 cái vào và thử xem sao.
                      Việc dùng nhiều chíp trên cùng một đường truyền ,rất nhiều vấn đề với một mạng kiểu như thế này. Đầu tiên là việc định khung dữ liệu, byte khởi đầu, các byte dât, byte kết thúc ( vì nó là một khung mà). Việc thêm một byte địa chỉ vào một khung chẳng có gì đáng bàn ( làm sẽ hiểu).
                      Cái khó là làm sao mà các con chíp cùng truyền trên một đường duy nhất mà không bị tranh chấp đường truyền, đảm bảo tốc độ giao tiếp ( với AVR tốc độ có thể lên đến 115200 bit/s). Nếu động đến delay,Timer trong phần giao tiếp này, coi như vứt đi bởi mạng có hàng chục con chíp, số lần truyền - nhận giữa 1 con chíp chủ với 10 con chíp tớ trong một giây chắc..đếm đc trên đầu ngón tay.
                      Bạn đã thử dùng 2 con max485 cho mỗi Node chưa? làm như thế sẽ có cả truyền và nhận cùng lúc cũng vẫn ổn.

                      Comment


                      • #12
                        Mọi người ai biết phần mềm opensource nào về Master MOBUS RTU trên PC chỉ em với, em có tìm nhưng toàn cần money.

                        Comment


                        • #13
                          Nguyên văn bởi mrcuongcon Xem bài viết
                          Việc dùng nhiều chíp trên cùng một đường truyền ,rất nhiều vấn đề với một mạng kiểu như thế này. Đầu tiên là việc định khung dữ liệu, byte khởi đầu, các byte dât, byte kết thúc ( vì nó là một khung mà). Việc thêm một byte địa chỉ vào một khung chẳng có gì đáng bàn ( làm sẽ hiểu).
                          Cái khó là làm sao mà các con chíp cùng truyền trên một đường duy nhất mà không bị tranh chấp đường truyền, đảm bảo tốc độ giao tiếp ( với AVR tốc độ có thể lên đến 115200 bit/s). Nếu động đến delay,Timer trong phần giao tiếp này, coi như vứt đi bởi mạng có hàng chục con chíp, số lần truyền - nhận giữa 1 con chíp chủ với 10 con chíp tớ trong một giây chắc..đếm đc trên đầu ngón tay.
                          Bạn đã thử dùng 2 con max485 cho mỗi Node chưa? làm như thế sẽ có cả truyền và nhận cùng lúc cũng vẫn ổn.
                          thế là truyền song công uh?cái này pác noi them di. vì em dùng con AT8 thì chỉ truyền bán song cong thôi.
                          Mà sao ko sử dụng chế độ đa xử lý nhỉ. M quản lý đường truyền

                          Comment


                          • #14
                            Nguyên văn bởi mrcuongcon Xem bài viết
                            Việc dùng nhiều chíp trên cùng một đường truyền ,rất nhiều vấn đề với một mạng kiểu như thế này. Đầu tiên là việc định khung dữ liệu, byte khởi đầu, các byte dât, byte kết thúc ( vì nó là một khung mà). Việc thêm một byte địa chỉ vào một khung chẳng có gì đáng bàn ( làm sẽ hiểu).
                            Cái khó là làm sao mà các con chíp cùng truyền trên một đường duy nhất mà không bị tranh chấp đường truyền, đảm bảo tốc độ giao tiếp ( với AVR tốc độ có thể lên đến 115200 bit/s). Nếu động đến delay,Timer trong phần giao tiếp này, coi như vứt đi bởi mạng có hàng chục con chíp, số lần truyền - nhận giữa 1 con chíp chủ với 10 con chíp tớ trong một giây chắc..đếm đc trên đầu ngón tay.
                            Bạn đã thử dùng 2 con max485 cho mỗi Node chưa? làm như thế sẽ có cả truyền và nhận cùng lúc cũng vẫn ổn.
                            để trên một đường truyền mà vừa có thê truyền, vừa có thể nhận data thì theo mình nghĩ có 2 cách, hoặc là chính thiết bị sẽ kiểm tra đường truyền và chỉ gửi data khi nào đường truyền rỗi, như thế sẽ không bị đụng data, cách thứ 2 là bắt tay phần mềm giữa 2 con, nghĩa là con này sẽ truyền data trong một khung nhất định và khi kết thúc khung đó, nó phải thả đường truyền ra để nhận data(nếu cần). tuy nhiên cách thứ 2 này nếu sử dụng không chắc thì sẽ dễ bị trùng data trên đường truyền.
                            ở cách 1, nếu phần cứng có chân nào đó báo cho mình biết đường truyền có rỗi hay không thì chỉ việc kiểm tra nó trước khi truyền là ok. còn nếu phần cứng không có chân này thì buộc phải dùng phần mềm kiểm tra thôi. mà muốn dùng phần mềm kiểm tra thì bắt buộc là phải dùng timer để định thời gian, nếu sau thời gian cần thiết để gửi một byte đi (10 bit : nếu truyền 8 data 1 stop non P) mà không có dữ liệu thì mới chắc là đường truyền rỗi. (tuy nhiên khi kiểm tra bằng cách này vẫn có thể bị lỗi trùng data nếu 2 thiết bị cùng bắt đầu đặt timeout và chờ đường truyền rỗi cùng lúc).

                            và khi giao tiếp kiểu mà data dễ bị mất như thế này thì phía con master buộc phải đặt timeout để chờ data trả về, vì không chắc là data nó gửi đi đã đến được thiết bị slave mong muốn hoặc là data đó đã đến được con slave kia, nhưng khi nó gửi data trở lại thì bị lỗi.., nếu như có data về trước khi timeout thì nó disenable cái timeout đó và xử lí data nhận về. nếu như tràn timeout mà vẫn ko thấy data về thì nó phải có cách xử lí. hoặc là tiếp tục gửi data gọi con slave này, hoặc là xóa nó khỏi danh sách slave có trên đường truyền.

                            vài dòng góp ý,mong mấy bác chỉ giáo!

                            Comment


                            • #15
                              Tôi thấy dùng RS 485 với 1 Master và nhiều slave có thể vừa truyền đến 1 slave và nhận tín hiệu từ 1 slave khác về. Phần cứng cần 2 con IC truyền thông và phần mềm nên test bit truyền và bit nhận để tránh bị lỗi( cần bit kiểm tra).

                              Comment

                              Về tác giả

                              Collapse

                              thienlong198 Tìm hiểu thêm về thienlong198

                              Bài viết mới nhất

                              Collapse

                              Đang tải...
                              X