Advertisement
Guest User

assembly

a guest
Dec 3rd, 2019
146
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
ARM 8.36 KB | None | 0 0
  1. .include "m16def.inc"
  2. ; omada 07
  3.  
  4. #define first_key (1 << 1)
  5. #define second_key (1 << 4)
  6. #define one r3
  7. #define zero r2
  8. #define tmp r30
  9.  
  10. ldi r24, low(RAMEND)
  11. out SPL, r24
  12. ldi r24, high(RAMEND)
  13. out SPH, r24 ; αρχικοποίηση stack pointer
  14.  
  15. ser r24
  16. out DDRD,r24 ; αρχικοποίηση PORTD που συνδέεται η οθόνη, ως έξοδος
  17. out DDRB,r24 ; r24 έξοδος
  18.  
  19. clr r2; 0
  20. clr r3
  21. dec r3; 0xff
  22.  
  23. ldi r24 ,(1 << PC7) | (1 << PC6) | (1 << PC5) | (1 << PC4) ; θέτει ως εξόδους τα 4 MSB
  24. out DDRC ,r24 ; της θύρας PORTC
  25.  
  26.  
  27. loop:
  28.     rcall scan_key
  29.     cpi r24,first_key
  30.     brne one_remainning
  31.     rcall scan_key
  32.     cpi r24,second_key
  33.     brne wrong
  34. correct:
  35.     ldi r24,LOW(4000)
  36.     ldi r25,HIGH(4000)
  37.     out PORTB,one
  38.     rcall wait_msec
  39.     out PORTB,zero
  40.     jmp loop
  41. one_remainning:
  42.     rcall scan_key
  43. wrong:
  44.    
  45.  
  46.     ldi tmp,8
  47. times8:
  48.  
  49.     out PORTB,one
  50.     ldi r24,LOW(250)
  51.     ldi r25,HIGH(250)
  52.     rcall wait_msec
  53.     out PORTB,zero
  54.     ldi r24,LOW(250)
  55.     ldi r25,HIGH(250)
  56.     rcall wait_msec
  57.     dec tmp
  58.     brne times8
  59.     jmp loop
  60.  
  61.  
  62. scan_key:
  63.     ldi r24,20; ms για σπινθιρισμό
  64.     rcall scan_keypad_rising_edge
  65.     clr tmp
  66.     or tmp,r24
  67.     or tmp,r25
  68.     cpi tmp,0
  69.     breq scan_key
  70.     ret
  71.  
  72.  
  73. scan_row:
  74.     ldi r25 , 0x08 ; αρχικοποίηση με ‘0000 1000’ 
  75. back_:
  76.     lsl r25 ; αριστερή ολίσθηση του ‘1’ τόσες θέσεις
  77.     dec r24 ; όσος είναι ο αριθμός της γραμμής
  78.     brne back_
  79.     out PORTC , r25 ; η αντίστοιχη γραμμή τίθεται στο λογικό ‘1’
  80.     nop
  81.     nop ; καθυστέρηση για να προλάβει να γίνει η αλλαγή κατάστασης
  82.     in r24 , PINC ; επιστρέφουν οι θέσεις (στήλες) των διακοπτών που είναι πιεσμένοι
  83.     andi r24 ,0x0f ; απομονώνονται τα 4 LSB όπου τα ‘1’ δείχνουν που είναι πατημένοι
  84.     ret ; οι διακόπτες.
  85.  
  86. scan_keypad:
  87.     ldi r24 , 0x01 ; έλεγξε την πρώτη γραμμή του πληκτρολογίου
  88.     rcall scan_row
  89.     swap r24 ; αποθήκευσε το αποτέλεσμα
  90.     mov r27 , r24 ; στα 4 msb του r27
  91.     ldi r24 ,0x02 ; έλεγξε τη δεύτερη γραμμή του πληκτρολογίου
  92.     rcall scan_row
  93.     add r27 , r24 ; αποθήκευσε το αποτέλεσμα στα 4 lsb του r27
  94.     ldi r24 , 0x03 ; έλεγξε την τρίτη γραμμή του πληκτρολογίου
  95.     rcall scan_row
  96.     swap r24 ; αποθήκευσε το αποτέλεσμα
  97.     mov r26 , r24 ; στα 4 msb του r26
  98.     ldi r24 ,0x04 ; έλεγξε την τέταρτη γραμμή του πληκτρολογίου
  99.     rcall scan_row
  100.     add r26 , r24 ; αποθήκευσε το αποτέλεσμα στα 4 lsb του r26
  101.     movw r24 , r26 ; μετέφερε το αποτέλεσμα στους καταχωρητές r25:r24
  102.     ret
  103.  
  104. .DSEG
  105. _tmp_: .byte 2
  106. ; ---- Τέλος τμήματος δεδομένων
  107. .CSEG
  108. scan_keypad_rising_edge:
  109.     mov r22 ,r24 ; αποθήκευσε το χρόνο σπινθηρισμού στον r22
  110.     rcall scan_keypad ; έλεγξε το πληκτρολόγιο για πιεσμένους διακόπτες
  111.     push r24 ; και αποθήκευσε το αποτέλεσμα
  112.     push r25
  113.     mov r24 ,r22 ; καθυστέρησε r22 ms (τυπικές τιμές 10-20 msec που καθορίζεται από τον
  114.     ldi r25 ,0 ; κατασκευαστή του πληκτρολογίου – χρονοδιάρκεια σπινθηρισμών)
  115.     rcall wait_msec
  116.     rcall scan_keypad ; έλεγξε το πληκτρολόγιο ξανά και απόρριψε
  117.     pop r23 ; όσα πλήκτρα εμφανίζουν σπινθηρισμό
  118.     pop r22
  119.     and r24 ,r22
  120.     and r25 ,r23
  121.     ldi r26 ,low(_tmp_) ; φόρτωσε την κατάσταση των διακοπτών στην
  122.     ldi r27 ,high(_tmp_) ; προηγούμενη κλήση της ρουτίνας στους r27:r26
  123.     ld r23 ,X+
  124.     ld r22 ,X
  125.     st X ,r24 ; αποθήκευσε στη RAM τη νέα κατάσταση
  126.     st -X ,r25 ; των διακοπτών
  127.     com r23
  128.     com r22 ; βρες τους διακόπτες που έχουν «μόλις» πατηθεί
  129.     and r24 ,r22
  130.     and r25,r23
  131.     ret
  132.  
  133.  
  134. ; ------------------------------------------
  135. ; LCD functions
  136. ; ------------------------------------------
  137.  
  138. write_2_nibbles:
  139.     push r24 ; στέλνει τα 4 MSB
  140.     in r25 ,PIND ; διαβάζονται τα 4 LSB και τα ξαναστέλνουμε
  141.     andi r25 ,0x0f ; για να μην χαλάσουμε την όποια προηγούμενη κατάσταση
  142.     andi r24 ,0xf0 ; απομονώνονται τα 4 MSB και
  143.     add r24 ,r25 ; συνδυάζονται με τα προϋπάρχοντα 4 LSB
  144.     out PORTD ,r24 ; και δίνονται στην έξοδο
  145.     sbi PORTD ,PD3 ; δημιουργείται παλμός Enable στον ακροδέκτη PD3
  146.     cbi PORTD ,PD3 ; PD3=1 και μετά PD3=0
  147.     pop r24 ; στέλνει τα 4 LSB. Ανακτάται το byte.
  148.     swap r24 ; εναλλάσσονται τα 4 MSB με τα 4 LSB
  149.     andi r24 ,0xf0 ; που με την σειρά τους αποστέλλονται
  150.     add r24 ,r25
  151.     out PORTD ,r24
  152.     sbi PORTD ,PD3 ; Νέος παλμός Enable
  153.     cbi PORTD ,PD3
  154.     ret
  155.  
  156.  
  157. lcd_data:
  158.     sbi PORTD ,PD2 ; επιλογή του καταχωρητή δεδομένων (PD2=1)
  159.     rcall write_2_nibbles ; αποστολή του byte
  160.     ldi r24 ,43 ; αναμονή 43μsec μέχρι να ολοκληρωθεί η λήψη
  161.     ldi r25 ,0 ; των δεδομένων από τον ελεγκτή της lcd
  162.     rcall wait_usec
  163.     ret
  164.  
  165. lcd_command:
  166.     cbi PORTD ,PD2 ; επιλογή του καταχωρητή εντολών (PD2=1)
  167.     rcall write_2_nibbles ; αποστολή της εντολής και αναμονή 39μsec
  168.     ldi r24 ,39 ; για την ολοκλήρωση της εκτέλεσης της από τον ελεγκτή της lcd.
  169.     ldi r25 ,0 ; ΣΗΜ.: υπάρχουν δύο εντολές, οι clear display και return home,
  170.     rcall wait_usec ; που απαιτούν σημαντικά μεγαλύτερο χρονικό διάστημα.
  171.     ret
  172.  
  173. lcd_init:
  174.     ldi r24 ,40 ; Όταν ο ελεγκτής της lcd τροφοδοτείται με
  175.     ldi r25 ,0 ; ρεύμα εκτελεί την δική του αρχικοποίηση.
  176.     rcall wait_msec ; Αναμονή 40 msec μέχρι αυτή να ολοκληρωθεί.
  177.     ldi r24 ,0x30 ; εντολή μετάβασης σε 8 bit mode
  178.     out PORTD ,r24 ; επειδή δεν μπορούμε να είμαστε βέβαιοι
  179.     sbi PORTD ,PD3 ; για τη διαμόρφωση εισόδου του ελεγκτή
  180.     cbi PORTD ,PD3 ; της οθόνης, η εντολή αποστέλλεται δύο φορές
  181.     ldi r24 ,39
  182.     ldi r25 ,0 ; εάν ο ελεγκτής της οθόνης βρίσκεται σε 8-bit mode
  183.     rcall wait_usec ; δεν θα συμβεί τίποτα, αλλά αν ο ελεγκτής έχει διαμόρφωση
  184.     ; εισόδου 4 bit θα μεταβεί σε διαμόρφωση 8 bit
  185.     ldi r24 ,0x30
  186.     out PORTD ,r24
  187.     sbi PORTD ,PD3
  188.     cbi PORTD ,PD3
  189.     ldi r24 ,39
  190.     ldi r25 ,0
  191.     rcall wait_usec
  192.     ldi r24 ,0x20 ; αλλαγή σε 4-bit mode
  193.     out PORTD ,r24
  194.     sbi PORTD ,PD3
  195.     cbi PORTD ,PD3
  196.     ldi r24 ,39
  197.     ldi r25 ,0
  198.     rcall wait_usec
  199.     ldi r24 ,0x28 ; επιλογή χαρακτήρων μεγέθους 5x8 κουκίδων
  200.     rcall lcd_command ; και εμφάνιση δύο γραμμών στην οθόνη
  201.     ldi r24 ,0x0c ; ενεργοποίηση της οθόνης, απόκρυψη του κέρσορα
  202.     rcall lcd_command
  203.     ldi r24 ,0x01 ; καθαρισμός της οθόνης
  204.     rcall lcd_command
  205.     ldi r24 ,low(1530)
  206.     ldi r25 ,high(1530)
  207.     rcall wait_usec
  208.     ldi r24 ,0x06 ; ενεργοποίηση αυτόματης αύξησης κατά 1 της διεύθυνσης
  209.     rcall lcd_command ; που είναι αποθηκευμένη στον μετρητή διευθύνσεων και
  210.     ; απενεργοποίηση της ολίσθησης ολόκληρης της οθόνης
  211.     ret
  212.  
  213.  
  214. wait_msec:
  215.     ;ret ;DEGUG
  216.     push r24
  217.     push r25
  218.     ldi r24 , low(998)
  219.     ldi r25 , high(998)
  220.     rcall wait_usec
  221.     pop r25
  222.     pop r24
  223.     sbiw r24 , 1
  224.     brne wait_msec
  225.     ret
  226. wait_usec:
  227.     sbiw r24 ,1
  228.     nop
  229.     nop
  230.     nop
  231.     nop
  232.     brne wait_usec
  233.     ret
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement