فهرست مطالب:
- مرحله 1: پاک کردن صفحه کلید 1
- مرحله 2: پاک کردن صفحه کلید 2
- مرحله 3: پاک کردن صفحه کلید 3
- مرحله 4: صفحه کلید را سیم کشی کنید
- مرحله 5: صفحه کلید را به آنالیزور خود وصل کنید
- مرحله 6: کدام سوئیچ های تعویض را باید تنظیم کنیم؟
- مرحله 7: Interrupt Handler را بنویسید
- مرحله 8: مقادیر کلید فشار را ترسیم کنید
- مرحله 9: کد و ویدیو برای نسخه 1
- مرحله 10: کد نسخه 2
- مرحله 11: چگونه از دکمه خلاص شویم؟ نسخه 3
- مرحله 12: کد و ویدئو برای نسخه کار
تصویری: آموزش AVR Assembler 7: 12 مرحله
2024 نویسنده: John Day | [email protected]. آخرین اصلاح شده: 2024-01-30 08:51
به آموزش 7 خوش آمدید!
امروز ما قصد داریم ابتدا نحوه پاک کردن صفحه کلید را نشان دهیم ، و سپس نحوه استفاده از پورت های ورودی آنالوگ برای ارتباط با صفحه کلید را نشان می دهیم. این کار را با استفاده از وقفه ها و یک سیم واحد به عنوان ورودی انجام می دهیم. ما صفحه کلید را طوری سیم کشی می کنیم که هر کلید فشار یک ولتاژ منحصر به فرد به ورودی آنالوگ ارسال کند که به ما اجازه می دهد با ولتاژ فشار داده شده کلید را تشخیص دهیم. سپس عدد فشار داده شده به آنالیز ثبت نام خود را برای نشان دادن اینکه همه چیز آنطور که باید اتفاق می افتد ، خروجی می دهیم. هنگام استفاده از مبدل آنالوگ به دیجیتال (ADC) در ATmega328p ، می توانید به آنها دامن بزنید و بنابراین ما در طی چند مرحله در راه تلاش کنید و دریابید که چگونه از آنها اجتناب کنید. ما همچنین خواهیم دید که چرا استفاده از مبدل آنالوگ به دیجیتال بهترین راه برای کنترل صفحه کلید نیست ، حتی اگر از پورت های کمتری در میکروکنترلر شما استفاده کند. در این آموزش به موارد زیر نیاز خواهید داشت:
- یک صفحه کلید می توانید یکی بخرید یا می توانید کاری را که من انجام دادم انجام دهید و یکی را تمیز کنید.
- 2 سرصفحه زن برای صفحه کلید (اگر در حال جمع آوری یکی هستید)
- سیم های اتصال
- یک تخته نان
- 4 مقاومت 1 کوهم
- مقاومت 1 15 کوهم
- 1 مقاومت 3.3 اهم
- 1 مقاومت 180 اهم
- مقاومت 1 680 اهم
- مولتی متر دیجیتال
- تجزیه و تحلیل شما از آموزش 5
اگر قبلاً یک صفحه کلید دارید و نیازی به پاک کردن آن ندارید ، ممکن است بخواهید چند مرحله اول را رد کنید.
در اینجا پیوندی به مجموعه کامل آموزش های مونتاژ AVR من آمده است:
مرحله 1: پاک کردن صفحه کلید 1
مدتها پیش ، زمانی که حتی پدربزرگ و مادربزرگ شما بچه بودند ، مردم برای ارتباط با یکدیگر از این وسایل عجیب و غریب که کابل های طولانی به دیوار وصل شده بود استفاده می کردند. به آنها "تلفن" می گفتند و معمولاً چیزهای پلاستیکی ارزان قیمت بودند که وقتی شخصی با شما تماس می گرفت صدای آزاردهنده ای ایجاد می کرد (نه اینکه آهنگ های زنگ "جاستین بیبر" امروزه به همان اندازه آزاردهنده نیستند). در هر صورت ، این دستگاهها دارای صفحه کلیدهایی بودند که به سادگی وصل شده بودند و به راحتی قابل جمع شدن هستند و 2 کلید اضافی روی آنها وجود دارد ("شماره گیری مجدد" و "فلش") از صفحه کلیدهایی که می توانید بخرید و ممکن است بخواهید مجدداً از آنها استفاده کنید. به عنوان "کلیدهای پیکان" ، "کلیدهای منو" ، یا چیزهای دیگر. بنابراین ما قصد داریم با پاک کردن صفحه کلید از تلفن قدیمی شروع کنیم. ابتدا تلفن را بردارید (همانطور که در تصاویر نشان داده شده است از GE استفاده می کنم) و آن را جدا کنید تا سیم کشی نشان داده شود. سپس یک اسکنه را بردارید و دستگیره های پلاستیکی کوچکی را که صفحه کلید را نگه داشته است بردارید و صفحه کلید را بردارید.
مرحله 2: پاک کردن صفحه کلید 2
حالا یک اره پی وی سی بردارید و پلاستیک را از اطراف سوراخ های کلید جدا کنید و سپس در اطراف لبه آن را ببرید تا عمق آن درست از صفحه کلید نازک خارج شود.
سپس صفحه کلید را با استفاده از گیره های کوچکی که پس از جدا کردن قسمت بالای آنها در آخرین مرحله باقی مانده است ، مجدداً قرار دهید و از آهن لحیم کاری استفاده کنید تا به سادگی آهن داغ را در هر سوراخ میخ بچسبانید که پلاستیک را ذوب کرده و روی سطح پهن می کند. پایین صفحه کلید "دستگیره" جدیدی تشکیل می دهد که صفحه کلید را مانند قبل در جای خود نگه می دارد.
من دوست دارم سه بلندگو را خراب کنم و شاید چیزهای دیگر مانند سوئیچ ها و چیزهایی که روی برد هستند. با این حال ، این بار من قصد ندارم سوئیچ ها و موارد دیگر را از بین ببرم ، زیرا در حال حاضر اهداف دیگری داریم. همچنین ، IC خطی TA31002 وجود دارد که زنگ تلفن است. برگه داده به آسانی یافت می شود و به صورت آنلاین بارگیری می شود و ویژگی ها را مشخص می کند. بنابراین من قصد دارم آن را فعلاً به تخته لحیم کنم و بعداً با آن بازی کنم. من می خواهم آن را به یک اسیلوسکوپ وصل کنم و ببینم چه سیگنال های جالبی می توانم از آن دریافت کنم. شاید حتی زنگ در را با آن بزنید. کی میدونه.
به هر حال پس از اتمام تخریب تلفن و جمع آوری قطعات ، ما صفحه کلید خود را تمام می کنیم.
مرحله 3: پاک کردن صفحه کلید 3
از یک فتیله لحیم کاری استفاده کنید و کابل های روبان را از پایین صفحه کلید بردارید و مطمئن شوید که سوراخ های صفحه مدار روشن هستند و سپس دو سر زن را روی تخته جایی که سوراخ وجود دارد وصل کنید. احتمالاً مجبور خواهید شد سرصفحه های خود را کوتاه کنید تا هدرهای 4 پین باشند.
اکنون که سرصفحه ها متصل شده اند ، می توانید آن را روی یک تخته نان متصل کنید ، یک مولتی متر بگیرید و کلیدها را با چسباندن مولتی متر در پین های تصادفی و اندازه گیری مقاومت آزمایش کنید. این به شما امکان می دهد کلیدها را ترسیم کنید. مشاهده نحوه اتصال کلیدها به خروجی ها با مشاهده مدار دشوار است ، اما اگر از مولتی متر استفاده می کنید می توانید آن را به هر دو پین متصل کرده و سپس دکمه ها را فشار دهید تا به جای مدار باز شماره ای را روی صفحه مشاهده کنید. به این گزینه pinout آن کلید خواهد بود.
تمام کلیدهای خروجی پین ها را به این ترتیب ترسیم کنید.
مرحله 4: صفحه کلید را سیم کشی کنید
حالا نمودار سیم کشی را دنبال کنید و صفحه کلید را به تخته نورد خود وصل کنید.
چگونه این کار می کند ما 5V را در سمت چپ قرار می دهیم و سمت راست به GND می رود. اولین پین سمت راست در نمودار به اولین پین های آنالوگ ما در میکروکنترلر Atmega328p وارد می شود. وقتی هیچ دکمه ای فشار داده نشود ، سیگنال 0 ولت خواهد بود ، و وقتی هر یک از دکمه های مختلف فشار داده شوند ، ورودی به پورت آنالوگ بین 0 ولت و 5 ولت با مقدار متفاوتی بسته به اینکه کدام کلید فشار داده شده است ، متغیر است. ما مقادیر مقاومت را طوری انتخاب کردیم که هر مسیر دارای مقاومت متفاوت از بقیه باشد. پورت آنالوگ روی میکروکنترلر یک سیگنال آنالوگ می گیرد و آن را به 1024 کانال مختلف بین 0 ولت و 5 ولت تقسیم می کند. این بدان معناست که هر کانال دارای عرض 5V/1024 = 0.005 V/کانال = 5 mV/channel است. بنابراین پورت آنالوگ می تواند ولتاژهای ورودی را تا زمانی که بیش از 5 میلی ولت متفاوت باشند تشخیص دهد. در مورد ما ، ما مقادیر مقاومت را انتخاب کرده ایم به طوری که هر دو فشار کلید سیگنال ولتاژی را که بیش از این متفاوت است ارسال می کند ، بنابراین میکروکنترلر باید به راحتی بتواند تعیین کند که کدام کلید فشار داده شده است. مشکل بزرگ این است که کل سیستم بسیار پر سر و صدا است ، بنابراین ما باید طیف وسیعی از ولتاژها را برای ترسیم هر دکمه انتخاب کنیم - اما کمی بعد به آن خواهیم رسید.
توجه داشته باشید که ما قادر به کنترل یک صفحه کلید 14 دکمه با استفاده از تنها یک خط ورودی به کنترلر هستیم. این یکی از جنبه های مفید ورودی های آنالوگ است.
در حال حاضر اولین تلاش ما برای کنترل صفحه کلید این است که یک کلید باعث وقفه شود ، زیر روال وقفه پورت ورودی آنالوگ را می خواند و تصمیم می گیرد که کدام کلید فشار داده شده است ، و سپس این عدد را به زیر روال تجزیه و تحلیل ثبتی ما ارسال می کند که نمایش می دهد مقدار کلیدی در باینری در 8 LED ما که در آموزش 5 تنظیم کرده ایم.
مرحله 5: صفحه کلید را به آنالیزور خود وصل کنید
تصاویر نشان می دهد که چگونه می خواهیم صفحه کلید را به میکروکنترلر وصل کنیم تا بتوانیم خروجی را روی نمایشگر آنالیزور خود ببینیم. اساساً ما خروجی را از صفحه کلید به پین 0 PortC وصل می کنیم ، که در ATmega328P ADC0 نیز نامیده می شود.
با این حال ، چند مورد اضافی وجود دارد. ما همچنین قصد داریم یک دکمه را به PD2 وصل کنیم. یعنی سیم را از ریل 5 ولت خود به یک دکمه و از طرف دیگر دکمه به PD2 ببرید ، و در نهایت ، ما می خواهیم پین AREF را از ریل 5 ولت خود جدا کرده و در عوض آن را قطع کنیم. در صورت تمایل می توانیم یک خازن جدا کننده 0.1 میکروفاراد را وارد کنیم. این یک خازن سرامیکی است که روی آن 104 نوشته شده است. دو رقم اول عدد است و آخرین رقم قدرت 10 است که آن را ضرب می کنیم تا در picofarads (پیکو به معنی 10^-12) است ، بنابراین 104 به معنی 10 * 10^4 پیکوفاراد است که برابر است با 100 نانو فاراد (نانو به معنی 10^-9) است که همان 0.1 میکرو فاراد (میکرو به معنی 10^-6) است. به هر حال ، همه اینها این است که پین AREF را ثابت کنیم وقتی می توانیم از آن به عنوان پین مرجع خود استفاده کنیم.
ما همچنین یک مقاومت 1 اهم بین PD2 و زمین می خواهیم. ما قصد داریم PD2 را به عنوان یک پین خروجی در 0V تنظیم کنیم و در آن پین بر روی لبه مثبت ایجاد می کنیم. ما می خواهیم وقتی دکمه را رها می کنیم ، لبه ناگهان ناپدید شود ، بنابراین این مقاومت "کشش پایین" را وارد می کنیم.
دلیل اینکه ما دکمه را می خواهیم این است که می خواهیم مبدل آنالوگ به دیجیتال را از پین INT0 روی تراشه که PD2 نیز است خاموش کنیم. در نهایت ما می خواهیم فشردن کلید هم ADC را فعال کند و هم اینکه ورودی را بدون داشتن دکمه جداگانه تبدیل کند ، اما به دلیل نحوه عملکرد زمان بندی ، با داشتن یک دکمه جداگانه برای فعال کردن ADC و هنگامی که همه را اتو می کنیم ، شروع می کنیم. اشکالات برطرف شده و مطمئن هستید که همه چیز به درستی کار می کند ، سپس ما با سر و صدا و مسائل مربوط به زمان بندی که با فعال شدن آن از همان دکمه ای که می خواهیم بخوانیم ، برخورد می کنیم.
بنابراین ، در حال حاضر ، نحوه کار ما این است که یک کلید را نگه داریم ، سپس دکمه را فشار دهیم تا ADC فعال شود ، و سپس رها شود و امیدوارم مقدار دودویی دکمه ای که ما فشار داده ایم روی آنالیزر نشان داده شود.
بنابراین اجازه دهید کمی کد بنویسیم که این کار را انجام دهد.
مرحله 6: کدام سوئیچ های تعویض را باید تنظیم کنیم؟
بیایید ابتدا در مورد چگونگی کدگذاری این مورد فکر کنیم تا کنترل کننده بتواند ورودی را از صفحه کلید بخواند و آن را به مقدار عددی مربوط به دکمه فشار داده تبدیل کند. ما قصد داریم از مبدل آنالوگ به دیجیتال (ADC) استفاده کنیم که در Atmega328p ساخته شده است. ما از AREF به عنوان ولتاژ مرجع خود استفاده می کنیم و خروجی صفحه کلید ما به PortC0 یا PC0 متصل می شود. توجه داشته باشید که این پین ADC0 برای مبدل آنالوگ به دیجیتال نیز نامیده می شود. شاید بهتر باشد قبل از دریافت بخش 12.4 بخش وقفه های ATmega328P و همچنین فصل 24 مبدل آنالوگ به دیجیتال را بخوانید. شروع کنید یا حداقل آن بخشها را برای مرجع آماده کنید. به منظور راه اندازی میکروکنترلر به طوری که بداند با سیگنال ورودی آنالوگ چه کار کند و چگونه با برنامه ما تعامل داشته باشد ، ابتدا باید تعدادی از ADC های مختلف را تنظیم کنیم بیت ثبت مربوطه اینها اساساً معادل سوئیچ های تعویض قدیمی در اولین رایانه ها هستند. شما یا یک کلید را روشن یا خاموش می کنید ، یا حتی بیشتر به عقب کابل ها را بین یک خروجی و دیگری به برق وصل می کنید تا الکترون هایی که در جاده به آن چنگال می رسند ، یک دروازه بسته و دریچه ای دیگر باز شود و آن را در مسیری متفاوت در پیچ و خم مجبور کند. مدار و در نتیجه انجام یک کار منطقی متفاوت. هنگام کد نویسی به زبان اسمبلی ، ما به این عملکردهای میکروکنترلر دسترسی نزدیک داریم که در وهله اول یکی از موارد جذاب انجام این کار است. این برنامه بیشتر "دست به دست" است و به مراتب کمتر "پشت صحنه" در جریان است. بنابراین تنظیم این رجیسترها را به عنوان یک کار خسته کننده تصور نکنید. این همان چیزی است که زبان اسمبلی را جالب می کند! ما با عملکرد درونی و منطق تراشه رابطه ای بسیار شخصی به دست آورده ایم و آن را دقیقاً همانطور که می خواهیم انجام می دهد - نه بیشتر و نه کمتر. بدون چرخه ساعت هدر رفته. بنابراین در اینجا لیستی از سوئیچ هایی است که باید تنظیم کنیم:
- بیت Power Reduction ADC ، PRADC را که بیت 0 ثبت PRR است خاموش کنید ، زیرا اگر این بیت روی آن باشد ADC خاموش می شود. رجیستر کاهش قدرت در اصل راهی است برای خاموش کردن موارد مختلف که از برق استفاده می کنند در صورت عدم نیاز به آنها. از آنجا که ما از ADC استفاده می کنیم ، می خواهیم مطمئن شویم که به این طریق غیرفعال نیست. (به PRADC در صفحه 46 مراجعه کنید)
- با خاموش کردن MUX3… 0 در ثبت ADC Multiplexer Selection (ADMUX) کانال ورودی آنالوگ را ADC0 انتخاب کنید (به جدول 24-4 صفحه 249 مراجعه کنید) اینها به طور پیش فرض خاموش هستند بنابراین ما واقعاً نیازی به این کار نداریم. با این حال ، من آن را اضافه می کنم زیرا اگر تا به حال از پورتی غیر از ADC0 استفاده می کنید ، باید این سوئیچ ها را مطابق آن تغییر دهید. ترکیب های مختلف MUX3 ، MUX2 ، MUX1 ، MUX0 به شما این امکان را می دهد که از هر یک از پورت های آنالوگ به عنوان ورودی خود استفاده کنید و اگر می خواهید به طور همزمان به دسته ای از سیگنال های مختلف آنالوگ نگاه کنید ، می توانید آنها را به طور همزمان تغییر دهید.
- بیت های REFS0 و REFS1 را در ثبت ADMUX خاموش کنید تا از AREF بعنوان ولتاژ مرجع خود و نه مرجع داخلی استفاده کنیم (صفحه 248 را ببینید).
- بیت ADLAR را در ADMUX روشن کنید تا نتیجه "تنظیم شود" در مرحله بعد در مورد این انتخاب بحث خواهیم کرد.
- بیت ADC0D را در Digital Input Disable Register (DIDR0) تنظیم کنید تا ورودی دیجیتال روی PC0 خاموش شود. ما از آن پورت برای ورودی آنالوگ استفاده می کنیم ، بنابراین ممکن است ورودی دیجیتال را برای آن غیرفعال کنیم.
- ISC0 و ISC1 را در External Interrupt Control Register A (EICRA) قرار دهید تا نشان دهد که می خواهیم در لبه بالایی سیگنال ولتاژ به پین INT0 (PD2) راه اندازی کنیم ، به صفحه 71 مراجعه کنید.
- بیت های INT0 و INT1 را در External Interrupt Mask Register (EIMSK) پاک کنید تا نشان دهد که ما از وقفه در این پین استفاده نمی کنیم. اگر بخواهیم وقفه ها را روی این پین فعال کنیم ، به یک کنترل کننده وقفه در آدرس 0x0002 نیاز داریم ، اما در عوض آن را طوری تنظیم می کنیم که سیگنالی در این پین باعث تبدیل ADC شود ، که تکمیل آن با تبدیل کامل ADC در وقفه کامل انجام می شود. آدرس 0x002A به صفحه 72 مراجعه کنید.
- بیت ADC Enable (ADEN) (بیت 7) را در ADC control and status status A (ADCSRA) تنظیم کنید تا ADC فعال شود. صفحه 249 را ببینید.
- ما می توانیم با تنظیم بیت تبدیل ADC (ADSC) هر بار که می خواهیم سیگنال آنالوگ را بخوانیم ، یک تبدیل واحد را شروع کنیم ، با این حال ، در حال حاضر ترجیح می دهیم وقتی کسی دکمه را فشار می دهد ، به طور خودکار خوانده شود ، بنابراین در عوض ADC را فعال می کنیم بیت Autotrigger Enable (ADATE) را در ثبت ADCSRA فعال کنید تا راه اندازی به طور خودکار انجام شود.
- ما همچنین ADPS2..0 بیت (بیت AD Prescalar) را روی 111 تنظیم می کنیم به طوری که ساعت ADC ساعت CPU تقسیم بر ضریب 128 است.
- ما منبع ADC triggering PD2 را انتخاب می کنیم که INT0 (درخواست وقفه خارجی 0) نیز نامیده می شود. ما این کار را با تغییر بیت های مختلف در ثبت ADCSRB انجام می دهیم (به جدول 24-6 در صفحه 251 مراجعه کنید). در جدول می بینیم که می خواهیم ADTS0 خاموش ، ADTS1 روشن و ADTS2 خاموش باشد تا ADC آن پین را خاموش کند. توجه داشته باشید که اگر بخواهیم به طور پیوسته از پورت آنالوگ نمونه برداری کنیم ، مانند زمانی که سیگنال آنالوگ پیوسته ای را می خواندیم (مانند نمونه برداری از صدا یا مواردی از این دست) ، این حالت را بر روی حالت اجرای آزاد قرار می دهیم. روشی که ما از تنظیمات راه اندازی در PD2 استفاده می کنیم ، بدون ایجاد وقفه ، خواندن ADC از پورت آنالوگ PC0 را فعال می کند. وقفه زمانی رخ می دهد که تبدیل کامل شود.
- بیت ADC Interrupt Enable (ADIE) را در ثبت ADCSRA فعال کنید تا وقتی تبدیل آنالوگ به دیجیتال کامل شد ، وقفه ای ایجاد کند که می توانیم یک کنترل کننده وقفه برای آن بنویسیم و در.org 0x002A قرار دهیم.
- بیت I را در SREG تنظیم کنید تا وقفه ها فعال شوند.
تمرین 1: اطمینان حاصل کنید که بخش های مربوط در برگه اطلاعات مربوط به هر یک از تنظیمات فوق را مطالعه کرده اید تا متوجه شوید که در حال رخ دادن است و اگر آنها را به تنظیمات متناوب تغییر دهیم ، چه اتفاقی می افتد.
مرحله 7: Interrupt Handler را بنویسید
در آخرین مرحله ما دیدیم که آن را طوری تنظیم کرده ایم که یک لبه بالا رونده در PD2 تشخیص تبدیل آنالوگ به دیجیتال را در PC0 ایجاد می کند و هنگامی که این تبدیل کامل می شود ، یک وقفه تبدیل کامل ADC را ایجاد می کند. حالا ما می خواهیم با این وقفه کاری انجام دهیم. اگر جدول 12-6 را در صفحه 65 بررسی کنید ، لیستی از وقفه های احتمالی را مشاهده خواهید کرد. قبلاً وقفه RESET را در آدرس 0x0000 و وقفه Timer/Counter0 Overflow را در آدرس 0x0020 در آموزشهای قبلی مشاهده کرده بودیم. اکنون می خواهیم وقفه ADC را مشاهده کنیم که در جدول می بینیم آدرس 0x002A است. بنابراین در ابتدای کد زبان اسمبلی ما به خطی نیاز داریم که روی آن نوشته شده است:
.org 0x002Arjmp ADC_int
هنگامی که ADC یک تبدیل را تکمیل می کند ، به کنترل کننده وقفه ما با عنوان ADC_int می پردازد. بنابراین چگونه باید کنترل کننده وقفه خود را بنویسیم؟ روش کار ADC با محاسبه زیر است:
ADC = Vin x 1024 / Vref
بنابراین اجازه دهید ببینیم اگر دکمه "شماره گیری مجدد" روی صفحه کلید را فشار دهم ، چه اتفاقی می افتد. در این صورت ولتاژ در PC0 به مقداری تغییر می کند ، مثلاً 1.52V ، و از آنجا که Vref در 5V است ، ما موارد زیر را داریم:
ADC = (1.52V) x 1024 / 5V = 311.296
و بنابراین 311 نشان داده می شود. اگر بخواهیم این را به ولتاژ تبدیل کنیم ، محاسبه را معکوس می کنیم. ما نیازی به این کار نخواهیم داشت ، زیرا ما به ولتاژهای واقعی علاقه ای نداریم فقط بین آنها تمایز قائل شویم. پس از اتمام تبدیل ، نتیجه در یک عدد 10 بیتی ذخیره شده در ثبت ADCH و ADCL ذخیره می شود و ما باعث شده است که "تنظیم شود" ، به این معنی که 10 بیت از بیت 7 ADCH شروع شده و به بیت 6 ADCL (در مجموع 16 بیت در این دو ثبات وجود دارد و ما فقط از 10 مورد آنها ، یعنی 1024 کانال استفاده می کنیم). اگر بخواهیم بیت ADLAR را در ثبت ADMUX پاک کنیم ، می توانیم نتیجه را "درست تنظیم کنیم". دلیل اینکه ما تنظیم سمت چپ را انتخاب می کنیم این است که سیگنال های ما به اندازه کافی از هم فاصله دارند و دو رقم آخر شماره کانال مربوط نیستند و احتمالاً فقط نویز هستند بنابراین ما فقط با استفاده از 8 رقم بالا کلیدهای فشرده را تشخیص می دهیم ، به عبارت دیگر ، ما فقط باید به ADCH نگاه کنیم تا بفهمیم کدام دکمه فشار داده شده است. بنابراین کنترل کننده وقفه ما باید به سادگی عدد ADCH را بخواند ثبت نام کنید ، آن عدد را به مقدار صفحه کلید تبدیل کنید ، و سپس آن مقدار را به LED های تجزیه و تحلیل ثبت نام ارسال کنید تا بتوانیم تأیید کنیم که با فشار دادن عدد 9 ، چراغ LED مربوط به "00001001" روشن می شود. قبل از رفتن به آن هرچند باید ابتدا ببینیم وقتی دکمه های مختلف را فشار می دهیم در ADCH چه چیزی نشان داده می شود. بنابراین اجازه دهید فقط یک کنترل کننده وقفه ساده بنویسیم که فقط محتویات ADCH را به نمایشگر آنالیز ارسال کند. بنابراین آنچه ما نیاز داریم در اینجا آمده است:
ADC_int: تجزیه و تحلیل lds ، ADCH ؛ مقدار ADCH را در آنالیزرهای ما بارگذاری کنید EIFR ، 0 ؛ پرچم وقفه خارجی را پاک کنید تا آماده بازگشت مجدد باشد
در حال حاضر ، شما می توانید فقط کد را از تجزیه و تحلیل ما در آموزش 5 کپی کرده و این وقفه و تنظیمات ضامن را اضافه کرده و اجرا کنید. تمرین 2: کد را بنویسید و اجرا کنید. مطمئن شوید که ADCH روی صفحه آنالایزر خود نمایش داده می شود. سعی کنید یک کلید را چندین بار فشار دهید. آیا همیشه در ADCH همان مقدار را دریافت می کنید؟
مرحله 8: مقادیر کلید فشار را ترسیم کنید
آنچه اکنون باید انجام دهیم این است که مقادیر ADCH را به اعداد مربوط به کلید فشرده شده تبدیل کنیم. ما این کار را با نوشتن محتویات ADCH برای هر فشار کلید و سپس تبدیل آن به عدد اعشاری مانند آنچه در تصویر انجام دادیم ، انجام می دهیم. در روال مدیریت وقفه ، ما طیف وسیعی از مقادیر مربوط به هر فشار کلید را در نظر می گیریم ، به طوری که ADC هر چیزی را در این محدوده به یک فشار کلید داده شده ترسیم می کند.
تمرین 3: این نقشه را انجام دهید و سپس روال وقفه ADC خود را دوباره بنویسید.
در اینجا چیزی است که من برای خود گرفتم (به احتمال زیاد مال شما متفاوت خواهد بود). توجه کنید که من آن را با طیف وسیعی از مقادیر برای هر فشار کلید تنظیم کرده ام.
ADC_int:؛ تجزیه و تحلیل قطع کننده خارجی handlerclr؛ آماده شدن برای دکمه numberlds جدید H، ADCH؛ ADCH وقتی ADCH خوانده می شود clccpi buttonH ، 240brlo PC+3 ؛ اگر ADCH بزرگتر است ، آنالایزر 1ldi ، 1 است. بنابراین تجزیه و تحلیل بار با بازگشت 1rjmp ؛ و دکمه بازگشت clccpiH ، 230 ؛ اگر ADCH بزرگتر از آنالیز کننده 2brlo PC+3ldi ، 2rjmp دکمه بازگشت clccpiH ، 217brlo PC+3ldi آنالیز ، 3rjmp دکمه بازگشت clccpiH ، آنالیزور 203brlo PC+3ldi ، 4rjmp return clccpiH ، 187brlo PC+3ldi آنالیز ، 5rjmp بازگشت clccpi دکمه ، 155brlo PC+3ldi analyzer، 6rjmp return clccpi buttonH، 127brlo PC+3ldi analyzer، 255؛ ما فلش را به عنوان تمام دکمه های بازگشتی onrjmp clccpiH ، 115brlo PC+3ldi آنالیز ، 7rjmp دکمه بازگشت clccpiH ، 94brlo PC+3ldi آنالیز ، 8rjmp دکمه بازگشت clccpiH ، 62brlo PC+3ldi آنالیز ، 9rjmp دکمه بازگشت clccpiH ، 37brlo PC+3ldi آنالیز ، 0b11110000؛ asterisk is top top onrjmp return clccpi buttonH، 28brlo PC+3ldi analyzer، 0rjmp return clccpi buttonH، 17brlo PC+3ldi analyzer، 0b00001111؛ علامت هش نیمه پایینی است onrjmp دکمه بازگشت clccpiH ، 5brlo PC+3ldi analyzer، 0b11000011؛ دوباره شماره گیری بالا 2 پایین 2rjmp return ldi analyzer، 0b11011011؛ در غیر اینصورت خطای return: reti رخ داد
مرحله 9: کد و ویدیو برای نسخه 1
من کد خود را برای اولین نسخه درایور صفحه کلید ضمیمه کرده ام. در این مورد باید کلید را فشار داده و سپس دکمه را فشار دهید تا ADC ورودی صفحه کلید را بخواند. چیزی که ما ترجیح می دهیم این است که هیچ دکمه ای وجود نداشته باشد ، اما در عوض سیگنال انجام تبدیل از طریق خود فشار دادن کلید می آید. تمرین 3: این کد را جمع آوری و بارگذاری کرده و آن را امتحان کنید. ممکن است مجبور شوید آستانه های مختلف تبدیل را مطابق با ولتاژهای فشار صفحه کلید خود تغییر دهید ، زیرا احتمالاً با من متفاوت است. اگر بخواهید از ورودی صفحه کلید هم برای ADC0 و هم برای پین وقفه خارجی به جای دکمه استفاده کنید ، چه اتفاقی می افتد؟ من همچنین ویدئویی از عملکرد این اولین نسخه از درایور صفحه کلید خود را ضمیمه می کنم. متوجه خواهید شد که در کد من بخشی وجود دارد که Stack Pointer را آماده می کند. ثبات های مختلفی وجود دارد که ممکن است بخواهیم در هنگام دستکاری متغیرها و چیزهای دیگر از پشته آنها را بیرون بیاوریم و ثبت شوند ، همچنین ثبت هایی وجود دارد که ممکن است بخواهیم بعداً آنها را ذخیره و بازیابی کنیم. به عنوان مثال ، SREG یک ثبت است که در بین وقفه ها حفظ نمی شود ، بنابراین پرچم های مختلفی که در نتیجه عملیات تنظیم و پاک می شوند ممکن است در صورت وقفه در وسط چیزی تغییر کنند. بنابراین بهتر است SREG را در ابتدای کنترل کننده وقفه روی پشته فشار دهید و سپس در انتهای کنترل کننده وقفه دوباره آن را خاموش کنید. من آن را در کد قرار داده ام تا نحوه اولیه شدن آن را نشان دهم و پیش بینی کنم که چگونه بعداً به آن احتیاج خواهیم داشت ، اما از آنجا که اهمیتی نمی دهد چه اتفاقی برای SREG در وقفه در کد ما می افتد ، من از پشته برای این استفاده نکردم. همچنین توجه کنید که من از عملیات shift برای تنظیم بیت های مختلف در ثبات هنگام راه اندازی اولیه استفاده کرده ام. به عنوان مثال در خط:
ldi temp ، (1 <
دستور "<<" در خط اول کد بالا یک عملیات تغییر است. در اصل عدد دوتایی 1 را که 0b00000001 است می گیرد و با مقدار ISC01 آن را به سمت چپ تغییر می دهد. این موقعیت بیتی با نام ISC01 در ثبت EICRA است. از آنجا که ISC01 بیت 1 است ، عدد 1 به موقعیت 1 چپ منتقل می شود تا 0b00000010 شود. به طور مشابه ، دوم ، ISC00 ، بیت 0 EICRA است و بنابراین تغییر عدد 1 موقعیت صفر به چپ است. اگر نگاه دیگری به فایل m328Pdef.inc که در اولین آموزش بارگیری کرده اید و از آن زمان از evrr استفاده می کنید ، نگاهی بیاندازید ، خواهید دید که این فقط یک لیست طولانی از عبارت های ".equ" است. متوجه خواهید شد که ISC01 برابر 1. مونتاژ کننده قبل از شروع مونتاژ هر چیزی ، هر نمونه آن را با 1 جایگزین می کند. آنها فقط اسامی برای ثبت بیت هستند تا به ما انسان ها در خواندن و نوشتن کد کمک کنند. اکنون ، خط عمودی بین دو عملیات شیفت بالا یک عملیات منطقی "یا" است. در اینجا این معادله است:
0b00000010 | 0b00000001 = 0b00000011
و این چیزی است که ما در حال بارگذاری (با استفاده از "ldi") در temp هستیم. دلیل استفاده مردم از این روش برای بارگذاری مقادیر در یک ثبات این است که به شخص اجازه می دهد از نام بیت به جای یک عدد استفاده کند و این باعث می شود کد بسیار راحت تر خوانده شود. همچنین دو تکنیک دیگر نیز استفاده کرده ایم. ما از دستورالعمل های "ori" و "andi" استفاده می کنیم. این به ما امکان می دهد بیت ها را به ترتیب SET و CLEAR بدون تغییر هیچ یک از بیت های دیگر در یک ثبات ثبت کنیم. به عنوان مثال ، وقتی استفاده می کردم
ori temp ، (1
این دمای "یا" با 0b00000001 که 1 را در بیت صفر قرار می دهد و بقیه را بدون تغییر می گذارد. همچنین وقتی نوشتیم
andi temp ، 0b11111110
این مقدار صفر درجه دما را به 0 تغییر می دهد و بقیه را بدون تغییر می گذارد.
تمرین 4: باید کد را مرور کنید و مطمئن شوید که هر خط را درک کرده اید. شاید برای شما جالب باشد که روشهای بهتری برای انجام کارها و نوشتن یک برنامه بهتر پیدا کنید. صد روش برای کدگذاری چیزها وجود دارد و من مطمئن هستم که می توانید راهی بسیار بهتر از روش من پیدا کنید. شما همچنین ممکن است خطاها و حذف ها را (خدای ناکرده!) پیدا کنید. در این صورت من مطمئناً دوست دارم در مورد آنها بشنوم تا بتوان آنها را برطرف کرد.
خوب ، حالا ببینیم آیا می توانیم آن دکمه اضافی را از بین ببریم یا خیر …
مرحله 10: کد نسخه 2
ساده ترین راه برای خلاص شدن از شر دکمه این است که آن را به کل حذف کنید ، ورودی PB2 را فراموش کرده و ADC را به "حالت اجرای رایگان" تغییر دهید.
به عبارت دیگر به سادگی ثبت نام ADCSRB را تغییر دهید تا ADTS2 ، ADTS1 و ADTS0 همه صفر باشند.
سپس بیت ADSC را در ADCSRA روی 1 تنظیم کنید که اولین تبدیل را آغاز می کند.
اکنون آن را روی میکروکنترلر خود بارگذاری کنید و متوجه خواهید شد که در حالی که دکمه را فشار می دهید و فقط در حالی که دکمه را فشار می دهید ، عدد صحیح روی صفحه نمایش ظاهر می شود. این به این دلیل است که ADC به طور مداوم از پورت ADC0 نمونه برداری می کند و مقدار را نشان می دهد. وقتی انگشت خود را از روی دکمه بر می دارید ، "برگشت دکمه" باعث می شود که چند مقدار تصادفی خیلی سریع اتفاق بیفتد و سپس به ورودی 0V برگردد. در کد ما این 0V را با 0b11011011 نشان می دهیم (زیرا کلید 0 "در حال حاضر از مقدار نمایش 0b00000000 استفاده می کند)
این راه حلی نیست که ما می خواهیم هر چند به دو دلیل. ابتدا ما نمی خواهیم مجبور باشیم دکمه را نگه داریم. ما می خواهیم آن را یکبار فشار دهیم و شماره نمایش داده شود (یا در برخی از کدهای جدید در آموزش بعدی استفاده شود). ثانیاً ، ما نمی خواهیم مدام از ADC0 نمونه بگیریم. ما می خواهیم که یک بار خوانده شود ، آن را تبدیل کرده و سپس بخوابد تا با فشار دادن کلید جدید تبدیل جدیدی ایجاد شود. حالت رایگان اجرا می شود اگر تنها کاری که می خواهید میکروکنترلر انجام دهد این است که مدام ورودی آنالوگ را بخوانید - مانند این که می خواهید دمای زمان واقعی یا مواردی را نشان دهید.
بنابراین بیایید راه حل دیگری بیابیم…
مرحله 11: چگونه از دکمه خلاص شویم؟ نسخه 3
راههای متعددی وجود دارد که می توانیم ادامه دهیم. ابتدا می توانیم سخت افزاری را برای خلاص شدن از شر دکمه اضافه کنیم. به عنوان مثال ، ممکن است سعی کنیم یک ترانزیستور را در مدار در خط خروجی فشار صفحه کلید قرار دهیم تا یک جریان کوچک از خروجی گرفته شده و یک پالس 5 ولت به پین قطع PD2 ارسال شود.
با این حال ، این احتمالاً حداقل بیش از حد پر سر و صدا خواهد بود و در بدترین حالت زمان کافی را برای خواندن دقیق کلید فشار نمی دهد ، زیرا ولتاژ خروجی صفحه کلید قبل از ضبط ADC زمان برای ثابت ماندن ندارد.
بنابراین ترجیح می دهیم یک راه حل نرم افزاری ارائه دهیم. آنچه ما می خواهیم انجام دهیم این است که یک وقفه در پین PD2 اضافه کنیم و برای آن یک کنترل کننده وقفه بنویسیم که یک خوانش واحد از پین صفحه کلید را فرا می خواند. به عبارت دیگر ، ما از وقفه autotrigger از ADC خلاص می شویم و یک وقفه خارجی اضافه می کنیم که ADC را درون آن فراخوانی می کند. به این ترتیب سیگنال خواندن ADC بعد از اینکه سیگنال PD2 قبلاً رخ داده است می آید و این ممکن است زمان کافی را برای ولتاژ دقیق قبل از خواندن و تبدیل پین PC0 ایجاد کند. ما هنوز یک وقفه تکمیل ADC داریم که نتیجه را در انتها به نمایشگر تجزیه و تحلیل می دهد.
معنی دارد؟ خوب انجامش بده…
به کد جدید پیوست نگاهی بیندازید.
تغییرات زیر را مشاهده می کنید:
- ما rjmp را به آدرس.org 0x0002 اضافه کردیم تا وقفه خارجی INT0 را مدیریت کند
- ما ثبت EIMSK را تغییر دادیم تا نشان دهیم می خواهیم در پین INT0 وقفه ایجاد کنیم
- ما پین ADATE را در ثبت ADCSRA تغییر دادیم تا فعالسازی خودکار غیرفعال شود
- ما از تنظیمات ADCSRB خلاص شدیم زیرا وقتی ADATE خاموش است بی ربط هستند
- ما دیگر مجبور نیستیم پرچم ماشه خارجی را بازنشانی کنیم زیرا روال وقفه INT0 این کار را به طور خودکار پس از اتمام انجام می دهد - قبلاً ما روال وقفه ای نداشتیم ، فقط ADC را از یک سیگنال در آن پین خاموش می کردیم ، بنابراین مجبور شدیم آن پرچم را با دست پاک کنید
اکنون در کنترل کننده وقفه به سادگی یک تبدیل واحد از ADC می نامیم.
تمرین 5: این نسخه را اجرا کنید و ببینید چه اتفاقی می افتد.
مرحله 12: کد و ویدئو برای نسخه کار
همانطور که در آخرین نسخه مشاهده کردیم ، وقفه دکمه خیلی خوب کار نمی کند زیرا وقفه در یک لبه رو به بالا برای پین کردن PD2 فعال می شود و سپس کنترل کننده وقفه تبدیل ADC را فراخوانی می کند. با این حال ، ADC سپس ولتاژ را قبل از تثبیت شدن دریافت می کند و بنابراین مزخرف می خواند.
آنچه ما نیاز داریم این است که بین وقفه در PD2 و خواندن ADC در PC0 تأخیر ایجاد کنیم. ما این کار را با افزودن زمان سنج/شمارنده ، وقفه سرریز شمارنده و روال تاخیری انجام می دهیم. خوشبختانه ما قبلاً می دانیم چگونه این کار را از آموزش 3 انجام دهیم! بنابراین ما فقط کد مربوطه را از آنجا کپی و جایگذاری می کنیم.
من کد حاصله و ویدئویی را که در حال کار است نشان داده ام.
متوجه خواهید شد که قرائتها آنطور که انتظار می رود دقیق نیستند. این به احتمال زیاد به دلیل تعدادی از منابع است:
- ما از خروجی ولتاژ صفحه کلید برای فعال کردن PD2 استفاده می کنیم که بر خواندن در PC0 تأثیر می گذارد.
- ما واقعاً نمی دانیم چه مدت بعد از ماشه تاخیر داشته باشیم تا بهترین خواندن را داشته باشیم.
- چند دوره طول می کشد تا تبدیل ADC کامل شود ، به این معنی که ما نمی توانیم روی صفحه کلید سریع شلیک کنیم.
- احتمالاً در خود صفحه کلید نویز وجود دارد.
- و غیره…
بنابراین ، اگرچه ما موفق شدیم صفحه کلید را به کار بیندازیم و اکنون می توانیم از آن در برنامه ها با استفاده از مقادیر کلید فشار به نحوی دیگر به جای خروجی آنها فقط به صفحه آنالیز استفاده کنیم ، اما بسیار دقیق نیست و بسیار آزاردهنده است. به همین دلیل است که من فکر می کنم بهترین راه برای سیم کشی صفحه کلید این است که هر خروجی را از صفحه کلید به درگاه دیگری بچسبانید و تصمیم بگیرید که کدام کلید توسط کدام پورت ها ولتاژ مشاهده می شود. این آسان ، بسیار سریع و بسیار دقیق است.
در واقع ، تنها دو دلیل وجود دارد که چرا شخص می خواهد صفحه کلید را به شیوه ای که در اینجا انجام داده ایم رانندگی کند:
- فقط از 2 پین روی میکروکنترلر ما به جای 8 استفاده می کند.
- این یک پروژه عالی برای نشان دادن جنبه های مختلف ADC بر روی میکروکنترلر است که متفاوت از چیزهای استاندارد است که می توانید در آنجا پیدا کنید مانند خواندن دما ، چرخش پتانسیومترها و غیره. من می خواستم یک نمونه از قرائت های تک و تحریک کننده خودکار پین خارجی به جای اینکه فقط حالت CPB gobbling را اجرا کنید.
به هر حال ، در اینجا چند تمرین آخر برای شما آمده است:
تمرین 6: برای استفاده از جدول Look-up ، کنترل کننده وقفه تبدیل ADC را دوباره بنویسید. یعنی به طوری که مقدار آنالوگ را با اولین مورد در جدول آزمایش می کند و اگر بزرگتر باشد از وقفه برمی گردد ، اگر اینطور نباشد Z را به مورد بعدی جدول افزایش می دهد و دوباره به آزمایش منشعب می شود. این باعث کوتاه شدن کد و تمیز کردن روال وقفه و زیباتر جلوه دادن آن می شود. (در مرحله بعد راه حل احتمالی را ارائه خواهم داد) تمرین 7: صفحه کلید خود را به 8 پین روی میکروکنترلر متصل کرده و درایور ساده را برای آن بنویسید و تجربه کنید که چقدر زیبا تر است. آیا می توانید به چند روش برای بهتر کارکردن روش ما فکر کنید؟
این همه برای این آموزش است. من نسخه نهایی را با اشاره گرها ضمیمه کرده ام. همانطور که به هدف نهایی خود نزدیک می شویم ، در آموزش 9 بار دیگر از صفحه کلید استفاده می کنیم تا نحوه کنترل هفت صفحه نمایش را با آن (و ایجاد چیزی جالب که از کلیدهای اضافی روی صفحه کلید تلفن استفاده می کند) نشان دهیم و سپس در عوض ، با فشار دادن دکمه ها به کنترل امور بپردازید (زیرا این روش با محصول نهایی که ما با این آموزش ها در حال ساختن آن هستیم ، بیشتر مناسب است) و ما فقط صفحه کلید را قفل می کنیم.
بعدا می بینمت!
توصیه شده:
آموزش AVR Assembler 2: 4 مرحله
آموزش AVR Assembler 2: این آموزش ادامه & quot؛ آموزش AVR Assembler 1 & quot؛ اگر از آموزش 1 استفاده نکرده اید ، باید همین حالا متوقف شوید و ابتدا این کار را انجام دهید. در این آموزش ما مطالعه برنامه نویسی زبان اسمبلی atmega328p u را ادامه می دهیم
آموزش AVR Assembler 1: 5 مرحله
آموزش AVR Assembler 1: من تصمیم گرفته ام که یک سری آموزش نحوه نوشتن برنامه های زبان اسمبلی برای Atmega328p که میکروکنترلری است که در آردوینو استفاده می شود ، بنویسم. اگر مردم به این موضوع علاقه نشان دهند ، من هفته ای یکبار این کار را انجام می دهم تا زمانی که تمام نشوم
آموزش AVR Assembler 6: 3 مرحله
آموزش AVR Assembler 6: به آموزش 6 خوش آمدید! آموزش امروز کوتاه خواهد بود که در آن ما یک روش ساده برای ارتباط داده ها بین یک atmega328p و دیگری با استفاده از دو پورت متصل به یکدیگر ایجاد می کنیم. سپس تاس را از آموزش 4 و ثبت نام برمی داریم
آموزش AVR Assembler 8: 4 مرحله
AVR Assembler 8 تخته مدار
آموزش AVR Assembler 9: 7 مرحله
AVR Assembler 9 در حین انجام این کار ، ما مجبور به تغییر نحوه استفاده از پشته می شویم