Bienvenue aux nouveaux arrivants sur FantasPic !

- Pensez à lire les règles durant votre visite, il n'y en a pas beaucoup, mais encore faut-il les respecter .
- N’hésitez pas à faire des remarques et/ou suggestions sur le Forum, dans le but de l'améliorer et de rendre vos prochaines visites plus agréables.
- Vous pouvez regarder votre "panneau de l'utilisateur" afin de configurer vos préférences.
- Un passage par "l'utilisation du forum" est recommandé pour connaître les fonctionnalités du forum.

--- L’équipe FantasPic ---
Forum général sur le langage C !

Modérateur : Jérémy

Décomposition de nombres binaire en caractères ASCII
Superphénix
Débutant
Débutant
Messages : 54
Enregistré en : mars 2020

#1 Message par Superphénix » lun. 6 mars 2023 21:46

Bonjour
Je cherche à transformer un unsigned short en une suite de 5 caractères ASCII. Exemple 1011001000101100 ==> '4', '5', '6', '1', '2'.
Ensuite je stock les caractères dans la mémoire EEPROM du PIC au milieu d'un texte...
Mais à part faire un algo assez lourd à base de divisions et multiplications par 10 (et rajouter un +48 à la fin) je vois pas ce que je peux faire. Et je ne trouve pas grand chose en cherchant.
Une idée ?
(J'utilise un PIC18F2523)

Décomposition de nombres binaire en caractères ASCII
satinas
Expert
Expert
Messages : 1225
Enregistré en : novembre 2015

#2 Message par satinas » mar. 7 mars 2023 01:35

Salut,
Pour ne pas se fatiguer il y a la fonction sprintf de la bibliothèque stdio.h, elle est très souple, tu peux forcer la conversion sur 5 caractères ou supprimer les '0' non significatifs.

En C la boucle qui divise par 10 semble le plus simple.
Le source de itoa, une fonction de C90 stdlib.h, qui disparaît en C99.
https://android.googlesource.com/kernel ... ibc/itoa.c

Des exemples ici en langage machine :
http://www.piclist.com/techref/microchi ... /index.htm

Décomposition de nombres binaire en caractères ASCII
Temps-x
Avatar de l’utilisateur
Expert
Expert
Messages : 2595
Enregistré en : juillet 2016
Localisation : Terre

#3 Message par Temps-x » mar. 7 mars 2023 01:51

Bonsoir Superphénix, satinas, et tout le forum,

J'ai une routine pour ça, mais elle est tout en assembleur (ASM).... si tu es intéressé fait le mois savoir...

==> A+
:roll: Les requins, c'est comme le langage ASM, c'est le sommet de la chaîne alimentaire. :wink:

Décomposition de nombres binaire en caractères ASCII
satinas
Expert
Expert
Messages : 1225
Enregistré en : novembre 2015

#4 Message par satinas » mar. 7 mars 2023 02:16

Il y a aussi utoa dans stdlib.h en C90.

D'après cela https://stackoverflow.com/questions/789 ... a-function

Code : Tout sélectionner

void u_to_a(unsigned int u, char *s, unsigned char n)
 {
   char *p = s+n;
   while (n--) {
     *--p = "0123456789"[u%10];
     u /= 10;
   }
 }

Salut Temps-x, l'autre fois je te disais que C ne retournait pas le signe du résultat de l'instruction sub, je me plantais car je pensais à l'instruction de comparaison cp des pics 16 bits, qui elle simule la soustraction pour mettre à jour les flags. Pour les 8 bits on a bien dans C le signe du résultat, mais inversé par rapport au bit de signe en complément à 2.

Décomposition de nombres binaire en caractères ASCII
Superphénix
Débutant
Débutant
Messages : 54
Enregistré en : mars 2020

#5 Message par Superphénix » mar. 7 mars 2023 21:05

Je voulais justement éviter la division, parce que ça génère des variables intermédiaires et il se trouve que la RAM de mon PIC est quasi saturé par le reste du programme. Par contre, il me reste 85% de la flashe. Pour avoir testé, si je rajoute une seule fois x = x/10 ; MPLAB me dit que la mémoire et pleine. Et sans, il me reste 7 octets :sifflotte:

Je viens d'essayer un algorithme pas du tout optimisé en thermes de longueur, mais qui marche :

Code : Tout sélectionner

unsigned char BINtoASCII(unsigned short x, char rg)
{
    unsigned short y ;
   
          if(x<10000) y=0 ;
    else {if(x<20000) y=1 ;
    else {if(x<30000) y=2 ;
    else {if(x<40000) y=3 ;
    else {if(x<50000) y=4 ;
    else {if(x<60000) y=5 ;
    else              y=6 ;}}}}}
   
    if(rg==5) return y + 48 ;
    else
    {
        y = (y<<3) + (y<<1) ;
        y = (y<<3) + (y<<1) ;
        y = (y<<3) + (y<<1) ;
        x = x - (y<<3) - (y<<1) ;   // x = x - y*10000 ;
              if(x<1000) y=0 ;
        else {if(x<2000) y=1 ;
        else {if(x<3000) y=2 ;
        else {if(x<4000) y=3 ;
        else {if(x<5000) y=4 ;
        else {if(x<6000) y=5 ;
        else {if(x<7000) y=6 ;
        else {if(x<8000) y=7 ;
        else {if(x<9000) y=8 ;
        else             y=9 ;}}}}}}}}
    }
   
    if(rg==4) return y + 48 ;
    else
    {
        y = (y<<3) + (y<<1) ;
        y = (y<<3) + (y<<1) ;
        x = x - (y<<3) - (y<<1) ;   // x = x - y*1000 ;
              if(x<100) y=0 ;
        else {if(x<200) y=1 ;
        else {if(x<300) y=2 ;
        else {if(x<400) y=3 ;
        else {if(x<500) y=4 ;
        else {if(x<600) y=5 ;
        else {if(x<700) y=6 ;
        else {if(x<800) y=7 ;
        else {if(x<900) y=8 ;
        else            y=9 ;}}}}}}}}
    }
   
    if(rg==3) return y + 48 ;
    else
    {
        y = (y<<3) + (y<<1) ;
        x = x - (y<<3) - (y<<1) ;   // x = x - y*100 ;
              if(x<10) y=0 ;
        else {if(x<20) y=1 ;
        else {if(x<30) y=2 ;
        else {if(x<40) y=3 ;
        else {if(x<50) y=4 ;
        else {if(x<60) y=5 ;
        else {if(x<70) y=6 ;
        else {if(x<80) y=7 ;
        else {if(x<90) y=8 ;
        else           y=9 ;}}}}}}}}
    }
   
    if(rg==2) return y + 48 ;
    else
    {
        x = x - (y<<3) - (y<<1) ;   // x = x - y*10 ;
        y = x ;
    }
   
    if(rg==1) return y + 48 ;
    else return ' ' ;
}


Qu'en pensez vous ?
En tout cas MPLAB ne me mets pas d'erreurs ni de warnings et curieusement il me reste toujours 7 octets dans la RAM. Peut être parce que j'appelle cette fonction à un moment du programme où une partie des autres variables ne servent plus ?

J'ai une routine pour ça, mais elle est tout en assembleur (ASM).... si tu es intéressé fait le mois savoir...

S'il n'y a pas de division par 10 oui :) Faut juste que je trouve un moyen d'intégrer ça dans le code en C.

Décomposition de nombres binaire en caractères ASCII
Temps-x
Avatar de l’utilisateur
Expert
Expert
Messages : 2595
Enregistré en : juillet 2016
Localisation : Terre

#6 Message par Temps-x » mer. 8 mars 2023 01:39

Bonsoir Superphénix, satinas, et tout le forum,

Superphénix a écrit :Source du message S'il n'y a pas de division par 10 oui :) Faut juste que je trouve un moyen d'intégrer ça dans le code en C.

Il y a aucune division, juste des soustractions et addition, de plus tu peux prendre bien plus de 5 caractères ASCII.

Ça va te prendre 5 octets de Ram dans tous les cas, pour une valeurs de 16 bits (pour stockage des caractères)

Normalement pour 16 bits ça corresponds à 5 caractères, quelle est la longueur de bit à convertir :?:

satinas a écrit :Source du message Salut Temps-x, l'autre fois je te disais que C ne retournait pas le signe du résultat de l'instruction sub, je me plantais car je pensais à l'instruction de comparaison cp des pics 16 bits, qui elle simule la soustraction pour mettre à jour les flags. Pour les 8 bits on a bien dans C le signe du résultat, mais inversé par rapport au bit de signe en complément à 2.


De toute façon, comme je ne fais pas de C je suis tranquille de ce coté là, mais en ASM Bigonoff dis ceci

Maintenant, si vous avez bien suivi, vous êtes en train de vous poser la question suivante :

Quand je vois B’11111101’, est-ce que c’est –3 ou est-ce que c’est 253 ?

Et bien vous ne pouvez pas le savoir sans connaître le contexte.

Sachez que les nombres signifient uniquement ce que le concepteur du programme a décidé qu’ils représentent.

S’il travaille avec des nombres signés ou non, ou si cet octet représente tout autre chose (une t°, un caractère, etc).

La seule chose qui importe c’est de respecter les conventions que vous vous êtes fixées lors de la création de cet octet.

C’est donc à vous de décider ce dont vous avez besoin pour tel type de données.

==> A+
:roll: Les requins, c'est comme le langage ASM, c'est le sommet de la chaîne alimentaire. :wink:

Décomposition de nombres binaire en caractères ASCII
satinas
Expert
Expert
Messages : 1225
Enregistré en : novembre 2015

#7 Message par satinas » mer. 8 mars 2023 08:16

Bonjour à tous,

Temps-x, quand je parlais de C, cela concernait la carry C du registre STATUS après soustraction. On en a parlé au sujet de ton algo d'affichage de cercle, je voyais une erreur là où il n'en y avait pas.

Superphénix, ok si tu ne veux pas faire de division, alors on décompose comme tu l'as fait. Si tu ne veux pas de la chaîne s, tu peux stocker un caractère après chaque while.

Code : Tout sélectionner

void u_to_a(unsigned int u, char *s)
{
  s[0] = '0'; while (u >= 10000) { s[0]++; u -= 10000; }
  s[1] = '0'; while (u >= 1000)  { s[1]++; u -= 1000; }
  s[2] = '0'; while (u >= 100)   { s[2]++; u -= 100; }
  s[3] = '0'; while (u >= 10)    { s[3]++; u -= 10; }
  s[4] = '0' + u;
}

Décomposition de nombres binaire en caractères ASCII
Superphénix
Débutant
Débutant
Messages : 54
Enregistré en : mars 2020

#8 Message par Superphénix » mer. 8 mars 2023 19:40

Merci Satinas! :) C'est quand même beaucoup mieux. J'ai adapté à mon code :

Code : Tout sélectionner

unsigned char BINtoASCII(unsigned short x, char rg)
{
    unsigned short y = '0' ;
    while (x >= 10000) { y++ ; x -= 10000 ; }
    if(rg==5) return y ;
    else
    {
       y = '0' ;
       while (x >= 1000)  { y++ ; x -= 1000 ; }
    }
    if(rg==4) return y ;
    else
    {
       y = '0' ;
       while (x >= 100)   { y++ ; x -= 100 ; }
    }
    if(rg==3) return y ;
    else
    {
       y = '0' ;
       while (x >= 10)    { y++ ; x -= 10 ; }
    }
    if(rg==2) return y ;
    else y = '0' ;
    if(rg==1) return y + x ;
    else return ' ' ;
}


Il y a aucune division, juste des soustractions et addition, de plus tu peux prendre bien plus de 5 caractères ASCII.
Ça va te prendre 5 octets de Ram dans tous les cas, pour une valeurs de 16 bits (pour stockage des caractères)
Normalement pour 16 bits ça corresponds à 5 caractères, quelle est la longueur de bit à convertir :?:

Je suppose que l'algo fait à peu près la même chose que celui de Satinas ?
Oui 5 caractères max.

Décomposition de nombres binaire en caractères ASCII
satinas
Expert
Expert
Messages : 1225
Enregistré en : novembre 2015

#9 Message par satinas » mer. 8 mars 2023 19:54

Si tu appelles plusieurs fois la fonction, il y aura beaucoup de calculs répétitifs, c'est toi qui voit.
Sinon pour quoi dimensionner y en 16 bits, 8 bits suffisent, pensons à la ram.
https://microchipdeveloper.com/tls2101:type-qualifiers

Décomposition de nombres binaire en caractères ASCII
Superphénix
Débutant
Débutant
Messages : 54
Enregistré en : mars 2020

#10 Message par Superphénix » mer. 8 mars 2023 21:52

Il me faut bien tout les 16bits. Les nombres que mon programme doit gérer sont rarement inférieurs à 256. Ou j'ai mal compris la question ?
Le temps de calcul n'est pas un problème pour cette fonction en particulier dans mon programme. La fonction est appelé une dizaine de fois, à la toute fin du programme.


Retourner vers « Langage C »

Qui est en ligne

Utilisateurs parcourant ce forum : Aucun utilisateur enregistré et 47 invités