Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
1316 connectés 

  FORUM HardWare.fr
  Programmation
  C

  [PIC/C] Pb Stack overflow

 



 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

[PIC/C] Pb Stack overflow

n°2051140
crom29
Posté le 23-01-2011 à 10:44:22  profilanswer
 

Bonjour !
 
J'ai un problème plutôt agaçant sur un programme en C pour PIC18F452 : Stack overflow is forcing device reset (message donné par ISIS lors de la simulation)
 
J'ai cherché un peu sur les forums, et il semblerait que cela provienne de trop de boucles les unes dans les autres
ors ce stack overflow n'apparait que quand je met une toute simple ( pBuzzer = 1; ), même pas dans une boucle. (ligne a déjà été utilisée ailleurs sans problèmes...).
 
Quelqu'un a t'il une idée d'où le problème peut bien venir? des solutions pour limiter/supprimer ce problème?
 
Merci d'avance !


Message édité par crom29 le 23-01-2011 à 10:50:26

---------------
Mods: HAF922 | Shinobi XL White    GitHub     Admin de La Colère d'Aurile, serveur RP-Action Neverwinter Nights 2
mood
Publicité
Posté le 23-01-2011 à 10:44:22  profilanswer
 

n°2051164
gilou
Modérateur
Modzilla
Posté le 23-01-2011 à 13:43:40  profilanswer
 

http://hfr-rehost.net/betaforum.kinssha.org/generateurSmileys/smiley99698.gif
A+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
n°2051202
crom29
Posté le 23-01-2011 à 18:41:40  profilanswer
 

heu... le code fait 700 lignes, et en plus c'est pas un problème lié à une ligne ou un bloc de lignes, mais a l'ensemble du programme (n'importe quelle ligne ajoutée/commentée peut donner un stack overflow/le supprimer)
 
ma question aurait plutôt du être :
Avez vous déja eu affaire à un stack overflow, et si oui comment l'avez vous résolu?


Message édité par crom29 le 23-01-2011 à 18:42:11

---------------
Mods: HAF922 | Shinobi XL White    GitHub     Admin de La Colère d'Aurile, serveur RP-Action Neverwinter Nights 2
n°2051276
billgatesa​nonym
Posté le 23-01-2011 à 22:15:02  profilanswer
 

1. Vérifiez votre code, parce que généralement ce problème est causé par un bug (fuite mémoire ou appel récursif).
 
2. Vérifier votre code, parce que vous avez peut-être des variables locales, ou en paramètres, qui sont trop grandes.
 
3. Voyez si vous ne pourriez pas réduire vos besoins d'espace sur la pile.
 
4. Voyez si vous ne pourriez pas agrandir la pile.

n°2051490
crom29
Posté le 24-01-2011 à 19:36:04  profilanswer
 

merci de ta réponse billgatesanonym ;)
 
voici quelques lignes de codes (j'ai testé et compilé, et en simulation sur isis, ça me lance des tonnes de "stack overflow" )

Code :
  1. //LCD
  2. sbit LCD_RS at RD4_bit;
  3. sbit LCD_EN at RD5_bit;
  4. sbit LCD_D4 at RD0_bit;
  5. sbit LCD_D5 at RD1_bit;
  6. sbit LCD_D6 at RD2_bit;
  7. sbit LCD_D7 at RD3_bit;
  8. sbit LCD_RS_Direction at TRISD4_bit;
  9. sbit LCD_EN_Direction at TRISD5_bit;
  10. sbit LCD_D4_Direction at TRISD0_bit;
  11. sbit LCD_D5_Direction at TRISD1_bit;
  12. sbit LCD_D6_Direction at TRISD2_bit;
  13. sbit LCD_D7_Direction at TRISD3_bit;
  14. //Entrees
  15. #define pHaut PORTB.F0
  16. #define pDroite PORTB.F1
  17. #define pBas PORTB.F2
  18. #define pGauche PORTB.F3
  19. #define pOK PORTB.F4
  20. #define pMenu PORTB.F5
  21. //Sorties
  22. #define pBuzzer PORTC.F0
  23. const int MENU_SELECT_MODES = 0;
  24. const int MENU_PARAMETRES = 1;
  25. void main()
  26. {
  27. int nMenu;
  28. int nCurPos;
  29. float fHauteurMur;
  30. char cHauteurMur[5] = "00.0";
  31. //Initialisation
  32. ADCON1 = 0b11001110;
  33. //Toute la porte B en entrée ( /!\ signal de groupe )
  34. TRISB = 0x00;
  35. PORTB = 0x00;
  36. TRISB = 0xFF;   
  37. TRISC = 0x00;    //Porte C = sorties
  38. PORTC = 0x00;
  39. Lcd_Init();
  40. Lcd_Cmd(_LCD_CLEAR);
  41. Lcd_Cmd(_LCD_CURSOR_OFF);
  42. ADC_Init();
  43. //blocage programme avec soundplay
  44. //Sound_Init(&PORTA, 3);
  45. //Sound_Play(440, 100);
  46. Lcd_Out(1,1,"O--Selection Mode-->" );
  47. Lcd_Out(2,1,"| > Automatique    |" );
  48. Lcd_Out(3,1,"|   Manuel         |" );
  49. Lcd_Out(4,1,"O   Asservit       >" );
  50. nMenu = MENU_SELECT_MODES;
  51. nCurPos = 2;
  52. while(!pOK)
  53.      {
  54.      if(pHaut)
  55.           {
  56.           //Efface l'ancien curseur
  57.           Lcd_Out(nCurPos,3," " );
  58.           //déplace la var curseur et le curseur
  59.           nCurPos--;
  60.           if(nCurPos == 1){nCurPos = 4;}
  61.           Lcd_Out(nCurPos,3,">" );
  62.           //Bip sonore
  63.           pBuzzer = 1;
  64.           Delay_ms(80);
  65.           pBuzzer = 0;
  66.          
  67.           while(pHaut){}
  68.           }
  69.      else if(pBas)
  70.           {
  71.           //Efface l'ancien curseur
  72.           Lcd_Out(nCurPos,3," " );
  73.           //déplace la var curseur et le curseur
  74.           nCurPos++;
  75.           if(nCurPos == 5){nCurPos = 2;}
  76.           Lcd_Out(nCurPos,3,">" );
  77.           //Bip sonore
  78.           pBuzzer = 1;
  79.           Delay_ms(80);
  80.           pBuzzer = 0;
  81.           while(pBas){}
  82.           }
  83.      else if(pDroite)
  84.           {
  85.           if(nMenu == MENU_SELECT_MODES)
  86.                {
  87.                MainMenu_Params:
  88.                Lcd_Cmd(_LCD_CLEAR);
  89.                Lcd_Out(1,1,"<----Parametres----O" );
  90.                Lcd_Out(2,1,"| > Hauteur Mur    |" );
  91.                Lcd_Out(3,1,"|   Affichage vit. |" );
  92.                Lcd_Out(4,1,"<   Version prmg   O" );
  93.                nCurPos = 2;
  94.                nMenu = MENU_PARAMETRES;
  95.                //Bip sonore
  96.                pBuzzer = 1;
  97.                Delay_ms(80);
  98.                pBuzzer = 0;
  99.                }
  100.              
  101.           while(pDroite){}
  102.           }
  103.      else if(pGauche)
  104.           {
  105.           if(nMenu == MENU_PARAMETRES)
  106.                {
  107.                MainMenu_SelecModes:
  108.                Lcd_Cmd(_LCD_CLEAR);
  109.                Lcd_Out(1,1,"O--Selection Mode-->" );
  110.                Lcd_Out(2,1,"| > Automatique    |" );
  111.                Lcd_Out(3,1,"|   Manuel         |" );
  112.                Lcd_Out(4,1,"O   Asservit       >" );
  113.                nCurPos = 2;
  114.                nMenu = MENU_SELECT_MODES;
  115.                //Bip sonore
  116.                pBuzzer = 1;
  117.                Delay_ms(80);
  118.                pBuzzer = 0;
  119.                }
  120.           while(pGauche){}
  121.           }
  122.      else if(pMenu)
  123.           {
  124.           while(pMenu){}
  125.           goto MainMenu_SelecModes;
  126.           }
  127.      }
  128.    
  129. pBuzzer = 1;
  130. Delay_ms(80);
  131. pBuzzer = 0;
  132. while(pOK){}
  133. switch(nMenu)
  134.      {
  135.      //Mode Automatique
  136.      case MENU_SELECT_MODES:
  137.      if(nCurPos == 2)
  138.           {
  139.           Lcd_Cmd(_LCD_CLEAR);
  140.           Lcd_Out(1,1,"O------------------O" );
  141.           Lcd_Out(2,1,"| Mode             |" );
  142.           Lcd_Out(3,1,"|      Automatique |" );
  143.           Lcd_Out(4,1,"O------------------O" );
  144.           Delay_ms(800);
  145.           }
  146.      else if(nCurPos == 3)
  147.           {
  148.           Lcd_Cmd(_LCD_CLEAR);
  149.           Lcd_Out(1,1,"O------------------O" );
  150.           Lcd_Out(2,1,"|   Mode           |" );
  151.           Lcd_Out(3,1,"|         Manuel   |" );
  152.           Lcd_Out(4,1,"O------------------O" );
  153.           Delay_ms(800);
  154.           }
  155.      else if(nCurPos == 4)
  156.           {
  157.           Lcd_Cmd(_LCD_CLEAR);
  158.           Lcd_Out(1,1,"O------------------O" );
  159.           Lcd_Out(2,1,"|  Mode            |" );
  160.           Lcd_Out(3,1,"|        Asservit  |" );
  161.           Lcd_Out(4,1,"O------------------O" );
  162.           Delay_ms(800);
  163.           }
  164.      break;
  165.      case MENU_PARAMETRES:
  166.      if(nCurPos == 2)
  167.           {
  168.           Lcd_Cmd(_LCD_CLEAR);
  169.           Lcd_Out(1,1,"<--Hauteur du mur--O" );
  170.           Lcd_Out(2,1,"|          metres  |" );
  171.           Lcd_Out(3,1,"| (Valider par OK) |" );
  172.           Lcd_Out(4,1,"<------------------O" );
  173.          
  174.           //fHauteurMur = EEPROM_Read(0x10); A RESOUDRE
  175.           fHauteurMur = 13.0;
  176.           FloatToStr(fHauteurMur, cHauteurMur);
  177.           Lcd_Out(2,4,cHauteurMur);
  178.          
  179.           while(!pOK && !pMenu && !pGauche)
  180.                {
  181.                if(pHaut)
  182.                     {/*
  183.                     fHauteurMur = fHauteurMur+0.1;
  184.                     FloatToStr(fHauteurMur, cHauteurMur);
  185.                     Lcd_Out(2,4,cHauteurMur);
  186.                     while(pHaut){}*/
  187.                     }
  188.                else if(pBas)
  189.                     {/*
  190.                     fHauteurMur = fHauteurMur-0.1;
  191.                     FloatToStr(fHauteurMur, cHauteurMur);
  192.                     Lcd_Out(2,4,cHauteurMur);
  193.                     while(pBas){}*/
  194.                     }
  195.                }
  196.           if(pOK)
  197.                {/*
  198.                while(pOK){}
  199.                EEPROM_Write(0x02, fHauteurMur*10);
  200.                goto MainMenu_Params;*/
  201.                }
  202.           else if(pMenu)
  203.                {/*
  204.                while(pMenu){}
  205.                goto MainMenu_SelecModes;*/
  206.                }
  207.           else if(pGauche)
  208.                {/*
  209.                while(pGauche){}
  210.                goto MainMenu_Params;*/
  211.                }
  212.           }
  213.      else if(nCurPos == 3)
  214.           {
  215.           Lcd_Cmd(_LCD_CLEAR);
  216.           Lcd_Out(1,1,"O------------------O" );
  217.           Lcd_Out(2,1,"| Mode Automatique |" );
  218.           Lcd_Out(3,1,"O------------------O" );
  219.           Delay_ms(800);
  220.           }
  221.      else if(nCurPos == 4)
  222.           {
  223.           Lcd_Cmd(_LCD_CLEAR);
  224.           Lcd_Out(1,1,"<-----Version------O" );
  225.           Lcd_Out(2,1,"| Programme : v2.1 |" );
  226.           Lcd_Out(3,1,"|  Du : 24/01/2011 |" );
  227.           Lcd_Out(4,1,"<------------------O" );
  228.          
  229.           while(!pGauche && !pMenu){}
  230.           if(pGauche){while(pGauche){} goto MainMenu_Params;}
  231.           else {while(pMenu){} goto MainMenu_SelecModes;}
  232.           }
  233.      break;
  234.      }
  235. }


L'erreur, enfin les erreurs proviennent des lignes commentées (aux environs de la ligne 210)
Deux solutions pour faire réapparaitre les stack overflow :
-Dé-commenter une des lignes : fHauteurMur = fHauteurMur+0.1; (ou -0.1)
-Dé-commenter une des lignes : FloatToStr(fHauteurMur, cHauteurMur);
 
J'ai cherché l'erreur, et franchement je ne vois pas...
l'itération de fHauteurMur est des plus classiques, et la fonction FloatToStr est utilisée juste au dessus et ne pose aucun problème...
 
 
que je soit sûr : la pile c'est les boucles du genre while(), et un stack overflow correspond à trop de boucles imbriquées les unes dans les autres?
Dans ce cas, réduire mes besoins de pile, c'est changer un peu le programme pour utiliser moins de boucles?
 
Agrandir la pile? ça serait super ça, mais je ne sais pas si c'est possible avec un PIC...
 
 
 
petite question à part : Je n'arrive pas à écrire sur l'eeprom du pic en simulation, isis me donne ce code d'erreur :
Attempt to write to data EEPROM address 0x0010 not allowed - WRTD bit in configuration is not set
C'est sûrement très simple, mais je n'ai jamais encore jamais fait ça, et j'hésite entre : c'est le simulateur qui me l'empêche / il faut désactiver la protection au flashage du pic / Il faut rajouter un qqch au programme / c'est dans la configuration du compilateur... ça fait pas mal de chose et je ne sais pas trop où chercher ^^
 
 
Merci :)


---------------
Mods: HAF922 | Shinobi XL White    GitHub     Admin de La Colère d'Aurile, serveur RP-Action Neverwinter Nights 2
n°2051529
Olivier51
Posté le 24-01-2011 à 22:43:43  profilanswer
 

Lorsque tu as le stack overflow, tu as decommente aussi les lignes "while(pHaut){}" et "while(pBas){}" ?
 
Ce qui est possible c'est que ton float fHauteur depasse les 4 characteres (+ 1 pour le charactere final) alloues initialement (ligne 37).
 
Si tu ne verifies pas que pHaut et pBas sont egales a zero, alors tes conditions seront tout le temps vraies et tu va facilement arriver a 100.0 ou -10.0 qui depassent les limites de ta chaine de caractere.

n°2051582
billgatesa​nonym
Posté le 25-01-2011 à 10:17:27  profilanswer
 

Les goto mettent sûrement la pagaille, par exemple les goto MainMenu_Params;
 
D'une manière générale, il est fortement déconseillé d'utiliser des goto, parce que cela rend le code difficilement lisible.
 
Mais il y a une autre raison, qui est que les compilateurs ont beaucoup de mal à les gérer dans certaines situations.
 
C'est pour cela qu'a été inventé l'instruction longjmp qui est comme un goto, mais sans certains problèmes.
Voir http://www.fmc-modeling.org/catego [...] ngjmp.html où il est écrit :

Citation :

the Longjump concept is very similar to using "goto". However as opposed to longjmp(), "goto" will not restore any of the program's state. Therefore longjmp() can be used for jumps without corrupting the call stack.


 
Edit : J'ai retrouvé une page sur les spécifications officielles du langage C http://c0x.coding-guidelines.com/6.8.6.1.html :

Citation :

A goto statement shall not jump from outside the scope of an identifier having a variably modified type to inside the scope of that identifier.
...
A goto statement is not allowed to jump past any declarations of objects with variably modified types. A jump within the scope, however, is permitted.
 
 
        goto lab3;                        // invalid: going INTO scope of VLA.
        {
                double a[n];
                a[j] = 4.4;
        lab3:
                a[j] = 3.3;
                goto lab4;                // valid: going WITHIN scope of VLA.
                a[j] = 5.5;
        lab4:
                a[j] = 6.6;
        }
        goto lab4;                        // invalid: going INTO scope of VLA.


Voici d'autres pages sur le goto http://msdn.microsoft.com/en-us/li [...] s.80).aspx

Citation :

It is good programming style to use the break, continue, and return statement in preference to goto whenever possible.


Voir aussi http://www.codeguru.com/forum/show [...] light=goto


Message édité par billgatesanonym le 25-01-2011 à 10:45:40
n°2051611
gilou
Modérateur
Modzilla
Posté le 25-01-2011 à 11:22:16  profilanswer
 


Le goto, c'est pas interdit en C, et il y a des situations (changements d'état d'un automate à états finis par exemple) ou c'est fortement utile et ou un setjmp/longjmp n'est pas optimal.
C'est déconseillé aux développeurs inexpérimentés.
Bon néanmoins dans la cas de ce code, on peut s'en passer au prix d'une variable exitcode supplémentaire.
Mais le pb ne vient pas probablement de cela.
 

Citation :

Ce qui est possible c'est que ton float fHauteur depasse les 4 characteres (+ 1 pour le charactere final) alloues initialement (ligne 37).


Ça me semble bien vu, et être probablement la cause du pb.
A+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
n°2051617
billgatesa​nonym
Posté le 25-01-2011 à 11:31:24  profilanswer
 

gilou a écrit :

Le goto, c'est pas interdit en C

Je n'ai jamais dit cela. Lisez avant de critiquer !

gilou a écrit :

Mais le pb ne vient pas probablement de cela.

Pourquoi vous dîtes cela ? Si vous critiquez, apportez des arguments. Ne le faîtes pas lâchement et arbitrairement.
Moi, je vous donne quatre références séireuses, qui donnent des exemples précis et similaires au cas présent, où le goto est la source de corruption de la pile. Et, vous, vous balayez ces quatre références d'un revers de main, sans aucun argument. Ce n'est pas comme cela que l'on discute sur un forum.
 

n°2051641
gilou
Modérateur
Modzilla
Posté le 25-01-2011 à 12:53:17  profilanswer
 

billgatesanonym a écrit :

Je n'ai jamais dit cela. Lisez avant de critiquer !

Et ou ais-je dit que vous l'aviez dit? C'est quoi ce procès d'intention? [:popol]

billgatesanonym a écrit :

Si vous critiquez, apportez des arguments.

La lecture du code est claire:
Parce que l'on voit bien ici les blocs étiquetés:

Code :
  1. {
  2.                MainMenu_Params:
  3.                Lcd_Cmd(_LCD_CLEAR);
  4.                Lcd_Out(1,1,"<----Parametres----O" );
  5.                Lcd_Out(2,1,"| > Hauteur Mur    |" );
  6.                Lcd_Out(3,1,"|   Affichage vit. |" );
  7.                Lcd_Out(4,1,"<   Version prmg   O" );
  8.                nCurPos = 2;
  9.                nMenu = MENU_PARAMETRES;
  10.                //Bip sonore
  11.                pBuzzer = 1;
  12.                Delay_ms(80);
  13.                pBuzzer = 0;
  14.                }


et

Code :
  1. {
  2.                MainMenu_SelecModes:
  3.                Lcd_Cmd(_LCD_CLEAR);
  4.                Lcd_Out(1,1,"O--Selection Mode-->" );
  5.                Lcd_Out(2,1,"| > Automatique    |" );
  6.                Lcd_Out(3,1,"|   Manuel         |" );
  7.                Lcd_Out(4,1,"O   Asservit       >" );
  8.                nCurPos = 2;
  9.                nMenu = MENU_SELECT_MODES;
  10.                //Bip sonore
  11.                pBuzzer = 1;
  12.                Delay_ms(80);
  13.                pBuzzer = 0;
  14.                }
 

Et on a pas de problème de scope de variable associable aux gotos: Tout est soit des variables globales, soit des locales avec main pour scope ici.

 

A+,

 


Message édité par gilou le 25-01-2011 à 13:31:00

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
mood
Publicité
Posté le 25-01-2011 à 12:53:17  profilanswer
 

n°2051648
crom29
Posté le 25-01-2011 à 13:28:50  profilanswer
 

merci de toutes vos réponses, ça fait vraiment plaisir :)
 
je regarde tout ça avec précision ce soir !


---------------
Mods: HAF922 | Shinobi XL White    GitHub     Admin de La Colère d'Aurile, serveur RP-Action Neverwinter Nights 2
n°2051853
crom29
Posté le 25-01-2011 à 21:14:22  profilanswer
 

bon j'ai fait quelques tests, et j'ai eu une surprise...
Lignes 211, 213, 214 dé-commentée, ce qui donne ça :

Code :
  1. if(pHaut)
  2.                     {
  3.                     fHauteurMur = fHauteurMur+0.1;
  4.                     //FloatToStr(fHauteurMur, cHauteurMur);
  5.                     Lcd_Out(2,4,cHauteurMur);
  6.                     while(pHaut){}
  7.                     }

et ça plante pas...  :heink: (pourtant hier ça plantait bien)
par contre, si je dé-commente la ligne FloatToStr(...); , là ça plante directement !
 
j'ai essayé en déclarant fHauteurMur ainsi : float fHauteurMur[10]; et j'ai aussi essayé comme ça : float fHauteurMur[];  
Dans les deux cas ==> stack overflow
 
ensuite j'ai aussi commenté tous les goto ... et leurs repères
==> Stack overflow, encore
 
 
 
Olivier51 :

Citation :

Si tu ne verifies pas que pHaut et pBas sont egales a zero, alors tes conditions seront tout le temps vraies et tu va facilement arriver a 100.0 ou -10.0 qui depassent les limites de ta chaine de caractere.

pHaut, pBas, ainsi que pDroite et pGauche sont des pins du PIC qui correspondent à un bouton poussoir
le truc c'est que un appui sur le bouton haut (en étant dans le menu Hauteur du mur bien sûr) augmente fHauteurMur de 10cm (normalement, le mur ne devrais pas dépasser les 13m ^^)
A moins d'avoir l'esprit torturé, fHauteurMur variera entre 5.0 et 15.0 (mais c'est vrai qu'il serait mieux d'y mettre des limites)
 
 
billgatesanonym :  
Vu que j'ai supprimé tous les goto du programme et qu'il fait encore du stack overflow, je ne vais garder ce longjmp de côté, je suis sûr qu'il va me servir un moment ou un autre ^^
D'ailleurs, je pense même remplacer mes goto par des longjmp une fois que je n'aurais pas ce foutu stack overflow sur le dos !
 
 
gilou :

Citation :

C'est déconseillé aux développeurs inexpérimentés

ah bah merci ! :cry:  
 
 
... mais nan je plaisante  :D  
Dans mon 1er jet de programme, j'avait plein de while imbriqués, avec plein de trucs du genre "while(1){... nReturnBoucle=1;break; ...}switch(nReturnBoucle){case...}" ... enfin bref c'était carément chiant et presque bordélique. Ensuite je me suis dit : "Un goto, c'est pas beau, mais ça serait hyper plus simple pour passer d'un menu à l'autre !", et voila ce que ça a donné ^^
 
ps : pas besoin de se mettre sur la tronche pour ça :p

Message cité 1 fois
Message édité par crom29 le 25-01-2011 à 21:19:01

---------------
Mods: HAF922 | Shinobi XL White    GitHub     Admin de La Colère d'Aurile, serveur RP-Action Neverwinter Nights 2
n°2051867
gilou
Modérateur
Modzilla
Posté le 25-01-2011 à 22:08:04  profilanswer
 

crom29 a écrit :

j'ai essayé en déclarant fHauteurMur ainsi : float fHauteurMur[10]; et j'ai aussi essayé comme ça : float fHauteurMur[];  
Dans les deux cas ==> stack overflow

c'est cHauteurMur qu'il faut modifier ici, hein.
Probablement en posant: char cHauteurMur[13] = "00.0"; (lire plus loin pour l'explication)
 
Bon, je pense que j'ai une piste, si tu utilises le MikroC de MikroElektronika: La fonction FloatToStr est connue pour avoir des défauts avec certaines versions du compilo, et représenter des nombres (plus grand que 10.0, si ils sont plus petit, il n'y a pas bug semble t'il) qui devraient être avec un chiffre après la virgule comme en ayant plus (dans la string):

Citation :

For example try this:  
define a float variable = 2610.5  
FloatToStr it  
you obtain 2610.499  
then: define a float variable = 0.5  
FloatToStr it  
this is good: 0.5  
now, FloatToStr(var1-var2, txt)  
and you obtain 2609.999


C'est un bug bien connu apparemment et qui semble se ramener à ceci:

Citation :

The FloatToStr function is not the culprit here (it could perform some forced rounding, but it's not a real solution). The source of the problem lies in Microchip floating point library (AN575), used, with some modifications, by mC. Due to errors in original code, the so-called unbiased rounding cannot be used and is blocked in the library. This also means that when converting from float to integral type, there's no rounding, as well - only truncation. These are the real reasons that lead to results with 9's at the end.


( http://www.mikroe.com/forum/viewto [...] =13&t=9061 )
Si cette fonction buggée fait trop de chiffres après la virgule, ça tiendra pas dans les 5 chars que tu lui donnes avec char cHauteurMur[5] = "00.0"; et c'est peut être ce qui provoque le bug.
Pour vérifier si le pb vient bien de la, remplaces char cHauteurMur[5] = "00.0"; par par cHauteurMur[13] = "00.0"; et regardes si ça colle (apparemment, 13 est la taille approprié pour la chaîne paramètre de FloatToStr selon ce que j'ai lu sur le web)
Certains, pour résoudre le pb d'affichage de juste la partie qui les intéresse et pas tous les chiffres utilisent ce type de technique:

Code :
  1. char temp[13];
  2. char LCDtemp[5];
  3. FloatToStr(temp_val.f, temp);
  4. for (i = 0; i < 5; i++){
  5. LCDtemp[i] = temp[i];
  6. }
  7. Lcd_Out(1, 1, LCDtemp);


Bref, ils copient les premiers chiffres qu'ils veulent (sans \0 final?), mais en évitant bien d'utiliser la chaine résultat de FloatToStr dans Lcd_Out
D'autres font:

Code :
  1. FloatToStr(temp_val.f, temp);
  2. Lcd_chr(1,15,temp[0]);
  3. Lcd_chr(1,16,temp[1]);
  4. Lcd_chr(1,17,temp[2]);
  5. Lcd_chr(1,18,temp[3]);
  6. Lcd_chr(1,19,temp[4]);


Tu peux sans doute procéder de même en adaptant selon tes besoins.
A+,


Message édité par gilou le 25-01-2011 à 22:17:29

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
n°2052144
crom29
Posté le 26-01-2011 à 19:53:32  profilanswer
 

ma solution pour le float to string va se résumer à ça :

Code :
  1. //===========================================================================================
  2. //==CUST_INTTOSTRING===CUST_INTTOSTRING===CUST_INTTOSTRING===CUST_INTTOSTRING===CUST_INTTOSTRING===CUST_INTTOSTRING===
  3. //==============================================================================================
  4. // nNbAConvertir = entier à convertir
  5. // Var : Variable dans laquelle sera placée la conversion
  6. // nChars : 0 => chiffres alignés à gauche, Sinon les chiffres seront alignés à gauche et nChars = nombre max de chiffres à afficher
  7. // bRemplir : FALSE => les caractères inutilisés seront ignorés, TRUE => seront remplis de "0" (inutile si nChars==0)
  8. void CustIntToString(int nNbAConvertir, char *Var, int nChars, unsigned short bRemplir)
  9. {
  10. unsigned int nVarSoustraction = 0;
  11. unsigned int nChiffreAConvertir = 0;
  12. int nChiffres = 1;
  13. int nPow = 10;
  14. int n;
  15. //Determination du nb de chiffres dans nNbAConvertir
  16. while(nNbAConvertir >= nPow)
  17.         {
  18.         nChiffres++;
  19.         nPow = 10*nPow;
  20.         }
  21. //Remplissage
  22. if(bRemplir)
  23.      {
  24.      for(n=1 ; nChars-nChiffres-(n-1)>=0 ; n++)
  25.           {
  26.           Var[nChars-nChiffres-(n-1)] = 0x0030;
  27.           }
  28.      }
  29. //Conversion
  30. for( n=1 ; n<=nChiffres ; n++ )
  31.      {
  32.      nChiffreAConvertir = (nNbAConvertir-nVarSoustraction)/( Puissance(10, (nChiffres-n)) );
  33.    
  34.      if(nChars!=0)
  35.           {
  36.           Var[nChars-nChiffres+(n-1)] = 0x0030+nChiffreAConvertir;
  37.           }
  38.      else
  39.           {
  40.           Var[n-1] = 0x0030+nChiffreAConvertir;
  41.           }
  42.          
  43.      nVarSoustraction += nChiffreAConvertir*( Puissance(10, (nChiffres-n)) );
  44.      }
  45. return;
  46. }


 
avec une séparation de deux int pour la partie entière et les décimales ou une adaptation du programme pour gérer les floats
 
je vais bientot tester si la fonction ne provoque pas de stack overflow (parce que là je l'ai faite dans un programme complètement a part)
 
je croise les doigts avec ferveur ;)


Message édité par crom29 le 26-01-2011 à 19:54:10

---------------
Mods: HAF922 | Shinobi XL White    GitHub     Admin de La Colère d'Aurile, serveur RP-Action Neverwinter Nights 2
n°2052506
crom29
Posté le 27-01-2011 à 22:09:53  profilanswer
 

stack overflow encore, c'est pas possible...
je rêve d'un monde ou la pile n'a pas de limite !
 
pour faire simple :  
CustIntToString fonctionne parfaitement dans un programme pas trop long, même si elle est placée dans 14 boucles while(1) infinies (j'ai essayé !)
par contre si je la place dans le vrai programme (~1000 lignes) que j'ai complètement refait (plus de goto, maximum 5 boucles imbriquées dans le void main et 3 dans les fonctions secondaires), ça me balance un stack overflow directement, quoi que je fasse...
Pour empêcher ce stack overflow je dois pratiquement tout commenter dans CustIntToString (même les lignes du genre "nChiffres++;" ) ET dans Puissance (que j'ai fait parce que la fonction de mikroC faisait une boucle infinie...)
 
grrr


---------------
Mods: HAF922 | Shinobi XL White    GitHub     Admin de La Colère d'Aurile, serveur RP-Action Neverwinter Nights 2
n°2052527
gilou
Modérateur
Modzilla
Posté le 27-01-2011 à 23:26:16  profilanswer
 

Il y en a qui avaient écrit leur propre fonction de conversion ici:
http://www.mikroe.com/forum/viewto [...] 88&t=24842
 
Sinon, en posant en posant: char cHauteurMur[13] = "00.0"; le problème persistait toujours?
A+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
n°2052578
crom29
Posté le 28-01-2011 à 10:00:10  profilanswer
 

"Sinon, en posant en posant: char cHauteurMur[13] = "00.0"; le problème persistait toujours?"
oui, j'ai essayé [13], [20], [100], []... ça plante toujours...
 
je vais regarder un peu ce qui a été fait sur le forum de mikroelectronika, merci :)


---------------
Mods: HAF922 | Shinobi XL White    GitHub     Admin de La Colère d'Aurile, serveur RP-Action Neverwinter Nights 2

Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  C

  [PIC/C] Pb Stack overflow

 

Sujets relatifs
Pb exportation de données vers feuille exceluControleur PIC export fichier texte
PB affichage incomplet d'un cadre javascriptPb contenu html en PHP
Pb commentaire HTML sous Opera et SafariPb deux liste en PHP
Pb contenu html en PHPPB SQL
[JavaScript] Pb compatibilité avec Chrome (page vierge affichée)PB à l'affichage des actualités dynamique
Plus de sujets relatifs à : [PIC/C] Pb Stack overflow


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR