# Συζήτηση Κυκλωμάτων > Ψηφιακά Κυκλώματα > Μικροελεγκτές >  >  συχνομετρο με PIC και  Microbasic

## billtech

παιδια θελω να κανω ενα συχνομετρο με PIC και προγραμματισμο στη Microbasic.
εχει κανεις καποιο σχεδιο υποψιν του?
εχει ασχοληθει κανεις με κατι παρομοιο για να με βοηθησει λιγο?
και στον κωδικα?
τι τυποι χρειαζονται για την μετρηση συχνοτητας?
οτι ξερει κανεις για να με βοηθεισει τον ευχαριστω.

ΥΓ: τελευταια χασαμε τον φιλο DT200.που πηγε το παιδι?που χαθηκε?εχει κανεις νεα του?

----------


## HFProject

κάτι γρήγορο :
1

άλλο :

2

----------


## billtech

φιλε μου καταρχας σε ευχαριστω για την απαντηση σου.
εγω θελω να το κανω εγω.δηλαδη να μην παρω κατι ετοιμο και να το κανω.
γιαυτο ειπα για βοηθεια απο εδω.
με δικο μας κυκλωμα, δικο μας κωδικα που μεσα θα βαλουμε τους τυπους που χρειαζονται αναλογος με το κυκλωμα που θα κανουμε.
δηλαδη ας πουμε ρε παιδι μου πως δουλευουν τα συχνομετρα?ποια ειναι η θεωρια τους?με βαση ποια θεωρια μπορω να κανω ενα συχνομετρο?

----------


## HFProject

Διάβασε τον κώδικα και θα καταλάβεις.

----------


## VaGyver

Καλησπέρα φίλε μου,

Εγώ θα σου πρότεινα να φτιάξεις κατευθείαν αυτό το συχνόμετρο (0-50 ΜΗΖ) με υλικά τσάμπα.
http://www.piclist.com/techref/piclist/weedfreq.htm

Το έχω φτιάξει και δουλεύει ΕΞΑΙΡΕΤΙΚΑ, άσε που είναι και auto-scale.
(Οπότε θα έχεις κάτι που θα παίζει σωστά και μετά πειραματίζεσαι).


Αν θέλεις να 'παίξεις' με κώδικα (τότε εκτός τις λύσεις του HF) και εφόσν γνωρίζεις τα βασικά από assembly, τότε θα σου πρότεινα να κάνεις ότι και εγώ.

Δηλαδή αρχικά να πάρεις ή βρεις ή φτιάξεις μία ρουτίνα μέτρησης σε assembly (που μόνο εκεί τελικά υπάρχει ακρίβεια).
Εγώ τελικά κατέληξα και πήρα την ρουτίνα μέτρησης του παραπάνω συχνομέτρου που είναι Super.
Mετά έφτιαξα το δικό μου συχνόμετρο, με τα δικά μου μενού.
Σου προτείνω να κάνεις το ίδιο.

Δυστυχώς εγώ έχω σαν compiler τον Proton+ για να σου δώσω κάτι έτοιμο.
Εσύ θα το δουλέψεις με τον δικό σου compiler.


Βέβαια αν ξεκινάς ΑΠΟΛΥΤΩΣ από το μηδέν (π.χ. δεν ξέρεις καν την αρχή λειτουργίας τους) τότε φαντάζομαι έχεις δουλειά μπροστά σου.

----------


## VaGyver

Πληροφορίες/manual για το ίδιο κύκλωμα (επείδή το πουλάνε και σαν kit).

http://www.invent-electronics.com/pd...ter_Manual.pdf

----------


## savnik

> Δυστυχώς εγώ έχω σαν compiler τον Proton+ για να σου δώσω κάτι έτοιμο.



Αν σου είναι εύκολο ανέβασε τον κώδικα.

----------


## billtech

τωρα χαθηκα....
θελω να ξεκινησω απο την αρχη...
αλλα θελω να εχω λιγη βοηθεια..αλλιως θα κανω ενα που προτινετε και δουλευει και μετα θα κατσω να καταλαβω πως δουλευει...
επειδη εγω θελω να το κανω σε microbasic.

----------


## HFProject

Οι PIC έχουν κάποιες δυνατότητες,

Το πρόγραμμα κάνει την υπόλοιπη δουλειά.

Διάβασε το 2ο link από αυτά που σου έστειλα. Μελέτησε των κώδικα.

Η βοήθεια που θες βρίσκεται στο data sheet του pic

----------


## Τρελός Επιστήμονας

Παιδιά, πρόσφατα κατασκεύασα αυτό: http://ironbark.bendigo.latrobe.edu....wfm/newfm.html
και σκίζει!!!

----------


## billtech

Μου εξηγας φιλε Δημητρη στα ελληνικα για το πηνιο? πως το εκανες?τι εκανες με αυτο?

----------


## Τρελός Επιστήμονας

Φίλε Βασίλη, δεν έβαλα το πηνίο (έβαλα στη θέση του βραχυκύκλωμα) αλλά αν ψάξεις βρίσκεις πηνιάκι 10 μΗ. Αντί για το BFR91 έβαλα στη θέση του το 2Ν3904 που το έχω πρόχειρο και δούλεψε μέχρι 45MHz περίπου. Η αντίσταση βάσης (πόλωσης) του τρανζίστορ είναι 47 kΩ. Επίσης δεν έβαλα το jumper στο pin18 του ολοκληρωμένου διότι δεν υπάρχει πρόβλημα αλλαγής γραμμής στην οθόνη 1Χ16 που έχω. Ευθυγράμμισα το συχνόμετρο (σύμφωνα με τη διαδικασία του άρθρου) με τον πομποδέκτη μου  ο οποίος έχει ταλαντωτή ακριβείας με "φουρνάκι" και είναι καλιμπραρισμένος με τον σταθμό πρότυπης συχνότητας WWV. Το αποτέλεσμα: σφάλμα μικρότερο από +/- 10 Hz στους 10MHz!
Αν βάλεις το πηνίο και το BFR91, σίγουρα θα μετράς μέχρι 50MHz. 
Επίσης, τον πυκνωτή εισόδου από 1μF τον έκανα 100nF γιατί δεν ενδιαφέρομαι για μετρήσεις χαμηλών συχνοτήτων.

Edit: Τελικά τοποθέτησα το βραχυκυκλωτήρα (jumper) από τον ακροδέκτη 18 προς τη γη και μου εμφάνισε κάποιες ενδείξεις που δεν φαίνονταν (πχ MHz ή την ένδειξη USB/LSB).

----------


## billtech

φιλε μου σε ευχαριστω.θα κανω αυτο τωρα να εχω να κανω καμια δουλεια και μετα θα προσπαθησω να το κανω και μονος μου σε Microbasic.

----------


## billtech

μπορει καποιος να με βοηθεισει με τον pic? λογω του οτι δεν ειμαι και τοσο καλος στα αγγλικα προσπαθησα να διαβσαω το datasheet του pic16f84a αλλα δεν βρηκα πως θα μετραω τους παλμους.
και οπως ειχα πει προσπαθω να μαθω τους pic μονος μου τωρα βρηκα ζορια.
και δεν θελω να κανω μια κατασκευη ετοιμη.
προτιμω να την παλεψω μονος μου.

----------


## DT200

εγώ ήθελα να μετράω την συχνότητα της ΔΕΗ και έκανα κάτι απλό , 
έγραψα ένα κώδικα που κάνει το εξής 

περιμένει να έρθει ο παλμός,
μετά περιμένει να πέσει και αφού συμβεί αυτό (η πτώση) τότε ενεργοποιώ 
τον Timer 1. (αυτό το κάνω για να συγχρονιστώ με το σήμα)  

με τον Timer 1 να μετράει αυτόματα από τον κρύσταλλο, ο μ/ε "κοιτάζει"
πότε ο παλμός θα ξανά γίνει θετικός αλλά δεν κάνει τίποτα.

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

βέβαια, δεν είναι το ποιο σωστό αλλά έχω κάνει άλλους τρεις συνδυασμούς 
και ο ένας με interrupt.

καλή τύχη.

----------


## billtech

πρεπει να κατσω να διαβασω λιγο για τον timer του pic μου.
και θα επανελθω. μεχρι ποση συχνοτητα μπορει να μετρησει ετσι?
δεν πολυκαταλαβα αυτο οπως μου το εξηγησες αλλα πριν σε πριξω να κατσω να διαβασω τους timers και μετα..οτι καταλαβω βεβαια...

----------


## lastid

Υπάρχουν δύο τρόποι για να μετρήσουμε συχνότητα. Τους περιγράφω γενικά χωρίς να αναφέρομαι σε συγκεκριμένο PIC:
*1) Χαμηλές συχνότητες (ο τρόπος του DT200)*
- Περιμένουμε την έναρξη του παλμού και ενεργοποιούμε τον timer ο οποίος αρχίζει να μετράει μόνος του πλέον από το 0 και με συγκεκριμένη συχνότητα.
- Περιμένουμε την λήξη του παλμού και τότε σταματάμε τον timer.
- Διαβάζουμε την τιμή του timer η οποία ουσιαστικά αντιστοιχεί στην περίοδο Τ (και όχι την συχνότητα) f του σήματος. Αν θέλουμε να δείξουμε τη συχνότητα, τότε f = 1/T.
*2) Υψηλές συχνότητες*
- Προετοιμάζουμε έναν counter ώστε να μετρά εξωτερικούς παλμούς από μία είσοδο του PIC.
- Προετοιμάζουμε έναν timer ώστε να μετράμε χρόνο (με interrupts ή όχι). 
- Μηδενίζουμε τον counter και αρχίζουμε να μετράμε χρόνο.
- Περιμένουμε να περάσει ένα συγκεκριμένο διάστημα (π.χ. 0.1sec ή 1sec κλπ), οπότε διαβάζουμε την τιμή του counter που είναι ανάλογη της συχνότητας.

Αυτά είναι τα βασικά. 
Η περιοχή συχνοτήτων που μπορεί να μετρήσει η κάθε μέθοδος εξαρτάται από τον PIC και την συχνότητα του ρολογιού του. Συνήθως οι δύο περιοχές επικαλύπτονται σε ένα μικρό τμήμα τους.
Μπορούμε τώρα να κάνουμε το κύκλωμα ώστε να μπορούν να χρησιμοποιηθούν και οι δύο μέθοδοι. Ποια μέθοδος θα επιλέγεται? Το πρόγραμμα δοκιμάζει την μία από τις δύο και αν δει ότι η μέτρηση είναι εκτός κλίμακας δοκιμάζει την άλλη. Μπορούμε έτσι να επιτύχουμε και ένα ωραίο auto range.
Επιπλέον, μπορεί να μπει και ένας διαιρέτης συχνότητας (προαιρετικά ή πάντα ενεργός) για να μετράμε συχνότητες αρκετά μεγαλύτερες από 50 ΜΗz.

----------


## billtech

ωραιο πολυ οπως το λες φιλε μου..
αλλα εγω οπως ειπα μονος μου μαθαινω τους PIC και την Microbasic.
ολα αυτα ου ειπες ναι πολυ ωραια και γουσταρω να ασχοληθω.ομως μονος μου ειναι πολυ δυσκολο. συν το προβλημα οτι δεν ειμαι και expert στα αγγλικα.
οπως το ειπες ειναι πολυ καλο συχνομετρο ετσι.αλλα σαν ιδεα για μενα..σαν υλοποιηση ειναι δυσκολο.
θελω αρκετη βοηθεια.μεχρι να μαθω να προγραμματιζω τοσο καλα οσο εσεις τους PIC.
δηλαδη ας πουμε απο που θα ξεκινησω? στο κωδικα..μεχρι να μπω στο κλιμα σιγα σιγα...

----------


## lastid

Μπορεί να σου τα περιέγραψα πολύ γενικά και να μην ξέρεις από πού να αρχίσεις. Αν είναι έτσι, η μέθοδος είναι να σπας το πρόβλημά σου σε μικρότερα.
Παράδειγμα:
Ας πούμε ότι εγώ λέω: "Περιμένουμε την έναρξη του παλμού και ενεργοποιούμε τον timer".
Εσύ σκέφτεσαι: Πως περιμένουμε την έναρξη του παλμού? 
Προκειμένου λοιπόν να μάθεις να κάνεις το πρόγραμμά σου πως να περιμένει ώστε μία είσοδος να γινει 1 από 0, διαβάζεις το datasheet του PIC, ρωτάς άλλους, βλέπεις παραδείγματα, πειραματίζεσαι και προχωράς.
Αφού το καταφέρεις, προχωράς στο επόμενο. Τί είναι ο timer μέσα στον PIC? Πως τον ενεργοποιούμε ώστε να μετράει μόνος του? Πως προγραμματίζουμε τη συχνότητά του? Πως τον διαβάζουμε? Και ούτω καθεξής.
Εαν όπως λες έχεις πρόβλημα στα Αγγλικά, θα χρειαστεί να αφιερώσεις περισσότερο χρόνο. Εαν κολλάς κάπου, ρωτάς. Όσο πιο συγκεκριμένη και απλή είναι η ερώτησή σου, τόσο πιο γρήγορα θα πάρεις απάντηση. 
Έτσι σιγά σιγά θα δεις και πολύ μεγάλη βελτίωση στα Αγγλικά σου, τουλάχιστο όσον αφορά την Αγγλική τεχνική ορολογία. Κανείς μας (πιστεύω) δεν έμαθε να διαβάζει datasheets στο σχολείο ή στο φροντιστήριο Αγγλικών. Την πρώτη φορά που διάβασα datasheet δεν κατάλαβα τίποτε. Θέλει λίγη προσπάθεια, εφόσον λες ότι γουστάρεις να ασχοληθείς. Αυτό είναι και το βασικότερο. Τα υπόλοιπα μην τα φοβάσαι. Όπως έλεγε ο παππούς μου, "το μάτι φοβάται, το χέρι δεν φοβάται".

----------


## billtech

πρωτα απο ολα πρεπει να καταλαβω πως ενεργοποιειται ο timer σωστα?
απο το datasheet καταλαβα οτι:
τον T0CS τον κανουμε 1 για να γινει counter 
και τον T0SE τον κανουμε 0 για να μετραμε στη αρχη του παλμου και 1 οταν πεσει ο παλμος.
δηλαδη ωραια με ενα if πεσει ο παλμος ξεκινα να ξεκινα ο timer. πως ξεκινα?
τον INTCON πρεπει πρωτα να κανω το bit5 1?

----------


## lastid

> τον T0CS τον κανουμε 1 για να γινει counter
> και τον T0SE τον κανουμε 0 για να μετραμε στη αρχη του παλμου και 1 οταν πεσει ο παλμος.



Σωστά. Τα παραπάνω τα βλέπουμε συνοπτικά και στο Figure 4.1 του datasheet για τον 16F84A.




> τον INTCON πρεπει πρωτα να κανω το bit5 1?



To bit 5 του INTCON (Τ0ΙΕ) ενεργοποιεί το interrupt λόγω overflow του Timer0. Όμως εσένα δεν σε ενδιαφέρει το overflow. Δεν θέλεις να κάνεις κάτι μόλις ο Timer0 περάσει από 255 σε 0. Θέλεις να μετρήσεις χρόνο (αλλιώς) και στο τέλος του χρόνου να διαβάσεις την τιμή του timer0. Και επειδή ο timer0 έχει δεσμευτεί να λειτουργεί σαν counter, πρέπει να βρεις άλλον τρόπο να μετρήσεις χρόνο.
Θα σου έλεγα να μετρήσεις χρόνο εκτελώντας ένα loop στο πρόγραμμά σου που είναι και το πιο απλό. Όμως για να μην παιδεύεσαι, καλύτερα να πας σε άλλον μικροελεγκτή, που θα έχει τουλάχιστο δύο timers: Τον έναν τον έχεις για counter και με τον άλλον μετράς χρόνο. Επιπλέον θα μπορείς να έχεις 16-bit timers, σε σχέση με τον 8-bit timer0 του 16F84A

----------


## billtech

απλα επειδη ειδα οτι γινετε με αυτον.και επειδη δεν εχω και πολλους αλλους ειπα να χρησιμοποιεισω αυτον.

----------


## lastid

Τότε κάνεις μέτρηση χρόνου εκτελώντας ένα απλό loop μερικές χιλιάδες φορές, έχοντας υπολογίσει θεωρητικά το χρόνο εκτέλεσής του. Είναι το πιο απλό.
Το interrupt τώρα που προκαλείται από overflow του timer0 μπορείς να το χρησιμοποιήσεις για να τον επεκτείνεις σε περισσότερα από 8 bits. Μόλις εκτελείται, θα αυξάνεις μία μεταβλητή που θα είναι τα ψηλά 8 (ή 16 ή 24 ή ...) bits του counter σου. Αν θέλεις για αρχή, μπορείς να το παραλείψεις. Κάνεις ένα πρόγραμμα που δουλεύει για χαμηλές σχετικά συχνότητες χωρίς interrupt και κατόπιν βλέπεις.
Όλα αυτά βέβαια για τον 2ο τρόπο (υψηλές συχνότητες).
Ελπίζω να μην τα είπα πολύ μπερδεμένα  :Rolleyes:

----------


## billtech

οι δα μωρε....εγω ζαλιστηκα...χεχε

----------


## savnik

> Τότε κάνεις μέτρηση χρόνου εκτελώντας ένα απλό loop μερικές χιλιάδες φορές, έχοντας υπολογίσει θεωρητικά το χρόνο εκτέλεσής του. Είναι το πιο απλό.
> Το interrupt τώρα που προκαλείται από overflow του timer0 μπορείς να το χρησιμοποιήσεις για να τον επεκτείνεις σε περισσότερα από 8 bits. Μόλις εκτελείται, θα αυξάνεις μία μεταβλητή που θα είναι τα ψηλά 8 (ή 16 ή 24 ή ...) bits του counter σου. Αν θέλεις για αρχή, μπορείς να το παραλείψεις. Κάνεις ένα πρόγραμμα που δουλεύει για χαμηλές σχετικά συχνότητες χωρίς interrupt και κατόπιν βλέπεις.
> Όλα αυτά βέβαια για τον 2ο τρόπο (υψηλές συχνότητες).
> Ελπίζω να μην τα είπα πολύ μπερδεμένα



Πολύ καλά τα είπες ,αλλά για έναν αρχάριο αυτά φαίνονται βουνό ( έκανα πολλούς μήνες μέχρι να τα κατανοήσω).
Καλύτερα όμως , αφού θέλεις να τον βοηθήσεις να του δίνεις και παραδείγματα (δεν νομίζω όμως να είναι σε microbasic , που έχει ασχοληθεί).

----------


## savnik

Η πιο απλή λύση  είναι:
Ρυθμίζεις τον ΤΙΜΕR0 σαν COUNTER και βάζεις την ανάλογη τιμή στον Prescaler.
Κάνεις είσοδο την PORTA.4 για 1 ms , μετά την κάνεις έξοδο και μετράς το περιεχόμενο του ΤΙΜΕR0 και του Prescaler.

----------


## lastid

> Πολύ καλά τα είπες ,αλλά για έναν αρχάριο αυτά φαίνονται βουνό ( έκανα πολλούς μήνες μέχρι να τα κατανοήσω).
> Καλύτερα όμως , αφού θέλεις να τον βοηθήσεις να του δίνεις και παραδείγματα (δεν νομίζω όμως να είναι σε microbasic , που έχει ασχοληθεί).



Επειδή δεν γράφω σε microbasic, έκανα ότι καλύτερο μπορούσα στο χρόνο που είχα: Του δείχνω το στόχο. 
Σίγουρα γεννιούνται απορίες, αλλά αυτό είναι καλό πιστεύω. 
Να δώσω και μία συμβουλή που εμένα τουλάχιστο με βοηθάει: Πριν προσπαθήσουμε να καταλάβουμε μία πρόταση, βεβαιωνόμαστε ότι κατανοούμε τις λέξεις. Αργά και σταθερά, χωρίς άγχος.

----------


## billtech

μπορει καποιος να κανει ενα διαγραμμα ροης?νομιζω θα με βοηθεισει.
καθομαι τωρα και προσπαθω να καταλαβω τους Timers.

----------


## briko

κατ'αρχας κατεβασε το 
http://pictimer.picbingo.com/
ειναι free
 για 1sec timer εγω εφτιαξα
sub procedure interrupt 






```
sub procedure interrupt
 TMR0L = 247         ' l kai h for tmr0 1 sec 
  TMR0H = 194 
  INTCON.TMR0IF = 0   ' reset and start TMR0 interrupt cycle 
 end sub 


main: 

T0CON = $86           'T0CON.TMR0ON = 1;  ; Timer0 On/Off Control bit:             1=Enables Timer0 / 0=Stops Timer0 
                      'T0CON.T08BIT = 0;  ; Timer0 8-bit/16-bit Control bit: 1=8-bit timer/counter / 0=16-bit timer/counter 
                      'T0CON.T0CS   = 0;  ; TMR0 Clock Source Select bit: 0=Internal Clock (CLKO) / 1=Transition on T0CKI pin 
                      'T0CON.T0SE   = 0;  ; TMR0 Source Edge Select bit: 0=low/high / 1=high/low 
    '  =86            'T0CON.PSA    = 0;  ; Prescaler Assignment bit: 0=Prescaler is assigned; 1=NOT assigned/bypassed 
                      'T0CON.T0PS2  = 1;  ; bits 2-0  PS2:PS0: Prescaler Select bits 
                      'T0CON.T0PS1  = 1; 
                      'T0CON.T0PS0  = 0; 
   INTCON = $A0          ' initialize and enable TMR0 
   TMR0L =247        '   l kai h for tmr0 1 sec 
   TMR0H =194 
  
  INTCON.TMR0IF = 0     ' start TMR0 interrupt cycle
```

----------


## billtech

το κατεβασα αυτο..απο παλια..
τι ειναι αυτο που αναιβασες?

----------


## briko

καθε 1 sec τρεχει την υπορουτινα

----------


## billtech

το θεμα μου ειναι να τους καταλαβω.
δηλαδη εγω θα περνω τους παλμους απο ενα ποδαρακι του επεξεργαστη.απο εκει και περα τι θα πρεπει να κανω.

----------


## lastid

Ποια περιοχή συχνοτήτων θέλεις να μετράς?

----------


## billtech

ξερω εγω..αμα ειναι να το κανουμε να το κανουμε απο 1Hz-50MHz.
οσο παει βασικα

----------


## briko

Καταρχάς δεν μπορώ να σε βοηθήσω μέχρι το τέλος – δεν έχω προς το παρόν τόσες γνώσεις 

Α: Πρέπει να μάθεις να φτιάχνεις την υπορουτινα να έχει ένα συγκεκριμένο χρόνο πχ 1sec η 0,1sec
B: μετά έχουμε κάποια πόρτα του PIC η οποία θα είναι η είσοδος εκεί δηλαδή θα πηγαίνει το σήμα (τετραγωνικός παλμός κατά προτίμηση) 
Γ: μέσα στηn υπορουτινα θα ανοίγουμε την πόρτα και για όσο χρονικό διάστημα έχουμε επιλέξει, θα μετρήσει τους παλμούς 
Δ: εκτυπώνουμε τους παλμούς στην οθόνη και μηδενίζουμε 
Χοντρά χοντρά αυτό είναι ένα συχνομετρο
Φυσικά υπάρχει και ένα μυστικό :
Αυτό είναι ο χρόνος ανοίγματος – εάν το ρυθμίσουμε για 1 sec τότε μαζί με τις άλλες γραμμές προγράμματος υπερβαίνει το 1 sec όποτε πρέπει να υπολογίσουμε και αυτές και να αφαιρέσουμε τον χρόνο τους από το 1 sec

----------


## savnik

> ξερω εγω..αμα ειναι να το κανουμε να το κανουμε απο 1Hz-50MHz.
> οσο παει βασικα



Τότε πρέπει να μετράς και το overflow του timer οπότε γίνεται πολύπλοκο.
Για αρχή δούλεψε μόνο με τον timer0 που είναι 8 bit και με κρύσταλο 4 ΜHZ θα μετράς μέχρι το 255.

----------


## billtech

σε ευχαριστω φιλε μου για την βοηθεια..
αλλα οπως ειπα προσπαθω να καταλαβω καλα τους timers.
ειδικα το Α και το Γ που εβαλες μου φενονται βουνα.

----------


## billtech

λοιπον παιδια...
εκατσα και παλεψα σημερα ολη μερα που ειχα χρονο το datasheet του PIC16F84A και προσπαθησα να καταλαβω τους REGISTERS που πρεπει να πρησιμοποιεισουμε..
δηλαδη τον OPTION REGISTER,INTCON REGISTER 
οπως επισης και τον καταχωρητη TMR0.
τα διαβασα αυτα αλλα δεν τα πολυ καταλαβα να πω την αληθεια.και ισως να φταιει που δεν μπορω να σκεφτω πως θα συνδεθουν ολα αυτα μεταξυ τους και με τα εξαρτηματα και με τον υπολοιπο κωδικα ωστε να γινει το συχνομετρο.

----------


## lastid

Ας ξεκινήσουμε λοιπόν από κάτι απλό που χρειαζόμαστε: Μέτρηση χρόνου.
Ας φτιάξουμε μαζί σε microbasic μία υπορουτίνα καθυστέρησης που να εκτελείται σε ένα δευτερόλεπτο. Θα το κάνουμε όχι με timers ή άλλα καλούδια αλλά με τον παραδοσιακό τρόπο: Εκτελώντας μία ανώφελη εντολή πολλές φορές.
Για να δοκιμάσουμε την υπορουτίνα μας, θα συνδέσουμε ένα led σε μία έξοδο του PIC και θα φτιάξουμε ένα προγραμματάκι όπου:
- Θα καλείται η υπορουτίνα
- Θα αλλάζει η κατάσταση του led (από σβηστό αναμμένο και από αναμμένο σβηστό)
... και ξανά πάλι από την αρχή.
Έτσι, θα έχουμε οπτική επιβεβαίωση ότι η υπορουτίνα μας δουλεύει σωστά μια και θα βλέπουμε ένα led που θα αναβοσβήνει κάθε δύο δευτερόλεπτα.
Το να φτιάξεις μία υπορουτίνα καθυστέρησης 1sec δεν είναι και το πιο εύκολο. Πρώτα λοιπόν φτιάξε μία υπορουτίνα καθυστέρησης οποιοδήποτε χρόνου! Δηλαδή κάνε την στην τύχη και όσο σου βγει ο χρόνος εκτέλεσής της. 
Αφού την γράψεις, μην τρέξεις τίποτε ακόμη. Δημοσίευσέ την μόνο εδώ για να την συζητήσουμε.
Θα μπορούσα να σου δώσω εγώ μία υπορουτίνα, όμως έτσι θα χάσουμε το νόημα αυτού που πάμε να μάθουμε. Και επιπλέον θέλω να δώ σε τί επίπεδο είσαι ώστε να προσαρμόσω τη συζήτηση.
Αν έχεις κάποιο πρόβλημα στο να την γράψεις  ή αν βλέπεις ότι παιδεύεσαι αλλά δεν ξέρεις από που να αρχίσεις, πες το. Να θυμάσαι πάντα ότι υπάρχουν πολλοί τρόποι για να γίνει μία τέτοια ρουτίνα καθυστέρησης.

----------


## billtech

εκανα κατι..δεν ξερω αν καταλαβα καλα τι εννουσες και αν εκανα αυτο που περιεμενες...



```
program sixnometro

main:
 TRISB=%00000000
 PORTB=1
 
START:delay_ms(1000)
      goto E1
      goto start
      
E1:   portb=not(portb)
      goto start
      end.
```

----------


## briko

αλλο πραγμα το delay και αλλο το timer με το delay καθυστερει σε νεκρο χρονο ο PIC και με το timer μπορεις να τρεχεις ενα προγραμμα
και οταν ερθει η στιγμη τοτε να τρεξει η υπορουτινα interupt

----------


## billtech

ναι φιλε μου.αυτο ας πουμε που ειπες τωρα δεν το ηξερα.
δεν ξερω καθολου τους timers. αν δειτε τους PIC εδω μεσα τους εμαθα λιγακι με τις ασκησεις και τη μεγαλη βοηθεια του DT200.οσα ξερω ειναι αυτα.
γιαυτο τωρα εψαξα βοηθεια εδω.γιατι θελω να μαθαινω κιολας τιποτα.οχι απλα παρε βαλε.αλλα και μονος μου τελειος δεν μπορω.δεν εξω τις γνωσεις και τη λογικη που πρεπει.μπορει να τελειωσα τωρα ηλεκτρονικος επιτελους αλλα δεν ξερω και πολλα...αυτα που μας μαθαινουν ειναι αχρηστα σχεδον.γιαυτο ρωτω την εμπηρεια.

----------


## briko

> .....αν δειτε τους PIC εδω μεσα τους εμαθα .....



και εγώ εδω τους έμαθα, απλώς είχα λίγο περισσότερο υπόβαθρο σε assembly και ξημέρωσα αρκετές νύχτες για να φτιάξω απλά μικρά progs

----------


## billtech

και πολυ καλα εκανες...εγω ημουν στους 8051 που μας εκαναν στη σχολη και μετα την κοπανησα για pic που εβλεπα συζητησεις εδω μεσα.

----------


## briko

> και εγώ εδω τους έμαθα, απλώς είχα λίγο περισσότερο υπόβαθρο σε assembly και ξημέρωσα αρκετές νύχτες για να φτιάξω απλά μικρά progs



και assembly οχι σε pic σε Ζ80!!

----------


## lastid

Τί μου θύμισες με τον Z80...
Λοιπόν bill:
Τα *κακά νέα* είναι ότι δεν έκανες αυτό που σου ζήτησα. Σου είπα να κάνεις μία ρουτίνα καθυστέρησης και εσύ μου χρησιμοποίησες μία έτοιμη (delay).
Τα *καλά νέα* είναι ότι έκανες πολύ καλά. Κερδίσαμε χρόνο και είδα ότι δεν βρίσκεσαι πολύ στην αρχή.
*Ηθικό δίδαγμα*: Στον μαθητευόμενο καλλιτέχνη σπάνια "πρέπει" να πει ο δάσκαλος ότι κάνει λάθος. Και εδώ μιλάμε για προγραμματισμό, που είναι τέχνη. Αλίμονο αν λέγανε του Πικάσο "Τί χαζομάρες είναι αυτές? Λάθος τα κάνεις! Ζωγράφιζε σωστά" και αυτός τους άκουγε. Το αν κάνεις λάθος ή όχι θα κριθεί από την πράξη.
Πάμε παρακάτω τώρα.
Όσον αφορά τον *τρόπο μέτρησης του χρόνου*, με delay ή με timer?
Στον 16F84 είπαμε ότι έχουμε έναν μόνο timer και ευτόν τον θέλουμε να μετράει τους παλμούς της εισόδου. Άρα δεν μπορούμε να τον χρησιμοποιήσουμε για μέτρηση χρόνου. Άρα θα χρησιμοποιήσουμε delay. Τον timer0 και το interrupt του θα τα κρατήσουμε για μετά.
Το *πρόγραμματάκι* σου τώρα θα μπορούσε ίσως να γίνει λίγο πιο μικρό και ευανάγνωστο:



```
program sixnometro

main:
 TRISB=%00000000
 PORTB=1

START:delay_ms(1000)
      portb.0 = not (portb.0)
      goto start
end.
```


αλλά σε γενικές γραμμές το έχεις πιάσει το νόημα.
Πές μου, μπορείς να το τρέξεις να δεις αν αναβοσβήνει το led και να πάμε στο επόμενο στάδιο?

----------


## billtech

φιλε μου καταρχας σε ευχαριστω.
δευτερον.αυτο το προγραμματακι που εγραψες το ηξερα απλα νομιζα οτι το ηθελες οπως στο εγραψα.
τωρα αμεσαδεν μπορω να το δοκιμασω.λογω του οτι δεν εχω μαζι μου τα καλωδια να προγραμματισω. ειμαι στο χωριο αυτες τις μερες(3-4) και ετσι δεν το εχω.μπορουμε αν θες να προχωραμε και μολις γυρισω θα δοκμασω οτι πρεπει να δοκιμαστει.

----------


## lastid

Κανένα πρόβλημα, κι εγώ είμαι εκτός βάσης για μερικές ημέρες. Ας το δουλέψουμε λίγο στο χαρτί τότε.
Έχεις την είσοδο RA4 και θέλεις να τη συνδέσεις με τον timer0 ώστε αυτός να μετράει παλμούς που καταφτάνουν σε αυτήν. Πρέπει να γράψεις λοιπόν λίγες γραμμές προγράμματος που να κάνουν τα εξής:

1. Γενική αρχικοποίηση
*TRISA.4 = 0* // για να γίνει η RΑ4 έξοδος και να μή μετράμε ακόμη. ΠΡΟΣΟΧΗ: Η RA4 δέχεται και σήμα από έξοδο άλλου κυκλώματος. Όταν αυτή θα λειτουργεί σαν έξοδος, θα έχουμε πρόβλημα (δύο έξοδοι στην ίδια γραμμή). Θα τροποποιήσουμε το κύκλωμα για να μην καεί τίποτε.
*OPTION_REG.T0SE = 1*  // για να πιάνουμε την κάθοδο του παλμού και όχι την άνοδο. Όχι σημαντικό, θα μπορούσαμε και να επιλέξουμε το αντίθετο.
*OPTION_REG.T0CS = 1*  // για να δουλεύει ο timer0 σαν counter και όχι σαν timer.
*OPTION_REG.PSA = 1*   // για να μην έχουμε prescaler προς το παρόν. Σύντομα όμως θα τον χρησιμοποιήσουμε κι αυτόν.
*INTCON.T0IE = 0* // για να μην έχουμε timer0 interrupt προς το παρόν. Πολύ σύντομα όμως θα το χρησιμοποιήσουμε κι αυτό.
Σημείωση: Μερικά από τα παραπάνω (όπως π.χ. το T0IE) είναι ήδη αρχικοποιημένα με τις τιμές που τους δίνουμε και δεν χρειάζονται προς το παρόν. Αργότερα όμως θα κάνουμε αλλαγές στο πρόγραμμα.


2. Αρχή μέτρησης
*TMR0 = 0* // Μηδενίζουμε τον μετρητή.
*TRISA.4 = 1*  // Κάνουμε την RA4 είσοδο. Από εδώ και μετά, ο μετρητής μας μετράει.

3. Τέλος μέτρησης
*TRISA.4 = 0*  // Κάνουμε την RA4 είσοδο. Εδώ ο μετρητής μας σταματάει να μετράει. Στον καταχωρητή TMR0 θα διαβάσουμε το αποτέλεσμα της μέτρησης.

Αφού λοιπόν ετοιμάσεις τις παραπάνω γραμμές και αφού φτιάξουμε το interface, θα τα βάλουμε όλα μαζί και θα έχουμε το πρώτο μας απλό συχνόμετρο.
Όταν λέω interface, εννοώ την είσοδο-έξοδο του κυκλώματος. 
Σε ένα PC το interface συνήθως είναι πληκτρολόγιο και ποντίκι για είσοδο, οθόνη και ηχεία για έξοδο.
Στο κύκλωμά μας τί interface έχεις διαθέσιμο?
Για είσοδο δεν θέλουμε τίποτε. Ας δουλεύει το συχνόμετρο συνέχεια.
Για έξοδο, θέλουμε το αποτέλεσμα της μέτρησης (1 byte). Εδώ αποφασίζεις εσύ, ανάλογα με τί έχεις διαθέσιμο (LCD? με leds? από το PC μέσω σειριακής? από το PC μέσω ICD? από αναπτυξιακό?)

----------


## billtech

εχουμε οθονη LCD 2x16 και θα παραγγειλω μολις γυρισω και οθονη 1Χ16.
εισοδο δεν πρεπει με τρανζιστορ να δινουμε το σημα στο ποδαρακι?

----------


## lastid

Δοκίμασέ το με την 2x16 τώρα και αργότερα βλέπεις. Που ξέρεις, μπορεί σου χρειαστεί και δεύτερη γραμμή.

Όχι απαραίτητα με transistor. Υπάρχουν πολλά κυκλώματα. Δες και πιο πάνω στη συζήτηση δύο από αυτά.
Στο κύκλωμα του VaGyver (74HC132) θα χρειαστεί να βάλεις μία αντίσταση μερικά KΩ.
Στο κύκλωμα του Τρελού Επιστήμονα (transistor) θα χρειαστεί να μεγαλώσεις λίγο την 470Ω.

----------


## billtech

θα το δουμε αυτο στη πορεια..οταν κανω το σχεδιο.
τωρα ας ασχοληθουμε με το κωδικα να δω πως γινετε.

----------


## billtech

```
program sixnometro

dim TEXT as float
dim TXT as string[15]


main:
 TRISA=%00000000
 PORTA=0
 OPTION_REG.T0SE = 1
 OPTION_REG.T0CS = 1
 OPTION_REG.PSA = 1
 INTCON.T0IE = 0
 
 Lcd_Config(PORTB,7,6,5,4,PORTB,2,1,3)
 LCD_Cmd(LCD_CLEAR)
 LCD_Cmd(LCD_CURSOR_OFF)

START:
      TMR0 = 0
      TRISA.4 = 1
      delay_us(1)
      TRISA.4 = 0
      TEXT=TMR0
      FloatToStr(TEXT, TXT)
      LCD_OUT(1,1,TXT)
      goto start

      end.
```


προσπαθησα και εκανα αυτο.κοιταξε το και πες μου αν εκανα κατι σωστο... :Confused1:

----------


## lastid

Καλό φαίνεται, βουρ! :Wink: 
Έχω μόνο δύο τρεις παρατηρήσεις:
1. Η καθυστέρηση του 1 microsecond  είναι πολύ μικρή για το απλό αυτό πρόγραμμά μας. Θα δουλέψει, αλλά θα υπάρχει ένα μεγάλο σφάλμα μέτρησης. Μπορούμε να δούμε αργότερα πώς θα εξαλέιψουμε αυτό το σφάλμα. Καλύτερα όμως τώρα διαλεξε μία καθυστέρηση μεγαλύτερη ή ίση με 100us. Εαν την κάνεις και μεγαλύτερη ή ίση από 1 sec, θα μπορείς να το δοκιμάσεις ακόμη και ανοιγοκλείνοντας ένα διακόπτη.
2. Εαν τυπωθεί π.χ. "230" και κατόπιν σε μία επόμενη μέτρηση τυπωθεί "5", στο LCD θα βλέπουμε "530" διότι τα ψηφία 3 και 0 δεν τα σβήνουμε. Άρα καλό είναι κάθε φορά να τυπώνουμε τον αριθμό *και* μερικά κενά ή να τυπώνουμε με format και σταθερό αριθμό ψηφίων. Βέβαια, δεν ξέρω αν η floattostr το φροντίζει αυτό στη Microbasic...
3. Η μεταβλητή TEXT υποδεικνύει με το όνομά της ότι είναι κείμενο, όμως στην πραγματικότητα είναι αριθμός (ένα byte 0-255). Αυτό μπερδεύει λίγο. Επιπλέον, το όνομά της δεν μας βοηθάει να μάθουμε τί κρατά μέσα της, τη συχνότητα που μετρήσαμε δηλαδή. Μπορούμε π.χ. τις ΤΕΧΤ και TXT να τις ονομάσουμε FREQNUM και FREQTEXT αντίχτοιχα.

----------


## Nemmesis

το 1us ειναι το 1/1000 του 1ms... οποτε θελει λιγο να το αλλαξεις...
οπως σου προτινε και ο lastid κανε τον χρονο 1sec.. ετσι δεν θα χρειαζετε και καθολου πραξεις... βεβαια καλα ειμαστε τωρα για τις δοκιμες ομως συχνομετρο σωστο χωρις timers δεν γινεται αλλα συμασια εχει να μπεις στο σκεπτικο πρωτα... για χαμηλες συνχοτιτες μετραμε τον χρονο απο παλμο σε παλμο... και μεγαλητερες συχνοτητες μετραμε ποσους παλμους εχουμε μεσα σε καποιο χρονο...

----------


## billtech

```
program sixnometro

dim FREQNUM as float
dim FREQTEXT as string[15]

main:
 TRISA=%00000000
 PORTA=0
 OPTION_REG.T0SE = 1
 OPTION_REG.T0CS = 1
 OPTION_REG.PSA = 1
 INTCON.T0IE = 0
 
 Lcd_Config(PORTB,7,6,5,4,PORTB,2,1,3)
 LCD_Cmd(LCD_CLEAR)
 LCD_Cmd(LCD_CURSOR_OFF)

START:
      TMR0 = 0
      TRISA.4 = 1
      delay_m(1000)
      TRISA.4 = 0
      FREQNUM=TMR0
      FloatToStr(FREQNUM, FREQTEXT)
      LCD_Cmd(LCD_CLEAR)
      LCD_OUT(1,1,FREQTEXT)
      goto start

      end.
```


αυτο εδω ειναι με τις διορθωσεις που μου προτινατε.
συγνωμη δεν καταλαβα κατι.τωρσ δεν χρησιμοποιουμε TIMERS? ρωτω για να μην μπερδευτω.
τωρα τι θα κανουμε?θα το προχωρισουμε μεχρι να παω πισω στη βαση μου θα το αφησουμε εδω?

----------


## lastid

Εντάξει φαίνεται για τώρα, άστο όπως είναι.

Σχετικά με το αν χρησιμοποιούμε timers: 
O 16F84 έχει όπως ξέρουμε έναν μόνο timer, τον timer0. Μπορούμε να τον χρησιμοποιήσουμε είτε σαν timer για μέτρηση χρόνου, είτε σαν counter για μέτρηση παλμών. Όχι και τα δύο ταυτόχρονα.
Εδώ εμείς τον χρησιμοποιούμε σαν counter, όχι σαν timer.  Αν θέλω λοιπόν να είμαι ακριβής, πρέπει να απαντήσω ότι τώρα δεν χρησιμοποιούμε timers.

Σχετικά με το πρόγραμμα:
Το πρόγραμμά μας έχει κάποιους περιορισμούς και καλό είναι να το τροποποιήσουμε για να τους ξεπεράσουμε. Προς το παρόν όμως, σου συνιστώ να το δοκιμάσεις όπως έχει.
Ας αναλύσουμε λίγο το πρόγραμμα για να δούμε τί δυνατότητες (και τί περιορισμούς) έχει:
Έχουμε λοιπόν περίοδο μέτρησης ένα δευτερόλεπτο και έναν μετρητή παλμών που μετρά από το 1 ως το 255. Αυτό σημαίνει ότι μπορεί να μετρήσει συχνότητες 1Hz-255Hz. Είναι όμως έτσι?
Αν του δώσω ένα σήμα 1.5Hz, θα έχω μία ένδειξη 1Hz ή 2Hz. Η ακρίβειά του λοιπόν στις χαμηλές συχνότητες είναι απαράδεκτη.
Αν του δώσω ένα σήμα μεγαλύτερο από 255 Hz, δεν θα έχω κανέναν τρόπο να μάθω ότι βγήκα εκτός ορίων.
Όσον αφορά τώρα τις τροποποιήσεις, η πρώτη τροποποίηση που προτείνω είναι η επέκταση του timer0 από 8bits σε περισσότερα, χρησιμοποιώντας interrupts. Επειδή όμως καμιά φορά τα interrupts είναι άτιμο πράμα γι αυτόν που τα πρωτοδουλεύει, επιμένω να δεις πρώτα το κύκλωμά σου να δουλεύει και μετά να τα καταπιαστείς. Αλλιώς, μπορεί να μή σου δουλεύει τίποτε και δεν θα ξέρεις τί να πρωτοτσεκάρεις. Μέχρι τότε, διάβασε την θεωρία τους.

----------


## billtech

ωραια.απο τριτης λοιπον..
θελεις να μου εξηγησεις λιγο τα interrups?που ειπες ειναι παγιδες?
βασικα πως ρυθμιζεις τον επεξεργαστη να κανει interupt?απο που το καταλαβενει και τα κανει?
πως τα βλεπουμε εμεις?
εννοειτε οτι διαβαζω μπας και τους καταλαβω αλλα ειναι δυσκολα αμα δεν εχεις καποιον να στα πει.
σε ευχαριστω ως τωρα

----------


## bxenos

INTERRUPT=διακοπή (ο αντίθετος τρόπος ελέγχου είναι το POLLING).

Το Interrupt σημαίνει ότι 
α) όταν συμβεί καποιο προκαθορισμένο απο το hardware συμβάν (π.χ. κάνει υπερχείληση ο timer απο 255 σε 0, πατιέται ένα button,...) 
β) ΚΑΙ έχει ρυθμιστεί o μικροελενκτής να ΑΠΟΔΕΧΕΤΑΙ το συγκεκριμένο interrupt (μεσω κάποιου flag)
γ) ΚΑΙ είναι γενικώς ενεργά τα interrupt  (μεσω κάποιου flag)
δ) ΚΑΙ δεν βρισκόμαστε σε κάποιο interrupt υψηλότερης ή ίσης προτεραιότητας,

τοτε: σταματάει η εκτέλεση του προγράμματος μας και μεταβαίνουμε στην ρουτίνα που έχουμε ορίσει ότι θα εκτελείται σε κάθε interrupt. 
Κάνουμε ΠΟΛΥ ΓΡΗΓΟΡΑ ότι είναι να κάνουμε ΚΑΙ χωρίς πολλά πολύπλοκα πράγματα (π.χ. εντολές χρονοβόρες,αναμονές εισόδων κτλ) και μετά το πρόγραμμα συνεχίζει απο εκεί που είχε μείνει σχεδόν σαν να μην συνέβη τίποτα.

μερικά απο τα προβλήματα: 
1) αν δεν είναι σύντομη η ρουτίνα του interrupt, μπορεί να έρθει και δεύτερο πριν τελειώσουμε με το πρώτο και να το χάσουμε ή να μην καταφέρουμε να επιστρέψουμε ποτές στο πρόγραμμα μας
2) αν στο πρόγραμμα εκτελούμε π.χ.
ΑΝ SEC>0
     ΚΑΝΕ-ΚΑΤΙ

Οταν ξεκινά το ΚΑΝΕ-ΚΑΤΙ δεν ειναι ΚΑΘΟΛΟΥ σίγουρο οτι το SEC είναι μεγαλύτερο απο το 0 αν το SEC αλλάζει και μέσα στην ρουτίνα του interrupt.

----------


## billtech

αρα αν ψιλοκαταλαβα καποια ελαχιστα εμας θα κανει Interupt οταν κανει μεταβασει ο TIMER απο 1 σε 0?

----------


## billtech

γεια σας και παλι.
βρηκα ενα προγραμμα μεσα στα παραδειγματα που νομιζω αν μπορεσει καποιος να μου το εξηγησει θα καταλαβω αρκετα πραγματακια πανω στους TIMERS και στα INTERUPTS.
σαε ευχαριστω πολυ.
βεβαια δεν ξερω αν ειναι σωστο προγραμμα αυτο που βρηκα και ειναι για τον TIMER0




```
' *
' * Project name
'     TMR0 (Simple 'Hello World' demonstration of interrupt handling)
' * Copyright:
'     (c) mikroElektronika, 2008
' * Revision History:
'     20080225:
'       - initial release.
' * Description
'     This code demonstrates using interrupts and TMR0. Program toggles LEDs on
'     PORTB and PORTD each second.
' * Test configuration
'     MCU:            P16F887
'     Dev.Board:      EasyPIC5
'     Oscillator:     HS, 08.0000 MHz
'     Ext. Modules:   -
'     SW:             mikroBasic v7.1
' * NOTES
'     None.
' *

program TMR0

dim cnt as word

sub procedure interrupt
  Inc(cnt)                   ' Increment value of cnt on every interrupt
  TMR0   = 96
  INTCON = $20           ' Set T0IE, clear T0IF
end sub

main:
  OPTION_REG = $84       ' Assign prescaler to TMR0
  ANSEL  = 0              ' Configure AN pins as digital I/O
  ANSELH = 0
  TRISB = 0               ' PORTB is output
  PORTB = $FF            ' Initialize PORTB
  TMR0  = 96              ' Timer0 initial value
  INTCON = $A0           ' Enable TMRO interrupt
  cnt = 0                 ' Initialize cnt

  while TRUE
    if (cnt = 400) then
      PORTB = not PORTB      ' Toggle PORTB LEDs
      cnt = 0             ' Reset cnt
    end if
  wend
end.
```

----------


## billtech

λοιπον....επανηθλα παλι...
σκιστικα τωρα το απογευμα στο διαβασμα και νομιζω καταλαβα καποια πραγματα και ειπα να τα γραψω εδω να μου πειτε αν καταλαβα καλα.
εμεις θα επιλεξουμε σαν εισοδο το T0CKI και μετα θα επιλεξουμε να γινετε με τη καθοδο καθε παλμου που ερχετε στο T0CKI. τον T0CS τον βαζουμε στο 1 για να μετραμε οχι τον κρυσταλλο αλλα τη συχνοτητα που ερχετε στο T0CKI.μετα θα την οδηγουμε στον prescaler Που θα τον προγραμματισουμε με τα 3bit του σε ποσο να διαιρει τη συχνοτητα και μετα τον PSA θα τον κανουμε 0 για να δουλευει με τον Prescaler μας και τον TIMER0 τον προγραμματιζουμε να μετραει απο το 0 εως το 255 και καθε φορα που μετραει να αυξανει ενας καταχωρητης ανα ενα και συνεχεια θα πολλαπλασιαζουμε αυτο τον καταχωρητη με τον Prescaler μας, θα κανουμε /1 να βρουμε τη συχνοτητα και θα την εμφανιζουμε στο LCD μας.
Σιγουρα δεν ειναι και οτι ποιο ευκολο να κανει αυτο ενας αρχαριος.
Σιγουρα δεν υπαρχει περιπτωση να τα καταλαβα ολα καλα και εδω θελω να μου πειτε που εκανα λαθος και αν καταλαβα κατι σωστα και τι παρελειψα.
ευχαριστω παιδες.Ευχαριστω για ολη τη βοηθεια γιατι ειναι κατι που προσπαθω να μαθω μονος μου αφου στις σχολες και στα πανεπηστιμια μας μαθαινουν κατι απαρχαιωμενα πραγματα και ουτε αυτα μας τα κανουν σωστα.

----------


## lastid

Οk, ας τα πούμε ξανά και ξανά μέχρι να τα έχεις κατανοήσει πλήρως. Η επανάληψη είναι μητέρα της μάθησης...
Το σκεπτικό σου σε γενικές γραμμές είναι σωστό εκτός από τα παρακάτω σημεία όπου πρέπει να επαναδιατυπωθούν:




> και τον TIMER0 τον προγραμματιζουμε να μετραει απο το 0 εως το 255



Τον timer0 δεν τον προγραμματίζουμε να μετράει από το 0 ως το 255. Θα το κάνει ούτως ή άλλως. Εμείς προγραμματίζουμε από πού να παίρνει την είσοδό του. Φαντάζομαι ότι αυτό εννοείς.





> και καθε φορα που μετραει να αυξανει ενας καταχωρητης ανα ενα



O TMR0 και ο καταχωρητής που αυξάνει είναι ένα και το αυτό. 





> και συνεχεια θα πολλαπλασιαζουμε αυτο τον καταχωρητη με τον Prescaler μας...



Εμείς (το πρόγραμμά μας δηλαδή) δεν πολλαπλασιάζουμε τίποτε. Ο prescaler το κάνει αυτό μόνος του. Και δεν πολλαπλασιάζει αλλά διαιρεί. Και το κάνει πριν τον timer0, όχι μετά.
Αν π.χ. έχουμε ενεργοποιήσει τον prescaler να κάνει 1:128 διαίρεση, τότε αν στείλουμε 128 παλμούς στην RA4/T0CKI, o TMR0 θα αυξηθεί κατά 1.

Ξαναλέω και τονίζω: Δες το Σχήμα 4.1 από το documentation του 16F84. Τα εξηγεί όλα.

Παραθέτω εδώ και δύο σχήματα βασισμένα στο Σχήμα 4.1:
Το πρώτο σχήμα δείχνει την διαδρομή του σήματός μας χωρίς prescaler, όπως δηλαδή στο πρόγραμμα που έγραψες.
Το δεύτερο σχήμα δείχνει την διαδρομή του σήματός μας με prescaler, όπως δηλαδή στο πρόγραμμα που βρήκες.

Για τα interrupts θα γράψω ξεχωριστά.

----------


## billtech

> Οk, ας τα πούμε ξανά και ξανά μέχρι να τα έχεις κατανοήσει πλήρως. Η επανάληψη είναι μητέρα της μάθησης...
> Το σκεπτικό σου σε γενικές γραμμές είναι σωστό εκτός από τα παρακάτω σημεία όπου πρέπει να επαναδιατυπωθούν:
> 
> Τον timer0 δεν τον προγραμματίζουμε να μετράει από το 0 ως το 255. Θα το κάνει ούτως ή άλλως. Εμείς προγραμματίζουμε από πού να παίρνει την είσοδό του. Φαντάζομαι ότι αυτό εννοείς.
> 
> 
> O TMR0 και ο καταχωρητής που αυξάνει είναι ένα και το αυτό. 
> 
> 
> ...



Λοιπον να πω που δεν καταλαβες τι εννουσα να το λυσουμε.
οταν ειπα πολλαπλασιαζουμε και δεν ειπα διαιρουμε εννουσα οταν εμεις παρουμε το αποτελεσμα απο τον timer0 αυτο θα ειναι διαιρεμενο ας πουμε δια 128 αρα εμεις για να βρουμε την πραγματικη τιμη που μπηκε στον prescaler μας πρεπει να πολλαπλασιασουμε με 128.αλλιως πως θα εχουμε την πραγματικη τιμη της εισοδου?.
εγω οτι διαβασα και καταλαβα νομιζω καποια πραγματα ειναι απο αυτο εδω το Link που το βρηκα στο google.ελπιζω να μην απαγορευετε η δημοσιευση του.
http://www.epil.gr/delta5/microPIC/c...0.htm#portaXOR

κοιταξε τα και μου λες...θα κατσω και αποψε να τα δω να δω τι καταλαβω και που χανομαι..

----------


## lastid

Κατάλαβα και έχεις δίκιο.
Μόνο που έτσι όπως το είχες γράψει ήταν νομίζω λίγο μπερδεμένο. Γιατί στην ίδια πρόταση περιγράφεις την πορεία του σήματος μέσα στον PIC ΚΑΙ την αντίστροφη διαδικασία που κάνει το πρόγραμμα για την ανάκτηση του σήματος αυτού, σαν να πρόκειται για την ίδια πορεία του σήματος.
Είμαστε λοιπόν οκ.

----------


## billtech

ωραια....τωρα?πινουμε καφε?χεχε πλακα κανω γιατι και η πλακα στη ζωη ειναι και το χιουμορ.
αυτα τωρα τα ψιλοκαταλαβα.στο κωδικα πως τα περνας?
θα το κοιταξω ακομα λιγο αυτο και απο δευτερα θα συνεχισουμε με το μεγαλο και με τον κωδικα.
αν μπορεις εξηγησε μου αυτες τις μερες και τα ιντεραπς για να τα καταλαβω ωστε να ειμαστε ετοιμοι απο δευτερα.

----------


## billtech

λοιπον..εκατσα και ψιλοκαταλαβα και τα intrerrups.
οταν χερουμε ποσι ορα θελει ο timer0 να παει απο το 1 στο 255 και ξερουμε ποσα intrerrups εγιναν μπορουμε να βρουμε το χρονο του παλμου της εισοδου.αρα κανονοντας 1/χρονο εχουμε τη συχνοτητα.
αρα εμεις πρεπει να εχουμε ενα timer που να μετραει μολιε εχουμε καθοδο η ανοδο του παλμου μεχρι να γινει το ιντεραπτ και ετσι θα εχουμε τη συχνοτητα σωστα?

----------


## lastid

Σωστά, μόνο που νομίζω ότι τώρα αναφέρεσαι στον Β' τρόπο μέτρησης.
Είπαμε έχουμε δύο τρόπους μέτρησης:
A) Μέτρηση συχνότητας (για ψηλές συχνότητες)
- O TMR0 δουλεύει σαν counter
 - Ξεκινάμε τη μέτρηση όποτε θέλουμε 
- Κάθε 256*Prescaler παλμούς εισόδου, συμβαίνει και ένα interrupt. Μέσα στο interrupt αυξάνουμε μία μεταβλητή.
- Σταματάμε τη μέτρηση μόλις περάσει κάποιος συγκεκριμένος χρόνος, πχ 1 sec. Για τη μέτρηση του χρόνου χρησιμοποιούμε υπορουτίνα delay.
- Η συχνότητα είναι ανάλογη της μεταβλητής.
Β) Μέτρηση περιόδου (για χαμηλές συχνότητες)
- O TMR0 δουλεύει σαν timer
- Ξεκινάμε τη μέτρηση μόλις έχουμε συγκεκριμένη μετάβαση του παλμού εισόδου (π.χ. από Low σε High).
- Κάθε 256 μονάδες χρόνου, συμβαίνει και ένα interrupt. Μέσα στο interrupt αυξάνουμε μία μεταβλητή.
- Σταματάμε τη μέτρηση μόλις έχουμε ξανά την ίδια μετάβαση του παλμού εισόδου.
- Η συχνότητα είναι αντιστρόφως ανάλογη της μεταβλητής.

----------


## billtech

δηλαδη εμεις ποιο τροπο θα χχρησιμοποιουμε?δεν θα μετραμε και χαμηλες και ψιλες?
τι θα κανουμε τωρα?κανενα διαγραμμα ροης μπορουμε να κανουμε?

----------


## lastid

Ναι, θα μετράμε και χαμηλές και ψηλές, αλλά όχι ταυτόχρονα  :Wink: 
Μετράμε ας πούμε με τον Α τρόπο (ψηλές). Αν δούμε ότι το σήμα μας είναι πολύ αργό,  γυρίζουμε αυτόματα στον B' τρόπο (χαμηλές).
Και αντίστροφα.
Άρα θέλουμε δύο βασικές υπορουτίνες που θα υλοποιούν τους δύο τρόπους και ένα πρόγραμμα που θα καλεί την μία ή την άλλη, ανάλογα με το αποτέλεσμα της τελευταίας μέτρησης.
Βάζουμε και λίγο autorange και είμαστε έτοιμοι.

----------


## billtech

σαν πολυ ευκολο μου το λες..
εμενα γτ μου φαινεται βουνο?
απο τωρα και εμπρος νομιζω θα θελω πολλη βοηθεια.ναι καταλαβα λιγο τους τιμερς και τα ιντεραπτ αλλα ειναι δυσκολα τα πραματα πια για μενα

----------


## lastid

"Στοιχειώδες αγαπητέ Γουάτσον!"  :Smile: 
Το κάνω για τόνωση ηθικού. Αλλά αν είναι να φέρω το αντίθετο αποτέλεσμα, να σταματήσω.
Πάντως είναι λογικό να σου φαίνεται βουνό. Πάντα έτσι γίνεται. Μόλις αρχίσεις και τα δοκιμάζεις και τα παιδέψεις και τα παιδέψεις και δουλέψουν - εκεί να δείς αγαλλίαση.
Άμα τα παρατήσεις, ε δεν θα πεθάνεις κιόλας..
Πάντως δεν βλέπω λόγο να μη σου δουλέψει. Αργά ή γρήγορα θα γίνει.

----------


## billtech

δεν ειπα θα σταματησω.
απλα ειπα ειναι βουνο.και θα θελω τρελλη βοηθεια.για να τα καταλαβαινω κιολας.

----------


## billtech

```
 program timertest 
dim ct as longint 
 
sub procedure interrupt 
 
    if INTCON.2 = 1 then 
      INTCON.2 = 0 
      ct = ct + 1 
      INTCON = $20 
    end if 
     
end sub 
 
'set registers 
main: 
     INTCON = %10100000 
     OPTION_REG = %10001000 
     TMR0 = 0 
     OSCCON = %01101110 
     TRISB = $00 
     PORTB = $FF 
     ct = 0 
      
eloop: 
     if ct = 3921 then 
     PORTB = not(PORTB) 
     ct = 0 
     end if 
 
goto eloop 
       
end.
```


καλησπερα παιδια.
μετα απο αρκετο διαβασμα καταλαβα αρκετα νομιζω και τα interrupts.
αν μπορει μονο καποιος να μου βαλει σχολια και να μου εξηγεισει με λιγα λογια πως δουλευει αυτος ο κωδικας και αν ειναι σωστος.
και αν μπορουμε να προχρησουμε στο προγραμμα του συχνομετρου.
αυριο θα δοκιμασω και το προγραμματακι που καναμε να δω αν εχουμε κανει ενα μικρο συχνομετρο.

----------


## billtech

nobody?
κανεις ρε παιδια?

----------


## billtech

```
program sixnometro

dim FREQNUM as float
dim FREQTEXT as string[15]

main:
 TRISA=%00000000
 PORTA=0
 OPTION_REG.T0SE = 1
 OPTION_REG.T0CS = 1
 OPTION_REG.PSA = 1
 INTCON.T0IE = 0
 
 Lcd_Config(PORTB,7,6,5,4,PORTB,2,1,3)
 LCD_Cmd(LCD_CLEAR)
 LCD_Cmd(LCD_CURSOR_OFF)

START:
      TMR0 = 0
      TRISA.4 = 1
      delay_ms(1000)
      TRISA.4 = 0
      FREQNUM=TMR0
      FloatToStr(FREQNUM, FREQTEXT)
      LCD_Cmd(LCD_CLEAR)
      LCD_OUT(1,1,FREQTEXT)
      goto start

      end.
```


δοκιμασα να κανω hex αυτο τον κωδικα και μου λεει οτι δεν εχει αρκετη μνημη.δεν ειναι λογικο αυτο.
τι φταιει?

----------


## lastid

*Σχετικά με το πρόγραμμα sixnometro:*
Χρησιμοποιείς τις υπορουτίνες lcd_config, lcd_cmd, lcd_out, delay_ms και floattostr από  βιβλιοθήκες της γλώσσας. Κάθε υπορουτίνα είναι αρκετά μεγάλη στον 16F84. Ίσως και να είναι λογικό το μήνυμα. 
Εγώ θα έκοβα πρώτη πρώτη την floattostr και θα χρησιμοποιούσα ακέραιους, μια και δεν χρειαζόμαστε πραγματικούς αριθμούς. Αν και πάλι είναι μεγάλο το πρόγραμμα, δοκίμασε να βάλεις σε σχόλια τις άλλες υπορουτίνες και να δεις αν σου βγάζει τελικά compile.
Σε κάθε περίπτωση, ρίξε μια ματιά στο .lst αρχείο που θα βγάλει ο compiler. Εκεί μπορείς να δεις την assembly που βγαίνει για κάθε εντολή.

*Σχετικά με το πρόγραμμα timertest:*

- Βάζε και κανένα σχόλιο για να ξέρει κανένας τί θέλεις να κάνει το πρόγραμμα, ειδικά εκεί που δεν είναι προφανές. Π.χ. η εντολή 
    if INTCON.2 = 1 then
καλό είναι να γράφεται ωε εξής:
    if INTCON.2 = 1 then   ; TMR0 overflow interrupt ?

- Μέσα στο interrupt εκτελείται η εντολή
    intcon.2 = 0
που καθαρίζει το TMR0 interrupt.
ΟΜΩΣ εκτελείται και η εντολή 
   intcon = $20
που καθαρίζει το TMR0 interrupt ΚΑΙ απενεργοποιεί τα interrupts.
Προφανώς πρέπει να κρατήσεις μόνο την μία από τις δύο. Μάλλον την πρώτη.

- OSCCON δεν υπάρχει στον 16F84. Δεν ξέρω αν η Microbasic κάνει κάτι ισοδύναμο, δεν νομίζω όμως. Μάλλον πρέπει να ορίσεις αλλιώς ότι θα υπάρχει εξωτ.κρύσταλλος 4ΜΗz.

- Μάλλον θέλεις να κάνεις την Port B  (έξοδος) να αλλάζει με ρυθμό 1Hz, σωστά? Όμως το interrupt overflow θα συμβαίνει κάθε 256 αυξήσεις του TMR0 και όχι κάθε 255. Άρα θέλουμε 3906 και όχι 3921 σαν όριο (TMR0:0..255  ct:0..3905).

- Το κομμάτι με τις εντολές που ελέγχει αν ο ct έφτασε στο τέλος και τον μηδενίζει και αλλάζει την port Β, καλό είναι (για περισσότερους από ένα λόγους) να μπεί μέσα στο interrupt, αμέσως μετά την αύξηση του ct κατά ένα.

----------


## billtech

> *Σχετικά με το πρόγραμμα timertest:*
> 
> - Βάζε και κανένα σχόλιο για να ξέρει κανένας τί θέλεις να κάνει το πρόγραμμα, ειδικά εκεί που δεν είναι προφανές. Π.χ. η εντολή 
>     if INTCON.2 = 1 then
> καλό είναι να γράφεται ωε εξής:
>     if INTCON.2 = 1 then   ; TMR0 overflow interrupt ?
> 
> - Μέσα στο interrupt εκτελείται η εντολή
>     intcon.2 = 0
> ...



φιλε μου το βρηκα ετοιμο το προγραμμα για να καταλαβω τα ιντεραπς.
ειναι για τον 628Α. συμγωνω και εγω με τις αλλαγες που φενεται οτι θελει να κανει για να δουλεψει σωστα.αλλα και οπως ειναι εβγαλα την εντολη του εσσωτερικου κρυσταλλου και το δοκιμασα με τον 84Α και δουλευει μια χαρα.
δεν ξερω πως γινεται.γιαυτο χαζεψα και το εβαλα να βαλει καποιος σχολια.
επειδη δεν ειναι λογικο να δουλευει και ομως δουλευει.

για το sixnometro θα κανω τις αλλαγες να τις δοκιμασω αλλα αμα απο τωρα μας εβγαλε τετοιο προβλημα πως θα γινει να τελειωσει το προγραμμα?αλλα νομιζω το προβλημα ειναι στο float και θα το κανω ακαιρεους.

----------


## billtech

λοιπον φιλε μου.
εκανα το σιχνομετρο απο float σε word και παιζει καλα.
εβαλα μια γεννητριουλα που ειχα που βγαζει απο 30-148Hz και τα μετραει.
τωρα τι κανουμε?

----------


## lastid

*Σχετικά με το timertest:*
Η τελευταία εντολή assembly που εκτελείται σε μία υπορουτίνα interrupt είναι η RETFIE (φροντίζει ο compiler της basic γι αυτό).
Η RETFIE κάνει 1 το GIE, γι αυτό και το παραπάνω πρόγραμμα δουλεύει. Δηλαδή δεν μπορούμε να απενεργοποιήσουμε τα interrupts μέσα σε μία interrupt ρουτίνα.
Τα υπόλοιπα είναι λεπτομέρειες. Γι αυτό και το πρόγραμμα δουλεύει σε (περίπου) 1Hz.

*Σχετικά με το sixnometro:*
Ωραία!
Το περίμενα ότι θα έφταιγαν οι float. Συνήθως παράγεται αρκετός κώδικας, ακόμη και για κάτι απλό.
Τώρα από εδώ και πέρα, κάνε πρώτα πρώτα την FREQNUM μεγαλύτερη από 8 bits, προσθέτοντας interrupts.

----------


## billtech

> *Σχετικά με το timertest:*
> Η τελευταία εντολή assembly που εκτελείται σε μία υπορουτίνα interrupt είναι η RETFIE (φροντίζει ο compiler της basic γι αυτό).
> Η RETFIE κάνει 1 το GIE, γι αυτό και το παραπάνω πρόγραμμα δουλεύει. Δηλαδή δεν μπορούμε να απενεργοποιήσουμε τα interrupts μέσα σε μία interrupt ρουτίνα.
> Τα υπόλοιπα είναι λεπτομέρειες. Γι αυτό και το πρόγραμμα δουλεύει σε (περίπου) 1Hz.
> 
> *Σχετικά με το sixnometro:*
> Ωραία!
> Το περίμενα ότι θα έφταιγαν οι float. Συνήθως παράγεται αρκετός κώδικας, ακόμη και για κάτι απλό.
> Τώρα από εδώ και πέρα, κάνε πρώτα πρώτα την FREQNUM μεγαλύτερη από 8 bits, προσθέτοντας interrupts.



πρωτον δεν καταλαβα αυτο που λες με την RETFIE Που κανει το GIE=1. ποια ειναι αυτη η εντολη?που ειναι? δλδ εννοεις οτι επειδει δινει το $20 που κανει το GIE=0 στη ουσια δεν το λαμβανει υποψιν γιατι ειναι μεσα στο intertupt?

τι εννοεις να το κανω μεγαλυτερο προσθετοντας interrups? με τον prescaler? πως?

----------


## lastid

Ναι, επειδή είναι μέσα στο interrupt, η INTCON=$20 αχρηστεύεται. Γιατί η "end sub" του interrupt θα παράγει μερικές εντολές σε assembly, από τις οποίες η τελευταία θα είναι η RETFIE που κάνει το GIE=1. Κοίτα μέσα στο LST αρχείο που παράγεται.

Για το sixnometro, ουσιαστικά πρέπει να "παντρέψεις" τα δύο προγραμματάκια. 
Αντί να παίρνεις το αποτέλεσμα της μέτρησης σαν :
FREQNUM = TMR0
θα πρέπει να το παίρνεις κάπως έτσι :
FREQNUM = ct*256+TMR0
, όπου η ct θα είναι ακριβώς ότι και στο πρόγραμμα timertest.
H FREQNUM φυσικά θα πρέπει να είναι τουλάχιστο 16 bits. 
Αν είναι 16 bits, θα μετράς μέχρι 65 KHz.
Αν είναι 32 bits, θα μετράς μέχρι 1 ΜΗz.
Όλα αυτά χωρίς prescaler. Το prescaler είναι ξεχωριστή υπόθεση και αυξάνει x2, x4, x8, ... το range.

----------


## billtech

νομιζω πρεπει πριν προχωρησουμε να κατασκευασουμε μια γεννητριουλα απο 1Hz εως 50MHz και μετα.για να μπορουμε να το δοκιμαζουμε το συχνομετρο.
φανταζομαι και αυτο με timers θα γινει ε?αλλα πως?πως θα γινει μεταβλητο εννοω?

----------


## lastid

Για βαθμονόμηση, μία απλή και γρήγορη λύση είναι να βάλεις την portB να αυξάνεται (σαν byte).
To main loop μπορεί να είναι:



```
mainloop: incf portb
   goto mainloop
```


που θέλει 3 κύκλους μηχανής για κάθε επανάληψη. 
Έτσι, αν έχεις έναν 16F84A στα 20ΜΗz:
Στην έξοδο Portb.0 θα παίρνεις μία συχνότητα 833.333 ΚΗz.
Στην έξοδο Portb.1 θα παίρνεις μία συχνότητα 416.666 ΚΗz.
Στην έξοδο Portb.2 θα παίρνεις μία συχνότητα 208.333 ΚΗz.
...
Στην έξοδο Portb.6 θα παίρνεις μία συχνότητα 14020.832 Ηz.
Στην έξοδο Portb.7 θα παίρνεις μία συχνότητα 6510.416 Ηz.
Αν o κρύσταλλος είναι στα 4MHz, θα παίρνεις συχνότητες 166.666 KHz ... 1302,083 Hz.
Με τροποποίηση, μπορείς να πάρεις και μικρότερες συχνότητες.
Δεν πάει πολύ ψηλά σε συχνότητες (MHz), αλλά είναι πολύ απλό.

----------


## billtech

συγνωμη αλλα δεν καταλαβα χριστο απο αυτο.
τι εννοεις?
δεν μπορω να το κανω μεταβλητο?με κουμπια?πανω κατω?φανταζομαι βεβαια ειναι δυσκολο αυτο.
το οποιο θα μπορουσε να μεινει και σαν απλο οργανακι παραγωγης συχνοτητων.
το σχηματικο του συχνομετρου ποιο προτινεις να ειναι?
για να μην κανουμε διαφορετικα?

----------


## bxenos

Μήπως να πας σε κανένα ΕΠΑΛ ηλεκτρονικών;  :Smile:

----------


## billtech

ελα μου?τι ειναι αυτο?ειμαι και απο χωριο ξερεις  :Rolleyes: 
κοιτα τωρα στην ουσια ειμαι πτυχιουχος ηλεκτρονικος.
πριν ενα μηνα τελειωσα τα παντα.
αλλα!!!! νομιζεις οτι στο ΤΕΙ εχω μαθει εστω και κατι?ελαχιστα.τιποτα δεν μας μαθαινουν.
ας πουμε μικροελεκτες μας εκαναν τον 8051 και σε ασεμπλυ.και μας τα εκαναν και αυτα ελαχιστα.οχι να εμβαθυνουν σε κατι.
ολα επιφανειακα μας τα κανουν.
τωρα για τους pic ειναι επεξεργαστες που αποφασισα να μαθω μονος μου( η καλυτερα με τη βοηθεια των παιδιων εδω μεσα) για να μπορεσω καποτε να πω ειμαι ηλεκτρονικος και ξερω εστω και κατι.γιατι αμα περιμενω απο τις σχολες.παει...την βαψαμε!!!
καταλαβες?

----------


## bxenos

μετα το γυμνάσιο:
Γενικό Λύκειο ή Επαγγελματικό Λύκειο ή Επαγγελματικη Σχολή

Στα ΕΠΑΛ υπάρχουν διάφορα τμήματα (ένα απο αυτά είναι ηλεκτρονικών). 
Και υπάρχει μάθημα μικροϋπολογιστών.

(βέβαια δεν ξέρω την ηλικία σου)

----------


## bxenos

Η δουλειά μιας σχολής δεν είναι να σε μάθει μια τεχνοτροπία ή έναν συγκεκριμένο μικροελενκτή. Η δουλειά της είναι να σε μάθει να μαθαίνεις μόνος σου (γειράσκω αεί δηδασκόμενος).

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

π.χ οι σχολές έχουν μείνει στον 8051 και στους pic16F. Και οι δύο είναι απαρχαιωμένοι. Όχι ότι δεν θα κάνουν για απλές δουλειές. Πριν διαλέξεις το τσιπάκι σου έκανες καμια έρευνα; κλίκ

Και εσύ όμως τα περιμένεις έτοιμα, άνοιξες ένα θέμα και περιμένεις απαντήσεις στις απορίες σου. Δεν ξέρω πόσο θα αντέχει (αν αντέχει ακόμα) ο lastid να σε βοηθά, καθότι ο χρόνος ολονών είναι πολύτιμος (και λόγω υποχρεωσεων επαγγελματικών και λόγω οικογενειακών). Εσύ ακόμα είσαι νέος , πιθανά να μην έχεις υποχρεώσεις ακόμα και έχεις αρκετό χρόνο. Αξιοποίησε τον να διαβάσεις να βρείς μόνος σου αυτό που θέλεις. Και αν κολήσεις εδώ είμαστε. Μην τα περιμένεις όλα έτοιμα.

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

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

----------


## briko

Απάντηση στoν bxenos
Ο Βασίλης δεν ζήτησε από κανένα με το ζόρι να τον βοηθήσει.
Αυτές τις απορίες που έχει της έχω και εγώ, ίσως λίγο λιγότερο η περισσότερες. Οι πληροφορίες αυτές δεν είναι ούτε για να περάσουμε κάποιο μάθημα ούτε για εμπορική εκμετάλλευση.
Βρέθηκε ο lastid και του απαντάει στις απορίες που έχει όπως θα μπορούσε να είναι και άλλοι όπως ο DT200 κτλ..
Εσύ άλλωστε έγραψες ‘*Αν κάποιος ενδιαφέρετε να υλοποιήσει την κατασκευή, μπορεί ελεύθερα να εκφράσεις τις απορίες του και τις εντυπώσεις του στο νήμα αυτό.*’
Αν υπάρχει κάποιο βιβλίο η φυλλάδιο το όποιο να έχει αυτές τις απαντήσεις θα παρακαλούσα να μου το πείτε.
Ευχαριστώ και ελπίζω να μην παρεξηγηθεί η άποψη μου.

----------


## lastid

Εντάξει, δεν υπάρχει πρόβλημα. Για ότι μπορώ να απαντήσω άμεσα το κάνω. Σε ότι χρειάζομαι το εργαστήριό μου, έχω ένα μικρό πρόβλημα χρόνου αυτό τον καιρό. Και είμαι και εκτός πόλης.
Μερικές φορές bill ξεχνιέμαι και γράφω, υποθέτοντας ότι γνωρίζεις ήδη αυτά που μαθαίνεις τώρα.
Αυτό που εννοούσα στο τελευταίο μου post, ήταν να βάλεις έναν άλλον pic σε ένα breadboard μόνο με κρύσταλλο και τροφοδοσία και να παίρνεις από 8 εξόδους του 8 διαφορετικές συχνότητες αναφοράς , με ένα πανεύκολο πρόγραμμα 2 γραμμών.
Εσύ βέβαια θέλεις μία κανονική γεννήτρια συχνοτήτων - και καλά κάνεις. Ωραίο θέμα (και υπάρχουν topics γι' αυτό στο forum) αλλά ξεφεύγει λίγο σε έκταση. Θέλω κι εγώ να κάνω κάτι παρόμοιο, αλλά επειδή έχω την τάση να λέω "ας βάλω κι αυτό", "ας βάλω κι ετούτο", "ας βάλω κι εκείνο", μακραίνει.

----------


## bxenos

briko δεν προσπάθησα να αποθαρύνω τον biitech, απλά έκανα μια πρόταση να προσπαθεί περισσότερο μόνος του διότι αυτά που καταφέρνεις μόνος σου μένουν. Και όπου κολάει κάποιος εδώ είμαστε. Αντιλαμβάνομαι τη χαρά του στο ενδιαφέρον θέμα που εργάζεται, αλλά ξεκίνησε απότομα απο τα βαθιά. Πριν το ε, υπάρχουν τα α,β,γ,δ

----------


## billtech

ειπες να διαβασω παραπανω μονος μου.
εκτος απο το datasheet τι αλλο εχω να διαβασω?μιλω για προγραμματισμο σε γλωσσα mikrobasic.
το οτι ζητησα βοηθεια εδω απο τα παιδια οπως σου ξαναειπαν δεν αναγκασα κανενα να βοηθεισει.
ηδη αν δεις μονος μου εψαξα και καταλαβα τους timers και τα interrups.το μονο που εμεινε τωρα ειναι να καταλαβω των κωδικα που χρειαζομαι για το μετα.
οταν βγαινω απο το Interrupt.αν παρακολουθουσες το θεμα απο την στιγμη που ξεκινησε ο φιλος να με βοηθαει εχω διαβασει αρκετα πραγματα μονος μου.
το οτι μιλησα για το σχηματικο το ειπα για να μπορουμε να συμβαδιζουμε.δηλαδη να μην μου λεει κανε αυτο και να το κανω και να μην παιζει.γιατι?γιατι εχω αλλο hardware εγω και αλλο αυτος(ειτε κανονικο ειτε στο νου του).
λες οτι ξεκινησα κατευθειαν στα βαθεια.αν δεις καλα στο forum με τη βοηθεια του φιλου DT200 και τον ευχαριστω πολυ σε αυτο εμαθα να χρησιμοποιω αρκετα την mikrobasic και επισης πως να ξεκινησω με απλα προγραμματα.και τα εχει βαλει για να τα εχουν οι πιο νεοι που θελουν να μαθουν πικ και την συγκεκριμενη γλωσσα.
δεν πηγα αν δεις καλυτερα κατευθειαν στα βαθεια.οπως επισης αν διαβαζες καλυτερα το ποστ θα εβλεπες οτι εχω προβλημα αγγλικων.γιαυτο και δυσκολευομε λιγο στα datasheet.σε αυτο φταιω εγω που καποτε αντι να πηγαινω αγγλικα επαιζα μπαλα...στερνη μου γνωση να σε ειχα πρωτα....τωρα αν εσυ αρχισες στο ποστ και μου την λες χωρις να εχεις καποιο σκοπο δεν ξερω.εχω εκανα ενα ποστ ζητησα καποια βοηθεια και οποιος ηθελε απαντουσε.καποιος βρεθηκε να απαντηση-να βοηθεισει.
εσυ αν καταφερες να κανεις οτι θες απο μονος σου μπραβο σου.
εγω δεν τα καταφερα.δεν ξερω ποσο χρονων εισαι και τι σχεση εχεις με τα πανεπιστημια σημερα αλλα αν το ψαξεις καλυτερα θα δεις οτι και αυτο που λες οτι κανουν δεν το κανουν.ουτε απλα την νοοτροπια των ηλεκτρονικων.
θες να σου πω ενα παραδειγμα? στη σχολη μου ηλεκτρονικη 2  ρωτησα μια απορια τον καθηγητη.που πιστευα την ηξερε,και μου λεει δεν το θυμαμαι τωρα ασε με να το δω και να σου πω στο επομενο.και στο επομενο που τον ξαναρωτησα μου λεει δεν ξερω.
ελπιζω τωρα να καταλαβες τι πτυχιο παιρνω.δεν ειμαι περιφανος για αυτο αλλα εγω δεν μπηκα στη σχολη να κανω μαθηματικους τυπους μονο αλλα να μαθω ηλεκτρονικα.
γιαυτο αμα δεν ξερεις πολλα μην στινεις τον αλλο στο τοιχο.
λοιπον.επειδη πηγε μακρια ολο αυτο σταματω το συχνομετρο.αν τα καταφερω μονος μου τα καταφερα και τελος.δεν θα κατσω αλλο να συζηταω τετοια.

----------


## bxenos

Λάθος κατάλαβες αυτά που είπα.
Ας αρχίσουμε απο την αρχή:
αν στη σχολή δεν είχες καλούς καθηγητές είχες ευθύνη και υποχρέωση να παραπονεθείς. Αν εμείς δεν αλλάξουμε την κατάσταση ποιός θα τι κάνει;
Εγώ έχω τσακωθεί με πολλούς καθηγητές για το λόγο αυτό. Οι γονείς μας τους πλήρωναν και έχουμε ευθύνη να αξιοποιούν το μισθό τους ορθά.

Το συχνόμετρο είναι πολύπλοκο και ένα μέρος απο το μπερδεμα που έχεις το εντοπίζω στο ότι δεν έχεις εμπειρία απο προγραμματισμό. Δηλαδή, να "κοψεις" σωστά την εργασία σε μικρότερες αυτόνομες (όσο το δυνατό) υποεργασίες. Δηλαδή πρώτα να βρείς το block διάγραμμα πως να κάνεις κάτι, και μετά να ξεκινησεις να το κάνεις.

----------


## billtech

που να παραππονεθω?αυτοι διδασκουν οτι πρεπει να διδαξουν.ασχετως αν ειναι χρησιμα η οχι.
το συστημα φταιει.γιαυτο ασε τι θα μπορουσε κανεις να κανει.ο καθε ενας τι κανει για τον εαυτο του.
αν διαβασεις επισης λεω καπου για το block διαγραμμα-διαγραμμα ροης.αλλα δεν το καναμε.
τι εμπειρια επισης να εχω οταν καναμε μονο led να αναβοσβηνουν και να τρεχουν?και κατι αλλες ψιλομακακιες.
αστο λοιπον να παει.

----------


## lastid

Εντάξει ρε παιδιά, αν πούμε και μία κουβέντα παραπάνω, άνθρωποι είμαστε. Ας μην μαλώνουμε. Μία παρέα είμαστε εδώ. Ο καθένας τα βλέπει από τη μεριά του και κάνουμε συζήτηση. Κυρίως για τα ηλεκτρονικά.
Πάντως είναι λογικό όταν κάποιος κάνει μία ερώτηση, να μη ξέρει πόση φασαρία κρύβει από πίσω της μία απάντηση μερικές φορές. Αλλά δεν θα πεθάνουμε κιόλας. Υπομονή και σιγά σιγά...

----------


## lastid

Bill, block διάγραμμα δεν κάναμε γιατί δεν ήταν σίγουρο τί θέλεις ακριβώς. Υπάρχουν πολλοί τρόποι για να γίνει κάτι. Και διαφορετικές προδιαγραφές. Π.χ. από την αρχή επιμένω ότι αν αλλάξεις PIC, θα κάνεις περισσότερα και με λιγότερο κόπο. Άρα είναι καλύτερα να γνωρίσεις τον PIC πρώτα και να δεις τους περιορισμούς του, πριν πάμε σε "τελική λύση". Είναι λίγο slow το ξέρω, αλλά έτσι πιστεύω ότι μαθαίνεις πραγματικά.

----------


## billtech

αυτο μην το λες σε εμενα με το block διαγραμμα.εγω δεν εκανα παραπονο για αυτο.
προτιμησα αυτον τον επεξεργαστη για ακριβως τον ιδιο λογο που διαβασα σημερα ολα αυτα.για να μαθω.γιατι αμα μαθω αυτον τοτε οπως ειπες και εσυ θα μου ειναι πολυ ευκολο να κανω με αλλον επεξεργαστη.οπως τον pic16f628 ας πουμε η τον 16f877A.
τεσπα.σε λιγο θα αναιβασω και το τελευταιο κομματι του κωδικα που εκανα ως τωρα απλα για να υπαρχει και τελειωνει εδω η post.
σε ευχαρισω πολυ για την βοηθεια.

----------


## billtech

```
program sixnometro

dim FREQNUM as integer
dim FREQTEXT as string[15]
dim ct as longint

sub procedure interrupt

              if INTCON.2 = 1 then
                 INTCON.2 = 0
                 ct = ct + 1
                 INTCON = $20
              end if

end sub

'set registers
 main:
     INTCON = %10100000
     OPTION_REG = %10001000
     TMR0 = 0
     Lcd_Config(PORTB,7,6,5,4,PORTB,2,1,3)
     LCD_Cmd(LCD_CLEAR)
     LCD_Cmd(LCD_CURSOR_OFF)
     ct = 0

sixnometro:
           'edo tha perno thn timh toy ct kai toy tmro kai toy prescaler kai tha vrisko tin sixnotita.
           'sinexeia tha ginete ayto gia kathe timi toy ct.opou ct einai oi fores pou ekane interupt o tmro

      end.
```


και οτι βγει βγηκε.

----------


## lastid

Πριν εκτελεστεί στην αρχή το 
 INTCON = %10100000
που ενεργοποιεί τα interrupts, πρέπει να έχεις ολοκληρώσει την αρχικοποίησή τους. Άρα πρώτα πρέπει να έχεις εκτελέσει τις εντολές που βάζουν αρχικές τιμές σε TMR0 και ct. Καλύτερα λοιπόν να βάλεις τιμή στην INTCON σαν τελευταία εντολή της αρχικοποίησης.

----------


## billtech

ok φιλε μου.
λοιπον αστο.θα τα βρω.σε εχυαριστω για την βοηθεια.
τα λεμε

----------


## bxenos

> που να παραππονεθω?αυτοι διδασκουν οτι πρεπει να διδαξουν.ασχετως αν ειναι χρησιμα η οχι.



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





> τι εμπειρια επισης να εχω οταν καναμε μονο led να αναβοσβηνουν και να τρεχουν?και κατι αλλες ψιλομακακιες.
> αστο λοιπον να παει.



Εχεις δίκιο για το πρόγραμμα σπουδων (βιβλία) του ΥΠΕΠΘ. Και σύμφωνα με ανακοινώσεις που βλέπω, τα πράγματα ίσως να χειροτερέψουν και άλλο, διότι προγραμματισμό πιά διδάσκουν μόνο ηλεκτρονικοί στους ηλεκτρονικούς (με ότι γνώσεις έχουν αυτοί) και όχι πληροφορικάριοι.

Συγνώμη αν σε στεναχώρησα δεν ήταν αυτός ο σκοπός μου. Γνωρίζοντας τον όγκο δουλειάς που έχει κάνει ο lastid για κάποιες απο τις απαντήσεις του (που μπορεί σε κάποιον τρίτο να φαίνονται απλές γιατι είναι λίγες γραμμές) και βλέποντας πόσο τραβά το νήμα, θεωρήσα χρήσιμο να παρέμβω. 

Εγώ δεν ξέρω (και ουτε θελω να μάθω) microbasic. Γι'αυτό και στο νήμα αυτό απάντησα μόνο στην απορία σου για τα interrupt. 
Συνεχίσε την εργασία και αν καπου μπορώ να σε βοηθήσω θα το κάνω.

----------


## billtech

διαβασες τα ιντεραπτ τα καταλαβα μονος μου σιγα σιγα μεσω του παραδειγματος που αναιβασα.
ειπες για βιβλια? ποια βιβλια?δεν υπαρχουν βιβλια.μονο σημειωσεις του καθηγητη.κανενα βιβλιο.
εγω δεν στεναχωριεμε μην ανυσηχεις.
οσο για να τους την πεις.αμα τους την πεις θα χρωστας πολυ καιρο το μαθημα τους. εχω πικρι πειρα απο αυτο.
γιαυτο ασε.

----------


## billtech

καλημερα.
αμα εχεις χρονο διαβασε το ηθικο διδαγμα που εγραψε ο φιλος lastid.
επισης διαβασε και τα 2-3 πρωτα ποστ μου.

τωρα στη κατασκευη.
για να βρουμε τη συχνοτητα θα πρεπει να πολλαπλασιασουμε:
1/(την τιμη του prescaler*TMR0*καταχωρητη που μετραει της φορες που εγινε Interrupt*255)
αυτο ομως παιζει και για τις χαμηλες και τις ψηλες συχνοτητες?
λογικα οχι.

----------


## lastid

Ο σωστός τύπος που δίνει τη συχνότητα είναι
*1/(τιμή_prescaler*(TMR0+καταχωρητής_που_μετράει_φορέ  ς_interrupts*256))*
Αυτό παίζει μόνο για *χαμηλές* συχνότητες, όπου ο TMR0 δουλεύει σαν timer και μετράμε από παλμό σε παλμό (δηλαδή περίοδο).

Στις *ψηλές* συχνότητες, ο TMR0 δουλεύει σαν counter και μετράμε παλμούς για ένα δευτερόλεπτο. Εκεί ο τύπος που δίνει τη συχνότητα είναι
*τιμή_prescaler*(TMR0+καταχωρητής_που_μετράει_φορές  _interrupts*256))*

Έστω ότι μετράω ψηλές συχνότητες και μου έρχεται ένα σήμα 2 Hz. Άρα ο TMR0 σε ένα δευτερόλεπτο θα μετρήσει 2 παλμούς, μπορεί και έναν μόνο. Αν το σήμα γίνει 1.9 Hz ο TMR0 θα μετρήσει πάλι 2 παλμούς, μπορεί και έναν μόνο. Άρα χάλια ακρίβεια. Όμως ο PIC θα το καταλάβει αυτό, γιατί θα δει ότι η συχνότητα είναι πολύ κοντά στο 0. Άρα θα κάνει ξανά την μέτρηση, αυτή τη φορά με τον τρόπο των χαμηλών. 
Έτσι θα έχουμε αυτόματη επιλογή τρόπου μέτρησης χαμηλών-ψηλών. 
Flowchart:



```
start_hi:
  Κάνε τον TMR0 counter
  Μηδένισε TMR0 και CT
  Ενεργοποίησε interrupts
  Περίμενε 1 sec
  FREQ = prescaler * (CT*256 + TMR0)
  Αν FREQ<1000 τότε πήγαινε start_lo
  τύπωσε FREQ
  Πήγαινε start_hi
start_lo:
  Κάνε τον TMR0 timer
  Περίμενε μέχρι η είσοδος να γίνει από low σε high
  Μηδένισε TMR0 και CT
  Ενεργοποίησε interrupts
  Περίμενε μέχρι η είσοδος να γίνει από low σε high
  FREQ = 1/( prescaler * (CT*256 + TMR0) )
   Αν FREQ > 1000 τότε πήγαινε start_hi
  τύπωσε FREQ
  Πήγαινε start_lo
```

----------


## billtech

λοιπον εκανα ενα κωδικα..αλλα δεν μπορω να τον δοκιμασω γιατι μου βγαζει οτι οτι δεν εχει αρκετη μνημη ο επεξεργαστης για να το μετατρεψει σε hex.
ποιο κατω βαζω τον κωδικα σε περιπτωση που καποιος εχει καποια ιδεα για το τι πρεπει να αφαιρεσω.εγω το προσπαθησα αλλα δεν καταφερα να το μικρινω αλλο.



```
program sixnometro

dim FREQNUM,ct as integer
dim FREQTXT as string[15]

sub procedure interrupt
              if INTCON.2 = 1 then
                 INTCON.2 = 0
                 ct = ct + 1
                 INTCON = $20
              end if
end sub

 main:
     Lcd_Config(PORTB,7,6,5,4,PORTB,2,1,3)
     LCD_Cmd(LCD_CLEAR)
     LCD_Cmd(LCD_CURSOR_OFF)
     
start_hi:
         option_reg=%00010100   'kane ton timer0  timer
         ct=0
         TMR0=0
         intcon=%10100000'         energopoiise ta interrupt
         delay_ms(1000)
         FREQNUM=32*(ct*256=TMR0)
         if FREQNUM<1000 then goto start_lo
           goto conv
           end if
         goto start_hi
         
start_lo:
         option_reg=%00110100'         kane to TMR0 counter
         delay_us(100)         'perimene mexri i eisodos na ginei apo low se high
         ct=0
         TMR0=0
         intcon=%10100000'         energopoiise ta interrupt
         delay_us(100)'         perimene mexri i eisodos na ginei apo low se high
         FREQNUM=1/(32*(ct*256+TMR0))
         if FREQNUM>1000 then goto start_hi
            goto conv
           end if
         goto start_lo
         
conv:    IntTostr(FREQNUM,FREQTXT)
         LCD_OUT(1,1,FREQTXT)
         
      end.
```

----------


## lastid

Ήμουνα μερικές μέρες εκτός....
Λοιπόν, μπορώ να το κοιτάξω καλύτερα αύριο, αλλά με μία πρώτη ματιά:
- Αντί για 32*(ct*256=TMR0), θέλει 32*(ct*256+TMR0)
- Οι δύο γραμμές με τα μαθηματικά (FREQNUM=....), μάλλον ευθύνονται για την παραγωγή αρκετών εντολών. Αν είναι έτσι, μπορούν να γίνουν αλλιώς, με πολύ λιγότερες εντολές. Για να σιγουρευτείς, μπορείς να εντοπίσεις τον κώδικα που παράγουν μέσα στο .LST αρχείο και να τον γράψεις εδώ ώστε να δούμε αν είναι έτσι?

----------


## billtech

το = καταλαθος μπηκε.
δεν μπορω να βρω το .LST γιατι δεν μου μετατρεπει τιποτα. μου βγαζει αυτο:
1:1 E-0 Linker error: NOT ENOUGH ROM

----------


## lastid

Για να σου βγάλει τότε .LST και να μπορέσεις να εξετάσεις τα επίμαχα σημεία, πετσόκοψε το πρόγραμμα κάνοντας σχόλια μερικές γραμμές, π.χ. ότι έχει σχέση με το lcd.
Με την τεχνική αυτή, θα μπορείς να υπολογίσεις τα bytes που σου πιάνει κάθε γραμμή και κατόπιν να αποφασίσεις τί πρέπει να ξαναγραφτεί ή να αφαιρεθεί.

----------


## billtech

> Για να σου βγάλει τότε .LST και να μπορέσεις να εξετάσεις τα επίμαχα σημεία, πετσόκοψε το πρόγραμμα κάνοντας σχόλια μερικές γραμμές, π.χ. ότι έχει σχέση με το lcd.
> Με την τεχνική αυτή, θα μπορείς να υπολογίσεις τα bytes που σου πιάνει κάθε γραμμή και κατόπιν να αποφασίσεις τί πρέπει να ξαναγραφτεί ή να αφαιρεθεί.



για κοιτα αυτα εδω.



```
program sixnometro

dim FREQNUM,ct as integer
dim FREQTXT as string[15]

sub procedure interrupt
              if INTCON.2 = 1 then
                 INTCON.2 = 0
                 ct = ct + 1
                 INTCON = $20
              end if
end sub

 main:
     'Lcd_Config(PORTB,7,6,5,4,PORTB,2,1,3)
'     LCD_Cmd(LCD_CLEAR)
'     LCD_Cmd(LCD_CURSOR_OFF)
     
start_hi:
         option_reg=%00010100   'kane ton timer0  timer
         ct=0
         TMR0=0
         intcon=%10100000'         energopoiise ta interrupt
         delay_ms(1000)
         FREQNUM=32*(ct*256+TMR0)
         if FREQNUM<1000 then goto start_lo
           goto conv
           end if
         goto start_hi
         
start_lo:
         option_reg=%00110100'         kane to TMR0 counter
         delay_us(100)         'perimene mexri i eisodos na ginei apo low se high
         ct=0
         TMR0=0
         intcon=%10100000'         energopoiise ta interrupt
         delay_us(100)'         perimene mexri i eisodos na ginei apo low se high
         FREQNUM=1/(32*(ct*256+TMR0))
         if FREQNUM>1000 then goto start_hi
            goto conv
           end if
         goto start_lo
         
'conv:    IntTostr(FREQNUM,FREQTXT)
        ' LCD_OUT(1,1,FREQTXT)

         
      end.
```


τα ' ειναι σχολια

και σου επισυναπτω το LST

----------


## lastid

Οκ, το είδα.
Τη ζημιά την κάνει η διαίρεση ..1/(32*...
Αν κοιτάξεις μέσα στο listing, ο compiler προκειμένου να κάνει τη διαίρεση που θέλεις, φτιάχνει δύο ρουτίνες, την _div_16x16_s και την _div_16x16_s_l που πιάνουν πολλά words μνήμης.
Πρέπει να ξαναγραφτεί η γραμμή χωρίς διαίρεση 16 bits - λίγο δύσκολο. Μία λύση είναι στην περίπτωση αυτή να μην κάνεις καθόλου τη διαίρεση για μετατροπή σε Hz, αλλά να δίνεις το αποτέλεσμα κατευθείαν σε milliseconds ή seconds.

Κάτι άλλο: Συγκρίνοντας το πρόγραμμα με το flowchart, βλέπουμε ότι πρέπει 
α) o TMR0 να χρησιμοποιηθεί σαν counter στην start_hi και σαν timer στην start_lo, δηλαδή ανάποδα
β) Στην start_lo, στα δύο σημεία που λέμε "περίμενε μέχρι η είσοδος..κλπ" πρέπει να μπει η κατάλληλη εντολή, αντί της delay. Μπορεί π.χ. να γραφτεί κάτι σαν 
repeat until PORTA.4=0
και
repeat until PORTA.4=1
Επειδή όμως η είσοδος μπορεί να διακοπεί όσο είμαστε μέσα στο repeat, το πρόγραμμά μας θα κολλήσει εκεί μέσα. Πρέπει λοιπόν να βάλουμε κι έναν τρόπο να ξεκολλήσει σε αυτή την περίπτωση του timeout. Αυτό μπορεί να γίνει εύκολα με το watchdog.

----------


## billtech

Λοιπον κοιτα αυτο.
το εκανα και μου το ετρεξε κανονικα και εκανε το hex με τις αλλαγες που εκανα.
κοιταξε το αν μπορεις και μου λες.
εκανα και τις διορθωσεις που μου ειπες με ενα αλλο τροπο απο αυτον που προτινες.για κοιταξε τον αν μας κανει.



```
program sixnometro

dim FREQNUM,ct,h as integer
dim FREQTXT as string[15]

sub procedure interrupt
              if INTCON.2 = 1 then
                 INTCON.2 = 0
                 ct = ct + 1
                 INTCON = $20
              end if
end sub

 main:
     Lcd_Config(PORTB,7,6,5,4,PORTB,2,1,3)
     LCD_Cmd(LCD_CLEAR)
     LCD_Cmd(LCD_CURSOR_OFF)
     
start_hi:
         option_reg=%00110100       'kane to TMR0 counter
         ct=0
         TMR0=0
         intcon=%10100000           'energopoiise ta interrupt
         delay_ms(1000)
         goto calc
         if FREQNUM<1000 then goto start_lo
           goto conv
           end if
         goto start_hi
         
start_lo:
         option_reg=%00010100                               'kane ton timer0  timer
l0:      if porta.4=0 then goto l1 else goto l0   end if     'perimene mexri i eisodos na ginei apo low se high
l1:      ct=0
         TMR0=0
         intcon=%10100000                                         'energopoiise ta interrupt
l3:      if porta.4=1 then goto l4 else goto l3    end if         'perimene mexri i eisodos na ginei apo low se high
l4:      goto calc
         h=1/FREQNUM
         if h>1000 then goto start_hi
            goto conv1
           end if
         goto start_lo

conv:    IntTostr(FREQNUM,FREQTXT)
         LCD_OUT(1,1,FREQTXT)
         Return
         
conv1:   IntTostr(h,FREQTXT)
         LCD_OUT(1,1,FREQTXT)
         Return
         
calc:    FREQNUM=32*(ct*256+TMR0)
         return

         
      end.
```

----------


## lastid

Χωρίς να είμαι 100% σίγουρος (λόγω έλλειψης χρόνου και γνώσης Mikrobasic):



```
program sixnometro


symbol SET_AS_COUNTER = option_reg = %00110100     'TMR0=Counter, diairei toys palmoys eisodoy dia 32
symbol SET_AS_TIMER   = option_reg = %00010100     'TMR0=Timer, me krystallo 4MHz metraei 1MHz dia 32 = 31250Hz
symbol INTERRUPTS_ON  = intcon = %10100000
symbol INTERRUPTS_OFF = intcon = %00000000

dim FREQNUM,ct,h as word  ' 0..65535
dim FREQTXT as string[15]

sub procedure interrupt
              if INTCON.2 = 1 then
                 INTCON.2 = 0
                 ct = ct + 1
              end if
end sub

 main:
     Lcd_Config(PORTB,7,6,5,4,PORTB,2,1,3)
     LCD_Cmd(LCD_CLEAR)
     LCD_Cmd(LCD_CURSOR_OFF)
     
start_hi:
         SET_AS_COUNTER
         ct=0
         TMR0=0
         INTERRUPTS_ON
         delay_ms(1000)
         INTERRUPTS_OFF
         gosub calc
         FREQNUM = FREQNUM << 5   ' FREQNUM = 32 * FREQNUM
         if FREQNUM<1000 then goto start_lo end if
         gosub conv
         goto start_hi
         
start_lo:
         SET_AS_TIMER
waitfor1:if porta.4=0 then goto waitfor1  end if     'perimene mexri i eisodos na ginei apo low se high
         ct=0
         TMR0=0
         INTERRUPTS_ON
waitfor0:if porta.4=1 then goto waitfor0  end if         'perimene mexri i eisodos na ginei apo high se low
         gosub calc
         FREQNUM =31250/FREQNUM    ' FREQNUM = 1000000 / (32 * FREQNUM)
         if FREQNUM>1000 then goto start_hi
         gosub conv
         goto start_lo

conv:    IntTostr(FREQNUM,FREQTXT)
         LCD_OUT(1,1,FREQTXT)
         Return
               
calc:    FREQNUM = ct << 8 +TMR0
         return
        
      end.
```


Δες αν γίνεται compile.

----------


## billtech

ετσι οπως ειναι δεν γινεται.αμα κανω σαν σχολια την αρχικοποιηση της LCD γινετε.αλλιως λεει δεν εχει ROM παλι.
μπορεις να μου εξηγησης σε παρακαλω τι εννοεις με τισ πραξεις που κανεις? για να καταλανω το <<? αυτο ολισθηση δεν ειναι μονο?

----------


## lastid

Ολίσθηση αριστερά/δεξιά κάνουμε όταν θέλουμε να πολλαπλασιάσουμε/διαιρέσουμε με αριθμό που είναι δύναμη του 2. Είναι ο πιο γρήγορος και πιο μικρός (σε εντολές) τρόπος.
Κατέβασα την Mikrobasic και κοιτάζω την assembly που παράγει. Δεν βγάζει και λίγα... 
Μέχρι στιγμής βλέπω ότι πιάνουν πολλά bytes a) οι lcd ρουτίνες b) η inttostr και c) η διαίρεση. Θα κάνω λίγες δοκιμές και θα σου πώ.

----------


## lastid

Έλα, το βρήκα.
Αντί για inttostr(), χρησιμοποίησε την wordtostr().  
Το 21% της μνήμης προγράμματος του PIC δεσμευόταν από αυτή την εντολή, γιατί ο compiler πρόσθετε ένα κάρο εντολές για αριθμητική με πρόσημο, ενώ όλοι οι ακέραιοι που χρησιμοποιούμε είναι θετικοί.

----------


## lastid

Έκδοση με μικροαλλαγές για να είναι πιο ευανάγνωστη και χωρίς να κολλάει αν διακόψουμε την είσοδο  σε χαμηλές συχνότητες:



```
program sixnometro

symbol SET_AS_COUNTER = option_reg = %00110100     'TMR0=Counter, diairei toys palmoys eisodoy dia 32
symbol SET_AS_TIMER   = option_reg = %00010100     'TMR0=Timer, me krystallo 4MHz metraei 1MHz dia 32 = 31250Hz
symbol INTERRUPTS_ON  = intcon = %10100000
symbol INTERRUPTS_OFF = intcon = %00000000

dim FREQNUM,ct as word  ' 0..65535

sub procedure interrupt ' timer interrupt
              if INTCON.2 = 1 then  ' timer interrupt
                 INTCON.2 = 0
                 if ct<255 then ' bale orio sto metrhma
                     ct = ct + 1
                     end if
              end if
    end sub

sub procedure calc_freq
    FREQNUM = ct << 8 +TMR0
    end sub

sub procedure display_freq ' steile to FREQNUM sto lcd
    dim FREQTXT as string[15]
    wordTostr(FREQNUM,FREQTXT)
    LCD_OUT(1,1,FREQTXT)
    end sub

main:
     Lcd_Config(PORTB,7,6,5,4,PORTB,2,1,3)
     LCD_Cmd(LCD_CLEAR)
     LCD_Cmd(LCD_CURSOR_OFF)

start_hi:
         SET_AS_COUNTER
         ct=0
         TMR0=0
         INTERRUPTS_ON
         delay_ms(1000)
         INTERRUPTS_OFF
         calc_freq
         FREQNUM = FREQNUM << 5   ' FREQNUM = 32 * FREQNUM
         if FREQNUM<1000 then goto start_lo end if
         display_freq
         goto start_hi

start_lo:
         SET_AS_TIMER
         while (porta.4=0) and (ct < 255) wend ' perimenoyme gia 0->1 h timeout
         ct=0
         TMR0=0
         INTERRUPTS_ON
         while (porta.4=1) and (ct < 255) wend ' perimenoyme gia 1->0 h timeout
         calc_freq
         FREQNUM =31250/FREQNUM    ' FREQNUM = 1000000 / (32 * FREQNUM)
         if FREQNUM>1000 then goto start_hi end if
         display_freq
         goto start_lo

end.
```

----------


## billtech

Καλησπερα φιλε μου.
σε ευχαριστω για τον κωδικα σου και για τον χρονο σου.
θα το δοκιμασω οσο ποιο συντομα μπορω γιατι η ατυχια μου χτυπησε και παλι την πορτα.
ειχα κανει το σχηματικο που μου εδωσε ο Επιστημων και φωρτωσα τον κωδικα που ειχε μαζι για να δω οτι παιζει και μετα να το αντικαταστησω με το δικο μας.δυστυχως ομως μετα απο ενα βραχυκυκλωμα που εκανε ενας φιλος μου πανω στο κυκλωματακι καηκε η LCD 1X16!!! συνεπως πρεπει να παραγγειλω αλλη και θα μου παρει μερες αυτο.
θα παραγγειλω συντομα ομως.

μπορεις σε παρακαλω με ενα παραδειγμα να μου δειξεις πως γινονται πο πραξεις  με το shift?αν εχεις χρονο βεβαια.
δηλαδη πες οτι μετρα ψηλες.και μετα το interrups_off βλεπει οτι το ct εχει τιμη 158. τι γινετε μεσα στην calc_freq?
και τι γινεται στη  FREQNUM = FREQNUM << 5   ' FREQNUM = 32 * FREQNUM

----------


## lastid

Κάθε shift προς τα αριστερά κατά 1 ισοδυναμεί με πολλαπλασιασμό επί δύο.
Άρα ένα shift προς τα αριστερά N φορές ισοδυναμεί με πολλαπλασιασμό επί δύο εις την Ν.

Στο παράδειγμα που αναφέρεις:
Έστω ότι ct=158 και TMR0 =3.
calc_freq: 
FREQNUM = 158 << 8 + 3 = 158*2^8 + 3 = 158*256+3 = 40448 + 3 = 40451
Κατόπιν:
FREQNUM = 40451 << 5 = 40451 * 2^5 = 40451 * 32 = 1294432
Εδώ όμως θα έχουμε πρόβλημα γιατί η FREQNUM είναι word, άρα πάει μέχρι 65535 το πολύ, άρα το αποτέλεσμα δεν θα χωρέσει στα 16 bits. Θα έχουμε overflow, θα χαθούν bits και θα δείξει λάθος αποτέλεσμα.
Πώς το λύνουμε?
α) Περιορίζουμε την περιοχή μέτρησης μέχρι τα 2ΚΗz περίπου (μπλιαχ!)
β) Χρησιμοποιούμε 32-bit μεταβλητές αντί για 16-bit (θα χωρέσει στον PIC?)
γ) Χρησιμοποιούμε κρύσταλλο 4.194.304 Hz αντί για 4.000.000 Hz και αντί για <<5 στο τέλος, κάνουμε >>5 και δείχνουμε την συχνότητα σε KHz αντί για Hz (δηλαδή δηλαδή??)

----------


## billtech

και αμα σου πω δεν εχω ιδεα?
θα πω ομως μια μακακια και βλεπουμε.
αν το  FREQNUM = 158 << 8 + 3 = 158*2^8 + 3 = 158*256+3 = 40448 + 3 = 40451 
το κανουμε δια 1000 και μετα το πολλαπλασιασουμε με το  FREQNUM = 40451 << 5
δεν θα ειναι σε kHz μετα η απαντηση μας?δεν θα μας κανει?

----------


## lastid

Σωστό κι αυτό. Ξέχασα να το αναφέρω σαν δ) και ουσιαστικά είναι παραλλαγή του γ).
Βλέπω επίσης ότι η Mikrobasic έχει ένα πρόβλημα στην ένωση strings, π.χ. ήθελα να κολλήσω ένα " KHz" στο τέλος και μου έβγαζε λάθος.
Πάντως το επόμενο βήμα λογικά είναι το autorange που λύνει εν μέρει προβλήματα overflow και underflow. 
Δηλαδή, αντί για 2 ενότητες μόνο (start_lo και start_hi), μπορείς να βάλεις περισσότερες (low11,low2,low3,high1,high2.high3,high4) και να πηδάς από την κάθε μία στην διπλανή της όταν η FREQNUM ξεπερνά κάποιο άνω ή κάτω όριο, όπως ακριβώς γίνεται τώρα με την start_lo και start_high. Η κάθε ενότητα θα βάζει διαφορετική τιμή στον διαιρέτη (που τώρα είναι καρφωτός στο 32) και θα έχει διαφορετικό delay_ms.

----------


## billtech

κατσε σωστο δεν ειπες ειναι και αυτο που ειπα?
γιατι μπορει να το ργραψα σαν μαλακια αλλα το σκεφτηκα και λιγο.
και νομιζω ειναι σωστο.

αφου εχεις βαλει περιορισμο στο ct εως το 255 τοτε με ενα 1000 και μετα επι 32 εχουμε το αποτελεσμα που μας κανει.ε?
και θα εμφανιζετε σαν kHz και αμα θελουμε βαζουμε και υποδιαστολες μονιμες στην LCD μας..

----------


## billtech

παιδια μπορω το συχνομετρο που εκανα να το βαλω να μετρησω την συχνοτητα της ΔΕΗ? πρεπει να βαλω καποια προστασια μπροστα?

----------

