Je ne sais pas si quelque chose a déjà été implémenté pour le faire automatiquement, mais voici ma solution.
En utilisant la fonction MIOS_DIN_NotifyToggle(), le contrôleur réagira à chaque changement d’état du bouton, c’est-à -dire aussi bien à l’appui qu’au relachement. Dans ce cas, il n’y a pas besoin de mémoriser la valeur (on ou off) envoyée par le bouton, puisqu’elle correspond à l’état du bouton.
Ce que tu cherches, au contraire, nécessite de se creuser un peu plus la tête car il faut mémoriser quelque part cette valeur. Que tu veuilles allumer ou éteindre ta LED, l’action sera la même : appui - relâchement d’un bouton. Donc, physiquement, rien ne distingue l’action “éteindre la LED” de l’action “allumer” : il faut une information supplémentaire.
La solution que j’ai trouvée est (pour simplifier) de stocker les états des LEDs dans un tableau, que j’initialise à zéro. Dans DIN_NotifyToggle(), je ne traite l’appui sur le bouton QUE lorsqu’il est enfoncé, pas relâché. J’inverse alors en mémoire l’état de la diode correspondante, puis je mets le flag d’affichage à un, pour pouvoir traiter ce changement d’état lors de l’appel de DISPLAY_Tick().
Et c’est dans DISPLAY_Tick que je colle la routine qui gère l’allumage/extinction des LEDs, via la fonction MIOS_DOUT_PinSet(…).
Ce qui donne en gros (dans main.c) :
....
//exemple pour traiter 8 boutons devant se comporter de cette façon
#define NB_LEDS 8
....
unsigned char led_status[NB_LEDS] ;
....
void Init() {
....
unsigned char i ;
for(i=0;i<NB_LEDS;i++) led_status[i]=0 ; //toutes les LEDs éteintes au début. Bien sûr tu peux aussi en avoir certaines allumées
//au début de l'application
app_flags.DISPLAY_UPDATE_REQ=1 ; //voir la fonction DISPLAY_Tick. Flag de requête de rafraîchissement d'affichage.
.....
}
void DISPLAY_Tick()
{
if(!app_flags.DISPLAY_UPDATE_REQ) return ; //signifie : ne rien faire et immédiatement quitter la fonction si le flag de réaffichage est à 0 .
app_flags.DISPLAY_UPDATE_REQ=0 ; // on réinitialise le drapeau
.......
unsigned char i ;
for(i=0;i<NB_LEDS;i++) MIOS_DOUT_PinSet(i,led_status[i]) ; //ici est l'instruction qui allume ou éteint directement les diodes
......
}
void DIN_NotifyToggle(unsigned char pin,unsigned char pin_value)
{
switch(pin)
{
case 0 : ....
break ;
case 1 : ....
break ;
case 2 : ....
break ;
//tout ça dépend de quels numéros sont attribués aux boutons qui nous intéressent ici.
// par exemple, admettons que le pin n° 23 soit le bouton qui commande la LED branchée sur le pin n° 4 :
case 23 : if(pin_value) break ; /*traduction : si le changement d'état qui a amené à l'appel de cette fonction vient du pin 23
et que sa valeur actuelle est non-nulle, ça signifie qu'il y a 5V sur ce pin, donc qu'il n'est pas connecté
à la masse, donc que l'interrupteur est ouvert, donc qu'il vient d'être relâché. Donc : break
(ne pas traiter les instructions suivantes du case). Ou même return à la rigueur, comme ça
on ne perd même pas de temps à traiter inutilement le reste de la fonction.
Note bien au passage que pin_value vaut 0 quand le bouton est enfoncé, 1 sinon. 0=ON, 1=OFF (!) */
led_status[4] = !led_status[4] ; //dans le cas contraire, inversion de l'état de la LED 4 ;
flags.DISPLAY_UPDATE_REQ=1 ;
break ;
......
}
Voiloù. Bon ce code n’est pas parfait (notamment dans le fait d’utiliser un unsigned char d’un octet pour stocker une valeur qui ne peut valoir que 0 ou 1) mais c’est juste pour avoir l’idée.
J’insiste sur le fait qu’ici on traite uniquement de l’affichage au niveau des diodes, concernant la véritable action du bouton, il faut ajouter le code correspondant (le tableau led_status peut être recyclé pour d’autres usages).
En espérant avoir été utile et pas trop lourd à lire …
Dubs.