Facebook
From Beefy Crow, 3 Years ago, written in Plain Text.
Embed
Download Paste or View Raw
Hits: 92
  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 main_loop  ; 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.  
  57.         ; COUNTER:
  58.                 push R20
  59.                 push R21
  60.                 push R22
  61.  
  62.                 ldi R20, 1
  63.                 add PulseEdgeCtrL, R20
  64.                 clr R20
  65.                 adc PulseEdgeCtrH, R20
  66.  
  67.                 LOAD_CONST R21, R22, 10000
  68.  
  69.                 cp PulseEdgeCtrL, R21
  70.                 brne Counter_End
  71.                 cp PulseEdgeCtrH, R22
  72.                 brne Counter_End
  73.  
  74.                 clr PulseEdgeCtrL
  75.                 clr PulseEdgeCtrH
  76.  
  77.                 Counter_End:
  78.  
  79.                 rcall NumberToDigits
  80.  
  81.                 pop R22
  82.                 pop R21
  83.                 pop R20
  84.  
  85. reti     ; powrót z procedury obsługi przerwania (reti zamiast ret)  
  86.  
  87.  
  88.  
  89.         Divide:
  90. ; X/Y = Q * Y + R
  91.  
  92.         push R24
  93.         push R25
  94.  
  95.         LOAD_CONST QCtrL, QCtrH, 0
  96.  
  97.         Divide_2:
  98.                 cp XH, YH    ;cp porównuje rejestry odejmując je.
  99.                 brcs Divide_2_End ; XH < YH
  100.                 brne Divide_2_Sub ; XH > YH
  101.  
  102.                 cp XL, YL ; XH = YH
  103.                 brcs Divide_2_End ; XL < YL
  104.  
  105.                 Divide_2_Sub:
  106.                         sub XL, YL
  107.                         sbc XH, YH
  108.                         adiw QCtrL:QCtrH, 1
  109.                         rjmp Divide_2
  110.  
  111.                 Divide_2_End:
  112.                         mov QH, QCtrH
  113.                         mov QL, QCtrL
  114.                         mov RH, XH
  115.                         mov RL, XL
  116.  
  117.         pop R25
  118.         pop R24
  119.  
  120.         ret
  121.  
  122.  
  123.  
  124. DelayInMs:
  125.         push R24
  126.         push R25
  127.         LOAD_CONST R24, R25, 30
  128.         Loop_1:
  129.                 rcall DelayOneMs
  130.                 sbiw R24, 1
  131.         brne Loop_1
  132.         pop R25
  133.         pop R24
  134.         ret
  135.  
  136. DelayOneMs:
  137.         push R24
  138.         push R25
  139.  
  140.         LOAD_CONST R24, R25, 1750
  141.         Loop_2:
  142.                 sbiw R24, 1
  143.                 brne Loop_2
  144.  
  145.         pop R25
  146.         pop R24
  147.         ret
  148.  
  149.  
  150.  
  151.         DigitTo7segCode:
  152.  
  153.         push R30
  154.         push R31
  155.  
  156.         ldi R30, low(Table<<1)
  157.         ldi R31, high(Table<<1)
  158.  
  159.         add R30,R16
  160.         clr R16
  161.         adc R31,R16
  162.         lpm R16, Z
  163.  
  164.         pop R31
  165.         pop R30
  166.  
  167.         ret
  168.  
  169. Table: .db 0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0xFF, 0x6F
  170.  
  171.  
  172.  
  173. NumberToDigits:
  174.         mov XL, PulseEdgeCtrL
  175.         mov XH, PulseEdgeCtrH
  176.         LOAD_CONST YL, YH, 1000
  177.         rcall Divide
  178.         mov Digit_0, QL
  179.  
  180.         LOAD_CONST YL, YH, 100
  181.         mov XH, RH
  182.         mov XL, RL
  183.         rcall Divide
  184.         mov Digit_1, QL
  185.  
  186.         LOAD_CONST YL, YH, 10
  187.         mov XH, RH
  188.         mov XL, RL
  189.         rcall Divide
  190.         mov Digit_2, QL
  191.  
  192.         mov Digit_3, RL
  193.         ret
  194.  
  195.  
  196.  
  197. Main_Loop:
  198.  
  199. Timer1_Init:   ; linijka 248 w manualu.
  200.  
  201.         .equ Timer_Period = 32150
  202.  
  203.         ldi R16, TCCR1B|(1<<CS12)|(1<<WGM12)
  204.         out TCCR1B, R16
  205.         ldi R16, high(Timer_Period)
  206.         out OCR1AH, R16
  207.         ldi R16, low(Timer_Period)
  208.         out OCR1AL, R16
  209.         ldi R16, 1<<OCIE1A
  210.         out TIMSK, R16
  211.  
  212.  
  213.  
  214.         push R27
  215.         push R28
  216.         LOAD_CONST R27, R28, 1234 ; TUTAJ WPISUJĘ LICZBĘ
  217.         mov PulseEdgeCtrH, R28
  218.         mov PulseEdgeCtrL, R27
  219.         pop R28
  220.         pop R27
  221.  
  222.         //clr PulseEdgeCtrL
  223.         //clr PulseEdgeCtrH
  224.  
  225.         rcall NumberToDigits
  226.  
  227.         sei
  228.  
  229.         SET_DIGIT 0
  230.         SET_DIGIT 1
  231.         SET_DIGIT 2
  232.         SET_DIGIT 3
  233.  
  234. rjmp Main_Loop