<< 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

19. La norme ISO 7816

Index coursIndex du cours
Chapitre précédent18. Astuces de programmation (suite)
Chapitre suivant19. La norme ISO 7816 (suite)

 

19. La norme ISO 7816

Le but de cette annexe est de vous montrer comment réaliser une application pratique en dépassant les limites apparentes de la PIC. J’ai choisi de créer l’ossature d’un programme de gestion d’une carte ISO7816, car c’est un sujet d’actualité.

De plus, c’est un excellent prétexte pour montrer qu’il est possible d’utiliser une 16F84, pourtant dépourvue de la gestion série, pour communiquer de cette manière avec le monde extérieur.

Cette annexe se limitera à la norme en général, sans entrer dans une application spécifique de cette norme. Le but n’est pas en effet de construire votre propre application (par exemple une serrure codée), mais plutôt de vous montrer comment la concevoir vous-même.

19.1 Spécificités utiles de la norme ISO 7816

Voyons tout d’abord quelques spécificités de la norme 7816 qui va nous servir à créer notre application.

Vous trouverez ces cartes partout dans le commerce de composants électroniques, sous la dénomination " carte pour serrure codée ". Elles permettent de réaliser des tas d’applications, et les lecteurs sont disponibles partout. Vous aurez besoin pour communiquer avec cette carte d’une interface dont vous trouverez le schéma sur Internet sous la dénomination " phœnix ", et d’un logiciel de communication ou du logiciel fourni avec l’interface.

  • La carte ne dispose pas de sa propre horloge, elle est fournie par l’interface, ou maître, et est généralement sous la barre des 4MHz.
  • Le temps séparant chaque bit est défini par la norme comme étant de 1 bit émis toutes les 372 impulsions de l’horloge du maître. Ceci donne un débit de l’ordre de 9600 bauds avec un quartz de 3,57 MHz.
  • La transmission est du type asynchrone, avec 1 start-bit, 8 bits de data, 1 bit de parité paire, et 2 stop-bits.
  • La communication est du type half-duplex, c’est à dire que les entrées et les sorties s’effectuent par alternance et en se servant de la même ligne physique.

19.1.1 Les commandes ISO 7816

Nous allons dans cet exercice utiliser des commandes " bidon " de la norme ISO7816. Il faut savoir que notre carte devra répondre à des commandes organisées suivant le protocole standard de cette norme.

La carte ne prend jamais l’initiative de l’échange d’informations. Elle ne fait que répondre à des commandes de la forme :

CLASSE INSTRUCTION PARAMETRE1 PARAMETRE2 LONGUEUR

Ou encore, sous forme abrégée :

CLASS INS P1 P2 LEN

Voici les significations de chacun des octets de la commande reçue :

  • CLASS : détermine le groupe d’instructions concernées. Si le nombre d’instructions utilisé n’est pas élevé, rien n’interdit de n’utiliser qu’une seule classe. C’est ce que nous ferons dans cet exercice simplifié.
  • INS : c’est l’instruction proprement dite, ou encore la commande. C’est cet octet qui détermine l’opération à effectuer par la carte.
  • P1 et P2 : sont 2 paramètres que la carte reçoit avec la commande. Leur signification dépend de la commande envoyée. Ils peuvent être inutilisés mais doivent tout de même être présents.
  • LEN : peut représenter 2 choses. Soit c’est le nombre d’octets qui suit la commande, dans ce cas la carte s’attendra à recevoir LEN octets supplémentaires avant de traiter la commande dans sa totalité. Soit ce sera la longueur de la chaîne de réponse que le maître s’attend à recevoir en provenance de la carte. C’est l’instruction qui permet d’établir le rôle de LEN.

19.1.2 Le protocole d’échange d’informations

Voici comment se déroule un échange standard d’informations entre le maître et la carte ISO 7816.

  • A la mise en service, le maître génère un RESET sur la pin MCLR, la carte répond avec un certain nombres d’octets. Cette réponse s’appelle ATR, pour Answer To Reset.
  • Le maître envoie la commande Class INS P1 P2 LEN
  • La carte renvoie l’instruction comme accusé de réception INS
  • Le maître envoie éventuellement les données complémentaires
  • La carte envoie la réponse
  • La carte envoie le status et repasse en mode d’attente de commande
19.2 Les liaisons série asynchrones

Pour comprendre la suite de ce chapitre, il faut comprendre ce qu’est une liaison série asynchrone.

Le mode série est défini pour signaler que tous les bits d’un octet vont être envoyés en série les uns derrière les autres. Ceci par opposition au mode parallèle pour lequel tous les bits sont envoyés en même temps, chacun sur un fil séparé.

Asynchrone est l’opposé de synchrone, c’est-à-dire qu’il s’agit d’une liaison qui ne fournit pas une horloge destinée à indiquer le début et la fin de chaque bit envoyé. Nous aurons donc besoin d’un mécanisme destiné à repérer la position de chaque bit. Notez qu’il s’agit ici d’un mode asynchrone particulier, étant donné que la carte utilise la même horloge que le maitre. La vitesse ne sera donc exeptionnellement pas donnée en bauds, mais en nombre d’impulsions d’horloge. Un bit toutes les 372 impulsions d’horloge.

Pour recevoir correctement les bits envoyés, il faut convenir d’un protocole de communication. Ce dernier doit comprendre les informations suivantes :

  • La vitesse de transmission en bauds
  • Le format, c’est à dire le nombre de start-bits, de stop-bits, de bits de données et le type de parité

Nous allons maintenant expliquer ces concepts et indiquer quelles sont les valeurs employées dans la norme ISO 7816.

19.2.1 Le start-bit

Au repos, la ligne se trouve à l’état haut. L’émetteur fait alors passer la ligne à l’état bas : c’est le start-bit. C’est ce changement de niveau qui va permettre de détecter le début de la réception des bits en série.

Les valeurs admissibles sont 1 ou 2 start-bit(s). La norme ISO 7816 nécessite un start-bit.

19.2.2 Les bits de donnée

Après avoir reçu le start-bit, on trouve les bits de données, en commençant par le bit 0. Les normes usuelles utilisent 7 ou 8 bits de data. Pour la norme ISO 7816, nous aurons 8 bits de donnée, ce qui nous donne des valeurs admissibles de 0 à 0xFF pour chaque octet reçu.

19.2.3 Le bit de parité

Le bit de parité est une vérification du bon déroulement du transfert. Lors de l’émission, on comptabilise chaque bit de donnée qui vaut 1. A la fin du comptage, on ajoute un bit à 1 ou à 0 de façon à obtenir un nombre de bits total impair ou pair.

On dira qu’on utilise une parité paire si le nombre de bits à 1 dans les bits de données et le dans bit de parité est un nombre pair.

De même, une parité impaire donnera un nombre impair de bits à 1.

Notez que le bit de parité n’est pas indispensable dans une liaison série asynchrone. Nous avons donc 3 possibilités, à savoir pas de parité, parité paire, ou parité impaire. Dans le cas de la norme ISO 7816, nous devrons utiliser une parité paire.

19.2.4 Le stop-bit

Après la réception des bits précédents, il est impératif de remettre la ligne à l’état haut pour pouvoir détecter le start-bit de l’octet suivant. C’est le rôle du stop-bit. Les valeurs admissibles sont de 1 ou 2 stop-bits.

Dans la norme ISO 7816, nous utiliserons 2 stop-bits, c’est à dire tout simplement un stop-bit d’une durée équivalente à la durée de 2 bits.

19.2.5 Vitesse et débit

La durée de chaque bit est une constante et dépend de la vitesse de transmission. Par exemple, pour une vitesse de 9600 bauds, c’est à dire 9600 bits par seconde, chaque bit durera 1s/9600 = 104,17 µS.

Le temps nécessaire pour recevoir un octet entier est la somme du temps nécessaire pour recevoir chacun des bits de cet octet. Dans le cas de la norme ISO 7816, nous utiliserons 1 start-bit + 8 bits de données + 1 bit de parité + 2 stop-bits = 12 bits. Le temps total pour recevoir un octet est donc de 1250 µS.

Le débit maximum en octets par seconde est donc égal à :

Débit maximum = 1 / (nbre de bits * durée d’un bit), soit pour la norme ISO 7816
1 / 1250 * 10-6 = 800 octets par seconde.

Nous parlons ici de débit maximum car ceci est le cas dans lequel un octet commence dès la fin du précédent, ce qui n’est pas obligatoire pour une liaison asynchrone.

19.3 Acquisition des bits

 

Nous allons d’abord représenter ce que nous venons de voir sous forme d’un graphique. Sur l’axe vertical nous avons les niveaux, sur l’axe horizontal, le temps. Chaque carré représente la durée d’un bit.

Examinons ce graphique. La ligne est à l’état haut depuis un temps indéterminé. Survient le start-bit, qui commence 2 carrés après notre axe vertical. Nous voyons que le meilleur moment pour lire le bit 0 est de le mesurer au milieu de sa largeur afin d’obtenir le moins de risque d’erreur possible.

Souvenez-vous que pour la norme ISO 7816, la largeur d’un bit vaut 372 impulsions d’horloge. Comme notre PIC divise déjà la fréquence d’horloge par 4, cela nous fera une largeur de bit équivalent à 372/4 = 93 impulsions d’horloge.

Le bit 0 sera donc lu 93 + 46 cycles d’horloge après le début du start-bit. Ensuite nous pourrons lire tous les bits à un intervalle de temps équivalent à 93 instructions.

Une fois le bit de parité lu, nous avons 2 possibilités :

  • Si nous souhaitons faire suivre cette lecture par la lecture d’un autre octet, nous devons nous positionner quelque part dans les 2 stop-bits afin d’être prêt à détecter le start-bit suivant. Nous devons donc attendre entre 0.5 et 2.5 bits.
  • Si nous souhaitons envoyer un octet après cette lecture, nous ne pourrons pas le faire avant la fin du second stop-bit, soit au minimum après 2.5 cycles.

Par curiosité, quel est donc l’octet que nous avons reçu dans cet exemple ? Et bien tout simplement :

B0 = 1
B1 = B2 = 0
B3 = 1
B4 = 0
B5 = 1
B6 = 0
B7 = 1
Parité = 0

L’octet reçu est donc B’10101001’ , soit 0xA9. Profitons-en pour vérifier la parité. Nombre de bits à 1 reçus = 4, donc parité paire, c’est donc conforme à la norme ISO 7816.

19.4 Caractéristique des cartes " standard "

Sur les cartes du commerce, de type "carte pour serrure codée" les connexions utilisées sont les suivantes :

Pin 4 MCLR Commande de reset de la carte Entrée
Pin 5 VSS Masse Alimentation
Pin 10 RB4 SDA – data pour eeprom externe (24C16) Bi-directionnel
Pin 11 RB5 SCL – horloge pour eeprom externe Sortie
Pin 13 RB7 DATA – données mode série half-duplex Bi-directionnel
Pin 14 VDD Alimentation +5V Alimentation
Pin 16 CLKIN Entrée de l’horloge externe Oscillateur

 

19.5 Création et initialisation du projet

Suivant note méthode habituelle, copiez / collez votre fichier " m16f84.asm " et renommez la copie " iso7816.asm ". Créez votre projet dans MPLAB. [ NDLR : Fichiers exemples ici ]

Ensuite, créez votre en-tête de programme :

;***********************************************************************
; Ce fichier est la base de départ pour la gestion d'une carte
; répondant à la norme ISO7816.
;
;***********************************************************************
;
; NOM: ISO7816
; Date: 10/03/2001
; Version: 1.0
; Circuit: Carte pour serrure codée
; Auteur: Bigonoff
;
;***********************************************************************
;
; Fichier requis: P16F84.inc
;
;***********************************************************************
;
; - MCLR Commande de reset de la carte Entrée
; - RB4 SDA - data pour eeprom externe Bi directionnel
; - RB5 SCL - horloge pour eeprom externe Sortie
; - RB7 DATA - données mode série Bi-directionnel
;
;***********************************************************************


Définissons la configuration : Nous n’allons pas utiliser le watch-dog pour cette application, et nous utiliserons une horloge externe. Nous aurons donc

  LIST p=16F84 ; Définition de processeur
  #include <p16F84.inc> ; Définitions des constantes
  __CONFIG _CP_OFF & _WDT_OFF & _PWRTE_ON & _HS_OSC
      ; Code protection OFF
; Timer reset sur power on en service
; Watch-dog hors service
; Oscillateur quartz grande vitesse

Calculons maintenant la valeur à encoder dans notre registre OPTION :

Nous devons utiliser, pour des raisons de compatibilité électronique, la résistance de rappel au +5V de la pin RB7. Nous aurons donc b7 du registre OPTION = 0. Ensuite, nous allons travailler avec le timer0. Comme l’écart entre 2 bits est de 93 instructions, nous travaillerons sans prédiviseur, ce qui nous impose de rediriger le prédiviseur vers le watchdog.

Définissons donc la valeur à placer dans OPTION :

OPTIONVAL EQU 0x08 ; Valeur registre option
      ; Résistance pull-up ON
; Préscaler timer à 1


19.6 La base de temps

Nous voyons déjà que nous allons avoir besoin de 2 temporisations : une de 93 instructions et une de 93+46 instructions, correspondant à 1 et 1,5 bits. Nous allons donc construire une sous-routine.

;*********************************************************************
; TEMPORISATION
;*********************************************************************
;--------------------------------------------------------------------------------------------------------
; temp_1bd: initialise tmr0 pour que la temporisation soit égale à
; l'équivalent d'un bit et demi, soit 46+93 incrémentations
; de tmr0 – le temps nécessaire pour arriver dans la routine
; temp_1b : Attend que l'écart entre la précédente tempo et la tempo
; actuelle soit de 1 bit, soit 93 instructions
;--------------------------------------------------------------------------------------------------------
temp_1bd      
  movlw -40 ; préparer valeur tmr0
  movwf TMR0 ; initialiser tmr0
  call temp_suite ; et attendre 1/2 bit
temp_1b      
  movlw -93 ; écart entre 2 bits
  addwf TMR0 , f ; ajouter à la valeur actuelle
temp_suite      
  bcf INTCON , T0IF ; effacer flag
temp_wait      
  btfss INTCON , T0IF ; attendre débordement timer
  goto temp_wait ; pas fini, attendre
  return   ; et sortir

Comment cette routine fonctionne-t-elle ? Et bien vous remarquez que vous avez 2 points d’entrée, temp_1bd et temp_1b. Commençons par examiner ce dernier point.

Nous commençons par charger la durée correspondant à 93 instructions avant le débordement du timer, soit 0 – 93, ou encore plus simplement –93. Il ne faut cependant pas oublier qu’un certain nombre d’instructions ont déjà été exécutées depuis le dernier passage dans la routine timer, lors de la réception ou l’émission du bit précédent.

Quel est le nombre de ces instructions ? Et bien tout simplement le nombre contenu dans TMR0, puisque le précédent passage avait attendu sa remise à 0. Il ne faut donc pas placer –93 dans tmr0, mais bien AJOUTER –93 au contenu actuel de TMR0.

De cette façon, nous sommes assurés que le débordement du TMR0 se fera exactement 93 cycles après le précédent débordement, quelque soit le nombre d’instructions exécuté entre les 2 appels. Ceci, bien entendu à condition que le timer n’ai pas débordé avant, mais ceci impliquerait que nous n’avons pas le temps de tout exécuter entre 2 bits, donc que la PIC n’est pas suffisamment rapide.

Tout de suite après, nous replaçons le flag T0IF à 0, et nous attendons simplement que le débordement du timer entraîne le repositionnement du flag.

Examinons maintenant le point d’entrée temp_1bd : Nous commençons par initialiser TMR0 avec –40, pour démarrer la temporisation de 40 instructions à partir de ce point. Comme c’est au début de l’acquisition que nous avons besoin d’un demi-bit, il n’y a pas eu de bit précédent, donc nous devons placer cette valeur et non faire une addition. De plus, entre la détection du start-bit et l’initialisation de TMR0, il s’est passé quelques instructions. On peut grossièrement considérer qu’il s’est passé 6 instructions, ce qui nous donne une valeur à charger de –(46 –6) = -40.

Quelle est en réalité notre marge d’erreur ? Et bien tout simplement la moitié de la durée d’un bit, c’est à dire 46 cycles, afin de ne pas tomber sur le bit contigu. Nous ne sommes donc pas à 1 cycle près, mais il faut rester le plus précis possible pour éviter une dérive de l’appareil connecté.

Ensuite nous appelons la sous-routine elle-même de façon à attendre la durée prévue, puis la sous-routine poursuit en exécutant la temporisation de 93 cycles. Nous avons donc attendu en tout 93 + 40 cycles, soit la durée de 1,5 bit. De plus cette sous-routine n’utilise aucune variable.

 

Index cours
Index du cours
Chapitre précédent
18. Astuces de programmation (suite)
Chapitre suivant
19. La norme ISO 7816 (suite)

 


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

Page http://fribotte.free.fr/bdtech/cours/pic16f84/PART1_cours19a.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