Установка
программного обеспечения.
Запускаем AVR Studio 4.
Почему компилятор AVR GCC?
Вообще существует
несколько компиляторов языка С для микроконтроллеров AVR. Наиболее используемые из других
компиляторов – IAR и Code vision AVR.  
Основными
достоинствами AVR GCC являются следующие: только он бесплатный, только он
встраивается в AVR Studio, генерирует самый компактный код, особенно при использовании чисел с плавающей точкой. 
К
достоинствам IAR следует отнести то, что только он полностью
поддерживает С++, AVR GCC поддерживает C++, но не полностью. 
К
достоинствам Code vision AVR следует отнести наличие в нём генератора начального кода, который
облегчает конфигурирование микроконтроллера и написание некоторых функций,
например для интерфейса 1-Wire или модулей ЖКИ. Кроме того, в Code vision AVR есть возможность подключить отладчики AVR Studio (но не все).
Таким образом,
основными недостатками AVR GCC являются – отсутствие полной поддержки C++ и отсутствие
генератора начального кода. Отсутствие полной поддержки C++ для
микроконтроллеров не очень важно, а генератор начального кода можно с успехом
заменить развитием библиотечных функций WinAVR, дополнять её можно
самостоятельно.
Приступаем к написанию исходного
кода. Структура программы на языке С.
Напишем программу для микроконтроллера ATmega16, которая будет
формировать на всех выводах порта B сигнал «SOS». Если к любому выводу порта B подключить катод
светодиода, а анод подключить к плюсу, через резистор на 560 Ом, то он будет
мигать, передавая сигнал SOS азбукой Морзе.
  
Программы
обычно начинаются с директив
препроцессора (начинаются с символа "#"), которые, по сути, не
являются конструкциями языка C и обрабатываются
до фактической компиляции программы. Их смысл — подстановка некоторого кода в
программу. Так, к примеру, очень часто используется директива #include, которая включает в файл с исходным кодом программы
текст внешнего заголовочного файла (с расширением .h). Заголовочные
файлы содержат определения глобальных типов, констант, переменных и
функций.
#include <avr/io.h>      // Подключение
устройств ввода/вывода в зависимости от типа МК AVR.
#include <avr/delay.h> // Подключаем функции
циклов задержки. 
//
Процедура «Пауза», время паузы задаётся из процедур «Точка» и «Тире» параметром
ms.
void Pause(unsigned char ms)     // Тип переменной
ms - unsigned char, то есть от 0 до 255.
{
            PORTB = 0xFF;         // Устанавливаем на всех выводах
порта B лог. 1.
            _delay_ms(ms);           // Задержка
}
//
Процедура «Точка»
void P(void)
{
            PORTB
= 0;    //
Устанавливаем на всех выводах порта B лог. 0.
            _delay_ms (5); // Короткая задержка.
            Pause(5);         // Вызов функции Pause, с
параметром 5ms
}
//
Процедура «Тире»
void D(void)
{
            PORTB
= 0;    //
Устанавливаем на всех выводах порта B лог. 0.
            _delay_ms (20);           // Длинная задержка.
            Pause(5);         // Вызов функции Pause, с
параметром 5ms
}
/* Главная
функция программы, отсюда начинает исполняться исходный код, в компиляторе AVR – GCC должна всегда иметь тип возвращения int */
int main (void)    
{
            DDRB = 0xFF;           // Настройка порта B как выхода 
while(1)    /* Бесконечный цикл (это основная часть программы, она будет крутиться в
этом цикле, поочерёдно вызывая функции точки и тире. */
            {
            //
Вызываем поочерёдно процедуры «Точка» и «Тире», формируем сигнал SOS.
             
P(); P(); P();
             
D(); D(); D();
             
P(); P(); P();
             
Pause(100);   // Вызываем процедуру «Пауза» с параметром 100
            } 
}
Комментарий — поясняющий
текст, который при компиляции не учитывается, например:
/*  
Многострочный   комментарий  часто 
размещают   в   начале  
файла, где   он   содержит  
имя   автора   и  
описание   программы   */
#include   <avr/io.h>   //Подключаем  заголовочный 
файл   io.h
Идентификатор — это
последовательность букв, цифр и символов подчеркивания "'_", которая
не должна начинаться с цифры, используемая для именования различных программных
элементов, - переменных, констант, функций, типов и т.д. Регистр букв имеет
значение. Например, в нашей программе – это - переменная ms, и названия процедур.
Ключевое слово — это
зарезервированное слово четко определенного назначения. Ключевые слова не
могут использоваться в качестве идентификаторов:
asm, auto;        bit, bool, break;           case, char, const, continue;      default, defined, do, double; 
else, enum, explicit, extern;       false, float, for;             goto;    if, inline, int;      long;     register, return;
short, signed, sizeof, static, struct, switch;         true,
typedef;    union, unsigned;           void;    while.
Например, в нашей программе – это -  char,  void и while.
Литерал
— постоянное значение некоторого типа, используемое в выражениях. 
Примеры
числовых литералов:
10 — число 10 в десятичной форме;
0хА — число 10 в шестнадцатеричной форме (префикс
0х);
0b1010 — число
10 в двоичной форме (префикс 0b);
012 — число 10 в восьмеричной форме (префикс 0);
10.5 — число с плавающей точкой;        
105е-1 — число 10,5 в экспоненциальной форме (105 *
10**-1);
10U —
беззнаковая константа (суффикс U);
10L — знаковая
константа (суффикс L).
Символьные
литералы заключаются в одинарные кавычки, например, 'В', '*'. Для обозначения
непечатаемых и специальных символов в литералах используются так называемые escape-последовательности:
'\а'— звуковой сигнал;
'\b' — клавиша
<Backspace>;                                                             
'\f' — прогон
листа;
'\n'— символ
перевода строки;                                                             
'\r'— возврат
каретки;                                                                       
'\t'—
горизонтальная табуляция;
'\v' —
вертикальная табуляция;
'\0'— нулевой символ;
'\\'— обратная косая;
'\''— апостроф.
Кроме
того, любой символ можно представить с помощью литерала по его ASCII-коду, например, литерал '\t' равнозначен '\х09'.
Строковые
литералы ограничиваются двойными кавычками, а в памяти хранятся как
последовательности символов, заканчивающиеся нулевым символом '\0'. Специальные
символы внутри строки должны предваряться обратной косой ("\").
Примеры строковых литералов:
""
— пустая строка: один символ '\0';
"В"
— два символа: 'В' и '\0';
"A\tB\n" — пять символов: 'А', табуляция, 'В', перевод
строки, '\0'.
Например, в нашей программе –
значения пауз, числа 5, 20 и 100 в десятичной форме.
Оператор
— это символ, указывающий компилятору, какие действия выполнить над
операндами. Некоторые символы могут трактоваться по-разному в зависимости от
контекста. Например, знак "-" может использоваться для изменения
знака числа или в качестве оператора вычитания. Операторы, соединяющие операнды,
представляют собой выражения. Выражения могут быть заключены в круглые скобки и
отделяются друг от друга символом точки с запятой (";").
Приоритет
(по убыванию)  выполнения  операторов 
в  выражениях  языка C  указан ниже.
| Уровень | Операторы | Категория | Описание | 
| 1 | ( ) |  | Круглые скобки | 
| [ ] |  | Элемент массива | |
| . | Доступ к данным | Обращение  к элементу структуры,  например: portb .
  1 — разряд 1 порта В. | |
| -> |  | Обращение к элементу структуры, определенной указателем, например: pStruct -> x — элемент х структуры, на которую указывает pStruct | |
| ++, --(постфиксы) | Арифметические | Операторы   автоинкремента   и   автодекремента после того как выражение, в котором задействованы соответствующие операнды, вычислено. Примеры: а  =  b++; равнозначно а   =  b;   b  =  b+1; а  =  b—; равнозначно а   =  Ь;   b  =  b-1; | |
| 2 | ++, --(префиксы) |  | Операторы   автоинкремента   и   автодекремента перед тем как выражение, в котором задействованы соответствующие операнды, будет вычислено. Примеры: а  =  ++Ь; равнозначно b  =  b+1;   a  =  b;
  а  =   —b;
  равнозначно b  =  b-1;   a  =  b; | 
| ! | Логические | Логическое (унарное) отрицание | |
| ~ | Поразрядные | Поразрядное отрицание | |
| & | Доступ к данным | Адрес | |
| 3 | +, -(унарные) | Арифметические | Изменение знака операнда | 
| *
  (унарный) | Доступ к данным | Разыменование указателя | |
| 4 | *
  (бинарные) | Арифметические | Умножение | 
| / |  | Деление | |
| % |  | Остаток от деления | |
| 5 | +, -(бинарные) |  | Сложение и вычитание | 
| 6 | << | Поразрядные | Поразрядный сдвиг влево | 
| >> |  | Поразрядный сдвиг вправо | |
| 7 | <, >, <=, >= | Сравнения | Меньше, больше и т.д. | 
| 8 | ==, ! = |  | Равно, не равно | 
| 9 | & | Поразрядные | Поразрядное "И" | 
| 10 | ^ | Поразрядные | Поразрядное "Исключающее ИЛИ" | 
| 11 | | | Поразрядные | Поразрядное "ИЛИ" | 
| 12 | && | Логические | Логическое "И" | 
| 13 | || | Логические | Логическое "ИЛИ" | 
| 14 | = | Присваивание | Возможны также сочетания оператора присваивания с арифметическими и поразрядными операторами, например: а  += Ь; равнозначно а  =  а  + b; а   *= b+с; равнозначно а  =   а   *    (b  +   с) ; | 
С
оператором присваивания используются вот такие сокращения:     
| ДЛИННАЯ ЗАПИСЬ | СМЫСЛ | СОКРАЩАЕТСЯ ДО | 
| x = x + 1; | добавить 1 | x++; или ++x; или x += 1; | 
| x = x - 1; | вычесть 1 | x--; или --x; или x -= 1; | 
| x = x + y; | прибавить y | x += y; | 
| x = x - y; | вычесть y | x -= y; | 
| x = x * y; | умножить на y | x *= y; | 
| x = x / y; | поделить на y | x /= y; | 
| x = x % y; | остаток от деления | x %= y; | 
Кроме
знаков +,-,*,/,% могут стоять поразрядные и побитные операторы. При сокращённой записи между знаками нельзя ставить
пробел!
Когда
инкремент или декремент используется в выражении то важно где стоят два знака +
или -  перед переменной или после
переменной:
a=4, b=7; 
a = b++; /*
Эта строчка на Си означает: взять значение переменной b присвоить его
переменной a затем добавить 1 к переменной b 
и сохранить результат в b. Теперь a = 7; b = 8  */
a=4, b=7; 
a = ++b;  /* Эта строчка на Си означает: взять значение
переменной b затем добавить к нему 1 и сохранить результат в b и этот же
результат присвоить переменной a. Теперь 
a = 8, b = 8. */
Объединенные
по некоторому признаку последовательности выражений заключаются в фигурные
скобки:
{
            PORTB = 0xFF;         // Устанавливаем на всех выводах
порта B лог. 1.
            _delay_ms(ms);           // Задержка
}.
Так,
к примеру, обозначаются границы функций, а также блоки выражений в циклических
и условных конструкциях (см. ниже соответствующие разделы).