Цель
задачи:
1) получить основные навыки работы с компилятором
Си для МК AVR от компании ImageCraft.
2) получить
файл work.hex - это "прошивка"
готовая для загрузки в МК или для
проверки работы на эмуляторе.
Задание
составлено на основе Application Note
AVR031 "Getting Started with ImageCraft C for AVR" компании Atmel - в котором рассказывается
как начать работать с этим компилятором (этот
документ находится и в папке где
установлен компилятор).
Для работы над задачей необходимы:
-
Установленый в директорию по умолчанию (C:\ICC)
компилятор ImageCraft
- Data Sheet на МК AVR AT90s2313
- Скачаные AVR 8-Bit RISC - Application Notes
Открываем указанный выше .pdf Features
• How to Open a New Project
• Description of Option Settings
• Writing and Compiling the C Code
• How to Load the Executable File into the
STK200 Starter Kit
Мы
выполним 3 первых пункта, 4 пункт -
прошивка МК установленого в плату
разработчика, вы почитайте но делать его
пока не будем. 1)
Как создать новый проект в компиляторе:
проделайте путь описанный в документе
по созданию проекта - при этом выберите
папку для проекта "c:\icc\work",
тогда:
- файл исходного текста Си будет
называться work.с (создается в п. 3)
- файл поекта - work.prj -
файл результат компиляции - work.hex
2) Описание установок
компилятора
Прочитайте и сделайте (не нужно
менять "Paths" в разделе "Settings in Project>Options")
3)
Написание и компиляция кода программы
на Си
После создания проекта WORK и и установки опций компилятора можно приступить к
написанию текста программы. Предлагается
простая программка инкрементирующая
(значит - увеличивающая
на единицу) значение в порте B (PORTB)
МК, к выводам которого подключены 8
светодиодов (eight LEDs).
Компилятор
использует названия "Железа" (переферии,
хадвэа и т.п.) МК в
точном соответствии с Data Sheet!
Мы проверим работу откомпилированной
программы в эмуляторе (в задаче
02), но
только с 5-ю светодиодами - столько есть в
эмуляторе
Вместо трех
других светодиодов используем
виртуальный осциллограф эмулятора -
посмотрим сигналы на соответствующих
ножках МК!
Для
организации пауз между инкрементами
значения в защелках PORTB применяем 8-ми
битный таймер. Паузы нужны для
замедления переключения светодиодов -
просто для того чтоб увидеть это глазами. Создадим файл исходного текста
программы work.c
- выбирете “File>New” или click по иконке “New”.
- в появившемся окне введите название
файла "work.c" и сохраните “File>SaveAs”.
Мы условились сохранять
проект в папке
“c:\icc\work”..
Так нам проще будет
общаться -
и решать проблемы.
Листинг программы на языке
Си для МК AT90S2313 (набран черным цветом)
#include <io2313.h> //
Включить вместо этой
//
строки текстовый файл - io2313.h
препроцессор компилятора, перед компиляцией
в место этой
строчки просто вставит текст
всего файла - io2313.h
- он содержит описание "железа" МК
на синтаксисе языка Си, чтобы
компилятор знал, что по какому адресу
находится и как называется в конкретном
МК.
Найдите в папках где установлен
компилятор и просмотрите
этот файл - интересно!
void initialization(void);
void delay(void);
Прототипы
функций которые мы будем использовать (простой
список-перечисление на память!).
В Си рекомендуется перечислить все
функции которые мы напишем и будем
использовать в нашей программе. После
каждой функции можно написать комментарий
- что она делает и т.д.
Ниже идут тексты кода этих функций:
1. функция "инициализации
железа" МК - она конфигурирует
аппаратные средства МК в соответствии с
решаемой нами задачей:
void initialization(void) <
здесь точку с запятой НЕ СТАВИТЬ!
{
DDRB = 0xff; // set PORTB as output
Записать
число -1111 1111- в регистр МК DDRB (этот
регистр управляет направлением работы
выводов МК: "вход - выход").
Мы установили этой строчкой направление
работы порта B на "выход" т.е. все биты
DDRB "1" и соответсвующие выводы МК
стали выходами.
Запись "0"
в какой либо бит
DDRx
означает что соответствующая ножка МК
будет входом. |
Например "1100 0001" в DDRB - значит что
0, 6 и 7-й "биты - ножки" порта B являются
выходами а биты 1-5 входами.
Десятичное
число 255 можно записать как:
0xFF в шестнадцатеричном виде или FFh
1111 1111 в двоичном виде.
Первые два варианта принимаются
большинством компиляторов.
Для
перевода чисел из одного
представления в другое начинающему
можно посоветовать калькулятор WINDOWS
в инженерном режиме.
Биты
в байте считаются с права на лево
начиная с "0"
в
других МК может быть по другому! |
Каждому
порту в МК AVR соответствуют
минимум три регистра: DDRx
- регистр направления работы
PINх - регистр содержит значения
физических (т.е. реальных) уровней сигнала на соотв. ножках МК. PORTх
- регистр в который МЫ записываем
значения "1" или "0" - которые хотим получить на
соотв. ножках МК при назначении их
выходом. т.е. если
соответствующий бит=1 в регистре DDRx.
ВАЖНО! - если бит в
регистре DDRx равен "0", а в такой же бит PORTх
записана "1" то "ножка" МК будет
"входом с подтяжкой" т.е. к ней как
бы подключен резистор примерно 100-150 кОм
от питания МК. PORTB -
подробно смотрим
стр. 52 ДатаШит
ДатаШит вам в руки! Особенно если выводы
МК несут дополнительные функции!
|
TCCR0 = 0x05; // Count clock/1024
Выбрали
частоту "тиканья" таймера в одну 1024
от частоты работы МК.
см. описание
таймера в ДатаШит ! Таймер тикает
постоянно.
} // закрывающие скобочки не
забывайте!
2.
эта функция выполняет задержку в 65 мС при
частоте кварца 4 мГц:
void delay(void) // Produce a delay of
{
// 65 ms at 4 MHz
while (!(TIFR&0x02));
// Wait for timer0 overflow
// flag to be set
наша программа
будет сидеть в цикле
while()
пока условие в скобках истино - т.е. "не ноль"
- на языке Си: !(0)
"!" - означает "не"
Так как после
while()
нет скобок
{...}
и в строке ниже
нет выполняемого кода - то после while()
нужно
поставить точку с запятой!
В
противном случае ;
не нужно!
|
Комбинация в
скобках while()
- станет
"0" то есть "ложно" когда бит1
регитстра TIFR
станет равным "1"
Это произойдет
когда значение в регистре таймера
станет 255 (значит насчитано 256 тиков - от 0
до 255) - соответственно будет установлен бит1
регистра TIFR
- это "флаг переполнения таймера".
TIFR = 0x02;
// Clear overflow flag Подготовимся
засечь окончание следующей паузы.
Для этого сделаем
бит1 опять "0", записав в него лог
"1" - да именно так... Да вот так
забавно решили сделать инженеры
компании ATMEL.
Почитайте
описание регистра TIFR в ДатаШит МК стр.
24-25 и посмотрите, что делает запись в
остальные биты регистра нулей?
"Bit 1 – TOV0:
Timer/Counter0 Overflow Flag
The bit TOV0 is set (one) when an overflow occurs in Timer/Counter0.
TOV0 is cleared by hardware when executing the corresponding interrupt handling
vector.
т.е. МК и
сам бы очистил флаг если бы мы
использовли в программе
соответствующее прерывание! но мы
его не используем... так что пришлось
"ручками"...
Alternatively, TOV0 is cleared by writing a logical “1” to the
flag!
When the SREG I-bit and TOIE0
(Timer/Counter0 Overflow Interrupt Enable) and TOV0 are set (one), the Timer/Counter0 Overflow Interrupt is
executed."
|
}
Код любой
функции должен заканчиваться фигурной
скобкой!
в
программе на Си должна обязательно быть Главная
функция - main()
Ее можно считать скелетом программы:
void main (void)
{
initialization(); //Initialize Peripherals
Инициализировали (запустили)
периферию процессора в нужном режиме
вызвав соответствующую функцию.
while (1) //Forever
{
while(1) -
очень частое применение этого
цикла - означает "Делать пока
есть питание и нет прерывания" - так
как в скобках "не ноль" постоянно.
ВАЖНО: можно было
написать любое число 5, 25, или 3...
Запомните
в Си: "не ноль" это "истина"
а "ложно" только
"ноль" !!!
|
PORTB++; // Increment PORTB
Увеличить
на 1 предыдущее значение в PORTB
Но
каково было начальное значение? при
запуске МК?
смотрим
ДатаШит стр. 52
"Initial
value" под
схемой регистра "PORTB"
видим "Нули" - значит при запуске МК
PORTB=0 (или
0x00 или "00000000")
Значит все светодиоды загорятся после
выполнения строки "DDRB = 0xff;"
Типовая схема
включения светодиодов - между выводом МК
и "+" питания последовательно с резисторои
390-1200 Ом (на
светодиоде падение напряжения
примерно 2 вольта, а остальное
напряжение гасится на резисторе). Эмулятор который мы будем
использовать позволяет использовать ТОЛЬКО такую
схему подключения! Но
светодиод подключенный к выводу бит_0 PORTB
почти мгновенно погаснет из-за
выполнения строки "PORTB++;"
до вызова функции задержки:
Проверим
при эмуляции в задаче
02...
|
delay(); // Short delay
Задержались
на 65 мС - вызвав соответствующую функцию.
} // скобка
закрывающая для While(1);
} //
скобка
закрывающая для main-функции. Все
- текст программы закончен.
Не
все комментарии что я использовал
выше допустимы
в программе !!!
Комментарии могут быть двух типов:
// комментарии одной
строкой
/* комментарии
любой длины и
на любое количество строк */
в любом случае, старайтесь
делать комментарии как можно подробней - ведь
программу пишете для себя.
|
Идем
дальше - "Including the Source File in the Project"
стр. 5 AVR031 Включаем
наш файл исходного текста work.c в
состав проекта и запускаем компиляцию.
Если
текст набран без ошибок, то компиляция
проходит успешно и мы получаем
сообщение что использовано 6% ресурсов
МК - это условная ориентировочная цифра.
НО! когда она близка к 50% стоит задуматься о
применении более мощного МК!
Я не рассматриваю
вариант когда в тексте программы есть
ошибки - это был бы перевод ХЕЛПА
компилятора!
Скажу только что компилятор указывает
строку в которой ошибка и коротко
сообщает о ее характере. |
Теперь у нас
есть навыки работы с компилятором и есть
файл "прошивки" для МК: c:\icc\work\work.hex
Работу нашей прошивки мы будем проверять в
Задаче 02
Поставленные
цели достигнуты
Задача 01 завершена.
|