Читаем Занимательная микроэлектроника полностью

Листинг П5.1

;============== Программа часов

;AT90S2313 4 МГц

.include "2313def.inc"

;==== Управление сегментами ====

.equ segA = 5; PD5 (pin 9)

.equ segB = 6; PD6 (pin 11)

.equ segC = 2; PB2 (pin 14)

.equ segD = 4; PB4 (pin 16)

.equ segE = 5; PB5 (pin 17)

.equ segF = 6; PB6 (pin 18)

.equ segG = 7; PB7 (pin 19)

;==== Управление разрядами ====

.еqu em = 0; PD0 (pin2)

.equ dm = 1; PD1 (pin 3)

.equ eh = 2; PD2 (pin 6)

.equ dh = 4; PD4 (pin 8)

;==== Рабочие переменные ====

.def POS = r16  ;отсчет разрядов для динамической индикации

.def sek = r17  ;число секунд

.def temp = r18  ;рабочая переменная

.def emin = r19  ;число единиц минут

.def dmin = r20  ;число десятков минут

.def ehh = r21  ;число единиц часов

.def dhh = r22  ;число десятков часов

.def set_up = r23 ;отсчет разрядов при установке

.def count = r24  ;счетчик для мигания

.def Flag = r25  ;флаги режимов

;в регистре Flag: если бит0=1, то идет установка часов

;если бит1=1, то внешнее напряжение пропало

;======== Прерывания =========

rjmp RESET  ;процедура Reset

reti

rjmp INTT1  ;прерывание INTI по нажатию Кн1

reti

rjmp TIM1  ;прерывание Timer1 по сравнению CompareA (счет времени)

reti

rjmp TIM0  ;прерывание Timer0 по переполнению (управл. разрядами)

reti

reti

reti

rjmp ACOMPI  ;прерывание аналогового компаратора

;===== Программа =====

;===== прерывание по нажатию кнопки Кн1 ====

INTT1:

         sbrc Flag,1  ;если бит1=1 напряжения нет

         rjmp END_SET  ;какая установка — на выход

         clr temp

         out GIMSK,temp  ;запрещаем INTI

         sbr Flag,1  ;устанавливаем бит 0 флага — идет установка

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

         clr count  ;очищаем счетчик мигания

         cpi set_up,5  ;если счетчик разрядов

         brne END_SET  ;еще не больше 4, то на выход

         clr set_up  ;если больше, то обнуляем счетчик

         ldi sek,59  ;и устанавливаем число секунд = 59

         cbr Flag,1  ;сбрасываем бит 0 флага — конец установки

END_SET:

reti  ;конец прерывания INT1

;===== прерывание Timerl — ход часов ====

TIM1:

         sbrc Flag,1  ;если бит1=1 напряжения нет

         rjmp mtime  ;сразу посылаем на счет времени

         sbrs Flag,0  ;если бит0=1 идет установка

         rjmp mtime  ;иначе сразу на счет времени

         ldi temp, 0b10000000  ;на всякий случай

         out GIFR,temp  ;очищаем прерывание INT1

         cpi count,0  ;если счетчик =0

         breq CONT_1  ;то на продолжение

         ldi temp,1<  ;иначе разрешаем прерывание INT1

         out GIMSK,temp

CONT_1:  ;установка

         inc count  ;увеличиваем счетчик мигания на 1

         cpi set__up,1  ;если первый разряд, устанавливаем его

         brne mm1  ;иначе на следующий

         sbis PinB,0  ;если Кн2 нажата

         inc emin  ;увеличиваем число единиц минут на 1

         cpi emin,10  ;если число единиц минут еще не равно 10

         brne END_TIM1  ;то на выход из процедуры

         clr emin  ;если =10, то обнуляем

         rjmp END_TIM1  ;на выход

mm1:    cpi set_up,2  ;если второй разряд, устанавливаем его

         brne mm2  ;иначе на следующий

         sbis PinB,0  ;если Кн2 нажата

         inc dmin  ;увеличиваем число десятков минут на 1

         cpi dmin,6  ;если число десятков минут еще не равно 6

         brne END_TIM1  ;то на выход из процедуры

         clr dmin  ;если =6, то обнуляем

         rjmp END_TIM1  ;на выход

mm2:    cpi set_up,3  ;если третий разряд, устанавливаем его

         brne mm3  ;иначе на следующий

         sbis PinB,0  ; если Кн2 нажата

         inc ehh  ;увеличиваем число единиц часов на 1

         cpi ehh,4  ;если число единиц часов еще меньше 4

         brio END_TIM1  ;то на выход из процедуры

         cpi dhh,2  ;если число десятков часов не равно 2

         brne mm21  ;то на метку mm21

         clr ehh  ;иначе обнуляем число единиц часов

         rjmp END_TIM1  ;на выход из процедуры

mm21:    cpi ehh, 10  ;если число единиц часов не равно 10

         brne END_TIM1  ;то на выход

         clr ehh  ;иначе обнуляем число единиц часов

         rjmp END_TIM1  ;на выход

mm3:    sbis PinB,0  ;четвертый разряд

         inc dhh  ;увеличиваем число десятков часов на 1

         cpi dhh,3  ;если оно еще не равно 3

         brne END_TIM1  ;то на выход

         clr dhh  ;иначе обнуляем

         rjmp END_TIM1  ;на выход

         ;счет времени

mtime:   inc sek  ;увеличиваем число секунд на 1

         cpi sek,60  ;если оно не равно 60

         brne END_TIM1  ;то на выход

         clr sek  ;иначе обнуляем секунды

         inc emin  ;и увеличиваем единиц минут

         cpi emin,10  ;если число единиц минут не равно 10

         brne END_TIM1  ;то на выход

         clr emin  ;иначе обнуляем единиц минут

         inc dmin  ;и увеличиваем число десятков минут

         cpi dmin,6  ;если оно не равно 6

         brne END_TIM1  ;то на выход

         clr dmin  ;иначе обнуляем число десятков минут

         inc ehh  ;и увеличиваем число единиц часов

         cpi ehh,4  ;если число единиц часов не равно 4

         brio END_TIM1  ;то однозначно на выход

         cpi dhh,2  ;если число десятков часов при этом не равно 2

         brne mhh  ;то на метку mhh

         clr ehh  ;иначе обнуляем число единиц часов

         clr dhh  ;и сразу число десятков часов тоже (это полночь)

         rjmp END_TIM1  ;на выход

mhh:

         cpi ehh,10  ;если число единиц часов не равно 10

         brne END_TIM1  ;на выход

         clr ehh  ;иначе обнуляем единиц часов

         inc dhh  ;увеличиваем число десятков часов

END_TIM1:

reti  ;выход из прерывания Timer1

;==== прерывание Timer0 управление разрядами ====

TIM0:

         sbrc Flag,1  ;если бит1=1 напряжения нет

         rjmp END_TIM0  ;тогда сразу на выход

         clr temp  ;все очищаем

         out PortD,temp

         out РогtB,temp

         andi POS,3  ;счет разрядов от 0 до 3

         sbis PinB,0  ;пока нажата кнопка Кн2

         clr count  ;разряд при установке не мигает

         cpi P0s,0  ;если счетчик разрядов не 0

         brne m0  ;то на метку m0 — следующий разряд

         cpi set_up,1  ;если set_up=1, мигает этот разряд

         brne sm_1  ;иначе на включение разряда

         sbrs count,0  ;если бит 0 в count=0

sm_1:      sbi PortD,em  ;то уст. PDO в 1, разряд единиц мин. светится

         ;иначе он останется темным, т. е. мигает с частотой count

         mov temp,emin  ;в temp — число единиц минут

         rcall SEG_SET  ;устанавливаем сегменты

         rjmp END_0  ;на выход

m0:        cpi POS,1  ; если счетчик разрядов не 1

         brne m1  ;то на сл. разряд

         cpi set_up,2  ;если set_up=2, то мигает этот разряд

         brne sm_2  ;иначе на включение разряда

         sbrs count,0  ;если бит 0 в count=0

sm_2:    sbi PortD,dm  ;то уст. PD1 в 1, разряд десятков мин. светится

         mov temp,dmin  ;в temp — число десятков минут

         rcall SEG_SET  ;устанавливаем сегменты

         rjmp END_0  ;на выход

m1:       cpi POS,2  ;если счетчик разрядов не 2

         brne m2  ;то на сл. разряд

         cpi set_up,3  ;если set_up=3, то мигает этот разряд

         brne sm_3  ;иначе на включение разряда

         sbrs count,0  ;если бит 0 в count=0

sm_3:    sbi PortD,eh  ;то уст. PD2 в 1, разряд единиц часов светится

         mov temp, ehh  ;в temp — число единиц часов

         rcall SEG_SET  ;устанавливаем сегменты

         rjmp END_0  ;на выход

m2:  ;обработка 4 разряда десятков часов

         cpi set_up,4  ;если set_up=4, то мигает этот разряд

         brne sm_4  ;иначе на включение разряда

         sbrs count,0  ;если бит 0 в count=0

sm_4:    sbi PortD,dh  ;то уст. PD4 в 1, разряд десятков часов светится

         mov temp,dhh  ;в temp — число десятков часов

         rcall SEG_SET  ;устанавливаем сегменты

END_0:

         inc POS

END_TIM0:

reti  ;выход из прерывания Timer0

;===== компаратор — батарейка =====

ACOMPI:

           sbis ACSR,АСО  ;если бит АСО =1, то продолжим

           rjmp СОМР_1  ;иначе на установку мигания ldi temp,0b11000000

           ut TCCR1A,temp  ;двоеточие включено постоянно

           rjmp END_comp  ;на выход

СОМР_1:

           ldi temp,0b01000000

           out TCCR1A,temp  ;двоеточие мигает

END_comp:

reti  ;выход из процедуры компаратора

;===== процедура Reset ====

RESET:

cli  ;запрещаем прерывания на время установки

ldi temp,low(RAMEND)  ;загрузка указателя стека

out SPL,temp

ldi temp,0b01110111  ;порт D разряды 0,1,2,4,5,6 на выход

out DDRD,temp

ldi temp, 0b11111100  ;порт В все на выход, кроме 0,1 (компаратор)

out DDRB,temp

;- таймеры —

ldi temp,0Ь00000010  ;запуск Timer0 входная частота 1:8

out TCCR0,temp  ;управление разрядами по переполнению,

;частота около 2 кГц (4/8=0,5 МГц/256)

ldi temp,high(62 500) ;старший байт

out OCR1AH,temp  ;вых. частота 1 Гц при вх. частоте 1:64

ldi temp,low(62500)  ;младший байт out

OCR1AL,temp

ldi temp,0b01000000

out TCCR1A,temp  ;включаем переключающую моду для вывода ОС1 (15)

ldi temp,0b01001011  ;запуск 1/64 timer1 с обнулением при сравнении

out TCCR1B,temp;

;- прерывания —

ldi temp,1<  ;разрешаем прерывание INT1

out GIMSK,temp

ldi temp,(1<  ;разр. прерываний Tim0 и Tim1

out TIMSK,temp

ldi temp,(1<  ;разр. прерывания компаратора при переключении

out ACSR,temp

sei  ;разрешаем прерывания

;======= основной цикл ========

G_cycle:  ;все время будем отслеживать пропадание внешнего питания

          sbrs Flag,0  ;если бит0=1 идет установка

          rjmp G_cycle  ;если так, то ничего не делаем

          sbic PinB,0  ;если напряжение есть

          rcall Restore  ;вызываем процедуру восстановления выходов

          sbis PinB,0  ;если напряжения нет

          rcall Disable  ;вызываем процедуру отключения выходов

rjmp G_cycle  ;зацикливаем программу

;======= конец основного цикла ========

Disable:  ;процедура отключения

          sbrc Flag,2  ;если бит1=1, то уже все сделали

          rjmp END_dis  ;выход из процедуры

          cli  ;запрещаем прерывания на время установок

          sbr Flag,2  ;устанавливаем бит1 Flag

          ;обрываем внешние соединения и обнуляем все порты:

          clr temp

          out PortD,temp

          out PortB,temp

          out DDRD,temp

          out DDRD,temp

          sei  ;разрешаем прерывания

END_dis:

ret  ;конец процедуры отключения выходов

Restore:  ;процедура восстановления

          sbrs Flag,2  ;если бит1=0, то уже все остальное сделали

          rjmp end_res  ;выход из процедуры

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

          cli  ;запрещаем прерывания на время установок

          cbr Flag,2  ;сбрасываем бит1 Flag

          ;восстанавливаем внешние соединения:

          clr temp

          ldi temp,0b01110111  ;порт D разряды 0,1,2,4,5,6 на выход

          out DDRD,temp

          ldi temp, 0b11111100  ;порт В все на выход, кроме 0,1

          out DDRB,temp

          sei  ;разрешаем прерывания

END_res:

ret  ;конец процедуры восстановления выходов

SEG_SET:  ;процедура установки сегментов

         cpi temp,0  ;ищем число, равное temp

         brne ss_0

         rcall OUT_0  ;и посылаем на нужную процедуру вывода сегментов

         rjmp END_seg

ss_0:    cpi temp,1

         brne ss_1

         rcall OUT_1

         rjmp END_seg

ss_1:    cpi temp,2

         brne ss_2

         rcall OUT_2

         rjmp END_seg

ss_2:    cpi temp,3

         brne ss_3

         rcall OUT_3

         rjmp END_seg

ss_3:    cpi temp,4

         brne ss_4

         rcall OUT_4

         rjmp END_seg

ss_4:    cpi temp,5

         brne ss_5

         rcall OUT_5

         rjmp END_seg

ss_5:    cpi temp,6

         brne ss 6

         rcall OUT_6

         rjmp END_seg

ss_6:    cpi temp,7

        brne ss_7

        rcall OUT_7

        rjmp END_seg

ss_7:    cpi temp,8

        brne ss_8

        rcall OUT_8

        rjmp END_seg

ss_8:    cpi temp,9

        rcall OUT_9

END_seg:

jret  ;конец процедуры установки сегментов

;процедуры для отображения цифр на семисегментном индикаторе

;ABCDEF(0);ВС(1)/ABDEG(2)/ABCDG(3)/BCFG(4);ACDFG(5)

;ACDEFG(6);ABC(7);ABCDEFG(8);ABCDFG(9)

Out_0:

        sbi PortD,segA

        sbi PortD,segB

        sbi PortB,segC

        sbi PortB,segD

        sbi PortB,segE

        sbi PortB,segF

        ret

OUT_1:

        sbi PortD,segB

        sbi PortB,segC

        ret

OUT_2:

        sbi PortD,segA

        sbi PortD,segB

        sbi PortB,segG

        sbi PortB,segE

        sbi PortB,segD

        ret

OUT_3:

        sbi PortD,segA

        sbi PortD,segB

        sbi PortB,segG

        sbi PortB,segC

        sbi PortB,segD

        ret

OUT_4:

        sbi PortD,segB

        sbi PortB,segC

        sbi PortB,segF

        sbi PortB,segG

        ret

OUT_5:

        sbi PortD,segA

        sbi PortB,segF

        sbi PortB,segG

        sbi PortB,segC

        sbi PortB,segD

        ret

OUT_6:

        sbi PortD,segA

        sbi PortB,segF

        sbi PortB,segG

        sbi PortB,segC

        sbi PortB,segE

        sbi PortB,segD

        ret

OUT_7:

        sbi PortD,segA

        sbi PortD,segB

        sbi PortB,segC

        ret

OUT_8:

        sbi PortD,segA

        sbi PortD,segB

        sbi PortB,segC

        sbi PortB,segD

        sbi PortB,segE

        sbi PortB,segF

        sbi PortB,segG

        ret

OUT_9:

        sbi PortD,segA

        sbi PortD,segB

        sbi PortB,segC

        sbi PortB,segD

        sbi PortB,segF

        sbi PortB,segG

        ret

Перейти на страницу:

Похожие книги

Электроника для начинающих (2-е издание)
Электроника для начинающих (2-е издание)

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

Чарльз Платт

Радиоэлектроника / Технические науки
Электроника для начинающих
Электроника для начинающих

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

Паоло Аливерти , Чарльз Платт

Радиоэлектроника / Технические науки
Искусство схемотехники. Том 3 (Изд.4-е)
Искусство схемотехники. Том 3 (Изд.4-е)

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

Пауль Хоровиц , Уинфилд Хилл

Техника / Радиоэлектроника