Home Pic in Greek Παραδείγματα χρήσης Pic Πινακίδα Ι   Θεωρητικό κύκλωμα


 

Πινακίδα Ι  - θεωρητικό κύκλωμα



 


Τίτλος προγράμματος

;**********************************************************************
;                                                                     *
;             Πινακίδα μηνυμάτων Ι                                    *
;                                                                     *
; Author : Seiichi Inoue Ελληνική απόδοση : Παναγιώτης Πανταζόπουλος  *
;**********************************************************************


Ο τίτλος και τα σχόλια του προγράμματος πρέπει υποχρεωτικά να έχουν μπροστά το σύμβολο ( ; ).




Ψευδοεντολές LIST & INCLUDE 

 
        list            p=pic16f84a
        include         p16f84a.inc

    Ο τύπος του μικροεπεξεργαστή δηλώνεται με την ψευδοεντολή List.

    Με το αρχείο p16f84a.inc και με την ψευδοεντολή Include, εισάγονται στον κώδικα σας έτοιμες αντιστοιχίες ονομάτων με καταχωρητές, κ.λ.π
    Εάν χρησιμοποιείτε το include αρχείο της Microchip, κατά την μεταγλώττιση θα σας εμφανίζεται ένα μήνυμα προειδοποίησης σχετικά με τους καταχωρητές TRISA και TRISB. Για να αποφύγετε την εμφάνιση του μηνύματος αυτού μπορείτε να κάνετε την παρακάτω τροποποίηση.

    Τα include αρχεία συνήθως βρίσκονται στον κατάλογο:  

    c:\Program Files\Mplab\p16f84a.inc

; P16F84A.INC  Standard Header File, Version 2.00'(Διόρθωση)

TRISA      EQU     H'0085'    ->     H'0005'
TRISB      EQU     H'0086'    ->     H'0006'

    Μπορείτε επίσης να χρησιμοποιήσετε την ψευδοεντολή  ERRORLEVEL για να απενεργοποιήσετε την εμφάνιση του μηνύματος.




Διαμόρφωση μικροεπεξεργαστή

    Με το Configuration Word ενημερώνεται ο Assembler για τις ρυθμίσεις των ‘σημαιών’ διαμόρφωσης του μικροεπεξεργαστή όπως, αν θα χρονίζει με κρύσταλλο, αν θα ενεργοποιήσουμε το Watchdog timer, αν θα προστατεύσει το πρόγραμμα από αντιγραφή κ.λ.π .

        __config _hs_osc & _wdt_off & _pwrte_on & _cp_off

    Το Configuration Word μπορείτε να το δηλώσετε μέσα από το λογισμικό της συσκευής προγραμματισμού, ή να δηλωθεί αυτόματα χρησιμοποιώντας την ψευδοεντολή CONFIG. 

    Παρατηρήστε πώς υπάρχουν δύο underscore (Κάτω παύλες), πριν από την ψευδοεντολή.

    Εάν δεν χρησιμοποιήσετε το p16f84a.inc πρέπει να εισάγετε στον κώδικά σας τα παρακάτω.

_CP_OFF        EQU     H'3FFF'
_PWRTE_ON      EQU     H'3FF7'
_WDT_OFF       EQU     H'3FFB'
_HS_OSC        EQU     H'3FFE'

    Επειδή οι τιμές των δηλώσεων προστίθενται, η τελική τιμή του Configuration Word θα είναι όπως παρακάτω:

_CP_OFF 0011 1111 1111 1111 (3FFFh)
AND
_PWRTE_ON 0011 1111 1111 0111 (3FF7h)
AND
_WDT_OFF 0011 1111 1111 1011 (3FFBh)
AND
_HS_OSC 0011 1111 1111 1110 (3FFEh)

Αποτέλεσμα 0011 1111 1111 0010 (3FF2h)


    Την ψευδοεντολή CONFIG μπορείτε να την γράψετε όπως παρακάτω: 

        __config    h'3ff2'  ή   __CONFIG _CP_OFF & _PWRTE_ON & _WDT_OFF & _HS_OSC

    Δείτε στον πίνακα που ακολουθεί αναλυτικά τις ρυθμίσεις για το συγκεκριμένο Configuration Word.

    Είδος Λειτουργία Όνομα Ψηφία Bit(s)
    Προστασία κώδικα χωρίς CP 1111111111
    Χρον. Εκκίνησης Με PWRTE(inv) 0
    Χρον. Watchdog χωρίς WDTE 0
    Επιλογή ταλαντωτή High Speed FOSC1 and FOSC0 10




Ορισμός ονομάτων (Ετικετών)

;****************  Label Definition  ********************


    Σε αυτό το σημείο ‘βαφτίζουμε’ τους ελεύθερους προς χρήση καταχωρητές του μικροεπεξεργαστή και ότι άλλο χρειαζόμαστε, με ονόματα που θα μπορούμε να θυμόμαστε κατά την διάρκεια γραφής του προγράμματος . Δείτε το παράδειγμα για να καταλάβετε περισσότερα.

;************************
;*     Time adjust      *
;************************
;Σε αυτό το σημείο αντιστοιχίζετε η ταχύτητα σάρωσης των Led με την τιμή 0ch (12).  Σάρωση ανά 26msec.
tm_adj  equ     0c              ;Time adjust(26msec x 12)


;************************
;*   EEPROM data size   *
;************************
;Το e_size αντιστοιχίζεται με την τιμή 32, δηλαδή το μέγεθος των δεδομένων θα είναι ίσο με 32 ψηφιολέξεις (Bytes).
e_size  equ    d'32'            ;EEPROM data size



Ορισμός των δεδομένων της EEPROM

;***************  EEPROM Data Definition  ***************
        org     h'2100'
        de      b'11111111'


    Στο παράδειγμα αυτό, το κινούμενο μήνυμα αποθηκεύεται στην μνήμη EEPROM. 
    Η διεύθυνση h'2100' είναι η πρώτη κατά σειρά διεύθυνση της EEPROM.
    Η προσπέλαση της διεύθυνσης της EEPROM γίνεται με την ψευδοεντολή ORG. 
    Κάθε ένα ψηφίο (bit) του δυαδικού αριθμού δηλώνει την κατάσταση των Led, το "1" σημαίνει Led σβηστό, ενώ το "0", Led αναμμένο.




Εκκίνηση προγράμματος

;****************  Program Start  ***********************


    Μετά το Power on ο μικροεπεξεργαστής αρχίζει να εκτελεί τις εντολές που έχει αποθηκευμένες στην μνήμη του από την διεύθυνση μηδέν ‘Address 0’. Σε περίπτωση που χρησιμοποιούμε Interrupts η εκτέλεση των εντολών αρχίζει από την διεύθυνση τέσσερα.




Λειτουργία αρχικοποίησης

;****************  Initial Process  *********************


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

     

    Όλα τα ψηφία σε κάθε πόρτα ορίζονται σαν έξοδοι (RA0-RA4 & RB0-RB7).
    Ρυθμίζεται η κατάσταση του χρονομετρητή και του interrupt.
    Χρήση εσωτερικού χρονομετρητή. TOCS = 0

    Ο προδιαιρέτης (prescaler) ρυθμίζεται για τον TMR0. PSA = 0

    Τιμή προδιαιρέτη = 256 PS2 = 1


    PS1 = 1


    PS0 = 1

    Τιμή χρονομετρητή TMR0 = 0 ( 256 αυξήσεις ) TMR0 = 0

    Η τιμή 0ch (12) "φορτώνεται" στον καταχωρητή tm_cnt   TM_ADJ = TM_CNT



    Ρυθμίζεται η κατάσταση της EEPROM.

    Δήλωση της πρώτης διεύθυνσης της μνήμης EEPROM

    Δήλωση του μεγέθους των δεδομένων της EEPROM
    Ρυθμίζεται η κατάσταση του Interrupt.

    Ενεργοποίηση του interrupt στον  TMR0  T0IE = 1

    Ενεργοποίηση όλων των Interrupt. GIE = 1





Λειτουργία οδήγησης "φορτώματος" της οθόνης

;**************  Screen Load Process  *******************


    Επειδή το μήνυμα απεικονίζεται σε 128 Led (16 κολώνες x 8 στήλες), το σύνολο αυτών των Led ονομάζεται οθόνη.
    Η κατάσταση (αναμμένο - σβηστό) όλων των Led ρυθμίζεται από 16 ψηφιολέξεις (Bytes), της μνήμης Ram.
    Επειδή η πόρτα RB μπορεί να οδηγήσει μία μόνο στήλη (8 Led) κάθε φορά, η οδήγηση και των 128 Led γίνεται με μεγάλη ταχύτητα έτσι ώστε το ανθρώπινο μάτι να βλέπει το μήνυμα στην οθόνη κανονικό.  Η οδήγηση ξεκινά από την πρώτη από δεξιά στήλη και ολισθαίνει στην επόμενη προς τα αριστερά.
    Εάν αλλάξετε τα δεδομένα των 16 ψηφιολέξεων της μνήμης Ram που οδηγούν την οθόνη, το μήνυμα θα αλλάξει ανάλογα.
    Η οδήγηση κάθε στήλης Led γίνεται απευθείας από την πόρτα RB, ενώ η οδήγηση της κάθε μίας κολώνας γίνεται από την έξοδο της πόρτας RA (RA3-RA0) στην είσοδο του 74HC154  και την έξοδο του τελευταίου που οδηγεί το αντίστοιχο τρανζίστορ κάθε κολώνας.


    Για την οδήγηση της οθόνης χρησιμοποιείται η έμμεση προσπέλαση της μνήμης Ram.              
    Έτσι η προς προσπέλαση διεύθυνση μνήμης "φορτώνεται" στον καταχωρητή INDF.

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


     bcf     intcon,gie      ;Interrupt disable
    
     bsf     intcon,gie      ;Interrupt enable

     

    Ένα σημείο που πρέπει να προσέξετε είναι πως κατά την ανανέωση - οδήγηση της οθόνης, δεν πρέπει να υπάρξει παλμός διακοπής ροής προγράμματος (Interrupt).
    Όταν δημιουργηθεί παλμός διακοπής (interrupt), διακόπτεται προσωρινά η εκτέλεση του προγράμματος, και εκτελείται η υπορουτίνα του interrupt. Συνεπώς καταλαβαίνετε πως εάν υπάρξει interrupt κατά την ανανέωση της οθόνης, η ανανέωση θα σταματήσει για να εκτελεστεί η υπορουτίνα του interrupt, και έτσι η απεικόνιση του μηνύματος θα παρουσιάζει κενά. Το interrupt μπορεί να χρησιμοποιηθεί μόνο κατά την προετοιμασία της επόμενης οθόνης.





Λειτουργία διακοπής προγράμματος (Interruption)

;************  Begin Interruption Process  **************

    Στα μαθήματα για τον 16F84A είδατε πως διακοπή ροής προγράμματος δημιουργείται και όταν υπερχειλίζει ο χρονομετρητής. Μετά την διακοπή ροής, ο μετρητής προγράμματος (Program counter), δείχνει την διεύθυνση '0004h', την ίδια στιγμή το ψηφίο T0IF του καταχωρητή INTCON γίνεται '1', η διεύθυνση επιστροφής από την υπορουτίνα του interrupt αποθηκεύεται στον καταχωρητή σωρού (Status), και το ψηφίο GIE του καταχωρητή INTCON αυτόματα γίνεται '0' για να αποφευχθεί διπλό interrupt.

    Στη συνέχεια αποθηκεύονται τα περιεχόμενα των καταχωρητών W και STATUS.
    Πρώτα αποθηκεύεται το περιεχόμενο του καταχωρητή W γιατί θα χαθεί, κατά την αποθήκευση του περιεχομένου του STATUS, αφού ο πρώτος χρησιμοποιείται για την μεταφορά των δεδομένων από και προς τους καταχωρητές. 


    Τέλος γίνεται έλεγχος του είδους της διακοπής, ελέγχεται το ψηφίο  (T0IF) για time-out. Εάν δεν υπάρχει time-out και προκύψει interrupt η εκτέλεση του προγράμματος συνεχίζεται στην υπορουτίνα αρχικοποίησης "Initial Process".




Λειτουργία τερματισμού διακοπής (Interruption)

;************  END of Interruption Process **************

    Μόλις ολοκληρωθεί η ρουτίνα διακοπής (interruption), ο μετρητής προγράμματος επιστρέφει και εκτελεί τον κώδικα από το σημείο που είχε σταματήσει όταν συνέβη η διακοπή. 
    Το περιεχόμενο του καταχωρητή STATUS επαναφέρεται πρώτα και μετά του W, για το λόγο που αναφέραμε στη Λειτουργία παλμού διακοπής προγράμματος. 
    Για την επαναφορά του W, πρέπει να ακολουθήσετε την εξής διαδικασία:

    Επειδή το περιεχόμενο του STATUS αλλάζει εάν επαναφέρετε το W  με την εντολή MOVF, η επαναφορά πρέπει να γίνει με την χρήση της εντολής SWAPF, έτσι το περιεχόμενο που μόλις πριν επαναφέρθηκε στον STATUS παραμένει αναλλοίωτο. Παρατηρήστε πώς για την επαναφορά του W η εντολή SWAPF χρησιμοποιείται δύο φορές.
    Η ρουτίνα κλείνει με την εντολή RETFIE, η οποία επαναφέρει το τον μετρητή προγράμματος (Program counter) στο σημείο που ήταν πριν την διακοπή, επίσης κάνει '1' (ενεργοποιεί) το ψηφίο GIE του καταχωρητή INTCON. 



Λειτουργία διακοπής ροής προγράμματος από υπερχείλιση του χρονομετρητή 

;***********  Time-out interruption Process  ************

    Ο μέγιστος χρόνος που μπορεί να μετρηθεί από τον χρονομετρητή του PIC, ακόμα και με την χρήση προδιαιρέτη (Prescaler), είναι περίπου 26mSec (milliseconds), με κύκλωμα χρονισμού 10-MHz. Στη διάρκεια αυτού του χρόνου το μήνυμα ολισθαίνει (κυλάει) επάνω στην οθόνη. Εάν υποτεθεί πως χρησιμοποιούμε τα 26 mSec, τότε η ταχύτητα ολίσθησης του μηνύματος θα είναι, 16 κολώνες x 26mSec = 416mSec, η οποία είναι υπερβολικά γρήγορη (Θα μοιάζει σαν να ανάβουν όλα τα Led ταυτόχρονα). Στο παράδειγμα μας μετρούνται οι φορές που υπερχειλίζει (Time-out) ο χρονομετρητής (TMR0) και πολλαπλασιάζεται με τα 26mSec. Οι φορές που χρειάζεται να υπερχειλίσει ο χρονομετρητής (TMR0) μπορεί να ρυθμιστεί αλλάζοντας τιμή στην ετικέτα : tm_adj. Εάν η tm_adj έχει την τιμή 6 τότε το μήνυμα για να κυλήσει επάνω στην οθόνη θα κάνει χρόνο ίσο με 16 κολώνες x 26mSec x 6 interrupt time-outs= 2,496mSec, δηλαδή περίπου 2,5 δευτερόλεπτα. 

    Το ψηφίο T0IF του καταχωρητή INTCON γίνεται '1' (παράγεται interrupt) κάθε φορά που υπερχειλίζει ο χρονομετρητής. Προσέξτε, πως εάν δεν μηδενίσετε το ψηφίο T0IF εσείς μέσα από το πρόγραμμα, την επόμενη φορά που θα υπερχειλίσει ο χρονομετρητής δεν θα δημιουργηθεί interrupt.
    Επίσης πρέπει να ορίσετε ξανά τον αριθμό υπερχειλίσεων που θα μετρηθούν (για παράδειγμά η τιμή '6').

    Ο χρονομετρητής TMR0 μετρά πάντοτε θετικά (count up timer), υπερχειλίζει και παράγει διακοπή (interrupt), κάθε φορά που η τιμή του γίνεται από 255 (FFh) --> 0 (00h). Συνεπώς εάν θέλετε να κάνει 6 υπερχειλίσεις πρέπει να κάνετε την αφαίρεση 256 μετρήσεις (0 έως και 255 = 256) μείων 6 υπερχειλίσεις = 250, άρα σαν τιμή εκκίνησης του TMR0 πρέπει να δηλώσετε την τιμή 250. 

    Για χρονισμό 10-MHz, ο κύκλος μηχανής είναι 0,4μSec, εάν δηλωθεί τιμή προδιαιρέτη (prescaler) ίση με 256 ο μέγιστος χρόνος για μια υπερχείλιση θα είναι 256 μετρήσεις x 0.4 κύκλος μηχανής = 102.4 µsec.
    Για χρόνο ίσο με 20mSec θα έχουμε 20mSec / 0.1024 = 195 μετρήσεις δηλαδή η τιμή έναρξης του TMR0 θα είναι 256-195 = 61(3Dh).

    Για να μην μπερδεύεστε με πράξεις και κάνετε λάθος μπορείτε να χρησιμοποιήσετε το ΔΩΡΕΑΝ προγραμματάκι PIC TIMER που έχω φτιάξει. Aπλά εισάγετε τη συχνότητα του κυκλώματος χρονισμού (π.χ κρυστάλλου), και τον επιθυμητό χρόνο, πατήστε το κουμπί υπολογισμός και θα σας δείξει αμέσως την τιμή εκκίνησης του TMR0, την τιμή του προδιαιρέτη (prescaler), και των καταχωρητών πολλαπλασιασμού εάν χρειάζονται.






Λειτουργία ολίσθησης (κίνηση μηνύματος) οθόνης

;************  Screen data shift Process  ***************

    Σε κάθε υπερχείλιση του χρονομετρητή δημιουργείται μία διακοπή προγράμματος (Interrupt time-out), και γίνεται μία ολίσθηση του μηνύματος της οθόνης, από δεξιά προς αριστερά.
    Η ολίσθηση αυτή μετακινεί το μήνυμα μία κολώνα (κάθετη σειρά Led) αριστερά, ενώ εμφανίζει τον επόμενο χαρακτήρα στην πρώτη από δεξιά κολώνα.
    Πρώτα ολισθαίνει η δεύτερη κολώνα μια θέση αριστερά, μετά η τρίτη στη δεύτερη κ.ο.κ, συνολικά γίνονται 15 ολισθήσεις. Όπως προαναφέρθηκε για αυτή την λειτουργία χρησιμοποιείται έμμεση (Indirect) προσπέλαση της μνήμης. 

     



Λειτουργία ανάγνωσης δεδομένων από την EEPROM

;**************  New data write Process  ****************

    Μετά τις 15 ολισθήσεις έχει ολοκληρωθεί η απεικόνιση του μηνύματος. Το πρόγραμμα διαβάζει πάλι δεδομένα από την μνήμη EEPROM και ξεκινά την εμφάνιση του μηνύματος από την πρώτη δεξιά κολώνα ολισθαίνοντας προς την επόμενη αριστερά.


 


Για την ανάγνωση από την EEPROM χρησιμοποιούνται οι καταχωρητές, EEADR, EECON1, EEDATA.
Πρώτα ορίζεται η προς προσπέλαση διεύθυνση στον καταχωρητή EEADR, μετά πρέπει το ψηφίο RD του καταχωρητή EECON1 να γίνει '1' (έναρξη ανάγνωσης eeprom), μόλις ολοκληρωθεί η ανάγνωση το ψηφίο RD γίνεται αυτόματα '0' και τα δεδομένα που διαβάστηκαν από την μνήμη EEPROM αποθηκεύονται στον καταχωρητή EEDATA. Οι διευθύνσεις της EEPROM που μπορείτε να προσπελάσετε είναι από την '00'h έως '3f'h και στο σύνολο τους αποτελούν 64 ψηφιολέξεις (bytes).

Προσοχή! η πρώτη διεύθυνση της EEPROM για προσπέλαση μέσα από το πρόγραμμα είναι η '00'h και όχι η '2100'h. Η τελευταία δηλώνεται με την ψευδοεντολή org και χρησιμοποιείται για να εγγραφούν δεδομένα στην EEPROM κατά την μεταφορά του μεταγλωττισμένου κώδικα στον μικροεπεξεργαστή.
  movwf   eeadr           ;Ορισμός διεύθυνσης EEPROM 
  bsf     status,rp0      ;Αλλαγή σε Bank1
  bsf     eecon1,rd       ;Έναρξη ανάγνωσης
  bcf     status,rp0      ;Αλλαγή σε Bank0
  movf    eedata,w        ;Μεταφορά περιεχομένων του EEDATA στον W


    Τα δεδομένα που διαβάστηκαν από την πρώτη διεύθυνση της μνήμης EEPROM μεταφέρονται στην PORTB όπου και οδηγούν τα Led της πρώτης από δεξιά κολώνας, γίνεται μία ολίσθηση προς αριστερά, διαβάζεται η επόμενη διεύθυνση και ο κύκλος επαναλαμβάνεται έως ότου ολόκληρο το μήνυμα απεικονιστεί στην οθόνη.




Τέλος κώδικα

;********************************************************
;          END of signboard control processing
;********************************************************

        end

    Στο τέλος του κώδικα πάντα πρέπει να υπάρχει η ψευδοεντολή END, προσέξτε εάν λείπει δεν θα γίνει η μεταγλώττιση.