اطلاعیه

Collapse
No announcement yet.

اختلال ایجاد کردن USART بر روی کار وقفه خارجی و تایمر 1 .

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

    اختلال ایجاد کردن USART بر روی کار وقفه خارجی و تایمر 1 .

    سلام . من برای خواندن فرکانس یک سیگنال ، آن سیگنال را به پایه ورودی اینتراپت خارجی 1 میدهم. تایمر 1 را هم فعال کرده ام و با اندازه گیری فاصله زمانی بین دو سیگنال متوالی فرکانس ورودی را میخوانم.
    در حالت عادی مشکلی ندارم و کار درست انجام میشود. اما وقتی که از وقفه دریافت اطلاعات usart استفاده میکنم ، به صورت اتفاقی مقدار فرکانس خوانده شده پرش پیدا میکند. برای اطمینان، یک delay در حدود 2 میلی ثانیه در روتین وقفه usart نوشتم و دیدم که کلا مقدار فرکانس خوانده شده درب و داغون شد!
    سوال من این است که اصلا وقفه usart چی کاره است که بخواهد کار وقفه خارجی را مختل کند؟ چون طبق دیتاشیت مگا8 میدانیم که اولویت وقفه خارجی 0 از همه وقفه ها بیشتر است. و وقفه USART نباید تاثیری روی آن داشته باشد. همچنین این وقفه USART روی مقدار تایمر هم نباید تاثیری بگذارد؟ چون من از وقفه تایمر اصلا استفاده ای نکرده ام. مقدار تایمر در رویت وقفه خارجی هر بار ریست میشود.
    در عجبم چرا گذاشتن delay در وقفه USART دارد کارها را خراب میکند :cry2: اصلا با منطق جور در نمیاد. خواهشا اگه ممکنه کمک کنید. چند روزه معطل این قضیه هستم این هم بخشی از کدم:
    کد:
    // USART Receiver interrupt service routine
    interrupt [USART_RXC] void usart_rx_isr(void)
    {
    char status,data;
    status=UCSRA;
    data=UDR;
    
    //*************************************************
     
    if (recieve_mode==0 && data==0x0A)
        {
        recieve_mode=1;
        data_ok=1;
        }
    else if (recieve_mode==1 && data==0x0B)
        {
        recieve_mode=2;
        data_ok=1;
        }
    else if (recieve_mode==2)
        {
        a=data;
        recieve_mode=3;
        data_ok=1;
        }
    else if (recieve_mode==3)
        {
        b=data;
        recieve_mode=4;
        data_ok=1;
        }
    else if (recieve_mode==4)
        {
        c=data;
        recieve_mode=5;
        data_ok=1;
        }
    
    else if (recieve_mode==5 && data==0x0E)
        {
    
        recieve_mode=6;
        data_ok=1;
        }
    else if (recieve_mode==6 && data==0x0F)
        {
        data_ok=1;   //This flag means that the recieved data is in correct format 
        recieve_mode=0;
        }
        if (data_ok==1)
        data_ok=0;   // this command means that if recieved data is not in correct format mode=0. So the cycle will be terminated.
        else
        recieve_mode=0;
        
    //*************************************************
    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;
       };
      };
      
    }
    
    //****************************************************************************8
    
    // External Interrupt 0 service routine
    interrupt [EXT_INT0] void ext_int0_isr(void)
        {
        //komaki2=komaki3*timer_over_flow;
        timer_value=TCNT1;
        array[komaki2]=timer_value;
        TCNT1=0;
        komaki2++;
        if (timer_value<1428 && timer_over_flow==0)           // f>700
            flag=1;
        else if (timer_value<2000 && timer_over_flow==0)        // f>500
            flag=2;
        else if (timer_value<50000 && timer_over_flow==0)        // f>100
            flag=3;
        else
            flag=4;        
        timer_over_flow=0;
        
        if (komaki2>50)
        komaki2=0;
        }
    //************************************************************************
    دلا خوبـــان دل خونيــــن پســـندند
    دلا خون شو که خوبان اين پسندند
    متاع کفر و دين بيآ‌مشتري نيست
    گروهــــي آن گروهي اين پســـندند

    #2
    پاسخ : اختلال ایجاد کردن USART بر روی کار وقفه خارجی و تایمر 1 .

    با سلام
    منظورتون رو از اینکه فرمودین فرکانس درب و داغون میشه نفهمیدم .ولی ببینید اگه از وقفه 0 برای تشخیص سطح موج ورودی استفاده میکنید ووقفه usart هم فعال هست درست است که اولویت وقفه 0 از همه وقفه ها بالاتر است ولی اگر همزمان هر دو وقفه اتفاق بیافته بعد از پایان وقفه 0 وقفه usart اجرا خواهد شد و اگر در این حین(اجرای روتین وقفه usart)
    یک دوره تناوب اتفاق بیافتد میکرو مقدار درست تایم رو از دست خواهد داد ومقدار ناصحیح را به نمایش خواهد گذاشت.
    من راه حلی که پیشنهاد میکنم اینه که در برنامه وقفه usart تایمری که مربوط به اندازه گیری فرکانس شده رو صفر کنید و بعد از پایان اجرای وقفه کار رصد سیگنال ورودی رو از نو انجام بدین .
    یا اینکه تو برنامه usart وقفه 0 رو فعال کنید .که اینو مطمین نیستم جواب بده .تست کردی اگه جواب داد ممنون میشیم فیدبک بذارین.موفق باشین.

    دیدگاه


      #3
      پاسخ : اختلال ایجاد کردن USART بر روی کار وقفه خارجی و تایمر 1 .

      سلام دادا.
      چیز زیاد عجیب و غریبی هم نیست! :mrgreen:
      مشکل رو درست فهمیدی. تداخل وقفه ها. که این از ضعف های AVR هه. یه سرچ با همین عنوان می زدی کلی در موردش بحث شده.
      با یه نگاه به برنامه می شه به نکاتی رو فهمید.
      اول اینکه روتین وقفه رو تا جای ممکن کم کن. مثلاً برا وقفه سریال نیاز نیست توی روتین پردازش کنی. تو همون while میشه پردازشش کرد.
      برا یافتن فرکانس و ... هم میشه از مد کپچر تایمر ها استفاده کرد که بسیار دقیقتر هم هست.
      اگه باز هم نیاز به وقفه خارجی بود حتماً از تغییر سطح استفاده کن نه تغییر لبه.
      در ضمن در زمان وقوع وقفه سریال میکرو به طور خودکار تمام وقفه ها رو غیر فعال می کنه. میشه دستی دوباره فعالش کرد.
      راستی بادریت هم تا جای ممکن ماکزیمم کن.
      تشکر لازم نیست!

      دیدگاه


        #4
        پاسخ : اختلال ایجاد کردن USART بر روی کار وقفه خارجی و تایمر 1 .

        نوشته اصلی توسط iman-63
        مشکل رو درست فهمیدی. تداخل وقفه ها. که این از ضعف های AVR هه.
        با تشکر از راهنماییتون دوست عزیز. چرا مشکل AVR؟ مگه بقیه میکرو ها این ایرادو ندارند؟ حدس من این است که علت این فرمایش شما این است که اولویت وقفه ها را در AVR نمیشه جابجا کرد . اگه اشتباه فهمیدم بفرمایید.
        نوشته اصلی توسط iman-63
        اول اینکه روتین وقفه رو تا جای ممکن کم کن. مثلاً برا وقفه سریال نیاز نیست توی روتین پردازش کنی. تو همون while میشه پردازشش کرد.
        علت اینکه اون برنامه را نبرد داخل while این بود که با خودم گفتم اگه مثلا هنگام اجرای while هی بخواهد بپرد این ور اون ور توی وقفه های مختلف ممکن است نتونه به ازای دو بار اجرای متوالی وقفه usart کامل کارهای مرتبطش را انجام بده. ولی وقتی توی روتین وقفه نوشته بشه، مطمئن میشیم که این دستورات با اولویت و سرعت بیشتری نسبت به سایر برنامه های while اجرا میشه. البته من یه سوال دیگه هم داشتم.
        من در اصل میخوام 3 بایت اطلاعات را با usart بفرستم. حالا برای اینکه ترتیب این سه بایت درست رعایت بشه و قر و قاطی نشه ( مثلا بایت اول مربوط به ولتاژ یک نقطه است و بایت دوم مثلا دما و بایت سوم جریان) از چند بایت آدرس استفاده کردم. به این معنی که اول دو بایت آدرس 0x0A و 0x0B میفرستد. وقتی این دو بایت را دید فرض میکند که سه بایت بعدی به ترتیب بایتهای اول و دوم و سوم هستند. بعد از این سه بایت هم دو بایت آدرس 0x0F و 0x0E گذاشتم . وقتی این دو تا بایت را هم ببیند دیگه مطمئن میشه که ترتیب داده ها درست بوده .
        سوال من اینه که آیا واقعا این همه دنگ و فنگ لازم است ؟ اگه اینطوری باشه برای هر تعداد بایت باید یک عالمه آدرس هم باهاشون فرستاده بشه که ترتیبشون در گیرنده قابل شناسایی باشه. کسی پیشنهاد بهتری اگه داشته باشه و راهنمایی کنه ممنون میشم.
        نوشته اصلی توسط iman-63
        اگه باز هم نیاز به وقفه خارجی بود حتماً از تغییر سطح استفاده کن نه تغییر لبه.
        میشه یک کم در مورد علت این فرمایشتون توضیح بدهید؟
        نوشته اصلی توسط iman-63
        راستی بادریت هم تا جای ممکن ماکزیمم کن.
        تا جایی که من مطالعه کردم باید از مقاومتهای termination در خطوط RS485 استفاده بشود که موج برگشتی را حذف کند. حالا برای محاسبه مقدار این مقاومت های ترمینشین باید مشخصه امپدانسی کابل را داشته باشیم. من هم که این مشخصه را ندارم و بلد هم نیستم که دقیقا چطوری باید این مشخصه را بدست بیاوریم. برای همین باد ریت را تا حد ممکن کم کردم . چون در باد ریت های کمتر ( به دلیلی که برام روشن نیست) این موجهای برگشتی کوچکتر و قابل اغماض تر میشود. در ضمن هر چقدر باد ریت بیشتر باشه این میکرو بدبخت هی باید تند تند برود توی روتین وقفه یوزآرت . بیچاره بهش فشار بیشتری میاد که؟ :surprised:
        میگم این میکرو ها اگه چند تا کار همزمان ازشون بخواهیم دیگه خسته میشن و زیر سبیلی رد میکنند. مثل کسی که بهش بگیم برو نون بخر. وقتی رفته نون بخره یکهو خونه آتیش میگیره. تا میاد آتیش خونه را خاموش کنه مثلا یک کار دیگه یه جای دیگه پیش میاد. تا میره اونو انجام بده زنگ میزنن موبایلش میگن مثلا زود بیا حال بابات بد شده ... بالاخره هر چقدر هم فرز باشه نمیتونه به همه کارها برسه
        دلا خوبـــان دل خونيــــن پســـندند
        دلا خون شو که خوبان اين پسندند
        متاع کفر و دين بيآ‌مشتري نيست
        گروهــــي آن گروهي اين پســـندند

        دیدگاه


          #5
          پاسخ : اختلال ایجاد کردن USART بر روی کار وقفه خارجی و تایمر 1 .

          سلام دادا.
          ببخشید اگه دیر جواب میدم. این روزا گرفتارم شدید.
          با تشکر از راهنماییتون دوست عزیز. چرا مشکل AVR؟ مگه بقیه میکرو ها این ایرادو ندارند؟ حدس من این است که علت این فرمایش شما این است که اولویت وقفه ها را در AVR نمیشه جابجا کرد . اگه اشتباه فهمیدم بفرمایید.
          دقیقاً. :applause:
          نگفتم درست فهمیدی!!!

          علت اینکه اون برنامه را نبرد داخل while این بود که با خودم گفتم اگه مثلا هنگام اجرای while هی بخواهد بپرد این ور اون ور توی وقفه های مختلف ممکن است نتونه به ازای دو بار اجرای متوالی وقفه usart کامل کارهای مرتبطش را انجام بده. ولی وقتی توی روتین وقفه نوشته بشه، مطمئن میشیم که این دستورات با اولویت و سرعت بیشتری نسبت به سایر برنامه های while اجرا میشه
          میکرو کارش پریدن اینطرفو اون طرفه! نگران نباش

          من در اصل میخوام 3 بایت اطلاعات را با usart بفرستم. حالا برای اینکه ترتیب این سه بایت درست رعایت بشه و قر و قاطی نشه ( مثلا بایت اول مربوط به ولتاژ یک نقطه است و بایت دوم مثلا دما و بایت سوم جریان) از چند بایت آدرس استفاده کردم. به این معنی که اول دو بایت آدرس 0x0A و 0x0B میفرستد. وقتی این دو بایت را دید فرض میکند که سه بایت بعدی به ترتیب بایتهای اول و دوم و سوم هستند. بعد از این سه بایت هم دو بایت آدرس 0x0F و 0x0E گذاشتم . وقتی این دو تا بایت را هم ببیند دیگه مطمئن میشه که ترتیب داده ها درست بوده .
          سوال من اینه که آیا واقعا این همه دنگ و فنگ لازم است ؟ اگه اینطوری باشه برای هر تعداد بایت باید یک عالمه آدرس هم باهاشون فرستاده بشه که ترتیبشون در گیرنده قابل شناسایی باشه. کسی پیشنهاد بهتری اگه داشته باشه و راهنمایی کنه ممنون میشم.
          یه پروژه داشتم که 8 بایت رو باید با سریال ارسال میکردم.
          همین مشکلو داشتم. اما بناچار این راهو رفتم. متاسفانه این تنها راهه!
          یعنی شمارنده کانتر آرایه سریال رو باید بدونی که کی باید صفر بشه. بهترین کار هم همینه. ارسال یه کد مثل "#" یا یه " " یا حتی اینتر. بهتره از دو یا یه کارکتور استفاده کنی تا خطای تشخیص کمتر شه. نگران شلوغی و سرعت نباش. اینقدرا هم خدا زده نیست این AVR مادر مرده.
          اما از وقتی با can bus و pic کار میکنم دیگه این مشکلاتو ندارم. برا ارتباطات هیچ چیز مناسبتر از can نیس.

          اگه باز هم نیاز به وقفه خارجی بود حتماً از تغییر سطح استفاده کن نه تغییر لبه.
          توی تنظیمات فعال سازی وقفه خارجی، چند مد رو میتونی انتخاب کنی. برا تشخیص پالس بهتره از مد سطح (از پایین به بالا و یا از بالا په پایین) استفاده شه تا مد تشخیص سطح.
          راستی چرا از کپچر تایمرها استفاده نمیکنی.

          تا جایی که من مطالعه کردم باید از مقاومتهای termination در خطوط RS485 استفاده بشود که موج برگشتی را حذف کند. حالا برای محاسبه مقدار این مقاومت های ترمینشین باید مشخصه امپدانسی کابل را داشته باشیم. من هم که این مشخصه را ندارم و بلد هم نیستم که دقیقا چطوری باید این مشخصه را بدست بیاوریم. برای همین باد ریت را تا حد ممکن کم کردم . چون در باد ریت های کمتر ( به دلیلی که برام روشن نیست) این موجهای برگشتی کوچکتر و قابل اغماض تر میشود. در ضمن هر چقدر باد ریت بیشتر باشه این میکرو بدبخت هی باید تند تند برود توی روتین وقفه یوزآرت . بیچاره بهش فشار بیشتری میاد که؟
          طول کابلت چند متره؟
          معمولاً در 485 از کابل های معمولی استفاده میشه. کابل زوج بسیار مناسبه. مقاومت این کابل ها معمولاً 120 اهمه.
          تا جایی که من تا حالا کار کردم، ابتدا و انتهای خط ارتباطی یه مقاومت 120 اهم گذاشتم. بادریت رو هم 115200 گذاشتم. مشکلی هم تا حالا نبوده.
          اینقدر نگران میکرو نباش. یه کریستال 11.0592 بذار. با یه حساب 2 *2 تا میشه فهمید که کلی داری بهش حال میدی.
          این میکرو ها اگه چند تا کار همزمان ازشون بخواهیم دیگه خسته میشن و زیر سبیلی رد میکنند. مثل کسی که بهش بگیم برو نون بخر. وقتی رفته نون بخره یکهو خونه آتیش میگیره. تا میاد آتیش خونه را خاموش کنه مثلا یک کار دیگه یه جای دیگه پیش میاد. تا میره اونو انجام بده زنگ میزنن موبایلش میگن مثلا زود بیا حال بابات بد شده ... بالاخره هر چقدر هم فرز باشه نمیتونه به همه کارها برسه
          هنر برنامه نویس اینجاس دیگه!.
          تشکر لازم نیست!

          دیدگاه


            #6
            پاسخ : اختلال ایجاد کردن USART بر روی کار وقفه خارجی و تایمر 1 .

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

            دیدگاه


              #7
              پاسخ : اختلال ایجاد کردن USART بر روی کار وقفه خارجی و تایمر 1 .

              نباید بادریت آن با وقفه و تایمر یکی بشه
              باد می وزد ...
              میتوانی در مقابلش هم دیوار بسازی ، هم آسیاب بادی
              تصمیم با تو است ...

              دیدگاه

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