اطلاعیه

Collapse
No announcement yet.

مشکل در سوییچ بین RS485 re , de

Collapse
X
 
  • فیلتر
  • زمان
  • Show
Clear All
new posts

    مشکل در سوییچ بین RS485 re , de


    سلام
    دوستان توی یه شبکه 4s485
    برای سوییچ بین حالت ارسال و دریافت در rs485 باید delay بزارم ؟

    وقتی بدون دخالت میکرو خودم پایه های max485 رو برای حالت های ارسال و دریافت تنظیم میکنم (یعنی خودم به vcc یا gnd وصل میکنم) و یک فرستنده با یک گیرنده میزارم اطلاعات رو درست ارسال میکنه....

    ولی وقتی میخوام کار سوییچ کردن رو به عهده خود میکرو بزارم اطلاعات نصف کاره میاد...انگار وقتی داره میفرسته خط زود تر به حالت دریافت میره...یا برعکس :sad:

    من قبل اینکه ارسال کنم RE/DE رو صفر میکنم و یه تاخیر 500 میلی میدم تا پایه به حالت پایدار در بیاد(یه جایی اینو گفته بود) بعد داده ارسال میشه و دوباره پایه 1 میشه و یک تاخیر 500 میلی...
    ولی نمیشه...
    چیکار باید کنم ؟

    #2
    پاسخ : مشکل در سوییچ بین RS485 re , de

    من قبل اینکه ارسال کنم RE/DE رو صفر میکنم و یه تاخیر 500 میلی میدم تا پایه به حالت پایدار در بیاد(یه جایی اینو گفته بود) بعد داده ارسال میشه و دوباره پایه 1 میشه و یک تاخیر 500 میلی...
    اگر درست فهمیده باشم اشتباه گفتی.
    باید اینجوری باشه:re/de یک میشه > ارسال داده > تاخیر 10 میلی ثانیه > re/de صفر میشه

    دیدگاه


      #3
      پاسخ : مشکل در سوییچ بین RS485 re , de

      نوشته اصلی توسط freedom_truth
      اگر درست فهمیده باشم اشتباه گفتی.
      باید اینجوری باشه:re/de یک میشه > ارسال داده > تاخیر 10 میلی ثانیه > re/de صفر میشه
      من میخوام داده بفرسته بلافاصله بره توی مد دریافت ...

      تاخیر رو بعد از نغییر وضعیت re/de باید بدم یا بعد از ارسال داده ؟!

      دیدگاه


        #4
        پاسخ : مشکل در سوییچ بین RS485 re , de

        بعد از ارسال تاخیر میدی، بعد سیگنال رو صفر میکنی.
        البته میزان تاخیر به اسلیو بستگی داره که کی جواب بده.
        اگر بادریت 9600 باشه دو میلی ثانیه کافیه. اسلیو هم از دریافت آخرین داده تا ارسال جواب باید حدود 6 میلی ثانیه تاخیر داشته باشه.
        سوال نکن. برو امتحان کن. با مدار عملی. نه با پروتیوس.

        دیدگاه


          #5
          پاسخ : مشکل در سوییچ بین RS485 re , de

          نوشته اصلی توسط freedom_truth
          بعد از ارسال تاخیر میدی، بعد سیگنال رو صفر میکنی.
          البته میزان تاخیر به اسلیو بستگی داره که کی جواب بده.
          اگر بادریت 9600 باشه دو میلی ثانیه کافیه. اسلیو هم از دریافت آخرین داده تا ارسال جواب باید حدود 6 میلی ثانیه تاخیر داشته باشه.
          سوال نکن. برو امتحان کن. با مدار عملی. نه با پروتیوس.
          پس اسلو ها باید قبل پاسخ تاخیر بیشتری داشته باشن؟ دارم عملی امتحان میکنم .... یه پست دیگه هم زده بودم اول با پروتیوس امتحان کردم دیدم درس جواب نمیده اومدم عملی...
          اینکارا رو میکنم نمیشه....اطلاعات از مستر میره به اسلو و اسلو هم دریافت میکنه ... ولی اطلاعات بازگشت به مستر نمیرسه...زمان تکرار درخواست مسترم 2 ثانیه هست...
          من اوب re/de رو یک میکنم و 10 میلی وا میستم اطلاعات رو میفرستم پس از ارسال آخرین دیتا صفرش میکنم 10 میلی وا میستم...
          اشتباهه؟
          کد:
          interrupt [USART_TXC] void usart_tx_isr(void)
          {
          
           if (tx_counter)
           {
            --tx_counter;
            UDR=tx_buffer[tx_rd_index]; 
            // ModBus -- > if end command ModBus Go to Recive Mode
            if(useModBus & tx_buffer[tx_rd_index] == ';')
            { 
              delay_ms(10); 
              Read;      
            }  
            if (++tx_rd_index == TX_BUFFER_SIZE)
             tx_rd_index=0;
           }; 
          }
          من گفتم آخرین کاراکترم ; باشه و بعد 10 میلی re/de رو ضفر کنه (#define Read RٍE_DE = 0)

          دیدگاه


            #6
            پاسخ : مشکل در سوییچ بین RS485 re , de

            :angry: :angry: :angry:
            بابا دیوونه شدم :cry2: :cry2: :cry2:
            چرا وقتی فقط یکی ارسال میکنه و یکی دریافت درس کار میکنه ... ولی میخوام اتوماتیک سوییچ بشن رو ارسال و دریافت نمیشه :cry2:

            مستر ارسال >> اسلو دریافت >> پاسخ به مستر وتکرار...

            اسلو در یافت میکنه ولی اصلا اطلاعات رو نمیفرسته... با rs232 حداقل با یک مستر و اسلو مشکل نداشتم(اول که میخواستم فقط نرم افزار رو چک کنم)...وقتی دوتا اسلو میشدن خط tx بسته میشد . از یکی پرسیدم گفت توی rs485 درس کار میکنه...الانم که مشکل دارم توی سوییچ کردن ارسال و دریافت :angry:
            قرار داد کردم ; آخرین کاراکتر داده باشه و : شروع داده...
            کد:
            #define useModBus 1 
            #define DDR_RD_WR DDRD.7 
            #define RD_WR PORTD.7
            #define ModBus_Status PIND.7 
            
            #define FRAMING_ERROR (1<<FE)
            #define PARITY_ERROR (1<<PE)
            #define DATA_OVERRUN (1<<DOR)
            #define DATA_REGISTER_EMPTY (1<<UDRE)
            #define RX_COMPLETE (1<<RXC)
            
            #define Write RD_WR = 1
            #define Read RD_WR = 0 
            
            char ModBus_RX[100]; 
            char empty_100[100];
            int ModBus_HasData = 0;
            /*USART*/ 
            /* USART Receiver*/
            #define RX_BUFFER_SIZE 64
            char rx_buffer[RX_BUFFER_SIZE];
            #if RX_BUFFER_SIZE<256
            unsigned char rx_wr_index,rx_rd_index,rx_counter;
            #else
            unsigned int rx_wr_index,rx_rd_index,rx_counter;
            #endif
            
            // This flag is set on USART Receiver buffer overflow
            bit rx_buffer_overflow;
            
            // USART Receiver interrupt service routine
            interrupt [USART_RXC] void usart_rx_isr(void)
            {
             char status,data;
             status=UCSRA;
             data=UDR;
             if(useModBus)
              if(data==';')
                ModBus_HasData++;   
             if ((status & (FRAMING_ERROR | PARITY_ERROR |DATA_OVERRUN))==0)
             {
              rx_buffer[rx_wr_index]=data;
              if (++rx_wr_index == RX_BUFFER_SIZE)
               rx_wr_index=0;
              if (++rx_counter == RX_BUFFER_SIZE)
              {
               rx_counter=0;
               rx_buffer_overflow=1;
              };
             };
                
            }
            
            #ifndef _DEBUG_TERMINAL_IO_
            // Get a character from the USART Receiver buffer
            #define _ALTERNATE_GETCHAR_
            #pragma used+
            char getchar(void)
            {
             char data;
             while (rx_counter==0);
             data=rx_buffer[rx_rd_index];
             if (++rx_rd_index == RX_BUFFER_SIZE) rx_rd_index=0;
             #asm("cli")
             --rx_counter;
             #asm("sei")
             return data;
            }
            #pragma used-
            #endif
            
            /* USART Transmitter*/
            #define TX_BUFFER_SIZE 64
            char tx_buffer[TX_BUFFER_SIZE];
            #if TX_BUFFER_SIZE<256
            unsigned char tx_wr_index,tx_rd_index,tx_counter;
            #else
            unsigned int tx_wr_index,tx_rd_index,tx_counter;
            #endif
            
            // USART Transmitter interrupt service routine
            interrupt [USART_TXC] void usart_tx_isr(void)
            {
            
             if (tx_counter)
             {      
              //while ((UCSRA & DATA_REGISTER_EMPTY)==0);
              --tx_counter;
              UDR=tx_buffer[tx_rd_index];  
              // ModBus -- > if end command ModBus Go to Recive Mode
              if(useModBus & tx_buffer[tx_rd_index] == ';')
              {       
                while ((UCSRA & DATA_REGISTER_EMPTY)==0);
                delay_ms(10); 
                Read;      
              }  
              if (++tx_rd_index == TX_BUFFER_SIZE)
               tx_rd_index=0;
             }; 
            }
            
            
            
            #ifndef _DEBUG_TERMINAL_IO_
            #define _ALTERNATE_PUTSCHAR_
            #pragma used+
            void putschar(char *c)
            {
             while(*c)
             { 
              while (tx_counter == TX_BUFFER_SIZE);
              #asm("cli")
              if (tx_counter || ((UCSRA & DATA_REGISTER_EMPTY)==0))
              {
                tx_buffer[tx_wr_index]=*c;
                if (++tx_wr_index == TX_BUFFER_SIZE)
                tx_wr_index=0;
                ++tx_counter;
              }
              else
              {  
                UDR=*c;
              }
              c++;  
              #asm("sei") 
             }
            } 
            #pragma used-
            #endif

            دیدگاه


              #7
              پاسخ : مشکل در سوییچ بین RS485 re , de

              پیشنهاد میکنم بجای استفاده از این کد خودتون یک کد ساده بنویسید و ازش جواب بگیرید.
              بعد میتونید برید سراغ مواردی مثل بافر نرم افزاری و ...

              خلاصه اینکه RE/DE به جز در حد چند میکروثانیه ذاتاً تاخیر نمیخواد.
              دلیل اینکه میگن تاخیر بزارید اینه که چون ارسال داده روی uart از وقتی دستورش اجرا میشه تا وقتی که تمام داده از شیفت رجیستر uart خارج بشه کمی طول میکشه. شما هم میتونید تاخیر بزارید و هم بیت وضعیت خالی شدن شیفت رجیستر رو بررسی کنید.

              موفق باشید

              دیدگاه


                #8
                پاسخ : مشکل در سوییچ بین RS485 re , de

                نوشته اصلی توسط freedom_truth
                پیشنهاد میکنم بجای استفاده از این کد خودتون یک کد ساده بنویسید و ازش جواب بگیرید.
                بعد میتونید برید سراغ مواردی مثل بافر نرم افزاری و ...

                خلاصه اینکه RE/DE به جز در حد چند میکروثانیه ذاتاً تاخیر نمیخواد.
                دلیل اینکه میگن تاخیر بزارید اینه که چون ارسال داده روی uart از وقتی دستورش اجرا میشه تا وقتی که تمام داده از شیفت رجیستر uart خارج بشه کمی طول میکشه. شما هم میتونید تاخیر بزارید و هم بیت وضعیت خالی شدن شیفت رجیستر رو بررسی کنید.

                موفق باشید
                نمیدونم دقیقا مشکل کجا بود...ولی درس شد
                از همه ممنون،انقد سماجت کردم که راه افتاد
                واسه نرم افزار هم یک checksum درست کردم که اطلاعات اگه در راه نویز دار شد از طرف مستر رد بشه...

                دیدگاه

                لطفا صبر کنید...
                X