آموزش میکروکنترلر AVR – قسمت دهم;
در قسمت نهم آموزش میکروکنترلر AVR به stack یا پشته و مقدمه ای بر تایمرها و کانترها پرداختیم، در این جلسه از آموزش میکروکنترلر AVR به شیوه استفاده از تایمرها و جزئیات آنها و همچنین وقفه ها میپردازیم.
تایمرها :
در خانواده AVR تایمرها به دو صورت 8 و 16 بیتی وجود دارند. تعداد تایمرها در هر میکروکنترلر بسته به شماره آن متفاوت است، مثلاً در ATTINY12 فقط یک تایمر 8 بیتی و در ATMEGA2560 دو تایمر 8 بیتی و 4 تایمر 16 بیتی و جود دارد.
عملکرد تایمرها را بر اساس نمودارهای آنها بررسی میکنیم:
نوع اول : عملکرد این نوع تایمر به این صورت است که از صفر شروع به افزایش میکند تا به مقدار مشخصی برسد و مجدداً صفر میشود.
نوع دوم: عملکرد این نوع تایمرها مانند نوع اول است. با این تفاوت که نوع اول شبیه موج دندانه ارهای عمل میکند ولی نوع دوم شبیه موج مثلثی است.
صرف نظر ار نوع عملکرد، منبع کلاک تایمر کانترها میتواند از طرق مختلفی تأمین شوند.
اگر کلاکی که سختافزارهای اطراف CPU مانند تایمر کانترها و … را تأمین میکند، کلاک I/O نام گذاری کنیم، رابطه “CLK I/O) / N)” میتواند یکی از منابع تأمین کننده برای کلاک تایمر کانترها باشد. با تنظیمات رجیستر مربوط به تعیین کننده نوع کلاک میتوان مقدار N را به یکی از مقدار های 1، 8، 64، 256 و 1024 تغییر داد.
این سوال پیش میآید که N بر چه مبنایی تعیین میشود؟
پاسخ این سوال را با ذکر یک مثال توضیح میدهیم.
یک تایمر 8 بیتی برای طی یک سیکل حداکثر 256 کلاک لازم دارد. (255 کلاک از صفر تا 255 و یک کلاک از 255 تا صفر). اگر یک کلاک 1MHZ که از طریق فیوز بیت تنظیم شده است در نظر بگیریم، طول هر کلاک از نظر زمانی 1میکرو ثانیه است و حداکثر مقداری که یک تایمر کانتر 8 بیتی برای رسیدن از 0 به 255 میتواند تأمین کند و دوباره به صفر برسد 256 میکروثانیه است. حال اگر در کاربردهای مختلف مقدار 256 میکروثانیه کافی نباشد با قرار دادن N روی مقادیر بزرگتر به این نتیجه میرسیم.
برای مثال اگر N را 8 قرار دهیم،حداکثر این زمان 8*256 میکروثانیه خواهد شد، که بیشترین مقدار با فرض کلاک 1MHZ برابر 1024*256 میکروثانیه است.
محاسبات بر اساس زمان و طول تایمر باید انجام شود. حداکثر زمان برای طی یک سیکل در تایمر 16 بیتی مقدار 65536 کلاک است. بنابراین برای ساخت زمان مورد نیاز، بر حسب ظرفیت 8 یا 16 بیتی و مقدار کلاک I/O عمل میکنیم.
اگر مقدار CLK I/O=8MHZ باشد، زمان سپری شدن تایمر از 0 تا 255 و مجدداً به صفر با سرعت 8 برابر انجام میشود.
در شرایطی که کلاک تایمر کانتر از یک مقدار مشخصی مانند CLK I/O تأمین میشود، میتوان نام TIMER را برای آن گذاشت، زیرا زمانی که کلاک یک تایمر کانتر مشخص باشد، از تغییرات مقدار آن میتوان زمان را اندازه گیری کرد.
در شرایط دیگر اگر کلاک میکروکنترلر از بیرون میکروکنترلر تأمین شود به آن COUNTER میگویند.
در حالت سوم که در برخی تایمر کانترها موجود است، این امکان وجود دارد که یک کریستال 32768 هرتز که کریستال ساعت نامیده میشود، به پینهای خاصی متصل شود و اسیلاتوری فعال شود که آن اسیلاتور تأمین کننده منبع کلاک است.
در شمارههای مختلف این مسأله متفاوت است، مثلاً در ATMEGA32 تایمر2 و در ATMEGA64 تایمر0 این امکان را فراهم میکند.
CPU به چه طریق میتواند از تایمر کانترها استفاده کند؟
روش اول:
خواندن مقدار تایمر کانتر است. نامگذاری مقدار تایمر کانترها به صورت TCNT است. مثلاً برای تایمر کانتر 0 که 8 بیتی است باید TCNT0 نوشته شود و در تایمر کانترهای 16 بیتی 2 بایت اختصاص داده میشود و به صورت زیر نوشته میشوند:
TCNT1L
TCNT1H
این دو، یک بایت در همان فضای I/O که در جلسات قبل توضیح داده شد هستند و راه ارتباط با CPU از طریق همین فضا انجام میگیرد.
روال خواندن و نوشتن در رجیسترهای 16 بیتی بدین صورت است که برای نوشتن ابتدا high byte و سپس low byte نوشته میشود و برای خواندن عکس این عمل انجام میشود. این کار در سطح برنامه نویسی اسمبلی انجام میشود.
از آنجایی که تغییرات تایمر کانتر سریع است، در زمانهایی که اندازهگیری زمان و دقت بالا مورد نظر باشد، خواندن این مقدار به صورت نرمافزاری میتواند خطاهایی را ایجاد کند ،بناب راین امکانی در خانواده AVR تحت عنوان capture کردن تایمر پیشبینی شده است. عملکرد capture به این صورت است که تحت فرمان یک پین بیرونی نمونهای از یک تایمر ذخیره میشود.
روش دوم:
ارتباط CPU با تایمر کانتر این است که توسط خطوط برنامه یک پین خارجی مربوط به تایمر کانترها فعال شود و سپس یک نمونه از آن در محل مشخصی ذخیره شود و CPU از این نمونه اطلاع حاصل کند و بر اساس آن تصمیمگیری کند.
(TIFR (TIMER INTERRUPT FLAG REGISTER:
یکی از رجیسترهای مهم در ATMEGA32 رجیستر TIFR است. عملیات مختلف در تایمر میتواند باعث یک شدن در بیتهای آن شود. به این بیتها اصطلاحاً Flag گفته میشود.
TOV0 | OCF0 | TOV1 | OCF1B | OCF1A | ICF1 | TOV2 | OCF2 |
(TOV0 (TIMER OVER FLOW: سرریز تایمر شماره صفر
سرریز شدن تایمر شماره صفر منجر به یک شدن یک بیت میشود. همچنین در این رجیستر بیتهای متناظر با این عبارتند از : TOV1 , TOV2
ICF1:
اگر عملیات CAPTURE اتفاق بیفتد این Flag یک خواهد شد. به این ترتیب راه دوم ارتباط CPU با تایمر و اطلاع CPU از وضعیت تایمر از طریق این رجیستر است، یعنی به جای اینکه CPU مقدار تایمر را قرائت کند مقدار این Flag ها را بررسی میکند.
روش سوم:
صادر شدن مجوز وقفه در قبال یک شدن Flag مربوطه است.
TIFR
TOV0 | OCF0 | TOV1 | OCF1B | OCF1A | ICF1 | TOV2 | OCF2 |
TIMSK
TOIE0 | OCIE0 | TOIEI | OCIEB | OCIEA | TICIEI | TOIE2 | OCIE2 |
بیتهایی که در این تایمر هستند هرکدام که یک شوند، به معنای مجوز ایجاد وقفه در صورت یک شدن Flag متناظر در بایت بالا است.
برای مثال اگر TOIE0=1 باشد هر زمانی که TOV0 یک شود، در صورت وجود مجوز وقفه کلی، یک وقفه تایمر یا OVERFLOW0 ایجاد میشود. در این صورت روند اجرای برنامه متوقف میشود و پرشی در برنامه به آدرسی مشخص در حافظه انجام میشود.
حال میخواهیم بر اساس وقفه از تایمر صفر استفاده کنیم:
در ابتدا منبع کلاک تایمر را مشخص میکنیم و توسط خطوط اجرای برنامه مقدار مناسبی به آن میدهیم. به صورت پیش فرض مقدار تایمر صفر است.
در مرحله بعدی مجوز وقفه را به صورت محلی یک میکنیم، یعنی TOIE0=1 و در انتها Flag I که در Status register توضیح داده شد را برابر یک قرار میدهیم.
در این شرایط اگر TOV0 یک شود، پرشی به آدرس متناظر با تایمر 0 در حافظه FLASH ایجاد میشود و برنامهای که در آنجا نوشته شده اجرا میشود.
تا قبل از اجرای وقفه فلگ TOV0 یک است. اگر وقفهای ایجاد شود، به صورت خودکار بعد از پرش به آدرس مشخص ، فلگ TOV0 پاک میشود.
به دو روش این Flag میتواند صفر یا پاک شود:
1-اگر وقفه ایجاد شود و پرشی به آدرس آن وقفه انجام شود.
2-به روش نرمافزاری برای پاک کردن Flag باید روی آن یک بنویسیم. (اگر روی Flag که مقدار آن از قبل یک باشد، مجدداً یک بنویسیم مقدار آن برابر صفر میشود.)
آنچه در بیت پایین مشخص است مجوز وقوع وقفه است و آنجه در بیت بالایی مشخص است Flag است که CPU توسط آن میتواند از مقدار تایمر اطلاع پیدا کند.
مجوز وقوع وقفه CAPTURE ، بیت TICIEI است.
مقدار تایمرها به صورت دائمی با رجیسترها میتواند مقایسه شوند. یک مقایسه کننده را در نظر بگیرید که مقدار 8 یا 16 بیتی تایمر کانتر را به صورت دائمی با رجیستر 8 یا 16 بیتی مقایسه میکند. اگر تساوی برقرار شود میتواند منجر به یک شدن Flag های OCF0 ,OCF1A ,OCFAB ,OCF2A شود. در ATMEGA32، تایمر 1 دو مقایسه کننده 16 بیتی وجود دارد. که به صورت دائمی با مقدار تایمر 1 مقایسه می شوند. اگر این دو ورودی با هم برابر شود خروجی Flag برابر 1 میشود.
اگر تایمر کانترها تحت شرایطی پینهای به خصوصی را high و low کنند، به این تولید شکل موج گویند. یعنی تحت برنامه کانتر تایمرها تنظیم شوند و زمانی که مقایسه کننده با پین مورد نظر برابر شد پین یک شود.
از آنجا که تایمرها از اهمیت بالای برخوردار هستند در قسمتهای آتی بطور مجزا راجب تایمر0 و تایمر1 صحبت خواهیم کرد. در قسمت یازدهم آموزش میکروکنترلر AVR، تایمر0 در ATMEGA32 را با جزئیات بیشتری بررسی میکنیم. با سیسوگ همراه باشید.
سری مقالات آموزش میکروکنترلر AVR توسط آقای مهندس کینژاد تهیه شده است.
با درود و تشکر. چقدر ادم با دیدن جناب مهندس کی نژاد احساس ارامش و عشق و صداقت و مهربانی و … میکنه. مگه یک ادم چقدر میتونه خوب باشه؟
ای کاش سیستم اموزشی کل ایران دست ایشون بود.
بنظرم باید ایشون اینطور معرفی کرد : خداوند متعال هوژن کی نژاد.
با عرض ادب و احترام،
آیا میشود دو تایمر کانتر 1و 2 و یا 1و0 بصورت همزمان استفاده کرد اگه میشه ممنون میشم راهنمایی کنید.
با تشکر
سلام در مورد این کدها راهنمایی بفرمایید مثلا اگر فرکانس 200 باشد
;freq_t=-(float)1000000/frequncy
;TCNT1L_TEMP=freq_t & 0x00ff
;TCNT1H_TEMP=freq_t/256
ببیتید در واقع باید فرکانس تایمر رو تقسیم بر فرکانس مورد نیازتون کنید – اگر فرض کنیم شما ۲۰۰ هرتز نیاز داشته باشید
میشه ۱ مگاهرتز تقسیم بر ۲۰۰ که میشه 5000 هزار و مقدار ۵۰۰۰ رو توی تایمر ست کنید 🙂
عالی
سلام ممنون از آموزش خوبتون.آموزش رو ادامه نمی دهید ؟
سلام دوست عزیز… این مجموعه آموزشی در سایت نالج پلاس به صورت فیلم موجود هست (http://knowledgeplus.ir/electronics/AVR/video.aspx?lang=Fa)
ما هم اگر فرصت داشته باشیم به صورت مکتوب این آموزشها را منتشر خواهیم کرد.