Скачать 1.28 Mb.
|
Что такое микроконтроллер AVR? Сразу определимся с терминами и прочим “по умолчанию”. Рассматривать будем восьмиразрядные микроконтроллеры семейства AVR (далее - МК). Считаем, что читатель имеет представление о цифровой технике, знает, за какой конец держится паяльник и знает хотя бы Бейсик. Не рассматривайте этот учебник как абсолютно полный и точный - наверное, это просто невозможно. Я хочу написать предельно простое и понятное пособие для первого ознакомления с МК, которое не запугает начинающего до смерти :-) Итак, что же представляет собой типичный МК? Это микросхема, в которой на одном кристалле умещается уйма разнообразнейших устройств. Управляет всем арифметико-логическое устройство (АЛУ). К АЛУ подключен тактовый генератор, частота которого определяется, как правило, внешним кварцем, подключенным к выводам XTAL1 и XTAL2. Для AT90S8535 максимальная частота тактового генератора – 8 МГц, соответственно период, или длительность одного такта – 125 нс. Именно за это время выполняется большинство команд МК. Но не будем торопиться. Итак, на АЛУ поступает тактовый сигнал (TCK), АЛУ выбирает из ПЗУ команду и выполняет ее. А вот тут надо как-то одновременно рассказать и о командах, и о том, что они, собственно, изменяют и на что влияют… И рассказать желательно одновременно, поскольку все между собой тесно завязано. Наверное, все-таки начнем со второго. Несмотря на такое, казалось бы, различие между этими двумя МК (8535 и Tiny15) - ядро и система команд у них практически одинаковы
Упомянем еще биты блокировки памяти и биты конфигурации. Они никак не связаны с адресным пространством и не читаемы программно, изменяются только программатором. Первые предназначены для защиты от пиратства - будучи установленными, запрещают чтение ПЗУ программ снаружи. На работу программы не влияют, и сбрасываются только при очистке кристалла. Вторые определяют режимы работы МК и не изменяются при стирании кристалла. Количество их разных МК - от одного до двух десятков. Подробнее мы их рассмотрим позже. ПОРТЫ Порты A, B, C и D - это двунаправленные восьмиразрядные порты ввода-вывода. Они имеют аналогичную структуру. Каждый порт представлен тремя регистрами: PORTx, PINx и DDRx. Каждый бит регистров соответствует выводу МК. Так, PORTA.0, PINA.0 и DDRA.0 соответствуют выводу 40 МК AT90s8535 (см. рисунок). Каждый вывод порта может быть настроен на ввод или на вывод. Да... Не звучит. Вывод на вывод. Давайте условимся - контакт(вывод) МК будем обзывать pin. Итак - каждый pin может быть настроен на ввод или вывод в любых комбинациях. Для того, чтобы pin стал выходом, надо записать лог. "1" в соответствующий разряд регистра DDRx. В этом случае то, что будем записывать в регистр PORTx - будет отображаться на pin МК, то есть управлять внешней схемой, зажигать светодиод или еще что... Если pin настроен на вход, то состояние pin-а может быть прочитано МК в регистре PINx. Регистр PORTx в этом случае управляет подтягивающим резистором (на Vcc) - при записи "1" в соответствующий разряд PORTx он включается. Входное сопротивление настроенного на ввод pin-а велико, и если он никуда не подключен ("болтается в воздухе"), то достаточно поднести к устройству руку, чтобы МК начал читать оттуда все что угодно, но чаще - наводку 50 Гц Почти каждый pin модет выполнять альтернативную функцию (а в некоторых МК - более одной). Естественно, что использовать его в качестве обычной линии ввода-вывода нельзя. Альтернативные функции (на рисунке - в скобках) включаются при разрешении и соответствующей настройке соответствующих им периферийных устройств. Но режим ввод/вывод надо настроить самому. Так, если нужно использовать USART (асинхронный последовательный интерфейс), то нужно включить USART, разрешить работу приемника и передатчика и настроить PORTD.1 на выход (на вход без подтягивающих резисторов все линии всех портов настроены по сбросу). Регистры ввода-вывода Как мы уже упомянули в прошлом уроке, в адресном пространстве МК отведено 64 байта под регистры ввода-вывода (далее-РВВ). В зависимости от модели МК число реально имеющихся РВВ различно, физическая суть тоже отличается очень сильно. Наверное, лучше всего взять какой-то конкретный МК и коротко расписать его РВВ. Для более подробной информации - кликайте по имени. Поскольку AT90s8535 наиболее универсален, рассмотрим его в качестве примера. Некоторые существенные отличия семейств Меga и Tiny смотрите в Система команд(Mega) Прошу извинить что тут еще не все регистры описаны подробно - не успел.
Время летит быстро - не успел оглянуться, как classic AVR уже устарели, и им на смену пришли Mega и Tiny... И при всех своих преимуществах еще и стоят дешевле :-) Итак, какие же основные отличия их от classic? Опять же сразу оговорюсь - я вряд ли смогу на этой страничке ухватить все... Но с чем сам работал - постараюсь не забыть. Итак, начнем с системы команд. Тут тоже надо оговориться - не все команды присутствуют во всех новых МК.
Основное отличие архитектуры - настраиваемый тактовый генератор. Точное описание надо смотреть в даташите на конкретный МК, поскольку возможности и "умолчание" могут сильно отличаться, но основные отличия от classic таковы: Тактовый генератор может работать не только от внешнего кварца, но и от внешнего генератора и - самое главное - от встроенного RC генератора. Последний режим - по умолчанию, кроме того, частота этого RC генератора может выбираться установкой fuse-бит. У большинства МК по умолчанию - 1 МГц встроенный RC по умолчанию. Но, например, у Tiny2313 по другому! Сразу хочу предупредить - с установкой fuse надо быть осторожным, помнить о том, что "галочка" или "1" - это состояние НЕЗАПРОГРАММИРОВАНО! Многие на этом обламывались :-) да и я сам. Помните о том, что неверная комбинация fuse бит может привести к неработоспособности МК! Описания регистров. SREG $3F ($5F) Слово состояния процессора. Биты этого РВВ отображают результаты выполнения команд процессора: C - перенос , Z-ноль, N - отрицательный результат, V - переполнение, H - перенос из младшей тетрады, S - знак, T - копируемый бит, I - общее разрешение прерываний. Все биты, кроме I и T, изменяются в зависимости от результата выполнения процессором арифметических и логических операций. Так, если результат операции равен нулю, будет установлен в лог."1" бит Z. Все биты могут быть изменены и прочитаны программно, и все они определяют работу команд ветвления. Обязательно должен сохраняться при входе в прерывание и восстанавливаться перед выходом из него! Делается это примерно так: Timer_int:push R16 in R16,SREG push R16 ; тут собственно обработка прерывания pop R16 out SREG,R16 pop R16 reti SPL $3D ($5D), SPH $3E ($5E) Два регистра - SPL и SPH - образуют 10-ти битный указатель стека. Вообще-то я почти уверен, что понятие "стек" читающего эти строки не пугает. Добавлю только, что стек у AVR растет вниз, указатель декрементируется ПОСЛЕ выполнения команды PUSH. То есть инициализировать указатель стека надо занесением туда адреса последней ячейки SRAM. ldi R16, lo(RAMEND) out SPL,R16 ldi R16, hi(RAMEND) out SPH, R16 Константа RAMEND обычно определена в .inc файле соответствующего процессора. Надо еще отметить, что в некоторых МК, размер SRAM которых менее 256 байт, указатель стека не имеет старшего байта. GIMSK $3B ($5B), GIFR $3A ($5A) Эти два регистра предназначены для управления внешними прерываниями. Внешнее прерывание программы вызывается фронтом, спадом или уровнем на выводе INTx МК в том случае, если установлен общий флаг разрешения прерывания I в SREG и соответствующий флаг INTx в регистре GIMSK. Если ваша программа работает с прерываниями, то регистр GIFR вам, в общем-то, и не нужен. В нем устанавливается в "1" флаг INTFx в том случае, если прерывание запрещено, а ситуация возникновения прерывания имеется. Программа может опрашивать эти флаги и предпринимать какие-либо действия. Следует только помнить, что флаги в регистре GIFR автоматически сбрасываются при обработке прерывания, если же прерывания запрещены - то сбросить их программно можно, записывая в соответствующий бит "1" (нелогично? но именно так и есть) Если вы знаете, что такое прерывания - далее можете не читать. А я попробую простым языком изложить суть прерываний. На мой взгляд, это очень важная тема, без понимания механизма прерываний построить эффективную realtime программу для МК просто невозможно. Допустим, нужно создать на МК устройство, которое должно выполнять какое-нибудь достаточно сложное вычисление (занимающее, например, 0,1 секунды) и в то же время переключать один из своих pin-ов с частотой 1 кГц. Как это сделать? Ну, время считать будет таймер - это естественно. Настроили таймер так, чтобы он через 1 мс выставлял флажок переполнения. А дальше? Вставлять в программу через 10 команд проверку этого флага? Это уже не программа будет, а сыр с дырками. Да к тому же 10 команд можно написать таких, что выполняться они будут и в течение секунды. Как быть? А вот тут-то и надо использовать прерывание. Таймер у нас настроен на переполнение через 1 мс, так разрешим прерывание переполнения. Кроме этого. должен быть установлен флаг общего разрешения прерываний. Что же произойдет при переполнении таймера? Закончив выполнение текущей команды, МК сохранит значение счетчика команд в стеке, после чего выполнение передастся на соответствующий вектор прерывания, а проще - конкретный адрес, закрепленный за прерыванием. См. таблицу векторов для МК 8535
TIMSK $39 ($59), TIFR $38 ($58) Эти два регистра предназначены для управления прерываниями от таймеров. У МК 8535 три таймера, таймер 0 может генерировать только прерывание по переполнению счетчика, таймер 2 - по переполнению счетчика и по совпадению с регистром сравнения, а таймер 1 - целых четыре: по переполнению, по сравнению(2) и по сигналу захвата. Подробнее - см. в описании таймеров. Так вот в регистре TIMSK установкой соответствующего бита в "1" прерывание разрещается (не забывайте по общий флаг разрешения прерывания в SREG!). Если прерывание не разрешено, а событие возникновения этого прерывания произошло, то соответствующий бит (по расположению совпадает с TIMSK) будет установлен в регистре TIFR - регистре флагов прерываний таймеров. Программа МК может эти флаги анализировать, чтобы сбросить - надо записать туда "1". MCUCR $35 ($55)
MCUSR $34 ($54) Регистр статуса MCUSR нужен для определения причины сброса процессора. В нем определены только два бита - PORF (MCUSR.0) и EXTRF (MCUSR.1). В зависимости от того, из-за чего произошел сброс (говоря иначе - пуск программы с 0 адреса) - биты MCUSR будут установлены следующим образом: Установлен в "1" бит PORF - по сути, это и не сброс вовсе, а старт программы по включению питания. Но так как при включении питания программа стартует с вектора 0 - считается сбросом по включению питания. Установлен в "1" бит EXTRF - сброс произошел из-за подачи низкого уровня на pin Reset Есть еще одна возможная причина сброса - сторожевой таймер, если он включен. В этом случае биты PORF и EXTRF не изменяются. Следовательно, если в программе нужно определять режим сброса - то после анализа этих бит их просто нужно установить в "0". Тогда сброс по сторожевому таймеру можно будет определить по отсутствию "1" в вышеописанных битах TCCR0 $33 ($53), TCNT0 $32 ($52) >>Следующий Таймер 0 - самый простой из таймеров, присутствует практически во всех МК AVR. В своем составе он имеет 8-ми разрядный счетчик TCNT0 и регистр управления TCCR0. TCCR0 - определяет скорость и режим счета таймера. В него записывается число от 0 до 7 (3 разряда):
При переполнении (переход из состояния 0xFF в 0x00) счетчика таймера устанафливается флаг TOV0 в регистре TIFR, и если разрешено прерывание (установлен TOIE0 в TIMSK и I в SREG - будет выполнено прерывание по вектору 0x009. Никаких других "фишек" таймер 0 не имеет. ТАЙМЕР1 >>Следующий Таймер 1 - наиболее сложный таймер. Счетчик у него 16-ти разрядный, доступ к нему со стороны процессора осуществляется через два регистра - TCNT1L и TCNT1H. Кроме него, таймер 1 содержит еще три 16-ти разрядных регистра - OCR1A, OCR1B и ICR1( Кстати, обратите внимание на порядок их чтения и записи!). Но не будем торопиться и начнем с регистров управления.
|