اطلاعیه

Collapse
No announcement yet.

مشکل در برگشتن مجدد به روال وقفه در AIC

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

    مشکل در برگشتن مجدد به روال وقفه در AIC

    سلام عرض میشه
    توی این برنامه که AIC فعال شده و PA20 به عنوان وقفه خروجی تعیین شده، وقتی که PA20 تحریک شد، می ره و روال وقفه رو بدرستی اجرا می کنه و بعدش میره دنبال بقیه برنامه. اما وقتی که دوباره PA20 تحریک شد، دیگه نمیره تو روال وقفه!
    توی تایمر هم همین طور بود که وقتی یکبار سرریز می شد، برای بار دوم نمی رفت وقفه رو انجام بده.

    کد:
    #include <at91sam7s64.h>
    #include <delay.h>
    #include <pio.h>
    
    
    __irq void IRQ0_handler(void)
    {
    porta_set=0x1;
    delay_ms(900);
    porta_rset=0x1;
    delay_ms(900);
    
    }
    
    int main()
    {
    porta_output=0x3;
    
    AT91C_BASE_PMC->PMC_PCER = ( 1<<AT91C_ID_PIOA ); // AT91C_ID_PIOA=2
    
    AT91C_BASE_PIOA->PIO_PER=(1<<0);
    AT91C_BASE_PIOA->PIO_OER=(1<<0);
    AT91C_BASE_PIOA->PIO_PDR = (1<<20);
    AT91C_BASE_PIOA->PIO_MDER = (1<<20);
    AT91C_BASE_PIOA->PIO_BSR = (1<<20);
    
    
    AT91C_BASE_AIC->AIC_SVR[AT91C_ID_IRQ0] = (unsigned int) IRQ0_handler;
    AT91C_BASE_AIC->AIC_SMR[AT91C_ID_IRQ0] = 0x12;
    AT91C_BASE_AIC->AIC_ICCR = (1<<AT91C_ID_IRQ0);
    AT91C_BASE_AIC->AIC_IECR = (1<<AT91C_ID_IRQ0);
    
    while (1)
    {
    	porta_set=0x2;
    	delay_ms(200);
    	porta_rset=0x2;
    	delay_ms(200);
    
    }
    
    }

    #2
    پاسخ : مشکل در برگشتن مجدد به روال وقفه در AIC

    فکر کنم مشکل از پس از تموم شدن زیر روال وقفه رجیستر AIC_EOICR رو مقدار دهی نکردین.
    End of Interrupt Command Register مشخص میکنه که زیر روال اینتراپت تموم شده و AIC میتونه یه اینتراپت دیگه قبول کنه.

    آخر زیر برنامه اینتراپت این سطر رو اضافه کنین :
    کد:
    *AT91C_AIC_EOICR = 0;

    دیدگاه


      #3
      پاسخ : مشکل در برگشتن مجدد به روال وقفه در AIC

      حق با شماست ولی موقعی که در تایمر این خط رو به برنامه اضافه کردم همین که وقفه سرریزی تایمر تحریک شد برنامه به داخل روال وقفه وارد می شه و مثل یک حلقه بی پایان روال وقفه رو اجرا می کنه و دیگه برنمی گرده به برنامه اصلی! :sad:
      ولی با اینتراپت خارجی درست کار می کنه و بعد از اجرای روال وقفه به برنامه اصلی برمی گرده و مشکل برگشتن مجدد هم نداره. قضیه چیه؟!

      دیدگاه


        #4
        پاسخ : مشکل در برگشتن مجدد به روال وقفه در AIC

        با کدوم تایمر مشکل دارین ؟

        مثل این اینتراپت کد راه اندازی تایمر و ISR رو بزارین ببینیم مشکل از کجاشه .

        دیدگاه


          #5
          پاسخ : مشکل در برگشتن مجدد به روال وقفه در AIC

          برنامه این هست:
          کد:
          #include <at91sam7s64.h>
          #include <delay.h>
          #include <pio.h>
          
          
          __irq void TC0_handler(void)
          {
          
          porta_set=0x1;
          delay_ms(500);
          porta_rst=0x1;
          delay_ms(500);
          
          *AT91C_AIC_EOICR=0x1;
          
          }
          
          int main()
          {
          
          
          porta_output=0x3;			  
                                     
          *AT91C_PMC_PCER= (1<<AT91C_ID_TC0);
          *AT91C_TC0_CMR=0x4004;
          *AT91C_TC0_CCR=0x5;
          *AT91C_TC0_IER=(1<<0); 
          
          AT91C_BASE_AIC->AIC_SVR[AT91C_ID_TC0] = (unsigned int) TC0_handler;
          AT91C_BASE_AIC->AIC_SMR[AT91C_ID_TC0] = 0x40;
          AT91C_BASE_AIC->AIC_ISCR = (1<<AT91C_ID_TC0);
          AT91C_BASE_AIC->AIC_IECR = (1<<AT91C_ID_TC0);
          	
          while (1)
          {
          porta_set=0x2;
          delay_ms(200);
          porta_rst=0x2;
          delay_ms(200);
          
          }
          }

          وقتی که وارد ISR میشه دیگه یادش میره که باید برگرده به همون جایی که بوده. و دائم ISR رو مثل یک حلقه بینهایت اجرا می کنه

          دیدگاه


            #6
            پاسخ : مشکل در برگشتن مجدد به روال وقفه در AIC

            مهندس آخه کی توی اینتراپت از delay استفاده میکنه اونم نه یزه بلکه تقریبا 1 ثانیه!!!
            ببین رجیستری هست که interrupt رو ACK کنه!

            دیدگاه


              #7
              پاسخ : مشکل در برگشتن مجدد به روال وقفه در AIC

              منظورتون رو نفهمیدم که چرا از delay استفاده نکنم. ضمنا این یک برنامه نمومه هست. حتی اگه از delay هم استفاده نکردم باز هم مشکل سر جاش بود.

              بین رجیستری هست که interrupt رو ACK کنه!
              همچین رجیستری ندیدم. رجیسترها مربوط به تنظیمات هستند.

              دیدگاه


                #8
                پاسخ : مشکل در برگشتن مجدد به روال وقفه در AIC

                دوستانی هم که مثل من به همچین مشکلی برخوردند بهشون بگم که متوجه شدم که ایراد از کجا بود:
                باید در پایان روال وقفه، علاوه بر
                کد:
                *AT91C_AIC_EOICR=0x1;
                ، عبارت
                کد:
                a= *AT91C_TC0_SR;
                رو هم اضافه می کردم. :bye

                دیدگاه

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