PIC18 et langage C : j'ai un pb de débutant...

Do you have a question? Post it now! No Registration Necessary

Translate This Thread From French to

Threaded View
Bonjour à tous,
avant j'étais pic16 et assembleur mais comme je passe aux pic18 je me
confronte maintenant au langage C, et c'est le début j'ai du mal...
Il me semble que je passe a côté de trucs élémentaires, donc si tu veux
bien jeter un oeuil sur mon code, merci de critiquer !

Je vous expose mon problème : sur le portB j'ai un clavier en matrice
4x4. RB0-3 en entrées, RB4-7 en sorties, Résistances de pullup actives,
interruptions désactivés.

Mon programme principal fait régulièrement un appel de la fonction
"LireTouche()", elle met à jour ma variable "touche" qui devrait
contenir le code de la touche activée.
Le problème est que "Touche" ne contient pas toujours le bon code, ça
marche bien pour environ 80% des touches, mais pour certaines elle me
renvoie un mauvais code.


BOOL LireTouche(void)
{
/* Variables Locales */
    BYTE CLAVier;

/* Instructions */
    mInitClavier();
    Touche=0;        // variable qui contiendra le code de la touche appuyée


    CLAV=0b00001110; // Charge le masque de la 1ere ligne (RB0=0) (RB0-3 en
sorties)
    CLAVier=CLAV;            // effectue une lecture du Clavier (RB4-7 en entrées)
    if(CLAVier & 0b00010000) ; else Touche = 0b00010001;  //RB4 Clic Droit
    if(CLAVier & 0b00100000) ; else Touche = 0b00100001;  //RB5 Bas Droite
    if(CLAVier & 0b01000000) ; else Touche = 0b01000001;  //RB6 Bas
    if(CLAVier & 0b10000000) ; else Touche = 0b10000001;  //RB7 Bas Gauche

    CLAV=0b00001101;  // Charge le masque de la 2e ligne (RB1=0)
    CLAVier=CLAV;
    if(CLAVier & 0b00010000) ; else Touche = 0b00010010;  //RB4
    if(CLAVier & 0b00100000) ; else Touche = 0b00100010;  //RB5
    if(CLAVier & 0b01000000) ; else Touche = 0b01000010;  //RB6
    if(CLAVier & 0b10000000) ; else Touche = 0b10000010;  //RB7

    CLAV=0b00001011;  // Charge le masque de la 3e ligne (RB2=0)
    CLAVier=CLAV;
    if(CLAVier & 0b00010000) ; else Touche = 0b00010100;  //RB4
    if(CLAVier & 0b00100000) ; else Touche = 0b00100100;  //RB5
    if(CLAVier & 0b01000000) ; else Touche = 0b01000100;  //RB6
    if(CLAVier & 0b10000000) ; else Touche = 0b10000100;  //RB7

    CLAV=0b00000111;  // Charge le masque de la 4e ligne (RB3=0)
    CLAVier=CLAV;
    if(CLAVier & 0b00010000) ; else Touche = 0b00011000;  //RB4
    if(CLAVier & 0b00100000) ; else Touche = 0b00101000;  //RB5
    if(CLAVier & 0b01000000) ; else Touche = 0b01001000;  //RB6
    if(CLAVier & 0b10000000) ; else Touche = 0b10001000;  //RB7

    if (Touche!=0) return TRUE;
}  //Fin de LireTouche()


Voilà, j'espère que l'exposé de ma situation aura été asses clair.
Qu'est-ce qui ce passe d'après vous ?

Laurent

Re: PIC18 et langage C : j'ai un pb de débutant...
J'ai oublié de dire que CLAV = PORTB

Re: PIC18 et langage C : j'ai un pb de débutant...
Quoted text here. Click to load it

Pourquoi tu utilises une variable globale eu lieu de renvoyer la valeur
directement par la fonction ?

Ensuite tu écris des choses du genre
if(<test>) ; else Touche = <valeur>;
... Ce qui veut dire, "si <test> est vrai, alors ne rien faire, sinon
mettre Touche = <valeur>". Je ne pense pas que ce soit ce que tu veux
faire. Ca m'étonne même que ton code marche dans 80% des cas ;-)

La fonction peut être remplacée par :

BYTE LireTouche(void)
{
     BYTE row, col;

     mInitClavier();

     for(row=0x08; row != 0; row >>= 1) {
         CLAV = 0x0F & ~row;
         for(col = 0x80; col != 0x08; col >>= 1) {
             if(CLAV & col)
                 return row | col;
         }
     }

     return 0;
}

v.

Re: PIC18 et langage C : j'ai un pb de débutant...
Le 15/04/2010 15:02, vic a écrit :

Quoted text here. Click to load it
Parce que j'y vais progressivement...

Quoted text here. Click to load it
si si, c'est ce que j'ai besoin, car si ma touche est appuyée alors je
lit un zéro en entrée (logique inverse). et je ne sais pas faire le test
'ET-NON' !


Quoted text here. Click to load it

waow, nickel, c'est dense !
j'ai juste modifié le 'if' par :
    if(CLAV & col) ; else return (col | row);

pour l'histoire du ET-NON, et pour rétablir l'ordre des lignes/colonnes
qui étaient inversées.

En tous cas merci beaucoup vic, c'est efficace et ça tourne au poil !
Tu viens de m'aider d'une étape dans mon ascension du mont "C" ...

Laurent

Re: PIC18 et langage C : j'ai un pb de débutant...
Quoted text here. Click to load it

OK, je n'avais pas trop fait attention à ça en répondant, car je ne
savais pas comment était branché ton clavier. Le "NON" en C, c'est "!" :

Quoted text here. Click to load it

Tu peux écrire aussi :
if(!(CLAV & col)) return col | row;

Pour info col | row == row | col.

Essaie de trouver un tutoriel sur Internet avec les bases du langage,
les opérateurs logiques, les structures de contrôle, etc, ça te sera
utile ;-)

v.

Re: PIC18 et langage C : j'ai un pb de débutant...
On 15 avr, 16:05, Laurent CLAUDE

Quoted text here. Click to load it

Pour faire cela en C, la faE7%on la plus idiomatique est:

if ( !(CLAV & col) ) return ( col | row );

ou

#define true 1
#define false 0


if ( (CLAV & col) 3D%3D false)
{
  return col | row;
}

l'inconvE9%nient d'un if sans instruction, c'est le
risque d'erreur en lisant le code.

--
-Stan

Re: PIC18 et langage C : j'ai un pb de débutant ...
Stan, le 15/04/2010 a écrit :
Quoted text here. Click to load it

Il me semble que *c'est* la bonne façon. Ou si c'est plus parlant:

if ( !CLAV | !col ) return ( col | row );

Quoted text here. Click to load it

C'est risqué. Déjà, une coquetterie fait qu'on préfère parfois:

#define false 0
#define true !false

Mais ça ne change rien.

if (condition == false)

n'est vraiment pas idiomatique, par rapport à tout simplememt:

if(!condition)

Et puis le danger est de définir true à 1 et d'écrire:

if(cond == true)

cond est par exemple cond1 || cond2, ça va bien se passer. Mais si
c'est cond1 | cond2, voire 0b00000010, alors ça risque de merder. En
revanche, le truc suivant doit être sûr, mais assez ugly:

if(!!cond == true)
ou
if(!cond != true)

Et comme vous-mêmes utilisez (pourquoi ?) des opérateurs bitwise là où
la sémantique est booléenne, il vaut mieux éviter. A mon avis.

En fait, pour la lisibilité, il est préférable de se concentrer sur le
nommage que d'introduire des booléens artificiels.

Tout ceci dans le cadre d'un compilateur standard, je n'ai du PIC que
l'expérience d'un projet en assembleur. Donc je peux me tromper, si le
compilateur PIC est spécifique.

Quoted text here. Click to load it

Ou encore pire en le maintenant.

--
Pierre Maurette



Re: PIC18 et langage C : j'ai un pb de débutant ...

Quoted text here. Click to load it


FAIL.

Re: PIC18 et langage C : j'ai un pb de débutant...
Quoted text here. Click to load it

VoilE0% ce que c'est de rE9%pondre E0% un post en regardant
la tE9%lE9% :-)

La conversion implicite d'un int vers le bool
n'existe qu'en C++.
Mais dans ce cas, la dE9%finition d'un boolean est inutile
puisqu'elle existe dE9%ja.


--
-Stan


Re: PIC18 et langage C : j'ai un pb de débutant...
Quoted text here. Click to load it

Je n'ai pas la norme du C99 sous les yeux,
mais c'est sans doute pareil.

Mais avant qu'un compilo PIC soit C99...

--
-Stan




Re: PIC18 et langage C : j'ai un pb de débutant ...
debug this fifo, le 16/04/2010 a écrit :
Quoted text here. Click to load it

Ça passerait avec:

if ( (CLAV && col) == false)

Mais c'est ripoux...

--
Pierre Maurette



Re: PIC18 et langage C : j'ai un pb de débutan t...
Quoted text here. Click to load it

c'est surtout le true qui coince...
CLAV = 2;
col = 2;
CLAV & col -> 2 -> donc c'est vrai mais pas true !

Re: PIC18 et langage C : j'ai un pb de débutant...
Le Thu, 15 Apr 2010 16:05:29 +0200, Laurent CLAUDE a écrit :

Quoted text here. Click to load it

une bonne pratique dans ce genre de chose est de tirer un listing avec
les lignes de C et d'assembleur imbriquées.

Ton programme teste les bits. Il y a une instruction test de bit qui
existe.
Un petit "pragma" (une ligne d'assembleur) ne serait pas une solution ?
Je ne connais pas ton compilateur mais cela serait un bon exercice.

Après compares l'expansion entre les 2 solutions ... et le temps CPU.

N'oublies pas que ton environnement est limité.

CH

Re: PIC18 et langage C : j'ai un pb de débutant ...
vic a tapoté du bout de ses petites papattes :

Quoted text here. Click to load it

C'est, je suppose, une vieille coutume qui vient de certains compilos
qui ne permettaient pas d'utiliser directement le retour d'une fonction
et il fallait la mettre dans une variable pour jouer avec.
Je fais toujours pareil par précaution. Mais quand on fait du C proche
machine, surtout avec des ressources limitées, c'est évidemment un peu
grossier.
C'est l'avantage de l'assembleur (en plus de la vitesse), on a un
nombre précis (et des formats) de registres et des emplacements
mémoire. Un assembleur ne peut pas te jeter à cause d'un retour de
fonction mal utilisé (enfin sauf si c'est dans la stack et que tu
dépiles mal, mais bon, c'est un métier, hein ? ;) ).

--
LeLapin



Re: PIC18 et langage C : j'ai un pb de débutan t...
Quoted text here. Click to load it

Sur PIC il me semble que la pile est dans un espace mémoire différent de
la RAM normale. Mais sur AVR, il se passe parfois des choses marrantes
quand le bas de la pile vient toucher le haut du tas. Le problème
apparaît quand il y a trop de fonctions imbriquées, et si on débugge la
fonction qui pose problème seule, tout marche très bien. Pas évident à
debugger la première fois :-)

v.

Re: PIC18 et langage C : j'ai un pb de débutant ...
vic a tapoté du bout de ses petites papattes :
Quoted text here. Click to load it

AVR ? Kézako ? Instruis-moi de toutes ces modernités, j'en suis avide !

--
LeLapin



Re: PIC18 et langage C : j'ai un pb de débutan t...
Quoted text here. Click to load it

C'est le nom donné par Atmel à sa série de µC, comme ATtiny2313 ou
ATmega328 , etc ...
http://www.atmel.com/products/avr/

Contrairement aux PICs leur architecture est compatible avec GCC, ce qui
est un gros point positif (pour moi en tous cas ;)). L'inconvénient est
qu'il sont un poil plus chers (ça se joue en centimes) et moins
populaires que les PICs en France donc un peu plus durs à trouver.

v.

Re: PIC18 et langage C : j'ai un pb de débutant ...
vic a tapoté du bout de ses petites papattes :
Quoted text here. Click to load it

Ah oui, Atmel, j'avais vu ça dans ma recherche de µC modernes. En gros,
à part le prix quelles sont les vraies différences avec les PICs (bon
je sais que si on met un amateur de 6800, une de 6502 rt un de 8080
dans la même pièce, chacun trouvera toujours le sien meilleur que les
autres, mais bon, en étant en peu neutre) ? Je sais pas moi, en
vitesse, gestion des IT, jeu d'instructions, interfaçage,
programmabilité...?

--
LeLapin



Re: PIC18 et langage C : j'ai un pb de débutant...

Quoted text here. Click to load it

Ah, papy sait utiliser un moteur de recherche :o)

Quoted text here. Click to load it

J'ai du travailler autant avec de l'Intel que du Motorola.
Quand c'est pour des raisons professionnelles on n'a pas
toujours le choix de l'uC.
Objectivement, les archi Motorola sont mieux conE7%ues.

Quoted text here. Click to load it

Pour certaines familles de PIC, la gestion des IT est trE8%s moche.
( peut EA%tre est-elle mieux conE7%ue pour celles que je ne connait pas).

--
-Stan

Re: PIC18 et langage C : j'ai un pb de débutan t...
Quoted text here. Click to load it

J'ai personnellement une grosse préférence pour les AVR donc je ne suis
pas hyper objectif, mais voici les différences des AVR par rapport aux
PICs :

* Architecture :
- Pas de registre W, mais 32 registres généraux
- Pas de banque de mémoire à switcher à tout bout de champ. L'adressage
peut se faire sur 16 bits.
- Pas d'espace mémoire séparé pour la pile.
- Compatible avec GCC

* Jeu d'instructions
- Plus complet, avec toute sorte d'instruction de branchements et
d'adressage différent, mais plus long à apprendre (mais pourquoi
utiliser l'assembleur quand on a GCC ;))
- Sur PIC on peut toujours calculer le moment d'exécution d'une
interruption exactement. Sur AVR, il y a toujours une incertitude de +/-
1 cycle.

* Périphériques
- Pour les I/O, il y a 3 registres : direction, valeur écrite sur le
port, et valeur réellement présente sur le port. Evite les erreurs du
type "read-modify-write"
- Moins de périphériques que les PICs en ADC, USB, Ethernet, etc ...

* Vitesse
- Généralement plus rapides, la fréquence d'horloge est celle du quartz,
  sur les PICs elle est divisée par 4.

* Utilisabilité
- Moins de choix dans la gamme que pour les PICs. Pas forcément gênant
pour un amateur mais en production ça peut obliger à prendre un modèle
un peu plus cher que nécéssaire.
- Outils open-source, gratuits, multi-plateforme. IDE ou bien ligne de
commande.
- Programmation série sous 5V au lieu de 12V.

v.

Site Timeline