Facebook
From Emerald Wolf, 3 Years ago, written in Plain Text.
Embed
Download Paste or View Raw
Hits: 118
  1. .equ Digits_P = PORTB
  2. .equ Segments_P = PORTD
  3.  
  4. .def Digit_0 = R5
  5. .def Digit_1 = R4
  6. .def Digit_2 = R3
  7. .def Digit_3 = R2
  8.  
  9. .def PulseEdgeCtrL = R0
  10. .def PulseEdgeCtrH = R1
  11.  
  12. ; INPUTS
  13. .def XL=R16 ; divident
  14. .def XH=R17
  15.  
  16. .def YL=R18 ; divisor
  17. .def YH=R19
  18.  
  19. ; OUTPUTS
  20. .def RL=R16 ; remainder
  21. .def RH=R17
  22.  
  23. .def QL=R18 ; quotient
  24. .def QH=R19
  25.  
  26. ; INTERNAL
  27. .def QCtrL=R24
  28. .def QCtrH=R25
  29.  
  30.  
  31.  
  32. .macro LOAD_CONST
  33.         ldi @0, low(@2)
  34.         ldi @1, high(@2)
  35. .endmacro
  36.  
  37. .macro SET_DIGIT
  38.         mov R16, Digit_@0
  39.         rcall DigitTo7segCode
  40.         ldi R24, 2<<@0
  41.         out Digits_P, R24
  42.         out Segments_P, R16
  43.         rcall DelayInMs
  44. .endmacro
  45.  
  46.  
  47.  
  48. .cseg           ; segment pamięci kodu programu  
  49.  
  50. .org 0     ; ustawia pamięć kodu na 0.
  51. rjmp timer1_init  ; skok po resecie (do programu głównego)
  52. .org OC1Aaddr  
  53. rjmp Timer_isr ; skok do obsługi przerwania timera
  54.  
  55. Timer_isr:      ; procedura obsługi przerwania timera
  56.         ; COUNTER:
  57.                 push R20
  58.                 push R21
  59.                 push R22
  60.  
  61.                 ldi R20, 1
  62.                 add PulseEdgeCtrL, R20
  63.                 clr R20
  64.                 adc PulseEdgeCtrH, R20
  65.  
  66.                 LOAD_CONST R21, R22, 10000
  67.  
  68.                 cp PulseEdgeCtrL, R21
  69.                 brne Counter_End
  70.                 cp PulseEdgeCtrH, R22
  71.                 brne Counter_End
  72.  
  73.                 clr PulseEdgeCtrL
  74.                 clr PulseEdgeCtrH
  75.  
  76.                 Counter_End:
  77.                 rcall NumberToDigits
  78.     reti     ; powrót z procedury obsługi przerwania (reti zamiast ret)  
  79.  
  80.  
  81.  
  82.         Divide:
  83. ; X/Y = Q * Y + R
  84.  
  85.         push R24
  86.         push R25
  87.  
  88.         LOAD_CONST QCtrL, QCtrH, 0
  89.  
  90.         Divide_2:
  91.                 cp XH, YH    ;cp porównuje rejestry odejmując je.
  92.                 brcs Divide_2_End ; XH < YH
  93.                 brne Divide_2_Sub ; XH > YH
  94.  
  95.                 cp XL, YL ; XH = YH
  96.                 brcs Divide_2_End ; XL < YL
  97.  
  98.                 Divide_2_Sub:
  99.                         sub XL, YL
  100.                         sbc XH, YH
  101.                         adiw QCtrL:QCtrH, 1
  102.                         rjmp Divide_2
  103.  
  104.                 Divide_2_End:
  105.                         mov QH, QCtrH
  106.                         mov QL, QCtrL
  107.                         mov RH, XH
  108.                         mov RL, XL
  109.  
  110.         pop R25
  111.         pop R24
  112.  
  113.         ret
  114.  
  115.  
  116.  
  117. DelayInMs:
  118.         push R24
  119.         push R25
  120.         LOAD_CONST R24, R25, 30
  121.         Loop_1:
  122.                 rcall DelayOneMs
  123.                 sbiw R24, 1
  124.         brne Loop_1
  125.         pop R25
  126.         pop R24
  127.         ret
  128.  
  129. DelayOneMs:
  130.         push R24
  131.         push R25
  132.  
  133.         LOAD_CONST R24, R25, 1750
  134.         Loop_2:
  135.                 sbiw R24, 1
  136.                 brne Loop_2
  137.  
  138.         pop R25
  139.         pop R24
  140.         ret
  141.  
  142.  
  143.  
  144.         DigitTo7segCode:
  145.  
  146.         push R30
  147.         push R31
  148.  
  149.         ldi R30, low(Table<<1)
  150.         ldi R31, high(Table<<1)
  151.  
  152.         add R30,R16
  153.         clr R16
  154.         adc R31,R16
  155.         lpm R16, Z
  156.  
  157.         pop R31
  158.         pop R30
  159.  
  160.         ret
  161.  
  162. Table: .db 0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0xFF, 0x6F
  163.  
  164.  
  165.  
  166. NumberToDigits:
  167.         mov XL, PulseEdgeCtrL
  168.         mov XH, PulseEdgeCtrH
  169.         LOAD_CONST YL, YH, 1000
  170.         rcall Divide
  171.         mov Digit_0, QL
  172.  
  173.         LOAD_CONST YL, YH, 100
  174.         mov XH, RH
  175.         mov XL, RL
  176.         rcall Divide
  177.         mov Digit_1, QL
  178.  
  179.         LOAD_CONST YL, YH, 10
  180.         mov XH, RH
  181.         mov XL, RL
  182.         rcall Divide
  183.         mov Digit_2, QL
  184.  
  185.         mov Digit_3, RL
  186.         ret
  187.  
  188.  
  189.  
  190. Timer1_Init:   ; linijka 248 w manualu.
  191.  
  192.         .equ Timer_Period = 32150
  193.  
  194.         ldi R16, TCCR1B|(1<<CS12)|(1<<WGM12)
  195.         out TCCR1B, R16
  196.         ldi R16, high(Timer_Period)
  197.         out OCR1AH, R16
  198.         ldi R16, low(Timer_Period)
  199.         out OCR1AL, R16
  200.         ldi R16, 1<<OCIE1A
  201.         out TIMSK, R16
  202.  
  203.  
  204.  
  205.         push R27
  206.         push R28
  207.         LOAD_CONST R27, R28, 1234 ; TUTAJ WPISUJĘ LICZBĘ
  208.         mov PulseEdgeCtrH, R28
  209.         mov PulseEdgeCtrL, R27
  210.         pop R28
  211.         pop R27
  212.  
  213.         //clr PulseEdgeCtrL
  214.         //clr PulseEdgeCtrH
  215.  
  216.         rcall NumberToDigits
  217.         sei
  218.  
  219.  
  220.  
  221. Main_Loop:
  222.  
  223.         SET_DIGIT 0
  224.         SET_DIGIT 1
  225.         SET_DIGIT 2
  226.         SET_DIGIT 3
  227.  
  228.         pop R22
  229.         pop R21
  230.         pop R20
  231.  
  232. rjmp Main_Loop