بخش پنجم آموزش AVR : آموزش کدویزارد Codewizard

بازگشت به آموزشگاه

مقدمه

در فصل های گذشته به طور مقدماتی با نحوه کار با واحد I/O و رجیسترهای مربوط به تنظیم آنها آشنا شدیم و با استفاده از آن ها کلید ، صفحه کلید و نمایشگر سون سگمنت را راه اندازی کردیم . در این فصل نیز ابتدا به شرح مجدد واحد I/O و سپس معرفی ابزار Codewizard ( جادوگر کد ) خواهیم پرداخت و در ادامه به معرفی و بررسی واحد های دیگر نظیر تایمرها و کانترها ، ارتباطات سریال ، وقفه ها و … می پردازیم.

هر یک از واحدهای یک میکروکنترلر از سه دیدگاه قابل بررسی است :

  • معرفی عملکرد ، ویژگی ها و وظایف واحد مورد نظر .
  • تشریح نحوه عملکرد مداری واحد مورد نظر .
  • معرفی و بررسی رجیسترهای تنظیمات واحدمورد نظر.

هر یک از واحدهای گفته شده در Atmega32 به جز CPU ، رجیسترهایی دارد که تنظیمات واحد مورد نظر را مشخص می کند . برنامه نویس باید رجیسترهای مربوط به هر واحد را شناخته و آنها را بسته به پروژه مورد نظر به درستی مقدار دهی نماید . برای اینکه این مقداردهی راحت تر ، سریعتر و با دقت بیشتر صورت گیرد از ابزار CodeWizard استفاده می شود . در این فصل ابتدا با رجیسترهای واحد I/O بیشتر آشنا خواهیم شد و سپس ضمن آموزش CodeWizard بقیه واحد ها را نیز به ترتیب در این بخش و بخش های بعدی آموزش خواهیم داد .

 


واحد پورت های ورودی/خروجی

پورت های ورودی/خروجی یکی از مهم ترین واحدهای هر میکروکنترلر می باشد که به منظور استفاده عمومی و کاربردهای همه منظوره طراحی شده است . به طور کلی نکات زیر در مورد واحد I/O در میکروکنترلرهای AVR وجود دارد :

1- هر یک از پایه های میکروکنترلر ممکن است چندین عملکرد از جمله پورت ورودی/خروجی باشد که به صورت همزمان نمی توان از آنها استفاده نمود . بنابراین در صورت استفاده از واحد I/O در یک پایه ، فقط به عنوان پورت ورودی یا خروجی همه منظوره ( General Purpose I/O ) استفاده می شود .

2- در صورت استفاده از یک پایه به عنوان خروجی ، پایه مورد نظر می تواند دو حالت ( منطق ۱ یا منطق ۰ ) داشته باشد. در صورتی که آن پایه منطق ۱ داشته باشد ولتاژ آن پایه حداکثر Vcc می گردد و جریانی از داخل میکرو به بیرون کشیده می شود که به آن جریان Source گویند. زمانی که پایه منطق ۰ داشته باشد ، ولتاژ آن پایه حداقل ۰ ولت می گرد و جریانی از بیرون به آن وارد می شود که به آن جریان sink گویند.

3- حداکثر جریان Source و Sink در میکروکنترلر Atmega32 برای وقتی که Vcc=5v و دما ۲۵ درجه باشد ، به مقدار ۶۰ میلی آمپر می رسد . با افزایش جریان Source ، ولتاژ منطق ۱ پایه شروع با کاهش از مفدار Vcc می کند . هر چه جریان دهی پایه بیشتر باشد  افت ولتاژ پایه از مقدار Vcc نیز بیشتر می شود . همانطور که در شکل صفحه ۳۰۸ دیتاشیت قسمت Typical Characteristicsنیز برای Vcc=5v و دما ۲۵ درجه مشاهده می شود ، با افزایش جریان دهی با کاهش ولتاژ از ۵ ولت تا ۳ ولت مواجه هستیم .

برای جریان Source هم به همین صورت اگر جریانی که به پایه آی سی وارد می شود افزایش یابد ولتاژ آن از حالت ایده آل ( ۰ ولت ) افزایش پیدا کرده به طوری که برای Vcc=5v و دمای ۲۵ درجه به ۲ ولت نیز می رسد .

4- در صورت استفاده از یک پایه به عنوان ورودی ، پایه مورد نظر می تواند یکی از سه حالت زیر را داشته باشد :

  • حالت اتصال پایه به منطق ولتاژی ۰ یا ۱ از بیرون : مانند شکل زیر

Atmega32_Button

  • حالت دارای مقاومت Pull Up داخلی : در این حالت یک مقاومت Rpu از داخل میکروکنترلر تنها به صورت پول آپ میتواند وصل شود . شکل زیر این مقاومت را به همراه دیگر اجزای داخلی هر پایه نشان می دهد . هر پایه واحد I/O دارای دیودهای هرزگرد ، خازن و مقاومت پول آپ می باشد .

MCU_PinConfig

نکته : مقدار مقاومت پول آپ به طور تقریبی برابر ۵ کیلو اهم است .

  • حالت بدون اتصال ( مدار باز یا High Z ) : پایه هایی که به هیچ جایی متصل نیستند به صورت بدون اتصال ، مدار باز یا امپدانس بالا ( High Z ) هستند ( در حالت پیش فرض کلیه پایه ها ورودی و بدون اتصال هستند ) .

نکته : Tri-State به معنای سه حالته می باشد . یعنی پایه در سه حالت بدون اتصال ، اتصال به ۰ و اتصال به ۱ میتواند قرار گیرد .

 


رجیسترهای واحد I/O

در ATmega32 چهار پورت ورودی/خروجی وجود دارد که برای هر یک پین هایی خروجی درنظر گرفته شده است . هر یک از این ۴ پورت ورودی/خروجی دارای سه رجیستر DDR ، PIN و PORT هستند که در نتیجه مجموعا ۱۲ رجیستر ۸ بیتی برای واحد ورودی/خروجی وجود دارد که همگی در حقیقت درون SRAM می باشند که با مقدار دهی آنها در برنامه این واحد کنترل می شود . همانطور که در فصول قبل توضیح داده شد ، رجیستر DDR برای تعیین جهت ورودی یا خروجی بودن ، رجیستر PORT برای تعیین مقاومت PullUp در حالت ورودی بودن پایه و تعیین منطق ۰ یا ۱ در حالت خروجی بودن پایه کاربرد دارد و رجیستر PIN نیز برای خواندن منطق اعمال شده از بیرون در حالت ورودی می باشد . شکل زیر حالت های مختلف پایه ها را بسته به بیت n ام رجیستر DDR و PORT و نیز بیت PUD در رجیستر SFIOR نشان می دهد . لازم به توضیح است که رجیستر SFIOR یک رجیستر ۸ بیتی برای تنظیمات خاص پایه ها می باشد که بیت دوم آن PUD یا PullUp Disable مربوط به غیر فعال کردن کلیه مقاومت های PullUp می باشد .

Atmega32_PinDrive3


نحوه فعالسازی مقاومت پول آپ

همانطور که در شکل فوق نیز مشاهده می کنید ، در حالتی که رجیستر DDRX.n صفر باشد یعنی پایه ورودی بوده و در صورتی که رجیستر PORTX.n را یک کنیم ، مقاومت پول آپ داخلی فعالسازی می شود . بنابراین رجیستر PORTX.n در حالت خروجی بودن پایه ، منطق ۰ یا ۱ پایه را مشخص می کند و در حالت ورودی بودن پایه فعال بودن یا نبودن مقاومت پول آپ را مشخص می کند . بنابراین برای فعال شدن مقاومت پول آپ داخلی باید سه شرط زیر برقرار باشد :

  1. بیت PUD یا Pull Up Disable غیر فعال یا ۰ باشد که همیشه برقرار است مگر زمانی که میکروکنترلر ریست باشد یا هنگ کرده باشد .
  2. رجیستر DDRX.n مربوطه ۰ باشد یعنی پایه ورودی باشد . پس در حالت خروجی مقاومت پول آپ نمیتواند فعال شود .
  3. رجیستر PORTX.n مربوطه ۱ باشد . در صورت ۰ بودن نیز مقاومت پول آپ غیر فعال است .

 


 CodeWizard چیست ؟

در حقیقت CodeWizard ابزار کاملی برای برنامه نویسی کلیه میکروکنترلرهای AVR است که به همراه نرم افزار CodeVision ارائه شده و بخشی از این نرم افزار می باشد . این ابزار که به جادوگر کد معروف است به شما این امکان را می دهد که با انتخاب کردن مدل میکروکنترلر ، فرکانس کاری و تنظیم و پیکره بندی کلیه واحدهای میکروکنترلر ( نظیر پورت ها ، تایمر/کانترها و … ) از میان گزینه های آماده موجود در ابزار ، کدهای مربوط به تنظیمات اولیه رجیسترها به زبان C را به طور اتوماتیک تولید کند.

 

شروع کار با ابزار CodeWizard

ابتدا به صفحه اصلی نرم افزار CodeVision AVR رفته و اگر پروژه ای باز است از منوی File و گزینه Close All آن را می بندیم .

  1. برای راه اندازی کدویزارد در صفحه اصلی نرم افزار CodeVision از منوی tools ، گزینه CodeWizard AVR را انتخاب کنید. همچنین می توانید به جای آن از منوی ابزار بالای نرم افزار گزینه چرخ دنده را کلیک کنید ( شکل زیر ) . در پنجره باز شده میخواهد که نوع چیپ را از نظر سری ساخت مشخص کنید. چون چیپ مورد استفاده ما atmega32 است ، گزینه اول atmega را انتخاب کرده و ok کنید . اکنون پنجره codeWizardAVR جلوی شماست .  CodeWizard_1
  2. در این قسمت اولین کاری که باید انجام دهید تنظیم نوع چیپ و فرکانس کاری میکروکنترلر است . دیگر گزینه ها را کاری نداریم . فرکانس کاری میکروکنترلر باید همان فرکانسی انتخاب شود که در قسمت Fuse Bits ( فیوز بیت ها ) تنظیم شده است. در صورتی که میکروکنترلر Atmega32 را تازه خریداری کرده اید ، فرکانس پیش فرض آن ۱Mhz می باشد.CodeWizard_2
  3. در مرحله بعد وارد سربرگ Port می شویم . در این مرحله باید طبق سخت افزار طراحی شده پورت ها را تنظیم کرد. همانطور که مشاهده می شود ، پورت ها را میتوان ورودی in یا خروجی out نمود و در صورت ورودی بودن با تغییر T یعنی Tri-State به P میتوان مقاومت PullUp داخلی میکرو را نیز فعال کرد و در صورت خروجی بودن نیز میتوان با تغییر ۰ و ۱ مقدار اولیه منطق پورت خروجی را تعیین نمود . سربرگ های دیگر هر کدام مختص واحدهای دیگر میکروکنترلر است که در صورت لزوم در این مرحله باید تنظیم شود. در شکل زیر مثالی از نحوه این تغییرات را مشاهده می کنید .CodeWizard_PinConfig
  4. بعد از پایان تنظیمات از منوی File گزینه Generate, save and Exit را کلیک کنید. اکنون سه بار باید فایل های مربوط به پروژه را با نام ترجیحا یکسان ذخیره کنید . در پنجره اول اسمی برای فایل با پسوند .C وارد می کنیم و ذخیره می کنیم و همین طور در پنجره های بعدی برای project و codeWizardAVR نام وارد کرده و ذخیره کنید . مشاهده می کنید که کد ویزارد بخش اولیه برنامه شما را ایجاد کرده است . اکنون شما می توانید شروع به ادامه برنامه نویسی با تغییر یا اضافه کردن کدهای ساخته شده نمایید .

 


 راه اندازی LCD های کارکتری

صفحه نمایش کاراکتری یکی از پرکاربرد ترین وسایل خروجی است که به میکرو وصل می شود و میتوان کاراکترهای قابل چاپ را روی آن نمایش داد. مشخصه اصلی LCD های کاراکتری تعداد سطر و ستون آنها است برای مثال LCD های ۲*۱۶ دارای ۲ سطر و ۱۶ ستون می باشند و در مجموع ۳۲ کاراکتر را میتوان با آنها نشان داد .

character_LCD

در نرم افزار پروتئوس نیز انواع LCD های کاراکتری و گرافیکی در کتابخانه optoelectronics موجود است که میتوان از آنها برای شبیه سازی این قطعه استفاده کرد . در این آموزش ما از LM016L که یک LCD کاراکتری با ۲ سطر و ۱۶ ستون است ، بیشترین استفاده را خواهیم کرد .

ال سی دی های کارکتری اغلب دارای ۱۴ پایه هستند که ۸ پایه برای انتقال اطلاعات ۳ پایه برای کنترل نرم افزاری یک پایه برای کنترل سخت افزاری و دو پایه تغذیه می باشد در جدول زیر اطلاعات پایه ها را مشاهده می کنید :

توضیحات

نام

پایه

پایه (-) تغذیه

vss

۱

پایه(+) تغذیه

vcc

۲

کنترل درخشندگی صفحه

VEE

۳

انتخاب دستور داده

RS

۴

فعال ساز خواندن یا نوشتن

R/w

۵

فعال ساز

E

۶

دیتا

DB0

۷

دیتا

DB1

۸

دیتا

DB2

۹

دیتا

DB3

۱۰

دیتا

DB4

۱۱

دیتا

DB5

۱۲

دیتا

DB6

۱۳

دیتا

DB7

۱۴

پایه + روشنایی صفحه( +بک لایت)

A

۱۵

پایه – روشنایی صفحه(- بک لایت)

k

۱۶

LCD ها را میتوان با ۸ خط دیتا یا ۴ خط دیتا راه اندازی کرد اما نرم افزار CodeVision تنها از ۴ خط دیتا پشتیبانی می کند که در آن تنها پایه های RS ، R/W ، E و D4 تا D7 به پورت دلخواه از میکرو متصل می شود. تنها تفاوت راه اندازی ۴ خط دیتا در این است که داده های ۸ بیتی LCD به جای یکبار ، دو بار از طریق ۴ بیت ارسال می شوند. مزیت این راه اندازی نیز در این است که اتصال LCD به میکروکنترلر تنها یک پورت از میکرو را اشغال می کند. پایه های LCD کاراکتری ۲ در ۱۶ و نحوه وصل شدن به میکروکنترلر را در شکل زیر مشاهده می کنید.

 

CodeWizard_LCD

تذکر: در نرم افزار Proteus و به هنگام شبیه سازی میتوان پایه های ۱ ، ۲ ، ۳ ، ۷ ، ۸ ، ۹ و ۱۰ را بدون اتصال گذاشت اما در عمل و پیاده سازی تمامی پایه ها باید به محل مربوطه مطابق شکل فوق متصل باشد .

 

نکته 1 : پایه سوم ( VEE ) برای تنظیم کنتراست نوشته های روی LCD می باشد. با وصل کردن این پایه به یک مقاومت متغیر میتوان کیفیت نمایش را تنظیم کرد.

 

نکته 2 : در عمل میتوان به جای استفاده از مقاومت متغیر ، از اتصال پایه VEE توسط یک مقاومت 1K با زمین مدار ، حداکثر کنتراست را برای LCD داشت. درنتیجه کافی است یک مقاومت 1K بین پایه 3 و 1 قرار دهیم. شکل زیر این موضوع را نشان می دهد.

LCD_2in16

 

تنظیمات CodeWizard برای راه اندازی LCD کاراکتری

در سربرگ Alphanumeric LCD ابتدا تیک Enable را بزنید و سپس در قسمت Character/line باید تعداد ستون ها را وارد نمایید و در قسمت بعدی باید نام پایه های متصل به LCD را مشخص کنید. با این کار در برنامه هدر فایلی با نام alcd.h و تابع راه انداز LCD به صورت lcd_init(16) به برنامه اضافه می شود که عدد ۱۶ در آن نشان دهنده تعداد ستون های LCD است. با اضافه شدن این هدر فایل از توابع زیر برای کار با LCD در برنامه دلخواه می توان استفاده کرد.

 


توابع کار با LCD کاراکتری

  1. پاک کردن تمام LCD :

این تابع lcd را پاک کرده و مکان نما را در سطر و ستون صفر قرار می دهد.

  1. رفتن به ستون x و سطر y ام :

تابع فوق مکان نمای ال سی دی را در سطر x و ستون y قرار می دهد و باید به جای x و y عدد سطر و ستون مورد نظر جا گذاری شود.

  1. چاپ یک کاراکتر:

  1. چاپ یک رشته :

  1. چاپ یک متغیر رشته ای :

 

نکته1 : ورودی تابع lcd_putsf یک رشته ثابت مانند “IRAN” است اما ورودی تابع lcd_puts یک متغیر رشته ای از نوع آرایه ای می تواند باشد .

 

نکته 2 : برای مقدار دهی به یک متغیر رشته ای میتوان از تابع sprintf استفاده کرد . برای استفاده از این تابع که در کتابخانه stdio.h می باشد ، ابتدا هدر فایل را اضافه کرده به صورت زیر عمل می کنیم :

توضیح : با اضافه کردن stdio.h میتوان از تابع sprintf در برنامه استفاده کرد . در این مثال میخواهیم دمای اتاق را در رشته ای به صورت temp=%d که در آن %d یک عدد متغیر است و در جایی از برنامه به آن مقدار دهی کردیم ، بریزیم و سپس روی lcd نمایش دهیم . پس در آرگومان تابع sprintf ابتدا نام متغیر رشته ای را نوشته سپس رشته مورد نظر را به صورت جدول زیر و در آخر نام متغیر را مینویسیم .

فرمت متغیرهای کاراکتری ارسالی :

کاراکتر نوع اطلاعات ارسالی
 c%  یک تک کاراکتر
 d%  عدد صحیح علامت دار در مبنای ۱۰
 i%  عدد صحیح علامت دار در مبنای ۱۰
 e%  نمایش عدد ممیز شناور به صورت علمی
 E%  نمایش عدد ممیز شناور به صورت علمی
 f%  عدد اعشاری
 s%  عبارت رشته ای واقع در حافظه SRAM
 u%  عدد صحیح بدون علامت در مبنای ۱۰
X% به فرم هگزا دسیمال با حروف بزرگ
 x%   به فرم هگزا دسیمال با حروف کوچک
 P%  عبارت رشته ای واقع در حافظه FLASH
 %%  نمایش علامت ٪

 


 مثال عملی شماره ۴

با استفاده از اتصال یک LCD کاراکتری ۱۶ در ۲ و یک صفحه کلید ۴ در ۴ به میکروکنترلر Atmega32 ، برنامه ای بنویسید که با فشار دادن هر کلید کاراکتر مربوطه روی نمایشگر چاپ شود . برنامه را توسط کدویزارد نوشته و راه اندازی صفحه کلید را با استفاده از مقاومت پول آپ داخلی انجام دهید .

حل:

مرحله اول : طراحی سخت افزار در پروتئوس

Atmega32_Mesal4

مرحله دوم : انجام تنظیمات در کدویزارد

در این مرحله بعد از مشخص کردن نوع چیپ و فرکانس کاری میکرو ، در سربرگ port تنظیمات پورت C و D را طبق سخت افزار طراحی شده و به صورت زیر انجام می دهیم .

Mesal4_PORTC Mesal4_PORTD

سپس به سربرگ Alphanumeric LCD رفته و تنظیمات آن را نیز به صورت زیر انجام می دهیم .

Mesal4_LCDتنظیمات کدویزارد پایان می یابد . بعد از ذخیره و خروج از کدویزارد ( Save,Generate & Exit ) کد مورد نیاز تولید شده است . در این مرحله بهتر است با حذف کامنت ها و قسمت های اضافی برنامه حجم کد برنامه را کاهش دهیم .

 

مرحله سوم : تکمیل برنامه

در این مرحله تابع خواندن از صفحه کلید ۴ در ۴ را اضافه کرده و برنامه را به صورت زیر کامل می کنیم :

مرحله چهارم : شبیه سازی

بعد از اضافه کردن فایل hex در نرم افزار پروتئوس برنامه را run می کنیم .

Atmega32_Mesal4_proteus

نکته : در هنگام پیاده سازی دقت داشته باشید که پورت C تنها زمانی در دسترس است که فیوزبیت JTAGEN غیرفعال باشد.

دانلود مثال عملی شماره ۴

 


 معرفی و تشریح واحد وقفه های خارجی

اساسا وقفه زمانی مورد نظر می باشد که دستگاههای جانبی متعددی کنار میکرو وجود داشته باشد . برای سرویس دهی به وسایل جانبی که در اطراف میکروکنترلر می باشد ، دو روش وجود دارد . روش اول سرکشی منظم به دستگاههای جانبی موجود و روش دوم مراجعه به آن دستگاه فقط در زمان بروز وقفه می باشد .

در حالت سرکشی میکرو طوری برنامه نویسی شده است که دائما واحد جانبی مورد نظر را بررسی کند و با آن ارتباط برقرار می کند . برای مثال وقتی که یک صفحه کلید به میکرو متصل کردیم ، میکرو توسط تابعی به نام keyboard که در حلقه نامتناهی نوشته شده بود ، دائما تمام کلیدهای صفحه کلید را بررسی می کرد تا اینکه کاربر کلیدی را وارد کند و …

اما در هنگام بروز وقفه ، پردازنده کار فعلی خود را رها کرده و به اجرای وقفه مورد نظر می پردازد . علت بوجود آمدن واحد کنترل وقفه این است که باعث می شود پردازنده کمتر درگیر شود . در حالتی وقفه وجود نداشته باشد ، پردازنده مجبور است طی فواصل زمانی مشخصی چندین بار به واحد مورد نظر سرکشی کرده و بررسی کند که دیتای خواسته شده از آن واحد آماده است یا خیر که اغلب آماده نبوده و وقت پردازنده تلف می شود . اما در حالتی که واحد وقفه فعال است ، پردازنده آزاد است تا زمانی که دیتای واحد مورد نظر آماده شود. سپس واحد وقفه یک سیگنال وقفه به پردازنده مبنی بر آماده بودن دیتا ارسال می کند تا پردازنده متوجه شده و دیتا را پردازش کند .

 

انواع منابع وقفه در میکروکنترلرهای AVR

منبع وقفه در میکروکنترهای AVR دو نوع می باشد : ۱-داخلی ۲-خارجی
۱-وقفه داخلی : تقریبا تمام امکانات داخلی میکرو دارای وقفه بوده مانند تایمر/کانترها و پروتکل های ارتباطی و مقایسه کننده ها و مبدل آنالوگ به دیجیتال . یعنی مثلا وقتی که میکرو مقدار آنالوگ را ابه دیجیتال تبدیل کرده و کارش تمام شد ، وقفه را فعال می کند و برنامه ای را که در تابع سابروتین وقفه نوشتیم انجام می دهد و بعد ادامه ی برنامه را اجرا می کند. هر کدام از این وقفه ها را در محل مربوطه توضیح خواهیم داد.
۲-وقفه خارجی : در میکرو پایه هایی به نام INTx وجود دارد که زمانی تحریک شوند میکرو به تابع سابروتین وقفه پرش می کند و برنامه نوشته شده را اجرا می کند . این وقفه ها می توانند با یک لبه بالا رونده یا پایین رونده و یا یک منطقی تحریک شوند .

نکته : در میکروکنترلر Atmega32 تعداد ۱۸ منبع وقفه داخلی و ۳ منبع وقفه خارجی وجود دارد .

 

راه اندازی واحد وقفه خارجی در Atmega32 :

در میکروکنترلر Atmega32 سه وقفه خارجی به نامهای INT0 ( پایه ۱۶ ) ، INT1 ( پایه ۱۷ ) و INT2 ( پایه ۳ ) وجود دارد .

با فعالسازی یک یا چند وقفه خارجی در سربرگ External IRQ در برنامه CodeWizard ، پایه مربوطه به آن به عنوان ورودی تنظیم می شود . سپس بر اساس تنظیمات دلخواه کاربر وقفه میتواند در یکی از ۴ حالت مختلف زیر رخ دهد :

  • وقفه در لبه بالا رونده پالس ورودی رخ دهد .
  • وقفه در لبه پایین رونده پالس ورودی رخ دهد .
  • وقفه در سطح منطقی ۰ رخ دهد .
  • وقفه در هر تغییر ۰ به ۱ یا بالعکس رخ دهد .

Interrupt_Codewizard

نکته : شکل لبه ها و سطوح پالسی را در یک سیگنال دیجیتال نمونه ، نشان می دهد.

pulse_edge

تذکر : وقتی از کلید و مقاومت پول آپ شده استفاده می شود بهتر است وقفه در لبه پایین رونده رخ دهد.

با فعال کردن و انجام تنظیمات واحد وقفه خارجی در کدویزارد یک تابع به ابتدای برنامه اضافه می شود که تابع سابروتین وقفه نام دارد . زمانی که وقفه خارجی روی پایه ی مورد نظر رخ دهد ، میکرو در هر کجای اجرای برنامه اصلی در حلقه while نامتناهی که باشد کار خود را رها کرده و تابع سابروتین وقفه را اجرا می کند و بعد از پایان تابع سابروتین وقفه به همان مکان از برنامه اصلی بر میگردد و ادامه برنامه را اجرا می کند .

نکته : برای فعال سازی و غیرفعالسازی کلیه وقفه ها با هم ، از دستورات اسمبلی زیر استفاده می شود . خط اول اجازه سراسری فعالسازی وقفه خارجی را می دهد یعنی فقط بعد از آن وقفه اجازه رخ دادن دارد. برای غیر فعال کردن وقفه در برنامه از عبارت خط دوم استقاده می شود . معمولا در ابتدای سابروتین وقفه ، وقفه را غیر فعال کرده و در پایان سابروتین ، وقفه را دوباره فعال می کنند تا از بروز وقفه مجدد زمانی که برنامه درون تابع سابروتین وقفه قرار دارد جلوگیری شود .

#asm(“sei”);  //set enable interrupt

 #asm(“cli”);  //clear interrupt


 مثال عملی شماره ۵

یک LCD کاراکتری ۲ در ۱۶ و یک صفحه کلید ۴ در ۴ به روش وقفه به میکروکنترلر متصل کرده و برنامه ای بنویسید که با فشار دادن هر کلید کاراکتر مربوطه روی نمایشگر چاپ شود .

حل :

مرحله اول : طراحی سخت افزار در پروتئوس

در این مرحله باید سخت افزاری را طراحی کنیم تا به محض اینکه هر یک از کلید ها توسط کاربر زده شود ، پالس وقفه ایجاد شود و برنامه به تابع سابروتین وقفه برود و در آنجا اینکه کدام کلید زده شده محاسبه گردد و چاپ شود . روش های متفاوتی برای تولید پالس وقفه وجود دارد با استفاده از دیود ، گیت های منطقی و … است اما در این طراحی از یک گیت NOR با ۴ ورودی ( آی سی ۷۴۴۰ ) و اتصال آنها به سطرهای صفحه کلید ( ورودی های پول آپ شده میکرو ) به صورت شکل زیر استفاده کردیم .

Atmega32_Mesal5

مرحله دوم : انجام تنظیمات در کدویزارد

Mesal5_Codewizard

مرحله سوم : تکمیل برنامه

بعد از تولید کدهای اولیه توسط کدویزارد برنامه را به صورت زیر تکمیل می کنیم :

تمرین: این برنامه را با برنامه مثال قبل مقایسه کنید .

 

مرحله چهارم : شبیه سازی

Mesal5_Proteus

دانلود مثال عملی شماره ۵

 


 معرفی و تشریح واحد مبدل آنالوگ به دیجیتال ADC

واحد مبدل سیگنال‌های آنالوگ به دیجیتال (Analog to Digital Converter=ADC)، مداری الکترونیکی است که سیگنال‌های پیوسته آنالوگ را به داده‌های گسسته دیجیتالی تبدیل می‌کند. همانطور که میدانید تمامی کمیت های فیزیکی ، آنالوگ هستند. کمیت های آنالوگ برای پردازش توسط میکروکنترلر ابتدا می بایست تبدیل به دیجیتال ( 0 و 1 ) شوند. تبدیل ولتاژ ورودی آنالوگ به کد دیجیتال متناسب با آن ولتاژ ورودی توسط این واحد انجام می پذیرد.

adc_in_out

در هر مبدل آنالوگ به دیجیتال شش مساله اساسی زیر وجود دارد:

  1. ولتاژ مرجع ( reference Voltage ) : که حداکثر ولتاژ قابل نمونه برداری را مشخص می کند .
  2. رزولوشن یا دقت نمونه برداری ( Resolution ) : تعداد بیت های خروجی دیجیتال به توان دو ، دقت نمونه برداری را مشخص می کند .
  3. نرخ نمونه برداری ( Sample Rate ) : یعنی فرکانس نمونه برداری که تعداد نمونه برداری از ولتاژ آنالوگ در واحد زمان است .
  4. تعداد کانال ها ( channels ) : تعداد ولتاژهای آنالوگی که مبدل میتواند به عنوان ورودی آنالوگ به صورت مجزا به دیجیتال تبدیل کند .
  5. ضریب بهره کانال ( gain ) : که مشخص می کند ورودی آنالوگ قبل از تبدیل به دیجیتال در چه عددی ضرب شود ( برای سیگنال های ضعیف کاربرد دارد ).
  6. روش نمونه برداری ( ADC type ) : به طور کلی ۶ روش زیر برای تبدیل سیگنال های آنالوگ به دیجیتال وجود دارد :
  • روش موازی یا همزمان
  • روش پله ای
  • روش تقریب متوالی ( Successive Approximation )
  • روش تک شیب
  • روش دو شیب
  • روش تبدیل ولتاژ به فرکانس

 

تذکر : در کلیه میکروکنترلرهای AVR از روش تقریب متوالی در مبدل ADC استفاده شده است .

 


ولتاژ مرجع واحد ADC در AVR

در یکی از سه حالت زیر میتواند قرار گیرد :

  • AVCC : یعنی همان ولتاژ تغذیه واحد که به پایه تغذیه آنالوگ یا AVCC متصل می شود.
  • AREF : ولتاژ مرجع خارجی که ولتاژی دلخواه بین ۰ تا Vcc است و به پایه AREF متصل می شود.
  • داخلی internal : ولتاژی داخلی است که مقدار آن ثابت و برابر ۲٫۵۶ ولت است.

 

نکته : اگر از ولتاژ مرجع داخلی استفاده می کنید باید یک خازن ۱۰۰ نانو فاراد بین پایه AREF با زمین قرار دهید.

 

دقت نمونه برداری واحد ADC در AVR

دقت کلیه میکروکنترلرهای AVR در حالت ۸ بیتی یا ۱۰ بیتی قابل تنظیم می باشد .

 

 سرعت نمونه برداری واحد ADC در AVR

در میکروکنترلرهای AVR سرعت نمونه برداری حداکثر ۱۵ هزار نمونه در ثانیه ( ۱۵KSPS ) است .

 

تعداد کانال ها و بهره واحد ADC در میکروکنترلرهای AVR

در میکروکنترلرهای مختلف متفاوت است برای مثال Atmega32 دارای ۸ کانال مجزا ( از پایه های ADC0 تا ADC7 ) و atmega8 دارای ۶ کانال مجزا می باشد .

فرکانس کار واحد ADC در AVR :

فرکانس پالس واحد مبدل ADC طبق پیشنهاد شرکت Atmel باید بین ۵۰ کیلوهرتز تا ۲۰۰ کیلو هرتز باشد ( بازه مجاز ) . این فرکانس که تقسیمی قابل تنظیم از کلاک اصلی میکرو است ، بسته به نیاز کاربرد مورد نظر باید روی یک مقدار خاصی تنظیم شود.

 

نکته : برای استفاده از این واحد ابتدا باید تغذیه آن ( پایه های ۳۰ و ۳۱ ) را وصل نمود . برای اینکه نویز محیط روی عملکرد این واحد تاثیر کمتری بگذارد شرکت atmel مدار زیر را برای اتصال تغذیه این واحد پیشنهاد می کند که یک فیلتر متشکل از سلف ۱۰ میکروهانری و خازن ۱۰۰ نانو فاراد مطابق اتصالی به صورت شکل زیر است .

ADC_NoiseCanceler


تنظیمات CodeWizaed برای راه اندازی واحد ADC

در نرم افزار به سربرگ ADC رفته و پس از فعالسازی باید ولتاژ مرجع و کلاک را در قسمت های مربوطه مشخص کرد. همانطور که میدانید واحد ADC دارای یک رجیستر ۱۰ بیتی است که میتوان با تیک زدن گزینه Use 8 Bit تنها از ۸ بیت آن استفاده کرد. با استفاده از ۸ بیت دقت ADC کم میشود. همچنین قابلیت ایجاد وقفه نیز با زدن تیک مربوطه فعال می شود ( معمولا نیازی به فعالسازی آن نیست )

adc_codewizard

پس از تولید کد تابع read_adc به برنامه اضافه می شود که از این تابع میتوان در برنامه هنگام نیاز به مبدل ADC استفاده کرد. برای استفاده از این تابع کافیست تا شماره یکی از ۸ کانالی که میخواهیم را در تابع قرار داده تا کد ۱۰ یا ۸ بیتی تبدیل شده به دیجیتال را در خروجی تابع تحویل دهد.

برای مثال زمانی که ولتاژ مرجع را 5 ولت در نظر بگیریم و از دقت 10 بیتی استفاده نماییم، رابطه ورودی و خروجی، مشابه شکل زیر می شود. که در آن بازه مجاز ورودی آنالوگ بین 0 تا 5 ولت است و عدد دیجیتال در خروجی بین 0 تا 210-1=1023 متناسب با ورودی تغییر می کند.

adc_code

اما برای استفاده از کد دیجیتال خروجی در برنامه، و فهمیدن مقدار ولتاژ آنالوگی که در ورودی بوده است از فرمول زیر استفاده می شود. که در آن n دقت نمونه برداری و برابر ۱۰ یا ۸ است ، Vref برابر مقدار ولتاژ رفرنس و channel شماره کانال ورودی ( عددی بین ۰ تا ۷) است.

تعریف ضریب تفکیک : ضریب تفکیک مشخص می کند که حساسیت واحد ADC چقدر است یعنی به ازای چقدر تغییر در سیگنال آنالوگ ورودی ، عدد دیجیتال خروجی مبدل ADC ، یک واحد تغییر می کند .

ADC_Formules


 مثال عملی شماره ۶

با استفاده از یک سنسور دماسنج LM35 و LCD کاراکتری ۲ در ۱۶ برنامه دماسنج دیجیتال را بنویسید .

حل :

راه اندازی سنسور LM35 : خروجی این سنسور ولتاژی از نوع آنالوگ می باشد که در دمای ۰ درجه ، ولتاژ پایه خروجی آن نیز ۰ می شود و به ازای افزایش هر درجه سانتی گراد دمای محیط اطرافش ، خروجی سنسور ۱۰ میلی ولت افزایش پیدا می کند. ( برای مثال در دمای 25 درجه اتاق می شود 250 میلی ولت ). پایه های این سنسور به صورت شکل زیر است :

LM35

اگر به دیتاشیت این آی سی مراجعه نماییم، مدار های مختلفی برای کار در دماهای مختلف پیشنهاد کرده است. برای دماهای بین 2 تا 150 درجه میتوان از مدار شکل زیر استفاده کرد:

LM35

مرحله اول : طراحی سخت افزار

Atmega32_Mesal6

مرحله دوم : تنظیمات کدویزارد

بعد از انجام تنظیمات سربرگ های chip ، port و Alphanumeric LCD به همان صورت مثال شماره ۴ به سربرگ ADC رفته و تنظیمات را به صورت زیر انجام می دهیم :

Mesal6_Codewizard

نکته : با قرار دادن ولتاژ مرجع واحد ADC روی ولتاژ داخلی 2.56 ولت، ضریب تفکیک نسبت به حالت ولتاژ مرجع 5 ولت کوچکتر می شود و در نتیجه حساسیت دماسنج بهتر می شود.

مرحله سوم : تکمیل برنامه

توضیح : بعد از حذف کامنت ها و برنامه های اضافی از برنامه تولید شده توسط کدویزارد ، ضریب تفکیک را از رابطه گفته شده بر حسب میلی ولت تقریبا ۲٫۵۰ محاسبه می کنیم اما عددی که باید نمایش دهیم ولتاژ نیست بلکه دماست پس چون به ازای هر ۱۰ میلی ولت باید دما یک واحد افزایش یابد یعنی به ازای ۴ برابر ضریب تفکیک بنابراین در برنامه عدد دیجیتال گرفته شده را تقسیم بر ۴ می کنیم .

 

مرحله چهارم : شبیه سازی

بعد از اضافه کردن فایل hex در نرم افزار پروتئوس برنامه را run می کنیم .

Atmega32_Mesal6_Proteus

دانلود مثال عملی شماره۶

 


با کلیک بر روی تصویر زیر به بخش بعدی آموزش بروید

next-image



در صورتی که این مطلب مورد پسندتان بود لایک و اشتراک گذاری فراموش نشود.

دیدگاه (17)

  • hameddd پاسخ

    سلام
    فک کنم توی مثال عملی 4 توی تنظیمات کدویزارد وقتی پورتD رو تنظیم کردین جای سطرو و ستونو برعکس وارد کردین.

    1394-12-16 در 08:10
    • محمد حسین پاسخ

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

      1394-12-16 در 19:49
  • hameddd پاسخ

    سلام
    یه توضیح کلی در مورد پایه های vcc و gnd و aref واحد adc میدین؟
    avcc و gnd همیشه باید وصل باشه؟
    aref هم وقتی ولتاز مرجع aref یا internal میشه وصل میشه؟
    خازنی که گفتین 100نانو فاراد از نوع عدسی هست؟

    1395-01-01 در 05:13
    • محمد حسین پاسخ

      سلام دوست عزیز تغذیه واحد ADC و ولتاژ مرجع آن Vref در صورت استفاده از ADC باید وصل شوند که در بالا توضیح داده شده است. بله عدسی

      1395-01-01 در 15:28
  • hameddd پاسخ

    سلام
    آقا محمد حسین من یه برنامه نوشتم برا دما با سون سگمنت
    کار میکنه فقط مثلا دما تغییر میکنه مثلا از 13 به 14 این سون سگمنت هی بین 13 و 14 عوض میشه تا اینکه پایدار بشه
    میخاستم بدونم این خاصیت lm35 هستش یا اینکه تو برنامم یه شرط باید بزارم که مثلا تا تغییر نکرده دما همون عدد.و هی نشون بده!!!

    1395-01-02 در 14:47
    • محمد حسین پاسخ

      سلام دوست عزیز تاخیر موجود در برنامه را کمی بیشتر کنید تا مثلا در هر ثانیه یک بار مقدار LM35 را دریافت و نمایش دهد

      1395-01-03 در 18:26
  • مرتضی پاسخ

    با سلام
    من در بخش adcاز مد تحریک اینتراپت خارجی صفر استفاده کردم و در پروتئوس ام امتحان کردم اما وقتی پروگرام میکنم عملا هیچ جوابی نمی دهد اما از مد free که استفاده میکنم جواب میدهد
    مشکل کجاست لازم به ذکر است که از میکرو amega16استفاده میکنم
    ممنون از وقتی که میگذارید

    1395-02-05 در 07:42
    • محمد حسین پاسخ

      سلام دوست عزیز مبحث اینتراپت خارجی به طور کلی تفاوت دارد با مبحث ADC و نمیتوانید از اینتراپت خارجی و ADC به طور همزمان استفاده کنید زیرا هر پایه فقط یک عملکرد میتواند داشته باشد. برای فعالسازی وقفه ADC در کدویزارد کافی است تا تیک گزینه interrupt را بزنید و در برنامه تولید شده تابع اینتراپت بوجود می آید و درون آن برنامه دلخواه نوشته می شود.

      1395-02-06 در 05:34
      • مرتضی پاسخ

        میبخشید منظور استفاده از مد single در ADC در Atuo trigger source قسمت External IRQ0 رو عرض میکنم

        1395-02-07 در 05:11
  • حجت پاسخ

    سلام.من برنامه کیپد رو کامل نوشتم اما موقع اجرا سه تا ارور میده که دو تاش undefined symbol c هستش.برنامم مطابق مطلب شماست .کامل.مشکل چیه؟؟؟
    ارور بعدی هم اونجایی که نوشتم unsigned char c تو ارور میگه [ expected
    مشکل چیه؟؟؟لطفا پاسخ بدید

    1395-04-25 در 08:16
    • شجاع داودی پاسخ

      سلام دوست عزیز در تایپ کردن اشتباه بوجود اومده . یک متغیر وجود داره که در برنامه تعریف نکردید. یک جایی از برنامه هم یک پرانتز زیاد یا کم گذاشتید.

      1395-04-26 در 06:37
  • hanieh پاسخ

    با تشکر از مطالب بسیار بسیار مفیدی که گذاشتید.موفق و پیروز باشیییییییییییییییییییییید

    1395-09-06 در 05:08
  • مهدی پاسخ

    برای atmega32 چه پروگرامری با قیمت خوب استفاده کنم؟

    1395-10-30 در 10:10
    • ادمین الکترو ولت پاسخ

      USBasp

      1395-10-30 در 15:07
  • مهدی فروغی پاسخ

    سلام
    ممنون از جزوه ی خوبتون
    میبخشید من ابتدای کار همه ی مراحل ساخت پروژه را انجام میدم و قبل از نوشتن برنامه/سراغ تنظیمات کد ویزارد میرم

    فقط قسمت شماره ی 5 در صفحه ی 160 جزوه رو متوجه نمیشم( اکنون سه بار باید فایل های مربوط به پروژه را با نام ترجیحا یکسان ذخیره کنید. در پنجره اول اسمی برای فایل با پسوند c. وارد می کنیم و ذخیره می کنیم و همین طور در پنجره های بعدی برای codeWizardAVR وproject نام وارد کرده و ذخیره کنید.)

    من اماتور هستم و لطفا این قسمت رو کمک کنید.
    خودم اقداماتی انجام دادم و کدویزارد کد های مربوطه را ایجاد کرد ولی موقع boild فایل hex ساخته نشد و ارور L1 : not expected میده پایین قسمت فایل با پسوند .c

    با تشکر از وقتی ک میگذارین…

    1396-05-10 در 15:33
    • مهدی فروغی پاسخ

      میبخشید مشکلم حل شد
      توی کد ویزارد پرت adc با lcd تداخل داشته ….

      1396-05-10 در 15:45
      • ادمین الکترو ولت پاسخ

        خواهش میکنم موفق باشید

        1396-05-11 در 18:00

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *

بازگشت به آموزشگاه