;upper part
.include "m32def.inc"
.def temp = R16
.def datal = R17
.def datah = R18
.def cntrl = R19
.def count = R20
.def num = R21
.def srgtemp = R22
.def tmpmux = R23
;.def n1 = R22
;.def n2 = R23
;.def n3 = R24
;.def n4 = R25
;.def n5 = R26
;.def n6 = R27
;.def n7 = R28
;.def n8 = R29
;interruptions' part
rjmp RESET
.org $020
jmp ADC_CMP ;adc conversion completed
; rjmp MAIN
; .org $F1

;after reset
RESET: clr datah ;after reset data
clr datal ; is cleared
ldi cntrl, 0b11100000 ;control register
clr count ;after reset no conversation's happened yet
ldi num, $04 ;number of adc's scans

ldi temp, low(RAMEND) ;stack
out SPL, temp ; ini-
ldi temp, high(RAMEND) ; tiali-
out SPH, temp ; zation
;bulbs - port B
ser temp ;set port B
out DDRB, temp ; for outputting
;buttons - port D
clr temp ;set port D
out DDRD, temp ; for receiving
;adc - port A
;"wholesale" set adc0, left adjust
out ADMUX, cntrl ; and internal voltage reference
ldi temp, 0b10001000 ;"wholesale" set 2x gain, adc interrupt enable,
out ADCSR, temp ; adif=0,one conversion,no start conversion,enable adc
;clr temp ;"wholesale" set free
;out SFIOR, temp ; running mode
;start it!
sei ;enable global interruptions

in temp, ADCSR ;start
ori temp, 0b01000000 ; conver-
out ADCSR, temp ; sion

;main part - cycle waiting for external interruptions
MAIN:
in tmpmux, PIND ;check buttons
;cpi temp, $FF ;check if no button is pushed
;breq MAIN ;if no buttons were pushed - go on scanning
sbrs tmpmux, 0
ldi cntrl, 0b11100000 ;E0
sbrs tmpmux, 1
ldi cntrl, 0b11100001 ;E1
sbrs tmpmux, 2
ldi cntrl, 0b11100010 ;E2
sbrs tmpmux, 3
ldi cntrl, 0b11100011 ;E3
sbrs tmpmux, 4
ldi cntrl, 0b11100100 ;E4
sbrs tmpmux, 5
ldi cntrl, 0b11100101 ;E5
sbrs tmpmux, 6
ldi cntrl, 0b11100110 ;E6
sbrs tmpmux, 7
ldi cntrl, 0b11100111 ;E7
;-----------
;rjmp ADC_CMP
;-----------

;program's end of cycle
rjmp MAIN
;external interruption
ADC_CMP:
in srgtemp, SREG
in temp, ADCH ;
adc datal, temp ;data<-data+ADCH
brcc C1 ;check carry flag, go to C1 if no carry
inc datah ;if c=1 datah++
C1: inc count ;count++ (number of interruptions++)
cp count, num ;check if it was asked enough times
breq OVDATA ;branch if Z=1, i. e. count=num

out ADMUX, cntrl ;if necessary - change channel

in temp, ADCSR ;start
ori temp, 0b01000000 ; conver-
out ADCSR, temp ; sion

out SREG, srgtemp
;-----------
;rjmp MAIN
;-----------

reti ;return from interruption
OVDATA:
; data/4:
lsr datal
lsr datal
lsr datah
brcc C2
ori datal, 0b01000000
C2: lsr datah
brcc C3
ori datal, 0b10000000
;end dividing, now datal = (U1+U2+U3+U4)/4
C3: com datal ;result->
out PORTB, datal ; ->port B
clr count ;count=0

out ADMUX, cntrl ;if necessary - change channel

clr datal
clr datah

in temp, ADCSR ;start
ori temp, 0b01000000 ; conver-
out ADCSR, temp ; sion

out SREG, srgtemp
;-----------
;rjmp MAIN
;-----------

reti ;return from interruption







Чтобы не видеть здесь видео-рекламу достаточно стать зарегистрированным пользователем.
Чтобы не видеть никакую рекламу на сайте, нужно стать VIP-пользователем.
Это можно сделать совершенно бесплатно. Читайте подробности тут.