اطلاعیه

Collapse
No announcement yet.

وقفه خارجی در WinAVR

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

    وقفه خارجی در WinAVR

    سلام.

    بچه ها من یه برنامه با winavr واسه وقفه های خارجی نوشتم. (int0 and int1)

    اول برنامه رو ببینید:

    کد:
    #include <avr/io.h>//iom32.h
    #include <avr/interrupt.h>
    #include <avr/pgmspace.h>
    #include <avr/delay.h>
    
    #include "Global/global.h"
    
    ISR(INT0_vect)
    {
      PORTC |= (1<<PINC1);
    	
      _delay_ms(500);
      PORTC &= ~(1<<PINC1);//clear bit pc1
    } 
    
    ISR(INT1_vect)
    {
      PORTC |= (1<<PINC0);
    	
      _delay_ms(1000);
      PORTC &= ~(1<<PINC0);//clear bit pc0
    } 
    
    
    
    void main()
    {
    
    	DDRC = 0xff;
    	PORTC = 0;
    
    	
    	GICR &= ~(1<<INT0); //disable external interrup (int0)
    	GICR &= ~(1<<INT1); //disable external interrup (int1)
    	
    	
    	MCUCR &= (1<<ISC01)& ~(1<<ISC00); //falling edge of int0
    	MCUCR |= (1<<ISC11)|(1<<ISC10); //rising edge of int1
    	
    	//MCUCR &= (1<<ISC11)& ~(1<<ISC10); //rising edge of int1
    	
    	GICR |= (1<<INT0); //enable int0
      GICR |= (1<<INT1); //enable int1
    	
    	sei(); // Enable interrupt.
    	
    	for(;;)
    	{
    	}	
    }

    اینم شماتیکش:

    [img]http://www.*****upload.com/images/20196710319658593001.gif[/img]

    int0 رو بصورت falling و int1 هم بصورت rising تعریف کردم.

    وقتیکه مدار شروع به کار میکنه، led که واسه وقفه int1 گذاشتم، چند ثانیه روشن میمونه و بعدش خاموش میشه! چرا اینطوریه؟ درسته؟!

    int0 که بصورت falling هست، وقتیکه کلید را پایین فشار میدهم و نگه میدارم، تا زمانیکه کلید پایینه، leD مربوط به اون روشن میمونه و با رها کردن کلید خاموش میشه!

    int1 که به صورت rising هست، وقتیکه کلید رو پایین نگه میدارم led روشن میشه ولی بعد زا یه مدت خاموش میشه! در حالیکه کلید هنوز پایینه! اشکال کار از کجاست؟! :angry:

    ممنونم...

    http://ceworld.ir/images/ads/dornablogcom_ads.gif

    #2
    پاسخ : وقفه خارجی در WinAVR

    اول بگم احساس می کنم فرکانس رو درست معرفی نکردی!

    که به صورت rising هست، وقتیکه کلید رو پایین نگه میدارم led روشن میشه ولی بعد زا یه مدت خاموش میشه! در حالیکه کلید هنوز پایینه! اشکال کار از کجاست؟!
    اگه مدتی که می گی 1 ثانیه باشه درسته! کلید رو فشار می دی یه لبه بالا رونده ایجاد می کنی و وقفه اجرا میشه. تو وقفه هم که نوشتی led روشن بشه، 1 ثانیه تاخیر و led خاموش بشه. اگه این مدتی که می گی 1 ثانیه نیست مشکل از فرکانس و فیوزبیت....

    وقتیکه مدار شروع به کار میکنه، led که واسه وقفه int1 گذاشتم، چند ثانیه روشن میمونه و بعدش خاموش میشه! چرا اینطوریه؟ درسته؟!
    احتمالا بخاط اینه که با شروع مدار یه لبه بالا رونده رو int0 ایجاد میشه. (اگه فرض کنیم میکرو با سطح صفر رو پایه int0 شروع کنه)


    int0 که بصورت falling هست، وقتیکه کلید را پایین فشار میدهم و نگه میدارم، تا زمانیکه کلید پایینه، leD مربوط به اون روشن میمونه و با رها کردن کلید خاموش میشه!
    چقدر کلید رو پایین نگه میداری؟

    ضمنا بنظرم بهتر باشه از SIGNAL استفاده کنی تا ISR . تو کتابخونه extint از avrlib، از SIGNAL استفاده شده.
    تعریف لبه ها هم فکر کنم کامل نیست! یه نگاه می کنم ...
    https://www.linkedin.com/in/mohammadhosseini69

    http://zakhar.blog.ir

    دیدگاه


      #3
      پاسخ : وقفه خارجی در WinAVR

      نوشته اصلی توسط محمد حسینی
      اول بگم احساس می کنم فرکانس رو درست معرفی نکردی!
      والا مثل همیشه معرفی کردم!

      نوشته اصلی توسط محمد حسینی
      اگه مدتی که می گی 1 ثانیه باشه درسته! کلید رو فشار می دی یه لبه بالا رونده ایجاد می کنی و وقفه اجرا میشه. تو وقفه هم که نوشتی led روشن بشه، 1 ثانیه تاخیر و led خاموش بشه. اگه این مدتی که می گی 1 ثانیه نیست مشکل از فرکانس و فیوزبیت....
      احتمالا بخاط اینه که با شروع مدار یه لبه بالا رونده رو int0 ایجاد میشه. (اگه فرض کنیم میکرو با سطح صفر رو پایه int0 شروع کنه)
      درسته دستورات داخلش اجرا میشه، ولی چون تا زمانیکه کلید رو پایین نگه داشتم، لبه بالا هست، پس چرا باید led خاموش شه؟! مگه تا زمانیکه لبه بالا هست، مدام دستورات وقفه اجرا نمیشه؟!

      نوشته اصلی توسط محمد حسینی
      چقدر کلید رو پایین نگه میداری؟
      تو falling تا آخر عمرم هم کلید رو پایین نگه دارم، led روشن میمونه ولی تو rising نه!

      نوشته اصلی توسط محمد حسینی
      ضمنا بنظرم بهتر باشه از SIGNAL استفاده کنی تا ISR . تو کتابخونه extint از avrlib، از SIGNAL استفاده شده.
      تعریف لبه ها هم فکر کنم کامل نیست! یه نگاه می کنم ...
      فرقشون چیه؟!


      کد:
      	MCUCR &= (1<<ISC01)& ~(1<<ISC00); //falling edge of int0

      با این isc01 برابر 1 و isc00 برابر صفر هست واسه falling

      زمانی که هر دوی اینها صفر باشن، چه حالتی پیش میاد؟! توضیح انگلیسیش اینه ولی من نفهمیدم:
      the low level of int0 generates an interrupt request

      اینجا هم برنامه و فایل پروتوس رو واسه دانلود گذاشتم، اگه لطف کنی یه نگاه بهشون بندازی و اجراش ممنون میشم...
      http://www.4shared.com/file/zNrnwyRa...Interrupt.html
      http://ceworld.ir/images/ads/dornablogcom_ads.gif

      دیدگاه


        #4
        پاسخ : وقفه خارجی در WinAVR

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

        وضعیت آخری یعنی سطح صفر یعنی مادامی که سیگنال ورودی صفر باشه وقفه پشت سر هم تکرار میشه. چون سطح یعنی عدم تغییر وضعیت سیگنال.

        دیدگاه


          #5
          پاسخ : وقفه خارجی در WinAVR

          نوشته اصلی توسط reza_agha
          لبه فقط یکبار اونهم در هنگام تغییر سیگنال از صفر به یک و بالعکس پیش میاد. بنا بر این فشار دادن کلید و نگهداشتنش بفرض عدم وجود bounce فقط یکبار وقفه رو اجرا میکنه.

          وضعیت آخری یعنی سطح صفر یعنی مادامی که سیگنال ورودی صفر باشه وقفه پشت سر هم تکرار میشه. چون سطح یعنی عدم تغییر وضعیت سیگنال.
          خوب پس چرا سطح 1 باعث تکرار پشت سر هم وقفه نمیشه؟!
          http://ceworld.ir/images/ads/dornablogcom_ads.gif

          دیدگاه


            #6
            پاسخ : وقفه خارجی در WinAVR

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

            با این isc01 برابر 1 و isc00 برابر صفر هست واسه falling
            نه دیگه!! اشتباه کردی. هردوتاش صفر میشه. یعنی همونی که آقا رضا گفت!
            بیت ها رو جدا صفر و یک کن... چرا دردسر درست می کنی!


            لبه یعنی تغییر وضعیت. از صفر که بره به 1 ، یه لبه بالا رونده داریم. از 1 بره به صفر یه لبه پایین رونده داریم. پالس ساعت رو مجسم کن... تا زمانی که تغییر وضعیت نداشته باشیم، وقفه اجرا نمیشه.
            یه وقفه هم (که من الان شناختمش) برای سطح صفر تعریف شده که تا زمانی که رو سطخ صفر باشیم وقفه اجرا میشه. (همونی که شما به اشتباه تعریف کردی)
            https://www.linkedin.com/in/mohammadhosseini69

            http://zakhar.blog.ir

            دیدگاه


              #7
              پاسخ : وقفه خارجی در WinAVR

              نوشته اصلی توسط محمد حسینی
              چه جالب!! من تا حالا به این حالتش توجه نکرده بودم! از بس این لبه ها کاربرد دارن! اولین بار سطح صفر رو دیدم!!
              نه دیگه!! اشتباه کردی. هردوتاش صفر میشه. یعنی همونی که آقا رضا گفت!
              بیت ها رو جدا صفر و یک کن... چرا دردسر درست می کنی!


              لبه یعنی تغییر وضعیت. از صفر که بره به 1 ، یه لبه بالا رونده داریم. از 1 بره به صفر یه لبه پایین رونده داریم. پالس ساعت رو مجسم کن... تا زمانی که تغییر وضعیت نداشته باشیم، وقفه اجرا نمیشه.
              یه وقفه هم (که من الان شناختمش) برای سطح صفر تعریف شده که تا زمانی که رو سطخ صفر باشیم وقفه اجرا میشه. (همونی که شما به اشتباه تعریف کردی)
              پس MCUCR &= (1<<ISC01)& ~(1<<ISC00); //falling edge of int0 میشه همون the low level of int0 generates an interrupt request ؟؟؟؟

              http://ceworld.ir/images/ads/dornablogcom_ads.gif

              دیدگاه


                #8
                پاسخ : وقفه خارجی در WinAVR

                نوشته اصلی توسط behnam_kh2002
                پس MCUCR &= (1<<ISC01)& ~(1<<ISC00); //falling edge of int0 میشه همون the low level of int0 generates an interrupt request ؟؟؟؟

                نمی دونم!

                (1<<ISC01) = 00000010
                ~(1<<ISC00) = 11111110

                and که بشن میشه 00000010
                و در آخر این مقدار رو با رجیستر and کردی! ISC00 رو صفر میکنه ولی اگه بیت ISC01 صفر باشه که اینطوری 1 نمیشه! (اشتباه میگم!؟ نصف شب به خودم شک کردم! )
                https://www.linkedin.com/in/mohammadhosseini69

                http://zakhar.blog.ir

                دیدگاه


                  #9
                  پاسخ : پاسخ : وقفه خارجی در WinAVR

                  نوشته اصلی توسط محمد حسینی
                  نمی دونم!

                  (1<<ISC01) = 00000010
                  ~(1<<ISC00) = 11111110

                  and که بشن میشه 00000010
                  و در آخر این مقدار رو با رجیستر and کردی! ISC00 رو صفر میکنه ولی اگه بیت ISC01 صفر باشه که اینطوری 1 نمیشه! (اشتباه میگم!؟ نصف شب به خودم شک کردم! )
                  من الان مغزم قدرت and کردن 2 تا بیت هم نداره! یه ذره مغزم از تعطیلی در بیاد میشینم and میکنم!
                  http://ceworld.ir/images/ads/dornablogcom_ads.gif

                  دیدگاه


                    #10
                    پاسخ : وقفه خارجی در WinAVR

                    وقتیکه هر دو صفر باشن میشه: the low level of int0 generates an interrupt request

                    تو سه حالتش جواب داد جز 1 حالت! :angry:


                    اونم وقتی هست که
                    کد:
                    MCUCR |= (1<<ISC00); 
                    	MCUCR &= ~(1<<ISC01);

                    توضیحش میشه: هر تغییر منطقی روی intX یه درخواست وقفه ایجاد میکند! ولی هیچ تغییری ندیدم! چرا؟!
                    http://ceworld.ir/images/ads/dornablogcom_ads.gif

                    دیدگاه


                      #11
                      پاسخ : وقفه خارجی در WinAVR

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

                      دیدگاه

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