.include "E:\PROG\AVR\avrasm\APPNOTES\2313def.inc" ;ИНДИКАТОРЫ у на с общим катодом, поэтому выход на сегменты с высоким ;уровнем (1), а разряды выбираются (0) ; PB0-7 - выход индикаторов ; PD0 - разрешение индикатора сотни ; PD1 - предустановка ; PD2 - разрешение индикатора десятки ; PD3 - разрешение индикатора единицы ; PD4 - вход импульсов ; PD5 - старт/стоп ; PD6 - выход на реле .def Temp1=R16 ; присваиваем регистрам собственные имена .def Temp2=R17 .def Temp3=R18 .def Temp5=R19 .def Temp4=R24 .def Temp=R20 .def t=R21 .def sr=R22 .def ed=R25 .def ds=R26 .def sot=R23 .def k=R27 .def i=R28 .dseg Digit: .byte 3 ; резервируем в оперативной памяти 3 байта памяти ; ******************************************************************* ;пишем макросы (можно и не надо, тогда этот кусок ;дописывается в программу, вместо команды) ;******************************************************************** .macro stsi ;пишем макрос для присвоения командой stsi ldi Temp,@1 ;десятичных данных переменным в ОЗУ sts @0,Temp .endmacro .cseg .org 0 rjmp RESET ; Reset Handler настраиваем прерывания rjmp EXT_INT0 ; IRQ0 Handler rjmp EXT_INT1 ; IRQ1 Handler rjmp TIM_CAPT1 ; Timer1 Capture Handler rjmp TIM_COMP1 ; Timer1 Compare Handler rjmp TIM_OVF1 ; Timer1 Overflow Handler rjmp TIM_OVF0 ; Timer0 Overflow Handler rjmp UART_RXC ; UART RX Complete Handler rjmp UART_DRE ; UDR Empty Handler rjmp UART_TXC ; UART TX Complete Handler rjmp ANA_COMP ; Analog Comparator Handler ;RESET : ret ;разрешить прерывание EXT_INT0 : ret EXT_INT1 : ret TIM_CAPT1 : ret TIM_COMP1 : ret TIM_OVF0 : ret TIM_OVF1 : ret UART_RXC : ret UART_DRE : ret UART_TXC : ret ANA_COMP : ret ;******************************************************* ;ИНИЦИАЛИЗАЦИЯ ;******************************************************* reset: ldi Temp1,RamEnd ;инициализация стека, выполняется out SPL,Temp1 ;по прерыванию reset cli ;Запретить прерывания ldi Temp,0b11111111 ;настройка портов все PB (0-7) на выход out ddrb,Temp ldi Temp,0b01001101 ;(выход на PD 0,2,3,6 вход на PD 1,4,5 больше нет:-)) out ddrd,Temp ldi sr,0 ;запись 0 в регистр старт-стоп ldi i,0 ;запись 0 в регистр сравнения вход. сигналов ldi k,40 ;запись коэффициента пересчета ldi ed,1 ;запись 1 в регистр едениц ldi ds,0 ;запись 0 в регистр десятков ldi sot,0 ;запись 0 в регистр сотен ;******************************************************* ; МОЯ ПРОГРАММА ;******************************************************* main: rcall outs ; загрузить первичные данные на выход индикатора main1: in Temp5,PinD ; опрос кнопок sbrs Temp5,5 ; если Теmp5=1,то следующая команда пропускается rjmp kn1 cpi sr,1 ; Сравниваем содержание регистра с 1 breq k3 ; Если равно, то переход k3 sbrs Temp5,1 rjmp kn2 k3: sbrs Temp5,4 rjmp sign cpi sr,0 ; Сравниваем содержание регистра пуск-стоп с 0 brne IndicCycle1 ; Если неравно, то переход ;********************************************************* ;ЦИКЛ ИНДИКАЦИИ ;********************************************************* IndicCycle: rcall Display ;выходим в цикл индикации rjmp main1 IndicCycle1: rcall Display1 ;выходим в цикл индикации rjmp main1 Display: ;последовательный вывод на индикацию содержимого ;переменной Digit с выключеным реле lds Temp1,Digit ;загружаем 0-ю ячейку (индикация сегментов) ldi Temp,0b00000100 out PortD,Temp ;активируем 0-й разряд числа (вывод PD2) ;индикации (здесь для общего анода) rcall Decoder ;вызываем 7-сегм декодер out PortB,Temp1 ;выводим значение в порт rcall Delay1 ;ждем lds Temp1,Digit+1 ;загружаем 1 ячейку ldi Temp,0b00001000 out PortD,Temp ;активируем 1-й разряд (вывод PD3) ; rcall Decoder out PortB,Temp1 rcall Delay1 ;lds Temp1,Digit+2 ;загружаем 2 ячейку ;ldi Temp,0b00000001 ;out PortD,Temp ;активируем 3-й разряд (вывод PD0) ; и т. д. скоко хошь разрядов ;rcall Decoder ;out PortB,Temp1 ;rcall Delay1 ret Display1: ;последовательный вывод на индикацию содержимого ;переменной Digit с включеным реле lds Temp1,Digit ;загружаем 0-ю ячейку (индикация сегментов) ldi Temp,0b01000100 ; и выход PD6 на реле out PortD,Temp ;активируем 0-й разряд числа (вывод PD2) ;индикации (здесь для общего анода) rcall Decoder ;вызываем 7-сегм декодер out PortB,Temp1 ;выводим значение в порт rcall Delay1 ;ждем lds Temp1,Digit+1 ;загружаем 1 ячейку ldi Temp,0b01001000 ; и выход PD6 на реле out PortD,Temp ;активируем 2-й разряд (вывод PD3) rcall Decoder out PortB,Temp1 rcall Delay1 ;lds Temp1,Digit+2 ;загружаем 2 ячейку ;ldi Temp,0b01000001 ;out PortD,Temp ;активируем 3-й разряд (вывод PD0) ; и т. д. скоко хошь разрядов ;rcall Decoder ;out PortB,Temp1 ;rcall Delay1 ret ;********************************************************* Decoder: ;преобразование двоичного числа ;в код 7-сегментного индикатора ldi ZL,Low(DcMatrix*2) ;инициализация массива ldi ZH,High(DcMatrix*2) ldi Temp2,0 ;прибавление переменной add ZL,Temp1 ;к 0-му адресу массива adc ZH,Temp2 lpm ;загрузка значения mov Temp1,r0 ret DcMatrix: ;массив - таблица истинности декодера .db 0b11000000,0b11111001 ;0,1 (для общего анода) .db 0b10100100,0b10110000 ;2,3 .db 0b10011001,0b10010010 ;4,5 .db 0b10000010,0b11111000 ;6,7 .db 0b10000000,0b10010000 ;8,9 ;********************************************************* ;циклы задержки ;********************************************************* Delay1: push Temp3 push Temp4 ldi Temp3,0 ldi Temp4,50 d11: dec Temp3 brne d11 dec Temp4 brne d11 pop Temp4 pop Temp3 ret delay2: rcall delay1 rcall delay1 rcall delay1 rcall delay1 rcall delay1 rcall delay1 rcall delay1 rcall delay1 rcall delay1 rcall delay1 rcall delay1 rcall delay1 rcall delay1 rcall delay1 rcall delay1 rcall delay1 rcall delay1 rcall delay1 rcall delay1 rcall delay1 rcall delay1 ret ;******************************************************** ; цикл регистрации сигнала на кнопке старт/стоп ;******************************************************** kn1: rcall delay1 ; сигнал пришел, пауза rcall delay1 ; сигнал пришел, пауза rcall delay1 ; сигнал пришел, пауза rcall delay1 ; сигнал пришел, пауза cycle1: sbis PIND,5 ; Жду исчезновения сигнала на PD5 rjmp cycle1 cpi sr,0 ; Сравниваем содержание регистра с 0 breq pusk ; Если равно, то переход на pusk rjmp stop stop: ldi sr,0 ; Присваиваем в SR значение 0 ;inc ed ; если останавливаем в процессе, чтобы не изменился ;rjmp out1 ; счет при обнулении добавляем 1... ;на индикацию без реле rjmp plus ; Используем для этого уже имеющуюся функцию plus pusk: ldi sr,1 ; Присваиваем в SR значение 1 ;dec ed ; вычитаем 1(при обр.отсчете сработка при -1, а не при 0) ;rjmp out2 ; на индикацию с реле rjmp minus ; используем точно так же, как в plus ;******************************************************** ;цикл регистрации ИМПУЛЬСОВ на вход PD4 ;********************************************************* sign: rcall delay1 ; сигнал пришел, пауза cycle2: sbis PIND,4 ; Жду исчезновения сигнала на PD4 rjmp cycle2 cpi sr,0 ; Сравниваем содержание регистра с 0 breq out1 ; Если равно, то переход (нет старта) inc i ; увеличить значение i на 1 cpi i,40 ; Сравниваем содержание регистра с 40 breq minus ; Если равно, то переход на minus rjmp out1 ;******************************************************** ; предустановка значения индикатора (вход PD1) ;******************************************************** kn2: rcall delay2 rcall delay2 ust: rjmp plus ;******************************************************** ; цикл Формирования числа для индикатора при сложении (предустановка) ;******************************************************** tys: ldi ed,0 ; в данном случае записываем нули ldi ds,0 ; и уходим на вывод... rjmp stop ; и уходим на stop... plus: inc ed ; увеличить значение на 1 cpi ed,10 ; Сравниваем содержание регистра с 10 breq des ; если равно 10, переход к des rjmp out1 des: inc ds ldi ed,0 cpi ds,10 ; Сравниваем содержание регистра с 10 breq sotn ; если равно 10, переход к sotn... и т.д. rjmp out1 sotn: :020000020000FC :1000000014C009C009C009C009C00AC008C009C09D :1000100009C009C009C00895089508950895089574 :10002000089508950895089508950FED0DBFF8946B :100030004FEF47BB4DE441BB60E0C0E0B8E291E068 :10004000A0E070E09BD030B335FF58C0613011F0B4 :1000500031FF6AC034FF5FC0603011F403D0F3CFCA :1000600010D0F1CF0091600044E042BB19D008BB32 :1000700024D00091610048E042BB12D008BB1DD0E3 :1000800008950091600044E442BB0AD008BB15D03B :100090000091610048E442BB03D008BB0ED0089534 :1000A000E0EBF0E010E0E00FF11FC895002D08959F :1000B000C0F9A4B0999282F880902F938F9320E09A :1000C00082E32A95F1F78A95E1F78F912F910895B0 :1000D000F4DFF3DFF2DFF1DFF0DFEFDFEEDFEDDFA4 :1000E000ECDFEBDFEADFE9DFE8DFE7DFE6DFE5DFD4 :1000F000E4DFE3DFE2DFE1DFE0DF0895DEDFDDDF25 :10010000DCDFDBDF859BFECF603019F000C060E0F4 :1001100011C061E022C0D1DF849BFECF603051F17D :10012000C395C832D1F026C0D3DFD2DF03C090E040 :10013000A0E0EDCF93959A3009F01CC0A39590E014 :10014000AA3009F017C0739590E0A0E07A3079F3F7 :1001500011C090E0A0E070E0DACFC0E09A950CF01A :1001600009C0AA9514F099E005C07A9594F399E036 :10017000A9E000C003D072CF01D072CF909360008D :0A018000A0936100709362000895DF :00000001FF