#include #byte PORTB =0xF81 #byte PORTC =0xF82 #byte PORTD =0xF83 // Ορισμοί μεταβλητών int8 des=0; //Μεταβλητή για επιλογή ενδείκτη 7 τομέων //από τον πίνακα int8 dig[3] μέσω της πόρτας C int8 seconds=0; //Μεταβλητή για την μέτρηση των δευτερολέπτων int8 minute=0; //Μεταβλητή για την μέτρηση των ωρών int8 hour=12; //Μεταβλητή για την μέτρηση ωρών int8 counter=200; //Μεταβλητή για την μέτρηση διακοπών int1 flag=0; //Μεταβλητή για επιλογή εμφάνισης ωρών ή λεπτών //Πίνακας για εμφάνιση των ψηφίων στους ενδείκτες int8 table[16] = { 0b00111111, //0 0b00000110, //1 0b01011011, //2 0b01001111, //3 0b01100110, //4 0b01101101, //5 0b01111101, //6 0b00000111, //7 0b01111111, //8 0b01101111, //9 0b01101011, //Ω //Ω Σύμβολο για την ώρα 0b00110111, //Π //Π Σύμβολο για τα λεπτά }; int8 dig[3] = {1,2,4}; //Πίνακας για ενεργοποίηση ενός μόνο ενδείκτη από την //πόρτα C. Η πόρτα C εφαρμόζει 5V στην βάση ενός μόνον //από τα τρία τρανζίστορ που συνδέουν την κοινή κάθοδο //των ενδεικτών προς την γη. //1 => 0000 0001, 2 => 0000 0010, 4 => 0000 0100 // Δήλωση συναρτήσεων void timer0_int(void); void init (void); //Κύρια συνάρτηση void main() { init(); while (1){ // Το κύριο πρόγραμμα δεν κάνει τίποτα. // Περιμένει να συμβεί μια διακοπή } } // Ορισμός ρουτινών // Ρουτίνα διακοπών #INT_TIMER0 HIGH // Διακοπή με μεγάλη προτεραιότητα void timer0_int(void){ int16 mon,dec,eka; //μεταβλητές για εμφάνιση ψηφίων //στους ενδείκτες 7 τομέων set_timer0(5536); // αρχική τιμή του μετρητή για να συμβαίνουν //διακοπές κάθε 5 ms counter--; //Ο μετρητής ελαττώνεται κατά 1 και μηδινίζεται // κάθε 200 * 5 msec = 1 sec if (counter == 0){ seconds++; // Αυξάνεται ο μετρητής δευτερολέπτων κατά 1 κάθε // 1 δευτερόλεπτο counter = 200; // Αρχική τιμή του μετρητή διακοπών ώστε να μηδενίζεται // μετά από 200 διακοπές δηλαδή μετά από 1 δευτερόλεπτο //διότι 200 * 5 msec = 1 sec flag^=1; // Ισοδυναμεί με το flag=flag^1. // Σημαία που χρησιμοποιείται για να εμφανιστούν οι // ώρες ή τα λεπτά if (seconds > 59){ seconds = 0; // μετά την τιμή 59 ο μετρητής δευτερολέπτων παίρνει // την τιμή 0 minute++; //Αν περάσουν 60 δευτερόλεπτα αυξάνει ο μετρητής // λεπτών κατά 1 if (minute > 59){ minute = 0; hour++; //Αν περάσουν 60 λεπτά αυξάνει ο μετρητής ωρών κατά 1 } if (hour >24){ hour = 0; //Αν περάσουν 24 ώρες ο μετρητής ωρών γίνεται 0 } } } if (flag == 0){ //αν το flag=0 τότε εμφανίζονται τα λεπτά dec = (int8)minute / 10; //Υπολογίζονται οι δεκάδες των λεπτών mon = minute - dec * 10; //Υπολογίζονται οι μονάδες των λεπτών eka = 11; // Στο 11ο στοιχείο το πίνακα int8 table[16] αντιστοιχεί // το σύμβολο για τα λεπτά "Π" // Το σύμβολο αυτό θα εμφανιστεί στον πρώτο από αριστερά // ενδείκτη(των εκατοντάδων) } if (flag == 1){ //Αν το flag είναι 1 τότε εμφανίζονται οι ώρες dec = (int8)hour / 10; // υπολογισμός των δεκάδων των ωρών mon = hour - dec * 10; // υπολογισμός των μονάδων των ωρών eka = 10; //Στο 10ο στοιχείο το πίνακα int8 table[16] // αντιστοιχεί το σύμβολο για την ώρα, "Ω" // Το σύμβολο αυτό θα εμφανιστεί στον πρώτο από αριστερά // ενδείκτη(των εκατοντάδων) } des = ++des%3; /* Η μεταβλητή αυτή παίρνει διαδοχικά τις τιμές 0, 1, 2, 0, 1, 2, 0, 1, … ώστε να επιλέγονται από τον πίνακα dig[des] διαδοχικά οι τιμές … 0000 0001, 0000 0010, 0000 0100 … και να ενεργοποιούνται με την σειρά οι ενδείκτες */ PORTC = dig[des]; if (des==0){ PORTB = table[mon]; // εμφανίζονται οι μονάδες της ώρας ή των λεπτών } if (des==1){ PORTB = table[dec]; // εμφανίζονται οι μονάδες της ώρας ή των λεπτών } if (des==2){ PORTB = table[eka]; // εμφανίζεται ή ένδειξη ώρας "Ω" ή λεπτών "Π" } } // Ρουτίνα αρχικοποίησης void init (void){ set_tris_b(0x00); // Καθορισμός της πόρτας Β ως εξόδου set_tris_c(0x00); // Καθορισμός της πόρτας C ως εξόδου PORTB = 0; // αρχική τιμή της πόρτας Β PORTC = 0; //αρχική τιμή της πόρτας C counter = 200; // Αρχική τιμή του counter seconds = 0; // Αρχική τιμή του μετρητή δευτερολέπτων minute =0; // Αρχική τιμή του μετρητή λεπτών hour = 12; // Αρχική τιμή του μετρητή ωρών des =0; // Αρχική τιμή της μεταβλητής για επιλογή ενδείκτη flag = 0; //Αρχική τιμή της μεταβλητής για εμφάνιση ώρας ή λεπτών SETUP_TIMER_0(T0_INTERNAL | T0_DIV_1 ); // Ρύθμιση prescaler=1 set_timer0(5536); // Αρχική τιμή του timer0 enable_interrupts(INT_TIMER0); // Ενεργοποίηση διακοπών από τον timer0 enable_interrupts(GLOBAL); // Ενεργοποίηση του γενικού διακόπτη των διακοπών }