Написання програм для світлодіода
Принципова електрична схема
Спробуємо розробити принципову електричну схему, здатну виконувати описану вище задачу. Отже, до мікроконтролера нам потрібно підключити світлодіод і кнопку управління. Як ми вже говорили, для підключення до мікроконтролеру AVR будь-яких зовнішніх пристроїв використовуються порти вводу-виводу. Причому кожен такий порт здатний працювати або на ввід, або і на вивід.
Найзручніше світлодіод підключити до одного з портів, а кнопку - до іншого. У цьому випадку керуюча програма повинна буде налаштувати порт, до якого підключений світлодіод, на вивід, а порт, до якого підключена кнопка, на ввід. Інших спеціальних вимог до мікроконтролера немає. Для цієї задачі і для усіх інших обираємо мікроконтроллер MEGA8.
Мікроконтролер має три основних порти вводу-виводу (порт В, С і D). Домовимося, що для управління світлодіодом ми будемо використовувати третій розряд порту С (лінія РС.3), а для зчитування інформації з кнопки управління використовуємо перший розряд порту С (лінія PС.1). Повна схема пристрою, що дозволяє вирішити поставлене вище завдання, наведено на рис.14.
Рисунок 14 - Принципова схема з одним світлодіодом і однією кнопкою
При замиканні кнопки напруга на резисторі R1 зростає до напруги живлення, що відповідає логічній одиниці. Таким чином, зчитуючи значення сигналу на відповідному виводі порту, програма може визначати момент натискання кнопки.
Головне при написанні програми - не забути відключити програмним шляхом відповідний навантажувальний резистор.
Підключення світлодіода також виконано за класичною схемою. Це безпосереднє підключення до виходу порту. Кожен вихід мікроконтролера розрахований на безпосереднє керування світлодіодом середньої потужності із струмом споживання до 20 мА. У коло світлодіода включений струмообмежуючий резистор R2.
Для того, щоб запалити світлодіод, мікроконтролер повинен подати на вивід РС.3 сигнал логічної одиниці. У цьому випадку висока напруга, прикладена до кола VD1, R2, викличе струм через світлодіод, і він загориться. Якщо ж на вивід РС.3 подати сигнал логічного нуля, спад напруги на світлодіоді і резисторі виявиться рівним нулю, і світлодіод погасне.
Крім кола підключення кнопки і кола керування світлодіодом, на схемі може бути кілька кіл. Це стандартні кола, що забезпечують нормальну роботу мікроконтролера. Кварцовий резонатор Х1 забезпечує роботу вбудованого тактового генератора. Конденсатори С2 і СЗ - це кола узгодження кварцового резонатора.
Елементи Cl, R3 - це стандартне коло початкового онулення (RESET). Таке коло забезпечує онулення мікроконтролера в момент включення живлення. Ще недавно подібне коло було обов'язковим атрибутом будь-якої мікропроцесорної системи. Однак технологія виробництва мікроконтролерів досягла такого рівня, що ці обидва кола (зовнішній кварц і коло початкового онулення) тепер можна відкинути.
Коло початкового онулення теж можна опустити. Будь-який мікроконтролер AVR має внутрішню систему онулення, яка в більшості випадків прекрасно забезпечує стабільне онулення при включенні живлення. Зовнішні кола RESET застосовуються тільки за наявності особливих вимог до тривалості імпульсу онулення. А це буває лише в тих випадках, коли мікроконтролер працює в умовах великих перешкод і нестабільного живлення.
Всі описані вище налаштування виробляються за допомогою відповідних fuse-перемикачів.
Спростимо схему, показану на рис. 14, з урахуванням описаних вище можливостей. Від зовнішнього кварцу поки відмовлятися не будемо. Він стане в нагоді трохи пізніше, коли ми почнемо формувати часові інтервали. Допрацьована схема зображена на рис. 15. Ця схема буде використана як основа для наступних завдань.
Рисунок 15 - Принципова схема з одним світлодіодом і однією кнопкою
Алгоритм
Отже, схема складена. Приступаємо до розробки програми. Розробка будь-якої програми починається з розробки алгоритму.
Визначення.'>Визначення. Алгоритм - це послідовність дій, яку повинен зробити мікроконтролер, щоб досягти необхідного результату. Для простих завдань алгоритм можна просто описати словами. Для більш складних завдань алгоритм подається у графічному вигляді.
У нашому випадку алгоритм такий: Після операцій початкової настройки портів мікроконтролер повинен увійти в безперервний цикл, в процесі якого він повинен опитувати вхід, підключений до кнопци, і залежно від її стану управляти світлодіодом. Опишемо це докладніше.
Операції початкової настройки:
- встановити початкове значення для вершини стека мікроконтролера;
- налаштувати лінію 3 порту С на вивід інформації;
- подати на лінію РС.3 сигнал логічного нуля (згасити світлодіод);
- налаштувати лінію 1 порту С на введення;
- виключити внутрішній навантажувальний резистор порту РС.1.
Операції, що становить тіло циклу:
- прочитати стан першого розряду порту PС (PС.1);
- якщо значення цього розряду дорівнює нулю, вимкнути світлодіод;
- якщо значення розряду РС.1 дорівнює одиниці, включити світлодіод;
- перейти на початок циклу.
Програма мовою Сі
Для створення програм мовою Сі використаємо програмне середовище CodeVisionAVR. За допомогою майстра створимо новий проект.
У вікні налаштувань CodeWizard налаштуємо параметри контролера для створюваного проекту. Відразу після запуску майстра всі параметри приймають значення за замовчуванням (всі внутрішні пристрої вимкнені, а всі порти вводу-виводу налаштовані на ввід, внутрішні навантажувальні резистори відключені). Це відповідає початковому стану мікроконтролера безпосередньо після системного онулення.
На вкладці «Chip» вибираємо загальні параметри проекту. Використовуючи псадаючий список, виберемо тип мікроконтролера – Atmega8. У полі «Clock» вибираємо частоту кварцового резонатора. У нашому випадку вона залишається заводською і рівна1 МГц. За допомогою поля «Crystal Oscillator Divider» вибирається коефіцієнт зниження частоти тактового генератора. Цей параметр вимагає пояснень. Справа в тому, що обраний нами мікроконтролер має систему попереднього зниження частоти (ділення) тактових імпульсів. Якщо частота тактового генератора нас не влаштовує, ми можемо поділити її, і мікроконтролер буде працювати на інший, більш низькій частоті. Коефіцієнт ділення може змінюватися від 1 до 256. Ми виберемо його рівним одиниці (без поділу). Тобто залишимо значення за замовчуванням.
Без змін залишимо прапорець «Check Reset Source» (Перевірка джерела сигналу онулення). Установка даного прапорця додає до створюваної програмі процедуру, пов'язану з визначенням джерела сигналу системного Reset.
У вкладці «Ports» (порти) налаштуємо потрібні порти вводу-виводу. Як вже говорилося вище, у проекті використовуємо порт РС, тому відразу вибираємо вкладку «Port С».
Стовпець «Data direction» (Напрям передачі даних) дозволяє налаштувати кожну лінію порту або на ввід, або на вивід. За замовчуванням кожен параметр має значення «In» (вхід). Поміняємо для третього розряду це значення на «Out» (Вихід). Кожне поле стовпця «Data direction» визначає, яке значення буде присвоєно відповідному розряду регістра DDRС в нашій майбутній програмі.
Другий стовпець на тій же вкладці називається «Pullup / Output Value» (Включення навантаження / Вихідне значення). Цей стовпець визначає, яке значення буде присвоєно кожному з розрядів регістра PORTС. У нашому випадку лінія порту РС.3 працює на вивід. За умовами нашого завдання лінія порту РС.3 повинна бути рівна нулю (при старті програми світлодіод повинен бути погашений). Тому у цьому полі залишаємо нуль. Тепер перейдемо до налаштування останнього порту. За умовою завдання лінія порту PС.1 мікроконтролера повинна працювати на введення. Тому стан лінії порту PС.1 ми не змінюємо.
Однак не забувайте, що нам потрібно відключити внутрішні навантажувальні резистори для входу PС.1. Для цього змінимо значення елемента другого стовбця. Так як PС.1 працює в режимі вводу, елемент в стовпці «Pullup / Output Value» може приймати значення «Т» або «Р».
Скористаємося ще однією корисною властивістю майстра програм. Відкриємо вкладку «Project Information». В полі «Project Name» можна вказати назву проекту. Поле «Version» призначено для номера версії. В полі «Date» поміщають дату розробки програми. У полях «Author» і «Company» поміщається, відповідно, ім'я автора та назву компанії. В полі «Comments:» можна помістити будь-які необхідні коментарі. Вся ця інформація буде автоматично поміщена в заголовок майбутньої програми.
Після того, як всі параметри виставлені, приступаємо безпосередньо до процесу генерації програми. Для цього вибираємо в меню «File» нашого майстра пункт «Generate, Save and Exit». Рекомендується для кожного проекту створювати свій окремий каталог.
Отже, отримали заготовку програми. Програма мовою Сі, на відміну від Ассемблера, більше абстрагована від системи команд мікроконтролера. Основні оператори мови Сі зовсім не прив'язані до команд мікроконтролера. Для реалізації однієї команди мовою Сі насправді використовується не одна, а кілька команд мікроконтролера. Іноді навіть невелика програма.
В результаті полегшується праця програміста, так як він тепер працює з більш великими категоріями. Йому не доводиться вдаватися в дрібні подробиці, і він може зосередитися на головному. Мова Сі так само, як і інші мови програмування, складається з команд. Для запису кожної команди Сі використовує свої оператори та псевдооператор. Форма написання команд у програмі наближена до форми, прийнятої в математиці.
Текст програми, який ви бачите в лістингу Рис.17, в основному сформований автоматично. Більшу частину програми займає функція main. Вона починається в рядку 2 і закінчується в кінці програми. Вся програма забезпечена докладними коментарями, які також сформовані автоматично.
/***************************************************** This program was produced by the CodeWizardAVR V2.04.4a Advanced Automatic Program Generator © Copyright 1998-2009 Pavel Haiduc, HP InfoTech s.r.l. http://www.hpinfotech.com Project : lab1 Version : 1 Date : 06.10.2014 Author : Vovk P. Company : Comments: Chip type : ATmega8 Program type : Application AVR Core Clock frequency: 1,000000 MHz Memory model : Small External RAM size : 0 Data Stack size : 256 *****************************************************/ char a=0; //Оголошуємо змінну а довжиною 8 біт // Declare your global variables here { // Declare your local variables here // Input/Output Ports initialization // Port B initialization // Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In // State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T PORTB=0x00; DDRB=0x00; // Port C initialization Налаштування ліній порту С // Func6=In Func5=In Func4=In Func3=Out Func2=In Func1=In Func0=In // State6=T State5=T State4=T State3=0 State2=T State1=Т State0=T PORTC=0x02; DDRC=0x08; // Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In // State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T PORTD=0x00; DDRD=0x00; // Clock source: System Clock // Clock value: Timer 0 Stopped TCCR0=0x00; TCNT0=0x00; // Clock source: System Clock // Clock value: Timer1 Stopped // Mode: Normal top=FFFFh // OC1A output: Discon. // OC1B output: Discon. // Noise Canceler: Off // Input Capture on Falling Edge // Timer1 Overflow Interrupt: Off // Input Capture Interrupt: Off // Compare A Match Interrupt: Off // Compare B Match Interrupt: Off TCCR1A=0x00; TCCR1B=0x00; TCNT1H=0x00; TCNT1L=0x00; ICR1H=0x00; ICR1L=0x00; OCR1AH=0x00; OCR1AL=0x00; OCR1BH=0x00; OCR1BL=0x00; // Timer/Counter 2 initialization // Clock source: System Clock // Clock value: Timer2 Stopped // Mode: Normal top=FFh // OC2 output: Disconnected ASSR=0x00; TCCR2=0x00; TCNT2=0x00; OCR2=0x00; // INT0: Off // INT1: Off MCUCR=0x00; // Timer(s)/Counter(s) Interrupt(s) initialization TIMSK=0x00; // Analog Comparator initialization // Analog Comparator: Off // Analog Comparator Input Capture by Timer/Counter 1: Off ACSR=0x80; SFIOR=0x00; {a=PINC.1;// присвоюємо зчитане з лінії РС.1 значення змінній а if (a==1) {PORTC.3=1;}// якщо а=1 (кнопка натиснена), то запалюємо //світлодіод (на лінію РС.3 виставляємо високу напругу) else {PORTC.3=0;}//якщо кнопка не натиснена (а=0),на лінію РС.3 //виставляємо низьку напругу };//кінець циклу } |
Винятки становлять усі українськомовні коментарі, які додано вручну, і три рядки в кінці програми. Починається програма із заголовку. На початку заголовку майстер помістив інформацію про проект (тип процесора, його тактову частоту, модель пам'яті (Tiny - означає мала модель), розмір використовуваної зовнішньої пам'яті і розмір стеку).
Команда include приєднує файл описів. Після команди include майстер помістив повідомлення для програміста. Повідомлення попереджає про те, що саме в цьому місці програмісту потрібно помістити опис всіх глобальних змінних (якщо, звичайно, вони вам знадобляться). У даному конкретному випадку глобальною змінною є змінна а.
Зайві команди при бажанні можна прибрати. У нашому випадку достатньо залишити лише команди ініціалізації портів. А також команду ініціалізації компаратора.
Тепер подивимося, як же відбувається присвоєння значень. Регістру CLKPR присвоюється значення 0x80. Для присвоєння значення використовується символ «=» (дорівнює). У мові С такий символ називається оператором привласнення. Таким же самим чином присвоюються значення і всім іншим регістрів.
Регістрам PORTB, PORTD та DDRB, DDRD присвоюється значення 0x00, а в регістри PORTС записується 0x02, DDRС – 0х08.
Особливістю архітектури мікроконтроллерів є можливість напряму присвоювати порту значення іншого порту. Тому основний цикл можна спростити до однієї команди: PORTC.3 = PINC.1 (регістру PORTС присвоюється значення регістра PІNС.1. Виконуючись багаторазово у нескінченному циклі, команда присвоєння постійно переносить вміст порту PС.1 в порт РС.3, реалізуючи тим самим наш алгоритм.
Комментариев нет:
Отправить комментарий