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

Пособие HCS12 & Elvis II v.7.01

.pdf
Скачиваний:
223
Добавлен:
03.05.2015
Размер:
4.14 Mб
Скачать

 

BCS

CHK3

;Если результат отрицательный, то перейти на CHK4.

 

CMPB

#20

;Иначе сравнить полученную разность с числом 20.

 

BCS

RES2

;Если меньше 20, то перейти на RES2.

 

BSET Result,$10

 

;Иначе Data2 − Data1 ≥ 20, значит надо

 

JMP

quit

 

;установить бит 4 результирующей ячейки в 1.

RES2

 

 

BSET Result,$04

 

;Если 0 < Data2 − Data1 < 20, то установить бит 2

 

JMP

quit

 

;результата в 1.

CHK3

;Загрузка в аккумулятор A данных из ячейки Data1.

LDAA

Data1

 

SUBA

Data2

;Вычитание из Data1 и значения ячейки памяти Data2.

 

CMPA

#20

;Сравнение полученной разности с числом 20.

 

BCS

RES1

;Если меньше 20, то переход по метке RES1.

 

BSET Result,$08

 

;Иначе Data1 − Data2 ≥ 20, значит надо

 

JMP

quit

 

;установить бит 3 результирующей ячейки в 1.

RES1

 

 

BSET

Result,$02

;Если 0 < Data1 − Data2 < 20, то установить бит 1

quit

JMP

quit

 

;результата в 1.

 

 

 

ORG

StartVector

 

 

DC.W

EX_5_1

 

 

Пример 5.2. Дан массив однобайтовых чисел без знака. Начальный адрес – $110, количество элементов – 15. Переписать массив, начиная с адреса $130, заменив числа, у которых младший бит равен нулю, а старший – единице, кодом $A9. Определить количество таких чисел.

RAMStart

EQU

$0000

ROMStart

EQU

$E000

StartVector

EQU

$FFFE

INITRG

EQU

$0011

Array1

EQU

$0110

;Адрес первого элемента исходного массива.

Array2

EQU

$0130

;Адрес первого элемента конечного массива.

N

EQU

$0150

;Ячейка памяти, в которую помещается количество

CNT

EQU

RAMstart

;элементов, подвергшихся замене.

;Ячейка памяти для счёта циклов.

EXC

EQU

$A9

;Код, на который необходимо заменить элементы

 

 

 

;массива, удовлетворяющие заданному условию.

 

ORG

ROMstart

 

EX_5_2

MOVB

#$08, INITRG

 

CLR

N

;Очистка ячейки с количеством изменённых элементов.

 

MOVB #15,CNT

;Загрузка счётчика циклов начальным значением.

 

LDX

#Array1

;Загрузка в регистр X адреса первого элемента

CHK

LDAB ,X

;исходного массива.

;Загрузка в аккумулятор B значения ячейки с адресом,

 

ANDB #$81

;находящимся в X.

 

;Выделение старшего и младшего битов.

 

CMPB #$80

;Сравнение с желаемым значением.

 

BNE

INIT

;Если не равны, то перейти по метке INIT.

 

 

 

131

 

INC

N

;Иначе увеличить счётчик заменённых элементов на 1.

 

LDAB

#EXC

;Загрузить код для замены.

INIT

BRA

SAVE

;Безусловный переход на SAVE.

LDAB

,X

;Загрузка в аккумулятор A элемента исходного массива.

SAVE

STAB

$20,X

;Сохранение элемента нового массива.

 

INX

CNT

;Увеличение адреса, хранящегося в регистре X, на 1.

 

DEC

;Уменьшение счётчика циклов.

 

BNE

CHK

;Если обработаны не все элементы, то перейти по метке

 

JMP

*

;CHK.

 

 

 

ORG

StartVector

 

DC.W

EX_5_2

 

Предложенный способ решения имеет ряд особенностей.

Во-первых, для проверки разрядов чисел мы воспользовались универсальным методом, который не зависит от местонахождения в памяти чисел первого массива. Метод заключается в выделении с помощью маски и команды “AND” значимых разрядов числа, т.е. тех, которые необходимо проверить по условию задачи. Элемент массива, ранее находившийся в аккумуляторе, при этом перестает соответствовать значению, записанному в ячейке памяти. Далее значение аккумулятора сравнивается с эталонной константой, которая гарантирует совпадение выделенных разрядов с заданными значениями. Обратите внимание, для переноса элемента из первого массива во второй, элемент необходимо заново восстановить в аккумулятор. Чтобы этого не приходилось делать, для анализа условий можно использовать команды битового процессора.

Во-вторых, мы воспользовались тем фактом, что все элементы первого массива и все элементы второго массива находятся в пределах одной страницы памяти. Поэтому возможно использование команды “INX” вместо “LEAX 1,X”.

Задачи для самостоятельной работы

1.Дан массив однобайтовых чисел со знаком. Начальный адрес – $200, количество элементов массива – 27. Начиная с адреса $100, переписать только положительные четные числа, определить количество отрицательных чисел.

2.Дан массив однобайтовых чисел со знаком. Начальный адрес – $120, код последнего элемента – $Е1. Найти среднее арифметическое максимального и минимального положительных чисел и количество положительных чисел.

3.Дан массив однобайтовых чисел со знаком. Начальный адрес – $E200, код последнего элемента – $Е1. Найти среднее арифметическое максимального и минимального положительных чисел и количество отрицательных чисел.

4.Произвести сортировку по возрастанию чисел, расположенных в ячейках $100..$120.

5.Произвести сортировку по убыванию чисел, расположенных в ячейках $50..$70.

6.Дан массив двухбайтовых чисел в прямом коде со знаком. Начальный адрес – $120, код последнего элемента – $1А24. Начиная с адреса $150 переписать только положительные чётные числа, определить количество отрицательных чисел.

7.Дан массив двухбайтовых чисел без знака. Начальный адрес – $E300, количество элементов массива – 11. Определить максимальное чётное число.

8.Дан массив однобайтовых чисел со знаком. Начальный адрес – $80, код последнего элемента – $12. Определить минимальное положительное нёчетное число и его адрес.

132

9.Дан массив двухбайтовых чисел без знака. Начальный адрес – $100, код последнего элемента – $3724. Начиная с адреса $120 записать только чётные числа, определить количество нечётных чисел.

10.Дан массив двухбайтовых чисел без знака. Начальный адрес – $120, количество элементов массива – 8. Определить максимальное число и его адрес.

133

Лабораторная работа № 6

Порты ввода/вывода и работа с ними

Содержание

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

Подготовка к работе

При подготовке к данной работе необходимо повторить систему команд.

Схемотехника учебного стенда

Рис. 9. Схема подключения периферии к портам МК

Практическая часть

Пример 6.1. Написать программу вывода следующих значений на порт B (светодиоды) в зависимости от кода выставленного на переключателях 1,2 (PRTB0, PRTB1): код 00 – значение $7, код 01 – значение $8, код 10 – значение $F, код 11 – значение $3.

В этой лабораторной работе и последующих мы не будем инициализировать начальный адрес пространства регистров специальных функций. Тогда он будет по умолчанию равен $0000. Т.е. эта область памяти расположится в начале всего адресного пространства. Оперативная память же будет следовать за ней по адресам $0400..$0FFF. Такая карта памяти устанавливается автоматически после сброса микроконтроллера и является конфигурацией по умолчанию. Именно она рассматривается в технической

134

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

RAMStart

EQU

$0400

;Теперь ОЗУ располагается по адресам $400..$FFF.

ROMStart

EQU

$E000

 

 

StartVector

EQU $FFFE

 

 

PRTB

EQU

$01

;Адрес регистра данных порта B.

DDRB

EQU

$03

;Адрес регистра направления передачи данных через

PUCR

EQU

$0C

;порт B.

;Адрес регистра контроля подтягивающих резисторов.

 

ORG

$E800

 

 

 

DC.B $80,$70,$00,$С0

;Запись в память массива значений,

 

 

 

 

;выводимых на порт B. Взяты значения в

 

 

 

 

;обратном коде, т.к для светодиодов

 

 

 

 

;активным уровнем является логический

 

 

 

 

;ноль.

 

ORG

ROMstart

 

 

 

MOVB #$F0,DDRB

 

;Инициализация младших четырёх битов

 

 

 

 

;порта B на ввод, остальных старших – на

 

BSET PUCR,$02

 

;вывод.

 

 

;Включение подтягивающих резисторов

 

 

 

 

;порта В.

EX_6_1

LDAA #$E8

 

;Загрузка в аккумулятор A старшего байта

 

LDAB PRTB

 

;адреса заданного массива.

 

 

;Считывание данных из порта B.

 

ANDB #$03

 

;“Отсечка” ненужных старших разрядов.

 

 

 

 

;Таким образом, в аккумуляторе D сформирован

 

 

 

 

;адрес ячейки памяти, данные из которой нужно

 

XGDX

 

 

;вывести на порт B.

 

 

 

;Посылка адреса в индексный регистр X.

 

LDAB ,X

 

;Побитная инверсия значения аккумулятора B.

 

COMB

 

 

 

STAB PRTB

 

 

 

JMP

EX_6_1

 

;Возвращение в начало программы.

 

 

 

 

;Т.к. цикл бесконечный, то порт B будет

 

 

 

 

;постоянно опрашиваться микроконтроллером.

 

ORG

StartVector

 

 

DC.W

EX_6_1

 

 

Комментарий к примеру:

В микроконтроллере лабораторного стенда к каждому выводу порта можно программно подключать или отключать «подтягивающие вверх» (pull-up) резисторы. Эти сопротивления нужны для того, чтобы на ножку микроконтроллера, если она настроена на ввод, стабильно приходила логическая единица. Если не использовать эти резисторы, то на выводе порта в режиме ввода и отсутствии на нём внешнего сигнала будет

135

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

Пример 6.2. Реализовать двоичный 4-разрядный счётчик с отображением его текущего значения на светодиодах. Тактовым входом счётчика является кнопка SW1 (PRTP0).

RAMStart

 

EQU

$0400

 

 

ROMStart

 

EQU

$E000

 

 

StartVector

EQU

$FFFE

 

 

PRTB

 

EQU

$01

;Адрес регистра данных порта B.

DDRB

 

EQU

$03

;Адрес регистра направления передачи данных через

PUCR

EQU

$0C

 

;порт B.

 

;Адрес регистра контроля подтягивающих резисторов.

PRTP

EQU

$0258

;Адрес регистра данных порта P.

DDRP

EQU

$025A

;Адрес регистра направления передачи данных через

PERP

EQU

$025C

;порт P.

;Адрес регистра контроля подтягивающих резисторов

 

 

 

 

 

;ножек порта P.

CT

EQU

RAMstart+$10

;Ячейка памяти ОЗУ для счётчика.

TMP

EQU

CT+$1

 

;Ячейка памяти для временных данных.

 

ORG

ROMstart

 

 

 

MOVB #$F0,DDRB

;Инициализация порта B: младший ниббл на

 

MOVB #$F0,PRTB

 

;ввод, старший – на вывод.

 

 

;Потушить все светодиоды.

 

BSET PUCR,$02

 

;Включение подтягивающих резисторов

 

BCLR DDRP,$03

 

;порта В.

 

 

;Установка двух младших разрядов порта P

 

BSET PERP,$03

 

;на ввод.

 

 

;Включение подтягивающих резисторов на

 

 

 

 

 

 

;двух младших разрядах порта P.

 

CLR

CT

 

 

 

;Установка начального значения счётчика в 0.

 

LDX

#PRTP

 

;Загрузка адреса порта P в индексный регистр X.

EX_6_2

LDY

#$4500

 

 

 

BRSET

,X,$01,*

 

;Ожидание логического нуля на ножке 0

DL1

NOP

 

 

 

 

;порта B.

 

 

 

 

;Цикл для создания временной задержки для

 

NOP

 

 

 

 

;подавления дребезга. Команда NOP не

 

NOP

 

 

 

 

;выполняет никаких действий (No Operation),

 

DEY

DL1

 

 

;лишь увеличивает задержку.

 

BNE

 

 

 

 

LDY

#$4500

 

 

 

BRCLR

,X,$01,*

 

;Ожидание логической единицы на ножке 0

DL0

NOP

 

 

 

 

;порта B.

 

 

 

 

;Цикл для создания временной задержки для

 

NOP

 

 

 

 

;подавления дребезга.

 

 

 

 

 

 

136

NOP

 

 

DEY

DL0

 

BNE

 

INC

CT

;Увеличение значения счётчика на 1.

MOVB CT,TMP

;Выгрузка значения счётчика во временную

COM

TMP

;ячейку памяти.

;Побитная инверсия значения ячейки TMP.

LSL

TMP

;Четыре сдвига влево содержимого временной

LSL

TMP

;ячейки памяти.

LSL

TMP

 

LSL

TMP

 

MOVB TMP,PRTB

;Перемещение данных из временной ячейки в

 

 

;порт B.

JMP

EX_6_2

;Возврат в начало, бесконечный цикл.

ORG StartVector

DC.W ROMstart

Комментарии к примеру:

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

Задачи для самостоятельной работы

1.Дан массив символов: фамилия, представленная в ASCII-коде. При переключении переключателя SW3-1 (PRTB0) из 0 в 1 в прямом порядке циклически отображать элементы массива на светодиодах. Т.е. сначала старший ниббл первого элемента, потом младший ниббл первого элемента, затем старший ниббл второго элемента и т.д.

2.Дан массив символов: фамилия, представленная в ASCII коде. При переключении переключателя SW3-2 (PRTB1) из 1 в 0 в обратном порядке циклически отображать элементы массива на светодиодах. Т.е. сначала младший ниббл последнего элемента, потом старший ниббл последнего элемента, затем младший ниббл предпоследнего элемента и т.д.

3.Дан массив символов: фамилия, представленная в ASCII-коде. Если переключатель SW3-2 в положении 0, то при переключении переключателя SW3-1 из 0 в 1 выводить на светодиоды поочерёдно младшие нибблы массива, а если переключатель SW3-2 в положении 1, то при переключении переключателя SW3-1 из 0 в 1 выводить на светодиоды поочерёдно старшие нибблы.

4.Дан массив символов: имя и фамилия, представленных в ASCII коде. При переключении переключателя SW3-3 (PRTB2) из 0 в 1 в прямом порядке отображать элементы массива на светодиодах. При переключении переключателя SW3-4 (PRTB3) из 1 в 0 в обратном порядке отображать элементы массива на светодиодах.

137

5.Реализовать реверсивный двоичный 4-разрядный счётчик с отображением значения на светодиодах. Тактовым входом для направления счёта вверх является переключатель SW3-1, тактовым входом для направления счёта вниз является переключатель SW3-2.

6.Реализовать реверсивный двоичный 4-разрядный счётчик с отображением значения на светодиодах. Тактовым входом является кнопка SW1 (PRTP0). Направление счёта определяется переключателем SW3-3: если 1 то вверх, если 0 то вниз. У счётчика должен быть также вход синхронного сброса: если переключатель SW3-4 установлен в 0, то по тактовому импульсу происходит сброс, если 1, то счётчик работает в нормальном режиме.

7.Реализовать сдвиговый регистр. Параллельный код с выхода регистра отображается на светодиодах. Входом данных регистра является положение переключателя SW3-3 (PRTB2). Тактовым входом регистра является кнопка SW2 (PRTP1).

138

Лабораторная работа № 7

Подсистема счётчика временных интервалов

Содержание

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

Подготовка к работе

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

Схемотехника учебного стенда

Рис. 10. Схема подключения периферии к портам МК

Практическая часть

Пример 7.1. Написать программу создания «бегущего огня» на светодиодах LED1..LED4 слева направо.

RAMStart

 

EQU

$0400

ROMStart

 

EQU

$С000

StartVector

EQU

$FFFE

PRTB

EQU

$01

;Адрес регистра данных порта B.

DDRB

EQU

$03

;Адрес регистра направления передачи данных через

PUCR

EQU

$0C

;порт B.

;Адрес регистра контроля подтягивающих резисторов.

TSCR1

EQU

$46

;Адрес регистра управления таймером TSCR1.

139

TSCR2

EQU

$4D

;Адрес регистра управления таймером TSCR2.

TFLG2

EQU

$4F

;Адрес регистра флагов прерываний TFLG2 таймера.

TMP

EQU

RAMstart+$10

;Ячейка памяти для временных данных.

 

ORG

ROMstart

 

 

EX_7_1

LDS

#$0FFF

 

;Инициализация верхушки стека. В качестве неё

 

 

 

 

;взят адрес последней ячейки оперативной

 

MOVB #$F0,DDRB

 

;памяти.

 

 

;Инициализация порта B: младший ниббл на

 

BSET PUCR,$02

 

;ввод, старший – на вывод.

 

 

;Включение подтягивающих резисторов

 

MOVB #$E0,PRTB

 

;порта В.

 

 

;Зажечь светодиод LED1.

 

MOVB #$10,TMP

 

;Установка начального значения временной

 

BSET TSCR2,$83

 

;ячейки в 1.

 

 

;Разрешение прерываний по переполнению

 

 

 

 

;таймера, установка частоты его тактирования

 

BSET TSCR1,$80

 

;равной fBUS/8.

 

 

;Включение таймера.

 

CLI

 

 

;Разрешение прерываний.

 

JMP

*

 

;Бесконечный пустой цикл, ожидание

 

 

 

 

;прерываний.

 

ORG

ROMstart+$100

 

TOF_INT

BSET TFLG2,$80

 

;Сброс флага переполнения таймера (TOF).

 

LSL

TMP

 

;Логический сдвиг влево содержимого

 

 

 

 

;временной ячейки памяти. Старший разряд

 

BCC

OUT

 

;помещается в бит переноса C.

 

 

;Если бит, значение которого равно 1, не был

 

MOVB #$10,TMP

 

;помещён в бит C, то перейти по метке.

 

 

;Иначе восстановить исходное значение

OUT

LDAB TMP

 

;временной ячейки (значение $10).

 

;Загрузка в аккумулятор B содержимого

 

COMB

 

 

;временной ячейки памяти.

 

 

 

;Поразрядная инверсия данных в регистре B.

 

 

 

 

;Производится, потому что активным уровнем,

 

 

 

 

;зажигающим светодиод порта B, является

 

STAB PRTB

 

;логический ноль.

 

 

;Сохранение данных в порт B.

 

RTI

 

 

;Возврат из подпрограммы прерывания.

 

ORG

$FFDE

 

;Запись вектора прерывания по переполнению

 

DC.W

TOF_INT

 

;таймера.

 

ORG

StartVector

;Запись вектора начального пуска.

 

DC.W

EX_7_1

 

 

 

 

 

 

140