Thông báo

Collapse
No announcement yet.

xin giúp đỡ lỗi truyền thông 485!

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

  • xin giúp đỡ lỗi truyền thông 485!

    Mình có 3 slave để truyền thông.
    - Vấn đề của mình như sau : trên máy tính sẽ gửi xuống 3 byte : địa chỉ slave +địa chỉ thiết bị + mã xác nhận (kí tự 'a').

    - khi mình test từ máy tính truyền xuống thì nếu như thỏa mãn điều kiện đúng byte xác nhận và đúng slave thì nó sẽ cho con led on con led 7 đoạn led để mình biết các slave có nhận đúng không . và mình test thì thấy rất ok. Vậy là phần cứng của mình chắc không có gì sai.

    và đây là code test :
    [CODE]while (1)
    {
    if(rx_counter >= 3)
    {unsigned char temp_receive[3];
    temp_receive[0]= getchar();// dia chi slave
    temp_receive[1]= getchar();// dia chi device
    temp_receive[2]= getchar();// ma xac nhan

    if(('a'== temp_receive[2])&&(temp_receive[0]== slave)) // kiểm tra mã xác nhận và slave
    {

    device = temp_receive[1]; // nếu đúng thì gán dữ liệu device vào biến toàn cục device để cho on con led 7 đoạn này led trong ngắt timer.

    }

    }
    }

    }[/CODE]



    - Vấn đề sai phát sinh như sau mà có lẽ mình nghĩ chắc chắn là do code :khi mình gửi từ cp xuống vẫn với frame truyền như ví dụ trên và yêu cầu nếu đúng slave nào thì nó phải gửi lại máy tính một frame gồm 8 byte :

    ví dụ trên cp mình sẽ yêu cầu slave 3 gủi về data của thiết bị 3 ( device =3).kết quả là gửi bình thường . Nhưng khi mình không chọn slave 3 nữa mà chọn slave khác 2 hay 1 chẳng hạn và yêu cầu nó gửi về thì nó không gửi.---> lúc này mình chỉ có thể yêu cầu slave 3 gửi về mà thôi. nếu muốn slave khác gửi về thì mình phải nhấn reset cái slave đó và gửi lại yêu cầu từ máy tính xuống. Nhưng vẫn chỉ được 1 slave thôi.

    => vậy là nếu slave nào mà mình gửi yêu cầu trên máy tính xuống trước thì nó hoạt động còn slave khác thì không.

    => Mình nghĩ sai có lẽ là khi mà slave nào đó được chọn và gửi data về cp thì các slave khác cũng nhận (nhận tới 8 byte). và khi đó nó cũng đọc và xử lý nhưng không hết bộ đệm nên khi cp yêu cầu những slave này gủi thì nó không nhận đúng thứ tự byte trong bộ đệm nhận nữa. tuy nhiên mình cũng đã khắc phục lỗi này bằng cách :
    Code:
     // sau khi đọc từ bộ đệm nhận thì phải xóa cái biến đếm nhận đi
    rx_counter = 0;
    nhưng mình vẫn không khấc phục được lỗi trên. xin được chỉ giáo thêm.

    đây là code mà mình miêu tả có lỗi ở trên.
    Code:
    while (1)
          {
          if(rx_counter >= 3)
            {unsigned char temp_receive[3];
             temp_receive[0]= getchar();// dia chi slave
             temp_receive[1]= getchar();// dia chi device
             temp_receive[2]= getchar();// ma xac nhan
            
             if(('a'== temp_receive[2])&&(temp_receive[0]== slave)) //ma xac nhan dung thi gui lai du lieu ve may tinh  */
               {
                 putchar(slave); // dia chi slave    ( byte 1)
                 putchar(device);// dia chi device ( byte 2)
                 device = temp_receive[1]; // gan dia chi thiet bi
                 putchar(2222%256);// du lieu byte thap   (byte 3)  
                 putchar(2222/256);// gui byte cao        (byte 4)
                 putchar(3333%256);// gui thap                (byte 5)
                 putchar(3333/256);// gui byte cao           (byte 6)
                 putchar(100); // (byte 7) 
                 putchar('a'); // ma xac nhan   (byte 8)
               
               }
             
             }
          }
    
    }

  • #2
    sau khi ăn xong tô mì tôm và suy nghĩ một tí mình đã nghĩ ra một giải pháp là vô cái hàm ngắt UART của codevision được tạo ra khi mình khai báo chỉnh sửa một tí thế là cả 3 thằng slave chạy oke. Không biết bạn nào có kiến giải tốt hơn cho trường hợp lỗi của mình xin đóng góp, và đúng như mình đã nói ở trên thì nguyên nhân lỗi là do mấy thằng slave nó nhận data từ các con slave khác mà các slave này nó truyền 8 byte trong khi cp truyền lệnh 3 byte và vì vậy khi mình kiểm tra có 3 byte trong void main(); mới dẫn đến lỗi kia slave nào đc chọn trước sẽ độc quyền chiếm quyền giao tiếp với cp một cách ngoài mong mún như thế.

    Comment


    • #3
      Nếu byte nhận được không đúng địa chỉm thì liên tục xóa bộ đệm, thế chắc là đc. Cậu dùng nguyên hàm getchar() à? có chỉnh sửa gì ko?

      Comment


      • #4
        Nguyên văn bởi newbie_avr Xem bài viết
        sau khi ăn xong tô mì tôm và suy nghĩ một tí mình đã nghĩ ra một giải pháp là vô cái hàm ngắt UART của codevision được tạo ra khi mình khai báo chỉnh sửa một tí thế là cả 3 thằng slave chạy oke. Không biết bạn nào có kiến giải tốt hơn cho trường hợp lỗi của mình xin đóng góp, và đúng như mình đã nói ở trên thì nguyên nhân lỗi là do mấy thằng slave nó nhận data từ các con slave khác mà các slave này nó truyền 8 byte trong khi cp truyền lệnh 3 byte và vì vậy khi mình kiểm tra có 3 byte trong void main(); mới dẫn đến lỗi kia slave nào đc chọn trước sẽ độc quyền chiếm quyền giao tiếp với cp một cách ngoài mong mún như thế.
        Bạn đã chỉnh sửa trong ngắt thế nào? mà nó chạy OK

        Comment


        • #5
          thực ra cách refix của mình có độ tin cậy không cao. và sẽ có xác xuất lỗi xảy ra. Cái thằng ngắt Uart sài khai báo tự động khi làm như vậy mình mới thấy nó tiện nhưng là con dao hai lữa. nếu frame từ cp truyền xuống = frame từ slave gửi lên thì chỉ cần gọi mấy hàm getchar và putchar mà vẫn không có lỗi.

          Nhưng như bạn thấy đó hai khung truyền của mình khác nhau và lúc đó nó sẽ phát sinh lỗi. bởi vậy mình nghĩ nếu mún sài nó tạm oke thì phải hiểu được cái hàm nó sẽ làm gì.

          ở đây cách khắc phục như mình nói là có độ an toàn không cao nhưng mình test mỏi cả tay vẫn thấy oke là thế này :
          Code:
          interrupt [USART_RXC] void usart_rx_isr(void)
          {
          char status,data;
          status=UCSRA;
          data=UDR;
          if ((status & (FRAMING_ERROR | PARITY_ERROR | DATA_OVERRUN))==0)
             {
             rx_buffer[rx_wr_index]=data;
             if(rx_buffer[0]== slave)
                  {
                  if (++rx_wr_index == RX_BUFFER_SIZE) rx_wr_index=0;
                  if (++rx_counter == RX_BUFFER_SIZE)
                   {
                   rx_counter=0;
                  rx_buffer_overflow=1;
                   };
                  };
          mình chèn thêm thằng này (dòng màu đỏ). vì như mình nói lỗi sẽ xảy ra khi mà slave nào đó được chọn trước và nó gửi về cp theo dạng (slave+device+data+check error) cái frame thì tùy mình thôi nếu mún pro thì cứ ngâm cứu modbus. Thì rõ ràng là các thằng slave khác nó cũng lại nhận 8 byte. Nên mình sẽ check ngay cái byte đầu tiên trong ngắt nhận lun nếu mà không trùng tên với nó thì sẽ không tăng chỉ số mảng lên nữa và cũng không tăng thằng rx_counter lên để khi hàm chính check cái rx_counter thì nó sẽ không đc thỏa mãn.
          để khắc phục với cách làm trên cho hệ số an toàn cao hơn thì thay vì slave đặt với các số đơn giản (1,2,3..) thì sẽ đặt nó là kí tự hoặc số lớn chẳng hạn sẽ cho kết quả ok hơn nhỉ. mì Hảo hảo 100 đồng hành cùng sv
          ù còn đây là mấy modul mà mình định sẽ bv lv hi vọng là suôn sẻ mạch ủi tay nên có board bị lem mực hơi dơ. bạn nào thích mình bv đc xong lấy về mà tham khảo cũng củ chuối thôi. Vì mình mới tập tành avr đcj chút nên code chạy bad.
          http://www.mediafire.com/?mnyqyiyydfn
          Last edited by newbie_avr; 23-01-2010, 21:55.

          Comment


          • #6
            Nguyên văn bởi newbie_avr Xem bài viết
            thực ra cách refix của mình có độ tin cậy không cao. và sẽ có xác xuất lỗi xảy ra. Cái thằng ngắt Uart sài khai báo tự động khi làm như vậy mình mới thấy nó tiện nhưng là con dao hai lữa. nếu frame từ cp truyền xuống = frame từ slave gửi lên thì chỉ cần gọi mấy hàm getchar và putchar mà vẫn không có lỗi.

            Nhưng như bạn thấy đó hai khung truyền của mình khác nhau và lúc đó nó sẽ phát sinh lỗi. bởi vậy mình nghĩ nếu mún sài nó tạm oke thì phải hiểu được cái hàm nó sẽ làm gì.

            ở đây cách khắc phục như mình nói là có độ an toàn không cao nhưng mình test mỏi cả tay vẫn thấy oke là thế này :
            Code:
            interrupt [USART_RXC] void usart_rx_isr(void)
            {
            char status,data;
            status=UCSRA;
            data=UDR;
            if ((status & (FRAMING_ERROR | PARITY_ERROR | DATA_OVERRUN))==0)
               {
               rx_buffer[rx_wr_index]=data;
               if(rx_buffer[0]== slave)
                    {
                    if (++rx_wr_index == RX_BUFFER_SIZE) rx_wr_index=0;
                    if (++rx_counter == RX_BUFFER_SIZE)
                     {
                     rx_counter=0;
                    rx_buffer_overflow=1;
                     };
                    };
            mình chèn thêm thằng này (dòng màu đỏ). vì như mình nói lỗi sẽ xảy ra khi mà slave nào đó được chọn trước và nó gửi về cp theo dạng (slave+device+data+check error) cái frame thì tùy mình thôi nếu mún pro thì cứ ngâm cứu modbus. Thì rõ ràng là các thằng slave khác nó cũng lại nhận 8 byte. Nên mình sẽ check ngay cái byte đầu tiên trong ngắt nhận lun nếu mà không trùng tên với nó thì sẽ không tăng chỉ số mảng lên nữa và cũng không tăng thằng rx_counter lên để khi hàm chính check cái rx_counter thì nó sẽ không đc thỏa mãn.
            để khắc phục với cách làm trên cho hệ số an toàn cao hơn thì thay vì slave đặt với các số đơn giản (1,2,3..) thì sẽ đặt nó là kí tự hoặc số lớn chẳng hạn sẽ cho kết quả ok hơn nhỉ. mì Hảo hảo 100 đồng hành cùng sv
            ù còn đây là mấy modul mà mình định sẽ bv lv hi vọng là suôn sẻ mạch ủi tay nên có board bị lem mực hơi dơ. bạn nào thích mình bv đc xong lấy về mà tham khảo cũng củ chuối thôi. Vì mình mới tập tành avr đcj chút nên code chạy bad.
            http://www.mediafire.com/?mnyqyiyydfn
            Bạn chỉ làm thế mày nó chạy ok ah.. hay nhỉ..

            Comment


            • #7
              Bạn thử test thế này nhé.
              Mới vào, khởi động ctr lên, gọi con thứ nhất, xong gọi con thứ 2. đến đây thì mọi việc sẽ bình thường.

              sau đó, bạn gọi con thứ nhất.. xem thử có việc j xảy ra...

              Ah, mình hỏi thêm là kích thước bộ đệm của bạn là bao nhiêu vậy, RX_BUFFER_SIZE

              Comment


              • #8
                chẳng có vấn đề gì cả bạn ah vẫn ok. để cho thêm độ tin cậy mình thêm thằng này vào void main
                Code:
                if(rx_counter >= 3)
                       { 
                         unsigned char temp_receive[3];
                         temp_receive[0]= getchar();// dia chi slave
                         temp_receive[1]= getchar();// dia chi device
                         temp_receive[2]= getchar();// ma xac nhan
                         rx_wr_index = 0;
                         rx_rd_index = 0;
                         rx_counter = 0;
                         
                         if(('r'== temp_receive[2])&&(temp_receive[0]== slave))
                rx_buffer_size là biến tự động.. giống mảng động sẽ ở codevision mình khai báo tự động ngăt UART nên biến này sẽ có 2 khả năng.
                thực ra mình chỉ cần can thiệp vào 2 chỉ số trên thôi còn cái rx_counter sẽ đc giảm trong hàm getchar(); khi mình gọi.

                Comment


                • #9
                  Nguyên văn bởi newbie_avr Xem bài viết
                  chẳng có vấn đề gì cả bạn ah vẫn ok. để cho thêm độ tin cậy mình thêm thằng này vào void main
                  Code:
                  if(rx_counter >= 3)
                         { 
                           unsigned char temp_receive[3];
                           temp_receive[0]= getchar();// dia chi slave
                           temp_receive[1]= getchar();// dia chi device
                           temp_receive[2]= getchar();// ma xac nhan
                           rx_wr_index = 0;
                           rx_rd_index = 0;
                           rx_counter = 0;
                           
                           if(('r'== temp_receive[2])&&(temp_receive[0]== slave))
                  rx_buffer_size là biến tự động.. giống mảng động sẽ ở codevision mình khai báo tự động ngăt UART nên biến này sẽ có 2 khả năng.
                  thực ra mình chỉ cần can thiệp vào 2 chỉ số trên thôi còn cái rx_counter sẽ đc giảm trong hàm getchar(); khi mình gọi.
                  Mình lại nghĩ nó sẽ có vấn đề nếu như bạn ko xóa rx_wr_index và rx_rd_index.
                  vì theo như bạn kt là kiểm tra byte đầu tiên của bộ đệm, do đó, khi nhận lệnh gọi đầu tiên là byte này đã bằng đưa về giá trị slave của nó rồi, và giá trị này sẽ giữ ở vị trí đó đến khi nào tổng số data bạn nhận dc lớn hơn bộ đệm thì nó mới bị ghi đè.. do đó, khi gọi sang con thứ 2 thì nó vẫn kiểm tra đúng và nhận data về bình thường, kể cả data từ con thứ 2 gửi ngược lên... do đó khi gọi lại nó lần thứ 2 thì sẽ gặp lỗi.
                  trừ khi bạn gọi con thứ nhất.. xong gọi con thứ 2 với 3 lần liên tiếp rồi quay lại gọi nó thì may ra..hi.

                  RX_BUFFER_SIZE là hằng số, được define ngay ở đầu, nó là thông số về bộ đệm nhận, đơn vị là byte, chỉ có các biến khác đi theo bộ đệm mới là biến tự động có kiểu biến hợp với kích thước của bộ đệm thôi. bạn coi kĩ lại đi.

                  Comment


                  • #10
                    mình cũng test thử nhiều cách rồi nếu không xóa mấy chỉ số kia đi. thì cũng không có lỗi nhưng như mình nói ở trên bắt buộc phải có dòng code màu đỏ. nếu không thì làm miết vẫn lỗi. nếu không có dòng code màu đỏ mình thử xóa ( gán = 0) hoặc không xóa đi thì vẫn lỗi bạn ah.

                    Comment


                    • #11
                      Nguyên văn bởi newbie_avr Xem bài viết
                      mình cũng test thử nhiều cách rồi nếu không xóa mấy chỉ số kia đi. thì cũng không có lỗi nhưng như mình nói ở trên bắt buộc phải có dòng code màu đỏ. nếu không thì làm miết vẫn lỗi. nếu không có dòng code màu đỏ mình thử xóa ( gán = 0) hoặc không xóa đi thì vẫn lỗi bạn ah.
                      Mình nghĩ là có cách hay hơn, nhưng ko biết bạn còn thời gian để viết ko, cũng giống giống cách của bạn, nhưng sẽ làm chương trình dễ nhìn và có vẻ sáng sủa hơn...

                      Comment

                      Về tác giả

                      Collapse

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

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

                      Collapse

                      Đang tải...
                      X