Микроконтроллеры AVR
Однокристальные микроконтроллеры находят широкие применение в самых разнообразных сферах: от измерительных приборов, фотоаппаратов и видеокамер, принтеров, сканеров и копировальных аппаратов до изделий электронных развлечений и всевозможной домашней техники.
Со времени появления первых микропроцессоров в 1970-х годах их сложность постоянно возрастала за счет появления новых аппаратных решений и добавления новых команд, предназначенных для решения новых задач. Так постепенно сложилась архитектура, получившая впоследствии название CISC (Complete Instruction Set Computers – компьютеры со сложным набором команд). В дальнейшем обозначилось и нашло активное развитие еще одно направление: архитектура RISC (Reduced Instruction Set Computers – компьютеры с сокращенным набором команд). Именно к этой архитектуре относятся микроконтроллеры AVR от компании Atmel и PIC от компании Microchip, которым посвящена эта книга.
Основное преимущество RISC-процессоров заключается в том, что они просты, выполняют ограниченный набор команд, и, как следствие, очень быстродействующие. Это позволяет снизить стоимость и сложность их программирования.
Обратной стороной RISC-архитектуры стала необходимость создания дополнительных команд на ассемблере, которые у CISC-устройств реализованы в аппаратной части. Например, вместо того, чтобы просто вызвать команду деления, которая характерна для устройств CISC, разработчику, имеющему дело с RISC-процессором, приходится применять несколько последовательных команд вычитания. Однако подобный недостаток с лихвой компенсируется ценой и скоростью работы RISC-устройств. Кроме того, если создавать программы на языке С, то подобные проблемы вообще перестают иметь какое-либо значение для разработчика, поскольку они решаются компилятором, который автоматически генерирует весь недостающий ассемблерный код.
На заре возникновения микропроцессоров разработка программного обеспечения происходила исключительно на том или ином языке ассемблера, ориентированном на конкретное устройство. По сути, такие языки представляли собой символьные мнемоники соответствующих машинных кодов, а перевод мнемоники в машинный код выполнялся транслятором. Однако главный недостаток ассемблерных языков заключается в том, что каждый из них привязан к конкретному типу устройств и логике его работы. Кроме того, ассемблер сложен в освоении, что требует достаточно больших усилий для его изучения, которые, к тому же, оказываются потраченными впустую, если впоследствии потребуется перейти на использование микроконтроллеров других производителей.
Язык С, являясь языком высокого уровня, лишен подобных недостатков и может использоваться для программирования любого микропроцессора, для которого есть компилятор с языка С. В языке С все низкоуровневые операции, выполняемые компьютерами, представлены в виде абстрактных конструкций, позволяющих разработчикам сосредоточиться на программировании одной лишь логики, не заботясь о машинном коде. Изучив язык С, можно легко переходить от одного семейства микроконтроллеров к другому, тратя гораздо меньше времени на разработку.
1.Архитектура микроконтроллеров AVR и PIC
В общем, все микроконтроллеры построены по одной схеме. Система управления, состоящая из счетчика команд и схемы декодирования, выполняет считывание и декодирование команд из памяти программ, а операционное устройство отвечает за выполнение арифметических и логических операций; интерфейс ввода/вывода позволяет обмениваться данными с периферийными устройствами; и, наконец, необходимо иметь запоминающее устройство для хранения программ и данных (рис. 1.1).
Рис. 1.1. Обобщенная структура микроконтроллера
Будем рассматривать микроконтроллеры в общем, не привязываясь к какому-либо конкретному типу микроконтроллеров AVR, поэтому ниже будут рассмотрены только общие для большинства микроконтроллеров особенности архитектуры памяти, вопросы ввода/вывода, обработки прерываний, сброса и др.
В микроконтроллерах AVR память реализована по Гарвардской архитектуре, что подразумевает разделение памяти команд и данных. Это означает, что обращение к командам осуществляется независимо от доступа к данным. Преимуществом такой организации является повышение скорости доступа к памяти.
Память данных предназначена для записи/чтения данных, используемых программами. Является энергозависимой, то есть, при отключении питания микроконтроллера все хранимые в ней данные, будут потеряны. В микроконтроллерах AVR память данных имеет более развитую структуру по сравнению с микроконтроллерами PIC, что показано на рис. 2.1.
Здесь и далее шестнадцатеричные числа будут представлены в форме, принятой в языке С: с префиксом 0х.
Рис. 2.1. Структура памяти данных в микроконтроллерах AVR и PIC
Область статической памяти SRAM (Static Random Access Memory) обозначена на рис. 2.1 пунктиром, поскольку используется не всеми микроконтроллерами AVR (это относится как к внутренней, так и к внешней SRAM). Ее начальный адрес – 0x060, а верхний адрес – разный в различных устройствах.
В некоторых микроконтроллерах AVR можно увеличивать пространство памяти SRAM посредством подключения внешних блоков памяти вплоть до 64 Кбайт, однако для этого приходится пожертвовать портами А и С, которые в этом случае применяются для передачи данных и адресов.
Область регистров общего назначения (рабочих регистров) предназначена для временного хранения переменных и указателей, используемых процессором для выполнения программ. В микроконтроллерах AVR она состоит из 32 восьмиразрядных регистров (диапазон адресов 0x000 – 0x01F). В микроконтроллерах PIC регистры общего назначения также восьмиразрядные, однако их количество и диапазон адресов зависят от конкретного типа устройства.
В программах, написанных на языке С, непосредственное обращение к регистрам общего назначения обычно не требуется, если только не используются фрагменты на языке ассемблера.
Регистры специальных функций используются в микроконтроллерах PIC для управления различными операциями. Как и в случае с регистрами общего назначения, их количество и адресация отличаются от устройства к устройству. В программах, написанных на языке С, непосредственное обращение к регистрам специальных функций обычно не требуется, если только не используются фрагменты на языке ассемблера.
Область ввода/вывода микроконтроллеров AVR содержит 64 регистра, используемых для управления или хранения данных периферийных устройств. К каждому из этих регистров можно обращаться по адресу ввода/вывода (начиная с 0x000) или по адресу SRAM (в этом случае к адресу ввода/вывода следует прибавить 0x020). В программах на языке С обычно используются условные имена регистров ввода/вывода, а адреса имеют значение только для программ на языке ассемблера.
Имена, адреса ввода/вывода и SRAM, а также краткое описание регистров из области ввода/вывода микроконтроллеров AVR представлены в табл. 2.1. При этом следует отметить, что в различных моделях микроконтроллеров некоторые из перечисленных регистров не используются, а адреса, не указанные в табл. 2.1, зарезервированы компанией Atmel для использования в будущем.
Таблица 2.1. Описание регистров из области ввода/вывода
Имярегистра | Адрес ввода/ вывода | Адрес SRAM | Описание | |
ACSR | 0x08 | 0x28 | Регистр управления и состояния аналогового компаратора | |
UBRR | 0x09 | 0x29 | Регистр скорости передачи данных через UART | |
UCR | 0х0А | 0х2А | Регистр управления приемопередатчиком UART | |
USR | 0x0В | 0x2В | Регистр состояния приемопередатчика UART | |
UDR | 0х0С | 0х2С | Регистр данных приемопередатчика UART | |
SPCR | 0x0D | 0x2D | Регистр управления интерфейсом SPI | |
SPSR | 0х0Е | 0х2Е | Регистр состояния интерфейса SPI | |
SPDR | 0x0F | 0x2F | Регистр ввода/вывода данных интерфейса SPI | |
PIND | 0x10 | 0x30 | Выводы порта D | |
DDRD | 0x11 | 0x31 | Регистр направления передачи данных порта D | |
PORTD | 0x12 | 0x32 | Регистр данных порта D | |
PINC | 0x13 | 0x33 | Выводы порта С | |
DDRC | 0x14 | 0x34 | Регистр направления передачи данных порта С | |
PORTC | 0x15 | 0x35 | Регистр данных порта С | |
PINB | 0x16 | 0x36 | Выводы порта В | |
DDRB | 0x17 | 0x37 | Регистр направления передачи данных порта В | |
PORTB | 0x18 | 0x38 | Регистр данных порта В | |
PINA | 0x19 | 0x39 | Выводы порта А | |
DDRA | 0x1А | 0х3А | Регистр направления передачи данных порта А | |
PORTA | 0x1В | 0х3В | Регистр данных порта А | |
EECR | 0x1С | 0х3С | Регистр управления памяти EEPROM | |
EEDR | 0x1D | 0x3D | Регистр данных памяти EEPROM | |
EEARL | 0x1Е | 0х3Е | Регистр адреса памяти EEPROM (младший байт) | |
EEARH | 0x1F | 0x3F | Регистр адреса памяти EEPROM (старший байт) | |
WDTCR | 0x21 | 0x41 | Регистр управления сторожевым таймером | |
ICR1L | 0x24 | 0x44 | Регистр захвата таймера/счетчика Т/С1 (младший байт) | |
ICR1H | 0x25 | 0x45 | Регистр захвата таймера/счетчика Т/С1 (младший байт) | |
OCR1BL | 0x28 | 0x48 | Регистр сравнения В таймера Т/С1 (младший байт) | |
OCR1BH | 0x29 | 0x49 | Регистр сравнения В таймера Т/С1 (старший байт) | |
OCR1AL | 0х2А | 0х4А | Регистр сравнения А таймера Т/С1 (младший байт) | |
OCR1AH | 0x2В | 0x4В | Регистр сравнения А таймера Т/С1 (старший байт) | |
TCNT1L | 0х2С | 0х4С | Счетный регистр таймера/счетчика Т/С1 (младший байт) | |
TCNT1H | 0x2D | 0x4D | Счетный регистр таймера/счетчика Т/С1 (старший байт) | |
TCCR1B | 0x2Е | 0х4Е | Регистр управления В таймера/счетчика Т/С1 | |
TCCR1A | 0x2F | 0x4F | Регистр управления А таймера/счетчика Т/С1 | |
TCNT0 | 0x32 | 0x52 | Счетный регистр таймера/счетчика Т/С0 | |
TCCR0 | 0x33 | 0x53 | Регистр управления таймера/счетчика Т/С0 | |
MCUCR | 0x35 | 0x55 | Регистр управления микроконтроллером | |
TIFR | 0x38 | 0x58 | Регистр флагов прерываний от таймеров/счетчиков | |
TIMSK | 0x39 | 0x59 | Регистр маскирования прерываний от таймеров | |
GIFR | 0х3А | 0х5А | Общий регистр флагов прерываний | |
GIMSK | 0х3В | 0x5В | Общий регистр маскирования прерываний | |
SPL | 0x3D | 0x5D | Указатель стека (младший байт) | |
SPH | 0х3Е | 0х5Е | Указатель стека (старший байт) | |
SREG | 0x3F | 0x5F | Регистр состояния |
Регистр состояния содержит флаги условий микроконтроллеров AVR и располагается в области ввода/вывода по адресу $3F (адрес SRAM – $5F). После подачи сигнала сброса он инициализируется нулями.