Text
                    В.Я. Хартов
МИКРОКОНТРОЛЛЕРЫ
PB5(MOS1) PB6(MISO) PB7(SCK) RESET
VCC GND XTAL2 XTAL1 PD0\RXD PD1\TXD
PD2\INT0p П
AT90S8535-8AC
ADC4\PA4 ADC5VPA5 ADC6\PA6 ADC7\PA7 AREF AGND AVCC
TOSC2VPC7 TOSC1\PC6 PC5 PC4
33
32
31
25
24
23
Практикум для начинающих
2-е издание
m ’т wi чг г~ — в — сч m oaoflauguuuu
Издательство
МГТУ им. Н.Э. Баумана
УДК 621.396(075.8)
ББК 32.81
Х22
Рецензенты:
проф., зам. зав. кафедрой «Вычислительная техника» МИРЭАЕ.Л. Иванов] зам. директора департамента «Ростелеком» С.М. Коновалов]
доц. МГТУ им. Н.Э. Баумана В.М. Недашковский
Хартов В. Я.
Х22 Микроконтроллеры AVR. Практикум для начинающих : учеб, пособие / В. Я. Хартов. - 2-е изд., испр. и доп. - М. : Изд-во МГТУ им. Н. Э. Баумана, 2012. - 280 с.: ил.
ISBN 978-5-7038-3565-4
Практикум содержит материалы для изучения микроконтроллеров AVR с архитектурой RISC. Рассмотрены необходимые инструментальные средства и предложен большой комплект учебных программ для изучения функциональных возможностей микроконтроллеров. Тематика учебного пособия охватывает практически все аспекты архитектуры микроконтроллеров. Базовые программы могут быть использованы в качестве основы для обучения и самостоятельного программирования на языке Ассемблер AVR в курсовом и дипломном проектировании.
Материалы книги автор использует в учебном процессе в МГТУ им. Н.Э. Баумана.
Для студентов высших и средних специальных учебных заведений, обучающихся по направлению «Информатика и вычислительная техника».
УДК 621.396(075.8)
ББК 32.81
Учебное издание
Хартов Вячеслав Яковлевич
МИКРОКОНТРОЛЛЕРЫ AVR
Практикум для начинающих
Редактор В.М. Царев. Художник С.С. Водчиц.
Технический редактор Э.А. Кулакова. Корректор М.А. Василевская.
Компьютерная верстка О. В. Беляевой.
Подписано в печать 25.01.2012. Формат 60x90 1/16. Усл. печ. л. 17,5.
Тираж 1000 экз. Заказ 53
Издательство МГТУ им. Н.Э. Баумана. 105005, Москва, 2-я Бауманская, 5.
E-mail: press@bmstu.ru http://www. baumanpress.ru
Отпечатано в типографии МГТУ им. Н.Э. Баумана.
105005, Москва, 2-я Бауманская ул., д. 5. E-mail: baumanprint@gmail.com
© Хартов В.Я., 2007
© Хартов В.Я., 2012, с изменениями
© Оформление. Издательство
ISBN 978-5-7038-3565-4	МГТУ им. Н.Э. Баумана, 2012
ОГЛАВЛЕНИЕ
Предисловие................................................ 5
1.	Инструментальные средства практикума.................... 8
1.1.	Микроконтроллеры АТх8515.............................. 9
1.2.	Интегрированная отладочная среда AVR Studio 4........ 41
1.3.	Стартовый набор STK500 фирмы ATMEL................. 46
1.4.	Интерфейс STK500 в AVR Studio 4 и программирование микроконтроллера....................................... 52
1.5.	Интегрированная отладочная среда VMLab.............
2.	Программирование портов ввода/вывода................... 65
2.1.	Взаимодействие микроконтроллера с кнопками и светодиодами .................................................. 66
2.2.	Обработка внешних прерываний....................... 69
3.	Арифметическая обработка данных........................ 76
3.1.	Представление чисел в микроконтроллерах............ 76
3.2.	Сложение и вычитание чисел в дополнительном коде... 77
3.3.	Умножение чисел без знака.......................... 79
3.4.	Деление целых чисел................................ 80
3.5.	Сложение и вычитание двоично-десятичных чисел...... 86
3.6.	Программирование арифметических операций........... 90
3.7.	Операции над числами с плавающей точкой............ 97
3.8.	Программы для преобразования чисел................ 121
4.	Таймеры микроконтроллеров АТх8515..................... 133
4.1.	Таймер/счетчик ТО микроконтроллера AT90S8515...... 134
4.2.	Таймер/счетчик Т1 микроконтроллеров АТх8515....... 136
4.3.	Программирование таймера ТО....................... 144
4.4.	Программирование функций сравнения, захвата и ШИМ таймера Т1...................................... 149
4.5.	Сторожевой таймер..................................
5.	Обмен данными по последовательному интерфейсу......... 163
5.1.	Последовательный обмен данными по каналу UART..... 163
5.2.	Работа последовательного канала SPI............... 178
5.3.	Обмен данными по интерфейсу 12C(TWI).............. 189
4
Оглавление
6.	Организация ввода/вывода данных по параллельному интерфейсу............................................... 218
6.1.	Взаимодействие с клавиатурой и ЖК-дисплеем....... 218
6.2.	Организация асинхронного параллельного обмена данными с квитированием......................................... 230
7.	Устройства для обработки аналоговых сигналов.......... 240
7.1.	Аналого-цифровой преобразователь................. 240
7.2.	Аналоговый компаратор............................ 242
8.	Энергонезависимая память данных EEPROM................ 248
9.	Программирование микроконтроллеров.................... 251
9.1.	Способы программирования и конфигурационные биты.. 251
9.2.	Самопрограммирование микроконтроллеров........... 256
10.	Программирование и отладка программ на языке Си....... 266
10.1.	Среда CodeVision AVR............................ 266
10.2.	Отладка в AVR Studio............................ 272
Литература............................................... 277
Приложение. Обозначения регистров ввода/вывода АТх8515 .. 278
ПРЕДИСЛОВИЕ
Появление новых семейств микроконтроллеров (МК) с RISC-архитектурой (Reduced Instraction Set Computer), выполненных с Flash-памятью для программ, не могло не привлечь внимания спе-циа-листов, занятых разработкой компьютерных систем управления. Высокие технические и конструктивные характеристики, низкая цена и невысокая потребляемая мощность способствовали их признанию; они быстро завоевали популярность, потеснив на мировом рынке широко известное семейство MCS-51 и ему подобные. Сказанное относится прежде всего к микроконтроллерам общего назначения семейств PicMicro, AVR Atmel и др. Но если первые имеют сравнительно небольшой набор операций (до 35), то вторые с системой команд, насчитывающей до 120 и более, практически ни в чем не уступают микроконтроллерам с CISC-архитектурой (Complex Instruction Set Computer). Эти микроконтроллеры имеют более развитую систему адресации данных, что чрезвычайно важно при создании эффективного программного обеспечения.
Наряду с новыми технологическими решениями разработчики компьютерных управляющих систем получили в свое распоряжение удобный аппарат в виде интегрированных систем проектирования и отладки программ (Integrated Development Environment, IDE) и стартовых наборов (Starter Kit, STK), которые при совместном использовании являются неоценимым инструментом, ускоряющим процесс разработки и повышающим его эффективность.
Излагаемый материал базируется на трех «китах».
Во-первых, это архитектура 8-разрядных микроконтроллеров AVR, относящихся к средним по своим функциональным характеристикам семействам микроконтроллеров общего применения (например, AT90S8515 семейства Classic или его аналога ATmega8515 семейства Mega). Знание архитектуры этих микроконтроллеров позволит быстро освоить иные модели микроконтроллеров этих семейств, а также микроконтроллеры других фирм-изготовителей.
6
Предисловие
Во-вторых, использование интегрированной среды проектирования AVR Studio 4, свободно распространяемой в сети Internet, дает возможность не только разрабатывать, но и отлаживать создаваемое программное обеспечение с помощью встроенного симулятора, а в среде VMLab совместно моделировать работу микроконтроллера и простых внешних устройств.
Наконец, подключив к AVR Studio 4 стартовый набор разработчика STK500, можно проверить созданную программу непосредственно в целевом микроконтроллере, а подключив через разъем расширения дополнительные устройства, - и в составе системы. Попутно отметим сравнительно невысокую стоимость STK500, что немаловажно для учебных заведений.
Пособие построено следующим образом. Вначале дается описание микроконтроллеров AVR, отладочных инструментов AVR Studio и VMLab и, наконец, стартового набора STK500. Освоение архитектуры и системы команд микроконтроллеров начинается с изучения приводимых в пособии проектов и программ, подготовленных на языке Ассемблер AVR, знакомящих с функциями портовой системы микроконтроллера, возможностями арифметической обработки данных, разнообразными функциями таймеров, организацией ввода-вывода по параллельным и последовательным каналам связи, с устройствами обработки аналоговых сигналов.
Одна из глав пособия посвящена технологии работы над проектом, использующим программы, написанные на языке Си, и компилятор Code Vision С Compiler, разработанный HP Info Tech. В работах над проектами автор использовал помимо основных упомянутых интегрированных систем проектирования и другие, в частности, программу ISIS из пакета Proteus 6 Professional (Labcenter Electronics), что позволило провести совместную симуляцию программ в проектах, содержащих более одного микроконтроллера, вместе с виртуальными периферийными устройствами. Описанные программы и инструменты можно исполь-зовать в качестве основы при разработке программного обеспечения в приложениях общего назначения.
Все разделы пособия содержат альтернативные задания разной сложности для самостоятельного программирования, которые могут быть реализованы на основе полученных знаний, и контрольные вопросы.
Автор с удовлетворением отмечает большой интерес к первому изданию пособия, проявленный со стороны пользователей сети Internet, что подтолкнуло его к продолжению работы над данным учебным пособием. Во второе издание внесен ряд изменений и
Предисловие
7
дополнений. Переработана глава 3, в которую кроме методов арифметической обработки в микроконтроллерах вошли материалы по преобразованию форматов числовых данных (двоичный, двоично-десятичный целочисленный, с плавающей точкой). Заново написан ряд учебных программ, делающих их более наглядными для применения. Попутно устранены ошибки и неточности, допущенные в первом издании в программах арифметической обработки, выявленные при проведении учебного процесса во время активного тестирования описанных программ. Автор выражает благодарность студентам, принявшим участие в этой работе.
В пособие добавлен ряд новых разделов, посвященных отладке в интегрированной среде VMLab (1.5), программированию энергонезависимой внутренней памяти EEPROM (гл. 8) и памяти программ микроконтроллеров (гл. 9). Для сокращения времени подготовки учебных программ для AVR Studio 4 предлагается архив с файлами программ, размещенный в сети Internet по ссылке /8/.
Автор надеется, что проделанная работа будет и дальше способствовать плодотворному самостоятельному изучению архитектуры микроконтроллеров широким кругом лиц, интересующихся новыми схемотехническими решениями.
1. ИНСТРУМЕНТАЛЬНЫЕ СРЕДСТВА ПРАКТИКУМА
Микроконтроллеры AVR фирмы Atmel, появившись на рынке интегральных микросхем в 1996 г., сразу же привлекли к себе внимание разработчиков электронной аппаратуры. Удачное сочетание RISC-архитектуры «ядра», обеспечивающей высокую производительность, с широким набором команд, Flash-памятью для программ быстро выдвинуло микроконтроллеры AVR на передовые позиции.
На смену микроконтроллерам первых семейств (Tiny и Classic) пришло новое поколение микроконтроллеров (Mega). Сохранив программную преемственность, микроконтроллеры Mega приобрели новые свойства: пониженные напряжение питания (до 2,7 В) и энергопотребление, повышенные быстродействие (до 16 МГц) и объем Flash-памяти (до 128 Кбайт). Вслед за 8-разрядными микроконтроллерами появились 32-разрядные микроконтроллеры AVR32 и др.
Одновременно были созданы программные продукты и технические средства, поддерживающие разработку программ для микроконтроллеров. Это, прежде всего, фирменный пакет фирмы Atmel AVR Studio, свободно распространяемый в сети Internet, и отладочные платы в виде стартовых наборов разработчика (STK500, STK501, STK502 нового STK600), выпущенные для поддержки разработок на микроконтроллерах AVR. Вместе они образуют единую платформу, на которой можно успешно проводить разработку и отладку различных приложений.
Инструментальными средствами разработки и отладки про-, грамм для микроконтроллеров AVR, используемыми в практикуме, являются интегрированный пакет AVR Studio 4 и стартовый набор STK500 фирмы Atmel. Целевыми микроконтроллерами, которые используются во всех проектах практикума, являются АТх8515, поставляемые в комплекте со стартовым набором STK500 и занимающие среднее положение в семействе выпускаемых моделей AVR.
1.1. Микроконтроллеры АТх8515
9
В связи с этим, прежде чем перейти непосредственно к инструментальным средствам проектирования, рассмотрим кратко основные характеристики используемых микроконтроллеров и их структуру.
1.1. МИКРОКОНТРОЛЛЕРЫ АТх8515
Аппаратные ресурсы
Все микроконтроллеры AVR имеют гарвардскую архитектуру, которая предполагает разделение памяти программ и данных. Используемые при этом средства адресации позволяют создавать эффективные программы с высоким быстродействием.
Упрощенная структурная схема микроконтроллера AT90S8515 представлена на рис. 1.1. Ядро микроконтроллера образуют блок процессора, объединяющий арифметико-логическое устройство (АЛУ) с регистром признаков (SREG) и устройство управления, память программ (Flash) объемом 8 Кбайт, регистры общего назначения, память данных статического типа (SRAM) объемом 512 байт. Устройство управления включает схему синхронизации, регистр управления микроконтроллера (MCUCR), генератор, а также регистр команд с дешифратором, программный счетчик и указатель стека.
Периферийные устройства представлены достаточно широко:
-	8-разрядные порты ввода/вывода РА, РВ, PC, PD;
-	последовательный асинхронный приемопередатчик UART (Universal Asynchronous Receiver-Transmitter);
-	последовательный синхронный порт SPI (Serial Peripheral Interface);
-	8-разрядный таймер ТО;
-	16-разрядный таймер Т1;
-	сторожевой таймер;
-	широтно-импульсный модулятор PWM;
-	энергонезависимая память EEPROM объемом 512 байт;
-	блок прерываний;
-	аналоговый компаратор.
Для памяти программ и энергонезависимой памяти в составе микроконтроллера имеются средства для внутрисистемного программирования по интерфейсу SPI.
Память микроконтроллера организована, как показано на рис. 1.2.
РА0-РА7
РС0-РС7
Рис. 1.1. Структурная схема микроконтроллера AT90S8515
1.1. Микроконтроллеры А Тх8515
11
Память данных
Память программ Flash 8 Кбайт	32 регистра общего назначения	Память EEPROM 512 байт
64 регистра ввода/ вывода
Статическая память SRAM 512 байт
Рис. 1.2. Карта памяти микроконтроллеров ATxS8515
Память программ Flash обособлена, ее размер составляет 8 Кбайт. Каждая ячейка Flash-памяти содержит 16 разрядов.
Память данных делится на три части: регистровая, оперативная статическая SRAM и энергонезависимая EEPROM.
Регистровую память составляют 32 регистра общего назначения и 64 регистра ввода/вывода, представляющих периферийные устройства.
Оперативная память объемом 512 байт предназначена для хранения данных при выполнении программы. Регистровая и оперативная память образуют единое адресное пространство: регистры общего назначения занимают адреса $0000-$001F, за ними располагаются регистры ввода/вывода $0020-$005F, затем ячейки оперативной памяти $0060-$025F. Расширение адресного пространства вплоть до верхней границы $FFFF можно осуществить за счет подключения внешнего запоминающего устройства ERAM.
Для долговременного хранения данных, которые могут изменяться в процессе работы микроконтроллера, используют память EEPROM объемом 512 байт. Память EEPROM имеет обособленное адресное пространство, каждая ячейка содержит восемь разрядов. Данные в EEPROM могут быть записаны при программировании микроконтроллера. При выключении питания данные сохраняются.
Регистры общего назначения разбиты на две группы: Ro.. .R15 и R16...R31. Принадлежность регистра к той или иной группе необходимо учитывать при написании программы.
Микроконтроллер AT90S8515 содержит 44 регистра ввода/вывода, используемых в составе периферийных устройств (еще 20 регистров зарезервировано), из них 14 - 8-разрядные регистры данных, остальные являются регистрами управления и состояния. Если
12
1. Инструментальные средства практикума
учесть, что они представлены битами управления и состояния, общее количество которых 187 (!), и часть их объединена полями с кодами управления, то нетрудно понять, насколько многообразны функциональные возможности этих устройств (к примеру, одно 3-разрядное поле управления позволяет задать восемь управляющих функций). Список регистров ввода/вывода и их адреса в адресном пространстве SRAM приведены в табл. 1.1.
Таблица 1.1. Адреса регистров ввода/вывода AT90S8515
Адрес	20	30	40	50
0	Резерв	PIND	Резерв	Резерв
1	Резерв	DDRD	WDTCR	Резерв
2	Резерв	PORTD	Резерв	TCNTO
3	Резерв	PINC	Резерв	TCCRO
4	Резерв	DDRC	ICR1L	Резерв
5	Резерв	PORTC	ICR1H	MCUCR
6	Резерв	PINB	Резерв	Резерв
7	Резерв	DDRB	Резерв	Резерв
8	ACSR	PORTB	OCR 1 BL	TIFR
9	UBRR*	PINA	OCR1BH	TIMSK
А	UCR*	DDRA	OCR1AL	GIFR
В	USR*	PORTA	OCR1AH	GIMSK’
С	UDR	EECR	TCNT1L	Резерв
D	SPCR	EEDR	TCNT1H	SPL
Е	SPSR	EEARL	TCCR1B	SPH
F	SPDR	Резерв	TCCR1A	SREG
Все регистры имеют штатные имена, которые можно использовать при написании программ. Для этого в программу на языке Ассемблера необходимо включить файл определений 8515def.inc, а в программу на языке Си - файл 90s8515.h.
Расшифровка названий регистров, формат и назначение каждого бита в отдельности приведены в последующих разделах практикума при описании работы соответствующих периферийных устройств. Регистры, имена которых отмечены знаком *, в модели ATmega8515 получили другие имена: по адресу $29 - UBRRL, по адресу $2А -UCSRB, по адресу $2В - UCSRA, по адресу $5В - GICR.
1.1. Микроконтроллеры А Тх8515
13
Список регистров ввода/вывода микроконтроллера ATmega8515 и их адреса в адресном пространстве SRAM приведены в табл. 1.2. Микроконтроллер ATmega8515 содержит 55 регистров ввода/вывода. Файл определений штатных имен регистров для ATmega8515, включаемый в программы на Ассемблере, носит имя m8515def.inc, на языке Си - mega8515.h.
Таблица 1.2. Адреса регистров ввода/вывода ATmega8515
Адрес	20	30	40	50
0	Резерв	PIND	UBRRH	SFIOR
1	Резерв	DDRD	WDTCR	OCRO
2	Резерв	PORTD	Резерв	TCNTO
3	Резерв	PINC	Резерв	TCCRO
4	OSCCAL	DDRC	ICR1L	MCUCSR
5	PINE	PORTC	ICR1H	MCUCR
6	DDRE	PINB	Резерв	EMCUCR
7	PORTE	DDRB	Резерв	SPMCR
8	ACSR	PORTB	OCR1BL	TIFR
9	UBRRL	PINA	OCR1BH	TIMSK
А	UCSRB	DDRA	OCR1AL	GIFR
В	UCSRA	PORTA	OCR1AH	GICR
С	UDR	EECR	TCNT1L	Резерв
D	SPCR	EEDR	TCNT1H	SPL
Е	SPSR	EEARL	TCCR1B	SPH
F	SPDR	EEARH	TCCR1A	SREG
Оперативная память служит для оперативного хранения данных при выполнении программы. Данные для записи в ячейку SRAM поступают из регистра общего назначения. Считываемые из ячейки памяти данные поступают в регистр общего назначения. При выключении напряжения питания данные в памяти SRAM теряются.
Стек располагается в памяти SRAM, обычно под него выделяется область адресов, начиная с $025F. Стек растет в сторону убывающих адресов, контроль его размера возлагается на программиста.
14
1. Инструментальные средства практикума
Контроллер прерываний обрабатывает внешние прерывания и прерывания от периферийных устройств (таймеров, портов последовательного ввода/вывода, аналогового компаратора и др.). Все прерывания являются маскируемыми. Адреса, маски и флаги прерываний указаны в табл. 1.3. В таблице представлены:
INTO, INTI - сигналы внешних прерываний, поступающие по линиям порта PD2, PD3. Маски внешних прерываний представлены разрядами INTO и INT1 (соответственно 6-й и 7-й разряды регистра GIMSK микроконтроллера AT90S8515 или регистра GICR микроконтроллера ATmega8515). Сигналы внешних прерываний устанавливают в состояние 1 флаги прерываний INTF0 и INTF1 (соответственно 6-й и 7-й разряды регистра GIFR);
прерывания от таймеров Т1, ТО, имеют адреса $003 - $007. Маскирование прерываний от таймеров осуществляется битами регистра TIMSK. Флаги прерываний таймеров располагаются в регистре TIFR;
последующие адреса прерываний для запросов от последовательных каналов ввода/вывода SPI ($008), UART или USART ($009, $00А, $00В) и аналогового компаратора ($00С). Маскирование прерываний осуществляется разрядами регистров: для канала UART - UCR (или UCSRB), для канала SPI - SPCR, для компаратора - ACSR. Соответствующие флаги прерываний располагаются в регистрах состояния USR (или UCSRA), SPSR, ACSR;
остальные прерывания (внешние прерывания INT2, от схемы сравнения таймера ТО, по окончании записи в память EEPROM и в память Flash), помеченные знаком *, поддерживаются микроконтроллером ATmega8515.
Из таблицы 1.3 видно, что таблица векторов прерываний моделей АТх8515 располагается в начальной области памяти программ, начиная с адреса $0001. Размер таблицы зависит от типа модели. Следует также иметь в виду, что микроконтроллеры семейства Mega допускают перемещение таблицы векторов из начальной области памяти программ в начало области загрузчика, которая располагается в конце программной памяти. Для этого используют два младших бита регистра GICR микроконтроллеров ATmega8515: IVSEL (1-й разряд) и IVCE (0-й разряд). Если IVSEL=0, таблица векторов располагается в начале памяти программ, при IVSEL=1 - в начале области загрузчика. Конкретное значение начального адреса области загрузчика определяется конфигурационными ячейками BOOTSZ1 и BOOTSZ2, о чем подробно говорится в главе 9. Бит IVCE используется для разрешения изменения бита IVSEL.
1.1. Микроконтроллеры АТх8515
15
Таблица 1.3. Адреса и маски прерываний АТх8515
Запрос	Адрес	Маска	Флаг
RESET	ООО	GIMSK.6/	-
INTO	001	GICR.6 GIMSK.7/	GIFR.6
INTI	002	GICR.7	GIFR.7
Т/Cl CAPT	003	TIMSK.3	TIFR.3
T/Cl COMPA	004	TIMSK.6	TIFR.6
Т/Cl COMPB	005	TIMSK.5	TIFR.5
T/Cl OVF	006	TIMSK.7	TIFR.7
T/CO OVF	007	TIMSK.l	TIFR.1
SPI STC	008	SPCR.7	SPSR.7
UART RXC/	009	UCR.7/	USR.7/
USART RXC		UCSRB.7	UCSRA.7
UART DRE/	00A	UCR.5/	USR.5/
USART DRE		UCSRB.5	UCSRA.5
UART ТХС/	00B	UCR.6/	USR.6/
USART TXC		UCSRB.6	UCSRA.6
ANA COMP	OOC	ACSR.3	ACSR.4
INT2*	00D	GICR.5	GIFR.5
T/CO COMP*	00E	TIMSK.O	TIFR.0
EERDY*	OOF	EECR.3	—
SPMRDY*	010	SPMCR.7	—
Положение вектора в таблице прерываний определяет приоритет соответствующего прерывания. Запрос с меньшим адресом имеет более высокий приоритет. Флаг общего разрешения прерывания I расположен в регистре состояния микроконтроллера SREG (бит 7). При I = 1 и единичном значении маски запроса прерывание данного типа разрешено. При поступлении запроса устанавливается флаг прерывания в одном из регистров ввода/вывода, который может вызвать аппаратное прерывание. Состояние флага может быть также опрошено программой.
16
1. Инструментальные средства практикума
Обработка прерывания начинается после завершения текущей команды, для чего может понадобиться несколько тактов в зависимости от типа выполняемой команды. При обработке прерывания разряд I в регистре SREG сбрасывается в состояние 0, запрещая обработку всех остальных запросов. В стеке сохраняется адрес возврата и выполняется переход по вектору прерывания на первую команду обработчика прерывания. При выходе из прерывающей программы разряд I вновь устанавливается в состояние 1, разрешая обработку прерываний. Программа, выполняемая при пуске микроконтроллера и использующая вектор запроса RESET, не зависит от состояния разряда I. Для обработки прерываний она должна выполнить команду разрешения прерываний, устанавливающую флаг I в состояние 1.
Аналоговый компаратор сравнивает по значению аналоговые сигналы, поступающие на входы порта РВ2, РВЗ, и формирует запрос прерывания ANA COMP при изменении знака разности, а также сигнал захвата для таймера.
На рис. 1.3 приведены условные графические обозначения микросхем микроконтроллеров AT90S8515 и ATmega8515, используемых в практикуме. Все выводы портов имеют альтернативные функции, конфигурируемые автоматически при использовании периферийных устройств микроконтроллера. Их имена приведены
(ТО) РВОЕ	1	40	J VCC
(Tl) РВ1 Е	2	39	3 РАО (AD0)
(AINO) РВ2 Е	3	38	3 PAI (AD1)
(AIN11 РВЗ Е	4	37	3 РА2 (AD2)
(SS)PB4 Е	5	36	3 РАЗ (AD3)
(MOSI) РВ5 Е	6	35	3 РА4 (AD4)
(MISO) РВ6 Е	7	34	J РА5 (AD5)
(SCK) РВ7 Е	8	33	3 РА6 (AD6)
RESETЕ	9	32	3 РА7 (AD7)
(RXD) PD0 Е	10	31	3 ICP
(TXD) РО1 Е	И	30	1 ALE
(INTO) PD2 Е	12	29	3 ОС1В
(INTI) PD3 Е	13	28	3 РС7 (А15)
PD4 Е	14	27	J РС6 (А14)
(ОС1А) PD5 Е	15	26	1 РС5 (А13)
(WR) PD6E	16	25	3 РС4 (А12)
(RD) PD7 Е	17	24	3 РСЗ(А11)
XTAL2 Е	18	23	3 РС2 (А10)
XTAL1 Е	19	22	3 PCI (А9)
GNDE	20	21	3 РСО (А8)
AT90S8515
(ОСО/ТО) (Т1)	PBOE PB1E	1 2	40 39	J vcc J РАО (ADO)
(AIN0)	PB2E	3	38	3 PAI (ADI)
(AIN1)	PB3E	4	37	3 PA2 (AD2)
(SS)	PB4E	5	36	J РАЗ (AD3)
(MOSI)	PB5E	6	35	3 PA4 (AD4)
(MISO)	PB6E	7	34	J PA5 (ADS)
(SCK) PB7E		8	33	J PA6 (AD6)
RESETE		9	32	3 PA7 (AD7)
(RXD)	PDOE	10	31	J PE0 (ICP/INT2)
(TDX)	PD1E	11	30	3 PEI (ALE)
(INTO)	PD2E	12	29	3 PE2 (OC1B)
(INTI)	PD3E	13	28	3 PC7 (A15)
(XCK)	PD4E	14	27	3 PC6 (A14)
(OC1A)	PD5 E	15	26	3 PC5 (A13)
(WR)	PD6E	16	25	3 PC4 (A12)
(RD)	PD7 E	17	24	3 PC3(A11)
XTAL2E		18	23	3 PC2 (A10)
XTAL1E		19	22	3 PCI (A9)
GNDE		20	21	3 РСО (A8)
ATmega8515
Рис. 1.3. Интерфейсы микроконтроллеров АТх8515
1.1. Микроконтроллеры АТх8515
в скобках. По сравнению с AT90S8515 в микроконттодлере ATmega8515 выводы 29-31 образуют 3-разрядный порт РЕ.
контроллеры АТх8515 выпускают в разных корпусах: TQFP, 1^|^О8 PDIP. Поставляемые со стартовым набором STK500 микроконтроллеры выполнены в 40-выводном корпусе PDIP, устанавливаемом в панели STK500, и допускают замену в процессе эксплуатации.
Тактирование, пуск микроконтроллера и режимы энергосбережения
В микроконтроллерах AVR используют различные схемы формирования тактовых сигналов. В зависимости от типа модели в качестве источника тактовых сигналов могут быть использованы:
-	встроенный генератор с подключаемым кварцевым или керамическим резонатором (XTAL);
-	генератор с низкочастотным кварцевым резонатором на частоту 32768 Гц - «часовой кварц» (XTAL Low);
-	внутренний RC-генератор (IRC);
-	внутренний генератор с внешней RC-цепочкой (ERC);
-	внешний генератор (EXT).
Сведения об источниках тактовых сигналов, которые можно выбрать для некоторых моделей микроконтроллеров, приведены в табл. 1.4. В микроконтроллерах mega8, mega8515 выбор генератора осуществляется значением установочных битов CKSEL3...0 конфигурационных ячеек (табл. 1.5).
Таблица 1.4. Источники тактовых сигналов
Источник	Тип микроконтроллера			
	8515	8535	mega8	mega8515
XTAL	+	+	+	+
XTAL Low			+	+
IRC			+	+
ERC			+	+
EXT	+	+	+	+
Таблица 1.5. Выбор генератора для ATmega8, ATmega8515
CKSEL3...0	Источник
1111 - 1010	XTAL
1001	XTAL Low
1000-0101	ERC
0100-0001	IRC
0000	EXT
18
1. Инструментальные средства практикума
а	б	в
Рис. 1.4. Генераторы тактовых сигналов:
а - с внешним резонатором; б - с внешним источником сигналов; в - с внешней RC-цепью
Резонатор подключается к выводам микроконтроллера XTAL1, XTAL2 (рис. 1.4, а). Конденсаторы Cl, С2, подключаемые между выводами резонаторов и общей шиной, зависят от типа резонатора и составляют для кварцевых резонаторов 12...22 пФ, а для керамических резонаторов выбираются согласно рекомендациям производителей.
При внешней синхронизации (рис. 1.4, б) сигнал от внешнего источника подается на вход XTAL1. Параметры внешнего сигнала должны удовлетворять требованиям микроконтроллера. Вывод XTAL2 остается неподключенным.
ERC-генератор с внешней RC-цепью представлен схемой (рис. 1.4, в). Рекомендуемая емкость конденсатора - 22 пФ, величина сопротивления - 3,3... 100 кОм. Частота тактовых сигналов равна 1/3RC. Тактовый генератор может работать в четырех различных режимах работы, каждый из которых характеризуется определенным диапазоном частот и устанавливается 4-разрядной кодовой комбинацией CKSEL3...0 (0101 - до 0,9 МГц, ОНО -от 0,9 до 3 МГц, 0111 - от 3 до 8 МГц, 1000 - от 8 до 12 МГц).
IRC-генератор с внутренней RC-цепью является наиболее экономичным решением, не требующим никаких внешних компонентов. Номинальная частота внутреннего генератора для указанных типов микроконтроллеров зависит от коэффициента CKSEL3...0 (0001 - 1 МГц, 0010 - 2 МГц, 0011-4 МГц, 0100 - 8 МГц). Во всех случаях при работе с внутренним IRC-генератором бит СКРОТ в конфигурационной ячейке должен быть установлен в 1. Кроме того, предусмотрена возможность подстройки частоты внутреннего генератора (калибровка) путем изменения содержимого регистра OSCCAL.
1.1. Микроконтроллеры АТх8515
19
Пуск микроконтроллера происходит при подаче напряжения питания на выводы VCC и RESET (Power-On Reset, POR). Все регистры ввода/вывода переводятся в исходное состояние, а программный счетчик сбрасывается в 0.
Перезапуск микроконтроллера в процессе работы может произойти в следующих случаях:
-	при появлении на входе RESET сигнала низкого уровня с последующим возвращением к высокому уровню (аппаратный или внешний сброс External Reset, EXR);
-	при поступлении сигнала тайм-аут от сторожевого таймера (Watchdog Reset, WDTR);
-	при падении напряжения питания ниже заданной величины (Brown-Out Reset, BOR).
При пуске и перезапусках формируется внутренний сигнал сброса определенной длительности /Тоит (рис. 1.5), по окончании которого микроконтроллер приступает к выполнению программы с нулевого адреса.
vcc, RESET
Тайм-аут таймера сброса
ZTOUT
Внутренний сброс
Рис. 1.5. Временные диаграммы сигналов сброса при пуске в момент подачи напряжения, вывод RESET подключен к VCC
В микроконтроллерах, имеющих в своем составе регистр MCUSR (семейства Classik) или MCUCSR (семейства Mega), имеется возможность определения программными средствами используемый способ пуска/перезапуска микроконтроллера. Так, например, микроконтроллер AT90S8535 имеет два бита-флага EXTRF и PORF, единичное значение которых служит указателем типа запуска, а микроконтроллеры ATmega8, ATmega8515 - четыре бита WDRF, BORF, EXTRF, PORF соответственно для WDTR, BOR, EXR, POR.
20
1. Инструментальные средства практикума
Длительность внутреннего сигнала сброса можно изменить с помощью установочных битов CKSEL, FSTRT, SUT. Величина длительности может изменяться в широких пределах от нескольких десятков микросекунд до нескольких сотен милисекунд. Наборы значений установочных битов различны для разных типов микроконтроллеров, напряжений питания, применяемых генераторов тактовых сигналов и указаны в технической документации на микроконтроллеры.
Режимы энергосбережения. Различные модели микроконтроллеров AVR поддерживают от двух до шести режимов пониженного энергопотребления. Эти режимы отличаются количеством устройств, работающих в «спящем» режиме, и уровнем энергопотребления.
У всех типов микроконтроллеров имеются два режима энергосбережения: холостого хода (IM, Idle Mode) и пониженного энергопотребления (PDM, Power Down Mode).
В режиме IM процессор остановлен, содержимое регистров общего назначения и ячеек SRAM сохраняется неизменным, устройства ввода/вывода продолжают работать. Общий ток потребления 1сс микроконтроллеров уменьшается в 2-4 раза. Выход из режима происходит при перезапуске микроконтроллера или при поступлении разрешенного запроса прерывания.
В режиме PDM остановлены процессор и генератор тактовых сигналов. Все устройства ввода/вывода, за исключением сторожевого таймера и блока прерываний, не работают. Содержимое регистров общего назначения и ячеек SRAM не изменяется. Ток потребления 1сс не превышает нескольких десятков микроампер. Вывести микроконтроллер из этого режима можно либо перезапустив микроконтроллер, либо по сигналу разрешенного внешнего прерывания статического уровня. Длительность сигнала прерывания при этом должна сохраняться до тех пор, пока генератор не войдет в установившийся режим. Для некоторых типов микроконтроллеров существуют другие возможности вывода микроконтроллера из режима PDM.
Микроконтроллеры AVR, имеющие в своем составе таймер реального времени, можно перевести в режим энергосохранения (PSM, Power Save Mode). В этом режиме, в отличие от режима PDM, продолжает работать таймер реального времени, который может вывести микроконтроллер из этого режима сигналом прерывания. В микроконтроллерах, имеющих в своем составе модуль АЦП, имеется режим снижения шумов (ADC Noise Reduction).
1.1. Микроконтроллеры АТх8515
21
В ряде моделей микроконтроллеров семейства Mega возможны режимы Standby и Extended Standby, в которых функционирует тактовый генератор с внешним резонатором.
Для перевода микроконтроллера в энергосберегающий режим необходимо установить бит SE регистра MCUCR в состояние 1. Выбор режима энергосбережения при наличии двух возможных режимов осуществляется установкой/сбросом бита SM в регистре MCUCR. При SM=0 устанавливается режим холостого хода, при SM=1 - режим пониженного энергопотребления. При наличии трех и более режимов энергосбережения выбор режима осуществляется с помощью двух или трех битов. Переход микроконтроллера в энергосберегающий режим происходит при выполнении команды SLEEP.
Система команд микроконтроллеров AVR
Для программирования микроконтроллера AT90S8515 используется 118 команд, ATmega8515-130. Все команды можно разбить по группам:
-	арифметических и логических операций;
-	передачи управления;
- операций с битами.
В табл. 1.6-1.9 приведено описание базового набора команд микроконтроллеров AVR. При описании команд использованы следующие обозначения:
Rd, Rr - регистры общего назначения с номерами биг;
Rdh:Rdl - пара регистров;
К - константа (данные);
Р,Ь - разряд b (Ь = 0, ...,7) порта Р;
Rr(b) - разряд b (Ь = 0, ...,7) регистра Rr;
(X), (Y), (Z) - содержимое ячеек, адресуемых регистровыми парами X, Y, Z соответственно;
s - номер разряда в регистре SREG;
PC - содержимое программного счетчика;
к - приращение в счетчике команд;
q - 6-разрядное смещение;
STACK - область памяти SRAM, адресуемая указателем стека SP;
С, Z, N, V, S, Н, Т, I - биты регистра состояния SREG;
d, г = 0.. .31 во всех случаях, кроме специально отмеченных.
22
1. Инструментальные средства практикума
Таблица 1.6. Арифметические и логические операции
Мнемоника	Описание команды	Операция	Признаки
ADD Rd, Rr	Сложение двух регистров	Rd<—Rd + Rr	Z, C, N, V, H
ADC Rd, Rr	Сложение двух регистров и переноса	Rd«—Rd + Rr + С	Z, C, N, V, H
ADIW Rdl, К	Сложение регистровой пары с константой	Rdh:Rdl«— Rdh:Rdl + К	Z, C, N, V, S
SUB Rd, Rr	Вычитание двух регистров	Rd<—Rd-Rr	Z, C, N, V, H
SUBI Rd, К	Вычитание константы из регистра	Rd*—Rd-К, d= 16-31	Z, C, N, V, H
SBC Rd, Rr	Вычитание двух регистров с заемом	Rd<—Rd-Rr-C	Z, C, N, V, H
SBCI Rd, К	Вычитание константы из регистра с заемом	Rd«—Rd-K-C, d =16-31	Z, C, N, V, H
SBIW Rdl, К	Вычитание константы из регистровой пары	Rdh:Rdl<— Rdh:Rdl - К	Z, C, N, V, S
AND Rd, Rr	Логическое И двух регистров	Rd<—Rd л Rr	Z, N, V
ANDI Rd, К	Логическое И регистра и константы	Rd<—RdAK, d= 16-31	Z, N, V
OR Rd, Rr	Логическое ИЛИ двух регистров	Rd<—Rd v Rr	Z, N, V
ORI Rd, К	Логическое ИЛИ регистра и константы	Rd^-RdvK, d= 16-31	Z, N, V
EOR Rd, Rr	Логическое исключающее ИЛИ регистров	Rd<—Rd ® Rr	Z, N, V
LSLRd	Логический сдвиг влево	Rd(n + 1)«-Rd(n), Rd(0)<—0	Z, C, N, V
LSRRd	Логический сдвиг вправо	Rd(n)<—Rd(n+1), Rd(7)«—0	Z, C, N, V
1.1. Микроконтроллеры АТх8515
23
Окончание табл. 1.6
Мнемоника	Описание команды	Операция	Признаки
ROLRd	Сдвиг влево через	Rd(0)«—С,	
	перенос	Rd(n + 1)«—Rd(n), С«—Rd(7)	Z, C, N, V
RORRd	Сдвиг вправо через	Rd(7)«—С,	
	перенос	Rd(n)<—Rd(n+1), C«—Rd(0)	Z, C, N, V
ASRRd	Арифметический сдвиг вправо	Rd(n)<—Rd(n+1), n = 0...6	Z, C, N, V
СР Rd, Rr	Сравнение регистров	Rd-Rr	Z, N, V, С, H
CPC Rd, Rr	Сравнение регистров с учетом зае-ма	Rd-Rr-C	Z, N, V, С, H
CPI Rd, К	Сравнение регистра с константой	Rd-K,d= 16-31	Z, N, V, С, H
COM Rd	Инверсия регистра	Rd «- $FF - Rd	Z, C, N, V
NEG Rd	Изменение знака	Rd $00 - Rd	Z, C, N, V, H
SBR Rd, К	Логическое ИЛИ регистра и константы	Rd«—RdvK, d = 16-31	Z, N, V
CBR Rd, К	Логическое И Rd с инверсией константы	Rd^Rd л ($FF - K)	Z, N, V
INC Rd	Инкремент регистра	Rd <— Rd + 1	Z,N,V
DEC Rd	Декремент регистра	Rd <— Rd - 1	Z, N, V
TSTRd	Проверка регистра	Rd «— Rd a Rd	Z, N, V
CLRRd	Сброс регистра в 0	Rd Rd Ф Rd	Z,N,V
SER Rd	Установка 1 в разрядах регистра	Rd«-$FF, d = 16-31	
24
1. Инструментальные средства практикума
Таблица 1.7. Команды пересылки
Мнемоника	Описание команды	Операция
MOV Rd, Rr	Пересылка между регистрами	Rd <—Rr
*MOVW Rd, Rr	Пересылка между парами регистров	Rd+l:Rd«—Rr+l:Rr
SWAP Rd	Обмен тетрадами	Rd(3...0)«->Rd(7...4)
LDI Rd, К	Загрузка константы в регистр	Rd«—K,d = 16-31
LD Rd, X	Косвенная загрузка регистра	Rd«- (X)
LD Rd, X+	Косвенная загрузка с постинкрементом	Rd <- (X), X <- X + 1
LD Rd, -X	Косвенная загрузка с предде-крементом	X^X- l,Rd«—(X)
LD Rd, Y	Косвенная загрузка регистра	Rd <- (Y)
LD Rd, Y+	Косвенная загрузка с постинкрементом	Rd <- (Y), Y <— Y + 1
LD Rd, -Y	Косвенная загрузка с предде-крементом	Y <— Y- l,Rd<— (Y)
LDD Rd,Y+q	Косвенная загрузка относительная	Rd <— (Y + q)
LD Rd, Z	Косвенная загрузка регистра	Rd ♦- (Z)
LD Rd, Z+	Косвенная загрузка с постинкрементом	Rd <- (Z), Z «- Z+l
LD Rd, -Z	Косвенная загрузка с предде-крементом	Z«-Z- l,Rd«-(Z)
LDD Rd, Z+q	Косвенная загрузка относительная	Rd <— (Z + q)
LDS Rd, k	Прямая загрузка регистра	Rd <- (k)
ST X, Rr	Косвенное сохранение	(X)«—Rr
ST X+, Rr	Косвенное сохранение с постинкрементом	(X) <- Rr, X X + 1
ST-X, Rr	Косвенное сохранение с преддекрементом	X^-X-1,(X)«- Rr
1.1. Микроконтроллеры А Тх8515
25
Окончание табл. 1.7
Мнемоника	Описание команды	Операция
ST Y, Rr ST Y+, Rr ST-Y, Rr STD Y + q, Rr ST Z, Rr ST Z+, Rr ST-Z, Rr STD Z + q, Rr STS k, Rr LPM *LPM Rd, Z+ *SPM IN Rd, P OUT P, Rr PUSHRr POP Rd	Косвенное сохранение Косвенное сохранение с постинкрементом Косвенное сохранение с преддекрементом Косвенное сохранение относительное Косвенное сохранение Косвенное сохранение с постинкрементом Косвенное сохранение с преддекрементом Косвенное сохранение относительное Прямое сохранение Загрузка из программной памяти в R0 Загрузка из программной памяти в регистр Rd с постинкрементом Сохранение в программной памяти Чтение регистра ввода/вывода Запись в регистр ввода/вывода Сохранение в стеке Извлечение из стека	(Y)«—Rr (Y) <— Rr, Y <— Y + 1 Y«—Y-1, (Y) ♦-Rr (Y + q)«— Rr (Z) Rr (Z) Rr, Z Z + 1 Z«—Z - 1, (Z)«—Rr (Z + q) Rr (k)«-Rr RO «- (Z) Rd <-(Z), Z Z+l (Z)<—R1:RO Rd <— P, P = 0 - 63 P «- Rr, P = 0 - 63 STACK «- Rr Rd STACK
26
1. Инструментальные средства практикума
Таблица 1.8. Команды управления
Мнемоника	Описание команды	Операция
RJMPk	Переход	PC <- PC + к + 1
IJMP	Косвенный переход по (Z)	PC«-Z
RCALL к	Вызов подпрограммы	STACK«—PC + 1, PC <— PC + к + 1
ICALL	Косвенный вызов по (Z)	STACK<—PC + 1, PC^-Z
RET	Возврат из подпрограммы	PC STACK
RETI	Возврат из прерывания	PC «- STACK, I
CPSE Rd,Rr	Сравнить и пропустить команду, если равны	если (Rd = Rr), to PC<—PC + 2/3
SBRC Rr, b	Пропустить, если бит в регистре равен 0	если (Rr(b) = 0), to PC-s-PC + 2/3
SBRS Rr, b	Пропустить, если бит в регистре равен 1	если (Rr(b) = 1), to PC<—PC + 2/3
SBIC P, b	Пропустить, если бит порта равен 0	если (P(b) = 0), to PC^PC + 2/3
SBIS P, b	Пропустить, если бит порта равен 1	если (P(b) = 1), to PC<— PC + 2/3
BRBS s, к	Перейти, если флаг в SREG = 1	если (SREG(s) = 1), to PC^PC+k+1
BRBC s, к	Перейти, если флаг в SREG = 0	если (SREG(s) = 0), то PC^PC + к + 1
BREQk	Перейти, если равно	если (Z = 1), то PC«—PC + к + 1
BRNEk	Перейти, если не равно	если (Z = 0), то PC^-PC + к + 1
BRCSk	Перейти, если С = 1	если (С = 1), то РС«-РС + к + 1
BRCCk	Перейти, если С = 0	если (С = 0), то РС^РС + к + 1
BRSHk	Перейти, если больше или равно	если (С = 0), то РС<—PC + к + 1
BRLOk	Перейти, если меньше	если (С = 1), то РС^РС + к + 1
BRMIk	Перейти, если минус	если (N = 1), то РС<—PC + к + 1
BRPLk	Перейти, если плюс	если (N = 0), то PC's- PC + к + 1
1.1. Микроконтроллеры А Тх8515
27
Окончание табл. 1.8
Мнемоника	Описание команды	Операция
BRGEk	Перейти, если больше или равно (со знаком)	если (N®V = 0), то PC^PC + k+ 1
BRLTk	Перейти, если меньше (со знаком)	если (N@V = 1), то РС<—PC + к + 1
BRHSk	Перейти, если межтетрадный перенос Н = 1	если (Н = 1), то РС<—РС + к+ 1
BRHCk	Перейти, если межтетрадный перенос Н = 0	если (Н = 0), то PC <— PC + к + 1
BRTSk	Перейти, если флаг Т = 1	если (Т = 1), то PC <- PC + к + 1
BRTCk	Перейти, если флаг Т = 0	если (Т = 0), то PC <— PC + к + 1
BRVSk	Перейти, если флаг переполнения V= 1	если (V = 1), то PC <— PC + к + 1
BRVCk	Перейти, если флаг переполнения V = 0	если (V = 0), то PC <— PC + к + 1
BRIE k	Перейти, если флаг прерывания 1=1	если (1=1), то РС^-РС + к+1
BRIDk	Перейти, если флаг прерывания 1 = 0	если (I = 0), то PC <— PC + к + 1
Таблица 1.9. Операции с битами
Мнемоника	Операция	Мнемоника	Операция
SBI Р,Ь	(P,b)«- l,P=0-31	SES	S<- 1
CBI Р,Ь	(P,b) «- 0, P=0-31	CLS	s^o
BSETs	SREG(s) «- 1	SEV	V«- 1
BCLRs	SREG(s) «- 0	CLV	v^o
BST Rr,b	T <- Rr(b)	SET	T «— 1
BLD Rd,b	Rd(b) «- T	CLT	T«-0
SEC	C«- 1	SEH	H 1
CLC	C^-0	CLH	H <-0
SEN	N«— 1	NOP	Нет
CLN	N«—0	SLEEP	Режим энерго-
			сбережения
SEZ	Z <— 1		
CLZ	Z«-0	WDR	Сброс WDT
SEI	I«-1		
CLI	1^0		
28
1. Инструментальные средства практикума
Способы адресации данных в микроконтроллерах AVR
Ключевым моментом к пониманию функций, выполняемых каждой командой, помимо кода операции являются используемые командой способы адресации данных (операндов).
Микроконтроллеры AVR применяют разнообразные способы адресации данных. По количеству и способам адресации они превосходят возможности микроконтроллеров MCS-51. При том или ином способе адресации можно осуществить доступ к любой области памяти данных (регистрам общего назначения, регистрам ввода/вывода, памяти SRAM), а также Flash-памяти программ и энергонезависимой памяти данных EEPROM. При этом часто к одному и тому же объекту можно обратиться разными способами, используя для этого соответствующий вид адресации. Рассмотрим каждый из них подробнее.
Прямая регистровая адресация с одним регистром Rd. При этом способе адресации данные находятся в регистре d(Rd), адрес которого содержится непосредственно в команде (рис. 1.6, а). Примером команд, использующих этот метод адресации, являются команды для
Регистровый	Регистровый
файл	файл
Рис. 1.6. Прямая регистровая адресация одного (а) и двух (б) регистров общего назначения
работы со стеком (PUSH, POP), обмена тетрадами в регистре (SWAP), ряд команд арифметических и логических операций.
Прямая регистровая адресация с двумя регистрами Rd и Rr. Данный способ адресации применяется в командах, которые используют два регистра общего назначения: d(Rd) и r(Rr) (рис. 1.6, б). Этот вид адресации используют команды пересылки данных из регистра в регистр и большинство команд арифмети-
1.1. Микроконтроллеры АТх8515
29
ческих операций, ряд команд логических операций. При этих операциях результат операции сохраняется в регистре d (Rd).
Прямая адресация регистра ввода/вывода. Данный вид адресации используют для выполнения обмена между регистром
ввода/вывода, расположенным в адресном пространстве ввода/вывода, и одним из регистров общего назначения по командам IN и OUT (рис. 1.7).
Прямая адресация памяти данных. Данный способ адресации применяется при обращении к любой ячейке адресного пространства SRAM. Имеются всего
Рис. 1.7. Прямая адресация регистра ввода/вывода
две команды: LDS и STS, каждая длиной в два слова (32 разряда).
Первое слово содержит код операции и адрес регистра общего назначения, второе - 16-разрядный адрес ячейки, к которой направ-
лено обращение (рис. 1.8).
Косвенная адресация памяти данных. При косвенной адресации
ОЗУ данных
$0000
Рис. 1.8. Прямая адресация памяти данных
$FFFF
обращение направлено к ячейке памяти, адрес которой находится в 16-разрядном индексном регистре X, Y или Z (рис. 1.9). В роли этих регистров выступают пары регистров: R26, R27 (регистр X), R28, R29 (регистр Y) и R30, R31 (регистр Z).
Косвенная адресация памяти данных со смещением. При этом способе адрес ячейки памяти
памяти данных
определяется путем суммирования содержимого индексного регистра Y или Z с 6-разрядным смещением, задаваемым в команде (рис. 1.10). Этот способ адресации используют команды LDD (пересылка байта из ячейки памяти SRAM в регистр Rd) и STD (пересылка байта из регистра Rr в ячейку SRAM).
30
1. Инструментальные средства практикума
$0000
Рис. 1.10. Косвенная адресация памяти данных со смещением
$FFFF
Косвенная адресация памяти данных с преддекрементом. При этом способе адресации содержимое индексного регистра X, Y или Z сначала уменьшается на 1, а затем производится обращение к памяти по полученному адресу (рис. 1.11). Этот способ адресации используют команды LD (пересылка байта данных из памяти в
Рис. 1.11. Косвенная адресация с преддекрементом
регистр Rd) и ST (пересылка байта данных из регистра Rr в память), всего шесть команд - по две для каждого регистра.
Косвенная адресация памяти данных с постинкрементом. При этом способе адресации содержимое индексного регистра X, Y или Z сначала используется в качестве адреса обращения к памяти данных, а затем увеличивается на 1 (рис. 1.12). Этот способ адре
Рис. 1.12. Косвенная адресация с постинкрементом
1.1. Микроконтроллеры АТх8515
сации используют команды LD (пересылка байта данных из памяти в регистр Rd) и ST (пересылка байта данных из регистра Rr в память), всего шесть команд - по две для каждого регистра.
Косвенная адресация памяти программ. Микроконтроллеры AVR позволяют обратиться к ячейкам памяти программ для считывания констант, а в моделях семейства Mega - и для записи данных во Flash-память программ, используя механизм косвенной адресации через регистр Z. При этом старшие 15 разрядов регистра определяют адрес слова, а младший нулевой разряд - младший или старший байт слова. Если младший разряд адреса равен 0, выбирается младший байт, в противном случае выбирается старший байт (рис. 1.13). Данный вид адресации используют команды считывания из ячейки памяти в регистр RO (LPM) и записи в память из регистров R1 :R0 (SPM).
Память программ
15________________10
| Z-регистр |Д-
$000
-------------$FFF
Рис. 1.13. Косвенная адресация констант в памяти программ
Кроме простой косвенной адресации при чтении константы в регистр Rd можно применить косвенную адресацию с постинкрементом (команда LPM Rd, Z+).
Помимо команд, связанных с передачей данных, косвенная адресация может быть использована в командах косвенного перехода по адресу в регистре Z (IJMP) и косвенного вызова подпрограммы через регистр Z (ICALL) (рис. 1.14).
15__________________0
| Z-регистр |-
Память программ
$000
-------------$FFF
Рис. 1.14. Косвенная адресация памяти программ
32
1. Инструментальные средства практикума
Относительная адресация памяти программ. При этом способе адрес вычисляют путем сложения содержимого программного счетчика PC и константы к, задаваемой в команде (рис. 1.15). Относительную адресацию используют команды относительного перехода (RJMP) и относительного вызова подпрограммы (RCALL), многочисленная группа команд условных переходов.
В дополнение к перечисленным в Руководстве по микроконтроллерам способам адресации укажем еще два ее вида.
Непосредственная адресация. Данный вид адресации подразумевает указание одного из операндов (константы К) непосредственно в команде. Непосредственная адресация используется командой пересылки константы в регистр LDI, а также некоторыми командами арифметических и логических операций.
Битовая адресация. Этот вид адресации позволяет указать один из восьми битов любого из 32 регистров общего назначения или первой половины регистров ввода/вывода с номерами 0-31, а также регистра SREG. Для этого нужно указать имя регистра общего назначения Ri (i = 0...31) либо имя регистра ввода/вывода Pi (i = 0...31), либо имя SREG и номер бита b (b = 0...7). Командами SBI и CBI осуществляется установка в 1 и сброс в 0 указанного бита регистра ввода/вывода, командами BLD, BST - обмен значениями бита Т из регистра SREG и адресованного бита из регистра общего назначения. Помимо этого есть группа команд битовых операций, обеспечивающая установку и сброс битов регистра состояния SREG. При записи мнемоники команд допускается использование символических (штатных) имен регистров ввода/вывода и имен битов. Существует группа команд условного перехода, где в качестве условия используется либо значение бита в регистре общего назначения (SBRC, SBRS), либо значение бита в регистре ввода/вывода (SBIC, SBIS).
1.1. Микроконтроллеры АТх8515
33
Описание команд
Ранее приведены таблицы с описанием команд микроконтроллеров AVR, разбитые по группам. Кроме операции и операндов для каждой команды указаны признаки результата, формируемые в регистре SREG. Мнемоники команд, выполняемых только в микроконтроллерах семейства Mega, помечены *.
Группа арифметических и логических операций по составу достаточно традиционна для архитектуры 8-разрядных микроконтроллеров, за исключением микроконтроллеров семейства Mega. Так, например, в группу арифметических команд микроконтроллера ATmega8515 добавлены шесть операций умножения: беззнаковых чисел MUL, чисел со знаком MULS, беззнакового числа на число со знаком MULSU, дробных беззнаковых чисел FMUL, дробных со знаком FMULS, дробного беззнакового и дробного со знаком FMULSU.
Дробные сомножители имеют формат 1.7, их произведение -формат 1.15, где справа от точки указано число дробных разрядов. Во всех операциях умножения источниками операндов являются регистры Rd и Rr, произведение формируется в регистрах R1:RO. Во всех операциях над целыми и дробными числами исходные сомножители и формируемые произведения со знаком (-) изображаются в дополнительном коде.
Приведем ряд примеров на умножение (С = Л хВ).
MUL - умножение целых беззнаковых чисел
1)	А = 240= 1111 00002,
В = 225 = 1110 0001г,
С = 54 000 = 1101 0010 1111 00002.
MULS - умножение целых чисел со знаком
2)	Л=-10= 1111 01102,
В = + 10 = 0000 10102,
С = -100= 1111 1111 1001 11002
3)	Л =-10= 1111 01102,
В = -56 = 1100 10002,
С = +560 =000000100011 00002.
MULSU - умножение числа со знаком (А) на число без знака (В)
34
1. Инструментальные средства практикума
4)	А =-10= 1111 01102, 5= 200= 1100 10002, С= -2000 = 1111 1000 0011 00002
5)	Л = -1 = 1111 11112, В= 255 = 1111 11112, С = -255 = 1111 1111 0000 00012. FMUL - умножение дробных беззнаковых чисел
6)	А = 0,5 = 0.100 00002, 5 = 0,25 = 0.010 00002, С = 0,125 = 0.001 0000 0000 00002. FMULS - умножение дробных чисел со знаком
7)	А = -0,5 = 1.100 0000г, В = -0,25 = 1.110 0000 2, С = 0,125 = 0.001 0000 0000 00002, 8) Л = -0,5 = 1.100 00002, 5 = + 0,5 = 0.100 0000 2, С = -0,25 = 1.110 0000 0000 00002. FMULSU - умножение дроби со знаком (А) на дробь без знака (В)
9)	А = -0,5 = 1.100 00002, 5 = 0,25 = 0.010 00002, С =-0,125 = 1.111 0000 0000 00002.
Эти команды удобны при перемножении знаковых 16-разряд-ных сомножителей для получения 32-разрядного произведения. Ниже приведена программная процедура mulsl 6x16_32 перемножения целочисленных сомножителей, размещенных в регистрах г23 : г22 и г21 : г20. Образуемое произведение помещается в регистры г19 : rl8 : rl7 : г16.
Программа 1.1
mulsl6x16_32:	; г19:г18:г17:г16 = г23:г22 * г21:г20
clr г2 muls г23, г21	; (знаковое) Ah * (знаковое) Bh
movw rl9:rl8, rl:r0 mul r22, r20	; Al * Bl
movw rl7:rl6, rl:r0 mulsu r23, r20	; (знаковое) Ah * Bl
1.1. Микроконтроллеры А Тх8515
35
sbc г19, г2
add г17, гО adc rl8, rl adc г19, г2 mulsu г21л г22	; (знаковое) Bh * Al
sbc rl9, r2 add rl7, rO adc rl8, rl adc rl9, r2 ret
Аналогично строится процедура перемножения fmulsl6xl6_32 знаковых 16-разрядных дробных для получения 32-разрядного произведения. Здесь при перемножении 8-разрядных компонентов дробных сомножителей дополнительно выполняется необходимое форматирование промежуточных результатов путем сдвига частичных произведений влево.
Программа 1.2 fmulsl6xl6_32:
; rl9:rl8:rl7:rl6 = ( r23:r22 * r21:r20 )«1 clr г2 fmuls г23, г21	;( (знаковое) ah * (знаковое) bh) << 1
movw rl9:rl8, rl:rO fmul r22, r20	;(al * bl) « 1
adc rl8, r2 movw rl7:rl6, rl:rO fmulsu r23, r20	;((знаковое)ah * bl) << 1
sbc rl9, r2 add rl7, rO adc rl8, rl adc rl9, r2 fmulsu r21, r22	;((знаковое)bh * al) « 1
sbc rl9, r2 add rl7, rO adc rl8, rl adc rl9, r2 ret
При выполнении операций сложения/вычитания приемником результата является один из регистров общего назначения, в котором до операции находится один из операндов. Таким образом,
36
1. Инструментальные средства практикума
можно говорить о реализации АЛУ аккумуляторного типа по отношению к любому регистру общего назначения (сравните: микроконтроллеры с ядром MCS-51 имеют всего лишь один аккумулятор, что, безусловно, ухудшает эффективность обработки данных и ведет к снижению производительности в целом). Особенностью системы команд микроконтроллеров AVR является отсутствие команды двоично-десятичной коррекции.
Команды пересылки можно использовать для передачи данных из регистра в регистр, для пересылок между регистрами и косвенно адресуемыми ячейками адресного пространства SRAM, регистрами ввода/вывода и регистрами общего назначения, для сохранения и извлечения данных из стека, чтения констант из Flash-памяти программ и даже записи во Flash-память (в модели ATmega8515). Следует обратить внимание, что непосредственная загрузка константы в регистры общего назначения первой половины (R0...R15) невозможна. Для этого необходимо предварительно загрузить константу в один из регистров второй половины (R16...R31), а затем переслать содержимое вспомогательного регистра в регистр первой половины.
Широко представлена группа команд передачи управления. Помимо традиционных команд безусловной и условной передачи управления по флагу имеются команды косвенного перехода и косвенного вызова подпрограмм. Команды условных переходов делятся на два типа. Команды первого типа при выполнении условия обеспечивают переход по адресу, вычисляемому как сумма (PC + k + 1). При невыполнении условия происходит переход к следующей команде программы по адресу (PC +1). Команды второго типа при выполнении условия обеспечивают переход к команде, следующей за очередной, т. е. по адресу (PC + 2), если длина очередной команды составляет одно слово, или по адресу (PC + 3), если длина очередной команды составляет два слова. Если условие не выполняется, происходит переход к следующей команде по адресу (PC + 1). Такое разнообразие команд управления способствует эффективной работе компиляторов программ, написанных на языке Си.
В битовых операциях следует обратить внимание, что все операции пересылки битов в области регистров общего назначения осуществляются только через вспомогательный бит Т регистра состояния SREG. В области регистров ввода/вывода биты можно изменять только путем установки 1 или 0. Программно путем установки 1 или 0 можно изменять состояния флагов регистра со
1.1. Микроконтроллеры АТх8515
37
стояния SREG. В эту группу включены также операции WDR (сброс сторожевого таймера), SLEEP (переход в энергосберегающий режим), пустая операция NOP.
Выполнение команд
В микроконтроллерах AVR используется конвейерная обработка команд. Работу конвейера иллюстрирует рис. 1.16. Во время первого такта Т1 происходит выборка 1-й команды и декодирование кода операции. Во время второго такта Т2 эта команда выполняется и параллельно происходит выборка и декодирование 2-й команды. В дальнейшем выборка очередной команды совмещается с исполнением ранее выбранной команды. Таким образом, фактическое время выполнения каждой команды составляет один машинный такт. Нарушение работы конвейера происходит при выполнении команд условного перехода, а также команд типа Test&Skip (проверка и пропуск следующей команды, если результат проверки дал положительный результат). При выполнении команд условного перехода в случае истинности проверяемого условия программа продолжается с указанного адреса. Однако на конвейер уже поступила следующая по порядку команда. Поэтому время выполнения команды перехода увеличивается на один машинный такт, необходимый для выборки команды по указанному адресу. Аналогичная ситуация имеет место при выполнении команд тестирования с пропуском следующей команды. Задержка выполнения команды может составить два или три такта в зависимости от пропускаемой команды. Во всех случаях, когда происходит замещение содержимого программного счетчика, происходит «разрыв» в работе конвейера, продолжающийся от двух до четырех машинных тактов в зависимости от типа команды.
:	Т1 :	Т2 ; ТЗ ; Т4
CLKcpu j—-----------------V_J------------------V_
Выборка 1-й команды	j	i__________!________
Выборка 2-й команды,	;	; ________!	;
исполнение 1-й команды —I-------К	!	>	I--------
Выборка 3-й команды,	!	!	:	у
исполнение 2-й команды ~|
Выборка 4-й команды,	!________!__________!__________Н--------
исполнение 3-й команды	|	|	К
Рис. 1.16. Выполнение команд в конвейере AVR
38
1. Инструментальные средства практикума
Большинство команд обработки данных из группы логических и арифметических операций выполняется за один машинный такт. Исключение составляют арифметические команды, оперирующие с двухбайтовыми операндами и команды умножения. Битовые операции выполняются за один такт. Команды пересылки и команды передачи управления требуют для выполнения от одного до трех тактов.
Директивы Ассемблера
При написании программ на языке Ассемблер используются директивы, которые указывают компилятору положение программы в памяти, определяют макросы, инициализируют память и др. Список директив и их описание приведен в табл. 1.10. Запись всех директив начинается с точки. Кратко перечислим выполняемые директивами функции в каждом из сегментов.
Таблица 1.10. Список директив
Директива	Описание
.BYTE .CSEG .DB .DEF .DEVICE .DSEG .DW .ENDM, .ENDMACRO .EQU .ESEG .EXIT .INCLUDE .LIST .LISTMAC .MACRO .NOLIST .ORG .SET	Резервировать байты в ОЗУ Сегмент программы Определить байт - константу во Flash-памяти или EEPROM Назначить регистру символическое имя Определяет устройство, для которого компилируется программа Сегмент данных Определяет слово во Flash-памяти или EEPROM Конец макроса Установить постоянное выражение Сегмент EEPROM Выход из файла Вложить другой файл Включить генерацию листинга Включить разворачивание макросов в листинге Начало макроса Выключить генерацию листинга Установить положение в сегменте Установить для переменной эквивалентное выражение
1.1. Микроконтроллеры АТх8515
39
Сегмент программы открывается директивой .CSEG. Если программа начинается с этого сегмента, директива может отсутствовать. В сегменте программы с помощью директивы .ORG можно указать начало сегмента.
Директива .DB в сегменте определяет один байт или группу байтов, констант, записываемых во Flash-память. Директива .DW определяет слово или группу слов, записываемых в память в качестве констант. Начало записи констант определяется меткой, стоящей перед соответствующей директивой. Перечисляемые константы разделяются запятыми.
Директива .DEF присваивает регистру символическое имя. Директивы .EQU, .SET присваивают значение имени. Имя, которому присвоено значение директивой .EQU, не может быть переназначено, и значение не может быть изменено. Имя, присвоенное директивой .SET, может быть изменено другой директивой .SET.
Директива .DEVICE определяет тип целевого микроконтроллера, который будет использован для выполнения программы. Наличие этой директивы подключает средства контроля инструкций программы по отношению к физическому устройству, предупреждая о невозможности выполнения некоторых инструкций, размеров используемой памяти и др.
Директива .INCLUDE с именем файла используется для включения в текст программы другого файла.
Директивы .MACRO и .ENDMACRO обрамляют макроопределение. Макроопределение может иметь до 10 параметров с фиксированными именами @0,..., @9. При вызове макроопределения параметры задают в виде списка в порядке нумерации.
Сегмент данных начинается директивой .DSEG. В сегменте могут быть использованы директивы .ORG и .BYTE. Директива .BYTE определяет количество байтов, к которым будет производиться обращение при выполнении программы. Резервируемая область начинается по адресу, определяемому меткой перед директивой.
Сегмент типа EEPROM начинается директивой .ESEG. В сегменте могут быть использованы директивы .ORG, .DB, .DW. Директива .DB в сегменте определяет один или группу байтов, записываемых в EEPROM. Директива .DW определяет слово или группу слов, записываемых в память EEPROM парами по 2 байта. Начало записи байтов и слов определяется меткой, стоящей перед соответствующей директивой.
Директивы .LIST, .NOLIST, .LISTMAC используют для управления выводом листинга.
40
1. Инструментальные средства практикума
Выражения
При записи команд на Ассемблере могут использоваться выражения, по которым в процессе ассемблирования программы вычисляются значения. Операндами выражений могут быть:
-	числа (десятичные, шестнадцатеричные и двоичные);
-	метки;
-	коды символов ASCII ('А') и строки ASCII;
-	символические имена, представляющие переменные, определенные директивой .SET, и константы, определенные директивой .EQU;
-	текущее значение счетчика команд (PC).
Для обозначения шестнадцатеричных чисел используют указатели Ох или $ (Oxla, Oxff, $ff), для двоичных чисел - 0Ь (ОЬОООО1 111, 0Ь11111111), десятичные числа не имеют указателей (255, 0).
Помимо операндов в выражения могут входить функции, например:
LOW (выражение) - возвращает младший байт выражения;
HIGH (выражение) - возвращает старший байт выражения; ЕХР2 (N) - возвращает 2N;
LOG2 (N) - возвращает целую часть logjN.
При записи выражений можно использовать арифметические, логические и операции отношения. Группу арифметических операций образуют сложение двух чисел или выражений (N + М), вычитание (N - М), умножение (N*M), деление (N/М), изменение знака числа (-N). Группу логических операций образуют инверсия (~N), побитовое И (N&M), побитовое ИЛИ (N | М), побитовое исключающее ИЛИ (NCIM), сдвиг влево (N«M - сдвинуть N влево на М разрядов), сдвиг вправо (N»M - сдвинуть N вправо на М разрядов). Операции отношений:
-	логическое отрицание (!N - возвращает 1, если N = 0, и 0, если N Ф 0);
-	меньше (N < М - возвращает 1, если N < М, и 0, если N > М);
-	больше (N > М - возвращает 1, если выражение N > М, и 0, если N < М);
-	меньше или равно (N <= М - возвращает 1, если N <= М, и 0, если N > М);
-	больше или равно (N >= М - возвращает 1, если N >= М, и 0, если N < М);
1.2. Интегрированная отладочная среда A VR STUDIO 4
41
-	равно (N = М - возвращает 1, если N = М, и 0, если N М);
-	не равно (N != М - возвращает 1, если N * М, и 0, если N = M);
-	логическое И (N&&M - возвращает 1, если N *0 иМ # О, иначе 0);
-	логическое ИЛИ (N||M - возвращает 1, если N = 0 и М = 0, иначе 0).
Для указания очередности операций можно использовать круглые скобки.
1.2. ИНТЕГРИРОВАННАЯ ОТЛАДОЧНАЯ СРЕДА AVR STUDIO 4
Широкое применение микроконтроллеров в мире способствовало появлению на рынке программных продуктов сопровождения разработки приложений от различных фирм-производителей. На смену отдельным программам (ассемблерам, компиляторам, отладчикам и др.) пришли интегрированные системы разработки приложений (IDE - Integrated Development Environment), разработанные под Windows, с удобным пользовательским интерфейсом, множеством функций, начиная от редактирования программ и заканчивая программированием микроконтроллеров.
AVR Studio - это интегрированная отладочная среда разработки приложений для 8-разрядных RISC - микроконтроллеров семейств AVR (Tiny, Classic, Mega). Версия AVR Studio 4 объединяет средства управления проектами, текстовый редактор, Ассемблер и отладчик программ на языках Си и Ассемблер. Таким образом, AVR Studio 4 поддерживает проектировщика на стадиях разработки, отладки и верификации программного обеспечения. Кроме того, AVR Studio 4 поддерживает аппаратную платформу STK500, которая позволяет программировать все устройства AVR, и внутрисхемные эмуляторы ICE40, ICE50, ICE200, JTAG ICE. AVR Studio 4 распространяется бесплатно и доступна на сайте производителя http://www.atmel.com.
AVR Studio 4 состоит из нескольких панелей и модулей, каждый из которых выполняет часть общей задачи. Внешний вид программы в режиме редактора показан на рис. 1.17.
42
1. Инструментальные средства практикума
П Не Pmied hdit View Tools Debug Window
ff x iiiill
 test!
- _j A^emble
0 to.Tl.nsm
- J Output
0 Wd map
ox q a 0 ij 0
пн tj
;;«««Инициализация**» ENIT
\sl.T out-lei it
Т,Г ?• TTCTl PT
req led OhFE • ' , ' w ‘	; J
;C=1	\	1|
T = 1 - флаг» напраВ|| ; инициализация 8ыВ|| ; порта PB на 8ы6о|| ; погасижь СД |Т Жиициализация 0-о|| ; порта PD на ВВод|| ; Включение поджязи|| .:  резисторов nopiiWj|
temp
DDRB,temp
FORTD temp t f=mp
DDHL- temp teap 0x0 J
FORTE' temp

Ww hp<e
J.y 0 , .

lllllll

Ph C:\Pt ogi am FilesWn d'i, A VP ГсюЦД л 5hjd©4^e5tlV.estl .asm
Constar Ее (dw/db): 0 words
Unused : 0 words
Total : 36 words
Assembly comuluto with rm Hums.
AW63515
Рис. 1.17. Графический интерфейс AVR Studio 4
Создание программ в среде AVR Studio 4 происходит в виде проектов, каждый из которых имеет файл, сохраняющий информацию о проекте и входящих в него файлах, установки Ассемблера, пользовательские настройки и т. д.
Редактор служит для написания программного кода, он полнофункционален, имеет подсветку синтаксиса, которая может быть изменена и дополнена пользователем. Окно редактора также используется при отладке, при этом точки возможного программного останова могут быть размещены на левой границе поля.
В панели вывода Output отображается текущая и служебная информация среды разработки. Щелкнув по ярлыку, можно выбрать то или иное окно:
•	Build. Окно сообщений о процессе и результатах компи-ляции/трансляции.
•	Messages. AVR Studio 4 составляют множество объектов, инкапсулированных по технологии Microsoft DCOM. Некоторые из них
1.2. Интегрированная отладочная среда A VR STUDIO 4
43
не имеют графического интерфейса. Messages - это общее окно предоставления сообщений пользователю от всех модулей приложения. Сообщения кодируются цветом. Большинство составляют простые сообщения без значимого приоритета. Они не выделяются цветом. Предупреждения о потенциальных проблемах выделяются желтым цветом, ошибки - красным. Для всех сообщений может быть записано время прихода (опция timestamp контекстного меню). Имеется функция фильтра, позволяющая включать/выключать сообщения разных видов.
•	Find in Files. AVR Studio 4 имеет функцию встроенного поиска в файлах. В окне отображается информация о результатах поиска.
•	Breakpoints. Список активных точек возможного прерывания программы во всех модулях программы пользователя. Точки могут быть вклю
trV яйймйййи
I "Sr	«
= О
Fingram EatrAef
I	S lad, Earner
Cjcfe Counter
I	УчадкЬяг
Ziegstar
I	SlnpWsteh
I -	Ц TO AX® 8515
J	4	AI-MGGJX'MPARMOR
cm
-f Й EEPROM
+ E.KTERM^LJNrEflRlJF'I
.	4 PORTA
4 ф FORTH
. ?g PORTC
-t in FDRTD
4	5 Pi
4 || TIMERjXiUNTEFLO
:	4	i	TIMERjxhjntefli
I	4	uART
у	4.	/J	WATCHDOG
! e • Щ i/oj СЭ
Рис. 1.18. Вкладка регистров ввода/вывода
[, выключены и удалены в
этом окне.
Панель рабочего пространства Workspace предназначена для помощи при отладке написанного кода и имеет три вкладки:
•	Project. Окно со списком файлов, составляющих проект. Если для отладки был открыт объектный файл, то окно покажет имя загруженного файла, а также исходные файлы, с которыми связан данный.
•	I/O. Окно ввода/вывода содержит несколько секций (рис. 1.18):
Регистры. Микроконтроллеры AVR имеют 32 регистра общего назначения (РОН), разбитые на две равные группы 0-15 и 16-31, которые могут свободно использоваться программистом и обновляться во время прерывания процесса симуляции. Если состояние регистра изменилось относительно последнего прерывания, он выделяется цветом (по умолчанию красным).
44
1. Инструментальные средства практикума
Процессор. В секцию входят регистры Program Counter (программый счетчик), Stack Pointer (указатель стека), Cycle Counter (счетчик циклов), Stop Watch (системные часы) и др. Содержимое регистров процессора также обновляется при прерывании симуляции.
Регистры ввода/вывода I/O. Микроконтроллеры AVRразличают по количеству и составу встроенных периферийных устройств. Все периферийные устройства имеют 8- или 16-разряд-ные регистры, образующие группу регистров ввода/вывода, которые доступны для чтения и записи. В окне I/O отображаются логически сгруппированные управляющие регистры и регистры данных периферийных устройств, что позволяет осуществить полный контроль периферийного устройства в процессе отладки. Список устройств, отображаемых в одноименной секции I/O, соответствует модели выбранного микроконтроллера и изменяется при переходе от одной модели к другой.
•	Info. Окно содержит:
-	список всех прерываний микроконтроллера с соответствующими адресами (векторы прерываний);
-	список типов корпусов, в которых выпускается микроконтроллер, с указанием номеров и наименований выводов;
-	список регистров ввода/вывода с их адресами.
Для контроля работы программы в процессе отладки можно открыть ряд окон в меню View.
-	окно Watch используется для вывода значений переменных при отладке программ, необходимо мышью «перетащить» переменную из окна программы в данное окно. Если это массив или иная структурная переменная, то рядом появится символ +, раскрывающийся при щелчке;
-	окно памяти Memory может представлять содержимое различных видов памяти микроконтроллера: памяти данных (Data), энергонезависимой памяти (Eeprom), регистров ввода/вывода (I/O), памяти программы (Program), регистров общего назначения (Register). При отладке программы можно открыть три окна памяти;
-	окно Register служит для отображения содержимого всех регистров регистрового файла.
Создание проекта
AVR Assembler - это удобный инструмент для написания небольших программ. После компиляции сразу получается выполняемый код, стадия компоновки отсутствует. Для начала работы при
1.2. Интегрированная отладочная среда A VR STUDIO 4
45
запуске AVR Studio нужно нажать кнопку Create new project, в проектном диалоговом окне выбрать AVR Assembler, задать имя проекта и рабочую папку для него, затем нажать кнопку Finish. Можно сразу указать модель микроконтроллера, для которого разрабатывается программа, нажав Next и выбрав платформу для отладки и тип устройства. Создается проектный файл, файл *.asm будет доступен в окне редактора для ввода программы.
При написании программы на языке AVR Assembler можно воспользоваться файлом помощи, где перечислены и объяснены все инструкции и директивы. Обратиться к нему можно, выполнив команды из меню команд AVR Studio 4: Help/AVR Tools User Guide. В открывающемся окне Html Help следует выполнить A VR Assembler/Parts и указать тип микроконтроллера. Подробное описание каждой из команд можно найти в разделе AVR Assembler! Instructions. Также доступна контекстная помощь при нажатии клавиши F1, дающая информацию о синтаксисе команды, расположенной рядом с курсором.
Предполагается включение в разрабатываемый код директивой .include файла *def.inc, по умолчанию расположенного в папке \Program Files\Atmel\AVR Tools\AvrAssembler\Appnotes. В подобных файлах для каждого устройства AVR определены мнемоники всех внутренних регистров, битов, векторов прерываний и т. п., что упрощает процесс написания программы для конкретного микроконтроллера.
Для трансляции программы необходимо нажать клавишу F7 или выбрать пункт меню Project/ Build. При использовании директивы .device с указанием типа микроконтроллера, для которого создается программа, транслятор выполняет проверку программы на наличие в тексте инструкций, недопустимых для выбранного микроконтроллера. При отсутствии директивы такая проверка не проводится. Результаты трансляции будут показаны в окне Build панели вывода.
Если трансляция прошла без ошибок, выводится сообщение, помеченное зеленым кружком и указывающее, что ошибок нет и созданы файлы с расширениями .hex и .obj. В противном случае список ошибок помечается красными кружками. Для исправления ошибки необходимо дважды щелкнуть левой клавишей мыши по строке сообщения. В соответствующей строке программы появится синяя стрелка и текстовый курсор. При трансляции можно получить файл определений программы (строки с директивами .def и .equ) с расширением .тар и файл листинга с расширением
46
1. Инструментальные средства практикума
.1st, включающий команды в символьном и шестнадцатеричном коде. Для этого необходимо выполнить команды Project/ A VR Assembler Setup и в открывающемся окне установить соответствующие флажки.
Сама по себе успешная трансляция говорит лишь о том, что программа не содержит синтаксических ошибок. Отладка же в симуляторе способна ответить прежде всего на такие вопросы: действительно ли алгоритм выполняется так, как это было задумано, и каково время выполнения той или иной процедуры. До начала отладки можно выбрать или изменить платформу для отладки, выполнив команды меню Debug/Select Platform and Devise и выбрав A VR Simulator и тип устройства.
Запускается отладчик командой меню Debug/Start Debugging. Эта команда будет доступна только в случае успешной трансляции программы.
Выполнив команду меню Debug/AVR Simulator Options, в окне Device Selection указываем частоту работы микроконтроллера, а в окне Stimuli and Logging - метод работы с портами микроконтроллера.
Возможен автоматический ввод данных в порт (stimuli) из файла с расширением .sti и(или) протоколирование (logging) вывода. В обоих случаях данные представляются в виде
номер цикла', данные на ввод/вывод в шестнадцатеричном коде. Протоколируя вывод, указываем имя порта, устанавливаем флаг То screen для вывода на экран. Затем нажимаем кнопки Add Entry и ОК.
Подготовительные операции закончены. Исходное состояние: все регистры микроконтроллера в окне НО сброшены в 0, желтая стрелка в окне редактора указывает на первую команду программы. Используя опции меню Debug, выполняем отладку в одном из выбранных режимов: пошаговом, с контрольными точками, автоматическом. Подробно методика отладки программ в среде AVR Studio 4 описана в [7].
1.3. СТАРТОВЫЙ НАБОР STK500 ФИРМЫ ATMEL
STK500 представляет собой универсальный стартовый набор разработчика, позволяющий создавать приложения совместно с интегрированной средой проектирования AVR Studio 4.
Набор STK500 поставляется с микроконтроллером АТх8515, но поддерживает целый ряд других микроконтроллеров AVR, для чего служат соответствующие панели для установки и средства
1.3. Стартовый набор STK500 фирмы Atmel
47
коммуникации. Исходные установки перемычек обеспечивают работу микроконтроллера совместно с тактовым генератором и стабилизатором напряжения, установленным на плате STK500. Набор также имеет широко используемые средства ввода и индикации, интерфейс RS-232, средства расширения для подключения внешних устройств.
Описание аппаратных средств
В состав отладочной платы STK500 (рис. 1.19) входят:
-	стабилизированный источник питания с входным напряжением 10... 15В и программно управляемым выходным напряжением;
-	восемь кнопок общего назначения;
-	восемь светодиодов общего назначения;
-	разъемы всех портов ввода/вывода микроконтроллера;
-	8-, 20-, 28-, 40-выводные панели для установки DIP-корпусов микроконтроллеров AVR;
-	интерфейс RS-232 для программирования и управления из программы AVR Studio 4, установленной на персональном компьютере;
-	дополнительный порт RS-232 общего назначения;
-	разъемы расширения для подключения внешних модулей при макетировании;
-	память DataFlash емкостью 2 Мбит для энергонезависимого хранения данных;
-	средства поддержки параллельного и последовательного программирования повышенным напряжением всех AVR-микроконтроллеров;
-	средства последовательного внутрисистемного программирования (ISP) всех AVR-микроконтроллеров;
-	внутрисистемный программатор для программирования микроконтроллера непосредственно в целевом приложении.
Светодиоды и кнопки общего назначения. В набор STK500 входит восемь желтых светодиодов и восемь кнопок без фиксации. Светодиоды и кнопки электрически отделены от остальной части платы и подключены к собственным разъемам. Они могут быть подключены к AVR-микроконтроллерам 10-проводными шлейфами через разъемы портов ввода/вывода.
Кнопки
Разъем DataFlash
Индикатор питания
Разъем для светодиодов
Кнопка сброса МК
Разъем для КНОПО]
Разъем
RS-232
рг	Разъем для
Разъемы портов	плат РасшиРения
\ контроллеров	/ Пере]
коммуникационный
Светодиоды
Выключатель " питания
Разъемы параллельного программирования
Разъем RS232 для программирования
Статусный светодиод
Разъем для Разъемы для	Разъем Кнопка
плат расширения внутрисистемного программатора Program программирования
_ Разъем питания
Рис. 1.19. Компоненты STK500
1.3. Стартовый набор STK500 фирмы Atmel
49
Схема одного разряда индикации изображена на рис. 1.20, а. При поступлении на вывод LEDn сигнала с низким уровнем напряжения (логический 0) светодиод светится, а сигнала с высоким уровнем напряжения (логическая 1) - светодиод гаснет.
Схема подключения кнопки изображена на рис. 1.20, б. При нажатии на кнопку на выводе SWn отмечается низкий уровень напряжения (GND), а при отпускании - высокий (VTG). Рабочий диапазон напряжения VTG =1,8.. .6,0 В.
VTG
|^| 10 кОм
150 Ом
—О* SWn
б
Рис. 1.20. Схема включения светодиода (а) и кнопки (б)
Выводы светодиодов LEDx и кнопок SWx (х = 0...7) соединены с соответствующими контактами разъемов SWITCHS и LEDS. Следует иметь в виду, что контакты 9 и 10 разъемов использованы для сигналов GND и VTG. Поэтому необходимо соблюдать соединение шлейфами одноименных выводов разъемов индикаторов и кнопок с портами микроконтроллеров (шлейф не должен перекручиваться). С этой целью в шлейфе красным цветом выделена одна из линий, которая должна соединять одноименные выводы разъемов (например, LED0 и РхО).
Особенности работы светодиодов и кнопок необходимо учитывать при программировании портовых операций микроконтроллеров, связанных с обращением к светодиодам и кнопкам.
Разъемы портов. Любой порт ввода/вывода AVR-микроконтроллера может быть подключен к светодиодам и кнопкам с помощью 10-проводного шлейфа. На разъемы в дополнение к линиям портов выведены напряжение питания целевого микроконтроллера VTG (VCC) и общий провод GND.
Расположение выводов разъемов и их соответствие линиям портов ввода/вывода показано на рис. 1.21, а.
50
1. Инструментальные средства практикума
1 2
РхО	D О	Рх1
Рх2	ОО	РхЗ
Рх4	оо	Рх5
Рхб	оо	Рх7
GND	о о	VTG
PORTx
1 2
РЕО	ИО	РЕ1
РЕ2	оо	RST
REF	оо	GND
ХТ1	оо	ХТ2
GND	оо	VTG
PORTE/AUX б
Рис. 1.21. Выводы разъемов портов Рх (х = А, В, С, D) и РЕ микроконтроллера
Разъем порта Е (PORTE/AUX) содержит специальные сигналы и функции в дополнение к линиям порта РЕ. Расположение и назначение выводов этого разъема показано на рис. 1.21, б.
Интерфейс RS-232 для пользователя. STK500 содержит два порта RS-232. Один порт используется для связи с AVR Studio. Другой можно использовать для связи микроконтроллера, установленного на плате, с компьютером через его последовательный порт RS-232 (COM-порт). Для этого два вывода канала UART микроконтроллера необходимо физически соединить с входами порта RS-232, выведенными на 2-штырьковый разъем RS232 SPARE. Порт RS-232 на плате STK содержит схему преобразования уровней сигналов интерфейса.
Flash-память данных DataFlash. В состав платы STK500 входит микросхема Flash-памяти AT45D021 емкостью 2 Мбит из семейства DataFlash, которая может быть использована для энергонезависимого хранения данных. DataFlash - Flash-память с последовательным программированием через SPI-интерфейс, может быть подключена к линиям порта РВ микроконтроллера. Для этого необходимо использовать 4-штырьковый разъем с маркировкой DATAFLASH, который связан с SPI-интерфейсом DataFlash. Для соединения разъема DATAFLASH с линиями порта РВ необходимо соединить PB6-SO, PB7-SCK, PB4-/CS, PB5-SI.
Секция целевых панелей. Модуль программирования состоит из восьми панелей в центре платы. В одну из них необходимо установить целевой AVR-микроконтроллер для программирования и дальнейшего использования в приложении. Для Flash-памяти AVR-микроконтроллеров гарантированная износостойкость составляет 10 000 циклов программирования.
Секция перемычек и программирования. Управляющий микроконтроллер и восемь перемычек определяют работу данного стартового набора. В поставке эти перемычки установлены в исходное положение.
1.3. Стартовый набор STK500 фирмы Atmel
51
После установки микроконтроллера в панель может быть выполнено программирование, для чего необходимо использовать AVR Studio 4 и один из предлагаемых методов:
-	внутрисистемное программирование при нормальном напряжении питания. Этот метод используется как основной при проведении лабораторных работ;
-	программирование повышенным напряжением, при котором напряжение питания всегда равно 5 В. Допускается подключение цепей VTARGET, RESET, XTAL1 и AREF к секции панелей.
Подробное описание каждого метода программирования приведено в руководстве [1].
Прочие аппаратные компоненты. STK500 имеет два разъема расширения, установленные по обе стороны от секции целевых панелей. Все сигналы портов ввода/вывода AVR-микроконтрол-лера, сигналы программирования и управляющие присутствуют на выводах этих разъемов. Разъемы расширения позволяют легко подключить макеты приложений к STK500.
STK500 имеет две кнопки специального назначения и три светодиода для индикации состояния.
Нажатие на кнопку RESET приводит к сбросу целевого микроконтроллера.
Новые версии AVR Studio 4 способны обновить программу управляющего микроконтроллера STK500. При обнаружении старой версии программы STK500 AVR Studio обновит Flash-память управляющего микроконтроллера. Для выполнения этой функции пользователю необходимо нажать на кнопку PROGRAM после подачи напряжения питания на STK500.
Основной индикатор напряжения питания - красный светодиод - непосредственно подключен к основному источнику питания STK500. Данный индикатор должен непрерывно светиться после подачи питания на STK500 переключателем POWER.
Индикатор целевого напряжения - светодиод, связанный с линией питания VCC (VTG) целевого микроконтроллера. Индикатор непрерывно светится при наличии напряжения питания на целевых панелях микроконтроллеров.
Статусный светодиод трехцветный. При программировании он желтый, после успешного завершения программирования становится зеленым. Красный цвет показывает, что программирование было прервано. При программировании статусный светодиод последовательно изменяет свое состояние от красного через желтый к зеленому для индикации готовности целевого микроконтроллера.
52
1. Инструментальные средства практикума
1.4. ИНТЕРФЕЙС STK500 В AVR STUDIO 4 И ПРОГРАММИРОВАНИЕ МИКРОКОНТРОЛЛЕРА
Интерфейс STK500 в AVR Studio 4
В качестве программного приложения для связи с платой STK500 используется AVR Studio 4. Выполнение команды Tools/ STK500 из меню AVR Studio приводит к открытию окна пользовательского интерфейса STK500, показанного на рис. 1.22.
|АГ 9058615	|||
|м1^^
Рис. 1.22. Окно программирования пользовательского интерфейса STK500
1.4. Интерфейс STK500 в AVR Studio 4...
53
Пользовательский интерфейс STK500 выполняет функции управления платой STK500. Доступные настройки разделены на шесть окон, каждое из которых открывается щелчком на соответствующей вкладке. В зависимости от выбранного типа микроконтроллера определяется доступный набор функций для выбора и установки. Недоступные функции окрашиваются серым цветом.
Установки окна Program (программирование). Окно программирования разделено на пять областей.
В поле программируемого устройства Device из раскрывающегося списка необходимо выбрать тип целевого микроконтроллера. Кнопка Erase Device осуществляет стирание памяти микроконтроллера (Flash и EEPROM).
В поле Programming Mode задается режим программирования. Установка флажка Erase Device Before Programming активизирует полезную функцию стирания памяти программ перед программированием, а при установке флажка Verify Device After Programming STK500 будет выполнять проверку правильности записанной информации не только во Flash-память, но и в EEPROM.
Поле программирования памяти Flash. Если необходимый hex-файл хранится отдельно, используется кнопка Input HEX File (входной hex-файл). После нажатия указывается путь к файлу и его имя. Файл должен быть создан в формате Intel-hex или extended Intel-hex.
Поле программирования EEPROM. Если необходимый hex-файл хранится отдельно, используется кнопка Input HEX File (входной hex-файл). После нажатия указывается путь к файлу и его имя. Файл должен быть создан в формате Intel-hex или extended Intel-hex.
Поле истории. Поле истории находится внизу окна пользовательского интерфейса STK500. В нем отображается диалог между AVR Studio 4 и STK500. При выполнении каждой команды содержимое данного поля обновляется.
Окно Fuses установки битов конфигурации. В окне Fuses представлены доступные для выбранного типа микроконтроллера конфигурационные биты. Детальная информация о доступных конфигурационных битах в различных режимах программирования и их назначении приведена в документации на соответствующий микроконтроллер.
Окно LockBits установки битов защиты программы. Окно LockBits показывает, какие режимы защиты программы доступны для выбора при заданном типе микроконтроллера. Все биты защиты доступны как в режиме ISP-программирования, так и в режиме
54
1. Инструментальные средства практикума
программирования повышенным напряжением. Режим защиты задается комбинацией нескольких битов защиты.
Окно прочих установок Advanced. Окно Advanced представляет собой два поля для идентификации параметров микроконтроллера, не вошедших в предыдущие окна.
Поле сигнатурных байтов Signature Bytes. Нажатие на кнопку считывания сигнатуры Read Signature приводит к считыванию из микроконтроллера и отображению сигнатурных байтов. Сигнатурные байты используют для идентификации микросхемы и ее производителя. После считывания сигнатуры программа проверяет ее на соответствие выбранному типу микроконтроллера.
Поле калибровочного байта генератора Oscillator Calibration Byte. Калибровочный байт записывается в микроконтроллер на стадии производства, поэтому доступен только для чтения. Он используется в программе при записи в регистр OSCCAL для подстройки номинальной частоты встроенного RC-генератора.
Считывание калибровочного байта. Нажатие на кнопку Read Cal. Byte приводит к отображению на экране его значения в текстовом поле Value. Если данная опция выделена серым цветом, то это означает, что в выбранном микроконтроллере нет встроенного подстраиваемого RC-генератора.
Запись калибровочного байта. Поскольку значение калибровочного байта невозможно определить автоматически при выполнении программы, пользователь должен вручную записать его, предварительно указав адрес в памяти Flash или EEPROM. Адрес задается в текстовом поле Write Address. С помощью переключателя Flash, Еергот выбирается получатель данных, а затем нажимается кнопка Write to Memory для записи калибровочного байта по указанному адресу.
Окно настроек платы Board. В окне Board (рис. 1.23) можно изменить рабочие условия на плате STK500. Для изменения доступны следующие параметры: VTARGET, AREF и частота генератора.
Интерфейс задания параметров очень гибкий и позволяет задать рабочие условия, выходящие за рамки рекомендуемых для микроконтроллера параметров. Делать этого не следует, чтобы не вывести из строя используемый микроконтроллер. Информация о рекомендуемых рабочих условиях приведена в документации для каждого типа микроконтроллера.
1.4. Интерфейс STK500 в AVR Studio 4...
55
’ М" ' XX77 ,	":гг:
7ТзМ: - ММ ММ
|М1^МДМШ1|^^МММММИ1|М|1М^^^^М|1^^МИ
ОМ"гМ Сххк
зтммсх:;. о:: змЧ ,^г^: м ;;
ММ	М ММ 77
ШХМХЖХХХХХШВВШХ
Пс1©' The iSP f^queecy ххМ ее :ess -h?e 1 '•- M Uee; cGM
'He- 572, Sx ефг. Cxi J Se. •re:r. dhi-
Gettea recedes . H'V' 37 S’7! Hep- /42. €’;? ^r^-- 57 OK MM VMRGET. 507 -GehegARELP.M .07
:-3eM,c сМзР'рееМее. HM0L0M02 37-7M Ox	;
Рис. 1.23. Окно управления платой
Поле настроек генератора Oscillator. Плата STK500 использует схему программируемого генератора, которая формирует широкий диапазон тактовых частот для целевого микроконтроллера. Ввиду того что генерировать сигнал с произвольно заданным значением частоты невозможно, пользовательский интерфейс STK500 позволяет вычислить ближайшую доступную частоту при введении желаемой, что отображается в текстовом поле Closest Attainable Vol-ue. Из раскрывающегося списка можно выбрать фиксированные частоты 32,7 кГц, 1,23 1,84, 3,69 МГц (максимальная частота) или вообще остановить генератор (stopped). Чтение/запись частот генератора осуществляется нажатием соответствующих кнопок Read Osc и Write Osc.
56
1. Инструментальные средства практикума
Окно управления функциями автоматизации Auto. При программировании нескольких микроконтроллеров одним и тем же программным кодом функция Auto выступает в качестве полезного инструмента по автоматизации последовательности действий. Действия представлены в виде списка в порядке очередности выполнения при активизации. Для разрешения выполнения действия его необходимо пометить флажком. Например, если отмечено только действие Program FLASH, то после нажатия кнопки Start будет произведена запись во Flash-память в соответствии с настройками в окне Program. Все действия используют настройки в пределах пользовательского интерфейса STK500. Проверка выполненных действий может быть осуществлена благодаря использованию функции записи в журнал Log to file, которая все действия записывает в текстовый файл.
Настройка функции автопрограммирования выполняется путем указания действий, желаемых для исполнения STK500.
Запись процесса автопрограммирования в журнал. При активизации функции Log to file все выполняемые действия будут записаны в текстовый файл. Выбрать или создать файл можно нажатием кнопки Browse, в дальнейшем следует указать путь и имя имеющегося или создаваемого файла. Последовательность выполняемых действий будет фиксироваться в файле, который можно просмотреть.
Программирование микроконтроллера в STK500
Для программирования целевого микроконтроллера АТх8515 необходимо предварительно соединить плату STK500 с источником питания и компьютером.
1.	Подключить источник постоянного напряжения 10... 15 В, 500 мА.
2.	При выключенном компьютере соединить кабелем его СОМ-порт и разъем RS232 CTRL на плате STK500. AVR Studio автоматически определяет COM-порт с подключенным STK500.
3.	Для программирования АТх8515 соединить шестипроводным шлейфом разъемы ISP6PIN и SPROG3.
4.	Переключателем питания POWER можно включить или отключить STK500. Свечение красного светодиода сигнализирует о подаче питания, состояние статусного светодиода будет меняться от красного к желтому, а затем к зеленому. Зеленый цвет светодиода сигнализирует о наличии напряжения VCC (питание микроконтроллера). Стартовый набор может настраиваться на разные частоты тактирования и источники питания.
1.5. Интегрированная отладочная среда VMLab
57
Дальнейшие действия выполнить в окне программы AVR Studio 4.
1. Создать проект для микроконтроллера, установленного на плате STK500. Загрузив рабочую программу в окно редактора, выполнить команду Build из меню Project. После отладки программы с помощью встроенного симулятора можно перейти к программированию микроконтроллера.
2. Для того чтобы загрузить hex-файл в AVR-микроконтроллер, необходимо выполнить команду Tools/ STK.500 из меню программы AVR Studio 4. После открытия окна выбрать тип микроконтроллера из раскрывающегося списка на вкладке Program и указать путь к записываемому Intel-hex файлу в поле Input HEX File. Нажать кнопку Program. Статусный светодиод на плате STK500 во время программирования светится желтым цветом, а после успешного завершения - зеленым. При выявлении ошибки программирования светодиод красный.
В случае ошибки детектирования устройства рекомендуется закрыть неиспользуемые программы, выключив питание на плате, разъединить установленные проводные связи, повторить программирование, затем снова при выключенном питании аккуратно выполнить необходимые соединения. Включив питание и убедившись, что статусный светодиод горит зеленым цветом, можно приступать к работе.
1.5.	ИНТЕГРИРОВАННАЯ ОТЛАДОЧНАЯ СРЕДА VMLAB
При отсутствии стартового набора STK500 или более нового STK600 можно воспользоваться средой проектирования Visual Micro Lab (VMLab). Эта среда предназначена для отладки проектов, содержащих микроконтроллер и несложную периферию. Разработку и отладку проектов можно осуществлять на языках Си и ассемблера. В сети Internet на сайте http://www.amctools.com представлены различные версии программы, среди них свободно распространяемая версия, удобная для симуляции учебных проектов. Программа поддерживает архитектуру микроконтроллеров AVR и ST6 и имеет встроенный компилятор для компиляции программ на языке ассемблера.
При разработке программ на языке Си необходимо установить внешний пакет программ для компиляции программ, например CodeVisionAVR или WinAVR. Последний обеспечивает поддерж
58
1. Инструментальные средства практикума
ку пакета утилит компиляции GCC (GNU compiler collection/GNU С compiler). Основным требованием к компилятору является возможность генерации выходных файлов в форматах .coff и .hex.
Создание проекта на ассемблере и подготовка проектного файла
Достоинством VMLab является возможность построения виртуальной окружающей микроконтроллер среды, состоящей из простых логических и электронных элементов. Файлом, задающим функционирование виртуальной модели, является файл проекта с расширением .prj. В нем описываются тип и параметры микроконтроллера, частота работы, его внешние связи, используемые отладочные средства, файлы с исходным кодом программы, контрольные точки (узлы) схемы. В проект добавляют виртуальные компоненты схемы и описывают их согласно электрической схеме.
Файл проекта содержит ряд директив, в которых перечислены свойства проекта. Все директивы можно разделить на три группы: общие, директивы ассемблера и директивы компилятора Си. Некоторые из них описаны ниже.
.MICRO "Attinyl5" - определяет тип используемого микроконтроллера;
.CLOCK 8meg - указывает частоту работы ядра микроконтроллера в начале симуляции. В дальнейшем во время симуляции частота может быть изменена через панель управления;
.PROGRAM "test.asm" - определяет основной исходный файл проекта на языке ассемблера. Данная директива несовместима с директивой .SOURCE;
.TARGET "testhex" - задает имя выходного бинарного файла, который используется симулятором при отладке. Директива используется при компиляции проекта из нескольких файлов с помощью обобщенной цепочки компиляции или при использовании цепочки компиляции GCC. При компиляции одного файла на ассемблере по умолчанию генерируется выходной файл с тем же именем;
.TRACE - указывает на необходимость отслеживать состояние выводов и узлов, перечисленных в директиве .PLOT;
.POWER VDD=5 VSS=0 - указывает уровни напряжений на шинах питания и земли. Напряжения могут быть положительными и отрицательными;
.PLOT V(node_l) V(PAO) V(PBO) - указывает, сигналы каких узлов следует контролировать при симуляции. Возможно использование нескольких директив;
1.5. Интегрированная отладочная среда VMLab
59
.TOOLCHAIN "ASM" - указывает на то, как будет компилироваться исходный код программы. Возможны три варианта: ASM - исходный код на языке ассемблера, GCC - исходный код на языке Си будет компилирован с помощью предварительно установленного пакета компиляции GCC, GENERIC - цепочка компиляции определяется пользователем;
.SOURCE "file 1 .с" "file2.c" "ШеЗ.с" - используется при отладке программы на языке Си для указания исходных файлов. Директива несовместима с директивой .PROGRAM.
Файл проекта имеет простой текстовой формат, который редактируется вручную без использования шаблонов. Синтаксис и параметры директив описаны в файле помощи (Help).
Для эмуляции устройств, входящих в микроконтроллерную систему, используют описания компонентов системы путем добавления в файл проекта шаблонов электронных компонентов и заполнения их именами узлов, соединяющих эти компоненты с микроконтроллером и между собой. Вызов шаблонов осуществляется из главного меню программы (Components).
При создании виртуальной модели в файле проекта можно указывать:
-	простые внешние компоненты, такие как резисторы, конденсаторы, светодиоды, кнопки и переключатели;
-	логические элементы И-НЕ/ИЛИ-НЕ, компараторы, генераторы сигналов;
-	аналого-цифровые и цифро-аналоговые преобразователи;
-	терминалы.
Используемые компоненты описываются в файле проекта в формате:
<тип> <имя> <узлы соединения> <параметры>.
Пример 1. Для описания схемы соединения вывода РВО микроконтроллера со светодиодом на контрольной панели dl через ограничительное сопротивление R1 и вывода PD0 с кнопкой кО в проектный файл необходимо внести описания: dl vdd al	; светодиод dl контрольной панели
Rl al pbO 560	; сопротивление 560 Ом
k0 pdO gnd monostable (10m) ; кнопка kO контрольной панели с временем замыкания 10 мс
Пример 2. Шаблон описания виртуального терминала RS-232 имеет вид:
60
1. Инструментальные средства практикума
X[inst_name] TTY(baud_rate [n_bits] [parity] [odd__parity] [n_stop_bits] [rx_display_as]) node_tx node_rx,
где TTY - список параметров последовательного канала: скорость (указывается всегда), количество передаваемых бит, отсутствие (0) или наличие (1) бита четности, число стоповых бит (1 или 2), способ представления передаваемых символов в окне приемника терминала (ASCII (1 или 2), десятичный (3), шестнадцатеричный (4)); node tx - узел, соединяемый с выходом передатчика терминала; node rx - узел, соединяемый с входом приемника терминала.
Например, при подключении терминала к линиям передатчика PD1 и приемника PD0 микроконтроллера и передаче данных со скоростью 9600 бит/с описание терминала можно представить в виде:
Xmyterm TTY (9600 8 00 1 4) PD0 PD1
Во избежание ошибок при описании компонентов моделируемой схемы рекомендуется предварительно нарисовать электрическую схему и указать на ней имена узлов всех соединений.
После запуска программы VMLab создается новый проект {Project/New Project). После нажатия кнопки Enter Name/ Browse/ Create directory в открывающемся окне можно создать директорию (папку) для проекта. Открыв ее, указывают имя проекта пате.
Из выпадающего списка Select Micro выбирают тип микроконтроллера. Добавляют в проект подготовленный файл программы с расширением .asm. При запросе на копирование файла в папку проекта выполняют копирование. Закрывают окно нажатием на кнопку ОК. В окне Code программы с помощью директивы указывают путь к файлу определений микроконтроллера, например .include "c:\vmlab\include\8515def.inc". Синтаксически правильную программу на языке ассемблера можно подготовить непосредственно в среде VMLab, воспользовавшись встроенным компилятором. В окне проекта name.prj вводят директивы со свойствами проекта и добавляют описания компонентов схемы.
Подготовив программу, выполняют ее компиляцию. Программой VMLab предусмотрены собственные два режима компиляции, выполняемых командами из меню Project {Build и Rebuild). Далее выполняется отладка в среде VMLab.
1.5. Интегрированная отладочная среда VMLab
61
Отладка проектов в среде VMLab
После подготовки проектного файла и компиляции наступает самый главный этап реализации проекта - его отладка.
Инструменты отладки вызываются из меню View. Традиционными для всех симуляторов являются окна, представляющие внутренние ресурсы микроконтроллера: регистры (Registers/Flags), память данных (Data Memory), энергонезависимая память данных (EEPROM), память программ (Program Memory), порты ввода/вывода (I/O ports) и периферийные устройства микроконтроллера (Peripherals).
Одним из важных инструментов является окно контрольной панели Control Panel (рис. 1.24). Данное окно предоставляет пользователю интерфейс взаимодействия с отлаживаемой программой - кнопки, светодиоды, окно терминала и т. д. На рис. 1.24 показан вид контрольной панели с двумя расположенными внизу окнами последовательного канала.
Speed. 4 >
Тетр.: < - ►
Clock. < ►
Micro Idd’
11Ж |D1 -
25<С	:
е.4 .
3.7 МН;	-
0	12	3
 4J	5 6	7
8	У A.	G
L D Е F
К>: instances
TTY: 1„ 13200 baud.. 7 bits, по parity
ТХ	~TxTfe~| Clear Set parameters  Clear ; |^u RX
..............................a	AVR '	' ................л
Рис. 1.24. Окно контрольной панели
Не менее полезным инструментом отладки является виртуальный осциллограф Scope (он же логический анализатор), открываемый командой View/Scope. Выбор контрольных точек для вывода временных диаграмм определяется директивой .PLOT проектного файла. В окне Scope можно изменять масштаб развертки по времени (вдоль горизонтальной оси) и амплитуде (по вертикальной).
62
1. Инструментальные средства практикума
Отладка проекта ведется по исходному коду в окне Code, поверх которого накладывается график частоты использования кода - желтая полоска, указывающая на частоту обращения к каждой отдельно взятой строке программы.
Окно Code является центральным при отладке проекта в том смысле, что в нем отображаются все редактируемые файлы проекта, а из контекстного меню можно командой Go to Program Memory открыть окно программной памяти и производить прогон программы до заданной точки (команда Run to cursor).
Процесс отладки запускается после компиляции проекта из меню командой Run. Для управления состоянием программы используется отдельная панель управления с кнопками, нажатие которых позволяет запускать и останавливать программу, а также выполнять ее в различных режимах:
•	Go/Continue - позволяет запускать программу в режиме реального времени. В данном режиме программа работает только под управлением внешних воздействий и останавливается на точках прерывания;
•	Step over - позволяет выполнить данную команду за один шаг. Если это обычная команда, то после ее выполнения отладка останавливается. Если это инструкция вызова, то отладчик выполнит процедуру до конца и остановится на команде, следующей за командой вызова;
•	Step into - режим пошаговой отладки. Отладчик выполняет одну команду и останавливается;
•	Stop - выполнение данной команды приводит к приостановке выполнения программы для последующей пошаговой отладки или для более детального просмотра параметров микропроцессора;
•	Restart (light) - данная команда аналогична выполнению перезагрузки микроконтроллера. Текущее время симуляции устанавливается в 0, программный счетчик PC сбрасывается, но вся периферийная часть остается в состоянии, как и до сброса, содержимое памяти не изменяется;
•	Restart (deep) - данная команда аналогична полному сбросу микроконтроллера. Следует заметить, что при рестарте микроконтроллера все ячейки в окне памяти получают значение, обозначаемое символами «??». Это позволяет определить ячейки, в которые производилась запись данных, и ячейки неинициализированной области, откуда производилось чтение. Измененные со времени прошлого обращения программы значения ячеек подсвечиваются желтым цветом.
1.5. Интегрированная отладочная среда VMLab
63
Чтобы остановить симуляцию программы в нужном месте программы, в VMLab используется общеизвестный механизм прерываний в заданных точках останова (Break Point). В окне Code слева от исполняемых строчек текста программы везде, где можно поставить точку останова, появляются зеленые квадратики. Если щелкнуть по такому квадратику, он станет красным восьмиугольным знаком останова. При запуске программы путем нажатия в панели инструментов на кнопку светофора произойдет останов программы на строке с точкой останова. Счетчик времени работы Time, расположенный внизу окна программы, останавливается. При этом строка в окне Code подсветится, а в окне Messages появится сообщение о состоянии программного счетчика PC, времени, прошедшем с начала программы, и причине останова.
Точки останова можно устанавливать и удалять в любом месте до начала симуляции и во время симуляции. Следует, однако, иметь в виду, что при изменении симулируемых файлов точки останова не сохраняются. Потребуется их повторная установка.
Одним из наиболее удобных инструментов отладки является окно переменных Watches. Для его настройки имеется специальный мастер (Debug/Watch Manager), с помощью которого можно добавлять или удалять переменные и, что тоже удобно, ставить условия останова программы при чтении (R) или записи (W) переменных.
Для наблюдения по ходу работы программы за значениями используемых в программе переменных нужно открыть окно, выполнив команду Window/Watch. Щелкнув в окне правой кнопкой мыши, можно открыть окно настройки переменных Watch Manager. В нем помечают переменные, за которыми устанавливается наблюдение, и способ отображения их содержимого. Пока программа не запущена, вместо значений переменных стоят вопросительные знаки. После пуска программы при остановах наблюдаются текущие значения переменных.
Для выполнения отладки запускают программу VMLab и открывают созданный проект (Project/Open Project). Для этого перейдя в папку проекта, выбирают файл проекта для VMLab (name.prj) и открывают его кнопкой Открыть. В меню View подключают необходимые инструменты для отладки проекта: контрольную панель (Control Panel), виртуальный запоминающий осциллограф (Scope), порты ввода/вывода (I/O), память данных и др. Открыв через меню Window/Code окно Code (обычно оно открывается сразу при открытии проекта), можно увидеть текст симули
64	1. Инструментальные средства практикума
руемой программы. В меню Project выполняют Re-Build all ... и приступают к отладке программы, нажимая кнопку светофора на панели инструментов и наблюдая за окнами Scope, Control Panel и Code. При обнаружении ошибок в работе программы останавливают симуляцию, нажав кнопку Stop. Выполняют полный рестарт командами RunZRestart(deep). Вносят изменения в код программы. После повторной компиляции и сборки проекта возобновляют отладку программы.
2.	ПРОГРАММИРОВАНИЕ ПОРТОВ ВВОДА/ВЫВОДА
Цель работы - изучение системы команд микроконтроллеров AVR, приемов программирования на AVR Ассемблере, получение навыков отладки программ в среде отладки AVR Studio 4, работа со стартовым набором STK500.
Микроконтроллеры AVR фирмы Atmel обладают широкими возможностями по вводу и выводу данных. Микроконтроллеры моделей АТх8515 имеют четыре параллельных 8-разрядных порта Рх (х = А, В, С, D) и один 3-разрядный порт РЕ (в модели АТше-ga8515). Все линии портов могут программироваться на ввод или вывод данных независимо друг от друга и подключаться через внутренние подтягивающие резисторы с сопротивлением 35... ... 120 кОм к шине питания VCC.
В состав каждого порта Рх входят три регистра с именами DDRx, PORTx и PINx. В микроконтроллере AT90S8515 регистр PINx не имеет аппаратной реализации. Это имя используется для чтения линий интерфейса. На рис. 2.1 приведена общая структурная схема 8-разрядных портов Рх и структурная схема одного разряда порта PD.y (у = 0, 1...7) микроконтроллера AT90S8515.
Состояние разряда DDRx.y определяет направление передачи бита данных через вывод порта Рх.у. При DDRx.y = 0 вывод порта Рх.у является входом, при DDRx.y = 1 - выходом.
В режиме входа состояние разряда PORTx.y определяет состояние вывода Рх.у. При PORTx.y = 1 вывод порта через внутренний резистор подключен к шине питания VCC. При PORTx.y = 0 резистор отключается, вывод Рх.у находится в высокоимпедансном состоянии (Z-состояние).
В режиме выхода состояние разряда PORTx.y определяет значение сигнала на выводе Рх.у. При PORTx.y = 0 на выводе устанавливается напряжение низкого уровня, при PORTx.y = 1 - высокого.
66
2. Программирование портов ввода/вывода
Рис. 2.1. Структура порта Рх (а) и схема одного разряда порта PD (б)
При пуске и перезапуске микроконтроллера все разряды регистров DDRx и PORTx сбрасываются в нулевое состояние, вследствие чего выводы портов работают в режиме входа и находятся в Z-состоянии.
При совместном использовании всех разрядов порта для ввода байта данных используют команды с мнемоникой IN Rd, PINx, для вывода - OUT PORTx, Rr (d, г = 0.. .31). Значение выходного сигнала на отдельном выводе порта можно задать с помощью команд установки 0 (CBI х,у) и 1 (SBI х,у). Входной сигнал на отдельном выводе порта можно проверить, используя команды условного перехода SBIC PINx,у или SBIS PINx,у, которые предусматривают пропуск следующей команды по нулевому или единичному значению PINx,у.
2.1.	ВЗАИМОДЕЙСТВИЕ МИКРОКОНТРОЛЛЕРА С КНОПКАМИ И СВЕТОДИОДАМИ
Подготовить программу, которая при нажатии кнопки START выполняет поочередное переключение светодиодов, при нажатии кнопки STOP останавливает переключение и возобновляет при повторном нажатии кнопки START.
Пример программы приведен далее. В программе для микроконтроллера AT90S8515 используется файл определений 8515def.inc, для ATmega8515 - m8515def.inc.
В программе линии порта РВ использованы для индикации и, следовательно, проинициализированы на вывод, а линии 0 и 1
2.1. Взаимодействие микроконтроллера с кнопками и светодиодами 67
порта PD, соединяемые с кнопками, - на ввод. После нажатия кнопки START начинается последовательное переключение светодиодов с задержкой и проверка состояния кнопки STOP.
Программа 2.1
********************************************************** Л
/Программа 2.1 для микроконтроллеров АТх8515:
/переключение светодиодов (СД) при нажатии на кнопку START
/(SW0), после нажатия кнопки STOP (SW1) переключение /прекращается и возобновляется с места остановки
/при повторном нажатии на кнопку START
• *Г*Г*'*Г*Г*Г*Г*Г*Г^*Г*Г*С^*Г7**Г*'*Г*Г^*Г*Г*Т*С*С*Г*Г*С*г9с*Г*-*Г*Г*Г*Г*Г*Г^*Г*Г'*-*'-*''*'*Г'*''*''*'-*,*Г*Г-*--*--*-'*-Л
.include "8515def.inc” /.include "m8515def.inc" .def temp = rl6 .def reg_led = r20 .equ START = 0 .equ STOP = 1
.org $000
rjmp init
/* * *Инициализация* ** INIT: Idi reg_led,OxFE
sec set ser temp out DDRB,temp out PORTB,temp clr temp out DDRD,temp Idi temp,0x03 out PORTD,temp WAITSTART:
sbic PIND,START rjmp WAITSTART LOOP: out PORTB,reg_led /***3адержка
Idi rl7,2 dl:Idi rl8,2 d2:dec rl8 brne d2
/файл определений для AT90S8515 /файл определений для ATmega8515 /временный регистр /состояние регистра светодиодов /0-й разряд порта PD /1-й разряд порта PD
/сброс reg_led.O
/ для включения LED0
/0=1
/Т=1 - флаг направления
/инициализация
/ порта РВ на вывод /погасить СД
/инициализация
/ порта PD на ввод
/включение подтягивающих
/ резисторов порта PD
/ожидание
/ нажатия
/ кнопки START
/включение СД
(два вложенных цикла)***
68
2. Программирование портов ввода/вывода
dec г17 brne dl
sbic FIND,STOP
rjmp MM
rjmp WAITSTART
MM:ser temp
out PORTB,temp brts LEFT sbrs reg_led,0
set
ror reg_led rjmp LOOP
LEFT: sbrs reg_led,7
clt
rol reg_led rjmp LOOP
;если замкнута кнопка STOP,
; то переход
; для проверки кнопки START, /иначе выключение светодиодов
/переход, если флаг Т установлен /пропуск следующей команды, если / 0-й разряд reg_led установлен /Т=1 - переключение флага /сдвиг reg_led вправо
/пропуск следующей команды, если / 7-й разряд reg_led установлен /Т=0 - переключение флага / направления
/сдвиг reg_led влево
Задание 1. Проверить работу программы в шаговом режиме работы с помощью симулятора AVR Studio 4. Симуляция замыкания и размыкания кнопок START и STOP осуществляется путем установки 0 (белый цвет) и 1 (черный цвет) в маленьких квадратиках порта линий интерфейса PIND. Перед прогоном программы установите для обеих кнопок состояние логической 1 (кнопки отжаты).
Убедившись в правильной работе программы, измените параметры циклов задержки, чтобы длительность задержки составила 0,5 с. Проверьте время задержки. Для этого установите контрольные точки (Debug/ Toggle Breakpoint) перед началом выполнения программного блока задержки и после выхода из него. Запустив программу в режиме прогона (Debug/Run) с остановом в контрольных точках, оцените время задержки, контролируя либо показания счетчика циклов Cycle Counter в окне Workspace AVR Studio 4 (вкладка I/O, секция Processor), либо показания Stop Watch.
Выполнив трансляцию программы, загрузите hex-файл в STK500. При программировании следите, чтобы тип целевого микроконтроллера, установленного на используемой плате, совпадал с типом микроконтроллера в поле Program. В процессе программирования в окне STK500 появляются сообщения о ходе загрузки программы.
2.2. Обработка внешних прерываний
69
Убедившись в правильности загрузки по выводимым сообщениям, проверьте работу программы на макете. Для этого, выключив питание STK500, с помощью 10-проводного шлейфа соедините выводы разъема порта PD с выводами разъема кнопок общего назначения. С помощью второго 10-проводного шлейфа соедините выводы разъема порта РВ с выводами разъема светодиодов. Включите питание и проверьте работу загруженной программы.
Задание 2. Проверить работу программы в среде VMLab. Для этого, запустив программу VMLab, создать проект, используя рекомендации, изложенные в 1.5. В окне проекта, кроме типовых директив, определяющих частоту работы микроконтроллера, имя файла с исходным текстом программы и др., добавить директивы для описания связей виртуальных кнопок контрольной панели кО, к1 с входами порта PDO, PD1, светодиодов dl...d8 с выходами порта РВ и резисторов, используя для этого шаблоны компонентов. Выполнив компиляцию проекта, запустить программу командой Run. Нажимая кнопки кО(Старт) и к 1 (Стоп), проконтролировать работу программы по состояниям светодиодов контрольной панели. При необходимости изменить в программе время задержки, обеспечивающее время включения светодиодов.
Внести в проект директивы, обеспечивающие контроль работы с помощью логического анализатора (Scope), указав все выходы порта РВ. Настроить Scope так, чтобы увидеть полный цикл осциллограммы и запротоколировать его.
2.2.	ОБРАБОТКА ВНЕШНИХ ПРЕРЫВАНИЙ
В качестве входов внешних прерываний используются входы портов с альтернативной функцией: PD2, PD3 - для прерываний INTO, INTI и РЕО - для прерывания INT2 в микроконтроллере ATmega8515. Запросы внешних прерываний INTO, INTI могут быть представлены низким уровнем сигнала прерывания (L), переходом от высокого уровня сигнала к низкому (HL - по отрицательному фронту), переходом от низкого уровня сигнала к высокому (LH - по положительному фронту), запрос INT2 только переходами (LH) и (HL). В зависимости от типа запроса в регистре управления микроконтроллера MCUCR необходимо установить биты ISCxO и ISCxl согласно табл. 2.1 для каждого из прерываний INTx (х = 0,1) и определить бит ISC2 в регистре EMCUCR для прерывания INT2. При ISC2 = 0 прерывание осуществляется по отрицательному фронту, при ISC2 = 1 - по положительному.
70
2. Программирование портов ввода/вывода
(Прим. Все внешние прерывания можно сгенерировать программно, если сконфигурировать соответствующие выводы микроконтроллера как выходы).
Далее подготовим программу переключения светодиодов с использованием внешнего прерывания от кнопки STOP.
Согласно поставленным условиям, в блок инициализации микро-
Таблица 2.1. Таблица выбора типа запроса
ISCxl	ISCxO	Тип запроса
0	0	L
0	1	—
1	0	HL
1	1	LH
контроллера внесем ряд изменений:
-	добавим вектор прерываний;
-	указатель стека установим на последнюю ячейку ОЗУ;
-	разрешим внешнее прерывание INTO (по сигналу 0 на линии 2 порта PD) и прерывания вообще.
Поскольку внешнее прерывание INTO представлено сигналом на входе порта PD2, в качестве кнопки STOP используем кнопку SW2 и программируем PD2 на ввод. Пример программы 2.2 приведен ниже. Задержка представлена подпрограммой DELAY. Программа работает аналогично 2.1, но нажатие кнопки STOP вызыва
ет прерывание.
Программа 2.2
********************************************************** г
/Программа 2.2 для поочередного переключения светодиодов ;при нажатии на кнопку START (SW0). После нажатия на кноп-;ку STOP (SW2) переключение прекращается и возобновляется
;с места остановки при повторном нажатии на кнопку START г
include "8515def.inc" .include "m8515def.inc" def temp = rl6 def reg_led = r20 equ START = 0
/файл определений для AT90S8515 /файл определений для ATmega8515 /временный регистр
/состояние регистра светодиодов /0-й разряд порта PD
.org $000
/* * *Векторы прерываний* * * rjmp INIT
rjmp STOP_PRESSED
/обработка сброса
/обработка внешнего прерывания
/ INTO(STOP)
2.2. Обработка внешних прерываний
71
;* * ^Инициализация MK* * *	
INIT: Idi reg_led,OxFE Idi temp,$5F	;установка
out SPL,temp	; указателя стека
Idi temp,$02	; на последнюю
out SPH,temp	; ячейку ОЗУ
sec	;С=1
set	;Т=1
ser temp	/инициализация выводов
out DDRB,temp	; порта РВ на вывод
out PORTB,temp	/погасить светодиоды
clr temp	/инициализация
out DDRD,temp	/ порта PD на ввод
Idi temp,0x05	/включение подтягивающих
out PORTD,temp	/ резисторов порта PD
Idi temp,(1<< INTO)	/разрешение прерывания INTO
out GIMSK,temp	/ (GIMSK или GICR)
Idi temp,0x00	/обработка прерывания INTO
out MCUCR,temp	/ по низкому уровню
sei	/разрешение прерываний
WAITSTART: sbic PIND,START	/ожидание нажатия
rjmp WAITSTART	/ кнопки START
LOOP: out PORTB,reg_led	/включение светодиодов
rcall DELAY	/задержка
ser temp	/выключение
out PORTB,temp	/ светодиодов
brts LEFT	/переход, если флаг Т установлен
sbrs reg_led,0	/пропуск следующей команды, если
set	/ 0-й разряд reg_led установлен /Т=1
ror reg_led	/сдвиг reg_led вправо
rjmp LOOP LEFT: sbrs reg_led, 7	/пропуск следующей команды, если
clt	/ 7-й разряд reg_led установлен /Т=0
rol reg_led	/сдвиг reg_led влево
rjmp LOOP ;***Обработка прерывания от	кнопки STOP***
STOP_PRESSED: WAITSTART_2:	/ожидание
sbic PIND,START	/ нажатия
rjmp WAITSTART_2	/ кнопки START
reti
/*** Задержка *** DELAY: 1 di rl7,2 dl: Idi rl8,2 d2: dec r!8
72
2. Программирование портов ввода/вывода
brne d2 dec rl7 brne dl ret
Задание 3. Проверить работу программы с помощью отладчика AVR Studio 4. Изменить параметры задержки, чтобы длительность задержки составила 0,5 с. Запрограммировать микроконтроллер и проверить работу программы.
Задание 4. Изменить программу для включения (выключения) светодиодов в одной из заданных последовательностей:
a)	7-6-5-4-3-2-1-0-1-2-3^1-5-6-7-6-5...
б)	в четных разрядах;
в)	в нечетных разрядах;
г)	последовательно увеличивая количество включенных (выключенных) светодиодов до восьми и затем уменьшая до нуля.
Отладив программу, загрузите ее в микроконтроллер и проверьте работу.
Задание 5. Изменить программу, добавив внешнее прерывание INT1 (сигнал на линии PD3, адрес прерывания 002, бит 7 регистра маски GIMSK или GICR) от кнопки START. Открыв при отладке программы окно памяти данных, проверить работу стека, размещаемого в памяти с адреса $025F. Отлаженную программу загрузить в микроконтроллер и проверить ее работу.
Обработка кнопочного регистра с индикацией состояния
Ввод данных от кнопок рассмотрим на примере программы 2.3, выполняющей последовательный опрос и индикацию нажатия кнопок SWx (х = 0,1,2,3) кратковременным включением соответствующего светодиода LEDx, а также включением светодиодов LEDx (х = 4, 5, 6, 7) и выключением после повторного нажатия кнопок SWx (х = 4, 5, 6, 7).
Обратите внимание на использование в программе макроопределений для проверки состояния кнопок. При каждом нажатии кнопки значение соответствующего бита в слове состояния младшей и старшей групп кнопок (st_L, st_H) меняется на противоположное (командой еог) и сохраняется. Для вывода на светодиоды формируется байт вывода reg led.
Программа 2.3 г
/Программа 2.3 для обработки нажатий кнопок и индикации их
2.2. Обработка внешних прерываний
73
;состояний
********************************************************** Z
.include "8515def.inc"
.def temp = rl6
.def st_L = rl7
.def st_H = rl8
.def sw_cod = r22
.def reg_led = r23
/файл определений для AT90S8515 /временный регистр
/состояние младшей группы SW_0123 /состояние старшей группы SW_4567 /код состояния замкнутой кнопки /регистр состояния светодиодов
.macro	testH_sw	/макроопределение
sbic	PIND, @0	/проверка кнопки SWx(x=4,5,6,7)
rjmp	quit	/ и установка
bld	sw_cod, @0	/ бита замкнутой кнопки
eor	st_H,sw_cod	/переключение бита состояния
mov	reg_led,st_H	/байт для индикации
com	reg_led	/инвертирование для вывода
out	PORTB,reg_led	/ на светодиоды
clr clr	reg_led sw_cod	/очистка
rcall DELAY		/задержка
wait: sbis PIND, @0 rjmp wait		/кнопка отпущена?
quit: пор .endmacro
.macro testL_sw
sbic PIND,@0 rjmp quit bld sw_cod,@0 eor st_L,sw_cod mov reg_led,sw_cod or reg_led,st_H com reg_led out PORTB,reg_led clr sw_cod rcall DELAY_0 ori reg_led,0x0f out PORTB,reg_led quit: nop .endmacro .org $000
rjmp init
/* * ^Инициализация***
/макроопределение
/проверка кнопки SWx(х=0,1,2,3)
/ и установка
/ бита замкнутой кнопки /переключение бита состояния / байт
/ для индикации
/инвертирование для вывода
/ на светодиоды
/короткая задержка
/ перед гашением
/ светодиодов младшей группы
74
2. Программирование портов ввода/вывода
INIT:	Idi temp,low(RAMEND)	;установка
out	SPL,temp	; указателя стека
Idi	temp,high(RAMEND)	; на последнюю
out	SPH,temp	; ячейку ОЗУ
ser	temp	;настройка
out	DDRB,temp	; порта РВ
out	PORTB,temp	; на вывод
clr	temp	;настройка
out	DDRD,temp	; порта PD
ser	temp	; на
out	PORTD,temp	; ввод
clr	sw_cod	/очистка кода кнопки
clr	st_L	/очистка операнда
clr	st_H	
clr	reg_led	
set		/ Т=1
input:	testL_sw 0	
testL_sw 1 testL_sw 2 testL_sw 3
testH_sw 4 testH_sw 5 testH_sw 6 testH_sw 7 rjmp input ;*** Задержка *** DELAY_O: Idi r21,255 dO: dec r21
brne dO ret
;*** Задержка *** DELAY: Idi rl9,10 dl: Idi r20,255
rcall DELAY_0 dec r20 brne d2 dec rl9 brne dl ret
Задание 6. На основе 2.3 разработать программу «кодового замка», которая после набора 4-разрядного PIN-ко да с помощью кнопок SW0 - SW3 и ввода данных, например с помощью кнопки
2.2. Обработка внешних прерываний
75
SW5, осуществляет сравнение с паролем и включает светодиод LED7 при правильном вводе. При трех неправильных попытках введения PIN-кода кнопочная клавиатура должна быть заблокирована, а все светодиоды включены.
Контрольные вопросы
1.	Какова роль подтягивающих резисторов? Каким образом можно подключить и отключить резисторы?
2.	Как задается альтернативная функция разряда порта?
3.	Какие линии портов микроконтроллера можно использовать для внешних прерываний? Каковы адреса векторов внешних прерываний? Как управлять внешними прерываниями? Какое из них имеет более высокий приоритет?
4.	Каким сигналом (логический 0 или логическая 1) можно включить светодиод STK500? Как должен выглядеть бит порта PINx,у в AVR Studio 4 при замыкании (размыкании) кнопки?
5.	Как повысить точность программной задержки?
3.	АРИФМЕТИЧЕСКАЯ ОБРАБОТКА ДАННЫХ
Цель работы - изучение способов представления числовых данных в микроконтроллерах, алгоритмов арифметических операций, программирование арифметических процедур.
3.1.	ПРЕДСТАВЛЕНИЕ ЧИСЕЛ В МИКРОКОНТРОЛЛЕРАХ
При обработке числовой информации в микроконтроллерах обычно полагают, что целые числа имеют формат с фиксированной точкой справа - D = dn_xДР°бные числа меньше 1 имеют формат с точкой слева - D = d_xd_2...d_Xn_^d_n, где п -число разрядов, равное 8 или 16. Обрабатываемые числа могут быть со знаком и без знака.
При целочисленном представлении </0 - младший разряд числа с весом 2 , старшин разряд dn_\ используется для представления знака (0 - положительный, 1 - отрицательный). Старший цифровой разряд - dn_2 с весом 2” 2. При обработке чисел без знака разряд <7„_i является цифровым с весом 2” \
Дробь без знака имеет старший цифровой разряд d_x с весом 2"1. Для дробных чисел со знаком разряд d_x отводится под знак, старший цифровой разряд в этом случае - d_2 с весом 2-1.
Отрицательные числа, как целые, так и дробные, обычно представляют в виде дополнений до основания системы счисления. Для двоичных целых чисел это будет дополнение до 2”, для дробных -дополнение до 2.
В общем случае дополнение любого целого ^-разрядного числа D до основания Ь системы счисления можно получить путем вычитания D из Ьп. Если D находится в пределах 1 до bn -1, то при вычитании получается другое число в тех же пределах. Если D = 0, то результат вычитания равен Ьп и имеет вид 100...0 при
3.2. Сложение и вычитание чисел в дополнительном коде
77
общем числе разрядов, равном (и + 1). Отбросив цифру старшего разряда, получим 0. Следовательно, в системе представления чисел дополнением до основания системы счисления существует только одно представление 0. В системе, где отрицательные числа представлены в дополнительном коде, число является положительным, если значение старшего разряда dn_\ = 0, и отрицательным, если dn_\ = 1. Десятичный эквивалент двоичного числа, представленного дополнительным кодом, вычисляется так же, как и для числа без знака, за исключением того, что вес старшего разряда равен -2^” а не +2^ Представляемые числа находятся в диапазоне от -2^ до +2*” 1')- 1. Для дробных чисел дробь положительна, если разряд <7_i = 0, и отрицательна, если cLi = 1. Диапа-_______________________________________^2 Н- 1
зон дробных чисел составляет от -1 до +(1 - 2	).
3.2.	СЛОЖЕНИЕ И ВЫЧИТАНИЕ ЧИСЕЛ В ДОПОЛНИТЕЛЬНОМ КОДЕ
Графически 8-разрядные двоичные (2-разрядные шестнадцатеричные) числа со знаком в дополнительном коде показаны на рис. 3.1, а позициями (внутри круга указаны десятичные значения, снаружи - их шестнадцатеричные изображения). Сложение с положительным числом N легко интерпретировать, перемещая указатель по ходу часовой стрелки на N позиций; вычитание (-N) -против хода часовой стрелки или перемещая по ходу часовой стрелки на (256-N) позиций, что равносильно замене вычитания сложением с дополнением числа до 28 = 256. Если при сложении (или вычитании) получают результат, который выходит за пределы диапазона чисел (от -128 до +127), фиксируется переполнение.
Правило выявления переполнения. При сложении переполнение возникает только в том случае, если слагаемые имеют одинаковые знаки, а знак суммы отличается от знака слагаемых. При вычитании переполнение происходит, если операнды имеют разные знаки, а знак разности отличается от знака уменьшаемого. Правило переполнения можно сформулировать иначе. Переполнение OVR возникает, если значения переносов в знаковый разряд р7 и из знакового разряда pg различны (OVR = pg © Р7). Из анализа рис. 3.1, а следует, что переполнение возникает при сложении, если указатель перейдет границу между позициями +127 и -128, при вычитании - границу между -128 и +127.
78
3. Арифметическая обработка данных
Рис. 3.1. Круговые диаграммы
Числа в дополнительном коде складываются и вычитаются так же, как и числа без знака той же длины. Поэтому при сложении (вычитании) чисел со знаком и без знака необходима одна и та же команда сложения (вычитания). Различие заключается лишь в том, что результаты интерпретируются по-разному в зависимости от того, какими числами оперирует пользователь: числами со знаком (от -128 до +127) или без знака (от 0 до 255).
На рис. 3.1, б представлены графически 8-разрядные двоичные (2-разрядные шестнадцатеричные) числа без знака. Видно, что двоичные кодовые комбинации занимают те же позиции, что и на рис. 3.1, а, а сложение и вычитание можно осуществить, перемещая указатель на N позиций в том или ином направлении.
3.3. Умножение чисел без знака
79
При сложении чисел без знака результат выходит за пределы диапазона представления при пересечении границы между 255 и 0. В этом случае говорят о возникновении переноса из старшего разряда. При вычитании чисел без знака результат выходит за пределы диапазона при пересечении границы между 0 и 255. В этом случае возникает заем, а разность получается в дополнительном коде. Но так как вычитание N можно заменить сложением с дополнительным кодом числа N, равным (256 - N), то из диаграммы видно, что заем возникает без переноса из старшего разряда. Тот же вывод следует при выполнении операции в машинном коде. Действительно, вычитая из шестнадцатеричного числа $05 число $07, имеем $05 - $07 = $05 + $F9 = $FE = -2 . Переноса нет. Заем, определяемый по отсутствию переноса при операции вычитания, есть. И наоборот, вычитая из $07 число $05, имеем $07 - $05 = = $07 + $FB = $102 = $100 (перенос) + $02 = 2. Перенос есть, что при вычитании соответствует отсутствию заема. Сказанное необходимо учитывать при обработке операндов двойной длины, например 16-разрядных операндов в 8-разрядном процессоре.
3.3.	УМНОЖЕНИЕ ЧИСЕЛ БЕЗ ЗНАКА
Наиболее просто умножение целых чисел С = А  В можно выполнить по алгоритму, изображенному на рис. 3.2. После загрузки мно-жимого А и множителя В в регистры общего назначения и об-ну-ления регистра произведения С проводится анализ содержимого регистра множителя. Если В 0, то к сумме частичных произведений С прибавляется множимое Л.
Затем содержимое регистра множителя уменьшается на 1 и цикл умножения повторяется до тех пор, пока содержимое регистра множителя не окажется равным 0. При умножении «-разрядных сомножителей 2и-разрядное произведение размещают в двух регистрах. Данный метод умножения находит ограниченное применение в тех приложениях, где время умножения некритично (при 8-разрядных сомножителях максимальная продолжительность опе-рации умножения может составить 255 циклов сложения).
На практике больше распространены методы умножения путем сложения ряда частичных произведений С = X^Abj, где Ь, - значение разряда множителя (/ = 0, 1,..., п - 1). Один из алгоритмов умножения, начиная с младших разрядов множителя, со сдвигом вправо суммы частичных произведений приведен на рис. 3.3.
80
3. Арифметическая обработка данных
Рис. 3.2. Схема простейшего алгоритма умножения
Рис. 3.3. Схема алгоритма умножения, начиная с младших разрядов множителя
Этот алгоритм может быть использован для получения произведения двух двоичных чисел без знака. Количество итераций умножения п определяется числом разрядов множителя. Поскольку в процессе умножения на каждой итерации выполняется сдвиг множителя В на один разряд вправо, на место освобождаемого разряда можно записать выталкиваемый при сдвиге вправо разряд произведения С. Таким образом, 2«-разрядное произведение можно получить, объединив содержимое «-разрядного регистра, в котором формируется старшая часть произведения, и регистра В, в котором после выполнения умножения окажется младшая часть произведения.
3.4.	ДЕЛЕНИЕ ЦЕЛЫХ ЧИСЕЛ
Для типичного алгоритма целочисленного деления С = А/В делимым является двойное слово AH.AL (два байта), а делителем -одинарное В (один байт); частное С и остаток получают в виде
3.4. Деление целых чисел
81
одинарных слов. При выполнении деления необходимо исключить возможность деления на 0. Если для представления частного потребуется более одного слова, то фиксируется переполнение. При выполнении деления необходимо проверить условие - делитель должен быть больше старшего слова делимого (В > АН).
При делении целых чисел можно использовать алгоритм деления без восстановления остатка и алгоритм с восстановлением остатка.
Схема алгоритма деления с восстановлением остатка приведена на рис. 3.4. Алгоритм деления представляет собой итерационную процедуру. На каждой итерации сначала удваивается делимое (на первой итерации) или остаток (на всех последующих) путем сдвига влево на один разряд, затем вычитается делитель и определяется цифра частного по знаку разности. Если разность положительная, определяемая на данной итерации цифра частного с, = 1, если разность отрицательная, цифра частного с, = 0. Восстановление остатка выполняется путем сложения делителя с остатком после вычитания на текущей итерации деления. Деление выполняется до получения всех цифр частного.
Алгоритм деления без восстановления остатка (рис. 3.5) представляет собой итерационную процедуру, на каждой итерации которой проводится либо вычитание делителя В, заменяемое сложением с дополнительным кодом [-Б]доп, либо прибавление В в зависимости от знака остатка, полученного на предыдущей итерации деления. Если полученный остаток больше или равен 0, при очередной итерации деления выполняется вычитание В; если остаток меньше 0 - прибавление В. Перед каждым вычитанием (или сложением) остаток удваивается путем сдвига влево. На начальной итерации деления делимое сдвигается на один разряд влево.
Деление чисел со знаком можно выполнить разными способами. Если исходные операнды заданы в прямых кодах, то путем сложения по модулю 2 знаковых разрядов можно определить знак частного. Модули делимого и делителя можно разделить, используя один из вышеописанных алгоритмов. Для определения переполнения необходимо выполнить пробное вычитание А - 2^” 1>В, резервируя один разряд «-разрядного частного для знака.
Далее приведен пример деления 16-разрядного числа А на 8-разрядное число В с восстановлением остатка:
82
3. Арифметическая обработка данных
Рис. 3.4. Схема алгоритма деления с восстановлением остатка
3.4. Деление целых чисел
83
А = 1024 = 00000100.00000000,
С = С7С6С5С4С3С2С1С0- частное,
00000100.00000000
+ 11110110
11111010
00001000.0000000х
11110110
11111110
ОООЮООО.ООООООхх
+ 11110110
00000110
00001 ЮО.ОООООххх
+ 11110110
00000010
00000 ЮО.ООООхххх
+ 11110110
11111010
00001 ООО.ОООххххх
+ 11110110
11111110
ОООЮООО.ООхххххх
+ 11110110
00000110
00001 ЮО.Оххххххх
+ 11110110
00000010
000001 ОО.хххххххх
+ 11110110
11111010
11111010
+ 00001010
00000100
В= 10 = 00001010,
-В = [-10]доп =11110110,
х - бит, свободно
определяемый при сдвиге
делимое A(AHAL)
пробное вычитание В так как разность меньше О, переполнения нет
сдвиг А влево вычитание В
1-й остаток меньше 0, разряд частного
С7 = О
сдвиг влево восстановленного АН вычитание В
2-й остаток больше 0, разряд частного с6= 1
сдвиг остатка
вычитание В
3-й остаток, с5 = 1
сдвиг остатка вычитание В
4-й остаток, С4 = 0
сдвиг восстановленного АН вычитание В
5-й остаток, сз = 0
сдвиг восстановленного АН вычитание В
6-й остаток, С2 = 1
сдвиг остатка вычитание В 7-й остаток, с\ = 1
сдвиг остатка
вычитание В
8-й остаток, со = 0
прибавление В
восстановлен остаток АН = 4
С= 01100110 = 102
84
3. Арифметическая обработка данных
Рис. 3.5. Схема алгоритма деления без восстановления остатка
3.4. Деление целых чисел
85
Пример деления 16-разрядного числа А на 8-разрядное число В без восстановления остатка:
А = 1024 = 00000100.00000000, С = С7С6С5С4С3С2С1С0- частное, 00000100.00000000 + 11110110 11111010 ООООЮОО.ОООООООх + 11110110 11111110 , ШШОО.ООООООхх 00001010 00000110 00001 ЮО.ОООООххх + 11110110 00000010 000001 ОО.ООООхххх + 11110110 11111010 ШЮЮО.ОООххххх + 00001010 11111110 ШШОО.ООхххххх 00001010 00000110 00001 ЮО.Оххххххх + 11110110 00000010 00000 ЮО.хххххххх 11110110 11111010	£= 10 = 00001010, -В = [-10]доп =11110110, х - бит, свободно определяемый при сдвиге делимое А (AH.AL) пробное вычитание В так как разность < 0, переполнения нет сдвиг влево AH.AL вычитание В 1-й остаток меньше 0, разряд частного = 0 сдвиг влево AH.AL прибавление В 2-й остаток больше 0, разряд частного <?б = 1 сдвиг влево AH.AL вычитание В 3-й остаток больше 0, = 1 сдвиг влево AH.AL вычитание В 4-й остаток меньше 0, = 0 сдвиг влево AH.AL прибавление В 5-й остаток меньше 0, сз = 0 сдвиг влево AH.AL прибавление В 6-й остаток больше 0, cz = 1 сдвиг влево AH.AL вычитание В 7-й остаток больше 0, с\ = 1 сдвиг влево AH.AL вычитание В 8-й остаток меньше 0, с$ = 0
86
3. Арифметическая обработка данных
11111010
+ 00001010
00000100
прибавление В
восстановлен остаток АН = 4
01100110 = 102
3.5.	СЛОЖЕНИЕ И ВЫЧИТАНИЕ ДВОИЧНО-ДЕСЯТИЧНЫХ ЧИСЕЛ
При сложении двух двоично-десятичных чисел А = ап~\ап_. ...а^ао и В = Ьп_1Ьь_2---Ь1Ьо поступают следующим образом. Если оба операнда имеют одинаковые знаки, то выполняют сложение модулей этих чисел (|Л| + |5|), а знаковый разряд суммы определяют по знаку одного из слагаемых. Если операнды имеют разные знаки, то предварительно знак суммы устанавливают по знаку первого операнда А. Затем производят вычитание модулей чисел (|Л| - \В\). Если полученная разность больше нуля, знак суммы сохраняется без изменений. Если разность меньше нуля, следует найти дополнительный код разности и изменить знак суммы на противоположный.
При сложении двух чисел А и В, представленных в 2-10 коде, с весом 8-4-2-1 в каждой тетраде, в одном разряде суммы S = А + В можно получить результаты:
1)	5/ < 9; не требует коррекции;
2)	10 < 5/< 15; требует коррекции путем увеличения 5/на шесть с образованием переноса из тетрады;
3)	Sj > 15; требует коррекции путем увеличения 5/ на шесть. В этом случае перенос из тетрады образуется автоматически при сложении операндов до выполнения коррекции.
В микроконтроллерах с архитектурой MCS-51 коррекция осуществляется аппаратно при выполнении команды 2-10 коррекции. При отсутствии схемы 2-10 коррекции, как в микроконтроллерах AVR, поступают следующим образом. При сложении двоичнодесятичных чисел добавляют число, каждый разряд которого равен шести. В этом случае, если вычисляемая поразрядная сумма Si < 9, перенос из тетрады не возникнет и избыточное значение шесть подлежит удалению. Во всех остальных случаях добавленное в разряд значение шесть удаляется автоматически с переносом из тетрады в процессе сложения. При таком способе сложения программная реализация упрощается, так как для коррекции результата в тетраде проверяется лишь один признак - наличие или отсутствие переноса из тетрады.
3.5. Сложение и вычитание двоично-десятичных чисел
87
Таким образом, сложение беззнаковых чисел (как и модулей |Л| + |2?|) можно выполнить по алгоритму, схема которого приведена на рис. 3.6:
1)	двоично-десятичный код первого операнда я„_1аи_2...а1а0 складывается с кодом 66...66, образуя первую промежуточную сумму s'n_{s'n_2...s{s'^
2)	к полученной сумме прибавляется двоично-десятичный код второго операнда 6и_1й„_2..Д6g,образуя вторую промежуточную сумму s"n_xs"n_2...s^;
3)	потетрадно выполняется коррекция результата. Правило коррекции формулируется следующим образом: если в результате второго сложения перенос из z-й тетрады отсутствует (сг+1 = 0), то из s” вычитается шесть (или прибавляется 10 = [-6]доп). При возникновении переноса из z'-й тетрады коррекция не выполняется, а полученный результат s" является истинным. При выполнении коррекции перенос из тетрады не должен изменять содержимое следующей тетрады суммы 5;"+1.
Рис. 3.6. Алгоритм сложения 2-10 чисел
88
3. Арифметическая обработка данных
При побайтовой обработке длинных операндов в 8-разрядном процессоре микроконтроллера для исключения ошибок коррекцию необходимо выполнять отдельно для каждой тетрады.
Пример. А = 50, В = 25. Найти сумму Л + В.
Двоично-десятичное представление чисел А и В: А = 0101 0000, В = = 00100101.
Складывая числа 66 + А + В, получаем
0110 0110	66
+ 0101 0000	50
1011 ОНО
1011 ОНО
+ 0010 0101	25
1101 1011
Выполняем коррекцию младшей тетрады:
1101 1011
+1111 1010	-$06 = $FA
1101 0101
Выполняем коррекцию старшей тетрады:
1101 0101
+ 1010 0000	-$60 = $А0
01110101	75
Программный код процедуры 2-10 сложения однобайтовых операндов приведен в программе 3.1.
Вычитание беззнаковых чисел A-В можно выполнить по алгоритму, схема которого представлена на рис. 3.7:
1) выполняют вычитание A-В (складывая А с дополнительным кодом В), образуя первый промежуточный результат R'. Если в результате операции образуется перенос из старшей тетрады (при этом флаг заема равен 0), результат является положительным. При отсутствии переноса (флаг заема равен 1) результат является отрицательным и его следует перевести в дополнительный код А";
2) коррекция положительного результата осуществляется по правилу, сформулированному для сложения 2-10 чисел. Коррекция отрицательного результата выполняется иначе: если произошел перенос из г-й тетрады (флаг межтетрадного заема равен 0) при вычитании А - В, то из z-й тетрады R" вычитается шесть. При выполнении коррекции перенос из тетрады не должен изменять содержимое следующей тетрады промежуточного результата.
3.5. Сложение и вычитание двоично-десятичных чисел
89
Рис. 3.7. Алгоритм вычитания 2-10 чисел
Пример. А = 23, В = 62. Найти разность Л -В.
Двоично-десятичное представление чисел А и В: А = 0010 ООП, В = = 0110 0010.
Дополнение числа В: [5]Д0П = 1001 1110. Вычитая А - В = А + [5]Д0П, получаем R':
0010 0011
+ 1001 1110
1100 0001
Переноса нет: результат отрицательный, флаг заема равен 1.
Формируем дополнение [Яг]доп и выполняем коррекцию:
ООП 1111
+ 1111 1010	-$06 = $FA
ООП 1001
Результат: флаг знака - разность 39.
Когда отрицательный результат требуется сохранить в дополнительном коде, шаг формирования дополнения [7?']доп опускается. Можно сразу переходить к коррекции (вычитанию шести в тех тетрадах, где не было переноса). Программный код процедуры 2-10 вычитания однобайтовых операндов для этого случая приведен в программе 3.1.
90
3. Арифметическая обработка данных
3.6. ПРОГРАММИРОВАНИЕ АРИФМЕТИЧЕСКИХ ОПЕРАЦИЙ
Задание 1. Ниже приведена тестовая программа 3.1 для проверки операций сложения и вычитания двоичных и двоичнодесятичных однобайтовых чисел в среде AVR Studio 4. Для двоичного сложения/вычитания числа можно задать со знаком и без знака. Двоично-десятичные числа представлены в упакованном формате без знака.
Открыв AVR Studio 4, создать проект. Загрузить тестовую программу и, выполняя ее в пошаговом режиме, наблюдать результаты выполнения команд. Выполнить ряд примеров с разными значениями операндов. Чтобы не выполнять повторную компиляцию программы при изменении значений операндов, можно воспользоваться ручной перезагрузкой операндов в регистрах в окне НО. Для этого необходимо после команд занесения исходных значений операндов щелкнуть кнопкой мыши на соответствующем регистре в окне ПО и занести новое значение.
Программа 3.1
• 'k-k-k-k-k-k-kic-k-k-k-k-k-k'k'k'k-k-k'k'k-k-k-k-k-k-k-k-k-k-k'k-k-k'k-k-k-k-k-k-k'k-k-k'k-k-k-k-k-k-k-k-k-k'k'k'k г
/Тестовая программа 3.1 сложения и вычитания однобайтовых ;операндов
• ^^^k-k'k-k-k-k-k-k-k-k'k-k'k-k'k-k-k'k'k'k'k-k-k'k-k-k-k-k-k-k-kii-k-^-k-k-k-k-k-k-k-k-k-k-k-k-k-k-k-k-k-k-k-k
.include "8515def.inc"
/.include "m8515def.inc"
.def BCDa = r30
.def BCDb = r31
.def tmpadd = r29
.def temp = r28
. org 0
rjmp INIT
• 'k'k-k'k-k'k'kii'k'k-k'k'k-k-k-k-k'k-k-k-k-k-k-k-kii-^ii-k-k-k-k-k-k-k-k-k-k-k-k-k'k-k-k'kdi'k-^-k-k-k-k'k-k'k-k-k f
/Подпрограмма сложения 2-10 упакованных беззнаковых чисел /BCDa и BCDb. Результат возвращается в BCDa, перенос - в /BCDb
.it********************************************************
BCDadd:
Idi tmpadd,$66
add BCDa,tmpadd
add BCDa,BCDb
3.6. Программирование арифметических операций
91
clr BCDb
brcs add_O
rjmp add_l
add_O: Idi BCDb,1 add_l:	brhs add_2
subi BCDa,$06 add_2: sbrs BCDb,0
subi BCDa,$60
/установить выходной перенос /если межтетрадный перенос равен 0, ; LSD = LSD - 6 /если выходной перенос равен 0, ; MSD = MSD - 6
ret
.********************************************************* л
/Подпрограмма вычитания 2-10 упакованных беззнаковых чисел
/BCDa и BCDb (BCDa - BCDb).
/Результат возвращается в BCDa,знак разности - в BCDb
********************************************************** f
BCDsub:		
sub	BCDa,BCDb	
clr	BCDb	
brcc	sub_0	/если флаг заема равен 1,
Idi	BCDb,1	/ сохранить его
sub_0:	brhc sub_l	/если межтетрадный заем равен 1,
subi	BCDa,$06	/ LSD = LSD - 6
sub_l:	sbrs BCDb,0	/если сохраненный флаг заема равен
ret		/ выйти,
subi	BCDa,$60	/иначе вычесть $60
ret		
• ^^^^^^^^^^^'k'k'k'k'k'k'k'k'k'k'k-^'^'-k'k'k'k'k'-k'k'k'k'k'k'k'k'k'k'-k'k'k'k'k'k^'k'k'k'k'k'k'k'k'k'k'k f
/Основная программа
.***k********-k-k-k-k-k-k-k-k-k-k-k'k-k-k-k'k-k**-k-kic-k*-k-k***-k*-k-k*-k*-k***-k-k-k-k-k
INIT: Idi temp,low(RAMEND)
out SPL,temp
Idi temp,high(RAMEND)
out SPH,temp
;*** Add BIN
loop: Idi BCDa,51
Idi BCDb,-79
add BCDa,BCDb /Результат: BCDa=$E4
;*** Sub BIN
Idi BCDa,72
Idi BCDb,28
sub BCDa,BCDb /Результат: BCDa=$2C
92
3. Арифметическая обработка данных
★★★ Add	BCD Unsigned
Idi	BCDa,$51
Idi	BCDb,$79
rcall	BCDadd	/Результат: BCDb:BCDa=$0130
*** Sub	BCD Unsigned
Idi	BCDa,$72
Idi	BCDb,$28
rcall	BCDsub	/Результат: / BCDb=$0О-положительный,BCDa=44
Idi	BCDa,$00
Idi	BCDb,$90
rcall	BCDsub	/Результат: / ВСОЬ=$01-отрицательный, BCDa=10
rjmp	loop
Задание 2. Изучить программу 3.2, приведенную ниже для исследования арифметических операций в стартовом наборе STK500.
Программой предусмотрен ввод кода операции, 8- и 16-раз-рядных операндов, выполнение заданной операции и показ результатов.
В стартовом наборе STK500 всего восемь кнопок общего назначения (SW7...SW0). При тестировании арифметических операций эти кнопки используются следующим образом: кнопки SW0...SW2 - для ввода младшего (AL) и старшего байта (АН) первого операнда и одного байта второго операнда (BL), SW3...SW6 - для выполнения операций сложения, вычитания, умножения и деления, SW7 - для просмотра.
Программа 3.2 г /Программа тестирования в STK500 двоичных арифметических /операций сложения, вычитания, умножения, деления /Порт PD - порт управления для выбора операндов и операций /Порт РВ - порт индикации исходных операндов и результатов /операции. Соединения шлейфами: порт РВ-LED, порт PD-SW ********************************************************** г .include "m8515def.inc” /файл определений для ATmega8515 /Выводы порта PD .equ SW_op_AL	=	0	/кнопка	выбора	операнда	op_AL
.equ SW_op_AH	=	1	/кнопка	выбора	операнда	ор_АН
.equ SW_op_BL	=	2	/кнопка	выбора	операнда	op_BL
.equ SW_ADD =	3	/кнопка	сложения res=op_AL+op_BL
.equ SW_SUB = 4 /кнопка вычитания res=op_AL-op_BL
3.6. Программирование арифметических операций
93
.equ SW_MUL = 5
.equ SW_DIV = 6
.equ SW-SHOW = 7
.def op_AL = rl6 .def op_AH = rl7 .def op_BL = rl8 .def res = rl .def show = r31
;кнопка умножения op_ALxop_BL /кнопка деления ; op_AH.op_AL/op_BL /кнопка просмотра признаков сложения-/ вычитания, / старшего байта произведения или / остатка при делении
/1-й операнд AL
/старший байт делимого АН
/2-й операнд BL
/результат операции (сумма, разность, / младший байт произведения или частное) /регистр признаков сложения-вычитания, / старшего байта произведения или
/ остатка при делении
def mul_l =	r21	/младший байт произведения
def mul_h =	r22	/старший байт произведения
def copy_AH	= r23	/копия старшего байта делимого
def copy_AL	= r24	/копия младшего байта делимого
def copy_BL	= r25	/копия множителя
def temp = .	r26	/временный регистр
def sw_reg :	= r27	/регистр состояния кнопок
def count =	r28	/число операндов в таблице операндов
def c bit =	r29	/счетчик циклов умножения (деления)
.macro vvod 1pm mov @0,r0 mov res,rO adiw zl,1 dec count brne exit
/ввод операнда /считывание байта из flash-памяти в гО / и пересылка в регистр операнда
/увеличение указателя адреса на 1
Idi ZL,low(tabl_op*2)
Idi ZH,high(tabl_op*2)
Idi count,16 exit: nop .endmacro .org $000 /Инициализация
Idi temp,low(RAMEND) out SPL,temp
Idi temp,high(RAMEND) out SPH,temp
/перезагрузка начала таблицы
/ операндов
/ в регистр Z
/установка
/ указателя стека
/ на последнюю
/ ячейку ОЗУ
94
3. Арифметическая обработка данных
ser temp out DDRB,temp	/настройка / порта PB
out PORTB,temp	/ на вывод
clr temp	/настройка
out DDRD,temp	/ порта PD
ser temp	/ на
out PORTD,temp	/ ввод
Idi ZL,low(tabl_op*2)	/загрузка адреса таблицы
;операндов
Idi ZH,high(tabl_op*2); в регистр Z
Idi count,16	/число операндов 16
/Опрос кнопок и выполнение заданных действий LOOP: in sw_reg,PIND sbrs sw_reg,0 rjmp f_op_AL sbrs sw_reg,1 rjmp f_op_AH sbrs sw_reg,2 rjmp f_op_BL sbrs sw_reg,3 rjmp add_bin sbrs sw_reg,4 rjmp sub_bin sbrs sw_reg,5 rjmp mul_bin sbrs sw_reg,6 rjmp div_bin sbrc sw_reg,7 rjmp loop mov res,show rjmp outled
/Выборка 1-го операнда из таблицы операндов f_op_AL: vvod op_AL rjmp outled
/Выборка старшего байта 1-го операнда (при делении) f_op_AH: vvod ор_АН rjmp outled
/Выборка 2-го операнда f_op_BL: vvod op_BL rjmp outled
/Сложение 8-разрядных операндов add_bin: mov res,op_AL
add res,op_BL in show,SREG /выборка из регистра SREG rjmp outled /Вычитание 8-разрядных операндов
3.6. Программирование арифметических операций
95
sub_bin: mov res,op_AL
sub res,op_BL
in show,SREG /выборка из регистра SREG rjmp outled
/Умножение 8-разрядных операндов
mul_bin: clr mul_l	/очистка младшего
clr mul_h	/ и старшего байта произведения
Idi c_bitr 8 mov copy_BL,op_BL	/счетчик циклов
LI:clc	/очистка флага С
sbrc copy_BL,0	/проверка младшего бита множителя
add mul_h,op_AL	/прибавление множимого AL
L2:ror mul_h	/сдвиг вправо
ror mul_l	/ 2-х байтов произведения
Isr copy_BL	/сдвиг множителя вправо
L3:dec c_bit	/уменьшение счетчика циклов
brne LI	/если не 0, продолжаем умножение
mov res,mul_l	/выводимые значения - младший
mov show,mul_h rjmp outled	/ и старший байты произведения
/Деление 16-разрядного	числа на 8-разрядное
div_bin: sbrc op_AH,7 rjmp error sbrc op_BL,7 rjmp error	/ошибки исходных данных
tst op_BL brsh error	/ошибка при делении на 0
cp op_AH,op_BL brge error	/ошибка при переполнении
clr res	/обнуляем частное
Idi c_bit,8 mov copy_AH,op_AH mov copy_AL,op_AL L4:clc	/число итераций
rol copy_AL	/сдвиг
rol copy_AH	/ делимого
Isl res	/сдвиг частного влево
sub copy_AH,op_BL	/вычитание делителя
brcs recov	/если остаток < 0,переход
inc res rjmp L5	/ иначе добавить 1 в частное
recov: add copy_AH,op_ L5:dec c_bit brne L4	BL /восстановление остатка
mov show,copy_AH rjmp outled error: clr show	/пересылка остатка
96
3. Арифметическая обработка данных
out PORTB,show rcall delay ser show out PORTB,show rjmp wait outled: com res out portb,res rcall delay wait: in sw_reg,PIND /ждать, пока кнопка не отпущена com sw_reg brne wait rjmp loop
; Задержка
DELAY: Idi rl0,10 dl:	Idi	r20,255
d2:	Idi	r21,255
d3:	dec	r21
brne d3 dec r20 brne d2 dec rl9 brne dl ret
; Таблица операндов
tabl_op: .db 0xE5,0x10,OxlE,OxAA,0x6C,0xC7,OxlD,0xE2 .db 0x15,0xD6,OxOE,0xB6,0x5D,0xB7,0x03,0xB2
Сложение/вычитание двоичных чисел
Задание 3. Выполнить ряд примеров на сложение и вычитание, выбирая операнды слагаемых AL и BL нажатием кнопок SW0 и SW2. Объяснить результаты операций при нажатиях кнопки SW3 (сложение) и SW4 (вычитание), рассматривая операнды как беззнаковые числа, затем как числа со знаком. В последнем случае вводимые отрицательные числа, содержащие единицу в старшем разряде, следует рассматривать в дополнительном коде. Нажатие кнопки SW7 показывает признаки результата операции, формируемые в регистре SREG (табл. 3.1): С - перенос при сложении (заем при вычитании), Z - признак нулевого результата, N - знак результата при операциях с числами со знаком, V - переполнение разрядной сетки, S=N®V - знак результата вне зависимости от переполнения, Н - межтетрадный перенос (заем).
3.7. Операции над числами с плавающей точкой
97
Таблица 3.1. Байт признаков результата
№ разряда	7	6	5	4	3	2	1	0
Флаг			н	S	V	N	Z	с
Результаты наблюдений (исходные операнды, результаты операций и признаки) представить в виде табл. 3.2 в двоичном и десятичном виде.
Таблица 3.2. Результаты
Число Л2 /Лю	Число В21В10	А + В/А-В	Признаки: HSVNZC
11000001/193	01111111/127	01000000/64	1--- 01
Беззнаковое	Беззнаковое	01000010/66	1 --- 00
11000001/-63	01111111/+127	01000000/+64	100001
Со знаком	Со знаком	01000010/+66	1 1 1000
Умножение и деление целых чисел
Задание 4. Выполнить ряд примеров умножения 8-разрядных двоичных чисел. Нажатие кнопки SW5 показывает младший байт произведения, SW7 - старший байт.
Задание 5. Выполнить деление беззнаковых чисел, 16-разряд-ного делимого на 8-разрядный делитель, с восстановлением остатка при условиях, что делитель не равен 0 и его значение не вызовет переполнения, а также делимое и делитель заданы с нулевыми значениями старших разрядов. Если деление невозможно, выводится предупреждение путем зажигания и гашения всех светодиодов. Нажатие кнопки SW6 показывает частное, SW7 - остаток. Выполнить ряд примеров на деление двоичных чисел.
3.7.	ОПЕРАЦИИ НАД ЧИСЛАМИ С ПЛАВАЮЩЕЙ ТОЧКОЙ
Для выполнения арифметических операций над числами с плавающей точкой в микроконтроллерах необходимо разрабатывать довольно сложные подпрограммы. Исходные числа в формате с плавающей точкой представлены знаком, мантиссой и порядком. Мантисса является правильной дробью, разряды которой представляют значащие разряды числа, порядок показывает фактическое положение точки в записи мантиссы.
Для представления чисел с плавающей точкой разработан и введен стандарт IEEE-754, включающий базовый одинарный, ба
98
3. Арифметическая обработка данных
зовый двойной, расширенный одинарный и расширенный двойной форматы, отличающиеся количеством разрядов и способами представления мантиссы и порядка. На рис. 3.8 приведена структура полей базового 32-разрядного одинарного формата. Формат содержит знаковый разряд S, 8-разрядное поле для смещенного порядка Е и 23-разрядное поле для мантиссы F.
7	0 1	23
S	Е	F
31	о
Рис. 3.8. Базовый одинарный формат
В этом формате при изображении порядка используется смещение, равное 127, скрытый бит целой части мантиссы Fo, содержащий 1. Минимальный (Е = 0) и максимальный (Е = 255) порядки зарезервированы для представления специальных чисел. Диапазон представления чисел в этом формате составляет ± 10±38, а точность 6-7 десятичных разрядов. Приведем несколько примеров кодирования чисел в этом формате:
1024=1,Ох210 01000100 10000000 00000000 00000000	0x44800000
-66 - = -1.00001011х26	11000010 10000101 10000000 00000000
4
0хС2858000 3/16 = 1,1 х2‘3 00111110 01000000 00000000 00000000 0хЗЕ400000
Число в форме с плавающей точкой записывается следующим образом:
А = та • 2Ра,
где тапра- мантисса числа А и его порядок.
Если мантисса та удовлетворяет условию 2’1 < \та\ < 1, то число А является нормализованным. Для совместимости изображения мантиссы с представлением в базовом формате с целой частью («скрываемой единицей») при изображении числа мантиссу умножают на 2, одновременно уменьшая на 1 порядок числа.
В рассмотренных далее алгоритмах для 8-разрядных микроконтроллеров принимается представление истинного нуля нулевым набором (знак, порядок, мантисса). Специальные числовые значения из стандарта (на изображения бесконечности, неопределенности) учитывать не будем.
3.7. Операции над числами с плавающей точкой
99
Во всех приводимых программах арифметических операций для микроконтроллеров AVR принято размещение исходных операндов и результатов во второй половине регистров общего назначения (R16...R31). Первый операнд, символически обозначаемый А, размещается в четырех регистрах А: рА (порядок), тАН, тАМ, mAL (старший, средний и младший байты мантиссы). Второй операнд, символически обозначаемый В, размещается в регистрах В: рВ (порядок), тВН, тВМ, mBL (мантисса). Результат помещается перед выходом из процедуры в регистры рА, тАН, тАМ, mAL.
Сложение
Сумма чисел с плавающей точкой определяется формулой:
С = А + В = 2та<^> Рь\т'а + т'ь\ т'а=та,т'ь=ть1 $Ра~Рь\, если ра- рь> О, т'а=та1?\Ра~Рь\ ,т'ь = ть, если ра-рь<А).
где та и ра - мантисса и порядок первого слагаемого Л; ть и рь -мантисса и порядок второго слагаемого В.
Таким образом, при сложении порядок суммы рс принимает значение большего порядка, а мантисса тс получается путем вычисления выражения, заключенного в скобки. Для вычисления этого выражения необходимо получить разность порядков, а затем мантиссу числа с меньшим порядком сдвинуть вправо на число разрядов, равное разности порядков слагаемых. Такая операция называется выравниванием порядков. После выравнивания порядков следует сложить мантиссы для образования мантиссы суммы. Если мантисса окажется ненормализованной, следует произвести ее нормализацию. Эти положения являются основой построения алгоритма сложения чисел с одинаковым знаком.
Процедура сложения С = А + В чисел с плавающей точкой одного знака включает следующие действия:
•	определяется разность порядков слагаемых Др = (рА - рВ). При неравенстве порядков, если разность порядков больше О, сдвигается мантисса числа В вправо до тех пор, пока порядок
100
3. Арифметическая обработка данных
меньшего числа В не станет равным большему; если разность порядков меньше 0, сдвигается мантисса числа А вправо;
•	после выравнивания порядков слагаемых при Др = 0 производится сложение мантисс. В качестве порядка суммы принимается рА или рВ;
•	проверяется мантисса суммы на возможность нарушения нормализации. При сложении чисел с одинаковыми знаками возможно нарушение нормализации только влево на один разряд. Чтобы получить нормализованную мантиссу, необходимо сдвинуть ее вправо. Порядок увеличивается на единицу, что может привести к переполнению.
На рис. 3.9 приведена схема алгоритма сложения чисел А и В с плавающей точкой и одинаковыми знаками. Каждое слагаемое представлено однобайтовым порядком и трехбайтовой мантиссой в стандартном формате: знак числа, 8-разрядный смещенный порядок, 23-разрядная мантисса со скрытой единицей (всего 32 разряда). Число А перед началом операции размещено в регистрах рА, тВН, тВМ, mBL, число В - в регистрах рВ, рВН, рВМ, pBL. Результат операции сохраняется на месте первого операнда Л.
Процедура сложения с плавающей точкой AddF начинается с проверки знаков слагаемых. Если знаки операндов не совпадают, знак второго операнда изменяется на противоположный и выполняется переход к процедуре вычитания чисел SubF. Если исходные операнды имеют один знак, каждый из них проходит проверку на равенство 0. Если один из операндов равен 0, сложение не проводится, а результат принимается равным другому операнду. При этом в случае равенства 0 первого операнда регистры А и В обмениваются операндами. На этом операция заканчивается. Преобразование результата в стандартный формат не проводится.
Если оба операнда ненулевые, в однобитовом флаге Т регистра состояния микроконтроллера SREG сохраняется общий знак операндов и выполняется их восстановление из базового формата. Поскольку для этого используется одна и та же процедура гес из библиотеки вспомогательных процедур, настроенная на работу с регистрами А, перед вторым восстановлением проводится обмен операндами.
Далее вычитают порядки. При получении отрицательной разности выполняется обмен операндами и вычитание повторяется. При равенстве порядков, когда их разность Ар = 0, выполняется переход
3.7. Операции над числами с плавающей точкой
101
Рис. 3.9. Схема алгоритма сложения с плавающей точкой
102
3. Арифметическая обработка данных
к сложению мантисс. В противном случае предварительно разность Др сравнивается с длиной мантиссы. Если разность превысит 24, то при выравнивании порядков со сдвигом вправо мантиссы меньшего числа она покинет разрядную сетку, происходит потеря значимости. В качестве результата принимается операнд, который в этот момент находится в регистрах первого операнда (рА, mA). Если разность меньше 24, переходим к сдвигу мантиссы меньшего числа, поместив ее в регистры (тАН, тАМ, mAL), разность порядков - в регистре рВ, меньший порядок - в регистре рА. Сдвиг мантиссы вправо сопровождается увеличением порядка в регистре рА, уменьшением в регистре рВ и продолжается до тех пор, пока в регистре рВ не получим 0.
Сложив побайтно мантиссы, проверяем признак переноса, который свидетельствует о нарушении нормализации. При отсутствии его (С = 0) выполняется переход к преобразованию числа в базовый формат. При С = 1 мантиссу суммы сдвигаем вправо и порядок увеличиваем на 1. Выполняем проверку переполнения. Если образовался порядок равный 255, программа завершается с установленным флагом переполнения С. Полученный в регистрах рА, mA результат считается неопределенным и не форматируется. При отсутствии переполнения флаг С сбрасывается и выполняется преобразование в базовый формат.
Алгоритм сложения чисел с одинаковым знаком представлен листингом программы 3.3. Программа позволяет выполнить алгебраическое сложение чисел с учетом знаков слагаемых. В том случае, когда слагаемые имеют разные знаки, происходит обращение к модулю вычитания. С помощью директивы .include "flsub.asm" подключают программный модуль вычитания чисел с плавающей точкой одинаковых знаков. Это позволяет в дальнейшем выполнить посредством одной и той же программы не только сложение, но и вычитание чисел.
В начале общей программы сложения/вычитания выполняют проверку кода выполняемой операции: 1 - для сложения, 2 - для вычитания. В зависимости от заданной операции и знаков операндов запускают процедуру сложения или вычитания беззнаковых чисел (табл. 3.3). При необходимости производится перемена мест операндов. В итоге можно применить одну из двух процедур: сложение или вычитание модулей чисел.
3.7. Операции над числами с плавающей точкой
103
Таблица 3.3. Выполняемые операции
Заданная операция	1-й операнд	2-й операнд	Выполняемая операция
+	+ А	+ в	А + В
+	+ А	-в	А- В
+	-А	+ в	В- А
+	-А	-в	-(А + В)
—	+ А	+ в	А-В
—	+ А	-в	А + В
-	-А	+ в	-(А + В)
-	-А	- в	В-А
Программа 3.3 г
/Программа 3.3 сложения/вычитания чисел с плавающей ;точкой.
/Первый операнд находится в регистрах рА, шАН, mAM, mAL, /второй - в регистрах pB,mBH, mBM, mBL. Результат /возвращается в регистры первого операнда. При переполне-/нии флаг С устанавливается в 1. Вызываемые процедуры /расположены в файлах flsub.asm (модуль вычитания) и /fllib.asm (библиотечные модули)
'k'k'k'k'k-k'k'k-k-k'k'k-k-k-k'k'k-k'k-k'k'k'k'i	t*****************:	*•***•*	: * * * * * * * * * * *
include "8515def.inc"	/файл определений	ДЛЯ	AT90S8515
.include "m8515def.inc" def temp = rl6 def acc = rl7 def cop = rl8 def pA = r20 def mAH = r21 def mAM = r22 def mAL = r23 def pB = r24 def mBH = r25 def mBM = r2 6 def mBL = r27	/файл определений для ATmega8515 /временный регистр /регистр аккумулятор /код операции: / 1 - сложение, 2 - вычитание /операнд А (рА - байт порядка), /(mAH, mAM, mAL - байты мантиссы) /операнд В (рВ - байт порядка), /(mBH, mBM, mBL - байты мантиссы)		
org $000			
Idi temp, low(RAMEND)	/инициализация указателя стека		
out spl, temp
104
3. Арифметическая обработка данных
Idi temp, high(RAMEND) out sph, temp
cpi cop,0x01	/проверка кода операции
breq AddF rjmp SubF /модуль сложения чисел с плавающей точкой ; с одинаковым знаком AddF: mov асс,рА
eor асс,рВ
brpl AddFl
Idi temp,0x80	/изменение знака
add pB,temp rjmp SubF
AddFl: rcall cp_B_0 /сравнение В c 0
breq Quit rcall cp_A_0	/сравнение A c 0
brne AddF2 rcall swapAB	/обмен А и В
rjmp Quit
AddF2: bst pB,7	/сохранение знака T=pB.7
rcall rec	/восстановление
rcall swapAB	/ чисел через регистры А
rcall rec	
mov acc,pA	/вычитание порядков
sub acc,pB	
brpl AddF3	/переход, если больше 0,
rcall swapAB	/ иначе обмен и
mov acc,pA	/ снова вычитание
sub acc,pB	
AddF3: breq AddF6	/переход, если порядки равны
cpi acc,24	/сравниваем
brmi AddF4	
rjmp AddF7	/переход при потере значимости
AddF4: mov pA,acc	/разность порядков в рА
rcall swapAB	/разность теперь в рВ
AddF5: rcall shift	/сдвиг в регистрах mA
inc pA	/увеличиваем порядок меньшего числа
dec pB	/уменьшаем разность порядков
brne AddF5	
AddF6: add mAL,mBL	/сложение мантисс
3.7. Операции над числами с плавающей точкой
105
adc mAM,mBM adc тАН,тВН brcc AddF7 inc рА cpi рА,Oxff breq Quit rcall shift
AddF7: rcall pack Quit: rjmp Quit .include ’’flsub.asm" .include "fllib.asm"
/проверка нарушения нормализации
;корректируем порядок
;выход с флагом переполнения
;сдвиг мантиссы вправо
/форматирование результата
/подключение модуля вычитания
/ и библиотечных процедур
Типовые процедуры, используемые алгоритмами сложе-ния/вычитания, помещены в библиотеку, подключаемую директивой .include "fllib.asm". Библиотека fllib содержит процедуры восстановления операнда из базового формата гес, упаковки в базовый формат pack, обмен операндов swapAB, сдвига мантиссы вправо на один разряд shift, логического сложения 24-разрядной
мантиссы для сравнения с нулем.
Восстановление числа из базового формата производится с помощью четырех операций, как показано на рис. 3.10, а. Вначале при помощи логического сдвига влево ф младший бит порядка из регистра старшего байта мантиссы тАН выталкивается на флаг переноса С. Затем выполняется циклический сдвиг влево содержимого регистра порядка рА ®. Благодаря этому 8-разрядный порядок полностью оказывается в регистре рА. Далее мантисса тАН сдвигается вправо ® и в разряд 7 регистра тАН восстанавливается скрытая 1 @.
б
Рис. 3.10. Схема восстановления числа из базового формата (а) и преобразования в базовый формат (б)
106
5. Арифметическая обработка данных
Преобразование результата операции, помещаемого после обработки в регистры А, в базовый формат выполняется по схеме на рис. 3.10, б. Вначале сохраняем порядок рА в одном из регистров, например рВ ф. Затем знак результата, сохраняемый на флаге Т, переносим на флаг С @. Выполняя сдвиг вправо регистра порядка рА, вводим знак числа в разряд 7 регистра рА ®. Передачу младшего бита порядка в старший разряд мантиссы шАН выполняем за два шага: сначала из разряда 0 регистра рВ в Т @, затем из Т в разряд 7 регистра тАН ® на место старшего разряда мантиссы.
Обмен 32-разрядных операндов в регистрах А и В осуществляется с использованием логической функции Исключающее ИЛИ. Действительно, получив сначала А <— А Ф В, выполняем далее В <— В Ф А и А <— А Ф В. Эти операции повторяют отдельно для каждого байта порядка и мантиссы (всего 12 операций). Используемые библиотечные процедуры с комментариями представлены в листинге программы 3.4.
Программа 3.4
• **********’А'***********7*г**’А-^г*********’Лг^г'Аг’А-***^г г
/Модуль 3.4 библиотечных процедур fllib.asm
.******************************************** Л
/Восстановление операнда из базового формата
rec: Isl тАН rol рА Isr тАН
ori тАН, 0x80 ret
/Упаковка в базовый pack: mov pb,pa clc brtc m2 sec
m2 : ror pA clc bst pb,0 bld mAH,7 ret
/Обмен операндов swapAB:
eor pA,pB eor pB,pA eor pA,pB
eor mAL,mBL eor mBL,mAL eor mAL,mBL
/младший разряд порядка /восстановление порядка /сдвиг вправо мантиссы /восстановление скрытой
формат
/сохраняем pA
/проверяем знак
/вводим знак в рА.7
/младший разряд порядка
/ переносим в АН.7
/обмен регистров
/ рА и рВ
/ за три операции
3.7. Операции над числами с плавающей точкой
107
еог mAM,mBM
еог тВМ,тАМ
еог тАМ,тВМ
еог тАН,тВН
еог тВН,тАН еог тАН,тВН ret
;Сложение для сравнения А(В) с 0
ср_А_0: mov асс,рА
or асе,тАН
or асе,тАМ
or асе,mAL ;при А=0 возвращает флаг Z=1
ret	;при А^О - Z=0
ср_В_0: mov асс,рВ
or асс,тВН
or асс,тВМ
or acc,mBL ; при В=0 возвращает флаг Z=1 ret	;при В^О - Z=0
;Сдвиг вправо 24-разрядной мантиссы mA shift: Isr mAH
ror mAM
ror mAL clc ret
Вычитание
Разность чисел с плавающей точкой определяется формулой:
С = А - В = 2тах(^’ Рь\т'а - т'ь\ т'а=та,т'ь- ть12^Ра~рь\ если Ра - Рь> 0, тп'а =та12^Ра~РЬ\ т'ь =ть, если ра - pb <Q,
Так же, как и при сложении, порядок разности рс принимает значение большего порядка, выравнивание порядков выполняется аналогично вышеописанному. После этого из мантиссы уменьшаемого та вычитается мантисса вычитаемого mh и при необходимости проводится нормализация мантиссы разности тс.
Операция С = А - В начинается с проверки знаков слагаемых (рис. 3.11). Если знаки операндов не совпадают, знак вычитаемого изменяется на противоположный и выполняется переход к процедуре сложения чисел AddF. Если исходные операнды с одинаковым знаком, каждый проходит проверку на равенство 0. Если один из операндов равен 0, вычитание не проводится, а результат принимается равным другому операнду, при необходимости корректируется знак результата.
108
3. Арифметическая обработка данных
СТ SubF
Сдвиг mA вправо, Ар = Др - 1
Да
А^В
mA = mB - mA, рА<- рВ
Рис. 3.11. Схема алгоритма вычитания с плавающей точкой
3.7. Операции над числами с плавающей точкой
109
Если оба операнда не равны 0, в Т сохраняется знак уменьшаемого и восстанавливают оба числа. При этом восстановлению числа В предшествует регистровый обмен А о В. Затем выполняют сравнение порядков. Если порядки равны, сравнивают мантиссы, при их равенстве результат операции считается равным 0. Выявляется большее число без учета знака, которое помещается в регистры В. Если при этом выполняется обмен регистров, то хранимый в Т знак меняется на противоположный.
Дальнейшие действия связаны с выравниванием порядков и сдвигом вправо мантиссы меньшего числа, которое находится в регистрах А. После выравнивания порядков выполняется вычитание мантисс и формирование результата в регистрах А. При вычитании мантисс с одинаковым знаком может возникнуть нарушение нормализации вправо, т. е. появление одного или нескольких нулей в старших разрядах мантиссы разности. Устранение нарушения нормализации выполняется путем сдвига мантиссы разности влево и уменьшения порядка результата рА на единицу при каждом сдвиге. Если при уменьшении порядка возникнет антипереполнение (при изменении порядка от минимально допустимого значения 0x00 к максимальному значению OxFF), выполняется выход из процедуры с установленным флагом С = 1 и возврат в головной модуль программы с неопределенным результатом. После устранения нарушения нормализации выполняется форматирование результата в регистрах А и выход из процедуры вычитания в основную программу.
Программа модуля вычитания, согласно описанному алгоритму, представлена в листинге программы 3.5. В ней, как и в предыдущем случае, использованы стандартные библиотечные процедуры для сдвига мантиссы, обмена операндов, преобразования форматов. Следует отметить, что использование команд с условным переходом, выполняемых по механизму относительной адресации, привело к необходимости выполнения длинных переходов за два шага: сначала на близко расположенную локальную метку QuitS, а затем с помощью команды безусловного перехода RJMP на метку выхода Quit.
Программа 3.5
********************************************************** г
/Программа 3.5 модуля вычитания чисел с плавающей точкой ;с одинаковым знаком выполняет вычитание из 1-го числа А,
по
3. Арифметическая обработка данных
/размещенного в регистрах (рА,тА) , 2-го числа, размещенного /в регистрах (рВ,МВ).
/Исходные операнды представлены в базовом формате.
/Результат операции возвращается в регистры 1-го числа
/(рА,тА) в базовом формате.
/Программный модуль размещается в файле flsub.asm и /подключается к основной программе с помощью директивы / .include "flsub.asm"
********************************************************** z
SubF:	mov асс,рА	/сравнение знаков чисел
еог асс,рВ brpl SubFl Idi temp,0x80	/при неравных знаках смена
add pB,temp rjmp AddF	/ знака 2-го числа
SubFl: rcall cp_B_O	/проверка В на 0
breq Quit	
rcall cp_A_0	/проверка А на 0
brne SubF2 rcall swapAB Idi temp,0x80	/обмен операндов
add pA,temp	/ со сменой знака результата
QuitS: rjmp Quit	
SubF2: bst pA,7	/сохранение знака в Т
rcall rec	/восстановление числа А
rcall swapAB	/теперь в рА порядок 2-го числа
rcall rec	/восстановление числа В
mov acc,pB	/из порядка 1-го вычитаем
sub acc,pA brne SubF3	/ порядок 2-го
cp mBH,mAH	/при равенстве порядков
brne SubF3 cp mBM,mAM brne SubF3	/ сравниваем мантиссы
cp mBL,mAL brne SubF3 clr pA	/если числа равны,
clr mAH clr maM clr mAL rjmp Quit	/ результат равен 0
SubF3: brcc SubF4
rcall swapAB brbc 6,s2
/переход, если 1-е число / (оно в рВ,шВ) больше, / иначе обмен числами / и изменение знака в Т
3.7. Операции над числами с плавающей точкой
111
rjmp s3 s2:	set
rjmp SubF4 s3:	clt
SubF4: mov acc,pB sub acc,pA breq SubF7 cpi acc,24 brmi SubF6 rcall swapAB
rjmp SubF9
SubF6: rcall shift dec асе brne SubF6
;снова вычитание порядков
;переход при одинаковых порядках
/передача большего числа
; в (рА,тА) перед
; форматированием результата
;сдвиг мантиссы меньшего числа
; в mA, пока
; разность порядков не равна О
/Вычитание мантисс и сохранение разности в mA
SubF7:	sub mBL,mAL	
mov	mAL,mBL	
sbe	mBM,mAM	/вычитание с заемом
mov	mAM,mBM	
sbe	mBH,mAH	/вычитание с заемом
mov	mAH,mBH	
mov	pA, pB	/передача порядка результата в рА
SubF8:	sbre mAH,7	/проверка нарушения нормализации
rjmp	SubF9	/переход, если нарушения нет,
dec	pA	/ иначе, не сдвигая мантиссу,
cpi	pA,Oxff	/ проверяем антипереполнение,
sec		/ заранее установив флаг в 1,
breq Quits		/при антипереполнении выходим
		/ с флагом 1, иначе
Isl	mAL	/ сдвигаем мантиссу mA влево
rol	mAM	
rol	mAH	
clc		/ и сбрасываем флаг
rjmp	SubF8	/повторяем проверку
SubF9:	rcall pack	/форматируем результат
rjmp	Quit	/выход из процедуры вычитания
Следует заметить, что описанные здесь алгоритмы и программы сложения и вычитания не являются полностью оптимальными. Например, восстановленные операнды можно с учетом заданной операции и операндов представить в дополнительных кодах со знаковым разрядом; в дальнейшем проводить операции сложения мантисс в дополнительных кодах, исключив тем самым необходимость перестановки операндов (табл. 3.4).
112
3. Арифметическая обработка данных
Таблица 3.4. Операции в дополнительных кодах
Заданная операция	1-й операнд	2-й операнд	Выполняемая операция
+	+ А	+ в	А + В
+	+ А	-в	А + [В] доп
+	-А	+ в	[А]доп + В
+	-А	-в	[А]доп + [В]доп
-	+ А	+ в	А “1" [В]доп
—	+ А	-в	А + В
-	-А	+ в	[А]доп + [В]д0П
—	-А	-в	[А]д0П + В
В рамках практикума не предполагалось получение оптимального кода по времени исполнения и по размеру, а требовалось лишь достижение результативности алгоритмов. Тем не менее предложенные программные решения могут оказаться достаточно эффективными в целом ряде приложений.
Умножение
Произведение двух чисел с плавающей точкой вычисляется по формуле:
С =	= 2Ра+Рь.
Алгоритм умножения чисел с плавающей точкой С = А х в включает следующие действия:
•	сложение знаков сомножителей по модулю 2 для определения знака произведения;
•	сложение порядков сомножителей;
•	перемножение мантисс как чисел с фиксированной точкой;
•	нормализация и коррекция порядка произведения при получении ненормализованной мантиссы произведения.
В процессе сложения порядков может возникнуть как переполнение, так и антипереполнение. При перемножении нормализованных мантисс не может быть нарушения нормализации влево, а нарушение нормализации вправо - только на один бит.
При сложении смещенных порядков может возникнуть перенос, что необходимо учитывать при определении порядка произведения.
На рис. 3.12 приведена схема алгоритма умножения А на множитель В, начиная с младших разрядов множителя В со сдвигом вправо суммы частичных произведений и множителя. Умножение
Рис. 3.12. Схема алгоритма умножения с плавающей точкой
114
3. Арифметическая обработка данных
начинается с проверки сомножителей на 0. Если один из сомножителей равен нулю, результат приравнивают 0 и операция прекращается. Определяется знак произведения, сохраняемый на флаге Т. Далее восстанавливают мантиссы сомножителей.
Затем выполняется сложение смещенных порядков. Если при сложении порядков перенос не возник, из полученной суммы вычитается 127, так как в сумме это значение участвовало дважды. При отсутствии заема (флаг С = 0) выполняется переход к умножению мантисс. Наличие заема при вычитании 127 свидетельствует о возникновении антипереполнения. Происходит выход из процедуры умножения с флагом С = 1.
Если при сложении порядков возник перенос, эквивалентный потере 256, к сумме добавляют корректирующее значение 129 (-256 + 129 = -127). Отсутствие переноса в этом случае сопровождается перемножением мантисс, наличие переноса свидетельствует о переполнении и прекращении операции.
Умножение мантисс выполняется с помощью циклической процедуры из 24 итераций (по числу разряда множителя), включающей сдвиг мантиссы множителя вправо на один разряд, анализ на флаге С очередного бита множителя, прибавление множимого к сумме частичных произведений (если С = 1) или пропуск сложения (если С = 0), сдвиг мантиссы произведения вправо. При умножении мантисс разряды произведения, покидающие при сдвиге вправо разрядную сетку, утрачиваются.
Так как цикл завершается операцией сложения, после этого проверяется значение переноса. Если С = 0, полученная мантисса произведения гпС нормализована, выполняется преобразование произведения в базовый формат. Если С = 1, мантисса нормализуется путем сдвига вправо, порядок произведения увеличивается на 1 и выполняется проверка на переполнение. Алгоритм умножения представлен листингом программы 3.6.
Программа 3.6 'k'k'k'k'k'k'k'k'k'k'kic'k'k'k'k'k'k'fc'k'k'k'k'fc'k'k'k'k'k'-k'k'k-fc'k'k-k'k'-k'k'k'k'k-fc'k'k'k-k-fc'k'k'k'k'k'k'k'k'k'k
/Программа 3.6 умножения чисел с плавающей точкой
.include ”8515def.inc"	/файл определений для AT90S8515
/.include	"m8515def.inc" /файл определений для	ATmega8515
.def temp	=	rl6	/временный регистр
.def асе	=	rl7	/аккумуляторный регистр
.def Cnt	=	rl8	/счетчик циклов
3.7. Операции над числами с плавающей точкой
115
.def рА = г20	;определение множимого
.def тАН = г21 .def тАМ = г22 .def mAL = r23 .def рВ = г24	;определение множителя
.def тВН = г25 .def тВМ = г26 .def mBL = r27 .def_pC = r28	/определение произведения
.def тСН = г2 9	/ (_рС - переопределение
.def тСМ = гЗО	/ компилятора)
.def mCL = r31 .org $000 Idi temp, low(RAMEND)	/ инициализация указателя стека
out spl, temp Idi temp, high(RAMEND) out sph, temp clr_pC	/очищаем регистры результата
clr mCL clr mCM clr mCH rcall cp_A_0	/проверка А на 0
breq Quit rcall cp_B_0	/проверка В на 0
breq Quit mov acc,pA	/получение знака произведения
eor acc,pB bst acc,7	/сохранение знака в Т
rcall rec	/восстановление рА и тАН
rcall swapAB rcall rec	/восстановление рВ и тВН
mov_pC,pB add_pC,pA brcs MulFl subi_pC,127	/сложение смещенных порядков /вычитание лишнего смещения
brcc MulF2 rjmp Quit MulFl:	Idi temp,129	/если был перенос при сложении
add_pC,temp	/ -256+129=-127
brcs Quit
/умножение мантисс (mC=mAxmB)
116
3. Арифметическая обработка данных
MulF2:Idi Cnt, 24	/инициализируем счетчик циклов
MulF3:ror mBH	/сдвиг множителя
ror mBM	/ для анализа младшего бита
ror mBL	
brcc MulF4	/если бит множителя равен 1,
add mCL,mAL	/ прибавляем множимое(L-байт),
ade	mCM,mAM	/ затем М-байт
ado mCH,mAH	/ и Н-байт
MulF4 :	dec Cnt	/уменьшаем счетчик циклов
brne MulF5	/если не конец, повторяем
rjmp MulF6	
MulF5: ror mCH	/сдвигаем вправо сумму
ror mCM	/ частичных
ror mCL	/ произведений
rjmp MulF3	
/проверка нормализации MulF6:brcc MulF7	/результат нормализован
ror mCH	
ror mCM	
ror mCL	
inc _pC	/увеличиваем порядок
cpi _pC, OxFF	
sec	/С=1
breq Quit	/выход с флагом переполнения
MulF7: mov pA, _pC	/подготовка результата
mov mAL,mCL mov mAM,mCM mov mAH,mCH	/ для форматирования
rcall pack	/преобразование формата
Quit: rjmp Quit	/операция завершена
.include ’’fllib.asm”	
Приведем ряд примеров на умножение. В правом столбце сомножители и результат умножения представлены в базовом формате:
1 3 3
— х —= —	3F000000 х 3FC00000 = 3F400000
2 2 4
(-64) х (-512) = 32768	С2800000 х С4000000 = 47000000
-256 х 2 =-512	СЗ800000х 40000000 = С4000000
3.7. Операции над числами с плавающей точкой
117
Деление
Частное при делении двух чисел с плавающей точкой вычисляется по формуле:
С = А1В = та/тъ-2Р°-Рь.
При делении чисел с плавающей точкой знаки операндов складывают по модулю 2 для определения знака частного, из порядка рА вычитают порядок рВ, мантиссы делят как числа с фиксированной точкой. При делении мантисс нарушение нормализации может возникнуть только влево на один разряд, так как деление нормализованных мантисс при условии mA > mB дает целую часть частного, равную 1. Для деления нормализованных мантисс при условии mA < mB нарушения нормализации нет (0,5 < mC < 1).
Схема алгоритма деления чисел приведена на рис. 3.13. Вначале выполняется проверка делимого и делителя на равенство 0. Если делитель равен 0, устанавливается флаг ошибки (как при переполнении). Если делимое равно 0, частное принимается равным 0.
Если операнды ненулевые, осуществляется преобразование формата каждого операнда и размещение их в прежних регистрах. После вычитания смещенных порядков смещение разности утрачивается, поэтому необходимо полученную разность порядков увеличить на значение смещения 127. При возникновении переполнения (антипереполнения) выполняется выход с установленным флагом.
Далее следует циклическая процедура деления мантисс методом, известным как деление с восстановлением остатка. После завершения цикла деления проводится нормализация частного.
Особенностью программной реализации описываемого алгоритма деления является то, что уже после первого вычитания значение бита частного поступает в младший разряд регистра частного. По окончании цикла этот бит окажется на позиции старшего разряда. Если он равен 1, это говорит о том, что mA > mB и сдвиг мантиссы проводить не надо. Частное пересылается на место делимого, и форматируется результат операции. Если старший бит мантиссы шС окажется равным 0 (mA < mB), для получения нормализованной мантиссы частного необходимо сдвинуть ее влево на один разряд и уменьшить порядок на 1. При возникновении антипереполнения устанавливается флаг и частное не определено.
Деление чисел с плавающей точкой представлено листингом программы 3.7.
118
3. Арифметическая обработка данных
DivF
____ I __________
рС = 0, шС = О
Т <- sA © sB, восстановление А и В, рС = рА - рВ
рС = рС + 127 рС = рС + 127
—  <3f=0^>H|eT
I Счетчик циклов 24 I
Сдвиг вправо mA и шВ
mA = mA - mB
mA = mA + mB
н---------
Сдвиг mA и частного тС влево
Сдвиг тС влево, рС = рС - 1, флаг С= 1
Нет у----------1--------
----Антипереполнение?
Передача С -> А, форматирование результата
Рис. 3.13. Схема алгоритма деления с плавающей точкой
3.7. Операции над числами с плавающей точкой
119
Программа 3.7
k-k-k-k-kk-kk-k	k-kkkkk-kk^-kk-k-k	kkk-k-k-k-k-kkk-k'k-kk*	t-k-k-k-k-k-k-k-kk	kkkk-k'k-kkkk-
Программа	3.7 деления	чисел с плавающей точкой		
	*************	kk-kkkk-kkk-kk-kkk*	:k~kkkkkkkk	kkkkkkkkkk-
include "	8515def.inc"	;файл определений для		AT90S8515
.include	"m8515def.inc	" /файл определений для		ATmega8515
def temp	= Г16	/временный регистр		
def acc	= rl7	/аккумуляторный регистр		
def Cnt	= rl8	/счетчик циклов		
def pA	r20	/определение	делимого	А
def mAH =	r21			
def mAM =	r22			
def mAL =	r23			
def pB	r24	/определение	делителя	В
def mBH =	r25			
def mBM =	r26			
def mBL =	r27			
def _pC =	r28	/определение	частного	С
def mCH =	r29			
def mCM =	r30			
def mCL =	r31			
.org $000
Idi temp, low(RAMEND)	/инициализация указателя стека
out spl, temp Idi temp, high(RAMEND)	
out sph, temp clr _pC	/	очищаем регистры частного
clr mCL clr mCM clr mCH rcall cp_B_0	/	проверка делителя на 0
sec breq Quit	/	выход с флагом ошибки деления
rcall cp_A_0	/	проверка делимого на 0
breq Quit mov acc, pA	/	получение знака частного
eor acc, pB bst acc,7	/	сохранение знака в Т
rcall rec	/	восстановление рА и шАН
rcall swapAB rcall rec	/	восстановление рВ и mBH
rcall swapAB	/	оставляем их в своих регистрах
;вычитание смещенных порядков mov _рС,рА sub _рС,рВ
120
3. Арифметическая обработка данных
Ьгсс DivFl	
Idi temp,127 add _pC,temp brcs DivF2	;при заеме (C=l)
sec	; и C=0 установка флага
rjmp Quit	; антипереполнения
DivFl: Idi temp,127 add _pC,temp	;при отсутствии заема (С=0)
brcs Quit cpi _pC,OxFF sec breq Quit	; и С=1 переполнение
; деление мантисс (mc=	:mA/mB)
DivF2: Idi Cnt,24	/инициализируем счетчик циклов
Isr mAH ror mAM ror mAL	;сдвиг делимого вправо
Isr mBH ror mBM ror mBL	;сдвиг делителя вправо
DivF3: sub mAL,mBL sbe mAM,mBM sbe mAH,mBH brcc DivF4	;шА-шВ
add mAL,mBL	/восстановление mA
adc mAM,mBM adc mAH,mBH	/ (остатка)
clc rjmp DivF5	/бит частного равен 0
DivF4: sec	/бит частного равен 1
DivF5: rol mCL rol mCM rol mCH	/сдвиг частного влево
Isl mAL rol mAM rol mAH	/сдвиг mA влево
dec Cnt	/уменьшаем счетчик циклов
brne DivF3 ;проверка нормализации	/повторяем, пока Cnt/0
sbre mCH,7	/старший бит мантиссы частного
rjmp DivF6	/результат нормализован
rol	mCL	/сдвигаем
rol	mCM	/ мантиссу частного
rol	mCH	/ влево
dec	_pc	/уменьшаем порядок частного
cpi	_pC,OxFF	
sec		
3.8. Программы для преобразования чисел
121
breq Quit DivF6: mov pA,_pC mov mAL,mCL mov mAM,mCM mov mAH,mCH rcall pack Quit: rjmp Quit
;выход с флагом антипереполнения /подготовка результата
; для форматирования
/преобразование формата
/операция завершена
.include "fllib.asm”
Приведем ряд примеров на деление. В правом столбце операнды и частное представлены в базовом формате:
2-1-1
4’2~2
32768: (-512)= -64
-512 :2 = -256 1024: 10= 102,4
3F400000 / 3F000000 = 3FC00000
47000000 / С4000000 = С2800000 С4000000 / 40000000 = С3800000
44800000/ 41200000 = 42СССССС
Практическая часть
Задание 1. Открыв AVR Studio 4, создать проект. Загрузить программу 3.3 для проверки операций сложения и вычитания чисел с плавающей точкой. Привести ряд примеров с разными значениями операндов, воспользовавшись ручной загрузкой операндов в регистры окна I/O. Выполнить операции, фиксируя время их исполнения.
Задание 2. Создать проект и загрузить программу 3.6 для умножения чисел с плавающей точкой. Привести ряд примеров с разными значениями операндов. Оценить время выполнения операции умножения. Заменить программу умножения программой деления 3.7 и проверить ее работу.
3.8. ПРОГРАММЫ ДЛЯ ПРЕОБРАЗОВАНИЯ ЧИСЕЛ
Преобразование двоичных и двоично-десятичных чисел
При вводе и выводе числовых данных часто необходимо выполнять преобразования десятичных и двоичных целых и дробных чисел из одного формата в другой, преобразуя, например, вводимые двоично-десятичные числа в двоичные для последующей обработки и обратно, двоичные числа в двоично-десятичные после завершения обработки перед выводом результатов.
122
3. Арифметическая обработка данных
Применяемые способы преобразования часто основаны на использовании методов сдвига и коррекции. При этом сдвиг двоичных чисел выполняется без коррекции, для десятичных чисел необходима коррекция в зависимости от направления сдвига.
Если при сдвиге вправо (деление на 2) слева из старшего десятичного разряда поступает 0, коррекция не проводится. При поступлении 1, она приобретает вес 8 вместо 5, что должно быть при делении 1 старшего разряда на 2 (при сдвиге вправо). В связи с этим необходима коррекция вычитанием 3. Пример преобразования 2-разрядного 2-10 числа:
Исходное	1 0100 0100 = 144
Сдвиг вправо	1010 0010
Коррекция	- ООП
Результат	0111 0010 =72
Программа процедуры сдвига вправо и последующей коррекции для одного упакованного байта, помещенного в аккумуляторный регистр:
divd2: ror асе ror rl4	/сдвиг байта вправо ;сохранение младшего бита ; операнда из С в г14
push асе	/сохранение в стеке
andi acc,OxOf cpi acc,8 brcs nocl subi acc,3 nocl: mov rl3,acc	/если из старшей тетрады сдвинут 0, / коррекция не нужна, /иначе вычитание 3 /сохранение младшей тетрады в г13
pop acc andi acc,0xf0 cpi acc,0x80 brcs noc2 subi acc,0x30 noc2: or acc,rl3 rol rl4	/восстановление из стека /если из старшей тетрады сдвинут 0, / коррекция не нужна, / иначе вычитание $30 /объединение тетрад /восстановление бита в С
ret
При сдвиге влево (умножение на 2) все значения тетрад, которые меньше 5, дают верный результат. Для всех значений, начиная от 5 и выше, необходимо формировать единицу переноса, так как после умножения на 2 они дают результат, равный 10 и более. Коррекцию удобно провести перед сдвигом влево путем прибав-
3.8. Программы для преобразования чисел
ПЪ
ления 3 к тетраде. Это дает возможность автоматически получить перенос после сдвига влево. Пример преобразования 2-разрядного 2-10 числа:
Исходное	0101 0100 =54
Коррекция + ООН
1000 0100
Сдвиг влево 1 0000 1000 = 108 (результат)
Программа процедуры коррекции и сдвига влево для одного упакованного байта:
muld2: ror г14 /сохранения в г14 бита С,
; полученного от предыдущего сдвига
push асе	/сохранение в стеке
andi acc,0x0f
cpi acc,5	/сравнение с 5 младшей тетрады
bres noclm /коррекция не нужна, если асс<5,
subi асс,-3	/ иначе прибавление 3
noclm: mov г13,асс /сохранение в г13
pop асе	/восстановление из стека
andi acc,0xf0
cpi acc,0x50 /сравнение с 5 старшей тетрады
bres noc2m /коррекция не нужна, если асс<$50,
subi асс,-$30	/ иначе прибавление $30
noc2m: or асс,г13 /объединение тетрад
rol г14	/восстановлен бит С для младшего
/ разряда сдвигаемого байта rol асе	/сдвиг байта влево
ret
Преобразование целого десятичного числа в двоичное можно выполнить путем последовательного деления на 2 исходного значения, затем получаемых частных, используя образуемые остатки (0 или 1) в качестве разрядов двоичного числа, начиная с младшего.
Пример:
71:2 = 35(1 - младший разряд двоичного числа);
35:2= 17(1);
17:2 = 8(1);
8:2 = 4(0);
4:2 = 2(0);
2:2= 1(0) - старшие разряды.
Результат: 1000111
124
3. Арифметическая обработка данных
Деление упакованного десятичного числа на 2 можно выполнить, последовательно применяя для каждого байта, начиная со старшего, процедуру сдвига и коррекции divd2.
Алгоритм преобразования ^-байтового двоично-десятичного числа в «-байтовое двоичное (рис. 3.14, а) содержит два последовательно выполняемых цикла: первый цикл осуществляет процедуру divd2 (побайтовый циклический сдвиг вправо с коррекцией двоично-десятичного числа и получение остатка на флаге переноса С), второй цикл передает остаток из С в старший разряд старшего байта двоичного числа с циклическим сдвигом вправо остальных разрядов байта и последующее повторение сдвига вправо остальных (w- 1) байтов двоичного числа. Описанные операции повторяются 8и раз, определяя все биты двоичного числа.
Рис. 3.14. Схемы алгоритмов преобразования целых чисел: а - двоично-десятичного в двоичное; б - двоичного в двоично-десятичное
Преобразование целого двоичного числа в десятичное можно выполнить, используя представление двоичного числа в виде полинома Горнера:
D — (.. .(dn_\ х 2 + х 2 + ...+ d\) х 2 + d$.
3.8. Программы для преобразования чисел
125
Умножив исходное число на 2 (или сдвинув код числа влево на 1 разряд) можно выделить старший разряд добавив его значение (0 или 1) в десятичную ячейку и удвоив ее содержимое. Действия повторяют для всех разрядов двоичного числа. Для умножения на 2 десятичного числа используется процедура muld2, применяемая последовательно для каждого байта числа, начиная с младшего.
Преобразование «-байтового двоичного числа в ^-байтовое двоично-десятичное начинается со сдвига влево на один разряд двоичного числа. После сдвига всех байтов двоичного числа, начиная с младшего, начинается цикл, в котором, также начиная с младшего байта, проводится коррекция и сдвиг влево каждого байта двоично-десятичного числа с использованием процедуры muld2. Циклический сдвиг влево через флаг С позволяет перенести значение выталкиваемого бита двоичного числа в младший разряд двоично-десятичного регистра, а при последующих сдвигах образуемый перенос из предыдущего байта в следующий. Цикл со сдвигом двоичного числа и вслед за ним двоично-десятичного повторяется 8и раз согласно алгоритму на рис. 3.14, б.
Преобразование десятичной дроби в двоичную выполняется традиционным способом: путем умножения на 2 исходной дроби и дробных частей получаемых произведений. Целые части произведений, принимающие значения 0 или 1, образуют ряд значений разрядов двоичной дроби, начиная со старшего, поэтому в алгоритме преобразования можно применить процедуру muld2 умножения на 2 десятичного числа с коррекцией. Образуемое значение переноса при обработке старшего байта дроби подают в младший разряд ячейки двоичной дроби, одновременно сдвигая все остальные разряды влево.
Преобразование двоичной дроби в десятичную можно выполнить, используя представление дроби в виде полинома Горнера:
D = 2~\d_x +...+	+2-’j_„)...).
Сдвигая вправо двоичную дробь и подавая выталкиваемые младшие разряды в ячейку десятичной дроби слева, где также выполняется деление на 2, можно получить десятичный эквивалент. Деление и коррекция каждого байта десятичной дроби, начиная со старшего, осуществляется с помощью процедуры divd2.
126
3. Арифметическая обработка данных
Далее приведена тестовая программа, демонстрирующая преобразование целых чисел. Исходные для преобразования данные и результаты размещают в памяти так, что младшие разряды чисел находятся по адресу bram (dram), старшие - по адресу bram + (п - 1) (dram + k- 1).
Программа 3.8
	k-k-k-k-k-k-k-k'k'k'k-k-k-k'k-k-k-k-k-k-k-k-k-k-k-k'k'k-k'k-k'k'k'k
/Тестовая программа для	преобразования упакованного целого
/десятичного числа длиной к байт в двоичное длиной п байт,	
/двоичного целого - в десятичное упакованное,	
/упакованной десятичной	дроби в двоичную и обратно.
. к-к^'к-к-к'к-к-к-^-к-к-к-к-к'к'к'к-к-к-к-к')	
.include ”8515def.inc”	/файл определений для AT90S8515
.equ dram = $060	/адрес десятичного числа
.equ bram = $0 6A	/адрес двоичного числа
.equ k = 2	/длина операндов для теста
.equ n = 1	
.def acc = rl6	/регистр-аккумулятор
.def bit_count = rl7	/счетчик битов
.def byte_count = rl8	/счетчик байтов
.org $000	
Idi acc,low(RAMEND)	/установка
out SPL,acc	/ указателя стека
Idi acc,high(RAMEND)	/ на последнюю
out SPH,acc	/ ячейку ОЗУ
/Преобразование десятичного числа в двоичное /Исходные данные для теста ($60)=37, ($61)=02 idb: Idi bit_count,8*n
loop: Idi XL,low(dram+k) Idi XH,high(dram+k) clc
Idi byte_count,k dloop: Id acc,-x rcall divd2 st x,acc dec byte_count brne dloop
Idi XL,low(bram+n)
Idi XH,high(bram+n)
Idi byte_count,n bloop: Id acc,-x
/установка
/ начального адреса /С=0
/сдвиг вправо десятичного числа / и коррекция
/установка
/ начального адреса
3.8. Программы для преобразования чисел
127
ror асе
st х,асс
dec byte_count brne bloop dec bit_count brne loop
/Результат ($6A)=ED
;сдвиг вправо
; двоичного числа
/повторить для всех разрядов
/Обратный перевод в упакованное десятичное
ibd: Idi bit_count,8*n Idi XL,low(dram+k) Idi XH,high(dram+k) Idi byte_count,k clr acc s_loop: st -x,acc dec byte_count brne s_loop
loopl: Idi XL,low(bram) Idi XH,high(bram) clc
Idi byte_count,n bloopl: Id acc,x rol acc st x+,acc dec byte_count brne bloopl Idi XL,low(dram) Idi XH,high(dram) Idi byte_count,k dloopl: Id acc, x rcall muld2 st x+,acc dec byte_count brne dloopl dec bit count
/установка
/ начального адреса
/ и очистка ячеек
/ десятичного числа
/установка
/ начального адреса
/ С=0
/сдвиг влево
/ двоичного числа
/установка
/ начального адреса
/коррекция десятичного числа
/ и сдвиг влево
brne loopl	/повторить для всех разрядов
/Преобразование упакованной десятичной дроби в двоичную /Исходные данные для теста ($60)=50, ($61)=62 fdb: Idi bit_count,8*n loop: Idi XL,low(dram) /установка
Idi XH,high(dram) / начального адреса
clc	/С=0
128
3. Арифметическая обработка данных
Idi byte_count,к
dloop: Id асс,х rcall muld2 st x+, acc dec byte_count
;коррекция
; десятичной дроби
; и сдвиг влево
brne dloop
Idi XL,low(bram)	/установка
Idi XH,high(bram)	; начального адреса
Idi byte_count,n
bloop: Id acc,x
rol acc	/сдвиг влево
st x+, acc	/ двоичной дроби
dec byte_count
brne bloop
dec bit_count
brne loop	/повторить для всех разрядов
/Результат ($6А)=А0=0,625
/Обратное преобразование двоичной дроби в десятичную fbd: Idi bit_count,8*n
Idi XL,low(dram+k) /установка
Idi XH,high(dram+k)/ начального адреса
Idi byte_count,k
clr acc	/ и очистка ячеек
s_loop: st -x, acc / десятичной дроби
dec byte_count
brne s_loop
loopl: Idi XL,low(bram+n)/установка
Idi XH,high(bram+n) / начального адреса
clc
Idi byte_count,n
bloopl: Id acc,-x ror acc
/0=0
/сдвиг вправо
/ двоичной дроби
st х, acc
dec byte_count
brne bloopl
Idi XL,low(dram+k)
Idi XH,high(dram+k)
Idi byte_count,k
dloopl: Id acc,-x
rcall divd2	/сдвиг вправо
st x, acc	/ десятичной дроби
dec byte_count	/ и коррекция
brne dloopl
3.8. Программы для преобразования чисел
129
dec bit_count
brne loopl fin:	rjmp fin
.include "muld2.asm" .include "divd2.asm”
/повторить для всех разрядов
/вызываемые подпрограммы
Преобразование двоичных целых чисел в формат с плавающей точкой
Полагаем, что двоичное число представлено в прямом коде со знаком и занимает перед началом преобразования регистры общего назначения: R15 (старший байт со знаком), R14, R13 (младший байт). Алгоритм преобразования достаточно прост. Вначале выполняется проверка числа на нуль. Если число равно нулю, в регистр порядка R16 заносится 0 и преобразование завершается. При ненулевом значении знак числа пересылается на флаг Т регистра состояния. Затем в регистре порядка устанавливается максимальный смещенный порядок. Для получения нормализованной мантиссы число в регистрах R15, R14, R13 сдвигается влево при одновременном уменьшении значения порядка до тех пор, пока старший разряд в регистре R15 не примет значение 1. Результат преобразования: знак числа в Т, смещенный порядок в регистре R16, нормализованная мантисса в регистрах R15, R14, R13. Преобразование нормализованной мантиссы в стандартный формат со скрытой единицей было рассмотрено ранее (см. 3.7). Программа преобразования по описанному алгоритму представлена ниже.
О******************************************************** Л /Преобразование двоичного целого числа / (24 разряда) в формат с плавающей точкой.
.******************************************************** i_ft: clr rl6 or rl6, rl5 or rl6, rl4 or rl6, rl3 breq exit bst rl5,7	/передача знака в T
Idi г16,151	/исходный порядок 127+24=151
clc loop: dec rl6	/уменьшение порядка
rol rl3	/ при сдвиге влево
rol rl4 rol rl5 brpl loop	/нормализация не закончена
exit: ret
130
3. Арифметическая обработка данных
Обратное преобразование двоичного числа с плавающей точкой рассмотрим на примере исходного числа, представленного в классическом формате (знак мантиссы, 1 байт - смещенный порядок, 3 байта - нормализованная мантисса). В случае если исходное число представлено в стандартном формате со скрытой единицей, его можно привести к указанному виду, как это описано в 3.7. Предварительно устанавливаем диапазон преобразуемых чисел, в соответствии с которым определяется длина целой и дробной части. Установив максимальное и минимальное значение смещенного порядка, переходим к проверке преобразуемого числа. Если порядок числа находится за границами диапазона, преобразование не выполняется (при этом устанавливается признак переполнения). Если порядок лежит в допустимых границах, выполняются действия по разделению целой и дробной части числа. Для этого определяют разность между значением смещенного порядка преобразуемого числа и смещением. Если разность к больше 0, выделяем целую часть числа, сдвигая мантиссу влево на к разрядов и передавая выталкиваемые биты в младший разряд регистра целого одновременно со сдвигом остальных разрядов регистра. Оставшиеся разряды мантиссы рассматриваем как дробную часть. Освобождаемые при сдвиге влево младшие разряды регистра мантиссы заполняем нулями.
Если разность порядков к окажется меньше 0, мантисса числа представляет дробь, которую необходимо сдвинуть на к разрядов вправо. Содержимое регистра целого в этом случае равно нулю.
В заключение, выполняем форматирование полученного результата, сохраняя требуемое число разрядов для дроби и добавляя знак. Полученный результат может быть в дальнейшем приведен к десятичному виду вышеописанными способами.
Задания для самостоятельного программирования
1.	Для микроконтроллера ATmega8515 проверить работу операций умножения по их описанию, открыв файл помощи по AVR Ассемблеру, используя команды меню: Help/AVR Tools User Guide. В окне Html Help щелчком открыть A VR Assembler, выбрать Parts и затем ATmega8515. Подробное описание каждой из команд умножения можно найти в разделе A VR Assembler/Instructions.
2.	Рассмотреть операцию умножения дробных чисел на примерах. Проверить результаты с помощью симулятора AVR Studio 4.
3.8. Программы для преобразования чисел
131
3.	Написать процедуру сложения (вычитания) 2-байтовых операндов для проверки с помощью STK500. Сформировать признаки результата, как признаки 2-байтовой суммы (разности).
4.	Написать макрос для двоично-десятичной коррекции при сложении, равноценный команде DA А в системе команд микроконтроллеров MCS-51.
5.	Написать процедуру сложения (вычитания) двух 4-байтовых упакованных двоично-десятичных чисел.
6.	Выполнить операции умножения 16-разрядных целых и дробных чисел, используя базовые программы 1.1, 1.2. Объяснить работу программ по шагам.
7.	Настроить программу 3.8, задав к и п, чтобы выполнить преобразование целого десятичного числа 16 777 215 в двоичное и обратно.
8.	Изменить программы для обработки чисел с плавающей точкой:
а)	с усеченным форматом мантиссы (16 разрядов);
б)	с усеченным порядком в зависимости от выбранного диапазона обрабатываемых чисел.
9.	Нарисовать схему алгоритма алгебраического сложения -вычитания чисел с плавающей точкой в дополнительных кодах. Дать оценку сложности разработанного алгоритма путем сравнения с описанным. Написать программу и проверить ее работу с помощью отладчика.
Контрольные вопросы
1.	Какой бит в регистре SREG определяет флаг заема? Каким значением флага определяется переполнение при вычитании чисел со знаком и без знака?
2.	При каком минимальном значении делимого возникает переполнение, если делитель равен 10?
3.	Для каких 2-10 чисел (упакованных или распакованных) действительны приведенные программы 2-10 арифметики? Какие изменения следует внести в программные процедуры при изменении формата представления чисел?
4.	Рассчитать диапазон чисел в зависимости от количества разрядов порядка для случаев п = 8, п = 11, где п - число разрядов.
132	3. Арифметическая обработка данных
Написать формулу для расчета количества требуемых разрядов порядка при заданном числовом диапазоне.
5.	Проанализировать точность результатов арифметических операций, используя бытовой и научный электронные калькуляторы. Дать рекомендации по выбору числового формата для программы электронного калькулятора на основе 8-разрядного микроконтроллера.
6.	Объяснить, в каких случаях возникают переполнения (антипереполнения) при выполнении операций с плавающей точкой. Привести примеры.
4.	ТАЙМЕРЫ МИКРОКОНТРОЛЛЕРОВ АТх8515
Цель работы - изучение основных режимов работы таймеров и их программирование, анализ схем включения таймеров для проведения исследований.
Микроконтроллеры AVR в зависимости от класса (Tiny, Classic, Mega) и типа модели имеют в своем составе от одного до трех таймеров/счетчиков общего назначения - ТО, Т1 и Т2.
Первый таймер (8-разрядный ТО), имеющийся во всех моделях, может использоваться для отсчета и измерения временных интервалов или как счетчик внешних событий, а в модели ATmega8515 еще и для сравнения с заданным значением. При переполнении счетного регистра таймера генерируется запрос на прерывание. Два других таймера (16-разрядный Т1 и 8-разрядный Т2) кроме уже названных имеют дополнительные функции. Оба таймера могут генерировать запрос на прерывание не только при переполнении счетного регистра, но и при наступлении ряда других событий. Они могут также использоваться в качестве широтно-импульсных модуляторов. Кроме того, таймер Т2 может работать в асинхронном (относительно тактового сигнала микроконтроллера) режиме.
Работа таймеров, используемых в практикуме микроконтроллеров АТх8515, описана далее. Каждый таймер/счетчик использует один или более выводов микроконтроллера. Эти выводы могут быть либо линиями портов ввода/вывода с альтернативной функцией, либо выделенными выводами микроконтроллера. Все выводы микроконтроллеров АТх8515, относящиеся к таймерам/счет-чикам, и их функции приведены в табл. 4.1.
Таблица 4.1. Выводы, используемые таймерами/счетчиками общего назначения
Название	АТх8515	STK500	Описание
то	РВО	РВО	Вход внешнего сигнала таймера ТО
Т1	РВ1	РВ1	Вход внешнего сигнала таймера Т1
134
4. Таймеры микроконтроллеров АТх8515
Окончание табл. 4.1
Название	АТх8515	STK500	Описание
ICP	ICP/PE0*	РЕО	Вход захвата таймера Т1
ОС1А	PD5	PD5	Выход схемы сравнения таймера Т1
ОС1В	ОС1В/РЕ2*	РЕ2	Выход схемы сравнения таймера Т1
* В микроконтроллере AT90S8515 - выделенный вывод, в ATmega8515 -вывод порта РЕ.			
При использовании линий портов ввода/вывода необходимо сконфигурировать выводы в соответствии с их функциональным назначением (вход или выход).
Во всех микроконтроллерах семейства AVR имеется также сторожевой таймер, который является непременным атрибутом всех современных микроконтроллеров. Этот таймер используется для предотвращения зацикливания программы.
4.1.	ТАЙМЕР/СЧЕТЧИК ТО МИКРОКОНТРОЛЛЕРА AT90S8515
Таймер/счетчик ТО (8-разрядный) может использоваться для формирования временных интервалов или для подсчета числа внешних событий. Структурная схема таймера/счетчика ТО микроконтроллера AT90S8515 приведена на рис. 4.1.
Таймер содержит базовый счетчик TCNT0, регистр управления TCCR0 и схему управления. Кроме того, в его состав входят по одному разряду регистра запросов прерываний TIFR и маски прерываний TIMSK.
Счетчик TCNT0 доступен в любой момент времени как для чтения, так и для записи. При записи в счетчик TCNT0 во время его работы счет будет продолжен в следующем за командой записи машинном цикле. После подачи напряжения питания счетчик TCNT0 принимает нулевое состояние.
При переходе таймера/счетчика TCNT0 из состояния $FF в состояние $00 устанавливается в 1 флаг TOVO в регистре TIFR и генерируется запрос на прерывание. Разрешение прерывания осуществляется установкой в 1 разряда TOIEO регистра маски TIMSK. Флаг общего разрешения прерывания I регистра SREG микроконтроллера также должен быть установлен в 1.
4.1. Таймер/счетчик ТО микроконтроллера AT90S8515
135
Зпр Т/СО OVER
Рис. 4.1. Структурная схема таймера/счетчика ТО
Таймер/счетчик ТО может работать в двух режимах:
1)	таймера; в этом режиме на вход поступают импульсы тактового сигнала микроконтроллера СК (непосредственно или через предделитель схемы управления);
2)	счетчика событий; в этом режиме инкремент содержимого счетчика производится по активному фронту сигнала на входе ТО микроконтроллера (линия порта РВО).
Выбор режима работы (источника тактового сигнала), а также запуск и останов таймера/счетчика осуществляются с помощью разрядов CS02 - CS00 регистра управления таймером TCCR0 (табл. 4.2). Соответствие между состоянием этих разрядов и режимом работы таймера/счетчика приведено в табл. 4.3. Остальные разряды регистра доступны только для чтения и содержат 0.
Таблица 4.2. Формат регистра TCCR0
№ разряда	7	6	5	4	3	2	1	0
Имя	-	-	-	-	-	CS02	CS01	CS00
136
4. Таймеры микроконтроллеров А Тх8515
Таблица 4.3. Выбор источника тактового сигнала для таймера/счетчика ТО
CS02	CS01	CS00	Источник тактового сигнала
0	0	0	Таймер/счетчик остановлен
0	0	1	СК (тактовый сигнал микроконтроллера)
0	1	0	СК/8
0	1	1	СК/64
1	0	0	СК/256
1	0	1	СК/1024
1	1	0	Вывод ТО, инкремент счетчика производится по спадающему фронту импульсов
1	1	1	Вывод ТО, инкремент счетчика производится по нарастающему фронту импульсов
При использовании таймера/счетчика в режиме счета внешних событий необходимо помнить, что сигнал, присутствующий на выводе ТО, синхронизируется частотой тактового генератора микроконтроллера (состояние вывода ТО считывается по нарастающему фронту внутреннего тактового сигнала). В связи с этим для обеспечения корректной работы таймера от внешнего сигнала промежуток времени между соседними импульсами должен быть больше периода тактового сигнала микроконтроллера.
Инкремент содержимого таймера/счетчика при работе в режиме счета внешних событий производится даже в том случае, если вывод ТО сконфигурирован как выход. Эта особенность дает пользователю возможность программно управлять процессом счета.
4.2.	ТАЙМЕР/СЧЕТЧИК Т1 МИКРОКОНТРОЛЛЕРОВ АТх8515
Таймер/счетчик Т1 (16-разрядный) имеет гораздо больше функций, чем таймер/счетчик ТО. Прежде всего, как и таймер/счетчик ТО, он может использоваться для формирования временных интервалов или для подсчета числа внешних событий по входу Т1 (линия порта РВ1). Во-вторых, таймер/счетчик Т1 может по внешнему сигналу сохранять свое текущее состояние в отдельном регистре ввода/вывода. В-третьих, он может выполнять определенные действия при равенстве содержимого счетного регистра и заданного значения. И, наконец, он может работать как широтноимпульсный модулятор (ШИМ). Следует иметь в виду, что гене
4.2. Таймер/счетчик Т1 микроконтроллеров АТх8515	137
рация сигнала ШИМа вынесена в отдельный режим работы таймера/счетчика, в котором недоступны остальные функции (кроме генерации прерываний). В дальнейшем режим генерации сигнала ШИМа будем называть режимом ШИМа, а режим, в котором доступны остальные функции таймера/счетчика, - режимом таймера.
Структурная схема таймера/счетчика Т1 приведена на рис. 4.2. В состав таймера/счетчика входят базовый 16-разрядный счетчик TCNT1, три 16-разрядных регистра (регистр захвата ICR1 и два
Запросы прерываний
Рис. 4.2. Структурная схема таймера/счетчика Т1
регистра сравнения OCR1A и OCR1B), два 16-разрядных компаратора (схемы сравнения), два 8-разрядных управляющих регистра TCCR1А и TCCR1B, а также блок управления таймером.
Все флаги состояния таймера/счетчика (переполнения, совпадения и захвата) находятся в регистре флагов прерываний от таймеров TIFR, а разрешение (запрещение) прерываний от таймера
138
4. Таймеры микроконтроллеров АТх8515
осуществляется установкой (сбросом) соответствующих разрядов регистра маски TIMSK.
Базовый 16-разрядный счетчик TCNT1 реализован как суммирующий (в режиме ШИМа - как суммирующий-вычитающий) счетчик и доступен в любой момент времени как для чтения, так и для записи. При записи в счетчик TCNT1 во время работы таймера счет будет продолжен по следующему за операцией записи импульсу тактового сигнала таймера/счетчика. После подачи напряжения питания счетчик TCNT1 принимает нулевое состояние.
Физически счетчик TCNT1 размещен в двух регистрах TCNT1H:TCNT1L. Чтобы при обращении процессорного устройства микроконтроллера к этим регистрам процесс записи (чтения) обоих байтов содержимого таймера/счетчика происходил одновременно, обращение производится с использованием специального 8-разрядного регистра TEMP. Этот регистр используется только процессором и программно недоступен.
Собственно запись и чтение регистра TCNT1 происходят следующим образом:
1)	при записи старшего байта значения в регистр TCNT1H он помещается в регистр TEMP. Далее при записи младшего байта в регистр TCNT1L он объединяется с содержимым регистра TEMP, и оба байта записываются в регистр TCNT1 одновременно. Из сказанного следует, что для выполнения полного цикла записи в 16-разрядный счетчик первым должен загружаться старший байт (регистр TCNT1H);
2)	при чтении регистра TCNT1L (младший байт) содержимое регистра TCNT1H пересылается в регистр TEMP. При последующем чтении регистра TCNT1H возвращается значение, сохраненное в регистре TEMP. Следовательно, для выполнения полной операции чтения 16-разрядного счетчика первым должен считываться младший байт (регистр TCNT1L).
Подобным образом с использованием регистра TEMP осуществляется обращение к остальным 16-разрядным регистрам: OCR1A, OCR1B и ICR1. Прерывания на время обращения к любому из этих регистров должны быть запрещены.
Управление таймером/счетчиком Т1 осуществляется с помощью двух 8-разрядных регистров управления: TCCR1A и TCCR1B. Формат регистров приведен в табл. 4.4. Значение отдельных разрядов этих регистров будет описано далее. Неиспользуемые разряды регистров доступны только для чтения и содержат 0.
4.2. Таймер/счетчик Т1 микроконтроллеров АТх8515
139
Таблица 4.4. Формат управляющих регистров TCCR1A, TCCR1B
Регистр/ бит	7	6	5	4	3	2	1	0
TCCR1A	СОМ1А1	СОМ 1 АО	СОМ1В1	СОМ 1 ВО	-	-	PWM11	PWM10
TCCR1B	ICNC1	ICES1	-	-	СТС1	CS12	CS11	CS10
По отношению к тактовому сигналу таймер/счетчик Т1 может работать в двух режимах, аналогично таймеру ТО. Выбор источника тактового сигнала, а также запуск и останов таймера/счетчика осуществляются с помощью разрядов CS12.. .CS10 регистра управления таймером TCCR1B. Соответствие между состоянием этих разрядов и режимом работы таймера/счетчика приведено в табл. 4.5.
Таблица 4.5. Выбор источника тактового сигнала для таймера/счетчика Т1
CS12	CS11	CS10	Источник тактового сигнала
0	0	0	Таймер/счетчик остановлен
0	0	1	СК (тактовый сигнал микроконтроллера)
0	1	0	СК/8
0	1	1	СК/64
1	0	0	СК/256
1	0	1	СК/1024
1	1	0	Вывод Т1, инкремент счетчика производится по спадающему фронту импульсов
1	1	1	Вывод Т1, инкремент счетчика производится по нарастающему фронту импульсов
Режим таймера
Принцип работы таймера/счетчика Т1 в режиме таймера такой же, как и таймера/счетчика ТО. По каждому импульсу, поступающему на тактовый вход таймера/счетчика, производится инкремент содержимого счетчика TCNT1. При переходе таймера/счетчика из состояния $FFFF в состояние $0000 устанавливается флаг TOV1 регистра TIFR и генерируется запрос на прерывание. Разрешение прерывания осуществляется установкой в 1 разряда TOIE1 (бит 7) регистра маски TIMSK (разумеется, флаг общего разрешения прерываний I регистра SREG также должен быть установлен в 1).
140
4. Таймеры микроконтроллеров АТх8515
Кроме основных функций - подсчет числа импульсов тактового сигнала микроконтроллера и числа внешних событий - в режиме таймера Т1 доступны и дополнительные.
Функция захвата (capture)
Данная функция заключается в сохранении в определенный момент времени состояния таймера/счетчика TCNT1 в регистре захвата ICR1. Это действие может производиться либо по активному фронту сигнала на выводе ICP микроконтроллера (линия порта РЕО), либо по сигналу от аналогового компаратора, которые определяют сигнал захвата на входе блока управления таймера. При этом устанавливается флаг ICF1 регистра TIFR и генерируется запрос на прерывание. Разрешение прерывания осуществляется установкой в 1 разряда TICIE1 (бит 3) регистра TIMSK.
Для управления схемой захвата используют два разряда регистра TCCR1B: ICNC1 и ICES1. Разряд ICNC1 управляет схемой подавления помех. Если этот разряд сброшен в 0, схема подавления помех выключена и захват проводится по первому же активному фронту на выводе ICP микроконтроллера. Если этот разряд установлен в 1, то при появлении активного фронта на выводе ICP схема управления выполняет четыре выборки с частотой, равной тактовой частоте микроконтроллера. Захват будет выполнен только в том случае, если все выборки имеют уровень, соответствующий активному фронту сигнала (уровень 1 - для нарастающего фронта и уровень 0 - для спадающего).
Активный фронт сигнала, по которому будет выполнено сохранение содержимого счетчика TCNT1 в регистре захвата, определяется состоянием разряда ICES1. Если этот разряд сброшен в 0, то активным является спадающий фронт. Если же этот разряд установлен в 1, то активным является нарастающий фронт.
Физически регистр захвата ICR1 размещен в двух регистрах ICR1H:ICR1L, доступных только для чтения. Поскольку регистр захвата является 16-разрядным, при его чтении, как уже было сказано, используется специальный регистр TEMP. При чтении регистра ICR1L (младший байт) его содержимое посылается в процессорное устройство, а содержимое регистра ICR1H (старший байт) сохраняется в регистре TEMP. При чтении регистра ICR1H возвращается значение, сохраненное в регистре TEMP. Следовательно, при чтении регистра ICR1 первым должен быть прочитан регистр ICR1L. Прерывания на время обращения к регистру ICR1 должны быть запрещены.
4.2. Таймер/счетчик Т1 микроконтроллеров АТх8515
141
Функция сравнения (compare)
Данная функция заключается в непрерывном (каждый машинный цикл) сравнении содержимого счетчика TCNT1 и регистра сравнения. При совпадении их содержимого устанавливается флаг соответствующего прерывания. В микроконтроллерах АТх8515 есть два регистра сравнения (OCR1A и OCR1B), причем операция сравнения производится для каждого регистра в отдельности. Если значение счетчика становится равным числу, находящемуся в регистре сравнения, то в следующем машинном цикле устанавливается соответствующий этому регистру флаг прерывания в регистре TIFR (для регистра OCR1A - флаг OCF1A, для регистра OCR1B -флаг OCF1B) и генерируется запрос на прерывание. Разрешение прерываний осуществляется установкой в 1 соответствующих разрядов регистра TIMSK (OCIE1A - бит 6 для запроса OCF1A и OCIE1B - бит 5 для запроса OCF1B).
Наряду с установкой флага в регистре TIFR при равенстве счетчика и регистра сравнения могут выполняться и другие действия: сброс таймера/счетчика (только для регистра OCR1A) и изменение состояния определенного вывода микроконтроллера (для обоих регистров).
Поведение микроконтроллера, т. е. выполнение или невыполнение указанных действий, определяется несколькими разрядами регистров управления TCCR1A и TCCR1B. Состояние разрядов СОМ 1x1, СОМ 1x0 (х = А,В) определяет поведение вывода ОС1х при совпадении содержимого счетчика TCNT1 и регистра сравнения OCRlx согласно табл. 4.6. При изменении состояния этих разрядов соответствующее прерывание от схемы компаратора рекомендуется запретить (во избежание ложной генерации прерывания). Чтобы таймер/счетчик мог управлять выводом, последний должен быть сконфигурирован как выход порта.
Таблица 4.6. Управление выводом ОС1х (х = А, В)
COMlxl	СОМ 1x0	Описание
0	0	Таймер/счетчик Т1 отключен от вывода ОС1х
0	1	Состояние вывода меняется на противоположное
1	0	Вывод сбрасывается в 0
1	1	Вывод устанавливается в 1
142
4. Таймеры микроконтроллеров АТх8515
Если разряд СТС1 регистра управления TCCR1B установлен в 1, то при совпадении содержимого счетчика TCNT1 и регистра сравнения OCR1A производится сброс таймера/счетчика в нулевое состояние.
Каждый регистр сравнения физически размещается в двух регистрах ввода/вывода: OCR1A - OCR1AH:OCR1AL; OCR1B -OCR1BH:OCR1BL.
Поскольку регистры сравнения являются 16-разрядными, при их чтении и записи используется специальный регистр TEMP. Процесс записи и чтения 16-разрядных регистров выполняется так же, как и регистра TCNT1. Прерывания на время обращения к регистрам сравнения OCR1A и OCR1B должны быть запрещены.
Режим ШИМа (PWM)
Широтно-импульсная модуляция является одним из видов непрерывной импульсной модуляции, при которой ширина импульса пропорциональна значению модулирующего сигнала. Соответственно в данном случае широтно-импульсная модуляция заключается в генерировании сигнала с программируемой частотой и скважностью.
Для перевода таймера/счетчика Т1 в режим ШИМа и задания частоты ШИМ-сигнала используют разряды PWM11:PWM1O регистра управления таймером TCCR1A. Соответствие между состоянием этих разрядов и режимом работы таймера/счетчика Т1 приведено в табл. 4.7.
Таблица 4.7. Управление режимом ШИМа таймера/счетчика Т1
PWM11	PWM10	Описание
0	0	Режим ШИМа таймера/счетчика выключен
0	1	8-разрядный ШИМ
1	0	9-разрядный ШИМ
1	1	10-разрядный ШИМ
Для генерации ШИМ-сигнала используется схема сравнения таймера/счетчика, поэтому в микроконтроллерах АТх8515 модулятор является сдвоенным (два регистра сравнения). Названия регистров сравнения и правила обращения к ним были описаны ранее. Сигнал снимается с выхода схемы сравнения таймера/счетчика.
4.2. Таймер/счетчик Т1 микроконтроллеров АТх8515
143
В рассматриваемом режиме счетчик TCNT1 функционирует как реверсивный, модуль счета которого (ТОР) зависит от режима работы модулятора. Частота ШИМ-сигнала зависит от частоты тактового сигнала /гскл таймера/счетчика Т1 и модуля счета ШИМа. Значение модуля счета и частота ШИМ-сигнала для каждого режима работы модулятора приведены в табл. 4.8.
Таблица 4.8. Режимы ШИМа
Режим модулятора	Модуль счета (ТОР)	Частота ШИМ-сигнала
8-разрядный	255	
9-разрядный	511	/тск\1№2
10-разрядный	1023	/тскл /2046
При работе таймера/счетчика Т1 в режиме ШИМа состояние счетчика меняется от 0 до значения ТОР, а затем снова до 0, после чего цикл повторяется. При равенстве состояния счетчика и содержимого регистра сравнения состояние соответствующего этому регистру вывода микроконтроллера изменяется согласно табл. 4.9 (х обозначает А или В). Таким образом, длительность ШИМ-сигнала равна 2п!/тскъ где п ~ содержимое регистра сравнения.
Таблица 4.9. Поведение выходов схемы сравнения в режиме ШИМа
COMlxl	COM 1x0	Поведение вывода ОС lx
0	0	Таймер/счетчик Т1 отключен от вывода
0	1	Таймер/счетчик Т1 отключен от вывода
1	0	Сбрасывается в 0 при прямом счете и устанавливается в 1 при обратном (неинвертирован-ный ШИМ-сигнал)
1	1	Устанавливается в 1 при прямом счете и сбрасывается в 0 при обратном (инвертированный ШИМ-сигнал)
Соответственно если в регистр сравнения записать значение О или ТОР, то при следующем совпадении состояния счетчика и содержимого регистра сравнения выход схемы сравнения переключится в устойчивое состояние согласно табл. 4.10 (х = А или В).
144
4. Таймеры микроконтроллеров АТх8515
Таблица 4.10. Устойчивые состояния выхода схемы сравнения
COMlxl	СОМ 1x0	Регистр OCRlx	Состояние вывода ОС1х
1	0	0	0
1	0	ТОР	1
1	1	0	1
1	1	ТОР	0
Особенностью работы таймера/счетчика Т1 в режиме ШИМа является то, что при записи в регистр сравнения младшие 10 разрядов записываемого числа на самом деле сохраняются в специальном временном регистре. Изменение содержимого регистра сравнения происходит только в момент достижения счетчиком максимального значения ТОР. Благодаря такому решению исключается появление в ШИМ-сигнале импульса со случайной длительностью.
Соответственно при чтении регистра сравнения в промежутке между записью в него и действительным изменением возвращается содержимое временного регистра, т. е. всегда возвращается значение, записанное последним.
При работе таймера/счетчика Т1 в режиме ШИМа может генерироваться прерывание по переполнению счетчика, а также прерывание от схемы сравнения. Флаги прерываний устанавливаются в 1 при изменении счетчиком направления счета: флаг TOV1 - в точке 0, а флаги OCF1A (для регистра OCR1A) и OCF1B (для регистра OCR1B) - в точке ТОР. Разрешение и обработка соответствующих прерываний выполняются как обычно.
4.3.	ПРОГРАММИРОВАНИЕ ТАЙМЕРА ТО
Режим счетчика событий
Подготовить программу для исследования таймера/счетчика ТО в режиме счетчика событий. Событием в данном случае может быть замыкание одной из кнопок SWx на плате STK500. Результат работы программы отобразить средствами индикации.
С помощью 10-проводного шлейфа подключим выводы порта РВ к выводам кнопок SW0-SW7 (в данном случае будет использован только вывод РВО - вход внешнего сигнала таймера ТО). С помощью второго 10-проводного шлейфа соединяем выводы порта PD с выводами светодиодов LED0-LED7. Программируем вывод РВО на ввод, все выводы порта PD - на вывод. Настраиваем тай
4.3. Программирование таймера ТО
145
мер на режим счета внешних событий (нажатие кнопки SW0). После нескольких, например четырех, нажатий должно произойти переполнение таймера (следовательно, начальное значение счетчика TCNT0 - $FC) и вызов обработчика прерываний. Обработчик должен включить светодиоды, показывая, что программа выполнена корректно, и заново инициализировать счетчик таймера для продолжения работы, если планируется неоднократное повторение программы. Время включения светодиодов установим, используя подпрограмму задержки.
Программа 4.1
********************************************************** Л
/Программа 4.1 для МК АТх8515:
/демонстрация работы таймера ТО в режиме счетчика событий/
/событие - нажатие кнопки SW0.
/Светодиоды включаются после четвертого нажатия на кнопку
/SW0. Соединения шлейфами: порт PB-SW, порт PD-LED
• *Г*С*Г*Г*Г*Г*Г*Г*Г*Г*Г*Г*Г*Г*Г*Г*Г*Г*Г*Г*Г*Г*Г*Г*Г*Г*С*Г*Г*Г*Г*Г*Г*Г*Г*Г*Г*Г^*Г^*С',*’'*-'*'*Г*Г*Г*С''А''Л’*С,*Г*Г*Г*Г*Г г
.include "m8515def.inc" /файл определений ATmega8515
.def temp = rl6	/временный регистр
;***Таблица векторов прерываний
.org $000
rjmp INIT	/обработка сброса
.org $007
rjmp T0_OVF	/обработка переполнения таймера
/ ** Инициализация МК
INIT: Idi temp,low(RAMEND)/установка
out SPL,tem	/ указателя стека
Idi temp,high(RAMEND)	/ на последнюю
out SPH,temp	/ ячейку ОЗУ
Idi temp,(1<<РВ0)	/включение
out PORTB,temp	/ подтягивающего резистора
ser temp	/инициализация порта PD
out DDRD,temp	/ на вывод
out PORTD,temp	/выключение светодиодов
Idi temp, (1«SE)	/разрешение перехода
out MCUCR,temp	/ в режим Idle
*Настройка таймера TO	на режим счетчика событий
Idi temp,0x02	/разрешение прерывания по
out TIMSK,temp	/ переполнению таймера
Idi temp,0x07	/переключение таймера
out TCCR0,temp	/ по положительному фронту
146
4. Таймеры микроконтроллеров АТх8515
sei	/разрешение прерываний
Idi temp,0xFC out TCNTO,temp LOOP: sleep	/$FC=-4 для ; отсчета четырех нажатий /переход в режим пониженного
nop rjmp LOOP	/ энергопотребления
/***Обработка прерывания при переполнении таймера ТО
TO_OVF: clr temp	
out PORTD,temp rcall DELAY	/включение светодиодов /задержка
ser temp	
out PORTD,temp	/выключение светодиодов
Idi temp,0xFC	/$FC=-4 для
out TCNTO,temp	/ отсчета четырех нажатий
reti	
;*** Задержка ***	
DELAY: idi rl9,10	
Idi r20,255	
Idi r21,255	
dd:dec r21	
brne dd	
dec r20	
brne dd	
dec rl9	
brne dd	
ret	
Результат работы программы будет таков. При четвертом нажатии на кнопку SW0 загораются все светодиоды (в случае дребезга контактов светодиоды могут включиться раньше). Длительность времени, в течение которого они горят, определяется задержкой DELAY. Далее действия могут быть повторены.
Как уже было сказано в теоретической части, события для таймера/счетчика ТО можно генерировать программно. Для этого необходимо настроить вывод РВО как выход. В данном случае инкремент счетчика будет происходить после выполнения команд программы, эмулирующих положительный или отрицательный фронт, как этого требует настройка таймера:
;положительный фронт сигнала на РВО cbi PORTB,О
4.3. Программирование таймера ТО
147
sbi PORTB,О
/отрицательный фронт сигнала на РВО sbi PORTB,О cbi PORTB,О
Режим таймера
Подготовить программу для исследования таймера/счетчика ТО в режиме таймера. Для наглядности работы таймера в этом режиме можно запрограммировать следующие действия: при нажатии на первую кнопку на вход таймера поступают сигналы с частотой, равной частоте тактового генератора СК, при нажатии на вторую кнопку на вход таймера поступают сигналы с частотой, например, СК/8. В обоих случаях сразу после нажатия загораются светодиоды, а после переполнения таймера и обработки соответствующего прерывания светодиоды гаснут. Таким образом, во втором случае время свечения светодиодов будет в восемь раз больше, чем в первом, что и означает правильность выполнения программы. Если установить частоту тактового генератора микроконтроллера равной 512 Гц, то время включения светодиодов в первом случае 0,5 с, во втором - 4 с (0,5- 8). (Внимание! Частоту тактового генератора необходимо изменять после программирования микроконтроллера, убедившись, что выбран флажок внешнего генератора Ext на вкладке Fuses окна программирования STK50O).
На плате STK500 необходимо соединить выводы порта PD с кнопками SW0 - SW7, выводы порта РВ - со светодиодами LED0 -LED7. Для обработки нажатия кнопок используем метод последовательного опроса состояния кнопок.
Программа 4.2 г
/Программа 4.2 для МК АТх8515: демонстрация работы таймера /ТО в режиме таймера. Для наблюдений необходимо установить /частоту тактового генератора СК=512 Гц. При нажатии на /SW2 на вход счетчика поступают сигналы с частотой СК, /при нажатии на SW3 - СК/8. В первом случае время с начала /счета до переполнения (выключения светодиодов) - 0,5 с, /во втором - 4 с.
/Соединения: пара PD2:PD3-napa SW2:SW3, PB-LED ********************************************************** z
/.include "8515def.inc" /файл определений AT90S8515 .include "m8515def.inc" /файл определений ATmega8515 .def temp = rl6	/временный регистр
148
4. Таймеры микроконтроллеров А Тх8515
.equ SW2 = 2	/2-й вывод порта PD
.equ SW3 = 3	/3-й вывод порта PD
/***Таблица векторов прерываний .org $000
rjmp INIT	/обработка сброса
.org $007
rjmp T0_OVF /обработка переполнения таймера ТО /***Инициализация МК INIT: Idi temp,low(RAMEND) /установка
out SPL,temp	/ указателя стека
Idi temp,high(RAMEND)	/ на последнюю
out SPH,temp	/ ячейку ОЗУ
clr temp	/инициализация порта PD
out DDRD,temp	/ на ввод
Idi temp, (1<<PD3) | (1«PD2)/включение подтягивающих	
out PORTD,temp	/ резисторов порта PD
ser temp	/инициализация порта РВ
out DDRB,temp	/ на вывод
out PORTB,temp	/выключение светодиодов
/***Настройка таймера TO	на режим таймера
Idi temp,0x02	/разрешение прерывания по
out TIMSK,temp	/ переполнению таймера ТО
clr temp	/таймер ТО
out TCCR0,temp	/ остановлен
sei	/разрешение прерываний
clr temp	/отсчет
out TCNT0,temp	/ начинается с 0
/***0жидание нажатия кнопок	
WAITSET_0: sbic PIND,SW2	/проверка нажатия
rjmp WAITSET_1	/ кнопки SW2
/***Обработка нажатия кнопки SW2	
Idi temp,0x01	/частота тактовых сигналов- СК
rcall LED_ON	/включение светодиодов
WAITSET_1: sbic PIND,SW3	/проверка нажатия
rjmp WAITSET_0	/ кнопки SW3
/***Обработка нажатия кнопки SW3	
Idi temp,0x02	/частота сигналов - СК/8
rcall LED_ON	/включение светодиодов
rjmp WAITSET_0	
/***Обработка прерывания	при переполнении таймера ТО
4.4. Программирование функций таймера Т1
149
TO_OVF: ser temp out PORTB,temp clr temp out TCCRO,temp clr temp out TCNTO,temp reti
;**^Включение светодиодов
LED_ON:out TCCRO,temp
clr temp
out PORTB,temp
ret
/выключение светодиодов
;останов
; таймера ТО
/установка О
/настройка источника
/ тактового сигнала
/включение
/ светодиодов
Результат работы программы: нажатие кнопки SW2 приводит к тому, что все светодиоды светятся в течение 0,5 с; при нажатии SW3 - в течение 4 с. (Примечание. Новое нажатие будет обрабатываться сразу, т. е. при нажатии сначала на SW3, а затем на SW2, не дожидаясь отключения светодиодов, они погаснут через 0,5 с после второго нажатия).
Работа таймера/счетчика Т1 в режимах счетчика событий и таймера аналогична работе таймера/счетчика ТО. Отличие состоит в разрядности базового счетчика: TCNT0 - 8-разрядный; TCNT1 -16-разрядный. Поэтому программы для исследования Т1 в этих режимах могут быть аналогичны ранее рассмотренным.
4.4.	ПРОГРАММИРОВАНИЕ ФУНКЦИЙ СРАВНЕНИЯ, ЗАХВАТА И ШИМ ТАЙМЕРА Т1
Функция сравнения
Подготовить программу для исследования функции сравнения таймера/счетчика Т1. Возможный вариант работы программы: при нажатии на кнопку START (SW0) запускается таймер - происходит инкремент счетчика с частотой СК. При совпадении значений счетчика TCNT1 и регистра сравнения OCR1B происходит изменение состояния вывода ОС1В на противоположное. При совпадении значений счетчика TCNT1 и регистра сравнения OCR1A происходит изменение состояния вывода ОС1А на противоположное и сброс счетного регистра в нулевое состояние. Временные диаграммы работы таймера Т1 приведены на рис. 4.3. Возможность останова таймера во время счета реализуется с помощью внешнего
150
4. Таймеры микроконтроллеров АТх8515
Рис. 4.3. Временные диаграммы работы таймера/счетчика Т1 при исследовании функции сравнения
прерывания от кнопки STOP (SW1). При записи значений в регистры сравнения необходимо соблюдать установленный порядок: сначала записывается старший байт, затем - младший.
Для наблюдения изменений состояний выводов ОС1А и ОС1В их необходимо соединить с выводами светодиодов. Коммутация осуществляется двухпроводными шнурами: LEDO - РЕ2, LED1 -PD5, SW0 - PDO, SW1 - PD2. Частота тактового генератора устанавливается равной 256 Гц.
Программа 4.3.
f
/Программа 4.3 для МК АТх8515: демонстрация работы функции /сравнения таймера Т1.Для наглядности необходимо выставить /частоту тактового генератора СК=256 Гц.При нажатии на SW0 /(START) происходит инкремент счетчика с частотой СК, при /нажатии на SW1 (STOP) счетчик останавливается.
/При совпадении содержимого счетчика и регистра сравнения /OCR1B происходит переключение светодиода LED0, счетчика и /регистра сравнения OCR1A - LED1.
;Соединения: LED0-PE2, LED1-PD5, SW0-PD0, SW1-PD2
г
/.include "8515def.inc" .include "m8515def.inc" .def temp = rl6
/файл определений AT90S8515
/файл определений ATmega8515 /временный регистр
4.4. Программирование функций таймера Т1
151
.equ START = 0	/О-й разряд порта PD
.org $000
rjmp INIT	/обработка	сброса
.org $002
rjmp STOP_PRESSED	/обработка	внешнего прерывания
/ INTO при	нажатии STOP
/ ** Инициализация МК
INIT:	Idi temp,low(RA	.MEND) /установка
out	SPL,temp	/ указателя стека
Idi	temp,high(RAMEND)	/ на последнюю	
out	SPH,temp	/ ячейку ОЗУ
Idi	temp,0x20	/инициализация выводов порта PD:
out	DDRD,temp	/ 0,2 - на ввод, 5 - на вывод
Idi	temp,0x05	/включение подтягивающих
out	PORTD,temp	/ резисторов и выключение LED
Idi	temp, (l«INT0)	/разрешение прерывания INTO
out	GICR,temp	/ в регистре GICR (или GIMSK)
clr	temp	/обработка прерывания INTO
out	MCUCR,temp	/ по низкому уровню
/***Настройка функции		сравнения таймера Т1
Idi	temp,0x50	/при равенстве / состояния выводов ОС1А и ОС1В
out	TCCR1A,temp	/ изменяются на противоположные
Idi	temp,0x00	/таймер
out	TCCR1B,temp	/ остановлен
Idi	temp,0x00	/запись числа в
out	OCR1BH,temp	/ регистр сравнения,
Idi	temp,0x80	/ первым записывается
out	OCR1BL,temp	/ старший байт
Idi	temp,0x00	/запись числа в
out	OCR1AH,temp	/ регистр сравнения,
Idi	temp,OxFF	/ первым записывается
out	OCR1AL,temp	/ старший байт
clr	temp	/обнуление
out	TCNT1H,temp	/ содержимого
out sei	TCNT1L,temp	/ счетного регистра /разрешение прерываний
WAITSTART: sbic PIND,;		START /ожидание нажатия
rjmp WAITSTART	/ кнопки START
Idi temp,0x09	/запуск таймера, при
out TCCRlB,temp	/ совпадении с OCR1A - сброс
LOOP: пор	/во время цикла происходит
152
4. Таймеры микроконтроллеров АТх8515
rjmp LOOP
; увеличение содержимого
;***Обработка прерывания STOP_PRESSED:
Idi temp,0x08
out TCCRlB,temp
WAITSTART_2:
sbic PIND,START rjmp WAITSTART_2 Idi temp,0x09 out TCCRlB,temp reti
; счетного регистра от кнопки STOP
;остановка
; таймера
;ожидание
; нажатия
; кнопки START
;запуск
; таймера
Результат работы программы соответствует диаграммам на рис. 4.3. При нажатии на кнопку SW0 светодиоды работают в такой последовательности: оба светодиода погашены, далее включается LED0, затем LED1, выключается LED0, затем LED1 и т. д. В любой момент процесс можно остановить нажатием кнопки SW1.
Функция захвата
Подготовить программу для исследования функции захвата таймера/счетчика Т1. Захват должен происходить при нажатии соответствующей кнопки. По событию захват должен вызываться обработчик прерывания, который переписывает содержимое 16-разрядного регистра захвата ICR1 в регистры для хранения младшего и старшего байта, так как пересылка данных в порт для индикации возможна только из регистров общего назначения. Вывод каждого байта может быть связан с нажатием отдельной кнопки. С помощью регистра сравнения OCR1A можно задать максимальное значение, которое получим в счетчике и, следовательно, в регистре захвата. Необходимо настроить работу таймера так, чтобы он обнулялся при равенстве значений счетчика TCNT1 и регистра сравнения, установив бит СТС1 регистра TCCR1B в 1. Это можно использовать как дополнительный признак правильности работы программы. Так, например, если содержимое OCR1A равно SOOFF, а бит СТС 1 установлен в 1, то в старшем байте регистра захвата всегда будет 0.
При моделировании функции захвата в AVR Studio 4 необходимо помнить, что вывод ICP в микроконтроллере AT90S8515 яв
4.4. Программирование функций таймера Т1
153
ляется выделенным, а в микроконтроллере ATmega8515 - это линия порта ввода/вывода РЕО, в обоих случаях в STK500 - это вывод порта РЕО. Вызов обработчика прерывания по событию захват происходит после установки в 1 флага TICIE1 регистра маски TIMSK и флага ICF1 регистра запросов TIFR.
Коммутация кнопок с выводами микроконтроллера осуществляется двухпроводными шнурами: SW0 - PDO, SW1 - PD1, SW2 -PD2, SW3 - РЕО. Светодиоды подключают к выводам порта РВ 10-проводным шлейфом.
Программа 4.4
.*********************************************************
f
/Программа 4.4 для МК АТх8515: демонстрация работы функции /захвата таймера Т1. Для наблюдения необходимо установить /частоту тактового генератора СК=256 Гц.
/При нажатии на SWO (START) на вход счетчика поступает /сигнал с частотой СК, при нажатии на SW3 (САРТ) /происходит захват состояния таймера.
/При совпадении содержимого счетчика и регистра сравнения /OCR1A происходит сброс таймера.
/При нажатии на SW1 (SHOW_L) на светодиоды выводится /значение младшего байта регистра захвата, SW2 (SHOW_H) -/старшего байта регистра захвата.
/Соединения: SW0-PD0,SW1-PD1,SW2-PD2,SW3-PE0,10-проводным /шлейфом PB-LED
.********************************************************* /
/.include "8515def.inc" /файл определений AT90S8515
.include "m8515def.inc" /файл определений ATmega8515
def	temp = rl6	/временный регистр
def	H_byte = rl7	/для хранения старшего байта
def	L_byte = rl8	/для хранения младшего байта
equ	START = 0	/0-й вывод порта PD
equ	SHOW_L = 1	/1-й вывод порта PD
equ	SHOW_H = 2	/2-й вывод порта PD
/***Векторы прерываний .org $000 rjmp INIT	/обработка сброса
.org $003
rjmp CAPT_PRESSED	/обработка прерывания по сигналу
/ захвата от кнопки SW3
Инициализация МК
154
4. Таймеры микроконтроллеров АТх8515
INIT:	Idi temp,low(RAMEND)	/установка
out	SPL,temp	/ указателя стека
Idi	temp,high(RAMEND)	/ на последнюю
out	SPH,temp	/ ячейку ОЗУ
Idi	temp,0x00	/инициализация
out	DDRD,temp	/ порта PD на ввод
Idi	temp,0x07	/включение подтягивающих
out	PORTD,temp	/ резисторов порта PD
ser	temp	/инициализация
out	DDRB,temp	/ порта РВ на вывод
out	PORTB,temp	/выключение светодиодов
Idi	temp,0x00	/отключение от таймера
out	TCCR1A,temp	/ выводов
Idi	temp,0x00	/таймер
out	TCCR1B,temp	/ остановлен
Idi	temp,OxFF	/запись числа в
out	OCR1AH,temp	/ регистр сравнения,
Idi	temp,OxFF	/первым записывается
out	OCR1AL,temp	/ старший байт
clr	temp	/обнуление
out	TCNT1H,temp	/ содержимого
out	TCNT1L,temp	/ счетного регистра
Idi	L_byte, OxFO	/начальные значения
Idi	H_byte, OxOF	/ для контроля
sei WAITSTART: sbic FIND,START		/разрешение прерываний /ожидание нажатия
rjmp WAITSTART		/ кнопки START
Idi	temp,0x08	/разрешение прерывания
out	TIMSK, temp	/ по событию захват таймера
Idi	temp,0xC9	/запуск таймера, при
out	TCCR1B,temp	/ совпадении с OCR1A - сбро
WAIT_L: sbic FIND,SHOW_L rjmp WAIT_H out PORTB,L_byte
WAIT_H: sbic FIND,SHOW_H rjmp WAIT_L out PORTB,H_byte rjmp WAIT_L
;***Обработка прерывания от CAPT PRESSED:
;ожидание нажатия кнопки
; для показа младшего байта /вывод на светодиоды
;ожидание нажатия кнопки
; для показа старшего байта
/вывод на светодиоды
кнопки САРТ
4.4. Программирование функций таймера Т1
155
in L_byte,ICRlL in HJoyte,ICR1H com L_byte com H_byte reti
/считывание младшего байта ;считывание старшего байта ;инвертирование
;инвертирование
Режим ШИМа
Подготовить программу для исследования работы таймера Т1 в режиме ШИМа. Выводы ОС1А (PD5) и ОС1В (РЕ2) необходимо подключить к светодиодам (PD5-LED0, PE2-LED1), выводы порта PD0-PD3 к кнопкам общего назначения SW0-SW3 соответственно. Варианты обработки нажатия кнопок:
1)	при нажатии SW0 на выходах ОС1А и ОС1В устанавливаются значения 0 и 1 соответственно;
2)	при нажатии SW1 происходит генерация ШИМ-сигнала со скважностью F1 (скважность зависит от значения в регистре сравнения);
3)	при нажатии SW2 происходит генерация ШИМ-сигнала со скважностью F2;
4)	при нажатии SW3 на выходах ОС1А и ОС1В устанавливаются 1 и 0 соответственно.
Временная диаграмма работы ШИМа приведена на рис. 4.4.
OCR1A(B) для F2
ОС1А(В) (LEDO,1)
OCR1A(B) для Fl О
Рис. 4.4. Формирование ШИМ-сигнала
Программа 4.5
А
/Программа 4.5 для МК АТх8515: демонстрация работы таймера ; Т1 в режиме ШИМа. Для наглядности необходимо установить ; частоту тактового генератора = 2048 Гц.
/При нажатии на SWO (SHOW_0) на выходах ОС1А и ОС1В
/устанавливаются 0 и 1, SW1 (SHOW_F1)~ генерация ШИМ-
156
4. Таймеры микроконтроллеров А Тх8515
/сигнала со скважностью Fl, SW2 (SHOW_F2)- со скважностью /F2, SW3 (SHOW_1)- на выходах устанавливаются 1 и 0.
;Связи:PD5-LED0,PE2-LED1, PD0:PD1-SW0:SW1, PD2:PD3-SW2:SW3
г
/.include "8515def.inc” .include "m8515def.inc" .def temp = rl6 ;***Выводы порта PD .equ SHOW_0 = 0 .equ SHOW_F1 = 1 .equ SHOW_F2 = 2 .equ SHOW_3 = 3 .org $000
rjmp INIT
;***Инициализация MK
/файл определений AT90S8515 /файл определений ATmega8515 /временный регистр
/обработка сброса
INIT:	Idi temp,low(RAMEND)	;установка
out	SPL,temp	/ указателя стека
Idi	temp,high(RAMEND)	/ на последнюю
out	SPH,temp	/ ячейку ОЗУ
Idi	temp,0x20	/	инициализация выводов порта PD:
out	DDRD,temp	/ 0-3 - на ввод, 5 - на вывод
Idi	temp,OxOF	/включение подтягивающих
out	PORTD,temp	/ резисторов порта PD
Idi	temp,0xB3	/настройка таймера на ШИМ
out	TCCR1A,temp	/ с выводами ОС1А и ОС1В
clr	temp	/обнуление
out	OCR1AH,temp	/ регистров
out	OCR1AL,temp	/ сравнения и
out	OCR1BH,temp	г
out	OCR1BL,temp	г
out	TCNT1H,temp	; счетного
out	TCNT1L,temp	/ регистра
Idi	temp,0x01	/таймер
out	TCCR1B,temp	/ запущен: частота - СК
WAIT_0:	r	ожидание
Sbic PIND,SHOW_0		нажатия
rjmp WAIT_F1
/ кнопки SHOW_0, состояния 0 и 1
4.4. Программирование функций таймера Т1
157
;***Перевод в устойчивые состояния выводов ОС1А=0, ОС1В=1
clr	temp	/запись числа в
out	OCR1AH,temp	/ регистры сравнения, первым
out	OCR1AL,temp	/ записывается старший байт
out	OCR1BH,temp	
out	OCR1BL,temp	
WAIT_Fl:sbic PIND,SHOW_F1/ожидание нажатия rjmp WAIT_F2	; кнопки SHOW_F1 - режим ШИМа
; со скважностью F1
;***Настройка таймера на режим ШИМа со скважностью F1
Idi temp,0x00 out OCRlAH,temp	/запись числа в / регистры сравнения,
out OCRlBH,temp	/ первым записывается
Idi temp,OxFF	/ старший байт
out OCRlAL,temp	
out OCRlBL,temp	
WAIT_F2:sbic PIND,SHOW_F2/ожидание нажатия rjmp WAIT—3	; кнопки SHOW_F2-режим ШИМа
; со скважностью F2
;***Настройка таймера на режим ШИМа со скважностью F2
Idi	temp,0x02	/запись числа в
out	OCR1AH,temp	/ регистры сравнения,
out	OCR1BH,temp	/ первым записывается
Idi	temp,OxFF	/ старший байт
out	OCR1AL,temp	
out	OCR1BL,temp	
WAIT_3:sbic PIND,SHOW_3 /ожидание нажатия
rjmp WAIT_0	; кнопки SHOW_3, состояния 1 и О
;***Перевод в устойчивые состояния выводов ОС1А=1, ОС1В=0 ser temp	/запись числа в
out OCRlAH,temp	/ регистры сравнения, первым
out OCRlAL,temp	/ записывается старший байт
out OCRlBH,temp out OCRlBL,temp rjmp WAIT_0
158
4. Таймеры микроконтроллеров АТх8515
Результат соответствует диаграммам на рис. 4.4. При нажатии на SW0 загорается только LEDO, при нажатии SW3 - только LED1. При нажатии SW1 или SW2 светодиоды попеременно включают-ся/выключаются со скважностью F1 или F2 соответственно.
4.5. СТОРОЖЕВОЙ ТАЙМЕР
Основная функция сторожевого таймера (Watchdog Timer) -защита устройства от сбоев. Благодаря сторожевому таймеру можно прервать выполнение зациклившейся программы или выйти из
MCU RESET
Рис. 4.5. Структурная схема сторожевого таймера
других непредвиденных ситуаций, препятствующих ее нормальному выполнению. Структурная схема сторожевого таймера приведена на рис. 4.5.
Для управления сторожевым таймером предназначен регистр WDTCR. Формат регистра приведен в табл. 4.11.
Таблица 4.11. Формат регистра WDTCR
№ разряда	7	6	5	4	3	2	1	0
Имя	-	—	—	WDTOE	WDE	WDP2	WDP1	WDP0
4.5. Сторожевой таймер
159
Для включения/выключения сторожевого таймера используют два разряда регистра WDTCR-WDE и WDTOE. Если разряд WDE установлен в 1, сторожевой таймер включен, если сброшен в 0 -выключен. Непосредственно перед включением таймера рекомендуется также сбросить его командой WDR.
Для предотвращения непреднамеренного выключения таймера предназначен разряд WDTOE. Дело в том, что выключение сторожевого таймера (сброс разряда WDE) можно осуществить только при установленном разряде WDTOE, который через четыре машинных цикла после установки в 1 аппаратно сбрасывается. Благодаря этому возможность случайного выключения сторожевого таймера практически исключается.
Исходя из сказанного, для выключения сторожевого таймера рекомендуем следующий порядок действий:
1) одной командой записать 1 в разряды WDE и WDTOE;
2) в течение следующих четырех машинных циклов записать О в разряд WDE.
Период наступления тайм-аута сторожевого таймера задается с помощью разрядов WDP2-WDP0 регистра WDTCR согласно табл. 4.12.
Чтобы избежать непреднамеренного сброса микроконтроллера при изменении периода сторожевого таймера, необходимо перед записью разрядов WDP2-WDP0 запретить работу таймера либо сбросить его (WDR).
Таблица 4.12. Задание периода сторожевого таймера для AT90S8515
WDP2	WDP1	WDP0	Число тактов генератора	Период наступления тайм-аута (типовое значение)	
				VCC = 3,0 в	VCC = 5,0 В
0	0	0	16-1024	47 мс	15 мс
0	0	1	32-1024	95 мс	30 мс
0	1	0	64-1024	0,19 с	60 мс
0	1	1	128-1024	0,38 с	0,12 с
1	0	0	256-1024	0,75 с	0,24 с
1	0	1	512-1024	1,5 с	0,49 с
1	1	0	1024-1024	3,0 с	0,97 с
1	1	1	2048-1024	6,0 с	1,9 с
160
4. Таймеры микроконтроллеров АТх8515
Программирование сторожевого таймера
Подготовить программу для исследования сторожевого таймера. Полагая, что при нажатии на кнопку SW0 тайм-аут таймера наступает через 0,49 с, а при нажатии на SW1 - через 1,9 с, выберем из табл. 4.12 (VCC = 5 В) значения загружаемых коэффициентов согласно заданному периоду сторожевого таймера. В обоих случаях до наступления тайм-аута светодиоды должны быть включены, после происходит сброс микроконтроллера, и светодиоды гаснут.
Программа для микроконтроллера приведена ниже. (Внимание! Перед программированием микроконтроллера ATmega8515 в окне STK500 AVR Studio 4 на вкладке Fuses установить флажок S8515C и запрограммировать конфигурационную ячейку.)
Коммутация выводов: SW0 - PDO, SW1 - PD1, LED - РВ 10-проводным шлейфом.
Программа 4.6
г
/Программа 4.6 для МК АТ9х8515: демонстрация работы /сторожевого таймера с независимым генератором.
/При нажатии на SWO (PERIOD_1) наступление тайм-аута /происходит через 0,49 с (время включения светодиодов), / SW1 (PERIOD_2) - через 1,9 с.
/Соединения: PDO:PD1-SW0:SW1, РВ-LED(10-проводной шлейф) .*********************************************************• г
.include "8515def.inc” /.include "m8515def.inc" .def temp = rl6 /***Выводы порта PD .equ PERIOD_1 = 0 .equ PERIOD_2 = 1 .org $000
rjmp INIT
/***Инициализация MK INIT: Idi temp,low(RAMEND) out SPL,temp Idi temp,high(RAMEND) out SPH,temp clr temp out DDRD,temp Idi temp,0x03
/файл определений AT90S8515
/файл определений ATmega8515 /временный регистр
/обработка сброса
/установка
/ указателя стека
/ на последнюю
/ ячейку ОЗУ
/инициализация порта PD
/ на ввод
/включение подтягивающих
4.5. Сторожевой таймер
161
out PORTD,temp	/ резисторов порта PD
ser temp	/инициализация порта РВ
out DDRB,temp	/ на вывод
out PORTB,temp	/выключение светодиодов
Idi temp,$18	/выключение
out WDTCR,temp	/ сторожевого
Idi temp,$10	/ таймера:
out WDTCR,temp	/WDE=0
WAIT SWO: sbic PIND,PERIOD_1	/ожидание нажатия
rjmp WAIT_SW1	; кнопки PERIOD_1
;** Назначение периода наступления тайм-аута = 0,49 с
clr temp	/включение
out PORTB,temp	; светодиодов
Idi temp,$0D /включение сторожевого таймера, out WDTCR,temp / период 0,49 с
WAIT_SW1: sbic PIND,PERIOD_2 /ожидание нажатия
rjmp WAIT_SW0	/ кнопки PERIOD_2
/**Назначение периода наступления тайм-аута = 1,9 с
clr temp	/включение
out PORTB,temp	/ светодиодов
Idi temp,$0F /включение сторожевого таймера,
out WDTCR,temp / период 1,9 с
rjmp WAIT_SW0
Задания для самостоятельного программирования
1.	Изменить программу 4.1, добавив в нее обработку нажатия кнопки, исключающую влияние дребезга.
Для этого запрограммировать линию порта РВО на вывод для программного ввода событий в таймер. Ввод событий выполнять при условии замыкания кнопки SWx, присоединенной к порту (линию и порт выбрать самостоятельно). Выполняя проверку состояния кнопки SWx, эмулировать сигнал 1 на выводе РВО при замкнутом состоянии 0 кнопки. Перед загрузкой программы выполнить ее отладку в AVR Studio и, убедившись в правильности работы программы, проверить ее в STK500.
2.	Изменить программу 4.1 так, чтобы при замыкании кнопки START (SW1) состоялся вывод на индикаторы числа зарегистрированных событий.
3.	Подготовить программу по примеру 4.2 для проверки работы таймера/счетчика Т1 в режиме таймера. Время включения светодиодов 1 и 8 с.
162
4. Таймеры микроконтроллеров АТх8515
4.	Написать программу, которая каждые 50 мс по запросу прерывания от таймера считывает состояние кнопочного регистра SW, при замыкании определяет номер замкнутой кнопки и высвечивает его на линейке светодиодов.
5.	Написать программу для электронного секундомера, предусмотрев вывод секундных значений в младшую тетраду, десятков секунд - в старшую тетраду светодиодной линейки STK500. Для отсчета времени использовать 16-разрядный таймер Т1, при переполнении которого формируется запрос прерывания для вызова обработчика прерывания, выполняющего накопление таймерных интервалов времени и обновление показаний индикатора.
Контрольные вопросы
1.	Какова скважность сигналов, формируемых программой 4.3? Как изменяется временная диаграмма выходного сигнала при изменении значения, загружаемого в регистр сравнения?
2.	В каком порядке выполняется запись байтов в 16-разрядные регистры?
3.	В каком порядке выполняется чтение байтов из 16-разряд-ного счетчика TCNT1, регистра захвата ICR1?
4.	Какие значения необходимо занести в регистры сравнения в программе 4.5 для формирования ШИМ-сигналов скважностью 4 (отношения периода к длительности сигнала) при том же периоде ШИМ-сигналов?
5.	Как изменится скважность ШИМ-сигналов, формируемых при работе программы 4.5, если сменить управляющее слово в регистре TCCR1A на $В 1 ($В2)?
6.	Назовите максимальное время наступления тайм-аута у сторожевого таймера АТх8515.
7.	Назовите максимальное время захвата, которое можно зарегистрировать при работе программы 4.4. В каких приложениях можно применить эту программу?
5. ОБМЕН ДАННЫМИ
ПО ПОСЛЕДОВАТЕЛЬНОМУ ИНТЕРФЕЙСУ
Проблема «узкого» интерфейса, особенно значимая для микроконтроллеров с небольшим числом выводов, способствовала появлению на рынке периферийных устройств, где обмен данными осуществляется по скоростным последовательным каналам связи. К ним относят каналы UART (или USART), SPI, I2C (или TWI), USB, для работы с которыми микроконтроллеры имеют встроенные порты.
5.1. ПОСЛЕДОВАТЕЛЬНЫЙ ОБМЕН ДАННЫМИ ПО КАНАЛУ UART
Цель работы - изучение приема и передачи информации по последовательному каналу UART (Universal Asynchronous Receiver-Transmitter) и программирование ввода/вывода.
Микроконтроллеры AVR имеют в своем составе модуль полнодуплексного универсального асинхронного приемопередатчика UART (в семействе Mega универсальный синхронный/асинхрон-ный приемопередатчик USART). Через него осуществляется прием и передача информации, представленной последовательным кодом, поэтому модуль UART часто называют также последовательным портом. С помощью этого модуля микроконтроллер может обмениваться данными с различными внешними устройствами.
Поток данных, передаваемых по каналу UART, представляет собой совокупность посылок или кадров. Каждый кадр содержит стартовый бит, восемь или девять битов данных и столовый бит. Стартовый бит имеет уровень логического 0, столовый - уровень логической 1.
Скорость передачи данных может варьироваться в широких пределах, причем высокие скорости передачи могут быть достигнуты даже при относительно низкой тактовой частоте микроконтроллера.
164
5. Обмен данными по последовательному интерфейсу
Известно, что при передаче данных могут произойти различные сбои. Модуль UART, реализованный в микроконтроллерах, способен при приеме обнаруживать ошибку формата и переполнение.
Для взаимодействия с программой в модуле предусмотрены прерывания при наступлении следующих событий: прием завершен с адресом вектора $009 в таблице векторов прерываний, регистр данных передатчика пуст с адресом вектора $00А, передача завершена с адресом вектора $00В.
Выводы микроконтроллера, используемые модулем UART, являются линиями порта PD. В качестве входа приемника (RXD) используют вывод PD0, а в качестве выхода передатчика (TXD) -вывод PD1.
Принимаемые и передаваемые данные (восемь разрядов) хранятся в регистре UDR. Физически регистр UDR состоит из двух отдельных регистров, один из которых используется для передачи данных, другой - для приема. При чтении регистра UDR выполняется обращение к регистру приемника, при записи - к регистру передатчика.
Управление работой UART
Управление работой приемопередатчика осуществляется с помощью регистра управления UCR. Текущее состояние приемопередатчика определяется с помощью регистра состояния USR. Формат этих регистров приведен в табл. 5.1 и 5.2.
Таблица 5.1. Формат регистра управления UCR
№ разряда	7	6	5	4	3	2	1	0
Имя	RXCIE	TXCIE	UDRIE	RXEN	TXEN	CHR9	RXB8	ТХВ8
Таблица 5.2. Формат регистра состояния USR
№ разряда	7	6	5	4	3	2	1	0
Имя	RXC	тхс	UDRE	FE	OR	-	-	-
Назначение управляющих битов:
RXCIE - разрешение прерывания по завершении приема, если RXCIE = 1;
5.1. Последовательный обмен данными по каналу UART
165
TXCIE - разрешение прерывания по завершении передачи, если TXCIE= 1;
UDRIE - разрешение прерывания при опустошении регистра данных UART, если UDRIE = 1;
RXEN - разрешение приема при RXEN = 1;
TXEN - разрешение передачи при TXEN = 1;
CHR9 - формат посылок (кадров). Если CHR9 = 1, производится передача и прием 9-разрядных данных. При передаче значение старшего (8-го) разряда берется из разряда ТХВ8 регистра, а при приеме записывается в разряд RXB8;
RXB8 - 8-й разряд принимаемых данных. Если флаг CHR9 = 1, разряд RXB8 содержит значение старшего разряда принятого слова;
ТХВ8 - 8-й разряд передаваемых данных. Если флаг CHR9 = 1, значение ТХВ8 передается как старший разряд слова.
Значения битов (флагов) регистра состояния:
RXC - флаг завершения приема. Данный флаг устанавливается в 1 при пересылке принятого слова из сдвигового регистра приемника в регистр данных UDR. Сбрасывается флаг аппаратно при чтении регистра UDR;
ТХС - флаг завершения передачи. Данный флаг устанавливается в 1 после передачи всех разрядов слова, включая стоп-бит, из сдвигового регистра передатчика, при условии, что в регистр данных UDR не было загружено новое значение. Этот флаг наиболее полезен при полудуплексной связи, когда передающее устройство должно освободить линию и перейти в режим приема сразу же после окончания передачи. Флаг сбрасывается аппаратно при выполнении подпрограммы обработки прерывания или программно при записи 1 (!) в этот разряд;
UDRE - регистр данных пуст. Данный флаг устанавливается в 1 после пересылки байта из регистра данных UDR в сдвиговый регистр передатчика. Установка этого флага означает, что передатчик готов к получению нового значения для передачи. Сбрасывается флаг аппаратно при записи в регистр UDR;
FE - флаг ошибки формата. Данный флаг устанавливается в 1, если стоп-бит принятого слова равен 0. Флаг сбрасывается при приеме стоп-бита, равного 1;
OR - флаг переполнения. Данный флаг устанавливается в 1, если в сдвиговом регистре приемника находится новое принятое слово, а старое содержимое регистра UDR не прочитано. Флаг остается установленным до тех пор, пока не будет прочитано содержимое регистра UDR. Флаг сбрасывается при пересылке принятых данных из сдвигового регистра приемника в регистр UDR.
166
5. Обмен данными по последовательному интерфейсу
В микроконтроллерах ATmega8515 функции регистров UCR, USR выполняют соответственно регистры UCSRB, UCSRA. Заметим, что в регистре UCSRA имеется дополнительный разряд МРСМ, присутствие которого позволяет организовать простейшую локальную мультипроцессорную систему. При значении МРСМ = 1 приемник принимает кадры, у которых 9-й бит равен 1 и игнорирует кадры с 9-м битом, равным 0. При значении МРСМ = = 0 приемник принимает кадры с любым значением 9-го бита. В микроконтроллерной сети один контроллер имеет статус ведущего, остальные - ведомых. У всех ведомых контроллеров перед началом работы бит МРСМ = 1. Ведущий контроллер посылает байт, содержащий адрес ведомого контроллера, с 9-м битом, равным 1. Все контроллеры принимают его, проверяют поступивший адрес, сравнивая с собственным адресом, присвоенным при инициализации сети. Тот контроллер, который опознал поступивший адрес как собственный, переключает бит МРСМ в состояние 0. Данные, пересылаемые ведущим контроллерам, содержат 9-й бит, равный 0. Эти данные могут быть приняты только тем контроллером, бит которого МРСМ = 0. Если от ведущего контроллера поступит новый адрес в кадре с 9-м битом, равным 1, принимающий изменит значение МРСМ на 1 и вернется в исходное состояние.
Передача данных
Структурная схема передатчика модуля UART приведена на рис. 5.1.
Работа передатчика разрешается установкой в 1 разряда TXEN регистра UCR. Если этот разряд сброшен (передатчик выключен), вывод PD1 (TxD) может использоваться как линия ввода/вывода порта PD. При установке разряда TXEN этот вывод подключается к передатчику UART и начинает функционировать как выход независимо от состояния l-ro разряда регистра DDRD порта PD.
Передача инициируется записью передаваемых данных в регистр данных UDR. После этого данные пересылаются из регистра UDR в сдвиговый регистр передатчика. При этом возможны два варианта:
1) новое значение записывается в регистр UDR после того, как был передан стоп-бит предыдущего слова. В этом случае данные пересылаются в сдвиговый регистр сразу же после записи в регистр UDR;
5.1. Последовательный обмен данными по каналу UART
167
Шина данных
ЗпрТХС Зпр UDRE
Рис. 5.1. Структурная схема передатчика UART
2) новое значение записывается в регистр UDR во время передачи. В этом случае данные пересылаются в сдвиговый регистр после передачи стоп-бита текущего слова.
После пересылки содержимого регистра UDR в сдвиговый регистр флаг UDRE регистра USR устанавливается в 1, что означает готовность передатчика к получению нового значения. В этом состоянии флаг остается до новой записи в регистр UDR. Одновременно с пересылкой формируется служебная информация: 0-й разряд сдвигового регистра сбрасывается в 0 (старт-бит), а 9-й (или 10-й) разряд устанавливается в 1 (стоп-бит). Если включен режим передачи 9-разрядных данных (разряд CHR9 регистра UCR установлен в 1), то значение разряда ТХВ8 регистра UCR копируется в 9-й разряд сдвигового регистра.
После загрузки сдвигового регистра его содержимое начинает сдвигаться вправо и поступает на вывод TXD в следующем порядке:
168
5. Обмен данными по последовательному интерфейсу
стартовый бит, данные (начиная с младшего разряда), столовый бит. Сдвиг осуществляется по тактовому сигналу, вырабатываемому контроллером скорости передачи. Если во время передачи в регистр UDR было записано новое значение, то после передачи стоп-бита оно пересылается в сдвиговый регистр. Если же к моменту окончания передачи стоп-бита новой записи выполнено не было, в регистре USR устанавливается флаг завершения передачи ТХС.
Прием данных
Структурная схема приемника модуля UART приведена на рис. 5.2. После обнаружения старт-бита начинается обработка поступающих разрядов слова данных. Решение о значении принятого
Шина данных
Зпр RXC
Рис. 5.2. Структурная схема приемника UART
5.1. Последовательный обмен данными по каналу UART
169
разряда принимается по результатам трех выборок входного сигнала в середине битового периода. Состоянием разряда считается логическое значение, которое было получено по меньшей мере в двух из трех выборок. По мере распознавания разрядов принимаемой последовательности они поступают, сдвигаясь вправо, в сдвиговый регистр приемника.
Распознавание стоп-бита производится также по трем выборкам входного сигнала. Стоп-бит считается принятым, если значения хотя бы двух из трех выборок входного сигнала равны 1. В противном случае фиксируется ошибка кадра и флаг FE регистра USR устанавливается в 1. Перед чтением регистра данных UDR следует всегда проверять состояние этого флага.
Независимо от того, был или не был обнаружен стоп-бит в конце принимаемой посылки, принятое слово пересылается в регистр данных UDR и устанавливается флаг RXC регистра USR. В случае обмена 9-разрядными данными при пересылке содержимого сдвигового регистра приемника в регистр данных 9-й разряд принятого слова загружается в разряд RXB8 регистра UCR.
Если новое слово поступит до того как из регистра UDR будут считаны предыдущие данные, возникает переполнение. Об этом сигнализирует флаг OR регистра USR, который в этом случае устанавливается в 1. Установка этого флага означает, что принятые данные не могут быть переданы из сдвигового регистра в регистр данных и оказываются потерянными. Сбрасывается указанный флаг только после обращения к регистру данных, поэтому при высоких скоростях передачи либо большой загрузке процессора программа должна проверять состояние флага OR в регистре USR для обнаружения возможного переполнения. В микроконтроллерах ATmega8515 добавлен контроль четности принимаемых байтов и возможность удвоения скорости обмена. В случае обнаружения ошибки в принятых данных устанавливается в 1 флаг РЕ (бит 2) в регистре UCSRA, а для ускорения обмена следует установить в 1 бит U2X (бит 1) в том же регистре, уменьшающий коэффициент предделителя контроллера скорости с 16 до 8.
Скорость приема/передачи
Управление скоростью приема/передачи данных осуществляется контроллером скорости передачи, который является обыкновенным делителем частоты. Скорость передачи зависит от содержимого регистра контроллера. В AT90S8515 - это регистр
170
5. Обмен данными по последовательному интерфейсу
ввода/вывода UBRR, в ATmega8515 - регистры UBRRH:UBRRL. Скорость передачи определяется следующим выражением:
BAUD =-----,
16(UBRR + 1)
где BAUD - скорость передачи, бод; fCLK - тактовая частота микроконтроллера, Гц; UBRR - содержимое регистра контроллера скорости передачи.
Как известно, существует ряд значений скорости передачи данных, являющихся, по сути, стандартными. Значения UBRR, позволяющие получить эти скорости передачи при использовании различных резонаторов, а также ошибки, получаемые относительно их теоретического значения, приведены в табл. 5.3. Поскольку максимальная тактовая частота, устанавливаемая с помощью STK500, равна 3,69 МГц, значения частот выше этого в табл. 5.3 не приведены. С увеличением ошибки помехозащищенность линии передачи снижается, скорости передачи, имеющие ошибку установки более 1 %, использовать не рекомендуется.
Таблица 5.3. Значения UBRR для различных/ськ
Скорость, бод	fCLK ~ 1 МГц	Ошибка, %	fcLK = 2,4576 МГц	Ошибка, %	fCLK= 3,6864 МГц	Ошибка, %
2400	25	0,2	63	0	95	0
4800	12	0,2	31	0	47	0
9600	6	7,5	15	0	23	0
14400	3	7,8	10	3,1	15	0
19200	2	7,8	7	0	11	0
28800	1	7,8	4	6,3	7	0
38400	1	22,9	3	0	5	0
57600	0	7,8	2	12,5	3	0
76800	0	22,9	1	0	2	0
115200	0	84,3	0	25,0	1	0
Практическая часть
Задание 1. Подготовить программы для исследования передачи и приема по последовательному каналу UART. Напомним, что в качестве выхода передатчика используется вывод PD1 (TXD), а в качестве входа приемника - PDO (RXD).
5.1. Последовательный обмен данными по каналу UART 171
Визуально, используя светодиодную индикацию, контролировать передаваемые данные невозможно из-за большой скорости передачи, поэтому возможны следующие варианты контроля работы канала UART:
1) используя программу Hiper Terminal для обмена сообщениями через COM-порт персонального компьютера с микроконтроллером на плате STK.500 по интерфейсу RS-232;
2) соединив выводы UART двух микроконтроллеров, размещенных на платах STK.500, напрямую либо через разъем интерфейса RS-232 и подключив к выходам принимающего микроконтроллера светодиодную индикацию STK500. Схема включения микроконтроллеров МК1 и МК2 для этого случая приведена на рис. 5.3.
МК1	МК2
Рис. 5.3. Схема устройства для передачи сообщения по интерфейсу UART
Запрограммируем микроконтроллер МК1 для передачи данных, микроконтроллер МК2 - для приема. Данные для передачи - три байта сообщения - разместим в памяти программ. Передача начинается с нажатия кнопки SW4 (Старт). Первый микроконтроллер выполняет в цикле последовательный вывод данных. После приема каждого байта данных второй микроконтроллер сохраняет их в своей памяти SRAM, начиная с адреса $180. Закончив прием, второй микроконтроллер последовательно выводит при нажатии кнопки SW5 (Просмотр) полученные данные на светодиоды.
Схемы алгоритмов передачи и приема приведены на рис. 5.4.
172
5. Обмен данными по последовательному интерфейсу
Рис. 5.4. Схемы алгоритмов передачи из микроконтроллера 1 (а) и приема в микроконтроллер 2 (б)
После инициализации оба микроконтроллера переходят в режим ожидания нажатия кнопки SW4. Микроконтроллер МК2, программируемый для приема, ожидает поступления данных. Его дальнейшая работа зависит от значения флага RXC: ожидание - при RXC = 0 и ввод байта данных - при RXC = 1. Состояние этого флага зависит от работы передающего устройства. Переход к последующим итерациям в циклах передачи (приема) происходит после установления флага завершения передачи ТХС (соответственно приема RXC) очередного байта данных. После завершения цикла приема включаются все светодиоды линейки индикации. Далее при последовательном нажатии на кнопку SW5 (Просмотр) осуществляется
5.1. Последовательный обмен данными по каналу UART
173
вывод принятых байтов данных на светодиоды. Ниже приведены тексты программ для передающего и принимающего микроконтроллеров.
Программа 5.1
• if-k-k-k-k-k-k-k-k-k-k-k-k-k-k-k-k-k-k-k-k-k-k-k-k-k-k'k-k-k-k^-k-k-k-k-k-k-k-k-k-k-k'k-k-k-k-k'k'k'k-k-k-k-k'k-k f
/Программа 5.1 для МК АТх8515: демонстрация работы UART.
/При нажатии на SW4 (START) происходит последовательная /передача по каналу UART трех байтов сообщения,считываемых /из ячеек Flash-памяти. При частоте генератора 3,69 МГц, /UBRR=11 скорость передачи 19219 бод. /Соединения: PD4-SW4, GND STK500-1 с GND STK500-2 • •k-k-k-k-k-k-k-k-k-k'k'k'k-^-k-k-k-k-k-k-k-k-k-k-k-k-k-k-k-k-k-k-k-k-k-k'k-k-k-k-k-k-k'k-k-k-k-k'k-k-^'k-k-k'k-k-k г .include "8515def.inc" /файл определений AT90S8515 /.include "m8515def.inc" /файл определений ATmega8515
def temp = rl6			/временный регистр /счетчик /4-й вывод порта PD
def count		= rl7 = 4	
equ	START		
org	$000		
rjmp init
/** Инициализация МК
INIT: Idi ZL,low(text*2) /загрузка адреса текста
Idi	ZH,high(text*2)	/ сообщения в регистр Z
Idi	count,3	/установка счетчика байтов
clr	temp	/настройка
out	DDRD,temp	/ вывода
Idi	temp,(1<<PD4)	/ порта PD4
out	PORTD,temp	/ на ввод
/***Настройка UART на передачу данных
//// для ATmega8515 регистр UCSRB вместо UCR, UBRRL
Idi temp, (1»TXEN)	/разрешение
out UCR,temp	/ передачи по	каналу UART
Idi temp,11	/скорость передачи
out UBRR,temp	/ 19219 бод
WAIT_START: sbic PIND,START /ожидание нажатия rjmp WAIT—START	/ кнопки START
OUTPUT: 1pm	/считывание байта из flash-памяти в rO
out UDR,rO /вывод байта в передатчик
,•/// для ATmega8515 регистр UCSRA вместо USR sbi USR,ТХС /сброс флага ТХС
174
5. Обмен данными по последовательному интерфейсу
WAIT: sbis USR,ТХС rjmp WAIT adiw zlf 1 dec count brne OUTPUT fin: rjmp fin text: .db ’A',’V’,’R'
;ожидание
; завершение передачи /увеличение адреса на 1 /уменьшение счетчика на 1 /продолжение вывода /передача завершена
/текст сообщения
/ (ASCII - коды $41, $56, $52)
Программа 5.2
********************************************************** f
/Программа 5.2 для МК АТх8515: демонстрация работы канала
/UART в режиме приема трех байтов без проверки флагов э /ошибки приема. При частоте тактового
/генератора 3,69 МГц, UBRR=11 скорость обмена 19219 бод.
/Соединения: шлейфом порты PB-LED, PD5-SW5, GND STK500-1 с /GND STK500-2
********************************************************** г
.include "8515def.inc"	/файл определений AT90S8515
/.include "m8515def.inc" /файл определений ATmega8515
.def temp = rl6	/временный	регистр
.def count = rl7	/счетчик
.equ SHOW = 5	/5-й вывод	порта PD
.org $000
rjmp init
. ** Инициализация MK
INIT: Idi temp,low(RAMEND) /установка
out SPL,temp	/ указателя стека
Idi temp,high(RAMEND)	/ на последнюю	
out SPH,temp	/ ячейку ОЗУ
Idi YL,0x80	/в регистре Y - адрес, по которому
Idi YH,0x01	/ происходит запись принятых данных
Idi count,3	/установка счетчика байтов
ser temp	/настройка
out DDRB,temp	/ порта РВ на вывод
out PORTB,temp clr temp	/ и выключение светодиодов
out DDRD,temp	/настройка
Idi temp,(1<<PD5)	/ вывода PD5
out PORTD,temp	/ на ввод
/***Настройка UART на прием данных
//// для ATmega8515 регистр UCSRB вместо UCR, UBRRL
Idi temp,(1<<RXEN) /разрешение приема
5.1. Последовательный обмен данными по каналу UART
175
out UCR,temp	; по каналу UART
Idi temp,11	/скорость приема/передачи
out UBRR,temp	; 19219 бод
;/// для ATmega8515 регистр UCSRA вместо USR
WAIT_RXC: sbis USR,RXC rjmp WAIT_RXC in temp,UDR st Y+,temp dec count brne WAITJRXC clr temp out PORTB,temp loop: Idi YL,0x80
Idi count,3
;ожидание
; завершение приема /ввод байта из приемника
/ и сохранение в памяти /уменьшение счетчика на 1
/продолжение приема
/сигнализация -
/ прием завершен
/установка начального адреса
/установка счетчика байтов
WAIT_SHOW: sbic FIND,SHOW rjmp WAIT_SHOW Id temp, Y+ com temp out PORTB,temp rcall DELAY dec count brne WAIT_SHOW ser temp out PORTB,temp rjmp loop
;*** Задержка *** DELAY:Idi rl9,10 Idi r20,255 Idi r21,255 dd:dec r21 brne dd dec r20 brne dd dec rl9 brne dd
/ожидание нажатия
/ кнопки SW5
/считывание байта из памяти
/инвертирование
/вывод на светодиоды
/задержка
/если показаны не все данные, / продолжение при нажатии SW5 /вывод окончен /светодиоды погашены /повторение вывода
ret
Проверка работы канала UART с помощью программы Hyper Terminal.
А. Создать в AVR Studio 4 проект для передачи данных с помощью программы 5.1. Проверить работу программы в режиме симуляции, наблюдая состояния регистров и битов состояния канала UART. Отлаженную программу запрограммировать в память микроконтроллера на плате STK500. Закрыть программу AVR Studio 4.
176
5. Обмен данными по последовательному интерфейсу
Проверить работу канала передачи UART, соединив при выключенном напряжении питания плату STK500 с компьютером. Для этого используем интерфейс RS-232 для передачи/приема данных из микроконтроллера по каналу UART. Соединение можно осуществить кабелем связи через 9-контактный разъем интерфейса RS-232, обозначенный на плате RS232 SPARE. Подключение микроконтроллера к интерфейсу RS-232 выполняется двухпроводным шнуром путем соединения выводов порта PDO, PD1 с контактами RXD, TXD двухконтактного разъема RS232 SPARE. После соединения подать напряжение питания на плату. Запустить программу Hyper Terminal из Windows, выбрав одноименную строку в меню Программы/ Стандартные/ Связь, и настроить канал связи, установив COM-порт, скорость обмена 19200 бод, 8-битный формат. Нажать кнопку Вызов. На плате замкнуть кнопку SW4 (Старт) для запуска передачи сообщения. Просмотреть в окне программы Hyper Terminal компьютера принятое сообщение. Повторить передачу, изменив скорость передачи данных. Проверив работу канала, закрыть программу Hyper Terminal.
Б. Создать в AVR Studio 4 проект для приема данных с помощью программы 5.2. Проверить работу программы в режиме симуляции, вручную устанавливая флаг приема RXC и данные в регистре UDR и контролируя вывод данных в выходной порт РВ.
Отлаженную программу запрограммировать в память микроконтроллера на плате STK500. Закрыть программу AVR Studio 4.
Подготовить текстовый файл короткого сообщения (из трех символов) с помощью стандартной программы Блокнот. Выполнить соединения, как описано выше. Включить напряжение питания на плате. Снова запустить программу Hyper Terminal и настроить канал связи (скорость - 19200 бит/с, биты данных - 8, четность - нет, стоповые биты - 1, управление потоком - Xon/Xoff). Выполнить команду меню Передача/Отправитъ текстовый файл. После включения светодиодов на плате вывести на индикаторы ASCII-коды принятых символов, трижды нажимая кнопку SW5. Выполнив сброс микроконтроллера, повторить передачу потока цифровых данных непосредственно с клавиатуры.
Проверка работы канала UART при передаче данных между микроконтроллерами.
Для проверки работы канала UART при передаче сообщения из микроконтроллера МК1 в микроконтроллер МК2 необходимо соединить напрямую вывод PDl(TXD) первого STK500 с выводом
5.1. Последовательный обмен данными по каналу UART
\П
PDO второго, а также соединив выводы GND обеих плат. При необходимости платы STK500 после программирования отсоединить от кабелей RS-232. При нажатии кнопок RESET оба микроконтроллера переводятся в режим ожидания. Передача сообщения начинается после нажатия кнопки SW4 (Старт) на плате первого STK500. После приема сообщения загораются все светодиоды второго STK500, показывая, что прием данных завершен. Полученные данные можно вывести на индикаторы, нажимая последовательно кнопку SW5.
Задание 2. Написать программу для передачи сообщения hello, хранимого в памяти программ микроконтроллера STK500-1, в память данных микроконтроллера STK500-2. Процедуру передачи и процедуру приема каждого символа сообщения запрограммировать, используя запросы прерываний от передатчика и приемника.
Задание 3. Изменить программу, осуществив передачу данных из памяти SRAM по каналу UART. Загрузку данных (констант) в ячейки SRAM осуществить непосредственно командами программы. Для приема данных по входу RXD использовать тот же микроконтроллер, соединив выход TXD с входом RXD.
Задания для самостоятельного программирования
1. Написать программы для двух микроконтроллеров АТх8515 для обмена данными по интерфейсу UART. Микроконтроллер МК1 после передачи данных переводится в режим приема ответного сообщения от микроконтроллера МК2. Соответственно микроконтроллер МК2 после приема данных переводится в режим передачи. Запрограммировать микроконтроллеры двух STK500: МК1 - для передачи и затем приема данных, МК2 - для приема и затем передачи. Схема устройства для исследований приведена на рис. 5.5.
Для проверки работы канала UART (USART) необходимо соединить напрямую выводы PDl(TXD), PDO(RXD) первого STK500 соответственно с выводами PDO(RXD), PDl(TXD) второго STK500, а также соединить выводы GND обеих плат. При нажатии кнопок RESET оба микроконтроллера переводятся в режим ожидания. Обмен сообщениями начинается после нажатия кнопки SW4 (старт) на плате первого STK500. По окончании обмена загораются все светодиоды обоих STK500, показывая, что обмен данными завершен. После обмена можно вывести полученные данные на индикаторы каждого STK500, нажимая последовательно кнопки SW5 (просмотр).
178
5. Обмен данными по последовательному интерфейсу
МК1	МК2
Рис. 5.5. Схема устройства для обмена сообщениями (SW4 - старт, SW5 - просмотр)
2. Написать программы для АТх8515 для обмена данными по интерфейсу UART между двумя микроконтроллерами МК1 и МК2. Обмен начинается при нажатии кнопки SW4 (старт) на плате STK500-1. Этот сигнал используется для запуска процесса одновременной передачи сообщений от каждого из микроконтроллеров, поступающих по каналу UART в присоединенный микроконтроллер. Передачу и прием данных в каждом микроконтроллере осуществить по запросам прерываний от передатчика и приемника. Скорость обмена установить равной 9600 бит/с. Принимаемые данные сохранить во внутренней памяти микроконтроллеров. После обмена данными перевести микроконтроллеры в режим просмотра принятых данных при последовательном нажатии кнопок просмотра SW5 (просмотр).
5.2. РАБОТА ПОСЛЕДОВАТЕЛЬНОГО КАНАЛА SPI
Цель работы - изучение приема и передачи информации по последовательному каналу SPI (Serial Peripheral Interface) и программирование ввода/вывода.
Интерфейс SPI используется для организации высокоскоростного канала связи между микроконтроллером и периферийными устройствами, а также обмена данными между микроконтроллерами.
В состав модуля SPI (рис. 5.6) входят:
5.2. Работа последовательного канала SP1
179
-	8-разрядный сдвиговый регистр SPDR, который принимает байт данных с шины данных микроконтроллера, сдвигает его вправо или влево с выдачей последовательного кода на вывод микроконтроллера, одновременно с выводом принимает последовательный код со входа микроконтроллера и через буферный регистр передает его на шину данных микроконтроллера;
-	8-разрядные регистр управления SPCR и регистр состояния SPSR;
-	предварительный делитель частоты;
-	схемы управления.
Рис. 5.6. Структурная схема SPI (имена сигналов на выходах 0-7 регистра SPCR приведены в табл. 5.4)
В микроконтроллерах АТх8515 для сигналов интерфейса SPI выделены четыре линии порта РВ: РВ5 - MOSI, РВ6 - MISO, PB7-SCK, PB4-/SS.
180
5. Обмен данными по последовательному интерфейсу
Порт SPI может работать в режиме ведущего (master) или ведомого (slave). Выбор режима определяется установкой бита MSTR управляющего слова SPCR (табл. 5.4).
Таблица 5.4. Управляющее слово SPCR порта SPI
№ разряда	7	6	5	4	3	2	1	0
Имя	SPIE	SPE	DORD	MSTR	CPOL	СРНА	SPR1	SPR0
При MSTR = 1 порт SPI работает в режиме ведущего. При этом вывод MOSI является выходом данных, вывод MISO - входом данных, вывод SCK - выходом для импульсов, используемых в качестве сдвиговых при приеме данных ведомым микроконтроллером. Функция вывода /SS зависит от состояния разряда DDRB.4. При DDRB.4 = 1 вывод /SS порта SPI не подключен к выводу порта РВ4, при DDRB.4 = 0 значение сигнала на входе влияет на работу порта SPI. Если PB4(/SS) = 1, порт работает в режиме ведущего, а при появлении сигнала 0 переключается в режим ведомого. Перевод порта SPI в рабочее состояние осуществляется путем установки бита SPE регистра SPCR.
При MSTR = 0 порт SPI работает в режиме ведомого. При этом вывод MOSI является входом данных, вывод MISO - выходом данных, вывод SCK - входом для импульсов сдвига, вывод /SS -входом. Выводы SPI подключаются к выводам порта РВ также при установке бита SPE регистра SPCR. Перевод порта в рабочее состояние осуществляется по сигналу логического 0 на входе /SS.
На рис. 5.7 приведена схема соединения двух микроконтроллеров для обмена данными по каналу SPI.
Рис. 5.7. Схема соединения двух микроконтроллеров (master - ведущий, slave - ведомый)
5.2. Работа последовательного канала SPI
181
Передача данных начинается после записи данных в регистр SPDR ведущего микроконтроллера. Диаграммы сигналов при передаче данных по интерфейсу SPI приведены на рис. 5.8.
Такты
6
2
3
1
4
5
7
8
SCK (CPOL=0)----
SCK (CPOL=1)----
MOSI----
Ведущий
MISO—Г Ведомый
/SS (ведомый)
MSB
2
LSB
MSB
2
LSB
СРНА=0 DORD = О
Такты
6
1
2
3
4
5
7
8
SCK (CPOL=0) — SCK (CPOL=1)—
MOSI —
Ведущий MISO^1 Ведомый
/SS (ведомый)
MSB
2
MSB
2
CPHA = 1 DORD = 0
Рис. 5.8. Временные диаграммы сигналов интерфейса SPI (* - неопределенное состояние)
Порядок выдачи определяется состоянием бита DORD при настройке канала. Если DORD = 1, вывод начинается с младшего разряда (LSB), иначе - со старшего (MSB). После выдачи последнего разряда устанавливается в 1 флаг SPIF (бит 7 регистра состояния SPSR) и одновременно вырабатывается запрос прерывания SPI STC с адресом вектора $008, если флаг разрешения прерывания SPIE от модуля SPI при настройке канала был установлен в 1. Одновременно с передачей производится прием данных от ведомого микроконтроллера. По окончании приема данных в ведомом микроконтроллере также устанавливается в 1 флаг SPIF и вырабатывается запрос прерывания SPI STC при разрешении прерывания. При попытке записи в регистр данных SPDR во время передачи очередного байта устанавливается в 1 флаг WCOL (бит 6 регистра состояния SPSR).
182
5. Обмен данными по последовательному интерфейсу
Таблица 5.5. Выбор коэффициентов деления К
SPR1	SPR0	к
0	0	4
0	1	16
1	0	64
1	1	128
Скорость передачи устанавливается для ведущего микроконтроллера с помощью битов SPR1, SPR0 регистра SPCR. Используемые для сдвига импульсы вырабатываются в результате деления тактовой частоты СК на коэффициент К согласно табл. 5.5. Значения этих битов для
ведомого МК не оказывают влияния на работу порта. Значения битов DORD (формат обмена) и CPOL (полярность сигналов сдвига на линии SCK) для ведущего и ведомого микроконтроллеров должны быть одинаковыми.
Практическая часть
Подготовить программу для исследования передачи и приема по последовательному каналу SPI. Напомним, что в качестве выхода передатчика используется вывод ведущего микроконтроллера MOSI (РВ5), а в качестве входа приемника ведомого микроконтроллера - вывод MOSI (РВ5).
Для контроля работы канала SPI используем два стартовых набора STK500. Запрограммируем микроконтроллер первого STK500 для передачи данных, микроконтроллер второго - для приема. Данные для передачи (три байта) загрузим в ячейки памяти SRAM, начиная с адреса $170, посредством команды для записи констант. Затем выполним в цикле последовательный вывод данных. После приема каждого байта данных второй микроконтроллер сохраняет его в своей памяти SRAM, начиная с адреса $180. Закончив прием, второй микроконтроллер последовательно выводит при нажатии кнопки SW5 полученные данные на светодиоды.
Схемы алгоритмов передачи и приема приведены на рис. 5.9.
Переход к следующей итерации в циклах передачи (приема) осуществляется после установки флага завершения передачи (приема) SPIF очередного байта данных. Проверка битов ошибки формата и переполнения в алгоритме приема не предусмотрена. После завершения цикла приема включаются все светодиоды линейки индикации, сигнализируя о его окончании. Затем при последовательном нажатии на кнопку SW5 осуществляется вывод принятых байтов данных на светодиоды. Далее приведены тексты программ для передающего и принимающего микроконтроллеров.
5.2. Работа последовательного канала SPI
183
Рис. 5.9. Схемы алгоритмов передачи из МК1 (а) и приема в МК2 (б)
а
Программа 5.3
********************************************************** Л
/Программа 5.3 для демонстрации работы канала SPI /передающего микроконтроллера АТх8515 в режиме MASTER. /После сброса МК1 происходит передача трех байтов, /считываемых из ячеек SRAM по адресам из регистра Z. /Соединения: РВ5мк1-РВ5мк2, РВ7мк1-РВ7мк2, РВ0мк1-РВ4мк2 • *Г*Г*Г*Г*Г*Г*Г*Г*Г**Г*Г^*Г*Г*Г*Г*Г*Г*Г*С*Г*Г*Г^*Г*Г*Г*Г*Г*Г*Г*Г*Г*Г*Г7к'*Г*Г*Г^*Г*Г*Г*Г^*С--*-*Г'*'*Г'*''*'-*'’*-*-'Л’ f .include "8515def.inc” /файл определений AT90S8515 /.include "m8515def.inc" /файл определений ATmega8515 .def temp = rl6	/временный регистр
184
5. Обмен данными по последовательному интерфейсу
.def count = rl7 .org $000	/ счетчик
rjmp init /** Инициализация MK INIT: Idi temp, OxBl out DDRB,temp Idi ZL,0x70 Idi ZH,0x01 Idi temp,0x41 st Z+,temp Idi temp,0x56 st Z+,temp Idi temp,0x52 st Z+,temp	/ SCK/PB7, MOSI/PB5, / SS/PB4, РВО для вывода /загрузка / данных в / память / данных / с использованием / косвенной / адресации с / постинкрементом
Idi ZL,0x70 Idi count,3	/установка счетчика передач
/***Настройка SPI в режиме MASTER на передачу данных Idi temp, (1«SPE) | (1«MSTR)
out SPCR,temp OUTPUT: sbi PORTB,0	/переключение сигнала
nop cbi PORTB,0 Id temp,Z+ out SPDR,temp	/ на выходе РВО / из 1 в 0 /считывание байта из памяти /вывод байта в передатчик
Wait_Transmit: sbis SPSR,SPIF	/проверка флага передачи
rjmp Wait_Transmit dec count brne OUTPUT loop: rjmp loop	/уменьшение счетчика на 1
Программа 5.4
•Ik******************************************************** г
/Программа 5.4 для демонстрации работы канала SPI /микроконтроллера АТх8515 в режиме SLAVE.
/После сброса МК2 происходит прием трех байтов, /записываемых в SRAM по адресам из регистра X. /По окончании приема загораются все светодиоды.
/При последовательном нажатии на SW5 (SHOW) происходит /чтение данных и вывод их на светодиоды.
/Соединения: SW5-PD5, шлейфом порт PC-LED ********************************************************** г
.include "8515def.inc"	/файл определений AT90S8515
/.include "m8515def.inc" /файл определений ATmega8515 .equ DD—MISO = 6
5.2. Работа последовательного канала SPI
185
.def temp = rl6
.def count = rl7
. equ SHOW = 5
.org $000 rjmp init
;***Инициализация MK
/временный регистр
;счетчик
/5-й вывод порта PD
INIT:	
Idi temp,low(RAMEND)	;установка
out SPL,temp	; указателя стека
Idi temp,high(RAMEND)	; на последнюю
out SPH,temp Idi temp, (1«DD_MISO) out DDRB,temp Idi temp,OxBO out PORTB,temp	; ячейку ОЗУ
clr temp	;настройка
out DDRD,temp	; вывода порта PD5
sbi PORTD,SHOW ser temp	; на ввод,
out DDRC,temp	; выводов порта РС
out PORTC,temp	; на вывод
Idi count,3	/установка счетчика байтов
Idi XL,0x80	;в регистре X - адрес, по которому	
Idi ХН,0х01	; происходит запись принятых данных	
;***Настройка SPI в режиме Idi temp,(1<<SPE) out SPCR,temp	SLAVE на прием данных
INPUT: sbis SPSR,SPIF rjmp INPUT	/проверка флага приема
in temp,SPDR	/ввод байта из приемника
st X+,temp	/сохранение байта в памяти
dec count brne INPUT	/уменьшение счетчика на 1
rcall OUTLED loop: rjmp loop ;***Вывод на индикаторы***	/вывод на индикацию
OUTLED: clr temp	/сигнализация -
out PORTC,temp	/ прием завершен
Idi XL,0x80	/установка начального адреса
Idi count,3	/установка счетчика байтов
WAIT_SHOW: sbic PIND,SHOW	/ожидание нажатия
rjmp WAIT_SHOW	/ кнопки SHOW
Id temp,X+	/считывание байта из памяти
com temp	/инвертирование и
186
5. Обмен данными по последовательному интерфейсу
out PORTC,temp rcall DELAY dec count
brne WAIT_SHOW ret
;***3адержка*** DELAY:Idi rl9,10
Idi r20,255
Idi r21,255 dd:dec r21 brne dd dec r20 brne dd dec rl9 brne dd ret
; вывод на светодиоды
;задержка
;если показаны не все данные,
; продолжение по нажатию SHOW
Задание 1. Создать в AVR Studio 4 проект для передачи данных с помощью программы 5.3. Проверить работу программы в режиме симуляции, наблюдая состояния регистров и линий интерфейса канала SPI. Сохранить файл с отлаженной программой.
Создать в AVR Studio 4 проект для приема данных с помощью программы 5.4. Проверить работу программы в шаговом режиме симуляции, наблюдая состояния регистров канала SPI и порта индикации PC, вручную обновляя флаг SPIF и регистр SPDR перед вводом данных и эмулируя замыкание кнопки SW5 в порту PIND.5. Сохранить файл с отлаженной программой.
Для совместной отладки программ и симуляции переда-чи/приема воспользуемся демонстрационной версией программы ISIS 6 Professional из пакета Proteus 6 Professional фирмы Labcenter Electronic с сайта http://www.labcenter.co.uk.
Создадим проект для схемы на рис. 5.10.
Микроконтроллер МК1 (U1) работает в режиме master (ведущий), микроконтроллер МК2 (U2) - в режиме slave (ведомый).
Выбрав из библиотеки компонентов Component/PickDevices/ Micro микроконтроллер AT90S8515 (ATmega8515), в окно редактора вводим два микроконтроллера, которые соединяем линиями связи. Добавляем периферийные устройства: переключатель (BUTTON) из библиотеки компонентов Component/Active и, при желании, светодиоды, так как выводы всех портов индицируются программой автоматически. Присоединяем выводы переключателя: один - к выводу порта PD5, второй - к общей шине GROUND, выбрав ее из списка Inter-sheet Terminal на панели инструментов.
5.2. Работа последовательного канала SPI
187
Рис. 5.10. Схема взаимодействия микроконтроллеров по интерфейсу SPI
Предварительно выделив правой кнопкой мыши переключатель и щелкнув левой кнопкой, в открывающемся окне назначаем ему новое имя - SW5. Сохраняем проект, создав для него новую папку (например, SamplelSPI). С помощью команд меню Source/Add /Remove Source files., добавляем файлы с программами передачи и приема. Для этого воспользуемся подготовленными в AVR Studio 4 файлами с расширением .asm. Выполняем совместную компиляцию программ командой Source/Build All. При отсутствии ошибок связываем микроконтроллеры с соответствующими им hex-файлами. Для этого нужно, выделив предварительно на схеме правой клавишей мыши обозначение микроконтроллера, щелчком левой клавиши мыши открыть окно, в котором указывается путь к файлу. (Микроконтроллеры можно связать также с hex-файлами, полученными при компиляции в AVR Studio 4, не прибегая к компиляции в ISIS. - Прим, авт.) Чтобы перейти к отладке, выполним команду меню Debug/Start/Restart Debugging. Открыв окна I/O Registers, Internal RAM, Source Code для обоих AVR устройств (Ul, U2), осуществляем пошаговую отладку, нажимая клавишу F11, наблюдая за состоянием регистров SPI и ячеек SRAM и замыкая-размыкая SW5 для вывода данных в порт PC (для светодиодов). Для ускорения работы при отладке в пошаговом режиме вызов подпрограммы задержки в программе следует закомментировать.
Задание 2. Изменить программу 5.3, организуя однократное переключение сигнала из 1 в 0 на линии РВО перед выводом первого байта и, таким образом, сохраняя постоянно уровень сигнала
188
5. Обмен данными по последовательному интерфейсу
О для всех последующих передач. Проверить работу интерфейса на модели путем симуляции.
Задание 3. Изменить обе программы, задав CPOL = 1. Проверить работу интерфейса на модели путем симуляции. Обратить внимание на изменение полярности сигналов на линии РВ7 (SCK).
Задание 4. Изменить обе программы, задав DORD = 1. Проверить работу интерфейса на модели. Обратить внимание на изменение порядка вывода битов данных на линию MOSI, т. е. начиная с младшего разряда.
Задание 5. Экспериментальная проверка передачи и приема по интерфейсу SPI в STK500.
Запрограммируем микроконтроллеры МК1 и МК2, используя две платы STK500. Отключив питание, выполним необходимые соединения между портами микроконтроллеров: PBOmki с РВ4мк2, пару (РВ5, РВ7)мк1 с парой (РВ5, РВ7)мк2, обеспечивающие передачу данных в одном направлении - из МК1 в МК2. При необходимости платы STK500 после программирования можно отсоединить от кабелей RS-232. Соединим между собой выводы GND обеих плат. На плате STK500-2 соединим шлейфом порт PC - LED, PD5-SW5. Включив питание, кнопкой RESET запустим программу микроконтроллера МК2 для приема данных, переведя его в режим ожидания установки флага приемника SPIF. Затем, запустив кнопкой RESET программу микроконтроллера МК1, выполняем передачу. По окончании приема (светодиоды включены) проверяем работу интерфейса. Нажимая кнопку SW5 на плате STK500 второго МК, наблюдаем на индикаторах принятые байты данных. Повторим передачу несколько раз, перезапуская программы микроконтроллеров (сначала МК2, затем МК1) и просматривая принимаемые данные.
Задания для самостоятельного программирования
1.	Модифицировать программы 5.3, 5.4, заменив программную проверку флага готовности SPIF обработкой запросов прерываний SPI STC. После начала передачи перевести микроконтроллер МК1 в режим ожидания, прерывая его по запросам прерываний. Микроконтроллер МК2 после выполнения инициализации ввести в режим ожидания.
2.	Написать программы для микроконтроллеров АТх8515 для обмена данными по интерфейсу SPI в полудуплексном режиме. Микроконтроллер МК1, работающий в режиме master, после передачи данных переводится в режим slave по сигналу, поступающему
5.3. Обмен данными по интерфейсу 12C(TWI)
189
на вход /SS от ведомого микроконтроллера МК2, для приема ответного сообщения. После приема данных вывести полученные данные в порт РС для индикации. Построить схемы алгоритмов программ для каждого из микроконтроллеров, связанных между собой каналом SPI. Провести отладку программ сначала в AVR Studio 4, а затем проверить их работу в STK500.
3.	Написать программы для микроконтроллеров АТх8515 для обмена данными по интерфейсу SPI в дуплексном режиме. Одновременно с передачей данных из микроконтроллера МК1 осуществить прием данных от ведомого микроконтроллера МК2. Принимаемые данные сохранить во внутренней памяти микроконтроллеров. После приема данных перевести микроконтроллеры в режим просмотра принятых данных при нажатии кнопки SW5. Отладить программы с помощью системы виртуального моделирования ISIS 6 Professional.
5.3.	ОБМЕН ДАННЫМИ ПО ИНТЕРФЕЙСУ I2C (TWI)
Цель работы - изучение приема и передачи информации по последовательному каналу I2C (Integrated Circuit) и программирование ввода/вывода.
Двухпроводный последовательный интерфейс I2C и подобные ему (Two-wire Serial Interface, TWI) обеспечивают взаимодействие МК с множеством микросхем (энергонезависимой памятью, контроллерами параллельных портов, LCD-дисплеями, микроконтроллерами и различными специализированными устрой-
VCC
Устр-во	Устр-во	Устр-во
1	2	3
Устр-во N
SDA -— SCL -— ствами).
Рис. 5.11. Схема соединения устройств по интерфейсу I2C
Данный интерфейс позволяет объединить до 128 устройств по схеме, приведенной на рис. 5.11.
Интерфейс представляет собой две линии: одна (SDA) используется для передачи данных, другая (SCL) - для тактовых сигналов. Через резисторы Rl, R2 обе линии подключены к источнику
190	5. Обмен данными по последовательному интерфейсу
питания VCC. Выходы устройств выполнены по схеме с открытым коллектором (стоком), что позволяет реализовать функцию «монтажное И» для выходных сигналов. Низкий уровень сигнала логического 0 на выходе любого из устройств устанавливает низкий уровень на всей линии. Высокий уровень на линии устанавливается, когда выводы всех устройств находятся в третьем (высокоимпедансном) состоянии.
Устройство, подключенное к шине, может иметь статус ведущего (master) или ведомого (slave). Статус микроконтроллера устанавливается программно.
Протоколом работы шины предусмотрены:
•	посылка ведущим устройством стартового бита начала обмена;
•	передача последовательности из семи разрядов адреса ведомого устройства;
•	транзакция чтения или записи 8-битовых данных;
•	получение ведущим устройством битов подтверждения передачи адреса и данных;
•	формирование бита подтверждения после приема данных;
•	посылка ведущим устройством стопового бита.
Шина I2C (TWI) является последовательной: все данные и адреса передаются по линии SDA поразрядно. Каждый передаваемый бит сопровождается тактовым сигналом на линии SCL. В течение всего времени действия сигнала SCL (SCL = 1) состояние линии SDA должно оставаться неизменным. Изменение данных на линии SDA происходит при отсутствии тактового сигнала на линии SCL (SCL = 0). Исключение составляют стартовый и столовый биты, определяющие начало и конец обмена. Стартовый бит формируется путем изменения уровня сигнала на линии SDA с 1 на 0 при SCL = 1, стоповый бит - при изменении сигнала SDA с 0 на 1 также при SCL = 1. Диаграмма изменения состояний линий интер-
Рис. 5.12. Временные диаграммы сигналов интерфейса I2C
5.3. Обмен данными по интерфейсу 12C(TWI)
191
Кроме названных особых случаев на диаграмме представлен бит повторного старта, который можно сформировать сразу после передачи байта данных. Это позволяет ведущему устройству организовать передачу нового байта данных сразу без потери контроля над шиной.
Протокол обмена по шине предполагает передачу двух типов кадров (пакетов): с адресом и данными (рис. 5.13).
| S I А6 I А5 I А4 I АЗ I А2 I Al I АО |R/W|ACK| а
| D7 | D6 | D5 | D4 | D3 | D2 | D1 | DO |АСК| б
Рис. 5.13. Формат кадра адреса (а) и кадра данных (б)
Кадр 7-разрядного адреса содержит:
S - стартовый бит;
А - 7-разрядный адрес ведомого устройства, передаваемый ведущим, начиная со старшего разряда;
R/W - управляющий бит, определяющий тип транзакции на шине (R/W = 0 - запись, R/W = 1 - чтение);
АСК - бит подтверждения.
Адрес, передаваемый ведущим устройством после захвата шины, поступает ко всем устройствам, подключенным к ней. Каждое из устройств сравнивает поступающий адрес с собственным. При распознавании ведомым устройством своего адреса оно возвращает на линию SDA сигнал подтверждения АСК низкого уровня во время 9-го тактового сигнала SCL. Если по каким-либо причинам ведомое устройство не способно обслужить запрос ведущего, оно удерживает на линии SDA сигнал высокого уровня. Нулевой адрес используется для общего вызова всех устройств. Управляющий бит в этом случае устанавливается в 0, чтобы обеспечить передачу одного и того же сообщения всем устройствам.
После передачи адреса начинается передача данных. Кадр байта данных (рис. 5.13, б) содержит восемь битов данных и один бит подтверждения, формируемый приемником. Данные, так же как и адрес, передаются последовательно бит за битом, начиная со старшего разряда. После приема каждого байта данных приемник вырабатывает сигнал подтверждения АСК путем выдачи на линию SDA сигнала низкого уровня. Высокий уровень сигнала свидетельствует об ошибке или невозможности продолжить прием. Не
192
5. Обмен данными по последовательному интерфейсу
получив подтверждения от приемника, ведущий может прекратить передачу данных, сформировав сигналы состояния Stop.
После завершения передачи байта данных работа может быть продолжена либо для передачи следующего байта в том же направлении без изменения ведомого, либо выбором нового ведомого и(или) сменой направления обмена. При завершении обмена шина освобождается ведущим устройством.
В микроконтроллерах AVR реализация протокола обмена может быть осуществлена двумя способами: программно или программно-аппаратно. Программный способ реализуется с использованием библиотеки функций для формирования протоколов обмена. Этот способ применяется в микроконтроллерах, в которых отсутствуют встроенные аппаратные средства, реализующие протокол обмена. К ним относят микроконтроллеры семейств ATtiny и АТ90. Микроконтроллеры семейства ATmega (модели 8х, 16х, 32х, 323х, 64х, 128х, 163х) имеют в своем составе модуль обмена по интерфейсу TWI, что упрощает программирование ввода/вывода. Рассмотрим подробнее оба способа.
Программная реализация протокола I2C
Программная реализация протоколов I2C для разных случаев взаимодействия устройств представляет собой набор программ, эмулирующих работу ведущего и ведомых устройств с учетом функциональных требований. Наиболее сложным является случай, когда в качестве ведущего и ведомых выступают микроконтроллеры, которые могут быть как передатчиками, так и приемниками при обмене данными и не имеют встроенных средств обмена по I2C. Более простым считается случай, когда одно из устройств (микроконтроллер) является ведущим, а ведомые устройства содержат встроенный порт для обмена по I2C. Такие устройства (датчики, устройства памяти, часы реального времени и др.) широко выпускаются различными фирмами-производителями электронных компонентов и могут быть подключены к микроконтроллеру достаточно просто.
Решая общую задачу организации взаимодействия микроконтроллера с периферийными устройствами, рассмотрим необходимые механизмы программной реализации I2C. Это предполагает программную эмуляцию I2C только со стороны ведущего микроконтроллера, что существенно упрощает работу. Алгоритмы основных транзакций шины, записи и чтения, которые использованы при программировании, представлены на рис. 5.14, 5.15.
5.3. Обмен данными по интерфейсу 12C(TWI)
193
Рис. 5.14. Схема алгоритма записи байта данных
Процедура транзакции записи (передача адресного байта и запись байта данных) начинается с захвата линии SDA (SDA = 0) -формирования стартового бита - и установки флага С = 1, косвенно используемого для выявления признака окончания цикла передачи. Путем циклического сдвига влево байта данных первый передаваемый бит вытесняет 1 из флага С в младший разряд регистра данных. Это исключает возможность преждевременного выхода из цикла,
194
5. Обмен данными по последовательному интерфейсу
Рис. 5.15. Схема алгоритма чтения байта данных
когда в регистре данных во время передачи байта остаются нулевые биты. Линия SCL переводится в 0. Значение бита С используется для управления состоянием линии SDA. Если передаваемый бит, установленный в С, равен 1, линия SDA принимает значение SDA = 1, в противном случае SDA = 0. Далее спустя время задержки устанавливается линия SCL в 1 и после проверки, если ведомое устройство не тормозит работу на линии SCL, выполняется циклический переход для вывода следующего бита данных. На последующих итерациях цикла выполняется логический сдвиг. После выявления признака конца передачи, когда все биты регистра данных равны 0, выполняется переход к процедуре проверки бита подтверждения.
Получение бита подтверждения АСК начинается с захвата линии SCL (SCL = 0) и освобождения ведущим линии SDA (SDA = = 1). После временной паузы линия SCL переключается в состояние 1 и, если она свободна от влияния ведомых устройств,
5.3. Обмен данными по интерфейсу 12C(TWI)
195
значение SDA считывается в качестве сигнала подтверждения АСК (установка или сброс бита С). После паузы на линии SCL устанавливается 0.
Процедура транзакции чтения (прием данных от ведомого) начинается с установки признака конца приема (1) в младший разряд регистра данных. Цикл чтения битов данных начинается с захвата линии SCL (SCL = 0), установки 1 на линии SCL, подтверждения высокого уровня сигнала SCL = 1 и последующего ввода бита данных в регистр данных путем опроса линии SDA и сдвига содержимого регистра данных. После очередной паузы выполняется проверка признака конца приема байта данных по значению флага С. Если не все биты получены (С = 0), прием продолжается. Если приняты все биты (С = 1), ведущее устройство переходит к формированию бита подтверждения приема АСК для ведомого устройства. При необходимости формирования бита АСК линия SDA устанавливается в 0, линия SCL переводится в состояние 1. После подтверждения SCL = 1 и паузы линия SCL вновь возвращается в состояние 0. На этом чтение байта данных заканчивается.
Процедуры формирования стартового бита, стопового и повторного старта сводятся к установке исходных состояний сигналов SDA = SCL = 1 и последующих изменений согласно приведенным выше временным диаграммам. Используемые задержки времени (паузы) необходимы для обеспечения надежной передачи. Их устанавливают согласно рекомендациям на период и длительность сигнала SCL; время удержания неактивного состояния линий интерфейса; время, предшествующее повторному старту, и др.
Практическая часть
Работу интерфейса I2C рассмотрим на примере обмена данными между микроконтроллером AT90S8515 и программируемым параллельным портом (ППП) РСА9554 фирмы Texas Instruments. Схема сопряжения микроконтроллера МК и параллельного порта ППП приведена на рис. 5.16.
Порт представляет собой микросхему, имеющую канал последовательной связи I2C, с одной стороны, и 8-разрядный параллельный канал ввода/вывода, с другой стороны. Разряды параллельного порта могут быть запрограммированы на ввод или вывод с помощью 8-разрядного управляющего слова, пересылаемого в регистр управления (конфигурации) порта. Для обращения к ППП в микроконтроллерной системе используется один из восьми адре
196
5. Обмен данными по последовательному интерфейсу
сов в диапазоне $40-$47. При этом три младших разряда определяют путем установки сигналов логического 0 и логической 1 на входах А2-А0. Для обращения к внутренним регистрам порта используется командный байт, значение которого определяет регистр и выполняемую операцию: 0 - чтение данных с входного регистра порта, 1 - запись данных в выходной регистр порта, 2 -изменение полярности сигналов, 3 - запись в регистр конфигурации (направления передачи). Обращение к порту содержит три посылки: первая служит для передачи адреса, вторая - команды, третья - данных. Обмен с портом выполняется по запросу прерывания, формируемому микросхемой ППП при изменении сигналов на входах порта. Для этого выход INT ППП подключен к входу INTO микроконтроллера (для AT90S8515 линия порта PD2).
Переключатели
Рис. 5.16. Схема связи микроконтроллера с параллельным портом по интерфейсу I2C
Задание У. Подготовить программу для исследования передачи и приема данных по последовательному каналу I2C, используя в качестве ведомого программируемый параллельный порт. Алгоритмом основной программы предусмотрена такая последовательность действий:
•	инициализация порта микроконтроллера с линиями интерфейса;
•	настройка системы прерываний микроконтроллера;
•	временная пауза;
•	настройка конфигурации ППП;
•	вызов процедуры обмена с ППП;
•	перевод микроконтроллера в режим пониженного энергопотребления и ожидания прерываний от ППП.
5.3. Обмен данными по интерфейсу 12С(ТИ7)
197
При поступлении запроса выполняются следующие действия:
•	инициализация обмена с ППП;
•	формирование состояния Start и посылка адреса;
•	запись в ППП команды ввода ($00);
•	изменение направления обмена;
•	повторный старт;
•	чтение данных из ППП;
•	обмен тетрадами;
•	сохранение данных;
•	формирование состояния Stop;
•	формирование состояния Start и посылка адреса;
•	запись команды вывода ($01);
•	обратная пересылка данных в ППП;
•	формирование состояния Stop и выход из прерывания.
Далее приведен текст программы на языке Ассемблер для обмена с ППП с включенными процедурами обмена ведущего микроконтроллера по интерфейсу I2C. При программировании протокола I2C ведущего микроконтроллера за основу взята бета-версия 1.0 программы из библиотеки AVR Studio. В программе используются две библиотечные функции задержки: i2c_hp_delay минимум на 5 мкс и i2c_qp_delay минимум на 2,5 мкс.
Программа 5.5
г
/Тестовая программа 5.5 для работы с программируемым /параллельным портом по интерфейсу I2C. Для ввода и вывода /данных используются по четыре вывода порта. При изменении /сигналов на входах порта на линии INT вырабатывается
/запрос прерывания низкого уровня. По прерыванию происходит /запись входных значений порта ППП и их передача на линии /вывода.
• k'k'k'k'k'k'k-k'k-k-k-k-k'k'k'k'k'k'k-k'k'k'k-k-k-k-k'k'k'k'k'k-k'k'k-k-k'k'k'k-k-kif-k'k-k-k-k-k'k'k'k-k-k-k-k'k
.org 0x000
rjmp RESET	/обработка сброса
.org 0x001
rjmp UPDATE	/обработчик прерывания от ППП
.include "8515def.inc"
.equ SCLP = 6
.equ SDAP = 7
.def i2cdelay = rl6
.def i2cadr = rl7
.def i2cdata = rl8
/файл определений AT90S8515
/ SCL-pin (PD6)
/ SDA-pin (PD7)
/счетчик цикла задержки /регистр адреса шины I2C /регистр данных шины I2C
198
5. Обмен данными по последовательному интерфейсу
.equ i2crd = 1	/1-чтение
.equ i2cwr = 0	/О-запись
.*********************************************************
RESET: main:
Idi rl6,HIGH(RAMEND) /установка
out sph,r!6	; указателя
Idi rl6,LOW(RAMEND) ; стека
out spl,rl6
; Инициализация интерфейса I2C
clr i2cdata	/очистка регистра данных
out DDRD,i2cdata
Idi i2cdata,0x04
out PORTD,i2cdata
/ Настройки микроконтроллера
Idi rl6, (l«INT0) /разрешение прерывания INTO / (по спаду)
out GIMSK,rl6
Idi rl6, (1«SE) | (0«ISC01) | (0«ISC00)
out MCUCR,rl6 sei
rcall i2c_hp_delay rcall i2c_hp_delay /rcall i2c_hp_delay
/пауза в ожидании
/ готовности всех устройств
/ подключенных к шине
/ Настройка конфигурации Idi i2cadr,$40+i2cwr rcall i2c_start Idi i2cdata,$03 rcall i2c_write Idi i2cdata,$f0 rcall i2c_write rcall i2c_stop rcall UPDATE
loop: sleep /переход nop rjmp loop
микросхемы ППП /посылка адреса ППП+записи /генерация стартового бита
/команда записи в порт конфигурации /старшие 4 /младшие 4 /генерация
/ввод/вывод через ППП
в режим пониженного энергопотребления
бита - на бита - на
стопового
ввод, вывод бита
/ Подпрограмма обработки прерывания от ППП
UPDATE:
idi i2cadr,$40+i2cwr /посылка адреса ППП+записи rcall i2c start
5.3. Обмен данными по интерфейсу 12C(TWI)
199
Idi i2cdata,$00	
rcall i2c_write	/команда чтения данных из порта
Idi i2cadr,$40+i2crd rcall i2c_rep_start	/изменение направления обмена
set	/подтверждения после чтения / не будет
rcall i2c_read	/чтение данных
swap i2cdata	/обмен тетрадами
mov r20,i2cdata	/сохранение
rcall i2c_stop	/генерация стопового бита
clt	/сброс флага Т
Idi i2cadr,$40+i2cwr rcall i2c_start Idi i2cdata,$01	/изменение направления обмена
rcall i2c_write mov i2cdata,r20	/команда вывода данных в порт
rcall i2c_write	/вывод данных
rcall i2c_stop reti	/генерация стопового бита
• 'к-^-к'к-к-к'к'к'к-к'к-к-к-к'к-к'к-к-к-к-к-к-к-^'к'^-к-к'к'к'к'к-к-к-к'к-к-к-к-к-к-к-к-к'кЗс'к-к-к'к'к'к-кЗсЗсЗс'к
;	ИМПОРТИРОВАННЫЕ ПОДПРОГРАММЫ,
; используемые для работы ведущего МК по протоколу I2C ********************************************************** г
/Для коммуникации используются линии порта PD - PD6(SCL) и ;PD7(SDA).Управление выводами SDA, SCL с открытым стоком /осуществляется путем начальной установки битов PORTD ;в 0 и в дальнейшем с помощью установки/сброса битов ;направления DDRD(!).
;**** Основные функции: ****
;i2c_start - стартовая посылка, посылка адреса и ;направления,
;i2c_rep_start - посылка "повторного старта" (repeated ;start),
;i2c_write - передача байта, i2c_read - прием байта, ;i2c_stop - стоповая посылка
• 'к'к-к-к-к-к-к-к-к-к'к'к'к'к'к'к-к-к-к-к-к-к-к'к'к'к'к-к-к'к-к'к'к'к-к-к-к-к-к-к-к-кЗ'-к'к-к'к-к-к'к******* г
/Функции задержек
• •к'к-к-к-к-к-к-к-к'к-к-к-^-к-^-к-к-к-к'к'к'к-к-к-к-к-к-к-к-к-к-к'к-к-к-к-к-к-к'к'к'к'к-к'к'к'к'к^'к'к'к'к'к-к'к-к
i2c_hp_delay:
Idi i2cdelay,2
/задержка (на 5 мкс минимум)
200
5. Обмен данными по последовательному интерфейсу
i2c_hp_delay_loop:
dec i2cdelay
brne i2c_hp_delay_loop ret
i2c_qp_delay:	/задержка (на 2,5 мкс минимум)
Idi i2cdelay, 1
i 2 c_qp_de1а у_1о op: dec i2cdelay brne i2c_qp_delay_loop ret
******************************************************** /
/Функция повторного старта подготавливает шину I2C к /формированию стартового бита
/За данной функцией должен следовать вызов i2c_start
******************************************************** г
i2c_rep_start:
rcall 12c_qp_delay
sbi DDRD,SCLP	/захват линии	SCL	(выход SCL=0)
cbi DDRD,SDAP	/освобождение	линии	SDA
rcall i2c_hp_delay	/задержка
cbi DDRD,SCLP /освобождение линии SCL (выход SC1=1) rcall i2c_qp_delay	/задержка
• *Г*Г*Г*Г*Г*Г*Г*Г^*Г*Г*Г^7к-*Г*Г*'^*Г*Г7к-*Г*’*Г*Г7*^^*Г^*Г*Г7к-*Г*Г*Г*Г*Г*Г^*Г*Г^*Г'*,'*''*'’*''*'*Г*Г-*,*Г,*'*Г f
/Функция формирования стартового бита
/За данной функцией должен следовать вызов i2c_wnte
г
i2c_start:
mov i2cdata,i2cadr
sbi DDRD,SDAP	/захват SDA
rcall i2c_qp_delay	/задержка
• *г*г*г*г*г*г9с^*г*г*г*г*г*г*г*г*г*г*г^*с^*г*г*г^*г*г*г^^*г*г^7к'*г^*г*с*г*с*г'***г’Л*'*'*г*г*г*г-*-,*,-*-*с--*-z
/Функция записи одного байта в ведомое устройство
/Также используется для передачи адреса
/За данной функцией должен следовать вызов i2c_get_ack
******************************************************** г
i2c_write:
sec	/установка флага С
rol i2cdata	/сдвиг первого бита в С
rjmp i2c_write_first
5.3. Обмен данными по интерфейсу 12C(TWI)
201
i2c_write_bit:
Isl i2cdata i2c_write_first: breq i2c_get_ack
sbi DDRD,SCLP brcs i2c_write_high
/посылка следующего бита в С
/переход, если передача завершена ; (регистр пуст) ;захват линии SCL /если бит установлен, / освободить SDA,
i2c_write_low: sbi DDRD,SDAP rjmp i2c_write_delay	;иначе / захват SDA
i2c_write_high: cbi DDRD,SDAP	/освобождение линии SDA
i2c_write_delay: rcall i2c_hp_delay cbi DDRD,SCLP	/задержка /освобождение линии SCL
rcall i2c_hp_delay r2c_write_check_wait: sbis PIND,SCLP	/задержка /ожидание состояния SCL=1
rjmp i2c_write_check_ rjmp i2c_write_bit • 'k-k-k-k-k-k-k'k-k'k'k'ki^-k-k'k-k'k'k-k-k-k-k	wait
/Функция чтения подтверждения. Используется функцией /i2c write
********************************************************** г
i2c_get_ack:
sbi DDRD,SCLP	/захват линии	SCL
cbi DDRD,SDAP	/освобождение	линии	SDA
rcall i2c_hp_delay /задержка cbi DDRD,SCLP	/освобождение	линии	SCL
i2c_get_ack_wait:
sbis PIND,SCLP /ожидание высокого уровня SCL rjmp i2c_get_ack_wait clc	/сброс флага С
sbic PIND,SDAP	/если SDA=1,
sec	/установка флага С
rcall i2c_hp_delay /задержка sbi DDRD,SCLP	/захват линии SCL
202
5. Обмен данными по последовательному интерфейсу
ret
.k-k-k-k-k-k-k-k-k^-k-k-k-k-k-k-k-k-k-icii-k-k-k-k-k-k'k-k-k-k-k-k-k-k^^-k-k-k-k-k-k-k-k-k-k-k-kidc^ic-k-k-k-k г /Функция чтения одного бай^га от ведомого в регистр ;i2c_data /Значение флага С=1 используется как признак конца приема /После данной функции должна следовать функция i2c_put_ack ********************************************************** г i2c_read: /Загружаем $01 - это после приема данных приведет к /установке флага С
Idi i2cdata,0x01 i2c_read_bit:
sbi DDRD,SCLP	/захват линии	SCL
rcall i2c_hp_delay	/задержка
cbi DDRD,SCLP	/освобождение	линии	SCL
12c_read_check_wait:
sbrs PIND,SCLP	/ожидание состояния SCL=1
rjmp 12c_read_check_wait
rcall i2c_hp_delay	/задержка
clc	/сброс флага С
sbic	PIND,SDAP	/если SDA=1,
sec	/установка флага	С
rol i2cdata	/сохранение принятого бита
brcc	i2c_read_bit	/прием закончен,	когда флаг С=1
********************************************************** Л /Функция формирования подтверждения. Используется функцией /i2c_read /При значении флага Т=1 подтверждение не формируется, /после чего обычно формируется столовый бит /При Т=0 формируется подтверждение приема • k-k-k'k'k-k-kic'k-k'k-k-k'k-k-k-^'k-kic-k'k'k-k-k-k-k'k-k-kicic-^-k-k-k-kic-k-k-k-k-k-k-k-k-k-k-k-k-k-kic'k-k-k-k г i2c_put_ack:
sbi DDRD,SCLP	/захват линии SCL
brtc i2c_put_ack_low /если T=0, формируем подтверждение cbi DDRD,SDAP	/освобождение линии SDA
rjmp i2c_put_ack_high i2c_put_ack_low:
sbi DDRD,SDAP	/захват SDA
i2c_put_ack_high:
5.3. Обмен данными по интерфейсу 12C(TWI)
203
rcall i2c_hp_delay cbi DDRD,SCLP
12 c_pu t_ac k_wa i t: sbis FIND,SCLP rjmp i2c_put_ack_wait rcall i2c_hp_delay sbi DDRD,SCLP ret
;задержка
;освобождение линии SCL
;ожидание освобождения SCL
;задержка
• ********************^ г	'.'k'-k-k-k-k'k'k'k'k'k'k'k'k-k'k'k'k'k'k'-k-k'k'k'k-k'k-fc-k-k-k-k'k-k'k'k
/Функция формирования	стопового бита
. ********************:* г	г ***********************************
i2c_stop:
sbi DDRD,SDAP	/захват SDA
rcall i2c_hp_delay cbi DDRD,SCLP	/задержка /освобождение линии SCL
rcall i2c_qp_delay cbi DDRD,SDAP	/задержка /освобождение линии SDA
rcall i2c_hp_delay ret	/задержка
********************************************************** f
Создать проект в AVR Studio 4 и загрузить тестовую программу. Проверить работу МК в пошаговом режиме, наблюдая выходы порта PD (PD6, PD7). Эмуляцию сигналов с порта ППП при чтении данных можно выполнить, устанавливая ручным способом биты данных на линии SDA (разряд PIND7). Чтобы ускорить прогон программы, рекомендуется перед компиляцией закомментировать строки программы с проверкой состояния линии SCL.
Создать проект устройства, используя схему рис. 5.16, для проверки работы канала I2C с помощью программы ISIS 6 Professional из пакета Proteus 6 Professional фирмы Labcenter Electronic. Проверить работу устройства в пошаговом режиме.
Модуль интерфейса TWI
Ряд микроконтроллеров семейства ATmega содержит встроенный модуль интерфейса TWI, позволяющий выполнять обмен данными по последовательному каналу в различных режимах.
204
5. Обмен данными по последовательному интерфейсу
Упрощенная структурная схема модуля приведена на рис. 5.17. Модуль содержит блок шинного интерфейса (SDA, SCL) с регистром данных TWDR и контроллером состояний Start/Stop, блок контроля адреса с регистром адреса TWAR и схемой сравнения, блок управления с регистрами управления TWCR и состояния TWSR, контроллер скорости передачи с предделителем и регистром скорости TWBR.
SCL
SDA
Блок интерфейса
Контроллер скорости
Контроллер состояний Start/Stop
Предделитель
Арбитраж
Сдвиговый регистр TWDR
АСК
Регистр скорости TWBR
Блок контроля адреса
Блок управления
Регистр адреса TWAR
Компаратор адреса
Регистр TWCR
Регистр TWSR
Рис. 5.17. Структура модуля TWI
Регистр данных TWDR обеспечивает параллельную загрузку байтов и последовательный вывод данных на линию SDA путем сдвига содержимого регистра влево в сторону старших разрядов.
Регистр адреса TWAR используется при работе микроконтроллера в качестве ведомого. Код, записанный в семи старших разрядах регистра, представляет собственный адрес микроконтроллера. Этот код сравнивается компаратором с адресом, поступающим в микроконтроллер при появлении адресного пакета в регистре TWDR. Младший бит TWGCE регистра TWAR разрешает распознавание общих вызовов (обращений с адресом $00). Если разряд TWGCE = 0, распознавание общих вызовов запрещено.
Управление работой порта осуществляется с помощью регистров TWCR (табл. 5.6) и TWSR (табл. 5.7).
5.3. Обмен данными по интерфейсу 12C(TWI)
205
Таблица 5.6. Формат регистра управления TWCR
№ разряда	7	6	5	4	3	2	1	0
Имя	TWINT	TWEA	TWSTA	TWSTO	TWWC	TWEN	-	TWIE
Таблица 5.7. Формат регистра состояния TWSR
№ разряда	7	6	5	4	3	2	1	0
Имя	TWS7	TWS6	TWS5	TWS4	TWS3	-	TWPS1	TWPSO
Биты регистра TWCR имеют следующее назначение:
TWEN - бит разрешения работы модуля TWI. При установке бита в состояние 1 выводы SDA, SCL подключаются к внешним выводам микроконтроллера PCI, РСО соответственно для всех ранее названных моделей микроконтроллеров, кроме ATmega8x (выводы РС4, РС5) и Atmega 64х, 128x(PDl, PDO);
TWSTA - флаг состояния Start. При установке бита в единичное состояние микроконтроллер может сформировать состояние Start, если шина свободна. Если шина занята, модуль ожидает появления состояния Stop и лишь после этого захватывает шину, формируя состояние Start;
TWSTO - флаг состояния Stop. Установка флага в состояние 1 приводит к формированию на шине состояния Stop;
TWEA - бит разрешения подтверждения. При установке бита в 1 устройство формирует сигнал подтверждения, когда это необходимо;
TWIE и TWINT - флаги разрешения и прерывания от модуля TWI. Запрос прерывания генерируется, если TWINT = 1 и TWIE = = 1. Сброс флага TWINT может быть осуществлен только при записи в него логической 1;
TWWC - флаг, устанавливаемый в 1 при попытке записи в регистр данных TWDR, когда флаг прерывания TWINT сброшен.
Биты регистра TWSR:
TWS7.. .TWS3 - код состояния модуля TWI;
TWPS1 :TWPS0 - коэффициент деления предделителя контроллера скорости передачи.
Контроллер скорости передачи формирует последовательность тактовых сигналов, поступающих на линию SCL. Частота формируемых сигналов зависит от коэффициентов деления TWBR и TWPS, загружаемых в регистры TWBR и TWSR, и для разных моделей микроконтроллеров рассчитывается по формулам:
206
5. Обмен данными по последовательному интерфейсу
-	для ATmegal63x, ATmega323x fscL =fcLK^(^ + 2TWBR);
-	для моделей ATmega 8x, 16x, 32x, 64x, 128x fsct =fcLK^ (16 + + 2TWB • R4TWPS).
Значения коэффициентов деления для различных частот fcLK и fscL приведены в табл. 5.8.
Таблица 5.8. Таблица коэффициентов для выбора скорости обмена по TWI
fcLK, МГц	TWBR	TWPS	fsCL, кГц	fcLK, МГц	TWBR	TWPS	fsCb кГц
16	12	0	400	8	10	0	-222
16	72	0	100	8	32	0	100
14,4	10	0	400	4	12	0	100
14,4	64	0	100	3,6	10	0	100
12	10	0	-333	2	10	0	-55
12	52	0	100	1	10	0	-28
При работе модуля в качестве ведомого скорость обмена зависит от импульсной последовательности, поступающей в микроконтроллер через вывод SCL.
Модуль TWI может работать в следующих режимах:
-	ведущий с передачей байтов данных;
-	ведущий с приемом байтов данных;
-	ведомый с приемом байтов данных;
-	ведомый с передачей байтов данных.
Процедура передачи одного байта данных от ведущего к ведомому представляет собой определенную последовательность действий.
1.	В регистр TWCR выводится команда для формирования состояния Start. Для этого необходимо установить в 1 бит TWSTA (TWSTA = 1), сбросить флаг TWINT (TWINT = 1) и установить бит активизации модуля TWI (TWEN = 1). После формирования состояния Start флаг TWINT устанавливается в 1. Для перехода к следующему действию выполняется проверка кода состояния $08 в регистре TWSR. (Ожидание установки флага TWINT можно заменить обработкой запроса прерывания. - Прим, авт.) Программная реализация функции старта представлена далее в программе 5.6 процедурой Send_Start.
5.3. Обмен данными по интерфейсу 12C(TWI)
207
2.	Содержимое пакета с адресом и нулевым значением бита направления записывается в регистр TWDR. Передача инициализируется сбросом флага TWINT. После завершения передачи адреса и получения бита подтверждения флаг TWINT устанавливается в 1, а в регистре TWSR устанавливается код статуса $18. Программная реализация функции записи представлена в программе процедурой Send_Adr.
3.	После проверки кода статуса в регистр данных TWDR загружается байт данных для передачи и сбрасывается флаг TWINT. По окончании передачи данных и получения бита подтверждения флаг TWINT устанавливается в 1, а в регистре TWSR устанавливается код статуса $28. Эти действия обеспечивают передачу от ведущего устройства ведомому как команд, так и данных. Программная реализация функции вывода данных (а также команд) представлена в программе процедурой Send_Com_Data.
4.	После успешного завершения передачи выполняются команды для формирования состояния Stop. Программная реализация функции представлена в программе процедурой Stop.
Кратко определим последовательность действий, выполняемых при приеме одного байта данных ведущим устройством:
1)	в регистр TWCR выводится команда для формирования состояния Start; после формирования состояния Start флаг TWINT устанавливается в 1. Для перехода к следующему действию выполняется проверка кода состояния ($08) в регистре TWSR. (Ожидание установки флага TWINT также можно заменить обработкой запроса прерывания. - Прим, авт.);
2)	содержимое пакета с адресом и единичным значением бита направления записывается в регистр TWDR и инициализируется передача. После завершения передачи адреса и получения бита подтверждения флаг TWINT устанавливается в 1, а в регистре TWSR устанавливается код статуса ($40);
3)	после сброса флага TWINT (разрешения приема) и получения байта данных от ведомого данные из регистра TWDR переписываются в один из регистров общего назначения. При успешном приеме код статуса в регистре TWSR принимает значение $50. При необходимости формируется бит подтверждения приема;
4)	после завершения приема выполняется команда для формирования состояния Stop.
Последовательность действий, выполняемых при приеме одного байта данных ведомым устройством, можно определить следующим образом:
208
5. Обмен данными по последовательному интерфейсу
1)	в регистр TWCR выводится команда, сбрасывающая флаг TWINT;
2)	после приема первого байта с адресом ведомого устройства формируется запрос прерывания, проверяется код статуса в регистре TWSR; если он равен $60, прием собственного адреса выполнен успешно;
3)	передается бит подтверждения путем установки TWEA = 1 и выполняется сброс флага TWINT;
4)	проверяется код статуса в регистре TWSR (если он равен $80, значит в регистр TWDR принят байт данных); передается бит подтверждения (TWEA = 1) и выполняется сброс флага TWINT;
Действия 4-го шага повторяются, пока не будет принято все сообщение. При поступлении состояния Stop в регистре TWSR формируется код статуса $А0 (конец пакета).
Подобным образом можно представить действия ведомого устройства при передаче данных. Подробное описание всех вариантов обмена и формируемые при этом значения статусных кодов можно найти в технической документации применяемой модели микроконтроллера.
Практическая часть
Работу встроенного модуля TWI рассмотрим на примере вывода данных из микроконтроллера ATmega8x в параллельный порт РСА9554 для индикации. Схема сопряжения микроконтроллера МК и параллельного порта приведена на рис. 5.18.
Рис. 5.18. Схема устройства для обмена данными с ППП по интерфейсу TWI
5.3. Обмен данными по интерфейсу 12C(TWI)
209
Задание 2. Подготовить программу для проверки обмена данными между микроконтроллером и параллельным портом, используя встроенный модуль интерфейса TWL В качестве примера ниже приведена программа 5.6, которая выполняет вывод в порт инвертируемого 8-разрядного кода данных. При передаче пакетов с адресами и данными использован механизм программной проверки условий установки в 1 флага TWINT и состояний регистра TWSR.
Создать проект устройства, используя схему рис. 5.18, для проверки работы канала TWI с помощью программы ISIS 6 Professional из пакета Proteus 6 Professional. Проверить работу устройства в пошаговом режиме.
Программа 5.6
кккккккк-кккккк-к-ккккккккккккккккккккккккккккккккк-ккккккккк
/Тестовая программа 5.6 для вывода данных в программируе-;мый параллельный порт по интерфейсу TWI .*********************************************************
org 0x000
rjmp init
include "m8def.inc"
/файл определений ATmega8
def SLA_W = rl7
/адресный байт
def DATA = rl8
/байт данных (команды)
equ i2crd = 1	/1-чтение
equ i2cwr = 0	/0-запись
;**** Коды статуса в .equ START = 0x08 .equ MT_SLA_ACK = 0x18 .equ MT_DATA_ACK = 0x28
init:
Idi rl6,HIGH(RAMEND) out sph,rl6
Idi rl6,LOW(RAMEND) out spl,rl6
/Подготовка TWI к работе Idi rl6,12 out TWBR,rl6 Idi rl6, (1«TWEN) out TWCR,rl6 Idi r20,0xAA
/Настройка микросхемы ППП
к к к к
старта передачи адреса передачи данных
/инициализация
/ указателя стека
режиме ведущий передатчик /после /после /после
/при частоте Folk = 4 МГц
/ TWBR=12 TWPS=0
/ Fscl=100 кГц
/ данные для вывода
210
5. Обмен данными по последовательному интерфейсу
rcall Send_Start Idi SLA_W,$40+i2cwr rcall Send_Adr Idi DATA,$03
rcall Send_Com_Data Idi DATA,0x00
rcall Send_Com_Data rcall Stop /Вывод данных
loop: rcall Send_Start Idi SLA_W,$40+i2cwr rcall Send_Adr Idi DATA,$01
rcall Send_Com_Data mov DATA,r20
rcall Send_Com_Data rcall Stop com r20 rjmp loop
;генерация стартового бита /посылка адреса+записи
/команда записи в порт
/ конфигурации
/настройка ППП на вывод
/генерация стопового бита
/генерация стартового бита /посылка адреса+записи
/выходной регистр
/вывод данных
/генерация стопового бита
/инвертирование /повторение вывода
л
/ Функции режима ведущего передатчика • 'к^'к'к-к-к-к-к-к-к-к-к-к-к-к-к-к-к-к'к'к'к'к-к-к-к-к-к-к-к-к-к-к'к'к-^'к-к-к-к-к-к-к-к-к-к'к'к'к'к'к'к'к-к-к-к-к г
Send_Start:
Idi rl6, (1«TWINT) | (1«TWSTA) | (1«TWEN)
out TWCR,rl6	/условия для состояния START
waitl:
in rl6,TWCR
sbrs rl6,TWINT /ожидание установки флага TWINT rjmp waitl in rl6, TWSR andi rl6,0xF8
cpi r16,START /проверка выполнения старта brne error ret
Send_Adr:
out TWDR,SLA_W /загрузка пакета с адресом Idi rl6, (1«TWINT) | (1«TWEN) out TWCR,rl6	/передача
wait2:
in rl6,TWCR
sbrs r16,TWINT /ожидание установки флага TWINT
5.3. Обмен данными по интерфейсу 12C(TWI)
211
rjmp wait2
in rl6,TWSR andi rl6r 0xF8 cpi rl6,MT_SLA_ACK /проверка выполнения передачи brne error
ret
Send_Com_Data:
out TWDR,DATA /загрузка байта данных
Idi rl6, (1«TWINT) | (1«TWEN)
out TWCR,rl6	/передача
wait3:
in rl6,TWCR
sbrs rl6,TWINT /ожидание установки флага TWINT rjmp wait3
in rl6,TWSR andi rl6,0xF8 cpi rl6,MT_DATA_ACK /проверка выполнения передачи brne error ret
Stop: Idi rl6, (KCTWINT) | (1«TWEN) | (1«TWSTO)
out TWCR,rl6	/условия для состояния STOP
Idi rl6,Oxlf
wait4: dec rl6	/задержка для состояния STOP
brne wait4 ret
error: Idi rl9, Oxff	/код ошибки
ret
Задание 3. Подготовить программы обмена данными для ведущего и ведомого микроконтроллеров. Проверить работу интерфейса TWI, по которому выполняется передача сообщения из микроконтроллера МК1 в МК2 (рис. 5.19), с помощью двух наборов STK500 по методике контроля работы интерфейса SPI, описанной в 5.2. Взамен внешних резисторов, требуемых спецификацией интерфейса, использовать внутренние подтягивающие резисторы выводов РС4, РС5 ведомого микроконтроллера.
В роли ведущего выступает микроконтроллер МК1, в роли ведомого - микроконтроллер МК2. Рабочий режим МК2 - режим ожидания. После передачи сообщения просмотреть коды символов сообщения на светодиодах, нажимая кнопку SW0.
212
5. Обмен данными по последовательному интерфейсу
Рис. 5.19. Схема устройства с интерфейсом TWI между двумя микроконтроллерами
Программа передачи ведущего микроконтроллера строится подобно 5.6. Каждый передаваемый пакет содержит служебные биты, байт адреса и байт данных. Ниже приведен основной модуль программы для передачи трех символов сообщения по интерфейсу TWI. Функции Send_Start, Send_Adx, Send_Com Data, Stop те же, что и в программе 5.6.
Программа 5.7
********************************************************** г
/Основной модуль программы 5.7 для передачи сообщения ве-;дущим микроконтроллером МК1 по интерфейсу TWI /Вызываемые функции Send_Start, Send_Adr, Send_Com_Data, / Stop из программы 5.6 /Соединения: РС4мк1-РС4мк2, РС5мк1-РС5мк2
• ^*г*г^*г*г*г*г*г*г*г^*г*г*г*-*г*г*с*г*г*г*г*г^*г*г*г*г^*г*г^*г*г9с^*г^^*г*г*г*г*г*г-^,*'*г-*--Л-*г*г-*''*'-*''*' f
org 0x000 rjmp init include "m8def.inc" def temp = rl6 def SLA_W = rl7 def DATA = rl8 def count = rl9 equ i2cwr = 0 **** Коды статуса в equ START = 0x08 equ MT_SLA_ACK = 0x18 equ MT_DATA_ACK = 0x28
/файл определений ATmega8
/адресный байт
/байт данных (команды)
/счетчик данных
/0-запись
режиме ведущий передатчик ***
/после старта
/после передачи адреса
/после передачи данных
5.3. Обмен данными по интерфейсу 12C(TWI)
213
init:
Idi rl6,HIGH(RAMEND) out sph,rl6
Idi rl6,LOW(RAMEND) out spl,rl6
Idi ZL,low(text*2)
Idi ZH,high(text*2)
Idi count,3 /Подготовка TWI к работе
Idi rl6,12
out TWBR,rl6
Idi rl6, (1«TWEN)
out TWCR,rl6 output:
rcall Send_Start
Idi SLA—W,$44+i2cwr rcall Send_Adr 1pm
mov DATA,rO
rcall Send_Com_Data rcall Stop adiw zl,l dec count brne output loop: rjmp loop text: .db ’A’,’V’,’R’
;инициализация ; указателя стека
/загрузка адреса текста
/ сообщения в регистр Z /установка счетчика передач
/при частоте Folk = 4 МГц
/ TWBR=12, TWPS-0
/ Fscl=100 кГц
/вывод данных
/генерация стартового бита /посылка адреса+записи
/считывание байта из
/ flash-памяти в гО
/вывод данных
/генерация стопового бита
/увеличение указателя адреса на 1
/уменьшение счетчика на 1
/передача выполнена
/текст сообщения
/ (ASCII - коды $41, $56, $52)
********************************************************** г
Программа ведомого микроконтроллера может иметь следующую структуру:
а)	начальная инициализация микроконтроллера, включая определение указателя стека, счетчика принимаемых данных, настройку портов, подготовку модуля TWI;
б)	разрешение прерываний и переход в режим ожидания прерываний;
в)	обработка запросов прерываний от модуля TWI, обеспечивающая прием пакетов с байтами адреса, команды и данных; сохранение байтов сообщения во внутренней памяти SRAM; подсчет числа байтов принятого сообщения; по окончании приема - последовательный вывод байтов сообщения при нажатии кнопки SW0.
214	5. Обмен данными по последовательному интерфейсу
Ниже приведен фрагмент программы ведомого микроконтроллера, включающий процедуру инициализации, и обработчик прерываний от модуля TWI, обеспечивающий прием сообщения по интерфейсу TWI и сохранение в памяти.
Программа 5.8 г
/Программа 5.8 приема по интерфейсу TWI для ведомого /микроконтроллера МК2(основной фрагмент программы) /Соединения: SW0-PB0, шлейфом порт PD-LED
• тк*^***********^*****^******^**********^*^******^*^*^**-^-^-^ f
.org 0x000 rjmp init .org 0x011
rjmp TWI_INT	/переход к обработке
/прерывания
.include "m8def.inc"		/файл определений ATmega8
. def	count = r22	/счетчик данных
. def . equ	temp = rl6 SHOW = 0	/для подпрограммы OUTLED
•	★ •A’ 1 f	*Коды статуса в режиме	ведомого****
. equ	TW_SR_SLA_ACK = 0x60	/принят байт с адресом
. equ	TW_SR_DATA_ACK = 0x80	/принят байт данных
. equ	TW_SR_STOP = 0xA0	/обнаружено состояние STOP
/***Инициализация ведомого		МК***
init:	Idi rl6,HIGH(RAMEND) out sph,rl6 Idi rl6,LOW(RAMEND) out spl, rl6 clr temp	/настройка out DDRB,temp	/	вывода порта	РВО sbi PORTB,0	/	на ввод, ser temp out DDRD,temp	/	выводов порта	PD out PORTD,temp	/ на вывод Idi count,3	/установка счетчика байтов Idi XL,0x80	/в регистре X адрес, по которому Idi ХН,0х01	/ происходит запись принятых данных	
5.3. Обмен данными по интерфейсу 12C(TWI)
215
/Подготовка модуля TWI к работе
Idi temp,0x30 /подключение подтягивающих резисторов out PORTC,temp / на линиях SCL,SDA
Idi г16,12	/при Folk = 4 МГц, TWBR=12,
out TWBR,rl6	/ TWPS=0 Fscl=100 кГц
Idi rl6,0x44	/адрес устройства I2C
out TWAR,rl6
Idi rl6, (1«TWINT) | (1«TWEA) | (1«TWIE) | (1«TWEN) out TWCR,rl6	/запуск обмена no TWI
sei loop: rjmp loop	/бесконечный цикл ожидания
.********************************************************* г /Обработчик прерывания от модуля TWI .********************************************************* г
TWI_INT: in rl6,TWSR cpi rl6,TW_SR_SLA_ACK /1-я проверка brne ierror Idi rl6, (1«TWINT) | (1«TWEA) | (1«TWEN) out TWCR,rl6
TW_WAIT_DATA:
in rl6,TWSR
cpi rl6,TW_SR_DATA_ACK/2-я проверка
brne TW_WAIT_DATA in r16,TWDR st X+,rl6	/сохранение байта данных в памяти
Idi rl6, (1«TWINT) | (1«TWEA) | (1«TWEN) out TWCR,rl6 TW_WAIT_STOP:	/ожидание состояния STOP
in rl6,TWSR cpi rl6,TW_SR_STOP	/3-я проверка
brne TW_WAIT_STOP /Байт данных принят dec count	/уменьшаем счетчик данных
brne ierror	/если не все, продолжаем,
rcall OUTLED	/ иначе выводим на индикаторы
reti ierror:
Idi rl6, (1«TWINT) | (1«TWEA) | (1«TWIE) | (1«TWEN) out TWCR,rl6	/перезапуск интерфейса
216
5. Обмен данными по последовательному интерфейсу
reti ;***Вывод на индикаторы*** OUTLED: clr temp
out PORTD,temp Idi XL,0x80 Idi count,3 WAIT_SHOW: sbic PINB,SHOW
rjmp WAIT_SHOW id temp,X+ com temp out PORTD,temp rcall DELAY dec count brne WAIT_SHOW ret . ********************** Л
;сигнализация -
; прием завершен
/установка начального адреса
;установка счетчика байтов
;ожидание нажатия
; кнопки SHOW
;считывание байта из памяти /инвертирование и
; вывод на светодиоды
;задержка из программы 5.4 /если показаны не все данные, / продолжение по нажатию SHOW
-k-k-k-k-k-k-k-j
************************
Полные тексты программ для ведущего и ведомого микроконтроллеров можно найти по ссылке [8] (проекты 5_7 и 5_8).
Задание 4. Изменить программу 5.7, выполнив передачу в одном пакете одного байта адреса и всех байтов сообщения.
Задания для самостоятельного программирования
1. Написать и отладить программу для режима ведущего микроконтроллера с приемом данных по интерфейсу TWI, используя встроенный модуль TWI.
2. Написать и отладить программу для ведущего микроконтроллера, выполняющего ввод 4-разрядного кода через младшие разряды порта ППП и вывод принятых данных через старшие разряды порта по интерфейсу TWI, используя встроенный модуль TWI.
Контрольные вопросы
1.	Как осуществляется асинхронный обмен данными по последовательному интерфейсу? Как остановить прием сообщения, длина которого заранее неизвестна?
2.	Как организовать вывод данных из программной Flash-памяти микроконтроллера?
3.	Сколько регистров данных в устройстве UART и в окне программы AVR Studio 4?
5.3. Обмен данными по интерфейсу 12C(TWI)
217
4.	Можно ли наблюдать побитовый вывод данных на линии TXD (PD1) при отладке программы 5.1 передачи данных по интерфейсу UART? Рассчитайте период представления битов на линии TXD при передаче данных со скоростью 19 200 бод. В каком порядке появляются биты на линии передачи?
5.	Объясните значения управляющих слов, загружаемых в регистр SPCR микроконтроллеров в режимах master и slave.
6.	Что произойдет, если в проекте с интерфейсом SPI вход РВ4МК2 подключить к общей шине GROUND?
7.	Как изменится режим работы устройства SPI микроконтроллера МК1 (master), если запрограммировать бит DDRB.4 в состояние 0, т. е. загрузить в регистр DDRB значение $А1 вместо $В1? В какой момент выполнения программы это произойдет?
8.	Можно ли наблюдать побитовый вывод данных на линии MOSI (РВ5) и синхросигналы SCK (РВ7) при отладке программы 5.3 передачи данных по интерфейсу SPI? Рассчитайте период синхросигналов на линии SCK по условиям инициализации порта SPI в программе 5.3.
9.	Перечислите последовательность битов в пакетах адреса, данных при вводе и при выводе по каналу I2C.
10.	Чем отличается работа ведущего устройства с битом подтверждения в транзакциях записи и чтения?
11.	Какими командами программы 5.5 выявляется конец цикла записи и цикла чтения байта данных?
12.	В какой последовательности выстраиваются транзакции на шине I2C при обмене с ППП? В каких транзакциях осуществляется передача адреса?
13.	Как изменится программа вывода в программируемый параллельный порт, если разрешить прерывания от модуля TWI?
6.	ОРГАНИЗАЦИЯ ВВОДА/ВЫВОДА ДАННЫХ ПО ПАРАЛЛЕЛЬНОМУ ИНТЕРФЕЙСУ
Для обмена с внешними устройствами широко применяют обмен байтами или тетрадами. Обмен данными микроконтроллеров с простейшими устройствами ввода/вывода пульта оператора, кнопками и индикаторами, был описан в гл. 2. Обмен данными с внешними устройствами (ВУ) в параллельном формате выполняется по протоколам, которые зависят от многих факторов - характеристик контроллеров внешних устройств, ширины интерфейса, типа обмена (однонаправленный, двунаправленный), применяемых алгоритмов обмена (синхронный, асинхронный, с квитированием, по прерыванию, по выделенной или общей шине данных, байтовый, блочный, с контролем по четности, с общей контрольной суммой и др.). При обмене могут быть использованы разнообразные инструкции (команды управления контроллерами периферийных устройств (ПУ), флаги готовности и байты состояния ВУ), адреса устройств, байты данных передаваемых или принимаемых сообщений, их контрольные суммы. Далее рассмотрены примеры возможных решений протоколов параллельного обмена в типовых приложениях.
6.1.	ВЗАИМОДЕЙСТВИЕ С КЛАВИАТУРОЙ И ЖК-ДИСПЛЕЕМ
Цель работы - изучение способов ввода/вывода информации по параллельному интерфейсу через порты микроконтроллера.
Типовым примером взаимодействия микроконтроллера с внешними устройствами по параллельному интерфейсу является обмен данными со стандартными устройствами ввода/вывода - матричной клавиатурой и дисплеем. Рассмотрим особенности работы этих устройств и программирование операций ввода/вывода.
Клавиатура. Клавиатура представляет собой кнопочный (клавишный) блок, в котором кнопки (клавиши) размещены в виде матрицы на пересечении горизонтальных и вертикальных линий связи (рис. 6.1).
6.1. Взаимодействие с клавиатурой и ЖК-дисплеем
219
Один ряд линий, например вертикальных, подключают к входному регистру, другой ряд (горизонтальных) - к выходному регистру. На входной регистр из контроллера подают код, содержащий 0 в одном разряде и единицы во всех остальных. При замыкании кнопки вертикального ряда, на котором присутствует сигнал 0, этот сигнал поступит в горизонтальную линию и по ней на выходной регистр. Проверив
состояние выходного регистра,
контроллер может идентифицировать строку, а вместе со столбцом и номер замкнутой кнопки. С помощью последовательности сканирующих кодов вида 1110,1101,1011,0111 можно опросить состояние всех столбцов клавиатуры и установить номер замкнутой кнопки (клавиши). Используя его как индекс, можно выбрать из таблицы переходов начальный адрес процедуры, выполняемой при замыкании соответствующей кнопки.
На рис. 6.2 приведен алгоритм опроса клавиатуры размером NxM и определения номера замкнутой кнопки. Перед началом цик
ла опроса устанавливают начальное значение ^-разрядного сканирующего кода и параметры циклов. Счетчик проверяемых кнопок (num) сбрасывается в исходное состояние 0. Алгоритм опроса клавиатуры представляет собой циклическую процедуру с вложенным циклом. Во внешнем цикле выполняется вывод сканирующего кода на входной регистр клавиатуры, затем ввод с выходного регистра слова состояния выбранного столбца клавиатуры. Внутренний цикл охватывает сдвиг считанного слова влево на один разряд с последующим анализом выдвинутого бита. При выполнении операции сдвига в микроконтроллере выдвигаемый бит попадает на флаг С. При С = 0 идентифицируется замыкание кнопки с номером, значение которого определено переменной num, и происходит выход из цикла. При С = 1 увеличивается на единицу значение num, повторяется сдвиг и новая проверка флага С. Если внутренний цикл не выявил факт замыкания (С = 1), выполняется выход из внутреннего цикла, сдвиг сканирующего кода влево на один разряд и повторение описанных действий. Как видно из алгоритма, его легко адапти-
220 6. Организация ввода/вывода данных по параллельному интерфейсу
Начало
Установка скан-кода, параметров циклов п, т; num = 0
Ввод состояния
Цикл i = 1, п
Сдвиг влево
num = num + 1
J
Сдвиг скан-кода влево
I-------
Рис. 6.2. Схема алгоритма опроса клавиатуры
ровать к клавиатуре любой размерности путем изменения параметров циклов (п, т).
Клавиатура, не имеющая входного и выходного регистров, может быть непосредственно подключена к выходному и входному портам микроконтроллера соответственно. Клавиатуру небольшой размерности 4x4 можно подключить к одному 8-разрядному порту, одна половина которого программируется на вывод, другая - на ввод. В качестве резисторов, устанавливаемых в горизонтальных линиях клавиатурной матрицы, используют подтягивающие резисторы разрядов порта микроконтроллера, работающих на ввод. Следует иметь в виду, что в разных конструкциях клавиатур масса и габариты кнопок могут сильно различаться. Из-за этого при замыкании и размыкании
возникают импульсные помехи - дребезг контактов, который продолжается 20 мс и более в зависимости от типа кнопки. Для борьбы с помехами клавиатуры могут быть выполнены со схемами подавления дребезга контактов в виде триггеров. При отсутствии подобных средств можно программными средствами предусмотреть блокировку от ложных срабатываний, например, повторив опрос состояния спустя 20 мс для подтверждения факта замыкания.
Процедура опроса клавиатуры осуществляется периодически через определенный интервал времени, например через 50 мс, либо по сигналу запроса, формируемому клавиатурой при замыкании любой из кнопок. Первый способ можно реализовать, настроив таймер микроконтроллера на отсчет временного интервала, определяющего период опроса. Второй способ можно реализовать в тех микроконтроллерах, порты которых формируют запрос прерывания при изменении состояния порта, как, например, в микроконтролле
6.1. Взаимодействие с клавиатурой и ЖК-дисплеем
221
рах серии Tiny. Если порты не обладают таким свойством, можно в качестве драйвера применить специальную микросхему типа 74С922 фирмы National Semiconductor, которая при подключении к клавиатуре 4x4 формирует 4-разрядный код замкнутой кнопки, подавляет дребезг и формирует запрос для микроконтроллера.
Далее в составе программы 6.1, иллюстрирующей взаимодействие микроконтроллера с клавиатурой и дисплеем, представлен программный модуль обслуживания клавиатуры размером 4x4 без дополнительного драйвера, присоединенной непосредственно к одному из портов микроконтроллера. Процедура опроса клавиатуры в этой программе запускается сигналом прерывания от таймера.
Дисплей. Дисплеи, применяемые при построении контроллеров, обычно выполняют на основе 7-сегментных индикаторов для отображения цифровой информации либо на основе жидкокристаллических (ЖК) дисплеев для отображения алфавитно-цифровой информации. Существует множество различных моделей ЖК-дисплеев, выпускаемых различными фирмами-производителями, -от простейших однострочных для вывода символьной информации, представленной ASCII-кодами, до матричных графических. Современные ЖК-дисплеи часто имеют встроенные контроллеры для управления дисплеем типа известного HD44780, который имеет собственную систему команд. Команды и данные для дисплея пересылаются по 8- или 4-разрядной шине данных, управляющие сигналы - по отдельным линиям связи.
На рис. 6.3 приведена схема простого двухстрочного дисплея LM016L, интерфейс которого содержит восемь входов для передачи команд и данных в контроллер дисплея и три линии управления:
RS - вход сигнала управления, сопровождающий передачу команд (RS = 0) и данных (RS = 1);
R/W - вход сигнала управления, определяющий тип обращения к дисплею - запись (R/W = 0) и чтение (R/W = 1);
Е - вход для синхронизирующего сигнала передачи по шине данных.
Рис. 6.3. ЖК-дисплей LM016L
222 6. Организация ввода/вывода данных по параллельному интерфейсу
Система команд контроллера HD44780 приведена в табл. 6.1. Для выполнения каждой из команд требуется определенное время, указанное в таблице. В связи с этим при программировании обмена с дисплеем необходимо после вывода каждой команды предусмотреть задержку в ожидании завершения заданной операции.
Таблица 6.1. Система команд контроллера HD44780
№	D7	D6	D5	D4	D3	D2	D1	DO	Описание команды	Время
1	0	0	0	0	0	0	0	1	Очистка дисплея, курсор по адресу 0	До 1,64 мс
2	0	0	0	0	0	0	1	-	Курсор по адресу 0, дисплей относительно буфера DDRAM в начальной позиции	От 40 мкс до 1,6 мс
3	0	0	0	0	0	1	I/D	S	Курсор сдвигается вправо (I/D = 1) или влево (I/D = 0), сдвиг дисплея (S = 1) вместе с курсором	40 мкс
4	0	0	0	0	1	D	С	в	Включение (D = 1) или выключение (D = 0) дисплея, включение курсора (С = 1) или гашение (С = 0). Мигание курсора (В = 1)	40 мкс
5	0	0	0	1	S/C	R/L	-	-	Сдвиг курсора (S/C = 0) или дисплея (S/C = 1) вправо (R/L =1) или влево (R/L = 0)	40 мкс
6	0	0	1	DL	N	F	-	-	Разрядность шины данных - четыре (DL = 0) или восемь (DL = 1) бит, количество строк дисплея -одна (N = 0) или две (N = 1), шрифт - 5 х 7 (F = 0) или 5x10 точек (F = 1)	40 мкс
6.1. Взаимодействие с клавиатурой и ЖК-дисплеем
223
Окончание табл. 6.1
№	D7	D6	D5	D4	D3	D2	D1	D0	Описание команды	Время
7	0	1	AG	AG	AG	AG	AG	AG	Установка адреса CGRAM	40 мкс
8	1	AD	AD	AD	AD	AD	AD	AD	Установка адреса DDRAM	40 мкс
9	BF			АС					Чтение состояния busy-флага и счетчика адреса	1 мкс
10	Данные								Запись данных в DDRAM или CGRAM	40 мкс
11				Данные					Чтение данных из DDRAM или CGRAM	40 мкс
Примечание. 1-8- команды, записываемые при значениях сигналов RS = = R/W = 0; 9 - чтение при RS = 0, R/W = 1; 10 - запись данных при RS = 1, R/W = = 0 в буфер данных DDRAM или в память знакогенератора CGRAM; 11 - чтение данных при RS = R/W = 1 из памяти DDRAM или CGRAM.										
Символьные данные для отображения на дисплее поступают в
коде ASCII в буфер контроллера дисплея, объем которого состав-
ляет 80 байтов. В зависимости от режима отображения (однострочный или двухстрочный) данные для вывода на экран представляют один 80-байтовый массив или два массива по 40 байтов каждый. При двухстрочном выводе начальный адрес верхней строки (строка 0) составляет $00, для нижней (строка 1) - $40. Количество позиций в строке дисплея
Окно дисплея
Рис. 6.4. Схема отображения символьной информации на двухстрочном дисплее
зависит от его типа. В модели LM016L длина строки составляет 16
позиций. Из этого следует, что длина буферного массива превышает число позиций дисплея. Поэтому для отображения всех эле
ментов массива данных окно дисплея перемещается вдоль массива (рис. 6.4).
Все элементы, попадающие в окно, отображаются на экране дисплея, остальные остаются вне зоны видимости. Курсор отоб
224 6. Организация ввода/вывода данных по параллельному интерфейсу
ражается на экране, если предварительно была введена команда отображать его и он находится в зоне видимости. В программе после передачи каждого символа данных необходимо предусмотреть временную задержку 40 мкс.
Процедуру инициализации дисплея и вывода сообщения из программной памяти микроконтроллера можно представить в виде последовательности действий.
При начальной инициализации:
1)	установка 8-битового режима вывода в две строки шрифтом 5x7, задержка;
2)	задание направления сдвига курсора вправо без сдвига дисплея, задержка;
3)	включение дисплея, гашение курсора, задержка;
4)	очистка дисплея и установка курсора в нулевую позицию, задержка;
5)	задержка 2 мс.
При выводе сообщения:
1)	установка адреса буферной памяти для вывода верхней строки дисплея, задержка;
2)	считывание байта сообщения из памяти и передача в дисплей, задержка;
3)	повторение п. 2 для вывода всех символов сообщения в верхнюю строку;
4)	установка адреса буферной памяти для вывода нижней строки дисплея, задержка;
5)	вывод символа на дисплей при замыкании кнопки клавиатуры, задержка;
6)	повторение п. 5 до заполнения строки дисплея;
7)	очистка дисплея и установка курсора в нулевую позицию,
8)	задержка 2 мс и продолжение вывода.
Программирование интерфейсов. Программирование обмена с клавиатурой и ЖК-дисплеем рассмотрим на примере проекта, в котором предусмотрен ввод с клавиатуры простого калькулятора размером 4x4, подключенного к микроконтроллеру АТ908515, и вывод на ЖК-дисплей LM016L постоянного информационного сообщения в начале работы и затем вывод кнопочных символов клавиатуры (цифр 0 - 9 и символов операций +, -, х, /). Для соединения с внешними устройствами используем порты микроконтроллера (PD - для клавиатуры, PC - для передачи команд и данных на ЖК-дисплей, РА - для передачи управляющих сигналов на дисплей). Схема проекта изображена на рис. 6.5.
6.1. Взаимодействие с клавиатурой и ЖК-дисплеем
225
7		8		9		в 1
4		5		6		X
1		2		3		—
		0				+
LM016L
Рис. 6.5. Схема соединения микроконтроллера с клавиатурой и ЖК-дисплеем
Программирование операций ввода/вывода представлено программой 6.1. После инициализации портов микроконтроллера, таймера и дисплея производится однократный вывод сообщения на верхнюю строку дисплея. Поскольку текст сообщения не изменяется при повторных запусках программы, он размещен в памяти программ. Символы кнопок отображаются на нижней строке дисплея. В этом случае по номеру замкнутой кнопки происходит обращение к таблице их символьных обозначений, откуда извлекается ASCII-код и пересылается в буфер дисплея. После заполнения строки дисплея весь экран очищается с помощью соответствующей команды, вывод на экран продолжается с начальной позиции.
Программа 6.1
л
/Программа 6.1 для демонстрации работы интерфейса
/с клавиатурой 4x4 и двухстрочным ЖК-дисплеем с встроенным /контроллером HD44780, передачей байтов команд и данных по /8-разрядной шине через порт РС. Управляющие сигналы /поступают на дисплей из МК по линиям РА5-РА7. Клавиатура /подключена к порту PD: входы клавиатуры (вертикальные
226 6. Организация ввода/вывода данных по параллельному интерфейсу
линии) соединены с выходами PD0-PD3, выходы клавиатуры		
(горизонтальные линии)	- с входами PD4-PD7.	***
include ”8515def.inc" def temp=rl6 def cols=rl8 def rots=r21 def key=rl9 def scancod=r20 def lcd=r22 def count_lcd=r23	/файл определений AT90S8515 /временная переменная /номер сканируемого ряда / клавиатуры /номер строки клавиатуры /номер кнопки /сканирующий код /регистр LCD (ЖК-дисплея) /счетчик выводимых символов / на LCD	
;Разряды порта РА для управления LCD
.equ rs=5	; (RS=1) - данные, (RS=0) - команды
.equ rw=6	;(RW=1) - чтение LCD, (RW=0) - запись в LCD
.equ e=7 /строб сигналов на шине команды/данные
.org $000 rjmp init .org $007 rjmp scankeys	/обработка клавиатуры
/Инициализация init: Idi temp,low(RAMEND)	/инициализация
out spl,temp	/ указателя стека
Idi temp,high(RAMEND) out sph,temp /Инициализация портов ser temp out DDRA,temp	/порт РА на вывод
out DDRC,temp	/порт PC на вывод
Idi temp,$0F	/линии порта PD0-PD3 на вывод,
out DDRD,temp	/ PD4-PD7 на ввод
Idi temp,$F0 out PORTD,temp /Инициализация таймера 0 Idi temp,$05 out TCCR0,temp	/коэффициент деления 1024
Idi temp, (l«TOIE0) out TIMSK, temp	/разрешение прерываний от таймера
/Инициализация ЖК-дисплея rcall delay2ms
6.1. Взаимодействие с клавиатурой и ЖК-дисплеем
227
Idi led,$38	/8-битовый режим вывода,
rcall ledcom	; 2 строки, шрифт 5x7
Idi led,$06 /Направление сдвига курсора вправо, без сдвига дисплея rcall ledcom Idi lcd,$0C	/включить дисплей,
rcall ledcom	/ погасить курсор
Idi led,$01 /Очистить дисплей и установить курсор в нулевую позицию rcall ledcom rcall delay2ms /Установка адреса буферной памяти для вывода верхней /строки дисплея Idi led,$80 rcall ledcom Idi count_lcd,12	/вывод на верхнюю строку дисплея
Idi zl,low(str_0*2) Idi zh,high(str_0*2) outO: 1pm adiw zl, 1 mov led,rO rcall leddat dec count_lcd brne outO /Установка адреса буферной памяти для вывода нижней строки /дисплея
Idi led,$С0 rcall ledcom Idi count_lcd,17 sei	/разрешение прерываний
loop: rjmp loop /Подпрограмма обработки клавиатуры scankeys: clr key clr scancod Idi cols,4 sec scan: rol scancod /формирование и вывод очередного / скан-кода
out PORTD,scancod /(0001, 0010,0100, 1000) clc Idi rots,4 in temp,PIND	/ввод состояния клавиатуры
mm: rol temp brcc nn	/проверка замыкания кнопки
228 6. Организация ввода/вывода данных по параллельному интерфейсу
rjmp press nn: inc key
dec rots brne mm dec cols brne scan
/переход при замыкании (С=0) /увеличение номера кнопки /уменьшение номера строки
/уменьшение номера ряда
press: cpi key,16
breq fl rcall led str 1
/выход при отсутствии замыканий /вывод на дисплей
fl: reti
/Подпрограмма вывода значения клавиши на нижнюю строку /дисплея lcd_str_l:
dec count_lcd brne met
/При достижении конца строки обновить счетчик вывода на /дисплей, очистить дисплей и установить курсор в нулевую /позицию
Idi count_lcd,16
Idi led,$01 rcall ledcom rcall delay2ms /Установка адреса буферной памяти на начало нижней строки
Idi led,$С0 rcall ledcom /Определение символа клавиши по ее номеру и вывод на /дисплей met: Idi zl,low(str_l*2)
Idi zh,high(str_l*2) add zl,key brcc me2 inc zh me2: 1pm mov lcd,r0 rcall leddat ret
/Подпрограмма вывода на дисплей байта команды ledcom:
out PORTC,lcd	/вывод команды
Idi temp,0x80	/установка режима	записи команд
out PORTA,temp cbi PORTA,e	/фронт 1/0 строба
rcall delay40us
6.1. Взаимодействие с клавиатурой и ЖК-дисплеем
229
ret
;Подпрограмма вывода на дисплей байта данных leddat:
out PORTC,lcd	/вывод символа
Idi temp,0xA0	/установка режима	записи данных
out PORTA,temp cbi PORTA,e	/фронт 1/0 строба
rcall delay40us ret
delay40us:	/задержка 40 мкс при Fclk = 3,69 МГц
Idi rl8,48 dO:dec rl8 brne dO ret delay2ms:	/задержка 2 мс
Idi rl7,48 dl:rcall delay40us dec rl7 brne dl ret
/ Текст сообщения для верхней строки дисплея str_0: .db ’K’,'E',’Y’,’P’,’A’,’D’,’	’,’L’,’C’,’D’
/ Обозначения клавиш, выводимые на нижнюю строку дисплея str_l: .db ’/’,’х’,’-’,’+’,’9’,’6',’3’,’=’,’8’,’5’,’2’,’0’,’7’,'4’,’1’,'*’
Задание 1. Запустить программу AVR Studio 4. Подготовить программу 6.1 для компиляции. Получить файл с расширением .hex, выполнив команды Project! Build.
Запустить программу Proteus/ ISIS для симуляции проекта с виртуальными устройствами, клавиатурой и дисплеем. Создать проект согласно схеме рис. 6.5. Выделив правой кнопкой мыши обозначение микроконтроллера, щелчком левой кнопки открыть окно настройки и указать путь к hex-файлу, полученному в AVR Studio 4. Запустить программу на выполнение. Нажимая кнопки виртуальной клавиатуры, убедиться в правильной работе программы обмена, наблюдая символы кнопок, выводимые на дисплей.
Задание 2. Изменить схему проекта, заменив клавиатуру 4x4 клавиатурой 6x4. Внести соответствующие изменения в программу. Проверить работу программы на модели с виртуальными устройствами.
230 6. Организация ввода/вывода данных по параллельному интерфейсу
Задание 3. Изменить программу, предусмотрев вывод символов на дисплей в направлении справа налево. Проверить работу программы.
Задание 4. Изменить программу, предусмотрев вывод команд и данных на дисплей по 4-разрядной шине данных. Проверить работу программы.
Задание 5. Подключить к разъемам STK500 схему дисплея и блок клавиатуры. Загрузить программу и проверить ее работу. (В комплекте STK500 эти устройства отсутствуют, поэтому задание можно выполнить при наличии соответствующих устройств клавиатуры и дисплея. - Прим, авт.)
6.2.	ОРГАНИЗАЦИЯ АСИНХРОННОГО ПАРАЛЛЕЛЬНОГО ОБМЕНА ДАННЫМИ С КВИТИРОВАНИЕМ
Цель работы - изучение режимов ввода/вывода информации через порты микроконтроллера и организация асинхронного параллельного обмена данными с квитированием.
Асинхронный обмен между микроконтроллером и ВУ можно осуществить различными способами.
Способ с опросом состояния внешнего устройства. При этом способе микроконтроллер считывает из контроллера адресованного ВУ слово состояния (SW) ВУ. Если бит готовности в слове состояния указывает на готовность ВУ к обмену данными, микроконтроллер запускает эту операцию (чтение при вводе или запись при выводе). При вводе данных микроконтроллер посылает ВУ сигнал чтения по линии управления, разрешающий передачу данных, получив который ВУ возвращает микроконтроллеру байт данных. При выводе микроконтроллер выводит в порт данные и посылает управляющий сигнал записи (Строб данных) по линии управления, по которому осуществляется фиксация данных в ВУ. Алгоритмы процедур асинхронного ввода и вывода приведены на рис. 6.6.
Способ с использованием квитирующих сигналов. Этот способ позволяет выполнить обмен между двумя устройствами - ведущим (инициатором обмена) и ведомым.
Напомним, что квитирующими называют сигналы, получаемые от ведомого устройства и используемые для подтверждения действия, инициированного ведущим устройством. Протокол обмена
6.2. Организация асинхронного параллельного обмена...
231
а
Рис. 6.6. Схемы алгоритмов асинхронного ввода (а) и вывода (б)
б
с квитированием рассмотрим на примере обмена микроконтроллера с одним ВУ, непосредственно адресуемым сигналом запроса, поступающим на вход устройства и заменяющим его адрес.
По сигналу запроса микроконтроллера ВУ информирует микроконтроллер о своей готовности, посылая ответный сигнал подтверждения (в более общем случае вместе с ним устройство может вернуть слово состояния ВУ). Приняв его, микроконтроллер получает информацию о готовности ВУ к выполнению обмена. Дальнейшие действия зависят от вида выполняемой транзакции.
Если выполняется передача данных из ВУ, микроконтроллер выводит через порт на шину байт с управляющей информацией, сопровождая его сигналом стробирования. Ведомое устройство, получив управляющую информацию, переходит к подготовке данных для передачи в микроконтроллер и выводит их (и при необходимости информацию о состоянии) на шину данных, вырабатывая сигнал подтверждения данных. Когда ведущее устройство (микроконтроллер), выполнив проверку возвращаемого сигнала, убедится, что данные отправлены, оно осуществляет их прием и сохранение в памяти. После этого ведущее устройство снимает сигнал Строб, извещая о том, что данные получены. Обнаружив сброс строба, ведомое устройство снимает данные (и управляющую информацию о состоянии) и сигнал подтверждения.
232 6. Организация ввода/вывода данных по параллельному интерфейсу
Аналогично протекают действия при операции записи данных в ВУ. После подтверждения готовности ведущее устройство выводит на шину байт данных и управляющую информацию. Получив управляющую информацию и установив тип операции обмена, ведомое устройство выполняет прием данных и по завершении возвращает сигнал подтверждения. Приняв его, ведущее устройство может начать подготовку к следующему циклу обмена.
Обмен данными между устройством ввода/вывода и микроконтроллером
С учетом возможностей используемого оборудования STK500 и базового микроконтроллера АТх8515 рассмотрим организацию асинхронного параллельного обмена по 4-разрядной шине. В зависимости от задания микроконтроллер осуществляет ввод данных по линиям порта PD3-PD0 или вывод по линиям РВЗ-РВО. Полагаем, что данные представляют собой последовательность двоично-кодированных десятичных цифр в упакованном или распакованном формате, сохраняемую при вводе в ячейках памяти SRAM и извлекаемую из ячеек SRAM при выводе. В упакованном виде каждый байт содержит по две десятичные цифры. В распакованном виде каждая цифра занимает младшую тетраду байта, старшая тетрада содержит код 0011.
Инициатором обмена выступает внешнее устройство либо микроконтроллер. В первом случае прежде чем начать обмен микроконтроллер ожидает сигнал запроса от ВУ, затем выставляет сигнал готовности к обмену, принимает или передает данные, снимает сигнал готовности, ожидает снятия запроса от ВУ, после чего продолжает работу.
Во втором случае каждая операция обмена начинается с выдачи микроконтроллером сигнала запроса к ВУ. Обмен осуществляется после приема от ВУ сигнала подтверждения готовности, при поступлении которого МК производит ввод или вывод данных, снимает запрос, ожидает снятия сигнала подтверждения со стороны ВУ и затем продолжает работу.
Обмен управляющими сигналами между МК и ВУ осуществляется при каждой передаче. ВУ вырабатывает сигнал запроса (или ответный сигнал готовности), передаваемый в МК по линии PD.7. МК выдает ответный сигнал готовности (или запрос), выводимый по линии РВ.6. Активное значение управляющего сигнала указывается в задании (Н - высокий уровень, L - низкий).
6.2. Организация асинхронного параллельного обмена... 233
На рис. 6.7 приведена диаграмма сигналов, которыми обмениваются ВУ и микроконтроллер при вводе данных по запросу ВУ. Оба сигнала управления - Зпр_ВУ (запрос от ВУ) и Подтв МК (подтверждение готовности от МК)
Зпр ВУ I*
Подтв МК |	|
WWIIWS ДАННЫЕ 1111
......... 1. !
Рис. 6.7. Диаграмма сигналов квитирования
- характеризуются высоким уровнем активности (Н).
Поскольку отладочная плата не имеет переключателя с двумя устойчивыми состояниями (0 и 1), с помощью которого можно сформировать потенциальный сигнал от ВУ, его функцию выполняют с помощью кнопки, вырабатывающей при каждом нажатии импульс, преобразуемый затем программой в потенциал, выводимый на светодиод ин
Рис. 6.8. Схема взаимодействия ВУ (оператора) и МК
дикации запроса.
На рис. 6.8 приведена схема взаимодействия кнопочного регистра SW платы STK500, программного модуля обработки кнопки, портов PD и РВ микроконтроллера и линейки светодиодов LED. Схемой предусмотрена индикация вводимых данных от кнопок SW0-SW3 с помощью светодиодов LED0-LED3 (на рис. 6.8 не показаны), сигнала запроса (LED7) и подтверждения готовности (LED6). Для этого необходимо на отладочной плате соединить 10-проводными шлейфами PD и SW, порт РВ и LED.
Для обращения по адресу в адресном пространстве SRAM (напомним, в это пространство входят регистры общего назначения, регистры ввода/вывода, ячейки внутренней памяти микроконтроллера SRAM и ячейки внешней памяти расширения ERAM) может быть использована косвенная адресация. При этом адрес ячейки памяти, из которой считываются данные при выводе или в
которую записываются данные при вводе, располагается в регистрах X (регистровая пара R26, R27), Y (пара R28, R29) или Z (пара R30, R31). При использовании команд косвенной адресации с постинкрементом после обращения по адресу, который находится
234 6. Организация ввода/вывода данных по параллельному интерфейсу
в индексном регистре, содержимое индексного регистра увеличивается на единицу. При использовании команд косвенной адресации с преддекрементом содержимое индексного регистра уменьшается на единицу, а затем производится обращение по полученному адресу. Из этого следует, что адрес в регистре X, Y или Z должен либо увеличиваться каждый раз после обработки очередного байта данных (для распакованных чисел это - обработка очередной цифры, а для упакованных - обработка двух цифр), либо уменьшаться до начала обработки байта данных. В табл. 6.2 для этого использованы обозначения Х+, Y+, Z+ и -X, -Y, -Z.
Таблица 6.2. Примеры заданий
№	Ввод/ вывод	Инициатор обмена	Уровни сигналов		Регистр адреса SRAM	Длина последовательности	Количество цифр в байте
			МК	ВУ			
1	Вывод	МК	н	н	-Z	5	1
2	Ввод	ВУ	н	L	х+	ССКО	2
3	Ввод	МК	L	Н	-Y	НЦ	1
4	Вывод	ВУ	L	L	-X	COOL	2
5	Вывод	МК	Н	L	Y+	R0	1
6	Ввод	ВУ	Н	Н	Z+	4	2
Длина цифровой последовательности задается значением либо хранится в регистре R0, либо определяется по начальной цифре передаваемой последовательности (НЦ), либо специальным символом конца обмена (ССКО), например *, ASCII-код которого равен $2А, а также по сигналу окончания обмена низкого уровня (COO L) на входе 4 порта PD (PIND.4). После завершения передачи цифровой последовательности управление передается на начало программы.
Пример программы ввода, согласно варианту 6 задания (табл. 6.2), рассмотрен ниже. Микроконтроллер осуществляет ввод упакованных чисел 4-разрядным параллельным кодом по линиям порта PD3-PD0. Начальный адрес памяти SRAM - $0170. Адресация
6.2. Организация асинхронного параллельного обмена...
235
ячеек памяти осуществляется через регистр Z с постинкрементом содержимого регистра. Длина вводимой последовательности -четыре цифры. Инициатор обмена - внешнее устройство, роль которого исполняет оператор, формирующий с помощью кнопки SW7 запрос по линии PD.7.
Программа 6.2
********************************************************** Л
/Программа 6.2 ввода четырех 2-10 цифр с упаковкой и /квитированием ввода в память SRAM по адресам /0x0170,0x0171 /SW0 - SW3 - кнопки ввода 2-10 цифры /LEDO - LED3 - индикаторы 2-10 цифры /SW7 - кнопка запроса от оператора /LED7 - индикатор запроса от оператора /LED6 - индикатор подтверждения от МК /Установить шлейфами соединения: PD-SW, PB-LED .•к-к-к-к-к-к-к-к-к-к-к-^-к-к'к-к-к-к-к'к'к'к'к-к'к'к-к'к'к'к-к-к-к'к'к'к'к-к'к-к'к-к-к'к'к'к'к'к-к-к'к'к'к'к'к'к'к г .include "8515def.inc” /файл определений для AT90S8515
/.include "m8515def.inc"	/файл определений для ATmega8515
.def temp = rl6	/временный регистр
.def in_dig = rl7	/вводимая цифра (операнд)
.def sw_cod = rl8	/код состояния замкнутой кнопки
.def in_data = r22	/формируемый байт данных
.def count = r23	/счетчик цифр одного байта
.def count_seq = r24	/счетчик цифровой / последовательности
.def reg_led = r25 /***Вывод порта pd***	/регистр состояния / светодиодов
.equ int_vu = 7 /***Выводы порта РВ***	/запрос от кнопки оператора
.equ led_int = 7	/индикатор запроса от кнопки
.equ ack_mk = 6 .macro in_sw	/индикатор подтверждения от МК
sbic PIND, @0	/проверка кнопки SW
rjmp quit	/ и установка
bld sw_cod, @0 eor in_dig,sw_cod	/ бита замкнутой кнопки
rcall OUTLED	/ с индикацией
quit: пор .endmacro
.org $000 rjmp init
236 6. Организация ввода/вывода данных по параллельному интерфейсу
;*** Инициализация *** INIT: idi temp, low(RAMEND) out SPL, temp Idi temp, high(RAMEND) out SPH, temp Idi ZL, 0x70 Idi ZH, 0x01 ser temp out DDRB, temp clr temp out DDRD, temp ser temp out PORTD, temp	/установка / указателя стека / на последнюю / ячейку ОЗУ /0x0170 - начальный адрес / памяти данных /настройка / порта РВ на вывод /настройка / порта PD / на / ввод
clr sw_cod clr in_dig set Idi count,0 Idi count_seq, 0	/очистка операнда /Т=1 (SREG) /обнуление счетчиков
/***Начало цикла передачи одной цифры*** /Инициализация регистра светодиодов (7,6 биты): /начальные значения сигналов запроса и подтверждения /по условию задания равны О loop: Idi reg_led,ObOOOOOOOO
rcall OUTLED wait: sbic PIND,int_vu	/вывод /ожидание запроса
rjmp wait bld sw_cod,int_vu	/установка бита запроса
rcall OUTLED bld sw_cod, ack_mk rcall OUTLED	/установка бита подтверждения /вывод на индикатор / подтверждения от МК
WAIT_SW7_2: in_sw 0	/ввод 4-разрядного кода данных
in_sw 1 in_sw 2 in sw 3
sbic PIND, int_vu rjmp WAIT_SW7_2	/ожидание повторного нажатия / кнопки SW7
bld sw_cod,int_vu rcall OUTLED inc count_seq inc count cpi count, 2 breq IN_DIG2 mov in_data, in_dig	/сброс запроса /увеличиваем счетчики цифр /если счетчик равен двум, то / переходим к записи 2-й цифры, / иначе сохраняем 1-ю цифру
st Z, in_data rjmp RES_ACK_mk
6.2. Организация асинхронного параллельного обмена...
237
;запись второй цифры
; в упакованном формате
; в память данных
;сброс подтверждения от МК
;очистка для записи
; новых значений
;если счетчик меньше четырех, то
; переход к новому циклу ввода
;закончен ввод четырех цифр
;с учетом предыдущего значения ; инвертирование для вывода
; на светодиоды
/обратное инвертирование
;для отпускания кнопки
IN_DIG2: swap in_data or in_data, in_dig
st Z +, in_data
Idi count, 0 RES_ACK_mk: bld sw_cod, ack_mk rcall OUTLED ;*** Сброс данных clr in_dig cpi count_seq, 4 brne loop rjmp init ;*** Индикация ввода ***
OUTLED:eor reg_led, sw_cod com reg_led out PORTB, reg_led com reg_led clr sw_cod rcall DELAY ret ;*** Задержка *** DELAY:Idi rl9,10
Idi r20,255
Idi r21,255 dd:dec r21 brne dd dec r20 brne dd dec rl9 brne dd ret
Задание 1. Составить программу на языке Ассемблер AVR для заданного варианта. Выполнить отладку программы в отладочной среде AVR Studio 4. Загрузить программу в микроконтроллер и проверить ее работу в STK500.
Обмен данными между микроконтроллерами
Обмен данными между двумя микроконтроллерами по параллельному интерфейсу может быть выполнен по протоколу с квитированием в случае занятости одного из них обслуживанием внешнего устройства. Протокол обмена рассмотрим на примере с двумя микроконтроллерами, когда один из них - МК1 - выполняет передачу данных в микроконтроллер МК2.
238 6. Организация ввода/вывода данных по параллельному интерфейсу
Для выполнения одного сеанса передачи в микроконтроллере МК1 следует предусмотреть следующие действия:
1)	посылку сигнала запроса в микроконтроллер МК2;
2)	ожидание сигнала, подтверждающего готовность МК2;
3)	при получении ответного сигнала вывод очередного байта (или тетрады) на шину данных;
4)	изменение сигнала запроса, используемое как признак присутствия данных на шине;
5)	ожидание сигнала, подтверждающего прием данных микроконтроллером МК2;
6)	выход из сеанса передачи.
За рамками сеанса связи микроконтроллер МК1 может выполнять любую работу, например подготовку очередного байта (или тетрады).
Микроконтроллер МК2 после инициализации ожидает поступления сигнала запроса на один из входов внешнего прерывания. При поступлении запроса осуществляется вызов обработчика прерывания, в котором следует предусмотреть следующие действия:
1)	возвращение запрашивающему микроконтроллеру МК1 сигнала подтверждения готовности к обмену;
2)	ожидание сигнала о присутствии данных на шине;
3)	прием данных и сохранение в пямяти;
4)	возвращение микроконтроллеру МК1 сигнала подтверждения приема;
5)	выход из прерывания.
После приема байта (тетрады) микроконтроллер МК2 возвращается к выполнению прерванной программы.
Задание 2. Разработать проект, осуществляющий передачу из МК1 в МК2 многоразрядного двоично-десятичного числа, например код номера телефона, по 4-разрядной шине.
В качестве исходного кода можно использовать данные, поступающие от оператора с кнопочного регистра, либо код, хранимый в программной памяти микроконтроллера МК1, обращение к которой начинается по сигналу от кнопки Старт.
Микроконтроллер МК2 постоянно находится в режиме бесконечного цикла. После завершения приема он осуществляет в целях контроля последовательный вывод числовой последовательности на светодиодную линейку.
Подготовить и отладить программы для обоих микроконтроллеров, используя AVR Studio 4. Проверить работу схемы на модели, используя симулятор программы ISIS Proteus 6. Загрузить обе
6.2. Организация асинхронного параллельного обмена...
239
программы в микроконтроллеры двух STK500. Выполнить необходимые соединения между микроконтроллерами. Проверить работу схемы на макете.
Задания для самостоятельного программирования
1.	Создать проект (схему и программу), осуществляющий опрос клавиатуры по запросу прерывания от замкнутой кнопки. Подготовить программу и проверить ее работу в режиме симуляции.
2.	Создать проект электронного калькулятора для выполнения целочисленных арифметических операций, используя программные модули из гл. 3.
3.	Создать проект для чередуемого ввода и вывода (двунаправленный режим обмена) по 8-разрядной шине данных через порт PD, реализующий обмен данными по запросам от микроконтроллера с квитированием. Проверить работу программы в AVR Studio 4, используя для запроса выход РВ.О и вручную симулируя в регистре PIND сигналы входных данных и на входе PINB.1 сигналы квитирования от внешнего устройства.
Контрольные вопросы
1. Как осуществляется асинхронный обмен данными по параллельному интерфейсу? Как остановить прием сообщения, длина которого заранее неизвестна?
2. Как организовать вывод данных из программной Flash-памяти микроконтроллера? Как записать данные в память программ микроконтроллера ATmega8515 в процессе выполнения программы?
7.	УСТРОЙСТВА ДЛЯ ОБРАБОТКИ АНАЛОГОВЫХ СИГНАЛОВ
Цель работы - изучение основных режимов работы аналого-цифрового преобразователя (АЦП) и аналогового компаратора, их программирование и проведение исследований в STK500.
7.1.	АНАЛОГО-ЦИФРОВОЙ ПРЕОБРАЗОВАТЕЛЬ
В своем составе ряд микроконтроллеров: ATtinyl5, AT90S/4433, AT90S8535, ATmega8x, ATmegal6x, ATmega32x и др. имеют аналого-цифровой преобразователь. Структурная схема аналого-цифрового преобразователя микроконтроллера AT90S8535 приведена на рис. 7.1.
Рис. 7.1. Схема аналого-цифрового преобразователя
7.1. Аналого-цифровой преобразователь
241
АЦП содержит 8-канальный аналоговый мультиплексор входных сигналов, регистр выбора входного сигнала ADMUX, 10-разрядный цифроаналоговый преобразователь, 8-разрядный регистр управления и состояния ADCSR, 16-разрядный регистр данных, схему формирования запроса прерывания ADC СС, схему аналогового компаратора и предварительный делитель (ПД) тактовой частоты.
Преобразователь работает по методу последовательных приближений, формируя 10-разрядный двоичный код, размещаемый в регистре данных. Работа преобразователя выполняется на частоте от 50 до 200 кГц. Для получения этой частоты используют делитель тактовой частоты с заданным коэффициентом деления. Значение коэффициента деления задают с помощью трех разрядов ADPS2, ADPS1, ADPS0 регистра управления ADCSR (табл. 7.1) согласно табл. 7.2.
Таблица 7.1. Формат регистра ADCSR
№ разряда	7	6	5	4	3	2	1	0
Имя	ADEN	ADSC	ADFR	ADIF	ADIE	ADPS2	ADPS1	ADPSO
Таблица 7.2. Таблица коэффициентов деления
ADPS2	ADPS1	ADPSO	к	ADPS2	ADPS1	ADPSO	к
0	0	0	2	1	0	0	16
0	0	1	2	1	0	1	32
0	1	0	4	1	1	0	64
0	1	1	8	1	1	1	128
Преобразование начинается после установки в 1 разряда ADSC в регистре ADCSR. После завершения преобразования устанавливается в 1 бит ADIF регистра ADCSR, используемый для формирования запроса прерывания ADC СС при разрешающем значении 1 бита ADIE регистра ADCSR. При переходе к прерывающей программе бит ADIF аппаратно сбрасывается в нулевое состояние. Программно этот бит можно сбросить в 0 путем установки 1 в данный разряд.
242
7. Устройства для обработки аналоговых сигналов
Результат преобразования, представляющий 10-разрядный двоичный код, размещается в старшей и младшей половинах регистра данных ADCH:ADCL, причем младшие восемь разрядов расположены в ADCL, оставшиеся два занимают младшие биты ADCH. Считывание результата выполняется с помощью двух операций ввода. Сначала считывается младший байт ADCL, затем старший ADCH. Такой порядок обеспечивает принадлежность читаемых данных одному и тому же результату преобразования.
Преобразователь может работать в одиночном режиме либо в циклическом. Выбор режима осуществляется с помощью бита ADFR регистра ADCSR: при ADFR = 0 выполняется одиночный режим преобразования, при ADFR = 1 - циклический. В обоих случаях преобразование начинается после установки в 1 бита ADSC. В одиночном режиме после завершения преобразования для выполнения следующего необходимо снова установить бит ADSC. В циклическом режиме следующее преобразование начинается автоматически после завершения предыдущего и прекращается после сброса бита ADFR. В обоих случаях время, затрачиваемое на первое преобразование, увеличивается для инициализации преобразователя.
Для уменьшения помех, вызываемых работой процессора, предусмотрена возможность преобразования с переводом микроконтроллера в режим холостого хода. Для этого биты управления устанавливают в состояния: ADEN = 1, ADSC = О, ADFR = О, ADIE = = 1. Далее контроллер переводится в режим холостого хода, при этом запускается АЦП. После выполнения преобразования формируется запрос прерывания, контроллер выходит из режима холостого хода и выполняет прерывающую программу.
7.2.	АНАЛОГОВЫЙ КОМПАРАТОР
Аналоговый компаратор входит в состав периферийных устройств практически всех микроконтроллеров AVR. На рис. 7.2 приведена структурная схема аналогового компаратора микроконтроллера AT90S8535. Аналоговый компаратор содержит собственно компаратор, на входы которого поступают два аналоговых сигнала - AINO и AIN1, 8-разрядный регистр управления и состояния ACSR (табл. 7.3) и элементы управления.
Компаратор имеет два входа: положительный (+) и отрицательный (-). Выходной сигнал компаратора АСО принимает значение 1, если напряжение на входе + больше напряжения на входе -.
7.2. Аналоговый компаратор
243
vcc
Рис. 7.2. Структурная схема аналогового компаратора
Таблица 7.3. Формат регистра ACSR
№ разряда	7	6	5	4	3	2	1	0
Имя	ACD	-	АСО	ACI	ACIE	ACIC	ACIS1	ACIS0
При определенном изменении сигнала АСО, обусловленном состоянием разрядов ACIS1, ACIS0 регистра ACSR (табл. 7.4), в регистре ACSR формируется сигнал ACI = = 1 и при разрешении прерывания ACIE = 1 вырабатывается запрос прерывания ANA COMP. При переходе к прерывающей программе бит ACI в регистре ACSR аппаратно
Таблица 7.4. Выбор типа запроса
ACIS1	ACIS0	Изменение АСО
0	0	Любое
0	1	-
1	0	1/0
1	1	0/1
сбрасывается в нулевое состояние. Программно этот бит можно сбросить в 0 путем установки 1 в этот разряд.
При установке разряда ACIC в состояние 1 АСО может быть использован в качестве сигнала захвата для таймера Т1. При уста-
новке ACD в 1 отключается питание компаратора, что ведет к уменьшению тока потребления микроконтроллера.
Практическая часть
Задание 1. Подготовить программу для исследования работы аналого-цифрового преобразователя в одиночном режиме. Загрузить программу в память микроконтроллера при выбранной частоте тактовых сигналов 3,69 МГц. С помощью 10-проводного шлей
244
7. Устройства для обработки аналоговых сигналов
фа соединить разъем порта РС с выводами светодиодов LEDO-LED? для наблюдения результатов и кнопку SW2 - с выводом порта PD2 для управления выводом. Вывод AGND соединить с выводом GND, AVCC - с VCC. Опорное напряжение Caref должно находиться в пределах L/gnd---^?avcc- При установленной перемычке AREF опорное напряжение для АЦП можно регулировать на вкладке Board в окне STK500 AVR Studio 4. На вход порта РАО подать напряжение с выхода потенциометра. Напряжение входного сигнала может изменяться от (7gnd Д° Гаусс- После пуска программы с помощью кнопки SW2 можно поочередно просмотреть байты результата и сделать оценку показаний АЦП.
Программа 7.1
.********************************************************* г
/Тестовая программа 7.1 работы АЦП в одиночном режиме с /просмотром 10-разрядного выходного кода на индикаторах /порта РС при нажатии кнопки SW2.
/Соединения: SW2-PD2,10-проводным шлейфом PC-LED, средняя /точка потенциометра - РАО, остальные выводы потенциометра /с выводами 9,10 (GND и VTG) разъема порта
********************************************************** г
.include "8535def.inc"	/файл определений AT90S8535
.def temp = г16	/временный регистр
.def reg_led = rl9	/регистр индикации
.org $0
rjmp init
.org $001
rjmp inter
.org $00E
rjmp adc
init:
Idi temp,low(RAMEND) out SPL,temp
Idi temp,high(RAMEND) out SPH,temp ser temp out DDRC,temp out PORTC,temp Idi temp,OxFB out DDRD,temp Idi temp,(1<<PD2) out PORTD,temp clr temp
/установка
/ указателя стека
/ на последнюю
/ ячейку ОЗУ
/порт РС
/ на вывод
/инициализация 2-го вывода
/ порта PD на ввод /включение подтягивающего / резистора порта PD /аналоговые входы
7.2. Аналоговый компаратор
245
out DDRA,temp out PORTA,temp	/ порта PA, отключены / подтягивающие резисторы
Idi temp,0x40	/разрешение внешнего
out GIMSK,temp	/ прерывания
Idi temp,0x02	/обработка прерывания INTO
out MCUCR,temp	/ по перепаду 1/0
set	/флаг Т=1 для вывода двух байтов
/Инициализация АЦП	
Idi temp,0x8D	/ ADEN=1, ADIE=1, Fadc=Fclk/32
out ADCSR,temp	/ Fadc=115 кГц при Fclk=3,69 МГц
Idi temp,0	/Канал 0 АЦП (вход РАО)
out ADMUX,temp	
sei	/разрешение прерываний
sbi ADCSR,ADSC	/пуск преобразования
loop: rjmp loop	/цикл ожидания прерываний
/Обработка прерывания от АЦП
adc: in г18,ADCL	; считывание ADCL:ADCH
in rl7,ADCH reti
/Обработка внешнего прерывания от кнопки для просмотра /результатов. Вывод в порт PC сначала двух старших, затем /восьми младших разрядов при повторном нажатии кнопки inter:
cbi ADCSR,ADIE /запрет прерывания от АЦП brtc tO clt mov reg_led, rl7 com reg_led
out PORTC, reg_led reti
tO:set
mov reg__led, rl8
com reg_led
out PORTC, reg_led
sbi ADCSR, ADIE /разрешение прерывания от АЦП sbi ADCSR, ADSC /пуск преобразования reti
Задание 2. Изменить программу, увеличив скорость преобразования в 1,5 раза.
Задание 3. Изменить программу, выполняя вывод старших восьми разрядов результата преобразования АЦП с первоначальной скоростью преобразования 115 кГц.
246
7. Устройства для обработки аналоговых сигналов
Задание 4. Изменить программу, снова увеличив скорость преобразования в 1,5 раза.
Задание 5. Изменить программу, предусмотрев возможность преобразования с переводом контроллера в режим холостого хода. Сравнить результаты наблюдений.
Задание 6. Подготовить программу для исследования работы аналогового компаратора. Загрузить ее в память микроконтроллера. На входы порта РВ2, РВЗ подать напряжения с выходов двух потенциометров. С помощью 10-проводного шлейфа соединить разъем порта PC с выводами светодиодов LED0-LED7 для наблюдения содержимого счетчика сигналов сравнения. Проверить работу программы, изменяя с помощью потенциометра напряжения на одном из входов (AINO, AIN1) при постоянном напряжении на другом входе. В окне STK500 на вкладке Board установить частоту, при которой счетчик программы count последовательно увеличивается на единицу при изменении знака разности входных сигналов.
Программа 7.2
********************************************************** г
/Тестовая программа 7.2 аналогового компаратора с выводом /счетчика изменений сигнала АСО на индикаторы порта PC. /Соединения: 10-проводным шлейфом PC-LED,
/РВ2 - выход потенциометра 1, РВЗ - выход потенциометра 2 • *Г*Г*Г*Г*Г*Г*Г*Г*Г*Г^*Г7**Г*Г*Г*Г*Г*Г*Г*С^*Г*Г*Г*Г*Г7**Г*Г*Г*С*Г*Г^*Г^*Г*Г*Г7к'*Г*Г*Г^*С*Г^*Г*Г*Г*Г'*'*Г'*'*Г'*-
f
include "8535def.inc" def temp = rl6 def count = rl7 def reg_led = rl9
/файл определений AT90S8535 /временный регистр
/регистр индикации
.org $0 rjmp init .org $010
rjmp ana_comp init:
Idi temp,low(RAMEND) out SPL,temp
Idi temp,high(RAMEND) out SPH,temp ser temp out DDRC,temp out PORTC,temp clr temp
/установка
/ указателя стека
/ на последнюю
/ ячейку ОЗУ
/порт PC
/ на вывод
/аналоговые входы РВ2,РВЗ
7.2. Аналоговый компаратор
247
out DDRB, temp out PORTB, temp clr count Idi temp,0x10 out ACSR,temp sei sbi ACSR,ACIE loop: rjmp loop ana_comp:	; отключены подтягивающие ; резисторы ;сброс ACI и ACSI1/ACSI0 /разрешение прерывания
inc count
mov reg_led,count
com reg_led
out PORTC,reg_led
reti
Задание 7. Изменить условие прерывания. Вместо прерывания при любом изменении сигнала АСО запрограммировать прерывания при изменении сигнала АСО 0/1. Проверить работу программы.
Задание 8. Модифицировать программу, запретив прерывания и организовав программную проверку АСО в регистре ACSR, увеличивая счетчик изменений при переходе АСО 1/0. Проверить работу программы.
8.	ЭНЕРГОНЕЗАВИСИМАЯ ПАМЯТЬ ДАННЫХ EEPROM
Энергонезависимая память EEPROM предназначена для сохранения данных при отключении питания. Данные могут быть запрограммированы перед началом работы микроконтроллера и изменены при выполнении программы.
Память EEPROM имеет обособленное адресное пространство размером 512 байт. Доступ к ячейкам EEPROM по адресам от 0x000 до Ox IFF осуществляется через регистры адреса EEARH:EEARL и регистр данных EEDR, управление через регистр EECR. Заметим, что при записи и чтении используется один и тот же регистр данных. Перед обращением к ячейке EEPROM необходимо в регистре EECR указать режим обращения (запись или чтение). При записи используются два бита управления EEMWE и EEWE (разрешение и сигнал записи), при чтении - бит разрешения EERE.
Для записи необходимо выполнить следующую последовательность действий:
1)	записать адрес в регистр адреса;
2)	записать байт данных в регистр данных;
3)	записать в регистр управления EECR бит EEMWEM, при этом бит EEWE должен быть равен 0. Бит EEMWE сохраняет единичное значение в течение 4-х тактов после установки, после чего аппаратно сбрасывается в 0;
4)	инициировать цикл записи, установив бит EEWE в 1. Время записи зависит от напряжения питания и составляет 2,5 - 4 мс. После завершения записи бит EEWE аппаратно сбрасывается в 0.
Для чтения данных из ячейки EEPROM необходимо:
1) записать адрес в регистр адреса;
2) записать в регистр управления бит EERE=1.
Цикл чтения завершается поступлением байта данных в регистр EEDR. Бит EERE аппаратно сбрасывается в 0.
Ниже приведены примеры программирования операций записи и чтения данных из ячеек EEPROM.
8. Энергонезависимая память данных EEPROM	249
Пример 1. Запись и чтение данных в отдельную ячейку EEPROM
EEWrite:
sbic	EECR,EEWE	/ожидание завершения предыдущей
rjmp	> EEWrite	/ записи
Idi out Idi out	temp,0x01 EEARH,temp temp,OxFE EEARL,temp	/запись в указанную ячейку
Idi out	temp,rO EEDR,temp	/байт данных из регистра г0
sbi	EECR,EEMWE	/разрешение записи
sbi EERead:	EECR,EEWE	/начать запись
sbic rjmp	EECR,EEWE EERead	/ожидание завершения предыдущей / записи
Idi out Idi out sbi	temp,0x01 EEARH,temp temp,OxFE EEARL,temp EECR,EERE	/чтение из ячейки OxlFE
in rl,EEDR		/сохранение данных в регистре rl
Пример 2. Для записи/чтения массива перед началом цикла обращения необходимо получить старый адрес, хранимый в регистрах EEARH:EEARL, увеличить его на единицу, затем вернуть в те же регистры адреса новое значение и выполнить цикл обращения (из файла avrlOO.asm папки Appnotes AVR Studio 4):
.def EEtmp = r24 .def EEtmph = r25 .def EEdwr_s = rl8 .def EEdrd_s = rO EEWrite_seq:
sbic EECR,EEWE rjmp EEWrite_seq in EEtmp,EEARL in EEtmph,EEARH adiw EEtmp,0x01 outEEARL,EEtmp ontEEARH,EEtmph
/временный адрес младший байт /временный адрес старший байт /данные для записи
/читаемые данные
250
8. Энергонезависимая память данных EEPROM
out EEDR,EEdwr_s sbi EECR,EEMWE sbi EECR,EEWE
EERead_seq:
sbic EECR,EEWE rjmp EERead_seq in EEtmp,EEARL in EEtmph,EEARH adiw EEtmp,0x01 out EEARL,EEtmp out EEARH,EEtmph sbi EECR,EERE in EEdrd_s,EEDR
;данные для записи
;чтение данных
Для контроля памяти EEPROM при отладке программы нужно открыть окно Memory, выполнив команды меню View'Memory, и выбрать из выпадающего списка строку Еергот. При необходимости данные в EEPROM при отладке программы можно загрузить ручным способом, выбрав нужную ячейку и двойным щелчком по ее значению открыв окно для записи нового значения.
9. ПРОГРАММИРОВАНИЕ МИКРОКОНТРОЛЛЕРОВ
9.1.	СПОСОБЫ ПРОГРАММИРОВАНИЯ
И КОНФИГУРАЦИОННЫЕ БИТЫ
В процессе программирования микроконтроллеров осуществляют:
-	запись команд и констант в flash-память;
-	запись данных в память EEPROM;
-	запись конфигурационных битов (Fuse Bits);
-	запись битов защиты (Lock Bits).
При выполнении этих работ можно дополнительно выполнить операции:
-	стирание памяти микроконтроллера (Chip erase);
-	чтение ячеек flash-памяти программ и памяти данных EEPROM для контроля правильности записи (верификацию);
-	чтение конфигурационных ячеек для определения состояния микроконтроллера;
-	чтение битов защиты;
-	чтение ячеек идентификатора для определения типа микроконтроллера и ячейки калибровочного байта для последующей записи в регистр OSCCAL при настройке внутреннего RC-генератора.
В микроконтроллерах после их изготовления содержимое ячеек flash-памяти равно $FFFF, ячеек памяти EEPROM - $FF, биты защиты имеют единичное значение, конфигурационные биты могут иметь по умолчанию различные значения. При выполнении операции стирания памяти, выполняемой перед перепрограммированием, в ячейках flash-памяти и памяти EEPROM восстанавливаются значения $FFFF и $FF, биты защиты принимают единичное значение, конфигурационные биты и байты идентификации остаются без изменений.
Для программирования микроконтроллеров AVR в зависимости от применяемого класса и типа модели могут быть использованы различные способы:
252
9. Программирование микроконтроллеров
1)	последовательное программирование с использованием дополнительного источника питания +12 В;
2)	параллельное программирование с использованием дополнительного источника питания +12 В;
3)	последовательное программирование при низком уровне напряжения (по интерфейсу SPI);
4)	самопрограммирование в микроконтроллерах семейства Mega;
5)	программирование по интерфейсу JTAG.
При этом второй, третий и четвертый способы поддерживаются всеми микроконтроллерам семейства Mega, второй и третий - большинством микроконтроллеров семейства Classic, по интерфейсу JTAG - микроконтроллерами ATmegal6x/152x/323x/64x/128x семейства Mega.
Программирование по интерфейсу SPI осуществляется путем посылки 4-байтовых команд на вывод MOSI микроконтроллера, в которых один или два байта определяют тип операции, остальные -адрес, записываемый байт, установочные биты и биты защиты, холостой байт. При выполнении операции чтения считываемый байт снимается через вывод MISO. Программирование памяти программ микроконтроллеров семейства Classic осуществляется с помощью команд «Запись flash-памяти». Программирование памяти программ микроконтроллеров семейства Mega осуществляется постранично. Сначала содержимое страницы побайтно заносится в буфер по командам «Загрузка страницы flash-памяти». При этом в каждой команде указываются младшие разряды адреса записываемой ячейки (положение ячейки на странице) и записываемое значение. Каждая ячейка памяти загружается в следующей последовательности: сначала младший байт, затем старший. Фактическое программирование страницы flash-памяти выполняется после загрузки буфера по команде «Запись страницы flash-памяти». В команде указываются старшие разряды адреса записываемой ячейки (номер страницы). Новую запись можно выполнять только после завершения записи страницы, выдержав паузу определенной длительности (например, для микроконтроллеров ATmega8x, ATmega8515x длительность паузы составляет не менее 4,5 мс).
Программирование памяти данных EEPROM осуществляется с помощью команд «Запись EEPROM памяти». В каждой команде указывается адрес записываемой ячейки и записываемое значение.
Полное описание форматов команд, используемых для программирования микроконтроллеров, можно найти в руководстве на применяемый микроконтроллер.
9.1. Способы программирования и конфигурационные биты 253
На плате STK500 программирование микроконтроллеров выполняется по 6-проводному интерфейсу SPI. Процесс программирования выполняется из окна STK500 путем указания файла с записываемой программой для flash-памяти микроконтроллера и файла данных для памяти EEPROM. Инициализация программирующей программы, которую выполняет управляющий микроконтроллер AT90S8535, установленный на плате STK500, производится при нажатии кнопки в окне STK500 на вкладке Program. Здесь же расположены командные кнопки стирания памяти кристалла, чтения (верификации) программ и данных EEPROM.
Конфигурационные биты
Конфигурационные (установочные) биты определяют параметры конфигурации микроконтроллера. Они расположены в ячейках отдельного адресного пространства и доступны только при программировании. Количество битов конфигурации зависит от типа микроконтроллера. Все они сгруппированы в байты (от одного до трех в зависимости от конкретной модели микроконтроллера). Набор конфигурационных битов и их роль рассмотрим на примере микроконтроллеров двух семейств: AT90S8515 из семейства Classic и микроконтроллеров ATmega8x, ATmega8515x из семейства Mega.
Микроконтроллер AT90S8515 содержит всего лишь два установочных бита: SPIEN и FSTRT. Бит SPIEN разрешает/запрещает программирование по интерфейсу SPI (0 - разрешено, 1 - запрещено, по умолчанию SPIEN=0). Бит FSTRT определяет длительность задержки сигнала сброса (короткая при FSTRT=0, увеличенная при FSTRT=1, по умолчанию FSTRT=1).
В микроконтроллерах семейства Mega количество конфигурационных битов составляет 16 и более, занимая два (три) байта. В частности, микроконтроллеры ATmega8x, ATmega8515x имеют в своем составе два конфигурационных байта. Форматы старшего и младшего конфигурационных байтов этих микроконтроллеров представлены в табл.9.1.
Таблица 9.1. Форматы конфигурационных байтов
Разряд	7	6	5	4	3	2	1	0
Имя	S8515C/*	WDTON	SPIEN	СКОРТ	EESAVE	BOOTSZ1	BOOTSZO	BOORST
а) старший конфигурационный байт
254
9. Программирование микроконтроллеров
Разряд	7	6	5	4	3	2	1	0
Имя	BODLEVEL	BODEN	SUT1	SUT0	CKSEL3	CKSEL2	CKSEL1	CKSEL0
б) младший конфигурационный байт
Ниже приведено назначение каждого из указанных битов:
S8515C - для микроконтроллеров ATmega8515x включа-ет/выключает режим совместимости с микроконтроллерами AT90S4414/8515 семейства Classic (0 - включен, 1 - выключен, по умолчанию S8515С=1).
WDTON - определяет режим работы сторожевого таймера (0 -постоянно включен, 1 - может быть программно выключен, по умолчанию WDTON=1);
SPIEN - разрешает/запрещает программирование по интерфейсу SPI (0 - разрешено, 1 - запрещено, по умолчанию SPIEN=0).
СКОРТ - определяет функционирование тактового генератора совместно с битами CKSEL3...CKSEL0 (по умолчанию СКОРТ=1);
EESAVE - устанавливает влияние команды «Стирание кристалла» на память EEPROM (0 - запрещает стирание, 1 - разрешает стирание, по умолчанию EESAVE=1);
BOOTSZ1, BOOTSZO - определяют размер секции загрузчика, занимающей верхнюю область адресного пространства: (00 - 1024 слова, 01 - 512 слов, 10 - 256 слов, 11 - 128 слов, по умолчанию BOOTSZ1.BOOTSZO=00). При размере секции 1024 слова начальный адрес секции загрузчика равен $С00, при размере секции 512 - $Е00,256 - $F00, 128 - $F80;
BOOTRST - определяет положение вектора сброса (при BOOTRST=0 вектор сброса располагается в начале секции загрузчика, при BOOTRST=1 - вектор сброса располагается в начале памяти программ по адресу $0000 , по умолчанию BOOTRST=1);
* (RSTDISBL) - в микроконтроллерах ATmega8x определяет функцию вывода микроконтроллера, совмещенного с выводом аппаратного сброса (0 - вход/выход порта, 1 - вывод сброса, по умолчанию RSTDISBL=1);
BODLEVEL - определяет порог срабатывания схемы BOD (Brown-Out Detection), которая отслеживает величину напряжения источника питания (0 - порог срабатывания равен 4,0 В; 1 - порог срабатывания равен 2,7 В; по умолчанию BODLEVEL=1);
9.1. Способы программирования и конфигурационные биты 255
BODEN - разрешает/запрещает функционирование схемы BOD (О - разрешает, 1 - запрещает, по умолчанию BODEN=1);
SUT1, SUT0 - определяют длительность задержки сигнала сброса (по умолчанию для платы STK500 принимается задержка 64 мс, при этом SUTl.SUT0=10);
CKSEL3...CKSEL0 - определяют режим работы тактового генератора, а также длительность задержки сигнала сброса (по умолчанию для платы STK500 с внешним генератором CKSEL=0000).
Для изменения конфигурационных битов при работе с STK500 можно использовать вкладку Fuses окна пользовательского интерфейса STK500. В остальных случаях следует использовать специальные команды программирования, описание которых приводится в технической документации на микроконтроллер с учетом используемого метода программирования. При необходимости на вкладке Fuses окна STK500 можно осуществить считывание конфигурационных битов.
Защита программы и данных
Для защиты содержимого flash-памяти и памяти EEPROM в микроконтроллерах AVR имеются биты защиты (Lock bits) LB1 и LB2. При значениях LB1=LB2=1 защита программного кода и данных отключена, допускается запись и чтение обоих видов памяти. При LB1=O, LB2=1 последующая запись в ячейки flash-памяти и EEPROM запрещена. Также запрещается изменение конфигурационных битов. При программировании LB1=LB2=O помимо записи запрещается также чтение памяти и конфигурационных битов.
Для изменения битов защиты при работе с STK500 можно использовать вкладку Lock окна пользовательского интерфейса STK500. Кроме записи предусмотрена возможность считывания запрограммированных битов защиты.
Микроконтроллеры семейства Mega имеют дополнительно четыре бита защиты, что обусловлено наличием двух секций в памяти программ - секции прикладной программы и секции загрузчика. Биты BLB02, BLB01 определяют режимы доступа из секции загрузчика в секцию прикладной программы, биты BLB12, BLB11 -наоборот, из секции прикладной программы в секцию загрузчика. Режимы защиты секции прикладной программы:
BLB02=BLB01=l - ограничения на доступ к секции прикладной программы отсутствуют;
256
9. Программирование микроконтроллеров
BLB02=l, BLB01=0 - блокируется запись по адресам в пределах секции прикладной программы;
BLB02=BLB01=0 - запрещены запись и чтение в секции прикладной программы командами из секции загрузчика. Блокируются также вызовы прерываний из секции прикладной программы, если таблица векторов прерываний размещена в секции загрузчика;
BLB02=0, BLB01=l - запрещено чтение из секции прикладной программы командами из секции загрузчика. Так же, как и в предыдущем случае, блокируются вызовы прерываний.
Аналогичным образом биты BLB12, BLB11 определяют режим защиты секции загрузчика по отношению к командам записи, чтения и вызова прерывания из секции прикладной программы.
9.2.	САМОПРОГРАММИРОВАНИЕ МИКРОКОНТРОЛЛЕРОВ
В отличие от ранее выпущенных микроконтроллеры семейства Mega способны к самопрограммированию, т. е. изменению программного кода самим микроконтроллером при возникновении каких-либо внутренних или внешних событий. Благодаря этому можно построить гибкий алгоритм работы путем замены первоначального кода программы альтернативным. Замещающий программный код можно получить по одному из последовательных интерфейсов микроконтроллера и временно хранить в ОЗУ данных, откуда затем с помощью специальной программы загрузчика перенести во flash-память.
Для поддержки самопрограммирования вся область программ микроконтроллера разбита на две секции: секцию прикладной программы и секцию загрузчика в верхней области памяти программ, в которой располагается программа-загрузчик. Размеры секций зависят от используемой модели микроконтроллера и значений конфигурационных ячеек BOOTSZ. На рис. 9.1 приведена общая схема расположения секций прикладной программы и загрузчика у микроконтроллеров ATmega8, ATmega8515, а в табл. 9.2 приведены размеры загрузчика и областей адресного пространства каждой секции в зависимости от значений конфигурационных ячеек BOOTSZ 1 :BOOTSZO.
Программная память микроконтроллеров семейства Mega организована по страничному принципу, поэтому в таблице указано также число страниц памяти загрузчика. Каждая страница содержит 32 слова (64 байта). Уровень доступа к каждой из секций устанавливается с помощью ячеек защиты: BLB02:BLB01 для секции прикладной программы и BLB12:BLB11 для секции загрузчика, согласно правилам, описанным в 9.1.
9.2. Самопрограммирование микроконтроллеров
257
Рис. 9.1. Расположение секций загрузчика и прикладной программы в памяти программ при BOOTSZ=10
Таблица 9.2. Конфигурация памяти программ
BOOTSZ1	BOOTSZO	Размер загрузчика (слов)	Страниц	Секция прикладной программы	Секция загрузчика
1	1	128	4	$000...$F7F	$F80...$FFF
1	0	256	8	$OOO...$EFF	$F00...$FFF
0	1	512	16	$000...$DFF	$E00...$FFF
0	0	1024	32	$000...$BFF	$C00...$FFF
Помимо описанного разделения flash-памяти имеется дополнительно деление памяти на две области фиксированного размера RWW (Read-While-Write) и NRWW (No Read-While-Write), называемых «чтение при записи» и «нет чтения при записи». Области отличает их поведение при стирании или записи страниц программной памяти:
•	при изменении памяти в области RWW можно осуществлять чтение только из области NRWW;
•	при изменении памяти в области NRWW процессор приостанавливает работу до окончания начатых операций.
Таким образом, во время изменения памяти в области RWW чтение из этой области запрещено. Прерывания должны быть за
258
9. Программирование микроконтроллеров
прещены, либо таблица векторов прерываний должна быть перенесена в область NRWW. Для определения доступности по чтению области RWW, следует использовать флаг RWWSB из регистра SPMCR. При RWWSB=1 область RWW для доступа запрещена, при RWWSB=0 - разрешена. В то же время код, расположенный в области NRWW, остается доступен.
В табл. 9.3 приведены данные по размерам секций RWW и NRWW и занимаемым ими областям адресного пространства в микроконтроллерах ATmega8 и ATmega8515.
Таблица 9.3. Области RWW и NRWW
Секция	Страниц	Адреса
RWW	96	$000...$BFF
NRWW	32	$C00...$FFF
Стирание и запись страниц, а также изменение ячеек защиты осуществляется с помощью команды SPM, параметры которой заранее устанавливаются в регистре управления SPMCR. Для указания номера страницы и слова внутри страницы используется 16-разрядный индексный регистр Z (регистры R31, R30), для записываемых данных используется регистровая пара Rl :R0.
Рассмотрим состав и назначение битов регистра управления SPMCR (табл. 9.4).
Таблица 9.4. Формат регистра управления SPMCR
Бит 7	Бит 6	Бит 5	Бит 4	Бит 3	Бит 2	Бит 1	Бит 0
SPMIE	RWWSB	-	RWWSRE	BLBSET	PGWRT	PGERS	SPMEN
SPMIE - флаг разрешения прерывания SPM. Если SPMIE=1 и разряд I из регистра SREG равен 1, то разрешается прерывание готовности SPM. Запрос прерывания генерируется все время, пока разряд SPMEN (бит 0 регистра SPMCR) сброшен в 0.
RWWSB - флаг запрещения/разрешения доступа к области RWW. Если RWWSB=1, доступ запрещен; если RWWSB=0, доступ разрешен. Флаг устанавливается аппаратно при выполнении операций записи или стирания страницы памяти. Сброс флага осуществляется либо программно путем записи 1 в разряд RRWSRE (бит 4 регистра SPMCR) по окончании операции, либо аппаратно после загрузки страницы.
9.2. Самопрограммирование микроконтроллеров
259
RWWSRE - флаг разрешения чтения области RWW. Предварительные установки этого флага и флага SPMEN разрешают доступ к области RWW при запуске команды SPM, выполняемой в течение четырех машинных циклов после установки разрядов регистра SPMCR. После завершения операции программирования и сброса флага SPMEN доступ к области RWW разрешен.
BLBSET - изменение ячеек защиты программ. При установке этого флага и флага SPMEN команда SPM выполнит защиту ячеек загрузчика в соответствии с содержимым регистра защиты. Сброс флага BLBSET происходит аппаратно после установки ячеек защиты. Если после установки указанного разряда в течение трех машинных циклов выполнить команду LPM, будет осуществлено чтение либо конфигурационных ячеек, либо ячеек защиты в зависимости от значения нулевого разряда регистра Z.
PGWRT - запись страницы. При одновременной установке этого разряда и разряда SPMEN по команде SPM выполняется запись страницы памяти программ из временного буфера. Предварительно номер страницы должен быть загружен в старший байт регистра Z (R31). Сброс разряда PGWRT происходит аппаратно после завершения операции записи.
PGERS - стирание страницы. При одновременной установке этого разряда и разряда SPMEN по команде SPM выполняется стирание страницы. Предварительно номер страницы должен быть загружен в старший байт регистра Z (R31). Сброс разряда PGERS происходит аппаратно после завершения стирания страницы.
SPMEN - разрешение выполнения команды. Установка этого флага разрешает запуск команды SPM в течение четырех машинных циклов. Если установка флага выполняется одновременно с установкой одного их флагов BLBSET, PGWRT или PGERS, выполняется операция, определяемая этим флагом. Если устанавливается только флаг SPMEN, то при выполнении команды SPM во временный буфер по адресу в регистре Z записывается содержимое регистров R1:RO. Сброс флага SPMEN происходит аппаратно после завершения операции.
Запись в младшие пять разрядов регистра SPMCR значений, отличных от «10001», «01001», «00101», «00011» или «00001» не дает эффекта.
Следует заметить, что во время записи данных в память EEPROM изменение регистра SPMCR невозможно. Поэтому перед тем как обновить регистр SPMCR, необходимо дождаться сброса флага EEWE в регистре EECR.
260
9. Программирование микроконтроллеров
Как уже говорилось, память программ имеет страничную организацию. В связи с этим программный счетчик РС можно условно разбить на две части. Старшая 7-разрядная часть определяет номер страницы. Младшие пять разрядов адресуют ячейку на странице. При использовании команды SPM для указания номера страницы и ячейки на странице используется регистр Z, старший байт которого представлен регистром R31, младший - регистром R30. При этом номер страницы указывается в разрядах 12-6 регистра Z, адрес ячейки - в разрядах 5-1. Способ адресации памяти программ при использовании команды SPM иллюстрирует рис. 9.2.
15	12	6 5	1 0
Рис. 9.2. Адресация памяти программ при использовании команды SPM
Программирование памяти программ. Обновление памяти программ выполняется постранично. Вначале заполняется буфер страниц новым содержимым. Затем выполняется стирание страницы и после этого запись содержимого буфера в память программ.
9.2. Самопрограммирование микроконтроллеров 261
Для записи слова команды в буфер следует занести адрес слова в регистр Z, слово команды - в регистры Rl :R0, управляющий код «00000001» в регистр SPMCR и выполнить затем команду SPM. Очистка буфера осуществляется автоматически по окончании записи страницы в память, либо вручную путем записи 1 в разряд RWWSRE регистра SPMCR. Заметим, что повторная запись в буфер по одному и тому же адресу невозможна без его очистки.
Для стирания страницы памяти необходимо занести адрес страницы в регистр Z, управляющий код «хОООООИ» в регистр SPMCR и выполнить команду SPM. Содержимое регистров Rl:R0 при стирании страницы игнорируется.
Для записи содержимого буфера в память программ необходимо занести адрес страницы в регистр Z, код «х0000101» в регистр SPMCR и выполнить команду SPM. Содержимое регистров Rl :R0 при этом также игнорируется.
Для определения конца операции можно опрашивать состояние флага SPMEN в регистре SPMCR, пока он не станет равным 0, либо воспользоваться прерыванием "Готовность SPM". В последнем случае таблица векторов прерываний должна находиться в секции загрузчика и прерывание должно быть разрешено флагом SPMIE-1.
Программирование ячеек защиты загрузчика. Для изменения ячеек защиты загрузчика BLB12:BLB11 с помощью команды SPM необходимо загрузить в регистр R0 значение в соответствии с форматом регистра, приведенным в табл. 9.5. Напомним, значения битов, определяющие виды защиты, были описаны ранее в 9.1. Затем нужно занести код «хООО 1001» в регистр SPMCR и в течение четырех тактов запустить команду SPM. Содержимое регистра Z при этом игнорируется, однако в документации микроконтроллера рекомендуется записать в него значение $0001. Во время программирования ячеек защиты возможно чтение из любой области flash-памяти.
Таблица 9.5. Формат регистра защиты
Бит 7	Бит 6	Бит 5	Бит 4	Бит 3	Бит 2	Бит 1	Бит 0
1	1	BLB12	BLB11	BLB02	BLB01	1	1
Программой загрузчика можно осуществить также считывание конфигурационных ячеек и ячеек защиты. Для чтения байта защиты необходимо загрузить в регистр Z значение $0001, записать в регистр SPMCR значение «хОООЮО!» и выполнить команду LPM.
262
9. Программирование микроконтроллеров
Содержимое байта защиты будет считано в указанный регистр общего назначения. Размещение битов защиты в регистре для микроконтроллеров семейства Mega показано в табл. 9.6.
Таблица 9.6. Формат байта защиты
Бит 7	Бит 6	Бит 5	Бит 4	Бит 3	Бит 2	Бит 1	Бит 0
-	—	BLB12	BLB11	BLB02	BLB01	LB2	LB1
Для чтения конфигурационных байтов микроконтроллеров ATmega8, ATmega8515 в регистр Z следует загрузить адрес байта ($0000 - для младшего, $0003 - для старшего), записать в регистр SPMCR значение «х0001001» и выполнить команду LPM. Содержимое выбранного байта конфигурации будет считано в указанный регистр общего назначения. Размещение конфигурационных битов в регистре соответствует форматам, приведенным в табл. 9.1.
Рассмотрим на примере работу с программой загрузчика микроконтроллера ATmega8515. Программой загрузчика предусмотрено обновление страницы памяти программ из области прикладной программы программным кодом, временно хранимым в ОЗУ данных, начиная с адреса 0x0060. В качестве обновляемой страницы памяти программ выбрана страница с номером 1 (код этой страницы в регистре Z равен 0x0040). Основная часть прикладной программы находится на странице 0. После выполнения ряда операций прикладная программа осуществляет вызов программы загрузчика для обновления первой страницы. Выполнив обновление памяти программ, загрузчик возвращает управление прикладной программе, которая заканчивает свою работу бесконечным циклом ожидания. Предполагается, что прерывания запрещены.
Ниже приведена последовательность операций общего алгоритма работы загрузчика:
•	стирание страницы памяти программ;
•	разрешение секции RWW;
•	цикл пересылки данных из RAM в буфер страницы flash;
•	выполнение записи страницы;
•	разрешение секции RWW;
•	цикл чтения и контроля записанных данных;
•	проверка флага доступа в секцию RWW;
•	разрешение доступа в секцию RWW.
Следует обратить внимание, что для запуска команды SPM используется стандартная процедура, вызываемая всякий раз коман
9.2. Самопрограммирование микроконтроллеров
263
дой вызова. Процедурой предусмотрено выполнение следующих действий:
•	проверка выполнения предшествующей команды SPM;
•	запрет прерывания и сохранение содержимого регистра статуса SREG;
•	проверка записи в память EEPROM;
•	собственно выполнение команды SPM;
•	восстановление регистра SREG (для повторного разрешения прерываний).
Ниже приведен текст программы для микроконтроллера ATmega8515.
Программа 9.3
********************************************************** Л
/Пример программы с самопрограммированием.
/В прикладной программе определены указатель адреса Y для /считывания данных из памяти RAM, представляющих код /программы, полученный, например, по последовательному /интерфейсу, а также указатель Z для перепрограммирования /первой страницы flash памяти.
/После выполнения подпрограммы загрузчика, размещенного по /адресу SMALLBOOTSTART(0хЕ80) управление возвращается /в основную программу.
^-k-k-k-k'k'k'k-k'k-k'k-k'k^'k'k-k'k'k'k-^'k-k-k-k'k'k-k-k-k'k'k-k^-k-k-k'k-k'k-k-k'k-k-k-k-k'k-k'k'k-k-kic-k-k'k
.include "m8515def.inc"
.equ PAGESIZEB = PAGESIZE*2	/размер страницы в байтах
.def temp = rl8 .def tempi = rl6 .def temp2 = rl7
.def spmcrval = r20	/значение для регистра
SPMCR
.def looplo = r24	/счетчик байтов
.def loophi = r25
.org $000
Idi temp,low(RAMEND)
out SPL,temp
Idi temp,high(RAMEND)
out SPH,temp
Idi r28,0x60	;Yl=0x60	- начальный адрес
ОЗУ Idi r30,0x40	;Zl=0x40	1-я страница
flash call Write_page floop: rjmp floop		
.org SMALLBOOTSTART
264
9. Программирование микроконтроллеров
Write_page:
; стирание страницы
Idi spmcrval, (1«PGERS) | (1«SPMEN) rcall Do_spm
; разрешение секции RWW
Idi spmcrval, (1«RWWSRE) | (1«SPMEN) rcall Do_spm
; пересылка данных из RAM в буфер страницы flash Idi looplo, low(PAGESIZEB) /инициализация Idi loophi, high(PAGESIZEB); счетчика байтов Wrloop: Id rO, Y+
Id rl, Y+
Idi spmcrval, (1«SPMEN)
rcall Do_spm
adiw ZH:ZL, 2
sbiw loophi:looplo, 2 brne Wrloop
; выполнение записи страницы
subi ZL, low(PAGESIZEB) /восстановление указателя Z sbci ZH, high(PAGESIZEB)
Idi spmcrval, (1«PGWRT) | (1«SPMEN) rcall Do_spm
; разрешение секции RWW
Idi spmcrval, (1«RWWSRE) | (1«SPMEN) rcall Do_spm
; контроль записанных данных
Idi looplo, low(PAGESIZEB) ;инициализация Idi loophi, high(PAGESIZEB); счетчика байтов subi YL, low(PAGESIZEB) /восстановление указателя Y sbci YH, high(PAGESIZEB)
Rdloop: 1pm rO, Z+
Id rl, Y+
cpse rO, rl
/проверка записи
Error: rjmp Error
sbiw loophi:looplo, 1
brne Rdloop
; возврат в секцию прикладной программы
Return: in tempi, SPMCR
sbrs tempi, RWWSB ; при RWWSB=1 доступ в секцию
; RWW запрещен ret
; разрешение доступа в секцию RWW
Idi spmcrval, (1«RWWSRE) | (1«SPMEN) rcall Do_spm rjmp Return
; подпрограмма выполнения команды spm
Do_spm:
9.2. Самопрограммирование микроконтроллеров
265
; подпрограмма выполнения команды spm Do_spm: ; проверка выполнения предшествующей команды spm Wait_spm: in tempi, SPMCR sbrc tempi, SPMEN rjmp Wait_spm
; запретить прерывания, сохранить регистр статуса SREG
in temp2, SREG cli
; проверка записи в EEPROM
Wait_ee: sbic EECR, EEWE
rjmp Wait_ee ; выполнение spm
out SPMCR, spmcrval spm
; восстановление регистра SREG (для повторного разрешения ; прерываний)
out SREG, temp2 ret
10.	ПРОГРАММИРОВАНИЕ И ОТЛАДКА ПРОГРАММ НА ЯЗЫКЕ Си
При написании программ для микроконтроллеров все большую популярность приобретает язык Си. При его использовании сокращается время на разработку, что особенно заметно при написании больших программ, обеспечивается их переносимость на другие платформы. Недостатком языка Си по сравнению с языком Ассемблер является больший объем кода и, как следствие, более низкая скорость работы. Однако благодаря тому, что в архитектуре AVR изначально заложено эффективное декодирование и исполнение инструкций, генерируемых компиляторами, после компиляции Си-программ получается высокопроизводительный код.
Существует ряд компиляторов Си, поддерживающих архитектуру AVR: CodeVisionAVR, ImageCraft С, AVR GCC и др., которые включают в себя широкий набор библиотек для работы с периферийными устройствами и поддерживают форматы объектных файлов, используемых при отладке в AVR Studio 4. Кроме того, многие компиляторы поддерживают возможность программирования микроконтроллеров после компиляции исходного текста программы.
Далее описан процесс разработки и отладки программы на языке Си для учебного проекта. В качестве среды программирования использована программа CodeVision AVR версии 1.23.7а, для отладки - AVR Studio 4.
10.1.	СРЕДА CodeVision AVR
Программа CodeVision AVR фирмы HP InfoTech - это интегрированная среда разработки, содержащая компилятор языка Си, графическую оболочку, автоматический генератор программ и встроенный программатор, ориентированные на работу с семейством микроконтроллеров AVR.
Наряду со стандартными библиотеками языка Си и системой справок по языку компилятор имеет библиотеки для работы с пери-
10.1. Среда CodeVision AVR
267
ферийными устройствами (ЖКИ-индикаторами с встроенными контроллерами, датчиками температуры, часами реального времени, энергонезависимой памятью EEPROM, шиной SPI и др.). Также имеется автоматический генератор программ для инициализации внутренних и периферийных ресурсов микроконтроллера - портов, таймеров, UART, SPI и др. Для отладки систем, использующих последовательную передачу данных, имеется встроенный в компилятор буфер Terminal. Генерируемый при компиляции объектный файл .cof позволяет осуществлять с помощью отладчика AVR Studio 4 отладку программы непосредственно в коде Си.
Рис. 10.1. Окно программы CodeVision AVR
Внешний вид окна программы CodeVision AVR показан на рис. 10.1.
Создание проекта
Разработаем микроконтроллерное устройство, управляющее двумя светодиодами, один из которых показывает готовность к работе, второй переключается по числу нажатий кнопки управле
268	10. Программирование и отладка программ на языке Си
ния. Проект предполагает работу с портами ввода/вывода, таймером, обработку внешнего прерывания, энергосберегающий режим работы МК, использование библиотечной подпрограммы.
Схема устройства приведена на рис. 10.2. В ней предусмотрены две кнопки. Кнопкой SW0 задают число миганий, кнопкой SW2 запускают процесс мигания светодиода. Для подсчета числа нажатий на кнопку SW0 необходим счетчик, в качестве которого используем таймер ТО в режиме подсчета внешних событий. Для
Рис. 10.2. Схема устройства
9VCC
AT90S8515
LED6	
1	1 ГХ-Н 1—	РВ6
LED7Z-S^	(INT0)PD2
	Н>ГП н	РВ7 (ТО)РВО
SW2
SW0
индикации используем два светодиода: LED6 - индикатор готовности схемы и LED7 - мигания. Таким образом, микроконтроллер должен иметь возможность обработки внешнего прерывания от кнопки SW2, таймер с входом внешних событий от кнопки SW0 и две линии порта для управления светодиодами. Выберем микроконтроллер AT90S8515, рабочую частоту 1 МГц. Кнопки считаем идеальными без эффекта дребезга контакта. Подтягивающие резисторы на входах PD2, РВО подключаем при программировании режима работы портов.
Работа над проектом в Code Vision AVR начинается с выбора команды меню File!’New. В диалоговом окне выбираем Project и нажимаем ОК. Дальнейшие действия зависят от выбора No или Yes в появившемся окне. Если не используем автоматический генератор программ, выберем No, затем выполним действия п. 1, в противном случае - действия п. 2.
1.	В окне Create New Project задаем имя проекта. После сохранения появляется окно Configure Project (рис. 10.3), в котором на вкладке Files можно добавить (Add) существующие файлы в проект или удалить их (Remove) из него. При отсутствии файла с текстом программы создаем пустой файл, выполняя команды File/New/Source. После ввода текста программы сохраняем его. Затем переносим файл в папку проекта, выполнив команду Add в окне Configure Project. На вкладке С Compiler указываем тип микроконтроллера (Chip), частоту его работы (Clock), размер доступной памяти (SRAM), а также параметры компиляции: способ опта-
10.1. Среда CodeVision A VR
269
мизации кода - по размеру (Size) или скорости (Speed), соглашения по компиляции и форматы выходных файлов (File Output Format), использование терминала ввода/вывода.
Рис. 10.3. Окно компилятора Си
Для проекта устанавливаем: тип МК - АТ908515, рабочую частоту - 1 МГц, способ оптимизации - по размеру кода, формат выходного файла - COFF, после чего нажимаем ОК.
2.	В окне CodeWizardAVR на соответствующих вкладках задаем имя проекта, параметры внутренних ресурсов микроконтроллера (его тип, рабочую частоту, параметры порта ввода/вывода, внешнее прерывание по низкому уровню, переключение таймера/счетчика по перепаду из 1 в 0 на входе ТО). Выбираем команду меню File/Generate, Save and Exit. Три раза указываем в окнах Save... имя проекта. В итоге открывается файл-заготовка со строками инициализации требуемых ресурсов.
270
10. Программирование и отладка программ на языке Си
Для задания параметров проекта в целом необходимо выбрать команду меню Project/Configure. Дальнейшие действия выполняем, как указано в п. 1.
Работу устройства определяет программа, текст которой представлен ниже.
Программа 10.1
/*
Программа 10.1 с помощью таймера подсчитывает число нажатий на кнопку SW0. Затем после нажатия на кнопку SW2 переключает светодиод LED7 по значению таймера.
В режиме ожидания включен светодиод LED6. */ #include <90s8515.h>
//#include <mega8515.h> для микроконтроллера ATmega8515 #include <delay.h> // файл с процедурами задержки #define LED7 PORTB.7 #define LED6 PORTB.6
// Процедура обработки внешнего прерывания interrupt [EXT_INT0] void ext_intO_isr(void) { char timer;	// локальная переменная
timer = TCNTO; if (timer != 0)
{TCNTO = 0;	// сброс таймера/счетчика
LED6 =1;	// выключаем светодиод LED6
do {
LED7 = 0;
delay_ms(500);	// задержка 500 мс
LED7 = 1;
delay_ms(500) ;
} while (— timer != 0) ;
LED6 =0;	// включаем светодиод LED6
} } void main(void) { // инициализация портов
DDRB=0xC0;	// PB7, PB6 для LED7,LED6
PORTB=Ox81;	// PBO(SWO) - ввод событий
DDRD= (0«PD2 ) ;	// PD2(SW2)
PORTD= (0«PD2) ;
// инициализация таймера 0
TCCR0=0x06;
TCNT0=0x00;
// инициализация прерывания INTO в GIMSK (или GICR) GIMSK= (l«INT0) ;
10.1. Среда CodeVision AVR
271
MCUCR= (1«SE) ;
#asm("sei");
for (;;) {
#asm("sleep");
#asm("nop");
}
// разрешение перехода в режим Idle // глобальное разрешение прерываний
// переход в режим Idle
Компиляция
Для компиляции программы необходимо выбрать команду меню Project /Compile (F9). Результаты компиляции выводятся в окно Information, а в окне Navigator в дереве проекта появляются синие ветви. Щелкая по значкам, можно перемещаться по заголовкам процедур и именам глобальных переменных, что удобно при работе с большим проектом.
Ветвь дерева с ошибками (Errors) выделена красным цветом. Список ошибок также выводится в окне Messages внизу экрана. Чтобы исправить ошибку, нужно щелкнуть по листу дерева. Соответствующая строка программы выделится серым цветом, а рядом с ней появится курсор для ввода.
После компиляции будут созданы файлы с расширениями: .asm (файл Ассемблера), .шар (адреса ОЗУ расположения глобальных переменных), .vec (список векторов прерываний), .inc (файл определений).
В случае успешной компиляции выводится сообщение об отсутствии ошибок. В окне Navigator ветвь сообщений об ошибках пропадает, а список файлов пополняется файлом filename _.с - копией исходного файла на языке Си.
Для окончательной сборки проекта и получения файлов для отладки и программирования МК нужно выбрать в меню команду Project/Маке (Shift + F9). Появится окно Information, в котором сообщается о создании дополнительных файлов с расширениями .гот (программирование Flash-памяти МК - программа в формате «адрес : слово»), .еер (программирование EEPROM), .1st (листинг программы), .err (аналог содержимого окна Information), .obj (объектный файл) и .cof (символьный файл для отладки в среде AVR Studio).
Работа с CodeVision AVR на этом заканчивается, по крайней мере до момента, когда нужно будет исправить ошибки, найденные при отладке.
272
10. Программирование и отладка программ на языке Си
10.2.	ОТЛАДКА В AVR STUDIO
1.	Запускаем AVR Studio 4, проект создавать не нужно.
2.	Открываем объектный файл проекта (Open File) и выбираем фильтр Object Files в окне открытия файлов. AVR Studio 4 поддерживает семь типов объектных файлов. Выбираем файл с расширением .obj либо с расширением .cof. Открывается окно Select device and debug platform, в котором указываем платформу для отладки: AVRSimulator и АТх8515. После этого создается проектный файл и загружается отладчик. Дальнейшие действия зависят от выбранного типа файла.
3.	Выбираем файл для загрузки в AVR Studio 4.
Выбрав файл с расширением .obj, отладку можно осуществлять в кодах Ассемблера. Следует обратить внимание на то, что проект содержит три файла (.asm, .inc и .vec) и отладка начинается с файла .vec, содержащего векторы прерываний. Курсор отладки (желтая стрелка) установлен на команде ijmp_reset. После нажатия кнопки Step Into (Fl 1) курсор переходит на обработчик сброса, расположенный в файле .asm, и дальнейшая отладка продолжается в обычном режиме. Чтобы пропустить команды, добавленные компилятором, и перейти к отладке кода, написанного программистом, нужно установить курсор на первую команду процедуры main () и нажать кнопку Run to cursor. Все команды до курсора будут выполнены. Проект можно просмотреть в окне Disassembler, которое открывают, выбрав в меню View/Disassembler. Отладку можно продолжить в этом окне.
Для отладки программы на языке Си выбираем файл с расширением .cof.
4.	Устанавливаем параметры отладки в меню Debug/ AVRSimulator Options: АТх8515, частота 1 МГц, протоколирование порта РВ с выводом на экран.
5.	Содержимое используемых регистров ввода/вывода МК можно проконтролировать несколькими способами:
а)	непосредственно просматривая их содержимое на вкладке ПО панели Workspace;
б)	анализируя область памяти регистров ввода/вывода (View! Memory [Z/O]),
в)	присвоив их значения переменным, которые в дальнейшем просматривают в окне Watch.
В нашем случае имеем одну переменную timer, которая принимает значение таймера/счетчика TCNT0. Открываем окно Watch, выбрав команду меню View/Watch, и перетаскиваем мышью эту переменную в столбец Name. Пока переменная находится вне
10.2. Отладка в AVR Studio
273
зоны видимости отладчика, в столбце Value будет записано Not in Scope. Подготовка к отладке завершена.
6.	В начале процесса отладки и при нажатии кнопки сброса Reset курсор отладки устанавливается на первой строке процедуры main (). Выполнение программы можно контролировать, открыв окно Disassembler, однако имея программу на языке Си, значительно удобнее отлаживать программу в окне Си-программы.
7.	Нажимая кнопку Step Into (Fl 1), наблюдаем за изменением содержимого регистров ввода/вывода микроконтроллера. Одно из преимуществ отладки на Си - использование только программных инструкций, способствующее ускорению процесса отладки. В цикле for (;;) командой Ассемблера sleep микроконтроллер переводится в режим пониженного энергопотребления.
8.	Занесем в счетчик TCNT0 значение 2. При разомкнутой кнопке SW0 (состояние 1) эмулируем замыкание кнопки SW2 (состояние 0), что приведет к вызову обработчика прерывания. При вызове процедуры delayjns() отладчик не входит в нее, но вызов задерживает его работу и изменяет значение счетчика циклов.
9.	Установив курсор на команде sleep, выполним команду Run to Cursor (выполнить до курсора). После останова симуляции, что обнаруживается по желтому индикатору в строке состояния, в окне Output получим список сообщений (отчет), в котором значение 0x81(10000001) соответствует готовности схемы (светодиод LED7 выключен, LED6 включен), значение ОхС 1(11000001) - погашены оба светодиода, 0x41(01000001) - LED6 погашен, LED7 включен. Список сообщений:
AVR Simulator PORTB - 000003189:81
AVR Simulator PORTB - 000003276:Cl
AVR Simulator PORTB - 000003278:41
AVR Simulator PORTB - 000506301 :C1
AVR Simulator PORTB - 001009328:41
AVR Simulator PORTB - 001512351 :C1
AVR Simulator PORTB - 002015377:81
Длительность включения светодиода LED7 составляет 0,503 с.
10.	Изменим значение задержки в процедуре delay_ms(). Редактировать объектные файлы в AVR Studio 4 нельзя, поэтому снова открываем CodeVision AVR, исправляем соответствующие строки и заново выполняем компиляцию. Если AVR Studio 4 не был закрыт, то появится сообщение, что объектный файл был изменен и его нужно перезагрузить - выполняем перезагрузку.
274
10. Программирование и отладка программ на языке Си
И. Компилируем в CodeVision AVR, установив в окне Configure тип выходного файла Intel HEX. Загрузив полученный файл с расширением .hex в микроконтроллер STK500 и изменив на вкладке Board окна STK500 частоту, проверяем работу программы. Соединяем РВ6: РВ7 - LED6:LED7, SW0 - РВО, SW2 - PD2. В исходном состоянии светодиод LED6 включен, LED7 выключен. Нажав несколько раз на кнопку SW0, затем на кнопку SW2, наблюдаем мигание светодиода LED7 с частотой 1 Гц. В это время светодиод LED6 выключен. После завершения мигания LED6 вновь включается, а устройство переходит в режим ожидания.
Выводы
Работа над проектом с использованием языка Си позволяет сделать ряд наблюдений, касающихся наглядности программ, размеров кода, отладки и их переносимости.
Наглядность программы. Язык высокого уровня позволяет использовать сложные структуры данных, такие, как массивы, строки, списки, записи, обеспечивает максимальное удобство при написании циклов и ветвлений, избавляет программиста от написания рутинных фрагментов программ.
Программирование на Ассемблере требует знаний всех ресурсов микроконтроллера. Программа, написанная на Ассемблере, не всегда наглядна, разобраться в коде достаточно сложно, при использовании микроконтроллеров с RISC-архитектурой возникают проблемы с программированием сложных операций, таких, как умножение и деление, с обработкой структур данных.
Размер кода. При использовании всех возможностей языка Си программа может быть очень компактной, однако, если сравнивать откомпилированные коды, оценки могут измениться. Код, написанный на Ассемблере, минимален по размеру и оптимизирован под конкретную задачу, что позволяет получить высокую скорость работы программы. Компилятор же оперирует фрагментами кода по общим правилам. Так, в примере со светодиодами в начале работы программы 10.1 обнуляются все регистры микроконтроллера и оперативная память SRAM, при входе в процедуру прерывания регистры сохраняются в стеке, а затем восстанавливаются при выходе. Однако в приложении работа с памятью не предусмотрена - используется всего лишь несколько регистров.
10.2. Отладка в AVR Studio
275
Отладка. Если программа пишется на языке высокого уровня, а отлаживать предполагается откомпилированный код, то весь процесс может занять больше времени, чем написание и отладка программы на Ассемблере. Вместе с тем написание и отладка на языке Си программ, ориентированных в большей степени на обработку данных, проще, чем при использовании Ассемблера.
Переносимость. Изменение частоты синхронизации микроконтроллеров, очевидно, влияет на длительность выполнения процедур. Если время выполнения должно остаться неизменным (в нашем случае это время включения светодиода), потребуется вносить изменения в программу на Ассемблере, заново пересчитывая коэффициенты в циклах задержки. В программе на Си необходимо только заменить частоту в конфигурации проекта и компилятор пересчитает все автоматически, что, безусловно, проще.
Учитывая, что откомпилированный код всегда больше исходного, написанного на Ассемблере, и принимая невозможность простой его оптимизации, можно сделать выводы о предпочтении того или иного языка программирования в зависимости от сложности и направленности задачи, наличия средств отладки, доступного размера памяти микроконтроллера, требуемого быстродействия процедур, сроков проектирования и т. д.
В заключение приведем ряд рекомендаций по написанию программ на языке Си для микроконтроллеров. Для уменьшения размера программного кода рекомендуется:
-	компилировать с оптимизацией по размеру;
-	использовать локальные переменные, а не глобальные, так как первые хранятся в регистрах, а вторые - в ОЗУ;
-	использовать по возможности беззнаковые типы данных меньшего размера;
-	если глобальная переменная используется только в одной функции, она должна быть объявлена как Static;
-	использовать конструкцию for (;;) для бесконечных циклов;
-	использовать циклы с декрементом и конструкцию {} while (выражение);
-	выполнять доступ в память непосредственно, не используя указатели;
-	использовать макросы вместо функций для подзадач, компилируемых в две-три команды Ассемблера.
Для уменьшения требований к памяти SRAM следует:
-	константы и литералы располагать в памяти программ, объявляя их с помощью директивы Flash;
276	10. Программирование и отладка программ на языке Си
-	избегать объявления глобальных переменных, если они на самом деле локальные, так как последние размещаются динамически и убираются из памяти, когда выходят из зоны видимости;
-	правильно оценивать размер программного стека (Data Stack Size), который необходимо указывать в настройках проекта (Рго-ject/Configure. закладка CCompilier).
ЛИТЕРАТУРА
1.	AVR STK500. User Guide.
2.	AVR Assembler User Guide.
3.	Datasheet AT90S8515, ATmega8515, ATmega8, РСА9554/ PC A-9554A, AVR315.pdf
4.	Гребнев B.B. Микроконтроллеры семейства AVR фирмы Atmel. -M.: Радиософт, 2002.
5.	Евстифеев A.B. Микроконтроллеры AVR семейств Tiny и Mega фирмы ATMEL. - M.: Издательский дом «Додэка-XXI», 2005.
6.	Злобин B.K., Григорьев В.Л. Программирование арифметических операций в микропроцессорах. - М.: Высш, шк., 1991.
7.	Хартов В.Я. Проектирование и отладка программ для микроконтроллеров AVR фирмы Atmel. - М.: Изд-во МГТУ им. Н.Э. Баумана, 2004.
8.	Архив с файлами программ учебного пособия:
http://e-leaming.bmstu.ru/moodle/mod/resource/view.php?id=35
9.	Сайт фирмы Atmel: http://www.atmel.com
10.	Сайт фирмы Labcenter Electronics: http://www.labcenter.co.uk
278
Приложение
Приложение
Обозначения регистров ввода/вывода АТх8515
Имя регистра	Адрес I/O	Назначение
ACSR, Analog Comparator Control and Status Register	$08	Регистр управления и состояния аналогового компаратора
DDRA, Data Direction Register, Port A	$1A	Регистр направления данных порта А
DDRB, Data Direction Register, Port В	$17	Регистр направления данных порта В
DDRC, Data Direction Register, Port C	$14	Регистр направления данных порта С
DDRD, Data Direction Register, Port D	$11	Регистр направления данных порта D
EEARH, EEPROM Address Register High Byte	$1F	Регистр адреса EEPROM, старший байт
EEARL, EEPROM Register Address Register Low Byte	$1E	Регистр адреса EEPROM, младший байт
EECR, EEPROM Control Register	$1C	Регистр управления EEPROM
EEDR, EEPROM Data Register	$1D	Регистр данных EEPROM
GIFR, General Interrupt Flag Register	$3A	Общий регистр флагов прерываний
GIMSK, General Interrupt Mask Register*	$3B	Общий регистр маски прерываний
ICR1H, Т/Cl Input Capture Register High Byte	$25	Регистр захвата Т/С1, старший байт
ICR1L, Т/Cl Input Capture Register Low Byte	$24	Регистр захвата Т/С1, младший байт
MCUCR, MCU General Control Register	$35	Регистр управления микроконтроллером
OCR1AH, Т/Cl Output Compare Register A High Byte	$2B	Регистр сравнения А Т/Cl, старший байт
OCR1AL, Т/Cl Output Compare Register A Low Byte	$2A	Регистр сравнения А Т/С 1, младший байт
Приложение
279
Продолжение
Имя регистра	Адрес I/O	Назначение
0CR1BH, Т/Cl Output Compare Register В High Byte	$29	Регистр сравнения В Т/С 1, старший байт
OCR1BL, Т/Cl Output Compare Register В Low Byte	$28	Регистр сравнения В Т/С 1, младший байт
PINA, Input Pins, Port A	$19	Выводы порта А
PINB, Input Pins, Port В	$16	Выводы порта В
PINC, Input Pins, Port C	$13	Выводы порта С
PIND, Input Pins, Port D	$10	Выводы порта D
PORTA, Data Register, Port A	$1B	Регистр данных порта А
PORTB, Data Register, Port В	$18	Регистр данных порта В
PORTC, Data Register, Port C	$15	Регистр данных порта С
PORTD, Data Register, Port D	$12	Регистр данных порта D
SPCR, SPI Control Register	$0D	Регистр управления SPI
SPDR, I/O Data Register	$0F	Регистр данных SPI
SPH, Stack Pointer High	$3E	Старший байт указателя стека
SPL, Stack Pointer Low	$3D	Младший байт указателя стека
SPSR, SPI Status Register	$0E	Регистр состояния SPI
SREG, Status Register	$3F	Регистр состояния процессора
TCCRO, T/CO Control Register	$33	Регистр управления таймера/счетчика ТО
TCCR1A, Т/Cl Control Register A	$2F	Регистр управления А таймера Т/С1
TCCR1B, Т/Cl Control Register В	$2E	Регистр управления В таймера Т/С1
TCNTO, Timer/CounterO (8 bit)	$32	Счетный регистр таймера/счетчика 0
TCNT1H, Т/Cl High Byte	$2D	Счетный регистр Т/С1, старший байт
TCNT1L, Т/Cl Low Byte	$2C	Счетный регистр Т/С1, младший байт
280
Приложение
Окончание
Имя регистра	Адрес I/O	Назначение
TIFR, Т/С Interrupt Flag Register	$38	Регистр флагов прерываний от таймеров
TIMSK, T/C Interrupt Mask Register	$39	Регистр маски прерываний от таймеров
UBRR, UART Baud Rate Register	$09	Регистр скорости передачи UART
UCR, UART Control Register	$0A	Регистр управления UART
UDR, UART I/O Data Register	$0C	Регистр данных UART
USR, UART Status Register	$0B	Регистр состояния UART
WDTCR, Watchdog Control Register	$21	Регистр управления сторожевым таймером
Примечание. В модели ATmega8515 имена GIMSK, UBRR переименованы на GICR, UBRRL.		
Кроме перечисленных в таблице ATmega8515 содержит дополнительно девять регистров ввода-вывода:
SPMCR - регистр управления памятью программ (адрес $37);
EMCUCR - дополнительный регистр управления микроконтроллером ($36);
MCUCSR - регистр управления и состояния микроконтроллера ($34);
OCRO - регистр совпадения таймера/счетчика ($31);
SFIOR - регистр специальных функций ($30);
UBRRH - регистр старшего байта скорости передачи USART ($20);
PORTE - регистр данных порта Е ($07);
DDRE - регистр направления данных порта Е ($06);
PINE - выводы порта Е ($05).