Jump to content



Βοηθεια στο coding για Μικροεπεξεργαστες


gns

Recommended Posts

Καλησπερα σε ολους τους λαμπιτες

Ξερει κανεις απο προγραμματισμο σε microcontrollers(8051) και συγκεκριμενα στη C?

Θα ηθελα καποια βοηθεια με το προγραμματισμο και χρηση ADC(analogue to digital converter) με microcontroller μιας και ειναι πρωτη φορα που ασχολουμε σοβαρα με το θεμα.

Οποια βοηθεια δεκτη.

Ευχαριστω

Link to comment
Share on other sites

Έχω πολλά χρόνια ν' ασχοληθώ με 8051, αλλά ίσως σε βοηθήσω...

Ποιο ακριβώς είναι το πρόβλημα...?

Ή θέλεις τα πάντα όλα για τους ADC...?

Γενικά, ότι χρειάζεσαι είναι στο datasheet του μC και στο manual του compiler, που έχει τα libraries...

Τέλος, πες μου ποιον compiler χρησιμοποιείς, δώσε μου ένα link για την library του και δες αν έχει wrapper functions σε C για τους ADC ή τα θέλει όλα σε assembly...

Link to comment
Share on other sites

Χρησιμοποιω αυτο το microcontroller (http://www.atmel.com/dyn/products/product_card.asp?part_id=1917)

Και αυτο το ADC (http://www.national.com/mpf/DC/ADC0831.html#Overview)

Το compiler ειναι το Keil C (http://www.keil.com/dd/chip/3409.htm) και ολος το προγραμματισμος ειναι σε C.

Αυτο που θελω ειναι το πως να προγραμματισω το ADC με το microcontroller μιας και ειναι πρωτη φορα που ασχολουμε τοσο πολυ με προγραμματισμο σε microcontroller

Οποιαδηποτε πληροφορια ειναι δεκτη

Ευχαριστω Jaco.

Link to comment
Share on other sites

Ok... Το μόνο πράγμα που χρειάζεται είναι να δεις την σελίδα 9 από το datasheet του ADC... Εκεί δείχνει τα timing diagrams για την σειριακή επικοινωνία... Τα pins που χρειάζονται για την επικοινωνία είναι τα CLK, ~CS, DI και DO, τα οποία θα πρέπει να τα συνδέσεις σε αντίστοιχα pins του μC... το CLK είναι το clock και είναι output, το CS είναι το chip select και είναι output, το DI είναι το data in και είναι input και το DO είναι το data out και είναι output... οπότε έτσι δηλώνεις τα pins στον μC...

Όπως βλέπεις στα διαγράμματα της σελίδας 9, θα πρέπει να γράψεις τον κώδικά σου, ώστε τα pins του μC (CLK, CS, DI, DO) να κάνουν αυτό που λένε τα σχεδιαγράμματα...

Ρίξε μια ματιά σε αυτά και προσπάθησε να καταλάβεις, τι πρέπει να κάνει ο κώδικάς σου ώστε να δημιουργήσεις αυτά τα διαγράμματα... μην σκέφτεσαι καθόλου τον ADC και την λειτουργία του ακόμα, συγκεντρώσου μόνο στο πως μπορείς να στέλνεις αυτό το CLK, να κάνεις toggle το CS όταν πρέπει και να στέλνεις εντολές με το DO και να λαμβάνεις αποτελέσματα από το DI... αν το σκεφτείς όλο μαζί, φαίνεται δύσκολο, αν το κόψεις σε πολύ μικρά κομμάτια, είναι πανεύκολο, οπότε ξεκίνα από το πως κάνεις 0 ή 1 τα pins αυτά και με το πως μπορείς να δημιουργήσεις τα γραφήματα αυτά...

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

Link to comment
Share on other sites

για να μην ανοιγω νεο θεμα...

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

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

Link to comment
Share on other sites

Δεν υπάρχει λόγος πια να μάθεις assembly... παλιότερα, παρόλο που υπήρχαν και c compilers για κάποιους μC, πολλοί συνέχιζαν ή μάθαιναν assembly αντί για C, γιατί τότε οι μC είχαν πολύ λίγη RAM και ROM και αυτοί οι οποίοι είχαν περισσότερη ήταν πανάκριβοι... οπότε για να χωρέσουν μεγάλα προγράμματα στην ROM, έγραφαν σε assembly ώστε να γλιτώνουν ακόμα και ένα byte... Τώρα πια οι επεξεργαστές έχουν τόσο μεγάλη RAM και ROM και τόσο μικρή τιμή, που δεν υπάρχει λόγο να ξέρει κάποιος assembly... ;έναν τουμπανιασμένος ARM7 έχει λιγότερο από 4-5€... προσωπικά έχω χρόνια πια να χρησιμοποιήσω assembly, πλέον γράφω μόνο σε C...

Από την άλλη μαθαίνοντας assembly, μαθαίνεις πως πραγματικά λειτουργεί ο μC και μαθαίνεις ένα σωρό τεχνικές και κόλπα για efficient coding, που δεν τα μαθαίνεις πια με την C... αλλά έτσι που τρέχουν οι ρυθμοί και έτσι που έχουν γίνει οι compilers και οι βιβλιοθήκες, οι οποίες παρέχουν ένα σωρό ευκολίες είναι δύσκολο (ειδικά για τους χομπίστες ή αυτούς που δεν έχουν χρόνο) να μην τις χρησιμοποιήσεις... Από την άλλη αν είναι η δουλειά σου, τις περισσότερες φορές δεν θα πρέπει να χρησιμοποιείς ξένες libraries, αλλά τις γράφεις ο ίδιος...

Επομένως, θέλεις ένα καλό βιβλίο για C... όποιο και να πάρεις νομίζω το ίδιο είναι πια, γιατί είναι τόσο μεγάλη η βιβλιογραφία και τόσο παλιά γλώσσα που δεν μπορεί να είναι κακό βιβλίο... δοκίμασε κάποιο από αυτά του SAMs 24 days κτλ και μετά αφού έχεις αποκτήσει μια εμπειρία και ιδέα, τότε βρίσκεις ένα άλλο που θα είναι στα μέτρα σου...

Link to comment
Share on other sites

Γεια σου Jaco

Το οτι θα σπασω το κεφαλι μου για να τα καταφερω ειναι σιγουρο.

Καποια διευκρινηση ειχα μπερδευτει αυτος ειναι ο compiler που χρησιμοποιω http://www.mcu-raisonance.com/~c51-atmel__microcontrollers__sfp~sfp__T016:4co0wjrxfo4m.html)

και το adc ειναι αυτο με τα 8pins αρα 3 pins πρεπει να χρησιμοποιησω clk, cs και DO.

Εχω γραψει το κωδικα για να κανεις read απο το adc αν και δεν ειμαι σιγουρος για τα delays και πως θα κανεις το clk να τρεχει με το απαιτουμενο freq (10KHz-400KHz) εδω θα χρειαστω την βοηθεια σου.

Στο κωδικα θα δεις και καποια methods που καλω για να περασω το αποτελεσμα σε μια ldc_screen.

adc.rar

Link to comment
Share on other sites

Η ταχύτητα του clk εξαρτάται από την συχνότητα του μC, όπως επίσης και το delay... Τώρα, από την ακρίβεια που θες για το delay σου, θα εξαρτηθεί και τι γλώσσα θα χρησιμοποιήσεις, πχ. assembly ή C... φυσικά και με την C μπορείς να ξέρεις πόσο χρόνο θα κάνει το delay σου, αρκεί να ζητήσεις από τον compiler να σου φτιάξει και το αρχείο με την assebly και όχι μόνο το hex, το οποίο είναι τα opcodes...

Αν όμως θα να είσαι εξ' αρχής ακριβής, τότε θα πρέπει να γράψεις το delay σε assembly... από το manual του 8051 ή και από το internet γενικότερα, θα βρεις το ρεπερτόριο εντολών στου 8051... εκεί θα δεις ότι κάθε εντολή έχει το λεγόμενο execution time, του οποίου η μονάδα μέτρησης είναι τα cycles, δηλαδή πόσους κύκλους χρειάζεται ο μC για να εκτελέσει την εντολή, οπότε ο κάθε κύκλος ισούται με 1/(συχνότητα πυρήνα επεξεργαστή)... γράφω πυρήνα γιατί δεν είναι απαραίτητα η συχνότητα του κρυστάλλου, αλλά εξαρτάται και από το αν έχεις χρησιμοποιήσει pre-scalers κτλ...

Επομένως για να είσαι ακριβής, γράψε το delay σε assembly... σίγουρα ο compiler σου δίνει την δυνατότητα να γράψεις asm σε C, συνήθως είναι κάτι σε στυλ

asm{
MOV R1,R2}

ή κάτι παρόμοιο...

Ένα τυπικό delay είναι αυτό...:

MOV R7,#0FFH
LOOP1: DJNZ R7, LOOP1
RET

Αν είναι function και γίνεται call από κάπου αλλού, τότε χρειάζεται και μια RET στο τέλος, αν το θες inline βγάζεις το RET, αλλά δεν είναι τόσο ασφαλές, γιατί δεν ξέρεις τι έχει ο R7, μιας και τον χειρίζεται ο compiler... Αυτός ο κώδικας διαρκεί 512 κύκλους, οπότε για μια συχνότητα 10MHz αυτό σημαίνει ότι το delay αυτό είναι ίσο με 51.2μsec ή 19.531,25 ΚΗz... βάση της σελίδας 6 του datasheet του adc, τα 19KHz είναι μέσα στο όριο των 10-400ΚΗz (πίνακας σελ 6, τιμή fclk)...

Επίσης προσοχή θέλει και το delay του settling time του adc (tset-up), το οποίο είναι 250ns... γενικά όταν βλέπεις μερικά ns χρόνους σε τσιπάκια, τότε δεν έχεις πρόβλημα, γιατί οι μC είναι πιο αργοί... αλλά αυτό εξαρτάται κυρίως από την συχνότητα του μC, οπότε αν τρέχει στα 10ΜΗz τότε ένας κύκλος είναι 100ns, ο οποίος είναι μικρότερος από το tset-up, οπότε την ώρα που κάνεις toggle το CS, πρέπει να περιμένεις κάτι παραπάνω από 250ns για να δώσεις το πρώτο clk... αυτό πχ μπορεί να γίνει στα γρήγορα με τρεις NOP, αλλά αν θες να είσαι πιο σωστός, τότε θα πρέπει να κάνεις πάλι μια function, αλλά τώρα για πιο γρήγορα θα σου βάλω στον κώδικα μερικές nop, οπότε ο κώδικας θα γίνει (με 10MHz στο core)...

#include <at89x51>
#include "lcd.h"
#define clk P3_0
#define cs P3_1
#define DO P3_2

cs = 1;

void delay_51us(unsigned char loops)
{
while (loops) {
asm{
MOV R7,#0FFH
LOOP1: DJNZ R7, LOOP1
};
--loops;
}
// Δεν χρειάζεται RET, θα το κάνει μόνος του ο compiler
}

unsigned char read()
{
unsigned int i;
unsigned char rec;

clk = 0;
cs = 0;
nop; //συνήθως όλοι οι compiler υποστηρίζουν την nop.
nop;
nop;
clk = 1;
clk = 0;

for(i=0; i<8; i++)
{
clk = 1;
delay_51us(1);
clk = 0;
nop;
rec = DO;

}

clk = 1;
delay_51us(1);
clk = 0;
clk = 1;
delay_51us(1);
clk = 0;
cs = 1;
return rec;
}
void main()
{
unsigned char results;
lcd_init();
while(1)
{
results = read();
lcd_data(results);
}


}

Αν σου δουλέψει, θα σου πω και ένα κόλπο για βελτιώνεις την ακρίβεια του adc σου...

Link to comment
Share on other sites

αρχισα να καταλαβενω ενα περιπου τι παιζει με τα delays.

τωρα αν θελαμε να γραψουμε το delay σε C σε περιπτωση που δεν κανει compile assembly.

αν πχ πουμε οτι τρεχει με την ταχυτητα του κρυσταλλου που στη περιπτωση μου ειναι 12MHz εχουμε ενα method

delay(unsigned int k)

{

unsigned int i,j;

for(i=0;i<k;i++)

for(j=0;j<agnosto;j++);

{

πως μπορουμε να βρουμε το αγνωστο?δεδομενου οτι η τιμη που δινουμε στη method ειναι σε ms?

ps.νομιζω το βρηκα πρεπει να ειναι 12500. αρα αν θελουμε 50ms θα καλεσουμε delay(50). ειναι σωστη η λογικη μου?

Link to comment
Share on other sites

Για να το βρεις με ακρίβεια, πρέπει να ξέρεις τι κάνει ο assembler που μετατρέπει τον κώδικα από C σε asm... πολύ χοντρικά υπολογίζεις περίπου 2 cycles ανά for και για nested fors (δηλαδή for μέσα σε for) πολλαπλασιάζεις τους κύκλους της κάθε for...

Από την άλλη μπορείς πειραματικά, αν έχεις παλμογράφο, να βρεις με δοκιμές την τιμή που πρέπει, κάνοντας toggle ένα pin και μετρώντας την συχνότητα...

Πάντως, δεν υπάρχει περίπτωση να μην υποστηρίζει asm ο compiler... είναι ο νο 1 κανόνας στους compilers για μC, οπότε κάν' το με asm...

Link to comment
Share on other sites

οκ θα το δοκιμασω σε assembler.

δηλαδη για καθε κυκλο της for υπολογιζεις 2 cycles?

πχ αν εχεις nested fors που κανουν συνολικα 1000 κυκλους θα εχεις 2000 cycles του επεξεργαστη?

επισης δοκιμασα να κανω toggle ενα pin για να μετρησω με το παλμογραφο την συχνοτητα αλλα παρολο που εκανε compile ο κωδικας δεν μου δημιουργουσε το hex file

#include <reg51.h>
#include <at89x51.h>
#define led P0_1

delay()
{
unsigned int i,j;
for(i=0;i<100;i++)
for(j=0;j<300;j++);
}

main()
{
while(1)
{
led = 1;
delay;
led = 0;
delay;
}
}

Link to comment
Share on other sites

οκ βγηκα την επιλογη για να κανει hex file.

τωρα δοκιμασα να τρεξω το κωδικα για το adc και εχω μερικα errors

line 8: syntax error near '='

line 13: undefined 'MOV'

line 9: character '}' missing

line 13: invalid '#' character

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

τωρα για τα αλλα δυο τι μπορει να φταει?

Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.

×
×
  • Δημιουργία...

Important Information

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