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 ---
- 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 ---
Modérateur : Jérémy
Décomposition de nombres binaire en caractères ASCII
-
Superphénix
Débutant- Messages : 54
- Enregistré en : mars 2020
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)
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
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
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
Décomposition de nombres binaire en caractères ASCII
Il y a aussi utoa dans stdlib.h en C90.
D'après cela https://stackoverflow.com/questions/789 ... a-function
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'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- Messages : 54
- Enregistré en : mars 2020
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
Je viens d'essayer un algorithme pas du tout optimisé en thermes de longueur, mais qui marche :
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 ?
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.
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
Bonsoir Superphénix, satinas, et tout le forum,
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
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+
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+
Décomposition de nombres binaire en caractères ASCII
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.
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- Messages : 54
- Enregistré en : mars 2020
Merci Satinas! :) C'est quand même beaucoup mieux. J'ai adapté à mon code :
Je suppose que l'algo fait à peu près la même chose que celui de Satinas ?
Oui 5 caractères max.
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
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
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- Messages : 54
- Enregistré en : mars 2020
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.
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.
Qui est en ligne
Utilisateurs parcourant ce forum : Aucun utilisateur enregistré et 42 invités