Au lieu de faire un traditionnel clignotement de leds, j'ai volontairement complexifié ce projet, en me contraignant les points suivants :
1) deux rangés de leds, soit au total 2x9 leds. Il y a alternances de leds vertes, jaunes et rouges par bloque de trois leds.
2) deux interrupteurs. Le premier sert à sélectionner un groupe, et le second à sélectionner un effet visuel dans le groupe.
3) il y a au total six groupes :
--> 1er groupe : 18 effets, soit un clignotement par led.
--> 2ème groupe : 4 effets en faisant clignoter seulement les leds vertes.
--> 3ème groupe : 4 effets en faisant clignoter seulement les leds jaunes.
--> 4ème groupe : 4 effets en faisant clignoter seulement les leds rouges.
--> 5ième groupe : 4 effets sous la forme d'un chenillard à une seule led allumée.
--> 6ième groupe : 4 effets sous la forme d'un chenillard à deux leds allumées.
4) gestion d'un timer qui permet de séquencer le clignotement.
Ce timer permet de ne pas monopoliser la CPU par une activité qui ne sert à rien.
Autrement dit, si l'affichage dure un laps de temps très court, le reste du temps quand la led ne clignote pas, le programme ne fait rien.
5) gestion des deux interrupteurs indépendamment l'un de l'autre, au sein, de deux timers.
Au total, dans le programme, il y a trois timers.
6) j'ai utilisé la bibliothèque "BCM2835" pour gérer les GPIO.
7) j'ai ajouté une gestion des signaux.
Quand le programmes fonctionne, et que vous désirez l'arrêter brutalement, il suffit de faire un CTRL-C.
Un signal est transmit au programme et celui-ci sort sort correctement.
Ce qui permet de ne pas laisser les GPIO dans un état disons instable.
8) pour réaliser le pontage, je n'ai pas utilisé des jumpers car j'avais des problèmes de faux-contacts.
J'ai utilisé un câble rigide de 0.2mm2 ce qui m'a permis d'avoir un ensemble compact.
9) un T-Cobbler, une natte à 40 fils, et ma Raspberry PI 2.
10) voici le programme écrit en 'C' :
Code : Tout sélectionner
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <time.h>
#include <pthread.h>
#include <unistd.h>
#include <bcm2835.h>
/***********************/
/* */
/* Définitions */
/* */
/***********************/
#define _NBRE_LOOP 23 /* Nombre de Boucle avant arrêt */
#define _NBRE_THREAD 3 /* Nombre de Tâches Lancées */
#define _NBRE_KEY 2 /* Nombre de Boutons Poussoirs */
#define _NBRE_LED 18 /* Nombre de Leds Clignottantes */
#define _NBRE_EFFET 6 /* Nombre de Groupe de Séquences */
#define _NBRE_MODE 38 /* Nombre Total de Séquences */
/*============================================*/
/* Liste des GPIO & Broches Utilisées */
/*============================================*/
/*-----------+--------*/
/* Broche 01 | 3.3Vcc */
/* Broche 06 | Ground */
/*-----------+--------*/
uint8_t iKey[_NBRE_KEY] = {RPI_V2_GPIO_P1_08, /* Broche 08 | GPIO14 */
RPI_V2_GPIO_P1_11}; /* Broche 11 | GPIO17 */
/*-----------+--------*/
uint8_t iLed[_NBRE_LED] = {RPI_V2_GPIO_P1_40, /* Broche 40 | GPIO21 */
RPI_V2_GPIO_P1_38, /* Broche 38 | GPIO20 */
RPI_V2_GPIO_P1_36, /* Broche 36 | GPIO16 */
/*-----------+--------*/
RPI_V2_GPIO_P1_32, /* Broche 32 | GPIO12 */
RPI_V2_GPIO_P1_26, /* Broche 26 | GPIO07 */
RPI_V2_GPIO_P1_24, /* Broche 24 | GPIO08 */
/*-----------+--------*/
RPI_V2_GPIO_P1_22, /* Broche 22 | GPIO25 */
RPI_V2_GPIO_P1_18, /* Broche 18 | GPIO24 */
RPI_V2_GPIO_P1_16, /* Broche 16 | GPIO23 */
/*-----------+--------*/
RPI_V2_GPIO_P1_37, /* Broche 37 | GPIO26 */
RPI_V2_GPIO_P1_35, /* Broche 35 | GPIO19 */
RPI_V2_GPIO_P1_33, /* Broche 33 | GPIO13 */
/*-----------+--------*/
RPI_V2_GPIO_P1_31, /* Broche 31 | GPIO06 */
RPI_V2_GPIO_P1_29, /* Broche 29 | GPIO05 */
RPI_V2_GPIO_P1_23, /* Broche 23 | GPIO11 */
/*-----------+--------*/
RPI_V2_GPIO_P1_21, /* Broche 21 | GPIO09 */
RPI_V2_GPIO_P1_19, /* Broche 19 | GPIO10 */
RPI_V2_GPIO_P1_15}; /* Broche 15 | GPIO22 */
/*-----------+--------*/
/* Raspberry PI 2B */
/*-----------+--------*/
/******************************/
/* */
/* Variables Globales */
/* */
/******************************/
pthread_cond_t tCond;
pthread_mutex_t tMutex;
struct sigaction action;
/*====================================*/
/* Déclaration des structures */
/*====================================*/
typedef struct {
pthread_t tThread;
int iNumero;
void (*function)(union sigval);
time_t period_sec;
long period_nsec;
} PARAMS, *LPARAMS;
typedef struct {
int iArret;
int iOnOff;
int iEffet;
int iMode;
int iRang;
} ARGS, *LARGS;
ARGS args = {_NBRE_LOOP, 1, 0, 0, 0};
/*===============================*/
/* Enchaînement des leds */
/*===============================*/
int tBegin[_NBRE_EFFET] = { 0,18,22,26,30,34};
int tQuant[_NBRE_EFFET] = {18, 4, 4, 4, 4, 4};
int tSuivant[_NBRE_MODE][2*_NBRE_LED+1] = {
{ 1, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{ 3, 0, 0, 4, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{ 5, 0, 0, 0, 0, 6, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{ 7, 0, 0, 0, 0, 0, 0, 8, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{ 9, 0, 0, 0, 0, 0, 0, 0, 0,10, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,12,11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,14,13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,16,15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,18,17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,20,19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,22,21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,24,23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,26,25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,28,27, 0, 0, 0, 0, 0, 0, 0, 0},
{29, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,30,29, 0, 0, 0, 0, 0, 0},
{31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,32,31, 0, 0, 0, 0},
{33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,34,33, 0, 0},
{35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,36,35},
{ 1, 2, 7, 0, 0, 0, 0, 8,13, 0, 0, 0, 0,14,19, 0, 0, 0, 0,20,25, 0, 0, 0, 0,26,31, 0, 0, 0, 0,32, 1, 0, 0, 0, 0},
{31, 2,31, 0, 0, 0, 0, 8, 1, 0, 0, 0, 0,14, 7, 0, 0, 0, 0,20,13, 0, 0, 0, 0,26,19, 0, 0, 0, 0,32,25, 0, 0, 0, 0},
{ 1, 2,19, 0, 0, 0, 0, 8,25, 0, 0, 0, 0,14,31, 0, 0, 0, 0,20, 7, 0, 0, 0, 0,26,13, 0, 0, 0, 0,32, 1, 0, 0, 0, 0},
{31, 2,31, 0, 0, 0, 0, 8,19, 0, 0, 0, 0,14,25, 0, 0, 0, 0,20, 1, 0, 0, 0, 0,26, 7, 0, 0, 0, 0,32,13, 0, 0, 0, 0},
{ 3, 0, 0, 4, 9, 0, 0, 0, 0,10,15, 0, 0, 0, 0,16,21, 0, 0, 0, 0,22,27, 0, 0, 0, 0,28,33, 0, 0, 0, 0,34, 3, 0, 0},
{33, 0, 0, 4,33, 0, 0, 0, 0,10, 3, 0, 0, 0, 0,16, 9, 0, 0, 0, 0,22,15, 0, 0, 0, 0,28,21, 0, 0, 0, 0,34,27, 0, 0},
{ 3, 0, 0, 4,21, 0, 0, 0, 0,10,27, 0, 0, 0, 0,16,33, 0, 0, 0, 0,22, 9, 0, 0, 0, 0,28,15, 0, 0, 0, 0,34, 3, 0, 0},
{33, 0, 0, 4,33, 0, 0, 0, 0,10,21, 0, 0, 0, 0,16,27, 0, 0, 0, 0,22, 3, 0, 0, 0, 0,28, 9, 0, 0, 0, 0,34,15, 0, 0},
{ 5, 0, 0, 0, 0, 6,11, 0, 0, 0, 0,12,17, 0, 0, 0, 0,18,23, 0, 0, 0, 0,24,29, 0, 0, 0, 0,30,35, 0, 0, 0, 0,36, 5},
{35, 0, 0, 0, 0, 6,35, 0, 0, 0, 0,12, 5, 0, 0, 0, 0,18,11, 0, 0, 0, 0,24,17, 0, 0, 0, 0,30,23, 0, 0, 0, 0,36,29},
{ 5, 0, 0, 0, 0, 6,23, 0, 0, 0, 0,12,29, 0, 0, 0, 0,18,35, 0, 0, 0, 0,24,11, 0, 0, 0, 0,30,17, 0, 0, 0, 0,36, 5},
{35, 0, 0, 0, 0, 6,35, 0, 0, 0, 0,12,23, 0, 0, 0, 0,18,29, 0, 0, 0, 0,24, 5, 0, 0, 0, 0,30,11, 0, 0, 0, 0,36,17},
{ 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36, 1},
{35, 2,35, 4, 1, 6, 3, 8, 5,10, 7,12, 9,14,11,16,13,18,15,20,17,22,19,24,21,26,23,28,25,30,27,32,29,34,31,36,33},
{ 1, 2,19, 4,21, 6,23, 8,25,10,27,12,29,14,31,16,33,18,35,20, 3,22, 5,24, 7,26, 9,28,11,30,13,32,15,34,17,36, 1},
{35, 2,35, 4,19, 6,21, 8,23,10,25,12,27,14,29,16,31,18,33,20, 1,22, 3,24, 5,26, 7,28, 9,30,11,32,13,34,15,36,17},
{ 1,36, 5, 2, 7, 4, 9, 6,11, 8,13,10,15,12,17,14,19,16,21,18,23,20,25,22,27,24,29,26,31,28,33,30,35,32, 1,34, 3},
{35, 4,33, 6,35, 8, 1,10, 3,12, 5,14, 7,16, 9,18,11,20,13,22,15,24,17,26,19,28,21,30,23,32,25,34,27,36,29, 2,31},
{ 1,36, 3,20, 5,22, 7,24, 9,26,11,28,13,30,15,32,17,34, 1, 2,21, 4,23, 6,25, 8,27,10,29,12,31,14,33,16,35,18,19},
{35,20,17,22, 1,24, 3,26, 5,28, 7,30, 9,32,11,34,13,36,15, 4,35, 6,19, 8,21,10,23,12,25,14,27,16,29,18,31, 2,33}};
/****************************/
/* */
/* Gestion des GPIO */
/* */
/****************************/
void gpio_init(void)
{
for (int i=0; i<_NBRE_KEY; i++)
{
bcm2835_gpio_fsel( iKey[i], BCM2835_GPIO_FSEL_INPT);
bcm2835_gpio_set_pud(iKey[i], BCM2835_GPIO_PUD_OFF);
}
for (int i=0; i<_NBRE_LED; i++)
bcm2835_gpio_fsel( iLed[i], BCM2835_GPIO_FSEL_OUTP);
}
void raz_leds(void)
{
for (int i=0; i<_NBRE_LED; i++)
bcm2835_gpio_write(iLed[i], LOW);
}
void gpio_reset(void)
{
for (int i=0; i<_NBRE_KEY; i++)
{
bcm2835_gpio_fsel( iKey[i], BCM2835_GPIO_FSEL_INPT);
bcm2835_gpio_set_pud(iKey[i], BCM2835_GPIO_PUD_OFF);
}
for (int i=0; i<_NBRE_LED; i++)
{
bcm2835_gpio_fsel( iLed[i], BCM2835_GPIO_FSEL_INPT);
bcm2835_gpio_set_pud(iLed[i], BCM2835_GPIO_PUD_OFF);
}
}
/************************************************/
/* */
/* Handler sur Signal "SIGINT" (ctrl-c) */
/* */
/************************************************/
void handler(int signo)
{
printf("\nReçu Signal %d (SIGINT=2), sortie normale du programme\n", signo);
action.sa_handler = SIG_DFL;
sigemptyset(&action.sa_mask);
sigaction(SIGINT, &action, NULL);
args.iArret = 0;
}
/********************************/
/* */
/* Création des Threads */
/* */
/********************************/
void button1(union sigval sv)
{
static int iPrev=0;
volatile int iPress;
pthread_mutex_lock(&tMutex);
LARGS largs = sv.sival_ptr;
if ((iPress = bcm2835_gpio_lev(iKey[0])) != iPrev)
{
if (iPress == HIGH)
{
(largs->iArret)--;
largs->iOnOff = !largs->iOnOff;
if (largs->iOnOff)
{
largs->iEffet = (largs->iEffet+1) % _NBRE_EFFET;
largs->iMode = tBegin[largs->iEffet];
largs->iRang = 0;
printf("Bouton 1 --> ON Reste=%d\n", largs->iArret);
}
else printf("Bouton 1 --> OFF Reste=%d\n", largs->iArret);
}
iPrev = iPress;
}
if (largs->iArret<=0)
pthread_cond_signal(&tCond);
pthread_mutex_unlock(&tMutex);
pthread_exit(NULL);
}
void button2(union sigval sv)
{
static int iPrev=0;
volatile int iPress;
pthread_mutex_lock(&tMutex);
LARGS largs = sv.sival_ptr;
if ((iPress = bcm2835_gpio_lev(iKey[1])) != iPrev)
{
if (iPress == HIGH)
{
raz_leds();
largs->iMode = ((largs->iMode + 1 - tBegin[largs->iEffet]) % tQuant[largs->iEffet]) + tBegin[largs->iEffet];
largs->iRang = 0;
printf("Bouton 2 --> Mode=%d\n", largs->iMode);
}
iPrev = iPress;
}
if (largs->iArret<=0)
pthread_cond_signal(&tCond);
pthread_mutex_unlock(&tMutex);
pthread_exit(NULL);
}
void led(union sigval sv)
{
pthread_mutex_lock(&tMutex);
LARGS largs = sv.sival_ptr;
if (largs->iOnOff)
{
largs->iRang = tSuivant[largs->iMode][largs->iRang];
bcm2835_gpio_write(iLed[(largs->iRang-1)/2], 1 - (largs->iRang-1)%2);
}
else raz_leds();
if (largs->iArret<=0)
pthread_cond_signal(&tCond);
pthread_mutex_unlock(&tMutex);
pthread_exit(NULL);
}
/*******************************/
/* */
/* Création des Timers */
/* */
/*******************************/
void *timer(void *ptr)
{
int iStatus;
timer_t tTimerid;
struct sigevent sSevt;
struct itimerspec sIts;
pthread_mutex_lock(&tMutex);
LPARAMS lparams = ptr;
/*===========================*/
/* Création du Timer */
/*===========================*/
memset(&sSevt, 0, sizeof(struct sigevent));
sSevt.sigev_notify = SIGEV_THREAD;
sSevt.sigev_notify_function = lparams->function;
sSevt.sigev_notify_attributes = NULL;
sSevt.sigev_value.sival_ptr = &args;
if ((iStatus = timer_create(CLOCK_REALTIME, &sSevt, &tTimerid)) == -1)
{
printf("%s : %d : timer %d create failed : %d\n", __FILE__, __LINE__, lparams->iNumero, iStatus);
pthread_exit(NULL);
}
/*============================*/
/* Lancement du Timer */
/*============================*/
memset(&sIts, 0, sizeof(struct itimerspec));
sIts.it_interval.tv_sec = lparams->period_sec;
sIts.it_interval.tv_nsec= lparams->period_nsec;
sIts.it_value.tv_sec = lparams->period_sec;
sIts.it_value.tv_nsec = lparams->period_nsec;
if ((iStatus = timer_settime(tTimerid, 0, &sIts, NULL)) == -1)
{
printf("%s : %d : timer %d settime start failed : %d\n", __FILE__, __LINE__, lparams->iNumero, iStatus);
pthread_exit(NULL);
}
/*=================================================*/
/* Condition d'attente de l'arrêt du Timer */
/*=================================================*/
pthread_cond_wait(&tCond, &tMutex);
/*========================*/
/* Arrêt du Timer */
/*========================*/
sIts.it_interval.tv_sec = 0;
sIts.it_interval.tv_nsec= 0L;
sIts.it_value.tv_sec = 0;
sIts.it_value.tv_nsec = 0L;
if ((iStatus = timer_settime(tTimerid, 0, &sIts, NULL)) == -1)
{
printf("%s : %d : timer %d settime stop failed : %d\n", __FILE__, __LINE__, lparams->iNumero, iStatus);
pthread_exit(NULL);
}
/*==============================*/
/* Destruction du Timer */
/*==============================*/
if ((iStatus = timer_delete(tTimerid)) == -1)
{
printf("%s : %d : timer %d delete failed : %d\n", __FILE__, __LINE__, lparams->iNumero, iStatus);
pthread_exit(NULL);
}
pthread_mutex_unlock(&tMutex);
pthread_exit(NULL);
}
/********************************/
/* */
/* Procédure Principale */
/* */
/********************************/
int main(void)
{
int iStatus;
/*====================================*/
/* Déclaration des paramètres */
/*====================================*/
PARAMS params[_NBRE_THREAD] =
{{0, 1, button1, 0L, 50000000L},
{0, 2, button2, 0L, 50000000L},
{0, 3, led, 0L, 80000000L}};
/*=====================================*/
/* Gestion du signal 'SIGINTR' */
/*=====================================*/
action.sa_handler = handler;
sigfillset(&action.sa_mask);
sigaction(SIGINT, &action, NULL);
/*=================================*/
/* Initialisation des GPIO */
/*=================================*/
printf("Début : Boutons & Leds !\n");
if (!(iStatus = bcm2835_init()))
{
printf("%s : %d : bcm2835 init failed : %d\n", __FILE__, __LINE__, iStatus);
exit(-1);
}
gpio_init();
/*=============================*/
/* Création d'un mutex */
/*=============================*/
if ((iStatus = pthread_mutex_init(&tMutex, NULL)))
{
printf("%s : %d : mutex init failed : %d\n", __FILE__, __LINE__, iStatus);
exit(-1);
}
/*===========================================*/
/* Création d'une variable condition */
/*===========================================*/
if ((iStatus = pthread_cond_init(&tCond, NULL)))
{
printf("%s : %d : condition variable init failed : %d\n", __FILE__, __LINE__, iStatus);
exit(-1);
}
/*=======================================*/
/* Démarrage de tous les threads */
/*=======================================*/
for (int i=0; i<_NBRE_THREAD; i++)
{
if ((iStatus = pthread_create(¶ms[i].tThread, NULL, timer, (void *) ¶ms[i])))
{
printf("%s : %d : thread %4d create failed : %d\n", __FILE__, __LINE__, params[i].iNumero, iStatus);
exit(-1);
}
}
/*===============================================*/
/* Attente de la fin de tous les Threads */
/*===============================================*/
for (int i=0; i<_NBRE_THREAD; i++)
{
if ((iStatus = pthread_join(params[i].tThread, NULL)))
{
printf("%s : %d : thread %4d join failed : %d\n", __FILE__, __LINE__, params[i].iNumero, iStatus);
exit(-1);
}
// if ((iStatus = pthread_detach(params[i].tThread)))
// {
// printf("%s : %d : thread %4d detach failed : %d\n", __FILE__, __LINE__, params[i].iNumero, iStatus);
// exit(-1);
// }
}
/*==============================================*/
/* Destruction de la variable condition */
/*==============================================*/
if ((iStatus = pthread_cond_destroy(&tCond)))
{
printf("%s : %d : condition variable destroy failed : %d\n", __FILE__, __LINE__, iStatus);
exit(-1);
}
/*==============================*/
/* Destruction du Mutex */
/*==============================*/
if ((iStatus = pthread_mutex_destroy(&tMutex)))
{
printf("%s : %d : mutex destroy failed : %d\n", __FILE__, __LINE__, iStatus);
exit(-1);
}
/*============================*/
/* Fermeture des GPIO */
/*============================*/
raz_leds();
gpio_reset();
if (!(iStatus = bcm2835_close()))
{
printf("%s : %d : bcm2835 close failed : %d\n", __FILE__, __LINE__, iStatus);
exit(-1);
}
printf("Fin : Boutons & Leds !\n");
exit(EXIT_SUCCESS);
}
@+