- .equ Digits_P = PORTB
- .equ Segments_P = PORTD
- .def Digit_0 = R5
- .def Digit_1 = R4
- .def Digit_2 = R3
- .def Digit_3 = R2
- .def PulseEdgeCtrL = R0
- .def PulseEdgeCtrH = R1
- ; INPUTS
- .def XL=R16 ; divident
- .def XH=R17
- .def YL=R18 ; divisor
- .def YH=R19
- ; OUTPUTS
- .def RL=R16 ; remainder
- .def RH=R17
- .def QL=R18 ; quotient
- .def QH=R19
- ; INTERNAL
- .def QCtrL=R24
- .def QCtrH=R25
- .macro LOAD_CONST
- ldi @0, low(@2)
- ldi @1, high(@2)
- .endmacro
- .macro SET_DIGIT
- mov R16, Digit_@0
- rcall DigitTo7segCode
- ldi R24, 2<<@0
- out Digits_P, R24
- out Segments_P, R16
- rcall DelayInMs
- .endmacro
- .cseg ; segment pamięci kodu programu
- .org 0 ; ustawia pamięć kodu na 0.
- rjmp main_loop ; skok po resecie (do programu głównego)
- .org OC1Aaddr
- rjmp _timer_isr ; skok do obsługi przerwania timera
- _timer_isr: ; procedura obsługi przerwania timera
- inc R0 ; jakiś kod
- reti ; powrót z procedury obsługi przerwania (reti zamiast ret)
- Divide:
- ; X/Y = Q * Y + R
- push R24
- push R25
- LOAD_CONST QCtrL, QCtrH, 0
- Divide_2:
- cp XH, YH ;cp porównuje rejestry odejmując je.
- brcs Divide_2_End ; XH < YH
- brne Divide_2_Sub ; XH > YH
- cp XL, YL ; XH = YH
- brcs Divide_2_End ; XL < YL
- Divide_2_Sub:
- sub XL, YL
- sbc XH, YH
- adiw QCtrL:QCtrH, 1
- rjmp Divide_2
- Divide_2_End:
- mov QH, QCtrH
- mov QL, QCtrL
- mov RH, XH
- mov RL, XL
- pop R25
- pop R24
- ret
- DelayInMs:
- push R24
- push R25
- LOAD_CONST R24, R25, 30
- Loop_1:
- rcall DelayOneMs
- sbiw R24, 1
- brne Loop_1
- pop R25
- pop R24
- ret
- DelayOneMs:
- push R24
- push R25
- LOAD_CONST R24, R25, 1750
- Loop_2:
- sbiw R24, 1
- brne Loop_2
- pop R25
- pop R24
- ret
- DigitTo7segCode:
- push R30
- push R31
- ldi R30, low(Table<<1)
- ldi R31, high(Table<<1)
- add R30,R16
- clr R16
- adc R31,R16
- lpm R16, Z
- pop R31
- pop R30
- ret
- Table: .db 0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0xFF, 0x6F
- NumberToDigits:
- mov XL, PulseEdgeCtrL
- mov XH, PulseEdgeCtrH
- LOAD_CONST YL, YH, 1000
- rcall Divide
- mov Digit_0, QL
- LOAD_CONST YL, YH, 100
- mov XH, RH
- mov XL, RL
- rcall Divide
- mov Digit_1, QL
- LOAD_CONST YL, YH, 10
- mov XH, RH
- mov XL, RL
- rcall Divide
- mov Digit_2, QL
- mov Digit_3, RL
- ret
- Timer1_Init: ; linijka 248 w manualu.
- .equ Timer_Period = 32150
- ldi R16, TCCR1B|(1<<CS12)|(1<<WGM12)
- out TCCR1B, R16
- ldi R16, high(Timer_Period)
- out OCR1AH, R16
- ldi R16, low(Timer_Period)
- out OCR1AL, R16
- ldi R16, 1<<OCIE1A
- out TIMSK, R16
- push R27
- push R28
- LOAD_CONST R27, R28, 1234 ; TUTAJ WPISUJĘ LICZBĘ
- mov PulseEdgeCtrH, R28
- mov PulseEdgeCtrL, R27
- pop R28
- pop R27
- //clr PulseEdgeCtrL
- //clr PulseEdgeCtrH
- rcall NumberToDigits
- Main_Loop:
- push R20
- push R21
- push R22
- ldi R20, 1
- add PulseEdgeCtrL, R20
- clr R20
- adc PulseEdgeCtrH, R20
- LOAD_CONST R21, R22, 10000
- cp PulseEdgeCtrL, R21
- brne Counter_End
- cp PulseEdgeCtrH, R22
- brne Counter_End
- clr PulseEdgeCtrL
- clr PulseEdgeCtrH
- Counter_End:
- rcall NumberToDigits
- SET_DIGIT 0
- SET_DIGIT 1
- SET_DIGIT 2
- SET_DIGIT 3
- pop R22
- pop R21
- pop R20
- rjmp Main_Loop