۲-۷ نحوهی راه اندازی واحد Timer-Counter و شمارش تعداد پالسهای مربعی
۲۷ بهمن ۱۳۹۷۴-۷ طراحی یک ثانیه شمار با دقت بسیار بالا با استفاده از تایمرکانتر صفر
۲۷ بهمن ۱۳۹۷گاه در دنیای کامپیوتر ممکن است اتفاقاتی رخ دهد که اولویت بررسی آن اتفاق خاص برای ما از هر چیز دیگری مهمتر میشود و ما مجبوریم ابتدا به آن رخداد رسیدگی کنیم و سپس به کار قبلی خود بازگردیم و آن را از همان نقطهای که رها کردیم ادامه دهیم، به این نوع رخداد در دنیای کامپیوتر وقفه گفته میشود. مثلا ممکن است ما بخواهیم زمانی که یک سیگنال خاص وارد پردازندهی ما شد تمام کارها را به حال خود رها شوند و ابتدا بخش خاصی که مربوط به ورود این سیگنال خاص است را انجام دهیم و سپس به کار خود ادامه دهیم. در این نوع موقعیتها ما به استفاده از وقفهها احتیاج پیدا میکنیم.
در میکروکنترلرهای AVR یک نوع وقفه برای تایمرکانترها با نام وقفهی سرریز (Overflow Interrupt) تعریف شده است که هر زمان که رجیستر شمارندهی آن تایمر کانتر یعنی TCNTx سرریز میکند این وقفه فراخوانی میشود و ابتدا دستورات داخل این وقفه انجام میشود سپس بقیهی برنامه از مکانی که وقفه رخ داده است از سر گرفته میشود. با استفاده از این ویژگی برجسته ما میتوانیم به راحتی و بدون داشتن هیچگونه نگرانی بابت از دست دادن زمانی که TCNTx سرریز میکند تمام پالسهای ورودی به واحد Timer Counter را بشماریم. در ادامه با فعال کردن وقفهی سرریز در تایمرکانتر صفر در صدد آنیم که بدون از دست دادن حتی یک پالس تعداد کل پالسهای ورودی به میکروکنترلر را بشماریم.
در نرم افزار CodeVision پس از ساخت یک پروژهی جدید و حساس کردن تایمرکانتر صفر به Falling edge کار خود را با انتخاب بخش وقفه همانند روبرو ادامه میدهیم.
حال با فعال سازی این وقفه در قطعه کدی که توسط CodeWizard تولید میشود یک بخش با نام interrupt [TIM0_OVF] void timer0_ovf_isr(void) تولید میشود که میتوانیم داخل آن هر کاری را که میخواهیم در زمان سرریز TCNT0 رخ دهد را قرار دهیم. حال میخواهیم عمل شمارش تعداد پالس ها را به وسیلهی وقفه انجام دهیم. برای این منظور به قطعه کد زیر نگاه کنید:
#include <mega32.h> #include <alcd.h> #include <delay.h> #include <stdio.h> #include <stdlib.h> int counter=0; long int totalPulse=0; char str[20]; // Timer 0 overflow interrupt service routine interrupt [TIM0_OVF] void timer0_ovf_isr(void) { counter++; } // Characters/line: 16 lcd_init(16) // Global enable interrupts #asm("sei") while(1) { totalPulse=counter*256+TCNT0; sprintf(str,"allPulse = %d",totalPulse); lcd_puts(str); delay_ms(20); lcd_clear(); }
در قطعه کد بالا عمل اضافه کردن به متغیر counter در داخل روتین وقفه سرریز انجام شده است و این به ما امکان آن را میدهد که دیگر میزان تاخیر کد به هنگام چاپ کاراکترها بر روی LCD در شمارش پالسها خللی ایجاد نکند و ما کار شمارش پالسها را با دقت فوقالعادهای انجام دهیم.
برای تست این عمل کرد میتوانید میزان تاخیر را به مدت 1000ms تغییر دهید و بازهم مشاهده خواهید کرد که تعداد دقیق پالسها هر ۱ ثانیه بر روی LCD چاپ خواهد شد.
3 Comments
سلام من برنامه بالارو تو کدویژن اجراکردم جواب نمیده و error زیر رو میده:
Warning: C:\Users\HP\Desktop\milad\flasher\count-1.c(38): overflow is possible in 16 bit multiplication, casting to ‘long’ may be required
Warning: C:\Users\HP\Desktop\milad\flasher\count-1.c(38): overflow is possible in 16 bit addition, casting to ‘long’ may be required
لطفا راهنمایی کنید.
۱)چطور میتونم تعداد پالس های یک پالس مربعی بافرکانس ۸مگاهرتز رو بشمارم
۲)چطورمیتونم پالس کلاک یک میکرو رو تو یک پالس مشخص متوقف کنم.
با سلام
در جواب سوال اول باید خدمتتان عرض کنم که در واقع شما با یک اخطار مواجه شده اید و با Error دادن کد متفاوت است. در واقع در این حالت امکان اجرا و پروگرم کردن کد بر روی میکرو و اجرای آن وجود دارد ولی همان طور که از اخطار مشخص است ممکن است سر ریز رخ دهد که بهتر است به جای تعریف int از long int برای نگه داری تعداد پالس ها استفاده نمایید.
با میکرو کنترلر AVR امکان چنین چیزی وجود ندارد و علت هم این است که حداکثر کلاک میکرو AVR در اکثر موارد ۸Mhz است. واحد Intrupt و یا InputCapture با کسری از این کلاک کار می کنند که در اکثر موارد امکان شمارش پالسی با این فرکانس با AVR وجود ندارد. روش شمارش دقیقا مشابه روش گفته شده در بخش intruptاست. شما می توانید از میکروکنترلر های ARM برای این کار استفاده نمایید.
در جواب سوال آخر واحد Watch dog می تواند گزینه ی مناسبی برای این کار باشد که با توجه به امکانات میکرو کنترلرهای مختلف قابلیتهای زیادی را در اختیار کاربر می گذارد.
کی متوجه میشه که سرریز رخ داده تا میره وقفه رو اجرا میکنه؟