13.10.2022 Заняття №9

 Написання програм для світлодіода

Принципова електрична схема

        Спробуємо розробити принципову електричну схему, здатну виконувати описану вище задачу. Отже, до мікроконтролера нам потрібно підключити світлодіод і кнопку управління. Як ми вже говорили, для підключення до мікроконтролеру AVR будь-яких зовнішніх пристроїв використовуються порти вводу-виводу. Причому кожен такий порт здатний працювати або на ввід, або і на вивід.

        Найзручніше світлодіод підключити до одного з портів, а кнопку - до іншого. У цьому випадку керуюча програма повинна буде налаштувати порт, до якого підключений світлодіод, на вивід, а порт, до якого підключена кнопка, на ввід. Інших спеціальних вимог до мікроконтролера немає. Для цієї задачі і для усіх інших обираємо мікроконтроллер MEGA8.

        Мікроконтролер має три основних порти вводу-виводу (порт В, С і D). Домовимося, що для управління світлодіодом ми будемо використовувати третій розряд порту С (лінія РС.3), а для зчитування інформації з кнопки управління використовуємо перший розряд порту С (лінія PС.1). Повна схема пристрою, що дозволяє вирішити поставлене вище завдання, наведено на рис.14.





Рисунок 14 - Принципова схема з одним світлодіодом і однією кнопкою

        Для підключення кнопки S1 використана класична схема. У початковому стані контакти кнопки розімкнуті. Через резистор R1 на вхід PС.1 мікроконтролера подається «Земля» напруги живлення, що відповідає сигналу логічного нуля.

        При замиканні кнопки напруга на резисторі R1 зростає до напруги живлення, що відповідає логічній одиниці. Таким чином, зчитуючи значення сигналу на відповідному виводі порту, програма може визначати момент натискання кнопки.

        Головне при написанні програми - не забути відключити програмним шляхом відповідний навантажувальний резистор.

        Підключення світлодіода також виконано за класичною схемою. Це безпосереднє підключення до виходу порту. Кожен вихід мікроконтролера розрахований на безпосереднє керування світлодіодом середньої потужності із струмом споживання до 20 мА. У коло світлодіода включений струмообмежуючий резистор R2.

       Для того, щоб запалити світлодіод, мікроконтролер повинен подати на вивід РС.3 сигнал логічної одиниці. У цьому випадку висока напруга, прикладена до кола VD1, R2, викличе струм через світлодіод, і він загориться. Якщо ж на вивід РС.3 подати сигнал логічного нуля, спад напруги на світлодіоді і резисторі виявиться рівним нулю, і світлодіод погасне.

        Крім кола підключення кнопки і кола керування світлодіодом, на схемі може бути кілька кіл. Це стандартні кола, що забезпечують нормальну роботу мікроконтролера. Кварцовий резонатор Х1 забезпечує роботу вбудованого тактового генератора. Конденсатори С2 і СЗ - це кола узгодження кварцового резонатора.

        Елементи Cl, R3 - це стандартне коло початкового онулення (RESET). Таке коло забезпечує онулення мікроконтролера в момент включення живлення. Ще недавно подібне коло було обов'язковим атрибутом будь-якої мікропроцесорної системи. Однак технологія виробництва мікроконтролерів досягла такого рівня, що ці обидва кола (зовнішній кварц і коло початкового онулення) тепер можна відкинути.

        Більшість мікроконтролерів AVR, крім тактового генератора із зовнішнім кварцовим резонатором, містять внутрішній RC-генератор, який не потребує ніяких зовнішніх кіл. Якщо ви не пред'являєте високих вимог до точності і стабільності частоти тактового генератора, то мікросхему можна перевести в режим внутрішнього
RC-генератора і відмовитися як від зовнішнього кварцу (Х1), так і від узгоджувальних конденсаторів (С2 і СЗ).

        Коло початкового онулення теж можна опустити. Будь-який мікроконтролер 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» може приймати значення «Т» або «Р».

«Т» (Terminate) означає відсутність внутрішньої навантаження, а «Р» (Pull-up) означає: навантаження включене. Віключимо навантаження для PС.1, змінивши за допомогою миші значення поля на «Т». В результаті елементи управління будуть виглядати так, як показано на рис. 16.
Рисунок 16 – Налаштування портів проекту
Для даної програми налаштування можна вважати завершеними. Інші системи мікроконтролера нам поки не потрібні. Залишимо їх налаштування без змін.

Скористаємося ще однією корисною властивістю майстра програм. Відкриємо вкладку «Project Information». В полі «Project Name» можна вказати назву проекту. Поле «Version» призначено для номера версії. В полі «Date» поміщають дату розробки програми. У полях «Author» і «Company» поміщається, відповідно, ім'я автора та назву компанії. В полі «Comments:» можна помістити будь-які необхідні коментарі. Вся ця інформація буде автоматично поміщена в заголовок майбутньої програми.

Після того, як всі параметри виставлені, приступаємо безпосередньо до процесу генерації програми. Для цього вибираємо в меню «File» нашого майстра пункт «Generate, Save and Exit». Рекомендується для кожного проекту створювати свій окремий каталог.

Отже, отримали заготовку програми. Програма мовою Сі, на відміну від Ассемблера, більше абстрагована від системи команд мікроконтролера. Основні оператори мови Сі зовсім не прив'язані до команд мікроконтролера. Для реалізації однієї команди мовою Сі насправді використовується не одна, а кілька команд мікроконтролера. Іноді навіть невелика програма.

В результаті полегшується праця програміста, так як він тепер працює з більш великими категоріями. Йому не доводиться вдаватися в дрібні подробиці, і він може зосередитися на головному. Мова Сі так само, як і інші мови програмування, складається з команд. Для запису кожної команди Сі використовує свої оператори та псевдооператор. Форма написання команд у програмі наближена до форми, прийнятої в математиці.

Текст програми, який ви бачите в лістингу Рис.17, в основному сформований автоматично. Більшу частину програми займає функція main. Вона починається в рядку 2 і закінчується в кінці програми. Вся програма забезпечена докладними коментарями, які також сформовані автоматично.


Лістінг 1 – Найпростіша програма керування світлодіодом


/*****************************************************

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

*****************************************************/
#include //Підключення бібліотеки підтримки Atmega8

char a=0; //Оголошуємо змінну а довжиною 8 біт

// Declare your global variables here
void main(void)

{

// 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;
// Port D 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

PORTD=0x00;

DDRD=0x00;
// Timer/Counter 0 initialization

// Clock source: System Clock

// Clock value: Timer 0 Stopped

TCCR0=0x00;

TCNT0=0x00;
// Timer/Counter 1 initialization

// 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;
// External Interrupt(s) initialization

// 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;
while (1)//основний цикл програми

{a=PINC.1;// присвоюємо зчитане з лінії РС.1 значення змінній а

if (a==1) {PORTC.3=1;}// якщо а=1 (кнопка натиснена), то запалюємо //світлодіод (на лінію РС.3 виставляємо високу напругу)

else {PORTC.3=0;}//якщо кнопка не натиснена (а=0),на лінію РС.3 //виставляємо низьку напругу

};//кінець циклу

}

Винятки становлять усі українськомовні коментарі, які додано вручну, і три рядки в кінці програми. Починається програма із заголовку. На початку заголовку майстер помістив інформацію про проект (тип процесора, його тактову частоту, модель пам'яті (Tiny - означає мала модель), розмір використовуваної зовнішньої пам'яті і розмір стеку).

Команда include приєднує файл описів. Після команди include майстер помістив повідомлення для програміста. Повідомлення попереджає про те, що саме в цьому місці програмісту потрібно помістити опис всіх глобальних змінних (якщо, звичайно, вони вам знадобляться). У даному конкретному випадку глобальною змінною є змінна а.

Функція main містить в собі набір команд налаштування системи (рядки 3-30) і заготовку головного циклу програми.
ВизначенняНалаштування системи - це запис необхідних значень у всі керуючі регістри мікроконтролера.
Значення службових регістрів мікроконтролера, окрім портів, можна залишити за замовчуванням. Але майстер-будівник програми привласнює значення всім без винятку службовим регістрам. І тим, значення яких повинні відрізнятися від значень за замовчуванням, і тим, значення яких не змінюються. Такі, на перший погляд, надлишкові дії мають свій сенс. Вони гарантують правильну роботу програми в тому випадку, якщо в результаті помилки у програмі керування буде передано на її початок.

Зайві команди при бажанні можна прибрати. У нашому випадку достатньо залишити лише команди ініціалізації портів. А також команду ініціалізації компаратора.

Тепер подивимося, як же відбувається присвоєння значень. Регістру CLKPR присвоюється значення 0x80. Для присвоєння значення використовується символ «=» (дорівнює). У мові С такий символ називається оператором привласнення. Таким же самим чином присвоюються значення і всім іншим регістрів.

Регістрам PORTB, PORTD та DDRB, DDRD присвоюється значення 0x00, а в регістри PORTС записується 0x02, DDRС – 0х08.

Після ініціалізації всіх регістрів починається основний цикл програми.

Основний цикл - це обов'язковий елемент будь-якої програми для мікроконтролера. Тому майстер завжди створює заготовку цього циклу. Тобто створює цикл, тіло якого поки що не містить команд.
У тому місці, де програміст повинен розташувати команди, що утворюють тіло цього циклу, майстер поміщає спеціальне повідомлення, що запрошує вставити туди код програми - Place your code here (Будь ласка, вставте ваш код). У нашому випадку він складається всього із трьох команд.

Особливістю архітектури мікроконтроллерів є можливість напряму присвоювати порту значення іншого порту. Тому основний цикл можна спростити до однієї команди: PORTC.3 = PINC.1 (регістру PORTС присвоюється значення регістра PІNС.1. Виконуючись багаторазово у нескінченному циклі, команда присвоєння постійно переносить вміст порту PС.1 в порт РС.3, реалізуючи тим самим наш алгоритм.

Комментариев нет:

Отправить комментарий

ВАС ВІТАЄ "ШКОЛА РОБОТОТЕХНІКИ" Школа робототехніки - це осередок творчості та технічної фантазії. Місце де мистецтво переплітаєть...