Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
MPSU_laboratornye.doc
Скачиваний:
73
Добавлен:
11.05.2015
Размер:
1.26 Mб
Скачать

Примерырешения задач

Задача 3.1.Составим программу, обеспечивающую отображение состояния нулевого бита операнда на нулевой линии порта B. Собрать модель схемы в Proteus и подключить к нулевому выводу порта B светодиод, отображающий состояние нулевого бита операнда. Программу проверить для операндов FF и 00.

Соответствующая программа имеет вид:

.include "m2560def.inc"

init: ldi r16, 0x01; настройка на вывод линии 0 порта B

out DDRB, r16

ldir16, 0xFF; операнд

ldir17, 0x01; маска для проверки на 1 бита 0

main:andr16,r17; выделить нулевой бит

brne on ; переход по ненулю

ldir16, 0x00; вывод на линию 0 порта B "0"

outPORTB,r16

rjmpend; обход включения линии порта

on:ldir16, 0x01; вывод на линию 0 порта B "1"

out PORTB, r16

end: rjmp end; остановка программы

Модель микроконтроллерной системы Arduino для разработанной программы в среде Proteus выглядит следующим образом:

Светодиод подключен катодом к минусовому проводу ”земли“, поэтому включается подачей логической ”1“ с порта B. Резистор необходим для согласования уровня напряжения на выходе Arduino (5 вольт) с напряжением включения светодиода (3 вольта).

Эмуляция работы устройства показывает, что при значении операнда FF светодиод включен, а при значении 00 – выключен.

Задача 3.2.Составим программу, обеспечивающую отображение состояния клавиши, подключенной к линии 0 порта B, с помощью светодиода, подключенного к линии 0 портаD(нажато – горит, отжато – не горит). Промоделировать работу схемы в Proteus.

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

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

.include "m2560def.inc"

init: ldi r16, 0b00000000 ; настройка на ввод линии 0 порта B

out DDRB, r16

ldi r16, 0b00000001 ; настройка на вывод линии 0 порта D

out DDRD, r16

ldi r19, 0b00000001 ; маска для инверсии 0 бита

main: in r16, PINB

eor r16, r19 ; инвертирование 0 бита

out PORTD,r16 ; вывод на линию 0 состояния бита 0 r16

rjmp main ; организация бесконечного цикла

Модель микроконтроллерной системы Arduino для разработанной программы в среде Proteus выглядит следующим образом:

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

Задача 3.3.Составим программу, обеспечивающую подсчёт нажатий на клавишу, подключенную к линии 0 порта B. Отобразить десятичный эквивалент количества нажатий на семисегментном светодиодном индикаторе, подключенному к четырём младшим линиям порта D. Сброс в 0 клавишей на линии 1 порта B. При достижении значения счётчика 9 значение больше не увеличивать. Промоделировать работу схемы в Proteus.

.include "m2560def.inc"

init: ldi r16, 0b00000000 ; настройка на ввод линий 0,1 порта B

out DDRB, r16

ldi r16, 0b00001111 ; настройка на вывод линий 0-3 порта D

out DDRD, r16

clr r17 ; сброс счётчика

bclr 6 ; разрешить увеличение счёта b6SREG=0

main: sbis PINB, 1 ; проверить кнопку RESET

clr r17 ; если нажата, то сброс счётчика

sbic PINB, 0 ; проверить кнопку +

rjmp off ; переход если не нажато

brbs 6, nozero; можно увеличить счёт?

inc r17

nozero:bset 6; запретить увеличение счёта b6SREG=1

rjmp end ; обход разрешения

off: bclr 6 ; разрешить увеличение счёта

end:cpir17, 0x0A; сравнить r17 с числом A

brne indic ; перейти, если r16 /= A

dec r17

indic: out PORTD,r17 ; вывод

rjmp main ; организация бесконечного цикла

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

Модель микроконтроллерной системы Arduino для разработанной программы в среде Proteus выглядит следующим образом:

Задача 3.4.Составим программу, увеличивающую либо уменьшающую десятичный счётчик по нажатию клавиш “+” или “-“. Подключим их к линиям 0 и 1 портаD. Отобразим десятичное значение на семисегментном индикаторе, подключенном к портуB. При опросе клавиш используем внешнее прерывание. Сброс в 0 клавишей на линии 2 портаD. Промоделируем работу схемы в Proteus.

Для работы с прерываниями необходимо описать таблицу векторов для данного типа МК через директивы ассемблера .org. Из документации на МКATmega2560 следует, что внешние прерыванияINTxимеют диапазон адресов $0002.. $0010. При этомINT0 принимается с линии порта PD0 микроконтроллера, а INT1 – c PD1 соответственно. Для желаемыхINTxпо заданным адресам записывается команда перехода на обработчикrjmp Ext_INT. Подпрограмма-обработчик должна быть как можно короче и обязательно заканчиваться командойreti. Основная программа начинается с меткиReset, где настраивается указатель стека и внешние прерывания разрешаются локально (регистрEIMSK), а также условие срабатывания по спаду входного сигнала в регистре EICRA (адрес в пространстве ввода/вывода 0x69).

.include "m2560def.inc"

.cseg

.org $0000 rjmp Reset ; (Reset)

.org $0002 rjmp Ext_INT0 ; (INT0) External Interrupt Request 0

.org $0004 rjmp Ext_INT1 ; (INT1) External Interrupt Request 1

.org $0006 reti ; (INT2) External Interrupt Request 2

.org $0008 reti ; (INT3) External Interrupt Request 3

.org $000A reti ; (INT4) External Interrupt Request 4

.org $000C reti ; (INT5) External Interrupt Request 5

.org $000E reti ; (INT6) External Interrupt Request 6

.org $0010 reti ; (INT7) External Interrupt Request 7

.org $0012 reti ; (PCINT0) Pin Change Interrupt Request 0

.org $0014 reti ; (PCINT1) Pin Change Interrupt Request 1

.org $0016 reti ; (PCINT2) Pin Change Interrupt Request 2

.org $0018 reti ; (WDT) Watchdog Time-out Interrupt

.org $001A reti ; (TIMER2_COMPA) Timer/Counter2 Compare Match A

.org $001C reti ; (TIMER2_COMPB) Timer/Counter2 Compare Match B

.org $001E reti ; (TIMER2_OVF) Timer/Counter2 Overflow

.org $0020 reti ; (TIMER1_CAPT) Timer/Counter1 Capture Event

.org $0022 reti ; (TIMER1_COMPA) Timer/Counter1 Compare Match A

.org $0024 reti ; (TIMER1_COMPB) Timer/Counter1 Compare Match B

.org $0026 reti ; (TIMER1_COMPC) Timer/Counter1 Compare Match C

.org $0028 reti ; (TIMER1_OVF) Timer/Counter1 Overflow

.org $002A reti ; (TIMER0_COMPA) Timer/Counter0 Compare Match A

.org $002C reti ; (TIMER0_COMPB) Timer/Counter0 Compare Match B

.org $002E reti ; (TIMER0_OVF) Timer/Counter0 Overflow

.org $0030 reti ; (SPI_STC) Serial Transfer Complete

.org $0032 reti ; (USART0_RX) USART0 Rx Complete

.org $0034 reti ; (USART0_UDRE) USART0 Data Register Empty

.org $0036 reti ; (USART0_TX) USART0 Tx Complete

.org $0038 reti ; (ANALOG_COMP) Analog Comparator

.org $003A reti ; (ADC) ADC Conversion Complete

.org $003C reti ; (EE_READY) EEPROM Ready

.org $003E reti ; (TIMER3_CAPT) Timer/Counter3 Capture Event

.org $0040 reti ; (TIMER3_COMPA) Timer/Counter3 Compare Match A

.org $0042 reti ; (TIMER3_COMPB) Timer/Counter3 Compare Match B

.org $0044 reti ; (TIMER3_COMPC) Timer/Counter3 Compare Match C

.org $0046 reti ; (TIMER3_OVF) Timer/Counter3 Overflow

.org $0048 reti ; (USART1_RX) USART1 Rx Complete

.org $004A reti ; (USART1_UDRE) USART1 Data Register Empty

.org $004C reti ; (USART1_TX) USART1 Tx Complete

.org $004E reti ; (TWI) 2-wire Serial Interface

.org $0050 reti ; (SPM_RDY) Store Program Memory Ready

.org $0052 reti ; (TIMER4_CAPT) Timer/Counter4 Capture Event

.org $0054 reti ; (TIMER4_COMPA) Timer/Counter4 Compare Match A

.org $0056 reti ; (TIMER4_COMPB) Timer/Counter4 Compare Match B

.org $0058 reti ; (TIMER4_COMPC) Timer/Counter4 Compare Match C

.org $005A reti ; (TIMER4_OVF) Timer/Counter4 Overflow

.org $005C reti ; (TIMER5_CAPT) Timer/Counter5 Capture Event

.org $005E reti ; (TIMER5_COMPA) Timer/Counter5 Compare Match A

.org $0060 reti ; (TIMER5_COMPB) Timer/Counter5 Compare Match B

.org $0062 reti ; (TIMER5_COMPC) Timer/Counter5 Compare Match C

.org $0064 reti ; (TIMER5_OVF) Timer/Counter5 Overflow

.org $0066 reti ; (USART2_RX) USART2 Rx Complete

.org $0068 reti ; (USART2_UDRE) USART2 Data Register Empty

.org $006A reti ; (USART2_TX) USART2 Tx Complete

.org $006C reti ; (USART3_RX) USART3 Rx Complete

.org $006E reti ; (USART3_UDRE) USART3 Data Register Empty

.org $0070 reti ; (USART3_TX) USART3 Tx Complete

.org INT_VECTORS_SIZE ; Конец таблицы прерываний

Ext_INT0: ; обработчик прерывания по входу INT0

inc r17 ; счётчик++

cpi r17, 0x0A ; сравнить r17 с числом A

brne ret0 ; перейти, если r17 /= A

dec r17

ret0: reti ; выход из обработчика прерывания

Ext_INT1: ; обработчик прерывания по входу INT1

dec r17 ; счётчик--

cpi r17, 0xFF ; сравнить r17 с числом FF

brne ret1 ; перейти, если r17 /= FF

inc r17 ; счётчик++

ret1: reti ; выход из обработчика прерывания

Reset: ldi r16,Low(RAMEND) ; Старт программы

out SPL,r16 ; Обязательная инициализация стека

ldi r16,High(RAMEND); Указатель стека устанавливается на конец ОЗУ

out SPH,r16

ldi r16,0b00000011 ; Разрешаем прерывания INT0 и INT1 локально

out EIMSK,r16

ldi r16,0b00001010 ; Настройка условия генерации прерывания

sts EICRA,r16 ; по спаду входного сигнала

sei ; Разрешаем прерывания глобально

ldi r16,0b00000000 ; настройка на ввод линий 0,1,2 порта D

out DDRD,r16

ldi r16,0b00001111 ; настройка на вывод линий 0-3 порта B

out DDRB,r16

clr r17 ; сброс счётчика

main: sbis PIND,2 ; проверить кнопку RESET

clr r17 ; если нажата, то сброс счётчика

out PORTB,r17 ; вывод

rjmp main

Модель микроконтроллерной системы Arduino для разработанной программы в среде Proteus выглядит следующим образом:

Задача 3.5.Составим программу, увеличивающую либо уменьшающую десятичный счётчик при воздействии на энкодер, подключенный к линиям 0 и 1 портаD. Отобразим десятичное значение на семисегментном индикаторе, подключенном к портуB. При опросе энкодер задействуем механизм внешнего прерывания. Сброс в 0 клавишей на линии 2 портаD. Промоделируем работу схемы в Proteus.

Энкодер – это датчик положения движущихся частей, который имеет две контактные пары, формирующие при вращении его ротора две импульсные последовательности, сдвинутые на 90°. По этому сдвигу можно судить о направлении вращения энкодера.

На диаграмме показана зависимость выходов А и В друг от друга при вращении энкодера по часовой или против часовой стрелки.

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

.include "m2560def.inc"

.cseg

.org $0000 rjmp Reset ; (Reset)

.org $0002 rjmp Ext_INT0 ; (INT0) External Interrupt Request 0

.org INT_VECTORS_SIZE ; Конец таблицы прерываний

Ext_INT0: ; обработчик прерывания по входу INT0

inc r17 ; счётчик++

cpi r17, 0x0A ; сравнить r17 с числом A

brne ret0 ; перейти, если r17 /= A

dec r17

ret0: reti ; выход из обработчика прерывания

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]