Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Микроконтроллеры AVR

.pdf
Скачиваний:
119
Добавлен:
27.03.2015
Размер:
629.41 Кб
Скачать

ldi

r16,8

;r1 содержит анализируемое число

;счетчик цикла

clr

r0

;счетчик числа единиц в r1

loop:

 

 

sbrc r1,0

;инкремент r0, если бит 0 r1 равен единице

inc

r0

lsr

r1

;логический сдвиг r1 на один бит вправо

dec

r16

 

cpi

r16,0x00

brne loop

;бесконечный цикл

rjmp PC

 

Контрольные вопросы:

1.Логические команды.

2.Команды побитовой инверсии и дополнения до двух.

3.Каким образом реализуется команда TST? Какие способы ее реализации Вы еще можете предложить?

4.Какое значение принимает флаг С процессора после выполнения команды сдвига?

5.Отличия команд сдвига и вращения.

6.Отличия арифметического и логического сдвигов.

7.Реализация команд сдвигов и вращения влево через команды сложения.

8.Наращивание разрядности команд сдвигов.

9.Докажите, что при выполнении команд сдвига флаг S будет являться копией

флага C, если V принимает значение N C, а S всегда равен N V. 10.Алгоритм реализации операции умножения с помощью команд сдвига и

сложения.

Лабораторная работа №4.

Система команд AVR: команды манипуляций с битами. Модульное программирование. Подпрограммы

Цель работы: знакомство с командами манипуляций с битами, реализацией подпрограмм.

Порядок выполнения работы (п.п. 1-3 выполняются во внеаудиторное время):

1.Ознакомьтесь с теоретической частью лабораторной работы.

2.Разработайте блок-схемы программ для заданий 2-6.

3.Подготовьтесь к ответу на контрольные вопросы 1-10.

4.Выполните задания.

5.Защитите лабораторную работу.

К командам манипуляции с битами относятся команды установки и сброса отдельных разрядов в регистрах общего назначения и регистрах ввода/вывода.

Как уже говорилось, с помощью команд побитового И и ИЛИ реализуется сброс и установка битов регистров общего назначение. Еще четыре команды позволяют устанавливать и сбрасывать отдельные биты в регистрах

21

ввода/вывода. Команды SBI и CBI, соответственно, устанавливают и сбрасывают отдельные биты регистров ввода/вывода с адресами 0x000x1F. Команды BSET и BCLR устанавливают и сбрасывают отдельные биты регистра статуса процессора SREG (он имеет адрес 0x3F в адресном пространстве регистров ввода/вывода). На основе команд BSET и BCLR с помощью компилятора реализуется целая группа команд установки и сброса флагов (мнемоники команд этой группы начинаются с символов SE и CL).

В большинстве микроконтроллеров (в AVR – в том числе) отдельные выводы группируются в порты. У At90S2313 – два порта: 8-разрядный B и 7-разрядный D. Каждому выводу порта x (где x – это B или D) соответствует по одному разряду в трех регистрах: направления передачи (DDRx – Data Direction Register x), состояния внешнего вывода (PINx), и выходного регистра (PORTx). На рисунке 3 приводится обобщенная структура выводов At90S2313. Единица в соответствующем разряде DDRx открывает выходной буфер, разрешая тем самым передачу данных из соответствующего разряда регистра PORTx на внешний вывод Px.n. Операция чтения из регистра ввода/вывода PORTx, позволяет получить данные, которые записаны в PORTx. Операция чтения из регистра ввода/вывода PINx позволяет получить информацию о логическом уровне, присутствующем на выводе Px в действительности. В таблице 3 приведено описание режимов работы выводов микроконтроллера в зависимости от значений соответствующих разрядов DDRx и PORTx.

Vcc

RD

 

 

Подтяжка

&

 

 

Q D

 

 

C

WD

 

 

данных

 

DDRx.n

 

Px.n

Q D

 

 

C

WP

Шина

 

PORTx.n

 

 

RL

 

 

 

RP

 

 

RD - сигнал чтения регистра DDRx RL - сигнал чтения регистра PORTx RP - сигнал чтения состояния вывода

WD - сигнал записи регистра DDRx WP - сигнал записи регистра PORTx Vcc - напряжение питания

микроконтроллера

Рисунок 3. Обобщенная функциональная схема выводов общего назначения микроконтроллера At90S2313

22

Таблица 3. Режимы работы выводов At90S2313 в зависимости от состояния регистров DDRx и PORTx

DDRxn

PORTxn

Вход/ выход

Подтяжка

Комментарий

0

0

Вход

Выкл.

Третье состояние (высокий импеданс)

0

1

Вход

Включена

Px.n будет источником тока, если на

 

 

 

 

него извне подать логический ноль

1

0

Выход

Выкл.

Низкий уровень, двухтактный выход

1

1

Выход

Выкл.

Высокий уровень, двухтактный выход

До сих пор в рамках данного курса мы рассматривали программы, реализующие алгоритмы в виде единого целого. Такой метод проектирования программ, называемый монолитным, подходит для целей обучения или решения простейших прикладных задач.

С увеличением сложности задачи и объема программы монолитный метод становится неприемлемым – разработчик просто не в состоянии удерживать в своей памяти все необходимые детали. Естественный выход из такой ситуации

– переход к модульному программированию, т.е., разбиению большой и сложной задачи на более простые и мелкие части. В языках программирования низкого уровня такими частями являются подпрограммы.

Для реализации подпрограмм необходимы команды вызова подпрограммы и возврата из подпрограммы. Эти команды являются особыми командами передачи управления – для их работы требуется сохранение адреса возврата из подпрограммы. Для такого сохранения обычно используют стек. В некоторых процессорах такой стек реализуется аппаратно: имеется специальная память (обычно – всего несколько ячеек) и счетчик ячеек стека. При помещении информации в стек этот счетчик увеличивается, при извлечении – уменьшается. В других процессорах (в том числе – в At90S2313) стек реализуется аппаратнопрограммно: программистом под стек отводится область памяти данных, для доступа используется специальный регистр – указатель стека (англ. Stack Pointer – SP). Указатель стека хранит адрес вершины стека. После помещения информации в стек его указатель автоматически уменьшается; перед извлечением – увеличивается. Основное достоинство программного стека – потенциально бόльший объем, чем у аппаратного. Однако, перед использованием такого стека обязательно нужно проинициализировать указатель стека значением адреса конца области стека!

Механизм вызова подпрограммы и возврата из нее заключается в следующем. Команда вызова подпрограммы сохраняет в стеке адрес ячейки памяти следующей за этой командой (т.е., адрес следующей команды) и загружает в программный счетчик адрес вызываемой подпрограммы. После этого выполняется тело подпрограммы, в конце которой находится команда возврата. Команда возврата извлекает из стека адрес возврата (т.е., адрес команды, следующей за командой вызова) и загружает его в программный счетчик, возвращая тем самым управление вызывающе программе.

23

At90S2313 поддерживает команды относительного (RJMP) и косвенного

(IJMP) вызова подпрограмм. Обе эти команды являются безусловными. Другие процессоры поддерживают команды условного вызова подпрограмм; также, может задаваться абсолютный адрес подпрограммы. Возврат из подпрограмм обеспечивает команда RET.

Использование подпрограмм влечет несколько проблем:

1.В процессе своей работы подпрограммы изменяют содержимое различных регистров, ячеек памяти. При этом нельзя допускать порчи переменных, используемых в вызывающей программе (сохранение контекста).

2.Если подпрограмма обрабатывает какие-то данные, эти данные необходимо ей передать (передача параметров).

3.Если результатом работы подпрограммы являются какие-то данные, то необходимо их передать вызывающей программе (возврат результата).

Для сохранения контекста, очевидно, необходимо скопировать все регистры, которые используются подпрограммой, в некоторую область памяти; после выполнения – восстановить содержимое регистров. Наиболее удобно для целей сохранения/восстановления использовать механизм стека. В простейшем случае, это может быть тот же стек, что применяется для сохранения адреса возврата из подпрограммы, в других случаях – отдельный программно реализуемый стек.

Передачу параметров в подпрограммы можно организовать: через стек, через регистры, через глобальные переменные (неявно). Наиболее простой в случае программирования на Ассемблере для At90S2313 способ – передача параметров через регистры.

Возврат результата может происходить аналогичными способами. Если подпрограмма должна возвращать булево значение (ЛОЖЬ/ИСТИНА, 0/1), то это можно делать с помощью флага T из регистра состояния процессора.

При оформлении подпрограммы в ее заголовке следует обязательно указывать:

-назначение подпрограммы;

-способ передачи параметров;

-способ возврата результата;

-используемые ресурсы (изменяемые в процессе работы регистры, переменные, используемый объем стека).

На практике часто возникает необходимость обеспечить интерфейс микроконтроллера с внешними устройствами (микросхемы памяти различных типов, драйверы индикаторов, таймеры реального времени и т.д.). Во многих случаях это достигается путем программной эмуляции того или иного протокола с помощью команд манипуляции битами регистров ввода/вывода и команд условного выполнения. На рисунке 4 приводятся подключение и временная диаграмма обмена At90S2313 с микросхемой АЦП ADS1210 через программно эмулируемый порт SPI. По линии MOSI (Master Output Slave Input) происходит передача данных от микроконтроллера к АЦП; по линии MISO

24

(Master Input Slave Output) – от АЦП к микроконтроллеру. Захват данных по этим линиям должен происходить по отрицательному фронту сигнала синхронизации SCK, формируемого микроконтроллером. Микросхема АЦП реагирует на сигналы SCK, MOSI и формирует сигнал MISO только в том случае, когда сигнал выборки /CS имеет низкий логический уровень. Ниже приводятся подпрограммы, обеспечивающие обмен At90S2313 и ADS1210.

SCK

t

At90S2313

ADS1210

MOSI

 

 

 

 

 

 

PD3

MISO

SDOUT

I7

I6

I5

I1

I0

 

MOSI

t

PD4

SDIO

MISO

 

 

 

 

 

 

PD5

SCK

SCLK

O7

O6

O5

O1

O0

t

CS

PD6

CS

 

 

 

 

 

 

ADS1210: захват входных данных

 

 

 

 

 

 

ADS1210: готовность выходных данных

 

 

 

Рисунок 4. Обмен At90S2313 с микросхемой АЦП ADS1210

.EQU mosi_bit = 0x4

.EQU miso_bit = 0x3

.EQU

sck_bit

=

0x5

.EQU

ss_bit

=

0x6

;бит PORTx, отвечающий за линию MOSI ;бит PORTx, отвечающий за линию MISO ;бит PORTx, отвечающий за линию SCK ;бит PORTx, отвечающий за линию CS_ADC

;=================================================================== ;Подпрограмма инициализации SPI-порта

;r16 - используется spi_ini:

ldi r16,(EXP2(mosi_bit)|EXP2(sck_bit)|EXP2(ss_bit)|EXP2(cs_res_bit)) out DDRD,r16 ;разрешение выходов mosi, sck, ss

sbi PORTD,ss_bit sbi PORTD,cs_res_bit cbi PORTD,sck_bit cbi PORTD,mosi_bit

ret

;=================================================================== ;Подпрограмма эмуляциии SPI-порта

;r18 должен содержать передаваемый байт

;r17 содержит принятый байт

 

;r16 - используется

 

spi_emulation:

;регистр сдвигаемой маски

ldi r16,0x80

clr r17

;очистка регистра-приемника

spi_m1:

;MOSI=0

cbi PORTD,mosi_bit

sbrc r18,7

;

sbi PORTD,mosi_bit

;MOSI=1 если нужно выдать 1

sbi PORTD,sck_bit

;SCK=1

lsl r18

;сдвиг передаваемого байта

sbic PIND,miso_bit

;проверка уровня MISO

or r17,r16

;SCK=0

cbi PORTD,sck_bit

lsr r16

;сдвиг регистра-маски

brne spi_m1

 

ret

 

25

;=================================================================== ;Подпрограмма включения сигнала выборки АЦП

ADS1212_select:

cbi PORTD,ss_bit

ret

;=================================================================== ;Подпрограмма снятия сигнала выборки АЦП

ADS1212_unselect:

sbi PORTD,ss_bit

ret

Задания:

1.Пронаблюдайте работу программы из примера 8. Какую функцию выполняет оператор out SPL,r16 ?

2.Напишите подпрограмму, которая устанавливает флаг T, если выполняется условие (r0.0!=r1.7)&&( r0.3==r1.4)&&r1.2, и сбрасывает его в противном случае.

3.Напишите подпрограмму, которая производит умножение двух чисел, лежащих в диапазоне от 0 до 3, используя таблицу произведений.

4.Напишите программу, которая настраивает порт PB.1 как выход.

5.Напишите программу, которая настраивает Таймер 0 на синхронизацию от тактового сигнала микроконтроллера с коэффициентом деления 8.

6.Нарисуйте временную диаграмму работы драйвера 7-сегментного индикатора D1 на рисунке 5. Согласно нарисованной временной диаграмме разработайте подпрограмму, которая выводит 1 байт данных в драйвер D1.

 

 

D Q

dp

 

 

 

 

 

 

 

C

g

 

 

 

D Q

DATA

 

 

 

 

 

 

/CS

 

 

C

f

 

 

D Q

CLK

 

 

 

SEL

 

 

C

e

 

 

D Q

 

 

 

 

 

 

 

C

d

 

 

 

D Q

 

 

 

 

Vcc

 

 

C

 

 

 

c

 

 

 

D Q

 

 

 

 

 

 

 

C

b

 

 

 

D Q

 

/CS

&

 

 

C

 

 

CLK

a

 

 

D Q

 

DATA

 

 

 

 

 

C

 

 

 

 

D1

D2

 

 

 

 

Рисунок 5. Схема индикации

 

PB.1

At90S2313

 

PB.1

PB.1

PB.1

D3

SEL

26

Пример 8:

Показывает организацию вызова подпрограмм в микроконтроллерах AVR на примере преобразования ASCII-символов шестнадцатеричных чисел (‘0’…’9’ и ‘A’…’F’) в соответствующее им двоичное представление.

.INCLUDE "..\appnotes\2313def.inc" ;подключение файла со

.DSEG

 

;спецификацией регистров ввода/вывода

 

 

.ORG 0x60

.BYTE 10

;входной массив ASCII-символов

InArr:

OutArr:

.BYTE 10

;выходной массив двоичных чисел

.CSEG

;сегмент кода

rjmp Reset

;вектор прерывания, вызываемого по сбросу микроконтроллера

Reset:

;начало программы

ldi

r16,0x90

 

out

SPL,r16

;указатель X проинициализирован значением

ldi

XL,LOW(InArr)

ldi

XH,HIGH(InArr)

;адреса начала массива InArr

ldi

YL,LOW(OutArr)

;указатель Y проинициализирован значением

ldi

YH,HIGH(OutArr)

;адреса начала массива OutArr

ldi

r17,10

 

loop:

 

;передача исходного ASCII-символа

ld r16,X+

rcall ascii_to_bin

;вызов подпрограммы преобразования ASCII/двоич.

st Y+,r16

;сохранение двоичного эквивалента

dec

r17

 

cpi

r17,0

 

brne

loop

 

rjmp PC

;бесконечный цикл

;подпрограмма преобразует ASCII-символ 16-ного числа в двоичное число ;символ передается через r16, результат возвращается через r16

ascii_to_bin:

 

cpi

r16,0x39

 

brcs

atb_m1

 

subi

r16,0x30

;символ '0'...'9'

rjmp atb_end

 

atb_m1:

 

;символ 'A'...'F'

subi r16,0x37

atb_end:

 

 

ret

 

 

Контрольные вопросы и задания:

1.Опишите процесс вызова подпрограммы и возврата из нее.

2.Объясните, почему команды переходов, вызова/возврата из подпрограмм требуют для своего выполнения двух и более тактов, тогда как остальные команды – только один такт?

3.Виды команд передачи управления (переходы/вызовы, условные/безусловные, абсолютные/относительные/косвенные).

4.Сравните модульный и монолитный подход к разработке программного обеспечения.

27

5.Способы передачи параметров в подпрограммы, возвращения результата, сохранения контекста вызывающей программы.

6.Способы реализации стека для хранения адреса возврата из подпрограммы. Проблемы, связанные с использованием стека.

7.Какими средствами можно установить, сбросить, инвертировать значения отдельных битов регистров общего назначения?

8.Какими средствами можно установить, сбросить, инвертировать значения отдельных битов регистров ввода/вывода?

9.Какие средства в AVR существуют для копирования значений отдельных

битов из регистра в регистр?

10.Порты ввода/вывода At90S2313: функциональная схема, работа, способы использования.

Лабораторная работа №5. Прерывания. Программные автоматы

Цель работы: знакомство с организацией системы прерываний, программной реализацией автоматов с помощью микроконтроллеров.

Порядок выполнения работы (п.п. 1-3 выполняются во внеаудиторное время):

1.Ознакомьтесь с теоретической частью лабораторной работы.

2.Разработайте блок-схемы программ для заданий 1-4.

3.Подготовьтесь к ответу на контрольные вопросы 1-7.

4.Выполните задания.

5.Защитите лабораторную работу.

Имеется необходимость во взаимодействии процессора с внешним миром, его реакциях на внешние события. К организации этого взаимодействия можно подойти следующими способами:

-Процессор может периодически опрашивать состояния внешних входов, периферийных устройств и т.п. Такую чисто программную обработку внешних событий называют поллингом. Поллинг требует больших ресурсов времени процессора и обеспечивает невысокую скорость реакции на внешние события, причем, временные затраты с уменьшением времени реакции возрастают.

-Процессор может быть дополнен узлом, который независимо от самого процессора опрашивает состояния входов и периферийных устройств. В случае обнаружения какого-либо события (появление на внешнем входе того или иного фронта или уровня, изменение флага состояния периферийного устройства и т.п.), этот дополнительный узел прерывает выполнение процессором его текущего потока команд, загружая в программный счетчик адрес специальной подпрограммы. Такое принудительное изменение хода выполнения программы называется прерыванием, а вызываемая подпрограмма – подпрограммой обслуживания или обработки

28

прерывания (иногда используют термин "обработчик прерывания").

Событие вызывающее прерывание называется источником прерывания. В отличие от поллинга, прерывания обеспечивают реакции даже на кратковременные события с минимальными затрата времени процессора.

Организация опроса внешних выводов и устройств с помощью поллинга очевидна: программа представляет собой бесконечный цикл, в котором и производится анализ их состояния. В случае обнаружения интересующего события, происходит переход к ветви алгоритма, обрабатывающей это событие. Такую ветвь удобно оформить в виде подпрограммы.

В чем сходства и каковы различия между обычной подпрограммой и подпрограммой обработки прерывания?

Сам термин "подпрограмма" предполагает использование механизма вызова из основной программы некоторого модуля, с последующим возвратом управления основной программе. В случае обычной подпрограммы, адрес ее начала в том или ином виде содержится в команде вызова. Адрес обработчика прерывания задается через таблицу векторов прерываний. Каждому источнику прерывания соответствует свой вектор – одна или несколько ячеек памяти. В некоторых процессорах вектор хранит адрес начала обработчика прерывания. В других (к ним относятся и микроконтроллеры AVR) – первую (или, несколько первых) команду собственно обработчика прерывания. При этом, как правило, в векторе размещается команда безусловного перехода к основной части обработчика.

Из неопределенности точки вызова следует и то, что такой подпрограмме нельзя передавать параметры, а сама она не может возвращать параметры через стек или флаги слова состояния процессора (но вполне может изменять значения глобальных переменных).

Аналогично с вызовом обычной подпрограммы, при вызове обработчика прерывания в стеке автоматически сохраняется адрес возврата – адрес команды, с которой должно продолжится выполнение основной программы.

Особенностью вызова обработчика прерывания является неопределенность ее места вызова из основной программы. Поэтому подпрограмма обработки прерывания должна сохранять содержимое арифметических флагов процессора в том состоянии, в котором они находились на момент ее вызова. Проиллюстрируем такую необходимость. Предположим, основной фрагмент программы содержит следующие операторы:

mov r0, r5

;1

cmp r0, r1

;2

brne m1

;3

clr r4

;4

rjmp m2

;5

m1:

;

ser r4

;6

m2:

 

 

29

Пусть после выполнения команды №2 была вызвана подпрограмма обработки прерывания. Если эта подпрограмма изменит значение флага нулевого результата Z, то в регистр r4 может быть загружено неверное значение.

По этой же причине, подпрограмма обработки должна сохранять содержимое всех регистров, которые она использует, и которые используются в прерываемой программе.

Как правило, для сохранения флагов и регистров используется программный стек: в начале обработчика прерывания содержимое всех используемых регистров и флагов помещается в стек, откуда оно извлекается в конце обработчика. Следующий пример показывает подпрограмму обработки прерывания приемника последовательного порта. Обратите внимание, что, поскольку, доступ к стеку производится через его вершину, то порядок извлечения данных из стека – обратный порядку сохранения. В этом примере регистр X используется как глобальная переменная (указатель буфера) и, потому, не сохраняется в стеке.

;Обработчик прерывания от приемника последовательного порта

RX_Complete_ISR:

push r0

;сохраняем r0

push r16

;сохраняем r16

in r0,sreg

;сохраняем состояние флагов процессора

push r0

;

in r0,UDR

;считываем содержимое приемника

ldi r16,0x30

;

cp r0,r16

;

brlo m1

;корректируем полученный символ,

inc r0

;если необходимо

m1:

;сохраняем символ в буфере

st X+,r0

pop r0

;

out sreg,r0

;восстанавливаем состояние флагов процессора

pop r16

;восстанавливаем r16

pop r0

;восстанавливаем r0

reti

 

Один и тот же сигнал прерывания может присутствовать постоянно (если, например, прерывание формируется при наличии на входе заданного уровня). В этом случае, возникает угроза рекурсии вызова обработчика прерывания. Либо, во время работы одного обработчика прерывания может произойти событие, вызывающее другое прерывание – возникает проблема вложенности прерываний. Бывает необходимо запретить реакцию на все или некоторые источники прерываний. Могут возникнуть одновременно несколько событий, вызывающих прерывания – возникает необходимость выбора порядка их обслуживания. Для решения этих задач существуют следующие механизмы:

-Глобальный запрет (маскирование) прерываний – запрещает обслуживание прерываний от любых источников. Обычно, слово состояния процессора содержит бит глобального запрета/разрешения прерываний (в AVR – бит I). Если слово состояния доступно через пространства памяти

30