Σελίδα 44 από 55 ΠρώτηΠρώτη ... 34 42 43 44 45 46 54 ... ΤελευταίαΤελευταία
Εμφάνιση αποτελεσμάτων : 431 έως 440 από 543

Θέμα: Απορία για "κώδικα".

  1. #431
    Μέλος Το avatar του χρήστη Fire Doger
    Όνομα
    Στέφανος
    Εγγραφή
    Jan 2015
    Περιοχή
    .
    Μηνύματα
    1.519

    Προεπιλογή

    Να κάνω και εγώ μια ερώτηση σχετική με το περιεχόμενο του θέματος
    Έχω μια συνάρτηση πχ
    void test(char* x){}

    Άμα την καλέσω test("1234"); μου βγάζει warning (αφού τα έχω ενεργοποιήσει, δεν ξέρω αν βγαίνουν στις απλές ρυθμίσεις)
    deprecated conversion from string constant to 'char*' [-Wwrite-strings]

    Οπότε την έκανα void test(const char* x){} κομπλέ...

    Η απορία μου είναι γιατί γκρινιάζει ο compiler, το 1234\0 θα το ψάξει αν υπάρχει και σε άλλο σημείο της RAM και όπου στέλνω "1234" στέλνει τον ίδιο δείκτη ή για άλλο λόγο?

    0 Not allowed! Not allowed!

  2. #432
    Μέλος Το avatar του χρήστη finos
    Όνομα
    Βαγγελης
    Εγγραφή
    Feb 2013
    Περιοχή
    Θεσσαλονίκη
    Μηνύματα
    1.775

    Προεπιλογή

    off topic ...
    ΑΑΑΑ!!! αυτες ειναι οι συναρτησεις που κανουμε τρ στην αλγευρα (α λυκειου)
    Έχω μια συνάρτηση πχ
    void test(char* x){}
    πηγε εκει το μυαλο μ αλλα λεω θα τις εισάγω στων κωδικα διαφορετικα !!! αρα f(x) <=> void f (int x) !!!!

    0 Not allowed! Not allowed!

  3. #433
    Μέλος Το avatar του χρήστη finos
    Όνομα
    Βαγγελης
    Εγγραφή
    Feb 2013
    Περιοχή
    Θεσσαλονίκη
    Μηνύματα
    1.775

    Προεπιλογή

    Παράθεση Αρχικό μήνυμα από Fire Doger Εμφάνιση μηνυμάτων
    Να κάνω και εγώ μια ερώτηση σχετική με το περιεχόμενο του θέματος
    Έχω μια συνάρτηση πχ
    void test(char* x){}

    Άμα την καλέσω test("1234"); μου βγάζει warning (αφού τα έχω ενεργοποιήσει, δεν ξέρω αν βγαίνουν στις απλές ρυθμίσεις)
    deprecated conversion from string constant to 'char*' [-Wwrite-strings]

    Οπότε την έκανα void test(const char* x){} κομπλέ...

    Η απορία μου είναι γιατί γκρινιάζει ο compiler, το 1234\0 θα το ψάξει αν υπάρχει και σε άλλο σημείο της RAM και όπου στέλνω "1234" στέλνει τον ίδιο δείκτη ή για άλλο λόγο?
    char δεν οριζουμε με ' ' ?

    0 Not allowed! Not allowed!

  4. #434
    Μέλος
    Όνομα
    Παναγιώτης
    Εγγραφή
    Jan 2005
    Περιοχή
    ΑΘΗΝΑ
    Μηνύματα
    4.868

    Προεπιλογή

    Παράθεση Αρχικό μήνυμα από Fire Doger Εμφάνιση μηνυμάτων
    Να κάνω και εγώ μια ερώτηση σχετική με το περιεχόμενο του θέματος
    Έχω μια συνάρτηση πχ
    void test(char* x){}

    Άμα την καλέσω test("1234"); μου βγάζει warning
    Με void test(char x){} δοκίμασες;

    0 Not allowed! Not allowed!
    Διάλογος EL σε chat:
    - Μελενέ διονυση οιμε ελεφθεροσ εχής αγωρη εε
    - imina mi lene maria kia psixno agggoriii kalooo
    - Ελει νικα γράψαι ανκληκα δεν ξαιρο

  5. #435
    Μέλος Το avatar του χρήστη Fire Doger
    Όνομα
    Στέφανος
    Εγγραφή
    Jan 2015
    Περιοχή
    .
    Μηνύματα
    1.519

    Προεπιλογή

    Μα δεν θέλω 1 χαρακτήρα, συμβολοσειρά θέλω που να μην μπλέκει με το heap και κάνει allocation όπου νάνε χωρίς να υπάρχει λόγος.
    Ο κώδικας μια χαρά σωστότατος είναι, η απορία μου στον compiler για το πως διαχειρίζεται αυτό το κομμάτι της C στην μνήμη και σε επίπεδο μηχανής.

    Βαγγέλη άμα δεν μάθεις τα βασικά της C δεν θα πας πουθενά. Το * σου δίνει την θέση μνήμης που βρίσκετε κάτι. Αυτό μπορεί να είναι η αρχή δεδομένων οποιουδήποτε τύπου, είτε απλές τύπου int, είτε ποιο σύνθετες πχ πίνακας χαρακτήρων είτε ακόμα ποιο σύνθετες πχ χειροποίητα struct.
    Επίσης μπορεί να είναι η αρχή μιας συνάρτησης. (Και άλλα φαντάζομαι μπορεί να είναι αλλά μέχρι εδώ ξέρω)
    Το "1234" είναι 0χ31,0χ32,0χ33,0χ00 ή '1','2','3','/0'

    void f1(){}

    void f2(){}

    main(){
    void (*funPointer)(void);

    funPointer=f1;
    funPointer(); //Σε αυτό το σημείο θα καλέσει την f1

    funPointer=f2;
    funPointer(); //Σε αυτό το σημείο θα καλέσει την f2
    }

    **Edit
    Ο τύπος μεταβλητής πριν τον pointer δείχνει πόσες πραγματικές θέσεις μνήμης θα μετακινηθεί ο pointer όταν του λες να πάει +1
    Δηλαδή char* x;
    x[1] είναι το επόμενο byte απ' την x[0]
    uint32_t* y;
    y[1] δείχνει μετά από 4 byte απ' την y[0] γιατί η uint_32 πιάνει 4 byte, εσύ θες τον επόμενο int όχι το 2ο byte του 1ου int
    Ανάλογα και με τα υπόλοιπα.
    Το *(οτιδήποτε) είναι ένας uint ανάλογα με το μέγεθος μνήμης, μπορείς να το αποθηκεύσεις, να κάνεις μεταβλητές να δείχνουν όπου νάνε και άλλα παρόμοια. Αυτό κάνουμε στην συνάρτηση, έχουμε μια μεταβλητή ορισμένη ως συνάρτηση και ρυθμίζουμε όταν εκτελείτε από ποια θέση μνήμης να φορτώσει η CPU την επόμενη εντολή.

    (Σε γενικές γραμμές τα παραπάνω, εξαρτάται φυσικά απ' το αν δείχνει ROM, RAM, πως είναι οι μνήμες κλπ κλπ)
    !!!! Άμα τα κάνεις σκατά με τους pointer πολύ πιθανό να καταστρέψεις μέρος προγράμματος, έχω χαλάσει αρκετές φορές τον bootloader

    1 Not allowed! Not allowed!
    Τελευταία επεξεργασία από το χρήστη Fire Doger : 17-03-17 στις 18:23

  6. #436
    Μέλος Το avatar του χρήστη finos
    Όνομα
    Βαγγελης
    Εγγραφή
    Feb 2013
    Περιοχή
    Θεσσαλονίκη
    Μηνύματα
    1.775

    Προεπιλογή

    δεν δουλεει τι σκ@#$α εχω κανει
    Κώδικας:
    #include <SPI.h>int encodervPinA = 18;
    int encodervPinB = 19;
    int encoderaPinA = 20;
    int encoderaPinB = 21;
    int val;
    int VPos = 0;
    int APos = 0;
    int encodervPinALast = LOW;
    int encoderaPinALast = LOW;
    int nv = LOW;
    int na = LOW;
    int cs1=42;
    int cs2=44;
    void setup() {
        pinMode(encodervPinA, INPUT_PULLUP);
        pinMode(encodervPinB, INPUT_PULLUP);
        pinMode(encoderaPinA, INPUT_PULLUP);
        pinMode(encoderaPinB, INPUT_PULLUP);
        attachInterrupt(4, updateEncoderv, CHANGE);
        attachInterrupt(5, updateEncoderv, CHANGE);
        attachInterrupt(3, updateEncodera, CHANGE);
        attachInterrupt(2, updateEncodera, CHANGE);
      Serial.begin(9600);
      SPI.begin();
        pinMode(cs1,OUTPUT);
        pinMode(cs2,OUTPUT);
        digitalWrite(cs1,HIGH);
        digitalWrite(cs2,HIGH);
    }
    void loop() {
    }
    void updateEncoderv() {
        nv = digitalRead(encodervPinA);
        if ((encodervPinALast == LOW) && (nv == HIGH)) {
            if (digitalRead(encodervPinB) == LOW) {
                VPos--;
            }
            else {
                VPos++;
            }
           digitalWrite(cs1,LOW);//c
    SPI.transfer(0);
    SPI.transfer(VPos);//c5t34t4
    delay(10);
    digitalWrite(cs1,HIGH);
            Serial.println(VPos);
            Serial.print("vpos/");
        }
        encodervPinALast = nv;
    }
    void updateEncodera() {
        na= digitalRead(encoderaPinA);
        if ((encoderaPinALast == LOW) && (na == HIGH)) {
            if (digitalRead(encoderaPinB) == LOW) {
                APos--;
            }
            else {
                APos++;
            }
          digitalWrite(cs2,LOW);
    SPI.transfer(0);
    SPI.transfer(APos);
    delay(10);
    digitalWrite(cs2,HIGH);
            Serial.print(APos);
            Serial.println("apos/");
        }
        encoderaPinALast = na;
    }
    οταν δεν κουναω τα encoders ανεβενει - κατεβαίνει rundomly
    εκαν κατι λάθος?

    0 Not allowed! Not allowed!

  7. #437
    Μέλος Το avatar του χρήστη finos
    Όνομα
    Βαγγελης
    Εγγραφή
    Feb 2013
    Περιοχή
    Θεσσαλονίκη
    Μηνύματα
    1.775

    Προεπιλογή

    Παράθεση Αρχικό μήνυμα από Fire Doger Εμφάνιση μηνυμάτων
    Έχει μια βάση αυτό που έγραψες αλλά το πρόβλημα είναι ότι θα καταναλώνεις κύκλους σε κάθε loop για να γράψεις στον register το state ενώ μπορεί να είναι ίδιος.

    Μια ποιο σωστή προσέγγιση θα ήταν να είναι κάπως έτσι:
    Κώδικας:
    const byte ledPin = 13;
    const byte interruptPin = 2;
    byte state = LOW;
    volatile bool Change_State= False;
    
    void setup() {
       pinMode(ledPin, OUTPUT);
       pinMode(interruptPin, INPUT_PULLUP);
       attachInterrupt(digitalPinToInterrupt(interruptPin), blink, CHANGE);
    }
    
    void loop() {
       if(Change_State){
           state=!state;
           digitalWrite(ledPin, state);
           Change_State= False;
       }
    
    }
    
    void blink() { 
    Change_State= True;
    }
    Όταν θα έρθει το interrupt θα ανεβεί μια σημαία να αλλάξει κατάσταση. Και στην loop που υποτίθεται δεν έχει κάτι καλύτερο να κάνει θα ελέγχει την σημαία και αν την βρει σηκωμένη θα αλλάζει κατάσταση και θα την κατεβάζει. Έτσι σε κάθε loop απλώς θα κάνει έλεγχο αν κάτι χρειάζεται ενημέρωση και μόνο τότε θα το ενημερώνει. Σε κάτι τόσο απλό μπορείς και απευθείας απ' το interrupt να αλλάζεις κατάσταση, το να κρατάς τα interrupt μικρά είναι ένας γενικός κανόνας για να αποφύγεις δυσάρεστες καταστάσεις αλλά εφόσον γνωρίζεις τι κάνεις μπορείς να κάνεις και άλλα πράγματα εκτός από σημαίες.

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

    Πολλές βιβλιοθήκες το λαμβάνουν υπόψιν αυτό, άλλες πάλι όχι οπότε πρέπει να είσαι πολύ προσεκτικός γιατί είναι ένα bug που δεν θα εμφανίζεται συνέχεια, 10 θα δουλεύει, 1 όχι.

    Επίσης, αν έχεις είσοδο κάποιο κουμπί, τα interrupt είναι γρήγορα και το bounce το αντιλαμβάνονται οπότε με αυτόν τον κώδικα θα σου έρθουν πολλά interrupt το ένα πίσω απ' το άλλο, όταν έχεις έξοδο στην σειριακή αυτή θα καθυστερεί τον έλεγχο της σημαίας και δεν θα βλέπεις να φλικάρει. Πολλά παλαβά μπορεί να προκύψουν. Αν πχ το Serial.print το βάλεις κάτω απ' το Change_State= False; πολύ πιθανό έτσι όπως το βλέπω να μην αλλάζει κατάσταση το led γιατί κατά την εκτύπωση στην σειριακή ένα interrupt να το ξανακάνει high και να ξανά αλλάξει το led στο επόμενο loop.

    Και τα external interrupt είναι συγκεκριμένα σε κάθε μΕ και μπορεί να μην υποστηρίζουν όλα το CHANGE ή το HIGH, LOW κλπ, αυτά τα βλέπεις στο datasheet.


    Η συνάρτηση του interrupt είναι μια απλή συνάρτηση, η οποία ξεκινάει σε μια θέση μνήμης, όταν έρχεται το interrupt ουσιαστικά εκτελεί μια εντολή τύπου GO_TO που το στέλνει σε αυτήν την θέση μνήμης. Μπορείς αυτήν την συνάρτηση να την καλέσεις κανονικά. Σε μερικούς μΕ μπορείς να προκαλέσεις interrupt μέσω software σηκώνοντας χειροκίνητα την σημαία που ελέγχει η CPU για να εξυπηρετήσει τα interrupt. Σε μερικούς δεν γίνεται γιατί είναι ρυθμισμένοι σε αυτήν την σημαία αν στέλνεις 1 να γράφεται 0 και αν στέλνεις 0 να μην γίνεται τίποτα (αν θυμάμαι καλά)

    Τα interrupt λύνουν πολλά προβλήματα αλλά πρέπει να τα παίζεις στα δάχτυλα για να μην σου δημιουργήσουν άλλα προβλήματα που είναι δύσκολο να βρεις χωρίς in circuit debugger.

    *Edit: Άλλαξα σε volatile την μεταβλητή που αλλάζει στο interrupt, by Savvas
    Κλείνουμε τα interupt κάνοντας detachinterrupt() ?

    0 Not allowed! Not allowed!

  8. #438
    Μέλος Το avatar του χρήστη Fire Doger
    Όνομα
    Στέφανος
    Εγγραφή
    Jan 2015
    Περιοχή
    .
    Μηνύματα
    1.519

    Προεπιλογή

    Παράθεση Αρχικό μήνυμα από finos Εμφάνιση μηνυμάτων
    Κλείνουμε τα interupt κάνοντας detachinterrupt() ?
    ΤA interrupt κλείνουν από το Interrupt Enable bit.
    ΤO interrupt το ελέγχεις από το Interrupt Enable bit που έχει, μερικά περιφερειακά έχουν πολλούς λόγους να δώσουν interrupt, αρα πολλά bit...

    Στην wiring μάλλον με αυτήν την συνάρτηση κλείνει το interrupt για το πιν.

    0 Not allowed! Not allowed!

  9. #439
    Μέλος Το avatar του χρήστη finos
    Όνομα
    Βαγγελης
    Εγγραφή
    Feb 2013
    Περιοχή
    Θεσσαλονίκη
    Μηνύματα
    1.775

    Προεπιλογή

    Δεν κατάλαβα .....

    0 Not allowed! Not allowed!

  10. #440
    Μέλος Το avatar του χρήστη Fire Doger
    Όνομα
    Στέφανος
    Εγγραφή
    Jan 2015
    Περιοχή
    .
    Μηνύματα
    1.519

    Προεπιλογή

    Μερικά περιφερειακά έχουν κάποιους λόγους να δώσουν interrupt, δηλαδή να σηκώσουν 1 bit.
    Το αν θα σηκώσουν το bit όταν έρθει η στιγμή που πρέπει να το σηκώσουν εξαρτάται από 1 άλλο bit.
    Αν θέλεις να κλείσεις 1 interrupt τότε κλείνεις "το άλλο" bit για να μην σηκώνετε η σημαία που προκαλεί interrupt.

    Αν θες να κλείσεις όλα τα interrupt γιατί κάνεις​ κάτι πολύ σημαντικό που δεν σηκώνει διακοπή τότε κλείνεις το bit που ελέγχει το αν θα ακούει η cpu τις σημαίες και πάει στα διανύσματα και δεν κάνει σε τίποτα interrupt.
    (Στο arduino έχει σαν αποτέλεσμα να μην δουλεύει ούτε η millis και δεν μπορείς να κάνεις πολλά πράγματα γιατί πολλά interrupt γίνονται χωρίς να το βλέπεις)
    Μόλις το σηκώσεις θα πάει στα interrupt που έχουν έρθει με σειρά προτεραιότητας.

    Αν θες να κάνεις detach και μετά να το ξανανοίξεις με attach το πιο σωστό είναι να ανοίγωκλείσεις το bit.
    Αλλά επειδή δεν ψήνεσαι να το ψάξεις φαντάζομαι κάντο έτσι.

    *Hard Tip: στη C τα interrupt πηδάνε σε συνάρτηση με συγκεκριμένο όνομα για το κάθε διάνυσμα που το ρυθμίζει κατά το compile και δεν αλλάζει, για να μπορείς να το αλλάζεις live φαντάζομαι σε εκείνη την συνάρτηση φορτώνει τον δείκτη που έχεις ρυθμίσει με την attach από την Ram και ξαναπηδαει στην δικιά σου συνάρτηση.

    0 Not allowed! Not allowed!

Σελίδα 44 από 55 ΠρώτηΠρώτη ... 34 42 43 44 45 46 54 ... ΤελευταίαΤελευταία

Παρόμοια Θέματα

  1. Απαντήσεις: 8
    Τελευταίο Μήνυμα: 01-05-20, 14:51
  2. Απαντήσεις: 1
    Τελευταίο Μήνυμα: 27-05-11, 08:48
  3. Απαντήσεις: 0
    Τελευταίο Μήνυμα: 22-10-10, 23:51
  4. Απαντήσεις: 9
    Τελευταίο Μήνυμα: 22-02-10, 14:01
  5. Απαντήσεις: 39
    Τελευταίο Μήνυμα: 17-04-09, 13:43

Δικαιώματα - Επιλογές

  • Δημιουργία θεμάτων: Όχι
  • Υποβολή μηνυμάτων: Όχι
  • Σύναψη αρχείων: Όχι
  • Επεξεργασία μηνυμάτων: Όχι
  •  
  • BB code: σε λειτουργία
  • Smilies: σε λειτουργία
  • [IMG]: σε λειτουργία
  • [VIDEO] code is σε λειτουργία
  • HTML: εκτός λειτουργίας