Программирование микроконтроллеров AVR с использованием GCC
    ArticleCategory: [Choose a category, do not translate
    this]
    Hardware 
    AuthorImage:[Here we need a little image from you]
    ![[Photo of the Author]](Guido-S0.gif) 
    TranslationInfo:[Author + translation history. mailto: or
    http://homepage]
    original in en Guido Socher
    en to ru Пухляков Дмитрий
    AboutTheAuthor:[A small biography about the author]
    Guido loves Linux not only because it is fun to discover the
    great possibilities of this systems but also because of the
    people involved in its design.
    Abstract:[Here you write a little summary]
    Микроконтроллер AVR фирмы Atmel - 8-мибитный RISC микроконтроллер 
общего назначения, внутри которого размещены EEPROM, RAM, АЦП, большое количество портов ввода и вывода, таймеры и последовательный канал UART, реализующий связь по протоколу RS232, и многое другое.
    
    Большой плюс этого микроконтроллера - наличие средств разработки
под Linux. И эти средства предоставляет GCC. В этой статье я объясню
как установить и пользоваться GCC. Я также покажу, каким образом загрузить
исполняемый код в микроконтроллер. Для этого нам понадобится микроконтроллер AT90S4433, кварцевый резонатор на 4МГц, небольшой отрезок кабеля и еще несколько недорогих компонент.
    
    Эта статья является вводной, в следующей статье мы построим ЖКИ дисплей с несколькими кнопками, аналоговым и цифровым входами, аппаратным сторожевым таймером и светодиодами. Конечная цель, построить панель управления для Linux-сервера. Но для начала нам необходимо установить и настроить средства разработки, чему и посвящена эта статья.
    ArticleIllustration:[This is the title picture for your
    article]
    ![[Illustration]](illustra.jpg) 
 
    ArticleBody:[The article body]
    Установка: Что для этого необходимо?
     Для использования среды разработки GNU C, Вам понадобится следующее программное обеспечение:
    
      
        | binutils-2.11.2.tar.bz2 | Находится здесь: ftp://ftp.informatik.rwth-aachen.de/pub/gnu/binutils/
 или
 ftp://gatekeeper.dec.com/pub/GNU/binutils/
 | 
      
        | gcc-core-3.0.3.tar.gz | Находится здесь: ftp://ftp.informatik.rwth-aachen.de/pub/gnu/gcc/
 или
 ftp://gatekeeper.dec.com/pub/GNU/gcc/
 | 
      
        | avr-libc-20020106 .tar.gz | Библиотека AVR C находится здесь:         http://www.amelek.gda.pl/avr/libc/ Также Вы можете скачать ее отсюда: страница для загрузки | 
      
        | uisp-20011025.tar.gz | Программатор для AVR находится здесь:
        http://www.amelek.gda.pl/avr/libc/ Также Вы можете скачать ее отсюда: страница для загрузки | 
    
Все программное обеспечение мы установим в папку /usr/local/atmel. Это позволит нам 
избежать путаницы при ипользовании обычного компилятора С Linux. Создайте папку с помощью команды:
    mkdir /usr/local/atmel 
    
    Установка: GNU binutils
Пакет binulils содержит низкоуровневые средства необходимые для создания объектных файлов. Он включает в себя ассемблер AVR (avr-as), линкер (avr-ld), библиотеку средств управления библиотеками (avr-ranlib, avr-ar), программы для создания исполняемых модулей загружаемых в память 
программ микроконтроллера (avr-objcopy), дизассемблер(avr-objdump) и утилиты 
avr-strip и avr-size.
    
    Для установки пакета binutils выполните следующие команды: 
    bunzip2 -c binutils-2.11.2.tar.bz2 | tar xvf
    -
    cd binutils-2.11.2
    ./configure --target=avr --prefix=/usr/local/atmel
    make
    make install
    
    Добавьте строку /usr/local/atmel/lib в файле /etc/ld.so и обновите кэш линкера командой
/sbin/ldconfig.
    
    Установка: AVR gcc
    avr-gcc - собственно компилятор С. 
    
    Для его установки используйте следующие команды: 
    tar zxvf gcc-core-3.0.3.tar.gz
    cd gcc-core-3.0.3
    ./configure --target=avr --prefix=/usr/local/atmel
    --disable-nls --enable-language=c
    make
    make install
    
    Установка: Библиотека AVR C
    Библиотека AVR C до сих пор находится в стадии разработки и поэтому процесс установки может
немного изменяться от версии к версии. Я рекомендую использовать версию указанную выше в таблице, для приведенной мной процедуры установки. Именно эту версию я использовал при создании программ описанных в этой и последующих статьях. 
    Установите следующие пременные среды (синтаксис bash):
    export CC=avr-gcc
    export AS=avr-as
    export AR=avr-ar
    export RANLIB=avr-ranlib
    export PATH=/usr/local/atmel/bin:${PATH}
    
    ./configure --prefix=/usr/local/atmel/avr --target=avr
    --enable-languages=c --host=avr
    make
    make install
    
    Установка: Программатор
    Программатор предназначен для загрузки исполняего кода в память программ микроконтроллера. 
    
    Наилучшим образом для этих целей подходит uisp для Linux. Он может быть использован прямо
из make-файла. Вам только нужно будет добавить строку "make load" в make-файл и созданный
Вами код будет загружен в микроконтроллер сразу после компиляции. 
    
    uisp устанавливается следующими командами: 
    tar zxvf uisp-20011025.tar.gz
    cd uisp-20011025/src
    make
    cp uisp /usr/local/atmel/bin
    
    Небольшая тестовая программа
    Начнем с небольшого тестового проекта. Его основная задача проверить работоспособность 
установленного программного обеспечения. Нам предстоит скомпилировать, загрузить и проверить 
небольшую программу. Эта программа всего лишь должна заставить моргать светодиод. 
    
    Для этого я предлагаю Вам изготовить небольшую отладочную плату, в будущем Вы можете ее 
модифицировать и использовать для своих целей. Вы можете использовать макетную плату.
Однако не пытайтесь поставить на нее непосредственно микроконтроллер с кварцем, так как такие платы, как правило, не предназначены для высокочастотных цепей, лучше подключить выходные линии микроконтроллера к макетной плате с помощью коротких проводников. Кварц и конденсаторы разместите в непосредственной близости от микроконтроллера. 
    ![[circuit diagram]](schemati.gif) 
 
    Сопротивления на схеме между микроконтроллером и разъемом для подключения программатора в нашем случае необязательны, они могут понадобиться, в случае если Вы захотите в дальнейшем задействовать выводы порта В. 
    Необходимые компоненты
    Вам понадобятся детали, перечисленные ниже в таблице. Все они достаточно распространенные и недорогие. Самая дорогая деталь в списке - микроконтроллер, его стоимость около 7.30 EUR. Также возможно, что его не окажется в ближайшем к радиомагазине, но он всегда есть в продаже у крупных дистрибьюторов электронных компонент ( например, www.reichelt.de,www.conrad.de, и т.д., наверняка похожие компании есть и в вашей стране). 
    
      
        | ![[avr]](avr44330.jpg)  | AT90S4433,8-битный RISC микроконтроллер ф.Atmel - 1 шт. | 
      
        | ![[socket]](14pinics.jpg)  | Панелька для микросхем 14 ножек                 - 2 шт. или
 панелька 28 ножек( ширина 7,5 мм)           - 1 шт.
 Купить необходимую панельку на 28 ножек будет гораздо сложнее,т.к. обычно такие панельки имеют ширину 14 мм вместо требуемой 7.5 мм.
 | 
      
        | ![[resistor crystal capacitor]](resistor.jpg)  | Резистор 10 кОм (цветовая маркировка: коричневый, черный, оранжевый) - 1 шт. Резистор 470 Ом (цветовая маркировка: желтый, пурпурный, коричневый) - 3 шт.
 Резистор 1 кОм (цветовая маркировка: коричневый, черный, красный) - 1 шт.
 Резистор 220 Ом (цветовая маркировка: красный, красный, коричневый) - 1 шт.
 Кварцевый резонатор 4МГц - 1 шт.
 Конденсатор керамический 27 пФ - 2 шт.
 | 
      
        | ![[connector]](connecto.jpg)  | Любой разъем на 5 контактов, я обычно покупаю разъем в виде полоски на много контактов и отламываю необходимый мне кусок на 5 контактов. | 
      
        | ![[matrix board]](board000.jpg)  | Монтажная плата - 1 шт. | 
      
        | ![[db25]](db25male.jpg)  | 25-ти контактный разъем DB25 для подключения к параллельному порту - 1 шт. | 
      
        | ![[led]](led00000.jpg)  | Светодиод - 1 шт. | 
      
        | ![[beardboard]](breadboa.jpg)  | Макетная плата. Мы ей не пользовались, но я считаю, что она
        будет весьма кстати, если Вы захотите продолжить эксперименты с AVR.
        Рекомендую поместить микроконтроллер вместе с кварцем и конденсаторами
        на монтажной плате и подключать его входы и выходы с помощью коротких проводов к макетной плате. | 
    
Еще Вам понадобится 5-тивольтовый стабилизированный источник питания или батарейка на 4.5 В.
    Изготавливаем программатор
    AT90S4433 поддерживает режим внутрисхемного программирования. ![[AVR programmer]](pcable00.jpg)
    
Это означает, что Вам не нужно вытаскивать микроконтроллер из платы каждый раз, когда Вам необходимо его перепрограммировать. Опять-таки покупка готового программатора обойдется Вам в 50-150 EUR. В нашем случае Вы обойдетесь без лишних накладных расходов. С помощью Linux, uisp и свободного параллельного порта Вы сможете создать хороший и простой программатор. И этот программатор представляет собой простой кабель. Распайка этого кабеля выглядит следующим образом: 
    
      
        | pin on AVR | Pin on parallel port | 
      
        | SCK (19) | Strobe (1) | 
      
        | MISO (18) | Busy (11) | 
      
        | MOSI (17) | D0 (2) | 
      
        | Reset (1) | Init (16) | 
      
        | GND | GND (18) | 
    
    
    Длина кабеля не должна превышать 70 см. 
    Пишем программу
    Используя gcc Вы можете писать программы для AT90S4433 на чистом С. Знание AVR ассемблера может быть полезным, но необязательным. В состав AVR libc входит avr-libc-reference документирующий большинство ее функций. Harald Leitner написал документацию по использованию AVR и GCC(haraleit.pdf,286Kb, оригинал находится на  http://www.avrfreaks.net/AVRGCC) с огромным количеством полезных примеров. Со страницы Atmel (www.atmel.com далее по ссылкам: products->8 bit risc -> Datasheets) Вы можете загрузить полное описание на микроконтроллер (копия: avr4433.pdf,2361Kb).
 В нем дано описание внутренних регистров и описание использования CPU.
    
    При создании программ для 4433 Вам необходимо помнить о том, что в вашем распоряжении всего 128 байт ОЗУ и 4К ПЗУ. Поэтому не стоит объявлять огромные структуры данных и длинные строки. Также избегайте использования множественных вложенных вызовов подпрограмм и рекурсивных функций. Объявление переменной вроде 
    char string[90];
 уже чрезмерно. Тип данных "целое"(integer) имеет размерность в 16 бит. Если Вам необходимо короткое целое (small integer) используйте 
    unsigned char i; /* 0-255 */ 
Тем не менее, Вы будете удивлены тому, какие большие программы Вы сможете создать для этого микроконтроллера. Это действительно мощный процессор! 
    
 Итак, перейдем от теории к практике. Напишем программу, заставляющую мигать светодиод через интервалы 0.5 сек . Программа не такая уж полезная, но вполне достаточная для проверки установленной нами среды разработки и программатора. 
    void main(void)
    {
          /* enable PD5 as output
    */
          sbi(DDRD,PD5);
          while (1) {
                /*
    led on, pin=0 */
                cbi(PORTD,PD5);
                delay_ms(500);
                /*
    set output to 5V, LED off */
                sbi(PORTD,PD5);
                delay_ms(500);
          }
    }
    
    Приведенный выше фрагмент программы наглядно демонстрирует насколько просто создается программа.
Здесь приведена только основная функция, подпрограмма delay_ms включена в полный листинг программы
(avrledtest.c). Перед использованием ножки PD5 микроконтроллера ее необходимо сконфигурировать 
на вывод, установив бит PD5 в регистре управления направлением работы линий порта D 
(DDRD(Data Direction Register for port D)). После этого Вы можете контролировать ножку PD5
устанавливая ее в 0В с помощью функции cbi(PORTD,PD5)( clear bit PD5(сбросить бит PD5)) или
в 5В с помощью функции sbi(PORTD,PD5)(set bit PD5(установить бит PD5)). Значение "PD5" 
определено в io4433.h, который подключен через io.h. Далее следует бесконечный цикл (while(1){}), внутри которого и происходит управление светодиодом. Вас не должно пугать, что наша программа получилась зацикленной. Если Вы уже создавали программы для многопользовательских / многозадачных систем, таких как Linux, Вы должны знать, что ваша программа никогда не должна содержать неблокированный бесконечый цикл. Потому что такой цикл приведет к напрасным затратам процессорного времени и резкому снижению производительности системы. Но не в случае с AVR. У нас не многозадачная система и нет программ, выполняющихся параллельно с нашей программой. У нас нет даже операционной системы. Поэтому мы можем позволить себе замкнутый цикл.
    Компилируем и загружаем программу
    В начале убедитесь, что переменная среды PATH содержит путь /usr/locsl/atmel/bin. Если
необходимо отредактируйте ваш .bash_profile или .tcshrc , добавив: 
    export PATH=/usr/local/atmel/bin:${PATH} (for
    bash)
    setenv PATH /usr/local/atmel/bin:${PATH} (for tcsh)
    Для программирования AVR мы используем параллельный порт и программу uisp. Uisp в свою очередь
использует интерфейс ppdev кернела. Поэтому необходимо убедиться, что у Вас загружены следующие модули: 
    # /sbin/lsmod
    parport_pc
    ppdev
    parport
 С помощью команды /sbin/lsmod проверьте, что они загружены, в противном случае, находясь под root, 
загрузите их с помощью 
    modeprobe parport
    modeprobe parport_pc
    modeprobe ppdev
    
   Будет неплохо, если эти команды будут выполняться автоматически при запуске операционной системы. Для этого Вы можете занести их в скрипт rc ( для RedHat это /etc/rc.d/rc.local ).
Для использования обычным пользователем интерфейса ppdev Вам необходимо разрешить это, выполнив, находясь под root, команду 
    chmod 666 /dev/parport0
при этом необходимо удостовериться, что на этом порту нет программы обслуживания
принтера. В противном случае Вам придется остановить её перед подключением программатора.
Теперь все готово для компиляции и загрузки программы в микроконтроллер. 
Архив с нашей тестовой программой (avrledtest-0.1.tar.gz)
включает и make-файл. Все что Вам нужно, набрать:
    make 
    make load
    После этого программа будет откомпилирована и загружена. Я не рассматриваю детально все 
выполняемые  при этом команды. Вы можете посмотреть их в Makefile. Я даже не помню их все наизусть. Я просто помню, что необходимо набрать "make load". В дальнейшем, когда Вы будете писать свои программы, просто поменяйте в Makefile все попадающиеся "avrledtest" на название своей программы. 
    Немного о binutils
    Некоторые из программ пакета binutils, могут вызвать гораздо больший интерес, чем процесс компиляции программы.
    avr-objdump -h avrledtest.out
    Результатом вышеприведенной команды будет информация о размере различных секций нашей программы. .text - собственно программа загружаемая в ПЗУ микроконтроллера. .data - инициализированные переменные, такие как
     static char str[]="hello";
и .bss - неинициализированные глобальные переменные. Обе секции равны нулю в нашем случае. .eeprom описывает переменные хранящиеся в eeprom микроконтроллера. Их я еще никогда не использовал.
И наконец .stab и .stabstr информация для отладчика, к конечному коду, загружаемому в микроконтроллер отношения не имеет.    
avrledtest.out:     file format elf32-avr
Sections:
Idx Name          Size      VMA       LMA       File off  Algn
  0 .text         0000008c  00000000  00000000  00000094  2**0
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
  1 .data         00000000  00800060  0000008c  00000120  2**0
                  CONTENTS, ALLOC, LOAD, DATA
  2 .bss          00000000  00800060  0000008c  00000120  2**0
                  ALLOC
  3 .eeprom       00000000  00810000  00810000  00000120  2**0
                  CONTENTS
  4 .stab         00000750  00000000  00000000  00000120  2**2
                  CONTENTS, READONLY, DEBUGGING
  5 .stabstr      000005f4  00000000  00000000  00000870  2**0
                  CONTENTS, READONLY, DEBUGGING
Используя команду avr-size, можно получить эту же информацию, но в краткой форме: 
    avr-size avrledtest.out
   text    data     bss     dec     hex filename
    140       0       0     140      8c avrledtest.out
При работе с AT90S4433 Вам необходимо следить, чтобы суммарный размер text+data+bss не превышал 4К и размер data+bss+stack (размер стека не отображается, т.к. величина непостоянная и зависящая от количества вложенных вызовов в программе) не превышал 128 байт. 
    
Также заслуживает внимания команда
    avr-objdump -S avrledtest.out
Она выводит ассемблерный листинг вашей программы.
    Заключение
 Итак, теперь у Вас есть достаточно информации, чтобы начинать писать программы для AVR с использованием GCC. В дальнейшем на LinuxFocus ожидается серия статей, описывающих применение этой связки в гораздо более сложных и интересных проектах.
    Ссылки