Bonjour,
Je cherche à contrôler la valeur de RBx en fonction d'un paramètre x et je ne vois pas comment m'y prendre...
Contexte :
Je cherche à réaliser une matrice de boutons de type triangulaire étendue comme décrite dans ce lien.
Cela fonctionne à merveille : avec deux diodes par bouton, je peux bien appuyer sur n'importe quelle combinaison de boutons sans conflit et pour n entrées sur le Pic, je peux avoir n*(n-1) boutons. Pour mes essais, j'utilise 3 entrées et 6 boutons.
Mon code est fonctionnel : il teste si un bouton est appuyé ou relâché, affecte la valeur 1 ou 0 au tableau de boutons Bouton[i], puis fait clignoter une LED pour indiquer quels boutons sont appuyés.
Mon problème :
Pour optimiser le code, dans l'idéal, j'aurai aimé avoir un paramètre #define nbBoutons 6 qui définit le nombre total de boutons, adaptant le programme en fonction.
Je voudrais pour cela contrôler la valeur de RBx en fonction d'un paramètre x, sans passer par le test de RB0, RB1, RB2 dans le code. Je ne sais pas si je me fais bien comprendre...
C'est pour cette raison que j'ai défini la constante = #define Col(x) PORTBbits.RB##x
Malheureusement, dans le code, je peux sans problème contrôler la valeur de Col(1), Col(2), Col(3) etc... mais le code ne compile plus si j'y passe un paramètre :
Comment pourrais-je faire pour tester le bon port RB en fonction d'un paramètre ?Code:j = (ligne-1)*2; for (i=1; i<=3; i++) { if (Col(i) == Bouton[j]) { Bouton[j] = !Bouton[j]; } j++; }
Je vous mets mon code complet pour le contexte, mais mon problème est bien d'envoyer un paramètre à mon "tableau de constantes" Col(x).
Merci pour votre aide...Code:#include <xc.h> // CONFIG1H #pragma config FOSC = INTIO67 // Oscillator Selection bits (Internal Oscillator Block)) // CONFIG2H #pragma config WDTEN = OFF // Watchdog Timer Enable bits (Watch dog timer is always disabled. SWDTEN has no effect.) // CONFIG3H #pragma config PBADEN = OFF // PORTB A/D Enable bit (PORTB<5:0> pins are configured as digital I/O on Reset) #define _XTAL_FREQ 1000000 #define Debounce() __delay_ms(5) #define Col(x) PORTBbits.RB##x #define LED LATDbits.LATD0 char Bouton[] = {0,0,0,0,0,0}; void ControleLine(unsigned char ligne) { /* Pour tester une ligne, on la pose en sortie, les autres étant remises en entrée puis on la place à 0 * On testera ensuite chaque entrée une à une pour savoir si le bouton en question est appuyé ou non */ /* Si le bouton est appuyé, avec le pull-up, on a la colonne correspondante à 0 * On place la valeur de Bouton[i] à 1 s'il était à 0 (donc l'inverse) * Si on relâche le bouton, c'est que la colonne est repassée à 1 alors que le bouton était à 1 (égalité) */ unsigned char i = (ligne-1)*2; LATB = TRISB = 0xFF; switch (ligne) { case 1: // Active la ligne LATBbits.LATB1 = TRISBbits.TRISB1 = 0; // Contrôle if (Col(2) == Bouton[i] | Col(3) == Bouton[i+1]) { Debounce(); if (Col(2) == Bouton[i]) { Bouton[i] = !Bouton[i]; } if (Col(3) == Bouton[i+1]) { Bouton[i+1] = !Bouton[i+1]; } } break; case 2: // Active la ligne LATBbits.LATB2 = TRISBbits.TRISB2 = 0; // Contrôle if (Col(1) == Bouton[i] | Col(3) == Bouton[i+1]) { Debounce(); if (Col(1) == Bouton[i]) { Bouton[i] = !Bouton[i]; } if (Col(3) == Bouton[i+1]) { Bouton[i+1] = !Bouton[i+1]; } } break; case 3: // Active la ligne LATBbits.LATB3 = TRISBbits.TRISB3 = 0; // Contrôle if (Col(1) == Bouton[i] | Col(2) == Bouton[i+1]) { Debounce(); if (Col(1) == Bouton[i]) { Bouton[i] = !Bouton[i]; } if (Col(2) == Bouton[i+1]) { Bouton[i+1] = !Bouton[i+1]; } } break; } } void main(void) { unsigned char i, j; TRISD = 0; LATD = 0; INTCON2bits.RBPU = 0; // Pull-up on RB while(1) { /* Dans la pratique, on n'utilisera la valeur Bouton que pour enregistrer son dernier état * Puis on transmettra immédiatement un signal sans utiliser d, actuellement les délais de clignotement ralentissent beaucoup le traitement. */ for (i=1; i<=3; i++) { ControleLine(i); } for (i=0; i<6; i++) { if (Bouton[i] == 1) { for (j=0; j<=i; j++) { LED = 1; __delay_ms(50); LED = 0; __delay_ms(150); } __delay_ms(200); } } } }
-----