IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C Discussion :

Séparer une variable en 3 ?


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Nouveau membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2011
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Loire (Auvergne)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2011
    Messages : 7
    Par défaut Séparer une variable en 3 ?
    Bonjour,
    Je programme un PIC en C avec mikroC et mplab et j'aurais quelques questions à vous poser.

    J'ai une variable unsigned int de 16bits donc et qui est en BCD.
    C'est à dire pour le nombre 22 qui était dans ma variable, je l'ai convertis en BCD pour avoir le nombre 34 (0000 0000 0010 0010 )

    Mais je voudrais séparer cette variable en 3 par tranche de 4 bits. ( pour avoir les unités, les dizaines et les centaines )
    mais comment faire ?

    Est ce que les variables sont comme les registres ?
    Exemple : pour selectionner le bit 2 du portA, on fait : PORTA.2 sur mplab
    Est ce que pour prendre le bit 2 d'une variable, on fait : variable.2 ?


    Dernière question, savez vous pourquoi sur mikroC on utilise "PORTA.F2" pour selectionner le bit 2 ?
    Je vous remercie

  2. #2
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Chercheur d'emploi
    Inscrit en
    Septembre 2007
    Messages
    7 484
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Chercheur d'emploi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 484
    Par défaut
    Bonjour,

    En C, comme dans beaucoup d'autres langages, y compris en assembleur, lorsque l'on descend en dessous de la taille du mot élémentaire (byte), il faut utiliser les opérations logiques bit à bit (ET, OU, OU Exclusif, complément) et les décalages pour isoler les champs qui t'intéressent. Donc :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
        variable & 0x000F;
        (variable >> 4) & 0x000F;
    Dernière question, savez vous pourquoi sur mikroC on utilise "PORTA.F2" pour selectionner le bit 2 ?
    Je ne sais pas comment fonctionnent MPlab et MicroC, mais il y a de fortes chances pour qu'il s'agisse en fait d'une macro #define qui fasse ce travail pour toi.

  3. #3
    Nouveau membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2011
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Loire (Auvergne)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2011
    Messages : 7
    Par défaut
    Ah c'est super, merci bien !!

    Petite dernière question : je souhaite convertir la variable BCD en 7 segments. ( donc les 4 premiers bits en 7bits.

    J'ai les équations mais je ne pense pas pourvoir l'adapter.
    E0 .. E seront les 4 premiers bits d'une variable.
    a = E3 | (!E0 & !E2) | (E1 & !E2) | (E2 & E0)
    b = !E2 | (!E0 & !E1) | (E0 & E1)
    c = !E1 | E0 | E2
    d = (!E0 & !E2) | (!E0 & E1) | (E1 & !E2) | (E0 & !E1 & E2)
    e = (!E0 & !E2) | (!E0 & E1)
    f = (!E0 & !E1) | (!E0 & E2) | E3 | (!E1 & E2)
    g = (E1 & !E2) | (!E1 & E2) | E3 | (!E0 & E2);
    Mais ce sont des équations issus des tables de karnaugh et ça n'ira pas...

    Il n'est pas possible de modifier qu'un seul bit d'une variable tout comme un registre ( !PORTA.3 pour changer le bit 3 )

    Merci de votre réponse et de votre patience

  4. #4
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Chercheur d'emploi
    Inscrit en
    Septembre 2007
    Messages
    7 484
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Chercheur d'emploi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 484
    Par défaut
    Il n'est pas possible de modifier qu'un seul bit d'une variable tout comme un registre ( !PORTA.3 pour changer le bit 3 )
    Bien sûr que si, et heureusement. Pour mettre un bit à 1, cela se fait avec un OU logique. Par exemple : 0x80 | 0x01 = 0x81, 0x80 | 0x40 = 0xC0, 0x80 | 0x80 = 0x80. À l'inverse, pour forcer un bit à zéro, on utilise un ET avec le complément du masque ci-dessus. Tout les bits à 1 du masque seront préservés, et les autres forcés à zéro.

    Le OU est donc l'équivalent de l'union, et le ET celui de l'intersection.

    Tu peux enfin utiliser un OU exclusif pour inverser l'état d'un ou plusieurs bits.


    Petite dernière question : je souhaite convertir la variable BCD en 7 segments. ( donc les 4 premiers bits en 7bits. […] Mais ce sont des équations issus des tables de karnaugh et ça n'ira pas...
    Si, il est tout-à-fait possible d'y parvenir par le calcul. Mais c'est compliqué pour rien. Le plus simple est de tenir une table de traduction, c'est-à-dire une table de dix octets dont les entrées contiennent les configurations nécessaires à chaque chiffre. Tu utilises ensuite la valeur de ton chiffre en binaire (ou BCD, c'est pareil s'il n'y a qu'un seul chiffre) comme index dans cette table pour aller récupérer directement la bonne valeur.

  5. #5
    Membre Expert Avatar de davcha
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    1 258
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 1 258
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    typedef union T {
      unsigned short value;
      struct {
        unsigned short segment1 : x;
        unsigned short segment2 : y;
        unsigned short segment3 : z;
      };
    } T;
    Avec x, y et z le nombre de bits pour chaque segment.

    Utilisation:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    T unT;
    unT.value = valeurglobale;
    unT.segment1 = ...;
    unsigned short a = unT.segment2;
    Ce n'est pas ANSI par contre. Et il faut activer les extensions du langage.

  6. #6
    Nouveau membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2011
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Loire (Auvergne)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2011
    Messages : 7
    Par défaut
    Merci de vos réponses,
    J'ai bien compris pour modifier un bit :
    a = 0b00110011;
    Je veux mettre le 3ème LSB à 1 peu importe sa valeur initiale :
    a=(a&11111011) | 00000100;
    // ça me donnera : 0b00110111

    Et je fais pareil pour faire quelque chose de similaire.

    Pour ce qui est du BCD/7sgmts, d'accord donc il faut faire avec un switch et les 10 valeurs.. ( 0 à 9 ) voir plus si je veux afficher des lettres.

    Mais aurais-tu un exemple pour le faire quand même avec les équations ? ( pas forcément un BCD 7sgmts mais simplement utiliser des équations logiques )
    (je dirais avec pleins de if imbriqués .. )

    Car je dois faire la conversion pour 3 ou 4 chiffres et je devrais faire un multiplexage en espérant que ça ne mettent pas trop de temps pour que la rétine puisse voir les 3 afficheurs en même temps...
    Tout ça pour ne pas avoir 7*4 = 28 sorties pour gérer les 4 afficheurs mais seulement 7+4=11 sorties pour gérer mes 4 afficheurs.

    Davcha : merci mais je débute et ça m'a l'air pas mal compliqué , aurais-tu un exemple concret ou alors un nom que je puisse chercher sur google ?

  7. #7
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Chercheur d'emploi
    Inscrit en
    Septembre 2007
    Messages
    7 484
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Chercheur d'emploi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 484
    Par défaut
    Citation Envoyé par laolahaut Voir le message
    Merci de vos réponses,
    J'ai bien compris pour modifier un bit :
    a = 0b00110011;
    Je veux mettre le 3ème LSB à 1 peu importe sa valeur initiale :
    a=(a&11111011) | 00000100;
    // ça me donnera : 0b00110111
    Tout-à-fait. Sauf que tu n'es pas obligé de mettre d'abord le bit à 0 pour le repasser à 1 ensuite. Donc, tu fais directement « a = a | 00000100 ». Enfin, « 0x40 » plutôt que « 00000100 » parce qu'à ma connaissance, tu ne peux pas directement saisir une constante numérique en binaire dans ton programme C.

    Pour ce qui est du BCD/7sgmts, d'accord donc il faut faire avec un switch et les 10 valeurs.. ( 0 à 9 ) voir plus si je veux afficher des lettres.
    Non. Pas un switch. Fais directement un tableau.

    Mais aurais-tu un exemple pour le faire quand même avec les équations ? ( pas forcément un BCD 7sgmts mais simplement utiliser des équations logiques )
    (je dirais avec pleins de if imbriqués .. )
    Pourquoi faire ? Les équations elles-mêmes, tu les as écrites toi-même au-dessus.

    Car je dois faire la conversion pour 3 ou 4 chiffres et je devrais faire un multiplexage en espérant que ça ne mettent pas trop de temps pour que la rétine puisse voir les 3 afficheurs en même temps...
    Tout ça pour ne pas avoir 7*4 = 28 sorties pour gérer les 4 afficheurs mais seulement 7+4=11 sorties pour gérer mes 4 afficheurs.
    Oui mais tu ne pilotes pas chaque bit individuellement. Tu envoies des données vers un port dont chaque bit est reliée à une ligne électrique physique, que tu multiplexes ensuite vers l'afficheur de ton choix.

    C'est idiot de décomposer sept fois ton chiffre BCD vers le bit correspondant au segment de l'afficheur, pour ensuite les recomposer en une valeur que tu vas balancer au port, et ça l'est encore plus de faire ça à l'exécution et À CHAQUE FOIS ! Ces choses-là doivent être calculées à l'avance, mises dans une table constante et balancées telles quelles. C'est à la fois ce qu'il y a de plus simple et de plus efficace.

  8. #8
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 835
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 835
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par davcha Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    typedef union T {
      unsigned short value;
      struct {
        unsigned short segment1 : x;
        unsigned short segment2 : y;
        unsigned short segment3 : z;
      };
    } T;
    Avec x, y et z le nombre de bits pour chaque segment.

    Utilisation:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    T unT;
    unT.value = valeurglobale;
    unT.segment1 = ...;
    unsigned short a = unT.segment2;
    Salut


    Il faut faire attention avec ce genre de technique car même si ça marche 999999 fois sur 1000000, ce n'est pas conforme à la norme.
    Dans la norme sur les unions, on n'a le droit de ne lire que le membre qui a été écrit.
    Donc si tu remplis unT.value, tu ne peux aller lire que unT.value. Lire unT.segment1 produit un comportement non garanti (oserais-je dire "indéterminé" ?...)

    Citation Envoyé par laolahaut Voir le message
    J'ai bien compris pour modifier un bit :
    a = 0b00110011;
    Je veux mettre le 3ème LSB à 1 peu importe sa valeur initiale :
    a=(a&11111011) | 00000100;
    // ça me donnera : 0b00110111?
    Pourquoi mettre un "et" sur 11111011 ? Ca n'a aucun effet sur "a" !!!

    Tu veux mettre le 3° bit de "a" à 1
    a=a | 0x04

    Et si tu veux voir si le 4° bit de "a" vaut 1
    if (a & 0x08)

    Et si tu veux inverser le 5° bit de "a" (le faire passer de 0 à 1 et inversement)
    a=a^0x10

    Ce mécanisme permet de stocker plusieurs booléens sur une seule variable...
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

Discussions similaires

  1. Réponses: 7
    Dernier message: 12/07/2013, 16h24
  2. Séparer une variable en deux variables
    Par blablabli dans le forum Débutez
    Réponses: 2
    Dernier message: 28/01/2013, 15h55
  3. Séparer les variables d'une table
    Par Imfafa dans le forum SAS Base
    Réponses: 5
    Dernier message: 13/05/2011, 18h29
  4. Séparer une variable texte en deux
    Par Invité dans le forum Général JavaScript
    Réponses: 2
    Dernier message: 11/03/2009, 13h39
  5. Séparer nom de fichier / chemin d'accès / extension d'une variable
    Par mklHQ dans le forum Macros et VBA Excel
    Réponses: 8
    Dernier message: 25/06/2008, 12h56

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo