<< The Fribotte Homepage >>
Un club de passionnés en robotique participant à la coupe de France E=M6.
[Accueil] [Qui sommes-nous ?] [Robots] [Coupe e=m6] [BD Technique] [Forum] [Reportages] [Liens] [WiKiFri]

Fribotte

 

La Programmation des pics
par Bigonoff
Premiere partie - pic 16f84 - Révision 5

Téléchargement des fichiers originels ici
Publié le 27/02/2002

11. Réalisation d’un programme embarqué

Index coursIndex du cours
Chapitre précédent10. Les modes d’adressage
Chapitre suivant11. Réalisation d’un programme embarqué (Suite)

 

11. Réalisation d’un programme embarqué

On désigne généralement sous la dénomination " logiciel embarqué " un programme destiné à tourner localement sur une carte disposant d’un microcontroleur. Nous allons donc commencer la partie la plus amusante. Nous allons créer de petits programmes sur une carte à PIC.

11.1 Le matériel nécessaire

Utilisez une platine d’essais constituée de petits trous reliés ensemble par rangées. Les liaisons s’effectuent alors en fils volants. Vous trouverez ces platines chez tous les marchands d’électronique. Pour mettre ces leçons en pratique, il vous faudra le matériel suivant (récupérable et peu onéreux) :

  • 1 PIC 16F84 ou 16F84A en boîtier PDIP et de fréquence quelconque
  • 2 supports " tulipe " 18 pins / écartement entre les rangées : 0.3’’
  • 1 Quartz de 4MHz
  • 2 condensateurs de 27pF
  • 1 Led rouge
  • 1 Résistance de 330 ohms.
  • 1 bouton-poussoir " normalement ouvert " (N.O.)
  • 1 peu de fil rigide pour les connexions sur la platine d’essais
  • 1 alimentation stabilisée

Si vous ne disposez pas d’une alimentation de 5V, vous pouvez, soit utiliser une pile plate de 4.5V, soit réaliser une petite alimentation dont le schéma est donné page suivante.

Il vous faudra dans ce dernier cas :

  • 1 Bloc d’alimentation secteur de 9 à 15V, pas critique.
  • 1 Condensateur de 100µF/35V.
  • 1 Condensateur de 0.1 µF
  • 1 diode 1N4007, ou autre diode permettant un courant de 1A (pas critique)
  • 1 Régulateur de type 7805.

Cet ensemble ne vous ruinera pas. De plus, les composants pourront être récupérés pour vos prochaines applications. Vous verrez que les PICs peuvent être utilisées dans des tonnes d’applications au quotidien

11.2 Montage de la platine d’essais
  • Insérez la pic dans un des supports tulipe.
  • Insérez le support restant dans la platine d’essais, et procédez aux connexions suivant le schéma ci-joint.
  • Vérifiez tout avant de connecter l’alimentation.
  • Si vous n’avez pas d’alimentation stabilisée, utilisez une pile, ou connectez les composants suivant le schéma suivant.

Une fois tout ceci fait, vérifiez une dernière fois, sans placer la PIC avec son support dans le support de la platine, puis mettez sous tension. Vérifiez que les tensions sont correctes au niveau des broches d’alimentation de la PIC.

Vous êtes maintenant prêt à commencer les expérimentations.

Effectuez une copie de votre fichier m16F84.asm, et renommez cette copie Led_cli.asm. Lancez MPLAB et répondez " non " lorsqu’on vous demande si vous voulez charger Essai1.

Schéma de connexion de la PIC :

Schéma de la petite alimentation stabilisée :


11.3 Création du projet

Dans MPLAB, vous savez maintenant créer un projet. Créez donc le projet Led_cli dans votre répertoire de travail (project->new project). Si vous avez une fenêtre " untitled " à l’écran, fermez-la préalablement.

Editez le nœud, n’oubliez pas de cocher " Default radix : Dec ". Ajoutez ensuite le nœud " Led_cli.asm ". Vous êtes prêts à commencer.

N’oubliez pas bien sûr d’ouvrir votre fichier " Led_cli.asm " (" file->open ").De nouveau, ce fichier est disponible en annexe. [ NDLR : Fichiers exemples ici ]

11.4 Edition du fichier source

Complétez le cadre d’en-tête suivant votre désir. Je vous indique ci-dessous un exemple. Prenez l’habitude de toujours documenter vos programmes. Ce n’est pas un luxe, c’est impératif pour une maintenance efficace dans le temps.

;***************************************************************************
; PROGRAMME DE CLIGNOTEMENT D'UNE LED CONNECTEE SUR LE PORTA.2
; D'UNE PIC16F84. PROGRAMME D'ENTRAINEMENT AU FONCTIONNEMENT
; DES PICS.
;***************************************************************************
;
; NOM: LED-CLI
; Date: 09/02/2001
; Version: 1.0
; Circuit: Platine d'essais
; Auteur: Bigonoff
;
;***************************************************************************
;
; Fichier requis: P16F84.inc
;
;***************************************************************************
;
; Notes: Ce petit programme permet de faire clignoter une LED
; sur le port A.2 à une fréquence de 1Hz
; Ce programme fait partie de la leçon 6 des cours
;
;***************************************************************************

 

11.5 Choix de la configuration

Plus bas dans le fichier, vous trouverez ceci :

  __CONFIG _CP_OFF & _WDT_ON & _PWRTE_ON & _HS_OSC
 
; '__CONFIG' précise les paramètres encodés dans le processeur au moment de
; la programmation du processeur. Les définitions sont dans le fichier include.
; Voici les valeurs et leurs définitions :
 
; _CP_ON Code protection ON : impossible de relire
; _CP_OFF Code protection OFF
; _PWRTE_ON Timer reset sur power on en service
; _PWRTE_OFF Timer reset hors-service
; _WDT_ON Watch-dog en service
; _WDT_OFF Watch-dog hors service
; _LP_OSC Oscillateur quartz basse consommation
; _XT_OSC Oscillateur quartz moyenne vitesse ou externe
; _HS_OSC Oscillateur quartz grande vitesse
; _RC_OSC Oscillateur à réseau RC

J’ai inclus les commentaires dans le fichier de façon à ce qu’il soit plus rapidement modifiables sans devoir recourir au datasheet. Je vais donner un brin d’explication.

Remarquez qu’on effectue un AND (&) entre les différentes valeurs, les niveaux actifs sont donc des niveaux 0

Le premier paramètre précise si votre PIC sera protégée ou non contre la lecture à la fin de la programmation. Laissez ici ce paramètre sur " CP_OFF " = non protégée.

Le second paramètre précise si le " chien de garde " (watchdog) est mis ou non en service. Dans un premier temps, remplacez WDT_ON par WDT_OFF pour le mettre hors-service.

Ensuite, laissez PWRTE sur ON pour préciser que vous utilisez un reset " sécurisé ", donc avec un allongement du temps avant démarrage. Ceci vous met à l’abri des alimentations un peu lentes à démarrer. J’expliquerai ceci plus tard.

Enfin, vient le fonctionnement de l’oscillateur que vous allez utiliser. Le tableau 8-1 page 40 donne les valeurs recommandées en fonction des fréquences utilisées pour une PIC de 10MHz. Retenez que la valeur _HS_OSC convient pour les fréquences élevées, ce qui est notre cas, puisque nous utilisons la vitesse maximale de notre PIC.

Il est important de ne pas utiliser _RC_OSC si on utilise un quartz. Ce paramètre est réservé à un fonctionnement par réseau R/C tel que dessiné figure 8-7 page 41.

LE FAIT D’UTILISER LE PARAMETRE " RC " AVEC UNE HORLOGE EXTERNE PEUT ENTRAINER LA DESTRUCTION DE LA PIC.

Même, si en pratique, les PICs sont des composants très solides, évitez de vous tromper à ce niveau. Et voilà, vous connaissez parfaitement _Config. Vous avez maintenant la ligne suivante :

  __CONFIG _CP_OFF & _WDT_OFF & _PWRTE_ON & _HS_OSC

 

11.6 Le registre OPTION

Si vous regardez le tableau 4-2, vous constaterez que ce registre se trouve à l’adresse 0x81, donc dans la banque1. Dans les fichiers include de MPLAB, ce registre est déclaré avec le nom OPTION_REG. C’est donc ce nom que vous devrez utiliser. Nous allons le détailler ici. Ce registre est un registre de bits, c’est à dire que chaque bit a un rôle particulier.

Le tableau de la page 16 représente le contenu de ce registre :

b7 : RBPU 

Quand ce bit est mis à 0 (actif niveau bas en italique), une résistance de rappel au +5 volt est placée sur chaque pin du PORTB. Nous verrons dans cette leçon le fonctionnement du PORTB. Si vous regardez notre schéma, vous constaterez que le bouton-poussoir connecté sur RB2 place cette pin à la masse si on le presse.

Il n’existe aucune possibilité pour envoyer du +5V dans notre schéma. En validant cette option, la résistance interne force la pin RB2 à 1 lorsque le bouton n’est pas pressé. Notez que cette option valide les résistance sur toutes les pins du PORTB. Il n’est donc pas possible de choisir certaines résistances en particulier. De même cette fonction n’existe que pour le PORTB.

Vous constatez donc déjà que tous les ports ne sont pas identiques : il faut y penser au moment de la conception d’un circuit. Dans notre cas, nous mettrons donc les résistances en service avec b7 = 0

b6 : INTEDG

Donne, dans le cas où on utilise les interruptions sur RB0, le sens de déclenchement de l’interruption. Si b6 = 1, on a interruption si le niveau sur RB0 passe de 0 vers 1. Si b6 = 0, l’interruption s’effectuera lors de la transition de 1 vers 0.

Comme nous n’utilisons pas les interruptions dans cette leçon, nous pouvons laisser b6 = 0.

b5 : TOCS

Ce bit détermine le fonctionnement du timer0, que nous verrons bientôt. Retenez que le timer0 est incrémenté soit en fonction de l’horloge interne (synchronisé au programme) , dans ce cas b5 = 0, soit il compte les impulsions reçues sur la pin RA4, dans ce cas b5=1.

Comme ce dernier mode nécessite un circuit de génération de pulses externe, nous utiliserons pour le timer0 l’horloge interne, donc b5 = 0

b4 : TOSE

Donne, pour le cas ou le bit 5 serait 1, le sens de la transition qui détermine le comptage de tmr0. Si b4 = 1, on a comptage si le signal passe de 5V à 0V sur RA4, si on a b4 = 0, ce sera le contraire.

Comme nous avons placé b5=0, b4 est alors inutilisé. Nous laisserons donc b4 = 0.

b3 : PSA 

Nous avons dans la PIC un prédiviseur. Qu’est-ce que c’est ? Et bien tout simplement, ceci indique le nombre de pulses qui devra être reçu pour provoquer une incrémentation de la destination. Nous y reviendrons en détail avec le fonctionnement du tmr0.

A ce niveau, sachez simplement que ce prédiviseur peut servir à une des deux fonctions suivantes (et pas les deux) : soit il effectue une prédivision au niveau du timer du watchdog (b3 = 1), soit il effectue une prédivision au niveau du tmr0 (timer0) (b3=0). Dans notre cas, mettez b3 = 1 (nous verrons ci-dessous pourquoi).

b2, b1,b0 : PS2,PS1,PS0

Ces trois bits déterminent la valeur de prédivision pour le registre déterminé ci-dessus. Il y a donc 8 valeurs possibles, montrées dans le petit tableau de la page 16.

Remarquez que les valeurs sont différentes pour le watchdog et pour tmr0. En effet, il n’y a pas de ‘division  par 1’ pour ce dernier registre.

Si vous désirez ne pas utiliser de prédiviseur du tout, la seule méthode est de mettre b3=1 (prédiviseur sur watchdog) et PS2 à PS0 à 0. Dans ce cas : pas de prédiviseur sur tmr0, et prédiviseur à 1 sur watchdog, ce qui correspond à pas de prédiviseur non plus. Nous mettrons donc b2=b1=b0= 0.

11.7 Edition du programme

Voilà encore un registre vu. Nous utiliserons donc la valeur B’00001000’ pour notre programme, soit 0x08. J’ai l’habitude de ne pas traîner des valeurs fixes à travers mes programmes, afin d’en faciliter la maintenance. Je place ces valeurs en début de programme en utilisant des assignations.

L’assignation est déjà créée plus bas dans le programme. J’ai créé une CONSTANTE que j’ai appelé OPTIONVAL et qui contiendra la valeur à placer plus tard dans le registre OPTION_REG. Je rappelle que les CONSTANTES n’occupent pas de place dans la PIC, elles sont simplement remplacées par l’assembleur au moment de la compilation. Elles servent à faciliter la lecture du programme.

Cherchez donc plus bas dans le programme après les assignations, et remplacez la valeur affectée à OPTIONVAL par celle que nous avons trouvée et ajoutez vos commentaires. Supprimez l’assignation concernant INTERMASK, car nous ne nous servirons pas des interruptions dans ce premier programme. Dans la zone des assignations, il vous reste donc ceci :

;*********************************************************************
; ASSIGNATIONS
;*********************************************************************
       
OPTIONVAL EQU H'0008 ; Valeur registre option
      ; Résistance pull-up ON
      ; Pas de préscaler

Descendons encore jusqu'à la zone des définitions. Nous allons donner un nom à notre bouton-poussoir et à notre LED. Les instructions bcf et bsf que nous allons utiliser pour mettre ou lire des 1 ou des 0 dans les registres ont la syntaxe suivante  bsf f , n et comme le registre d’accès s’appelant PORTA (pour le port A) et PORTB (pour le port B), nous utiliserons des DEFINE permettant d’intégrer f et n en même temps.

Nous voyons sur le schéma que la LED est connectée sur le bit 2 du port A. Le bouton-poussoir est connecté sur le bit 2 du port B. Nous effaçons donc les définition d’exemple, et nous les remplaçons par les nôtres. Nous obtenons alors ceci :

;*********************************************************************
; DEFINE
;*********************************************************************
               
#DEFINE LED PORTA, 2 ; Led rouge
#DEFINE BOUTON PORTB, 2 ; bouton-poussoir

Notez que LED et BOUTON sont des noms que nous avons librement choisis, à condition qu’il ne s’agisse pas d’un mot-clé. Pas question par exemple d’utiliser STATUS ou encore MOVLW, bien que ces exemples soient tirés par les cheveux, cela pourrait vous arriver un jour d’utiliser un mot réservé par inadvertance.

A quoi servent les définitions ? Et bien supposons que vous décidez de connecter la LED sur le PORTB bit 1 (RB1), par exemple. Et bien, nul besoin de rechercher partout dans le programme, il suffira de changer dans la zone DEFINE.

On descend encore un peu, et on arrive dans la zone des macros. Nous n’en avons pas vraiment besoin ici, mais nous allons quand même les utiliser à titre d’exemple.

Effacez la macro donnée à titre d’exemple et entrons celles-ci :

;*********************************************************************
; MACRO
;*********************************************************************
               
LEDON macro    
  bsf LED  
  endm    
       
LEDOFF macro    
  bcf LED  
  endm    

La première colonne donne le nom de la macro (ici, 2 macros, une LEDON et une LEDOFF). La directive macro signifie ‘début de la macro’ la directive endm signifie ‘fin de la macro’. Notez que les macros peuvent évidemment comporter plusieurs lignes de code.

Prenons notre exemple : quand nous utiliserons la ligne suivante dans notre programme (attention, ne pas mettre la macro en première colonne) :

  LEDON    

Au moment de la compilation, notre assembleur remplacera LEDON par :

  bsf LED  

Il remplacera également LED par PORTA,2. Ce qui fait qu’en réalité nous obtiendrons :

  bsf PORTA, 2  

Nous avons donc obtenu une facilité d’écriture et de maintenance. Gardez à l’esprit que les macros sont des simples substitution de traitement de texte. Si votre macro se compose de 50 lignes de code, les 50 lignes seront copiées dans la PIC à chaque appel de la macro.

Nous arrivons dans la zone des variables. Nous ajouterons celles-ci au fur et à mesure de leur nécessité. Effacez donc les 2 variables présentes, car elles sont utilisées dans les routines d’interruption que nous n’utiliserons pas ici.

;*********************************************************************
; DECLARATIONS DE VARIABLES
;*********************************************************************
       
  CBLOCK 0x00C ; début de la zone variables
       
  ENDC   ; Fin de la zone

A l’ORG 0x00, laissons l’appel vers la routine d’initialisation. Tout programme comporte en effet une étape d’initialisation des variables et des registres. Prenez l’habitude de séparer cette initialisation du reste du programme.

Comme nous n’utiliserons pas les interruptions, supprimez tout ce qui suit jusqu’à la routine d’initialisation, vous obtenez :

;*********************************************************************
; DEMARRAGE SUR RESET
;*********************************************************************
       
  org 0x000 ; Adresse de départ après reset
  goto init ; Adresse 0: initialiser
       
;*********************************************************************
; INITIALISATIONS
;*********************************************************************

suite du programme

A ce stade, avant de poursuivre, nous allons étudier les registres dont nous allons nous servir, et tout d’abord :

11.8 Le registre PORTA

Ce registre est un peu particulier, puisqu’il donne directement accès au monde extérieur. C’est en effet ce registre qui représente l’image des pins RA0 à RA4, soit 5 pins. Si vous suivez toujours, c’est ce registre qui va servir à allumer la LED.

Ce registre se situe à l’adresse 05H, dans la banque0. Chaque bit de ce registre représente une pin. Donc, seuls 5 bits sont utilisés. Pour écrire sur une pin en sortie, on place le bit correspondant à 1 ou à 0, selon le niveau souhaité.

Par exemple :

  bsf PORTA, 1 ; envoyer niveau 1 sur RA1

place un niveau +5V sur la pin RA1. Notez qu’il faut pour cela que cette pin soit configurée en sortie (voir TRISA). Pour tester une entrée, on pourra par exemple utiliser :

  bsfss PORTA, 3 ; tester RA3 et sauter si vaut 5V

Pour les électroniciens, vous avez le schéma interne des bits RA0 à RA3 figure 5-1 page 21. Vous voyez que la sortie peut être placée au niveau haut ou bas grâce aux deux transistors de sortie (montage push-pull). Quand ces pins sont programmées en entrées, elles sont sensibles à des niveaux TTL.

Pour la pin RA4, figure 5-2, en sortie elle est de type drain ouvert, et en entrée elle comporte un trigger de Schmitt.

Les PORTS disposent d’une diode de protection vers le 0V et vers le 5V. De sorte qu’avec une simple résistance série, vous pouvez envoyer des signaux vers ces pins qui sortent de la gamme de tension TTL. La pin RA4 fait exception à cette règle, car elle dispose que d’une diode vers la masse.

Pour tous, retenez que les pins RA0 à RA3 peuvent être utilisées en entrée avec des niveaux 0/5V ou en sortie en envoyant du 0V ou du 5V. Quand à la pin RA4, en sortie, elle ne peut pas envoyer du 5V.

Elle ne peut que mettre la sortie " en l’air " sur niveau 1 et la forcer à la masse sur niveau 0. En entrée, elle comporte un dispositif permettant d’empêcher les hésitations lorsque le niveau présenté n’est pas franc. Par exemple lorsque le niveau varie lentement de 0V à 5V.

Tenez compte de ces spécificités lorsque vous construirez votre montage. Par exemple, si nous avions placé la LED telle quelle sur RA4, elle ne se serait jamais allumée.

A partir de la page 75, chapitre 11, vous avez les caractéristiques max de fonctionnement de la pic. Vous pouvez retenir simplement de vous limitez à utiliser 20mA maximum par pin de sortie, avec un maximum total de 80mA pour le PORTA, et 150mA pour le PORTB.

Si vous utilisez des caractéristiques proches de cette limite, analysez les tableaux avec plus de précision pour obtenir les limites en puissance et t°. Nous n’aurons pas ce genre de problème dans nos exercices. La consommation de notre LED sur RA2 répond à la formule suivante :

Intensité : (5V – Tension Led) / 330 ohms, soit (5V – 1,75V) / 330 ohms = 9,85mA.

11.8.1 Fonctionnement particulier des PORTS

Les PORTS fonctionnent toujours sur le principe lecture->modification->écriture.

Par exemple, si vous écrivez bsf PORTA,1, la PIC procède de la manière suivante :

  1. La totalité du PORTA est lu (même les bits en sortie)
  2. Le bit 1 est mis à 1
  3. La totalité du PORTA est réécrit.

Conséquences

supposons par exemple que le RA4 soit en sortie et mis à 1. Comme il est à drain ouvert, supposons qu’une électronique externe le force actuellement à 0.

Si vous effectuez l’opération suivante :

  bsf PORTA, 1 ; mettre RA1 à 1

Lorsque le PORTA va être lu, RA4 sera lu comme 0, bien qu’il soit à 1. RA1 sera forcé à 1, et le tout sera replacé dans PORTA. RA4 est donc maintenant à 0, sans que vous l’ayez modifié.

C’est vrai que ce type de cas n’est pas courant, mais il est bon de le savoir, si un jour une de vos interfaces vous pose problème, et si vous avez l’impression que vos pins en sortie changent de niveau sans que vous le désiriez.

Pour les non-électroniciens, ne paniquez pas, car, de toute façon, vous ne réaliserez sans doute jamais une interface qui pose ce type de problème. Je tenais cependant à être exhaustif.

11.9 Le registre TRISA

Ce registre est situé à la même adresse que PORTA, mais dans la banque 1. Son adresse complète sur 8 bits est donc 0x85.

Ce registre est d’un fonctionnement très simple et est lié au fonctionnement du PORTA.

Chaque bit positionné à 1 configure la pin correspondante en entrée. Chaque bit à 0 configure la pin en sortie.

Au reset de la PIC, toutes les pins sont mises en entrée, afin de ne pas envoyer des signaux non désirés sur les pins. Les bits de TRISA seront donc mis à 1 lors de chaque reset.

Notez également que, comme il n’y a que 5 pins utilisées sur le PORTA, seuls 5 bits (b0/b4) seront utilisés sur TRISA.

Exemple d’utilisation

Prenons en exemple le schéma de notre petit circuit : que devons-nous faire pour allumer la LED ?

PS : ne mettez pas pour l’instant ces instructions dans votre projet.

Premièrement, nous devons configurer TRISA et mettre le bit2 (RA2) en sortie.

Comme le registre TRISA se trouve en banque1, et que l’adressage DIRECT n’utilise que 7 bits, nous devrons donc commuter le bit RP0 du registre STATUS (voir chapitres précédents).

Ensuite, nous pourrons envoyer un niveau ‘1’ sur PORTA, correspondant à 5V sur la pin RA2. La séquence correcte sera donc :

  bsf STATUS , RP0 ; on passe en banque 1
  bcf TRISA , 2 ; bit 2 de TRISA à 0 = sortie pour RA2
  bcf STATUS , RP0 ; on repasse en banque 0
  bsf PORTA , 2 ; on envoie 5V sur RA2 : la LED s’allume
  xxx    
  xxx    
  xxx    
  bcf PORTA , 2 ; 0V sur RA2, la LED s’éteint

Notez que comme RA2 restera en sortie durant tout le programme (dépend du schéma), nous placerons la valeur de TRISA dans la routine d’initialisation. Quand nous voudrons allumer ou éteindre la LED dans le programme principal, nous n’auront donc plus qu’une seule instruction à utiliser. On commence à entrer dans le concret .

11.10 Les registres PORTB et TRISB

Ces registres fonctionnent exactement de la même manière que PORTA et TRISA, mais concernent bien entendu les 8 pins RB. Tous les bits sont donc utilisés dans ce cas.

Voyons maintenant les particularités du PORTB. Nous en avons déjà vu une, puisque les entrées du PORTB peuvent être connectées à une résistance de rappel au +5V de manière interne.

La sélection s’effectuant par le bit 7 du registre OPTION. Le schéma interne visible figures 5-3 et 5-4 page 23 vous montre que les bits b0 et b4/b7 peuvent être utilisés comme source d’interruption, le bit 0 peut de plus être utilisé de manière autonome pour générer un autre type d’interruption.

Nous verrons le fonctionnement des interruptions dans un autre chapitre. Sachez cependant déjà que les schémas que vous concevrez vous-même dans le futur devront tenir compte des particularités des PORTs.

Note :

Après un reset, vous vous demandez peut-être quel est l’état de tel ou tel registre.

Vous trouverez ces explications dans le tableau de la page 14. Vous voyez qu’après un reset, le registre OPTION_REG a tous ses bits à 1. Vous devez donc spécifier l’effacement du bit7 pour valider les résistances de rappel au +5V.
 

 

Index cours
Index du cours
Chapitre précédent
10. Les modes d’adressage
Chapitre suivant
11. Réalisation d’un programme embarqué (Suite)

 


Complétez cette page, posez vos questions et remarques ici : WiKiFri

Page http://fribotte.free.fr/bdtech/cours/pic16f84/PART1_cours11a.html modifiée le 14/10/2002.
Copyright fribotte@free.fr, libre de droit pour toute utilisation non commerciale.
Reproduction autorisée par simple mail