Home Pic in Greek Παραδείγματα χρήσης Pic Χρονόμετρο Αντίστροφης Μέτρησης Εξομοίωση προγράμματος


 

Χρονόμετρο αντίστροφης μέτρησης

Εξομοίωση προγράμματος


Προετοιμασία

Η ανίχνευση σφαλμάτων στο παράδειγμα αυτό γίνεται με την χρήση του εξομοιωτή (Simulator) του MPLAB της Microchip

    Αφού έχετε ετοιμάσει ένα project με το όνομα Cnt_dn_tmr.mcp, έχετε εισάγει το PIC16F84A.inc και το Cnt_dn_timer.asm,

     μην ξεχάσετε να ανοίξετε το αρχείο Cnt_dn_timer.lst κάνοντας κλικ στο File > Open >Αρχεία τύπου: All files > Cnt_dn_timer.lst 

     και  τέλος μεταγλωττίστε κάνοντας κλικ στο 

      Project >Make  ή κάντε κλικ στο κουμπί


Eξομοίωση με χρήση της ψευδοεντολής ifdef

    H 'IFDEF' είναι μια ψευδοεντολή του μεταγλωττιστή (Assembler) του MPLAB. Όταν χρησιμοποιείται, ο κώδικας μετά την ετικέτα στην οποία αναφέρεται η ψευδοεντολή 'IFDEF' μεταγλωττίζεται. Διαφορετικά δεν μεταγλωττίζεται. Για να γίνει πιο κατανοητό δείτε αναλυτικά το παρακάτω.

#define  _debug

(1)
#ifdef _debug
        movlw   d'255'
#else
        movlw   d'43'
#endif

(2)
#ifdef _debug
        movlw   d'255'
#endif

(3)
#ifndef _debug
        movlw   d'255'
#else
        movlw   d'43'
#endif

(4)
#ifndef _debug
        movlw   d'255'
#endif

Στο παράδειγμα αριστερά, ορίζεται η ετικέτα  '_debug' με την ψευδοεντολή '#define'.

Με την χρήση των, #ifdef, #ifndef, #else, #endif  ορίζεται μια συνθήκη, δηλαδή ποιο κομμάτι κώδικα θα μεταγλωττιστεί σε κάθε περίπτωση.

Στην περίπτωση του (1) και (2), επειδή η ετικέτα '_debug' έχει οριστεί, το κόκκινο κομμάτι κώδικα (red) μέχρι τις ψευδοεντολές #else ή #endif θα μεταγλωττιστεί. Το μπλε κομμάτι κώδικα (blue) από #else έως #endif δεν θα μεταγλωττιστεί.
Η ψευδοεντολή #ifdef σημαίνει "Εάν η ετικέτα l(_debug) έχει οριστεί".
και η ψευδοεντολή #else σημαίνει  "διαφορετικά".
Έτσι, με βάση το παράδειγμα έχουμε, για την πρώτη (1) περίπτωση "εάν η ετικέτα  _debug έχει οριστεί, μεταγλώττισε την εντολή movlw d'255', διαφορετικά (η ετικέτα  _debug δέν έχει οριστεί), μεταγλώττισε την εντολή movlw d'43'.".

Η περίπτωση (3) και (4) είναι ακριβώς το αντίθετο. Το 'n' της ψευδοεντολής #ifndef σημαίνει ΔΕΝ (ΟΧΙ - NOT).
Επομένως για την τρίτη (3) περίπτωση έχουμε,  "Εάν η ετικέτα _debug δέν έχει οριστεί, μεταγλώττισε την εντολή movlw d'255', διαφορετικά (η ετικέτα _debug έχει οριστεί), μεταγλώττισε την εντολή movlw d'43'.".

ΠΡΟΣΟΧΗ !!! ΔΈΝ πρέπει να ξεχάσετε την ψευδοεντολή τερματισμού της συνθήκης "Εάν", #endif.

Για την τέταρτη (4) περίπτωση, έχουμε "Εάν η ετικέτα _debug δέν έχει οριστεί, μεταγλώττισε την εντολή movlw d'255'. Δηλαδή το μπλε κομμάτι κώδικα, θα μεταγλωττιστεί μόνο εάν έχει οριστεί η ετικέτα _debug. Εάν δεν έχει οριστεί η _debug, απλά το κομμάτι αυτό παραλείπεται.

ΠΡΟΣΟΧΗ !!! ΔΈΝ πρέπει να ξεχάσετε την ψευδοεντολή τερματισμού της συνθήκης "Εάν", #endif.




Εξομοίωση με ορισμό της ετικέτας  _debug 

LOC  OBJECT CODE     LINE SOURCE TEXT
  VALUE
                      00060 #DEFINE  _DEBUG

                      00153 #IFDEF _DEBUG
0042   30FF           00154         MOVLW   D'255'          ;(Debugging step)
                      00155 #ELSE
                      00156         MOVLW   D'43'           ;Set Hard timer value
                      00157 #ENDIF

                      00173 #IFNDEF _DEBUG
                      00174         BTFSC   PORTA,RA4       ;Stop switch ON ?
                      00175 #ENDIF

Εξομοίωση χωρίς ορισμό της ετικέτας  _debug 

LOC  OBJECT CODE     LINE SOURCE TEXT
  VALUE
                      00060 ;#define  _debug

                      00153 #IFDEF _DEBUG
                      00154         MOVLW   D'255'          ;(Debugging step)
                      00155 #ELSE
0047   302B           00156         MOVLW   D'43'           ;Set Hard timer value
                      00157 #ENDIF

                      00173 #IFNDEF _DEBUG
0051   1A05           00174         BTFSC   PORTA,RA4       ;Stop switch ON ?
                      00175 #ENDIF

    Για εξομοίωση χωρίς ορισμό της ετικέτας _debug, βάλτε ένα Ελληνικό ερωτηματικό (;), στην αρχή της ψευδοεντολής #define, έτσι ώστε ο μεταγλωττιστής να την θεωρήσει σχόλιο.



Χρήση της συνθήκης #ifdef, #else, #ifndef, #endif, μέσα στο πρόγραμμα

    Μέσα στο πρόγραμμα, έχει τοποθετηθεί, για ευκολότερη εξομοίωση, η συνθήκη στα εξής κομμάτια.

    Ανάγνωση της κατάστασης των διακοπτών BCD : Επειδή δεν είναι δυνατόν να εξομοιωθεί η επιλογή χρόνου από τους διακόπτες BCD, ορίζει ένα χρόνο εκκίνησης.
    Ορισμός τιμής εκκίνησης του  χρονομετρητή TMR0 : Για να εξομοιωθεί ο χρόνος υπερχείλισης του TMR0 χρειάζεται αρκετός χρόνος. Για να μην περιμένετε άδικα, ορίζει τιμή εκκίνησης του, το TMR0 = 255, με αποτέλεσμα ο χρόνος υπερχείλισης να μειωθεί στο ελάχιστο.
    Ανάγνωση της κατάστασης του διακόπτη διακοπής του χρονόμετρου : Η κατάσταση της πόρτας εισόδου για τον εξομοιωτή του MPLAB βρίσκεται συνήθως σε λογικό '0'.
    Με αυτή την κατάσταση, ο διακόπτης διακοπής του χρονόμετρου (stop), θα είναι για τον PIC μόνιμα πιεσμένος, και έτσι θα σταματά η χρονομέτρηση πολύ πριν μηδενιστούν οι μετρητές ' Τέλος χρόνου'. Για την εξομοίωση η χρήση της '#ifndef' παρακάμπτει τον έλεγχο του διακόπτη Stop.

    #ifndef _debug
    btfsc PORTA,ra4      ;Stop switch is ON ?

    Χρονική καθυστέρηση ενός μιλισεκόντ (1mSec) : Για την εξομοίωση η ρουτίνα t1m παρακάμπτεται.




Εξομοίωση με χρήση σημείων διακοπής ροής κώδικα (Breakpoints) 

Τα breakpoint μπορούν να εισαχθούν στην εξομοίωση με την ακόλουθη διαδικασία.

(1) Θέλουμε να εισάγουμε διακοπή ροής (Breakpoint) στις διευθύνσεις 009Bh (295) και 009Dh (297). Κάντε διπλό κλικ στην εντολή που αντιστοιχεί η κάθε διεύθυνση στον εξομοιωτή. Αμέσως στο γκρίζο περιθώριο θα εμφανιστεί το σήμα   Β  .
(2)
κάντε δεξί κλικ.

στο μενού που θα εμφανιστεί κάντε κλικ στο Set Breakpoint με το αριστερό πλήκτρο του mouse .

Η εντολή που είχατε επιλέξει θα έχει τώρα στο γκρίζο περιθώριο το σήμα  Β .


Η εισαγωγή του σημείου διακοπής ολοκληρώθηκε.

κάντε κλικ στο κουμπί    ή ακολουθήστε τις επιλογές : Debugger > Run.

Μετά από σύντομο χρονικό διάστημα ο εξομοιωτής θα φτάσει στην διεύθυνση 009Bh του Breakpoint και θα σταματήσει εκεί. Με κάθε πάτημα του θα εναλλάσσονται οι διευθύνσεις 009Bh (295) και 009Dh (297) και θα μειώνονται ο μετρητής των μονάδων των λεπτών και ο μετρητής των δεκάδων των δευτερόλεπτων.


  • Στην περίπτωση του 00 00 : 00 01, η εξομοίωση σταματά στην διεύθυνση PC=009Bh. Η διεύθυνση PC=009Dh είναι ένα βήμα μετά τον έλεγχο του 'Τέλος χρόνου'. Όταν το περιεχόμενο του καταχωρητή μετρητή 0Fh γίνει 01, τότε ο μετρητής προγράμματος (Program Counter) πηγαίνει στην διεύθυνση που βρίσκεται η υπορουτίνα 'Τέλος χρόνου' (time-out). 

 

    0C - c10m 0D - c01m  0E - c10s 0F - c01s Καταχωρητές - μετρητές
    01 00 00 00  
    00 09 05 09  
    00 09 05 08  
    00 09 05 07  
     
      Ενδιάμεσος χρόνος
    00 00 00 01  
    00 00 00 00 ΤΕΛΟΣ ΧΡΟΝΟΥ !!!