اطلاعیه

Collapse
No announcement yet.

Pulse width capture

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

    Pulse width capture

    دوستان سلام.
    پروژه ای هست که نیاز دارم عرض پالس رو درش اندازه بگیرم در حقیقت میخوام میزان توانی که به دستگاه منتقل میشه رو اندازه بگیرم(عرض پالس مثبت)
    میکروکنترلر ATXmega32A4AU هست.
    کدهایی که در اینترنت در این زمینه هست رو اغلبش رو بررسی کردم. کد رو به صورت زیر نوشتم:
    کد:
      //------------ Pulse width capture pin config
      PORT_SetPinAsInput(&PORTC,PIN0_bp);	
    
      PORT_ConfigurePins(&PORTC,PIN0_bm,
    		  false,
     		  false,
    		  PORT_OPC_TOTEM_gc,
    		  PORT_ISC_BOTHEDGES_gc);
    EVSYS_SetEventSource(0,EVSYS_CHMUX_PORTC_PIN0_gc);
    
    
      //-------- Pulse width capture
        TC_SetPeriod(&TCC0,0xffff);// 0x04e2 => 10 ms
    	TC0_ConfigInputCapture(&TCC0,TC_EVACT_PW_gc | TC_EVSEL_CH0_gc);
    	TC0_EnableCCChannels(&TCC0,TC0_CCAEN_bm);        
    	TC0_SetCCAIntLevel(&TCC0,TC_CCAINTLVL_MED_gc);    
        TC0_ConfigClockSource( &TCC0, TC_CLKSEL_DIV1_gc);
    
    ISR(TCC0_CCA_vect)
    {
      PWMWidth=0;
      PWMWidth =TC_GetCaptureA( &TCC0 ); // read position
      Flags.LCDSHW=1;    
    	//  TCD0.CNT=0; // reset count
    }

    کد سه قسمت داره، یکی تنظیمات پورت و تظیمات event system، تنظیمات تایمر و آخری هم که تابع وقفه هست.
    مشکل اینه که بدون اینکه سیگنالی اعمال بشه (حالت بدون سیگنال سطح ولتاژ 1 هست(3.3V) ) برنامه دائم میره داخل وقفه.
    پورت رو به صورت جداگانه بررسی کردم و وقفه خارجی اون رو فعال کردم به درستی کار میکنه.
    حتی زمانی که قسمت زیر از کد رو هم غیر فعال میکنم باز زیر روال وقفه اجرا میشه:
    کد:
    EVSYS_SetEventSource(0,EVSYS_CHMUX_PORTC_PIN0_gc);
    ممنون میشم اگه کسی از دوستان تجربه ای در این زمینه داره به اشتراک بذاره.
    سپاس فراوان
    شأن انسان در ايمان و هجرت و جهاد است و هجرت، مقدمهآ‌ي جهاد فيآ‌سبيلآ‌الله.
    هجرت، هجرت از سنگينيآ‌هاست و جاذبهآ‌هايي كه تو را به خاك ميآ‌چسباند.
    چكمهآ‌هايت را بپوش، رهآ‌توشهآ‌ات را بردار و هجرت كن.

    #2
    پاسخ : Pulse width capture

    با تنظیم انجام شده، ورودی در وضعیت Float است که در صورت متصل نبودن به جایی می تواند وقفه های ناخواسته ایجاد کند.
    اوژن: به معنای افکننده و شکست دهنده است
    دانایی، توانایی است-Knowledge is POWER
    برای حرفه ای شدن در الکترونیک باید با آن زندگی کرد
    وضعمان بهتر می شود، اگر همه نسبت به جامعه و اطراف خود مسوول باشیم و نگوئیم به ما چه
    قوی شدن و خوب ماندن - خوبی کردن به دیگران یک لذت ماندگار است
    اگر قرار باشد نفت و منابع خام را بدهیم و چرخ بگیریم، بهتر است چرخ را از نو اختراع کنیم
    ساعت کار بدن اکثر انسان ها کمتر از 800000 ساعت است و بعد از آن از کار می افتد

    دیدگاه


      #3
      پاسخ : Pulse width capture

      سلام.
      پایه از طریق مقاومت 220 اهم همواره متصل به 3.3 ولت است.
      آزمایش جدیدی انجام دادم و تنظیمات تایمر رو از Pulse width capture به input capture تغییر دادم و به درستی کار کرد. یعنی تا زمانی که پالسی اعمال نمی شد میکرو وقفه را اجرا نمیکرد و با اعمال پالس وارد وقفه می شد.
      یان قطعه کد با تنظیمات فعلی درست هست؟ روند اجرا به همین صورته؟
      علت وقفه این نیست که مثلا در زمان روشن شدن پالسی رو دریافت میکنه بعد چون لبه پایین رونده رو نمیبینه تایمر سر ریز میکنه و وقفه CCA اجرا میشه؟
      البته من قبل اینکه شرط وقفه رو اجرا کنم یه بار CCA رو میخونم تا اگه احیانا پرچم وقفه اون فعال هست پاک بشه.
      با سپاس
      شأن انسان در ايمان و هجرت و جهاد است و هجرت، مقدمهآ‌ي جهاد فيآ‌سبيلآ‌الله.
      هجرت، هجرت از سنگينيآ‌هاست و جاذبهآ‌هايي كه تو را به خاك ميآ‌چسباند.
      چكمهآ‌هايت را بپوش، رهآ‌توشهآ‌ات را بردار و هجرت كن.

      دیدگاه


        #4
        پاسخ : Pulse width capture

        برای تنظیم مد Pulse width capture شما از تابع TC0_ConfigInputCapture استفاده کرده اید. در حالیکه اگر به جزئیات این تابع مراجعه کنید:

        کد:
        void TC0_ConfigInputCapture( volatile TC0_t * tc, TC_EVSEL_t eventSource )
        {
        	tc->CTRLD = ( tc->CTRLD & ~( TC0_EVSEL_gm | TC0_EVACT_gm ) ) |
        	      eventSource |
        	      TC_EVACT_CAPT_gc;
        }


        قابل مشاهده است که این تابع به دلیل OR کردن با TC_EVACT_CAPT_gc، فقط برای تنظیم مد Input capture نوشته شده است. بنابراین با مقداری که شما قرار داده اید، در سه بیت با ارزش بالاتر یا همان بیت های EVACT مقدار 111 قرار می گیرد که یک حالت رزرو شده است. پس در این وضعیت با توجه به فعال بودن تایمر و Enable بودن CCA بصورت مداوم وقفه Compare (بجای Capture) اتفاق می افتد.
        برای اصلاح این وضعیت به رجیستر CTRLD بصورت مستقیم مقداردهی کنید.
        اوژن: به معنای افکننده و شکست دهنده است
        دانایی، توانایی است-Knowledge is POWER
        برای حرفه ای شدن در الکترونیک باید با آن زندگی کرد
        وضعمان بهتر می شود، اگر همه نسبت به جامعه و اطراف خود مسوول باشیم و نگوئیم به ما چه
        قوی شدن و خوب ماندن - خوبی کردن به دیگران یک لذت ماندگار است
        اگر قرار باشد نفت و منابع خام را بدهیم و چرخ بگیریم، بهتر است چرخ را از نو اختراع کنیم
        ساعت کار بدن اکثر انسان ها کمتر از 800000 ساعت است و بعد از آن از کار می افتد

        دیدگاه


          #5
          پاسخ : Pulse width capture

          سلام.
          سپاس فراوان از وقتی که گذاشتید و دقت نظری که کردید.
          به نظرتون این ایراد کتابخونه نیست؟ چون سه مد capture تعریف شده
          کد:
          	TC_EVACT_OFF_gc = (0x00<<5),	///< No Event Action
          	TC_EVACT_CAPT_gc = (0x01<<5),	///< Input Capture
          	TC_EVACT_UPDOWN_gc = (0x02<<5),	///< Externally Controlled Up/Down Count
          	TC_EVACT_QDEC_gc = (0x03<<5),	///< Quadrature Decode
          	TC_EVACT_RESTART_gc = (0x04<<5),	///< Restart
          	TC_EVACT_FRQ_gc = (0x05<<5),	///< Frequency Capture
          	TC_EVACT_PW_gc = (0x06<<5),	///< Pulse-width Capture
          چه دلیلی داره که این تابع منحصر به یکی از حالات بشه؟
          اگه این تابع به صورت زیر تعریف شده بود چه مشکلی ایجاد میشد؟
          کد:
          void TC0_ConfigInputCapture( volatile TC0_t * tc, TC_EVSEL_t eventSource , TC_EVACT_t evectAction)
          {
          	tc->CTRLD = ( tc->CTRLD & ~( TC0_EVSEL_gm | TC0_EVACT_gm ) ) |
          	(eventSource |	evectAction);
          }

          سپاس فراوان
          شأن انسان در ايمان و هجرت و جهاد است و هجرت، مقدمهآ‌ي جهاد فيآ‌سبيلآ‌الله.
          هجرت، هجرت از سنگينيآ‌هاست و جاذبهآ‌هايي كه تو را به خاك ميآ‌چسباند.
          چكمهآ‌هايت را بپوش، رهآ‌توشهآ‌ات را بردار و هجرت كن.

          دیدگاه


            #6
            پاسخ : Pulse width capture

            تابع نوشته شده فقط برای تنظیم مد input capture نوشته شده است و برای یک تابع کلی تر (که جای آن در کتابخانه خالی است) همان شکلی که شما نوشته اید، صحیح است. اما برای حالت کلی تر به جای نام ConfigInputCapture شاید نامگذاری مانند ConfigEventAction یا شبیه آن مناسب تر باشد.
            اوژن: به معنای افکننده و شکست دهنده است
            دانایی، توانایی است-Knowledge is POWER
            برای حرفه ای شدن در الکترونیک باید با آن زندگی کرد
            وضعمان بهتر می شود، اگر همه نسبت به جامعه و اطراف خود مسوول باشیم و نگوئیم به ما چه
            قوی شدن و خوب ماندن - خوبی کردن به دیگران یک لذت ماندگار است
            اگر قرار باشد نفت و منابع خام را بدهیم و چرخ بگیریم، بهتر است چرخ را از نو اختراع کنیم
            ساعت کار بدن اکثر انسان ها کمتر از 800000 ساعت است و بعد از آن از کار می افتد

            دیدگاه


              #7
              پاسخ : Pulse width capture

              سلام.
              قصدم از این پست آخر جمع بندی پست هست برای دوستانی که احتمالا در آینده میخوان از این پرسش و پاسخ بهره ببرن.
              روند کار برای فعال سازی امکان محاسبه عرض پالس به صورت زیر هست:
              1- اختصاص یک بیت از پورت به عنوان ورودی و تعریف اون در حالت حساس به هر دو لبه (مسلما در مد ورودی)
              2- اتصال همین بیت بالا به یکی از کانال های event system
              3- تنظیم پیکربندی تایمر در مد Pulse width capture و اختصاص همون کانال event system به اون.
              4- فعال سازی CCA
              5- فعال سازی وقفه CCA
              6- اعمال کلاک مناسب با عرض پالس به تایمر.
              کد به صورت زیر:
              کد:
                //------------ Pulse width capture pin config
                PORT_SetPinAsInput(&PORTC,PIN0_bp);	
              
                PORT_ConfigurePins(&PORTC,
                          PIN0_bm,
                          false,
                          true,
                          PORT_OPC_TOTEM_gc,
                          PORT_ISC_BOTHEDGES_gc);
              					  
               EVSYS_SetEventSource(0,EVSYS_CHMUX_PORTC_PIN0_gc);
              
              
                TC_SetPeriod(&TCC0,0xffff);
                TC0_ConfigEventAction(&TCC0,TC_EVSEL_CH0_gc,TC_EVACT_PW_gc);
                TC0_EnableCCChannels(&TCC0,TC0_CCAEN_bm);        
                TC0_SetCCAIntLevel(&TCC0,TC_CCAINTLVL_MED_gc);    
                TC0_ConfigClockSource( &TCC0, TC_CLKSEL_DIV1_gc);    
              
              
              ISR(TCC0_CCA_vect)
              {
                PWMWidth =TC_GetCaptureA( &TCC0 ); // read position
              }
              توجه به چند نکته مهم هست:
              اول اینکه تابعی که با نام TC0_ConfigEventAction استفاده شده در کتابخانه TC_driver تعریف شده نیست و باید خودتون اون رو اضافه کنید(مکاتبه ای با سایت اتمل داشتم و تابع زیر مورد تایید هست):
              کد:
              void TC0_ConfigEventAction( volatile TC0_t * tc, TC_EVSEL_t eventSource , TC_EVACT_t eventAction)
              {
              	tc->CTRLD = ( tc->CTRLD & ~( TC0_EVSEL_gm | TC0_EVACT_gm ) ) |
              	(eventSource |	eventAction);
              }
              توجه داشته باشید که زمانی که پرچم وقفه CCA فعال میشه تا زمانی که مقدار داخل اون خونده نشده این پرچم 1 هست و مداوم تولید وقفه میکنه. بنابراین زمان که وارد وقفه CCA شدید حتما باید رجیستر CCA خوانده شود.

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

              موفق باشید
              شأن انسان در ايمان و هجرت و جهاد است و هجرت، مقدمهآ‌ي جهاد فيآ‌سبيلآ‌الله.
              هجرت، هجرت از سنگينيآ‌هاست و جاذبهآ‌هايي كه تو را به خاك ميآ‌چسباند.
              چكمهآ‌هايت را بپوش، رهآ‌توشهآ‌ات را بردار و هجرت كن.

              دیدگاه

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