Text
                    В.Я. Хартов
Микроконтроллеры AVR
Практикум для начинающих
Рекомендовано УМО вузов
по университетскому политехническому образованию
в качестве учебного пособия
для студентов высших учебных заведений,
обучающихся по направлению 230100
«Информатика и вычислительная техника»
Москва
Издательство МГТУ им. Н.Э. Баумана
2007


УДК 621.396(075.8) ББК 32.81 Х201 Рецензенты: проф., зам. зав. кафедрой «Вычислительная техника» МИ?ЭА Е.Л.Иванов; зам. ген. директора ЗАО «РБК софт» холдинга «Росбизнесконсалтинг» СМ. Коновалов; доц. МГТУ им. Н.Э. Баумана В.М. Недашковский Хартов В.Я. Х201 Микроконтроллеры AVR. Практикум для начинающих. - М.: Изд-во МГТУ им. Н.Э. Баумана, 2007. - 240 с: ил. ISBN 978-5-7038-3051-2 Практикум содержит материалы для изучения микроконтроллеров AVR с архитектурой RISC. Рассмотрены необходимые инструментальные средства - интегрированный пакет для разработки и отладки программ AVR Studio 4, стартовый набор разработчика STK500. Предложен комплект программ для изучения функциональных возможностей микроконтроллеров (27 учебных проектов). Тематика охватывает практически все аспекты архитектуры микроконтроллеров: работу портов, таймеров, арифметическую обработку данных, организацию ввода/вывода по параллельным и последовательным (UART, SPI и I2C) каналам связи, устройств обработки аналоговых сигналов, системы прерывания. Базовые программы могут быть использованы в качестве основы для обучения и самостоятельного программирования на языке Ассемблер AVR в курсовом и дипломном проектировании. Материалы книги автор использует в учебном процессе в МГТУ им. Н.Э. Баумана. Для студентов высших и средних специальных учебных заведений, обучающихся по направлению «Информатика и вычислительная техника». УДК 621.396(075.8) ББК 32.81 ISBN 978-5-7038-3051-2 © Хартов В.Я., 2007 © Оформление. Издательство МГТУ им. Н.Э. Баумана, 2007
ОГЛАВЛЕНИЕ Предисловие 4 1. Инструментальные средства практикума 7 1.1. Микроконтроллеры АТх8515 8 1.2. Интегрированная отладочная среда AVR Studio 4 32 1.3. Стартовый набор STK500 фирмы ATMEL 37 1.4. Интерфейс STK500 в AVR Studio 4 и программирование микроконтроллера 43 2. Программирование портов ввода/вывода 49 2.1. Взаимодействие микроконтроллера с кнопками и светодио- дами 50 2.2. Обработка внешних прерываний 53 3. Арифметическая обработка данных 59 3.1. Представление чисел в микроконтроллерах 59 3.2. Сложение и вычитание чисел в дополнительном коде 60 3.3. Умножение чисел без знака 62 3.4. Деление целых чисел 63 3.5. Сложение и вычитание двоично-десятичных чисел 69 3.6. Программирование арифметических операций 73 3.7. Операции над числами с плавающей точкой 82 4. Таймеры микроконтроллеров АТх8515 107 4.1. Таймер/счетчик ТО микроконтроллера AT90S8515 108 4.2. Таймер/счетчик Т1 микроконтроллеров АТх8515 110 4.3. Программирование таймера ТО 118 4.4. Программирование функций сравнения, захвата и ШИМ таймера Т1 123 4.5. Сторожевой таймер 132 5. Обмен данными по последовательному интерфейсу 137 5.1. Последовательный обмен данными по каналу UART 137 5.2. Работа последовательного канала SPI 152 5.3. Обмен данными по интерфейсу 12C(TWI) 163 6. Организация ввода/вывода данных по параллельному интерфейсу 191 6.1. Взаимодействие с клавиатурой и ЖК-дисплеем 191 6.2. Организация асинхронного параллельного обмена данными с квитированием 203 7. Устройства для обработки аналоговых сигналов 213 7.1. Аналого-цифровой преобразователь 213 7.2. Аналоговый компаратор 215 8. Программирование и отладка программ на языке Си 221 8.1. Среда CodeVision AVR 221 8.2. Отладка в AVR Studio 227 Приложения 231 Список литературы 239
ПРЕДИСЛОВИЕ Появление новых семейств микроконтроллеров с RISC-архитектурой (Reduced Instruction Set Computer), выполненных с Flash- памятью для программ, не могло не привлечь внимания специалистов, занятых разработкой компьютерных систем управления. Высокие технические и конструктивные характеристики, низкая цена и невысокая потребляемая мощность способствовали их признанию; они быстро завоевали популярность, потеснив на мировом рынке широко известное семейство MCS-51 и ему подобные. Сказанное относится прежде всего к микроконтроллерам общего назначения семейств PicMicro, AVR Atmel и др. Но если первые имеют сравнительно небольшой набор операций (до 35), то вторые с системой команд, насчитывающей до 120 и более, практически ни в чем не уступают микроконтроллерам с CISC-архитектурой (Complex Instruction Set Computer). Эти микроконтроллеры имеют более развитую систему адресации данных, что чрезвычайно важно при создании эффективного программного обеспечения. Наряду с новыми технологическими решениями разработчики компьютерных управляющих систем получили в свое распоряжение удобный аппарат в виде интегрированных систем проектирования и отладки программ (Integrated Development Environment, IDE) и стартовых наборов (Starter Kit, STK), которые при совместном использовании являются неоценимым инструментом, ускоряющим процесс разработки и повышающим его эффективность. Вместе с тем обучающий процесс в высших и средних специальных технических заведениях зачастую опирается на старые технологические решения и программное обеспечение, работающее в среде DOS. Предлагаемый практикум является попыткой преодоления разрыва между современным состоянием микроконтроллерной техники и образовательными инструментами в этой области. Излагаемый материал базируется на трех «китах». Во-первых, это архитектура 8-разрядных микроконтроллеров AVR, относящихся к средним по своим функциональным характе-
5 ристикам семействам микроконтроллеров общего применения (например, AT90S8515 семейства Classic или его аналога ATmega8515 семейства Mega). Знание архитектуры этих микроконтроллеров позволит быстро освоить иные модели микроконтроллеров этих семейств, а также микроконтроллеры других фирм-изготовителей. Во-вторых, использование интегрированной среды проектирования AVR Studio 4, свободно распространяемой в сети Internet, дает возможность не только разрабатывать, но и отлаживать создаваемое программное обеспечение с помощью встроенного симулятора. Наконец, подключив к AVR Studio 4 стартовый набор разработчика STK500, можно проверить созданную программу непосредственно в целевом микроконтроллере, а подключив через разъем расширения дополнительные устройства, - и в составе системы. Попутно отметим сравнительно невысокую стоимость STK500, что немаловажно для учебных заведений. В лаборатории микропроцессорных систем кафедры «Компьютерные системы и сети» МГТУ им. Н.Э. Баумана под руководством доктора технических наук, профессора В.В. Сюзева был разработан учебный комплекс лабораторных работ, послуживший основой данного учебного пособия. Комплекс содержит ряд учебных проектов, предназначенных для изучения студентами основ микроконтроллерной техники. Пособие построено следующим образом. Вначале дается краткое описание основных компонентов обучающего комплекса: микроконтроллеров AVR, отладочной среды AVR Studio 4 и стартового набора STK500. Освоение архитектуры микроконтроллеров начинается с изучения приводимых в пособии проектов и программ (всего 27), знакомящих с функциями портовой системы микроконтроллера, возможностями арифметической обработки данных, разнообразными функциями таймеров, организацией ввода/вывода по параллельным и последовательным каналам связи, с устройствами обработки аналоговых сигналов. Помимо текстов на сайте www.bmstu.ru/~iu6/ можно найти файлы программ, готовые для загрузки в AVR Studio 4. Освоение системы команд и архитектуры микроконтроллеров AVR идет постепенно - сначала модернизация предложенных программ (изменение или добавление каких-либо функций исследуемого функционального узла), в дальнейшем самостоятельное программирование. Такой подход показал, что в условиях временных ограничений на лабораторные
6 Предисловие занятия удается совместить самостоятельную подготовку с эффективной работой в лаборатории без больших потерь времени, которые неизбежно возникают при отладке программного обеспечения. Вместе с тем самостоятельное изучение предложенных программ способствует усвоению приемов программирования микроконтроллеров на языке AVR Ассемблер. Автор далек от мысли, что предложенные в пособии и протестированные во время учебных занятий программы являются оптимальными. В ряде случаев программы на Ассемблере, например для исследования таймеров, выглядят громоздкими, хотя, линейные по структуре, они достаточно просты. Данное обстоятельство привело к необходимости включения в пособие раздела, посвященного технологии работы над проектом, использующим программы, написанные на языке Си, и компилятор Code Vision С Compiler фирмы-производителя HP Info Tech. В процессе работы автор был вынужден обратиться помимо основных интегрированных систем проектирования к другим, в частности к программе ISIS из пакета Proteus 6 Professional фирмы Labcenter Electronic, что позволило провести совместную симуляцию программ в проектах, содержащих более одного микроконтроллера, вместе с виртуальными периферийными устройствами, для которых есть функциональные логические модели. Эти возможности обсуждаются в разд. 5.2, посвященном исследованию интерфейса SPI. Все разделы пособия с проектами содержат альтернативные задания разной сложности для самостоятельного программирования, которые могут быть реализованы на основе полученных знаний, а также контрольные вопросы. Автор надеется, что их выполнение будет способствовать развитию творческих способностей студентов при проектировании сложных систем управления. Внимательный читатель, возможно, найдет в пособии и приводимых программах недостатки или более рациональные пути решения. Все вопросы, замечания и предложения можно посылать автору по e-mail: khartov@bmstu.ru.
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), выпущенные для поддержки разработок на микроконтроллерах AVR. Вместе они образуют единую платформу, на которой можно успешно проводить разработку и отладку различных приложений. Инструментальными средствами разработки и отладки программ для микроконтроллеров AVR, используемыми в практикуме, являются интегрированный пакет AVR Studio 4 и стартовый набор STK500 фирмы Atmel. Целевыми микроконтроллерами, которые используются во всех проектах практикума, являются АТх8515, поставляемые в комплекте со стартовым набором STK500 и занимающие среднее положение в семействе выпускае-
8 1. Инструментальные средства практикума мых моделей AVR. В связи с этим, прежде чем перейти непосредственно к инструментальным средствам проектирования, рассмотрим кратко основные характеристики используемых микроконтроллеров и их структуру. 1.1. МИКРОКОНТРОЛЛЕРЫ АТх8515 Аппаратные ресурсы Все микроконтроллеры AVR имеют гарвардскую архитектуру, которая предполагает разделение памяти программ и данных. Используемые при этом средства адресации позволяют создавать эффективные программы с высоким быстродействием. Упрощенная структурная схема микроконтроллера AT90S8515 представлена на рис. 1.1. Ядро микроконтроллера образуют блок процессора, объединяющий арифметико-логическое устройство (АЛУ) с регистром признаков (SREG) и устройство управления, память программ (Flash) объемом 8 Кбайт, регистры общего назначения, память данных статического типа (SRAM) объемом 512 байт. Устройство управления включает схему синхронизации, регистр управления микроконтроллера (MCUCR), генератор, а также регистр команд с дешифратором, программный счетчик и указатель стека. Периферийные устройства представлены достаточно широко: - 8-разрядные порты ввода/вывода PA, РВ, PC, PD; - последовательный асинхронный приемопередатчик UART (Universal Asynchronous Receiver-Transmitter); - последовательный синхронный порт SPI (Serial Peripheral Interface); - 8-разрядный таймер ТО; - 16-разрядный таймер Т1; - сторожевой таймер; - широтно-импульсный модулятор PWM; - энергонезависимая память EEPROM объемом 512 байт; - блок прерываний; - аналоговый компаратор. Для памяти программ и энергонезависимой памяти в составе микроконтроллера имеются средства для внутрисистемного программирования по интерфейсу SPI. Память микроконтроллера организована, как показано на рис. 1.2.
Рис. 1.1. Структурная схема микроконтроллера AT90S8515
10 1. Инструментальные средства практикума Память данных Память программ 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 могут быть записаны при программировании микроконтроллера. При выключении питания данные сохраняются. Регистры общего назначения разбиты на две группы: Rq. . .R15 и R16...R31. Принадлежность регистра к той или иной группе необходимо учитывать при написании программы. Микроконтроллер AT90S8515 содержит 44 регистра ввода/вывода, используемых в составе периферийных устройств (еще 20 регистров зарезервировано), из них 14 - 8-разрядные регистры данных, остальные являются регистрами управления и состояния. Если
1.1. Микроконтроллеры АТх8515 11 учесть, что они представлены битами управления и состояния, общее количество которых 187 (!), и часть их объединена полями с кодами управления, то нетрудно понять, насколько многообразны функциональные возможности этих устройств (к примеру, одно 3-разрядное поле управления позволяет задать восемь управляющих функций). Список регистров ввода/вывода и их адреса в адресном пространстве SRAM приведены в табл. 1.1. Таблица 1.1. Адреса регистров ввода/вывода AT90S8515 Адрес 20 30 40 50 0 Резерв PIND Резерв Резерв 1 Резерв DDRD WDTCR Резерв 2 Резерв PORTD Резерв TCNT0 3 Резерв PINC Резерв TCCR0 4 Резерв DDRC ICR1L Резерв 5 Резерв PORTC ICR1H MCUCR 6 Резерв PINB Резерв Резерв 7 Резерв DDRB Резерв Резерв 8 ACSR PORTB OCR1BL 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.
12 1. Инструментальные средства практикума Список регистров ввода/вывода микроконтроллера АТте- ga8515 и их адреса в адресном пространстве SRAM приведены в табл. 1.2. Микроконтроллер ATmega8515 содержит 55 регистров ввода/вывода. Файл определений штатных имен регистров для ATmega8515, включаемый в программы на Ассемблере, носит имя m8515def.inc, на языке Си - mega8515.h. Таблица 1.2. Адреса регистров ввода/вывода ATmega8515 Адрес 20 30 40 50 0 Резерв PIND UBRRH SFIOR 1 Резерв DDRD WDTCR OCR0 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, обычно под него выделяется область адресов, начиная с S025F. Стек растет в сторону убывающих адресов, контроль его размера возлагается на программиста.
1.1. Микроконтроллеры А Тх8515 13 Контроллер прерываний обрабатывает внешние прерывания и прерывания от периферийных устройств (таймеров, портов последовательного ввода/вывода, аналогового компаратора и др.). Все прерывания являются маскируемыми. Адреса, маски и флаги прерываний указаны в табл. 1.3. В таблице представлены: INTO, INT1 - сигналы внешних прерываний, поступающие по линиям порта PD2, PD3. Маски внешних прерываний представлены разрядами INTO и INT1 (соответственно 6-й и 7-й разряды регистра GIMSK микроконтроллера AT90S8515 или регистра GICR микроконтроллера ATmega8515). Сигналы внешних прерываний устанавливают в 1 флаги прерываний INTF0 и INTF1 (соответственно 6-й и 7-й разряды регистра GIFR); прерывания от таймеров ТТ, ТО, имеют адреса $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. Запрос с меньшим адресом имеет более высокий приоритет. Флаг общего разрешения прерывания I расположен в регистре состояния микроконтроллера SREG (бит 7). При I = 1 и единичном значении маски запроса прерывание данного типа разрешено. При поступлении запроса устанавливается флаг прерывания в одном из регистров ввода/вывода, который может вызвать аппаратное прерывание. Состояние флага может быть также опрошено программой. Обработка прерывания начинается после завершения текущей команды, для чего может понадобиться несколько тактов в зависимости от типа выполняемой команды. При обработке прерывания разряд I в регистре SREG сбрасывается в состояние 0, запрещая обработку всех остальных запросов. В стеке сохраняется ад-
14 1. Инструментальные средства практикума рес возврата и выполняется переход по вектору прерывания на первую команду обработчика прерывания. При выходе из прерывающей программы разряд I вновь устанавливается в состояние 1, разрешая обработку прерываний. Программа, выполняемая при пуске микроконтроллера и использующая вектор запроса RESET, не зависит от состояния разряда I. Для обработки прерываний она должна выполнить команду разрешения прерываний, устанавливающую флаг I в состояние 1. Таблица 1.3. Адреса и маски прерываний АТх8515 Запрос Адрес Маска Флаг RESET ООО - - INTO 001 GIMSK.6/ GICR.6 GIFR.6 INT1 002 GIMSK.7/ GICR.7 GIFR.7 Т/С1 С APT 003 TIMSK.3 TIFR.3 T/Cl COMPA 004 TIMSK.6 TIFR.6 T/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 U ART DRE/ 00A UCR.5/ USR.5/ USART DRE UCSRB.5 UCSRA.5 U ART ТХС/ 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.O EERDY* OOF EECR.3 - SPMRDY* 010 SPMCR.7 -
1.1. Микроконтроллеры ЛТх8515 15 (ТО) РВОС (Tl) РВ1 с (AINO) РВ2 С (AINU РВЗ С (SS)PB4 С (MOSI) РВ5 С (MISO) РВбС (SCKLPB7C RESET С (RXD) PDO С (TXD) Р01 С (INTO) PD2 С (INT1) PD3 С PD4 С (ОС1А) PD5 С (WR) PD6 С (RD) PD7 С XTAL2 С XTAL1с GND С 40 39 38 37 36 35 34 33 32 31 30 29 28 27 26 25 24 23 22 21 3 VCC 3 РАО (ADO) D РА1 (AD1) D РА2 (AD2) 3 РАЗ (AD3) Ц РА4 (AD4) 3 РА5 (AD5) 3 РА6 (AD6) D РА7 (AD7) 3 ICP DALE 3 0С1В 3 РС7 (А15) D РС6 (А14) 3 РС5 (А13) 3 РС4 (А12) D РСЗ(АП) 3 РС2 (А10) D PCI (А9) 3 РСО (А8) (ОСО/ТО) РВ01 (Tl) PB1I (AINO) PB2I (AIN1) РВЗ I (S"§) PB4I (MOSI) PB5I (MISO) РВбС (SCKLPB7C RESET С (RXD) PDO С (TDX) PD1C (INTO) PD2 С (INT1) PD3C (XCK) PD4C (OC1A) PD5 С (WR) PD6 С (RD) PD7 С XTAL2 С XTAL1C GND С 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 40 39 38 37 36 35 34 33 32 31 30 29 28 27 26 25 24 23 22 21 3 vcc 3 РАО (ADO) 3 PA1 (AD1) 3 PA2 (AD2) 3 РАЗ (AD3) 3 PA4 (AD4) 3 PA5 (ADS) 3 PA6 (AD6) 3 PA7 (AD7) 3 PEO (ICP/INT2) 3 PE1 (ALE) 3 PE2 (OC1B) 3 PC7 (A15) 3 PC6 (A14) 3 PC5 (A13) D PC4 (A12) 3 PC3(A11) 3 PC2 (A10) 3 PCI (A9) 3 РСО (A8) AT90S8515 ATmega8515 Рис. 1.3. Интерфейсы микроконтроллеров ATx8515 Аналоговый компаратор сравнивает по значению аналоговые сигналы, поступающие на входы порта РВ2, РВЗ, и формирует запрос прерывания ANA СОМР при изменении знака разности, а также сигнал захвата для таймера. На рис. 1.3 приведены условные графические обозначения микросхем микроконтроллеров AT90S8515 и ATmega8515, используемых в практикуме. Все выводы портов имеют альтернативные функции, конфигурируемые автоматически при использовании периферийными устройствами микроконтроллера. Их имена приведены в скобках. По сравнению с AT90S8515 в микроконтроллере ATmega8515 выводы 29-31 образуют 3-разрядный порт РЕ. Микроконтроллеры АТх8515 выпускают в разных корпусах: TQFP, PLCC, PDIP. Поставляемые со стартовым набором STK500 микроконтроллеры выполнены в 40-выводном корпусе PDIP, устанавливаемом в панели STK500, и допускают замену в процессе эксплуатации. Система команд микроконтроллеров AVR Для программирования микроконтроллера AT90S8515 используется 118 команд, ATmega8515-130. Все команды можно разбить по группам: - арифметических и логических операций; - пересылки и загрузки;
16 1. Инструментальные средства практикума - передачи управления; - операций с битами. В табл. 1.4 - 1.7 приведено описание базового набора команд микроконтроллеров AVR. При описании команд использованы следующие обозначения: Rd, Rr - регистры общего назначения с номерами d и г; Rdh:Rdl - пара регистров; К - константа (данные); Р,Ь - разряд b (b = 0, ...,7) порта Р; Rr(b) - разряд 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 во всех случаях, кроме специально отмеченных. Таблица 1.4. Арифметические и логические операции Мнемоника Описание команды Операция Признаки ADD Rd, Rr Сложение двух регистров Rd*-Rd + Rr Z, С, 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 - K, d= 16-31 Z, C, N, V, H SBC Rd, Rr Вычитание двух регистров с заемом Rck-Rd - Rr - С Z, C, N, V, H
1.1. Микроконтроллеры Л Тх8515 17 Продолжение табл. 1.4 Мнемоника Описание команды Операция Признаки SBCI Rd, К Вычитание конRd<-Rd-K-C, Z, С, N, V, H станты из регистра d =16 - 31 с заемом SBIW Rdl, К Вычитание конRdh:Rdl+- Z, C, N, V, S станты из регистRdh:Rdl - К ровой пары AND Rd, Rr Логическое И двух Rd+-RdARr Z, N,V регистров ANDI Rd, К Логическое И региRd<—Rd л К, Z,N,V стра и константы d= 16-31 OR Rd, Rr Логическое ИЛИ Rd<-RdvRr Z, N, V двух регистров ORI Rd, К Логическое ИЛИ Rd<—Rd v K, Z,N,V регистра и константы d= 16-31 EOR Rd, Rr Логическое исклюRd<-Rd e Rr Z,N,V чающее ИЛИ регистров LSL Rd Логический сдвиг Rd(n+ l)^-Rd(n), Z, C, N, V влево Rd(0)<-0 LSR Rd Логический сдвиг Rd(n)^Rd(n+l), Z С N V вправо Rd(7)+-0 ROL Rd Сдвиг влево через Rd(0)<-C, перенос Rd(n+ 1)<-Rd(n), Z, C, N, V C^-Rd(7) ROR Rd Сдвиг вправо через Rd(7)<-C, перенос Rd(n)«-Rd(n+1), Z, C, N, V C<h-Rd(0) ASRRd Арифметический Rd(n)^Rd(n+l), Z, C, N, V сдвиг вправо n = 0...6 CP Rd, Rr Сравнение регистRd-Rr Z, N, V, С, H ров CPC Rd, Rr Сравнение регистRd - Rr - С Z, N, V, С, H ров с учетом заема
18 1. Инструментальные средства практикума Окончание табл. 1.4 Мнемоника Описание команды Операция Признаки CPI Rd, К Сравнение регистра с константой Rd-K,d= 16-31 Z,N, V, C, H COM Rd Инверсия регистра Rd <- $FF - Rd Z, C, N, V NEG Rd Изменение знака Rd <- $00 - Rd Z, C, N, V, H SBR Rd, К Логическое ИЛИ регистра и константы Rd<—Rd v K, 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 TST Rd Проверка регистра Rd <- Rd л Rd Z, N, V CLR Rd Сброс регистра в 0 Rd <- Rd 0 Rd Z, N, V SER Rd Установка 1 в разрядах регистра Rd <- $FF, d= 16-31 Таблица 1.5. Команды пересылки Мнемоника Описание команды Операция 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) рементом
1.1. Микроконтроллеры ЛТх8515 19 Продолжение табл. 1.5 Мнемоника Описание команды Операция LD Rd, Y Косвенная загрузка регистра Rd «- (Y) LD Rd, Y+ Косвенная загрузка с постинкрементом Rd 4- (Y), Y <— Y + 1 LD Rd, -Y Косвенная загрузка с пред- декрементом Y<-Y- l,Rd+-(Y) LDD Rd,Y+q Косвенная загрузка относительная Rd <— (Y + q) LD Rd, Z Косвенная загрузка регистра Rd 4- (Z) LD Rd, Z+ Косвенная загрузка с постинкрементом Rd<-(Z),Z^Z+1 LD Rd, -Z Косвенная загрузка с пред- декрементом Z«-Z-l,Rd<-(Z) LDD Rd, Z+q Косвенная загрузка относительная Rd 4- (Z + q) LDS Rd, k Прямая загрузка регистра Rd 4- (k) ST X,Rr Косвенное сохранение (X)<-Rr ST X+, Rr Косвенное сохранение с постинкрементом (X) 4- Rr, X <- X + 1 ST-X,Rr Косвенное сохранение с преддекрементом X<-X-l,(X)4-Rr ST Y, Rr Косвенное сохранение (Y) 4— Rr ST Y+, Rr Косвенное сохранение с постинкрементом (Y) 4- Rr, Y 4- Y + 1 ST -Y, Rr Косвенное сохранение с преддекрементом Y 4- Y - 1, (Y) 4- Rr STD Y + q, Rr Косвенное сохранение относительное (Y + q) 4- Rr ST Z,Rr Косвенное сохранение (Z)4-Rr ST Z+, Rr Косвенное сохранение с постинкрементом (Z) 4- Rr, Z 4- Z + 1 ST -Z, Rr Косвенное сохранение с преддекрементом Z4-Z-l,(Z)4-Rr
20 1. Инструментальные средства практикума Окончание табл. 1.5 Мнемоника Описание команды Операция STD Z + q, Rr Косвенное сохранение относительное (Z + q) <- Rr STS k, Rr Прямое сохранение (k) <- Rr LPM Загрузка из программной памяти в R0 R0 <- (Z) *LPM Rd, Z+ Загрузка из программной памяти в регистр Rd с постинкрементом Rd «-(Z),Z+-Z+l *SPM Сохранение в программной памяти (Z)«-R1:R0 IN Rd, P Чтение регистра ввода/вывода Rd «- P, P = 0 - 63 OUT P, Rr Запись в регистр ввода/вывода P^Rr,P = 0-63 PUSHRr Сохранение в стеке STACK <- Rr POPRd Извлечение из стека Rd 4- STACK Таблица 1.6. Команды управления Мнемоника Описание команды Операция RJMPk Переход PC <— PC + k + 1 IJMP Косвенный переход по (Z) PC<-Z RCALL k Вызов подпрограммы PC <- PC + k + 1 ICALL Косвенный вызов по (Z) PC<-Z RET Возврат из подпрограммы PC <- STACK RETI Возврат из прерывания PC <- STACK, I CPSE Rd,Rr Сравнить и пропустить команду, если равны если (Rd = Rr), то PC<—PC + 2/3 SBRC Rr, b Пропустить, если бит в регистре равен 0 если (Rr(b) = 0), то PC<—PC + 2/3 SBRS Rr, b Пропустить, если бит в регистре равен 1 если (Rr(b) = 1), то PC<-PC + 2/3 SBIC P, b Пропустить, если бит порта равен 0 если (P(b) = 0), то PC«—PC + 2/3 SBIS P, b Пропустить, если бит порта равен 1 если (P(b) = 1), то PC<- PC + 2/3
1.1. Микроконтроллеры АТх8515 21 Окончание табл. 1.6 Мнемоника Описание команды Операция В RES s, к Перейти, если флаг в SREG = 1 если (SREG(s)= 1), то РС«-РС+к+1 BRBC s, к Перейти, если флаг в SREG = 0 если (SREG(s) = 0), то РС<-РС + к + 1 BREQ к Перейти, если равно если (Z = 1), то РС<-РС + к + 1 BRNEk Перейти, если не равно если (Z = 0), то РС+-РС + к+ 1 BRCSk Перейти, если С = 1 если (С = 1), то РС<-РС + к + 1 BRCCk Перейти, если С = 0 если (С = 0), то РС+-РС + к + 1 BRSHk Перейти, если больше или равно если (С = 0), то РС«-РС + к+ 1 BRLOk Перейти, если меньше если (С = 1), то РС<—PC + к + 1 BRMIk Перейти, если минус е;сли (N = 1), то РС^РС + к + 1 BRPLk Перейти, если плюс если (N = 0), то РС^РС + к + 1 BRGEk Перейти, если больше или равно если (N0V = 0), (со знаком) то РС«-РС + к + 1 BRLTk Перейти, если меньше (со знаесли(К0У= 1), ком) то РС«-РС + к + 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 к Перейти, если флаг прерывания если (1=1), 1=1 то PC <— PC + к + 1 BRIDk Перейти, если флаг прерывания если (I = 0), 1 = 0 то PC PC + к + 1
22 1. Инструментальные средства практикума Таблица 1.7. Операции с битами Мнемоника Операция Мнемоника Операция SBI Р,Ь (P,b)<- 1,P=0-31 SES S^ 1 CBI Р,Ь (P,b)^0, P=0-31 CLS S^-0 BSETs SREG(s) *- 1 SEV V<- 1 BCLRs SREG(s) <- 0 CLV V<-0 BST Rr,b T <- Rr(b) SET T^- 1 BLD Rd,b Rd(b) T CLT T^O SEC C^- 1 SEH H <— 1 CLC C^-0 CLH H^O SEN N <- 1 NOP Нет CLN N<-0 SLEEP Режим энергосбережения SEZ Z^ 1 WDR Сброс WDT CLZ Z^-0 SEI I <-1 CLI I+-0 Способы адресации данных в микроконтроллерах AVR Ключевым моментом к пониманию функций, выполняемых каждой командой, помимо кода операции являются используемые командой способы адресации данных (операндов). Микроконтроллеры AVR применяют разнообразные способы адресации данных. По количеству и способам адресации они превосходят возможности микроконтроллеров MCS-51. При том или ином способе адресации можно осуществить доступ к любой области памяти данных (регистрам общего назначения, регистрам ввода/вывода, памяти SRAM), а также Flash-памяти программ и энергонезависимой памяти данных EEPROM. При этом часто к одному и тому же объекту можно обратиться разными способами, используя для этого соответствующий вид адресации. Рассмотрим каждый из них подробнее.
1.1. Микроконтроллеры ЛТх8515 23 Прямая регистровая адресация с одним регистром Rd. При этом способе адресации данные находятся в регистре d(Rd), адрес которого содержится непосредственно в команде (рис. 1.4, а). Примером команд, использующих этот метод адресации, являются команды для Регистровый файл Регистровый файл 15 I КОП | 1~| Рис. 1.4. Прямая регистровая адресация одного (а) и двух (б) регистров общего назначения работы со стеком (PUSH, POP), обмена тетрадами в регистре (SWAP), ряд команд арифметических и логических операций. Прямая регистровая адресация с двумя регистрами Rd и Rr. Данный способ адресации применяется в командах, которые используют два регистра общего назначения: d(Rd) и r(Rr) (рис. 1.4, б). Этот вид адресации используют команды пересылки данных из регистра в регистр и большинство команд арифметических операций, ряд команд логических операций. При этих операциях результат операции сохраняется в регистре d (Rd). Прямая адресация регистра ввода/вывода. Данный вид адресации используют для выполнения обмена между регистром ввода/вывода, расположенным в 15 5 0 адресном пространстве ввода/вы- | коп | r/d [ р | вода, и одним из регистров обще- I го назначения по командам IN и OUT (рис. 1.5). Прямая адресация памяти данных. Данный способ адресации применяется при обращении РиСв 15в Прямая адресация к любой ячейке адресного про- регистра ввода/вывода странства SRAM. Имеются всего две команды: LDS и STS, каждая длиной в два слова (32 разряда). Первое слово содержит код операции и адрес регистра общего Память ввода/ вывода
24 1. Инструментальные средства практикума 31 16 ОЗУ данных КОП | г/Т 16 младших бит 15 $0000 $FFFF Рис. 1.6. Прямая адресация памяти данных ОЗУ данных 15 0 |Х, Y или Z-регистр | $0000 назначения, второе - 16-разрядный адрес ячейки, к которой направлено обращение (рис. 1.6). Косвенная адресация памяти данных. При косвенной адресации обращение направлено к ячейке памяти, адрес которой находится в 16-разрядном индексном регистре X, Y или Z (рис. 1.7). В роли этих регистров выступают пары регистров: R26, R27 (регистр X), R28, R29 (регистр Y) и R30, R31 (регистр Z). Косвенная адресация памяти данных со смещением. При этом способе адрес ячейки памяти определяется путем суммирования содержимого индексного регистра Y или Z с 6-разрядным смещением, задаваемым в команде (рис. 1.8). Этот способ адресации используют команды LDD (пересылка байта из ячейки памяти SRAM в регистр Rd) и STD (пересылка байта из регистра Rr в ячейку SRAM). $FFFF Рис. 1.7. Косвенная адресация памяти данных ОЗУ данных 15 Y или Z-регистр 15 10 6 5 0 КОП п $0000 $FFFF Рис. 1.8. Косвенная адресация памяти данных со смещением Косвенная адресация памяти данных с преддекрементом. При этом способе адресации содержимое индексного регистра X, Y или Z сначала уменьшается на 1, а затем производится обращение к памяти по полученному адресу (рис. 1.9). Этот способ адресации используют команды LD (пересылка байта данных из памяти в
1.1. Микроконтроллеры Л Тх8515 25 Рис. 1.9. Косвенная адресация с преддекрементом регистр Rd) и ST (пересылка байта данных из регистра Rr в память), всего шесть команд - по две для каждого регистра. Косвенная адресация памяти данных с постинкрементом. При этом способе адресации содержимое индексного регистра X, Y или Z сначала используется в качестве адреса обращения к памяти данных, а затем увеличивается на 1 (рис. 1.10). Этот способ адре- Рис. 1.10. Косвенная адресация с постинкрементом сации используют команды LD (пересылка байта данных из памяти в регистр Rd) и ST (пересылка байта данных из регистра Rr в память), всего шесть команд - по две для каждого регистра. Косвенная адресация памяти программ. Микроконтроллеры AVR позволяют обратиться к ячейкам памяти программ для считывания констант, а в моделях семейства Mega - и для записи данных во Flash-память программ, используя механизм косвенной адресации через регистр Z. При этом старшие 15 разрядов регистра определяют адрес слова, а младший нулевой разряд - младший или старший байт слова. Если младший разряд адреса равен 0, выбирается младший байт, в противном случае выбирается старший байт (рис. 1.11). Данный вид адресации используют команды считывания из ячейки памяти в регистр R0 (LPM) и записи в память из регистров R1:R0 (SPM).
26 1. Инструментальные средства практикума Рис. 1.11. Косвенная адресация констант в памяти программ Память программ 15 1 $000 | Z-регистр |-i Рис. 1.12. Косвенная адресация памяти программ Относительная адресация памяти программ. При этом способе адрес вычисляют путем сложения содержимого программного счетчика PC и константы к, задаваемой в команде (рис. 1.13). Относительную адресацию используют команды относительного перехода (RJMP) и относительного вызова подпрограммы (RCALL), многочисленная группа команд условных переходов. В дополнение к перечисленным в Руководстве по микроконтроллерам способам адресации укажем еще два ее вида. Непосредственная адресация. Данный вид адресации подразумевает указание одного из операндов (константы К) непосредственно в команде. Непосредственная адресация используется командой пересылки константы в регистр LDI, а также некоторыми командами арифметических и логических операций.
1.1. Микроконтроллеры АТх8515 27 Рис. 1.13. Относительная адресация памяти программ Битовая адресация. Этот вид адресации позволяет указать один из восьми битов любого из 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). Описание команд Ранее приведены таблицы с описанием команд микроконтроллеров AVR, разбитые по группам. Кроме операции и операндов для каждой команды указаны признаки результата, формируемые в регистре SREG. Мнемоники команд, выполняемых только в микроконтроллерах семейства Mega, помечены *. Группа арифметических и логических операций по составу достаточно традиционна для архитектуры 8-разрядных микроконтроллеров, за исключением микроконтроллеров семейства Mega. Так, например, в группу арифметических команд микроконтроллера ATmega8515 добавлены шесть операций умножения: беззнаковых чисел MUL, чисел со знаком MULS, беззнакового числа на число со знаком MULSU, дробных беззнаковых чисел FMUL, дробных со знаком FMULS, дробного беззнакового и дробного со
28 1. Инструментальные средства практикума знаком FMULSU. Дробные сомножители имеют формат 1.7, их произведение - формат 1.15, где справа от точки указано число дробных разрядов. Во всех операциях умножения источниками операндов являются регистры Rd и Rr, произведение формируется в регистрах Rl :R0. При выполнении операций сложения/вычитания приемником результата является один из регистров общего назначения, в котором до операции находится один из операндов. Таким образом, можно говорить о реализации АЛУ аккумуляторного типа по отношению к любому регистру общего назначения (сравните: микроконтроллеры с ядром MCS-51 имеют всего лишь один аккумулятор, что, безусловно, ухудшает эффективность обработки данных и ведет к снижению производительности в целом). Особенностью системы команд микроконтроллеров AVR является отсутствие команды двоично-десятичной коррекции. Команды пересылки можно использовать для передачи данных из регистра в регистр, для пересылок между регистрами и косвенно адресуемыми ячейками адресного пространства SRAM, регистрами ввода/вывода и регистрами общего назначения, для сохранения и извлечения данных из стека, чтения констант из Flash- памяти программ и даже записи во Flash-память (в модели ATmega8515). Следует обратить внимание, что непосредственная загрузка константы в регистры общего назначения первой половины (R0...R15) невозможна. Для этого необходимо предварительно загрузить константу в один из регистров второй половины (R16...R31), а затем переслать содержимое вспомогательного регистра в регистр первой половины. Широко представлена группа команд передачи управления. Помимо традиционных команд безусловной и условной передачи управления по флагу имеются команды косвенного перехода и косвенного вызова подпрограмм. Команды условных переходов делятся на два типа. Команды первого типа при выполнении условия обеспечивают переход по адресу, вычисляемому как сумма (PC + k + 1). При невыполнении условия происходит переход к следующей команде программы по адресу (PC + 1). Команды второго типа при выполнении условия обеспечивают переход к команде, следующей за очередной, т. е. по адресу (PC + 2), если длина очередной команды составляет одно слово, или по адресу (PC + 3), если длина очередной команды составляет два слова. Если условие не выполняется, происходит переход к следующей команде по адресу (PC +1). Такое разнообразие команд управления способствует эффективной работе компиляторов программ, написанных на языке Си.
1.1. Микроконтроллеры Л Тх8515 29 В битовых операциях следует обратить внимание, что все операции пересылки битов в области регистров общего назначения осуществляются только через вспомогательный бит Т регистра состояния SREG. В области регистров ввода/вывода биты можно изменять только путем установки 1 или 0. Программно путем установки 1 или 0 можно изменять состояния флагов регистра состояния SREG. В эту группу включены также операции WDR (сброс сторожевого таймера), SLEEP (перевод в энергосберегающий режим), пустая операция NOP. Директивы Ассемблера При написании программ на языке Ассемблер используются директивы, которые указывают компилятору положение программы в памяти, определяют макросы, инициализируют память и др. Список директив и их описание приведен в табл. 1.8. Запись всех директив начинается с точки. Кратко перечислим выполняемые директивами функции в каждом из сегментов. Сегмент программы открывается директивой .CSEG. Если программа начинается с этого сегмента, директива может отсутствовать. В сегменте программы с помощью директивы .ORG можно указать начало сегмента. Директива .DB в сегменте определяет один байт или группу байтов, констант, записываемых во Flash-память. Директива .DW определяет слово или группу слов, записываемых в память в качестве констант. Начало записи констант определяется меткой, стоящей перед соответствующей директивой. Перечисляемые константы разделяются запятыми. Директива .DEF присваивает регистру символическое имя. Директивы .EQU, .SET присваивают значение имени. Имя, которому присвоено значение директивой .EQU, не может быть переназначено, и значение не может быть изменено. Имя, присвоенное директивой .SET, может быть изменено другой директивой .SET. Директива .DEVICE определяет тип целевого микроконтроллера, который будет использован для выполнения программы. Наличие этой директивы подключает средства контроля инструкций программы по отношению к физическому устройству, предупреждая о невозможности выполнения некоторых инструкций, размеров используемой памяти и др. Директива .INCLUDE с именем файла используется для включения в текст программы другого файла.
30 1. Инструментальные средства практикума Таблица 1.8. Список директив Директива Описание .BYTE Резервировать байты в ОЗУ .CSEG Сегмент программы .DB Определить байт - константу во Flash-памяти или EEPROM .DEF Назначить регистру символическое имя .DEVICE Определяет устройство, для которого компилируется программа .DSEG Сегмент данных .DW Определяет слово во Flash-памяти или EEPROM .ENDM, Конец макроса .ENDMACRO .EQU Установить постоянное выражение .ESEG Сегмент EEPROM .EXIT Выход из файла .INCLUDE Вложить другой файл .LIST Включить генерацию листинга .LISTMAC Включить разворачивание макросов в листинге .MACRO Начало макроса .NOLIST Выключить генерацию листинга .ORG Установить положение в сегменте .SET Установить для переменной эквивалентное выражение Директивы .MACRO и .ENDMACRO обрамляют макроопределение. Макроопределение может иметь до 10 параметров с фиксированными именами @0,...,@9. При вызове макроопределения параметры задают в виде списка в порядке нумерации. Сегмент данных начинается директивой .DSEG. В сегменте могут быть использованы директивы .ORG и .BYTE. Директива .BYTE определяет количество байтов, к которым будет производиться обращение при выполнении программы. Резервируемая область начинается по адресу, определяемому меткой перед директивой. Сегмент типа EEPROM начинается директивой .ESEG. В сегменте могут быть использованы директивы .ORG, .DB, .DW. Директива .DB в сегменте определяет один или группу байтов, записываемых в EEPROM. Директива .DW определяет слово или
1.1. Микроконтроллеры А Тх8515 31 группу слов, записываемых в память EEPROM парами по 2 байта. Начало записи байтов и слов определяется меткой, стоящей перед соответствующей директивой. Директивы .LIST, .NOLIST, .LISTMAC используют для управления выводом листинга. Выражения При записи команд на Ассемблере могут использоваться выражения, по которым в процессе ассемблирования программы вычисляются значения. Операндами выражений могут быть: - числа (десятичные, шестнадцатеричные и двоичные); - метки; - коды символов ASCII ('А') и строки ASCII; - символические имена, представляющие переменные, определенные директивой .SET, и константы, определенные директивой .EQU; - текущее значение счетчика команд (PC). Для обозначения шестнадцатеричных чисел используют указатели Ох или $ (Oxla, Oxff, $ff), для двоичных чисел - 0Ь (ObOOOOl111, Ob 11111111), десятичные числа не имеют указателей (255, 0). Помимо операндов в выражения могут входить функции, например: LOW (выражение) - возвращает младший байт выражения; HIGH (выражение) - возвращает старший байт выражения; ЕХР2 (N) - возвращает 2 ; LOG2 (N) - возвращает целую часть log2N. При записи выражений можно использовать арифметические, логические и операции отношения. Группу арифметических операций образуют сложение двух чисел или выражений (N + М), вычитание (N - М), умножение (N*M), деление (N/M), изменение знака числа (-N). Группу логических операций образуют инверсия (~N), побитовое И (N&M), побитовое ИЛИ (N | М), побитовое исключающее ИЛИ (NPIM), сдвиг влево (N«M - сдвинуть N влево на М разрядов), сдвиг вправо (N»M - сдвинуть N вправо на М разрядов). Операции отношений: - логическое отрицание (!N - возвращает 1, если N = 0, и 0, если N*0); - меньше (N < М - возвращает 1, если N < М, и 0, если N > М);
32 7. Инструментальные средства практикума - больше (N > М - возвращает 1, если выражение N > М, и О, если N < М); - меньше или равно (N <= М - возвращает 1, если N <= М, и О, если N > М); - больше или равно (N >= М - возвращает 1, если N >= М, и О, если N < М); - равно (N = М - возвращает 1, если N = М, и О, если N ф М); - не равно (N != М - возвращает 1, если N ф М, и 0, если N = М); - логическое И (N&&M - возвращает 1, если N ф О и М ф О, иначе 0); - логическое ИЛИ (N||M - возвращает 1, если N = 0 и М = 0, иначе 0). Для указания очередности операций можно использовать круглые скобки. L2. ИНТЕГРИРОВАННАЯ ОТЛАДОЧНАЯ СРЕДА 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 распространяется бесплатно, последняя версия 4.12
1.2. Интегрированная отладочная среда A VR Studio 4 33 доступна на сайтах фирмы Atmel: http://www.atmel.com и http://www.atmel.ru. AVR Studio 4 состоит из нескольких панелей и модулей, каждый из которых выполняет часть общей задачи. Внешний вид программы в режиме редактора показан на рис. 1.14. Рис. 1.14. Графический интерфейс AVR Studio 4 Создание программ в среде AVR Studio 4 происходит в виде проектов, каждый из которых имеет файл, сохраняющий информацию о проекте и входящих в него файлах, установки Ассемблера, пользовательские настройки и т. д. Редактор служит для написания программного кода, он полнофункционален, имеет подсветку синтаксиса, которая может быть изменена и дополнена пользователем. Окно редактора также используется при отладке, при этом точки возможного программного останова могут быть размещены на левой границе поля. В панели вывода Output отображается текущая и служебная информация среды разработки. Щелкнув по ярлыку, можно выбрать то или иное окно:
34 1. Инструментальные средства практикума • Build. Окно сообщений о процессе и результатах компиляции/ трансляции. • Messages. AVR Studio 4 составляют множество объектов, инкапсулированных по технологии Microsoft DCOM. Некоторые из них не имеют графического интерфейса. Messages - это общее окно предоставления сообщений пользователю от всех модулей приложения. Сообщения кодируются цветом. Большинство составляют простые сообщения без значимого приоритета. Они не выделяются цветом. Предупреждения о потенциальных проблемах выделяются желтым цветом, ошибки - красным. Для всех сообщений может быть записано время прихода (опция timestamp контекстного меню). Имеется функция фильтра, позволяющая включать/выключать сообщения разных видов. • Find in Files. AVR Studio 4 имеет функцию встроенного поиска в файлах. В окне отображается информация о результатах поиска. • Breakpoints. Список активных точек возможного прерывания программы во всех модулях программы пользователя. Точки могут быть включены, выключены и удалены в этом окне. Панель рабочего пространства Workspace предназначена для помощи при отладке написанного кода и имеет три вкладки: • Project. Окно со списком файлов, составляющих проект. Если для Рис. 1.15. Вкладка регистров ввода/вывода отладки был открыт объектный файл, то окно покажет имя загруженного файла, а также исходные файлы, с которыми связан данный. • I/O. Окно ввода/вывода содержит несколько секций (рис. 1.15): Регистры. Микроконтроллеры AVR имеют 32 регистра общего назначения (РОН), разбитые на две равные группы 0-15 и 16-31, которые могут свободно использоваться программистом и обнов-
1.2. Интегрированная отладочная среда Л VR Studio 4 35 ляться во время прерывания процесса симуляции. Если состояние регистра изменилось относительно последнего прерывания, он выделяется цветом (по умолчанию красным). Процессор. В секцию входят регистры 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 служит для отображения содержимого всех регистров регистрового файла.
36 1. Инструментальные средства практикума Создание проекта AVR Assembler - это удобный инструмент для написания небольших программ. После компиляции сразу получается выполняемый код, стадия компоновки отсутствует. Для начала работы при запуске 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. В противном случае список ошибок помечается красными кружками. Для исправления ошибки необходимо дважды щелкнуть левой клавишей мыши
1.3. Стартовый набор STK500 фирмы Atmel 37 по строке сообщения. В соответствующей строке программы появится синяя стрелка и текстовый курсор. При трансляции можно получить файл определений программы (строки с директивами .def и .equ) с расширением .тар и файл листинга с расширением .1st, включающий команды в символьном и шестнадцатеричном коде. Для этого необходимо выполнить команды Project/ AVR 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 и ОК. Подготовительные операции закончены. Исходное состояние: все регистры микроконтроллера в окне I/O сброшены в 0, желтая стрелка в окне редактора указывает на первую команду программы. Используя опции меню Debug, выполняем отладку в одном из выбранных режимов: пошаговом, с контрольными точками, автоматическом. Подробно методика отладки программ в среде AVR Studio 4 описана в [7]. 1.3. СТАРТОВЫЙ НАБОР STK500 ФИРМЫ ATMEL STK500 представляет собой универсальный стартовый набор разработчика, позволяющий создавать приложения совместно с интегрированной средой проектирования AVR Studio 4.
38 1. Инструментальные средства практикума Набор STK500 поставляется с микроконтроллером АТх8515, но поддерживает целый ряд других микроконтроллеров AVR, для чего служат соответствующие панели для установки и средства коммуникации. Исходные установки перемычек обеспечивают работу микроконтроллера совместно с тактовым генератором и стабилизатором напряжения, установленным на плате STK500. Набор также имеет широко используемые средства ввода и индикации, интерфейс RS-232, средства расширения для подключения внешних устройств. Описание аппаратных средств В состав отладочной платы STK500 (рис. 1.16) входят: - стабилизированный источник питания с входным напряжением 10... 15В и программно управляемым выходным напряжением; - восемь кнопок общего назначения; - восемь светодиодов общего назначения; - разъемы всех портов ввода/вывода микроконтроллера; - 8-, 20-, 28-, 40-выводные панели для установки DIP-корпусов микроконтроллеров AVR; - интерфейс RS-232 для программирования и управления из программы AVR Studio 4, установленной на персональном компьютере; - дополнительный порт RS-232 общего назначения; - разъемы расширения для подключения внешних модулей при макетировании; - память DataFlash емкостью 2 Мбит для энергонезависимого хранения данных; - средства поддержки параллельного и последовательного программирования повышенным напряжением всех AVR-микроконт- роллеров; - средства последовательного внутрисистемного программирования (ISP) всех AVR-микроконтроллеров; - внутрисистемный программатор для программирования микроконтроллера непосредственно в целевом приложении. Светодиоды и кнопки общего назначения. В набор STK500 входит восемь желтых светодиодов и восемь кнопок без фиксации. Светодиоды и кнопки электрически отделены от остальной части платы и подключены к собственным разъемам. Они могут быть подключены к AVR-микроконтроллерам 10-проводными шлейфами через разъемы портов ввода/вывода.
Рис. 1.16. Компоненты STK500
40 1. Инструментальные средства практикума Схема одного разряда индикации изображена на рис. 1.17, а. При поступлении на вывод LEDn сигнала с низким уровнем напряжения (логический 0) светодиод светится, а сигнала с высоким уровнем напряжения (логическая 1) - светодиод гаснет. Схема подключения кнопки изображена на рис. 1.17, б. При нажатии на кнопку на выводе SWn отмечается низкий уровень напряжения (GND), а при отпускании - высокий (VTG). Рабочий диапазон напряжения VTG =1,8.. .6,0 В. Выводы светодиодов LEDx и кнопок SWx (х = 0...7) соединены с соответствующими контактами разъемов SWITCHS и LEDS. Следует иметь в виду, что контакты 9 и 10 разъемов использованы для сигналов GND и VTG. Поэтому необходимо соблюдать соединение шлейфами одноименных выводов разъемов индикаторов и кнопок с портами микроконтроллеров (шлейф не должен перекручиваться). С этой целью в шлейфе красным цветом выделена одна из линий, которая должна соединять одноименные выводы разъемов (например, LED0 и РхО). Особенности работы светодиодов и кнопок необходимо учитывать при программировании портовых операций микроконтроллеров, связанных с обращением к светодиодам и кнопкам. Разъемы портов. Любой порт ввода/вывода AVR-микроконт- роллера может быть подключен к светодиодам и кнопкам с помощью 10-проводного шлейфа. На разъемы в дополнение к линиям портов выведены напряжение питания целевого микроконтроллера VTG (VCC) и общий провод GND. Расположение выводов разъемов и их соответствие линиям портов ввода/вывода показано на рис. 1.18, а. Рис. 1.17. Схема включения светодиода (а) и кнопки (б)
1.3. Стартовый набор STK500 фирмы Atmel Рис. 1.18. Выводы разъемов портов Рх (х = А, В, С, D) и РЕ микроконтроллера Разъем порта Е (PORTE/AUX) содержит специальные сигналы и функции в дополнение к линиям порта РЕ. Расположение и назначение выводов этого разъема показано на рис. 1.18, б. Интерфейс RS-232 для пользователя. STK500 содержит два порта RS-232. Один порт используется для связи с AVR Studio. Другой можно использовать для связи микроконтроллера, установленного на плате, с компьютером через его последовательный порт RS-232 (СОМ-порт). Для этого два вывода канала 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-микроконтроллеров гарантированная износостойкость составляет 1000 циклов программирования. Секция перемычек и программирования. Управляющий микроконтроллер и восемь перемычек определяют работу данного стартового набора. В поставке эти перемычки установлены в исходное положение.
42 1. Инструментальные средства практикума После установки микроконтроллера в панель может быть выполнено программирование, для чего необходимо использовать 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) целевого микроконтроллера. Индикатор непрерывно светится при наличии напряжения питания на целевых панелях микроконтроллеров. Статусный светодиод трехцветный. При программировании он желтый, после успешного завершения программирования становится зеленым. Красный цвет показывает, что программирование было прервано. При программировании статусный светодиод последовательно изменяет свое состояние от красного через желтый к зеленому для индикации готовности целевого микроконтроллера.
44 1. Инструментальные средства практикума Пользовательский интерфейс 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 показывает, какие режимы защиты программы доступны для выбора при заданном типе микроконтроллера. Все биты защи-
1.4. Интерфейс STK500 в AVR Studio 4. 43 1.4. ИНТЕРФЕЙС STK500 В AVR STUDIO 4 И ПРОГРАММИРОВАНИЕ МИКРОКОНТРОЛЛЕРА Интерфейс STK500 в AVR Studio 4 В качестве программного приложения для связи с платой STK500 используется AVR Studio 4. Выполнение команды Tools/ STK500 из меню AVR Studio приводит к открытию окна пользовательского интерфейса STK500, показанного на рис. 1.19. Рис. 1.19. Окно программирования пользовательского интерфейса STK500
1.4. Интерфейс STK500 в AVR Studio 4. 45 ты доступны как в режиме ISP-программирования, так и в режиме программирования повышенным напряжением. Режим защиты задается комбинацией нескольких битов защиты. Окно прочих установок 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.20) можно изменить рабочие условия на плате STK500. Для изменения доступны следующие параметры: VTARGET, AREF и частота генератора. Интерфейс задания параметров очень гибкий и позволяет задать рабочие условия, выходящие за рамки рекомендуемых для микроконтроллера параметров. Делать это не следует, чтобы не вывести из строя используемый микроконтроллер. Информация о рекомендуемых рабочих условиях приведена в документации для каждого типа микроконтроллера.
1.4. Интерфейс STK500 в AVR Studio 4. 47 Окно управления функциями автоматизации 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 автоматически определяет СОМ-порт с подключенным STK500. 3. Для программирования АТх8515 соединить шестипровод- ным шлейфом разъемы ISP6PIN и SPROG3. 4. Переключателем питания POWER можно включить или отключить STK500. Свечение красного светодиода сигнализирует о подаче питания, состояние статусного светодиода будет меняться от красного к желтому, а затем к зеленому. Зеленый цвет светодиода сигнализирует о наличии напряжения VCC (питание микро-
46 1. Инструментальные средства практикума Рис. 1.20. Окно управления платой Поле настроек генератора Oscillator. Плата STK500 использует схему программируемого генератора, которая формирует широкий диапазон тактовых частот для целевого микроконтроллера. Ввиду того что генерировать сигнал с произвольно заданным значением частоты невозможно, пользовательский интерфейс STK500 позволяет вычислить ближайшую доступную частоту при введении желаемой, что отображается в текстовом поле Closest Attainable Volue. Из раскрывающегося списка можно выбрать фиксированные частоты 32,7 кГц, 1,23 1,84, 3,69 МГц (максимальная частота) или вообще остановить генератор (stopped). Чтение/запись частот генератора осуществляется нажатием соответствующих кнопок Read Osc и Write Osc.
48 7. Инструментальные средства практикума контроллера). Стартовый набор может настраиваться на разные частоты тактирования и источники питания. Дальнейшие действия выполнить в окне программы AVR Studio 4. 1. Создать проект для микроконтроллера, установленного на плате STK500. Загрузив рабочую программу в окно редактора, выполнить команду Build из меню Project. После отладки программы с помощью встроенного симулятора можно перейти к программированию микроконтроллера. 2. Для того чтобы загрузить hex-файл в AVR-микроконтроллер, необходимо выполнить команду Tools/ STK500 из меню программы AVR Studio 4. После открытия окна выбрать тип микроконтроллера из раскрывающегося списка на вкладке Program и указать путь к записываемому Intel-hex файлу в поле Input HEX File. Нажать кнопку Program. Статусный светодиод на плате STK500 во время программирования светится желтым цветом, а после успешного завершения - зеленым. При выявлении ошибки программирования светодиод красный. В случае ошибки детектирования устройства рекомендуется закрыть неиспользуемые программы, выключив питание на плате, разъединить установленные проводные связи, повторить программирование, затем снова при выключенном питании аккуратно выполнить необходимые соединения. Включив питание и убедившись, что статусный светодиод горит зеленым цветом, можно приступать к работе.
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-разрядных портов Рх и структурная схема одного разряда порта Px.Y (Y = 0, 1...7) микроконтроллера AT90S8515. Состояние разряда DDRx.Y определяет направление передачи бита данных через вывод порта Px.Y. При DDRx.Y = 0 вывод порта Px.Y является входом, при DDRx.Y = 1 - выходом. В режиме входа состояние разряда PORTx.Y определяет состояние вывода Px.Y. При PORTx.Y = 1 вывод порта через внутренний резистор подключен к шине питания VCC. При PORTx.Y = 0 резистор отключается, вывод Px.Y находится в высокоимпедансном состоянии (Z-состояние). В режиме выхода состояние разряда PORTx.Y определяет значение сигнала на выводе Px.Y. При PORTx.Y = 0 на выводе устанавливается напряжение низкого уровня, при PORTx.Y = 1 - высокого.
50 2. Программирование портов ввода/вывода Рис. 2.1. Структура порта Рх (а) и схема одного разряда порта (б) При пуске и перезапуске микроконтроллера все разряды регистров DDRx и PORTx сбрасываются в нулевое состояние, вследствие чего выводы портов работают в режиме входа и находятся в Z-состоянии. При совместном использовании всех разрядов порта для ввода байта данных используют команды с мнемоникой IN Rd, PINx, для вывода - OUT PORTx, Rr (d, г = 0.. .31). Значение выходного сигнала на отдельном выводе порта можно задать с помощью команд установки 0 (CBI PORTx.Y) и 1 (SBI PORTx.Y). Входной сигнал на отдельном выводе порта можно проверить, используя команды условного перехода SBIC PINx,Y или SBIS PINx,Y, которые предусматривают пропуск следующей команды по нулевому или единичному значению Px.Y. 2.1. ВЗАИМОДЕЙСТВИЕ МИКРОКОНТРОЛЛЕРА С КНОПКАМИ И СВЕТОДИОДАМИ Подготовить программу, которая при нажатии кнопки START выполняет поочередное переключение светодиодов, при нажатии кнопки STOP останавливает переключение и возобновляет при повторном нажатии кнопки START. Пример программы приведен далее. В программе для микроконтроллера AT90S8515 используется файл определений 8515def.inc, для ATmega8515 - m8515def.inc.
2.1. Взаимодействие микроконтроллера с кнопками и светодиодами 51 В программе линии порта РВ использованы для индикации и, следовательно, проинициализированы на вывод, а линии 0 и 1 порта PD, соединяемые с кнопками, - на ввод. После нажатия кнопки START начинается последовательное переключение свето- диодов с задержкой и проверка состояния кнопки STOP. Программа 2.1 ,****************************^ /Программа 2.1 для микроконтроллеров АТх8515: ;переключение светодиодов (СД) при нажатии на кнопку START ;(SW0), после нажатия кнопки STOP (SW1) переключение /прекращается и возобновляется с места остановки ;при повторном нажатии на кнопку START .**********★****★★★*★************★*★**★★* .include "8515def.inc" ;файл определений для AT90S8515 /.include "m8515def.inc" /файл определений для ATmega8515 .def temp = rl6 /временный регистр .def reg_led = r20 /состояние регистра светодиодов .equ START = 0 /0-й разряд порта PD .equ STOP = 1 /1-й разряд порта PD .org $000 rjmp init .*★*инициализация* ** INIT: ldi reg_led,OxFE /сброс reg_led.O ; для включения LEDO sec /C=l set ;T=1 - флаг направления ser temp /инициализация out DDRB,temp / порта РВ на вывод out PORTB,temp /погасить СД clr temp /инициализация out DDRD,temp / порта PD на ввод ldi temp,0x03 /включение подтягивающих out PORTD,temp / резисторов порта PD WAITSTART: /ожидание sbic PIND,START / нажатия rjmp WAITSTART / кнопки START LOOP: out PORTB,reg_led /включение СД /***3адержка (два вложенных цикла)*** ldi г17,2 dl:ldi rl8,2 d2:dec rl8 brne d2
52 2. Программирование портов ввода/вывода dec г17 brne dl sbic PIND,STOP ;если замкнута кнопка STOP, rjmp MM ; то переход rjmp WAITSTART ; для проверки кнопки START, MM:ser temp ;иначе выключение светодиодов out PORTB,temp brts LEFT /переход, если флаг T установлен sbrs reg_led,0 /пропуск следующей команды, если ; 0-й разряд reg_led установлен set ;Т=1 - переключение флага ror reg_led /сдвиг reg_led вправо rjmp LOOP LEFT: sbrs reg_led,7 /пропуск следующей команды, если / 7-й разряд reg_led установлен clt ;Т=0 - переключение флага / направления rol reg_led /сдвиг reg_led влево rjmp LOOP Задание 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. Обработка внешних прерываний 53 Убедившись в правильности загрузки по выводимым сообщениям, проверьте работу программы на макете. Для этого, выключив питание STK500, с помощью 10-проводного шлейфа соедините выводы разъема порта PD с выводами разъема кнопок общего назначения. С помощью второго 10-проводного шлейфа соедините выводы разъема порта РВ с выводами разъема светодиодов. Включите питание и проверьте работу загруженной программы. 2.2. ОБРАБОТКА ВНЕШНИХ ПРЕРЫВАНИЙ Таблица 2.1. Таблица выбора типа запроса В качестве входов внешних прерываний используются входы портов с альтернативной функцией: PD2, PD3 - для прерываний INTO, INT1 и РЕО - для прерывания INT2 в микроконтроллере ATmega8515. Запросы внешних прерываний INTO, INT1 могут быть представлены низким уровнем сигнала прерывания (L), переходом от высокого уровня сигнала к низкому (HL - по отрицательному фронту), переходом от низкого уровня сигнала к высокому (LH - по положительному фронту), запрос INT2 только переходами (LH) и (HL). В зависимости от типа запроса в регистре управления микроконтроллера MCUCR необходимо установить биты ISCxO и ISCxl согласно табл. 2.1 для каждого из прерываний INTx (х = 0,1) и определить бит ISC2 в регистре EMCUCR для прерывания INT2. При ISC2 = 0 прерывание осуществляется по отрицательному фронту, при ISC2 = 1 - по положительному. Далее подготовим программу переключения светодиодов с использованием внешнего прерывания от кнопки STOP. Согласно поставленным условиям, в блок инициализации микроконтроллера внесем ряд изменений: - добавим вектор прерываний; - указатель стека установим на последнюю ячейку ОЗУ; - разрешим внешнее прерывание INTO (по сигналу 0 на линии 2 порта PD) и прерывания вообще. Поскольку внешнее прерывание INTO представлено сигналом на входе порта PD2, в качестве кнопки STOP используем кнопку ISCxl ISCxO Тип запроса 0 0 L 0 1 1 0 HL 1 1 LH
54 2. Программирование портов ввода/вывода SW2 и программируем PD2 на ввод. Пример программы 2.2 приведен ниже. Задержка представлена подпрограммой DELAY. Программа работает аналогично 2.1, но нажатие кнопки STOP вызывает прерывание. Программа 2.2 .***************************^ /Программа 2.2 для поочередного переключения светодиодов /при нажатии на кнопку START (SW0). После нажатия на кноп- ;ку STOP (SW2) переключение прекращается и возобновляется /с места остановки при повторном нажатии на кнопку START .************************************** .include "8515def.inc" /файл определений для AT90S8515 /.include "m8515def.inc" /файл определений для ATmega8515 .def temp = г16 /временный регистр .def reg_led = r2 0 /состояние регистра светодиодов .equ START = 0 /0-й разряд порта PD .org $000 /***Векторы прерываний*** rjmp INIT /обработка сброса rjmp STOP_PRESSED /обработка внешнего прерывания / INTO(STOP) /* * ^Инициализация МК* * * INIT: ldi reg_led,0xFE ldi temp,$5F /установка out SPL,temp / указателя стека ldi temp,$02 / на последнюю out SPH,temp / ячейку ОЗУ sec ;C=1 set ;T=1 ser temp /инициализация выводов out DDRB,temp / порта РВ на вывод out PORTB,temp /погасить светодиоды clr temp /инициализация out DDRD,temp / порта PD на ввод ldi temp,0x05 /включение подтягивающих out PORTD,temp / резисторов порта PD ldi temp,0x7F /разрешение прерывания INTO out GIMSK,temp / (6 бит GIMSK или GICR) ldi temp,0x00 /обработка прерывания INTO out MCUCR,temp / по низкому уровню sei / разрешение прерываний WAITSTART: sbic PIND,START / ожидание нажатия
2.2. Обработка внешних прерываний 55 rjmp WAITSTART ; кнопки START LOOP: out PORTB,reg_led /включение светодиодов rcall DELAY /задержка ser temp /выключение out PORTB,temp / светодиодов brts LEFT /переход, если флаг T установлен sbrs reg_led,О /пропуск следующей команды, если / 0-й разряд reg_led установлен set ;Т=1 ror reg_led /сдвиг reg_led вправо rjmp LOOP LEFT: sbrs reg_led,7 /пропуск следующей команды, если / 1-й разряд reg_led установлен clt ;Т=0 rol reg_led /сдвиг reg_led влево rjmp LOOP ;***Обработка прерывания от кнопки STOP*** STOP_PRESSED: WAITSTART_2: /ожидание sbic PIND,START / нажатия rjmp WAITSTART_2 / кнопки START reti /*** Задержка *** DELAY: ldi rl7, 2 dl: ldi rl8,2 d2: dec rl8 brne d2 dec rl7 brne dl ret Задание 2. Проверить работу программы с помощью отладчика AVR Studio 4. Изменить параметры задержки, чтобы длительность задержки составила 0,5 с. Запрограммировать микроконтроллер и проверить работу программы. Задание 3. Изменить программу для включения (выключения) светодиодов в одной из заданных последовательностей: а) 7-6-5^-3-2-1-0-1-2-3-4-5-6-7-6-5... б) в четных разрядах; в) в нечетных разрядах; г) последовательно увеличивая количество включенных (выключенных) светодиодов до восьми и затем уменьшая до нуля. Отладив программу, загрузите ее в микроконтроллер и проверьте работу. Задание 4. Изменить программу, добавив внешнее прерывание INT1 (сигнал на линии PD3, адрес прерывания 002, бит 7 регистра
56 2. Программирование портов ввода/вывода маски GIMSK или GICR) от кнопки START. Открыв при отладке программы окно памяти данных, проверить работу стека, размещаемого в памяти с адреса S025F. Отлаженную программу загрузить в микроконтроллер и проверить ее работу. Обработка кнопочного регистра с индикацией состояния Ввод данных от кнопок рассмотрим на примере программы 2.3, выполняющей последовательный опрос и индикацию нажатия кнопок SWx (х = 0,1,2,3) кратковременным включением соответствующего светодиода LEDx, а также включением светодиодов LEDx (х = 4, 5, 6, 7) и выключением после повторного нажатия кнопок SWx (х = 4, 5, 6, 7). Обратите внимание на использование в программе макроопределений для проверки состояния кнопок. При каждом нажатии кнопки значение соответствующего бита в слове состояния младшей и старшей групп кнопок (st_L, st_H) меняется на противоположное (командой еог) и сохраняется. Для вывода на светодиоды формируется байт вывода regled. Программа 2.3 .*****★******************************* /Программа 2.3 для обработки нажатий кнопок и индикации их ;состояний .**************************^ .include "8515def.inc" ;файл определений для AT90S8515 /.include "m8515def.inc" /файл определений для ATmega8515 .def temp = г16 /временный регистр .def st_L = г17 /состояние младшей группы SW_0123 .def st_H = rl8 /состояние старшей группы SW_4567 .def sw_cod = r22 /код состояния замкнутой кнопки .def reg_led = г23 /регистр состояния светодиодов .macro testH_sw /макроопределение sbic PIND, @0 /проверка кнопки SWx(х=4,5,6,7) rjmp quit / и установка bid sw_cod, 00 / бита замкнутой кнопки еог st_H,sw_cod /переключение бита состояния mov reg_led,st_H /байт для индикации com reg_led /инвертирование для вывода out PORTB,reg_led / на светодиоды clr reg_led /очистка
2.2. Обработка внешних прерываний 57 clr sw_cod rcall DELAY /задержка wait: sbis PIND, @0 /кнопка отпущена? rjmp wait quit: nop .endmacro testH_sw .macro testL_sw /макроопределение sbic PIND,@0 /проверка кнопки SWx(x=0,1, 2, 3) rjmp quit / и установка bid 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,OxOf / перед гашением out PORTB,reg_led / светодиодов младшей группы quit: nop .endmacro testL_sw .org $000 rjmp init /* * *Инициализация* ** INIT: ldi temp,low(RAMEND) /установка out SPL,temp / указателя стека ldi 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 / T=l input: testL_sw 0 testL_sw 1 testL_sw 2 testL_sw 3
58 2. Программирование портов ввода/вывода testH_sw 4 testH_sw 5 testH_sw б testH_sw 7 rjmp input .**★ задержка * * * DELAY_0: ldi r21,255 dO: dec r21 brne dO ret ;*** Задержка *** DELAY: ldi rl9,10 dl: ldi r20,255 d2: ldi r21,255 d3: dec r21 brne d3 dec r20 brne d2 dec rl9 brne dl ret Задание 5. На основе 2.3 разработать программу «кодового замка», которая после набора 4-разрядного PIN-кода с помощью кнопок SW0 - SW3 и ввода данных, например с помощью кнопки SW5, осуществляет сравнение с паролем и включает светодиод LED7 при правильном вводе. При трех неправильных попытках введения PIN-кода кнопочная клавиатура должна быть заблокирована, а все светодиоды включены. Контрольные вопросы 1. Какова роль подтягивающих резисторов? Каким образом можно подключить и отключить резисторы? 2. Как задается альтернативная функция разряда порта? 3. Какие линии портов микроконтроллера можно использовать для внешних прерываний? Каковы адреса векторов внешних прерываний? Как управлять внешними прерываниями? Какое из них имеет более высокий приоритет? 4. Каким сигналом (логический 0 или логическая 1) можно включить светодиод STK500? Как должен выглядеть бит порта PINx.Y в AVR Studio 4 при замыкании (размыкании) кнопки? 5. Как повысить точность программной задержки?
3. АРИФМЕТИЧЕСКАЯ ОБРАБОТКА ДАННЫХ Цель работы - изучение способов представления числовых данных в микроконтроллерах, алгоритмов арифметических операций, программирование арифметических процедур. 3.1. ПРЕДСТАВЛЕНИЕ ЧИСЕЛ В МИКРОКОНТРОЛЛЕРАХ При обработке числовой информации в микроконтроллерах обычно полагают, что целые числа имеют формат с фиксированной точкой справа - D = dn_ldn_2...dld0, дробные числа меньше 1 имеют формат с точкой слева - D = d_xd_2...d_(n_V}d_n, где п - число разрядов, равное 8 или 16. Обрабатываемые числа могут быть со знаком и без знака. При целочисленном представлении d0 - младший разряд числа с весом 2 , старший разряд dn_\ используется для представления знака (0 - положительный, 1 - отрицательный). Старший цифровой разряд - dn_2 с весом 2п~2. При обработке чисел без знака разряд dn_\ является цифровым с весом 2п \ Дробь без знака имеет старший цифровой разряд d_x с весом 2"1. Для дробных чисел со знаком разряд d_x отводится под знак, старший цифровой разряд в этом случае - d_2 с весом 2"1. Отрицательные числа, как целые, так и дробные, обычно представляют в виде дополнений до основания системы счисления. Для двоичных целых чисел это будет дополнение до 2п, для дробных - дополнение до 2. В общем случае дополнение любого целого «-разрядного числа D до основания Ь системы счисления можно получить путем вычитания D из Ьп. Если D находится в пределах 1 до Ъп -1, то при вычитании получается другое число в тех же пределах. Если D = 0, то результат вычитания равен Ьп и имеет вид 100...О при
60 3. Арифметическая обработка данных общем числе разрядов, равном (и + 1). Отбросив цифру старшего разряда, получим 0. Следовательно, в системе представления чисел дополнением до основания системы счисления существует только одно представление 0. В системе, где отрицательные числа представлены в дополнительном коде, число является положительным, если значение старшего разряда dn_\ = 0, и отрицательным, если dn_\ = 1. Десятичный эквивалент двоичного числа, представленного дополнительным кодом, вычисляется так же, как и для числа без знака, за исключением того, что вес старшего разряда равен -2^ ^. а не +2^ 1\ Представляемые числа находятся в диапазоне от -2 ^ до +2^п ^ - 1. Для дробных чисел дробь положительна, если разряд d_\ = 0, и отрицательна, если d_\ = 1. Диапазон дробных чисел составляет от -1 до +(1 - 2~п). 3.2. СЛОЖЕНИЕ И ВЫЧИТАНИЕ ЧИСЕЛ В ДОПОЛНИТЕЛЬНОМ КОДЕ Графически 8-разрядные двоичные (2-разрядные шестнадцате- ричные) числа со знаком в дополнительном коде показаны на рис. 3.1 позициями (внутри круга указаны десятичные значения, снаружи - их шестнадцатеричные изображения). Сложение с положительным числом N легко интерпретировать, перемещая указатель по ходу часовой стрелки на N позиций; вычитание (-N) - против хода часовой стрелки или перемещая по ходу часовой стрелки на (256-N) позиций, что равносильно замене вычитания сложением с дополнением числа до 28 = 256. Если при сложении (или вычитании) получают результат, который выходит за пределы диапазона чисел (от -128 до +127), фиксируется переполнение. Правило выявления переполнения. При сложении переполнение возникает только в том случае, если слагаемые имеют одинаковые знаки, а знак суммы отличается от знака слагаемых. При вычитании переполнение происходит, если операнды имеют разные знаки, а знак разности отличается от знака уменьшаемого. Правило переполнения можно сформулировать иначе, используя понятие переносов, возникающих при сложении/вычитании. Переполнение OVR возникает, если значения переносов в знаковый разряд р7 и из знакового разряда pg различны (OVR = р§ © Р7). Из анализа рис. ЗА, а следует, что переполнение возникает при сложении, если указатель перейдет границу между позициями +127 и -128.
3.2. Сложение и вычитание чисел в дополнительном коде 61 Числа в дополнительном коде складываются и вычитаются так же, как и числа без знака той же длины. Поэтому при сложении (вычитании) чисел со знаком и без знака необходима одна и та же команда сложения (вычитания). Различие заключается лишь в том, что результаты интерпретируются по-разному в зависимости от того, какими числами оперирует пользователь: числами со знаком (от -128 до +127) или без знака (от 0 до 255). Рис. 3.1. Круговые диаграммы На рис. 3.1, б представлены графически 8-разрядные двоичные (2-разрядные шестнадцатеричные) числа без знака. Видно, что двоичные кодовые комбинации занимают те же позиции, что и на рис. 3.1, а, а сложение и вычитание можно осуществить, перемещая указатель на N позиций в том или ином направлении.
62 3. Арифметическая обработка данных При сложении чисел без знака результат выходит за пределы диапазона представления при пересечении границы между 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 циклов сложения). На практике больше распространены методы умножения путем сложения ряда частичных произведений С = Y^Ab^ где й,- - значение разряда множителя (/ = 0, 1,п - 1). Один из алгоритмов умножения, начиная с младших разрядов множителя, со сдвигом вправо суммы частичных произведений приведен на рис. 3.3.
3.4. Деление челых чисел 63 Рис. 3.2. Схема простейшего алгоритма умножения Рис. 3.3. Схема алгоритма умножения, начиная с младших разрядов множителя Этот алгоритм может быть использован для получения произведения двух двоичных чисел без знака. Количество итераций умножения п определяется числом разрядов множителя. Поскольку в процессе умножения на каждой итерации выполняется сдвиг множителя В на один разряд вправо, на место освобождаемого разряда можно записать выталкиваемый при сдвиге вправо разряд произведения С. Таким образом, 2и-разрядное произведение можно получить, объединив содержимое «-разрядного регистра, в котором формируется старшая часть произведения, и регистра 5, в котором после выполнения умножения окажется младшая часть произведения. 3.4. ДЕЛЕНИЕ ЦЕЛЫХ ЧИСЕЛ Для типичного алгоритма целочисленного деления С = А/В делимым является двойное слово AH:AL (два байта), а делителем - одинарное В (один байт); частное С и остаток получают в виде
64 3. Арифметическая обработка данных одинарных слов. При выполнении деления необходимо исключить возможность деления на 0. Если для представления частного потребуется более одного слова, то фиксируется переполнение. При выполнении деления необходимо проверить условие - делитель должен быть больше старшего слова делимого (В > АН). При делении целых чисел можно использовать алгоритм деления без восстановления остатка и алгоритм с восстановлением остатка. Схема алгоритма деления с восстановлением остатка приведена на рис. 3.4. Алгоритм деления представляет собой итерационную процедуру. На каждой итерации сначала удваивается делимое (на первой итерации) или остаток (на всех последующих) путем сдвига влево на один разряд, затем вычитается делитель и определяется цифра частного по знаку разности. Если разность положительная, определяемая на данной итерации цифра частного с/ = 1, если разность отрицательная, цифра частного с/ = 0. Восстановление остатка выполняется путем сложения делителя с остатком после вычитания на текущей итерации деления. Деление выполняется до получения всех цифр частного. Алгоритм деления без восстановления остатка (рис. 3.5) представляет собой итерационную процедуру, на каждой итерации которой проводится либо вычитание делителя 5, заменяемое сложением с дополнительным кодом [-5]Д0П, либо прибавление В в зависимости от знака остатка, полученного на предыдущей итерации деления. Если полученный остаток больше или равен 0, при очередной итерации деления выполняется вычитание В; если остаток меньше 0 - прибавление В. Перед каждым вычитанием (или сложением) остаток удваивается путем сдвига влево. На начальной итерации деления делимое сдвигается на один разряд влево. Деление чисел со знаком можно выполнить разными способами. Если исходные операнды заданы в прямых кодах, то путем сложения по модулю 2 знаковых разрядов можно определить знак частного. Модули делимого и делителя можно разделить, используя один из вышеописанных алгоритмов. Для определения переполнения необходимо выполнить пробное вычитание А - 2^ В, резервируя один разряд «-разрядного частного для знака. Далее приведен пример деления 16-разрядного числа А на 8-разрядное число В с восстановлением остатка:
3.4. Деление целых чисел Рис. 3.4. Схема алгоритма деления с восстановлением остатка 3 — 1998
66 3. Арифметическая обработка данных А = 1024 = 00000100.00000000, В = 10 = 00001010, -Я = [-10]доп =11110110, С = с7с6с5с4с3с2с1с0 - частное, х - бит, свободно определяемый при сдвиге 00000100.00000000 делимое A(AH.AL) + 11110110 пробное вычитание В 11111010 так как разность меньше 0, переполнения нет 00001000.0000000Х сдвиг А влево + 11110110 вычитание В 11111110 1-й остаток меньше 0, разряд частного с7 = 0 00010000.000000хх сдвиг влево восстановленного АН + 11110110 вычитание В 00000110 2-й остаток больше 0, разряд частного 000011 ОО.ОООООххх сдвиг остатка + 11110110 вычитание В 00000010 3-й остаток, с5 = 1 000001 ОО.ООООхххх сдвиг остатка + 11110110 вычитание В 11111010 4-й остаток, с4= 0 00001000.000ххххх сдвиг восстановленного АН + 11110110 вычитание В 11111110 5-й остаток, с3 = 0 00010000.00хххххх сдвиг восстановленного АН + 11110110 вычитание В 00000110 6-й остаток, с2 = 1 000011 ОО.Оххххххх сдвиг остатка + 11110110 вычитание В 00000010 7-й остаток, с\ = 1 000001 ОО.хххххххх сдвиг остатка + 11110110 вычитание В 11111010 8-й остаток, с0= 0 11111010 + 00001010 прибавление В 00000100 восстановлен остаток АН = 4 С= 01100110 = 102
3.4. Деление целых чисел 67 Рис. 3.5. Схема алгоритма деления без восстановления остатка
68 3. Арифметическая обработка данных Пример деления 16-разрядного числа А на 8-разрядное число В без восстановления остатка: А = 1024 = 00000100.00000000, В=\0 = 00001010, -Я=[-10]до„ =11110110, С = с7с6с5с4с3с2с1с0 - частное, х - бит, свободно определяемый при сдвиге 00000100.00000000 делимое A (AHAL) + 11110110 пробное вычитание В 11111010 так как разность < 0, переполнения нет ООООЮОО.ОООООООх сдвиг влево AH.AL + 11110110 вычитание В 11111110 1-й остаток меньше 0, разряд частного с7 = 0 + ПППОО.ООООООхх сдвиг влево AH.AL 00001010 прибавление В 00000110 2-й остаток больше 0, разряд частного се = 1 000011 ОО.ОООООххх сдвиг влево AHAL + 11110110 вычитание В 00000010 3-й остаток больше 0, с5 = 1 00000 ЮО.ООООхххх сдвиг влево AHAL 11110110 вычитание В 11111010 4-й остаток меньше 0, с4 = 0 111101 ОО.ОООххххх сдвиг влево AHAL + 00001010 прибавление В 11111110 5-й остаток меньше 0, с3 = 0 111111 ОО.ООхххххх сдвиг влево AH.AL 00001010 прибавление В 00000110 6-й остаток больше 0, с2 = 1 000011 ОО.Оххххххх сдвиг влево AH.AL 11110110 вычитание В 00000010 7-й остаток больше 0, с\ = 1 + 00000100.хххххххх сдвиг влево AH.AL 11110110 вычитание В 11111010 8-й остаток меньше 0, со = 0
3.5. Сложение и вычитание двоично-десятичных чисел 69 11111010 + 00001010 прибавление В 00000100 восстановлен остаток АН = 4 С= 01100110 = 102 3.5. СЛОЖЕНИЕ И ВЫЧИТАНИЕ ДВОИЧНО-ДЕСЯТИЧНЫХ ЧИСЕЛ При сложении двух двоично-десятичных чисел А = ап_\ап_2--- ...а\ао и В = bn-ib^-'-bibo поступают следующим образом. Если оба операнда имеют одинаковые знаки, то выполняют сложение модулей этих чисел (\А\ + |2?|), а знаковый разряд суммы определяют по знаку одного из слагаемых. Если операнды имеют разные знаки, то предварительно знак суммы устанавливают по знаку первого операнда А. Затем производят вычитание модулей чисел (\А\ - \В\). Если полученная разность больше нуля, знак суммы сохраняется без изменений. Если разность меньше нуля, следует найти дополнительный код разности и изменить знак суммы на противоположный. При сложении двух чисел АиВ, представленных в 2-10 коде, с весом 8—4-2-1 в каждой тетраде, в одном разряде суммы S = А + В можно получить результаты: 1) Sf < 9; не требует коррекции; 2) 10 < st < 15; требует коррекции путем увеличения S( на шесть с образованием переноса из тетрады; 3) Sf > 15; требует коррекции путем увеличения 5/ на шесть. В этом случае перенос из тетрады образуется автоматически при сложении операндов до выполнения коррекции. В микроконтроллерах с архитектурой MCS-51 коррекция осуществляется аппаратно при выполнении команды 2-10 коррекции. При отсутствии схемы 2-10 коррекции, как в микроконтроллерах AVR, поступают следующим образом. При сложении двоично- десятичных чисел добавляют число, каждый разряд которого равен шести. В этом случае, если вычисляемая поразрядная сумма si < 9, перенос из тетрады не возникнет и избыточное значение шесть подлежит удалению. Во всех остальных случаях добавленное в разряд значение шесть удаляется автоматически с переносом из тетрады в процессе сложения. При таком способе сложения программная реализация упрощается, так как для коррекции результата в тетраде проверяется лишь один признак - наличие или отсутствие переноса из тетрады.
70 3. Арифметическая обработка данных Таким образом, сложение беззнаковых чисел (как и модулей \А | + \В\) можно выполнить по алгоритму, схема которого приведена на рис. 3.6: 1) двоично-десятичный код первого операнда an_xan_2...axa§ складывается с кодом 66...66, образуя первую промежуточную сумму *;_1*я-2--Фо; 2) к полученной сумме прибавляется двоично-десятичный код второго операнда ^_16^_2й160, образуя вторую промежуточную сумму snn_xs'n_2..s\sl\ 3) потетрадно выполняется коррекция результата. Правило коррекции формулируется следующим образом: если в результате второго сложения перенос из /-й тетрады отсутствует (см = 0), то из s" вычитается шесть (или прибавляется 10 = [-6]доп)- При возникновении переноса из /-й тетрады коррекция не выполняется, а полученный результат s" является истинным. При выполнении коррекции перенос из тетрады не должен изменять содержимое следующей тетрады суммы s-+l. Рис. 3.6. Алгоритм сложения 2-10 чисел
3.5. Сложение и вычитание двоично-десятичных чисел 71 При побайтовой обработке длинных операндов в 8-разрядном процессоре микроконтроллера для исключения ошибок коррекцию необходимо выполнять отдельно для каждой тетрады. Пример. А = 50, В = 25. Найти сумму А + В. Двоично-десятичное представление чисел А и В: А = 0101 0000, В = = 0010 0101. Складывая числа 66+А+В, получаем 01100110 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. Вычитание беззнаковых чисел А-В можно выполнить по алгоритму, схема которого представлена на рис. 3.7: 1) выполняют вычитание А-В (складывая А с дополнительным кодом В), образуя первый промежуточный результат R'. Если в результате операции образуется перенос из старшей тетрады (при этом флаг заема равен 0), результат является положительным. При отсутствии переноса (флаг заема равен 1) результат является отрицательным и его следует перевести в дополнительный код 2) коррекция положительного результата осуществляется по правилу, сформулированному для сложения 2-10 чисел. Коррекция отрицательного результата выполняется иначе: если произошел перенос из z'-й тетрады (флаг межтетрадного заема равен 0) при вычитании А - В, то из i-й тетрады R" вычитается шесть. При выполнении коррекции перенос из тетрады не должен изменять содержимое следующей тетрады промежуточного результата.
72 3. Арифметическая обработка данных Рис. 3.7. Алгоритм вычитания 2-10 чисел Пример. А = 23, В = 62. Найти разность^ - В. Двоично-десятичное представление чисел А и В: А = 0010 ООН, В = = 0110 0010. Дополнение числа В: [В]Д0П = 1001 1110. Вычитая А - В = А + [В]доп, получаем R': 0010 0011 + 1001 1110 1100 0001 Переноса нет: результат отрицательный, флаг заема равен 1. Формируем дополнение [Л']доп и выполняем коррекцию: ООП 1111 + 1111 1010 -$06 = $FA ООП 1001 Результат: флаг знака - разность 39. Когда отрицательный результат требуется сохранить в дополнительном коде, шаг формирования дополнения [Л']доп опускается. Можно сразу переходить к коррекции (вычитанию шести в тех тетрадах, где не было переноса) Программный код процедуры 2-10 вычитания однобайтовых операндов для этого случая приведен в программе 3.1.
3.6. Программирование арифметических операций 73 3.6. ПРОГРАММИРОВАНИЕ АРИФМЕТИЧЕСКИХ ОПЕРАЦИЙ Задание 1. Ниже приведена тестовая программа 3.1 для проверки операций сложения и вычитания двоичных и двоично- десятичных однобайтовых чисел в среде AVR Studio 4. Для двоичного сложения/вычитания числа можно задать со знаком и без знака. Двоично-десятичные числа представлены в упакованном формате без знака. Открыв AVR Studio 4, создать проект. Загрузить тестовую программу и, выполняя ее в пошаговом режиме, наблюдать результаты выполнения команд. Выполнить ряд примеров с разными значениями операндов. Чтобы не выполнять повторную компиляцию программы при изменении значений операндов, можно воспользоваться ручной перезагрузкой операндов в регистрах в окне ПО. Для этого необходимо после команд занесения исходных значений операндов щелкнуть кнопкой мыши на соответствующем регистре в окне ПО и занести новое значение. Программа 3.1 .*****************************^ ;Тестовая программа 3.1 сложения и вычитания однобайтовых ;операндов .********************************^ .include "8515def.inc" ;.include "m8515def.inc" .def BCDa =r30 .def BCDb =r31 .def tmpadd =r2 9 .def temp =r28 . org 0 rjmp INIT .**********************************^ ;Подпрограмма сложения 2-10 упакованных беззнаковых чисел ;BCDa и BCDb. Результат возвращается в BCDa, перенос - в ; BCDb .★*********************************** BCDadd: ldi tmpadd,$66 add BCDa,BCDb add BCDa,tmpadd
74 3. Арифметическая обработка данных clr BCDb brcs add_0 rjmp add_l add_0: ldiBCDb,l /установить выходной перенос add_l: brhs add_2 ;если межтетрадный перенос равен О, subi BCDa,$06 ; LSD = LSD - 6 add_2: sbrs BCDb,0 ;если выходной перенос равен О, subi BCDa,$60 ; MSD = MSD - 6 ret .*******★******************************* /Подпрограмма вычитания 2-10 упакованных беззнаковых чисел ;ВСDa и BCDb (BCDa - BCDb). /Результат возвращается в BCDa,знак разности - в BCDb .*******************************^ г BCDsub: sub BCDa,BCDb clr BCDb brcc sub_0 ;если флаг заема равен 1, ldi BCDb,1 ; сохранить его sub_0: brhc sub_l ;если межтетрадный заем равен 1, subi BCDa,$06 ; LSD = LSD - б sub_l: sbrs BCDb,0 /если сохраненный флаг заема равен 0, ret ; выйти, subi BCDa,$60 /иначе вычесть $60 ret .*********************************** /Основная программа .*************************************** INIT: ldi temp,low(RAMEND) Out SPL,temp ldi temp, high(RAMEND) out SPH,temp ;*** Add BIN loop: ldi BCDa,51 ldi BCDb,-79 add BCDa,BCDb /Результат: BCDa=$E4 ;*** Sub BIN ldi BCDa,72 ldi BCDb,28 sub BCDa,BCDb /Результат: BCDa=$2C /*** Add BCD Unsigned
3.6. Программирование арифметических операций 75 ldi BCDa, $51 ldi BCDb,$79 rcall BCDadd /Результат: BCDb:BCDa=$0130 ;*** Sub BCD Unsigned ldi BCDa,$72 ldi BCDb,$28 rcall BCDsub ;Результат: ; ВСОЬ=$00-положительный, BCDa=44 ldi BCDa,$00 ldi BCDb,$90 rcall BCDsub ;Результат: ; ВСОЬ=$01-отрицательный, BCDa=10 rjmp loop Задание 2. Изучить программу 3.2, приведенную ниже для исследования арифметических операций в стартовом наборе STK500. Программой предусмотрен ввод кода операции, 8- и 16-разрядных операндов, выполнение заданной операции и показ результатов. Поскольку в стартовом наборе STK500 всего восемь кнопок общего назначения (SW7-SW0), отсутствие функциональных кнопок вызывает некоторые трудности. Чтобы обеспечить ввод 8-рязряд- ных чисел, поступим следующим образом: кнопки SW0- SW3 будем использовать для ввода битов тетрады, SW4 - для обмена местами младшей и старшей тетрады, SW5 - для записи байтов, SW6 и SW7 - для показа байтов результата. Таким образом, ввод чисел производится побайтно при наличии всего восьми кнопок. Выбор и исполнение арифметической операции происходит по значению кода операции, вводимому первым, согласно табл. 3.1. Программа 3.2 .******★******★*★***★*******★*★******** /Программа 3.2 - эмуляция арифметического устройства ;SW0 - установка/сброс 0-го бита ;SW1 - установка/сброс 1-го бита ;SW2 - установка/сброс 2-го бита Таблица S Код .1. Коды операций операции Операция 1 Сложение 2 Вычитание 3 Умножение чисел без знака 4 Деление чисел без знака
76 3. Арифметическая обработка данных ; SW3 - установка/сброс 3-го бита ;SW4 - обмен местами младшей и старшей тетрад ;SW5 - запись кода операции, двух (а при делении трех) ; байтов операндов и выполнение операции при третьем ; нажатии кнопки (или 4-м при делении) ;SW6 - показ байта суммы или разности, или младшей части ; произведения, или частного при делении ;SW7 - показ байта признаков результата сложения или ; вычитания, или старшего байта произведения, или остатка ; при делении /Соединения шлейфами: порт PB-LED, порт PD-SW .★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★ .include "8515def.inc" ;файл определений для AT90S8515 /.include "m8515def.inc" ;файл определений для ATmega8515 .def temp = г16 /временный регистр .def sw_cod = rl7 ;код состояния замкнутой кнопки .def operand = г18 /операнд .def count = r22 /счетчик ввода .def count_bit = r23 /счетчик циклов умножения / (деления) .def сор = г24 /код операции .def semafor = r25 .def ор_А = rl /операнд А .def ор_В = г2 /операнд В .def ор_АН = г3 /старший байт делимого .def mul_l = г4 /младший байт произведения .def mul_h = г5 /старший байт произведения .def res = гб /частное .def showl = rl9 /1-й выводимый байт результата .def show2 = r20 /2-й выводимый байт .★★★выводы порта PD*** .equ SW_SWAP = 4 /кнопка обмена .equ SW_WR = 5 /кнопка записи операндов .equ SW6 = б /кнопки просмотра результатов .equ SW7 = 7 .macro test_sw sbic PIND, @0 /проверка кнопки SWx(x=0,1,2,3) rjmp quit / и установка bid sw_cod, 00 / бита замкнутой кнопки eor operand, sw_cod /переключение бита com operand /инвертирование для вывода out PORTB,operand / на светодиоды com operand /инвертирование clr sw_cod /очистка кода кнопки rcall DELAY /задержка
3. б. Программирование арифметических операций 11 wait: sbis PIND, 00 rjmp wait quit: nop .endmacro test_sw .macro test_show sbic PIND, 00 /проверка кнопки rjmp quit ; SW6(SW7) com 01 out PORTB, 01 /вывод на светодиоды com @1 rcall DELAY /задержка wait: sbis PIND, 00 rjmp wait quit: nop .endmacro test_show .org $000 rjmp init ;* * *Инициализация* ** INIT: ldi temp,low(RAMEND) /установка out SPL,temp / указателя стека ldi 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 operand /очистка операнда set ;SREG.T=1 ldi semafor,1 ser count /count=0xff - для обхода / подпрограммы oper LOOP: test_sw 0 /опрос кнопок 0,1,2,3 test_sw 1 test_sw 2 test_sw 3 rcall test_SWAP /опрос кнопки обмена тетрадами rcall test_WR /опрос кнопки записи cpi count,0 /условие перехода к / обработке операндов brne SW_SHOW
78 3. Арифметическая обработка данных rcall орег /вызов арифметической / операции ldi semafor,1 ser count SW_SHOW: test_show SW6,showl test_show SW7,show2 rjmp LOOP /Вызываемые подпрограммы ;******модуль арифметических операций OPER: cpi сор, 1 /анализ КОП brne Ь2 ;******Сложение или вычитание 8-разрядных операндов add ор_А,ор_В bO:mov showl,op_A /выводимые значения - сумма in show2,SREG / и признаки из регистра SREG andi show2,0xbf /обнуление флага Т ret Ь2 : cpi сор,2 brne ЬЗ sub ор_А,ор_В rjmp ЬО ЬЗ:cpi сор,3 brne Ь4 ;******Модуль умножения 8-разрядных операндов clr mul_l /очистка младшего байта / произведения clr mul_h /очистка старшего байта / произведения ldi count_bit,8 /счетчик циклов Llrsbrc ор_В,0 /проверка младшего разряда / множителя add mul_h,op_A /прибавление множимого А, / если В0=1 L2:ror mul_h /сдвиг ror mul_l / вправо двух байтов произведени lsr ор_В /сдвиг множителя вправо clc /очистка флага С L3:dec count_bit /уменьшение счётчика циклов brne L1 /если не 0, продолжаем умножение mov showl,mul_l /выводимые значения - младший mov show2,mul_h / и старший байты произведения ret b4:cpi сор,4 brne Ь5 ;******Модуль деления 16-разрядного числа на 8-разрядное
3.6. Программирование арифметических операций 79 DIV: clr res /обнуляем частное ldi count_bit,8 /результат 8-разрядный L4:rol ор_А /сдвиг rol ор_АН / делимого lsl res /сдвиг частного sub ор_АН,ор_В /вычитание делителя brcs recov /если остаток < 0,переход, ldi temp,0x01 /иначе установка or res,temp / разряда частного в 1 rjmp L5 recov: add ор_АН,ор_В / и восстановление остатка L5:dec count_bit brne L4 mov showl,res /выводимые значения - частное mov show2,op_AH / и остаток Ь5:ret ;*** Обмен тетрадами *** test_SWAP: sbic PIND,SW_SWAP /проверка кнопки rjmp quit / SWAP(SW4) swap operand /обмен тетрадами операнда com operand /инвертирование для вывода out PORTB,operand / на светодиоды com operand /инвертирование rcall DELAY /задержка wait: sbis PIND,SW_SWAP rjmp wait quit: nop ret /*** Подпрограмма ввода байта от кнопки с уменьшением / счетчика нажатий после каждой записи test_WR: sbic PIND,SW_WR /проверка кнопки rjmp w_quit / WR(SW5) rcall DELAY /задержка cpi semafor,1 brne w3 /переход для загрузки операндов clr semafor /сброс после 1-го входа mov сор,operand /запись кода операции cpi сор,4 /деление? breq w_div ldi count,3 /если нет, счетчик записи = 3 rjmp clear w_div: ldi count,4 /иначе счетчик записи = 4 rjmp clear
80 3. Арифметическая обработка данных Сложение/вычитание двоичных чисел Задание 3. Выполнить примеры, задавая слагаемые А и В числами без знака, затем со знаком. В последнем случае ввод отрицательных чисел выполнить в дополнительном коде. Последовательность ввода: код операции, слагаемое А, слагаемое В. Нажатие кнопки SW6 показывает результат операции, кнопки SW7 - признаки результата операции, формируемые в регистре SREG. Для отображения признаков результата используют флаги (табл. 3.2). Таблица 3.2. Байт признаков результата № разряда 7 6 5 4 3 2 1 0 Флаг Н S V N Z с Примечание. С - перенос при сложении (заем при вычитании), Z - признак нулевого результата, N - знак результата при операциях с числами со знаком, V - переполнение разрядной сетки, S = N0V - знак результата вне зависимости от переполнения, Н - межтетрадный перенос (заем). w3: cpi count,3 brne w2 /переходы по значению счетчика mov ор_АН,operand /запись первого операнда rjmp clear w2: cpi count,2 brne wl mov op_A,operand /запись первого операнда rjmp clear wl: mov op_B,operand /запись второго операнда clear: dec count clr operand /очистка ser temp /гашение out PORTB,temp / светодиодов wait5:sbis PIND, SW_WR rjmp wait5 w_quit: nop ret /*** Задержка *** DELAY:ldi rl9,10 ldi r20,255 ldi r21,255 dd:dec r21 brne dd dec r20 brne dd dec rl9 brne dd ret
3.6. Программирование арифметических операций 81 Таблица 3.3. Результаты Число А Число В Сумма Л + В Признаки: HSVNZC А без знака >120 50 >Л > 100 А<-Ш -50<Л<0 -100 < Л <-50 100 >В без знака > 50 В> 100 100 < Ж 128 50 < Ж 150 -50 < В < 0 Заполните табл. 3.3 операндов и наблюдаемых результатов в двоичном коде и признаков для десятичных чисел, удовлетворяющих заданным условиям. Объясните результаты машинной арифметики. Задание 4. Выполнить операцию вычитания чисел при заданных условиях (см. табл. 3.3), выполняя ввод отрицательных чисел в дополнительном коде и соблюдая такую последовательность ввода: код операции вычитания, уменьшаемое А, вычитаемое В. Умножение и деление целых чисел Задание 5. Выполнить ряд примеров умножения 8-разрядных двоичных чисел. Нажатие кнопки SW6 показывает младший байт произведения, SW7 - старший байт. Изменить модуль умножения, включив в него формирование нулевого результата, если один из сомножителей равен 0. Задание 6. Выполнить деление чисел с восстановлением остатка при условии, что делитель больше 0 и его значение не вызовет переполнения. Последовательность ввода: - код операции деления, - старший байт делимого с нулевым значением в 7-м разряде, - младший байт, - делитель с нулевым значением в 7-м разряде. Нажатие кнопки SW6 показывает частное, SW7 - остаток. Выполнить ряд примеров на деление двоичных чисел. Задание 7. Изменить программу деления, включив в нее проверку делителя на 0 и на переполнение. Для обоих случаев прекратить деление, индицируя аномальный случай включением-выключением всех светодиодов. Отладить программу с помощью симулятора, предварительно закомментировав ту ее часть, которая осуществляет проверку кнопок, либо скопировав модуль деления в тестовую программу 3.1 и отключив в ней остальные подпрограм-
82 3. Арифметическая обработка данных мы. Проверить работу обновленной подпрограммы деления в STK500. Задание 8. Изменить программу деления, расширив ее для вычисления дополнительных восьми двоичных разрядов частного при делении остатка. Проверить работу программы с помощью симулятора. 3.7. ОПЕРАЦИИ НАД ЧИСЛАМИ С ПЛАВАЮЩЕЙ ТОЧКОЙ Для выполнения арифметических операций над числами с плавающей точкой в микроконтроллерах необходимо разрабатывать довольно сложные подпрограммы. Исходные числа в формате с плавающей точкой представлены знаком, мантиссой и порядком. Мантисса является правильной дробью, разряды которой представляют значащие разряды числа, порядок показывает фактическое положение точки в записи мантиссы. Для представления чисел с плавающей точкой разработан и введен стандарт IEEE-754, включающий базовый одинарный, базовый двойной, расширенный одинарный и расширенный двойной форматы, отличающиеся количеством разрядов и способами представления мантиссы и порядка. На рис. 3.8 приведена структура полей базового 32-разрядного одинарного формата. Формат содержит знаковый разряд S, 8-разрядное поле для смещенного порядка Е и 23-разрядное поле для мантиссы F. Рис 3.8. Базовый одинарный формат В этом формате при изображении порядка используется смещение, равное 127, скрытый бит целой части мантиссы Fo, содержащий 1. Минимальный (Е = 0) и максимальный (Е = 255) порядки зарезервированы для представления специальных чисел. Диапазон ± 38 представления чисел в этом формате составляет ±10 , а точность 6-7 десятичных разрядов. Приведем несколько примеров кодирования чисел в этом формате: 1024=1,0х210 01000100 10000000 00000000 00000000 0x44800000 -663/4= - 1.00001011х26 11000010 10000101 10000000 00000000 0хС2858000 3/16 = 1,1 х2"3 00111110 01000000 00000000 00000000 0хЗЕ400000
3.7. Операции над числами с плавающей точкой 83 В рассмотренных далее алгоритмах для 8-разрядных микроконтроллеров принимается представление истинного нуля нулевым набором (знак, порядок, мантисса). Специальные числовые значения из стандарта (на изображения бесконечности, неопределенности) учитывать не будем. Во всех приводимых программах арифметических операций для микроконтроллеров AVR принято размещение исходных операндов и результатов во второй половине регистров общего назначения (R46...R31). Первый операнд, символически обозначаемый А, размещается в четырех регистрах А: рА (порядок), mAH, mAM, mAL (старший, средний и младший байты мантиссы). Второй операнд, символически обозначаемый В, размещается в регистрах В: рВ (порядок), шВН, шВМ, mBL (мантисса). Результат помещается перед выходом из процедуры в регистры рА, mAH, mAM, mAL. Сложение Процедура сложения чисел с плавающей точкой одного знака включает следующие действия: • определяется разность порядков слагаемых Ар = (рА - рВ). При неравенстве порядков, если разность порядков больше О, сдвигается мантисса числа В вправо до тех пор, пока порядок меньшего числа В не станет равным большему; если разность порядков меньше 0, сдвигается мантисса числа А вправо; • после выравнивания порядков слагаемых при Ар = 0 производится сложение мантисс. В качестве порядка суммы принимается рА или рВ; • проверяется мантисса суммы на возможность нарушения нормализации. При сложении чисел с одинаковыми знаками возможно нарушение нормализации только влево на один разряд. Чтобы получить нормализованную мантиссу, необходимо сдвинуть ее вправо. Порядок увеличивается на единицу, что может привести к переполнению. На рис. 3.9 приведена схема алгоритма сложения чисел А и В с плавающей точкой и одинаковыми знаками. Каждое слагаемое представлено однобайтовым порядком и трехбайтовой мантиссой в стандартном формате: знак числа, 8-разрядный смещенный порядок, 23-разрядная мантисса со скрытой единицей (всего 32 разряда). Число А перед началом операции размещено в регистрах рА, mAH, mAM, mAL, число В - в регистрах рВ, рВН, рВМ, pBL. Результат операции сохраняется на месте первого операнда А.
84 3. Арифметическая обработка данных Рис. 3.9. Схема алгоритма сложения с плавающей точкой
3.7. Операции над числами с плавающей точкой 85 Процедура сложения с плавающей точкой AddF начинается с проверки знаков слагаемых. Если знаки операндов не совпадают, знак второго операнда изменяется на противоположный и выполняется переход к процедуре вычитания чисел SubF. Если исходные операнды имеют один знак, каждый из них проходит проверку на равенство 0. Если один из операндов равен 0, сложение не проводится, а результат принимается равным другому операнду. При этом в случае равенства 0 первого операнда регистры А и В обмениваются операндами. На этом операция заканчивается. Преобразование результата в стандартный формат не проводится. Если оба операнда ненулевые, в однобитовом флаге Т регистра состояния микроконтроллера SREG сохраняется общий знак операндов и выполняется их восстановление из базового формата. Поскольку для этого используется одна и та же процедура гес из библиотеки вспомогательных процедур, настроенная на работу с регистрами А, перед вторым восстановлением проводится обмен операндами. Далее вычитают порядки. При получении отрицательной разности выполняется обмен операндами и вычитание повторяется. При равенстве порядков, когда их разность Ар = 0, выполняется переход к сложению мантисс. В противном случае предварительно разность Ар сравнивается с длиной мантиссы. Если разность превысит 24, то при выравнивании порядков со сдвигом вправо мантиссы меньшего числа она покинет разрядную сетку, происходит потеря значимости. В качестве результата принимается операнд, который в этот момент находится в регистрах первого операнда (рА, тА). Если разность меньше 24, переходим к сдвигу мантиссы меньшего числа, поместив ее в регистры (mAH, mAM, mAL), разность порядков - в регистре рВ, меньший порядок - в регистре рА. Сдвиг мантиссы вправо сопровождается увеличением порядка в регистре рА, уменьшением в регистре рВ и продолжается до тех пор, пока в регистре рВ не получим 0. Сложив побайтно мантиссы, проверяем признак переноса, который свидетельствует о нарушении нормализации. При отсутствии его (С = 0) выполняется переход к преобразованию числа в базовый формат. При С = 1 мантиссу суммы сдвигаем вправо и порядок увеличиваем на 1. Выполняем проверку переполнения. Если образовался порядок, равный 0, это означает превышение максимального порядка 255. Программа завершается с установленным флагом переполнения С. Полученный в регистрах рА, тА результат считается неопределенным и не форматируется. При от-
86 3. Арифметическая обработка данных сутствии переполнения флаг С сбрасывается и выполняется преобразование в базовый формат. Алгоритм сложения чисел с одинаковым знаком представлен листингом программы 3.3. Программа позволяет выполнить алгебраическое сложение чисел с учетом знаков слагаемых. В том случае, когда слагаемые имеют разные знаки, происходит обращение к модулю вычитания. С помощью директивы .include "flsub.asm" подключают программный модуль вычитания чисел с плавающей точкой одинаковых знаков. Это позволяет в дальнейшем выполнить посредством одной и той же программы не только сложение, но и вычитание чисел. В начале общей программы сложения/вычитания выполняют проверку кода выполняемой операции: 1 - для сложения (+), 2 - для вычитания (-). В зависимости от заданной операции и знаков операндов запускают процедуру сложения или вычитания беззнаковых чисел (табл. 3.4). При необходимости производится перемена мест операндов. В итоге можно применить одну из двух процедур: сложение или вычитание модулей чисел. Таблица 3.4. Выполняемые операции Заданная операция 1-й операнд 2-й операнд Выполняемая операция + + А + В А + В + + А -В А- В + -А + В В- А + -А -в -(А + В) - + А + В А-В - + А -В А + В - -А + В -(А + В) - -А - В В-А Программа 3.3 .*********************************^ /Программа 3.3 сложения/вычитания чисел с плавающей точ- ; кой. /Первый операнд находится в регистрах рА, mAH, mAM, mAL, /второй - в регистрах pB,mBH, тВМ, mBL. Результат /возвращается в регистры первого операнда. При переполне- /нии флаг С устанавливается в 1. Вызываемые процедуры
3.7. Операции над числами с плавающей точкой 87 /расположены в файлах flsub.asm (модуль вычитания) и ;fllib.asm (библиотечные модули) .***************★*****★*****★******* .include "8515def.inc" /файл определений для AT90S8515 /.include "m8515def.inc" /файл определений для ATmega8515 .def temp = г16 /временный регистр .def асе = г17 /регистр аккумулятор .def сор = г18 /код операции: / 1 - сложение, 2 - вычитание .def рА = г20 /операнд А (рА - байт порядка), .def mAH = r21 /(mAH, mAM, mAL - байты мантиссы) .def mAM = r22 .def mAL = r23 .def рВ = r24 /операнд В (рВ - байт порядка), .def mBH = r25 /(тВН, тВМ, mBL - байты мантиссы) .def mBM = г2б .def mBL = r27 .org $000 ldi temp, low(RAMEND) /инициализация указателя стека out spl, temp ldi temp, high(RAMEND) out sph, temp cpi cop,0x01 /проверка кода операции breq AddF rjmp SubF /модуль сложения чисел с плавающей точкой / с одинаковым знаком AddF: mov асс,рА еог асс,рВ brpl AddFl ldi temp,0x80 /изменение знака add рВ,temp rjmp SubF AddFl: rcall cp_B_0 /сравнение В с 0 breq Quit rcall cp_A_0 /сравнение А с 0 brne AddF2 rcall swapAB /обмен А и В rjmp Quit AddF2: bst pB, 7 /сохранение знака T=pB.7 rcall rec /восстановление rcall swapAB / чисел через регистры A rcall rec mov acc,pA /вычитание порядков
88 3. Арифметическая обработка данных Типовые процедуры, используемые алгоритмами сложения/вычитания, помещены в библиотеку, подключаемую директивой .include "fllib.asm". Библиотека fllib содержит процедуры восстановления операнда из базового формата гес, упаковки в базовый формат pack, обмен операндов swapAB, сдвига мантиссы вправо на один разряд shift, логического сложения 24-разрядной мантиссы для сравнения с нулем. Восстановление числа из базового формата производится с помощью четырех операций, как показано на рис. 3.10, а. Вначале при помощи логического сдвига влево ф младший бит порядка из регистра старшего байта мантиссы mAH выталкивается на флаг переноса С. Затем выполняется циклический сдвиг влево содержимого регистра порядка рА ©. Благодаря этому 8-разрядный порядок полностью оказывается в регистре рА. Далее мантисса mAH сдвигается вправо © и в разряд 7 регистра mAH восстанавливается скрытая 1 ®. sub асс,рВ brpl AddF3 /переход, если больше 0, rcall swapAB ; иначе обмен и mov асс,рА / снова вычитание sub асс,рВ AddF3: breq AddF6 /переход, если порядки равны cpi асе,24 /сравниваем brmi AddF4 rjmp AddF7 /переход при потере значимости AddF4: mov рА,асе /разность порядков в рА rcall swapAB /разность теперь в рВ AddF5: rcall shift /сдвиг в регистрах тА inc рА /увеличиваем порядок меньшего числа dec рВ /уменьшаем разность порядков brne AddF5 AddF6: add mAL,mBL /сложение мантисс adc mAM,mBM adc mAH,mBH brcc AddF7 /проверка нарушения нормализации inc рА /корректируем порядок breq Quit /выход с флагом переполнения rcall shift /сдвиг мантиссы вправо AddF7: rcall pack /форматирование результата Quit: rjmp Quit .include "flsub.asm" /подключение модуля вычитания .include "fllib.asm" / и библиотечных процедур
3.7. Операции над числами с плавающей точкой 89 Рис. 3.10. Схема восстановления числа из базового формата (а) и преобразования в базовый формат (б) Преобразование результата операции, помещаемого после обработки в регистры А, в базовый формат выполняется по схеме на рис. 3.10, б. Вначале сохраняем порядок рА в одном из регистров, например рВ ф. Затем знак результата, сохраняемый на флаге Т, переносим на флаг С ©. Выполняя сдвиг вправо регистра порядка рА, вводим знак числа в разряд 7 регистра рА ®. Передачу младшего бита порядка в старший разряд мантиссы mAH выполняем за два шага: сначала из разряда 0 регистра рВ в Т ®, затем из Т в разряд 7 регистра mAH © на место старшего разряда мантиссы. Обмен 32-разрядных операндов в регистрах А и В осуществляется с использованием логической функции Исключающее ИЛИ. Действительно, получив сначала А <— А Ф В, выполняем далее В<-В0АиА<-А0В. Эти операции повторяют отдельно для каждого байта порядка и мантиссы (всего 12 операций). Используемые библиотечные процедуры с комментариями представлены в листинге программы 3.4. Программа 3.4 .★★★★★★★★★★*******************^ /Модуль 3.4 библиотечных процедур fllib.asm .★**★★**★**★*★*****★*★**★***★★***** /Восстановление операнда из базового формата rec: lsl mAH /младший разряд порядка в С rol рА /восстановление порядка lsr mAH /сдвиг вправо мантиссы ori mAH, 0x80 /восстановление скрытой 1
90 3. Арифметическая обработка данных Операция начинается с проверки знаков слагаемых (рис. 3.11). Если знаки операндов не совпадают, знак вычитаемого изменяется на противоположный и выполняется переход к процедуре сложения чисел AddF. Если исходные операнды с одним знаком, каждый Вычитание ret /Упаковка в базовый формат pack: mov pb,pa /сохраняем рА clc brtc m2 /проверяем знак sec m2: ror рА /вводим знак в pA.7 bst pb,0 /младший разряд порядка bid mAH,7 / переносим в АН.7 ret /Обмен операндов swapAB: eor рА,рВ /обмен регистров еог рВ,рА / рА и рВ еог рА,рВ / за три операции eor mAL,mBL eor mBL,mAL eor mAL,mBL eor mAM,mBM еог тВМ,тАМ еог тАМ,тВМ еог тАН,тВН еог тВН,тАН еог тАН,тВН ret /Сложение для сравнения А(В) с 0 ср_А_0: mov асс,рА or асе,mAH or асе,mAM or асе,mAL /при А=0 возвращает флаг Z=l ret /при А*0 - Z=0 ср_В_0: mov асс,рВ or acc,mBH or асс,тВМ or acc,mBL /при В=0 возвращает флаг Z=l ret /при В*0 - z=0 /Сдвиг вправо 24-разрядной мантиссы тА shift: lsr mAH ror mAM ror mAL clc ret
3.7. Операции над числами с плавающей точкой 91 Рис. 3.11. Схема алгоритма вычитания с плавающей точкой
92 3. Арифметическая обработка данных проходит проверку на равенство 0. Если один из операндов равен 0, вычитание не проводится, а результат принимается равным другому операнду, при необходимости корректируется знак результата. Если оба операнда не равны 0, в Т сохраняется знак уменьшаемого и восстанавливают оба числа. При этом восстановлению числа В предшествует регистровый обмен А«-»В. Затем выполняют сравнение порядков. Если порядки равны, сравнивают мантиссы, при их равенстве результат операции считается равным 0. Выявляется большее число без учета знака, которое помещается в регистры В. Если при этом выполняется обмен регистров, то хранимый в Т знак меняется на противоположный. Дальнейшие действия связаны с выравниванием порядков и сдвигом вправо мантиссы меньшего числа, которое находится в регистрах А. После выравнивания порядков выполняется вычитание мантисс и формирование результата в регистрах А. При вычитании мантисс с одинаковым знаком может возникнуть нарушение нормализации вправо, т. е. появление одного или нескольких нулей в старших разрядах мантиссы разности. Устранение нарушения нормализации выполняется путем сдвига мантиссы разности влево и уменьшения порядка результата рА на единицу при каждом сдвиге. Если при уменьшении порядка возникнет антипереполнение (при изменении порядка от минимально допустимого значения 0x00 к максимальному значению OxFF), выполняется выход из процедуры с установленным флагом С = 1 и возврат в головной модуль программы с неопределенным результатом. После устранения нарушения нормализации выполняется форматирование результата в регистрах А и выход из процедуры вычитания в основную программу. Программа модуля вычитания, согласно описанному алгоритму, представлена в листинге программы 3.5. В ней, как и в предыдущем случае, использованы стандартные библиотечные процедуры для сдвига мантиссы, обмена операндов, преобразования форматов. Следует отметить, что использование команд с условным переходом, выполняемых по механизму относительной адресации, привело к необходимости выполнения длинных переходов за два шага: сначала на близко расположенную локальную метку QuitS, а затем с помощью команды безусловного перехода rjmp на метку выхода Quit Программа 3.5 .★**************************************** ;Программа 3.5 модуля вычитания чисел с плавающей точкой ;с одинаковым знаком выполняет вычитание из 1-го числа А,
3.7. Операции над числами с плавающей точкой 93 /размещенного в регистрах (рА,тА), 2-го числа, размещенного ;в регистрах (рВ,МВ). /Исходные операнды представлены в базовом формате. /Результат операции возвращается в регистры 1-го числа /(рА,тА) в базовом формате. /Программный модуль размещается в файле flsub.asm и /подключается к основной программе с помощью директивы / .include "flsub.asm" .*****************************^ SubF: mov асс,рА /сравнение знаков чисел еог асс,рВ brpl SubFl ldi temp,0x80 /при неравных знаках смена add pB,temp /знака 2-го числа rjmp AddF SubFl: rcall cp_B_0 /проверка В на О breq Quit rcall ср_А_0 /проверка А на О brne SubF2 rcall swapAB /обмен операндов ldi temp,0x80 add рА,temp / со сменой знака результата QuitS: rjmp Quit SubF2: bst pA, 7 /сохранение знака в T rcall гес /восстановление числа А rcall swapAB /теперь в рА порядок 2-го числа rcall гес /восстановление числа В mov асс,рВ /из порядка 1-го вычитаем sub асс,рА / порядок 2-го brne SubF3 ср mBH,mAH /при равенстве порядков brne SubF3 / сравниваем мантиссы ср mBM,mAM brne SubF3 ср mBL,mAL brne SubF3 clr рА /если числа равны, clr mAH / результат равен О clr maM clr mAL rjmp Quit SubF3: brcc SubF4 /переход, если 1-е число / (оно в рВ,тВ) больше, rcall swapAB / иначе обмен числами brbc 6,s2 / и изменение знака в Т
94 3. Арифметическая обработка данных Следует заметить, что описанные здесь алгоритмы и программы сложения и вычитания не являются полностью оптимальными. Например, восстановленные операнды можно с учетом заданной операции и операндов представить в дополнительных кодах со знаковым разрядом; в дальнейшем проводить операции сложения мантисс в дополнительных кодах, исключив тем самым необходимость перестановки операндов (табл. 3.5). rjmp s3 s2: set rjmp SubF4 s3: clt SubF4: mov acc,pB /снова вычитание порядков sub acc,pA breq SubF7 /переход при одинаковых порядках cpi асе,24 brmi SubF6 rcall swapAB /передача большего числа / в (рА,mA) перед rjmp SubF9 / форматированием результата SubF6: rcall shift /сдвиг мантиссы меньшего числа dec асе / в тА, пока brne SubF6 / разность порядков не равна О /Вычитание мантисс и сохранение разности в тА SubF7: sub mBL,mAL mov mAL,mBL sbc mBM,mAM /вычитание с заемом mov mAM,mBM sbc mBH,mAH /вычитание с заемом mov mAH,mBH mov pA,pB /передача порядка результата в рА SubF8: sbrc mAH,7 /проверка нарушения нормализации rjmp SubF9 /переход, если нарушения нет, dec рА / иначе, не сдвигая мантиссу, cpi pA,0xff / проверяем антипереполнение, sec / заранее установив флаг в 1, breq Quits /при антипереполнении выходим / с флагом 1, иначе lsl mAL / сдвигаем мантиссу тА влево rol тАМ rol тАН clc / и сбрасываем флаг rjmp SubF8 /повторяем проверку SubF9: rcall pack /форматируем результат rjmp Quit /выход из процедуры вычитания
3.7. Операции над числами с плавающей точкой 95 Таблица 3.5. Операции в дополнительных кодах Заданная операция 1-й операнд 2-й операнд Выполняемая операция + + А + В А + В + + А -В А+[В]Д0П + -А + в [А]доп + В + -А -в [А]доп + [В]доп - + А + в А+[В]Д0П - + А -в А + В - -А + в [А]Доп + ВДдоп - -А -в [А]доп + В В рамках практикума не предполагалось получение оптимального кода по времени исполнения и по размеру, а требовалось лишь достижение результативности алгоритмов. Тем не менее предложенные программные решения могут оказаться достаточно эффективными в целом ряде приложений. Умножение Алгоритм умножения чисел с плавающей точкой С = А х В включает следующие действия: • сложение знаков сомножителей по модулю 2 для определения знака произведения; • сложение порядков сомножителей; • перемножение мантисс как чисел с фиксированной точкой; • нормализация и коррекция порядка произведения при получении ненормализованной мантиссы произведения. В процессе сложения порядков может возникнуть как переполнение, так и антипереполнение. При перемножении нормализованных мантисс не может быть нарушения нормализации влево, а нарушение нормализации вправо - только на один бит. При сложении смещенных порядков может возникнуть перенос, что необходимо учитывать при определении порядка произведения. На рис. 3.12 приведена схема алгоритма умножения А на множитель В, начиная с младших разрядов множителя В со сдвигом вправо суммы частичных произведений и множителя. Умножение
96 3. Арифметическая обработка данных Рис. 3.12. Схема алгоритма умножения с плавающей точкой
3.7. Операции над числами с плавающей точкой 97 начинается с проверки сомножителей на 0. Если один из сомножителей равен нулю, результат приравнивают 0 и операция прекращается. Определяется знак произведения, сохраняемый на флаге Т. Далее восстанавливают мантиссы сомножителей. Затем выполняется сложение смещенных порядков. Если при сложении порядков перенос не возник, из полученной суммы вычитается 127, так как в сумме это значение участвовало дважды. При отсутствии заема (флаг С = 0) выполняется переход к умножению мантисс. Наличие заема при вычитании 127 свидетельствует о возникновении антипереполнения. Происходит выход из процедуры умножения с флагом С = 1. Если при сложении порядков возник перенос, эквивалентный потере 256, к сумме добавляют корректирующее значение 129 (-256 + 129 = -127). Отсутствие переноса в этом случае сопровождается перемножением мантисс, наличие переноса свидетельствует о переполнении и прекращении операции. Умножение мантисс выполняется с помощью циклической процедуры из 24 итераций (по числу разряда множителя), включающей сдвиг мантиссы множителя вправо на один разряд, анализ на флаге С очередного бита множителя, прибавление множимого к сумме частичных произведений (если С = 1) или пропуск сложения (если С = 0), сдвиг мантиссы произведения вправо. При умножении мантисс разряды произведения, покидающие при сдвиге вправо разрядную сетку, утрачиваются. После завершения цикла умножения, контролируемого с помощью счетчика, проверяется значение старшего бита мантиссы произведения. При значении mCH.7 = 1 нарушения нормализации нет и выполняется преобразование результата в базовый формат. При mCH.7 = 0 произошло нарушение нормализации вправо. Мантисса сдвигается влево на один разряд, порядок уменьшается на 1 и выполняется проверка на переполнение. Алгоритм умножения представлен листингом программы 3.6. Программа 3.6 ***********************************^ /Программа 3.6 умножения чисел с плавающей точкой .*************************************** .include "8515def.inc" /файл определений для AT90S8515 /.include "m8515def.inc" /файл определений для ATmega8515 .def temp = г16 /временный регистр .def асе = г17 /аккумуляторный регистр .def Cnt = г18 /счетчик циклов .def рА = г20 /определение множимого 4—1998
98 3. Арифметическая обработка данных .def mAH = r21 .def mAM = r22 .def mAL = r23 .def рВ = r24 /определение множителя .def mBH = г25 .def тВМ = г2б .def mBL = r27 .def рС = г28 /определение произведения .def тСН = г2 9 .def тСМ = гЗО .def mCL = r31 .org $000 ldi temp, low(RAMEND) / инициализация указателя стека out spl, temp ldi temp, high(RAMEND) out sph, temp clr рС /очищаем регистры результата 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 асе,7 /сохранение знака в Т rcall гес /восстановление рА и mAH rcall swapAB rcall гес /восстановление рВ и mBH /сложение смещенных порядков mov рС,рВ add рС,рА brcs MulFl subi рС,127 /вычитание лишнего смещения brcc MulF2 rjmp Quit MulFl: ldi temp,129 /если был перенос при сложении add pC,temp / -25б+129=-127 brcs Quit /умножение мантисс (mc=mAxmB) MulF2:ldi Cnt, 24 /инициализируем счётчик циклов MulF3:ror mBH /сдвиг множителя Ror mBM / для анализа младшего бита
3.7. Операции над числами с плавающей точкой 99 Приведем ряд примеров на умножение. В правом столбце сомножители и результат умножения представлены в базовом формате: У2 х 3/2 = 3Л 3F000000 х 3FC00000 = 3F400000 (-64) х (-512) = 32768 С2800000 х С4000000 = 47000000 -256 х 2 = -512 С3800000 х 40000000 = С4000000 Деление При делении чисел с плавающей точкой С = А/В знаки операндов складывают по модулю 2 для определения знака частного, из порядка рА вычитают порядок рВ, мантиссы делят как числа с фиксированной точкой. При делении мантисс нарушение нормализации может возникнуть только влево на один разряд, так как деление нормализованных мантисс при условии тА > тВ дает целую часть частного, равную 1. Для деления нормализованных мантисс при условии тА < тВ нарушения нормализации нет (0,5 < mC < 1). ror mBL brcc MulF4 /если бит множителя равен 1, add mCL,mAL / прибавляем множимое(L-байт), adc mCM,mAM / затем М-байт adc mCH,mAH / и Н-байт MulF4: dec Cnt /уменьшаем счетчик циклов brne MulF5 /если не конец, повторяем rjmp MulF6 MulF5:ror mCH /сдвигаем вправо сумму ror mCM / частичных ror mCL / произведений rjmp MulF3 /проверка нормализации MulF6:brrc MulF7 /результат нормализован ror mCH ror mCM ror mCL inc pC /увеличиваем порядок sec /C=l breq Quit /выход с флагом переполнения MulF7: mov pA,pC /подготовка результата mov mAL,mCL / для форматирования mov mAM,mCM mov mAH,mCH rcall pack /преобразование формата Quit: rjmp Quit /операция завершена .include "fllib.asm" 4*
100 3. Арифметическая обработка данных Схема алгоритма деления чисел приведена на рис. 3.13. Вначале выполняется проверка делимого и делителя на равенство 0. Если делитель равен 0, устанавливается флаг ошибки (как при переполнении). Если делимое равно 0, частное принимается равным 0. Если операнды ненулевые, осуществляется преобразование формата каждого операнда и размещение их в прежних регистрах. После вычитания смещенных порядков смещение разности утрачивается, поэтому необходимо полученную разность порядков увеличить на значение смещения 127. При возникновении переполнения (антипереполнения) выполняется выход с установленным флагом. Далее следует циклическая процедура деления мантисс методом, известным как деление с восстановлением остатка. Особенностью деления является то, что перед вычитанием из мантиссы делимого (в дальнейшем остатка) она сохраняется в стеке. Это позволяет при получении отрицательной разности выполнить восстановление путем выборки из стека сохраненного значения. После завершения цикла деления проводится нормализация частного. В отличие от целочисленного деления, которое не допускает переполнения, деление с плавающей точкой позволяет получить результат (если мантисса тА > тВ), сдвинув мантиссу частного и увеличив порядок на 1. Особенностью программной реализации описываемого алгоритма деления является то, что уже после первого вычитания значение бита частного поступает в младший разряд регистра частного. По окончании цикла этот бит окажется на позиции старшего разряда. Если он равен 1, это говорит о том, что шА > > тВ и сдвиг мантиссы проводить не надо. Частное пересылается на место делимого, и форматируется результат операции. Если старший бит мантиссы тС окажется равным 0 (тА < тВ), для получения нормализованной мантиссы частного необходимо сдвинуть ее влево на один разряд и уменьшить порядок на 1. При возникновении заема фиксируется антипереполнение. Деление чисел с плавающей точкой представлено листингом программы 3.7. Программа 3.7 ;Программа 3.7 деления чисел А/В с плавающей точкой .★★★★★★★★★★★★★★★★★★★^ .include "8515def.inc" ;файл определений для АТ9098515 /.include "m8515def.inc" /файл определений для Atmega 8515 .def temp = г16 /временный регистр
3.7. Операции над числами с плавающей точкой 101 Рис. 3.13. Схема алгоритма деления с плавающей точкой
102 3. Арифметическая обработка данных .def асе = г17 /аккумуляторный регистр .def Cnt = г18 /счетчик циклов .def рА = г20 /определение делимого .def mAH = r21 .def mAM = r22 .def mAL = r23 .def рВ = r2 4 /определение делителя .def mBH = г25 .def тВМ = г2б .def mBL = r27 .def рС = г28 /определение частного .def mCH = r2 9 .def mCM = гЗО .def mCL = r31 .org $000 ldi temp, low(RAMEND)/инициализация указателя стека out spl, temp ldi temp, high(RAMEND) out sph, temp clr рС /очищаем регистры частного clr mCL clr mCM clr mCH rcall cp_B_0 /проверка делителя В на 0 brne m0 sec breq Quit /выход с флагом ошибки деления m0: rcall ср_А_0 /проверка делимого А на 0 breq Quit mov асс,рА /получение знака частного еог асс,рВ bst асе,7 /сохранение знака в Т rcall rec /восстановление рА и mAH rcall swapAB rcall rec /восстановление рВ и mBH rcall swapAB /оставляем их в своих регистрах /Вычитание смещенных порядков mov рС,рА sub рС,рВ brcc DivFl ldi temp,127 /при заеме
3.7. Операции над числами с плавающей точкой 103 add рС, temp brcs DivF2 ; и отсутствии переноса sec rjmp Quit DivFl: ldi temp,127 ;при отсутствии заема add рС, temp brcs Quit ; и наличии переноса ; Деление мантисс (mc=mA/mB) DivF2: ldi Cnt,24 /инициализируем счетчик циклов DivF3: push mAL ;сохраняем делимое mA push mAM ; (остаток) в стеке push mAH sub mAL,mBL sbc mAM,mBM sbc mAH,mBH brcc DivF4 pop mAH /возвращаем остаток pop mAM ;"из стека, т.к. mA<mB pop mAL clc ;бит частного равен 0 rjmp DivF5 DivF4: sec ;бит частного равен 1 DivF5: rol mCL ; сдвиг частного влево rol mCM rol mCH clc rol mAL ;сдвиг делимого влево rol mAM rol mAH dec Cnt /уменьшаем счетчик циклов brne DivF3 ;повторяем, пока Cnt#0 ;Проверка нормализации sbrc mCH, 7 rjmp DivF6 /результат нормализован rol mCL ;сдвигаем rol mCM ; мантиссу частного rol mCH ; влево dec рС /уменьшаем порядок частного cpi pc,0xFF sec ;C=1 breq Quit ;выход с флагом антипереполнения
104 3. Арифметическая обработка данных Задание 1. Открыв AVR Studio 4, создать проект. Загрузить программу 3.3 для проверки операций сложения и вычитания чисел с плавающей точкой. Привести ряд примеров с разными значениями операндов, воспользовавшись ручной загрузкой операндов в регистры окна I/O. Подобрать операнды с равными и максимально различающимися порядками. Выполнить операции, фиксируя время их исполнения. Задание 2. Создать проект и загрузить программу 3.6 для умножения чисел с плавающей точкой. Привести ряд примеров с разными значениями операндов. Оценить время выполнения операции умножения. Заменить программу умножения программой деления 3.7 и проверить ее работу. Задания для самостоятельного программирования 1. Изменить модуль эмуляции арифметического устройства базовой программы, включив в него дополнительно одну из логических и(или) арифметических операций. 2. Для микроконтроллера ATmega8515 проверить работу операций умножения по их описанию, открыв файл помощи по AVR Ассемблеру, используя команды меню: Help/A VR Tools User Guide. В окне Html Help щелчком открыть A VR Assembler, выбрать Parts и затем ATmega8515. Подробное описание каждой из команд умножения можно найти в разделе A VR Assembler/Instructions. Практическая часть DivF6: mov рА,рС /подготовка результата mov mAL,mCL ; для форматирования mov mAM,mCM mov mAH,mCH DivF7: rcall pack /преобразование формата Quit: rjmp Quit /операция завершена .include "fllib.asm" Приведем ряд примеров на деление. В правом столбце операнды и частное представлены в базовом формате: % : У2 = 3/2 3F400000 / 3F000000 = 3FC00000 32768 : (-512) = - 64 47000000 / С4000000 = С2800000 -512:2 = -256 С4000000 / 40000000 = С3800000
3.7. Операции над числами с плавающей точкой 105 3. Рассмотреть операцию умножения дробных чисел на примерах. Проверить результаты с помощью симулятора AVR Studio 4. 4. Написать процедуру сложения (вычитания) 2-байтовых операндов для проверки с помощью STK500. Сформировать признаки результата, как признаки 2-байтовой суммы (разности). 5. Написать макрос для двоично-десятичной коррекции при сложении, равноценный команде DA А в системе команд микроконтроллеров MCS-51. 6. Написать процедуру сложения (вычитания) двух 4-байтовых упакованных двоично-десятичных чисел. Контрольные вопросы 1. Какой бит в регистре SREG определяет флаг заема? Каким значением флага определяется переполнение при вычитании чисел со знаком и без знака? 2. При каком минимальном значении делимого возникает переполнение, если делитель равен 10? 3. Для каких 2-10 чисел (упакованных или распакованных) действительны приведенные программы 2-10 арифметики? Какие изменения следует внести в программные процедуры при изменении формата представления чисел? 4. Рассчитать диапазон чисел в зависимости от количества разрядов порядка для случаев п = 8, п = 11, где п - число разрядов. Написать формулу для расчета количества требуемых разрядов порядка при заданном числовом диапазоне. 5. Проанализировать точность результатов арифметических операций, используя бытовой и научный электронные калькуляторы. Дать рекомендации по выбору числового формата для программы электронного калькулятора на основе 8-разрядного микроконтроллера. 6. Объяснить, в каких случаях возникают переполнения (антипереполнения) при выполнении операций с плавающей точкой. Привести примеры. 8. Изменить программы для обработки чисел с плавающей точкой: а) с усеченным форматом мантиссы (16 разрядов); б) с усеченным порядком в зависимости от выбранного диапазона обрабатываемых чисел.
106 3. Арифметическая обработка данных 9. Нарисовать схему алгоритма алгебраического сложения-вычитания чисел с плавающей точкой в дополнительных кодах. Дать оценку сложности разработанного алгоритма путем сравнения с описанным. Написать программу и проверить ее работу с помощью отладчика.
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
108 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 и маски прерываний TEMSK. Счетчик TCNT0 доступен в любой момент времени как для чтения, так и для записи. При записи в счетчик TCNT0 во время его работы счет будет продолжен в следующем за командой записи машинном цикле. После подачи напряжения питания счетчик TCNT0 принимает нулевое состояние. При переходе таймера/счетчика TCNT0 из состояния $FF в состояние $00 устанавливается в 1 флаг TOV0 в регистре TIFR и генерируется запрос на прерывание. Разрешение прерывания осуществляется установкой в 1 разряда TOIE0 регистра маски TIMSK. Флаг общего разрешения прерывания I регистра SREG микроконтроллера также должен быть установлен в 1.
4.1. Таймер/счетчик ТО микроконтроллера A T90S8515 109 Рис. 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
110 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 111 рация сигнала ШИМа вынесена в отдельный режим работы таймера/счетчика, в котором недоступны остальные функции (кроме генерации прерываний). В дальнейшем режим генерации сигнала ШИМа будем называть режимом ШИМа, а режим, в котором доступны остальные функции таймера/счетчика, - режимом таймера. Структурная схема таймера/счетчика Т1 приведена на рис. 4.2. В состав таймера/счетчика входят базовый 16-разрядный счетчик TCNT1, три 16-разрядных регистра (регистр захвата ICR 1 и два Рис. 4.2. Структурная схема таймера/счетчика Т1 регистра сравнения OCR1A и OCR1B), два 16-разрядных компаратора (схемы сравнения), два 8-разрядных управляющих регистра TCCR1А и TCCR1B, а также блок управления таймером. Все флаги состояния таймера/счетчика (переполнения, совпадения и захвата) находятся в регистре флагов прерываний от таймеров TIFR, а разрешение (запрещение) прерываний от таймера
112 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. Таймер/счетчик Tl микроконтроллеров АТх8515 113 Таблица 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. При переходе таймера/счетчика из состояния SFFFF в состояние $0000 устанавливается флаг ТОVI регистра TIFR и генерируется запрос на прерывание. Разрешение прерывания осуществляется установкой в 1 разряда TOIE1 (бит 7) регистра маски TIMSK (разумеется, флаг общего разрешения прерываний I регистра SREG также должен быть установлен в 1).
114 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. Если этот разряд сброшен в О, то активным является спадающий фронт. Если же этот разряд установлен в 1, то активным является нарастающий фронт. Физически регистр захвата ICR1 размещен в двух регистрах ICR1HTCR1L, доступных только для чтения. Поскольку регистр захвата является 16-разрядным, при его чтении, как уже было сказано, используется специальный регистр TEMP. При чтении регистра ICR1L (младший байт) его содержимое посылается в процессорное устройство, а содержимое регистра ICR1H (старший байт) сохраняется в регистре TEMP. При чтении регистра ICR1H возвращается значение, сохраненное в регистре TEMP. Следовательно, при чтении регистра ICR1 первым должен быть прочитан регистр ICR1L. Прерывания на время обращения к регистру ICR1 должны быть запрещены.
4.2. Таймер/счетчик Tl микроконтроллеров АТх8515 115 Функция сравнения (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. Управление выводом OClx (х = А, В) COMlxl СОМ 1x0 Описание 0 0 Таймер/счетчик Т1 отключен от вывода OClx 0 1 Состояние вывода меняется на противоположное 1 0 Вывод сбрасывается в 0 1 1 Вывод устанавливается в 1
116 4. Таймеры микроконтроллеров АТх8515 Если разряд СТС1 регистра управления TCCR1B установлен в 1, то при совпадении содержимого счетчика TCNT1 и регистра сравнения OCR1A производится сброс таймера/счетчика в нулевое состояние. Каждый регистр сравнения физически размещается в двух регистрах ввода/вывода: OCR1A - OCRlAHrOCRlAL; OCR IB - 0CR1BH:0CR1BL. Поскольку регистры сравнения являются 16-разрядными, при их чтении и записи используется специальный регистр TEMP. Процесс записи и чтения 16-разрядных регистров выполняется так же, как и регистра TCNT1. Прерывания на время обращения к регистрам сравнения OCR1А и OCR1B должны быть запрещены. Режим ШИМа (PWM) Широтно-импульсная модуляция является одним из видов непрерывной импульсной модуляции, при которой ширина импульса пропорциональна значению модулирующего сигнала. Соответственно в данном случае широтно-импульсная модуляция заключается в генерировании сигнала с программируемой частотой и скважностью. Для перевода таймера/счетчика Т1 в режим ШИМа и задания частоты ШИМ-сигнала используют разряды PWM11:PWM10 регистра управления таймером TCCR1A. Соответствие между состоянием этих разрядов и режимом работы таймера/счетчика Т1 приведено в табл. 4.7. Таблица 4.7. Управление режимом ШИМа таймера/счетчика Т1 PWM11 PWM10 Описание 0 0 Режим ШИМа таймера/счетчика выключен 0 1 8-разрядный ШИМ 1 0 9-разрядный ШИМ 1 1 10-разрядный ШИМ Для генерации ШИМ-сигнала используется схема сравнения таймера/счетчика, поэтому в микроконтроллерах АТх8515 модулятор является сдвоенным (два регистра сравнения). Названия регистров сравнения и правила обращения к ним были описаны ранее. Сигнал снимается с выхода схемы сравнения таймера/счетчика.
4.2. Таймер/счетчик Tl микроконтроллеров ЛТх8515 117 В рассматриваемом режиме счетчик TCNT1 функционирует как реверсивный, модуль счета которого (ТОР) зависит от режима работы модулятора. Частота ШИМ-сигнала зависит от частоты тактового сигнала fjcK\ таймера/счетчика Т1 и модуля счета ШИМа. Значение модуля счета и частота ШИМ-сигнала для каждого режима работы модулятора приведены в табл. 4.8. Таблица 4.8. Режимы ШИМа Режим модулятора Модуль счета (ТОР) Частота ШИМ-сигнала 8-разрядный 255 /гол/510 9-разрядный 511 /га,/1022 10-разрядный 1023 /га,/2046 При работе таймера/счетчика Т1 в режиме ШИМа состояние счетчика меняется от 0 до значения ТОР, а затем снова до 0, после чего цикл повторяется. При равенстве состояния счетчика и содержимого регистра сравнения состояние соответствующего этому регистру вывода микроконтроллера изменяется согласно табл. 4.9 (х обозначает А или В). Таким образом, длительность ШИМ- сигнала равна 2п1/тски где п ~ содержимое регистра сравнения. Таблица 4.9. Поведение выходов схемы сравнения в режиме ШИМа COMlxl СОМ 1x0 Поведение вывода OClx 0 0 Таймер/счетчик Т1 отключен от вывода 0 1 Таймер/счетчик Т1 отключен от вывода 1 0 Сбрасывается в 0 при прямом счете и устанавливается в 1 при обратном (неинвертирован- ный ШИМ-сигнал) 1 1 Устанавливается в 1 при прямом счете и сбрасывается в 0 при обратном (инвертированный ШИМ-сигнал) Соответственно если в регистр сравнения записать значение 0 или ТОР, то при следующем совпадении состояния счетчика и содержимого регистра сравнения выход схемы сравнения переключится в устойчивое состояние согласно табл. 4.10 (х = А или В).
118 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 при изменении счетчиком направления счета: флаг ТОVI - в точке 0, а флаги OCF1A (для регистра OCR1A) и OCF1B (для регистра OCR1B) - в точке ТОР. Разрешение и обработка соответствующих прерываний выполняются как обычно. 4.3. ПРОГРАММИРОВАНИЕ ТАЙМЕРА ТО Режим счетчика Подготовить программу для исследования таймера/счетчика ТО в режиме счетчика событий. Событием в данном случае может быть замыкание одной из кнопок SWx на плате STK500. Результат работы программы отобразить средствами индикации. С помощью 10-проводного шлейфа подключим выводы порта РВ к выводам кнопок SW0-SW7 (в данном случае будет использован только вывод РВО - вход внешнего сигнала таймера ТО). С помощью второго 10-проводного шлейфа соединяем выводы порта PD с выводами светодиодов LED0-LED7. Программируем вывод РВО на ввод, все выводы порта PD - на вывод. Настраиваем тай-
4.3. Программирование таймера ТО 119 мер на режим счета внешних событий (нажатие кнопки SW0). После нескольких, например четырех, нажатий должно произойти переполнение таймера (следовательно, начальное значение счетчика TCNT0 - $FC) и вызов обработчика прерываний. Обработчик должен включить светодиоды, показывая, что программа выполнена корректно, и заново инициализировать счетчик таймера для продолжения работы, если планируется неоднократное повторение программы. Время включения светодиодов установим, используя подпрограмму задержки. Программа 4.1 .***************************★******* /Программа 4.1 для МК АТх8515: /демонстрация работы таймера ТО в режиме счетчика событий; ;событие - нажатие кнопки SW0. /Светодиоды включаются после четвертого нажатия на кнопку ;SW0. Соединения шлейфами: порт PB-SW, порт PD-LED •*****************************^ /.include "8515def.inc" /файл определений AT90S8515 .include "m8515def.inc" /файл определений ATmega8515 .def temp = rl6 /временный регистр /***Таблица векторов прерываний .org $000 rjmp INIT /обработка сброса .org $007 rjmp T0_OVF /обработка переполнения таймера / ** инициализация МК INIT: ldi temp,low(RAMEND) /установка out SPL,tem / указателя стека ldi temp,high(RAMEND) / на последнюю out SPH,temp / ячейку ОЗУ clr temp /инициализация порта РВ out DDRB, temp / на ввод ldi temp,0x01 /включение out PORTB,temp / подтягивающего резистора PB0 ser temp /инициализация порта PD out DDRD,temp / на вывод out PORTD,temp /выключение светодиодов ldi temp,0x20 ;SE=1 - разрешение перехода out MCUCR, temp / в режим Idle /***Настройка таймера TO на режим счетчика событий ldi temp,0x02 /разрешение прерывания по out TIMSK, temp / переполнению таймера ldi temp,0x07 /переключение таймера
120 4. Таймеры микроконтроллеров АТх8515 Результат работы программы будет таков. При четвертом нажатии на кнопку SW0 загораются все светодиоды (в случае дребезга контактов светодиоды могут включиться раньше). Длительность времени, в течение которого они горят, определяется задержкой DELAY. Далее действия могут быть повторены. Как уже было сказано в теоретической части, события для таймера/счетчика ТО можно генерировать программно. Для этого необходимо настроить вывод РВО как выход. В данном случае инкремент счетчика будет происходить после выполнения команд программы, эмулирующих положительный или отрицательный фронт, как этого требует настройка таймера: /положительный фронт сигнала на РВО cbi PORTB, 0 out TCCR0,temp ; по положительному фронту sei ;разрешение прерываний ldi temp,0xFC ;$FC=-04 для out TCNT0,temp ; отсчета четырех нажатий LOOP: sleep ;переход в режим пониженного пор ; энергопотребления rjmp LOOP .***обработка прерывания при переполнении таймера ТО T0_OVF: clr temp out PORTD,temp ;включение светодиодов rcall DELAY /задержка ser temp out PORTD,temp /выключение светодиодов ldi temp,0xFC ;$FC=-04 для out TCNT0,temp ; отсчета четырех нажатий reti ;*** Задержка *** DELAY: idi rl9,10 ldi r20,255 ldi r21,255 dd:dec r21 brne dd dec r20 brne dd dec rl9 brne dd ret
4.3. Программирование таймера ТО 121 sbi PORTB,О /отрицательный фронт сигнала на РВО sbi PORTB,О cbi PORTB, О Режим таймера Подготовить программу для исследования таймера/счетчика ТО в режиме таймера. Для наглядности работы таймера в этом режиме можно запрограммировать следующие действия: при нажатии на первую кнопку на вход таймера поступают сигналы с частотой, равной частоте тактового генератора СК, при нажатии на вторую кнопку на вход таймера поступают сигналы с частотой, например, СК/8. В обоих случаях сразу после нажатия загораются светодиоды, а после переполнения таймера и обработки соответствующего прерывания светодиоды гаснут. Таким образом, во втором случае время свечения светодиодов будет в восемь раз больше, чем в первом, что и означает правильность выполнения программы. Если установить частоту тактового генератора микроконтроллера равной 512 Гц, то время включения светодиодов в первом случае 0,5 с, во втором - 4с (0,5-8). (Внимание! Частоту тактового генератора необходимо изменять после программирования микроконтроллера.) На плате 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 .★★****************************^ /.include "8515def.inc" /файл определений AT90S8515 .include "m8515def.inc" /файл определений ATmega8515 .def temp = rl6 /временный регистр
122 4. Таймеры микроконтроллеров АТх8515 .equ SW2 =2 /2-й вывод порта PD .equ SW3 = 3 ;3-й вывод порта PD ;***Таблица векторов прерываний .org $000 rjmp INIT /обработка сброса .org $007 rjmp T0_OVF /обработка переполнения таймера ТО . ★ ★ ★Инициализация МК INIT: ldi temp,low(RAMEND) /установка out SPL,temp / указателя стека ldi temp,high(RAMEND) / на последнюю out SPH,temp / ячейку ОЗУ clr temp /инициализация порта PD out DDRD,temp / на ввод ldi temp,0x0C /включение подтягивающих out PORTD,temp / резисторов порта PD ser temp /инициализация порта РВ out DDRB,temp / на вывод out PORTB,temp /выключение светодиодов /***Настройка таймера ТО на режим таймера ldi temp,0x02 /разрешение прерывания по out TIMSK,temp / переполнению таймера ТО clr temp /таймер ТО out TCCR0,temp / остановлен sei / разрешение прерываний clr temp /отсчёт out TCNT0,temp / начинается с 0 .★★★Ожидание нажатия кнопок WAITSET_0: sbic PIND,SW2 /проверка нажатия rjmp WAITSET_1 / кнопки SW2 ;★★★Обработка нажатия кнопки SW2 ldi temp,0x01 /частота тактовых сигналов- СК rcall LED_ON /включение светодиодов WAITSET_1: sbic PIND,SW3 /проверка нажатия rjmp WAITSET_0 / кнопки SW3 .★★★Обработка нажатия кнопки SW3 ldi temp,0x02 /частота сигналов - СК/8 rcall LED_ON /включение светодиодов rjmp WAITSET_0 .★★★Обработка прерывания при переполнении таймера ТО
4.4. Программирование функций таймера Т1 123 Результат работы программы: нажатие кнопки 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. Возможность останова таймера во время счета реализуется с помощью внешнего T0__OVF: ser temp out PORTB,temp /выключение светодиодов clr temp /останов out TCCR0,temp / таймера TO clr temp out TCNT0,temp /установка 0 reti ;***Включение светодиодов LED_ON:out TCCR0,temp /настройка источника / тактового сигнала clr temp /включение out PORTB,temp / светодиодов ret
124 4. Таймеры микроконтроллеров АТх8515 Рис. 4.3. Временные диаграммы работы таймера/счетчика Т1 при исследовании функции сравнения прерывания от кнопки STOP (SWT). При записи значений в регистры сравнения необходимо соблюдать установленный порядок: сначала записывается старший байт, затем - младший. Для наблюдения изменений состояний выводов ОС1А и ОС1В их необходимо соединить с выводами светодиодов. Коммутация осуществляется двухпроводными шнурами: LED0 - РЕ2, LED1 - PD5, SW0 - PDO, SW1 - PD2. Частота тактового генератора устанавливается равной 256 Гц. Программа 4.3. .***************************************** /Программа 4.3 для МК АТх8515: демонстрация работы функции /сравнения таймера Т1.Для наглядности необходимо выставить /частоту тактового генератора СК=256 Гц.При нажатии на SW0 /(START) происходит инкремент счетчика с частотой СК, при /нажатии на SW1 (STOP) счетчик останавливается. /При совпадении содержимого счетчика и регистра сравнения /0CR1B происходит переключение светодиода LED0, счетчика и /регистра сравнения OCR1A - LED1. ;Соединения: LED0-PE2, LED1-PD5, SWO-PDO, SW1-PD2 .**********************************^ /.include "8515def.inc" /файл определений AT90S8515 .include "m8515def.inc" /файл определений ATmega8515 .def temp = rl6 /временный регистр
4.4. Программирование функций таймера Т1 125 .equ START = 0 /О-й разряд порта PD .org $000 rjmp INIT /обработка сброса .org $002 rjmp STOP_PRESSED /обработка внешнего прерывания / INTO при нажатии STOP / ** инициализация МК INIT: ldi temp,low(RAMEND) /установка out SPL,temp / указателя стека ldi temp,high(RAMEND) / на последнюю out SPH,temp / ячейку ОЗУ ldi temp,0x20 /инициализация выводов порта PD: out DDRD,temp / 0,2 - на ввод, 5 - на вывод ldi temp,0x05 /включение подтягивающих out PORTD,temp / резисторов и выключение СД ldi temp,0x04 //// для ATmega8515 //// инициализация вывода порта out DDRE, temp ;/// РЕ2 (ОС1В) на вывод ldi temp,0x40 /разрешение прерывания INTO out GICR,temp / в регистре GICR (или GIMSK) clr temp /обработка прерывания INTO out MCUCR, temp / по низкому уровню /***Настройка функции сравнения таймера Т1 ldi temp,0x00 /запрещение прерываний out TIMSK,temp / от таймера cli /запрещение прерываний ldi temp,0x50 /при равенстве / состояния выводов ОС1А и ОС1В out TCCR1A, temp / изменяются на противоположные ldi temp,0x00 /таймер out TCCRlB,temp / остановлен ldi temp,0x00 /запись числа в out OCRlBH,temp / регистр сравнения, ldi temp, 0x80 / первым записывается out OCRlBL,temp / старший байт ldi temp,0x00 /запись числа в out OCRlAH,temp ; регистр сравнения, ldi temp,0xFF / первым записывается out OCRlAL,temp / старший байт clr temp /обнуление out TCNTlH,temp / содержимого out TCNTlL,temp ; счетного регистра sei / разрешение прерываний
126 4. Таймеры микроконтроллеров АТх8515 Результат работы программы соответствует диаграммам на рис. 4.3. При нажатии на кнопку SW0 светодиоды работают в такой последовательности: оба светодиода погашены, далее включается LED0, затем LED1, выключается LED0, затем LED1 и т. д. В любой момент процесс можно остановить нажатием кнопки SW1. Функция захвата Подготовить программу для исследования функции захвата таймера/счетчика Т1. Захват должен происходить при нажатии соответствующей кнопки. По событию захват должен вызываться обработчик прерывания, который переписывает содержимое 16-разрядного регистра захвата ICR1 в регистры для хранения младшего и старшего байта, так как пересылка данных в порт для индикации возможна только из регистров общего назначения. Вывод каждого байта может быть связан с нажатием отдельной кнопки. С помощью регистра сравнения OCR1A можно задать максимальное значение, которое получим в счетчике и, следовательно, в регистре захвата. Необходимо настроить работу таймера так, чтобы он обнулялся при равенстве значений счетчика TCNT1 и регистра сравнения, установив бит СТС1 регистра TCCR1B в 1. Это можно использовать как дополнительный признак правильности работы программы. Так, например, если содержимое OCR1A рав- WAITSTART: sbic PIND,START /ожидание нажатия rjmp WAITSTART /кнопки START ldi temp,0x09 /запуск таймера, при out TCCRlB,temp / совпадении с OCR1A - сброс LOOP: nop /во время цикла происходит rjmp LOOP / увеличение содержимого / счетного регистра /***Обработка прерывания от кнопки STOP STOP_PRESSED: ldi temp,0x08 /остановка out TCCRlB,temp / таймера WAITSTART_2: /ожидание sbic PIND,START / нажатия rjmp WAITSTART_2 / кнопки START ldi temp,0x09 /запуск out TCCRlB,temp / таймера reti
4.4. Программирование функций таймера Т1 127 но $00FF, а бит СТС1 установлен в 1, то в старшем байте регистра захвата всегда будет 0. При моделировании функции захвата в AVR Studio 4 необходимо помнить, что вывод ICP в микроконтроллереАТ9088515 является выделенным, а в микроконтроллере ATmega8515 - это линия порта ввода/вывода РЕО. Вызов обработчика прерывания по событию захват можно осуществить, установив в 1 флаг TICIE1 регистра маски TIMSK и флаг ICF1 регистра запросов TIFR. Коммутация кнопок с выводами микроконтроллера осуществляется двухпроводными шнурами: SW0 - PDO, SW1 - PD1, SW2 - PD2, SW3 - РЕО. Светодиоды подключают к выводам порта РВ 10-проводным шлейфом. Программа 4.4 .*★★★***★★*★★***★**★***★*★*★** /Программа 4.4 для МК АТх8515: демонстрация работы функции /захвата таймера Т1. Для наблюдения необходимо установить /частоту тактового генератора СК=25б Гц. /При нажатии на SWO (START) на вход счетчика поступает /сигнал с частотой СК, при нажатии на SW3 (CAPT) /происходит захват состояния таймера. /При совпадении содержимого счетчика и регистра сравнения /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 = г18 /для хранения младшего байта .equ START = 0 /0-й вывод порта PD .equ SHOW_L = 1 /1-й вывод порта PD .equ SHOW_H = 2 /2-й вывод порта PD /***Векторы прерываний .org $000 rjmp INIT /обработка сброса .org $003
128 4. Таймеры микроконтроллеров АТх8515 rjmp CAPT_PRESSED /обработка прерывания по сигналу ; захвата от кнопки SW3 .***инициализация МК INIT: ldi temp,low(RAMEND) /установка out SPL,temp / указателя стека ldi temp,high(RAMEND) / на последнюю out SPH,temp / ячейку ОЗУ ldi temp,0x00 /инициализация out DDRD,temp / порта PD на ввод ldi temp,0x07 /включение подтягивающих out PORTD,temp / резисторов порта PD ldi temp,0x00 ////для ATmega8515 инициализация out DDRE,temp //// PE0 (ICP) на ввод ser temp /инициализация out DDRB,temp / порта РВ на вывод out PORTB,temp /выключение светодиодов cli /запрещение прерываний ldi temp,0x00 /отключение от таймера out TCCR1A,temp / выводов ldi temp,0x00 /таймер out TCCRlB,temp / остановлен ldi temp,OxFF /запись числа в out OCRlAH,temp / регистр сравнения, ldi temp,OxFF /первым записывается out OCRlAL,temp / старший байт clr temp /обнуление out TCNTlH,temp / содержимого out TCNT1L, temp / счетного регистра ldi L_byte,0xF0 /начальные значения ldi H_byte,0x0F / для контроля sei /разрешение прерываний WAITSTART: sbic PIND,START /ожидание нажатия rjmp WAITSTART / кнопки START ldi temp,0x08 /разрешение прерывания out TIMSK,temp / по событию захват таймера ldi temp,0xC9 /запуск таймера, при out TCCRlB,temp / совпадении с OCR1A - сброс WAIT_L: sbic PIND,SHOW_L /ожидание нажатия кнопки rjmp WAIT_H / для показа младшего байта out PORTB,L_byte /вывод на светодиоды WAIT_H: sbic PIND,SHOW_H /ожидание нажатия кнопки
4.4. Программирование функций таймера Т1 129 Режим ШИМа Подготовить программу для исследования работы таймера Т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. Рис. 4.4. Формирование ШИМ-сигнала Программа 4.5 .★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★ /Программа 4.5 для МК АТх8515: демонстрация работы таймера ; Т1 в режиме ШИМа. Для наглядности необходимо установить rjmp WAIT_L ; для показа старшего байта out PORTB,H_byte ;вывод на светодиоды rjmp WAIT_L .★★★Обработка прерывания от кнопки CAPT CAPT_PRESSED: in L_byte,ICR1L ;считывание младшего байта in H_byte,ICRlH /считывание старшего байта com L_byte /инвертирование com H_byte /инвертирование reti
130 4. Таймеры микроконтроллеров АТх8515 ; частоту тактового генератора = 2048 Гц. ;При нажатии на SWO (SHOW_0) на выходах ОС1А и ОС1В /устанавливаются 0 и 1, SW1 (SH0W_F1)- генерация ШИМ- ;сигнала со скважностью Fl, SW2 (SHOW_F2)- со скважностью ;F2, SW3 (SHOW_l)- на выходах устанавливаются 1 и 0. ;Связи:PD5-LED0,PE2-LED1, PD0:PD1-SW0:SW1, PD2:PD3-SW2:SW3 .★★★★★★★★★********************^ ;.include "8515def.inc" ;файл определений AT90S8515 .include "m8515def.inc" ;файл определений ATmega8515 .def temp = rl6 /временный регистр ;***Выводы порта PD .equ SHOW_0 = 0 .equ SH0W_F1 = 1 .equ SHOW_F2 = 2 .equ SHOW_3 = 3 .org $000 rjmp INIT /обработка сброса ;***Инициализация MK INIT: ldi temp,low(RAMEND) /установка out SPL,temp ; указателя стека ldi temp,high(RAMEND) ; на последнюю out SPH,temp ; ячейку ОЗУ ldi temp,0x20 /инициализация выводов порта PD: out DDRD,temp ; 0-3 - на ввод, 5 - на вывод ldi temp,OxOF /включение подтягивающих out PORTD, temp / резисторов порта PD ldi temp,0x04 ////для ATmega8515 инициализация out DDRE, temp //// PE2 (OC1B) на вывод cli / запрещение прерываний ldi temp,0xB3 /настройка таймера на ШИМ out TCCRlA,temp / с выводами ОС1А и ОС1В clr temp /обнуление out OCRlAH,temp / регистров out OCRlAL,temp / сравнения и out OCRlBH,temp out OCRlBL,temp out TCNTlH,temp / счетного out TCNTlL,temp / регистра ldi temp,0x01 /таймер out TCCRlB,temp / запущен: частота - СК sei / разрешение прерываний
4.4. Программирование функций таймера Т1 131 WAIT_0: ;ожидание sbic PIND, SHOW_0 ; нажатия rjmp WAIT_F1 ; кнопки SHOW_0, состояния 0 и 1 ;***Перевод в устойчивые состояния выводов ОС1А=0, ОС1В=1 clr temp ;запись числа в out OCRlAH,temp ; регистры сравнения, первым out OCRlAL,temp ; записывается старший байт out OCRlBH,temp out OCRlBL,temp WAIT_F1:sbic PIND,SH0W_F1;ожидание нажатия rjmp WAIT_F2 ; кнопки SH0W_F1 - режим ШИМа ; скважностью Fl ;***Настройка таймера на режим ШИМа со скважностью F1 ldi temp,0x00 /запись числа в out OCRlAH,temp ; регистры сравнения, out OCRlBH,temp ; первым записывается ldi temp, OxFF ; старший байт out OCRlAL,temp out OCRlBL,temp WAIT_F2:sbic PIND, SHOW_F2;ожидание нажатия rjmp WAIT_3 ; кнопки SHOW_F2-режим ШИМа ; скважностью F2 ;***Настройка таймера на режим ШИМа со скважностью F2 ldi temp,0x02 /запись числа в out OCRlAH,temp ; регистры сравнения, out OCRlBH,temp ; первым записывается ldi temp, OxFF ; старший байт out OCRlAL,temp out OCRlBL,temp WAIT_3:sbic PIND,SHOW_3 ;ожидание нажатия rjmp WAIT_0 ; кнопки SHOW_3, состояния 1 и 0 ;***Перевод в устойчивые состояния выводов ОС1А=1, ОС1В=0 ser temp /запись числа в out OCRlAH,temp ; регистры сравнения, первым out OCRlAL,temp ; записывается старший байт out OCRlBH,temp out OCRlBL,temp rjmp WAIT_0 5*
132 4. Таймеры микроконтроллеров АТх8515 Результат соответствует диаграммам на рис. 4.4. При нажатии на SW0 загорается только LED0, при нажатии SW3 - только LED1. При нажатии SW1 или SW2 светодиоды попеременно включаются/выключаются со скважностью F1 или F2 соответственно. 4.5. СТОРОЖЕВОЙ ТАЙМЕР Основная функция сторожевого таймера (Watchdog Timer) - защита устройства от сбоев. Благодаря сторожевому таймеру можно прервать выполнение зациклившейся программы или выйти из Рис. 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. Сторожевой таймер 133 Для включения/выключения сторожевого таймера используют два разряда регистра 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 с
134 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_l) наступление тайм-аута /происходит через 0,4 9 с (время включения светодиодов), ;SW1 (PERIOD_2) - через 1,9 с. ;Соединения: PDO:PD1-SW0:SW1, PB-LED(10-проводной шлейф) .********************************* .include "8515def.inc" ;файл определений AT90S8515 /.include "m8515def.inc" ;файл определений ATmega8515 .def temp = rl6 ;временный регистр ;***Выводы порта PD .equ PERIOD_l = 0 .equ PERIOD_2 = 1 .org $000 rjmp INIT /обработка сброса ;* * *Инициализация МК INIT: ldi temp,low(RAMEND) /установка out SPL,temp ; указателя стека ldi temp,high(RAMEND) ; на последнюю out SPH,temp ; ячейку ОЗУ clr temp /инициализация порта PD out DDRD,temp ; на ввод ldi temp,0x03 /включение подтягивающих
4.5. Сторожевой таймер 135 out PORTD,temp ; резисторов порта PD ser temp /инициализация порта РВ out DDRB,temp ; на вывод out PORTB,temp /выключение светодиодов ldi temp,$18 /выключение out WDTCR, temp / сторожевого ldi temp,$10 / таймера: out WDTCR,temp /WDE=0 WAIT_SW0: sbic PIND,PERIOD_l /ожидание нажатия rjmp WAIT_SW1 / кнопки PERIOD_l ;***Назначение периода наступления тайм-аута = 0,49 с clr temp /включение out PORTB,temp / светодиодов ldi 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 / светодиодов ldi 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 с.
136 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. Скорость передачи данных может варьироваться в широких пределах, причем высокие скорости передачи могут быть достигнуты даже при относительно низкой тактовой частоте микроконтроллера.
138 5. Обмен данными по последовательному интерфейсу Известно, что при передаче данных могут произойти различные сбои. Модуль UART, реализованный в микроконтроллерах, способен при приеме обнаруживать ошибку формата и переполнение. Для взаимодействия с программой в модуле предусмотрены прерывания при наступлении следующих событий: прием завершен с адресом вектора $009 в таблице векторов прерываний, регистр данных передатчика пуст с адресом вектора $00А, передача завершена с адресом вектора $00В. Выводы микроконтроллера, используемые модулем UART, являются линиями порта PD. В качестве входа приемника (RXD) используют вывод РЕЮ, а в качестве выхода передатчика (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.7. Последовательный обмен данными по каналу UART 139 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.
140 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 и начинает функционировать как выход независимо от состояния 1-го разряда регистра DDRD порта PD. Передача инициируется записью передаваемых данных в регистр данных UDR. После этого данные пересылаются из регистра UDR в сдвиговый регистр передатчика. При этом возможны два варианта: 1) новое значение записывается в регистр UDR после того как был передан стоп-бит предыдущего слова. В этом случае данные пересылаются в сдвиговый регистр сразу же после записи в регистр UDR;
5.7. Последовательный обмен данными по каналу UART 141 Рис. 5.1. Структурная схема передатчика UART 2) новое значение записывается в регистр UDR во время передачи. В этом случае данные пересылаются в сдвиговый регистр после передачи стоп-бита текущего слова. После пересылки содержимого регистра UDR в сдвиговый регистр флаг UDRE регистра USR устанавливается в 1, что означает готовность передатчика к получению нового значения. В этом состоянии флаг остается до новой записи в регистр UDR. Одновременно с пересылкой формируется служебная информация: 0-й разряд сдвигового регистра сбрасывается в 0 (старт-бит), а 9-й (или 10-й) разряд устанавливается в 1 (стоп-бит). Если включен режим передачи 9-разрядных данных (разряд CHR9 регистра UCR установлен в 1), то значение разряда ТХВ8 регистра UCR копируется в 9-й разряд сдвигового регистра. После загрузки сдвигового регистра его содержимое начинает сдвигаться вправо и поступает на вывод TXD в следующем поряд-
142 5. Обмен данными по последовательному интерфейсу ке: стартовый бит, данные (начиная с младшего разряда), стопо- вый бит. Сдвиг осуществляется по тактовому сигналу, вырабатываемому контроллером скорости передачи. Если во время передачи в регистр UDR было записано новое значение, то после передачи стоп-бита оно пересылается в сдвиговый регистр. Если же к моменту окончания передачи стоп-бита новой записи выполнено не было, в регистре USR устанавливается флаг завершения передачи ТХС. Прием данных Структурная схема приемника модуля UART приведена на рис. 5.2. После обнаружения старт-бита начинается обработка поступающих разрядов слова данных. Решение о значении принятого разряда принимается по результатам трех выборок входного сигнала в середине битового периода. Состоянием разряда считается логическое значение, которое было получено по меньшей мере в двух из трех выборок. По мере распознавания разрядов принимаемой последовательности они поступают, сдвигаясь вправо, в сдвиговый регистр приемника. Распознавание стоп-бита производится также по трем выборкам входного сигнала. Стоп-бит считается принятым, если значения хотя бы двух из трех выборок входного сигнала равны 1. В противном случае фиксируется ошибка кадра и флаг FE регистра USR устанавливается в 1. Перед чтением регистра данных UDR следует всегда проверять состояние этого флага. Независимо от того, был или не был обнаружен стоп-бит в конце принимаемой посылки, принятое слово пересылается в регистр данных UDR и устанавливается флаг RXC регистра USR. В случае обмена 9-разрядными данными при пересылке содержимого сдвигового регистра приемника в регистр данных 9-й разряд принятого слова загружается в разряд RXB8 регистра UCR. Если новое слово поступит до того как из регистра UDR будут считаны предыдущие данные, возникает переполнение. Об этом сигнализирует флаг OR регистра USR, который в этом случае устанавливается в 1. Установка этого флага означает, что принятые данные не могут быть переданы из сдвигового регистра в регистр данных и оказываются потерянными. Сбрасывается указанный флаг только после обращения к регистру данных, поэтому при высоких скоростях передачи либо большой загрузке процессора программа должна проверять состояние флага OR в регистре USR для обнаружения возможного переполнения.
5.7. Последовательный обмен данными по каналу UART 143 Рис. 5.2. Структурная схема приемника UART Скорость приема/передачи Управление скоростью приема/передачи данных осуществляется контроллером скорости передачи, который является обыкновенным делителем частоты. Скорость передачи зависит от содержимого регистра контроллера. В AT90S8515 - это регистр ввода/вывода UBRR, в ATmega8515 - регистры UBRRH:UBRRL. Скорость передачи определяется следующим выражением: BAUD = ^ , 16(UBRR + 1) где BAUD - скорость передачи, бод; /clk - тактовая частота микроконтроллера, Гц; UBRR - содержимое регистра контроллера скорости передачи.
144 5. Обмен данными по последовательному интерфейсу Таблица 5.3. Значения UBRR для различных fuK Скорость, бод fcLK ~ 1 Ошибка, /clk = 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), а в качестве входа приемника - PD0 (RXD). Визуально, используя светодиодную индикацию, контролировать передаваемые данные невозможно из-за большой скорости передачи, поэтому возможны следующие варианты контроля работы канала UART: 1) используя программу Hiper Terminal для обмена сообщениями через СОМ-порт персонального компьютера с микроконтроллером на плате STK500 по интерфейсу RS-232; Как известно, существует ряд значений скорости передачи данных, являющихся, по сути, стандартными. Значения UBRR, позволяющие получить эти скорости передачи при использовании различных резонаторов, а также ошибки, получаемые относительно их теоретического значения, приведены в табл. 5.3. Поскольку максимальная тактовая частота, устанавливаемая с помощью STK500, равна 3,69 МГц, значения частот выше этого в табл. 5.3 не приведены. С увеличением ошибки помехозащищенность линии передачи снижается, скорости передачи, имеющие ошибку установки более 1 %, использовать не рекомендуется.
5.7. Последовательный обмен данными по каналу UART 145 Рис. 5.3. Схема устройства для передачи сообщения по интерфейсу UART 2) соединив выводы UART двух микроконтроллеров, размещенных на платах STK500, напрямую либо через разъем интерфейса RS-232 и подключив к выходам принимающего микроконтроллера светодиодную индикацию STK500. Схема включения микроконтроллеров МК1 и МК2 для этого случая приведена на рис. 5.3. Запрограммируем микроконтроллер МК1 для передачи данных, микроконтроллер МК2 - для приема. Данные для передачи - три байта сообщения - разместим в памяти программ. Передача начинается с нажатия кнопки SW4 (Старт). Первый микроконтроллер выполняет в цикле последовательный вывод данных. После приема каждого байта данных второй микроконтроллер сохраняет их в своей памяти SRAM, начиная с адреса $180. Закончив прием, второй микроконтроллер последовательно выводит при нажатии кнопки SW5 (Просмотр) полученные данные на светодиоды. Схемы алгоритмов передачи и приема приведены на рис. 5.4. После инициализации оба микроконтроллера переходят в режим ожидания нажатия кнопки SW4. Микроконтроллер МК2, программируемый для приема, ожидает поступления данных. Его дальнейшая работа зависит от значения флага RXC: ожидание - при RXC = 0 и ввод байта данных - при RXC = 1. Состояние этого флага зависит от работы передающего устройства. Переход к последующим итерациям в циклах передачи (приема) происходит после установления флага завершения передачи ТХС (соответственно приема RXC) очередного байта данных. После завершения
146 5. Обмен данными по последовательному интерфейсу Рис. 5.4. Схемы алгоритмов передачи из микроконтроллера 1 (а) и приема в микроконтроллер 2 (б) цикла приема включаются все светодиоды линейки индикации. Далее при последовательном нажатии на кнопку SW5 (Просмотр) осуществляется вывод принятых байтов данных на светодиоды. Ниже приведены тексты программ для передающего и принимающего микроконтроллеров. Программа 5.1 .******************************^ /Программа 5.1 для МК АТх8515: демонстрация работы UART. ;При нажатии на SW4 (START) происходит последовательная /передача по каналу UART трех байтов сообщения,считываемых ;из ячеек Flash-памяти. При частоте генератора 3,69 МГц, ;UBRR=11 скорость передачи 19219 бод.
5.1. Последовательный обмен данными по каналу UART 147 /Соединения: PD4-SW4, GND STK500-1 с GND STK500-2 .*★★★★*★★★★*★★★★★*★*★*★★***★★*★★****** .include "8515def.inc" ;файл определений AT90S8515 ;.include "m8515def.inc" ;файл определений ATmega8515 .def temp = rl6 ;временный регистр .def count = rl7 /счетчик .equ START = 4 ;4-й вывод порта PD .org $000 rjmp init ;***Инициализация MK INIT: ldi ZL,low(text*2) /загрузка адреса текста ldi ZH,high(text*2) / сообщения в регистр Z ldi count,3 /установка счетчика байтов clr temp /настройка out DDRD,temp / вывода ldi temp,0x10 / порта PD4 out PORTD,temp / на ввод /***Настройка UART на передачу данных //// для ATmega8515 регистр UCSRB вместо UCR ldi temp,0x08 /разрешение out UCR, temp / передачи по каналу UART ldi temp,11 /скорость передачи out UBRR,temp / 19219 бод WAIT_START: sbic PIND,START /ожидание нажатия rjmp WAIT_START / кнопки START OUTPUT: 1pm /считывание байта из flash-памяти в r0 out UDR,rO /вывод байта в передатчик //// для ATmega8515 регистр UCSRA вместо USR sbi USR,TXC /сброс флага ТХС WAIT: sbic USR,ТХС /ожидание rjmp next / завершения rjmp WAIT / передачи next: adiw zl,l /увеличение адреса на 1 dec count /уменьшение счетчика на 1 brne OUTPUT /продолжение вывода fin: rjmp fin /передача завершена text: .db 'A','V ,'R' /текст сообщения / (ASCII - коды $41, $56, $52) Программа 5.2 /Программа 5.2 для МК АТх8515: демонстрация работы канала /UART в режиме приема трех байтов. При частоте тактового
148 5. Обмен данными по последовательному интерфейсу /генератора 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 ;* * *Инициализация МК INIT: ldi temp,low(RAMEND) /установка out SPL,temp / указателя стека ldi temp,high(RAMEND) / на последнюю out SPH,temp / ячейку ОЗУ ldi YL,0x80 /в регистре Y - адрес, по которому ldi YH,0x01 / происходит запись принятых данных ldi count,3 /установка счетчика байтов ser temp /настройка out DDRB,temp / порта РВ на вывод out PORTB,temp / и выключение светодиодов clr temp out DDRD,temp /настройка ldi temp,0x20 / вывода PD5 out PORTD,temp / на ввод /***Настройка UART на прием данных //// для ATmega8515 регистр UCSRB вместо UCR, UBRRL ldi temp,0x10 /разрешение приема out UCR,temp / по каналу UART ldi temp,11 /скорость приема/передачи out UBRR,temp / 19219 бод //// для ATmega8515 регистр UCSRA вместо USR WAIT_RXC: sbic USR,RXC /ожидание rjmp INPUT / завершения rjmp WAIT_RXC / приема INPUT: in temp,UDR /ввод байта из приемника st Y+,temp / и сохранение в памяти dec count /уменьшение счетчика на 1 brne WAIT_RXC /продолжение приема clr temp /сигнализация - out PORTB,temp / прием завершен ldi YL,0x80 /установка начального адреса ldi count,3 /установка счетчика байтов
5.7. Последовательный обмен данными по каналу UART 149 WAIT_SHOW: sbic PIND,SHOW /ожидание нажатия rjmp WAIT_SHOW ; кнопки SW5 Id temp, Y+ /считывание байта из памяти com temp /инвертирование out PORTB,temp /вывод на светодиоды rcall DELAY /задержка dec count /если показаны не все данные, brne WAIT_SHOW / продолжение при нажатии SW5 ser temp /вывод окончен out PORTB,temp /светодиоды погашены ldi count,3 ldi YL,0x80 rjmp WAIT_SHOW /повторение вывода /*** Задержка *** DELAY:ldi rl9,10 ldi r20,255 ldi r21,255 dd:dec r21 brne dd dec r20 brne dd dec rl9 brne dd ret Проверка работы канала UART с помощью программы Hyper Terminal А. Создать в AVR Studio 4 проект для передачи данных с помощью программы 5.1. Проверить работу программы в режиме симуляции, наблюдая состояния регистров и битов состояния канала UART. Отлаженную программу запрограммировать в память микроконтроллера на плате STK500. Закрыть программу AVR Studio 4. Проверить работу канала передачи UART, соединив при выключенном напряжении питания плату STK500 с компьютером. Для этого используем интерфейс RS-232 для передачи/приема данных из микроконтроллера по каналу UART. Соединение можно осуществить кабелем связи через 9-контактный разъем интерфейса RS-232, обозначенный на плате RS232 SPARE. Подключение микроконтроллера к интерфейсу RS-232 выполняется двухпроводным шнуром путем соединения выводов порта PDO, PD1 с контактами RXD, TXD двухконтактного разъема RS232 SPARE. После соединения подать напряжение питания на плату. Запустить программу
150 5. Обмен данными по последовательному интерфейсу Hyper Terminal из Windows, выбрав одноименную строку в меню Программы/ Стандартные/ Связь, и настроить канал связи, установив СОМ-порт, скорость обмена 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 с выводом PD0 второго, а также соединив выводы GND обеих плат. При необходимости платы STK500 после программирования отсоединить от кабелей RS-232. При нажатии кнопок RESET оба микроконтроллера переводятся в режим ожидания. Передача сообщения начинается после нажатия кнопки SW4 (Старт) на плате первого STK500. После приема сообщения загораются все светодиоды второго STK500, показывая, что прием данных завершен. Полученные данные можно вывести на индикаторы, нажимая последовательно кнопку SW5. Задание 2. Написать программу для передачи сообщения hello, хранимого в памяти программ микроконтроллера STK500-1, в па-
5.7. Последовательный обмен данными по каналу UART 151 мять данных микроконтроллера STK500-2. Процедуру передачи и процедуру приема каждого символа сообщения запрограммировать, используя запросы прерываний от передатчика и приемника. Задание 3. Изменить программу, осуществив передачу данных из памяти SRAM по каналу UART. Загрузку данных (констант) в ячейки SRAM осуществить непосредственно командами программы. Для приема данных по входу RXD использовать тот же микроконтроллер, соединив выход TXD с входом RXD. Задания для самостоятельного программирования 1. Написать программы для двух микроконтроллеров АТх8515 для обмена данными по интерфейсу UART. Микроконтроллер МК1 после передачи данных переводится в режим приема ответного сообщения от микроконтроллера МК2. Соответственно микроконтроллер МК2 после приема данных переводится в режим передачи. Запрограммировать микроконтроллеры двух STK500: МК1 - для передачи и затем приема данных, МК2 - для приема и затем передачи. Схема устройства для исследований приведена на рис. 5.5. Рис 5.5. Схема устройства для обмена сообщениями (SW4 - старт, SW5 - просмотр) Для проверки работы канала UART (USART) необходимо соединить напрямую выводы PDl(TXD), PDO(RXD) первого STK500 соответственно с выводами PDO(RXD), PDl(TXD) второго STK500, а также соединить выводы GND обеих плат. При нажатии
152 5. Обмен данными по последовательному интерфейсу кнопок RESET оба микроконтроллера переводятся в режим ожидания. Обмен сообщениями начинается после нажатия кнопки SW4 (старт) на плате первого STK500. По окончании обмена загораются все светодиоды обоих STK500, показывая, что обмен данными завершен. После обмена можно вывести полученные данные на индикаторы каждого STK500, нажимая последовательно кнопки SW5 (просмотр). 2. Написать программы для АТх8515 для обмена данными по интерфейсу UART между двумя микроконтроллерами МК1 и МК2. Обмен начинается при нажатии кнопки SW4 (старт) на плате STK500-1. Этот сигнал используется для запуска процесса одновременной передачи сообщений от каждого из микроконтроллеров, поступающих по каналу UART в присоединенный микроконтроллер. Передачу и прием данных в каждом микроконтроллере осуществить по запросам прерываний от передатчика и приемника. Скорость обмена установить равной 9600 бит/с. Принимаемые данные сохранить во внутренней памяти микроконтроллеров. После обмена данными перевести микроконтроллеры в режим просмотра принятых данных при последовательном нажатии кнопок просмотра SW5 (просмотр). 5.2. РАБОТА ПОСЛЕДОВАТЕЛЬНОГО КАНАЛА SPI Цель работы - изучение приема и передачи информации по последовательному каналу SPI (Serial Peripheral Interface) и программирование ввода/вывода. Интерфейс SPI используется для организации высокоскоростного канала связи между микроконтроллером и периферийными устройствами, а также обмена данными между микроконтроллерами. В состав модуля SPI (рис. 5.6) входят: - 8-разрядный сдвиговый регистр SPDR, который принимает байт данных с шины данных микроконтроллера, сдвигает его вправо или влево с выдачей последовательного кода на вывод микроконтроллера, одновременно с выводом принимает последовательный код со входа микроконтроллера и через буферный регистр передает его на шину данных микроконтроллера; - 8-разрядные регистр управления SPCR и регистр состояния SPSR; - предварительный делитель частоты; - схемы управления.
5.2. Работа последовательного канала SPI 153 Зпр SPI STC Шина данных Рис. 5.6. Структурная схема SPI (имена сигналов на выходах 0-7 регистра SPCR приведены в табл. 5.4) В микроконтроллерах АТх8515 для сигналов интерфейса SPI выделены четыре линии порта РВ: РВ5 - MOSI, РВ6 - MISO, PB7-SCK, PB4-/SS. Порт 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
154 5. Обмен данными по последовательному интерфейсу При 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 подключаются к выводам порта РВ также при Рис. 5.7. Схема соединения двух микроконтроллеров (master - ведущий, slave - ведомый) установке бита SPE регистра SPCR. Перевод порта в рабочее состояние осуществляется по сигналу логического 0 на входе /SS. На рис. 5.7 приведена схема соединения двух микроконтроллеров для обмена данными по каналу SPI. Передача данных начинается после записи данных в регистр SPDR ведущего микроконтроллера. Диаграммы сигналов при передаче данных по интерфейсу SPI приведены на рис. 5.8. Порядок выдачи определяется состоянием бита DORD при настройке канала. Если DORD = 1, вывод начинается с младшего разряда (LSB), иначе - со старшего (MSB). После выдачи последнего разряда устанавливается в 1 флаг SPIF (бит 7 регистра состояния SPSR) и одновременно вырабатывается запрос прерывания SPI STC с адресом вектора $008, если флаг разрешения прерывания SPIE от модуля SPI при настройке канала был установлен в 1. Одновременно с передачей производится прием данных от
5.2. Работа последовательного канала SPI 155 Таблица 5.5. Выбор коэффициентов деления К Рис. 5.8. Временные диаграммы сигналов интерфейса SPI (* - неопределенное состояние) ведомого микроконтроллера. По окончании приема данных в ведомом микроконтроллере также устанавливается в 1 флаг SPIF и вырабатывается запрос прерывания SPI STC при разрешении прерывания. При попытке записи в регистр данных SPDR во время передачи очередного байта устанавливается в 1 флаг WCOL (бит 6 регистра состояния SPSR). Скорость передачи устанавливается для ведущего микроконтроллера с помощью битов SPR1, SPR0 регистра SPCR. Используемые для сдвига импульсы вырабатываются в результате деления тактовой частоты СК на коэффициент К согласно табл. 5.5. Значения этих битов для ведомого МК не оказывают влияния на работу порта. Значения битов DORD (формат обмена) и CPOL (полярность сигналов сдвига на линии SCK) для ведущего и ведомого микроконтроллеров должны быть одинаковыми. SPR1 SPR0 К 0 0 4 0 1 16 1 0 64 1 1 128
156 5. Обмен данными по последовательному интерфейсу Практическая часть Подготовить программу для исследования передачи и приема по последовательному каналу SPI. Напомним, что в качестве выхода передатчика используется вывод ведущего микроконтроллера MOSI (РВ5), а в качестве входа приемника ведомого микроконтроллера - вывод MOSI (РВ5). Для контроля работы канала SPI используем два стартовых набора STK500. Запрограммируем микроконтроллер первого STK500 для передачи данных, микроконтроллер второго - для приема. Данные для передачи (три байта) загрузим в ячейки памяти SRAM, начиная с адреса $170, посредством команды для записи констант. Затем выполним в цикле последовательный вывод данных. После приема каждого байта данных второй микроконтроллер сохраняет его в своей памяти SRAM, начиная с адреса $180. Закончив прием, второй микроконтроллер последовательно выводит при нажатии кнопки SW5 полученные данные на светодиоды. Схемы алгоритмов передачи и приема приведены на рис. 5.9. Переход к следующей итерации в циклах передачи (приема) осуществляется после установки флага завершения передачи (приема) SPIF очередного байта данных. Проверка битов ошибки формата и переполнения в алгоритме приема не предусмотрена. После завершения цикла приема включаются все светодиоды линейки индикации, сигнализируя о его окончании. Затем при последовательном нажатии на кнопку SW5 осуществляется вывод принятых байтов данных на светодиоды. Далее приведены тексты программ для передающего и принимающего микроконтроллеров. Программа 5.3 .********************************** /Программа 5.3 для демонстрации работы канала SPI /передающего микроконтроллера АТх8515 в режиме MASTER. /После сброса MK1 происходит передача трех байтов, /считываемых из ячеек SRAM по адресам из регистра Z. /Соединения: РВ5мк1-РВ5мк2, РВ7мк1-РВ7мк2, РВ0мк1-РВ4мк2 .************************************* .include "8515def.inc" /файл определений AT90S8515 /.include "m8515def.inc" /файл определений ATmega8515 .def temp = rl6 /временный регистр .def count = rl7 /счетчик .org $000
5.2. Работа последовательного канала SPI 157 Рис. 5.9. Схемы алгоритмов передачи из МК1 (а) и приема в МК2 (б) rjmp init ; ** инициализация МК INIT: ldi temp,0xBl out DDRB,temp ldi ZL,0x70 ldi ZH,0x01 ldi temp,0x41 st Z+,temp ldi temp,0x56 st Z+,temp ldi temp, 0x52 st Z+,temp ldi ZL,0x70 MOSI/PB7, SCK/PB5, SS/PB4, РВО для вывода загрузка данных в память данных с использованием косвенной адресации с постинкрементом
158 5. Обмен данными по последовательному интерфейсу ldi count,3 ;установка счетчика передач ;***Настройка SPI в режиме MASTER на передачу данных ldi temp, (1«SPE) I (1«MSTR) out SPCR,temp OUTPUT: sbi PORTB,0 /переключение сигнала nop ; на выходе РВО cbi PORTB,0 ; из 1 в О Id temp,Z+ /считывание байта из памяти out SPDR,temp /вывод байта в передатчик Wait_Transmit: sbis SPSR,SPIF /проверка флага передачи rjmp Wait_Transmit dec count /уменьшение счетчика на 1 brne OUTPUT loop: rjmp loop Программа 5.4 .********************************^ /Программа 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 .def temp = rl6 /временный регистр .def count = rl7 /счетчик .equ SHOW = 5 /5-й вывод порта PD .org $000 rjmp init /* * *Инициализация MK INIT: ldi temp,low(RAMEND) /установка out SPL,temp / указателя стека ldi temp,high(RAMEND) / на последнюю out SPH,temp / ячейку ОЗУ ldi temp, (l«DD_MISO) out DDRB, temp ldi temp, OxBO
5.2. Работа последовательного канала SPI 159 out PORTB,temp clr temp /настройка out DDRD,temp ; вывода порта PD5 sbi PORTD,SHOW ; на ввод, ser temp out DDRC,temp ; выводов порта PC out PORTC/temp ; на вывод ldi count,3 /установка счетчика байтов ldi XL,0x80 ;в регистре X - адрес, по которому ldi ХН,0x01 ; происходит запись принятых данных ;***Настройка SPI в режиме SLAVE на прием данных ldi temp, (1«SPE) out SPCR,temp INPUT: sbis SPSR,SPIF /проверка флага приема rjmp INPUT in temp,SPDR ;ввод байта из приемника st X+,temp /сохранение байта в памяти dec count /уменьшение счетчика на 1 brne INPUT rcall OUTLED /вывод на индикацию loop: rjmp loop /***Вывод на индикаторы*** OUTLED: clr temp /сигнализация - out PORTC,temp / прием завершен ldi XL,0x80 /установка начального адреса ldi count,3 /установка счетчика байтов WAIT_SHOW: sbic PIND,SHOW /ожидание нажатия rjmp WAIT_SHOW / кнопки SHOW Id temp,X+ /считывание байта из памяти com temp /инвертирование и out PORTC,temp /вывод на светодиоды rcall DELAY /задержка dec count /если показаны не все данные, brne WAIT_SHOW / продолжение по нажатию SHOW ret .★★★задержка*** DELAY:ldi г19,10 ldi r20,255 ldi r21,255 dd:dec r21 brne dd dec r20 brne dd dec rl9 brne dd ret
160 5. Обмен данными по последовательному интерфейсу Задание 1. Создать в AVR Studio 4 проект для передачи данных с помощью программы 5.3. Проверить работу программы в режиме симуляции, наблюдая состояния регистров и линий интерфейса канала SPI. Сохранить файл с отлаженной программой. Создать в AVR Studio 4 проект для приема данных с помощью программы 5.4. Проверить работу программы в шаговом режиме симуляции, наблюдая состояния регистров канала SPI и порта индикации РС, вручную обновляя флаг SPIF и регистр SPDR перед вводом данных и эмулируя замыкание кнопки SW5 в порту PIND.5. Сохранить файл с отлаженной программой. Для совместной отладки программ и симуляции передачи/приема воспользуемся демонстрационной версией программы Рис. 5.10. Схема взаимодействия микроконтроллеров по интерфейсу SPI 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), в окно редактора вводим два микроконтроллера, которые соединяем линиями связи. Добавляем периферийные устройства: переключатель (SW-SPST) из библиотеки компонентов Component/Active и, при желании, светодиоды, так как выводы всех портов индицируются программой автоматически. Присоединяем выводы переключателя: один - к выводу порта PD5, второй - к общей шине GROUND, выбрав ее из списка Inter-sheet Terminal на панели инструментов.
5.2. Работа последовательного канала SPI 161 Предварительно выделив правой кнопкой мыши переключатель и щелкнув левой кнопкой, в открывающемся окне назначаем ему новое имя - SW5. Сохраняем проект, создав для него новую папку (например, Sample/SPI). С помощью команд меню 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 для вывода данных в порт РС (для светодиодов). Для ускорения работы при отладке в пошаговом режиме вызов подпрограммы задержки в программе следует закомментировать. Задание 2. Изменить программу 5.3, организуя однократное переключение сигнала из 1 в 0 на линии РВО перед выводом первого байта и, таким образом, сохраняя постоянно уровень сигнала О для всех последующих передач. Проверить работу интерфейса на модели путем симуляции. Задание 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. 6—1998
162 5. Обмен данными по последовательному интерфейсу При необходимости платы 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 по сигналу, поступающему на вход /SS от ведомого микроконтроллера МК2, для приема ответного сообщения. После приема данных вывести полученные данные в порт РС для индикации. Построить схемы алгоритмов программ для каждого из микроконтроллеров, связанных между собой каналом SPI. Провести отладку программ сначала в AVR Studio 4, а затем проверить их работу в STK500. 3. Написать программы для микроконтроллеров АТх8515 для обмена данными по интерфейсу SPI в дуплексном режиме. Одновременно с передачей данных из микроконтроллера МК1 осуществить прием данных от ведомого микроконтроллера МК2. Принимаемые данные сохранить во внутренней памяти микроконтроллеров. После приема данных перевести микроконтроллеры в режим просмотра принятых данных при нажатии кнопки SW5. Отладить программы с помощью системы виртуального моделирования ISIS 6 Professional.
5.3. Обмен данными по интерфейсу 12C(TWI) 163 5.3. ОБМЕН ДАННЫМИ ПО ИНТЕРФЕЙСУ I2C (TWI) Цель работы - изучение приема и передачи информации по последовательному каналу I2C (Integrated Circuit) и программирование ввода/вывода. Двухпроводный последовательный интерфейс I2C и подобные ему (Two-wire Serial Interface, TWI) обеспечивают взаимодействие МК с множеством микросхем (энергонезависимой памятью, контроллерами параллельных портов, LCD-дисплеями, микроконтроллерами и различными специализированными устройствами). Рис. 5.11. Схема соединения устройств по интерфейсу I2C Данный интерфейс позволяет объединить до 128 устройств по схеме, приведенной на рис. 5.11. Интерфейс представляет собой две линии: одна (SDA) используется для передачи данных, другая (SCL) - для тактовых сигналов. Через резисторы Rl, R2 обе линии подключены к источнику питания VCC. Выходы устройств выполнены по схеме с открытым коллектором (стоком), что позволяет реализовать функцию «монтажное И» для выходных сигналов. Низкий уровень сигнала логического 0 на выходе любого из устройств устанавливает низкий уровень на всей линии. Высокий уровень на линии устанавливается, когда выводы всех устройств находятся в третьем (высокоим- педансном) состоянии. Устройство, подключенное к шине, может иметь статус ведущего (master) или ведомого (slave). Статус микроконтроллера устанавливается программно. Протоколом работы шины предусмотрены: • посылка ведущим устройством стартового бита начала обмена; • передача последовательности из семи разрядов адреса ведомого устройства; • транзакция чтения или записи 8-битовых данных; • получение ведущим устройством битов подтверждения передачи адреса и данных; б*
164 5. Обмен данными по последовательному интерфейсу • формирование бита подтверждения после приема данных; • посылка ведущим устройством стопового бита. Шина I2C (TWI) является последовательной: все данные и адреса передаются по линии SDA поразрядно. Каждый передаваемый бит сопровождается тактовым сигналом на линии SCL. В течение всего времени действия сигнала SCL (SCL =1) состояние линии SDA должно оставаться неизменным. Изменение данных на линии SDA происходит при отсутствии тактового сигнала на линии SCL (SCL = 0). Исключение составляют стартовый и стоповый Рис. 5.12. Временные диаграммы сигналов интерфейса I2C биты, определяющие начало и конец обмена. Стартовый бит формируется путем изменения уровня сигнала на линии SDA с 1 на 0 при SCL = 1, стоповый бит - при изменении сигнала SDA с 0 на 1 также при SCL = 1. Диаграмма изменения состояний линий интерфейса приведена на рис. 5.12. Кроме названных особых случаев на диаграмме представлен бит повторного старта, который можно сформировать сразу после передачи байта данных. Это позволяет ведущему устройству организовать передачу нового байта данных сразу без потери контроля над шиной. Протокол обмена по шине предполагает передачу двух типов кадров (пакетов): с адресом и данными (рис. 5.13). Кадр 7-разрядного адреса содержит: S - стартовый бит; А - 7-разрядный адрес ведомого устройства, передаваемый ведущим, начиная со старшего разряда; R/W - управляющий бит, определяющий тип транзакции на шине (R/W = 0 - запись, R/W = 1 - чтение); АСК - бит подтверждения. Адрес, передаваемый ведущим устройством после захвата шины, поступает ко всем устройствам, подключенным к ней. Каждое из устройств сравнивает поступающий адрес с собственным. При
5.3. Обмен данными по интерфейсу 12C(TWI) 165 распознавании ведомым устройством своего адреса оно возвращает на линию SDA сигнал подтверждения АСК низкого уровня во время 9-го тактового сигнала SCL. Если по каким-либо причинам ведомое устройство не способно обслужить запрос ведущего, оно удерживает на линии SDA сигнал высокого уровня. Нулевой адрес используется для общего вызова всех устройств. Управляющий бит в этом случае устанавливается в 0, чтобы обеспечить передачу одного и того же сообщения всем устройствам. После передачи адреса начинается передача данных. Кадр байта данных (рис. 5.13, б) содержит восемь битов данных и один бит S 1 А6 1 А5 1 А4 1 A3 | А2 1 Al 1 АО |R/WlACK D7 D6 D5 D4 D3 D2 Dl DO АСК Рис. 5.13. Формат кадра адреса (а) и кадра данных (б) подтверждения, формируемый приемником. Данные, так же как и адрес, передаются последовательно бит за битом, начиная со старшего разряда. После приема каждого байта данных приемник вырабатывает сигнал подтверждения АСК путем выдачи на линию SDA сигнала низкого уровня. Высокий уровень сигнала свидетельствует об ошибке или невозможности продолжить прием. Не получив подтверждения от приемника, ведущий может прекратить передачу данных, сформировав сигналы состояния Stop. После завершения передачи байта данных работа может быть продолжена либо для передачи следующего байта в том же направлении без изменения ведомого, либо выбором нового ведомого и(или) сменой направления обмена. При завершении обмена шина освобождается ведущим устройством. В микроконтроллерах AVR реализация протокола обмена может быть осуществлена двумя способами: программно или про- граммно-аппаратно. Программный способ реализуется с использованием библиотеки функций для формирования протоколов обмена. Этот способ применяется в микроконтроллерах, в которых отсутствуют встроенные аппаратные средства, реализующие протокол обмена. К ним относят микроконтроллеры семейств ATtiny и АТ90. Микроконтроллеры семейства ATmega (модели 8х, 16х, 32х, 323х, 64х, 128х, 163х) имеют в своем составе модуль обмена по интерфейсу TWI, что упрощает программирование ввода/вывода. Рассмотрим подробнее оба способа.
166 5. Обмен данными по последовательному интерфейсу Программная реализация протокола I2C Программная реализация протоколов I2C для разных случаев взаимодействия устройств представляет собой набор программ, эмулирующих работу ведущего и ведомых устройств с учетом функциональных требований. Наиболее сложным является случай, когда в качестве ведущего и ведомых выступают микроконтроллеры, которые могут быть как передатчиками, так и приемниками при обмене данными и не имеют встроенных средств обмена по I2C. Более простым считается случай, когда одно из устройств (микроконтроллер) является ведущим, а ведомые устройства содержат встроенный порт для обмена по I2C. Такие устройства (датчики, устройства памяти, часы реального времени и др.) широко выпускаются различными фирмами-производителями электронных компонентов и могут быть подключены к микроконтроллеру достаточно просто. Решая общую задачу организации взаимодействия микроконтроллера с периферийными устройствами, рассмотрим необходимые механизмы программной реализации I2C. Это предполагает программную эмуляцию I2C, существенно упрощающую работу только со стороны ведущего микроконтроллера. Алгоритмы основных транзакций шины, записи и чтения, которые использованы при программировании, представлены на рис. 5.14, 5.15. Процедура транзакции записи (передача адресного байта и запись байта данных) начинается с захвата линии SDA (SDA = 0) - формирования стартового бита - и установки флага С = 1, косвенно используемого для выявления признака окончания цикла передачи. Путем циклического сдвига влево байта данных первый передаваемый бит вытесняет 1 из флага С в младший разряд регистра данных. Это исключает возможность преждевременного выхода из цикла, когда в регистре данных во время передачи байта остаются нулевые биты. Линия SCL переводится в 0. Значение бита С используется для управления состоянием линии SDA. Если передаваемый бит, установленный в С, равен 1, линия SDA принимает значение SDA = 1, в противном случае SDA = 0. Далее спустя время задержки устанавливается линия SCL в 1 и после проверки, если ведомое устройство не тормозит работу на линии SCL, выполняется циклический переход для вывода следующего бита данных. На последующих итерациях цикла выполняется логический сдвиг. После выявления признака конца передачи, когда все биты регистра данных равны 0, выполняется переход к процедуре проверки бита подтверждения.
5.3. Обмен данными по интерфейсу 12C(TWI) 167 Рис. 5.14. Схема алгоритма записи байта данных Получение бита подтверждения АСК начинается с захвата линии SCL (SCL = 0) и освобождения ведущим линии SDA (SDA = = 1). После временной паузы линия SCL переключается в состояние 1 и, если она свободна от влияния ведомых устройств, значение SDA считывается в качестве сигнала подтверждения АСК (установка или сброс бита С). После паузы на линии SCL устанавливается 0.
168 5. Обмен данными по последовательному интерфейсу Рис. 5.15. Схема алгоритма чтения байта данных Процедура транзакции чтения (прием данных от ведомого) начинается с установки признака конца приема (1) в младший разряд регистра данных. Цикл чтения битов данных начинается с захвата линии SCL (SCL = 0), установки 1 на линии SCL, подтверждения высокого уровня сигнала SCL = 1 и последующего ввода бита данных в регистр данных путем опроса линии SDA и сдвига содержимого регистра данных. После очередной паузы выполняется проверка признака конца приема байта данных по значению флага С. Если не все биты получены (С = 0), прием продолжается. Если приняты все биты (С = 1), ведущее устройство переходит к формированию бита подтверждения приема АСК для ведомого устройства. При необходимости формирования бита АСК линия SDA устанавливается в 0, линия SCL переводится в состояние 1. После подтверждения SCL = 1 и паузы линия SCL вновь возвращается в состояние 0. На этом чтение байта данных заканчивается. Процедуры формирования стартового бита, стопового и повторного старта сводятся к установке исходных состояний сигналов
5.3. Обмен данными по интерфейсу 12C(TWI) 169 SDA = SCL = 1 и последующих изменений согласно приведенным выше временным диаграммам. Используемые задержки времени (паузы) необходимы для обеспечения надежной передачи. Их устанавливают, согласно рекомендациям, на период и длительность сигнала SCL; время удержания неактивного состояния линий интерфейса; время, предшествующее повторному старту, и др. Практическая часть Работу интерфейса I2C рассмотрим на примере обмена данными между микроконтроллером AT90S8515 и программируемым параллельным портом (ППП) РСА9554 фирмы Philips. Схема сопряжения микроконтроллера МК и параллельного порта ППП приведена на рис. 5.16. Рис. 5.16. Схема связи микроконтроллера с параллельным портом по интерфейсу I2C Порт представляет собой микросхему, имеющую канал последовательной связи I2C, с одной стороны, и 8-разрядный параллельный канал ввода/вывода, с другой стороны. Разряды параллельного порта могут быть запрограммированы на ввод или вывод с помощью 8-разрядного управляющего слова, пересылаемого в регистр управления (конфигурации) порта. Для обращения к ППП в микроконтроллерной системе используется один из восьми адресов в диапазоне $40-$47. При этом три младших разряда определяют путем установки сигналов логического 0 и логической 1 на входах А2-А0. Для обращения к внутренним регистрам порта используется командный байт, значение которого определяет регистр и выполняемую операцию: 0 - чтение данных с входного регистра порта, 1 - запись данных в выходной регистр порта, 2 -
170 5. Обмен данными по последовательному интерфейсу изменение полярности сигналов, 3 - запись в регистр конфигурации (направления передачи). Обращение к порту содержит три посылки: первая служит для передачи адреса, вторая - команды, третья - данных. Обмен с портом выполняется по запросу прерывания, формируемому микросхемой ППП при изменении сигналов на входах порта. Для этого выход INT ППП подключен к входу INTO микроконтроллера (для AT90S8515 линия порта PD2). Задание 1. Подготовить программу для исследования передачи и приема данных по последовательному каналу I2C, используя в качестве ведомого программируемый параллельный порт. Алгоритмом основной программы предусмотрена такая последовательность действий: • инициализация порта микроконтроллера с линиями интерфейса; • настройка системы прерываний микроконтроллера; • временная пауза; • настройка конфигурации ППП; • вызов процедуры обмена с ППП; • перевод микроконтроллера в режим пониженного энергопотребления и ожидания прерываний от ППП. При поступлении запроса выполняются следующие действия: • инициализация обмена с ППП; • формирование состояния Start и посылка адреса; • запись в ППП команды ввода ($00); • изменение направления обмена; • повторный старт; • чтение данных из ППП; • обмен тетрадами; • сохранение данных; • формирование состояния Stop; • формирование состояния Start и посылка адреса; • запись команды вывода ($01); • обратная пересылка данных в ППП; • формирование состояния Stop и выход из прерывания. Далее приведен текст программы на языке Ассемблер для обмена с ППП с включенными процедурами обмена ведущего микроконтроллера по интерфейсу I2C. При программировании протокола I2C ведущего микроконтроллера за основу взята бета-версия 1.0 программы из библиотеки AVR Studio. В программе используются две библиотечные функции задержки: i2c_hp_delay минимум на 5 мкс и i2c_qp_delay минимум на 2,5 мкс.
5.3. Обмен данными по интерфейсу 12C(TWI) 171 Программа 5.5 .******************************** /Тестовая программа 5.5 для работы с программируемым /параллельным портом по интерфейсу I2C. Для ввода и вывода /данных используются по четыре вывода порта. При изменении /сигналов на входах порта на линии INTO вырабатывается /запрос прерывания низкого уровня. По прерыванию происходит /запись входных значений порта ППП и их передача на линии /вывода. .***************************************^ .org 0x000 rjmp RESET /обработка сброса .org 0x001 rjmp UPDATE /обработчик прерывания от ППП .include "8515def.inc" /файл определений AT90S8515 .equ SCLP = б / SCL-pin (PD6) .equ SDAP = 7 / SDA-pin (PD7) .def i2cdelay = rl6 /счетчик цикла задержки .def i2cadr = rl7 /регистр адреса шины I2C .def i2cdata = rl8 /регистр данных шины I2C .equ i2crd = 1 /1-чтение .equ i2cwr = 0 /0-запись .*******************************★*** RESET: main: ldi rl6,HIGH(RAMEND) /установка out sph,rl6 / указателя ldi rl6, LOW(RAMEND) / стека out spl,rl6 / Инициализация интерфейса I2C clr i2cdata /очистка регистра данных out DDRD,i2cdata ldi i2cdata,0x04 out PORTD,i2cdata / Настройки микроконтроллера cli ldi rl6,l«INT0 /разрешение прерывания INTO /(по спаду) out GIMSK,rl6 ldi rl6, (1«SE) I (0«ISC01) I (O«ISC0O) out MCUCR, rl6 sei rcall i2c_hp_delay /пауза в ожидании rcall i2c_hp_delay / готовности всех устройств,
172 5. Обмен данными по последовательному интерфейсу ;rcall i2c_hp_delay ; подключенных к шине ; Настройка конфигурации микросхемы ППП ldi i2cadr, $40+i2cwr /посылка адреса ППП+записи rcall i2c_start /генерация стартового бита ldi i2cdata,$03 rcall i2c_write /команда записи в порт конфигурации ldi i2cdata,$f0 /старшие 4 бита - на ввод, rcall i2c_write /младшие 4 бита - на вывод rcall i2c_stop /генерация стопового бита rcall UPDATE /ввод/вывод через ППП loop: sleep /переход в режим пониженного энергопотреблени пор rjmp loop / Подпрограмма обработки прерывания от ППП UPDATE: ldi i2cadr,$40+i2cwr /посылка адреса ППП+записи rcall i2c_start ldi i2cdata,$00 rcall i2c_write /команда чтения данных из порта ldi i2cadr, $40+i2crd /изменение направления обмена rcall i2c_rep_start set /подтверждения после чтения /не будет rcall i2c_read /чтение данных swap i2cdata /обмен тетрадами mov r20,i2cdata /сохранение rcall i2c_stop /генерация стопового бита clt /сброс флага T ldi i2cadr,$40+i2cwr /изменение направления обмена rcall i2c_start ldi i2cdata,$01 rcall i2c_write /команда вывода данных в порт mov i2cdata,r20 rcall i2c_write /вывод данных rcall i2c_stop /генерация стопового бита reti .************************^ ИМПОРТИРОВАННЫЕ ПОДПРОГРАММЫ, / используемые для работы ведущего МК по протоколу I2C
5.3. Обмен данными по интерфейсу 12C(TWI) .*********************************^ /Для коммуникации используются линии порта PD - PD6(SCL) и ;PD7(SDA).Управление выводами SDA, SCL с открытым стоком /осуществляется путем начальной установки битов PORTx ;в 0 и в дальнейшем с помощью установки/сброса битов /направления DDRx. ;**** Основные функции: **** ;i2c_start - стартовая посылка, посылка адреса и ;направления, ;i2c_rep_start - посылка "повторного старта" (repeated ;start), ;i2c_write - передача байта, i2c_read - прием байта, ;i2c_stop - стоповая посылка .*************************^ г ;Функции задержек .************************************^ i2c_hp_delay: /задержка (на 5 мкс минимум) ldi i2cdelay,2 i 2 c_hp_de1a y_lо op: dec i2cdelay brne i2c_hp_delay_loop ret i2c_qp_delay: ;задержка (на 2,5 мкс минимум) ldi i2cdelay,1 i 2 c_qp_de1a y_lо op: dec i2cdelay brne i2c_qp_delay_loop ret .****************************★******** /Функция повторного старта подготавливает шину I2C к /формированию стартового бита ;3а данной функцией должен следовать вызов i2c_start .*****************************^ i2c_rep_start: rcall i2c_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 /задержка .*****************************^
174 5. Обмен данными по последовательному интерфейсу /Функция формирования стартового бита ;За данной функцией должен следовать вызов i2c_write .★★*★★★★★★*******★**************★*★**★ i2c_start: mov i2cdata,i2cadr sbi DDRD,SDAP /захват SDA rcall i2c_qp_delay /задержка .*****************************^ /Функция записи одного байта в ведомое устройство /Также используется для передачи адреса /За данной функцией должен следовать вызов i2c_get_ack .***********************^ i2c_write: sec /установка флага С rol i2cdata /сдвиг первого бита в С rjmp i2c_write_first i2c_write_bit: lsl i2cdata /посылка следующего бита в С i2c_write_first: breq i2c_get_ack /переход, если передача завершена / (регистр пуст) sbi DDRD, SCLP /захват линии SCL brcs i2c_write_high /если бит установлен, / освободить SDA, i2c_write_low: /иначе sbi DDRD, SDAP / захват SDA rjmp i2c_write_delay i2c_write_high: cbi DDRD,SDAP /освобождение линии SDA i2c_write_delay: rcall i2c_hp_delay /задержка cbi DDRD,SCLP /освобождение линии SCL rcall i2c_hp_delay /задержка i2c_write_check_wait: sbis PIND,SCLP /ожидание состояния SCL=1 rjmp i2c_write_check_wait rjmp i2c_write_bit .★****★★*★★*★*★***★★*★***★******★**★★★★
5.3. Обмен данными по интерфейсу 12C(TWI) 175 /Функция чтения подтверждения. Используется функцией ;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 ret •**************************************^ /Функция чтения одного байта от ведомого в регистр /i2c_data /Значение флага С=1 используется как признак конца приема /После данной функции должна следовать функция i2c_put_ack .********************************* i2c_read: /Загружаем $01 - это после приема данных приведет к /установке флага С ldi i2cdata,0x01 i2c_read_bit: sbi DDRD,SCLP /захват линии SCL rcall i2c_hp_delay /задержка cbi DDRD,SCLP /освобождение линии SCL i2c_read_check_wait: sbis PIND,SCLP /ожидание состояния SCL=1 rjmp i2c_read_check_wait rcall i2c_hp_delay /задержка clc /сброс флага С sbic PIND,SDAP /если SDA=1, sec /установка флага С rol i2cdata /сохранение принятого бита
176 5. Обмен данными по последовательному интерфейсу brcc i2c_read_bit /прием закончен, когда флаг С=1 .★**★★★★★*******★**★***★***★****★** г /Функция формирования подтверждения. Используется функцией /i2c_read /При значении флага Т=1 подтверждение не формируется, /после чего обычно формируется стоповый бит /При Т=0 формируется подтверждение приема .★**★**★*****★★*★★★*******★★**★**** 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: rcall i2c_hp_delay /задержка cbi DDRD,SCLP /освобождение линии SCL i2c_put_ack_wait: sbis PIND,SCLP /ожидание освобождения SCL rjmp i2c_put_ack_wait rcall i2c_hp_delay /задержка sbi DDRD,SCLP ret .**★***★★***★★★****★*****★*★★★**★*****★** /Функция формирования стопового бита .**★★***★*************★*********★★★★* 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 Создать проект в AVR Studio 4 и загрузить тестовую программу. Проверить работу МК в пошаговом режиме, наблюдая выходы
5.3. Обмен данными по интерфейсу 12C(TWI) 177 Модуль интерфейса TWI Ряд микроконтроллеров семейства ATmega содержит встроенный модуль интерфейса TWI, позволяющий выполнять обмен данными по последовательному каналу в различных режимах. Упрощенная структурная схема модуля приведена на рис. 5.17. Модуль содержит блок шинного интерфейса (SDA, SCL) с регистром данных TWDR и контроллером состояний Start/Stop, блок контроля адреса с регистром адреса TWAR и схемой сравнения, блок управления с регистрами управления TWCR и состояния TWSR, контроллер скорости передачи с предделителем и регистром скорости TWBR. Рис. 5.17. Структура модуля TWI порта PD (PD6, PD7). Эмуляцию сигналов с порта ППП при чтении данных можно выполнить, устанавливая ручным способом биты данных на линии SDA (разряд PIND7). Чтобы ускорить прогон программы, рекомендуется перед компиляцией закомментировать строки программы с проверкой состояния линии SCL. Создать проект устройства, используя схему рис. 5.16, для проверки работы канала I2C с помощью программы ISIS 6 Professional из пакета Proteus 6 Professional фирмы Labcenter Electronic. Проверить работу устройства в пошаговом режиме.
178 5. Обмен данными по последовательному интерфейсу Регистр данных TWDR обеспечивает параллельную загрузку байтов и последовательный вывод данных на линию SDA путем сдвига содержимого регистра влево в сторону старших разрядов. Регистр адреса TWAR используется при работе микроконтроллера в качестве ведомого. Код, записанный в семи старших разрядах регистра, представляет собственный адрес микроконтроллера. Этот код сравнивается компаратором с адресом, поступающим в микроконтроллер при появлении адресного пакета в регистре TWDR. Младший бит TWGCE регистра TWAR разрешает распознавание общих вызовов (обращений с адресом $00). Если разряд TWGCE = 0, распознавание общих вызовов запрещено. Управление работой порта осуществляется с помощью регистров TWCR (табл. 5.6) и TWSR (табл. 5.7). Таблица 5.6. Формат регистра управления TWCR № разряда 7 6 5 4 3 2 1 0 Имя TW1NT TWEA TWSTA TWSTO TWWC TWEN - TWIE Таблица 5.7. Формат регистра состояния TWSR № разряда 7 6 5 4 3 2 1 0 Имя TWS7 TWS6 TWS5 TWS4 TWS3 - TWPS1 rwpso Биты регистра TWCR имеют следующее назначение: TWEN - бит разрешения работы модуля TWI. При установке бита в состояние 1 выводы SDA, SCL подключаются к внешним выводам микроконтроллера РС1, РСО соответственно для всех ранее названных моделей микроконтроллеров, кроме ATmega8x (выводы РС4, РС5) и Atmega 64х, 128x(PDl, PDO); TWSTA - флаг состояния Start. При установке бита в единичное состояние микроконтроллер может сформировать состояние Start, если шина свободна. Если шина занята, модуль ожидает появления состояния Stop и лишь после этого захватывает шину, формируя состояние Start; TWSTO - флаг состояния Stop. Установка флага в состояние 1 приводит к формированию на шине состояния Stop; TWEA - бит разрешения подтверждения. При установке бита в 1 устройство формирует сигнал подтверждения, когда это необходимо;
5.3. Обмен данными по интерфейсу 12C(TWI) 179 TWIE и TWINT - флаги разрешения и прерывания от модуля TWL Запрос прерывания генерируется, если TWINT = 1 и TWIE = = 1. Сброс флага TWINT может быть осуществлен только при записи в него логической 1; TWWC - флаг, устанавливаемый в 1 при попытке записи в регистр данных TWDR, когда флаг прерывания TWINT сброшен. Биты регистра TWSR: TWS7.. .TWS3 - код состояния модуля TWI; TWPS1:TWPS0 - коэффициент деления предделителя контроллера скорости передачи. Контроллер скорости передачи формирует последовательность тактовых сигналов, поступающих на линию SCL. Частота формируемых сигналов зависит от коэффициентов деления TWBR и Таблица 5.8. Таблица коэффициентов для выбора скорости обмена по TWI TWBR TWPS fscb 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 TWPS, загружаемых в регистры TWBR и TWSR, и для разных моделей микроконтроллеров рассчитывается по формулам: - для ATmegal63x, ATmega323x fSCL =/ак/№ + 2TWBR); - для моделей ATmega 8х, 16х, 32х, 64х, 128х fscL =/clk / (16 + + 2TWBR*4TWPS). Значения коэффициентов деления для различных частот /ык и fscL приведены в табл. 5.8. При работе модуля в качестве ведомого скорость обмена зависит от импульсной последовательности, поступающей в микроконтроллер через вывод SCL. Модуль TWI может работать в следующих режимах: - ведущий с передачей байтов данных; - ведущий с приемом байтов данных;
180 5. Обмен данными по последовательному интерфейсу - ведомый с приемом байтов данных; - ведомый с передачей байтов данных. Процедура передачи одного байта данных от ведущего к ведомому представляет собой определенную последовательность действий. 1. В регистр TWCR выводится команда для формирования состояния Start. Для этого необходимо установить в 1 бит TWSTA (TWSTA = 1), сбросить флаг TWINT (TWINT = 1) и установить бит активизации модуля TWI (TWEN =1). После формирования состояния Start флаг TWINT устанавливается в 1. Для перехода к следующему действию выполняется проверка кода состояния $08 в регистре TWSR. (Ожидание установки флага TWINT можно заменить обработкой запроса прерывания. - Прим. авт.) Программная реализация функции старта представлена далее в программе 5.6 процедурой SendStart. 2. Содержимое пакета с адресом и нулевым значением бита направления записывается в регистр TWDR. Передача инициализируется сбросом флага TWINT. После завершения передачи адреса и получения бита подтверждения флаг TWINT устанавливается в 1, а в регистре TWSR устанавливается код статуса $18. Программная реализация функции записи представлена в программе процедурой SendAdr. 3. После проверки кода статуса в регистр данных TWDR загружается байт данных для передачи и сбрасывается флаг TWINT. По окончании передачи данных и получения бита подтверждения флаг TWINT устанавливается в 1, а в регистре TWSR устанавливается код статуса $28. Эти действия обеспечивают передачу от ведущего устройства ведомому как команд, так и данных. Программная реализация функции вывода данных (а также команд) представлена в программе процедурой SendComData. 4. После успешного завершения передачи выполняются команды для формирования состояния Stop. Программная реализация функции представлена в программе процедурой Stop. Кратко определим последовательность действий, выполняемых при приеме одного байта данных ведущим устройством: 1) в регистр TWCR выводится команда для формирования состояния Start; после формирования состояния Start флаг TWINT устанавливается в 1. Для перехода к следующему действию выполняется проверка кода состояния ($08) в регистре TWSR. (Ожидание установки флага TWINT также можно заменить обработкой запроса прерывания. - Прим. авт.);
5.3. Обмен данными по интерфейсу 12C(TWI) 181 2) содержимое пакета с адресом и единичным значением бита направления записывается в регистр TWDR и инициализируется передача. После завершения передачи адреса и получения бита подтверждения флаг TWINT устанавливается в 1, а в регистре TWSR устанавливается код статуса ($40); 3) после сброса флага TWINT (разрешения приема) и получения байта данных от ведомого данные из регистра TWDR переписываются в один из регистров общего назначения. При успешном приеме код статуса в регистре TWSR принимает значение $50. При необходимости формируется бит подтверждения приема; 4) после завершения приема выполняется команда для формирования состояния Stop. Последовательность действий, выполняемых при приеме одного байта данных ведомым устройством, можно определить следующим образом: 1) в регистр TWCR выводится команда, сбрасывающая флаг TWINT; 2) после приема первого байта с адресом ведомого устройства формируется запрос прерывания, проверяется код статуса в регистре TWSR; если он равен $60, прием собственного адреса выполнен успешно; 3) передается бит подтверждения путем установки TWEN = 1 и выполняется сброс флага TWINT; 4) проверяется код статуса в регистре TWSR (если он равен $80, значит в регистр TWDR принят байт данных); передается бит подтверждения (TWEN = 1) и выполняется сброс флага TWINT; Действия 4-го шага повторяются, пока не будет принято все сообщение. При поступлении состояния Stop в регистре TWSR формируется код статуса $А0 (конец пакета). Подобным образом можно представить действия ведомого устройства при передаче данных. Подробное описание всех вариантов обмена и формируемые при этом значения статусных кодов можно найти в технической документации применяемой модели микроконтроллера. Практическая часть Работу встроенного модуля TWI рассмотрим на примере вывода данных из микроконтроллера ATmega8x в параллельный порт РСА9554 для индикации. Схема сопряжения микроконтроллера МК и параллельного порта приведена на рис. 5.18.
182 5. Обмен данными по последовательному интерфейсу Рис. 5.18. Схема устройства для обмена данными с ППП по интерфейсу TWI Задание 2. Подготовить программу для проверки обмена данными между микроконтроллером и параллельным портом, используя встроенный модуль интерфейса TWI. В качестве примера ниже приведена программа 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 /после старта
5.3. Обмен данными по интерфейсу 12C(TWI) 183 .equ MT_SLA_ACK = 0x18 ;после передачи адреса .equ MT_DATA_ACK = 0x28 /после передачи данных init: ldi rl6,HIGH(RAMEND) /инициализация out sph,rl6 / указателя стека ldi r 16,LOW(RAMEND) out spl,rl6 /Подготовка TWI к работе ldi rl6,12 / Для частоты Fclk = 4 МГц out TWBR,rl6 / TWBR=12 TWPS=0 ldi rl6, (1«TWEN) / Fscl=100 КГц out TWCR,rl6 ldi r20,0xAA / данные для вывода /Настройка микросхемы ППП rcall Send_Start /генерация стартового бита ldi SLA_W,$40+i2cwr /посылка адреса+записи rcall Send_Adr ldi DATA,$03 /команда записи в порт /конфигурации rcall Send_Com_Data ldi DATA,0x00 /настройка ППП на вывод rcall Send_Com_Data rcall Stop /генерация стопового бита /Вывод данных loop: rcall Send_Start /генерация стартового бита ldi SLA_W,$40+i2cwr /посылка адреса+записи rcall Send_Adr ldi DATA,$01 /выходной регистр rcall Send__Com_Data mov DATA,r20 /вывод данных rcall Send_Com_Data rcall Stop /генерация стопового бита com r20 /инвертирование rjmp loop /повторение вывода .*************************★*****★******* / Функции режима ведущего передатчика .*******************★****************** Send_Start: ldi rl6, (1«TWINT) I (1«TWSTA) | (1«TWEN) out TWCR,rl6 /условия для состояния START
184 5. Обмен данными по последовательному интерфейсу waitl: in rl6,TWCR sbrs г16,TWINT /ожидание установки флага TWINT rjmp waitl in rl6, TWSR andi rl6,0xF8 cpi rl6,START /проверка выполнения старта brne error ret Send_Adr: out TWDR,SLA_W /загрузка пакета с адресом ldi rl6, (1«TWINT) I (1«TWEN) out TWCR,rl6 /передача wait2: in rl6,TWCR sbrs r16,TWINT /ожидание установки флага TWINT rjmp wait2 in rl6,TWSR andi rl6,0xF8 cpi rl6,MT_SLA_ACK /проверка выполнения передачи brne error ret Send_Com_Data: out TWDR,DATA /загрузка байта данных ldi rl6, (1«TWINT) I (1«TWEN) out TWCR,rl6 /передача wait3: in rl6,TWCR sbrs r16, TWINT /ожидание установки флага TWINT rjmp wait3 in rl6,TWSR andi rl6,0xF8 cpi r16,MT_DATA_ACK /проверка выполнения передачи brne error ret Stop: ldi rl6, (1«TWINT) | (1«TWEN) | (l«TWSTO) out TWCR,rl6 / условия для состояния STOP ldi rl6,0xlf wait4:dec rl6 /задержка для состояния STOP brne wait4 ret error: ret
5.3. Обмен данными по интерфейсу 12C(TWI) 185 Рис. 5.19. Схема устройства с интерфейсом TWI между двумя микроконтроллерами Задание 3. Подготовить программы обмена данными для ведущего и ведомого микроконтроллеров. Проверить работу интерфейса TWI, по которому выполняется передача сообщения из микроконтроллера МК1 в МК2 (рис. 5.19), с помощью двух наборов STK500 по методике контроля работы интерфейса SPI, описанной в 5.2. Взамен внешних резисторов, требуемых спецификацией интерфейса, использовать внутренние подтягивающие резисторы выводов РС4, РС5 ведомого микроконтроллера. В роли ведущего выступает микроконтроллер МК1, в роли ведомого - микроконтроллер МК2. Рабочий режим МК2 - режим ожидания. После передачи сообщения просмотреть коды символов сообщения на светодиодах, нажимая кнопку SW0. Программа передачи ведущего микроконтроллера строится подобно 5.6. Каждый передаваемый пакет содержит служебные биты, байт адреса и байт данных. Ниже приведен основной модуль программы для передачи трех символов сообщения по интерфейсу TWI. Функции SendStart, SendAdr, Send_Com Data, Stop те же, что и в программе 5.6. Программа 5.7 г /Основной модуль программы 5.7 для передачи сообщения ведущим микроконтроллером МК1 по интерфейсу TWI /Вызываемые функции Send_Start, Send_Adr, Send_Com_Data, /Stop из программы 5 . б /Соединения: РС4мк1-РС4мк2, РС5мк1-РС5мк2
186 5. Обмен данными по последовательному интерфейсу .org 0x000 rjmp init .include "m8def.inc" ;файл определений ATmega8 .def temp = rl6 .def SLA_W = rl7 /адресный байт .def DATA = rl8 /байт данных (команды) .def count = rl9 /счетчик данных .equ i2cwr = 0 /0-запись .★*** Коды статуса в режиме ведущий передатчик **** .equ START = 0x08 /после старта .equ MT_SLA_ACK = 0x18 /после передачи адреса .equ MT_DATA_ACK = 0x28 /после передачи данных init: ldi rl6,HIGH(RAMEND) /инициализация out sph,rl6 / указателя стека ldi rl6,LOW(RAMEND) out spl,rl6 ldi ZL,low(text*2) /загрузка адреса текста ldi ZH,high(text*2) / сообщения в регистр Z ldi count,3 /установка счетчика передач /Подготовка TWI к работе ldi г16,12 /для частоты Fclk = 4 МГц out TWBR,rl6 / TWBR=12, TWPS=0 ldi rl6, (1«TWEN) / Fscl=100 КГц out TWCR,rl6 output: /вывод данных rcall Send_Start /генерация стартового бита ldi SLA_W,$44+i2cwr /посылка адреса+записи rcall Send_Adr lpm /считывание байта из /flash-памяти в r0 mov DATA,г0 /вывод данных rcall Send_Com_Data rcall Stop /генерация стопового бита adiw zl,l /увеличение указателя адреса на 1 dec count /уменьшение счетчика на 1 brne output loop: rjmp loop /передача выполнена text: .db 'A', 'V, 'R' /текст сообщения / (ASCII - коды $41, $56, $52)
5.3. Обмен данными по интерфейсу 12C(TWI) 187 Программа ведомого микроконтроллера может иметь следующую структуру: а) начальная инициализация микроконтроллера, включая определение указателя стека, счетчика принимаемых данных, настройку портов, подготовку модуля TWI; б) разрешение прерываний и переход в режим ожидания прерываний; в) обработка запросов прерываний от модуля TWI, обеспечивающая прием пакетов с байтами адреса, команды и данных; сохранение байтов сообщения во внутренней памяти SRAM; подсчет числа байтов принятого сообщения; по окончании приема - последовательный вывод байтов сообщения при нажатии кнопки SW0. Ниже приведен фрагмент программы ведомого микроконтроллера, включающий процедуру инициализации, и обработчик прерываний от модуля TWI, обеспечивающий прием сообщения по интерфейсу TWI и сохранение в памяти. Программа 5.8 .**************************************** г /Программа 5.8 приема по интерфейсу TWI для ведомого микроконтроллера МК2(основной фрагмент программы) /Соединения: SW0-PB0, шлейфом порт PD-LED .*****************************^ г .org 0x000 rjmp init .org 0x011 rjmp TWI_INT /переход к обработке /прерывания .include "m8def.inc" /файл определений ATmega8 .def count = r22 /счетчик данных .def temp = rl6 .equ SHOW=0 /для подпрограммы OUTLED /****Коды статуса в режиме ведомого**** .equ TW_SR_SLA_ACK = 0x60 /принят байт с адресом .equ TW_SR_DATA_ACK = 0x80 /принят байт данных .equ TW_SR_STOP = 0хА0 /обнаружено состояние STOP /**инициализация ведомого мк*** init: ldi rl6,HIGH(RAMEND) out sph,rl6 ldi r16,LOW(RAMEND)
188 5. Обмен данными по последовательному интерфейсу out spl,rl6 clr temp /настройка out DDRB,temp ; вывода порта РВО sbi PORTB,0 ; на ввод, ser temp out DDRD,temp ; выводов порта PD out PORTD,temp ; на вывод ldi count,3 ;установка счетчика байтов ldi XL,0x80 ;в регистре X адрес, по которому ldi XH,0x01 ; происходит запись принятых данных /Подготовка модуля TWI к работе ldi temp,0x30 ;подключение подтягивающих резисторов out PORTC,temp ; на линиях SCL,SDA ldi г16,12 ;для Fclk = 4 МГц, TWBR=12, out TWBR,rl6 ; TWPS=0 Fscl=100 КГц ldi г1б,0х44 /адрес устройства I2C out TWAR,rl6 ldi rl6, (1«TWINT) I (1«TWEA) | (1«TWIE) I (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 ldi rl6, (1«TWINT) I (1«TWEA) | (1«TWEN) out TWCR,rl6 TW_WAIT_DATA: in rl6,TWSR cpi rl6,TW_SR_DATA_ACK;2-fl проверка brne TW_WAIT_DATA in rl6,TWDR st X+,rl6 /сохранение байта данных в памяти ldi rl6, (1«TWINT) I (1«TWEA) | (1«TWEN) out TWCR,rl6
5.3. Обмен данными по интерфейсу 12C(TWI) 189 Полные тексты программ для ведущего и ведомого микроконтроллеров можно найти на сайте (проекты 57 и 58). Задание 4. Изменить программу 5.7, выполнив передачу в одном пакете одного байта адреса и всех байтов сообщения. Задания для самостоятельного программирования 1. Написать и отладить программу для режима ведущего микроконтроллера с приемом данных по интерфейсу TWI, используя встроенный модуль TWI. 2. Написать и отладить программу для ведущего микроконтроллера, выполняющего ввод 4-разрядного кода через младшие разряды порта ППП и вывод принятых данных через старшие разряды порта по интерфейсу TWI, используя встроенный модуль TWI. 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: ldi rl6, (1«TWINT) I (1«TWEA) | (1«TWIE) I (1«TWEN) out TWCR,rl6 /перезапуск интерфейса reti ;***Вывод на индикаторы*** OUTLED: clr temp /сигнализация - out PORTD,temp ; прием завершен ldi XL,0x80 /установка начального адреса ldi count,3 /установка счетчика байтов WAIT_SHOW: sbic PINB, SHOW;ожидание нажатия rjmp WAIT_SHOW / кнопки SHOW Id temp,X+ /считывание байта из памяти com temp /инвертирование и out PORTD,temp / вывод на светодиоды rcall DELAY /задержка из программы 5.4 dec count /если показаны не все данные, brne WAIT_SHOW / продолжение по нажатию SHOW ret .****************************^
190 5. Обмен данными по последовательному интерфейсу Контрольные вопросы 1. Как осуществляется асинхронный обмен данными по последовательному интерфейсу? Как остановить прием сообщения, длина которого заранее неизвестна? 2. Как организовать вывод данных из программной Flash- памяти микроконтроллера? 3. Сколько регистров данных в устройстве UART и в окне программы AVR Studio 4? 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).
192 6. Организация ввода/вывода данных по параллельному интерфейсу Рис. 6.1. Матричная клавиатура Один ряд линий, например вертикальных, подключают к входному регистру, другой ряд (горизонтальных) - к выходному регистру. На входной регистр из контроллера подают код, содержащий 0 в одном разряде и единицы во всех остальных. При замыкании кнопки вертикального ряда, на котором присутствует сигнал О, этот сигнал поступит в горизонтальную линию и по ней на выходной регистр. Проверив состояние выходного регистра, контроллер может идентифицировать строку, а вместе со столбцом и номер замкнутой кнопки. С помощью последовательности сканирующих кодов вида 1110, 1101, 1011,0111 можно опросить состояние всех столбцов клавиатуры и установить номер замкнутой кнопки (клавиши). Используя его как индекс, можно выбрать из таблицы переходов начальный адрес процедуры, выполняемой при замыкании соответствующей кнопки. На рис. 6.2 приведен алгоритм опроса клавиатуры размером N*M и определения номера замкнутой кнопки. Перед началом цикла опроса устанавливают начальное значение m-разрядного сканирующего кода и параметры циклов. Счетчик проверяемых кнопок (num) сбрасывается в исходное состояние 0. Алгоритм опроса клавиатуры представляет собой циклическую процедуру с вложенным циклом. Во внешнем цикле выполняется вывод сканирующего кода на входной регистр клавиатуры, затем ввод с выходного регистра слова состояния выбранного столбца клавиатуры. Внутренний цикл охватывает сдвиг считанного слова влево на один разряд с последующим анализом выдвинутого бита. При выполнении операции сдвига в микроконтроллере выдвигаемый бит попадает на флаг С. При С = 0 идентифицируется замыкание кнопки с номером, значение которого определено переменной num, и происходит выход из цикла. При С = 1 увеличивается на единицу значение num, повторяется сдвиг и новая проверка флага С. Если внутренний цикл не выявил факт замыкания (С = 1), выполняется выход из внутреннего цикла, сдвиг сканирующего кода влево на один разряд и повторение описанных действий. Как видно из алгоритма, его легко адаптиро-
6.1. Взаимодействие с клавиатурой и ЖК-дисплеем 193 вать к клавиатуре любой размерности путем изменения параметров циклов (л, т). Клавиатура, не имеющая входного и выходного регистров, может быть непосредственно подключена к выходному и входному портам микроконтроллера соответственно. Клавиатуру небольшой размерности 4x4 можно подключить к одному 8-разрядному порту, одна половина которого программируется на вывод, другая - на ввод. В качестве резисторов, устанавливаемых в горизонтальных линиях клавиатурной матрицы, используют подтягивающие резисторы разрядов порта микроконтроллера, работающих на ввод. Следует иметь в виду, что в разных конструкциях клавиатур масса и габариты кнопок могут сильно различаться. Из-за этого при замыкании и размыкании возникают импульсные помехи - дребезг контактов, который продолжается 20 мс и более в зависимости от типа кнопки, и др. Для борьбы с помехами клавиатуры могут быть выполнены со схемами подавления дребезга контактов в виде триггеров. При отсутствии подобных средств можно программными средствами предусмотреть блокировку от ложных срабатываний, например, повторив опрос состояния спустя 20 мс для подтверждения факта замыкания. Процедура опроса клавиатуры осуществляется периодически через определенный интервал времени, например через 50 мс, либо по сигналу запроса, формируемому клавиатурой при замыкании любой из кнопок. Первый способ можно реализовать, настроив таймер микроконтроллера на отсчет временного интервала, определяющего период опроса. Второй способ можно реализовать в тех микроконтроллерах, порты которых формируют запрос прерывания при изменении состояния порта, как, например, в микроконтролле- 7 —1998 Рис. 6.2. Схема алгоритма опроса клавиатуры
194 6. Организация ввода/вывода данных по параллельному интерфейсу pax серии 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
6.1. Взаимодействие с клавиатурой и ЖК-дисплеем 195 Система команд контроллера 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) или5х 10 точек (F = 1) 40 мкс Т
196 6. Организация ввода/вывода данных по параллельному интерфейсу Окончание табл. 6.1 № D7 D6 D5 D4 D3 D2 Dl DO Описание команды Время 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. $00 Окно дисплея / Буфер данных $40 .Курсор 1 Буфер данных Символьные данные для отображения на дисплее поступают в коде ASCII в буфер контроллера дисплея, объем которого составляет 80 байтов. В зависимости от режима отображения (однострочный или двухстрочный) данные для вывода на экран представляют один 80-байтовый массив или два массива по 40 байтов каждый. При двухстрочном выводе начальный адрес верхней строки (строка 0) составляет $00, для нижней (строка 1) - $40. Количество позиций в строке дисплея зависит от его типа. В модели LM016L длина строки составляет 16 позиций. Из этого следует, что длина буферного массива превышает число позиций дисплея. Поэтому для отображения всех элементов массива данных окно дисплея перемещается вдоль массива (рис. 6.4). Все элементы, попадающие в окно, отображаются на экране дисплея, остальные остаются вне зоны видимости. Курсор отоб- Рис. 6.4. Схема отображения символьной информации на двухстрочном дисплее
6.1. Взаимодействие с клавиатурой и ЖК-дисплеем 197 ражается на экране, если предварительно была введена команда отображать его и он находится в зоне видимости. В программе после передачи каждого символа данных необходимо предусмотреть временную задержку 40 мкс. Процедуру инициализации дисплея и вывода сообщения из программной памяти микроконтроллера можно представить в виде последовательности действий. При начальной инициализации: 1) установка 8-битового режима вывода в две строки шрифтом 5x7, задержка; 2) задание направления сдвига курсора вправо без сдвига дисплея, задержка; 3) включение дисплея, гашение курсора, задержка; 4) очистка дисплея и установка курсора в нулевую позицию, задержка; 5) задержка 2 мс. При выводе сообщения: 6) установка адреса буферной памяти для вывода верхней строки дисплея, задержка; 7) считывание байта сообщения из памяти и передача в дисплей, задержка, 8) повторение п. 7 для вывода всех символов сообщения в верхнюю строку; 9) установка адреса буферной памяти для вывода нижней строки дисплея, задержка; 10) вывод символа на дисплей при замыкании кнопки, задержка; 11) повторение п. 10 до заполнения строки дисплея; 12) очистка дисплея и установка курсора в нулевую позицию, 13) задержка 2 мс и продолжение вывода. Программирование интерфейсов. Программирование обмена с клавиатурой и ЖК-дисплеем рассмотрим на примере проекта, в котором предусмотрен ввод с клавиатуры простого калькулятора размером 4x4, подключенного к микроконтроллеру АТ908515, и вывод на ЖК-дисплей LM016L постоянного информационного сообщения в начале работы и затем вывод кнопочных символов клавиатуры (цифр 0 - 9 и символов операций +, -, х5 /). Для соединения с внешними устройствами используем порты микроконтроллера (PD - для клавиатуры, РС - для передачи команд и данных на ЖК-дисплей, РА - для передачи управляющих сигналов на дисплей). Схема проекта изображена на рис. 6.5.
6.1. Взаимодействие с клавиатурой и ЖК-дисплеем 199 ;линии) соединены с выходами PD0-PD3, выходы клавиатуры /(горизонтальные линии) - с входами PD4-PD7. .************************************ г .include "8515def.inc" /файл определений AT90S8515 .def temp=rl6 /временная переменная .def cols=rl8 /номер сканируемого ряда / клавиатуры .def rots=r21 /номер строки клавиатуры .def key=rl9 /номер кнопки .def scancod=r2 0 /сканирующий код .def lcd=r22 /регистр LCD (ЖК-дисплея) .def count_lcd=r23 /счетчик выводимых символов / на 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: ldi temp,low(RAMEND) /инициализация out spl,temp / указателя стека ldi temp,high(RAMEND) out sph,temp /Инициализация портов ser temp out DDRA,temp /порт PA на вывод out DDRC,temp /порт PC на вывод ldi temp,$0F /линии порта PD0-PD3 на вывод, out DDRD,temp / PD4-PD7 на ввод ldi temp,$F0 out PORTD,temp /Инициализация таймера 0 ldi temp,$05 out TCCR0,temp /коэффициент деления 1024 ldi temp, (l«TOIE0) out TIMSK, temp /разрешение прерываний от таймера /Инициализация ЖК-дисплея rcall delay2ms
198 6. Организация ввода/вывода данных по параллельному интерфейсу AT90S8515 Рис. 6.5. Схема соединения микроконтроллера с клавиатурой и ЖК-дисплеем Программирование операций ввода/вывода представлено программой 6.1. После инициализации портов микроконтроллера, таймера и дисплея производится однократный вывод сообщения на верхнюю строку дисплея. Поскольку текст сообщения не изменяется при повторных запусках программы, он размещен в памяти программ. Символы кнопок отображаются на нижней строке дисплея. В этом случае по номеру замкнутой кнопки происходит обращение к таблице их символьных обозначений, откуда извлекается ASCII-код и пересылается в буфер дисплея. После заполнения строки дисплея весь экран очищается с помощью соответствующей команды, вывод на экран продолжается с начальной позиции. Программа 6.1 .*********************************** /Программа 6.1 для демонстрации работы интерфейса /с клавиатурой 4x4 и двухстрочным ЖК-дисплеем с встроенным /контроллером HD4 4 7 80, передачей байтов команд и данных по ;8-разрядной шине через порт РС. Управляющие сигналы /поступают на дисплей из МК по линиям РА5-РА7. Клавиатура /подключена к порту PD: входы клавиатуры (вертикальные
200 6. Организация ввода/вывода данных по параллельному интерфейсу ldi led,$38 ;8-битовый режим вывода, rcall ledcom ; 2 строки, шрифт 5x7 ldi led,$06 /Направление сдвига курсора вправо, без сдвига дисплея rcall ledcom ldi led,$0C /включить дисплей, rcall ledcom / погасить курсор ldi led,$01 /Очистить дисплей и установить курсор в нулевую позицию rcall ledcom rcall delay2ms /Установка адреса буферной памяти для вывода верхней /строки дисплея ldi led,$80 rcall ledcom ldi count_lcd,12 /вывод на верхнюю строку дисплея ldi zl,low(str_0*2) ldi zh,high(str_0*2) outO: 1pm adiw zl,1 mov lcd,r0 rcall leddat dec count_lcd brne outO /Установка адреса буферной памяти для вывода нижней строки /дисплея ldi lcd,$C0 rcall ledcom ldi count_lcd,17 sei /разрешение прерываний loop: rjmp loop /Подпрограмма обработки клавиатуры scankeys: clr key clr scancod ldi cols,4 sec scan: rol scancod /формирование очередного скан-кода out PORTD,scancod /вывод на клавиатуру clc ldi rots,4 in temp,PIND /ввод состояния клавиатуры mm:rol temp brcc nn /проверка замыкания кнопки
6.1. Взаимодействие с клавиатурой и ЖК-дисплеем 201 rjmp press /переход при замыкании (С=0) nn: inc key /увеличение номера кнопки dec rots /уменьшение номера строки brne mm dec cols /уменьшение номера ряда brne scan press: cpi key,16 breq fl /выход при отсутствии замыканий rcall lcd_str_l /вывод на дисплей fl: reti /Подпрограмма вывода значения клавиши на нижнюю строку /дисплея lcd_str_l: dec count_lcd brne met /При достижении конца строки обновить счетчик вывода на /дисплей, очистить дисплей и установить курсор в нулевую /позицию ldi count_lcd,16 ldi led,$01 rcall ledcom rcall delay2ms /Установка адреса буферной памяти на начало нижней строки ldi lcd,$C0 rcall ledcom /Определение символа клавиши по ее номеру и вывод на /дисплей met: ldi zl,low(str_l*2) ldi zh,high(str_l*2) add zl,key brcc me2 inc zh me2: 1pm mov led, rO rcall leddat ret /Подпрограмма вывода на дисплей байта команды ledcom: out PORTC,lcd /вывод команды ldi temp,0x80 /установка режима записи команд out PORTA, temp cbi PORTA,e /фронт 1/0 cipo6a rcall delay40us
202 6. Организация ввода/вывода данных по параллельному интерфейсу ret /Подпрограмма вывода на дисплей байта данных lcddat: out PORTC,lcd /вывод символа ldi temp,0xA0 /установка режима записи данных out PORTA,temp cbi PORTA,e /фронт 1/0 строба rcall delay40us ret delay40us: /задержка 40 мкс при Fclk = 3,69 МГц ldi rl8,48 dO: dec rl8 brne dO ret delay2ms: /задержка 2 мс ldi rl7,48 dl:rcall delay40us dec rl7 brne dl ret / Текст сообщения для верхней строки дисплея str_0: .db 'К', 'Е', 'У, 'Р', 'А', 'D', ' ',' + ',' 1, 'L' , 'С 1 , 'D' / Обозначения клавиш, выводимые на нижнюю строку дисплея str_l: .db '/' , 'х' , ■- ^, + ^,9^,б^,з^, = ^,8^,5^'2^,o^,7^f4^,l^,*, Задание 1. Запустить программу AVR Studio 4. Подготовить программу 6.1 для компиляции. Получить файл с расширением .hex, выполнив команды Project! Build. Запустить программу Proteus/ ISIS для симуляции проекта с виртуальными устройствами, клавиатурой и дисплеем. Создать проект согласно схеме рис. 6.5. Выделив правой кнопкой мыши обозначение микроконтроллера, щелчком левой кнопки открыть окно настройки и указать путь к hex-файлу, полученному в AVR Studio 4. Запустить программу на выполнение. Нажимая кнопки виртуальной клавиатуры, убедиться в правильной работе программы обмена, наблюдая символы кнопок, выводимые на дисплей. Задание 2. Изменить схему проекта, заменив клавиатуру 4x4 клавиатурой 6x4. Внести соответствующие изменения в программу. Проверить работу программы на модели с виртуальными устройствами.
6.2. Организация асинхронного параллельного обмена. 203 Задание 3. Изменить программу, предусмотрев вывод символов на дисплей в направлении справа налево. Проверить работу программы. Задание 4. Изменить программу, предусмотрев вывод команд и данных на дисплей по 4-разрядной шине данных. Проверить работу программы. Задание 5. Подключить к разъемам STK500 схему дисплея и блок клавиатуры. Загрузить программу и проверить ее работу. (В комплекте STK500 эти устройства отсутствуют, поэтому задание можно выполнить при наличии соответствующих устройств клавиатуры и дисплея. - Прим. авт.) 6.2. ОРГАНИЗАЦИЯ АСИНХРОННОГО ПАРАЛЛЕЛЬНОГО ОБМЕНА ДАННЫМИ С КВИТИРОВАНИЕМ Цель работы - изучение режимов ввода/вывода информации через порты микроконтроллера и организация асинхронного параллельного обмена данными с квитированием. Асинхронный обмен между микроконтроллером и ВУ можно осуществить различными способами. Способ с опросом состояния внешнего устройства. При этом способе микроконтроллер считывает из контроллера адресованного ВУ слово состояния (SW) ВУ. Если бит готовности в слове состояния указывает на готовность ВУ к обмену данными, микроконтроллер запускает эту операцию (чтение при вводе или запись при выводе). При вводе данных микроконтроллер посылает ВУ сигнал чтения по линии управления, разрешающий передачу данных, получив который ВУ возвращает микроконтроллеру байт данных. При выводе микроконтроллер выводит в порт данные и посылает управляющий сигнал записи (Строб данных) по линии управления, по которому осуществляется фиксация данных в ВУ. Алгоритмы процедур асинхронного ввода и вывода приведены на рис. 6.6. Способ с использованием квитирующих сигналов. Этот способ позволяет выполнить обмен между двумя устройствами - ведущим (инициатором обмена) и ведомым. Напомним, что квитирующими называют сигналы, получаемые от ведомого устройства и используемые для подтверждения действия, инициированного ведущим устройством. Протокол обмена с
204 6. Организация ввода/вывода данных по параллельному интерфейсу квитированием рассмотрим на примере обмена микроконтроллера с одним ВУ, непосредственно адресуемым сигналом запроса, поступающим на вход устройства и заменяющим его адрес. По сигналу запроса микроконтроллера ВУ информирует микроконтроллер о своей готовности, посылая ответный сигнал подтверждения (в более общем случае вместе с ним устройство может Рис. 6.6. Схемы алгоритмов асинхронного ввода (а) и вывода (б) вернуть слово состояния ВУ). Приняв его, микроконтроллер получает информацию о готовности ВУ к выполнению обмена. Дальнейшие действия зависят от вида выполняемой транзакции. Если выполняется передача данных из ВУ, микроконтроллер выводит через порт на шину байт с управляющей информацией, сопровождая его сигналом стробирования. Ведомое устройство, получив управляющую информацию, переходит к подготовке данных для передачи в микроконтроллер и выводит их (и при необходимости информацию о состоянии) на шину данных, вырабатывая сигнал подтверждения данных. Когда ведущее устройство (микроконтроллер), выполнив проверку возвращаемого сигнала, убедится, что данные отправлены, оно осуществляет их прием и сохранение в памяти. После этого ведущее устройство снимает сигнал Строб, извещая о том, что данные получены. Обнаружив сброс строба, ведомое устройство снимает данные (и управляющую информацию о состоянии) и сигнал подтверждения.
6.2. Организация асинхронного параллельного обмена. 205 Аналогично протекают действия при операции записи данных в ВУ. После подтверждения готовности ведущее устройство выводит на шину байт данных и управляющую информацию. Получив управляющую информацию и установив тип операции обмена, ведомое устройство выполняет прием данных и по завершении возвращает сигнал подтверждения. Приняв его, ведущее устройство может начать подготовку к следующему циклу обмена. Обмен данными между устройством ввода/вывода и микроконтроллером С учетом возможностей используемого оборудования STK500 и базового микроконтроллера АТх8515 рассмотрим организацию асинхронного параллельного обмена по 4-разрядной шине. В зависимости от задания микроконтроллер осуществляет ввод данных по линиям порта PD3-PD0 или вывод по линиям PB0-PB3. Полагаем, что данные представляют собой последовательность двоично-кодированных десятичных цифр в упакованном или распакованном формате, сохраняемую при вводе в ячейках памяти SRAM и извлекаемую из ячеек SRAM при выводе. В упакованном виде каждый байт содержит по две десятичные цифры. В распакованном виде каждая цифра занимает младшую тетраду байта, старшая тетрада содержит код 0011. Инициатором обмена выступает внешнее устройство либо микроконтроллер. В первом случае прежде чем начать обмен микроконтроллер ожидает сигнал запроса от ВУ, затем выставляет сигнал готовности к обмену, принимает или передает данные, снимает сигнал готовности, ожидает снятия запроса от ВУ, после чего продолжает работу. Во втором случае каждая операция обмена начинается с выдачи микроконтроллером сигнала запроса к ВУ. Обмен осуществляется после приема от ВУ сигнала подтверждения готовности, при поступлении которого МК производит ввод или вывод данных, снимает запрос, ожидает снятия сигнала подтверждения со стороны ВУ и затем продолжает работу. Обмен управляющими сигналами между МК и ВУ осуществляется при каждой передаче. ВУ вырабатывает сигнал запроса (или ответный сигнал готовности), передаваемый в МК по линии PD.7. МК выдает ответный сигнал готовности (или запрос), выводимый по линии РВ.6. Активное значение управляющего сигнала указывается в задании (Н - высокий уровень, L - низкий).
206 6. Организация ввода/вывода данных по параллельному интерфейсу На рис. 6.7 приведена диаграмма сигналов, которыми обмениваются ВУ и микроконтроллер при вводе данных по запросу ВУ. Оба сигнала управления - ЗпрВУ (запрос от ВУ) и ПодтвМК (подтверждение готовности от МК) - характеризуются высоким уровнем активности (Н). Поскольку отладочная плата не имеет переключателя с двумя устойчивыми состояниями (0 и 1), с помощью которого можно сформировать потенциальный сигнал от ВУ, его функцию выполняют с помощью кнопки, вырабатывающей при каждом нажатии импульс, преобразуемый затем программой в потенциал, выводимый на светодиод индикации запроса. На рис. 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). При использовании команд косвенной адресации с постинкрементом после обращения по адресу, который находится в ин-
6.2. Организация асинхронного параллельного обмена. 207 дексном регистре, содержимое индексного регистра увеличивается на единицу. При использовании команд косвенной адресации с преддекрементом содержимое индексного регистра уменьшается на единицу, а затем производится обращение по полученному адресу. Из этого следует, что адрес в регистре 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 COO_L 2 5 Вывод МК Н L Y+ R0 1 6 Ввод ВУ Н Н Z+ 4 2 Длина цифровой последовательности задается значением либо хранится в регистре R0, либо определяется по начальной цифре передаваемой последовательности (НЦ), либо специальным символом конца обмена (ССКО), например *, ASCII-код которого равен $2А, а также по сигналу окончания обмена низкого уровня (COOL) на входе 4 порта PD (PIND.4). После завершения передачи цифровой последовательности управление передается на начало программы. Пример программы ввода, согласно варианту 6 задания (табл. 6.2), рассмотрен ниже. Микроконтроллер осуществляет ввод упакованных чисел 4-разрядным параллельным кодом по линиям порта PD3-PD0. Начальный адрес памяти SRAM - $0170. Адресация
208 6. Организация ввода/вывода данных по параллельному интерфейсу ячеек памяти осуществляется через регистр Z с постинкрементом содержимого регистра. Длина вводимой последовательности - четыре цифры. Инициатор обмена - внешнее устройство, роль которого исполняет оператор, формирующий с помощью кнопки SW7 запрос по линии PD.7. Программа 6.2 .*★★*********★★★*★***★★***★★★★*★* /Программа 6.2 ввода четырех 2-10 цифр с упаковкой и /квитированием ввода в память SRAM по адресам /0x0170,0x0171 /SW0 - SW3 - кнопки ввода 2-10 цифры /LED0 - LED3 - индикаторы 2-10 цифры /SW7 - кнопка запроса от оператора /LED7 - индикатор запроса от оператора /LED6 - индикатор подтверждения от МК /Установить шлейфами соединения: PD-SW, PB-LED .**************************^ .include "8515def.inc" /файл определений для AT90S8515 /.include "m8515def.inc" /файл определений для ATmega8515 .def temp = г16 /временный регистр .def in_dig = rl7 /вводимая цифра (операнд) .def sw_cod = rl8 /код состояния замкнутой кнопки .def in_data = г22 /формируемый байт данных .def count = г23 /счетчик цифр одного байта .def count_seq = г24 /счетчик цифровой / последовательности .def reg_led = г25 /регистр состояния / светодиодов /***Вывод порта PD*** .equ int_vu = 7 /запрос от кнопки оператора /***Выводы порта рв*** .equ led_int = 7 /индикатор запроса от кнопки .equ ack_mk = б /индикатор подтверждения от МК .macro in_sw sbic PIND, @0 /проверка кнопки SW rjmp quit / и установка bid sw_cod, @0 / бита замкнутой кнопки eor in_dig,sw_cod rcall OUTLED / с индикацией quit: nop .endmacro in_sw .org $000 rjmp init
6.2. Организация асинхронного параллельного обмена. 209 .★** Инициализация *** INIT: ldi temp, low(RAMEND) /установка out SPL, temp ; указателя стека ldi temp, high(RAMEND) ; на последнюю out SPH, temp ; ячейку ОЗУ ldi ZL, 0x70 ;0x0170 - начальный адрес ldi ZH, 0x01 ; памяти данных ser temp ;настройка out DDRB, temp ; порта РВ на вывод clr temp ;настройка out DDRD, temp ; порта PD ser temp ; на out PORTD, temp ; ввод clr sw_cod clr in_dig /очистка операнда set ;T=1 (SREG) ldi count,0 ;обнуление счетчиков ldi count_seq, 0 ;***Начало цикла передачи одной цифры*** ;Инициализация регистра светодиодов (7,6 биты): ;начальные значения сигналов запроса и подтверждения ;по условию задания равны 0 loop: ldi reg_led,0Ь00000000 rcall OUTLED ;вывод wait: sbic PIND,int_vu /ожидание запроса rjmp wait bid sw_cod,int_vu /установка бита запроса rcall OUTLED bid 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 bid sw_cod, int_vu rcall OUTLED /сброс запроса inc count_seq /увеличиваем счетчики цифр inc count cpi count, 2 /если счетчик равен двум, то breq IN_DIG2 / переходим к записи 2-й цифры, mov in_data, in_dig /иначе сохраняем 1-ю цифру st Z, in_data rjmp RES_ACK_mk
210 6. Организация ввода/вывода данных по параллельному интерфейсу IN_DIG2: swap in_data or in_data, in_dig /запись второй цифры ; в упакованном формате st Z + , in_data ; в память данных ldi count, 0 RES_ACK_mk: bid 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:ldi г19,10 ldi r20,255 ldi r21,255 dd:dec r21 brne dd dec r20 brne dd dec rl9 brne dd ret Задание 1. Составить программу на языке Ассемблер AVR для заданного варианта. Выполнить отладку программы в отладочной среде AVR Studio 4. Загрузить программу в микроконтроллер и проверить ее работу в STK500. Обмен данными между микроконтроллерами Обмен данными между двумя микроконтроллерами по параллельному интерфейсу может быть выполнен по протоколу с квитированием в случае занятости одного из них обслуживанием внешнего устройства. Протокол обмена рассмотрим на примере с двумя микроконтроллерами, когда один из них - МК1 - выполняет передачу данных в микроконтроллер МК2.
6.2. Организация асинхронного параллельного обмена. 211 Для выполнения одного сеанса передачи в микроконтроллере МК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, обращение к которой начинается по сигналу от кнопки Start. Микроконтроллер МК2 постоянно находится в режиме бесконечного цикла. После завершения приема он осуществляет в целях контроля последовательный вывод числовой последовательности на светодиодную линейку. Подготовить и отладить программы для обоих микроконтроллеров, используя AVR Studio 4. Проверить работу схемы на модели, используя симулятор программы ISIS Proteus 6. Загрузить обе 8*
212 6. Организация ввода/вывода данных по параллельному интерфейсу программы в микроконтроллеры двух 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. Схема аналого-цифрового преобразователя
214 7. Устройства для обработки аналоговых сигналов АЦП содержит 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 ADPS0 Таблица 7.2. Таблица коэффициентов деления ADPS2 ADPS1 ADPS0 К ADPS2 ADPS1 ADPS0 К 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 в данный разряд.
7.2. Аналоговый компаратор 215 Результат преобразования, представляющий 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. Аналоговый компаратор содержит собственно компаратор, на входы которого поступают два аналоговых сигнала - AIN0 и AIN1, 8-разрядный регистр управления и состояния ACSR (табл. 7.3) и элементы управления. Компаратор имеет два входа: положительный (+) и отрицательный (-). Выходной сигнал компаратора АСО принимает значение 1, если напряжение на входе + больше напряжения на входе -.
216 7. Устройства для обработки аналоговых сигналов Рис. 7.2. Структурная схема аналогового компаратора Таблица 7.3. Формат регистра ACSR № разряда 7 6 5 4 со 2 1 0 Имя ACD - АСО ACI ACIE ACIC ACIS1 ACIS0 Таблица 7.4. Выбор типа запроса При определенном изменении сигнала АСО, обусловленном состоянием разрядов ACIS1, ACIS0 регистра ACSR (табл. 7.4), в регистре ACSR формируется сигнал ACI = = 1 и при разрешении прерывания ACIE = 1 вырабатывается запрос прерывания ANA СОМР. При переходе к прерывающей программе бит ACI в регистре ACSR аппаратно сбрасывается в нулевое состояние. Программно этот бит можно сбросить в 0 путем установки 1 в этот разряд. При установке разряда ACIC в состояние 1 АСО может быть использован в качестве сигнала захвата для таймера Т1. При установке ACD в 1 отключается питание компаратора, что ведет к уменьшению тока потребления микроконтроллера. ACIS1 ACIS0 Изменение АСО 0 0 Любое 0 1 - 1 0 1/0 1 1 0/1 Практическая часть Задание 1. Подготовить программу для исследования работы аналого-цифрового преобразователя в одиночном режиме. Загрузить программу в память микроконтроллера при выбранной частоте тактовых сигналов 3,69 МГц. С помощью 10-проводного шлей-
7.2. Аналоговый компаратор 217 фа соединить разъем порта РС с выводами светодиодов LED0- LED7 для наблюдения результатов и кнопку SW2 - с выводом порта PD2 для управления выводом. Вывод AGND соединить с выводом GND, AVCC - с VCC. Опорное напряжение UAREf должно находиться в пределах £/gnd---^avcc- При установленной перемычке AREF опорное напряжение для АЦП можно регулировать на вкладке Board в окне STK500 AVR Studio 4. На вход порта РАО подать напряжение с выхода потенциометра. Напряжение входного сигнала может изменяться от £/qnd д° ^avcc- После пуска программы с помощью кнопки 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: ldi temp,low(RAMEND) /установка out SPL,temp / указателя стека ldi temp,high(RAMEND) / на последнюю out SPH,temp / ячейку ОЗУ ser temp /порт PC out DDRC,temp / на вывод out PORTC,temp ldi temp,OxFB /инициализация 2-го вывода out DDRD,temp / порта PD на ввод
218 7. Устройства для обработки аналоговых сигналов ldi temp,0x04 /включение подтягивающего out PORTD,temp ; резистора порта PD clr temp /аналоговые входы out DDRA,temp ; порта РА, отключены out PORTA,temp ; подтягивающие резисторы ldi temp,0x7F /разрешение внешнего out GIMSK,temp ; прерывания ldi temp,0x02 /обработка прерывания INTO out MCUCR,temp ; по перепаду 1/0 set /флаг T=l для вывода двух байтов /Инициализация АЦП ldi temp,0x8D / ADEN=1, ADIE=1, Fadc=Fclk/32 out ADCSR,temp / Fadc=115 КГц при Fclk=3,69 МГц ldi temp,0 / Канал 0 АЦП (вход РАО) out ADMUX,temp sei /разрешение прерываний sbi ADCSR,ADSC /пуск преобразования loop: rjmp loop /цикл ожидания прерываний /Обработка прерывания от АЦП adc: in rl8,ADCL /считывание ADCL:ADCH in rl7,ADCH reti /Обработка внешнего прерывания от кнопки для просмотра /результатов. Вывод в порт РС сначала двух старших, затем /восьми младших разрядов при повторном нажатии кнопки inter: cbi ADCSR,ADIE /запрет прерывания от АЦП brtc t0 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. Изменить программу, выполняя вывод старших восьми разрядов результата преобразования АЦП с первоначальной скоростью преобразования 125 кГц.
7.2. Аналоговый компаратор 219 Задание 4. Изменить программу, снова увеличив скорость преобразования в 1,5 раза. Задание 5. Изменить программу, предусмотрев возможность преобразования с переводом контроллера в режим холостого хода. Сравнить результаты наблюдений. Задание 6. Подготовить программу для исследования работы аналогового компаратора. Загрузить ее в память микроконтроллера. На входы порта РВ2, РВЗ подать напряжения с выходов двух потенциометров. С помощью 10-проводного шлейфа соединить разъем порта РС с выводами светодиодов LED0-LED7 для наблюдения содержимого счетчика сигналов сравнения. Проверить работу программы, изменяя с помощью потенциометра напряжения на одном из входов (AINO, AIN1) при постоянном напряжении на другом входе. В окне STK500 на вкладке Board установить частоту, при которой счетчик программы count последовательно увеличивается на единицу при изменении знака разности входных сигналов. Программа 7.2 .***************************^ /Тестовая программа 7.2 аналогового компаратора с выводом /счетчика изменений сигнала АСО на индикаторы порта РС. /Соединения: 10-проводным шлейфом PC-LED, ;РВ2 - выход потенциометра 1, РВЗ - выход потенциометра 2 .*****************************^ .include "8535def.inc" /файл определений AT90S8535 .def temp = г16 /временный регистр .def count = rl7 .def reg_led = rl9 /регистр индикации .org $0 rjmp init .org $010 rjmp ana_comp init: ldi temp,low(RAMEND) /установка out SPL,temp / указателя стека ldi temp,high(RAMEND) / на последнюю out SPH,temp / ячейку ОЗУ ser temp /порт PC out DDRC,temp / на вывод out PORTC,temp clr temp /аналоговые входы PB2,PB3
220 7. Устройства для обработки аналоговых сигналов out DDRB, temp /отключены подтягивающие out PORTB, temp ; резисторы clr count ldi temp,0x10 /сброс ACI и ACSI1/ACSI0 out ACSR,temp sei sbi ACSR,ACIE /разрешение прерывания loop: rjmp loop ana_comp: inc count mov reg_led, count com reg_led out PORTC,reg_led reti Задание 7. Изменить условие прерывания. Вместо прерывания при любом изменении сигнала АСО запрограммировать прерывания при изменении сигнала АСО 0/1. Проверить работу программы. Задание 8. Модифицировать программу, запретив прерывания и организовав программную проверку АСО в регистре ACSR, увеличивая счетчик изменений при переходе АСО 1/0. Проверить работу программы.
8. ПРОГРАММИРОВАНИЕ И ОТЛАДКА ПРОГРАММ НА ЯЗЫКЕ Си При написании программ для микроконтроллеров все большую популярность приобретает язык Си. При его использовании сокращается время на разработку, что особенно заметно при написании больших программ, обеспечивается их переносимость на другие платформы. Недостатком языка Си по сравнению с языком Ассемблер является больший объем кода и, как следствие, более низкая скорость работы. Однако благодаря тому, что в архитектуре AVR изначально заложено эффективное декодирование и исполнение инструкций, генерируемых компиляторами, после компиляции Си-программ получается высокопроизводительный код. Существует ряд компиляторов Си, поддерживающих архитектуру AVR: CodeVisionAVR, ImageCraft С, AVR GCC и др, которые включают в себя широкий набор библиотек для работы с периферийными устройствами и поддерживают форматы объектных файлов, используемых при отладке в AVR Studio 4. Кроме того, многие компиляторы поддерживают возможность программирования микроконтроллеров после компиляции исходного текста программы. Далее описан процесс разработки и отладки программы на языке Си для учебного проекта. В качестве среды программирования использована программа Code Vision AVR версии 1.23.7а, для отладки - AVR Studio 4. 8.1. СРЕДА CODEVISION AVR Программа Code Vision AVR фирмы HP InfoTech - это интегрированная среда разработки, содержащая компилятор языка Си, графическую оболочку, автоматический генератор программ и встроенный программатор, ориентированные на работу с семейством микроконтроллеров AVR. Наряду со стандартными библиотеками языка Си и системой справок по языку компилятор имеет библиотеки для работы с пери-
222 8. Программирование и отладка программ на языке Си Рис. 8.1. Окно программы Code Vision AVR Внешний вид окна программы Code Vision AVR показан на рис. 8.1. Создание проекта Разработаем микроконтроллерное устройство, управляющее двумя светодиодами, один из которых показывает готовность к работе, второй переключается по числу нажатий кнопки управле- ферийными устройствами (ЖКИ-индикаторами с встроенными контроллерами, датчиками температуры, часами реального времени, энергонезависимой памятью EEPROM, шиной SPI и др.). Также имеется автоматический генератор программ для инициализации внутренних и периферийных ресурсов микроконтроллера - портов, таймеров, UART, SPI и др. Для отладки систем, использующих последовательную передачу данных, имеется встроенный в компилятор буфер Terminal. Генерируемый при компиляции объектный файл .cof позволяет осуществлять с помощью отладчика AVR Studio 4 отладку программы непосредственно в коде Си.
8.1. Среда CodeVision AVR 223 ния. Проект предполагает работу с портами ввода/вывода, таймером, обработку внешнего прерывания, энергосберегающий режим работы МК, использование библиотечной подпрограммы. Схема устройства приведена на рис. 8.2. В ней предусмотрены две кнопки. Кнопкой SW0 задают число миганий, кнопкой SW2 запускают процесс мигания светодиода. Для подсчета числа нажатий на кнопку SW0 необходим счетчик, в качестве которого используем таймер ТО в режиме подсчета внешних событий. Для индикации используем два светодиода: LED6 - индикатор готовности схемы и LED7 - мигания. Таким образом, микроконтроллер должен иметь возможность обработки внешнего прерывания от кнопки SW2, таймер с входом внешних событий от кнопки SW0 и две линии порта для управления светодиодами. Выберем микроконтроллер AT90S8515, рабочую частоту 1 МГц. Кнопки считаем идеальными без эффекта дребезга контакта. Подтягивающие резисторы на входах PD2, РВО подключаем при программировании режима работы портов. Работа над проектом в CodeVision AVR начинается с выбора команды меню File/New. В диалоговом окне выбираем Project и нажимаем ОК. Дальнейшие действия зависят от выбора No или Yes в появившемся окне. Если не используем автоматический генератор программ, выберем No, затем выполним действия п. 1, в противном случае - действия п. 2. 1. В окне Create New Project задаем имя проекта. После сохранения появляется окно Configure Project (рис. 8.3), в котором на вкладке Files можно добавить (Add) существующие файлы в проект или удалить их (Remove) из него. При отсутствии файла с текстом программы создаем пустой файл, выполняя команды File/New/Source. После ввода текста программы сохраняем его. Затем переносим файл в папку проекта, выполнив команду Add в окне Configure Project. На вкладке С Compiler указываем тип микроконтроллера (Chip), частоту его работы (Clock), размер доступной памяти (SRAM), а также параметры компиляции: способ оптимизации кода - по размеру (Size) или скорости (Speed), соглашения Рис 8.2. Схема устройства
& 1. Среда CodeVision A VR 225 Для задания параметров проекта в целом необходимо выбрать команду меню Project/Configure. Дальнейшие действия выполняем, как указано в п. 1. Работу устройства определяет программа, текст которой представлен ниже. Программа 8.1 /* Программа 8.1 с помощью таймера подсчитывает число нажатий на кнопку SW0. Затем после нажатия на кнопку SW2 переключает светодиод LED7 по значению таймера. В режиме ожидания включен светодиод LED6. */ #include <90s8515.h> //#include <mega8515.h> для микроконтроллера ATmega8515 #include <delay.h> // файл с процедурами задержки #define LED7 P0RTB.7 #define LED6 P0RTB.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=0x81; // PBO(SWO) - ввод событий DDRD=0xFB; // PD2(SW2) PORTD=0xFF; // инициализация таймера 0 TCCR0=0x06; TCNT0=0x00; // инициализация прерывания INTO в GIMSK (или GICR) GIMSK=0x40;
224 8. Программирование и отладка программ на языке Си по компиляции и форматы выходных файлов (File Output Format), использование терминала ввода/вывода. Рис. 8.3. Окно компилятора Си Для проекта устанавливаем: тип МК - АТ908515, рабочую частоту - 1 МГц, способ оптимизации - по размеру кода, формат выходного файла - COFF, после чего нажимаем ОК. 2. В окне CodeWizardAVR на соответствующих вкладках задаем имя проекта, параметры внутренних ресурсов микроконтроллера (его тип, рабочую частоту, параметры порта ввода/вывода, внешнее прерывание по низкому уровню, переключение таймера/счетчика по перепаду из 1 в 0 на входе ТО). Выбираем команду меню File/Generate, Save and Exit. Три раза указываем в окнах Save... имя проекта. В итоге открывается файл-заготовка со строками инициализации требуемых ресурсов.
226 8. Программирование и отладка программ на языке Си Компиляция Для компиляции программы необходимо выбрать команду меню Project /Compile (F9). Результаты компиляции выводятся в окно Information, а в окне Navigator в дереве проекта появляются синие ветви. Щелкая по значкам, можно перемещаться по заголовкам процедур и именам глобальных переменных, что удобно при работе с большим проектом. Ветвь дерева с ошибками (Errors) выделена красным цветом. Список ошибок также выводится в окне Messages внизу экрана. Чтобы исправить ошибку, нужно щелкнуть по листу дерева. Соответствующая строка программы выделится серым цветом, а рядом с ней появится курсор для ввода. После компиляции будут созданы файлы с расширениями: .asm (файл Ассемблера), .тар (адреса ОЗУ расположения глобальных переменных), .vec (список векторов прерываний), .inc (файл определений). В случае успешной компиляции выводится сообщение об отсутствии ошибок. В окне Navigator ветвь сообщений об ошибках пропадает, а список файлов пополняется файлом filename _.с - копией исходного файла на языке Си. Для окончательной сборки проекта и получения файлов для отладки и программирования МК нужно выбрать в меню команду Project/Make (Shift + F9). Появится окно Information, в котором сообщается о создании дополнительных файлов с расширениями .гот (программирование Flash-памяти МК - программа в формате «адрес : слово»), .еер (программирование EEPROM), .1st (листинг программы), .err (аналог содержимого окна Information), .obj (объектный файл) и .cof (символьный файл для отладки в среде AVR Studio). Работа с CodeVision AVR на этом заканчивается, по крайней мере до момента, когда нужно будет исправить ошибки, найденные при отладке. MCUCR=0x20; // разрешение перехода в режим Idle #asm("sei"); // глобальное разрешение прерываний for (;;) { #asm("sleep"); // переход в режим Idle #asm("nop"); } }
8.2. Отладка в AVR Studio 227 8.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, содержащего векторы прерываний. Курсор отладки (желтая стрелка) установлен на команде rjmpreset. После нажатия кнопки Step Into (Fl 1) курсор переходит на обработчик сброса, расположенный в файле .asm, и дальнейшая отладка продолжается в обычном режиме. Чтобы пропустить команды, добавленные компилятором, и перейти к отладке кода, написанного программистом, нужно установить курсор на первую команду процедуры main () и нажать кнопку Run to cursor. Все команды до курсора будут выполнены. Проект можно просмотреть в окне Disassembler, которое открывают, выбрав в меню View/Disassembler. Отладку можно продолжить в этом окне. Для отладки программы на языке Си выбираем файл с расширением .cof. 4. Устанавливаем параметры отладки в меню Debug/ AVRSimulator Options: АТх8515, частота 1 МГц, протоколирование порта РВ с выводом на экран. 5. Содержимое используемых регистров ввода/вывода МК можно проконтролировать несколькими способами: а) непосредственно просматривая их содержимое на вкладке I/O панели Workspace; б) анализируя область памяти регистров ввода/вывода (View/ Memory [I/O]), в) присвоив их значения переменным, которые в дальнейшем просматривают в окне Watch. В нашем случае имеем одну переменную timer, которая принимает значение таймера/счетчика TCNTO. Открываем окно Watch, выбрав команду меню View/Watch, и перетаскиваем мышью эту переменную в столбец Name. Пока переменная находится вне
228 8. Программирование и отладка программ на языке Си зоны видимости отладчика, в столбце Value будет записано Not in Scope. Подготовка к отладке завершена. 6. В начале процесса отладки и при нажатии кнопки сброса Reset курсор отладки устанавливается на первой строке процедуры main (). Выполнение программы можно контролировать, открыв окно Disassembler, однако имея программу на языке Си, значительно удобнее отлаживать программу в окне Си-программы. 7. Нажимая кнопку Step Into (F11), наблюдаем за изменением содержимого регистров ввода/вывода микроконтроллера. Одно из преимуществ отладки на Си - использование только программных инструкций, способствующее ускорению процесса отладки. В цикле for (;;) командой Ассемблера sleep микроконтроллер переводится в режим пониженного энергопотребления. 8. Занесем в счетчик TCNT0 значение 2. При разомкнутой кнопке SW0 (состояние 1) эмулируем замыкание кнопки SW2 (состояние 0), что приведет к вызову обработчика прерывания. При вызове процедуры delaymsQ отладчик не входит в нее, но вызов задерживает его работу и изменяет значение счетчика циклов. 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:C1 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 не был закрыт, то появится сообщение, что объектный файл был изменен и его нужно перезагрузить - выполняем перезагрузку. 11. Компилируем в CodeVision AVR, установив в окне Configure тип выходного файла Intel HEX. Загрузив полученный файл
8.2. Отладка в AVR Studio 229 с расширением .hex в микроконтроллер STK500 и изменив на вкладке Board окна STK500 частоту, проверяем работу программы. Соединяем РВ6: РВ7 - LED6:LED7, SW0 - РВО, SW2 - PD2. В исходном состоянии светодиод LED6 включен, LED7 выключен. Нажав несколько раз на кнопку SW0, затем на кнопку SW2, наблюдаем мигание светодиода LED7 с частотой 1 Гц. В это время светодиод LED6 выключен. После завершения мигания LED6 вновь включается, а устройство переходит в режим ожидания. Выводы Работа над проектом с использованием языка Си позволяет сделать ряд наблюдений, касающихся наглядности программ, размеров кода, отладки и их переносимости. Наглядность программы. Язык высокого уровня позволяет использовать сложные структуры данных, такие, как массивы, строки, списки, записи, обеспечивает максимальное удобство при написании циклов и ветвлений, избавляет программиста от написания рутинных фрагментов программ. Программирование на Ассемблере требует знаний всех ресурсов микроконтроллера. Программа, написанная на Ассемблере, не всегда наглядна, разобраться в коде достаточно сложно, при использовании микроконтроллеров с RISC-архитектурой возникают проблемы с программированием сложных операций, таких, как умножение и деление, с обработкой структур данных. Размер кода. При использовании всех возможностей языка Си программа может быть очень компактной, однако, если сравнивать откомпилированные коды, оценки могут измениться. Код, написанный на Ассемблере, минимален по размеру и оптимизирован под конкретную задачу, что позволяет получить высокую скорость работы программы. Компилятор же оперирует фрагментами кода по общим правилам. Так, в примере со светодиодами в начале работы программы 8.1 обнуляются все регистры микроконтроллера и оперативная память SRAM, при входе в процедуру прерывания регистры сохраняются в стеке, а затем восстанавливаются при выходе. Однако в приложении работа с памятью не предусмотрена - используется всего лишь несколько регистров. Отладка. Если программа пишется на языке высокого уровня, а отлаживать предполагается откомпилированный код, то весь процесс может занять больше времени, чем написание и отладка программы на Ассемблере. Вместе с тем написание и отладка на языке Си программ, ориентированных в большей степени на обработку данных, проще, чем при использовании Ассемблера.
230 8. Программирование и отладка программ на языке Си Переносимость. Изменение частоты синхронизации микроконтроллеров, очевидно, влияет на длительность выполнения процедур. Если время выполнения должно остаться неизменным (в нашем случае это время включения светодиода), потребуется вносить изменения в программу на Ассемблере, заново пересчитывая коэффициенты в циклах задержки. В программе на Си необходимо только заменить частоту в конфигурации проекта и компилятор пересчитает все автоматически, что, безусловно, проще. Учитывая, что откомпилированный код всегда больше исходного, написанного на Ассемблере, и принимая невозможность простой его оптимизации, можно сделать выводы о предпочтении того или иного языка программирования в зависимости от сложности и направленности задачи, наличия средств отладки, доступного размера памяти микроконтроллера, требуемого быстродействия процедур, сроков проектирования и т. д. В заключение приведем ряд рекомендаций по написанию программ на языке Си для микроконтроллеров. Для уменьшения размера программного кода рекомендуется: - компилировать с оптимизацией по размеру; - использовать локальные переменные, а не глобальные, так как первые хранятся в регистрах, а вторые - в ОЗУ; - использовать по возможности беззнаковые типы данных меньшего размера; - если глобальная переменная используется только в одной функции, она должна быть объявлена как Static; - использовать конструкцию for (;;) для бесконечных циклов; - использовать циклы с декрементом и конструкцию {} while (выражение); - выполнять доступ в память непосредственно, не используя указатели; - использовать макросы вместо функций для подзадач, компилируемых в две-три команды Ассемблера. Для уменьшения требований к памяти SRAM следует: - константы и литералы располагать в памяти программ, объявляя их с помощью директивы Flash; - избегать объявления глобальных переменных, если они на самом деле локальные, так как последние размещаются динамически и убираются из памяти, когда выходят из зоны видимости; - правильно оценивать размер программного стека (Data Stack Size), который необходимо указывать в настройках проекта (Project/Configure, закладка CCompilier).
Приложения 231 Приложения Ш. Обозначения регистров ввода/вывода Имя регистра Адрес I/O Назначение ACSR, Analog Comparator $08 Регистр управления и Control and Status Register состояния аналогового компаратора DDRA, Data Direction Register, $1A Регистр направления Port A данных порта А DDRB, Data Direction Register, $17 Регистр направления Port В данных порта В DDRC, Data Direction Register, $14 Регистр направления Port С данных порта С DDRD, Data Direction Register, $11 Регистр направления Port D данных порта D EEARH, EEPROM Address $1F Регистр адреса Register High Byte EEPROM, старший байт EEARL, EEPROM Register $1E Регистр адреса Address Register Low Byte EEPROM, младший байт EECR, EEPROM Control Regis$1C Регистр управления ter EEPROM EEDR, EEPROM Data Register $1D Регистр данных EEPROM GIFR, General Interrupt Flag $3A Общий регистр флагов Register прерываний GIMSK, General Interrupt Mask $3B Общий регистр маски Register прерываний ICR1H, T/Cl Input Capture $25 Регистр захвата Т/С1, Register High Byte старший байт ICR1L, T/Cl Input Capture Reg$24 Регистр захвата Т/С1, ister Low Byte младший байт MCUCR, MCU General Control $35 Регистр управления Register микроконтроллером OCR 1 AH, T/Cl Output Com$2B Регистр сравнения А pare Register A High Byte Т/С1, старший байт OCR1AL, T/Cl Output Com$2A Регистр сравнения А pare Register A Low Byte Т/С 1, младший байт
232 Приложения Продолжение прилож. Ш Имя регистра Адрес I/O Назначение 0CR1BH, T/Cl Output Com$29 Регистр сравнения В Т/С 1, pare Register В High Byte старший байт OCR1BL, T/Cl Output Com$28 Регистр сравнения В Т/С1, pare Register В Low Byte младший байт PINA, Input Pins, Port A $19 Выводы порта А PINB, Input Pins, Port В $16 Выводы порта В PINC, Input Pins, Port С $13 Выводы порта С PIND, Input Pins, Port D $10 Выводы порта D PORTA, Data Register, Port A $1B Регистр данных порта А PORTB, Data Register, Port В $18 Регистр данных порта В PORTC, Data Register, Port С $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 $33 Регистр управления тайRegister мера/счетчика ТО TCCR1A, T/Cl Control $2F Регистр управления А Register A таймера Т/С1 TCCR1B, T/Cl Control $2E Регистр управления В Register В таймера Т/С1 TCNTO, Timer/CounterO $32 Счетный регистр тайме(8 bit) ра/счетчика 0 TCNT1H, T/Cl High Byte $2D Счетный регистр Т/С1, старший байт TCNT1L, T/Cl Low Byte $2C Счетный регистр Т/С1, младший байт
Приложения 233 Окончание прилож. П1 Имя регистра Адрес I/O Назначение TIFR, Т/С Interrupt Flag $38 Регистр флагов прерываRegister ний от таймеров TIMSK, T/C Interrupt Mask $39 Регистр маски прерываRegister ний от таймеров UBRR, UART Baud Rate $09 Регистр скорости передаRegister чи UART UCR, UART Control Register $0A Регистр управления UART UDR, UART I/O Data Register $0C Регистр данных UART USR, UART Status Register $0B Регистр состояния UART WDTCR, Watchdog Control $21 Регистр управления стоRegister рожевым таймером
234 Приложения П2. Программы для преобразования чисел Здесь описаны приемы, используемые для преобразования двоичных и десятичных целых и дробных чисел, широко применяемые при вводе и выводе данных. Преобразования основаны на использовании методов умножения/деления на 2, выполняемых путем сдвига и коррекции. Сдвиг двоичных чисел выполняется без коррекции, для десятичных чисел необходима коррекция в зависимости от направления сдвига. Если при сдвиге вправо (деление на 2) слева из старшего десятичного разряда поступает 0, коррекция не проводится. При поступлении 1, она приобретает вес 8 вместо 5, что должно быть при делении 1 старшего разряда на 2 (при сдвиге вправо). В связи с этим необходима коррекция вычитанием 3. Пример преобразования 2-разрядного 2-10 числа: Исходное 1 0100 0100 =144 Сдвиг вправо 1010 0010 Коррекция - ООП Результат 0111 0010 = 72 Программа процедуры сдвига вправо и последующей коррекции для одного упакованного байта: divd2: ror асе ;сдвиг байта вправо ror rl4 ;г13,г14 - регистры временного хранения push асе /сохранение в стеке andi асе,0x0f cpi асе,8 ;если из старшей тетрады сдвинут 0, brcs nocl ; коррекция не нужна, subi асс,3 ;иначе вычитание 3 nocl: mov г13,асс /сохранение младшей тетрады pop асе /восстановление из стека andi acc,0xf0 cpi асе,0x80 /если из старшей тетрады сдвинут 0, brcs пос2 / коррекция не нужна, subi асе,0x30 /иначе вычитание $30 пос2: or асс,г13 /объединение тетрад rol г14 /восстановлен перенос С ret При сдвиге влево (умножение на 2) все значения тетрад, которые меньше 5, дают верный результат. Для всех значений, начи-
Приложения 235 ная от 5 и выше, необходимо формировать единицу переноса, так как после умножения на 2 они дают результат, равный 10 и более. Коррекцию удобно провести перед сдвигом влево путем прибавления 3 к тетраде. Это дает возможность автоматически получить перенос после сдвига влево. Пример преобразования 2-разрядного 2-10 числа: Исходное 0101 0100 =54 Коррекция + ООП 1000 0100 Сдвиг влево 1 0000 1000 = 108 (результат) Программа процедуры коррекции и сдвига влево для одного упакованного байта: muld2: ror rl4 ;rl3,rl4 - регистры временного хранения push асе /сохранение в стеке andi acc,0x0f cpi асе,5 /сравнение с 5 младшей тетрады brcs noclm /коррекция не нужна, если асс<5, subi асс,-3 /иначе прибавление 3 noclm: mov rl3,acc pop асе /восстановление из стека andi acc,0xf0 cpi асе,0x50 /сравнение с 5 старшей тетрады brcs noc2m /коррекция не нужна, если асс<$50, subi асе,-$30 /иначе прибавление $30 noc2m: or асс,г13 /объединение тетрад rol г14 /восстановлен перенос С rol асе /сдвиг байта влево ret Преобразование целого десятичного числа в двоичное можно выполнить путем последовательного деления на 2 исходного значения, затем получаемых частных, используя образуемые остатки (0 или 1) в качестве разрядов двоичного числа, начиная с младшего. Пример: 1)71:2 = 35(1 — младший разряд двоичного числа); 2)35:2 = 17(1); 3) 17:2 = 8(1); 4)8:2 = 4(0); 5)4:2 = 2(0); 6) 2:2 = 1(0) - старшие разряды. Результат: 1000111
236 Приложения Деление упакованного десятичного числа на 2 можно выполнить, последовательно применяя для каждого байта, начиная со старшего, процедуру сдвига и коррекции divd2. Преобразование целого двоичного числа в десятичное можно выполнить, используя представление двоичного числа в виде полинома Горнера: D = (.. .(dn_x2 + dn_2)2 + ...+ dx)2 + Jo- Умножив исходное число на 2 (или сдвинув код числа влево на 1 разряд) можно выделить старший разряд dn_x, добавив его значение (0 или 1) в десятичную ячейку и удвоив ее содержимое. Действия повторяют для всех разрядов двоичного числа. Для умножения на 2 десятичного числа используется процедура muldl, применяемая последовательно для каждого байта числа, начиная с младшего. Преобразование десятичной дроби в двоичную выполняется традиционным способом: путем умножения на 2 исходной дроби и дробных частей получаемых произведений. Целые части произведений, принимающие значения 0 или 1, образуют ряд значений разрядов двоичной дроби, начиная со старшего, поэтому в алгоритме преобразования можно применить процедуру muld2 умножения на 2 десятичного числа с коррекцией. Образуемое значение переноса при обработке старшего байта дроби подают в младший разряд ячейки двоичной дроби, одновременно сдвигая все остальные разряды влево. Преобразование двоичной дроби в десятичную можно выполнить, используя представление дроби в виде полинома Горнера: D = 2~\d_x +...+ 2'l\d<n.X)+2'ld_n...). Сдвигая вправо двоичную дробь и подавая выталкиваемые младшие разряды в ячейку десятичной дроби слева, где также выполняется деление на 2, можно получить десятичный эквивалент. Деление и коррекция каждого байта десятичной дроби, начиная со старшего, осуществляется с помощью процедуры divd2. Далее приведена тестовая программа, демонстрирующая преобразование целых чисел. Исходные для преобразования данные и результаты размещают в памяти так, что младшие разряды чисел находятся по адресу bram (dram), старшие - по адресу bram + (п-1) (dram + (к-1)).
Приложения 237 /Тестовая программа для преобразования упакованного целого /десятичного числа длиной к байт в двоичное длиной п байт, /двоичного целого - в десятичное упакованное. .******★*★**★********★***★********** .include "8515def.inc" /файл определений для AT90S8515 .equ dram = $0 60 /адрес десятичного числа .equ bram = $0 6А /адрес двоичного числа .equ к = 2 /длина операндов для теста .equ n = 1 .def асе = г1б /регистр-аккумулятор .def bit_count = г17 /счетчик битов .def byte_count = г18 /счетчик байтов .org $000 ldi асе,low(RAMEND) /установка out SPL,acc / указателя стека ldi асе,high(RAMEND) / на последнюю out SPH,acc / ячейку ОЗУ /Преобразование десятичного числа в двоичное /Исходные данные для теста ($60)=37, ($61)=02 idb: ldi bit_count,8*n loop: ldi XL,low(dram+k) /установка ldi XH,high(dram+k) / начального адреса clc /С=0 ldi byte_count,k dloop: Id acc,-x rcall divd2 /сдвиг вправо десятичного числа st х,асс /и коррекция dec byte_count brne dloop ldi XL,low(bram+n) /установка ldi XH,high(bram+n) / начального адреса ldi byte_count,n bloop: Id acc,-x ror асе /сдвиг вправо st x,acc / двоичного числа dec byte_count brne bloop dec bit_count brne loop /повторить для всех разрядов /Результат ($6А)=ED /Обратный перевод в упакованное десятичное ibd: ldi bit_count,8*n ldi XL,low(dram+k) /установка
238 Приложения ldi XH,high(dram+k) ; начального адреса ldi byte_count,k clr acc s_loop: st -x,acc ; и очистка ячеек dec byte_count ; десятичного числа brne s_loop loopl: ldi XL,low(bram) /установка ldi XH,high(bram) ; начального адреса clc ;C=0 ldi byte_count,n bloopl: Id acc,x rol асе /сдвиг влево st x+,acc ; двоичного числа dec byte_count brne bloopl ldi XL,low(dram) /установка ldi XH,high(dram) / начального адреса ldi byte_count,k dloopl: Id acc,x rcall muld2 /коррекция десятичного числа st x+,acc ; и сдвиг влево dec byte_count brne dloopl dec bit_count brne loopl /повторить для всех разрядов fin: rjmp fin .include "muld2.asm" /вызываемые подпрограммы .include "divd2.asm"
В мире наукоемких технологий микроконтроллеры занимают особое место. Будучи связующим мостом между объектами окружающей среды и интеллектуальной мощью современных вычислительных средств они все более становятся инструментом, с помощью которого человек получает информацию об окружающем мире и воздействует на предметы этого мира. Современный мир микроконтроллеров чрезвычайно широк и многообразен. Прикосновение к этому миру вооружает специалистов новыми представлениями и инструментальными средствами проектирования сложных управляющих систем. Материал книги дает лишь начальное представление о сферах возможного применения микроконтроллеров. Автор надеется, что знания, полученные читателями на примере популярного семейства микроконтроллеров AVR, помогут им в дальнейшем при освоении архитектуры других микроконтроллеров, программировании конкретных задач, и желает больших творческих успехов на этом пути. СПИСОК ЛИТЕРАТУРЫ 1. AVR STK500. User Guide. 2. AVR Assembler User Guide. 3. Datasheet: AT90S8515, ATmega8515, ATmega8, PCA9544/PCA-9544A, AVR315.pdf 4. Гребнев В.В. Микроконтроллеры семейства AVR фирмы Atmel. - М.: Радиософт, 2002. 5. Евстифеев А.В. Микроконтроллеры AVR семейств Tiny и Mega фирмы ATMEL. - М.: Издательский дом «Додэка-ХХ1», 2005. 6. Злобин В.К., Григорьев В.Л. Программирование арифметических операций в микропроцессорах. - М.: Высш. шк., 1991. 7. Хартов В.Я. Проектирование и отладка программ для микроконтроллеров AVR фирмы Atmel. - М.: Изд-во МГТУ им. Н.Э. Баумана, 2004. 8. Сайты фирмы Atmel: http://www.atmel.com, http://www.atmel.ru 9. Сайт фирмы Labcenter Electronics: http://www.labcenter.co.uk
Учебное издание Вячеслав Яковлевич Хартов МИКРОКОНТРОЛЛЕРЫ AVR Практикум для начинающих Редактор В.М. Царев Художник С. С. Водчиц Технический редактор Э.А. Кулакова Корректор О. В. Калашникова Компьютерная верстка О.В. Беляевой Оригинал-макет подготовлен в Издательстве МГТУ им. Н.Э. Баумана Санитарно-эпидемиологическое заключение № 77.99.02.953.Д.008880.09.06 от 29.09.2006 г. Подписано в печать 30.08.2007. Формат 60*90/16. Бумага офсетная. Гарнитура «Тайме». Усл. печ. л. 15. Уч.-изд. л. 14,09. Тираж 500 экз. Заказ 1998 Издательство МГТУ им. Н.Э. Баумана 105005, Москва, 2-я Бауманская, 5 Отпечатано с диапозитивов в ГУП ППП «Типография «Наука» 121099, Москва, Шубинский пер., 6