PDA

Επιστροφή στο Forum : Avr και βηματικός κινητήρας



fireball
08-03-08, 15:49
Έχω φτίαξει ένα κύκλωμα με το L297 (Stepper motor controller) και το L298 (driver) και μικροελεγκτή τον ATTINY 2313.

Με τον παρακάτω κώδικα δουλεύει κανονικά:


/* Standard Includes */
#include <inttypes>
#include <avr>
#include <avr>
#define F_CPU 1000000UL
#include <util>

/* Pin defs for ATTiny2313 */
/* Clockwise order */
#define HF _BV&#40;PB0&#41;
#define CL _BV&#40;PB1&#41;
#define CW _BV&#40;PD4&#41;

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


DDRB = 0xff; /* Enable output on all of the B pins */
DDRD = 0xff;
PORTB = 0x00;/* Set them all to 0v */
PORTD = 0x00;

forward&#40;&#41;;
&#125;

void forward&#40;void&#41;&#123;

uint8_t i;
const uint8_t delay = 500;

for &#40;i=0; i<=20; i++&#41;&#123;

PORTB = CL;
_delay_ms&#40;delay&#41;;
PORTB &= ~CL;
_delay_ms&#40;delay&#41;;
&#125;

&#125;


Όταν όμως βάλω το delay μέσα στο forward:


void forward&#40;uint8_t delay&#41;......



Και καλέσω την εντολή


forward &#40;500&#41;;

Δεν δουλεύει και εκτός αυτού το hex βγαίνει πολύ μεγάλο.

Χρησιμοποιώ το Programmer's Notepad για τον κώδικα και το PonyProg2000 για τον προγραμματισμό. Τι κάνω λάθος;

Επιστήμων
08-03-08, 15:57
void forward(void){

uint8_t i;
const uint8_t delay = 500; (<---------)

for (i=0; i<=20; i++){

PORTB = CL;
_delay_ms(delay);
PORTB &= ~CL;
_delay_ms(delay);


Την γραμμή που σου δείχνω με το βέλος την βγάζεις ?

fireball
08-03-08, 16:00
Ναι. Γράφω το παρακάτω:




/* Standard Includes */
#include <inttypes>
#include <avr>
#include <avr>
#define F_CPU 1000000UL
#include <util>

/* Pin defs for ATTiny2313 */
/* Clockwise order */
#define HF _BV&#40;PB0&#41;
#define CL _BV&#40;PB1&#41;
#define CW _BV&#40;PD4&#41;



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


DDRB = 0xff; /* Enable output on all of the B pins */
DDRD = 0xff;
PORTB = 0x00;/* Set them all to 0v */
PORTD = 0x00;



forward&#40;500&#41;;



&#125;

void forward&#40;uint8_t delay&#41;&#123;

uint8_t i;


for &#40;i=0; i<=20; i++&#41;&#123;

PORTB = CL;
_delay_ms&#40;delay&#41;;
PORTB &= ~CL;
_delay_ms&#40;delay&#41;;
&#125;

&#125;

fireball
08-03-08, 16:03
Στα include στην αρχή βάζω φυσικά το delay, το io και το interrupts απλά όταν το έκανα paste εδώ δεν τα εμφανίζει.

QED
09-03-08, 00:44
Φίλε μου έχω παρατήσει καιρό την C αλλά δοκίμασε να δηλώσεις τη forward στην αρχή
έξω από την main


void forward&#40;uint8_t delay&#41;;

QED
09-03-08, 00:47
ΑΑ να σου πω ο uint8_t μπορεί να πάρει την τιμή 500;
uint8_t δεν είναι < 255;

fireball
09-03-08, 01:05
Ναι όντως δεν μπορεί.... Θα τα δοκιμάσω και τα 2. Ευχαριστώ! Μάλλον αυτό θα φταίει. Θα ενημερώσω.

fireball
09-03-08, 05:42
Δήλωσα την forward στην αρχή.



void forward&#40;uint8_t delay&#41;;


και έτσι



void forward&#40;uint8_t&#41;;


Έβαλα τιμή μικρότερη απο 255 αλλά πάλι τίποτα. Δεν δουλεύει αλλά και το hex βγαίνει υπερβολικά μεγάλο, σχεδόν γεμίζει την μνήμα απο τον avr!

th_shak
09-03-08, 12:57
Ο compiler που χρησιμοποιείς λογικά είναι ο WinAVR. Δεν τον χρησιμοποιώ αλλά νομίζω ότι με την uint8_t δηλώνεις 8 Bit μεταβλητές. Γράψε το πρόγραμμα όπως το έγραψα και αν δεν δουλέψει τότε βλέπουμε.
Με τις βιβλιοθήκες εννοείται.


/* Pin defs for ATTiny2313 */
/* Clockwise order */
#define HF _BV&#40;PB0&#41;
#define CL _BV&#40;PB1&#41;
#define CW _BV&#40;PD4&#41;

void forward &#40;uint8_t delay&#41;; // an kai nomizw oti to "uint8_t" dilonei 8 bit variable opote max value <= 0xFF

void forward &#40;uint8_t delay&#41;
&#123;

uint8_t i;

for &#40;i=0; i<=20; i++&#41;
&#123;

PORTB = CL;
_delay_ms&#40;delay&#41;;
PORTB &= ~CL;
_delay_ms&#40;delay&#41;;
&#125;
return;
&#125;

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


DDRB = 0xff; /* Enable output on all of the B pins */
DDRD = 0xff;
PORTB = 0x00; /* Set them all to 0v */
PORTD = 0x00;

while&#40;1&#41;
&#123;
forward&#40;100&#41;;
&#125;

&#125;

fireball
09-03-08, 16:32
Ναι ο winavr είναι. Με τον παραπάνω κώδικα γυρίζει το βηματικό αλλά όχι όπως θα έπρεπε. Του αλλάζω το delay και βάζω forward (2) αλλά δεν περιστρέφετε πιο γρήγορα όπως όταν έχω την forward (void) και και το delay = 2; Απλά περιστρέφετε και κάνει κάτι διακοπές σε διάφορες θέσεις, άρα κάτι δεν δουλεύει σωστά. Θα το ψάξω και άλλο. Ευχαριστω πολύ πάντως!

Επιστήμων
10-03-08, 16:37
Κάτι ξέρω εγώ και δουλεύω σε assembly !

th_shak
10-03-08, 23:21
Κάτι ξέρω εγώ και δουλεύω σε assembly !

Καλή η assembly αλλά δυστυχώς ή ευτυχώς (μάλλον ευτυχώς) στην εποχή που ζούμε οι μικροελεγκτές βρίσκονται σε πολλές συσκευές και εκτελούν περίπλοκες πράξεις οι οποίες δεν υλοποιούνται εύκολα ή και καθόλου σε assembly. Εκτός αυτού πλέον υπάρχουν πολλοί compiler C ή Basic για κάθε οικογένεια μικροελεγκτών, με την βοήθεια των οποίων μπορείς να κάνεις εύκολα προγράμματα τα οποία θα έκανες σε μία βδομάδα ή σε ένα μήνα ή και καθόλου αν χρησιμοποιούσες assembly. Για παράδειγμα τον υπολογισμό του (1/B*(ln(0.0001*R)+3*10^-3)) δεν νομίζω ότι υπάρχει κάποιος που μπορεί να το κάνει εύκολα και μέσα σε λογικά χρονικά πλαίσια χρησιμοποιώντας assembly. Οπότε ξανασκέψου λίγο αυτή την απόφαση σου να παρατήσεις τη C.

Φιλικά, Θωμάς

vaggelis_cha
10-03-08, 23:36
Κάτι ξέρω εγώ και δουλεύω σε assembly !

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

Assembly έχει νόημα να χρησιμοποιήσεις εκεί που θέλεις να έχεις απόλυτο έλεγχο στο h/w και ειδικά σε θέματα timing.

chip
11-03-08, 09:31
Προσωπικά δεν θα χαρακτήριζα ορθογώνιο το set εντολών των AVR όταν έχει 5-6 εντολές μόνο για να κάνει μεταφορές δεδομένων..... τουλάχιστον συγκρίνωντας με μικροελεγκτές όπως οι PSOC της Cypress (πυρήνας M8)

vaggelis_cha
11-03-08, 10:54
Προσωπικά δεν θα χαρακτήριζα ορθογώνιο το set εντολών των AVR όταν έχει 5-6 εντολές μόνο για να κάνει μεταφορές δεδομένων..... τουλάχιστον συγκρίνωντας με μικροελεγκτές όπως οι PSOC της Cypress (πυρήνας M8)

Αγαπητέ chip, δεν έχω δουλέψει τα chips της Cypress, οπότε δεν μπορώ να σου πω περισσότερα επ'αυτών.

Σχετικά με την ορθογωνιότητα του set εντολών του AVR, αυτό έχει να κάνει με τη δυνατότητα να παίζουν όλες οι εντολές με όλους τους registers καθώς και τη μνήμη και όχι μόνο με τις εντολές μεταφοράς δεδομένων.

Για αυτό τον λόγο οι compilers των AVR είναι πολύ πιο αποδοτικοί σε σχέση με αυτούς των x51.



Orthogonal instruction set is a term used in computer engineering. A computer's instruction set is said to be orthogonal if any instruction can use data of any type via any addressing mode. Generally, having an orthogonal instruction set is a desirable attribute for any computer architecture.

chip
11-03-08, 11:16
Σε αυτό ακριβώς αναφέρομε κι εγώ... οτι δεν παίζουν όλες οι εντολές με όλα...
Δηλαδή άλλες παίζουν με τους 16 καταχωρητές άλλες και με τους 32. Άλλες εντολές έχει για τους καταχωτητές Ι/Ο και όλλες για τους γενικής χρήσης... άλλες εντολές για τους καταχωρητές και άλλες για τη RAM και ας είναι συνέχεια η RAM των καταχωρητών... Αυτό δεν είναι πραγματικά ορθογώνια αρχιτεκτονική απλά είναι καλύτερη από κάποιους άλλους... μικροελεγκτές....
Θυμάμαι όταν είχα βάλει τον αδερφό μου να μάθει AVR assembly που ήξερε assembly 8088 είχε φρικάρει.... κι εγώ δεν καταλάβαινα που είναι το πρόβλημα του..

vaggelis_cha
11-03-08, 11:57
Σε αυτό ακριβώς αναφέρομε κι εγώ... οτι δεν παίζουν όλες οι εντολές με όλα...
Δηλαδή άλλες παίζουν με τους 16 καταχωρητές άλλες και με τους 32. Άλλες εντολές έχει για τους καταχωτητές Ι/Ο και όλλες για τους γενικής χρήσης... άλλες εντολές για τους καταχωρητές και άλλες για τη RAM και ας είναι συνέχεια η RAM των καταχωρητών... Αυτό δεν είναι πραγματικά ορθογώνια αρχιτεκτονική απλά είναι καλύτερη από κάποιους άλλους... μικροελεγκτές....
Θυμάμαι όταν είχα βάλει τον αδερφό μου να μάθει AVR assembly που ήξερε assembly 8088 είχε φρικάρει.... κι εγώ δεν καταλάβαινα που είναι το πρόβλημα του..

Δεν έχεις άδικο και έχει πολύ πλάκα η μετάβαση από κάποιον που είχε μάθει σε CISC με accumulator σε RISC με ορθογώνιο set εντολών (όσο ορθογώνιο γίνεται έστω).

Και εγώ από 8086 ξεκίνησα και πολύ μετά έμαθα τον AVR. Στο ενδιάμεσο είχα ασχοληθεί με MIPS και PIC χεχεχεχε 8)

fireball
11-03-08, 17:56
Τελικά δούλεψε.


/* Playing with getting the small stepper motors driven. */

/* Standard Includes */
#include <inttypes>
#include <avr>
#include <avr>
#define F_CPU 1000000UL
#include <util>
/* Pin defs for ATTiny2313 */
/* Clockwise order */
#define HF _BV&#40;PB0&#41;
#define CL _BV&#40;PB1&#41;
#define CW _BV&#40;PD4&#41;

void forward &#40;double&#41;;

void forward &#40;double delay&#41;
&#123;

uint8_t i;

for &#40;i=0; i<=20; i++&#41;
&#123;

PORTB = CL;
_delay_ms&#40;delay&#41;;
PORTB &= ~CL;
_delay_ms&#40;delay&#41;;
&#125;

&#125;

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


DDRB = 0xff; /* Enable output on all of the B pins */
DDRD = 0xff;
PORTB = 0x00; /* Set them all to 0v */
PORTD = 0x00;

while&#40;1&#41;
&#123;
forward&#40;50&#41;;
&#125;

&#125;


Διάβασα το ένα tutorial για τις εντολές avr-lib και ήθελε double μεταβλητή και η τιμή που μπορεί να πάρει το delay εξαρτάτε απο την ταχύτητα του κρυστάλου.
"The maximal possible delay is 262.14 ms / F_CPU in MHz"