Microchip, C18, variable folle

titusIII Messages postés 100 Statut Membre -  
 Utilisateur anonyme -
Bonjour,
Je suis en train de faire un afficheur pour afficher les horaires de bus de Rennes dans mon appart, j'ai déjà réalisé avec succès ce projet sur un arduino. J'ai cependant besoin de libérer mon arduino pour un autre projet.
J'ai donc sortit un 18f2580 pour l'occasion. Je travaille avec mplabX et C18.

J'ai un problème qui me semble défier les lois de la programmation, je vous explique :


var = 38%10;//Récupérer '8'
printCar(var+48); //+48 pour la conversion en ascii, et afficher '8'
// --> mon écran affiche '8', pas de problème!
Maintenant voilà quelque chose de plus utile, mais qui tourne pas :

autreVar = 38;
var = autreVar%10;//Récupérer '8'
printCar(var+48); //l'afficher '8'
// --> mon écran affiche '0' peut importe la valeur de "autreVar"

J'hésite entre passer le karcher sur le pic ou mon ordi...

Merci de votre analyse, j'attend patiemment une réponse, voir solution?

Titus.

32 réponses

  • 1
  • 2
Résumé de la discussion

Le problème porte sur l'affichage sur un afficheur LCD via un PIC18F2580 lorsque var=autreVar%10 et que printCar(var+48) affiche correctement '8', mais que var = autreVar%10 affiche systématiquement '0'. Des échanges soulignent que des variables déclarées char ou int, des décalages mémoire et des interruptions cycliques peuvent fausser l'affichage et orienter le résultat vers zéro. Plusieurs suggestions visent à tester des affichages consécutifs, à revoir la conversion ASCII (utiliser '0' plutôt que 48), à vérifier la fonction d'envoi ecr_data et les réglages LCD et ports. En cas de doute, il peut être utile d'exposer le code entier et de tester sur une configuration minimale afin d'isoler si l'anomalie provient du format des variables ou du flux d'horloge.

Généré automatiquement par IA
sur la base des meilleures réponses
  1. Utilisateur anonyme
     
    Heureusement que quand je t'avais fait remarquer qu'une de tes variables était un int, tu m'avais confirmé que c'était un char. Maintenant, tu te rends compte que c'est un int. Passons encore, mais essaye de donner des réponses exactes.
    As-tu fait l'essai que je t'avais demandé de faire deux affichages consécutifs :
       
      ecr_data(tmp + '0');
      ecr_data(tmp + '0');

    Pour l'envoi du code, zippe tout en un seul fichier et utilise le site cjoint.com ou un autre si tu as une préférence.
    1
    1. sambia39 Messages postés 610 Date d'inscription   Statut Membre Dernière intervention   50
       
      +1
      0
  2. fiddy Messages postés 441 Date d'inscription   Statut Contributeur Dernière intervention   1 847
     
    Bonjour,

    Tout d'abord, plutôt que mettre 48, je te conseille de mettre '0'. C'est plus lisible et plus portable :-).

    Sinon, le problème est bizarre. Ca sent le bon vieux stack overflow. Peux-tu donner ton code en entier ?

    Cdlt,
    0
  3. titusIII Messages postés 100 Statut Membre 2
     

    char tmp,hourNextL3;
    char next3[] = "Next 3 : ";

    cursor(0,1);
    ecr_string(next3);

    hourNextL3 = 28;
    tmp = hourNextL3 % 10;
    ecr_data(tmp + 48);

    Mon code est pas beaucoup plus compliqué.
    Les drivers de mon LCD est fait maison, il a fait ses preuves, je l'écarte donc.
    0
  4. titusIII Messages postés 100 Statut Membre 2
     
    J'ai eu pas mal de problème pas très cohérents avec C18... Une autre histoire de variable que j'ai résolu en appliquant un genre de décalage de bit un peu bourrin...

    Si tu avais un autre compilateur moins nerveux?
    0
  5. Vous n’avez pas trouvé la réponse que vous recherchez ?

    Posez votre question
  6. titusIII Messages postés 100 Statut Membre 2
     
    excuse moi :

    char tmp,hourNextL3;
    char next3[] = "Next 3 : ";

    void fct()
    {
    cursor(0,1);
    ecr_string(next3);

    hourNextL3 = 28;
    tmp = hourNextL3 % 10;
    ecr_data(tmp + '0');
    }

    Et toujours 0 en sortie.
    Et tout mon code est consacré au drivers LCD pour l'instant, mais je l'écarte.
    0
  7. Utilisateur anonyme
     
    Bonjour

    Je n'ai jamais eu de problèmes avec C18.
    Vois-tu bien l'affichage de la chaîne "Next 3 : " ?
    Peux-tu donner le prototype de ecr_data ? Pourquoi n'as tu pas gardé la fonction printCar que tu utilisais dans ton post initial ?
    0
  8. titusIII Messages postés 100 Statut Membre 2
     
    Parce que j'ai changé le nom de ma fonction, ça reste la même.


    void ecr_data(char data){

    PORTBbits.RB2 = 1;
    hbit = data;
    hbit >>=4;

    PORTBbits.RB4 = hbit&0x01;
    PORTCbits.RC6 = (hbit>>1)&0x01;
    PORTCbits.RC5 = (hbit>>2)&0x01;
    PORTCbits.RC4 = (hbit>>3)&0x01;

    PORTBbits.RB3 = 1;
    PORTBbits.RB3 = 0;

    Delay10TCYx(1);

    PORTBbits.RB4 = data&0x01;
    PORTCbits.RC6 = (data>>1)&0x01;
    PORTCbits.RC5 = (data>>2)&0x01;
    PORTCbits.RC4 = (data>>3)&0x01;

    PORTBbits.RB3 = 1;
    PORTBbits.RB3 = 0;

    Delay10TCYx(5);
    }
    C'est la fonction qui me permet d'écrire un caractère sur mon afficheur, elle tourne bien, "Next 3 : " est bien affiché!
    0
  9. titusIII Messages postés 100 Statut Membre 2
     
    une autre exemple :

    hourNextL3 = 28;
    tmp = hourNextL3 % 10;
    if (tmp == 8) ecr_data(8 + '0'); // n'affiche rien

    Alors que

    ecr_data(8 + '0'); // affiche bien 8
    0
  10. Utilisateur anonyme
     
    Je viens de tester chez moi, ça se passe bien (en simulation de 18F4550).
    Peux-tu vérifier dans le .map à quelles adresses sont tes variables hourNextL3 et tmp ?
    0
  11. titusIII Messages postés 100 Statut Membre 2
     
    Hournextl3 à 0x74
    Et tmp à 0x78
    Je vois pas le probleme encore une fois!

    Je précise que j'ai déja changé de variable pour voir, de type de variable également.

    Sinon j'ai une piste, toute petite et autant improbable... J'ai un timer qui génère une interruption toutes les secondes (je m'en sers pour faire horloge, heures minutes secondes), c'est assez improbable que ça fasse planter mon code, vu qu'il y a un système de PUSH-POP en arrière plan je suppose.
    Ma fonction avec le modulo est appelée toutes les secondes et j'ai JAMAIS le résultat attendu. Ca serai un sacré manque de chance que mon timer la perturbe à ce point. J'essayerai sans pour voir, demain, quand j'aurai les yeux sur mon matériel.
    0
  12. Utilisateur anonyme
     
    Tes variables déclarées char tmp,hourNextL3; se retrouvent à 4 octets d'écart ? Étonnant, non ? Tu as une explication ?

    J'avais pensé aussi à une modification due à une interruption cyclique, mais si elle n'a lieu que toutes les secondes, elle ne peut pas fausser ton résultat à tous les coups.

    As-tu essayé :
       hourNextL3 = '8'; 
       tmp = hourNextL3 ;
       ecr_data(tmp);
    0
  13. titusIII Messages postés 100 Statut Membre 2
     
    Oui je les déclarent pas sur la meme ligne, bizarre ça me ressemble pas.
    Je vais essayer le code que tu me proposes, je connais je pense déjà le résultat! Ca va marcher
    0
  14. Utilisateur anonyme
     
    As-tu essayé ton code avec le simulateur de MPLABX pour voir à partir de quand les valeurs diffèrent de celles que tu attends ?

    D'autre part, peux-tu mettre ici le code assembleur généré par le compilateur pour ton opération qui ne marche pas ?
    0
  15. titusIII Messages postés 100 Statut Membre 2
     
    Ouaip,
    Le code en C :
       cursor(0,1);
       ecr_string(next3);
       testT = 17;
       tmp = testT%10;
       ecr_data(tmp + '0');
    


    Et en asm j'arrive pas à mettre la main sur le .asm, y'a un moyen particulier sur mplabX ?

    J'ai testé avec le simulateur intégré et aucun problème
    0
  16. Utilisateur anonyme
     
    Pas facile de te suivre : ton code change à chaque fois, ainsi que les noms de tes fonctions et de tes variables... Et tu n'as pas répondu à l'essai que je t'avais demandé.

    Quand tu dis qu'il n'y a aucun problème avec le simulateur, qu'est-ce que ça veut dire ? Le simulateur n'a pas d'afficheur ! Et quand tu simules, exécutes-tu tout bien depuis le reset du PIC ?

    Est-il possible d'avoir le programme complet ?
    0
    1. Utilisateur anonyme
       
      Pour afficher l'assembleur, si c'est comme avec MPLAB, tu fais un make de ton projet, puis tu fais menu View, commande Disassembly listing
      0
  17. titusIII Messages postés 100 Statut Membre 2
     
    48:               cursor(0,1);
    0516  6EE6     MOVWF POSTINC1, ACCESS
    0518  6AE6     CLRF POSTINC1, ACCESS
    051A  EC8E     CALL 0x31C, 0
    051C  F001     NOP
    051E  52E5     MOVF POSTDEC1, F, ACCESS
    0520  52E5     MOVF POSTDEC1, F, ACCESS
    49:               ecr_string(next3);
    0522  0EB6     MOVLW 0xB6
    0524  6EE6     MOVWF POSTINC1, ACCESS
    0526  0E01     MOVLW 0x1
    0528  6EE6     MOVWF POSTINC1, ACCESS
    052A  EC6F     CALL 0x2DE, 0
    052C  F001     NOP
    052E  52E5     MOVF POSTDEC1, F, ACCESS
    0530  52E5     MOVF POSTDEC1, F, ACCESS
    50:               testT = 17;
    0532  0E11     MOVLW 0x11
    0534  0100     MOVLB 0x0
    0536  6F79     MOVWF testT, BANKED
    0538  6B7A     CLRF 0x7A, BANKED
    51:               tmp = testT%10;
    053A  C079     MOVFF testT, __tmp_0
    053C  F010     NOP
    053E  C07A     MOVFF 0x7A, 0x11
    0540  F011     NOP
    0542  0E0A     MOVLW 0xA
    0544  6E0D     MOVWF 0xD, ACCESS
    0546  6A0E     CLRF 0xE, ACCESS
    0548  C010     MOVFF __tmp_0, 0x8
    054A  F008     NOP
    054C  C011     MOVFF 0x11, 0x9
    054E  F009     NOP
    0550  ECB8     CALL 0x570, 0
    0552  F002     NOP
    0554  C004     MOVFF 0x4, __tmp_0
    0556  F010     NOP
    0558  C005     MOVFF 0x5, 0x11
    055A  F011     NOP
    055C  C010     MOVFF __tmp_0, tmp
    055E  F078     NOP
    52:               ecr_data(tmp + '0');
    0560  0E30     MOVLW 0x30
    0562  0100     MOVLB 0x0
    0564  2578     ADDWF tmp, W, BANKED
    0566  6EE6     MOVWF POSTINC1, ACCESS
    0568  EC0F     CALL 0x21E, 0
    056A  F001     NOP
    056C  52E5     MOVF POSTDEC1, F, ACCESS
    
    0
  18. titusIII Messages postés 100 Statut Membre 2
     
    
    0532  0E11     MOVLW 0x11
    0534  0100     MOVLB 0x0
    0536  6F79     MOVWF testT, BANKED
    0538  6B7A     CLRF 0x7A, BANKED
    
    


    Quelque chose qui va pas ici me semble t'il...
    On déplace 0x11 vers W, on sélectionne la banque 0x0 pour mettre mon 0x11 ?
    Et on efface la banque 0x7A ?

    Ca fait longtemps que j'ai pas fait d'assembleur, je dois pas être loin de la vérité
    0
    1. Utilisateur anonyme
       
      Et on efface la banque 0x7A ?
      Non, on efface l'adresse 0x7A, qui est le poids fort de l'adresse 0x79 qui contient testT.
      testT est défini comme un char ou un int ?

      Je ne vois rien de choquant.

      Par contre, tu ne m'as pas répondu : Quand tu dis qu'il n'y a aucun problème avec le simulateur, qu'est-ce que ça veut dire ?
      Tu mets un point d'arrêt et tu observes les valeurs de variables ?

      Et quand tu fais le test en réel, tu as un programme qui tourne en boucle je suppose : As-tu laissé tourner le simulateur pour que lui aussi fasse plusieurs boucles avent de vérifier l'état des variables ?
      0
    2. Utilisateur anonyme
       
      Question subsidiaire et hors sujet : avec un nom de variable comme hourNextL3, tu ne serais pas étudiant du côté du campus de Beaulieu ?
      0
    3. titusIII Messages postés 100 Statut Membre 2
       
      Bravo, si effectivement je suis à Beaulieu! J'ai la ligne 1 à faire aussi!

      Sur simulation mon modulo se fait bien! Toutes mes variables sont en char!
      Je met un point d'arrêt juste avant de commencer le code qui m'intéresse et je fais du pas à pas pour observer les variations de mes variables.

      Le programme tourne quelques minutes oui, donc pas de doute ça marche pas.
      0
  19. Utilisateur anonyme
     
    J'étais INSAlien de 1974 à 1979 et c'était déjà la ligne 3 :)

    ta ligne
    0538  6B7A     CLRF 0x7A, BANKED
    montre que ta variable testT est en fait un int. J'ai fait l'essai, quand on déclare un char, il n'essaye pas de mettre à 0 le poids fort d'un char, il ne le fait que pour un int. Mais passons.

    Deux questions :

    Est-il possible d'avoir le programme en entier ? (via cjoint.com ou autre)
    Peux -tu afficher deux fois consécutives le chiffre :
    ecr_data(tmp + '0');
    ecr_data(tmp + '0');
    0
  20. titusIII Messages postés 100 Statut Membre 2
     
    Effectivement je l'avais laissée en int pour mes tests...

    Je peux t'envoyer le programme, par mail? Peux-tu m'envoyer une adresse mail?
    0
  21. titusIII Messages postés 100 Statut Membre 2
     
    Rectification, en sortie avec :
       testT = 17;
       tmp = testT%10;
       ecr_data(tmp + '0');
    


    J'ai 'T'.
    Soit 84-48=36

    36?
    17%10=36 d'après mon pic
    0
  • 1
  • 2