Программирование. CV AVR.
В
предыдущей статье мы давали поверхностные даные о микроконтроллерах
семейства AVR, теперь же мы узнаем как и чем их программировать.
Первое, что нужно сделать - это скачать компилятор CodeVision AVR
(среда для создания программ на МК). Скачать программу можно тут. Скачали?
Приступаем. Сейчас надо провести очень простую процедуру (ну если
понять что делать). Вообще, конечно, процедура геморойная и можно не
понять чего от Вас просят... Поэтому если все-таки не поймете пишите на
форум или в чат, перепишу этот кусок. А дело в том, что надо всего-лишь
создать новый проект в программе и вложить в него файл расширения '.c'
(файл написанный на языке С). Ниже Вы увидите картинку, после установки
и запуска программы, нажмите на кнопку и выполните действия показанные ниже (выполнять слева-направо сверху-вниз; комментарии к происходящему будут ниже):
Итак,
быстро пробежимся по последовательности действий. Нажимаем на кнопку
(белый листег), вылетает окошечко, выбираем тип Project, жмем ОК, далее
предлагает использовать Wizard, игнорируем его и говорим ему нет. Далее
просит сохранить проект, сохраняем, называя его при этом как душе
угодно. Потом вылетает окно настроек проекта на вкладке Files,
перейдите на вкладку C Compiler и сделайте так, как показано на
картинке (в пункте Clock выбирайте ту частоту, которую дает кварцевый
резонатор, установленный на вашей схеме), жмите ОК. Далее еще раз
тыкаем по белому листочку и на этот раз выбираем тип
Source. Сохраняем его, опять же называем как хочется (хотя
кириллическими символами называть не советуется ничего). После чего в
меню сверху открываем подменю Project -> Configure (Конфигурация),
открывается уже знакомое Вам окно, нужна будет вкладка Files, там надо
будет нажать на кнопку Add (вот такую ) и выбрать сохраненные Вами до этого файл с расширением '.c', вот и все, проект собран.
Теперь
читаем статью дальше, не забывая поглядывать на уже знакомую Вам
картинку и, совмещая прочитанное с увиденным, так будет легче усвоить:
Теперь
надо решить проблему: как писать программу? Начинать всегда надо с
присоединения необходимых библиотек. Сначало обычно вводят библиотеку
контроллера, на который пишется программа, в нашем случае это
библиотека "mega16.h", для АТмега8 - "mega8.h", да и для любого МК
семейства AVR в том же духе. Чтобы подключить библиотеку к программе
нужно написать:
#include "mega16.h"
Также, удобно включать библиотеку "delay.h". С ее помощью можно использовать задержки, вот например строка:
delay_ms(100);
-
будет означать остановку программы на 100 микросекунд, по прошествию
которых программа продолжит работу с места, где останавливалась. Также
можно писать "delay_us(50);" Только задержка будет измеряться не в
микросекундах, а в миллисекундах, и при таких условиях, программа
простоит 50 миллисекунд.
Таким
образом в начало программы следует включить 2 библиотеки, это опять же
база, можно включить и другие если на то есть своя необходимость:
#include "mega16.h"
#include "delay.h"
После чего следует вводить код программы в сию функцию:
void main(void) { //сюда пишется вся программа }
саму
программу следует заключать в бесконечный цикл, хотя и не обязательно,
просто в ином случае программа выполнится один раз и завершится:
while(1) { //сюда пишется код программы; переменные, подпрограммы и прочие вещи //можно вводить перед циклом. // - это однострочный комментарий, вся строка после этих символов будет // пропущена
/* это обозначение многострочного комментария
Все что стоит между символами /* и */ будет проигнорировано компилятором */ }
В
предыдущей статье мы говорили, о том, что ножки МК могут назначаться
как на вход, так и на выход, именно поэтому в начале цикла программы
следует проводить инициализацию используемых портов:
DDRD = 0xff; //ставим все лапки порта D на выход
/*0xff
- это запись двоичного числа 0b11111111 в шестнадцатиричной; 0x -
префикс для обозначения 16-тиричной системы; о значении этих двоичных
чисел Вы узнаете позже, тогда Вам станет понятно, что к чему. DDR - это регистр направления передачи данных.*/
PORTD = 0x00; //значение всех лапок порта D приравниваем к нулю
DDRB = 0x00; //ставим все лапки порта B на вход PORTB = 0x00; //значение всех лапок порта B приравниваем к нулю
После можно уже писать программу присваивая выходам того или иного порта то или иное значение:
PORTD.0=1; //подать напряжение на нулевую ножку порта D PORTD.2=1; //подать напряжение на вторую ножку этого же порта //остальные ножки этого порта будут равны ноль Мы
уже говорили что 8 битов одного порта составляют регистр, так хитрость
в том, что можно сразу записывать в программу значение регистра порта.
Вот так можно переписать предыдущий кусок программы: PORTD=Ob00000101;// .PORTD.76543210 /*
0b - приставка, говорящая компилятору, в какой системе счисления мы
пишем, 0b - значит bin (binery) или, проще говоря, двоичная система, 0x
- означало бы 16-тиричную систему (hex) Каждый
порт МК АТмега16 имеет 8 лапок, поэтому после приставки идет 8 битов,
эквивалентные значению каждой лапки, отчет начинается справа-налево или
иначе - по старшинству разрядов. Так например в десятичной системе
счисления досчитав до десяти мы переходим к более старшему разряду, так
и в двоичной - досчитав до одного переходм к более старшему разряду,
поэтому PORTD.7 - самый старший разряд регистра, PORTD.0 - самый
младший. */ Теперь рассмотрим функцию ЕСЛИ и порты назначенные на вход, посмотрим на примере как считывать входящие в МК данные:
DDRB = 0x00; //ставим все лапки порта B на вход PORTB = 0x00;
DDRD = 0xff; //ставим все лапки порта D на выход PORTD = 0x00; while(1) //бесконечный цикл { if
(PINB.0==1) /* "ЕСЛИ на порт Б обнаружено напряжение"; '==' - означает
сравнение, а '=' - присваивание значения. Когда лапка порта назначена
на вход, то в условии мы уже пишем не PORT, а PIN.*/
{
PORTD=0b00000001; }; //и не забывайте ставить ; в конце*
} Вообще функция ЕСЛИ имеет следующий вид: if (условие){ программа, если условие верно } else { программа, если условие не верно }; И
еще забыл сказать, что та хитрость с регистром применяется и в случае с
PIN. Так, например, в том случае можно было написать
(PINB.0==0b00000001).
Бонус этой хитрости в том, что Вы можете проводить различного рода математические операции со значениями портов и пинов:
0b01000110 + 0b01011000 ____________ 0b10011110
Чтобы
успокоить ваши нервы считаю все-таки необходимым выложить полную
программу на АТмега16, например для мигания светодиодом, ориентируясь
на уже знакомую Вам картинку.
#include "mega16.h" #include "delay.h"
void main(void) { DDRA = 0xff; //ставим все лапки порта A на выход PORTA = 0x00;
while(1) { PORTA.0=1; //включаем светик delay_ms(150); // ждем 150 мкс PORTA.0=0; // выключаем светик delay_ms(150); //ждем еще 150мкс и возвращаемся к началу программы, //т.к. цикл бесконечный } } |