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

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

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

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

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

Время, через которое переполнится таймер (период):

T =

kдел KT

=

8 65536

= 0.262 с.

fBUS

2 106 Гц

 

 

 

Пример 7.2. Написать программу, которая реализует свечение светодиодов LED2, LED3 порта B с максимальной яркостью, а LED1, LED4 – с намного меньшей яркостью.

Для понижения яркости свечения в программе реализуется ШИМ для светодиодов

LED1 и LED4.

RAMStart

 

EQU

$0400

 

ROMStart

 

EQU

$С000

 

StartVector

EQU

$FFFE

 

PRTB

EQU

$01

 

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

DDRB

EQU

$03

 

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

PUCR

EQU

$0C

 

;порт B.

 

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

TIOS

EQU

$40

 

;Адрес регистра выбора режима каналов: входной

TSCR1

EQU

$46

 

;захват или выходное сравнение.

 

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

TSCR2

EQU

$4D

 

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

TIE

EQU

$4C

 

;Адрес регистра разрешения прерываний по событиям

TFLG1

EQU

$4E

 

;в каналах таймера.

 

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

TFLG2

EQU

$4F

 

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

TC0H

EQU

$50

 

;Адрес старшего байта регистра канала

TC0L

EQU

$51

 

;захвата/сравнения 0 таймера.

 

;Адрес младшего байта регистра канала

TC7H

EQU

$5E

 

;захвата/сравнения 0 таймера.

 

;Адрес старшего байта регистра канала

TC7L

EQU

$5F

 

;захвата/сравнения 7 таймера.

 

;Адрес младшего байта регистра канала

 

 

 

 

;захвата/сравнения 7 таймера.

 

ORG

ROMstart

 

EX_7_2

LDS

#$0FFF

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

 

 

 

 

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

 

MOVB #$F0,DDRB

;памяти.

 

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

 

BSET PUCR,$02

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

 

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

 

MOVB #$00,PRTB

;порта В.

 

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

 

 

 

 

141

 

BSET TIOS,$81

;Выбор режима выходного сравнения для

 

 

 

;каналов 0 и 7. По событию в канале 7 будет

 

 

 

;сбрасываться таймер (т.е. устанавливаться

 

MOVB #$40,TC7H

;значение его счётчика равным $0000).

 

;Установка уровня сравнения канала 7 в $4000.

 

MOVB #$00,TC7L

 

 

MOVB #$20,TC0H

;Установка уровня сравнения канала 0 в $0200.

 

MOVB #$00,TC0L

;При достижении счётчиком этого значения

 

 

 

;будет вызываться подпрограмма прерывания по

 

BSET TIE,$01

;этому событию.

 

;Разрешение прерываний по событию в канале 0

 

BSET TSCR2,$88

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

 

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

 

 

 

;таймера, включение его сброса при успешном

 

 

 

;событии выходного сравнения в канале 7.

 

 

 

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

 

BSET TSCR1,$80

;fBUS.

 

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

 

CLI

 

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

 

JMP

*

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

 

 

 

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

OC7_INT

BSET TFLG1,$80

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

 

CLR

PRTB

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

 

RTI

 

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

OC0_INT

BSET TFLG1,$01

;Сброс флага события выходного сравнения в

 

BSET PRTB,$90

;канале 0 (C0F).

 

;Выключить светодиоды LED1 и LED4.

 

RTI

 

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

 

ORG

$FFE0

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

 

DC.W

OС7_INT

;выходного сравнения в канале 7 таймера.

 

ORG

$FFEE

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

 

DC.W

OC0_INT

;выходного сравнения в канале 0 таймера.

 

ORG

StartVector

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

 

DC.W

EX_7_2

 

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

Таймер сбрасывается не по переполнению, а по событию выходного сравнения в канале 7. Таким образом, максимальное значение при счёте равно не $FFFF, а $3FFF. Сделано это для того, чтобы уменьшить период таймера (в 4 раза) и, тем самым, устранить видимые пульсации яркости свечения светодиодов LED1 и LED4.

Для того чтобы изменить значение 16-разрядной ячейки уровня сравнения в любом из каналов, нужно записать значения в оба 8-разрядных регистра TCxH и

142

TCxL. Если это сделать только для одного из них, то данные в нём не сохранятся, пока не занести информацию во второй регистр.

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

Аналогично со случаем переполнения в подпрограммах прерывания по событию выходного сравнения первым делом нужно сбрасывать флаг (CxF).

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

1.Написать программу, в которой яркость свечения светодиодов спадает от LED4 к LED1.

2.Написать программу, в которой светодиоды LED1 и LED4 светятся с максимальной яркостью, а светодиоды LED2 и LED3 мигают с небольшой частотой.

3.Написать программу, в которой светодиоды LED1 и LED4 горят с максимальной яркостью, а свечение светодиодов LED2 и LED3 регулируется переключателем SW3-2: код 1 – максимальная яркость, код 0 – яркость, меньшая максимальной.

4.Реализовать «бегущий огонь» а светодиодах LED1..LED4. Переключателем SW3- 1 должно меняться направление пробега.

5.Реализовать «бегущий огонь» справа налево на светодиодах LED1..LED4. Скорость пробега регулируется двумя переключателями SW3-3 и SW3-4 следующим образом: код 00 – 1 переход/с, код 01 – 2 перехода/с, код 11 – 3 перехода/с, код 10 – 4 перехода/с.

6.Реализовать «бегущий огонь» слева направо на светодиодах LED1..LED4 с невысокой постоянной скоростью. Переключателем SW3-1 должно меняться направление пробега, а переключателем SW3-2 – скорость пробега на вдвое большую и обратно.

7.Реализовать «бегущий огонь» слева направо на светодиодах LED1..LED4 с маленькой постоянной скоростью. В начале каждого нового пробега скорость должна увеличиваться. После 6 пробегов скорость становится первоначальной и далее процесс повторяется.

143

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

Модуль аналого-цифрового преобразователя

Содержание

В лабораторной работе изучается периферийный модуль микроконтроллера – аналого-цифровой преобразователь (АЦП).

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

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

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

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

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

Пример 8.1. Произвести аналого-цифровое преобразование сигнала с потенциометра RV1 (PRTAD5). АЦП микроконтроллера работает в 8-разрядном режиме. Результат в двоичном виде вывести на линейку светодиодов LED4..LED1.

Т.к. светодиодов всего 4, то будем выводить на них старший ниббл результата.

RAMStart

 

EQU

$0400

ROMStart

 

EQU

$С000

StartVector

EQU

$FFFE

PRTB

EQU

$01

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

144

DDRB

EQU

$03

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

PUCR

EQU

$0C

;порт B.

 

 

 

 

 

 

 

 

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

ATDCTL2

EQU

$82

;Адрес регистра управления АЦП ATDCTL2.

ATDCTL3

EQU

$83

;Адрес регистра управления АЦП ATDCTL3.

ATDCTL4

EQU

$84

;Адрес регистра управления АЦП ATDCTL4.

ATDCTL5

EQU

$85

;Адрес регистра управления АЦП ATDCTL5.

ATDDR0H

EQU

$90

;Адрес старшего байта регистра результата

 

 

 

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

 

 

 

 

 

 

ORG

ROMstart

 

 

 

 

 

 

 

 

 

 

EX_8_1

LDS

#$0FFF

 

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

 

 

 

 

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

 

MOVB #$F0,DDRB

 

;памяти.

 

 

 

 

 

 

 

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

 

BSET PUCR,$02

 

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

 

 

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

 

MOVB #$F0,PRTB

 

;порта В.

 

 

 

 

 

 

 

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

 

BSET ATDCTL2,$82

;Включение АЦП и прерываний по завершению

 

LDAA #$50

 

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

 

 

 

 

;После включения АЦП необходимо выждать не

 

DBNE A,*

 

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

 

MOVB $08,ATDCTL3

;состояние его аналоговые компоненты.

 

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

 

BSET ATDCTL4,$81

;последовательности равным единице.

 

;Установка 8-битного разрешения АЦП и

 

 

 

 

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

 

 

 

 

; f

ATD

=

fCLK

4

=

4 МГц

4

=1 МГц.

 

 

 

 

 

 

 

BSET ATDCTL5,$05

 

 

 

 

 

 

 

;Выбор в качестве линии аналогового ввода

 

 

 

 

;ножки 5 порта AD. Установка одноканального

 

 

 

 

;режима работы и однократного сканирования

 

CLI

 

 

;АЦП выбранного входа.

 

*

 

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

 

JMP

 

;Ожидание прерываний.

 

ADC_INT

LDAA

ATDDR0H

 

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

 

COMA

 

 

;АЦП.

 

 

 

 

 

 

 

 

 

;Поразрядная инверсия содержимого

 

STAA PRTB

 

;аккумулятора A.

 

 

 

 

;Вывод на светодиоды.

 

 

MOVB

#$05,ATDCTL5

;Запуск новой последовательности

 

RTI

 

 

;преобразования АЦП.

 

 

 

 

 

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

 

ORG

$FFD2

 

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

 

DC.W

ADC_INT

 

;преобразования АЦП.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

145

ORG

StartVector

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

DC.W

EX_8_1

 

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

Инициализацию модуля АЦП нужно производить последовательно, т.е. сначала произвести запись в регистр ATDCTL2, затем – в ATDCTL3 и т.д. по возрастанию имён. В противном случае, даже если все команды верны, конфигурируемое устройство может не включиться или заработать неправильно.

АЦП, может работать как непрерывно, так и осуществлять однократные преобразования. В данном примере реализован второй режим. Он позволяет начинать новое преобразование только тогда, когда данные от предыдущего уже обработаны.

Сброс флага окончания преобразования (SCF, бит 7 в регистре ATDSTAT0) осуществляется автоматически при записи данных в регистр ATDCTL5. Это действие одновременно запустит АЦП на новое преобразование.

Пример 8.2. Произвести аналого-цифровое преобразование сигнала с потенциометра RV1 (PRTAD5). АЦП микроконтроллера работает в 8-разрядном режиме. Результата вывести результат на светодиоды LED4..LED1. При нажатии на кнопку SW1 все излучающие элементы должны быть погашены.

RAMStart

 

EQU

$0400

 

ROMStart

 

EQU

$C000

 

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.

ATDCTL2

EQU

$82

 

;Адрес регистра управления АЦП ATDCTL2.

ATDCTL3

EQU

$83

 

;Адрес регистра управления АЦП ATDCTL3.

ATDCTL4

EQU

$84

 

;Адрес регистра управления АЦП ATDCTL4.

ATDCTL5

EQU

$85

 

;Адрес регистра управления АЦП ATDCTL5.

ATDDR0H

EQU

$90

 

;Адрес старшего байта регистра результата

BTN

EQU

 

 

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

RAMstart+$10 ;Адрес ячейки с кодом состояния кнопки SW1.

 

ORG

ROMstart

 

EX_8_2

LDS

#$0FFF

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

 

 

 

 

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

 

MOVB

#$F0,DDRB

;памяти.

 

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

 

BSET

PUCR,$02

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

 

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

 

 

 

 

;порта В.

 

 

 

 

146

 

MOVB

#$F0,PRTB

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

 

BCLR

DDRP,$03

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

 

BSET

PERP,$03

;на ввод.

 

 

 

 

 

 

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

 

LDX

#PRTP

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

 

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

 

CLRB

 

;Загрузка в аккумулятор B нулевого значения.

 

BSET ATDCTL2,$82

;Включение АЦП и прерываний по завершению

 

LDAA

#$50

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

 

 

 

;После включения АЦП необходимо выждать не

 

DBNE

A,*

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

 

MOVB

$08,ATDCTL3

;состояние его аналоговые компоненты.

 

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

 

BSET ATDCTL4,$81

;последовательности равным единице.

 

;Установка 8-битного разрешения АЦП и

 

 

 

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

 

 

 

; f

ATD

=

fCLK

4

=

4 МГц

4

=1 МГц.

 

 

 

 

 

 

BSET ATDCTL5,$05

 

 

 

 

 

 

 

;Выбор в качестве линии аналогового ввода

 

 

 

;ножки 5 порта AD. Установка одноканального

 

 

 

;режима работы и однократного сканирования

 

CLI

 

;АЦП выбранного входа.

 

 

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

BTN_SCAN

LDY #$4500

;Опрос состояния кнопки

BTN_OFF

CLR

BTN

;Установка кода состояния кнопки равным

 

 

 

;нулю.

 

 

 

 

 

 

DL1

BRSET ,X,$01,BTN_OFF

 

;Ожидание нажатия кнопки SW1.

NOP

 

;Программная временная задержка для

 

NOP

 

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

 

NOP

 

 

 

 

 

 

 

 

 

 

 

DEY

DL1

 

 

 

 

 

 

 

 

 

 

BNE

 

 

 

 

 

 

 

 

 

 

LDY

#$4500

 

 

 

 

 

 

 

 

 

 

BRCLR ,X,$01,*

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

DL0

NOP

 

;порта B.

 

 

 

 

 

 

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

 

NOP

 

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

 

 

 

NOP

 

 

 

 

 

 

 

 

 

 

 

DEY

DL0

 

 

 

 

 

 

 

 

 

 

BNE

 

 

 

 

 

 

 

 

 

 

JMP

BTN_SCAN

;Возврат на опрос состояния кнопки.

ADC_INT

CMPB

BTN

;Проверка кода состояния кнопки.

 

BEQ

ADC_OUT

;Если равнее нулю (кнопка не нажата), то

 

MOVB

#$F0,PRTB

;перейти на вывод результата преобразования.

 

;Иначе погасить все светодиоды.

ADC_OUT

BRA

ADC_END

;И перейти на выход из подпрограммы.

LDAA

ATDDR0H

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

 

 

 

;АЦП.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

147

COMA

 

;Поразрядная инверсия содержимого

STAA PRTB

;аккумулятора A.

;Вывод на светодиоды.

ADC_END MOVB

#$05,ATDCTL5

;Запуск новой последовательности

RTI

 

;преобразования АЦП.

 

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

ORG

$FFD2

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

DC.W

ADC_INT

;преобразования АЦП.

ORG

StartVector

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

DC.W

EX_8_2

 

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

Временную задержку для подавления дребезга нужно формировать как при нажатии, так и отпускании кнопки.

Из-за упомянутого дребезга гашение светодиодов происходит в зависимости не от сигнала на линии 0 порта P, а от состояния некоторой промежуточной ячейки памяти BTN.

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

1.Реализовать на светодиодах LED1..LED4 линейную шкалу, отображающую уровень аналогового сигнала, поступающего с потенциометра RV1.

2.Написать программу, в которой положением движка потенциометра RV1 определяется яркость горения светодиодов LED1..LED4.

3.Реализовать на светодиодах LED1..LED4 эффект «бегущий огонь». Скорость пробега должна плавно регулироваться потенциометром RV1.

4.Реализовать на светодиодах LED1..LED4 эффект «бегущий огонь». Если сигнал с потенциометра RV1 превысил значение 3 В, то пробег должен осуществляться слева направо, если стал меньше 2 В, – то справа налево.

5.Написать программу, в светодиоды порта B мигают с некоторой небольшой скоростью. Сигналом с выхода потенциометра RV1 определяется следующее:

Если напряжение превысило значение 3 В, то мигают светодиоды LED1 и LED3.

Если напряжение стало меньше 2 В, то мигают светодиоды LED2 и LED4.

6.Написать программу, в которой нажатием кнопки SW2 запускается одна последовательность преобразования АЦП. Полученный результат вывести на светодиоды порта B.

7.Произвести аналого-цифровое преобразование сигнала с потенциометра RV1. Результата вывести результат на светодиоды LED4..LED1. Однократное нажатие кнопки SW2 должно включать/выключать отображение оцифрованного сигнала.

148

6. Дополнительные лабораторные работы по изучению ядра HCS12

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

Расширенные способы индексной адресации

Содержание

В данной лабораторной работе изучаются расширенные типы индексной адресации.

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

В процессе подготовки к лабораторной работе №9 рекомендуется ознакомиться с расширенными способами индексной адресации (п. 1.3.6).

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

Пример 9.1. Исходные данные находятся в ОЗУ по адресам $90..$94. Произвольные значения чисел должны быть занесены в эти ячейки под управлением программы. Затем эти числа должны быть перемещены в другую область ОЗУ по адресам $A0..$A4.

Условие примера взято из лабораторной работы № 2 (пр. 2.1). В решении ниже использованы команды с автоматическим изменением регистра-указателя, что способствует сокращению объёма программы.

RamStart

EQU

$0000

RomStart

EQU

$E000

StartVector

EQU

$FFFE

INITRG

EQU

$0011

ORG

RomStart

EX_2_1_3 LDAA

#$08

 

STAA

INITRG

LDX

#$90

;Загрузка в индексный регистр X начального адреса

LDD

 

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

#$4028

STAA

1,X+

;Помещение числа $40 в ячейку памяти с адресом $90.

STAB

1,X+

;После выполнения команды адрес увеличивается на 1.

;Помещение числа $28 в ячейку памяти с адресом $91.

LDD

 

;После выполнения команды адрес увеличивается на 1.

#$2BDE

STAA

1,X+

;Помещение числа $2B в ячейку памяти с адресом $92.

STAB

1,X+

;Помещение числа $DE в ячейку памяти с адресом $93.

LDAA

#$7D

 

STAA

0,X

;Сохранение числа $7D в ячейку памяти с адресом $94.

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

149

LDX

#$A0

;В индексный регистр X помещается новое начальное

LDD

-$10,X

;значение адреса равное $A0.

;Считывание двух ячеек памяти с адресами $90 и $91.

STD

2,X+

;Сохранение двух байт в ячейки памяти с адресами $A0

 

 

;и $A1. После выполнения значение регистра X

LDD

-$10,X

;увеличивается на 2.

;Считывание двух ячеек памяти с адресами $92 и $93.

STD

2,X+

;Сохранение двух байт в ячейки памяти с адресами $A2

LDAB -$10,X

;и $A3.

;Считывание ячейки памяти с адресом $94.

STAB

0,X

;Сохранение числа $7D в ячейку памяти с адресом $A4.

JMP

*

 

ORG

StartVector

DC.W

EX_2_1_3

 

Пример 9.2. Исходные данные находятся в ОЗУ по адресам $0110..$0114. Произвольные значения чисел должны быть занесены в эти ячейки под управлением программы. Затем эти числа должны быть помещены в обратном порядке в другую область ОЗУ по адресам $0150..$0154. Т.е. из ячейки с адресом $0110 число должно попасть в $0154, из $0111 – в $0153 и т.д.

Условие примера также взято из лабораторной работы № 2 (пр. 2.3). В программе использованы расширенные типы индексной адресации.

RamStart

EQU

$0000

 

RomStart

EQU

$E000

 

StartVector

EQU

$FFFE

 

INITRG

EQU

$0011

 

ORG

RomStart

 

EX_2_3_2 LDAA

#$08

 

 

STAA

INITRG

;Загрузка в индексный регистр X начального адреса

LDX

#$0110

LDD

#$5A21

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

 

STAA

1,X+

 

;Помещение чисел $5A и $21 в ячейки памяти с

STAB

1,X+

 

;адресами $0110 и $0111 соответственно.

LDD

#$2BDE

 

STAA

1,X+

 

;Помещение чисел $2B и $DE в ячейки памяти с

STAB

1,X+

 

;адресами $0112 и $0113 соответственно.

LDAA

#$FE

 

 

STAA ,X

 

;Помещение числа $7D в ячейку памяти с адресом

 

 

 

;$0114.

LDY

#$05

 

;Индексный регистр Y будет выполнять роль счётчика

 

 

 

;циклов, а также участвовать в формировании адреса

LDX

#$0110

;ячейки нового массива.

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

CLRB #$00

 

;Очищаем регистр B.

150