C18 et chaine de caracteres.
Répondre à la discussion
Affichage des résultats 1 à 12 sur 12

C18 et chaine de caracteres.



  1. #1
    invite6cb06424

    C18 et chaine de caracteres.


    ------

    Bonjour

    Je suis en train de réaliser un petit programme pour un 18F2220 qui me permettra d'afficher 5 tensions sur un ecran lcd 2*16 .

    Je programme en C18.

    Premièrement je voudrais savoir quelle est selon vous le meilleurs compilateurs C pour PIC, je m'y perd! Peut être cela dépend de ce qu'on veut faire?

    Ensuite j'ai un petit programme que je ne comprend pas pourquoi cela ne fonctionne pas, je m'explique :

    Voici 2 codes :
    Code:
    unsigned char txtbattery[] = {"Bat : "};
    affchainelcd(txtbattery);
    et

    Code:
    affchainelcd("Bat : ");
    Avec en commun :

    Code:
    void affcaralcd( char car)
    {
    	LCD = car;
    	EN = 1;
    	//Delay1KTCYx(1);
    	EN = 0;
    }
    
    void affchainelcd (char chaine[])
    {
    	int i;
    	for (i=0;i<strlen(chaine);i++)
    	{
    	affcaralcd(chaine[i]);
    	}
    }
    Je précise que "LCD" est le port de données du LCD. Pour EN je pense que c'est clair

    Ma question est : Quelle est la différence entre les 2 premiers codes? Le premiers fonctionne mais pas le second
    y a t'il quelque chose a mettre pour qu'il soit considéré comme un tableau?

    J'ai bien l'impression que quelque soit le compilateur, les chaines de caractères sont "mal vu"

    PS : Je sais qu'il y a une librairie intégrée dans C18 mais j'ai préféré faire la mienne. Il parait qu'il y a des bug dans la leur.

    Merci d'avance

    -----

  2. #2
    invite00e5225f

    Re : C18 et chaine de caracteres.

    Salut

    En fait quand tu écris

    Code:
    affchainelcd(txtbattery);
    Tu envoies l'adresse du pointeur du tableau.

    Il faut donc que ta fonction reçoive un pointeur. Je suppose que la fonction strlen te donne la taille de ton tableau, si c'est le cas il faut que tu le fasses passer en argument..

    En gros ta fonction sera de la forme

    Code:
    void affchainelcd (char *chaine,char taille)
    Je te laisse écrire la suite.

  3. #3
    invite6cb06424

    Re : C18 et chaine de caracteres.

    Bonjour peter pan

    Oui strlen envoie bien la taille de la chaine envoyée ; mais pourquoi devrais-je l'envoyer en argument? Le premier programme fonctionne très bien comme cela, mon seul soucis en fait, c'est que ca prend de la mémoire pour rien, j'aimerais une fois le texte affiché, pouvoir libérer l'espace mémoire.

    A l'écrire je me dis que quoi que je fasse, il faudra que ce soit la quelque part et donc que ca prenne de la place. alors a quoi bon chercher a faire directement

    Code:
    affchainelcd("Bat : ");
    Si ce n'est pour une question d'être pratique! Si vous avez des suggestions...

    Ensuite, existe t-il des fonctions simples sur C18 pour convertir un nombre en chaine de caractères? Ou il faut que je la fasse aussi celle ci?

    Merci encore

  4. #4
    paulfjujo

    Re : C18 et chaine de caracteres.

    bonsoir,

    Lorsqu'on initialise une chaine de caractere , elle (doit) se terminer par 0.
    dans le 1er cas tu transmet le pointeur sur ta chaine
    Strlen donne le bon nombre de caractere en detectant le zero de fin de chaine.

    Tu peux te passer de strlen, si dans ta boucle d'envoi de caractere
    tu test le zero de fin de chaine.
    char *ptr ;

    *ptr=txtbattery[0];

    void affchainelcd( char* ptr)
    {
    while (*ptr!=0)
    {
    affcaralcd(*ptr++);
    };
    }


    dans le 2em cas tu transmet directement la chaine !
    qui est mal interpretée..
    ----------------------------------------------

    Pour les fonctions de convertions ..
    regarde la doc Microchip MPLAB C18 C Compiler libraries chapitre 4.3
    document DS51297F

  5. A voir en vidéo sur Futura
  6. #5
    Jack
    Modérateur

    Re : C18 et chaine de caracteres.

    Ma question est : Quelle est la différence entre les 2 premiers codes? Le premiers fonctionne mais pas le second
    y a t'il quelque chose a mettre pour qu'il soit considéré comme un tableau?
    Il n'y a pas de raison pour que le second code ne fonctionne pas. Comme le dit paulfjujo, l'adresse du tableau est passée à la fonction dans le premier code, mais là ou je ne suis pas d'accord avec lui, c'est que c'est vrai également dans le second code. En effet, la chaine "Bat : " n'est pas passée à la fonction: mais c'est à nouveau un pointeur qui est passé, la chaine étant stockée dans la zone de code puisque constante et connue à la compilation.
    Le comportement de C18 est donc étonnant.
    Ce que tu pourrais faire, c'est mettre un point d'arrêt dans la fonction et visualiser le tableau chaine[] pour voir ce qui arrive.

    Ensuite, existe t-il des fonctions simples sur C18 pour convertir un nombre en chaine de caractères? Ou il faut que je la fasse aussi celle ci?
    oui, sprintf, itoa, strtod, etc.

    A+

  7. #6
    invite6cb06424

    Re : C18 et chaine de caracteres.

    Hello

    J'ai visualisé ce qui est envoyé a la fonction lorsque j'envoie "Bat : " et il y a ... 0x00 comme adresse et 0x000 comme contenu
    Bref, c'est clair, il n'envoie pas de pointeur malheureusement. Je pense que je vais rester comme ca, avec des tableaux, j'ai l'impression de chercher pour rien même si c'est censé fonctionner.

    Une autre chose, lorsque je met :
    Code:
    ligne xx : unsigned char txtbattery[] = {"Bat : "};
    ligne 85 : affchainelcd(txtbattery);
    J'obtiens ca lors de la compilation :

    85:Warning [2054] suspicious pointer conversion

    euh... Pourquoi il me dit ca lui, je lui donne l'adresse d'un tableau pourquoi il est pas content?
    Au fait, quelqu'un utilise CCS ou un autre compilateur? Je commence a aimer de moins en moins C18...

    Je vais essayer leur librairie, ca fonctionnera peut être, si ca ne marche pas, je crois que je vais changer de compilateur!

    Bref, Merci encore

  8. #7
    paulfjujo

    Re : C18 et chaine de caracteres.

    re-

    C18 est assez pointilleux entre les chaines de caracteres declarées en RAM ou celle en ROM
    (contrairement à MikroC !)
    il faut le preciser dans le cast de la variable.

    voici un exemple ou la chaine est declaré
    en RAM
    en ROM flash
    en dur dans le programme..
    la sortie est sur RS232 mais c'est tout comme pour le LCD...
    voir la partie entre le "do ... while(1)"

    Code:
    char Texte[80];   // reservation d'espace en RAM
    char *txt;
    
    rom const char txtbattery1[]={"Bat1 en rom :  ",0};   // 0 =frein à main !
    char txtbattery2[]={"Bat2 en ram  :  ",0};
    
    void affchaineROM (rom const char * ptr1)
    {
    while (*ptr1)
    {
    Put_RS(*(ptr1));
    ptr1++;
    };
    }
    
    void affchaineRAM (char * ptr2)
    {
    while (*ptr2)
    {
    Put_RS(*ptr2);
    ptr2++;
    };
    }
    
    void main()
    {
     Init_Hardware() ;
     Led_Rouge=Allume;
    // init des pointeurs stockage reception car
     received=0;
     Drapeaux.Fill=1;
     Drapeaux.Blc=1;
     
     Init_UART1();
     OUT_RS232
     
     while(DataRdy1USART())
     {
      Dummy=getc1USART();
      }
     Put_RS(CLS);
     Tempo(100000L);
     Led_Rouge=Eteint;
     CptCars=0;
     count=0;
     
     CRLF();
     Led_Rouge=Allume;
     txt=&Texte[0];
     strcpypgm2ram(txt,RS_Str[1]); // string en ROM
     k=PutStr_RS(txt);
     Tempo(100000L) ;
     
     PrintOut_Eeprom_Msg(0);      // init RS
     PrintOut_Eeprom_Msg(0x20);     
     PrintOut_Eeprom_Msg(0x60);     
     PrintOut_Eeprom_Msg(0x80);  
    
     CRLF();
     Led_Rouge=Eteint;
     Tempo(10000L) ;
     
     do
     {
      Put_RS('#'); 
      affchaineROM (txtbattery1);// string en ROM flash
      CRLF();
      Tempo(100000L);
      
      Put_RS('*'); 
      affchaineRAM(txtbattery2); // string en RAM
      CRLF();
      Tempo(100000L);
    
      Put_RS('@'); 
      affchaineROM ("Bat3 : en dur ");
      CRLF(); 
      Tempo(100000L);
      
      Put_RS('&'); 
      txt=&Texte[0];
      strcpypgm2ram(txt,txtbattery1); // string en ROM 
      k=PutStr_RS(txt);
      CRLF(); 
      Tempo(100000L);
     
     }
     while(1);
    ce qui donne le resultat suivant sur terminal
    Port comm 38400 ouvert ... String en ROM
    Projet: 18F46K22_tests
    Port Com 38400b & Init HARD.
    MPLAB IDE V8.63 C18 v3.37.01
    18F46K22 et microchip boot

    #Bat1 en rom :
    *Bat2 en ram :
    @Bat3 : en dur
    &Bat1 en rom :
    #Bat1 en rom :
    *Bat2 en ram :
    @Bat3 : en dur
    &Bat1 en rom :
    #Bat1 en rom :
    *Bat2 en ram :

  9. #8
    invite6cb06424

    Re : C18 et chaine de caracteres.

    Tout a fait d'accord avec le code précédent, justement, avant même de le lire j'étais allé voir les sources utilisées dans la librairie LCD créée par C18.

    Et j'ai vu :
    Code:
    const rom char *chaine
    Ce que j'ai bien sur essayé et ca fonctionne !!! (Ce qui ne fonctionne plus c'est la conversion 'ultoa' qui me donne maintenant des lettres étranges a l'écran. Je vais voir pourquoi! ) AU pire je ferais deux fonctions

    Code:
    void affchainelcd (char *chaine);
    void afftextelcd (const rom char *chaine);
    D'ailleurs, lors d'une conversion par le CAN, le résultat dans C18 est copié dans result grâce a

    Code:
    result = ReadADC();
    J'en conclus qu'il faut que 'result' soit au moins sur 10 bits. Donc 16 par logique. ce qui fait dans le cas ou c'est signé de -32768 à 32767.
    Donc si j'utilise 'itoa' (Convert a 16-bit signed integer to a string.) ca devrait marcher non? parce que ca fonctionne mais pas toujours, c'est a dire que de 0 à environ 2,5V pas de soucis mais au delà ca devient du n'importe quoi

    J'ai voulu essayer avec 'unsigned int' mais il n'y a pas de fonction de conversion.
    La seule déclaration qui fonctionne c'est (affichage de 0 à 1023):

    Code:
    unsigned long int result;
    affchainelcd(itoa(result));
    Le problème est que unsigned long int prend 32 bits! Ca fait beaucoup quand même

    Comment puis-je faire?

    PS : Merci pour MikroC, je vais y jeter un coup d'oeil

    Merci!

  10. #9
    invite6cb06424

    Re : C18 et chaine de caracteres.

    Bonjour a tous

    Par hasard j'ai regardé la mémoire occupée dans le PIC...

    Nom : Sans titre.jpg
Affichages : 516
Taille : 16,7 Ko

    72% d'occupé! Le truc c'est que pour l'instant je ne fais qu'affiché sur l'écran 2 tensions issue du CAN.
    Par la suite j'ai 5 tensions a afficher et une gestion de bouton pour modifier l'affichage ainsi que des commandes a gerer.

    J'ai fait un petit test et je ne peux faire pas plus que 4 acquisition de température et affichage.
    A quoi ca sert d'avoir aussi peut de mémoire et autant d'entrée/sortie sur le PIC si on ne peut pas tout utiliser?

    Dois-je retourner a l'assembleur? Je me met doucement au C pour les PIC, c'est vrai c'est rapide a mettre en oeuvre mais au niveau memoire c'est vraiment pas super

    Merci pour vos suggestions.

  11. #10
    paulfjujo

    Re : C18 et chaine de caracteres.

    bonjour,


    Effectivement sous C18
    j'ai du aussi me taper un sous programme ur la convertion d'un mot 16 bits Non signe
    le voila , cela prend un peu de place , mais on peu l'appeler X fois !

    Code:
    void Write_Word(unsigned int M,char Sign,char Bold)
    {
    // Sign 1 pour entier signé +32767 -32768     
    // Sign 0 pour entier non signé 0 à 65535
    // Bold =1 pour affichage double largeur sur nokia=Gras
    // Bold=0 ecriture normale sur nokia
    unsigned int i,k,l;
    unsigned long M1;
     valtxt=&Entree[0];    // init ponteur sur zone rangement caracteres
     if (Sign>1) return;   // argument signe doit etre 0 ou 1 
     if (Sign==0)
      {       M1=(long)M;
            ultoa(M1,valtxt);
      }
      else itoa(M,valtxt);
     if (Drapeaux.Fill==1)
     {
      k=strlen(Entree);
      for (i=0;i<k;i++) Entree[4+Sign-i]=Entree[k-i-1];
      for (i=0;i<(5+Sign-k);i++)
      {if (Drapeaux.Blc==1) Entree[i]='0'; else Entree[i]=' ';}
     }
     Entree[5+Sign]=0;
     if (Drapeaux.Lcd) //  flag d' indirection d'ecriture sur Nokia ou RS232 
       nokia_print_str(valtxt,Bold); 
        else 
      k=PutStr_RS(valtxt);
    }
    Le C18 prend beaucoup de place des qu'on utilise des bibliotheques
    et surtout les Maths et donc le format flottant.

    Ton PIC18F n'a en effet pas une grande capacité ..
    FLASH RAM
    18F220 2048 512
    18F2520 16384 1536
    18F26K20 32768 3936
    il y a meme un modele 96K Flash programme 18F4685

  12. #11
    invite6cb06424

    Re : C18 et chaine de caracteres.

    Bonjour,

    Merci pour le code, je vais l'utiliser ca prendra un peu moins de place, peut etre quelque modif a faire mais c'est pas génant, merci en tout cas.

    Je savais qu'il existait differente taille de memoire PIC mais je ne pensais pas que ca pouvait varier de plus 16 fois d'un PIC a un autre!

    Bref j'ai opté pour un 18F2620, meme brochage mais une mémoire 16 fois plus grande que le 16F2220, ca me convient beaucoup mieux! 1476/32768 ca sonne mieux non?

    Merci pour l'aide, ca m'a été bien utile

  13. #12
    invite35dbb7e4

    Re : C18 et chaine de caracteres.

    je remercie ici paulfjujo pour son aide...
    ... il a répondu à mon pb de pointeur incompatible en RAM et ROM de C18 ...
    la documentation de Microchip est pas terrible à ce sujet...

    Merci A+

Discussions similaires

  1. visual basic, longue chaine de caracteres
    Par invitec0b62935 dans le forum Programmation et langages, Algorithmique
    Réponses: 5
    Dernier message: 29/02/2012, 09h58
  2. Transformation d'une chaine de caractères
    Par invitefd4e7c09 dans le forum Programmation et langages, Algorithmique
    Réponses: 8
    Dernier message: 11/10/2011, 18h35
  3. Chaine de caractères en C
    Par invite953f8104 dans le forum Électronique
    Réponses: 8
    Dernier message: 03/03/2009, 21h28
  4. PIC : Chaine de caractères
    Par Toufinet dans le forum Électronique
    Réponses: 2
    Dernier message: 24/05/2006, 18h49
  5. PIC: Gestion de chaîne de caractères.
    Par invite4c7a167b dans le forum Électronique
    Réponses: 1
    Dernier message: 24/05/2004, 15h13
Dans la rubrique Tech de Futura, découvrez nos comparatifs produits sur l'informatique et les technologies : imprimantes laser couleur, casques audio, chaises gamer...