Отчёт №3 (Всё по лабораторным работам БМТ)
Описание файла
Файл "Отчёт №3" внутри архива находится в следующих папках: Всё по лабораторным работам БМТ, Лабы Нестерова. Документ из архива "Всё по лабораторным работам БМТ", который расположен в категории "". Всё это находится в предмете "электроника" из , которые можно найти в файловом архиве МГТУ им. Н.Э.Баумана. Не смотря на прямую связь этого архива с МГТУ им. Н.Э.Баумана, его также можно найти и в других разделах. Архив можно найти в разделе "лабораторные работы", в предмете "электроника и микропроцессорная техника" в общих файлах.
Онлайн просмотр документа "Отчёт №3"
Текст из документа "Отчёт №3"
Московский Государственный Технический Университет
имени Н. Э. Баумана
Лабораторная работа №2 по курсу «ЭиМПТ »
Выполнила студентка группы БМТ 1 – 71:
Магай Т. А.
Преподаватель:
Нестеров А. В.
Москва 2008 г.
Задание
Рис.1. Электрическая принципиальная схема устройства индикации
Задание:
1. Написать программу в результате которой на индикаторах будет отображаться информация о годе, месяце и дне рождения при выполнении следующих условий:
- при нажатии кнопки «S1» на четыре индикатора выводится информация о годе рождения;
- при нажатии кнопки «S2» на двух верхних индикаторах выводится информация о дне рождения;
- при нажатии кнопки «S3» на двух нижних индикаторах выводится информация о месяце рождения;
- при остальных комбинациях кнопок на индикаторы выводится информация о числе выполнения лабораторной работы;
Программа для МК ATMega16
;Program Timer Interrupt;
.include "m16def.inc";
.DEF STOP=R16
.DEF timer=R17
.DEF keyboard1=R20
.DEF keyboard2=R21
.DEF temp=R22
.DEF temp2=R23
.DEF kod=R24
.DEF key=R25
.DEF led=R26
.DEF opros=R27
.CSEG
.org 0;
jmp RESET;
.org OC0addr; устанавливаем программный счётчик на адрес 0x26 - адрес вектора прерывания таймера/счётчика
jmp Compare; безусловный переход в блок обработки прерывания "совпадение содержимого регистра сравнения с содержимым счётного регистра счётчика"
;ПОДПРОГРАММА обработки прерывания по совпадению содержимого регистра сравнения с содержимым счётного регистра счётчика
Compare:
clr timer; сбрасываем все разряды РОН
out tccr0, timer; останавливаем таймер/счётчик
out tcnt0, timer; стираем содержимое счётного регистра таймера/счётчика
reti; возвращение из подпрограммы обработки прерывания
RESET:
;инициализация регистра указателя стека
ldi R16, LOW(RAMEND);
out spl, R16;
ldi R16, HIGH(RAMEND);
out sph, R16;
; инициализация портов ВВ
ser R18 ; во все разряды 18 РОН записываем единицы
out ddrC, R18 ; порт C программируется на вывод информации
out ddrB, R18 ; порт B программируется на вывод информации
clr R18 ; очищаем все разряды 18 РОН - записываем туда нули
out ddrD, R18 ; порт D программируется на ввод информации
; инициализация таймера/счётчика (разрешение прерываний);
ldi R17, (1<<OCIE0);
out timsk, R17; устанавливаем флаг разрешения прерывания по событию "совпадение" таймера/счётчика0
ldi STOP, 20;
out OCR0,STOP; записываем в регистр сравнения таймера/счётчика число 20
sei; установка общего разрешения прерываний;
rjmp MAIN ; безусловный переход к телу основной программ
; ПОДПРОГРАММА - запуск таймера
Timer_go:
ldi timer, (1<<CS02);
out tccr0, timer; устанавливаем коэффициент предделителя равным 256, и режим работы - Normal
ser timer; устанавливаем все биты РОН в единичное состояние
LOOP:
tst timer;
brne LOOP; переход по "не равно" (Z=0) к метке, иначе - к следующей команде
ret ; возвращение из подпрограммы
; ПОДПРОГРАММА - определение нажатия кнопок клавиатуры
KEYBOARD:
;задаём дату выполнения - день/месяц
ldi keyboard1, 10 ; месяц выполнения
ldi keyboard2, 26 ; день выполнения
;проверяем нажатие кнопок:
sbis pinD, 0 ; если нулевой разряд PINC установлен (кнопка S1 не нажата, смотри схему), то следующая команда пропускается
ldi keyboard1, 88 ; если кнопка S1 нажата, то записываем в РОН младший байт года
sbis pinD, 0 ; если нулевой разряд PINC установлен (кнопка S1 не нажата), то следующая команда пропускается
ldi keyboard2, 19 ; если кнопка S1 нажата, то записываем в РОН старший байт года
sbis pinD, 1 ; если первый разряд PINC установлен (кнопка S2 не нажата), то следующая команда пропускается
ldi keyboard1, $17 ; если кнопка S2 нажата, то записываем в РОН байт дня
sbis pinD, 2 ; если второй разряд PINC установлен (кнопка S3 не нажата), то следующая команда пропускается
ldi keyboard1, $08 ; если кнопка S1 нажата, то записываем в РОН байт месяца
; на выходе получаем РОН Keyboard1/2 содержащие информацию о дне, месяце, годе или дате выполнения лабораторной в зависимости от комбинации нажатых кнопок
ret ; возвращение из подпрограммы
; ПОДПРОГРАММА - разделение разрядов выбранных чисел
DIVIDE:
clr temp
DIVIDE1:
subi key,10 ; вычитаем из РОН число 10
brcs DIVIDE2 ; переход по флагу переноса, иначе переход к следующей команде
inc temp
rjmp DIVIDE1 ; безусловный переход по ссылке
DIVIDE2:
subi key,-10 ; вычитаем из РОН число -10
; таким образом в регистре "key" осталось число единиц, а в регистре "temp" - число десятков
ret ; возвращение из подпрограммы
; ПОДПРОГРАММА - перевод в код семисегментного индикатора
TRANSLATE:
cpi temp2, 0 ; сравниваем число содержащееся в РОН temp2 с нулём
brne TRANSLATE1 ; если флаг нуля не установлен, то переходим по метке, иначе числа равны - переходим к следующей команде
ldi kod, $3F ; если же флаг нуля установлен записываем в выходной РОН "kod" код семисегментного индикатора для нуля
rjmp TRANSLATEEND ; безусловный переход в конец выполнения подпрограммы
TRANSLATE1:
cpi temp2, 1
brne TRANSLATE2
ldi kod, $06
rjmp TRANSLATEEND
TRANSLATE2:
cpi temp2, 2
brne TRANSLATE3
ldi kod, $5B
rjmp TRANSLATEEND
TRANSLATE3:
cpi temp2, 3
brne TRANSLATE4
ldi kod, $4F
rjmp TRANSLATEEND
TRANSLATE4:
cpi temp2, 4
brne TRANSLATE5
ldi kod, $67
rjmp TRANSLATEEND
TRANSLATE5:
cpi temp2, 5
brne TRANSLATE6
ldi kod, $6D
rjmp TRANSLATEEND
TRANSLATE6:
cpi temp2, 6
brne TRANSLATE7
ldi kod, $7D
rjmp TRANSLATEEND
TRANSLATE7:
cpi temp2, 7
brne TRANSLATE8
ldi kod, $07
rjmp TRANSLATEEND
TRANSLATE8:
cpi temp2, 8
brne TRANSLATE9
ldi kod, $7F
rjmp TRANSLATEEND
TRANSLATE9:
ldi kod, $6F
TRANSLATEEND:
ret ; возвращение из подпрограммы
MAIN:
rcall KEYBOARD ; вызываем подпрограмму, позволяющую определить нажатые кнопки (после её выполнения получаем информацию о выбранных числах в двух РОН, keyboard1 и keyboard2)
rcall IMAGE ; вызываем подпрограмму управления выводом чисел на семисегментный индикатор
rjmp MAIN ; безусловный переход в начало основной программы MAIN
; ПОДПРОГРАММА - вывод чисел на семисегментный индикатор
IMAGE:
; проверяем нажата ли хоть какая-нибудь кнопка
in temp, pinD ; записываем в РОН состояние входов порта D
cpi temp, $FF ; если не одна из кнопок не нажата то в результате этого сравнения будет установлен флаг нуля
breq NOTHING ; если флаг нуля будет установлен, то перейти по метке, иначе - дальше по программе:
mov key, keyboard1 ; подготавливаем младший байт числа, выбранного нажатием соответствующей кнопки, к разделению разрядов
rcall DIVIDE ; вызываем подпрограмму разделяющую разряды десятичного числа записанного в РОН "key"
cpi keyboard1, $17 ; сравниваем содержимое РОН с младшим байтом числа дня рождения
breq IMAGE1 ; если эти числа равны, то переходим по метке, иначе:
cpi keyboard1, $08 ; сравниваем содержимое РОН с младшим байтом числа месяца рождения
breq IMAGE1 ; если эти числа равны, то переходим по метке, иначе:
mov R18, key ; записываем число единиц в числе младшего байта выбранного числа в промежуточный 18 РОН
mov R19, temp ; записываем число десятков в числе младшего байта выбранного числа в промежуточный 19 РОН
mov key, keyboard2 ; подготавливаем старший байт числа к разделению разрядов
rcall DIVIDE ; вызываем подпрограмму разделяющую разряды десятичного числа записанного в РОН "key"
;подготовка к выводу чисел на индикаторы:
mov temp2, temp ; записываем в РОН "temp2" число десятков старшего байта года рождения
rcall TRANSLATE ; вызываем программу перевода чисел в код семисегментного индикатора
mov R28, kod ; записываем код для семисегментного индикатора старшего разряда года в промежуточный рнгистр РОН
mov temp2, key ; записываем в РОН "temp2" число единиц старшего байта года рождения
rcall TRANSLATE ; вызываем программу перевода чисел в код семисегментного индикатора
mov R29,kod ; записываем код для семисегментного индикатора третьего разряда года в промежуточный рнгистр РОН
mov temp2, R19 ; записываем в РОН "temp2" число десятков младшего байта года рождения
rcall TRANSLATE ; вызываем программу перевода чисел в код семисегментного индикатора
mov R30, kod ; записываем код для семисегментного индикатора второго разряда года в промежуточный рнгистр РОН
mov temp2, R18 ; записываем в РОН "temp2" число единиц младшего байта года рождения
rcall TRANSLATE ; вызываем программу перевода чисел в код семисегментного индикатора
ldi opros, 5 ; устанавливаем количество циклов вывода года до следующего опроса клавиатуры
GOYEAR:
; вывод старшего разряда года на первый индикатор
out portC, R28 ; вывод старшего разряда года с выходов порта C
ldi led, $FE ; указываем индикатор для вывода (здесь первый)
out portB, led ; программируем выходы порта B для работы первого индикатора
rcall Timer_go ; вызываем подпрограмму временной задержки
; вывод третьего разряда года на второй индикатор
out portC, R29 ; вывод третьего разряда года с выходов порта C
ldi led, $FD ; указываем индикатор для вывода (здесь второй)
out portB, led ; программируем выходы порта B для работы первого индикатора
rcall Timer_go ; вызываем подпрограмму временной задержки
; вывод второго разряда года на третий индикатор
out portC, R30 ; вывод второго разряда года с выходов порта C
ldi led, $FB ; указываем индикатор для вывода (здесь третий)
out portB, led ; программируем выходы порта B для работы первого индикатора
rcall Timer_go ; вызываем подпрограмму временной задержки
; вывод младшего разряда года на четвёртый индикатор
out portC, kod ; вывод младшего разряда года с выходов порта C
ldi led, $F7 ; указываем индикатор для вывода (здесь четвёртый)
out portB, led ; программируем выходы порта B для работы первого индикатора
rcall Timer_go ; вызываем подпрограмму временной задержки
dec opros
brne GOYEAR ; переход по "не равно",тем самым обеспечивается непрерывный вывод выбранного числа до следующего опроса клавиатуры
ret ; возвращение из подпрограммы IMAGE
NOTHING:
ldi opros, $FF ; устанавливаем количество циклов простоя до следующего опроса клавиатуры
NOTHING1:
dec opros ; декремент содержимого РОН
brne NOTHING1 ; перейти по "не равно", тем самым происходит задержка до следующего обращения к клавиатуре
ret ; возвращение из подпрограммы IMAGE
IMAGE1:
;подготовка к выводу чисел на индикаторы:
mov temp2, temp ; записываем в РОН "temp2" число десятков байта дня/месяца рождения
rcall TRANSLATE ; вызываем программу перевода чисел в код семисегментного индикатора
mov R28, kod ; записываем код для семисегментного индикатора старшего разряда дня/месяца в промежуточный регистр РОН
mov temp2, key ; записываем в РОН "temp2" число единиц байта дня/месяца рождения
rcall TRANSLATE ; вызываем программу перевода чисел в код семисегментного индикатора
ldi opros, 10 ; устанавливаем количество циклов простоя до следующего опроса клавиатуры
cpi keyboard1, $08 ; сравниваем содержимое РОН с байтом месяца рождения
breq IMAGE2
GODAY:
; вывод старшего разряда дня на первый индикатор
out portC, R28 ; вывод старшего разряда дня с выходов порта C
ldi led, $FE ; указываем индикатор для вывода (здесь первый)
out portB, led ; программируем выходы порта B для работы первого индикатора
rcall Timer_go ; вызываем подпрограмму временной задержки
; вывод третьего разряда дня на второй индикатор
out portC, kod ; вывод старшего разряда дня с выходов порта C