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

[résolu]Keypad 4x4
venom
Avatar de l’utilisateur
Confirmé
Confirmé
Messages : 599
Âge : 33
Enregistré en : avril 2016
Localisation : Klyntar
Contact :

#11 Message par venom » sam. 27 avr. 2019 21:03 lien vers la Data-Sheet : Cliquez ici

Salut Jérémy,

J'étais partie sur ta première solution, mais je n'arrive pas a récupérer la ligne et l'exploiter :cry:

En faite, j'ai essayé de faire une calculatrice tout seul sans demander de l'aide. Mais sa fait 2 jours que je suis dessus et pas moyen. Je vais devoir me tourner vers mon forum fétiche :sifflotte:

Pour le moment j'arrive a écrire sur la première ligne de l'écran ex: 12+8=
Et forcément je souhaiterais qu'à l'appui de la touche = j'obtiens le résultat sur la deuxième ligne. Mais pas moyen de réussir a récupérer 12+8 et l'exploiter genre 12 d'un côté et le 8 de l'autre.

Existe t-il des fonctions genre couper, se déplacer de autant dans la chaîne etc... ?

Peut être que je cherche trop compliqué :oops:

code:

Code : Tout sélectionner

///////////////////////////////
//    name : CALCULATERICE   //
//    create : venom         //
//    date : 23/04/2019      //
//    pic : 16f887 4MHz      //
///////////////////////////////





// LCD Definitions
#define _LCD_CLEAR              0x01        //vide l'ecran
#define _LCD_CURSOR_OFF         0x0C        //cache le curseur
#define _LCD_UNDERLINE_ON       0x0E        //Underline cursor on


// I2C adresse
#define LCD_ADDR 0x7E                       // adresse du PCF8574A = 0x7E. adresse du PCF8574 = 0x4E


// initialisation des varialbes etc...
unsigned short kp;

char code1[16];
int i = 0;
int j = 0;
int k = 0;
int l = 0;

int Type_Operation = 0;
int Operation = 0;

int Longeur_Operation = 0;

char Premiere_Valeur[16];
char Deuxieme_Valeur[16];

int Longeur_Premiere_Valeur = 0;
int Longeur_Deuxieme_Valeur = 0;

int Resultat;
int Resultat1;
float Resultat_Str;



// Keypad module connections
char  keypadPort at PORTD;


// textes constants
char txt1[] = "CALCULATRICE";
char txt2[] = "BY VENOM";
char txt3[] = "ENTREZ VOTRE";
char txt4[] = "OPERATION";
char txt5[] = "ERREUR";


// procedure I2C_LCD_Cmd By paulfjujo
void I2C_LCD_Cmd(char out_char) {

    char hi_n, lo_n;
    char rs = 0x00;

    hi_n = out_char & 0xF0;
    lo_n = (out_char << 4) & 0xF0;

    I2C1_Start();
    I2C1_Is_Idle();
    I2C1_Wr(LCD_ADDR);
    I2C1_Is_Idle();
    I2C1_Wr(hi_n | rs | 0x04 | 0x08);
    I2C1_Is_Idle();
    Delay_us(50);
    I2C1_Wr(hi_n | rs | 0x00 | 0x08);
    I2C1_Is_Idle();
    Delay_us(100);
    I2C1_Wr(lo_n | rs | 0x04 | 0x08);
    I2C1_Is_Idle();
    Delay_us(50);
    I2C1_Wr(lo_n | rs | 0x00 | 0x08);
    I2C1_Is_Idle();
    I2C1_stop();

    if(out_char == 0x01)Delay_ms(2);
}


// procedure I2C_LCD_Chr By paulfjujo
void I2C_LCD_Chr(char row, char column, char out_char) {

    char hi_n, lo_n;
    char rs = 0x01;

    switch(row){

        case 1:
        I2C_LCD_Cmd(0x80 + (column - 1));
        break;
        case 2:
        I2C_LCD_Cmd(0xC0 + (column - 1));
        break;
    };

    hi_n = out_char & 0xF0;
    lo_n = (out_char << 4) & 0xF0;

    I2C1_Start();
    I2C1_Is_Idle();
    I2C1_Wr(LCD_ADDR);
    I2C1_Is_Idle();
    I2C1_Wr(hi_n | rs | 0x04 | 0x08);
    I2C1_Is_Idle();
    Delay_us(50);
    I2C1_Wr(hi_n | rs | 0x00 | 0x08);
    I2C1_Is_Idle();
    Delay_us(100);
    I2C1_Wr(lo_n | rs | 0x04 | 0x08);
    I2C1_Is_Idle();
    Delay_us(50);
    I2C1_Wr(lo_n | rs | 0x00 | 0x08);
    I2C1_Is_Idle();
    I2C1_stop();
}


// procedure I2C_LCD_Init By paulfjujo
void I2C_LCD_Init() {

    char rs = 0x00;

    Delay_ms(100);                          // laisser le temps au LCD de s'alimenter correctement

    I2C1_Start();
    I2C1_Is_Idle();
    I2C1_Wr(LCD_ADDR);
    I2C1_Is_Idle();

    Delay_ms(30); //30 // laisser le temps au LCD de s'alimenter correctement

    I2C1_Wr(0x30 | rs | 0x04 | 0x08);
    I2C1_Is_Idle();
    Delay_us(50);
    I2C1_Wr(0x30 | rs | 0x00 | 0x08);
    I2C1_Is_Idle();

    Delay_ms(10); //10 // laisser le temps au LCD de s'alimenter correctement

    I2C1_Wr(0x30 | rs | 0x04 | 0x08);
    I2C1_Is_Idle();
    Delay_us(50);
    I2C1_Wr(0x30 | rs | 0x00 | 0x08);
    I2C1_Is_Idle();

    Delay_ms(10); //10 // laisser le temps au LCD de s'alimenter correctement

    I2C1_Wr(0x30 | rs | 0x04 | 0x08);
    I2C1_Is_Idle();
    Delay_us(50);
    I2C1_Wr(0x30 | rs | 0x00 | 0x08);
    I2C1_Is_Idle();

    Delay_ms(10); //10 // laisser le temps au LCD de s'alimenter correctement

    I2C1_Wr(0x20 | rs | 0x04 | 0x08);
    I2C1_Is_Idle();
    Delay_us(50);
    I2C1_Wr(0x20 | rs | 0x00 | 0x08);
    I2C1_Is_Idle();
    I2C1_Stop();

    Delay_ms(100); //100 // laisser le temps au LCD de s'alimenter correctement

    I2C_LCD_Cmd(0x28);
    I2C_LCD_Cmd(0x06);
}


// procedure I2C_LCD_Out By paulfjujo
void I2C_LCD_Out(char row, char col, char *text) {
    while(*text)
         I2C_LCD_Chr(row, col++, *text++);
}


// procedure texte au demarrage
void Welcome() {
  I2C_LCD_Cmd(_LCD_CURSOR_OFF);             // supprime le curseur
  I2C_LCD_Cmd(_LCD_CLEAR);                  // vide l'ecran
   delay_ms(100);                           // attend 100ms

    I2C_Lcd_Out(1,3,txt1);                  // affiche le texte CALCULATRICE en 1ere ligne
    I2C_Lcd_Out(2,5,txt2);                  // affiche le texte BY VENOM en 2eme ligne
     delay_ms(3000);                         // attend 2 secondes

  I2C_LCD_Cmd(_LCD_CURSOR_OFF);             // supprime le curseur
  I2C_LCD_Cmd(_LCD_CLEAR);                  // vide l'ecran
    I2C_Lcd_Out(1,3,txt3);                  // affiche le texte ENTREZ VOTRE en 1ere ligne
    I2C_Lcd_Out(2,4,txt4);                  // affiche le texte OPERATION en 2eme ligne
     delay_ms(3000);                         // attend 2 secondes
     
  I2C_LCD_Cmd
(_LCD_CURSOR_OFF);             // supprime le curseur
  I2C_LCD_Cmd(_LCD_CLEAR);                  // vide l'ecran
   delay_ms(100);
}

// procedure annulation de l'operation (touche *)
void Annulation(){
  I2C_LCD_Cmd(_LCD_CURSOR_OFF);             // supprime le curseur
  I2C_LCD_Cmd(_LCD_CLEAR);                  // vide l'ecran
  kp = 0;                                   // reset de la variable kp
  i = -1;                                   // reset de la variable i
  Type_Operation = 0;                       // reset de la variable Type_Operation
  Longeur_Operation = 0;                    // longeur de l'operation
  Longeur_Premiere_Valeur = 0;              // longeur de la premiere valeur
  Longeur_Deuxieme_Valeur = 0;              // longeur de la deuxieme valeur
   delay_ms(10);                            // attend 10ms

}


// procedure qui calcul l'operation
void Resultat_Calcul(){

if(
Type_Operation == 1)                     // si l'operation est une addition
{

}

else if(Type_Operation == 2)                // si l'operation est une soustraction
{

}

else if(Type_Operation == 3)                // si l'operation est une multiplication
{

}

else if(Type_Operation == 4)                // si l'operation est une division
{

}
 
}


// procedure recupere la touche appuyer et l'affichea l'ecran
void Touche_Clavier() {

  kp = 0;                                   // reset de la variable kp

     do
      kp 
= Keypad_Key_Click();              // Mémoriser la touche dans la variable kp

     while (!kp);
     // Préparer la valeur de sortie, transformer la touche en sa valeur ASCII
     switch (kp) {
      case  1: kp = 49; break; // 1
      case  2: kp = 50; break; // 2
      case  3: kp = 51; break; // 3
      case  4: kp = 43; break; // +
      case  5: kp = 52; break; // 4
      case  6: kp = 53; break; // 5
      case  7: kp = 54; break; // 6
      case  8: kp = 45; break; // -
      case  9: kp = 55; break; // 7
      case 10: kp = 56; break; // 8
      case 11: kp = 57; break; // 9
      case 12: kp = 120; break; // x
      case 13: kp = 42; break; // *
      case 14: kp = 48; break; // 0
      case 15: kp = 61; break; // =
      case 16: kp = 47; break; // /

     }

    code1[i] = kp;
    I2C_LCD_Chr(1,i+1,code1[i]);            // affiche la touche presser sur la 1ere ligne
    
    if
(code1[i] == 43)                      // si on appuie sur +
    {
     Type_Operation = 1;                    // Type_Operation prend la valeur 1 qui correspond a une addition
     Longeur_Premiere_Valeur = i;           // longeur de la premiere valeur
    }
    
    if
(code1[i] == 45)                      // si on appuie sur -
    {
     Type_Operation = 2;                    // Type_Operation prend la valeur 2 qui correspond a une soustraction
     Longeur_Premiere_Valeur = i;           // longeur de la premiere valeur
    }
    
    if
(code1[i] == 120)                      // si on appuie sur x
    {
     Type_Operation = 3;                    // Type_Operation prend la valeur 3 qui correspond a une multiplication
     Longeur_Premiere_Valeur = i;           // longeur de la premiere valeur
    }
    
    if
(code1[i] == 47)                      // si on appuie sur /
    {
     Type_Operation = 4;                    // Type_Operation prend la valeur 4 qui correspond a une division
     Longeur_Premiere_Valeur = i;           // longeur de la premiere valeur
    }

    if(code1[i] == 42)                      // si on appuie sur * (etoile)
    {
     Annulation();                          // on appele la procedure Annulation()
    }

    
    if
(code1[i] == 61)                      // si on appuie sur =
    {
     Longeur_Deuxieme_Valeur = Longeur_Operation-Longeur_Premiere_Valeur-1; // longeur de la deuxieme valeur
     Resultat_Calcul();                     // on appele la procedure Resultat_Calcul()
    }

    if(> 16)                              // si i est plus grand que 16 caracteres
    {
     Annulation();                          // on appele la procedure Annulation()
    }
    
    i
++;
    Longeur_Operation = i;                  // longeur de l'operation
    
    delay_ms
(100);                           // attend 100ms antirebond
}



void main() {
    OSCCON = 0b01101000;                   // configuration OSCCON interne 4mhz
                                           // 0b01110000 oscillateur 8 Mhz
                                           // 0b01101000 oscillateur 4 Mhz
                                           // 0b01011000 oscillateur 2 Mhz
                                           // 0b01001000 oscillateur 1 Mhz
                                           // 0b00111000 oscillateur 500 Khz
                                           // 0b00101000 oscillateur 250 Khz
                                           // 0b00011000 oscillateur 125 Khz
                                           // 0b00001000 oscillateur 31 kHz

    while(OSCCON.HTS==0);                  // boucle en attendant de voir le flag à 1

    C1ON_bit = 0;                          // Disable comparators             // Fill data buffer

    ANSEL  = 0;                            // Configure AN pins as digital I/O
    ANSELH = 0;

    TRISA = 0x00;                          // en sortie par defaut
    TRISC = 0xFE;                          // en entree par defaut sauf RC0


    Keypad_Init();                         // Initialize Keypad
     delay_ms(100);

    I2C1_Init(100000);                     // initialisation de l'I2C
     delay_ms(100);

    I2C_LCD_Init();
     delay_ms(100);

    I2C_LCD_Cmd(_LCD_CURSOR_OFF);
    

    Welcome
();                                // appele la procedure Welcome


    do {
     Touche_Clavier();
    }
     
    while
(1); {                             // boucle infini

    }
}







@++
En fait tout est une question de BIT ? :-D

[résolu]Keypad 4x4
Jérémy
Administrateur du site
Administrateur du site
Messages : 2314
Âge : 40
Enregistré en : juillet 2015
Localisation : Dans le sud
Contact :

#12 Message par Jérémy » sam. 27 avr. 2019 22:34 lien vers la Data-Sheet : Cliquez ici

Bonsoir ,

Oui il existe des procédures de procédures de recherches de caractères et pas que pour les chiffres !
A mon avis le plus simple dans ton cas de figure , moi je ferais, un enregistrement tant que je rencontre pas un signe genre "-", "+" , "/" ou "*" .si je rencontre un de ces signes je récupère mon chiffre et le stocke dans une variable.
Ensuite j'attends le "=" pour récupérer le second chiffre ! c'est une idée comme ca , du but en blanc !
C'est en faisant des erreurs, que l'on apprend le mieux !!!

[résolu]Keypad 4x4
venom
Avatar de l’utilisateur
Confirmé
Confirmé
Messages : 599
Âge : 33
Enregistré en : avril 2016
Localisation : Klyntar
Contact :

#13 Message par venom » sam. 27 avr. 2019 22:41 lien vers la Data-Sheet : Cliquez ici

C'est exactement l'idée que j'ai essayé durant ces 2 jours. (Ça m'a semblé logique) Mais pas moyen d'avoir une valeur cohérente en additionnant les variables :mur: puis après je me suis perdu a force de tout essayé :? , j'ai donc tout effacer pour y voir plus clair.

DÉTERMINER je vais réessayer. Ça me soulage que tu penses de la même façon que moi. :-)






@++
En fait tout est une question de BIT ? :-D

[résolu]Keypad 4x4
Temps-x
Avatar de l’utilisateur
Expert
Expert
Messages : 1207
Enregistré en : juillet 2016
Localisation : Terre

#14 Message par Temps-x » dim. 28 avr. 2019 01:42 lien vers la Data-Sheet : Cliquez ici

Bonjour venom, Jérémy, et tout le forum,

Sur ton LCD, il faut écrire les caractères un par un, sans effacer ton LCD

En langage ASM :langue: j'ai confectionné un programme pour décodage de caractère, se qui me permet d'écrire des grands nombres.

Si on peut incorporer du langage ASM dans le C je te le fait,

venom a écrit :Source du message Mais pas moyen de réussir a récupérer 12+8 et l'exploiter genre 12 d'un côté et le 8 de l'autre.


Dans ton cas, le résultat 12 doit occuper 1 variable de 8 bits, qu'il faut séparer en deux variables de 8 bits.

Si je fais les calculs ça fait 60, ce qui correspond au caractère <

Jérémy a écrit :Source du message Oui il existe des procédures de procédures de recherches de caractères et pas que pour les chiffres !


C'est bien le gros problème du C, faire sans comprendre ce qui se passe derrière tout ça, ce qui donne ceci.

Exemple avec un nombre à 1 chiffre

Tu appuies sur un chiffre, tu le rentre dans une variable, et tu l'affiches à l'écran

Tu attends un signe qui va déterminer le calcul (+ - * / ) une fois fait tu l'affiches à l'écran, et tu va à la fonction du signe
qui lui correspond, ça te fait 4 fonctions à faire pour les 4 opérations de base en arithmétique (Addition , soustraction, multiplication, division)

La fonction doit attendre le second chiffre, et pouvoir la quitter par le signe égal

Le signe égal sera bien sur afficher à l'écran, à la sortie d'une des fonctions

==> A++
Quand la souris nargue le chat, c'est que son trou n'est pas loin.

[résolu]Keypad 4x4
venom
Avatar de l’utilisateur
Confirmé
Confirmé
Messages : 599
Âge : 33
Enregistré en : avril 2016
Localisation : Klyntar
Contact :

#15 Message par venom » dim. 28 avr. 2019 06:10 lien vers la Data-Sheet : Cliquez ici

Salut Temps-X,

En faite dans mon combat depuis 2 jours, j'ai bien réussi a récupérer les 2 valeurs séparément. Du moins j'ai réussi a les faire afficher sur la 2eme ligne a l'appui de la touche=

Mais bizarrement, a l'addition des 2 j'avais un résultat trop étrange. (Car pour le moment je test que sur l'addition). Je me suis donc dit que j'ai mal fait :-D

Je vais revoir mon code et au pire vous le montrer.
J'ai même essayé en enregistrant les chiffres dans l'eeprom pour vous dire :sifflotte: :roll:






@++
En fait tout est une question de BIT ? :-D

[résolu]Keypad 4x4
Jérémy
Administrateur du site
Administrateur du site
Messages : 2314
Âge : 40
Enregistré en : juillet 2015
Localisation : Dans le sud
Contact :

#16 Message par Jérémy » dim. 28 avr. 2019 07:24 lien vers la Data-Sheet : Cliquez ici

Bonjour à tous,

J'attends ton nouveau code.

Mais dans le code du dessus je ne vois aucune conversion de caractères à chiffre ??? tu vas afficher le chiffre "0" , qui en fait vaut 48 . il te faut faire une conversion. Entre l'affichage et la réalité il y a 48 de différence .
De plus tu déclare ton premier chiffre en int et tout second aussi ; le résultat peut être un double et non un int comme tu l'as déclaré ! faire bien attention a la longueur du résultat comme on fait des calculs ! :idea:

Temps-x a écrit :Source du message C'est bien le gros problème du C, faire sans comprendre ce qui se passe derrière tout ça, ce qui donne ceci.

Pas du tout d'accord : ce n'est pas parce qu'on utilise une fonction toute faite qu'on ne comprends pas ce qui se passe ! totu dépend de la personne .
C'est en faisant des erreurs, que l'on apprend le mieux !!!

[résolu]Keypad 4x4
satinas
Passioné
Passioné
Messages : 389
Enregistré en : novembre 2015

#17 Message par satinas » dim. 28 avr. 2019 07:36 lien vers la Data-Sheet : Cliquez ici

Bonjour à tous,

On peut effectivement saisir des morceaux d'expression, et ensuite séparer les valeurs, avec les fonctions de traitement de chaînes de caractères du C.
Mais dans le cas d'une calculatrice simple, je pense qu'il vaut mieux contrôler et traiter la saisie caractère par caractère.
Ce qui permet de se dispenser des fonctions C qu'on a du mal à retenir si on ne les utilise pas couramment.
Pas la peine d'initialiser les variables lors de leur déclaration, il suffit d'exécuter la fonction Annulation() au départ.

int Type_Operation=0;
int Longueur_Premiere_Valeur=0;
int Longueur_Deuxieme_Valeur=0;
unsigned int Val1=0, Val2=0;
unsigned long tmp;

si on saisit le caractère d'annulation -> Annulation

si on saisit une des 4 opérations :
- si Longueur_Premiere_Valeur == 0 ou Type_Operation != 0 -> Annulation (ou refuser le caractère saisi)
- Type_Operation = kp;

si on saisit '=' :
- si Longueur_Deuxieme_Valeur == 0 -> Annulation (ou refuser le caractère saisi)
- on calcule le résultat et on l'affiche

si on saisit '0' à '9' :
- si Type_Operation == 0 -> tmp = 10*Val1 + (kp-48);
- si Type_Operation != 0 -> tmp = 10*Val2 + (kp-48);
- si tmp > 65535 -> Annulation (ou refuser le caractère saisi)
- si Type_Operation == 0 -> val1 = tmp; et Longueur_Premiere_Valeur++;
- si Type_Operation != 0 -> val2 = tmp; et Longueur_Deuxieme_Valeur++;

Il serait intéressant de remplacer la touche Annulation par une touche Backspace.

[résolu]Keypad 4x4
venom
Avatar de l’utilisateur
Confirmé
Confirmé
Messages : 599
Âge : 33
Enregistré en : avril 2016
Localisation : Klyntar
Contact :

#18 Message par venom » dim. 28 avr. 2019 12:59 lien vers la Data-Sheet : Cliquez ici

Jérémy a écrit :tu vas afficher le chiffre "0" , qui en fait vaut 48 . il te faut faire une conversion. Entre l'affichage et la réalité il y a 48 de différence.


:shock: Ah mais je n'avais pas vue sa comme ça moi :?
Ah le boulet que je suis :oops: :furieux:
Je vais me pencher là dessus.






@++
En fait tout est une question de BIT ? :-D

[résolu]Keypad 4x4
Temps-x
Avatar de l’utilisateur
Expert
Expert
Messages : 1207
Enregistré en : juillet 2016
Localisation : Terre

#19 Message par Temps-x » dim. 28 avr. 2019 13:19 lien vers la Data-Sheet : Cliquez ici

Bonjour venom, Jérémy, satinas, et tout le forum,

Jérémy a écrit :Source du message Pas du tout d'accord : ce n'est pas parce qu'on utilise une fonction toute faite qu'on ne comprends pas ce qui se passe ! tout dépend de la personne .


Exacte, :sifflotte: c'est peut être pas ton cas, mais en général c'est la plupart du temps comme ça.

Le C me fait penser à l’Arduino avec ses bibliothèques toute faite,
Faire fonctionner son module, et pas se soucier du reste, belle exemple pour des passionnés de programmation.

Autant acheté tout fait, ça économiseras du temps :lol:

Source du message Jérémy a écrit :
tu vas afficher le chiffre "0" , qui en fait vaut 48 . il te faut faire une conversion. Entre l'affichage et la réalité il y a 48 de différence.


Exacte, il faut faire une addition pour ta conversion : chiffre + 48 Attention seulement un chiffre compris entre 0 et 9


==> A+
Modifié en dernier par Temps-x le dim. 28 avr. 2019 14:55, modifié 1 fois.
Quand la souris nargue le chat, c'est que son trou n'est pas loin.

[résolu]Keypad 4x4
Gérard
Avatar de l’utilisateur
Expert
Expert
Messages : 1089
Âge : 60
Enregistré en : septembre 2015
Localisation : Alsace - Haut-Rhin

#20 Message par Gérard » dim. 28 avr. 2019 14:45 lien vers la Data-Sheet : Cliquez ici

venom a écrit :
:shock: Ah mais je n'avais pas vue sa comme ça moi :?
Ah le boulet que je suis :oops: :furieux:
Je vais me pencher là dessus.






@++



Et ce n'est pas moi qui ai dit que tu étais un boulet ...
Mais entre boulets, on devrait se comprendre. :lol:

dehors!!
Le 18 / 04 / 2019 je suis devenu papy de jumeaux, une fille et un garçon. Quel bonheur.


Retourner vers « Langage C »

Qui est en ligne

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