CLCLAVIER3AVIER PC AT et PIC 16F877A

1 Historique
2 La partie Hardware (matériel)
3 La partie logiciel
4 Le principe même
5 Les limitations nécessitées
6 Quelques détails du logiciel
6.1 La partie driver NON interruptible
6.2 Le driver interruptible
6.3 Tables de conversion et corbeilles
6.4 Le tableau EXCEL des SCAN Codes

7 La mise au point
8 Conclusions

Si vous arrivez directement sur cette page par un moteur de recherche, vous pouvez avoir accès à la table des matières et à chaque article, en page d'accueil.    L'accès se fait par l'un des deux liens en tête de colonne de droite ----->


Préambule

J'ai passé tellement de temps sur cette connexion, que j'ai décidé d'en faire un article séparé du projet initial. En effet le raccordement de ce clavier PC AT n'est qu'une partie d'un ensemble plus important qui est un Datalogger à base d'un PIC 16F877A.
Pour une application clavier seulement, il n'est pas nécessaire d'utiliser un PIC 16F877A, car un PIC 16F628 devrait largement convenir (voir en conclusions).
L'article à venir sur le Datalogger aurait été trop long à cause de ce sujet nécessairement développé, vu les difficultés rencontrées.

Vous retrouverez dans le courant de l'année 2010, l'article sur le Datalogger, dont les caractéristiques principales sont : 5 entrées analogiques avec CAN 10 bits, 5 entrées logiques, une entrée mesure de temps et une entrée comptage rapide à 65000, communications radio avec base séparée, liaison RS232 avec le PC, mise à l'heure automatique sur DCF77, clavier PC, display, buzzer, paramétrage des modalités et priorités de mesures (à l'aide du clavier naturellement, puisque c'est l'objet de cet article) avec commutation des tensions d'alimentation des 5 sondes analogiques, pour un équipement alimenté par 7 batteries R6 NiMH.

J'ai encore à cette occasion, eu le loisir de bien m'imprégner des subtilités des adressages des PIC avec les BANK, les PAGES et les GOTO calculés, et y compris les CALL…Au passage encore merci à BIGONOFF pour sa référence sur le 16F84 que je consulte encore parfois, mais de préférence maintenant surtout les datasheets des PIC utilisés.
Je suis de plus en plus étonné des possibilités impressionnantes de ces petits µ contrôleurs, et ce sont réellement de petites merveilles de possibilités mais aussi de complexité et de savoir faire.

Vous aurez également compris que ces claviers sont eux-mêmes déjà très certainement équipés de microcontrôleurs équivalents à des PIC. Initialement avant cette arrivée des microcontrôleurs, les claviers étaient équipés de microprocesseurs de genre 8031 ou 8048. Ils consommaient certainement un peu plus.

1 Historique

Un clavier trouvé au bord du chemin, dans l'herbe, destiné au ramassage des "monstres", dont le câble avait été coupé à ras a excité ma curiosité. (Je regrette la démarche qui est rigoureusement la traduction de : "je casse pour que tu ne puisses pas réutiliser" !)
Alors, après l'avoir nettoyé, je suis parti à la recherche des fils à connecter…(voir § ci-après) et en espérant qu'il fonctionne encore, mais c'était effectivement le cas !

J'ai débuté l'étude du sujet "clavier" sur la base de l'excellent article de présentation d'Olivier DARTOIS sur le clavier du PC AT, tant pour la recherche des éléments de connexion que pour élaborer ma structure de programme. .(  http://www.ac-limoges.fr/sti_ge/IMG/pdf/Clavier_PC_gere_par_un_PIC.pdf )

J'aurais bien aimé pouvoir tout reprendre tel quel, mais ça n'a pas été possible, car des différences importantes existent entre les projets, mais avoir les éléments de base était déjà un important chemin. Voici les grandes lignes de mon contexte nécessaire :

* Programme obligatoirement INTERRUPTIBLE
* Programme en assembleur seulement et en adressage absolu
* Clavier AZERTY Français
* Occupation mémoire minimum
* Limitation aux touches à un seul "MAKE" de SCAN code
* Toutes valeurs ASCII de touches cependant disponibles

2 La partie Hardware (matériCLAVIER5el)

Le clavier lui même est constitué d'un "mille feuilles" de différentes nature : métal, circuits imprimés souples argentés, ventouses caoutchouc, plastiques isolants, cabochons de touches etc...sans oublier un circuit imprimé traditionnel simple face comportant un condensateur, un connecteur miniature à 4 fils, 3 LED et je crois au verso un circuit intégré en bounding.

Le clavier sera donc en connexion directe sur le PORT B d'un PIC 16F877A. On peut regretter mon choix initial d'avoir affecté les signaux clavier sur la partie des 4 bits générant les interruptions sur changement d'état de l'un d'eux. (RB4 à RB7)

Cela n'est finalement pas trop important mais complique un peu la partie interruptible par la recherche du front négatif ET de l'entrée parmi 4 ayant changé d'état. Ce n'est en soi pas trop grave, aussi j'ai laissé ainsi.
Parallèlement ce choix hardware discutable favorise le Datalogger  avec l'entrée RB0  disponible pour la mesure ! Alors finalement ça ira ...!

Le seul impératif est d'avoir une interruption sur le signal d'horloge du clavier. Il est inutile et même gênant d'avoir aussi une interrupt sur le signal DATA (comme c'est mon cas, puisqu'elle ne servira à rien qu'à prendre un peu plus de temps d'analyse)
Le nec plus ultra aurait été d'utiliser l'interrupt unique du RB0 pour le signal d'horloge. Il aurait alors même été  possible de choisir directement le front négatif nécessaire par OPTION_REG, INTEDG Bit6.

Il faut maintenant commencer par retrouver les liaisons existCLAVIER4antes sans l'aide du bout CLAVIER6de fil coupé sauvagement à la pince coupante à ras du clavier. Pour ce faire le plus important est de retrouver les fils d'alimentation ! Il faut ouvrir le clavier en jouant sur les clips ou dévisser…Il y a tellement de variantes en ce domaine que je ne peux pas préciser les modalités de démontage. (En général, maintenant, toutes les touches des claviers ne vous sautent plus à la figure lors du démontage…)

Pour repérer les fils d'alimentation, il y a toujours un condensateur électrochimique, ayant ses repères de polarité.

Le MOINS du chimique devrait se retrouver sur le fil de masse, et le PLUS devra aller au +5 CLAVIER8Volts !
Il faut ensuite alimenter le clavier suivant ce qui vient d'être dit.
A l'oscilloscope, on différentiera facilement le signal d'horloge par sa régularité lors de l'appui sur n'importe quelle touche. A l'inverse le signal DATA correspondra aux codes de touches et sera variable suivant les touches.
On réalise ensuite les connexions suivant le schéma de brochage de O. DARTOIS.

Le clavier peut donc être maintenant raccordé directement au montage. Vous choisirez le type de prise qui vous convient le mieux, à savoir l'embase DIN 5 broches, comme anciennement en HIFI et que l'on trouve facilement chez les revendeurs ainsi que sur les premiers PC, ou la Mini-DIN comme sur les ordis de la génération suivante. (Je ne parle pas des claviers USB).

J'ai indiqué le brochage sur la photo, car les inscriptions sont très petites, mais elles existent ! Aujourd'hui, les inscriptions de numéro "du made in China" n'existent même plus sur les prises et c'est encore plus simple !

Un clavier PC AT tel que celui sur la photo consomme sous +5 Volts 0.92mA (soit 920 µA) en régime établi sans appui de touche, avec une petite pointe de courant au démaCLAVIER1rrage de quelques mA pour assurer la charge du condensateur et le test des LED.
C'est réellement très très peu, et je ne vois même pas la nécessité de le couper, même en fonctionnement sur batterie, vu que la puissance est de 5 mW (5/1000 de WATT pour les profanes). Le régulateur de tension LM317L réclame, de mémoire, # 5 mA au minimum pour réguler correctement.

Le schéma simplifié de raccordement au PIC est le suivant. Ce schéma est utile pour comprendre le programme. Ce schéma reste quelque chose de très simple, et j'irai même jusqu'à dire de rudimentaire, car c'est de la connexion directe sans autre artifice.
Je recommande cependant une résistance de forte valeur de l'ordre de 1 Mohm (à voir au VCC ou à la masse) pour fixer le potentiel des entrées clock et data en l'absence de clavier.

Un schéma d'ensemble complet fera partie de l'article du Datalogger. (Il manque ici la partie display)

3 La partie logiciel

Mon article concerne le clavier Français AZERTY avec son programme en assembleur qui est constitué d'un driver NON-INTERRUPTIBLE (dans la séquence de réponse aux interruptions en adresse 4), et d'une partie transcodage, INTERRUPTIBLE cette fois. (Il ne sera pas difficile de passer à un autre clavier QWERTY par exemple, très répandu chez les Anglophones)

Cette structure doit permettre d'assurer le paramétrage initial du Datalogger, mais doit aussi sans aucune boucle de surveillance supplémentaire, pouvoir répondre à un appel opérateur. C'est donc dans ce cas le mode interruptible qui s'impose.

Le logiciel est constitué de 2 modules distincts et liés par 2 octets de contrôle.
Cette structure double est aussi le résultat de la nécessité de ne garder sous contrôle des interruptions que le strict nécessaire. En effet, la précision des mesures réclame que le système ne soit pas perturbé au niveau temps, et il est donc hors de question de perdre des cycles d'horloge temps réel (TIMER 0) dont le réveil survient à chaque report de 256 sur le compteur Timer 0.
Dans le contexte, il ne faut pas passer plus de 5 mS dans la boucle d'interruption. Une possibilité à 2.5 mS est également disponible pour l'horloge temps réel, et là cela représente 2 à 3 caractères MAKE de temps, soit très très juste !

La priorité des interruptions est donc organisée en premier lieu avec l'horloge temps réel prioritaire dans la pyramide d'analyse des interrupts. Même avec un cycle d'instruction de 200 nS, il faut être prudent dans l'empilage des temps, et cela surtout avec les displays à cristaux liquides qui ont besoin de beaucoup de temps pour se rafraîchir…

Il semble délicat de les inclure à chaque caractère, mais à priori en fin de saisie. Ce sera certainement un peu laborieux de taper sans la vision directe de ce que l'on fait, mais c'est un autre sujet !

4 Le principe même

Le principe du clavier PC AT est réellement délicat à "empoigner" en termes d'analyse, et je m'en explique.
Le fait d'avoir la généralisation d'un type de fonctionnement identique pour toutes les touches peut sembler intéressant, mais cela est plus gênant qu'il n'y parait, au niveau programmation temps réel.
En effet certaines touches sont des commandes seulement, alors que d'autres sont exclusivement des données, alors cela va compliquer un peu.

Un autre principe intéressant cette fois, est d'avoir retenu des codes géographiques de touches (SCAN codes). Cela permet de faire par logiciel la conversion de disposition due aux langues diverses et de disposer d'une structure hardware unique (cabochons de touches exceptés) pour tous les claviers du monde AZERTY, QWERTY, KANA, QWERTZ…etc.

Le principe global très bien documenté par O. DARTOIS (voir son article) est d'envoyer un (ou plusieurs) codes de touche (SCAN Codes) à l'appui (MAKE), puis d'envoyer un (ou plusieurs) codes de relâché de touche (BREAK) suivi du même octet MAKE.
Ce principe permet la "frappe coulée" très rapide, dans laquelle on peut avoir plusieurs touches appuyées à un même instant.
Ce principe permet aussi de connaître l'état des touches de fonction (SHIFT, CTRL etc…) Ceci permet aussi l'envoi en "repeat" du SCAN code MAKE.
On verra à la mise au point, que le problème du "repeat" est gênant, car ce sont des caractères (provisoirement) sans BREAK code. Le BREAK surviendra seulement au relâché de touche.
Ceci est encore plus pénible pour les touches fonctions et quasiment délicat pour la touche CAPS, qui est une bascule.
(Pour la touche CAPS, un repeat non contrôlé en termes de temps d'appui pourra donc s'inverser plusieurs fois sans qu'on le sache ! C'est le prix de la très grande compatibilité de timing. Mais il faut aussi être sérieux, car appuyer une heure de temps sur la touche CAPS n'est pas très "fut fut")

Le grand problème issu de ces quelques lignes d'explications devient encore plus complexe lorsque l'on aura dit que certaine touches géographiques envoient non pas 2 octets lors du BREAK, mais 3 (et parfois de plus grands nombres) !
Imaginez donc, vous demandez 1 caractère et vous en recevez au minimum 3 et parfois beaucoup plus !
Naturellement on peut tout faire, mais avec un PC, il y a de la mémoire en Méga Octets et encore plus de vitesse, mais avec un PIC, la mémoire (vive) se compte en quelques dizaines d'octets !

C'est pourquoi, j'ai décidé de me limiter volontairement tout en ne perdant pas les possibilités des caractères représentés. Une seule exception qui peut très facilement être corrigée, est le caractère EURO (€) qui est en fonction ALT_Gr (CTRL+ALT), qui n'apparaît pas sur le display et qui de surcroît dans une application technique est inutile. Alors je l'ai tout bonnement sacrifié sur l'autel de l'oubli !
(Il vous suffira de l'introduire dans la table TblALT si nécessaire)

Un autre principe important est de "représenter la frappe par le résultat d'un COUP" qu'il faut décomposer en éléments d'actions pures, je m'explique :
La frappe est constituée d'une action initiale d'enfoncement d'une touche qui va créer une donnée ou un ordre, alors que le retour à la situation stable doit normalement ne donner aucune action, (ceci seulement pour les données).
Ce point est peut être un peu philosophique, mais cela explique que c'est à l'APPUI (MAKE) que se décide le résultat. Le retour à la situation stable est nécessaire, mais non générateur de résultat dans le cas normal des touches de données.
On distinguera du clavier, les touches de données (datas) comme "Abgfhjk…", les touches de fonction, à validation tant que dure l'appui, ou mémorisée qui commandent directement les actions de décodage (SHIFT Gauche et Droit, CTRL et ALT. (CAPS pour celle mémorisée)).

Les SCAN Codes ne sont jamais transmis au programme appelant, mais influent seulement sur le transcodage du code de touche d'un autre caractère de Data cette fois, en un caractère ASCII de la corbeille souhaitée (comme sur une ancienne machine à écrire)

On ajoutera également des données de contrôle au programme appelant sous forme de codes déjà recensés comme tels au niveau du standard ASCII (RETURN, TAB, ESC, Retour ARR). Ces caractères ont une entrée spécifique dans les tables de transcodage.

5 Les limitations nécessitées

Ces limitations se sont imposées par les temps nécessaires au CLAVIER10fonctionnement du datalogger, lui-même, et par le souci premier de faire le plus SIMPLE possible, mais efficace.
Aussi seule la partie standard d'une machine à écrire à été conservée ainsi que détaillé ci-après.

Il faut aussi admettre qu'un appareil de mesure n'est pas un organe de saisie de données et que l'ergonomie est un peu accessoire et qu'elle passera donc au second plan.
L'essentiel est d'obtenir l'accès à tous les codes ASCII et de pouvoir se sortir facilement d'une erreur de frappe. Voici donc les limitations décidées :

* SCAN codes complets au maximum  à 3 caractères (MAKE + BREAK)
* Abandon des touches fonctions F1 à F12, du pad numérique, des flèches de direction et des touches IMPR et des 2 autres du même secteur. (En résumé toute la partie droite)
* Abandon ALT_Gr remplacé par CTRL+ALT
* Abandon de toutes les touches fonction droite sauf SHIFT droit (Abandon E011, E027,E02F E014)
* Abandon des voyants claviersCLAVIER7 et autres commandes

Tous ces éléments conduisent à ne garder que les touches colorées correspondant au schéma ci-contre.
Il sera ainsi possible d'avoir accès à tous les codes sauf les flèches de direction.

Vous allez peut-être me dire que c'est important ces flèches de direction ? Je vais répondre non, car vous pensez PC !
Or vous n'êtes pas aux commandes d'un PC mais seulement d'un PIC, habituellement équipé d'un ou deux switchs et le contexte est totalement différent.
De plus le PIC dans ce cas, a un afficheur LCD avec 2 lignes de 16 caractères et seules les touches Retour AR pour la correction d'un caractère ainsi qu'ESC pour annuler une saisie complète, semblent suffisantes. (Il sera temps de voir par la suite si il reste de la place en mémoire)
Alors la simplicité a primé !

Dans la simplicité je suis aussi désolé de n'avoir pas repris les fonctions d'écriture clavier par le PIC, car cela nécessite l'inversion des TRISB des deux digits correspondant aux signaux clock et data, et en mode interruptible, cela alourdit un peu trop cette réponse aux interruptions.

Cette impossibilité d'écriture  empêche de connaître au niveau du clavier, l'état des corbeilles par les LED situées en haut à droite.
C'est est un peu gênant, mais cela m'arrange tout de même pour la consommation, vu que l'appareil est alimenté sur batterie.
Je préfère au besoin utiliser une LED de face avant pour indiquer la corbeille active (ou directement le display sur une position fixe). Il est aussi possible de commander par le programme les bonnes corbeilles en agissant directement sur les bits du Driver (Drv_CLA) sans se soucier de l'état initial de ces Bits.

Inverser de nouveau le bus pour que les voyants puissent être positionnés à la bonne valeur représente un ensemble de lignes de logiciel disproportionné et annexe pour un appareil dans la fonction initiale de datalogger. Alors c'est encore un sacrifice ! (Est ce finalement nécessaire de mettre un clavier ? Je vais tout de même répondre un tout petit OUI ! Ça me rapelle un certain sketch...)

On notera également que la séquence de tests de mise sous tension du clavier sera ignorée (dans mon cas d'utilisation) car d'autres tests assez longs se réalisent en premier et notamment la présence du module DCF77, pour savoir si l'on doit (ou non) rentrer la date et l'heure (justement à partir du clavier).
J'ai cependant au cours des essais pu vérifier la valeur 0xAA envoyée juste après la mise sous tension. (Cette valeur est un SCAN code unique)

Si l'état du test initial du clavier vous intéresse, vous devrez valider rapidement les interruptions et lancer la lecture par le Bit7 de Cnt_CLA, pour pouvoir récupérer cette valeur (Au niveau Car_CLA).

6 Quelques détails du logiciel

Pour les impatients qui attendent le Source, celui-ci a été extrait de l'ensemble de ce qui est déjà développé pour le Datalogger. Vous pouvez le télécharger en cliquant ce lien CLAVIER1

Bien entendu tout a été développé sous MPLAB de MICROCHIP avec quelques difficultés, car sans un émulateur, ce n'est pas très facile de comprendre ce qui se passe, car le clavier envoie ses données à son rythme rapide de 10 KHZ et beaucoup de séquences de touches ne sont pas toujours évidentes à comprendre dans l'enchaînement des codes générés.

Comme toujours, il faut découvrir les cas aux limites, car ce sont ceux-ci les plus difficiles a intégrer dans une démarche globale de fonctionnement.
Ainsi on peut citer quelques particularités découvertes :

* L'appui maintenu sur une touche quelconque envoie un SCAN code MAKE puis la fonction de répétition s'enchaîne après quelques fractions de secondes ("repeat"). Seul le SCAN code MAKE est transmis dans ce cas lors de l'appui maintenu. Au relâché de la touche, le code BREAK du SCAN est transmis, dans mon cas toujours F0 en tête suivi du code de touche initial.

* A vérifier car je n'ai pu le faire avec certitude, mais un repeat serait arrêté (codes MAKE transmis) par l'appui sur une autre touche. Cela semblerait logique ! Il n'y aurait pas de reprise du MAKE initial.

* Lors d'un appui normal de touche durant l'envoi du F0, ce qui suit le F0 est toujours le SCAN code correspondant au BREAK (Je n'ai pu le vérifier car trop difficile à mettre en œuvre au niveau timing à respecter, mais le principe parait absolument nécessaire et semble vérifié). Ainsi à partir du moment ou un F0 est envoyé, le caractère suivant est déjà préparé par le clavier. En conséquence le caractère inséré sera décalé dans le temps de la valeur nécessaire et séparé d'environ 2 mS du caractère précédent (le rappel du SCAN code après le BREAK).

* Recevoir un SCAN code MAKE ne veut pas dire qu'il n'y en aura qu'un seul et/ou qu'un autre peut survenir (La fonction repeat est possible !)

* Un SCAN Code BREAK n'est pas obligatoirement suivi d'un MAKE car d'autres BREAK peuvent être enchaînés lors de la frappe coulée.

* Le fait de maintenir une touche enfoncée pour les corbeilles, nécessite de mémoriser cette action dans un mot de contrôle, car plusieurs caractères peuvent s'insérer ainsi que des caractères F0 de touches normales ou de contrôle de corbeilles.

* La touche ALT_Gr n'est pas acceptée (SCAN code MAKE à 2 caractères) mais remplacée par CTRL+ALT. Le Bit ALT_Gr n'existe donc pas réellement par la touche correspondante, mais est seulement la concaténation logiciel des touches CTRL et ALT. (Je crois me rappeler que la touche ALT_Gr a d'ailleurs été crée dans cet esprit pour simplifier la frappe)

* Les touches SHFT_L ou SHFT_R et CAPS concourent toutes à une action sur le Bit UPCASE (voir les mots de contrôle ci-dessous)

Un élément important est de pouvoir traiter des caractères excédentaires et des les interpréter pour ne communiquer au driver Interruptible qu'un seul code de touche correct pouvant être transcodé en ASCII.
Pouvoir réaliser une entrée clavier est donc le fait des deux modules logiciels dont l'un est interruptible et l'autre non.
Chronologiquement, c'est le module NON interruptible qui travaille le premier et qui "passe ensuite la main" au module interruptible.
Voici le détail des actions réalisées par chacun. La précision sera à rechercher directement dans les lignes de code assembleur. (lien de téléchargement ci-dessus "CLAVIER1")
Ces deux modules sont habituellement chaînés et un seul appel au driver Interruptible s'occupe de tout. Mais les cas particuliers de travail en temps masqué sont possibles et là aussi le seul module Interruptible peut s'occuper de presque tout.

L'ensemble des drivers clavier est piloté par deux octets de contrôle, accessibles par les deux modules mais spécialisés ainsi et dans l'ordre des bits PF--->Pf (voir aussi le rappel schématique sur l'un des organigrammes)

Cnt_CLA  (Pas de nom générique aux Bits) Affecté principalement au driver NON interruptible

  Bit 7*  Start=1 (lecture d'un caractère et reste à 1 le temps de celle-ci) ou Rdy=0
  Bit  6  1ère fois (bit start valable pour 1 caractère)
  Bit 5   Dernier Bit lu y compris parité
  Bit 4  Err Parité
  Bits 0 à 3   bits de comptage à 10 (start bit non compté)

* Ce Bit7 peut aussi être relancé en interne par le driver non Interruptible (sans que le driver interruptible en ait connaissance)

Drv_CLA  Principalement utilisé par le driver interruptible : conversion ASCII

  Bit 7  Alt_Gr Concaténation des touches ALT et CTRL simultanées
  Bit 6   F0Bit  Le byte F0 (Break) a été détecté Précédemment au caractère en analyse
  Bit 5   M1PTR  F0Bit à 1 lancement Cnt_CLA Bit7 ordre de lecture complémentaire
  Bit 4   CTRL Touche CTRL appuyée
  Bit 3  ALT  Touche ALT appuyée
  Bit 2   UPCASE  Touches SHFT_L ou SHFT_R ou CAPS (impulsion seulement)
  Bit 1   ErrCLA Erreur dans les limites de conversion
  Bit 0   (Non Utilisé)

6.1 La partie driver NON interruptible

Par driver NON Interruptible il faut comprendre le driver situé dans la zone d'analyse et de réponse aux interruptions et donc sans autre interruption possible avant le RETFIE.
On valide donc les interruptions clock clavier (RBIE) si ce n'est déjà fait, mais on positionne surtout le Bit7 de Cnt_CLA qui autorisera la séquence NON interruptible à regarder toute interruption pouvant intervenir sur la ligne clock du clavier et donc le début d'une frappe clavier et de réception d'un caractère (front négatif). (GIE est invalidé lors d'un saut en 0x04)
Le premier front (start bit) n'est pas comptabiliséCLAVIER12 mais initialise le driver pour compter les 10 fronts suivants et effectuer le calcul de parité.

Le principe du calcul de parité est simple. Chaque bit data à 1 est ADDITIONNÉ dans un mot et à l'issue, si le Bit 0 de ce mot de sommation est à 1, il y a imparité et si le Bit 0 est à 0 alors c'est une parité. Ce calcul est confronté au dernier bit lu (le bit de parité) qui se trouve alors en Cnt_CLA Bit 5.

Ce driver NON interruptible outre les touches de datas, est chargé de gérer et mémoriser les touches fonction, pour positionner les bits de Drv_CLA, de fournir un SCAN code au driver interruptible, mais aussi et surtout de forcer des lectures pour épuiser les caractères non attendus et rendre le driver "Ready" pour une nouvelle lecture réelle demandée.
Dans le principe adopté, seul un buffer de 1 caractère est nécessaire (BUFF_CLA), ce qui est un énorme avantage avec les PIC qui sont très limités en mémoire de données.

On remarquera que les touches spéciales de datas de contrôle, qui fournissent des codes (ESC, TAB, Retour AR et Carriage Return) sont transcodées également suivant le code ASCII habituel, mais la fonction logique résultante sera à décider par le programme utilisateur totalement en dehors des drivers.

Ainsi dans l'exemple, le caractère RETURN est contrôlé en sortie de driver Interruptible pour interrompre (terminer) la saisie et afficher. (voir le code source)

Pour bien comprendre cette partie et la relance nécessaire de lectures complémentaires par le driver NON interruptible, il faut faire attention que le driver INTERRUPTIBLE, qui examine le Bit 7 et le recherche à zéro, n'en déduise que la lecture est finie, alors que l'on relance une lecture dont on ne regardera même pas la valeur si c'est une touche data.
Heureusement ce cas ne se produira pas, car aucune interrupt ne peut se arriver à cet instant et on ne pourra jamais redonner la main à la partie INTERRUPTIBLE avant que le Bit 7 ne soit effectivement remis à 1 par la réponse NON interruptible, juste avant le RETFIE !

(Avez-vous suivi ? Allez on recommence d'une autre manière ! Durant une interrupt le bit GIE est remis à zéro et aucune autre interruption ne peut avoir lieu. Ainsi la remise à 1 du Bit 7 de Cnt_CLA par le driver NON interruptible est impérative et suffisante pour éviter la désynchronisation entre les deux parties de Driver. C'est mieux ainsi ?...)
A l'inverse pour une touche fonction, cela déterminera la fin d'une touche maintenue par exemple (SHFT...).

Ce driver de part son principe autorise la fonction repeat sur chaque touche et y compris pour les touches fonctions.
Il n'autorise pas les SCAN codes MAKE multiples, mais le principe reste possible avec beaucoup plus de tests de caractères.
Dans ce cas, 2 touches devraient être testées séparément, car trop compliquées, à savoir IMPR écran (ou Syst) et PAUSE (ou Attn). Il me semble à ce stade que la mémorisation de plus d'un seul caractère est nécessaire ?

D'un point de vue complexité, cette partie est certainement la plus difficile à comprendre, car il faut tout IMAGINER DANS LE TEMPS, car c'est là que tout se joue.
Ainsi ne pas confondre un caractère F0 détecté en cours, et sa MÉMORISATION PRÉCÉDENTE dans le bit "F0Bit" du driver.
Tout est ainsi !
Pour reprendre ce que j'ai déjà évoqué, lors d'un Break composé de 0xF0 et du SCAN code, il ne peut pas y avoir d'insertion d'un autre caractère tapé durant la mS qui les séparent. Le caractère tapé sera obligatoirement décalé dans le temps que ce soit un MAKE ou un BREAK d'ailleurs. Un F0 accompagne ainsi toujours "son" SCAN code (de la touche correspondante).

Une fois le Bit 7 de Cnt_CLA positionné à 1 pour demande de caractère au clavier, il est possible de travailler indépendamment avec le PIC à faire autre chose et je pense notamment à des acquisitions analogiques avec le convertisseur AD.
Il suffit alors de tester périodiquement dans la boucle de surveillance générale du datalogger, si le Bit 7 est repCLAVIER11assé à 0. L'ordre de lecture concerne toujours UN seul caractère, (SCAN Code) et celui-ci reste disponible dans Car_CLA (jusqu'au prochain ou au relâché de la même touche seulement).

Le temps ainsi disponible entre un MAKE et un BREAK est de l'ordre de la milliseconde ce qui permet de travailler en temps masqué et de dérouler tout de même quelques milliers d'instructions. (oscillogramme ci-contre du signal clock clavier)

Ce buffer de 1 caractère contenant un SCAN code peut ensuite être repris tranquillement (s'il n'y a pas d'autre frappe) par le driver interruptible…

6.2 Le driver interrupclavier13tible

Ce programme est implanté en 4 ème Page mémoire (PAGE_3). Il est en effet très peu appelé par le Datalogger.
Il assure au choix, plusieurs modes de fonctionnement pour 3 points d'entrées différents dont :

- RD_CLAFULL assure la lecture de 1 caractère en testant préalablement la disponibilité d'un SCAN code provenant de la séquence NON interruptible (Bit7 de Cnt_CLA). La séquence ne rend la main qu'à l'issue d'1 caractère frappé qui sera transcodé et mis en BUFF_CLA.

- Un deuxième point RD_CLAT permet de faire d'autres travaux avec le processeur pendant le travail du clavier et de revenir quand on a terminé. Ce point teste la fin du driver NON interruptible et ne rend plus la main jusqu'à la fin complète du transcodage. (Il faut alors écrire indépendamment le Bit 7 de Cnt_CLA en dehors du Driver juste avant d'aller faire l'autre travail)

- Enfin le troisième point d'entrée RD_CLA suppose que le Bit 7 de Cnt_CLA est à zéro par un test préalable indépendant. Ce point d'entrée permet d'effectuer aussi un autre travail en ayant testé la fin de lecture et d'effectuer immédiatement le transcodage. Il faut là aussi lancer l'ordre de lecture (Cnt_CLA, Bit7) indépendamment, et en plus s'assurer du Bit Ready à zéro. Cette entrée permet de prendre une décision de terminer ce qui est en cours ou au contraire de répondre au clavier. (Cette décision doit nécessairement s'appuyer sur le temps, car il ne faudrait pas perdre de caractères...)

Dans les tests initiaux, on trouve en premier lieu, le test de M1PTR (Moins 1 Pointeur) qui évite de faire un travail car il s'agit du BREAK relancé automatiquement par le driver NON interruptible. Ce caractère ne présente aucun intérêt puisque c'est le relâché d'une touche. Il restera ainsi en Car_CLA et ne sera jamais transcodé.
Il a été cependant nécessaire de relancer cette lecture pour obtenir READY sur Cnt_CLA et pouvoir enchaîner avec un autre caractère (utile cette fois).

Vient ensuite le test du caractère ESCAPE. Ce caractère a été "sorti" des tables, car il permet de gagner 32 caractères en table UP-LO (Upper Lower de nom réel TBLASCII) ainsi que 2 autres en table ALT_Gr. Ce caractère sera traduit identiquement pour les 3 corbeilles, la valeur ASCII est 0x1B (conformément au code ASCII).

Dans la partie qui suit du driver Interruptible, et pour ne pas surcharger le driver NON interruptible, les Bits mémorisés CTRL et ALT sont testés pour voir si ils sont simultanés. Dans ce cas on positionne le bit ALT_Gr, et inversement, ce qui est tout de même beaucoup plus facile à tester.

On évalue ensuite les corbeilles et on dirige la conversion vers la table TBLALT ou la table TBLASCII, qui suivant la valeur UPCASE va donner le code ASCII correspondant.

6.3 Tables de conversion et corbeilles

Elles sont au nombre de 2 et sont reléguées en fond de mémoire programme dans les derniers 256 octets. Leur structure est très différente pour 2 raisons principales.
Ces tables sont de type RETLW avec calcul sur le PCL.

Il y a 90 SCAN codes à convertir (Télécharger le fichier EXCEL AZERTY.XLS) à convertir en 3 corbeilles, ce qui donne 270 caractères et dépasse donc les possibilités d'une indexation sur un octet.
De plus la table des ALT_Gr est très petite et ce serait en plus une difficulté de traiter l'ensemble en deux zones non contigues.

J'ai donc procédé avec deux tables différentes, l'une TBLASCII fonctionnant en indexation avec FSR/INDF avec la première valeur ASCII en UPPER CASE suivie de la deuxième valeur ASCII en LOWER CASE, et ainsi de suite avec l'index qui est le SCAN code de la touche appuyée, qui est multiplié par 2 pour pointer correctement.
Le contrôle de conversion sera assuré par les limites de l'index. Cette conversion est donc quasiment instantanée.

La deuxième table très petite en nombre d'entrées puisqu'elle ne comporte que 2x16 valeurs, concerne les caractères habituellement en ALT_Gr (regroupés par CTRL+ALT voir ci-dessus)

Le premier caractère est ici directement le SCAN Code de touche et celui qui suit sa valeur correspondante ASCII.
Il y a nécessité de balayage (éventuellement complet) de la table pour trouver le bon caractère.
Pour cette table, le contrôle des limites sera fait sur le comptage maximum possible (0 à 15)

Un seul octet contiendra le résultat ASCII qui sera BUFF_CLA dans le cas des deux tables.
En cas d'erreur de touche un ou deux bips (call buzz) seront émis.

Les touches de fonctions (CAPS, SHFT_L, SHFT_R, CTRL, ALT) vont générer les bons Bits dans le mot de contrôle Drv_CLA
Les codes ASCII correspondants aux autres touches dites spéciales vont donner les valeurs ASCII suivantes :

SCAN code (Hexa)  Dénomination   Valeur ASCII (Hexa)
5A              RETURN        0D
66             BACKSPACE      08
7               ESCAPE        1B
0D               TAB          09

Dans la philosophie retenue, et comme sur une ancienne machine à écrire, la retombée de corbeille peut être activée par CAPS (LOCK) ET par SHIFT indifféremment.

Pour les claviers autres qu'AZERTY, la table UP-LO (TBLASCII) sera à reprendre intégralement. Le repérage en table  est facilité par le tri sur le SCAN code et les commentaires.

Pour la table TBLALT, seul le SCAN Code peut être modifié pour la valeur ASCII qui peut rester. (L'ordre n'a pas d'importance puisque cette table n'est pas indexée)

6.4 Le tableau EXCEL des SCAN CodCLAVIER2es

Le tableau EXCEL est assez compliqué, car malheureusement ma version ne sait pas trier en Hexadécimal !. Il a donc fallu ajouter un SCAN code décimal pour "tromper l'adversaire"…Pour retrouver également l'ordre de saisie, de gauche à droite des touches, un N° en première colonne a aussi été ajouté. Enfin pour compter sans faire d'erreurs, la dernière colonne a été utilisée à cette fin. (Télécharger le fichier EXCEL AZERTY.XLS)

Vous aurez remarqué qu'il y a de nombreux "trous" dans l'ordonnancement des SCAN Codes. C'est une table "creuse" dont la conséquence est un certain "gaspillage de place".
Ce gaspillage reste pourtant la meilleure solution pour la table TBLASCII, question place, mais aussi de rapidité, car une comparaison des valeurs (comme la table TBLALT) serait encore plus désastreuse (Fois 3, avec seulement un peu moins d'entrées) et de plus très lente !
(Vous pouvez réutiliser au besoin quelques positions libres pour de courts messages par exemple)

Que dire des opérations EXCEL / WORD de conversion et "déconversion" de texte et tableau, pour arriver à générer automatiquement l'assembleur correspondant en RETLW…(Là c'est de la vraie cuisine !), mais l'essentiel est de ne pas avoir tout retapé une deuxième fois, car les risques d'erreurs sont trop importants !

Il faut dire aussi que ce tableau correspond à un modèle de clavier (NEC) pour être précis, mais que j'ai vérifié avec deux autres très vieux claviers, et qu'il n'y a pas de différence pour les touches retenues.

Je n'ai pas été en mesure de vérifier les SCAN codes des 3 touches IMPR, ARRET, PAUSE situées en haut et à droite, car les SCAN codes sont en nombre trop important. Les SCAN codes qui sont représentés sur les touches de l'image clavier (voir précédemment l'image clavier) sont vérifiés et correspondent parfaitement aux valeurs données par O. DARTOIS.

Lors de la transposition du tableau EXCEL en assembleur généré avec RETLW, j'ai utilisé EXCEL et le tri associé à WORD pour générer les lignes complètes en RETLW. J'ai seulement trouvé une seule erreur lors des essais qui est issue de mon tableau originel EXCEL et qui est maintenant corrigée.

Un dernier mot enfin, les valeurs non utilisées et figurant en NU dans les tableaux ont été transposées en 0xFF lors de la génération des RETLW.

7 La mise au point

Elle a été particulièrement longue, car sans "ICE", il n'est pas facile de simuler ce fonctionnement.
Le plus grave est certainement la non prise en compte de possibilités d'arrivées fortuites de caractères, et de rechercher à quel endroit devront se réaliser les différents tests, à la fois pour les touches datas, et pour les touches fonction.

Le simulateur de MPLAB est très bien, mais pour simuler ces types d'entrées, ce n'est pas très aisé. Il y a peut être des "trucs particuliers" sous forme de fichiers de commandes, mais je ne maîtrise pas suffisamment le simulateur et je n'ai pas le courage de chercher sans être certain de trouver, alors il faut être vigilant sur tout ce qui se passe et en déduire le problème !

Ainsi pour piège de ma première utilisation des interrupts sur RB 4 à 7, j'ai rencontré le problème de la remise à zéro d'une interrupt RBIF sur changement d'état, avec l'obligation d'assurer une lecture préalable du PORT RB sous peine de voir une deuxième interrupt en séquence.

C'est pourtant marqué en toutes lettres dans le "datasheet", mais il faut aussi y être passé pour s'en souvenir. (On ne peut que saluer la synthèse de la documentation constructeur qui est tout de même de qualité, mais il faut lire et relire, bien traduire et  se remettre en question !)
Que voulez vous, un PIC c'est certainement toute une culture qui ne s'acquiert qu'au fil de l'expérience, et comme je commence…
En tous cas, tous ces petits trucs qui "bouffent" un temps fou ne se trouvent pas toujours facilement, et je dirais même que ce serait une erreur de chercher une solution sur Internet et de passer plus de temps en recherche sur Internet en lieu et place de l'anomalie elle-même.

Le point le plus difficile à appréhender est cette succession de codes clavier dans le temps car on oublie rapidement à quel niveau on se trouve… (Le(s) caractère en cours ou le précédent !)

Attention de bien charger le PCLATH pour la zone précise (concernant les tables) et pas seulement les deux bits habituels de pages, car il y a les deux éléments perturbateurs qui interviennent : CALL et GOTO calculés car les adressages sont différents avec le PCLATH. (Là je ne me suis pas fait prendre car j'avais déjà donné pour le DCF77 !)
Vous pourrez augmenter assez facilement les tables en fonction de vos besoins, notamment pour les touches fonctions…(limite à 128 maxi !) A vous de voir et d'ajouter les codes à 2 SCAN Codes, mais ça se complique !

Cet essai était aussi pour moi l'occasion de jongler avec les pages et les BANK, et je dois dire que je me suis fait piéger de nombreuses fois, principalement sur les corrections rapides de mise au point, mais ça va beaucoup mieux maintenant.

Je me suis fait piéger aussi par les difficultés à gérer l'horloge temps réel qui est traitée par un autre PIC avec quartz adapté, ce qui permet de fonctionner à la vitesse maxi sur le 16F877A, mais qui pose des petits problèmes de compatibilités en simulation, avec l'oubli quasi permanent de repréciser OPTION_REG à chaque itération.

Pour résoudre ce problème, j'ai utilisé l'assemblage conditionnel à certains endroits avec les instructions correspondantes pour permettre en fonction de OPTION_REG, un assemblage automatique pour utilisation aussi bien en réel qu'en simulation. (ça marche très bien !)

Tout d'abord et il faut le rappeler, rien n'aurait été possible sans cet excellent article d'Olivier DARTOIS qui indique clairement le fonctionnement général d'un clavier PC : www.ac-limoges.fr/sti.../Clavier_PC_gere_par_un_PIC.pdf, et je vous invite à vous y reporter pour la théorie que je ne veux pas plagier inutilement, car cet article explique parfaitement le sujet.
Attention cependant car il faut transposer au clavier AZERTY, mais ce n'est plus très difficile à ce stade, c'est juste un peu laborieux pour ne rien oublier…

Comme il s'agit d'un PIC avec afficheur LCD, et comme tout un chacun le sait, les chinois fabriquent tout (y compris le CO²), les afficheurs sont tous avec les codes chinois en extension ASCII. Cela ne facilite pas les choix !
Faut-il garder le bon code ASCII pour aller vers un PC et afficher n'importe quoi, ou au contraire privilégier l'affichage ?

J'ai choisi de privilégier le PC, car l'essentiel du stockage et des traitements se réaliseront sur PC. Le PIC n'a qu'un rôle de saisie et de mise en forme, avec un affichage de "complaisance", surtout là pour vérifier le bon fonctionnement, la saisie des paramètres des essais et l'intervention opérateur.

Le clavier reste déjà quelque chose de "riche" relativement au montage, et je crois qu'il faut se limiter au strict nécessaire.
De plus une certaine limitation est également importante, car les tables prennent de la place et il n'y en a déjà pas de trop. (Ce n'est pas un PC !) Alors pourquoi pas ne garder que la partie clavier type machine à écrire sans aucune flèches ni pad numérique ? C'est donc mon choix !

Une, concession, la "touche miracle ESC" sera naturellement prise en compte, bien que son SCAN code soit très élevé (0x76) mais elle sera la seule testée séparément. Cette touche miracle sera à analyser par le programme appelant.

Je n'ai pas trouvé sur INTERNET de sous-programmes Assembleur en Interruptions pour gérer un clavier PC tout en ayant le souci de l'économie de place et en gardant toutes les possibilités ASCII.
Les possibilités ASCII ne sont pas altérées, par cette structure, et pour ceux qui souhaiteraient en plus la possibilité d'entrer tout code binaire, il est encore possible de le faire avec une combinaison ALT+ SHIFT et les 3 valeurs décimales, (comme avec le PAD numérique). Il y a un bit libre dans Drv_CLA !
Il reste aussi la possibilité de récupérer le SCAN Code directement depuis le driver NON Interruptible (Code de touche).
On peut donc faire beaucoup de choses avec finalement peu de choses ....

La retombée de corbeille sera acceptée aussi bien par CAPS que par SHFT, ce qui n'est plus le cas aujourd'hui sur PC, mais qui l'a été aux tout début de l'XT sous DOS ? ….

Dans un autre registre, j'ai essayé de visualiser à chaque caractère, mais j'ai eu des soucis conjugués à la fois avec des erreurs de programme et les temps d'affichage du display.
Sur ce dernier point j'ai été ennuyé et il serait nécessaire de refaire des mesures réelles pour vérifier si la cause était seulement les erreurs de programmation ou les temps d'affichage. (Je ne ferai ce test que lors de l'étape suivante).
On remarquera que pour le display, je teste le bit "READY", et que je ne connais pas explicitement le temps de réponse effectif.

Une bonne vérification à réaliser est de prendre un clavier ancien et nouveau et de voir que tout fonctionne de manière identique.

8 Conclusions

Un PIC 16F877A n'est pas nécessaire, je l'ai seulement utilisé dans le cadre de mon application Datalogger où le nombre d'entrées sorties est important.
Si vous souhaitez seulement faire un clavier ASCII, un PIC 16F628 suffira largement. Une précision tout de même, comme ces claviers sont très rapides, et surtout si vous décidez de traiter toutes les touches, je pense qu'un modèle à 20 MHZ est nécessaire.
Je n'ai pas de vérification absolue de cette recommandation, mais si il y a une horloge temps réel et quelques autres "babioles", les temps finissent par devenir importants, et de plus, suivant la vitesse de frappe vous pourriez vous faire déborder par les temps de traitement.

Ce morceau du programme clavier est important en termes de volume d'instructions et de tables. Cela me semble tout de même utile, car ça permet de réutiliser des claviers qui s'entassent au gré des évolutions des unités centrales des PC et des Operating System. Merci Bill...

La solution retenue n'est donc pas attachée à la vitesse de l'horloge clavier. Les simulations ont d'ailleurs été réalisées au simulateur avec les RB positionnés avec les stimulus et "Fire" à l'aide de la souris ! Ceci est important pour que ces lignes de programme puissent marcher sur la majorité des vieux claviers !

Aujourd'hui, du fait de l'USB, je pense que l'on va tendre à reprendre son ancien clavier s'il est encore en état…Encore que… l'échec de COPENHAGEN passant par là, et  tout le monde "s'en foutant" on va refaire la même chose comme avec les banques.   NON NON NON pas les banques les BANK des PIC !!!!!

Les éléments de programmes source nécessaires ont été extraits du contexte général du Datalogger. Moyennant quelques ajustements, je pense que vous pourrez les réutiliser tels quels, aussi bien avec un PIC 16F877 que 16F628.
Ce programme fonctionne correctement dans l'ensemble global du Datalogger en cours, et je n'ai pas pu le mettre en défaut.
Vous pourrez le retrouver intégralement dans son contexte lors de la sortie de l'article sur le Datalogger qui aura lieu dans le premier semestre 2010.

Allez Maurice, frappe qu'un coup, mais un bon !

____ ( retour début d'article ) ____

____ ( retour accueil bricolsec) ____
____ ( retour accueil lokistagnepas) ____