میکروکنترلرهای سری AVR دارای یک تایمر داخلی به نام تایمر watchdog هستند. این تایمر همان طور که از نام لاتین آن پیداست به معنای «سگ نگهبان» است. علت این نام گذاری را در ادامه خواهیم گفت. این تایمر دارای قابلیت های خوبی است، از جمله : دارا بودن منبع ساعت مجزای ۱۲۸ کیلوهرتز، توانایی ریست کردن میکروکنترلر و ایجاد وقفه. از دید سخت افزاری تایمر واچ داگ چیزی نیست جز یک کانتر ساده که پس از این که به حد نهایی خود رسید یک پالس تولید می کند. این پالس می تواند ایجاد وقفه کند و یا MCU میکروکنترلر را ریست کند و یا این که هر دو کار را به طور همزمان انجام دهد.
این تایمر را هر زمان که می خواهیم می توانیم روی مقدار صفر ریست کنیم. این کار با دستور اسمبلی WDR امکان پذیر است. و اینجاست که قضیه جالب می شود. اگر تصمیم گرفتید که از تایمر watchdog استفاده کنید باید در طول برنامه به طور مدام قبل از این که این تایمر پر شود آن را ریست کنید. وگرنه به طور ناخواسته MCU ریست می شود و برنامه تان از ابتدا اجرا می شود. شاید بپرسید که «پس تایمر watchdog چه کاربردی دارد؟» فرض کنید که برنامه تان جایی هنگ نموده و یا در حلقه ی تکرار بینهایت گرفتار شود، در این صورت دیگر طبق روال برنامه تایمر watchdog ریست نشده و پس از این که پر شد سیستم را ریست می کند. در این صورت شما یک محافظ کارامد برای برنامه تان دارید که همیشه مراقب روال اجرای برنامه است. به همین دلیل است که این تایمر به تایمر watchdog یا سگ نگهبان موسوم است.
تایمر watchdog با اسیلاتور ۱۲۸ کیلوهرتزی مجزایی کار می کند. این اسیلاتور یک اسیلاتور توان پایینی است که برای عملیات های زمان دقیق به اندازه ی کافی دقت ندارد. البته تحت تنظیمات خاصی در فیوزهای MCU می توان از این اسیلاتور به عنوان منبع ساعت اصلی میکروکنترلر استفاده نمود که در این صورت تایمر سگ نگهبان با کلاک پالس اصلی همزمان (سنکرون) می شود. اما این یک مورد خاص است که در این جا با آن کاری نداریم و آن را در نظر نمی گیریم. تایمر watchdog سیستم تقسیم فرکانسی مشابه با دیگر تایمرها دارد تا استفاده از آن دارای انعطاف پذیری بیشتری باشد. بر اساس تنظیماتی که روی بیت های WDP3:0 از رجیستر WDTCSR انجام می گیرد می توان زمان وقفه ی تایمر واچ داگ را از ۱۶ میلی ثانیه تا ۸ ثانیه تنظیم نمود (البته حداکثر زمان قابل تنظیم، از تراشه ای به تراشه ی دیگر تفاوت می کند).
وقفه ی تایمر واچ داگ یک منبع وقفه ی باارزش است، زیرا به منبع ساعت مستقلی وابسته است. به همین دلیل می توان از این وقفه برای راه اندازی MCU پس از حالت sleep استفاده نمود. به عنوان مثال شما می توانید یک سیستم باتری دار و با راندمان بالا بسازید که مثلا هر ۸ ثانیه از حالت sleep خارج شده، وظیفه ای را انجام داده و دوباره به حالت sleep بازگردد. البته یک حالت خاص هم وجود دارد که تایمر watchdog می تواند هر دو موردِ وقفه و ریست را باعث شود. در چنین حالتی این امکان را دارید که قبل از ریست کردن MCU مقادیر باارزش را (مثلا در EEPROM داخلی) ذخیره نمایید (قابلیت ایجاد وقفه توسط تایمر واچ داگ فقط در بعضی از تراشه ها موجود است).
در ادامه تایمر watchdog در میکروکنترلر Atmega32 را تشریح خواهیم نمود:
ابتدا با رجیسترهای مرتبط با تایمر watchdog آشنا شویم.
رجیستر WDTCR مخفف عبارت watchdog timer control register و به معنای رجیستر کنترل تایمر واچ داگ می باشد. در این رجیستر پنج بیت قابل تنظیم وجود دارند. شکل زیر نشان دهنده این رجیستر می باشد:
در ادامه هریک از این پنج بیت را شرح می دهیم:
بیت های WDP0 ، WDP1 و WDP2 بیت هایی هستند که مقسم فرکانس تایمر واچ داگ را هنگامی که این تایمر فعال باشد، تعیین می کنند. جدول زیر مقادیر مختلف مقسم فرکانس و تنظیم های متناظر بیت ها را نشان می دهد:
WDE مخفف WatchDog Enable و به معنای فعالسازی واچ داگ و WDTOE مخفف WatchDog Turn-Off Enable به معنای فعالسازی خاموشی واچ داگ می باشد.
برای فعال کردن تایمر watchdog باید مقدار “۱” بر روی بیت WDE نوشته شود.
به منظور غیرفعال نمودن تایمر watchdog باید روند زیر انجام پذیرد:
رجیستر MCUCSR مخفف MCU Control and Status Register و به معنای رجیستر وضعیت و کنترل واحد MCU می باشد. در این رجیستر با یک بیت سر و کار داریم.
عبارت Watchdog Reset Flag به معنای پرچم ریست واچ داگ می باشد و همانطور که از اسم آن پیداست هنگامی که ریست واچ داگ رخ می دهد، مقدار آن یک می شود.
برای این که با برنامه نویسی و به کاربردن تایمر watchdog آشنا شوید، اجازه دهید تا مثالی را طرح نموده و ادامه ی نکات را با آن مثال پیش ببریم. همانطور که مشاهده می کنید این مثال ساده را به این دلیل مطرح خواهیم کرد که فقط با مفهوم به کارگیری تایمر واچ داگ و چگونگی برنامه نویسی آن آشنا شوید.
فرض کنید می خواهیم با میکروکنترلر Atmega32 برنامه ای بنویسیم که در آن یک LED به طور مداوم خاموش و روشن شود. فقط در ابتدای راه اندازی میکروکنترلر پس از گذشت دو ثانیه LED به مدت چند ثانیه خاموش شود و سپس به روال چشمک زدن ادامه دهد.
این کار را می شود با تایمرهای دیگر نیز انجام داد. ولی در این جا هدف ما به کاربردن تایمر نگهبان است. به منظور برنامه نویسی این مثال ابتدا باید تایمر واچ داگ را برای تاخیر ۲ ثانیه فعال کنیم. سپس در یک حلقه LED را خاموش و روشن کنیم. پس از گذشت دو ثانیه MCU ریست شده و برنامه از ابتدا اجرا می شود. قبلا گفتیم که به هنگام ریست شدن MCU توسط تایمر Watchdog، بیت WDFR یک می شود. برای همین ابتدای برنامه چک می کنیم که آیا مقدار این بیت یک است یا صفر. اگر یک بود، یعنی تایمر Watchdog قبلا ریست شده و الان باید LED به مدت چند ثانیه خاموش بماند و سپس طبق روال قبل چشمک بزند. پس تایمر واچ داگ را نیز غیرفعال می کنیم. ولی اگر مقدار بیت WDFR برابر صفر بود یعنی برنامه برای اولین بار اجرا شده و تاکنون تایمر واچ داگ ریست نشده است. پس باید تایمر watchdog را فعال کنیم. با نوشتن این برنامه به هدف خود خواهیم رسید.
کد این مثال به زبان سی و در محیط کدویژن ورژن ۳٫۱۲ نوشته شده است.
خط شماره ی ۶ : چک می کنیم که بیت WFDR یک است یا خیر. در صورتی که یک باشد یعنی قبلا تایمر واچ داگ باعث ریست شدن MCU شده است.
خط شماره ی ۸ تا ۱۶: LED را خاموش کرده و چند ثانیه صبر می کنیم. سپس تایمر نگهبان را غیرفعال می نماییم.
خط شماره ی ۱۷ تا ۲۰ : در صورتی که بیت WFDR باشد، یعنی تایمر واچ داگ تاکنون فعال نشده و ایجاد ریست نیز نکرده است، پس آن را برای زمان ۲ ثانیه فعال می کنیم.
خطوط ۲۱ تا ۲۷ : روال عادی چشمک زدن LED.
خطوط ۲۹ تا ۳۵ : تابع ایجاد تأخیر که به صورت دو حلقه ی تو در تو نوشته شده است.
پایان..
موفق باشید!