PDA

Επιστροφή στο Forum : Περι CCS...



Lykos1986
06-01-06, 21:13
Ρε gsm μπορείς να μου στείλεις τον κώδικα από ένα μικρό παράδειγμα πάνω στην ccs (πχ για τον 16F628 να ανάψει ένα led σε κάποιο pin);;;

Κατάλαβα αρκετά πράγματα από τα παραδείγματα που έχει αλλά τα έχω μπερδέψει λίγο με τις εντολές προ-επεξεργαστή (Αυτές δηλαδή με το # μπροστά. Πολλά παραδείγματα για παράδειγμα έχουν μέσο δομών else-if πολλούς μC κτλ) και θέλω κάτι αρκετά γελοίο για να δω ώστε να εκκινήσω!!!

gsmaster
07-01-06, 00:41
#include <16F628.H>
#fuses XT,NOWDT,NOPUT,NOPROTECT,NOBROWNOUT,MCLR,NOLVP,NOC PD
#use delay&#40;clock=4000000&#41; // 4 MHz OSC

void main&#40;&#41;
&#123;

do&#123;

output_high&#40;pin_b0&#41;;
delay_ms&#40;500&#41;;
output_low&#40;pin_b0&#41;;
delay_ms&#40;500&#41;;

&#125;while&#40;1&#41;


&#125;




Δεν δοκίμασα να το κάνω compile γιατί δεν έχω τπτ εγκατεστημένο εδώ. Τα fuses τα πήρα απο ένα παλιό backup που έχω εδώ απο μια κατασκευή με τον 628.

Τα fuses τα ρυθμίζεις ανάλογα με την λειτουργεία που θες και σε κάθε Pic έχουν μικροδιαφορές. Για να δεις πώς θα τα ρυθμίσεις, στο παράθυρο της CCS πας view->Valid fuses και πράτεις αναλόγως.

Lykos1986
04-02-06, 11:01
Λοιπόν έγραψα τον παρακάτω κώδικα:


#include <16F628.H>
#fuses XT,NOWDT,NOPUT,NOPROTECT,NOBROWNOUT,MCLR,NOLVP,NOC PD
#use delay&#40;clock=4000000&#41; // 4 MHz OSC

void main&#40;&#41;
&#123;
setup_adc&#40;adc_clock_internal&#41;;
setup_adc_ports&#40;all_analog&#41;;
do
&#123;
set_adc_channel&#40;0&#41;;
x=read_adc&#40;&#41;;
output_b&#40;x&#41;;
&#125;while&#40;1&#41;;
&#125;

αλλά μου βγάζει πρόβλημα σε όλες τις εντολές που έχουν μέσα τους την λέξη adc. Που έχω κάνει λάθος;;;

gsmaster
04-02-06, 14:15
- Δεν έχεις ορίσει τον καταχωρητή x
- Τα setup_adc τα είχες ανάποδα αλλά δεν ξέρω αν επηρρεάζει.
- Δεν χρειάζεται κάθε φορά να επιλέγεις το adc κανάλι αφού δεν τον αλλάζεις.



#include <16F628.H>
#fuses XT,NOWDT,NOPUT,NOPROTECT,NOBROWNOUT,MCLR,NOLVP,NOC PD
#use delay&#40;clock=4000000&#41; // 4 MHz OSC

int x;

void main&#40;&#41;
&#123;
setup_adc_ports&#40;all_analog&#41;;
setup_adc&#40;adc_clock_internal&#41;;
set_adc_channel&#40;0&#41;;

do
&#123;
x=read_adc&#40;&#41;;
output_b&#40;x&#41;;
&#125;while&#40;1&#41;;
&#125;





Μην ξεχνάς ότι έτσι όπως είναι τώρα, διαβάζει το adc με 8bit. Αν το αυξήσεις, θα πρέπει να αλλάξεις και τον καταχωρητή x σε int16 αλλά μετά στην potrtb θα παίρνεις μόνο τα 8 LSB ψηφία.

Τις έκανα τις αλλαγές και δοκίμασα να το κάνω compile αλλά δεν έγινε.
Τα errors οφείλονται στο ότι στο 16F628.H δεν αναφέρονται οι εντολές του adc, δεν ξέρω γιατί όμως... πχ δες στο 16F88.h κάπου έχει μια ενότητα με τα πάντα για το adc. Η λύση που σου προτείνω είναι να πας σε άλλο pic, ούτως η άλλως τα 2K μνήμης του θα γεμίσουν εύκολα αν κάνεις κάποια όχι και τόσο περίπλοκη εφαρμογή.

Lykos1986
04-02-06, 17:41
Θα δοκιμάσω τον 16F88 που μου είπες. Νομίζω πως έχω έναν. Οσο για τα παρακάτω:

- Δεν έχεις ορίσει τον καταχωρητή x
- Δεν χρειάζεται κάθε φορά να επιλέγεις το adc κανάλι αφού δεν τον αλλάζεις.

Είναι λάθη βιασύνης, αλλά για το:

- Τα setup_adc τα είχες ανάποδα αλλά δεν ξέρω αν επηρεάζει

Νομίζω πως σε ένα παράδειγμα τα είχα δει με αυτήν την σειρά.
Τέλος πάντων, θα κάνω μια δοκιμή με τον άλλο μC και θα σου πω νεότερα.

Lykos1986
15-02-06, 22:27
Ακόμα μια ερώτηση!

Σε ένα πρόγραμμα γραμμένο για την CCS χρησιμοποιούμε έναν driver. Ο driver από την κατασκευή του ορίζει κάποια pins επικοινωνίας με την συσκευή που χειρίζεται. Πώς θα αλλάξω τα pins, με αυτά που θέλω εγώ;;; Για παράδειγμα οι περισσότεροι drivers χρησιμοποιούν pins της πόρτας B και εγώ θέλω να χρησιμοποιώ τον driver από pins της πόρτας Α. Πώς θα γίνει αυτό. Θα πρέπει να πειράξω τον diver στο σημείο που ορίζει τα pins (σε μερικούς λίγο δύσκολο) ή μπορώ να το κάνω από το πρόγραμμα που εγώ γράφω. Κάπου είδα πως το κάνουν με χρήση της εντολής #define “όνομα αρχικού pin” “όνομα pin που θέλουμε”.

Ισχύει κάτι τέτοιο;;;

Κανένα παράδειγμα;;;

gsmaster
16-02-06, 01:28
Βασικά είναι:
#define onoma PIN_b0

όπου onoma βάζεις ότι θες, και όπου PIN_b0 είναι το πίν στο οποίο αντιστοιχείς το όνομα αυτό.
ΠΧ αντί να λές:
output_high(PIN_b0);
λες απλά
output_high(onoma);

o compiler αντιστοιχίζει το όνομα με το πιν για να μην χρειάζεται να θυμάσαι πιο πιν είναι τι.

Και ναί μπορείς να το αλλάξεις απο το αρχείο του driver, αλλά πρόσεξε να το βάλεις στον ίδιο φάκελο με το .c αρχείο σου πριν το αλλάξεις, γιατί αν το αφήσεις στον φάκελο drivers που είναι κανονικά, σε επόμενο project θα πρέπει να το ξανααλλάεξις και δεν θα δουλεύει με το πρώτο πρόγραμμα, και θα γίνει χαμός.

Σε ορισμένα αρχεία πχ lcd.c και στο lcd420.c ορίζει μια πόρτα σαν ένα byte και μετά δίνει ονόματα στα πινς, και είναι λίγο παράξενο να το καταλάβεις...

EDIT Ξέχασα να σου πώ ότι το PIN_b0 κτλ δεν είναι τυχαίο όνομα, όλα τα πιν και όλες οι πόρτες έχουν ήδη ονομαστεί στο αρχείο .h του μΕ (πχ: 16F628.h)

Lykos1986
16-02-06, 09:35
ΟΚ, κατάλαβα!!! Θέλω να κάνω τις αλλαγές γιατί μου την έχουν σπάσει οι drivers που συνδέονται κατά 90% στην πόρτα Β και κατά 10% στην πόρτα D. Γιατί, η πόρτα Α δεν έχει ψυχή!!!!!!

Lykos1986
19-03-06, 15:48
Μπορεί κάποιος να μου πει τι συμβαίνει με την CCS και τον 16F628!!!!!!!!

Σχεδόν ποτέ δεν μπόρεσα να δουλέψω έναν driver κανονικά. Έκανα πειράματα με τον DS1868. Στην αρχή όλα καλά, μετά το σύστημα τρελαίνεται!!! Με DS1302 το ίδιο!!! Πάω να οδηγήσω κλασική οθόνη 2*16 HD44780. Το αποτέλεσμα είναι να μπορώ να γράψω μόνο στην πρώτη γραμμή και με τίποτα στην δεύτερη!!!!!!!!! Πάω να χρησιμοποιήσω τον εσωτερικό ADC και το αποτέλεσμα είναι πως δεν υπάρχουν οι ρουτίνες για να γίνει κάτι τέτοιο!!! Αν είναι δυνατόν!!!! Με όλους τους άλλους μC (16F88, 16F876, 16F877) όλα τα παραπάνω δουλεύουν κανονικά. Και να πώ πως ο 628 είναι κάποιος περίεργος μC, από τους πιο πολυχρησιμοποιημένους της Microchip. Υπάρχει κανένα κόλπο για να λειτουργήσει ο 628, το οποίο δεν το ξέρω;;;

gsmaster
19-03-06, 15:55
Ίσως κάτι να παίζει στο hardware σου ή και στα fuses που χρησιμοποιείς για τον 628. Επίσης υπάρχει ο 628 και 628Α για δες ποιο έχεις και ποιό έχεις επιλέξει στον compiler...

Ε κι εσύ, κόλλησες στον 628, τόσα PIC βγάζει η Microchip....

Lykos1986
19-03-06, 20:09
100% κανένα πρόβλημα στο hardware, κανένα πρόβλημα στα fuses, και τέλος τα προβλήματα δημιουργούνται και στα δύο μοντέλα του 628, Α και μη!!!

Κόλλησα στον 628 γιατί είναι ο καλύτερος για μερικές εφαρμογές. Ούτε με πολλά pins αλλά και με αρκετές δυνατότητες.

Lykos1986
07-06-06, 23:04
Ποιά είναι η εντόλή nop ή null στην CCS;

gsmaster
07-06-06, 23:14
delay_cycles&#40; 1 &#41;; // Same as a NOP

Κι εγώ δεν το ήξερα, τώρα το βρήκα στο help :)

Lykos1986
08-06-06, 19:20
Έχω τον παρακάτω κώδικα ή μάλλον ένα μέρος του κώδικα αλλά δεν μπορώ να τον δοκιμάσω για να δω την ως τώρα σωστή λειτουργία. Ο κώδικας είναι:


#include <16F876>
#fuses NOWDT, XT, PUT, NOPROTECT, NOBROWNOUT, NOLVP,NOCPD, NOWRT
#use delay &#40;clock = 4000000&#41; //4Mhz external crystal

void up_rutine&#40;&#41;;
void down_rutine&#40;&#41;;



void main &#40;&#41;
&#123;

int x;
x = 0;

setup_adc_ports&#40;all_analog&#41;;
setup_adc&#40;adc_clock_internal&#41;;
set_adc_channel&#40;x&#41;;
output_high&#40;pin_c1&#41;;


while&#40;1&#41;
&#123;
output_low&#40;pin_c0&#41;;
delay_ms&#40;100&#41;;

output_b&#40;read_adc&#40;&#41;&#41;;

if &#40;!input&#40;pin_c7&#41;&#41;
up_rutine&#40;&#41;;
if &#40;!input&#40;pin_c6&#41;&#41;
down_rutine&#40;&#41;;

output_high&#40;pin_c0&#41;;
delay_ms&#40;100&#41;;
&#125;

&#125;

void up_rutine&#40;&#41;;
&#91;b&#93;&#123;&#91;/b&#93;
x=x+1;
//&#228;&#239;&#236;&#222; &#227;&#233;&#225; &#244;&#225; led
if &#40;x==6&#41;
x=0;
set_adc_channel&#40;x&#41;;
while &#40;!input&#40;pin_c7&#41;&#41;
&#123;
delay_cycles&#40;1&#41;;
&#125;
&#125;

void down_rutine&#40;&#41;;
&#123;
x=x-1;
//&#228;&#239;&#236;&#222; &#227;&#233;&#225; &#244;&#225; led
if &#40;x<0&#41;
x=5;
set_adc_channel&#40;x&#41;;
while &#40;!input&#40;pin_c6&#41;&#41;
&#123;
delay_cycles&#40;1&#41;;
&#125;
&#125;


Το πρόβλημα που μου βγάζει είναι ότι: Expecting a declaration και το εμφανίζει στο σημείο που φαίνεται με έντονο χρώμα στον κώδικα. Το πιο πιθανό είναι να έχω κάνει κάποια μαλ**ια με την μεταβλητή αλλά δεν μπορώ να καταλάβω τι!!!

gsmaster
09-06-06, 01:33
void up_rutine&#40;&#41;;
Βγάλε το ερωτηματικό (;) απο το τέλος.
το ίδιο και παρακάτω, στο άλλο void.....

Lykos1986
09-06-06, 13:21
Τα ερωτηματικά τα έβαλα γιατί αν δεν κάνω λάθος τα ζητάει το πρωτόκολλο ANCI C. Μάλλον η CCS δεν θα είναι 100% ANCI C!!!

Το πρόβλημα είναι πως ακόμα και αν βγάλω το ερωτηματικό θα έχω πάλι πρόβλημα το οποίο είναι:

Function definition different from definition up_rutine Param#1

Και το εμφανίζει στην up_rutine που αναφέρεις.

gsmaster
09-06-06, 16:44
Το ερωτηματικό δεν χρειάζεται. τώρα το "Function definition different from definition up_rutine Param#1" ίσως να προκλήθηκε επειδή ορίζεις τις υπορουτίνες στην αρχή και μετά τις γράφεις.



Αυτό compilarεται μια χαρά σε μένα με αστεράκια είναι οι αλλαγές που χρειάστηκαν


#include <16F876> //**************************#include <16F876> einai to swsto alla trwei to .h
#fuses NOWDT, XT, PUT, NOPROTECT, NOBROWNOUT, NOLVP,NOCPD, NOWRT
#use delay &#40;clock = 4000000&#41; //4Mhz external crystal

//void up_rutine&#40;&#41;;
//void down_rutine&#40;&#41;;


int x; //******************************

void main &#40;&#41;
&#123;

x = 0;

setup_adc_ports&#40;all_analog&#41;;
setup_adc&#40;adc_clock_internal&#41;;
set_adc_channel&#40;x&#41;;
output_high&#40;pin_c1&#41;;


while&#40;1&#41;
&#123;
output_low&#40;pin_c0&#41;;
delay_ms&#40;100&#41;;

output_b&#40;read_adc&#40;&#41;&#41;;

if &#40;!input&#40;pin_c7&#41;&#41;
up_rutine&#40;&#41;;
if &#40;!input&#40;pin_c6&#41;&#41;
down_rutine&#40;&#41;;

output_high&#40;pin_c0&#41;;
delay_ms&#40;100&#41;;
&#125;

&#125;

void up_rutine&#40;&#41; //**************************
&#123;
x=x+1;
//&#228;&#239;&#236;&#222; &#227;&#233;&#225; &#244;&#225; led
if &#40;x==6&#41;
x=0;
set_adc_channel&#40;x&#41;;
while &#40;!input&#40;pin_c7&#41;&#41;
&#123;
delay_cycles&#40;1&#41;;
&#125;
&#125;

void down_rutine&#40;&#41; //**************************
&#123;
x=x-1;
//&#228;&#239;&#236;&#222; &#227;&#233;&#225; &#244;&#225; led
if &#40;x<0&#41;
x=5;
set_adc_channel&#40;x&#41;;
while &#40;!input&#40;pin_c6&#41;&#41;
&#123;
delay_cycles&#40;1&#41;;
&#125;
&#125;

Lykos1986
09-06-06, 22:29
Θα τρελαθώ!!! Ποια έκδοση του compiler έχεις; Σε εμένα δεν κάνει compile Με τίποτα!!!! :head:

Lykos1986
10-06-06, 14:40
Έβαλα την καινούρια έκδοση του Compiler και προσπάθησα να κάνω compile τον δικό σου κώδικα. Ούτε αυτός δούλευε αν και μπορώ να πω πως το περίμενα αφού δεν μπορεί να χρησιμοποιήσεις μια δικιά σου συνάρτηση χωρίς πρώτα να την δηλώσεις. Οπότε έπρεπε να μπουν υποχρεωτικά τα void up_rutine(); και void down_rutine();. Το σφάλμα που παρήγαγε αν δεν τοποθετούσα τις παραπάνω εντολές ήταν ότι ο κώδικας των συναρτήσεων έπρεπε να δηλωθεί κάπου.

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

Ο τελικός λειτουργικός κώδικας είναι έτσι. Καντόνα ένα compile για να δούμε τι θα κάνει σε εσένα γιατί από ότι μου είπες και ο προηγούμενος δουλεύει αλλά σε εμένα δεν έκανε τίποτα!!! Περιμένω νέα…


#include <16F876>
#fuses NOWDT, XT, PUT, NOPROTECT, NOBROWNOUT, NOLVP,NOCPD, NOWRT
#use delay &#40;clock = 4000000&#41; //4Mhz external crystal

void up_rutine&#40;&#41;;
void down_rutine&#40;&#41;;


int x;

void main &#40;&#41;
&#123;

x = 0;

setup_adc_ports&#40;all_analog&#41;;
setup_adc&#40;adc_clock_internal&#41;;
set_adc_channel&#40;x&#41;;
output_high&#40;pin_c1&#41;;


while&#40;1&#41;
&#123;
output_low&#40;pin_c0&#41;;
delay_ms&#40;100&#41;;

output_b&#40;read_adc&#40;&#41;&#41;;

if &#40;!input&#40;pin_c7&#41;&#41;
up_rutine&#40;&#41;;
if &#40;!input&#40;pin_c6&#41;&#41;
down_rutine&#40;&#41;;

output_high&#40;pin_c0&#41;;
delay_ms&#40;100&#41;;
&#125;

&#125;

void up_rutine&#40;&#41;
&#123;
x=x+1;
//...
if &#40;x==6&#41;
x=0;
set_adc_channel&#40;x&#41;;
while &#40;!input&#40;pin_c7&#41;&#41;
&#123;
delay_cycles&#40;1&#41;;
&#125;
&#125;

void down_rutine&#40;&#41;
&#123;
x=x-1;
//...
if &#40;x<0&#41;
x=5;
set_adc_channel&#40;x&#41;;
while &#40;!input&#40;pin_c6&#41;&#41;
&#123;
delay_cycles&#40;1&#41;;
&#125;
&#125;

gsmaster
10-06-06, 15:48
Δοκίμασε αυτό
(πρόσεχε μόνο να βάλεις το .h στο 16F876 γιατί το τρώει το φόρουμ...)

#include <16F876>
#fuses NOWDT, XT, PUT, NOPROTECT, NOBROWNOUT, NOLVP,NOCPD, NOWRT
#use delay &#40;clock = 4000000&#41; //4Mhz external crystal

//void up_rutine&#40;&#41;;
//void down_rutine&#40;&#41;;


int x;


void up_rutine&#40;&#41;
&#123;
x=x+1;
//...
if &#40;x==6&#41;
x=0;
set_adc_channel&#40;x&#41;;
while &#40;!input&#40;pin_c7&#41;&#41;
&#123;
delay_cycles&#40;1&#41;;
&#125;
&#125;

void down_rutine&#40;&#41;
&#123;
x=x-1;
//...
if &#40;x<0&#41;
x=5;
set_adc_channel&#40;x&#41;;
while &#40;!input&#40;pin_c6&#41;&#41;
&#123;
delay_cycles&#40;1&#41;;
&#125;
&#125;


void main &#40;&#41;
&#123;

x = 0;

setup_adc_ports&#40;all_analog&#41;;
setup_adc&#40;adc_clock_internal&#41;;
set_adc_channel&#40;x&#41;;
output_high&#40;pin_c1&#41;;


while&#40;1&#41;
&#123;
output_low&#40;pin_c0&#41;;
delay_ms&#40;100&#41;;

output_b&#40;read_adc&#40;&#41;&#41;;

if &#40;!input&#40;pin_c7&#41;&#41;
up_rutine&#40;&#41;;
if &#40;!input&#40;pin_c6&#41;&#41;
down_rutine&#40;&#41;;

output_high&#40;pin_c0&#41;;
delay_ms&#40;100&#41;;
&#125;


&#125;

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

gsmaster
04-09-06, 23:52
Να έχετε υπόψη (λύκε για σένα το λέω) ότι οι νεότερες εκδόσεις έχουν βασικές διαφορές στην printf όσον αφορά τα ορίσματα των μεταβλητών, και τον χειρισμό της μορφής τους.

Γι αυτό αν έχετε εφαρμογές σε παλιότερη έκδοση ενδέχεται να μην τρέχουν όπως θα θέλατε :(

Lykos1986
05-09-06, 11:38
Βασικά τρέχω με την 3.249 που είναι η σχεδόν τελευταία έκδοση. Από ότι έμαθα υπάρχει και η έκδοση 4 που πιστεύω πως σε κανένα μήνα θα την έχω. Θα σε κρατήσω ενήμερο!!! :wink:

gsmaster
06-09-06, 00:15
Τελικά τώρα το είδα, έχουν κάνει κάποιες αλλαγές σε έναν driver και δίνει τα δεδομένα σε άλλη μορφή. Οπότε πρέπει να κρατάμε backup τους παλιούς drivers για να μην παιδευόμαστε να αλλάζουμε το πρόγραμμα.......
Η printf μια χαρά είναι...


Για την 4 απ ότι διαβάζω στο φόρουμ, κάποιοι κάνουν beta testing αμα βγεί καμια σταθερή έκδοση θα μάθουμε. Απ ότι διαβάζω πάντως θα έχει πολλά καλά στον editor... Ελπίζω να κάνουν κάτι και για μας που παίζουμε μέσω MPLAB :)

DT200
06-09-06, 00:33
Συγνώμη για την σφήνα στην κουβέντα σας αλλά για τον λόγο ότι η C έχει τόσες ιδιοτροπίες
( σύμβολα , γράμματα , κενά , κ.α.) δεν την έμαθα και ασχολήθηκα με άλλη που είναι ποιο κατανοητή.

gsmaster
06-09-06, 02:06
Γούστα είναι αυτά.
Στην αρχή τα σύμβολα σου φαίνονται κάπως, αλλα μετά συνηθίζεις.

Lykos1986
06-09-06, 09:27
Συγνώμη για την σφήνα στην κουβέντα σας αλλά για τον λόγο ότι η C έχει τόσες ιδιοτροπίες
( σύμβολα , γράμματα , κενά , κ.α.) δεν την έμαθα και ασχολήθηκα με άλλη που είναι ποιο κατανοητή.


Είναι καλύτερη όμως όπως και να το κάνεις, αρκεί ο compiler που έχεις να είναι αρκετά κοντά στο πρωτόκολλο ANCI C έτσι ώστε να μην μπερδεύεσαι. Σκέψου πως σε γλώσσα C μπορείς να βρεις σχεδόν τα πάντά. Πριν μερικές μέρες βρήκα ακόμα και compiler C για τα FPGA!!! Πράγμα πολύ καλό αφού η VHDL είναι παλούκι.

Lykos1986
21-10-06, 13:43
Τι ακριβός κάνουμε για να ενεργοποιήσουμε το εσωτερικό ρολόι ενός μικροελεγκτή;;; Έκανα μερικά πειράματα με έναν 12F682 και ακολούθησα τις οδηγίες που υπάρχουν στο εγχειρίδιο της CCS. Το πρόβλημα είναι πως δεν κατάφερα να τον κάνω να δουλέψει!!!

Επίσης, αν δουλέψω με εσωτερικό ρολόι μπορώ να χρησιμοποιήγσω την delay_ms() γράφοντας στην αρχή #use delay κτλ κτλ κτλ ή ο μC θα γυρίσει σε λειτουργία εξωτερικού κρυστάλου;;;

gsmaster
22-10-06, 03:11
Πρέπει να βάλεις το σωστό fuse (INTRC_IO), και πάντα να ορίζεις #use delay(clock=....) για να λές στον compiler τη συχνότητα ταλαντωτή του μΕ για να φτιάξει ανάλογα όλα τα delay_ms() delay_us() κτλ...

12F682 ??? Μήπως μπερδεύτηκες?

Lykos1986
22-10-06, 18:59
Ελα 12F683 είναι!!!

Χρησιμοποιώ την fuse που λες (#fuses NOWDT, NOCPD, NOPROTECT, MCLR, NOPUT, INTRC_IO). Δεν θα πρέπει όμως να γράψουμε και setup_oscillator(OSC_4MHZ); Αν του πω και το Use delay κτλ πιστεύω πως χάνετε!!!

Lykos1986
11-01-07, 16:58
Λοιπόν έχω το εξής πρόβλημα:


void deltaWrite&#40;int delta_byte&#41; // Main Write function
&#123;
int i;
int out_bit;
for &#40;i=0; i<=7; i++&#41;
&#123;
out_bit = shift_right&#40;delta_byte,1,0&#41;;
if &#40;out_bit&#41;
write_one&#40;&#41;;
else
write_zero&#40;&#41;;
&#125;
&#125;

κανονικά θα έπρεπε να μου περνάει στο out_bit την τιμή του bit που φεύγει και σαν συνέπεια της τιμής αυτού θα μπορούσα να τρέχω ανάλογα δύο άλλες υπορουτίνες. Το πρόβλημα είναι πως στο out_bit δεν μου δουλεύει όπως θέλω αφού συνέχεια έχει την τιμή “0”. Πού κάνω το λάθος ρε γ****o!!!

gsmaster
11-01-07, 23:04
To out_bit το έχεις ορίσει σαν int (8bit), και απο κάτω το ελέγχεις με την IF σαν να ήταν 0 ή 1 δηλαδή σαν να ήταν int1. Στην ουσία η πρώτη επιλογή του IF θα εκτελεστεί όταν το out_bit είναι 00000001, δηλαδή τρέχα γύρευε. Θα πρέπει να ορίσεις το out_bit σαν int1 και μετά να δεις πως ακριβώς δουλεύει η shift. Θα πρέπει πάντως να αποθηκεύεις κάθε ολίσθηση γιατί έτσι όπως είναι τώρα, σε κάθε επανάληψη του loop θα έχεις το ίδιο αποτέλεσμα..... ΆΚΥΡΟ δες στο help τι λέει για το Shift... "Shifts a bit into an array or structure...." Άρα δεν σου κάνει χρησιμοποίησε το ">>" για περιστροφή του byte δεξια

Γιατί δεν χρησιμοποιείς την BIT_TEST?

Τέσπα δοκίμασε αυτό



void deltaWrite&#40;int delta_byte&#41; // Main Write function
&#123;
int i;
//int out_bit;
for &#40;i=0; i<=7; i++&#41;
&#123;


if &#40;bit_test&#40;delta_byte,0&#41;&#41;
write_one&#40;&#41;;
else
write_zero&#40;&#41;;

delta_byte=delta_byte>>1;

&#125;
&#125;

Lykos1986
12-01-07, 20:14
Τέλεια λειτουργία!!!

Η αλήθεια είναι πως δεν είχα δουλέψει ποτέ με την bit_test() και το κακό είναι πως δεν σκέφτηκα ποτέ να την κοιτάξω!!!

gsmaster
21-01-07, 14:23
Τελικά βρήκα γιατί τρώει τον κώδικα, πρέπει να τσεκάρεις το "Απενεργοποίηση HTML σ' αυτή τη δημοσίευση" για να εμφανιστεί σωστά

Lykos1986
23-01-07, 00:29
Προσπαθώ να κάνω την αλλαγή από βαθμούς F σε Celsius αλλά κάτι δεν δουλεύει σωστά. Το αποτέλεσμα είναι πάντα 00. Τι τύπου θα πρέπει να είναι οι μεταβλητές για να δουλέψει;

Ουσιαστικά αυτό που κάνω είναι:

C_temp = (5/9) * (read_temp() - 32);

gsmaster
23-01-07, 01:04
hmmmm... απο ποιό αισθητήριο διαβάζεις? υποψιάζομαι μια άλλη λύση

Επίσης καλό είναι να σπάσεις τον τύπο σε κανα-δυο κομμάτια.
Αυτό το (5/9) στην αρχή μου φαίνεται κάπως...

Σύμφωνα με αυτό http://www.greenigsociety.org/tempchart.htm έχεις λάθος στον τύπο.

Fahrenheit to Celsius
1. Subtract 32 from degrees Fahrenheit
2. Multiply by 5
3. Divide by 9

δηλαδή
C_temp = ((read_temp() - 32)*5)/9;

Lykos1986
23-01-07, 01:09
Διαβάζω την θερμοκρασία με το DS1621. Σε F κλίμακα δεν έχω κανένα πρόβλημα. Το πρόβλημα δημιουργείτε με την C κλίμακα.

Σύμφωνα πάντως με αυτούς εδώ:
http://www.csgnetwork.com/tempconvjava.html
δεν έχω λάθος στον τύπο…

gsmaster
23-01-07, 01:46
χε χε καλά το υποψιάστηκα. Το DS1621 έχει καταργηθεί, ο αντικαταστάτης είναι το DS1631.
Αυτό λοιπόν σου δίνει την θερμοκρασία σε κελσίου αλλά ο αυτός που έγραψε τον driver της ccs επιστρέφει σε φαρενάιτ.
Λίγο ξεκαθάρισμα ο κώδικας του read_temp() θέλει και είναι οκ. Το χρησιμοποιώ μια χαρά παίζει.

Απλά αντικατέστησε στον κώδικα του driver το παρακάτω κομμάτι (ή απλά βγάλε εκτός τις commented γραμμές)


signed int read_low_temp&#40;&#41;
&#123; // Returns degrees C
signed int datah, datal;
signed long data;

i2c_start&#40;&#41;;
i2c_write&#40;0x90&#41;;
i2c_write&#40;0xaa&#41;;
i2c_start&#40;&#41;;
i2c_write&#40;0x91&#41;;
datah=i2c_read&#40;&#41;;
datal=i2c_read&#40;0&#41;;
i2c_stop&#40;&#41;;

data=datah;
// data=data*9; //gia 8ermokrasia se Fahreneit

// if&#40;bit_test&#40;datal,7&#41;&#41;
// &#123;
// if&#40;data < 0&#41;
// data -= 4;
// else
// data += 4;
// &#125;

// data = &#40;data / 5&#41; + 32; //gia 8ermokrasia se Fahreneit



if&#40;data > 127&#41;
data = 127;

return&#40;data&#41;;
&#125;


Θα έβαζα όλον τον κώδικα του driver αλλα είναι λίγο χύμα γιατί έκανα κι άλλα πειράματα. :P

Lykos1986
23-01-07, 01:51
Θα το δοκιμάσω αύριο τώρα. Τώρα θα δοκιμάσω μάλλον τον ύπνο!!!!

Lykos1986
26-01-07, 16:13
Έκανα αυτό με τον driver και δουλεύει μια χαρά. Το πρόβλημα είναι πως βγάζει λίγο μεγάλη θερμοκρασία μέτρησης. Για παράδειγμα όταν δείχνει θερμοκρασία 24 βαθμούς η πραγματική είναι κάπου στους 21. Κοίταξα τον driver αλλά δεν βλέπω να έχει κάποια άλλη ρύθμιση. Λες να προσθέσω στον κώδικα και μια αφαίρεση έτσι ώστε να τον ρυθμίσω λίγο;

gsmaster
26-01-07, 23:50
Την μετατροπή στον driver την έκανα σύμφωνα με το datasheet του ds1631

Lykos1986
27-01-07, 20:26
Λοιπόν, χτυπάω το κεφάλι μου εδώ και ώρα και δεν μπορώ να καταλάβω γιατί συμβαίνει το παρακάτω!!! Έχω γράψει ένα πρόγραμμα στην CCS που πιάνει 40% την μνήμης ROM και 5% της RAΜ του PIC 16F876A. Με το που πάω όμως να γράψω και τις παρακάτω γραμμές κώδικα το πρόγραμμα μου λέει:
Out of ROM, A segment or the program is too large MAIN

Και ο κώδικα είναι:

void time_set&#40;&#41;
&#123;
int hour, min;
lcd_putc&#40;"\fTime set?"&#41;;
while&#40;1&#41;
&#123;
if&#40;!input&#40;pin_c5&#41;&#41;
&#123;
while&#40;!input&#40;pin_c5&#41;&#41;
&#123; ; &#125;
lcd_putc&#40;"\fHoure set&#58;\n00 &#58; --"&#41;;
while&#40;1&#41;
&#123;
if&#40;!input&#40;pin_c4&#41;&#41;
// break;
if&#40;!input&#40;pin_c5&#41;&#41;
&#123;
hour = hour + 1;
if&#40;hour > 12&#41;
hour = 0;
printf&#40;lcd_putc,"\fHoure set&#58;\n%02u &#58; --",hour&#41;;
&#125;
&#125;

//min set
lcd_putc&#40;"\fMinutes set&#58;\n -- &#58; 00"&#41;;
while&#40;1&#41;
&#123;
if&#40;!input&#40;pin_c4&#41;&#41;
&#123;
setings_register = 2;
rtc_set_datetime&#40;1,1,1,1,hour,min&#41;;
return;
&#125;
if&#40;!input&#40;pin_c5&#41;&#41;
&#123;
min = min + 1;
if&#40;min > 56&#41;
min = 0;
printf&#40;lcd_putc,"\fMinutes set&#58;\n-- &#58; %02u",min&#41;;
&#125;
&#125;
&#125;


if&#40;!input&#40;pin_c4&#41;&#41;
&#123;
while&#40;!input&#40;pin_c4&#41;&#41;
&#123; ; &#125;
setings_register = 2;
return;
&#125;
&#125;
&#125;

Υπάρχει περίπτωση με αυτές τις γραμμές κώδικα να πιάσω το άλλο 60% της μνήμης του μC!!!;;;!!!;;;!!! Κάτι άλλο φταίει 100%. Λες να έχω γεμίσει τον stack register του PIC;

gsmaster
27-01-07, 23:54
Ναρροου ντάουν δε πρόμπλεμ, που λεν κι οι φίλοι μας οι άγγλοι.
Βγάλε εκτός κάποιες γραμμές και δες την συμπεριφορά του μεγέθους. Όλα αυτά μήοως τα έχεις μέσα στη main()?

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

Μου έχει τύχει, αλλά όχι στο 40% εγώ ήμουν περίπου στο 80% και μου το κανε.

Lykos1986
28-01-07, 10:57
Μπα δεν είναι μέσα στην main(), ή main() είναι πολύ μικρή. ¨όλα γίνονται μέσα σε άλλες συναρτήσεις. Επίσης έβγαλα κάποιες γραμμές κώδικα. Για την ακρίβεια κατάργησα κάποια συνάρτηση που ήταν όμως πάρα πολύ μικρή, με ασήμαντες λειτουργίες και τότε η CCS έκανε κανονικά compile χρησιμοποιώντας και πάλι το 40% της μνήμης του PIC. Τρέλα με λίγα λόγια

Lykos1986
25-03-07, 12:28
Θέλω λίγο βοήθεια με την εντολή goto label. Προσπαθώ να κάνω διαχείριση των menu σε ένα πρόγραμμα που γράφω και κάπου τα έχω χάσει αφού έχουν μπει αρκετές επιλογές…

Μπορώ να χρησιμοποιήσω κανονικά την εντολή goto label και να πάει κανονικά στην label αλλά αυτό μόνο όταν η εντολή goto και η label είναι στην ίδια συνάρτηση. Πώς μπορώ να την κάνω να λειτουργεί σε διαφορετικές συναρτήσεις; Δηλαδή η goto label να είναι στην μια συνάρτηση αλλά η label που θα πρέπει να πάει να είναι σε άλλη.


------
Για να σου δώσω να καταλάβεις το πράγμα έχει ως εξής. Ενώ είμαι στην main() με το πάτημα ενός κουμπιού μπαίνω στο menu. Από εκεί και πέρα αν φτάσω σε βάθος ενός menu τότε απλά με την εντολή return γυρνάω στην main() από εκεί που ξεκίνησα. Και όλα είναι μια χαρά.

Αν όμως έχω φτάσει σε βάθος δύο menu τότε με την εντολή return εγώ θα γυρίσω στην προηγούμενη συνάρτηση που είναι το αμέσως προηγούμενο menu και όχι η main(). Ουσιαστικά εδώ πατάω το κουμπί Exit.

PS1:
Βασικά αν βάλω όλο το menu στην ίδια συνάρτηση τότε τα πράγματα είναι μια χαρά ( το έχω κάνει και δουλεύει περίφημα ) αλλά τότε έχουμε μια χάλια συνάρτηση που είναι πολύ μπερδεμένη.

PS2:
Μπορεί να γράφω και βλακείες αλλά ξεκίνησα το πρόγραμμα από το μηδέν σήμερα το πρωί (ήταν και τεράστιο) και κάπου τώρα έχω κάνει κεφάλι!!!

gsmaster
25-03-07, 22:27
Απ ότι κατάλαβα έχεις βάλει τα μενού σε σειρά, για να φτάσεις δλδ στο 3ο μενού πρέπει να περάσεις απο τα δυο πρώτα. Αν είναι έτσι τότε λογικό είναι αυτό που σου συμβαίνει.
Εγώ πάντως αποφεύγω να χρησιμοποιώ την goto αλλά καλώ απ ευθείας τις συναρτήσεις.

Lykos1986
25-03-07, 22:40
Και μετά πως επιστρέφεις στην main; Για παράδειγμα πατάς το κουμπί του menu και στη οθόνη σου έχεις την πρώτη επιλογή του menu. Με τα πλήκτρα πάνω – κάτω μεταβαίνεις στο menu που θες και κάνεις τις απαιτούμενες ρυθμίσεις. Μετά θέλεις να πατήσεις το exit για να φύγεις. Αν είσαι στην πρώτη επιλογή τότε με την εντολή return επιστρέφεις κανονικά πίσω στην main(). Αν όμως είσαι για παράδειγμα στην τρίτη επιλογή του menu χρησιμοποιώντας συναρτήσεις θα γράψεις return και θα πας στην προηγούμενη συνάρτηση όχι όμως στην main (από εκεί που πάτησες το menu για να συνεχίσεις την δουλειά σου), εκτός και αν υπάρχει κάποια άλλη επιλογή που ακόμα και αν είσαι σε βάθος δύο συναρτήσεων ή και παραπάνω μπορεί να σε επαναφέρει στην main() από εκεί ακριβός που ξεκίνησες. Αν μπορεί να γίνει κάτι τέτοιο τότε σίγουρα θα χρησιμοποιήσω συναρτήσεις!!! Για την ώρα όμως χρησιμοποιώ συναρτήσεις για όλα τα άλλα εκτός από τα menu των οθονών!

PS:
Βασικά έχω τελειώσει αυτό που έκαναν με τον κλασικό τρόπο του goto (αν και όχι ο σωστός) και το κύκλωμα δουλεύει περίφημα.

gsmaster
25-03-07, 23:25
Ενας άλλος τρόπος για να κανεις Loop
do{
....
....
}while(true);


για να βγείς απο το Loop
- break;
- στο while(); βάζεις μια συνθήκη πχ while(menu<5); αν το μενού γίνει 5 ή μεγαλύτερο θα σταματήσει το Loop

Επίσης μπορεις να το κάνεις με switch... διαλέγεις και παίρνεις.

Radiometer
04-07-07, 22:52
Mια που είδα ότι έχετε ένα πολύ ωραίο θέμα για την CCS και να μην γράψω πουθενά αλλού
εχω να κάνω μια ερώτηση.

Εχετε πουθενά υπόψιν κάνα έτοιμο κώδικα για να οδηγήσω ένα βηματικο κινητήρα ( step motor ) με 16F628
οπού πάνω στον κώδικα θα κανό κάποιες παραλλαγές ανάλογα με τις απαιτήσεις μου :?:

DT200
29-12-07, 13:11
Μπορεί κάποιος να μου πει τι συμβαίνει με την CCS και τον 16F628!!!!!!!!
Πάω να χρησιμοποιήσω τον εσωτερικό ADC και το αποτέλεσμα είναι πως δεν υπάρχουν οι ρουτίνες για να γίνει κάτι τέτοιο!!!
Αν είναι δυνατόν!!!! Με όλους τους άλλους μC (16F88, 16F876, 16F877) όλα τα παραπάνω δουλεύουν κανονικά.
Και να πώ πως ο 628 είναι κάποιος περίεργος μC, από τους πιο πολυχρησιμοποιημένους της Microchip.
Υπάρχει κανένα κόλπο για να λειτουργήσει ο 628, το οποίο δεν το ξέρω;;;


Την πάτησα και εγώ έτσι , αγόρασα 20 κομμάτια από το e-bay και τελικά δεν έχει ADC και να δω τι θα τα κάνω τώρα .

Lykos1986
29-12-07, 18:51
Χα χα χα!!! :lol:

Όλοι την πατήσαμε έτσι! Εγώ δούλευα με έναν άλλο μC εκείνη την εποχή (16F876A) αλλά λόγο ότι ήθελα κάτι με μικρότερο foot print είπα να πάω κατευθείαν σε έναν 16F628. Το κακό είναι πως δεν κοίταξα ποτέ το datasheet του (μέγα λάθος) αφού ήμουν πεπεισμένος ότι έχει μέσα του 100% ADC. Έτσι πήγα κατευθείαν με την CCS να γράψω κώδικα!!! Τελικός μου έβγαζε τόσα λάθη που αναγκάστηκα να ανοίξω το header file του μC για να δω τι πάει στραβά. Τελικός μέσα δεν είχε καμιά συνάρτηση για τους ADC όπως ήταν φυσικό αφού ο μC δεν έχει κανένα ADC μέσα του.


Το πρόβλημα σε εμένα δεν ήταν ότι αγόρασα τον μC αλλά ότι έφαγα σχεδόν ένα ολόκληρο απόγευμα ψάχνοντας πως λειτουργεί κάτι που δεν υπάρχει!!! Ευτυχώς ποτέ ξανά δεν έκανα κάποιο τέτοιο λάθος... πάντα κοιτάω το datasheet!