برنامه نویسی Atmega8 برنامه نویسی میکروکنترلرهای AVR رابط MK در حالت برنامه نویسی

برای انتقال از کامپیوتر به میکروکنترلر به USBasp و برنامه AVRDUDE نیاز داریم.امروزه انتخاب گسترده ای از برنامه نویسان برای برنامه نویسی طراحی شده اند میکروکنترلرهای AVR. در میان آنها می توانید بسیاری از موارد خانگی را پیدا کنید که حتی نمی توان آنها را برنامه نویس نامید، زیرا آنها مستقیماً با استفاده از چند مقاومت به پورت COM متصل می شوند. با این حال کامپیوترهای مدرنو لپ‌تاپ‌ها عملاً دیگر به پورت‌های COM مجهز نیستند، بنابراین یکی از معیارهای اصلی هنگام انتخاب برنامه‌نویس، قابلیت اتصال آن به پورت USB. ارزان ترین، ساده ترین و رایج ترین برنامه نویس USBasp است. تقریباً می توان آن را در هر فروشگاه رادیویی خریداری کرد قیمت قابل قبول. هزینه آن است اینترنت چینیقیمت این فروشگاه بین 1.5 تا 3 دلار است.

برنامه نویس USBasp

کامپیوتر با استفاده از برنامه نویس USBasp از طریق پورت USB با میکروکنترلر ارتباط برقرار می کند و داده ها از طریق رابط منتقل می شوند. SPI اس erial پ محیطی من رابط(رابط جانبی سریال). برای برقراری ارتباط MK با برنامه نویس، از پین های مخصوص استفاده می شود: MOSI، MISO، SCK، RESET، VCC، GND. با اينكه SPI استفاده از تنها سه پایه MOSI، MISO و SCK را فرض می کند، اما ما از هر شش پایه استفاده خواهیم کرد.

هنگام تبادل داده ها از طریق رابط SPI میکروکنترلر می تواند به طور همزمان یا دریافت (پاین MISO) و یا انتقال داده (پایین MOSI). تنظیم حالت دریافت یا انتقال داده ها با اعمال یک پالس خاص به پین ​​SCK انجام می شود.

کانکتور پروگرامر، به طور معمول، دارای 10 پین است و با استفاده از یک کابل 10 سیم به میکروکنترلر متصل می شود. با این حال، استفاده از کابل هایی که دارای آداپتور 6 پین هستند راحت تر است، زیرا در این حالت همه پین ​​ها اشغال می شوند. برای یک کانکتور ده پین، یک پایه خالی می ماند و چهار پایه به سیم مشترک (GND) متصل می شوند.

برای اینکه کامپیوتر برنامه نویس را شناسایی کند، باید درایور USBasp را نصب کنید.

عکس پروگرامر متصل به میکروکنترلر ATmega8 در زیر نشان داده شده است.

تنها ایراد یا به عبارت بهتر، ناراحتی جزئی این برنامه نویس عدم پشتیبانی (بدون ترفندهای مختلف) توسط Atmel Studio است، بنابراین باید از آن استفاده کنید. برنامه شخص ثالث. اثبات شده ترین آنها AVRDUDE است.

تنظیمات

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

برای اطمینان از اینکه پروگرامر توسط سیستم عامل شناسایی شده است (درایور پروگرامر به درستی نصب شده است) و به درستی به میکروکنترلر متصل شده است، روی دکمه کلیک کنید. خواندن. اگر خطایی وجود نداشته باشد، پنجره ای با ورودی ظاهر می شود. سلول های کالیبراسیون ژنراتور خوانده شده اند!و عدد هگزادسیمال در پنجره بالا نمایش داده می شود. هر MK شماره مخصوص به خود را دارد.

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

حال بر روی دکمه Program در دسته بندی کلیک کنید فلاش. هنگامی که برنامه با موفقیت در MK ضبط شد، پنجره ای با ورودی زیر ظاهر می شود.

نتیجه برنامه ضبط شده یا همانطور که می گویند سیستم عامل یک LED روشن است که به پین ​​PC0 میکروکنترلر ما متصل است.

روز خوب. بیا ادامه بدهیم. بعد از اینکه با فرآیند اشکال زدایی برنامه ای که در "atmel studio" نوشتیم آشنا شدیم و به صورت مجازی یک مدار با یک LED را در "proteus" مونتاژ کردیم، نوبت به مونتاژ مدار در سخت افزار و فلش کردن میکروکنترلر رسید.

برای برنامه ریزی یک نمونه اولیه ( اتمگا 8) از برنامه نویس USBASP استفاده خواهیم کرد. به نظر می رسد این است:

یک کابل به کانکتور متصل می شود که جامپرها به آن متصل می شوند، که به نوبه خود به سوکت های تخته نان که میکروکنترلر روی آن نصب شده است وصل می شود:

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


بعد از اینکه برنامه نویس را فهمیدیم. بیایید به مونتاژ مدار در سخت افزار بپردازیم. میکروکنترلر را روی تخته نان نصب می کنیم. یادآوری می کنم که پایه اول روی MK با یک دایره کوچک مشخص شده است.

وظیفه اتصال پین های برنامه نویس به پین ​​های "سنگ" است.

جامپرها را به کانکتور 10 پین وصل می کنیم. ما از پین های زیر MOSI، RST، SCK، MISO، VTG (VCC)، GND استفاده می کنیم.

امیدوارم قبلاً دیتاشیت را در atmega8 دانلود کرده باشید. اگر نه، می توانید آن را دانلود کنید. ما به پایه پین ​​های میکروکنترلر نگاه می کنیم.

ما جامپرها را به پین ​​های زیر وصل می کنیم:

  • VCC به پین ​​7 MK؛
  • SCK به پین ​​19 MK؛
  • MISO به پین ​​18 MK؛
  • MOSI به پین ​​17 MK؛
  • GND (پایه برنامه نویس 10) به پایه 8 MK؛
  • RST تا 1 پین MK؛

برای عملکرد موفقیت آمیز بیشتر، سیستم عامل، هنگام راه اندازی ماشین شیطان (برنامه نویس) برای اولین بار، نصب درایورهای لازم برای عملکرد دستگاه را پیشنهاد می کند.

هنگام کار با تسریع کننده نباید هیچ مشکلی وجود داشته باشد. دانلود. پوشه ای ایجاد کنید که آرشیو دانلود شده را در آن باز کنیم. سپس در Hardware Installation Wizard مسیر پوشه با درایور زیپ نشده را مشخص می کنیم.

اگر از ویندوز 7 یا بالاتر استفاده می کنید، ممکن است با مشکلات جزئی مواجه شوید. درایورهای برنامه نویس کاملا قدیمی هستند، بنابراین ندارند امضای دیجیتالی. وقتی می خواهید چنین درایوری را نصب کنید، سیستم عامل چیزی شبیه به این نمایش می دهد *

امضای دیجیتال رانندگان مورد نیاز برای از این دستگاه. در آخرین تغییرتجهیزات یا نرم افزارامضا نادرست یا فایل آسیب دیدهیا بد افزارمنشا ناشناخته (کد 52).

برای اصلاح وضعیت، باید تأیید امضای دیجیتال راننده را غیرفعال کنید. من نحوه غیرفعال کردن آن را توضیح نمی دهم (هرکسی سیستم عامل خود را دارد)، آنها را می توان در اینترنت یافت.

پس از غیرفعال کردن تأیید امضا، در Hardware Installation Wizard، مسیر پوشه را با درایور زیپ نشده مشخص کنید.

امیدوارم همه چیز برای شما درست شده باشد و برنامه نویس آماده کار باشد.

بیایید به مونتاژ مدار با LED برویم.

برای فلش کردن سیستم عامل میکروکنترلر از برنامه "avrdudeprog" استفاده می کنیم. در آرشیو عمومی موجود است.

از لیست میکروکنترلرها، atmega8 را انتخاب کنید. پس از انتخاب MK، پنجره ای ظاهر می شود که به شما اطلاع می دهد که فیوز و بیت قفل به طور پیش فرض تنظیم شده اند.

سپس تب Fuses را باز کنید. به زبان سادهفیوزها تنظیمات پیکربندی MK هستند که بهتر است با آنها بازی نکنید. برای مواردی که شما همان کنترل کننده من را خریداری کردید و تشدید کننده کوارتز خارجی ندارید (از نوسانگر داخلی استفاده می کنید فرکانس ساعت، دقیقاً همان کادرهایی را که در تصویر نشان داده شده است علامت بزنید. باید یک علامت تیک در کنار مورد "معکوس" وجود داشته باشد.

تنظیمات پیکربندی شده به Atmega8A دستور می دهد تا کار خود را با توجه به کلاک از نوسانگر داخلی (فرکانس کلاک 8 مگاهرتز) انجام دهد. برای اینکه تنظیمات اعمال شوند، باید روی دکمه "برنامه نویسی" کلیک کنید. اما قبل از فشار دادن، دوباره بررسی کنید که همه چیز به درستی تنظیم شده باشد.

به صفحه "برنامه" بازگردید.

بعد از اینکه قبلاً به برنامه گفتیم که کدام میکروکنترلر را فلش می کنیم، فایل سیستم عاملی را که در درس گذشته نوشتیم انتخاب می کنیم. دارای پسوند HEX است. در پوشه "Debug" قرار دارد

قبل از چشمک زدن "پبل"، روی دکمه "پاک کردن همه چیز" کلیک کنید. این شما را از اشتباهات غیرقابل درک محافظت می کند (اگر سنگ قبلاً دوخته شده باشد چه می شود):

ما از نتیجه کارمان لذت می بریم :) ادامه دارد...

من بیش از یکی دو بار گفته ام که مطالعه MK باید با اسمبلر شروع شود. یک دوره کامل در وب سایت به این اختصاص داده شده است (اگرچه خیلی سازگار نیست، اما به تدریج آن را به یک ظاهر مناسب تبدیل می کنم). بله، دشوار است، نتیجه در روز اول نخواهد بود، اما شما یاد خواهید گرفت که بفهمید در کنترلر خود چه اتفاقی می افتد. شما خواهید دانست که چگونه کار می کند، و مانند یک میمون از منابع دیگران کپی نکنید و سعی کنید بفهمید که چرا ناگهان کار نمی کند. علاوه بر این، برای C بسیار ساده تر است که کد redneck ایجاد کند که در نامناسب ترین لحظه با یک pitchfork بیرون بیاید.

متأسفانه همه خواهان نتیجه فوری هستند. بنابراین تصمیم گرفتم راه دیگری را بروم - یک آموزش در C، اما با نشان دادن لباس زیر او. یک برنامه نویس امبددر خوب همیشه قطعه سخت افزاری خود را محکم با پیچ و مهره نگه می دارد و اجازه نمی دهد یک قدم بدون اجازه بردارد. بنابراین ابتدا کد C وجود خواهد داشت، سپس کامپایلر چه چیزی را تولید کرده و واقعاً چگونه کار می کند :)

از سوی دیگر، شی نقطه قوتاین قابلیت حمل کد است. البته اگر همه چیز را درست بنویسید. تفکیک الگوریتم های کار و پیاده سازی سخت افزاری آنها در قسمت های مختلف پروژه. سپس، برای انتقال الگوریتم به یک میکروکنترلر دیگر، کافی است فقط لایه رابط را بازنویسی کنید، جایی که همه تماس‌های سخت‌افزاری در آن نوشته شده‌اند، و همه کدهای کار را به همان صورت باقی بگذارید. و البته خوانایی. کد منبع C در نگاه اول راحت تر قابل درک است (اگرچه... برای مثال، برایم مهم نیست که به چه چیزی اشاره کنم - C یا ASM :))، اما اگر همه چیز به درستی نوشته شده باشد. من هم به این نکات توجه خواهم کرد.

سهم شیر همه نمونه ها به عنوان قطعه آزمایشی که سهم شیر همه نمونه ها روی آن نصب می شود، متعلق به من خواهد بود. هیئت توسعه.

اولین برنامه C برای AVR

انتخاب کامپایلر و تنظیم محیط
کامپایلرهای C زیادی برای AVR وجود دارد:
اول از همه این IAR AVR C- تقریباً به طور قطع به عنوان بهترین کامپایلر برای AVR شناخته می شود، زیرا خود کنترلر با همکاری نزدیک بین Atmel و متخصصان IAR ایجاد شد. اما شما باید برای همه چیز هزینه کنید. و این کامپایلر نه تنها یک نرم افزار تجاری گران قیمت است، بلکه دارای تنظیمات بسیار زیادی است که برای کامپایل کردن آن به سادگی در آن تلاش زیادی می شود. من واقعاً با او دوستی نداشتم؛ پروژه به دلیل خطاهای عجیب در مرحله پیوند در حال پوسیدگی بود (بعداً متوجه شدم که یک شکاف کج بود).

دوم می آید WinAVR GCC- یک کامپایلر بهینه سازی قدرتمند کاملا متن باز، کراس پلتفرم، به طور کلی، تمام لذت های زندگی. همچنین کاملاً با آن ادغام می شود AVR Studioبه شما امکان می دهد همان جا اشکال زدایی کنید، که بسیار راحت است. در کل من آن را انتخاب کردم.

نیز وجود دارد CodeVision AVR Cیک کامپایلر بسیار محبوب است. به دلیل سادگی اش محبوب شد. برنامه کارشما می توانید آن را تنها در چند دقیقه دریافت کنید - جادوگر کد شروع تا حد زیادی به این امر کمک می کند، استانداردهای اولیه برای شروع انواع uarts را مهر و موم می کند. صادقانه بگویم، من به نوعی به آن مشکوک هستم - زمانی که مجبور شدم برنامه ای را که توسط این کامپایلر نوشته شده بود را از بین ببرم، معلوم شد که یک جور آشفتگی است و کد نیست. حجم وحشتناکی از حرکات و عملیات غیر ضروری که منجر به مقدار قابل توجهی کد و عملکرد کند شد. با این حال، ممکن است در DNA شخصی که فریمور اصلی را نوشته است، خطایی وجود داشته باشد. به علاوه او پول می خواهد. نه به اندازه IAR، اما قابل توجه است. و در حالت دمو به شما امکان می دهد بیش از 2 کیلوبایت کد بنویسید.
البته یک شکاف وجود دارد، اما اگر قصد سرقت دارید، یک میلیون است، به معنای IAR :)

نیز وجود دارد Image Craft AVR Cو میکرو سیاز میکروالکترونیک من مجبور نبودم از هیچکدام استفاده کنم، اما S.W.G.بسیار تحسین برانگیز میکرو پاسکالآنها می گویند، یک محیط برنامه نویسی و کتابخانه های فوق العاده راحت. فکر می‌کنم MicroC بدتر نخواهد بود، اما پولی نیز دارد.

همانطور که گفتم من انتخاب کردم WinAVRبه سه دلیل: رایگان است، در AVR Studio ادغام می شود و برای آن نوشته شده است. کد آمادهبرای همه مناسبت ها

بنابراین نصب WinAVR را با AVR Studio دانلود کنید. در مرحله بعد، ابتدا استودیو نصب می شود، سپس WinAVR در بالا رول می شود و به صورت یک پلاگین به استودیو متصل می شود. من به شدت توصیه می کنم WinAVR را در یک مسیر کوتاه نصب کنید، چیزی مانند C:\WinAVR، به این ترتیب از مشکلات زیادی در مسیرها جلوگیری می کنید.

ایجاد یک پروژه
بنابراین، استودیو نصب شده است، C پیچ می شود، وقت آن است که سعی کنید چیزی را برنامه ریزی کنید. بیایید با ساده ترین، ساده ترین شروع کنیم. یک استودیو راه اندازی کنید، آنجا را انتخاب کنید پروژه جدید، به عنوان کامپایلر AVR GCC و نام پروژه را وارد کنید.

یک فیلد کاری با یک فایل *.c خالی باز می شود.

اکنون پیکربندی نمایش مسیرها در نشانک‌های استودیو ضرری ندارد. برای این کار به آدرس زیر بروید:
Menu Tools - Options - General - FileTabs و گزینه "Filename Only" را از لیست کشویی انتخاب کنید. در غیر این صورت، کار غیرممکن خواهد بود - برگه شامل مسیر کامل فایل خواهد بود و بیش از دو یا سه برگه روی صفحه وجود نخواهد داشت.

راه اندازی پروژه
به طور کلی، ایجاد یک فایل make که در آن تمام وابستگی ها توضیح داده شده است، کلاسیک در نظر گرفته می شود. و احتمالاً درست است. اما برای من که با IDE های کاملاً یکپارچه مانند بزرگ شدم uVisionیا AVR Studioاین رویکرد عمیقاً بیگانه است. بنابراین، من آن را به روش خودم انجام خواهم داد، همه چیز با استفاده از استودیو به معنی است.

دکمه را با چرخ دنده فشار دهید.


اینها تنظیمات پروژه شما یا بهتر است بگوییم تنظیمات تولید خودکار یک فایل ساخت هستند. در صفحه اول فقط باید فرکانس عملکرد MK خود را وارد کنید. این به بیت فیوز بستگی دارد، بنابراین ما فرکانس ما را 8000000 هرتز فرض می کنیم.
به خط بهینه سازی نیز توجه کنید. اکنون -Os وجود دارد - این بهینه سازی اندازه است. فعلاً آن را همانطور که هست بگذارید، سپس می توانید سعی کنید با این پارامتر بازی کنید. -O0 اصلا بهینه سازی نیست.

مرحله بعدی پیکربندی مسیرها است. اول از همه، دایرکتوری پروژه خود را در آنجا اضافه کنید - کتابخانه های شخص ثالث را در آنجا اضافه خواهید کرد. مسیر ".\" در لیست ظاهر می شود.

فایل Make ایجاد شده است، می توانید آن را در پوشه پیش فرض پروژه خود نگاه کنید، فقط نگاهی بیندازید و ببینید چه چیزی در آنجا وجود دارد.


فعلاً همین است. همه جا OK را کلیک کنید و به منبع بروید.

فرمول بندی مسئله
یک ورق کاغذ خالی وسوسه انگیز است که ایده ای حیله گرانه را اجرا کند، زیرا پلک زدن پیش پا افتاده یک دیود دیگر کار نمی کند. بیایید فوراً گاو نر را از شاخ بگیریم و اتصال را با رایانه پیاده سازی کنیم - این اولین کاری است که انجام می دهم.

به این صورت کار خواهد کرد:
وقتی یک (کد 0x31) به پورت COM می رسد، دیود را روشن می کنیم و وقتی صفر می رسد (کد 0x30) خاموش می شود. علاوه بر این، همه چیز در وقفه ها انجام می شود و وظیفه پس زمینه چشمک زدن یک دیود دیگر خواهد بود. ساده و معنی دار.

مونتاژ مدار
ما باید ماژول مبدل USB-USART را به پین ​​های USART میکروکنترلر متصل کنیم. برای این کار از دو سیم یک جامپر بردارید و به صورت ضربدری روی پین ها قرار دهید. یعنی Rx کنترلر را به Tx مبدل و Tx مبدل را به Rx کنترلر وصل می کنیم.

در پایان، این نمودار است:


من اتصال پین‌های باقی‌مانده، برق یا تنظیم مجدد را در نظر نمی‌گیرم، این استاندارد است.

کد نوشتن

اجازه دهید فوراً رزرو کنم که به طور خاص به توصیف خود زبان C نپردازم. صرفاً حجم عظیمی از مطالب برای این کار وجود دارد، از "زبان برنامه نویسی C" کلاسیک از K&R گرفته تا کتابچه های راهنمای مختلف.

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

درست است که هنوز همه فصل ها منتقل نشده اند، اما فکر می کنم خیلی طول نکشید.

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

افزودن کتابخانه ها
ابتدا کتابخانه ها و هدرهای لازم را با تعاریف اضافه می کنیم. از این گذشته، C یک زبان جهانی است و باید به او توضیح دهیم که به طور خاص با AVR کار می کنیم، بنابراین خط را در کد منبع بنویسید:

1 #عبارتند از

#عبارتند از

این فایل در پوشه قرار دارد WinAVRو شامل توضیحاتی در مورد تمامی رجیسترها و پورت های کنترلر می باشد. علاوه بر این، همه چیز حیله گر است، با اتصال به یک کنترلر خاص، که توسط کامپایلر از طریق انتقال داده می شود. ساختنفایل در پارامتر MCUو بر اساس این متغیر، یک فایل هدر به پروژه شما متصل می شود که آدرس تمام پورت ها و رجیسترهای این کنترلر خاص را شرح می دهد. وای! بدون آن، این امکان نیز وجود دارد، اما پس از آن نمی‌توانید از نام‌های ثبت نمادین مانند SREG یا UDR استفاده کنید و باید آدرس هر یک مانند «0xC1» را به خاطر بسپارید، که باعث سردرد خواهد شد.

خود تیم #عبارتند از<имя файла> به شما امکان می دهد هر نوع محتوایی را به پروژه خود اضافه کنید فایل متنیبه عنوان مثال، یک فایل با شرح توابع یا یک قطعه کد دیگر. و برای اینکه دستورالعمل بتواند این فایل را پیدا کند، مسیر پروژه خود را مشخص کردیم (دایرکتوری WinAVR قبلاً به طور پیش فرض در آنجا ثبت شده است).

عملکرد اصلی
یک برنامه C کاملاً از توابع تشکیل شده است. آنها را می توان تودرتو کرد و از یکدیگر به هر ترتیبی صدا زد راه های مختلف. هر تابع دارای سه پارامتر مورد نیاز است:

  • مقدار بازگشتی به عنوان مثال است. گناه (x)مقدار سینوس x را برمی گرداند. به طور خلاصه مانند ریاضیات.
  • پارامترهای ارسال شده همان X هستند.
  • بدن عملکرد.

همه مقادیر ارسال شده و برگردانده شده باید بسته به داده ها از نوعی باشند.

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

1 2 3 4 5 int main(void) (return 0 ; )

int main(void) (return 0; )

اول همین است ساده ترین برنامهنوشته شده است، مهم نیست که کاری انجام نمی دهد، ما تازه شروع کرده ایم.

بیایید بفهمیم چه کردیم.
بین المللیاین نوع داده ای است که تابع اصلی برمی گرداند.

البته در میکروکنترلر اصلیدر اصل هیچ چیز قابل بازگشت نیست و در تئوری باید وجود داشته باشد خالی اصلی (باطل)، اما GCC در ابتدا برای رایانه شخصی طراحی شده بود و در آنجا برنامه می تواند مقدار را برگرداند سیستم عاملپس از اتمام. بنابراین GCC روشن است خالی اصلی (باطل)قسم به هشدار.

این یک خطا نیست، کار خواهد کرد، اما هشدارها را دوست ندارم.

خالیاین نوع داده ای است که در این مورد به تابع ارسال می کنیم اصلیبنابراین نمی تواند چیزی را از بیرون بپذیرد خالی- یک ساختگی زمانی که نیازی به ارسال یا بازگرداندن چیزی نباشد از یک خرد استفاده می شود.

آن ها اینجا هستند { } بریس های فرفری یک بلوک برنامه هستند، در این مورد بدنه یک تابع اصلی، کد در آنجا قرار خواهد گرفت.

برگشت- این مقدار بازگشتی است که تابع main پس از تکمیل آن را برمی گرداند، زیرا ما یک int داریم، یعنی یک عدد، پس باید یک عدد را برگردانیم. اگرچه این هنوز منطقی نیست، زیرا ... در میکروکنترلر، ما فقط نمی توانیم از اصلی به جایی برسیم. من پوچ برمی گردم چون مهم نیست. اما کامپایلر معمولا هوشمند است و برای این مورد کد تولید نمی کند.
اگر چه، اگر منحرف، سپس از اصلیشما می توانید به MK بروید - به عنوان مثال، در بخش بوت لودر قرار بگیرید و آن را اجرا کنید، اما برای تصحیح آدرس های انتقال نیاز به دستکاری سطح پایین با سیستم عامل دارد. در زیر خودتان خواهید دید و متوجه خواهید شد که چگونه این کار را انجام دهید. برای چی؟ این یک سوال دیگر است، در 99.999٪ موارد این ضروری نیست :)

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

1 2 3 4 5 6 int main(void) (char i بدون علامت؛ بازگشت 0؛ )

int main(void) ( char i بدون علامت؛ بازگشت 0؛ )

بدون امضایعنی بدون امضا واقعیت این است که در نمایش باینری، مهم ترین بیت به علامت اختصاص می یابد، به این معنی که عدد +127/-128 در یک بایت (char) قرار می گیرد، اما اگر علامت کنار گذاشته شود، از 0 تا 255. معمولاً علامت لازم نیست. بنابراین بدون امضا.
منفقط یک نام متغیر است. بیشتر نه.

حال باید پورت ها را مقداردهی اولیه کنیم و UART. البته، می توانید کتابخانه را بگیرید و متصل کنید و نوعی UartInit (9600) را فراخوانی کنید. اما پس از آن شما نمی دانید واقعا چه اتفاقی افتاده است.

ما این کار را انجام می دهیم:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 int main(void) ( char i بدون علامت؛ #define XTAL 8000000L #define baudrate 9600L #define bauddivider (XTAL/(16*baudrate)-1)#define HI(x) ((x)>>8) #define LO(x) ((x)& 0xFF) UBRRL = LO(bauddivider) ; UBRRH = HI(bauddivider) ; UCSRA = 0 ; UCSRB = 1<< RXEN| 1 << TXEN| 1 << RXCIE| 0 << TXCIE; UCSRC = 1 << URSEL| 1 << UCSZ0| 1 << UCSZ1; }

int main(void) ( char i بدون علامت؛ #define XTAL 8000000L #define baudrate 9600L #define bauddivider (XTAL/(16*baudrate)-1) #define HI(x) ((x)>>>8) #define LO( x) ((x)& 0xFF) UBRRL = LO(bauddivider)؛ UBRRH = HI(bauddivider)؛ UCSRA = 0؛ UCSRB = 1<

ترسناک؟ در واقع، تنها پنج خط آخر کد واقعی وجود دارد. همه چیز، آن #تعريف كردناین یک زبان ماکرو پیش پردازنده است. تقریباً همان موارد در اسمبلی است، اما نحو کمی متفاوت است.

آنها عملیات معمول شما را برای محاسبه ضرایب لازم تسهیل می کنند. در سطر اول به جای آن می گوییم XTALمی توانید با خیال راحت 8000000 را جایگزین کنید، و L- نشانگر نوع، گفتن طولانی فرکانس ساعت پردازنده است. همینطور بادریت- فرکانس انتقال داده از طریق UART.

بوددیوادردر حال حاضر پیچیده تر است، به جای آن عبارت محاسبه شده با استفاده از فرمول دو فرمول قبلی جایگزین می شود.
خوب و L.O.و سلامبایت کم و زیاد از این نتیجه گرفته می شود، زیرا بدیهی است که ممکن است در یک بایت قرار نگیرد. که در سلام X (پارامتر ورودی ماکرو) هشت بار به سمت راست جابه جا می شود و در نتیجه تنها مهم ترین بایت باقی می ماند. و در L.O.با عدد 00FF به صورت بیتی AND انجام می دهیم، در نتیجه فقط بایت کم باقی می ماند.

بنابراین هر کاری که انجام می شود مانند است #تعريف كردنمی توانید با خیال راحت آن را دور بیندازید و اعداد لازم را روی یک ماشین حساب محاسبه کنید و بلافاصله آنها را در خطوط UBBRL = ... وارد کنید. و UBBRH = …..

می توان. ولی! این کار را انجام دهید کاملا غیر ممکن است!

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

سپس همه چیز ساده است:
همه این "UBRRL و Co" ثبت پیکربندی فرستنده UART هستند که با کمک آنها با جهان ارتباط برقرار خواهیم کرد. و اکنون مقادیر مورد نیاز را به آنها اختصاص داده ایم و آنها را روی سرعت و حالت دلخواه قرار می دهیم.

نوع ضبط 1<به معنی زیر است: 1 را بردارید و در جای خود قرار دهید RXENدر بایت RXENاین بیت چهارم ثبت است UCSRB، بنابراین 1<عدد باینری 00010000 را تشکیل می دهد، TXEN- این بیت 3 است و 1< 00001000 خواهد داد. تک "|" به صورت بیتی است یا، بنابراین 00010000 | 00001000 = 00011000. به همین ترتیب، بیت های پیکربندی لازم باقیمانده تنظیم شده و به هیپ عمومی اضافه می شوند. در نتیجه، تعداد جمع آوری شده در UCSRB ثبت می شود. جزئیات بیشتر در دیتاشیت MK در بخش USART توضیح داده شده است. بنابراین اجازه دهید با جزئیات فنی پرت نشویم.

تمام شد، وقت آن است که ببینیم چه اتفاقی افتاده است. روی compilation کلیک کنید و شبیه سازی را شروع کنید (Ctrl+F7).

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

واقعیت این است که در ابتدا، در واقع، در خط UBRRL = LO (bauddivider) قرار داشت. از این گذشته، آنچه ما در تعریف داریم کد نیست، بلکه محاسبات اولیه است، به همین دلیل است که شبیه ساز کمی کسل کننده است. اما حالا او متوجه شد، اولین دستور تکمیل شده است و اگر به درخت بروید نمای ورودی/خروجی، به بخش USART بروید و بایت UBBRL را در آنجا نگاه کنید، خواهید دید که مقدار از قبل وجود دارد! 0x33.

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

افتتاح
حالا شبیه سازی را به صفر برگردانید. آنجا کلیک کنید بازنشانی (Shift+F5). لیست جدا شده را باز کنید، اکنون خواهید دید که در کنترلر چه اتفاقی می افتد. مشاهده -> Disassembler. و نه YYAAAAA!!! مونتاژ کننده!!! وحشت!!! و ضروری است. به طوری که بعداً، هنگامی که مشکلی پیش می‌آید، در کد احمق نباشید و در انجمن‌ها سؤالات لنگ نپرسید، بلکه بلافاصله وارد جرات شوید و ببینید کجا گیر کرده‌اید. اونجا هیچ چیز ترسناکی نیست

ابتدا تاپ های این سری وجود خواهد داشت:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 00000000 +: 940C002A JMP 0x0000002A پرش +00000002: 940C0034 JMP 0x00000034 پرش +00000004: 940C0034 JMP 0x0000000: JMP 0x0000000 0x00000034 پرش +00000008: 940C0034 JMP 0x00000034 پرش +0000000A: 940C0034 JMP 0x000000034 پرش +00000000C: 00000000C: 00000000C: 94000000C 0000000E: 940C0034 JMP 0x00000034 Jump +00000010: 940C0034 JMP 0x00000034 Jump +00000012: 940C0034 JMP 0x0000000C 0x00000034 پرش + 00000016: 940C0034 JMP 0x00000034 پرش +00000018: 940C0034 JMP 0x00000034 پرش +00000001A: 940000001A: 940000001A: 94000001A: 9400000C : 940C0034 JMP 0x00000034 Jump +0000001E: 940C0034 JMP 0x00000034 Jump +00000020: 940C0034 JMP 0x000000034 JMP 0x000000034 JMP 0x000000034 JMP 0x000000034 0x000000034 پرش +00000001E: 940C0034 JMP 0x0000000034 34 پرش + 00000024: 940C0034 JMP 0x00000034 پرش +00000026: 940C0034 JMP 0x00000034 پرش +00000028: 940C00304 Jump0x0

00000000: 940C002A JMP 0x0000002A پرش +00000002: 940C0034 JMP 0x00000034 پرش +00000004: 940C0034 JMP 0x3000000 0x00000034 Jump +00000008: 940C0034 JMP 0x00000034 Jump +0000000A: 940C0034 JMP 0x000000034 Jump +00000000C: 940C0034 JMP 0x000000034 : 940C0034 JMP 0x00000034 Jump +00000010: 940C0034 JMP 0x00000034 Jump +00000012: 940C0034 JMP 0x000000034 JMP 0x000000034 JMP 0x000000034 پرش +000000034 940C0034 34 پرش +00000016: 940C0034 JMP 0x00000034 پرش +00000018: 940C0034 JMP 0x00000034 پرش +0000001A: 940C00304 Jump +00000034 JMP000C : 940C0034 JMP 0x00000034 Jump +0000001E: 940C0034 JMP 0x00000034 Jump +00000020: 940C0034 JMP 0x000000034 JMP 0x000000034 JMP 0x000000034 JMP 0x000000034 0x000000034 پرش +00000001E: 940C0034 JMP 0x0000000034 34 پرش + 00000024: 940C0034 JMP 0x00000034 پرش +00000026: 940C0034 JMP 0x00000034 پرش +00000028: 940C00304 Jump0x0

این جدول برداری وقفه است. بعداً به آن باز خواهیم گشت، اما در حال حاضر فقط نگاه کنید و به یاد داشته باشید که وجود دارد. ستون اول آدرس سلول فلش است که دستور در آن قرار دارد، دومی کد دستوری، سومی دستور mnemonic، همان دستورالعمل اسمبلی، سومی عملوندهای دستور است. خب نظر خودکار
بنابراین، اگر نگاه کنید، انتقال های مداوم وجود دارد. و کد دستور JMP چهار بایت است، حاوی آدرس پرش به عقب نوشته شده است - بایت کم در آدرس پایین و کد دستور پرش 940C

0000002B: BE1F OUT 0x3F، R1 خروجی به محل ورودی/خروجی

ثبت این صفر در آدرس 0x3F.اگر به ستون نمای ورودی/خروجی نگاه کنید، خواهید دید که آدرس 0x3F آدرس رجیستر SREG - ثبت پرچم کنترل کننده است. آن ها ما SREG را برای اجرای برنامه در شرایط صفر بازنشانی می کنیم.

1 2 3 4 +0000002C: E5CF LDI R28,0x5F بارگیری فوری +0000002D: E0D4 LDI R29,0x04 بارگیری فوری +0000002E: خروجی BFDE OUT 0x3E,R29 خروجی به مکان ورودی/خروجی +00000002F موقعیت مکانی ورودی/خروجی +00000002F

0000002C: E5CF LDI R28,0x5F بارگیری فوری +0000002D: E0D4 LDI R29,0x04 بارگیری فوری +0000002E: خروجی BFDE OUT 0x3E,R29 خروجی به محل ورودی/خروجی +00000002F موقعیت مکانی ورودی/خروجی +000000002

این در حال بارگیری نشانگر پشته است. شما نمی توانید مستقیماً در رجیسترهای ورودی/خروجی بارگذاری کنید، فقط از طریق یک ثبات میانی. بنابراین، ابتدا LDI به متوسط، و سپس از آنجا OUT به I/O. همچنین در مورد پشته بعداً به شما خواهم گفت. در حال حاضر، بدانید که این یک ناحیه حافظه پویا است که در انتهای RAM آویزان است و آدرس ها و متغیرهای میانی را ذخیره می کند. حالا ما نشان دادیم که پشته ما از کجا شروع می شود.

00000032: 940C0041 JMP 0x00000041 پرش

به انتهای برنامه بروید، و در آنجا ممنوعیت وقفه ها و حلقه زدن محکم روی خود را داریم:

1 2 +00000041: 94F8 CLI وقفه جهانی غیرفعال کردن +00000042: CFFF RJMP PC-0x0000 پرش نسبی

00000041: 94F8 CLI وقفه جهانی غیرفعال کردن +00000042: CFFF RJMP PC-0x0000 پرش نسبی

این در شرایط پیش بینی نشده مانند خروج از عملکرد اصلی است. کنترلر را می توان با بازنشانی سخت افزاری یا به احتمال زیاد با بازنشانی از یک سگ نگهبان از چنین حلقه ای خارج کرد. خوب، یا، همانطور که در بالا گفتم، این را در ویرایشگر هگز تصحیح کنید و به هر جایی که دلمان می‌خواهد بریم. همچنین توجه داشته باشید که دو نوع انتقال وجود دارد: JMP و RJMP؛ اولین انتقال مستقیم به یک آدرس است. چهار بایت را اشغال می کند و می تواند مستقیماً از کل منطقه حافظه پرش کند. نوع دوم انتقال RJMP - نسبی است. دستور او دو بایت طول می کشد، اما او از موقعیت فعلی (آدرس) 1024 قدم به جلو یا عقب حرکت می کند. و پارامترهای آن نشان دهنده افست از نقطه فعلی است. بیشتر استفاده می شود زیرا در یک فلاش نیمی از فضا را اشغال می کند و به ندرت نیاز به انتقال طولانی است.

1 +00000034: 940C0000 JMP 0x00000000 پرش

00000034: 940C0000 JMP 0x00000000 پرش

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

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

1 2 3 4 5 6 7 8 9 10 11 12 <

00000036: E383 LDI R24,0x33 بارگیری فوری +00000037: B989 OUT 0x09,R24 خروجی به محل ورودی/خروجی 15: UBRRH = HI(bauddivider); +00000038: BC10 OUT 0x20,R1 خروجی به محل ورودی/خروجی 16: UCSRA = 0; +00000039: B81B OUT 0x0B,R1 خروجی به محل ورودی/خروجی 17: UCSRB = 1<

و این اشکال است:

1 2 3 +0000003E: E080 LDI R24.0x00 بارگیری فوری +0000003F: E090 LDI R25.0x00 بارگیری فوری +00000040: 9508 بازگشت زیربرنامه RET

0000003E: E080 LDI R24.0x00 بارگیری فوری +0000003F: E090 LDI R25.0x00 بارگیری فوری +00000040: 9508 بازگشت زیربرنامه RET

سوال اینجاست که چرا کامپایلر چنین تاپ هایی را اضافه می کند؟ و این چیزی بیش از Return 0 نیست، ما تابع را به عنوان int main(void) تعریف کردیم و بنابراین چهار بایت دیگر را بیهوده تلف کردیم :) و اگر void main(void) را ایجاد کنید، فقط RET باقی می ماند، اما یک هشدار ظاهر می شود. ، که تابع اصلی ما چیزی را بر نمی گرداند. در کل هر کاری که دوست داری انجام بده :)

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

تا یکی دو روز دیگر ادامه دارد...

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

وظیفه: بیایید برنامه ای برای کنترل یک LED ایجاد کنیم. با فشار دادن دکمه، LED روشن می شود و پس از رها شدن، خاموش می شود.

ابتدا، بیایید یک نمودار شماتیک از دستگاه ایجاد کنیم. پورت های I/O برای اتصال هر دستگاه خارجی به میکروکنترلر استفاده می شود. هر یک از پورت ها می توانند به عنوان ورودی و خروجی کار کنند. بیایید LED را به یکی از پورت ها و دکمه را به دیگری وصل کنیم. برای این آزمایش از یک کنترلر استفاده خواهیم کرد Atmega8. این تراشه شامل 3 پورت ورودی/خروجی، دارای 2 تایمر/ شمارنده 2 هشت بیتی و 1 شانزده بیتی است. همچنین یک PWM 3 کاناله، مبدل 10 بیتی آنالوگ به دیجیتال 6 کاناله و بسیاری موارد دیگر روی هواپیما وجود دارد. به نظر من میکروکنترلر برای یادگیری اصول برنامه نویسی عالی است.

برای اتصال LED از خط PB0 و برای خواندن اطلاعات از روی دکمه از خط PD0 استفاده می کنیم. نمودار در شکل 1 نشان داده شده است.

برنج. 1

از طریق مقاومت R2، به علاوه ولتاژ تغذیه به ورودی PD0، که مربوط به یک سیگنال منطقی است، عرضه می شود. هنگامی که دکمه بسته می شود، ولتاژ به صفر می رسد که مربوط به یک صفر منطقی است. در آینده، R2 را می توان از مدار حذف کرد، آن را با یک مقاومت بار داخلی جایگزین کرد و تنظیمات لازم را در برنامه وارد کرد. LED از طریق مقاومت محدود کننده جریان R3 به خروجی پورت PB0 متصل می شود. برای روشن کردن LED، باید یک سیگنال منطقی به خط PB0 اعمال کنید. ما از یک ژنراتور اصلی کلاک داخلی با فرکانس 4 مگاهرتز استفاده خواهیم کرد، زیرا دستگاه نیازهای بالایی برای ثبات فرکانس ندارد.

حالا برنامه را می نویسیم. من از محیط برنامه نویسی برای نوشتن برنامه استفاده می کنم AVR Studioو WinAvr. AVR Studio را باز کنید، یک پنجره خوشامدگویی ظاهر می شود، روی دکمه "ایجاد پروژه جدید" کلیک کنید، سپس نوع پروژه - AVR GCC را انتخاب کنید، نام پروژه را به عنوان مثال "cod1" بنویسید، "ایجاد پوشه پروژه" و "ایجاد" را بررسی کنید. فایل اولیه را انتخاب کنید، روی دکمه «بعدی» کلیک کنید، «AVR Simulator» را در پنجره سمت چپ انتخاب کنید، و میکروکنترلر «Atmega8» را در پنجره سمت راست تایپ کنید، روی دکمه «پایان» کلیک کنید، ویرایشگر و درخت دسته پروژه باز می شود - تنظیمات اولیه تکمیل شد

ابتدا، بیایید متن توضیحات استاندارد Atmega8 را با استفاده از عملگر برای پیوست کردن فایل های خارجی اضافه کنیم: #عبارتند از

نحو دستوری #عبارتند از

#عبارتند از<имя_файла.h>
#include "filename.h"

براکت های زاویه< и >به کامپایلر نشان دهید که فایل های شامل ابتدا باید در پوشه استاندارد WinAvr به نام include جستجو شوند. دو گیومه "و" به کامپایلر می گوید که جستجو را در دایرکتوری که پروژه در آن ذخیره شده است آغاز کند.

هر نوع میکروکنترلر فایل هدر مخصوص به خود را دارد. برای ATMega8 این فایل iom8.h، برای ATtiny2313 - iotn2313.h نامیده می شود. در ابتدای هر برنامه باید فایل هدر میکروکنترلر مورد استفاده را قرار دهیم. اما یک فایل هدر مشترک io.h نیز وجود دارد. پیش پردازنده این فایل را پردازش می کند و بسته به تنظیمات پروژه، فایل هدر مورد نیاز را در برنامه ما قرار می دهد.

برای ما، خط اول برنامه به این صورت خواهد بود:

#عبارتند از

هر برنامه C باید دارای یک تابع اصلی باشد. اصلی نامگذاری شده است. اجرای برنامه همیشه با اجرای تابع اصلی شروع می شود. این تابع دارای یک سرصفحه - int main(void) و یک بدنه است - با مهاربندهای فرفری ().

int main (void)
{
بدن عملکرد
}

ما کد خود را به بدنه تابع اضافه می کنیم. نوع برگشتی قبل از نام تابع نشان داده شده است. اگر تابع مقداری را برنگرداند، از کلید استفاده می شود خالی.

بین المللی- این یک عدد صحیح 2 بایتی است، محدوده مقادیر از - 32768 تا 32767 است.

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

سپس پورت را پیکربندی می کنیم Dدر ورودی حالت عملکرد پورت توسط محتویات رجیستر تعیین می شود DDRD(ثبت جهت انتقال اطلاعات). ما عدد "0x00" (0b0000000 - به شکل باینری) را در این ثبات می نویسیم؛ هیچ چیز به این پورت به جز دکمه متصل نیست، بنابراین کل پورت D را به عنوان ورودی پیکربندی می کنیم. می توانید با نوشتن اعداد 0 یا 1 در هر بیت رجیستر (0-ورودی، 1-خروجی)، پورت را بیت به بیت پیکربندی کنید، به عنوان مثال DDRD = 0x81 (0b10000001) - اولین و آخرین خطوط پورت D به عنوان خروجی، بقیه به عنوان ورودی. مقاومت بار داخلی نیز باید متصل شود. رجیستر PORTx کنترل می کند که آیا مقاومت های داخلی زمانی که پورت در حالت ورودی است روشن یا خاموش شوند. بیایید واحدها را آنجا بنویسیم.

راه اندازی پورت ببه خروجی حالت عملکرد پورت توسط محتویات رجیستر تعیین می شود DDRB. چیزی جز LED به پورت نیست بمتصل نیست، بنابراین کل پورت را می توان به عنوان خروجی پیکربندی کرد. این کار با نوشتن در رجیستر انجام می شود DDRBاعداد "0xFF". برای جلوگیری از روشن شدن LED در اولین روشن کردن آن، به پورت بنویسید بصفرهای منطقی این کار با ضبط انجام می شود PORTB= 0x00;

برای تخصیص مقادیر، از نماد "=" استفاده می شود و عملگر انتساب نامیده می شود، نباید با علامت "برابر" اشتباه گرفته شود.

پیکربندی پورت به شکل زیر خواهد بود:

DDRD = 0x00;
PORTD = 0xFF;
DDRB = 0xFF;
PORTB = 0x00;

حلقه اصلی برنامه را می نویسیم. در حالی که("while" از انگلیسی) - این دستور یک حلقه را سازماندهی می کند و بدنه حلقه را بارها تکرار می کند تا زمانی که شرط برآورده شود، یعنی در حالی که عبارت داخل پرانتز درست است. در C، یک عبارت اگر برابر با صفر نباشد درست و اگر برابر باشد نادرست در نظر گرفته می شود.

دستور به شکل زیر است:

در حالی که (شرط)
{
بدنه حلقه
}

در مورد ما، حلقه اصلی تنها از یک دستور تشکیل خواهد شد. این دستور ثبت نام را اختصاص می دهد PORTBمقدار ثبت نام معکوس شود پورت.

PORTB = ~PIND; //مقدار را از پورت D بگیرید، آن را برعکس کنید و به PORTB اختصاص دهید (به PORTB بنویسید)

// عبارات C از راست به چپ خوانده می شوند

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

#عبارتند از int main (void) (DDRD = 0x00; //پورت D - ورودی PORTD = 0xFF؛ //مقاومت بار را وصل کنید DDRB = 0xFF؛ //پورت B - خروجی PORTB = 0x00؛ //خروجی را روی 0 تنظیم کنید while(1 ) ( PORTB = ~PIND؛ //~ علامت وارونگی بیتی ) )

نظرات به طور گسترده در زبان C استفاده می شود. دو راه برای نوشتن وجود دارد.

/*یک نظر*/
//یک نظر

در این صورت کامپایلر به آنچه در کامنت نوشته شده توجهی نخواهد کرد.

اگر از همان برنامه استفاده کنید و همانطور که در شکل 2 نشان داده شده است 8 دکمه و 8 LED را به میکروکنترلر متصل کنید، مشخص می شود که هر بیت از پورت Dبا بیت پورت آن مطابقت دارد ب. با فشردن دکمه SB1، HL1 روشن می شود، با فشار دادن دکمه SB2، HL2 روشن می شود و غیره.

شکل 2

در این مقاله از مطالب کتاب A.V. Belov استفاده شده است. "آموزش برای توسعه دهندگان دستگاه AVR"

میکروکنترلرهای Atmega8 محبوب ترین نمایندگان خانواده خود هستند. از بسیاری جهات، آنها این را مدیون سادگی عملکرد و ساختار قابل درک از یک سو، و از سوی دیگر، عملکرد نسبتاً گسترده هستند. این مقاله به برنامه نویسی Atmega8 برای مبتدیان می پردازد.

اطلاعات کلی

میکروکنترلرها همه جا هستند. آنها را می توان در یخچال، ماشین لباسشویی، تلفن، ماشین آلات کارخانه و تعداد زیادی از وسایل فنی دیگر یافت. میکروکنترلرها از ساده تا بسیار پیچیده هستند. دومی ویژگی ها و عملکردهای بسیار بیشتری را ارائه می دهد. اما شما نمی توانید فوراً فناوری پیچیده را درک کنید. در ابتدا، شما باید به چیزی ساده تسلط داشته باشید. و Atmega8 به عنوان نمونه گرفته می شود. برنامه نویسی بر روی آن به لطف معماری شایسته و رابط دوستانه آن دشوار نیست. علاوه بر این، عملکرد کافی برای استفاده در اکثر موارد را دارد و حتی در صنعت نیز کاربرد دارد. در مورد Atmega8، برنامه نویسی به دانش زبان هایی مانند AVR (C/Assembler) نیاز دارد. از کجا شروع کنیم؟ تسلط بر این فناوری از سه طریق امکان پذیر است. و هر کس برای خود انتخاب می کند که از کجا شروع به کار با Atmega8 کند:

  1. برنامه نویسی از طریق آردوینو
  2. خرید دستگاه آماده.
  3. خود مونتاژ میکروکنترلر.

نکات اول و سوم را در نظر خواهیم گرفت.

آردوینو

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

  1. شرایط آستانه پایین برای توسعه دستگاه های فنی نیازی به داشتن مهارت های خاصی ندارید.
  2. طیف گسترده ای از عناصر برای اتصال بدون آماده سازی اضافی در دسترس خواهد بود.
  3. شروع سریع توسعه با آردوینو می‌توانید مستقیماً وارد ساخت دستگاه‌ها شوید.
  4. در دسترس بودن تعداد زیادی مواد آموزشی و نمونه هایی از اجرای طرح های مختلف.

اما معایب خاصی نیز وجود دارد. بنابراین، برنامه‌نویسی آردوینو Atmega8 به شما اجازه نمی‌دهد تا عمیق‌تر در دنیای میکروکنترلر فرو رفته و بسیاری از جنبه‌های مفید را درک کنید. علاوه بر این، شما باید یک زبان برنامه نویسی را یاد بگیرید که با زبان های مورد استفاده AVR (C/Assembler) متفاوت است. و یک چیز دیگر: آردوینو طیف نسبتاً محدودی از مدل ها دارد. بنابراین دیر یا زود نیاز به استفاده از میکروکنترلر وجود خواهد داشت که در بردها استفاده نمی شود. اما در کل برای کار با Atmega8 گزینه خوبی است. برنامه نویسی از طریق آردوینو به شما یک شروع مطمئن در دنیای الکترونیک می دهد. و بعید است که شخص به دلیل شکست ها و مشکلات تسلیم شود.

خود مونتاژ

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

برای مونتاژ چه چیزی لازم است؟

ابتدا باید خود Atmega8 را دریافت کنید. می دانید که برنامه ریزی یک میکروکنترلر بدون آن غیرممکن است. هزینه آن چند صد روبل خواهد بود - در حالی که عملکرد مناسبی را ارائه می دهد. همچنین این سوال وجود دارد که Atmega8 چگونه برنامه ریزی خواهد شد. USBAsp دستگاه بسیار خوبی است که ثابت کرده است بسیار خوب است. اما می توانید از برنامه نویس دیگری استفاده کنید. یا خودتان آن را مونتاژ کنید. اما در این حالت، این خطر وجود دارد که در صورت ایجاد ضعیف، میکروکنترلر را به یک قطعه پلاستیکی و آهنی غیر کاربردی تبدیل کند. همچنین داشتن تخته نان و جامپر ضرری ندارد. آنها مورد نیاز نیستند، اما در اعصاب و زمان شما صرفه جویی می کنند. و در نهایت، شما به یک منبع تغذیه 5 ولت نیاز دارید.

برنامه نویسی Atmega8 برای مبتدیان با استفاده از یک مثال

بیایید نگاه کنیم که به طور کلی چگونه یک دستگاه ایجاد می شود. بنابراین، فرض کنید که ما یک میکروکنترلر، یک LED، یک مقاومت، یک برنامه نویس، سیم های اتصال و یک منبع تغذیه داریم. اولین قدم نوشتن سیستم عامل است. این به عنوان مجموعه ای از دستورات برای میکروکنترلر درک می شود که به عنوان یک فایل نهایی در یک فرمت خاص ارائه می شود. لازم است ارتباط همه عناصر و همچنین تعامل با آنها مشخص شود. پس از این، می توانید مونتاژ مدار را شروع کنید. پین VCC باید تغذیه شود. به هر دیگری که برای کار با دستگاه ها و عناصر طراحی شده است، ابتدا یک مقاومت و سپس یک LED متصل می شود. در این مورد، قدرت اولی بستگی به توان مورد نیاز دومی دارد. می توانید از فرمول زیر استفاده کنید: R=(Up-Ups)/Is. در اینجا p توان و s LED است. بیایید تصور کنیم که یک LED داریم که 2 ولت مصرف می کند و به جریان تغذیه 10 میلی آمپر نیاز دارد، آن را به شکلی راحت تر برای عملیات ریاضی تبدیل کنیم و 0.01 آمپر دریافت کنیم. سپس فرمول به این صورت خواهد بود: R=(5V-2V)/0.01A=3V/0.01A=300 اهم. اما در عمل اغلب غیرممکن است که عنصر ایده آل را انتخاب کنید. بنابراین، مناسب ترین آن گرفته می شود. اما باید از مقاومتی با مقاومت بالاتر از مقدار بدست آمده از نظر ریاضی استفاده کنید. به لطف این رویکرد، ما عمر مفید آن را افزایش خواهیم داد.

بعدش چی؟

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

نکات مهم

من می خواهم به مبتدیان نکات مفیدی در مورد برنامه نویسی Atmega8 ارائه کنم. متغیرها و توابع داخلی را تغییر ندهید! توصیه می شود پس از بررسی عدم وجود "حلقه های ابدی" که هر گونه تداخل دیگری را مسدود می کند و با استفاده از یک فرستنده خوب، دستگاه را با برنامه ایجاد شده فلش کنید. اگر از یک محصول خانگی برای این اهداف استفاده می کنید، باید از نظر ذهنی برای از کار افتادن میکروکنترلر آماده باشید. هنگامی که دستگاهی را با استفاده از برنامه نویس فلش می کنید، باید خروجی های مربوط به VCC، GND، SCK، MOSI، RESET، MISO را وصل کنید. و نکات ایمنی را زیر پا نگذارید! اگر مشخصات فنی تصریح می کند که منبع تغذیه باید 5 ولت باشد، باید دقیقاً به این ولتاژ پایبند باشید. حتی استفاده از المان های 6 ولت می تواند بر عملکرد میکروکنترلر تأثیر منفی بگذارد و عمر مفید آن را کاهش دهد. البته، باتری های 5 ولت تفاوت های خاصی دارند، اما، به عنوان یک قاعده، همه چیز در محدوده معقول است. به عنوان مثال، حداکثر ولتاژ در 5.3 ولت نگه داشته می شود.

آموزش و ارتقای مهارت ها

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

آیا شروع ساختن چیزی از خودتان دشوار است؟

کافی است 500-2000 روبل و چند شب رایگان داشته باشید. این زمان برای آشنایی با معماری Atmega8 بیش از اندازه کافی است. پس از کمی تمرین، به راحتی می توانید پروژه های خود را ایجاد کنید که وظایف خاصی را انجام می دهند. به عنوان مثال، یک بازوی رباتیک. Atmega8 به تنهایی باید برای انتقال عملکردهای حرکتی اولیه انگشتان و دست کافی باشد. البته این کار نسبتاً دشواری است، اما کاملاً امکان پذیر است. در آینده امکان ایجاد چیزهای پیچیده ای وجود خواهد داشت که به ده ها میکروکنترلر نیاز دارند. اما این همه پیش رو است، قبل از آن باید یک مدرسه تمرینی خوب در مورد چیز ساده بگیرید.