همانطور که از موضوع این مطلب مشخص است، مقایسه کننده آنالوگ از هر مدلی که باشد دو سیگنال آنالوگ را مقایسه کرده و نتیجه مقایسه را بصورت 0 یا 1 منطقی برمیگرداند. یکی از کابردهای متداول این نوع مقایسه کنندهها، مدارات اشمیت تریگر است. اشمیت تریگر هر نوع سیگنال آنالوگ اعم از سینوسی یا مثلثی را دریافت کرده و به موج مربعی تبدیل میکند. در ادامه پس از تشریح ساختمان مقایسه کننده آنالوگ، یک نمونه از اشمیت تریگر را با ATmega16 برنامهنویسی خواهیم کرد.
مقایسه کننده آنالوگ در AVR
در اکثر میکروکنترلرهای سری AVR مقایسه کننده آنالوگ تعبیه شده و دارای دو پایه به نامهای AIN0 و AIN1 است.
پایه AIN0 ورودی + و پایه AIN1 ورودی – مقایسه کننده است. به بیانی دیگر اگر ولتاژ AIN0 از AIN1 بیشتر شود، خروجی مقایسه کننده برابر 1 منطقی و اگر AIN1 بیشتر از AIN0 گردد، خروجی 0 میشود. از آنجایی که نمیتوان گفت که سطح ولتاژ دو سیگنال مساوی است، بنابراین حالت مساوی وجود ندارد. به همین خاطر یا خروجی 1 منطقی و یا 0 منطقی است. اینکه خروجی مقایسه کننده کجاست، در ادامه گفته خواهد شد.
رجیسترهای مقایسه کننده آنالوگ
اگر آموزشهای پیشین را مطالعه کرده باشید، گفتیم که هر کدام از قسمتهای میکروکنترلر، یک سری رجیستر یا ثبات جهت کنترل دارد. مقایسه کننده آنالوگ، تنها یک رجیستر اختصاصی با نام ACSR دارد و همچنین از دو رجیستر فرعی SFIOR و ADMUX هم میتواند کنترل شود. اما در درجه اول رجیستر ACSR حائز اهمیت است و در اکثر مواقع هیچگونه نیازی به استفاده از دو مورد دیگر نیست.
رجیستر Analog Comparator Control Status Register) ACSR)
قسمت اصلی کنترل واحد مقایسه کننده آنالوگ این رجیستر است و با تنظیم بیتهای آن میتوان عملکرد آن را تغییر داد.
بیت Analog Comparator Disable) ACD)
اگر این بیت 1 شود، واحد مقایسه کننده آنالوگ غیر فعال خواهد شد. در حالت عادی این بیت 0 بوده و مقایسه کننده فعال است.
بیت Analog Comparator Bandgap Select) ACBG)
گفتیم که پایه AIN0 ورودی + و پایه AIN1 ورودی – سیگنال است. اگر این بیت 1 شود، ولتاژ ثابت 1.23 ولت به عنوان ورودی + در نظر گرفته شده و سیگنال اعمالی به پایه AIN0 هیچ تاثیری در عملکرد نخواهد داشت. به عبارتی دیگر با 1 شدن بیت ACBG، ولتاژ اعمال شده به AIN1 با ولتاژ 1.23 ولت مقایسه خواهد شد.
بیت Analog Comparator Output) ACO)
این بیت، خروجی مقایسه کننده است. هرگاه ولتاژ ورودی + از ورودی – بیشتر شود، این بیت 1 میشود. در غیر این صورت 0 خواهد شد.
بیت Analog Comparator Interrupt Flag) ACI)
بیت پرچم وقفه است. هر زمان که تغییری در مقایسه دو سیگنال ورودی + و – ایجاد شود، این بیت 1 خواهد شد. منظور از ایجاد تغییر، بزرگتر یا کوچکتر شدن دو سیگنال نسبت به هم است. البته رفتار این بیت وابسته به دو بیت ACIS0 و ACIS1 میباشد که کمی جلوتر گفته میشود.
بیت Analog Comparator Interrupt Enable) ACIE)
با 1 کردن این بیت وقفه مقایسه کننده آنالوگ فعال شده و در صورتی که بیت وقفه عمومی هم فعال باشد، با هر بار 1 شدن بیت ACI وقفه رخ میدهد.
بیت Analog Comparator Input Capture Enable) ACIC)
اگر این بیت 1 شود، هر بار تغییر سطح دو سیگنال ورودی + و – نسبت به یکدیگر، باعث تحریک شدن ورودی Capture تایمر کانتر 1 خواهد شد. از این مورد در مواقع خیلی خاص استفاده میشود و ما هم در مثالها این بیت را 0 مقدار میدهیم.
نکته: مفهوم کپچر در قسمت تایمر کانتر 1 گفته شده است. برای مشاهده، روی این لینک کلیک کنید.
بیتهای ACIS0 و Analog Comparator Interrupt Mode Select) ACIS1)
این دو بیت مربوط به تنظیم چگونگی وقوع وقفه هستند و میتوانند یکی از 4 حالت زیر را داشته باشند.
این 4 حالت عبارتاند از:
- حالت “00” که هرگونه تغییر از 0 به 1 یا از 1 به 0 در بیت ACO باعث وقوع وقفه میشود.
- حالت “01” که غیر مجاز است و برنامهنویس از اعمال کردن این مقدار باید خودداری کند.
- حالت “10” که باعث میشود تنها تغییر از 1 به 0 یا به اصطلاح لبه پایین رونده موجب ایجاد وقفه شود.
- حالت “11” که باعث میشود تنها تغییر از 0 به 1 یعنی لبه بالارونده، ایجاد وقفه کند.
مثال: فرض کنیم که ولتاژ اعمالی به پایه AIN0 برابر 2.8 ولت و ولتاژ AIN1 برابر 2.9 ولت باشد (با توجه به توضیحات بالا بیت ACO صفر خواهد بود). اگر رجیستر ACSR را 0x0A مقداردهی کنیم، در این صورت وقفه مقایسه کننده فعال شده و بیتهای ACIS در حالت “10” قرار میگیرند که تنها تغییر مقدار ACO از 1 به 0 باعث وقوع وقفه میشود. حال اگر ولتاژ پایه AIN0 به 3.0 ولت برسد مقدار بیت ACO برابر 1 شده اما وقفه رخ نمیدهد. اما با کاهش دوباره AIN0 یا افزایش AIN1، مقدار بیت ACO برابر 0 شده و بلافاصله وقفه رخ میدهد.
مثال: اگر رجیستر ACSR را 0x08 مقداردهی کنیم، وقفه فعال شده و حالت “00” برای ACIS انتخاب میشود. در این حالت چه AIN0 از AIN1 بیشتر شود یا کمتر شود، وقفه رخ خواهد داد.
رجیستر Special Function Input Output Register) SFIOR)
در این رجیستر تنها یک بیت مربوط به مقایسه کننده آنالوگ است و ACME نام دارد.
بیت Analog Comparator Multiplexer Enable) ACME)
اگر این بیت 1 شود و مبدل آنالوگ به دیجیتال غیر فعال باشد، در این صورت ورودی – مقایسه کننده آنالوگ از یکی از پایههای ADC0 تا ADC7 (پایه 33 تا 40 میکروکنترلر) گرفته میشود. اینکه کدام پایه به عنوان ورودی – انتخاب شود، بستگی به مقدار رجیستر ADMUX خواهد داشت.
رجیستر ADC Multiplexer) ADMUX)
این رجیستر یکی از رجیسترهای اختصاصی مبدل آنالوگ به دیجیتال است و تنها سه بیت کم ارزش آن میتوانند در مقایسه کننده آنالوگ دخیل باشند.
به عنوان یک توضیح تکراری با 1 شدن ACME در رجیستر SFIOR و همچنین خاموش بودن واحد ADC، حالتهای مختلف بیتهای MUX0 تا MUX2 بصورت زیر خواهند شد.
این حالات عبارتاند از:
- اگر ACME برابر 0 باشد، در هرصورت ورودی – همان پایه AIN1 خواهد بود.
- اگر ACME برابر 1 باشد و ADEN (فعال ساز مبدل ADC) هم برابر 1 باشد، باز هم ورودی – همان AIN1 است.
- اگر ACME برابر 1 و ADEN برابر 0 باشد، با توجه به مقادیر MUX0 تا MUX2 یکی از ورودیهای ADC0 تا ADC7 به عنوان ورودی – مقایسه کننده آنالوگ عمل خواهد کرد.
مثال 1 : اشمیت تریگر
برنامهای مینویسیم که سطح ولتاژ AIN0 و AIN1 را مقایسه کرده و حاصل آن (منظور بیت ACO) را روی پایه PORTA.0 قرار دهد. در این صورت با اعمال یک موج سینوسی به پایه AIN0 و یک ولتاژ ثابت 2.5 ولت به AIN1، سیگنال خروجی PORTA.0 بصورت مربعی میشود.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
#include <mega16.h> void main(void){ DDRA = 0x01; ///////////////// ACSR = 0x08; ///////////////// #asm ("sei") ///////////////// while(1); } interrupt[ANA_COMP]void Comparator(void){ PORTA.0 = ((ACSR&0x20) == 0x20); } |
توضیخ برنامه
در ابتدای main پایه PORTA.0 را بصورت خروجی قرار دادیم (DDRA = 0x01). سپس با مقداردهی ACSR برابر 0x08 تنها وقفه مقایسه کننده آنالوگ فعال شده و ورودی + همان پایه AIN0 و ورودی – همان پایه AIN1 باقی میماند. در نهایت هم بیت وقفه عمومی فعال شده و برنامه وارد حلقه بیانتهای while میشود. در بیرون از main، سرویس روتین وقفه مربوط به مقایسه کننده آنالوگ قرار دارد که با کلمه کلیدی interrupt و برچسب ANA_COMP مشخص شده است. چون بیتهای ACIS در وضعیت “00” هستند، هر گونه تغییر وضعیت دو ورودی نسبت به هم باعث وقوع وقفه شده و دستور داخل سرویس روتین اجرا میشود. این دستور بیت ACO در رجیستر ACSR را درون PORTA.0 قرار میدهد. در نتیجه هرگاه سیگنال آنالوگ بیشتر از 2.5 ولت شود، خروجی 1 و هرگاه کمتر از 2.5 ولت شود، خروجی 0 خواهد شد.
مثال 2 : مقایسه ADC7 با ولتاژ داخلی 1.23 ولت
برنامهای مینویسیم که ولتاژ اعمالی به پایه ADC7 (پایه شماره 33) را با ولتاژ داخلی 1.23 ولت مقایسه کرده و با اجرای سرویس روتین، یک رقص نور ساده بر روی پورت D انجام دهد.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
#include <mega16.h> #include <delay.h> unsigned char i; void main(void){ DDRD = 0xFF; /////////////////// SFIOR = 0x08; ADMUX = 0x07; ACSR = 0x48; /////////////////// #asm ("sei") /////////////////// while(1); } interrupt[ANA_COMP]void Comparator(void){ for(i=0;i<8;i++){ PORTD = 0x01 << i; delay_ms(2000); } PORTD = 0x00; } |
توضیح برنامه
در بخش main تنها تفاوت خروجی شدن تمام پورت D و اضافه شدن دو رجیستر SFIOR و ADMUX است. با مقدار دادن 0x08 به SFIOR بیت ACME برابر 1 شده و چون مقدار ADMUX برابر 0x07 است، پایه ADC7 به عنوان ورودی – انتخاب میشود. اما با مقداردهی ACSR به 0x48، وقفه مقایسه کننده آنالوگ فعال شده و با 1 شدن بیت ACBG، ولتاژ ثابت 1.23 به ورودی + اعمال خواهد شد. در نتیجه ولتاژ روی پایه ADC7 با ولتاژ 1.23 ولت مقایسه میگردد. در آخر با اجرای سرویس روتین وقفه، حلقه for ایجاد رقص نور بر روی پورت D را انجام میدهد.
هرگونه سوال و مشکلی در تحلیل هر قسمت داشتید، زیر همین پست کامنت بگذارید.
برای آموزشهای بیشتر با رزدینو همراه باشید.
2 پاسخ
خیلی عالییی.مرسی.
سلام
بسیار یسیار عالی ممنون