Calcul hexadécimal

Résolu
DJBra'v Messages postés 39 Statut Membre -  
DJBra'v Messages postés 39 Statut Membre -
Bonjour. Je dois mettre en oeuvre un capteur de température qui est en i2c. Mon programme me permet de récupérer deux trames distinctes des résultat de la conversion de la température acquérir. Pour 128 degrés je devrait avoir 0x7ff mais je reçois 0x07 et 0xff dans deux octets distincts. J'aimerai obtenir 0x7ff mais je ne connaît pas de calcul pour y arriver. Quelqu'un connaîtrait t'il une solution ? Merci!

4 réponses

  1. Twinuts Messages postés 27 Date d'inscription   Statut Membre Dernière intervention   2
     
    Salut,

    Tu peux aussi faire comme suit:
    int main(int argc, char** argv) {
      int trames [] = { 0x07, 0xff };
      int t = (trames[0] << 8) | trames[1];
    
      printf("%#x\n", t);
      return 0;
    }
    


    Dev addict
    "On n'est pas au resto : ici on ne fait pas dans les plats tout cuits ..."
    1
    1. sambia39 Messages postés 610 Date d'inscription   Statut Membre Dernière intervention   50
       
      Bonjours & (+1 )
      mais il n'est pas préférable d'utiliser un "^" exclusif ? enfin peut-être que je me trompe, ça éviterait le renvoient retours de la résultante sachant que la valeur de la première trame[0] est utilisée.
      à bientôt
      0
    2. fiddy Messages postés 441 Date d'inscription   Statut Contributeur Dernière intervention   1 847
       
      @sambia39,
      Surtout pas... Aucun risque que le décalage à gauche renvoie autre chose que 0.
      Et comme 0 ^ 0 donne 1, la concaténation deviendrait fausse.
      0
    3. sambia39 Messages postés 610 Date d'inscription   Statut Membre Dernière intervention   50
       
      Bonsoir
      je l'avais bien compris au début, c'est juste que je me suis posé la question suivante même si la valeur de la première trame est 0x00 le décalage fait le boulot et le "ou" exclusif corrige la donne tout en retournant qu'une seule résultante que sinon les deux dans le cas d'un "|" simple enfin je sais pas si je me suis fais comprendre

      #include <stdio.h>
      
      int main(int argc, char** argv) {
        int trames [] = { 0x00, 0x00};
        int t = (trames[0] << 8) ^ trames[1]; //exclusif
        int a = (trames[0] ) | trames[1];
      
        printf(" Cas 1 -> %#x\n", t);
        printf(" Cas 2 -> %#x\n", a);
        return 0;
      }
      


      Résultat


      Success time: 0 memory: 2292 signal:0
      Cas 1 -> 0
      Cas 2 -> 0

      Success time: 0 memory: 2248 signal:0
      Cas 1 -> 0x1
      Cas 2 -> 0x1


      Des suggestions et éclaircissement ??
      0
    4. fiddy Messages postés 441 Date d'inscription   Statut Contributeur Dernière intervention   1 847
       
      Ton programme ne peut pas donner deux traces différentes...
      Sinon, je ne comprends pas ton explication.
      Quoi qu'il en soit, pour le cas présent, l'usage du XOR ou du OR ne changera rien. Classiquement, on utilise plutôt OR pour la concaténation.
      Mais, libre à toi de faire ce que tu veux ;-).
      0
    5. sambia39 Messages postés 610 Date d'inscription   Statut Membre Dernière intervention   50
       
      :) Les deux traces différentes sont des précédents test avec des valeurs différentes de trames afins de voir le résultat. ce qui justifie la trace quant à mon explication j'avoue elle est tordue et mal formulée. (désolée )
      Je pensais juste que le décalage vers la gauche joue un grand rôle qui permetais d'avoir un d'avoir un 0 ^ 0 = 0 au lieu de un 0 ^ 0 = 1 c'est pour cela que je voulais avoir un avis un éclaircissement
      0
  2. Reivax962 Messages postés 3742 Statut Membre 1 011
     
    Bonjour,

    0x07 * 0x100 + 0xff = 0x7ff

    Je ne connais pas suffisamment le C pour te dire si tu peux écrire directement le calcul comme ceci.

    Mais mathématiquement, le résultat que tu souhaites est égal à Trame1 * 0x100 + Trame2.

    Je te fais confiance pour arriver à quelque chose avec ça.

    Xavier
    0
    1. sambia39 Messages postés 610 Date d'inscription   Statut Membre Dernière intervention   50
       
      Bonjour,
      inspire-toi de ça pour essayer d'implémenter ta conversion et @Reivax962 tu peux faire le calcule directement mais à condition de stocker le résulta dans un variable typé si tu veux la manipuler plus tard le resulta.
      à bientôt

      int main(void) {
      	
      	int iCpt	= 0x0000;	        // unsigned valeur NULL
      	int iTab[]	= {0x07,0x100,0xff};	// tableaux exemple
      	int iC		= (0x07 * 0x100 + 0xff);// vérification teste
      	
      	/*	boucle */	
      	while(iCpt < 3){
      		printf(" valeur [%d] = %d\n", iCpt, iTab[iCpt]);
      		iCpt++;	
      	}
      	
      	/*	Affichage décimal	*/
      	printf("%d * %d + %d =", iTab[0],iTab[1],iTab[2]);
      	printf(" %d en decimal\n", ( (iTab[0]*iTab[1])+iTab[2]) );
      	
      	/*	Affichage Hexa	*/
      	printf("%#x * %#x + %#x =", iTab[0], iTab[1],iTab[2]);
      	printf(" %#x en Hexa\n", ( (iTab[0]*iTab[1])+iTab[2]) );
      	
      	return (0);
      }
      


      Resultat

      Success time: 0 memory: 2292 signal:0
      valeur [0] = 7
      valeur [1] = 256
      valeur [2] = 255
      7 * 256 + 255 = 2047 en decimal
      0x7 * 0x100 + 0xff = 0x7ff en Hexa
      0
  3. DJBra'v Messages postés 39 Statut Membre 1
     
    Merci beaucoup pour vos réponse. Je pense que je vais essayer la version de Twinuts. Mais te serais t'il possible de commenter le programme pour mieux comprendre à quoi sert chaque ligne de code? Merci!
    0
    1. Reivax962 Messages postés 3742 Statut Membre 1 011
       
      Son programme est utilisé pour afficher les valeurs.
      Il n'y a qu'une seule ligne à en retenir pour toi :
      int iC		= (0x07 * 0x100 + 0xff);
      0
    2. fiddy Messages postés 441 Date d'inscription   Statut Contributeur Dernière intervention   1 847
       
      Oui une seule ligne suffit.
      Je te conseille plutôt :
      int iC = 0x07<< 8 | 0xff; 

      <<8 te permettra de multiplier par 0x100 (256). Et |0xff te permettra d'additionner par 0xff (255).
      0
    3. DJBra'v Messages postés 39 Statut Membre 1
       
      Ok merci, j'essaye ça!
      0
  4. Utilisateur anonyme
     
    Bonjour

    Je suis étonné de tous ces calculs.
    Il n'y a aucun calcul à faire, un entier de 16 bits, c'est simplement deux octets côte à côte : il suffit de déclarer une union, ce qui permet de manipuler ces 16 bits comme 2 octets distincts ou comme un short selon les besoins.
    union {
          char octet[2];
          short x ;
    } toto;
    
      toto.octet[0]=0xff;
      toto.octet[1]=7;
    
      printf("%04x",toto.x );
    

    Attention, l'ordre des octets poids forts/poids faibles est peut-être l'inverse, ça dépend du processeur ou éventuellement du compilateur utilisé.
    0
    1. DJBra'v Messages postés 39 Statut Membre 1
       
      Ok! Ca me semble super intéressant et ça répond exactement à ce qui me faut! Merci le père.
      0