Урок 3. Первая программа
На прошлых уроках мы с вами разобрались в том как устроен МК и посмотрели что
такое порты ввода/вывода и их альтернативные функции. Давайте попробуем написать
простенькую программу "Мигание светодиодом". Писать программу будем на языке С.
Конечно многие начнут возмущаться, мол это жлобство, надо только на ассемблере, ну
да и бог с ними. Если я начну рассказывать как писать программу на ассемблере, то
скорее всего часть из вас просто подумает: "Как тут все заморочено! А ну его к
черту". И от части будут правы. Для того чтобы писать программу, нам потребуется
специальная программа. Я пользуюсь CodeVisionAVR V2.04.4a и найти его
можно тут. Или прямо у нас на сайте, это тут. Надеюсь что с установкой вопросов не
возникнет. Запускаем программу.
Рисунок 1.
Теперь давайте создадим новый проект. Для этого нажимаем File->New.
Рисунок 2.
Появится вот такое окно.
Рисунок 3.
Ну тут все понятно, выбираем Project и давим "Ок". И снова вопрос.
Рисунок 4.
Здесь программа предлагает вам запустить генератор кода. Для начала, а может и
всегда, тут уж сами решайте, давим "Yes".
Рисунок 5.
Вот здесь мы с вами остановимся по подробнее. Это окно, как раз и есть тот самый
генератор кода. Здесь мы выбираем что будет проинициализировано МК перед
выполнением основной программы. Начнем с вкладки Chip.
Ну тут я думаю все понятно. Выбираем наш контроллер, а именно как с вами
договорились, ATmega8 и частоту кварца 4 МГц.
Рисунок 6.
Больше в этой вкладке ничего трогать не надо. Переходим в вкладку Ports.
Рисунок 7.
Здесь выбираем Port B и нулевой бит меняем с In на Out. Значение по
умолчанию на выходе оставим 0. Это значит что при первом старте МК на порту B в
нулевом разряде будет висеть логический ноль. В общем смотрите на рисунок выше.
Более подробно по настройкам я напишу в отдельных статьях по программированию в
среде CodeVisionAVR, а сейчас у нас задача поморгать светодиодом. Ну
вроде ничего не забыли. Далее надо сохранить наш проект. Для этого жмем на иконку
дискетки и выбираем путь куда сохраним наш проект. Я выбрал так:
C:/my_cvavr/project_led, а проект назвал led. Получилось как-то так.
Рисунок 8.
Но это еще не все. Теперь давайте попросим программу сгенерить нам наш стартовый
код. Для этого жмем на иконку "шестеренка" и дважды под тем же именем, а
именно led сохраняем проект. Все. Программа с генерировала нам код и
теперь давайте взглянем на него. Расписывать весь код не буду, так как это другая
тема, а вот на что мы обратим внимание. Смотрим на картинку ниже.
Рисунок 9.
Строка: #include <mega8.h>
В этой строке мы просим компилятор подключить файл с описаниями всех регистров
МК ATmega8. Это сделано для понимания. Что проще понять PORTB или 0x18.
По моему тут все очевидно. Просто в этом файле прописаны эквиваленты понятные
простому человеку. Легче понять название порта не же ли его адрес.
Строка: PORTB=0x00;
Помним, мы хотели чтоб у нас был ноль на выходе по умолчанию, вот он. Правда
здесь выстрел и пушки по воробьям, так как это выражение выводит нули в весь
порт. А можно по проще PORTB.0=0x00; но это не суть важно.
Строка: DDRB=0x01;
Вспоминаем предыдущий урок, кто не читал вам сюда. Так как цифра 0x01 в hex равна
0b00000001 и bin. Учимся переводить из шестнадцатеричной системы в двоичную! То
мы видим что в нулевой разряд регистра направления DDRB записали 1. То есть будем
выводить данные через нулевой разряд порта В.
Ну вот, просмотрев код мы убедились что генератор кода с генерировал код как нам
надо. Заметьте, очень удобно и быстро. Теперь давайте посмотрим где же нам-то
писать код. Для этого бежим вниз до вот этих строк.
Рисунок 10.
Да, да. Внутри этого бесконечного цикла и будет наш код. О чем говорит коментарий
написанный в теле цикла. Кажется мы хотели поморгать светодиодом. Ну давайте.
Так как светодиодом мы будем управлять через нулевой разряд порта "В", то пишем
вот такой код.
PORTB.0 = 0x01;
PORTB.0 = 0x00;
Это самый простой способ. Сначала мы записываем в нулевой разряд порта, о чем
говорит точка с нулем после порта, единицу, а затем ноль. Вроде светодиод сначала
включится, а потом погаснет. А так как это все в бесконечном цикле, то все
завертится по кругу. Но к сожалению если мы соберем схему и включим ее, наш
светодиод будет гореть постоянно. А почему же, спросите вы. А вот почему. Помните
мы выбрали частоту кварца 4 МГц. Во... 4 миллиона импульсов за секунду. И вы
хотите уследить за ними. Не получится! Что же делать? А выход есть и даже не
один. Вставить паузы длинной, ну к примеру в пол секунды. Вариант первый,
использовать аппаратный таймер с прерыванием, но для нашего примера я думаю
рановато. Вариант два, мы же работаем в такой замечательной программе как
CodeVisionAVR. И для нас сделали хорошую библиотеку полезных функций.
И одна из них пауза delay_ms(int x) или delay_us(int x).
Первая задает паузу длинной х миллисекунд, а вторая х микросекунд. Но чтоб ей
воспользоваться давайте вернемся на самый верх и после строки #include <mega8.h>
и напишем под ней #include <delay.h>. Тем самым мы подключили библиотеку и
можем смело пользоваться функциями пауз. Давайте допишем наш код.
PORTB.0 = 0x01;
delay_ms(500);
PORTB.0 = 0x00;
delay_ms(500);
Теперь собираем наш проект. Project->Build All После сборки мы увидим окно
Рисунок 11.
в котором говорится, что все сделано без ошибок и нет предупреждений. Две строки
No errors
No warnings
Рисунок 12.
Вот и все. Для тех кто все же не понял что куда подключать.
Рисунок 13.
На схеме отсутствуют питание, кварц и конденсаторы. Я их не стал рисовать
так как мы про них уже распинались в предыдущих уроках. Просто эта обвязка
обязательна в любом проекте и в дальнейшем не будем рисовать, а при сборке
не забудем о них. В следующем уроке мы сваяем программатор и прошьем наш МК.
<-Назад Вперед ->