اطلاعیه

Collapse
No announcement yet.

external interrupt

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

    external interrupt

    سلام دوستان

    در برنامه ای قصد دارم پالس های ورودی را به وسیله اینتراپت خارجی بخونم و وقتی به تعداد معینی رسید، وضعیت یک پین toggle بشه. اما برنامه در حال زیر جواب نمیده.

    کد:
    unsigned int count=0;
    
    ISR(PORTB_INT0_vect)
    {
    	count++;	
    }
    
    int main(void)
    {
    	// External interrupt 0 on PB0, enable pullup, sence Rising edge
    	PORTB.PIN2CTRL = PORT_ISC_RISING_gc | PORT_SRLEN_bm;
    	PORTB.INT0MASK = PIN2_bm;
    	//PORTD.INT1MASK = PIN2_bm;
    	PORTB.INTCTRL = PORT_INT0LVL0_bm;
    
    	// Enable low level interrupts
    	PMIC.CTRL |= PMIC_LOLVLEN_bm;
    	sei();
    	PORTC.DIR = 0x3F;
    	
      while(1)
      {
    		if (count == 50)
    		{
    			count =0;
    			PORTC.OUTTGL = 1<<0;	
    		}
     }
    }
    اما جالبه زمانی که چک کردن متغییر count را به داخل روتین وقفه انتقال میدم همه چیز درسته و برنامه زیر درست کار میکنه

    کد:
    ISR(PORTB_INT0_vect)
    {
    	count++;
    	if (count == 50)
    	{
    		count =0;
    		PORTC.OUTTGL = 1<<0;
    	}
    }
    در دو نمونه الگوریتم یکیه. اما نمیدونم توی حالت اول مشکل از کجاست. متغییر count هم به صورت سراسری تعریف شده.
    ممنون میشم راهنماییم کنید.
    گفت که دیوانه نهی لایق این خانه نهی

    #2
    پاسخ : external interrupt

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

    دیدگاه


      #3
      پاسخ : external interrupt

      بینهایت ممنون.
      میتونید بگید چرا در حالت قبل مشکل داشت در صورتی که متغییر از نوع سراسری بود؟
      و اینکه با اضافه کردن volatile چه تغییری انجام میشه؟
      گفت که دیوانه نهی لایق این خانه نهی

      دیدگاه


        #4
        پاسخ : external interrupt

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

        در لینک [TUT][C]Optimization and the importance of volatile in GCC در این باره به طور مفصل توضیح داده شده.
        گاهی افرادی به موفقیت های بزرگ می رسند، تنها به این دلیل ساده که نمی دانند کاری که به آن دست زده اند بسیار دشوار، بلکه غیر ممکن است.

        دیدگاه

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