Formation aux PIC - Page 3

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

Translate This Thread From French to

Threaded View
Re: Formation aux PIC

Quoted text here. Click to load it
============
La HP9100  (pas une machine d'écolier étant donné son poids ) cent nonante
six pas de programme, mémoire tores, cartes magnétiques ...   n'en'etait pas
loin ...




Re: Formation aux PIC

Quoted text here. Click to load it

le problème c'est le programmeur
lambda est persuadé
de programmer asm à la main mieux que
ne le ferait un compilateur C...

hors c'est faux... ça fait mal
à l'ego mais bon...

meme en C on retrouve le meme
syndrome, on peut écrire du C compact
et difficilement lisible...

ça flatte le programmeur mais ça compile en
donnant exactement le meme asm que le C
écrit en version "neuneu"....




Re: Formation aux PIC
Quoted text here. Click to load it

Exact ! J'avais essayé de faire avec deux entiers :

a = a^b;
b = a^b;
a = a^b;

Cela inverse a et b sans utiliser de variable temporaire, moins d'accès
mémoire et tout ça, en seulement trois cycles...

Gcc avec les options d'optimisations activées a compris la manoeuvre, a viré
les xors et a codé ça de façon différente. Outch !

Et le pire, c'est que le test était au début, avant que je ne lui empêche :

printf("%d %d\n", a, b);
a = a^b;
b = a^b;
a = a^b;
printf("%d %d\n", a, b);

... qu'il a remplacé par :

printf("%d %d\n", a, b);
printf("%d %d\n", b, a);

Le petit malin ;))

N'empêche, c'est assez impressionnant, je trouve.

--
cLx

Re: Formation aux PIC

h90koq$1i3$ snipped-for-privacy@news.trigofacile.com...
Quoted text here. Click to load it

pareil.... et encore plus impressionnant, l'intelligence
des gars capables d'écrire GCC...




Re: Formation aux PIC

Quoted text here. Click to load it

Moi je trouve pas, pour le fun je colle ci dessous un programme en C que
j'ai écris en 2 ou 3 soirées, sur un tout petit 12F675 (8 broches) vraiment
minuscule, je précise que je n'avais jamais approché de près ni de loin ce
composant, c'est un petit automate à état pour controler de façon soit
manuelle soit full-automatique suivant le temps d'appui sur les boutons,
avec gestion des e/s (capteurs, vérins, boutons, un buzzer) l'ouverture et
la fermeture d'une capote électrique de voiture sans connaitre le moins du
monde l'assembleur de ce composant et comme vous pouvez le voir il n'y a pas
la moindre ligne de code asm("....") .

Je suis sur que même un débutant saura comprendre comment ça marche sans y
passer des nuits parce que "visuellement" ça ressemble à quelque chose,
c'est simpliste et j'aurais pu le faire en assembleur, mais franchent, aucun
interet. et si demain ce composant n'est plus dispo, en adaptant quelques
trucs je peux passer à un autre modèle qui n'a rien à voir ou même une autre
marque (atmel par exemple que j'aime bien aussi car très performants) en
changeant juste les port io, l'initialisation et la gestion du timer qui est
un peu différente.

#include <htc.h>

__CONFIG(CPD & PROTECT & BOREN & MCLRDIS & PWRTEN & WDTEN & INTIO);

// Tempo de passage en automatique
#define AUTO_TIMEOUT 20 // 2 secondes (valeur exprimée en 1/10 de s car le
timer tourne à 10Hz)

// E/S
#define OPEN_PUSHED  GPIO0 // ENTREE bouton 'ouverture' logique positive
#define CLOSE_PUSHED GPIO1 // ENTREE bouton 'fermeture' logique positive
#define CMD_BUZZER  GPIO2 // SORTIE buzzer, logique positive
#define PUMP_STOPPED GPIO3 // ENTREE entrée pompe, logique inverse (1 =
pompe arrétée, 0 = pompe en marche)
#define CMD_NOT_OPENING GPIO4 // SORTIE commande d'ouverture  logique
NEGATIVE (1 = repos, 0 = simul bouton ouverture)
#define CMD_NOT_CLOSING GPIO5 // SORTIE commande de fermeture logique
NEGATIVE (1 = repos, 0 = simul bouton fermeture)

// Etats de l'automate
typedef enum STATE {
 STOPPED,   // A l'arret (capote ouverte, fermée ou arrétée en cours de
cycle)
 MANUAL_OPENING,  // Ouverture en mode manuel
 MANUAL_CLOSING,  // Fermeture en mode manuel
 AUTO_OPENING,  // Début d'ouverture en mode auto après tempo et bouton
toujours appuyé
 AUTO_CLOSING,  // idem en fermeture
 FULL_AUTO,   // mode séquentiel entièrement automatique, les boutons sont
relachés
 WAIT_RELEASE  // mode séquentiel ou manuel stoppé en cours de route, attend
le relachement des boutons
} STATE;

// déclare les fonctions de chaque état
void stopped(void);
void manual_opening(void);
void manual_closing(void);
void auto_opening(void);
void auto_closing(void);
void full_auto(void);
void wait_release(void);

// Etat courant, à l'arret par défaut au boot
static volatile STATE state;

// Timeout d'appui pour passer en auto après X secondes
static volatile char timeout_auto;

// Programme principal
void main()
{
 // efface les flags de reset
 PCON = 0;
 // tous les ports sont des E/S numériques
 ANSEL = 0b00000000;
 // minimise la conso des ports analogiques inutilisés
 CMCON = 0b00000111;
 // les options (presacler timer 0 au maxi 1:256) weak pullup
 OPTION = 0b00000111;
 // Règle le sens des ports d'entrée/sorties
 TRISIO = 0b00001011;
 // Weak pull up
 WPU    = 0b00000011;

 // désactive les sorties
 CMD_BUZZER = 0;
 CMD_NOT_OPENING = 1;
 CMD_NOT_CLOSING = 1;

 // efface timeout
 timeout_auto = 0;
 // efface timer
 TMR0 = 0;

 // Etat par défaut au reset
 // on vérifie que les touches ne sont pas appuyées
 state = WAIT_RELEASE;

 // Boucle infinie
 while(1) {
  // efface chien de garde anti-plantage
  CLRWDT();

  // Effectue les actions suivant l'état de l'automate
  // uniquement quand le timer 0 déclenche pour limiter
  // la vitesse de traitement (et les rebonds intempestifs)

  // Le timer tourne à 1Mhz / 256 soit 3904Hz donc 195 = 20Hz
  if(TMR0 > 194) {
   // Reset du timer
   TMR0 = 0;
   switch(state)
   {
    case STOPPED:
     stopped();
     break;
    case MANUAL_OPENING:
     manual_opening();
     break;
    case MANUAL_CLOSING:
     manual_closing();
     break;
    case AUTO_OPENING:
     auto_opening();
     break;
    case AUTO_CLOSING:
     auto_closing();
     break;
    case FULL_AUTO:
     full_auto();
     break;
    case WAIT_RELEASE:
     wait_release();
     break;
   }
  }
 }
}

// A l'arret
void stopped()
{
 // Si on appuie sur ouverture ou fermeture (mais pas les 2 en même
temps...)
 if((OPEN_PUSHED || CLOSE_PUSHED) && !(OPEN_PUSHED && CLOSE_PUSHED)) {
  char closing;
  // reinitialise le timeout de passage en automatique
  timeout_auto = 0;
  // active la fermeture / ouverture
  closing = CLOSE_PUSHED;
  CMD_NOT_CLOSING = ! closing;
  CMD_NOT_OPENING =   closing;
  // change d'état et passe en manuel
  state = closing ? MANUAL_CLOSING : MANUAL_OPENING;
 }
}

// début de l'ouverture (en manuel)
void manual_opening()
{
 // bouton d'ouverture relaché
 if(! OPEN_PUSHED) {
  CMD_NOT_OPENING = 1; // stoppe la commande d'ouverture
  state = STOPPED;  // change d'état passe à l'arret
 }
 else {
  // ne passe pas en mode auto tant que la pompe n'a pas démarré
  // ou si elle s'arrete en cours de route en mode manuel (fin de séquence)
  if(PUMP_STOPPED) {
   if(timeout_auto > 0) {
    timeout_auto = 0;
    CMD_NOT_OPENING = 1; // stoppe la commande d'ouverture
    CMD_BUZZER=1;    // allume le buzzer
    state = WAIT_RELEASE; // attend que le bouton soit relaché
   }
  }
  else {
   // incrémente le timer du mode automatique
   // si le timer auto est arrivé au bout, on passe en auto
   if(timeout_auto++ >= AUTO_TIMEOUT) {
    CMD_BUZZER = 1; // active le buzzer
    state = AUTO_OPENING; // change d'état, passe en ouverture automatique
   }
  }
 }
}

// début de la fermeture (en manuel)
void manual_closing()
{
 // bouton de fermeture relaché
 if(! CLOSE_PUSHED) {
  CMD_NOT_CLOSING = 1; // stoppe la commande de fermeture
  state = STOPPED;  // change d'état passe à l'arret
 }
 else {
  // ne passe pas en mode auto tant que la pompe n'a pas démarré
  // ou si elle s'arrete en cours de route en mode manuel (fin de séquence)
  if(PUMP_STOPPED) {
   if(timeout_auto > 0) {
    timeout_auto = 0;
    CMD_NOT_CLOSING = 1; // stoppe la commande de fermeture
    CMD_BUZZER=1;    // allume le buzzer
    state = WAIT_RELEASE; // attend que le bouton soit relaché
   }
  }
  else {
   // incrémente le timer du mode automatique
   // si le timer auto est arrivé au bout, on passe en auto
   if(timeout_auto++ >= AUTO_TIMEOUT) {
    CMD_BUZZER = 1; // active le buzzer
    state = AUTO_CLOSING; // change d'état, passe en fermeture automatique
   }
  }
 }
}

// début du mode automatique, le bouton ouverture est toujours appuyé
void auto_opening()
{
 // abandonne le mode auto si la pompe s'arrete en cours de route (fin de
séquence)
 if(PUMP_STOPPED) {
  timeout_auto = 0;
  CMD_NOT_OPENING = 1; // stoppe la commande d'ouverture
  CMD_BUZZER = 1;   // stoppe le buzzer
  state = WAIT_RELEASE; // attend que le bouton soit relaché
 }
 else {
  // le bouton d'ouverture est relaché, on passe en mode full auto
  if(! OPEN_PUSHED) {
   CMD_BUZZER = 0; // stoppe le buzzer au relachement
   state = FULL_AUTO; // passe en état full auto
  }
 }
}

// début du mode automatique, le bouton fermeture est toujours appuyé
void auto_closing()
{
 if(PUMP_STOPPED) {
  timeout_auto = 0;
  CMD_NOT_CLOSING = 1; // stoppe la commande de fermeture
  CMD_BUZZER=1;    // allume le buzzer
  state = WAIT_RELEASE; // attend que le bouton soit relaché
 }
 else {
  // le bouton de fermeture est relaché, on passe en mode full auto
  if(! CLOSE_PUSHED) {
   CMD_BUZZER = 0; // stoppe le buzzer au relachement
   state = FULL_AUTO; // passe en état full auto
  }
 }
}

void full_auto()
{
 // stoppe la commande si la pompe ne tourne plus
 if(PUMP_STOPPED) {
  // cycle terminé normalement
  CMD_NOT_OPENING = 1; // stoppe la commande d'ouverture
  CMD_NOT_CLOSING = 1; // stoppe la commande de fermeture
  CMD_BUZZER = 0;   // stoppe le buzzer
  state = STOPPED;  // change d'état passe à l'arret
 }
 // stoppe en cours de route si un des boutons est appuyé
 else if(OPEN_PUSHED || CLOSE_PUSHED) {
  // stoppé en cours de route, met le buzzer en route
  CMD_NOT_OPENING = 1; // stoppe la commande d'ouverture
  CMD_NOT_CLOSING = 1; // stoppe la commande de fermeture
  CMD_BUZZER=1;    // allume le buzzer
  state = WAIT_RELEASE; // attend que le bouton soit relaché
 }
}

// abandon du mode auto en cours de route
// ou fin de cycle normal en manuel
void wait_release()
{
 // on attend que le bouton soit relaché pour repasser en mode stoppé
 if(! (OPEN_PUSHED || CLOSE_PUSHED)) {
  CMD_BUZZER=0;
  state = STOPPED; // passe en état stoppé
 }
}


Re: Formation aux PIC

snipped-for-privacy@g23g2000vbr.googlegroups.com...
Quoted text here. Click to load it


je pense qu'on ne peux pas généraliser
le mot 'assembleur'...

il y a les CISC et les RISC...

les CISC c'est intel ou mieux motorola (freescale)...
là ok ça se fait à la main, c'est plaisant...
j'en ai fait des centaines de lignes...

par contre les RISC des PIC, c'est absolument
imbitable... (même avec le super cours de bigonoff)

pour moi c'est obligatoire de faire du C sur
un PIC... et je ne vois pas le problème pour accéder
au moindre recoin du micro puisque tous les registres
sont déclarés en une ligne, par exemple :

#include "p18f452.h"

ensuite c'est quand même super facile d'écrire

PORTBbits.RB0 = 1 ;






Re: Formation aux PIC
Guillaume a écrit :
Quoted text here. Click to load it

Puisque le polémique tourne autour du langage utilisé, voici mon petit 1% :

je suis entré dans le monde des pic par l'assembleur (merci biggonof),
par ce que c'est le langage que j'avais appris à l'école (dans le temps...).
J'ai été tout a fait satisfait d'avoir ces compétences tant que je
restai aux pic16,
mais maintenant mes besoins m'obligent a passer aux pic18, et là il
faudrait plutôt que je connaisse le C, et a presque 40 balais et autre
chose a faire dans la journée ... apprendre un nouveau langage : bonjour
la galère !!!
(au passage, si quelqu'un connait un équivalent des cours de biggonof
pour le C : je suis preneur !)

Donc mon conseil : laisse tomber le basic et l'assembleur passe au C
tout de suite !

Laurent

Re: Formation aux PIC

Quoted text here. Click to load it

+1
comme il a été dit plus haut, à part quelques lignes très spécifiques en
asm, et encore
plusieurs compilos dispos avec forum, exemples etc...
j'utilise CCS ( http://www.ccsinfo.com )

Philippe

Re: Formation aux PIC


dans le message de groupe de discussion : 4ab2736f$0$15162$
Quoted text here. Click to load it

+1 (enfin +0.5)

Quelque connaissances en assembleur restent quand même utiles pour écrire de
petite routines hyper optimisée (surtout en ce qui concerne la gestion de
interruptions par exemple)

Maintenant moi, a mon avis C ou Basic ça n'a pas vraiment d'importance à ce
niveau. Avec un bon compilateur et si on ne code pas avec les pieds, que ce
soit écrit en C ou en Basic (je parle du basic dans sa version moderne)
donnera au final à peu prêt le même code assembleur. Donc jusqu'a preuve du
contraire, pour moi dire que l'un et plus optimisé que l'autre pour ce genre
d'application, c'est de la querelle de cloché et du trollage en règle. (on
parle bien de compilateurs pour le RISC des PICs et non pas de je ne sais
quelle connerie d'interpréteur embarqué)
Moi j'ai choisit le compilateur basic Proton+ parce qu'après en avoir essayé
plusieurs il me semblait le plus performant et le plus complet, avec une
philosophie de programmation proche de celle du VB  qui je connaissais déjà
bien (et non j'ai jamais eu besoin de faire de GOTO en VB, puisque c'est
visiblement ce que l'on reproche au Basic).

Maintenant je suis d'accord, quelqu'un qui n'a aucune connaissance
particulière en programmation et qui souhaite se lancer à tout intérêt à
partir sur le C, en ce qui concerne la programmation sur PIC, comme je l'ai
dis ça ne fait pas une énorme différence (on ne peut pas reprocher au C
d'être plus compliqué que le Basic pour ce genre d'application) et ce qui
sera acquis comme connaissance sur le PIC sera toujours utile et plus
universel pour programmer sur PC ou autre.


Re: Formation aux PIC
Moi, je trouve que la vraie mauvaise idE9%e dans cette histoire, c'est
le "PIC". D'abord de quel PIC parle-t-on : PIC 16 ? "assembleur facile
car seulement 35 instructions RISC E0% apprendre "??. "35 instructions"
signifie plutF4%t un jeu d'instructions trE8%s "pauvre" et avec plein de
piE8%ges. Bon exemples de Doumai : http://pagesperso-orange.fr/doumai/Assem =
bleur/Assembleur.htm
. Risc- SFB%rement pas. Lorsque la notion de "Risc" est apparue dans les
annE9%es 90, l'idE9%e E9%tait qu'un compilateur pouvait produire un code
plus efficace avec des jeux d'instructions rE9%duits bie adaptE9%s. Oui,
mais l'asm PIC16 est tout sauf adaptE9% aux compilateurs pour langages
de haut niveau. L'assembleur PIC 16 s'apparente plus E0% du microcode
qu'E0% un jeu d'instructions RISC.
Bref, choisissez d'abord un B5%C rE9%cent et performant et si vous voulez
commencer absolument en Basic, essayez Bascom pour AVR ou embrayez
directement vers le C (il n'y a pas besoin d'E9%crire du code en asm
pour les interruptions), et quasi tous les micros ont leur compilateur
C gratuit, ce qui n'est pas le cas du basic.

th. (GCC sur ColdFire)

Re: Formation aux PIC

Quoted text here. Click to load it
============
Le gros avantage du  "C" est l'usage des fonctions avec  passage et retour
d'arguments de valeur
Que l'on peu stocker  dans des fichiers " include "  et utiliser
universellement dans n'importe quel autre nouveau programme  (elles ne  se
compilent que si elles  peuvent etre  appelées par le programme "main")




Re: Formation aux PIC

Quoted text here. Click to load it

 N'importe quoi.
Il ne faut pas confondre E9%dition des liens et compilation.

--
-Stan

Re: Formation aux PIC

snipped-for-privacy@s6g2000vbp.googlegroups.com...

Quoted text here. Click to load it

 N'importe quoi.
Il ne faut pas confondre édition des liens et compilation.
==========
C'est toi le " n'importe quoi"  le nouveau programme compile forcement les
fichiers  include edités  "en clair"  et comme je l'ai dit , seulement les
fonctions  suceptibles d'etre utilisées





Re: Formation aux PIC
Quoted text here. Click to load it

Sans rentrer dans une polémique, les includes, c'est quand même fait pour
déclarer les prototypes des fonctions et les types mais pas pour y écrire du
code.

Même si en effet le compilo s'en fout complètement et ça ne le gène pas du
tout que le code soit dans les includes parce qu'en réalité il ne fait que
"merger" les .h avec les .c, rien n'empèche de mettre tout le code dedans,
et beaucoup de programmeurs, par facilité et moi le premier(j'ai pas dit
fainéantise :-) ) y mettent des fonctions dans des #define (c'est pas bien
non plus), dans des inline (mieux) ou carrément des fonctions complètes
(crado :-)) ).

Ca se fait d'ailleurs assez souvent de façon assez natuelle en c++ on a
tendance à laisser dans les .h les prototypes et aussi le code des méthodes
microscopiques (quelques lignes) et les méthodes inline, et les const mais
bon, si on veut faire proprement, c'est le code dans le .c et uniquement les
prototypes et déclarations de types dans les .h il ne doit rien avoir à
compiler qui "produise" du code autre que les glue d'appel aux
fonctions/méthodes externes. le mieux c'est de faire une ou plusieurs
librairie + des headers, dont les fonctiones ne sont linkées automatiquement
au programme final que si elles sont utilisées, c'est propre et
réutilisable, et on ne compile la lib que lorsqu'elle évolue et tous les
programmes en bénéficient (tant qu'on ne fait qu'ajouter de nouvelles
fonctiones sans changer les prototypes des fonctions existantes évidemment)
et moins il y a de code dans les .h, moins il y a de dépendances avec les
programmes qui s'en servent (dans une lib, il y a les .h "internes" juste
pour compiler la lib et les .h "interfaces" qui sont des .h simplifiés à
destination des clients de la librairie, sorte de contrat d'interface avec
le strict minimum).

bon si c'est pour faire un petit prog en C de quelques parges sur un µc, ça
change pas la face du monde si tout est dans 1 seul .c même sans include ou
si on mets quelques fonction dans des .h...

Pascal


Re: Formation aux PIC

Quoted text here. Click to load it
============
Mon outil de travail  procède de cette façon
../..
#include<stdlib.h>
#include<string.h>
#include<lcd_elcd.c>
#include<pcf8583.c>
../..
Les "fichiers include" <.... > certains compris dans la bibliothèque du
fournisseur ou élaborés  soi-même  sont écrit en code ( C ou ASM ou les
deux ) et sont compilés  en même temps que le nouveau programme,   par le
compilateur dont on sait bien sûr que c'est le travail du "près processeur"





Re: Formation aux PIC
Quoted text here. Click to load it

Normalement le lcd_elcd.c et pcf8583.c devraient être compilés à part
(ajoutés dans le projet ou bien en faire une lib) et donc générer un .o (ou
équivalent), il devrait y avoir un lcd_elcd.h et un pcf8583.h qui ne servent
qu'à déclarer les fct/types utilisés dans les .c et rien d'autre et c'est
l'édition des lien finale qui recompose le binaire définitif avec tous les
fichiers compilés .o

Mais comme j'ai dit, tel que tu le montres ça marche aussi, juste que c'est
pas élégant, c'est détourner la fonction de preprocesseur et c'est surtout
pas efficace chaque fois que tu changes 1 ligne de codes quelque part, il
faut tout recompiler, alors que si les .o sont recombinés à la fin (les .c
étant corrcetement déclarés dans un makefile ou dans le projet), seul le
fichier .c touché se recompile et pas les autres

Pascal


Re: Formation aux PIC

Quoted text here. Click to load it
================
C'est la façon  recommandée de procéder par le fabricant de l'outil de
développement,
la façon la plus simple.  les "fichiers include" , ( que l'on peut aussi
baptiser xxx.h  que xxx.c , ) sont stockés en code source, cela permet de
les modifier à loisir.
Il est possible bien sûr avec cet outil de compiler les fichiers sources ,
header et les autres , séparément mais je ne vois pas l'inélégance de
cliquer sur <make> pour compiler ou recompiler le tout . au final, le volume
est le même.
Après quoi le préprosesseur, c'est son rôle, les appelle pour générer le
code exécutable dans l'ordre ou " ils sont déclarés"

Rappelons que le sujet discuté  concerne la mise en oeuvre et la
programmation  c ou basic  "amateur" de  µC,  de peu souvent plus de 64 k,
le temps d'exécution de la recompilation de l'ensemble ne prend que quelques
secondes.
Et qu'en outre  ma réflexion de comparaison basic <=> C  sur le sujet [
n'etait que] ( le "C" bien pratique (entre autre)  à cause surtout du
principe des fonctions dont certaines universelles,  stockées (en clair)
dans un répertoire de réserve  et rappelables  très simplement par
l'instruction "#include"). c'est tout.




Re: Formation aux PIC
On Sep 21, 3:07 pm, "Pierre_Edouard" :

Quoted text here. Click to load it

Non : un fichier include est un ".H", pas un ".C"

Quoted text here. Click to load it

Non : un fichier include ".H" ne contient pas de code, mais
uniquement les prototypages des fonctions, et les definitions
des structures de donnees afin de pouvoir ensuite linker
l'ensemble des fichiers source et des librairies.

Quoted text here. Click to load it

Non : le travail du preprocesseur n'est pas de compiler,
mais de pre-processer le code source avant la compilation,
comme par exemple l'interpretation des macros via "#define".
La compilation est le job du compilateur, comme son nom l'indique.

Quoted text here. Click to load it

Non : la limite de 64Ko due aux 16 bits d'adresses est depassee depuis
longtemps.

Quoted text here. Click to load it

Non : dans le cas que tu cites, les fichiers d'include ne contiennent
que les declarations des fonctions et structures de donnees
necessaires
au compilateur puis au linker pour generer le code d'appel des
fonctions
predefinies, et celles-ci ne sont pas "en clair" mais pre-compilees
en code machine dans les fichiers objet de la librairie.


Re: Formation aux PIC
Quoted text here. Click to load it

Pas d'accord.
Le rF4%le de la directive "include"  est de charger un fichier c'est
tout.
Fichier qui sera analysE9% avant (d'oF9% le nom de fichier d'entEA%te) celu=
i
oF9% la directive est invoquE9%e.
Le reste n'est que convention ou habitude, mais dans la norme,
c'est son seul rF4%le.

Quoted text here. Click to load it

Ils sont mEA%me utiles avant le linkage, ,E0% la compilation, pour le
controle du typage .

--
-Stan





Re: Formation aux PIC
On Sep 25, 11:38A0%am, Stan :

Quoted text here. Click to load it



Je suis d'accord, et je ne dis pas le contraire.
Ne pas confondre la directive "#include" avec "fichier d'include".
Un fichier d'include pourrait tout aussi bien etre une table de
donnees.

Quoted text here. Click to load it

Agreed.



CQFD

Site Timeline