Quantcast
Channel: PICatout
Viewing all 192 articles
Browse latest View live

interface SPI

$
0
0

Dans cet article j'explique ce qu'est une interface SPI sans faire référence à un MCU en particulier. Il s'agit simplement de comprendre le fonctionnement de ce protocole de communication.

Serial Peripheral Interface

voici un schéma représentant cette interface.

Il s'agit donc d'un protocole de communication sériel. C'est à dire que les bits d'information circulent à la queue leu leu sur 1 seul fil. Cependant contrairement au protocole RS-232 il y a un signal clock sur un autre fil qui sert à synchroniser l'information.

Description des signaux

  • SCLK, Serial CLOCK est un signal de synchronisation qui détermine la position des bits.
  • MOSI est l'acronyme de Master Output Slave Input. Ce fil sert à transmettre les bits d'information du maître vers l'esclave.
  • MISO est l'acronyme de Master Input Slave Output. Ce fil sert à transmettre les bits d'information de l'esclave vers le maître.
  • SS est l'acronyme de Slave Select. Sur un bus SPI il peut y avoir plusieurs périphériques esclaves. Ce signal permet de sélectionner lequel est actif pour la communication. Notez la présence d'une barre au dessus du SS sur le schéma. Cette barre signifie que ce signal est actif lorsque le voltage est à zéro. Donc on sélectionne un esclave en mettant sa ligne SSà zéro. Les signaux de sorties d'un esclave non sélectionné sont en haute impédance et il ignore les signaux SCLK et MOSI.

A l'interne

A l'interne une interface SPI possède un seul registre à décalage1 pour la transmission et la réception.

Le maître comme son nom l'indique contrôle la communication. Les étapes de la communication sont les suivantes:
  1. Mettre à zéro la ligne SS de l'esclave.
  2. Envoie d'un octet de commande. En inscrivant l'octet dans le registre à décalage.
  3. Lecture de l'octet reçu de l'esclave
  4. Envoie des arguments de la commande
  5. Lorsque l'échange est terminé remettre la ligne SSà Vdd.

Le bit le plus significatif est envoyé en premier. Si vous regardez le schéma du transfert de donnée vous voyez que le maître comme l'esclave n'ont besoin que d'un seul registre à décalage pour recevoir et transmettre. La transmission et la réception se font en simultané. A chaque cycle du signal SCLK les registres de chacun sont décalés vers la gauche et reçoivent un bit d'information dans le bit de droite qui vient d'être libéré par le décalage vers la gauche.

Pour un octet, après 8 périodes du signal SCLK les registres de décalage du maître et de l'esclave contiennent un nouvel octet reçu de l'autre partie. Si besoin est le maître qui est habituellement un MCU peut lire le registre pour récupérer cet octet avant de l'écraser avec le prochain octet à transmettre.

Phase et polarité

Avant d'utiliser une interface SPI sur MCU ont doit déterminer les paramètres suivants:

  • Est-ce que le MCU est le maître ou l'esclave?
  • Quel est la fréquence du signal SCLK?
  • Quel est la phase du signal SCLK, paramètre CPHA
  • Quel est la polarité du signal SCLK, paramètre CPOL

Dans la majorité des cas le MCU sera le maître et la fréquence de SCLCK dépend des capacités du MCU, du périphérique SPI et de l'application.

La phase CPHA et la polarité CPOL de SCLK dépend du périphérique SPI utilisé. Ces paramètres sont configurés par l'état d'un bit dans un registre de configuration de l'interface SPI sur le MCU. Puisqu'il y a 2 bits il y a 4 combinaisons possibles:

MODECPOLCPHAdécalageéchantillonnage
000Tr desc.Tr mont.
101Tr mont.Tr desc.
210Tr mont.Tr desc.
311Tr desc.Tr mont.

CPOL détermine simplement à quel niveau logique doit-être la ligne SCLK lorsque l'interface est au repos. Lorsque ce bit est à zéro ça signifie que la ligne SCLK est à zéro au repos sinon elle est à 1.

CPHA détermine sur quelle transition le registre est décaler, i.e. envoie du bit sur la ligne. L'autre transition et utilisée pour échantillonner le bit sur la ligne de réception.

Le tableau ci-haut indique l'influence de ces 2 paramètres sur le moment du décalage et de l'échantillonnage.

exemple de périphérique SPI

Microchip vend des mémoires à interface SPI. Nous allons prendre pour notre exemple un 23LC512 qui est une mémoire RAM sérielle de 64Ko.

La procédure de communication est celle indiquée ci-haut. Supposons qu'on veut écrire un octet dans la RAM. Le diagramme suivant indique le timing sur l'entrée SPI du 23LC512.

Sur ce diagramme le signal SI correspond au signal MOSI de l'interface SPI. On voit donc que le 23LC512 échantillonne la ligne MOSI sur la transition montante. On voit aussi que le signal SCK est à zéro lorsque l'interface est inactive. Donc Sur le MCU on va configurer CPOL=0 et CPHA=0 c'est à dire le mode 0 selon la table ci-haut.

Si on regarde le diagramme du timing de la ligne SO (MISO du SPI) du 23LC512 on a ceci.

Les chiffres sur ces diagrammes réfère à une ligne de la table AC CHARACTERISTICS. La 12 de cette table nous dit que le signal sur la ligne SO est valide au maximum 25nsec (nanosecondes) après la transition descendante de SCK. Donc le maître peu lire en toute confiance cette ligne sur la transition montante à condition que le temps entre la transition descendante et la transition montante de SCK soit d'au moins 25nsec. Ce qui correspond à une fréquence maximale pour le signal SCLK de l'interface SPI de 20Mhz2.

Conclusion

Pour utiliser une interface SPI sur un MCU le plus important est de comprendre la relation entre CPOL et CPHA et de connaître les paramètres des signaux du périphérique utilisé. Le protocole SPI est utilisé entre autre par des mémoires sérielles RAM, EEPROM et FLASH. Aussi par certains affichages LCD ainsi que pour les carte SD. Vos profiterez donc d'une bonne connaissance de ce protocole dans vos projets MCU.


Notes

  1. Un registre à décalage permet de sérialiser un bloc de bits. Il peut s'agit d'un octet ou d'un mot plus long. Le mot est inscris dans le registre ensuite un signal clock permet de décaler les bits dans le registre un bit à la fois vers une sortie unique (1 bit). Dans le cas du protocole RS-232 les bits sont sérialisés en sortant le bit de poids faible en premier. Pour le protocole SPI c'est le bit de poids fort qui est sortie en premier. Un registre à décalage peut aussi faire l'inverse. Sois recevoir un train de bits sur une entrée et par le même principe de décalage recouvrer le mot complet dans le registre. En anglais on parle de SerDes c'est à dire Serialiser/Deserialiser. Dans le protocole SPI c'est le même registre qui accompli les 2 fonctions.
  2. On suppose que le signal SCLK est une onde carrée et que Thigh=Tlow donc pour Tlow=Thigh=25nsec on a une période pour SCLK de 50nsec donc 20Mhz. C'est bien selon les spécifications du 23LC512 la fréquence maximale pour SCK.

interface I2C

$
0
0

Dans cet article je présente le protocole i2C. qui est un bus de communication entre circuits intégrés. Ce type d'interface sérielle est utilisés avec de nombreux capteurs et aussi par certaines mémoires sérielles.

Inter-Integrated Circuit

I2C est l'abréviation pour Inter-Integrated Circuit. Il s'agit d'un protocole de communication sériel et synchrone utilisé pour la communication entre des circuits intégrés. Comme le SPI il s'agit d'un protocole bus, c'est à dire que plusieurs dispositifs peuvent-être connectés sur les même lignes de communication. Contrairement au protocole SPI il peut y avoir plusieurs maître sur le bus, c'est un bus Multi-maîtres, multi-esclaves. Il n'utilise que 2 fils pour la communication SDA et SCL par contre le débit est plus lent que pour un bus SPI. De plus la communication est semi-duplex, c'est à dire que la transmission et la réception se font en alternance.

Puisque les lignes de communication SDA et SCL peuvent-être contrôlées par plus d'un dispositifs il faut qu'elles soient configurées en drain ouvert. Il y a donc une résistance pull-up sur chaque ligne.

Seul un dispositif maître peut initier une communication. Mais puisqu'il peut y avoir plusieurs maître sur le bus, avant de débuter une transaction un maître doit vérifier l'état du bus. Évidemment s'il n'y a qu'un seul maître cette vérification peut être omise.

Dans cet introduction on ne verra que l'utilisation la plus simple soit un MCU utilisant une mémoire EEPROM et deux sondes de température branchés sur le même bus I2C.

Disons que ce dispositif sert à lire deux températures et à enregistrer les données dans la mémoire EEPROM. Les lignes A0-A2 sont branchées soit à Vdd ou Vss pour sélectionner l'adresse du périphérique. Ainsi l'EEPROM est à l'adresse 0 (b000), la sonde 1 à l'adresse 2 (b010) et la sonde 2 à l'adresse 4 (b100).

Adressage

Puisqu'il y a plusieurs dispositifs sur le même bus et qu'il n'y a pas de ligne Slave Select il faut une autre méthode pour distinguer les différents périphériques. Le protocole I2C utilise un adressage via le canal de données. Le maître procède de la manière suivante pour communiquer avec un périphérique esclave.

  1. Envoie du START bit.
  2. Envoie de l'octet d'adresse.
  3. Envoie du bit écriture(0)/lecture(1)
  4. Si un dispositif sur le bus reconnait l'adresse il répond par un ACK bit.
  5. Si le maître reçoit un ACK bit il peut continuer à transmettre ou recevoir en utilisant la ligne SCL pour cadencer les bits.
  6. Une transmission se termine par un STOP bit.

Lorsque le bus est inactif les 2 lignes sont à 1. Pour signaler un START le maître garde la ligne SCLà 1 et fait passer la ligne SDA de 1à 0. Pour un STOP c'est l'opposé, la ligne SCL toujours à 1 et la ligne SDA passe de 0à 1. Toutes les autres transitions de la ligne SDA se font lorsque la ligne SCL est à 0.

Le maître contrôle la ligne SCL et après l'envoie de chaque octet il doit envoyer un cycle supplémentaire sur la ligne SCL pour lire le bit ACK envoyé par l'esclave. Notez que ce bit ACK n'est envoyer pendant la phase d'adressage qu'après le bit WRITE/READ. Le maître doit lire le bit ACK pour s'assurer que l'octet a bien été reçu. On a donc 9 périodes du signal clock par octet envoyé. Lorsque le maître est en mode réception c'est lui qui doit envoyer un bit ACK pour chaque octet reçu. Cependant il ne doit pas envoyer de ACK pour le dernier octet reçu. Dans ce cas l'esclave cesse la transmission et attend le stop bit. Les octets sont transmis en commençant par le bit le plus significatif.

extrait du feuillet de spécification du 24LC512

Dans le cas des dispositifs Microchip utilisés dans le montage ci-haut l'octet d'adressage se compose de 5 bits de contrôle et de 3 bits d'adressage.

extrait du feuillet de spécifications du 24LC512

La signification des 5 bits les plus significatifs dépend du dispositif et on en retrouve la description dans le feuillet de spécification. Les 3 bits A0-A2 sont comparés à la valeur des broches de même nom et servent à sélectionner le dispositif.

Puisqu'un ACK doit-être envoyé à chaque octet transmis le MCU doit reconfiguré la ligne SDA en conséquence. Par exemple lorsqu'il transmet il doit configuré la broche qui sert de SDA en mode entrée pour recevoir le ACK et la remettre en mode sortie autrement. Lorsqu'il reçoit c'est le contraire il doit garder cette broche configurée en entrée et la mettre en sortie pour transmette le ACK.

Mette en application une interface I2C en logiciel es plus complexe que pour une interface SPI à cause du changement continuel de direction de la ligne SDA. Pour un exemple concret d'utilisation vous pouvez consulter le projet sonnette d'entrée sur ce blog.

Conclusion

Le seul avantage de l'interface I2C par rapport au SPI est le nombre réduit de broches requises sur le MCU. Autrement la vitesse de communication est plus lente et la mise en oeuvre plus complexe au niveau logiciel s'il n'y a pas de périphérique I2C intégré au MCU. Les périphériques I2C intégrés au MCU sont plus rares que les périphériques SPI. Donc plus souvent qu'autrement on doit le faire en bit bang.

convertisseur numérique/analogique

$
0
0

La majorité des microcontrôleurs possèdent au moins un périphérique de conversion analogique/numérique. Par contre les convertisseurs numérique/analogiques sont moins répandus. Dans cette article je fais une présentation des différentes méthodes utilisées pour convertir un signal numérique en signal analogique.

PWM

Comme presque tous les MCU possèdent au moins 1 périphérique PWM l'utilisation de celui pour convertir un signal numérique en analogique est très répandu. Son principe de fonctionnement est basé sur l'intégration du signal ou si vous préférez la moyenne. Voici une illustration.

On a donc un signal numérique qui varie entre Vcc et 0 volt à la sortie d'une broche du MCU. Cependant le rapport cyclique de ce signal varie selon l'amplitude du signal analogique qu'on veut reproduire. Le filtre passe-bas composé d'une résistance R et d'un condensateur C sert d'intégrateur. L'onde rectangulaire du PWM est envoyée à l'entrée du filtre et à la sortie on retrouve un voltage dont la valeur et directement proportionnelle au rapport cyclique. En effet lorsque le signal est à Vcc le condensateur se charge à travers la résistance et lorsque le signal et à 0 volt le condensateur se décharge à travers la résistance. Lorsque le rapport cyclique est de 50% le voltage moyen est de Vcc/2. En fait le voltage moyen à la sortie est


Vout=Vcc/Rcy*100
où Rcy est le rapport cyclique exprimé en pourcentage du cycle. Pour que ce convertisseur fonctionne bien il faut que la fréquence de coupure Fc calculée par la formule:

Fc=1/2*PI*R*C
soit beaucoup plus basse que la fréquence du PWM. Avec un filtre simple pôle comme celui illustré ici Fc doit-être au moins un dixième la fréquence PWM. Par exemple si on veut convertir un signal audio avec une fréquence maximale de 10Khz la fréquence PWM doit-être au minimun 20Khz et le filtre devrait avoir une valeur Fc de 2Khz ou plus bas. En remplaçant ce filtre simple par un filtre actif multipôles la fréquence de coupure du filtre peut-être au maximum la moitié de la fréquence PWM. Par exemple un filtre 8 pôles avec une fréquence de coupure 10Khz atténue la fréquence PWM de 48db. Alors que le filtre passif 1 pôle ne l'atténue que de 6db.

Cette méthode de conversion est simple et économique. On peut obtenir un résultat satisfaisant avec un filtre passif à 2 pôles. C'est à dire 2 filtres bout à bout. Mais dans ce cas On calcul Fc du premier filtre au double de la valeur de 2ième filtre en tenant compte de la charge du second filtre. Une façon simple de procéder est d'utiliser la même valeur pour R mais d'utiliser 2*C pour le deuxième filtre. L'impédance de sortie doit-être d'au moins 10 fois l'impédance de sortie du filtre pour ne pas le charger. exemple:


Fpwm=20khz
Fc=10Khz et 1Kohm
C=1/2*PI*R*FC ->> C= 1/2*PI*1000*10000=159nF
la valeur standard la plus proche est de 150nF

Avec ce filtre il faut utiliser une fréquence PWM d'au moins 20Khz pour de l'audio jusqu'à 10Khz.

Conversion delta-sigma

Le convertisseur delta-sigma fonctionne sur le même principe d'intégration d'une onde rectangulaire sauf qu'il ne n'agit pas d'une fréquence constante dont le rapport cyclique varie selon l'amplitude du signal analogique. Les échantillons numériques n'ont qu'un seul bit. Pour représenter un voltage plus élevé on fait suivre plusieurs bit à 1 et pour représenter un signal de faible amplitude on fait suivre plusieurs bit à zéro. Les bits se succèdent à une fréquence beaucoup plus rapide que pour le PWM. On peut utiliser un périphérique SPI pour sortir les bits.

Plus il y a de 1 qui se succèdent plus le voltage monte à la sortie du filtre. Plus il y a de zéro qui se succèdent plus le voltage descend vers zéro. Pour que ça fonctionne il faut que les échantillons représentent une densité d'impulsion plutôt qu'une amplitude.

Conversion par diviseur de tension

Il y a 2 méthodes.

Première méthode: utilisation de résistances croissantes.

Ce convertisseur à 4 bits et chaque bit doit donner en tension en sortie qui est le double de celle du bit de poids précédent. Lorsque tous les bits en sortie sont à 1 on doit avoir une tension en sortie de:

Vout=15*Vin/16
Supposons que la valeur de la résistance Ro est de 1Kohm. On doit avoir en sortie

Vout=1*Vin/16=Rb0*Vin/(Rb0+Ro)
Rb0 doit-être de 15Kohm.
Rb1 doit-être de 15Kohm/2=7,5Kohm
Rb2 doit-être de 15Kohm/4=3,75Kohm
Rb3 doit-être de 1Kohm/8=1,875Kohm
Ces valeurs ne sont valides que si on met les bits qui ne sont pas à 1 en haute impédance et non à zéro volt. Car si on met c'est bits à zéro volt ça modifie la valeur de la branche basse du diviseur de tension. exemple si b0-b2 sont à zéro alors que b3 est à Vcc la valeur équivalente de Ro1 est de:

Ro = 1/(1/Ro+1/Rb0+1/Rb1+1/Rb2)= 682 ohm
donc la tension en sortie serait de

Vout = 1,875*Vin/(1,875+0,682)
au lieu de

Vout=1,875*Vin/(1,875+1)

Cette méthode n'est pas pratique car elle donne des valeurs de résistances non standard et oblige à mettre les bits qui ne sont pas à Vcc en haute impédance.

méthode R/2R

Heureusement il y a une méthode beaucoup plus simple. Le diviseur de tension R/2R n'utilise que 2 valeurs de résistances dont l'une est le double de l'autre d'où son nom.

Cette arrangement de résistances fait en sorte que quel que soit la valeur des bits en sortie la branche basse du diviseur de tension vue par les bits de poids plus faible garde une valeur constante de R. De plus on peut choisir 2 valeurs standards ou une seule valeur standard en utilisant 2 résistances en série pour les 2R. Le seul inconvénient c'est que ça demande plus de résistances.


  1. La valeur équivalente de résistances en parallèle est l'inverse de la somme de leur conductance.

megaprocessor, un projet incroyable.

$
0
0

Je veux seulement mentionner ici un projet qui m'impressionne par sa qualité et surtout l'incroyable quantité de travail que son auteur y a consacré. the mega processor comme son auteur l'a baptisé est un ordinateur fabriqué entièrement avec des transistors 2N7000. L'objectif de l'auteur, James Newman, est de rendre visible le fonctionnement interne du processeur. Ainsi tous les bits des différents registres sont connectés à une LED de sorte qu'on voit leur état 0/1. Il a même construit une mémoire de 32 mots de 8 bits avec une LED connecté à chacun de ces bits, Cette mémoire occupe un cadre d'aluminium complet à elle seule. Le processeur est composé de plusieurs cadre d'aluminium, 1 pour chaque unité logique: ALU, RAM, I/O, etc. Il faut voir les photos et vidéos sur son site WEB.

Impressionnant, un travail titanesque.

Projet PV16SOG

$
0
0

Ce projet est une suite logique des projets comme PICvision et PICvision portable. Il s'agit d'un petit ordinateur dans le style 1978, pensez à Apple II ou TRS-80 modèle I. Le montage électronique est réalisé avec seulement 3 composants actifs, le MCU PIC24EP512MC202, la mémoire SPI RAM 23LC512 et le régulateur de tension 3,3Volt. Le montage est réalisé sur une carte à pastilles passantes (sur les 2 faces).

Puisque ce projet a sa propre page WEB je ne ferai ici qu'une brève présentation.

Caractéristiques

  • Processeur: MCU PIC24EP512MC202. Il s'agit d'un MCU 16 bits avec 512Ko de mémoire flash et 48Ko de mémoire RAM.
  • Video: Sortie vidéo NTSC 16 tons de gris.
    • Mode texte: 21 lignes de 40 caractères.
    • Mode graphique: 240x170 pixels 16 tons de gris
  • Son: Sortie tonalité simple (onde carré).
  • périphériques utilisateur: Clavier PS/2 et joystick Atari 2600
  • Stockage: Carte SD format en FAT/FAT32.
  • Shell: Shell de commandes dans le style MS-DOS avec des commandes comme dir, del, ren,etc.
  • Programmation: BASIC inspiré de QBASIC. Il s'agit d'un compilateur BASIC entier 16 bits procédural. Pas de numéro de lignes ni de GOTO et GOSUB, je voulais quelque chose de plus moderne. Ce BASIC peut-être utilisé en interactif à la manière de Python, mais il y a aussi un éditeur de texte pour écrire des programmes et les sauvegardés dans un fichier.
  • RAM: La mémoire RAM disponible pour les programmes BASIC est de 20512 octets. La SPI RAM peut-aussi être utilisée pour conserver des données temporaires.

Vidéo de présentation

présentation du boitier. Réalisé en contre-plaqué de merisier 3mm.

Présentation du shell de commande. Exécution de quelques commandes, de quelques petits démo en BASIC et finalement écriture d'une fonction factiorielle utilisant la résursivité.

État du projet

L'ordinateur est utilisable dans l'état actuel du code. Lorsque je tombe sur un bogue je le corrige rapidement. La documentation n'est pas tout à fait complétée. Je dois encore écrire des exemples pour le BASIC.

Liens

Que se passe t-il avec Intel?

$
0
0

Intel a annoncé qu'ils abandonnaient le marché du mobile après avoir dépensé 10 milliards pour à essayer de se tailler une place sur ce marché. Sans parler de cette autre nouvelle daté du 27 avril: Intel Will Layoff 12,000 American Workers After Requesting 14,523 Foreign Workers. Ils veulent mettre à pied plus de 14,000 travailleurs Américain après avoir fait venir des travailleurs étrangers qui leur coûte moins chers, sous prétexte qu'il n'y avait pas assez de travailleurs aux U.S.A pour combler tous les postes. Quel culot! Faut-il s'étonner que tant d'Américains soient en colère contre leur classe politique qui laisse faire ça?

Le bonheur des uns fait le malheur des autres.

Revenons au sujet en titre. Tout a commencé avec la mise en marché du iPhone en 2006 (déjà 10 ans!). Apple avait choisi un processeur à coeur ARM et comme nous le savons le iPhone a été plus qu'un succès. Il a carrément changer le monde. Il a été suivit par d'autres téléphones sous Androïd et aujourd'hui presque tout le monde a son smartphone. Puis il y a aussi les tablettes. Et quel processeurs ces gadgets utilisent-il? Ils utilisent tous des processeurs à coeur ARM au grand bonheur des actionnaires de ARM corporation.

Non seulement ces nouveaux gadgets ont envahient le marché ils ont fait chuter de façon dramatique la vente de PC et de laptops qui eux utilisaient en grande majorité des processeurs Intel. Intel est donc perdant sur les 2 tableaux, incapable d'installer ses processeurs sur les smartphone et tablettes et en même temps diminution dramatique de ses ventes de processeurs pour PC. Le marché du PC a tellement chuté que même les grands distributeurs vendent des PC reconditionnés!

Imaginez Intel ce géant qui a dominé le marché des microprocesseurs depuis les années 1970 est maintenant obligé de couper dans les dépenses de toutes les façons imaginables. Intel possède ses propres usines de fabrication de microprocesseurs. Hors une seule de ces usines coûte plusieurs milliards de dollars. Leur frais fixes sont faramineux à comparer à ceux de ARM corporation qui ne fabrique rien du tout. ARM corp. est une compagnie d'ingénieurs et ne font que concevoir les microprocesseurs et vendent des licences.

Dans le contexte actuel l'avenir est pas mal plus rose pour ARM corp. que pour Intel corp.

Pour ARM il n'y a pas que les processeurs applicatifs, regardez du côté des microcontrôleurs, à peut prêt tous les fabricants vendent des MCU à base de coeur ARM cortex-M. Nommez les, TI, Atmel, NXP, etc. Il n'y a guère que Microchip qui a préféré utiliser les coeurs MIPS. Mais Microchip vient d'acheter Atmel. Alors vraiment ARM corp. a le vent dans les voiles tandis que Intel décline. Bien sur le déclin d'Intel n'est pas encore dramatique ils dominent encore le marcher des serveurs et il se vend encore des PCs et laptops pour les entreprises. Mais il est bon de se rappeler que rien n'est éternel.

mise à jour 2016-05-05

iOT qui signifie Internet Of Things voilà la nouvelle stratégie de marketing des manufacturiers qui veulent nous faire croire que le moindre objet a besoin d'être relié à l'internet. Évidemment Intel veut sa part de ce gâteau. Voilà pourquoi ils ont mis en marché les SoC et MCU Quark. Intel s'est même associé au populaire projet Arduino pour produire la carte Arduino Galileo qui utilise un tel processeur. J'ai bien peur que se soit trop peu trop tard pour Intel. Alors qu'ils avaient pour ainsi dire abandonner le marché des MCU, croient-ils qu'ils pourront s'y tailler une place aussi facilement. L'ironie de la situation c'est qu'en 1980 ils ont mis en marché le MCU 8051 qui a été un grand succès et que le coeur 8051 est encore utilisé de nos jours par d'autres manufacturiers. Mais plutôt que de développer le marché des MCU ils ont préférer mettre tous leur oeufs dans le panier des PCs et serveurs. Pourtant plus de 90% des processeurs vendues dans le monde actuellement sont des microcontrôleurs5. Le marge de profit est moindre mais compensée par les volumes gigantesques. Imaginé Microchip qui vend le PIC10F200-I/OT 0,41US$ l'unité en quantité de 5000+5. Ils faut qu'ils en vendent des millions chaque année pour que le profit soit significatif. En 2013 il s'est vendu 19,1Milliard de MCU1 (toutes variétés confondues). En 2015 il s'est vendu à l'échelle mondiale 238,5 millions d'ordinateurs (tous types confondus)2. Pour les années à venir la croissance des revenus prévue est de 4,8%/année1 pour les MCU. Si l'iOT gagne en traction ce chiffre pourrait bien être supérieur. Et dans ce secteur on voit de plus en plus de ARM cortex-M. Les Quark de Intel risque bien de passer de l'univers quantique à la basse-cour en se transformant en quack3 de canard boiteux.


NOTES et références

  1. référence: http://www.icinsights.com/news/bulletins/MCU-Market-On-Migration-Path-To-32bit-And-ARMbased-Devices/
  2. référence: http://www.statisticbrain.com/computer-sales-statistics/
  3. jeux de mot anglophone, quack est l'onomatopée anglophone pour coin-coin.
  4. référence: https://en.wikipedia.org/wiki/Microcontroller
  5. référence: https://www.microchipdirect.com/ProductSearch.aspx?keywords=pic10f200-i/ot

tube électronique

$
0
0

L'électronique n'a pas débutée avec l'invention du transistor mais avec l'invention du tube électronique. Les tubes électroniques sont encore en usage de nos jours dans certaines applications comme dans les satellites de communications sous forme de TWT ou encore les émetteurs radio grande puissance. Dans cet article j'explique le fonctionnement des tubes électroniques.

Lampe diode

Commençons par le tube électronique le plus simple, la diode a été inventée en 1904 par Ambrose Flemming. Dans un tube de verre dans lequel on fait le vide complet on insère 1 filament chauffé et une autre électrode froide celle-là.

Le filament chauffé s'appelle la cathode car il fournir les électrons et l'électrode froide qui reçoit les électrons s'appelle l'anode.
Fonctionnement

lorsqu'on chauffe le filament en appliquant un faible voltage 6 ou 12 volt, il se forme un nuage d'électrons autour de celui-ci. Les électrons étants les porteurs de la charge électrique négative sont attirés par un champ électrique positif. Donc si on applique un voltage positif à l'anode par rapport à la cathode, le nuage d'électrons sera accéléré vers l'anode. Il va donc y avoir un courant électrique qui va circulé. Par contre si on applique un voltage négatif sur l'anode les électrons seront repoussé par l'anode et aucun courant ne circule. Donc si on applique un voltage alternatif à l'anode le courant ne circulera que pendant la phase positive on aura donc ceci à la sortie du tube.

Seule les alternances positives laisse passées le courant donc pendant les alternances négatives il n'y a pas de chute de tension aux bornes de RL. Une chute tension aux bornes de RL implique que l'anode du tube devient négative par rapport à la masse d'où le graphique indiquant des impulsions négative aux bornes de RL. On a donc un redresseur.

Il faut mentionner l'importance du vide à l'intérieur du tube. Si on laissait l'air dans le tube les électrons entreraient en collision avec les molécules d'air et perdraient leur énergie avant d'arriver à l'anode.

La triode

Pour obtenir un amplificateur il faut pouvoir contrôler le flux d'électrons à travers le tube en fonction du signal qu'on désire amplifié. Lee de Forest en 1906 a inventé un tel tube à 3 électrodes. La troisième électrode s'appelle la grille de contrôle. Il s'agit habituellement d'un fil enroulé en spirale autour de la cathode sans y toucher cependant. Un circuit d'amplification à triode ressemble à ceci.

On a donc le voltage de chauffe du filament Vf. Il est représenté ici par une pile mais en pratique il s'agit d'un voltage AC basse tension 6 ou 12 volt provenant du secondaire d'un transformateur. Vp est le voltage appliqué à l'anode. Il provient habituellement de la rectification d'un 2ième bobinage du même transformateur. Ce voltage peut dépasser 200 VDC mais peut-être aussi bas que 50VDC dépendant du type de tube et de l'application. Rg est la résistance de polarisation de la grille. Un certain courant circule dans circuit entre la grille et la cathode à travers Rg. Cette résistance est de l'ordre de 1Mohm et le voltage qui se développe à ces bornes fait en sorte que la grille est négative par rapport à la cathode ce qui limite le courant vers l'anode. La valeur de Rg est choisie en fonction des caractéristiques du tube afin d'obtenir le point d'opération désiré. Lorsque le signal à amplifier est présenté sur la grille il module le voltage entre la cathode et la grille et donc le courant qui circule vers l'anode. La résistance d'anode Rp permet de développer un voltage en inversion de phase du voltage sur la grille mais amplifié.

Tétrode et pentode

Des tubes à 4 électrodes, les tétrodes et à 5 électrodes, les pentodes ont été inventés pour améliorer les performances des tubes amplificateurs. La quatrième électrode appelée grille écran insérée entre la grille de contrôle et l'anode sert à réduire l'effet capacitif entre l'anode et la grille de contrôle. Cet effet capacitif réduisait le gain en haute fréquence des triodes. Cette grille écran est gardée à un voltage positif constant plus bas que celui de l'anode.

Les pentodes ont été inventées pour régler le problème des émissions secondaires. En effet l'anode bombardée par les électrons chauffe et parce qu'elle chauffe elle émet des électrons à son tour comme la cathode. L'effet est plus prononcé dans les tétrodes parce que les électrons arrivent plus rapidement à l'anode à cause de l'accélération supplémentaire produire par la grille écran. La 3ième grille appelée grille d'arrêt est gardée au même voltage que la cathode ce qui a pour effet de ralentir les électrons avant qu'ils ne frappent l'anode. Les pentodes sont utilisées dans les circuits audio de puissance comme les amplificateurs de guitares électriques.

Autre perfectionnement

Si les premières diodes et triodes émettaient les électrons directement à partir du filament, rapidement une amélioration a été apportée sous la forme d'une cathode séparée du filament. Dans les tubes modernes la cathode est formée d'un cylindre recouvert d'oxyde de baryum à l'extérieur. Le filament chauffant est inséré à l'intérieur du cylindre cathode mais est isolé électriquement de celui-ci. Cette amélioration présente 2 avantages. Premièrement lorsque le filament et chauffé en alternatif à la fréquence du secteur, 50 ou 60 hertz dépendant des régions, la quantité d'électrons émis est modulée par cette fréquence et est donc amplifiée par le tube. La cathode isolée a une température plus constante et une émission d'électrons qui n'est pas modulée par la fréquence secteur. Le deuxième avantage de la cathode est que certains métaux émettent plus facilement des électrons lorsqu'ils sont chauffés que d'autres. C'est le cas de l'oxyde de baryum. Puisque la cathode émet plus facilement des électrons elle peut-être gardée à une température moindre ce qui augmente la durée de vie du filament. La cathode cylindrique produit aussi une émission mieux distribuée sur la totalité de sa surface.


pour en savoir plus

Regency TR-1

$
0
0

Après avoir lu cet article sur Hackaday.com où on mentionne la mise en marché en 1954 du premier récepteur radio à transistors. J'étais curieux de voir son schéma électronique et une recherche dans Google par permis de trouver rapidement. Dans cet article je décris le fonctionnement de ce récepteur radio.

schéma électronique du Regency TR-1

Vous pouvez cliquer sur l'image pour l'agrandir.

Il s'agit d'un récepteur super-hétérodyne qui n'utilise que 4 transistors. À cette époque il s'agissait de transistors au germanium.

Super-hétérodyne

Un récepteur super-hétérodyne est un récepteur qui convertie le signal reçu à une fréquence fixe appelée fréquence intermédiaire qui est amplifiée avant que le signal ne soit démodulé (recouvrement de l'information). Dans les récepteurs commerciaux pour la bande de diffusion MW (530-1700Khz) la fréquence intermédiaire est standardisée à 455Khz et est obtenue par soustraction de la fréquence de l'oscillateur local à la fréquence de la station reçue par l'antenne. L'oscillateur local doit-être accordée en même temps que l'amplificateur RF de sorte que sa fréquence soit maintenue à 455Khz au dessus de la station syntonisée. Par exemple si on syntonise une station à la fréquence de 610Khz l'oscillateur local aura une fréquence de 1065Khz. Cette syntonisation se fait par un condensateur variable à 2 sections dont les plaques mobiles sont sur un axe commun. Sur le diagramme bloc la ligne pointillée représente le lien de syntonisation entre l'oscillateur local et l'amplificateur radio-fréquence.

Variable Capacitor.jpg
Par Ulfbastel de de.wikipedia.org, CC BY-SA 3.0, https://commons.wikimedia.org/w/index.php?curid=605145

L'intérêt du super-hétérodyne est d'améliorer la sélectivité en fréquence, c'est à dire la capacité à séparer les stations qui sont proches en fréquence l'une de l'autre. La bande passante d'un circuit accordé est Fr/Q. Où Fr représente la fréquence d'accord et Q est le facteur de qualité de l'inductance du circuit accordée. A partir de cette formule on comprend que si le facteur Q est constant la sélectivité d'un circuit accordé diminue avec l'augmentation de la fréquence. En convertissant la fréquence reçu à une fréquence constante de 455Khz la sélectivité sera la même à 1700Khz qu'à 540Khz.

Fonctionnement du Regency TR-1

Pour suivre cette description reportez-vous au schéma électronique détaillé ci-haut. Première remarque, il n'y a que 4 transistors. Les premiers transistors étaient coûteux il fallait donc en réduire le nombre. X4 est l'amplificateur audio. Puisque l'impédance de sortie au collecteur de X4 est trop haute pour alimenter directement un haut-parleur on utilise le transformateur T4 pour abaisser cette impédance. Ce type de transformateur a habituellement une impédance de 1 ou 2 Kohm au primaire (côté collecteur de X4) et 8 ohm au secondaire.

La bande MW étant modulée en amplitude la démodulation est très simple. Il suffit de redressé le signal à la sortie de l'amplificateur IF. Cette tâche est accomplie par la diode D1. le condensateur C18élimine le résidu radio-fréquence pour qu'il ne se propage pas dans l'amplificateur audio. Le potentiomètre R12 insérée entre le détecteur et l'amplificateur audio permet de régler le volume sonore.

Les transistors X2 et X3 sont utilisés pour l'amplificateur de fréquence intermédiaire. Le couplage entre les étages se fait par circuit accordé à 455Khz. C'est ce qui assure la sélectivité du récepteur. À l'entrée de l'amplificateur IF on a T1 et C6 qui forme le premier circuit accordé à 455Khz. Entre X2 et X3 on a T2 et C12 qui forme le deuxième et finalement à la sortie on a T3 et C16 qui forme le troisième circuit accordé. Avec ces 3 circuits accordés à 455Khz la sélectivité est suffisante pour cette bande de fréquence.

On arrive à la partie la plus intéressante du circuit. Sur le diagramme bloc on voit 3 modules, RF AMP., OSC. LOCAL et MIXER. Mais sur le schéma électronique on ne voit qu'un seul transistor X1. En fait ce transistor joue les 3 rôles. Comme je l'ai écris ci-haut, les transistors coûtaient cher à l'époque. On a donc synthétisé les 3 fonctions dans un seul étage à transistor.

Le rôle d'antenne est joué par une barre de ferrite sur laquelle est bobinée le circuit d'accord radio-fréquence constitué de L1 et C2. Le bobinage L2 couple le signal radio reçu vers la base de X1. L2 sert à abaisser l'impédance pour ne pas chargé le circuit accordé radio-fréquence, ce qui aurait pour effet de réduire la sensibilité et la sélectivité de celui-ci.

Le circuit accordé de l'oscillateur local est formé de L3, C3 et C5. L3 possède un branchement partiel pour retourner une partie du signal de sortie vers l'émetteur de X1à travers le condensateur C4. Cette rétro-action positive permet de créer un oscillateur de type Hartley. C'est l'oscillateur local. Puisque X1 amplifie à la fois le signal RF reçu de l'antenne et le signal de l'oscillateur il agit automatiquement comme un mélangeur (MIXER). Sur le collecteur de X1 on retrouve la fréquence de la station émettrice, la fréquence de l'oscillateur local ainsi que la somme et la différence de ces 2 fréquences. Ce signal est couplé à travers L4à T1 et C6. Mais puisqu'il s'agit d'un circuit accordé à 455Khz seule la différence entre la fréquence de la station syntonisée et celle de l'oscillateur local passe dans l'amplificateur de fréquence intermédiaire.

A propos de C2 et C3 il s'agit en fait de 2 sections d'un même condensateur variable. Dans un schéma moderne aurais plutôt utilisé les notations C2a et C2b pour les désignés.

Ce n'est pas terminé, ce récepteur malgré sa simplicité possède aussi un contrôle de gain automatique. Puisque la puissance du signal varie d'une station à l'autre il est utile d'ajuster le gain en fonction de la puissance reçu sans que l'utilisateur est besoin de toucher au contrôle de volume. À l'anode de la diode D1 en plus du signal audio fréquence il y a un certain voltage DC négatif puisque la diode redresse le signal de sortie de l'amplificateur IF. La valeur de ce voltage devient plus négative avec la puissance du signal reçu. La résistance R11 ramène ce volage vers la base de X2. Ce signal filtré par C9 pour enlever toute trace de fréquence audio modifie la polarisation du transistor X2 de sorte que plus le signal reçu es puissant, plus le gain de X2 diminue. Ce qui permet de contrôler le volume audio lorsqu'on change de station.

Conclusion

Ce type de montage était très fréquent dans les années 60, 70 et même 80. Sauf qu'à partir des années 60 les transistors au germanium ont étés remplacés progressivement par les transistors au silicium. Les transistors au silicium sont plus stables, ont un courant de fuite plus faible et offre un gain plus élevé. A partir des années 70 on a vu apparaître des circuit-intégrés qui accomplissait le travail de certain module du super-hétérodyne. Par exemple des amplificateurs audio en circuit-intégré comme le LM386. Puis sont apparues des circuit intégrés contenant toute la partie RF, IF et détection.

Aujourd'hui les technologies analogiques ont été en grande partie remplacées par des circuits numériques. Silicon Labs est un des manufacturiers les plus actif dans le domaine des C.I. radio-fréquence. Voici le schéma d'un récepteur MW/SW/FM réalisé avec un si4825-a10 de Silicon labs.

Il ne manque que l'amplificateur audio.

Notez qu'il n'y a pas de condensateur variable, la sélection de fréquence se fait par un potentiomètre. Les technologies numériques ont fait presque disparaître les condensateurs variables. Seul quelque vendeurs spécialisés en tiennent encore en inventaire. Les derniers que j'ai acheté, je les ai trouvé sur ebay. Il s'agit de condensateurs usagés. Il est plus facile de les trouver en Europe de l'est.


La machine à thé

$
0
0

Je me suis fabriqué une machine à infuser les sachets de thé. Dans cet article je fais une présentation détaillée du projet. Le code source et tous les autres documents sont disponible sur https://github.com/picatout/machineathe.

Sommaire

La machine à thé que j'ai fabriqué a pour fonction de prendre en charge le chronométrage de l'infusion du thé. Elle a un bras motorisé auquel j'attache le sachet. j'ajuste le chronomètre et pèse sur le bouton MARCHE. Le bras descend le sachet dans la tasse. lorsque le temps est expiré le bras soulève le sachet hors de la tasse et sonne l'alarme. De cette façon même si je suis occupé à autre chose et ne peu me déplacer immédiatement pour sortir le sachet de la tasse, le retrait automatique du sachet évite d'avoir à boire un thé trop concentré au goût amer.

Analyse du problème

Il faut donc un chronomètre et un bras motorisé. Il faut un bouton pour ajuster le temps et un affichage pour indiquer la durée. Il n'est pas nécessaire d'avoir une précision à la seconde. J'ai donc décidé que le temps pouvait-être incrémenté par multiple de 15 secondes. Pour l'affichage une barre de LED à 10 segments sert à indiquer le temps. Chaque segment représente un multiple de 15 secondes pour une durée maximale de 150 secondes. Un deuxième bouton sert à démarrer le chronomètre. Lorsque le temps est écoulé le sachet est retiré de la tasse, l'alarme sonne et finalement le microcontrôleur est mis en sommeil (sleep mode). L'interface utilisateur est donc simple, 2 boutons et un affichage barre de LED.

La procédure d'utilisation de l'appareil est la suivante:

  1. Attacher le sachet de thé au bras et placé la tasse sous le sachet.
  2. Peser sur le bouton MARCHE/ARRET pour sortir le MCU du mode sommeil. La mise en marche est signalée par un BEEP.
  3. Ajuster le temps avec le bouton TEMPS
  4. Peser à nouveau sur le bouton MARCHE/ARRET pour démarrer la séquence d'infusion.
Pendant l'infusion il est possible d'annuler en pesant à nouveau sur le bouton MARCHE/ARRET . Ce bouton est donc multi fonctions.
  • Allumer l'appareil
  • démarrer la séquence d'infusion
  • Annuler la séquence d'infusion

Le choix du microcontrôleur.

Rapidement dans ma réflexion j'ai choisi d'utiliser un servomoteur Hitec HS-422 que j'avais en ma possession ainsi que la barre de segments LED pour la même raison. Il me restait à choisir un microcontrôleur. le servomoteur se contrôle avec des impulsions dont la largeur varie entre 2,1 et 2,9 millisecondes. Ces impulsions doivent-être répétées 50 fois par secondes. Un périphérique PWM est tout désigné pour ce travail.

Pour l'alarme un petit haut-parleur alimenté par une tonalité ou une séquence de tonalités de fréquence différente peut-être utilisé. Encore là un périphérique PWM est tout désigné pour générer les tonalités.

Pour les 2 boutons il suffit de 2 entrées digitales.

Pour l'affichage des entrées/sorties 3 états (sortie 5 volt,sortie 0 volt, haute impédance) sont nécessaires. On peut cependant réduire le nombre nécessaire en utilisant une méthode de multiplexage appelée Charlieplexing. Le nombre de LEDs qui peuvent-être multiplexés par cette méthode est de N*(N-1). Où N est le nombre de broches utilisées. Avec 4 broches 3 états (tristate) on peut donc contrôler 12 LEDs. La barre en a 10.

On a donc besoins d'un MCU qui dispose de 2 périphériques PWM et d'au moins 8 E/S numériques et au minimum 2 minuteries, une pour les PWM et pour servir de chronomètre. Rien de plus que ça. Le plus petit PIC16F1xxx qui possède ces caractéristiques doit-être disponible dans un boitier PDIP 14 broches.

Les générations PIC 8 bits

Il y a 4 générations de PIC 8 bits. Les baseline mis en marché en 1990, les mid-range, les enhanced mid-range et finalement les extended c'est à dire les PIC18Fxxxx.

La famille enhanced mid-range est celle qui offre la plus grande variété de produits hormis les PIC18F qui sont inutilement coûteux pour ce projet. De plus il n'y a aucun PIC18F qui viens en format PDIP-14. Les enhanced mid-range ont 4 chiffres après le F, i.e. PIC1y(L)F1xxx où y est soit 2 ou 6.

En utilisant le sélecteur de MCU sur le site WEB de Microchip j'ai trouvé un bon candidat pour le rôle, le PIC16F1703. Voilà un petit MCU intéressant.

PIC16(L)F1703
mémoire flash 2048 instructions.
mémoire RAM 256 octets
11 entrées/sorties 3 états. 1 entrée seulement RA3/~MCLR/Vpp
Analog-to-Digital Converter (ADC) 10 bits
Fixed Voltage Reference (FVR)
Zero-Cross Detection (ZCD), utile dans les applications de contrôle de voltage AC. i.e thermostat, atténuateur d'éclairage.
Temperature Indicator
2 Capture/Compare/PWM (CCP/ECCP) Modules
Master Synchronous Serial Ports MSSP
2 Op Amp
Timer0, 8 bits avec pré-diviseur
Timer1, 8 bits avec gating et clocking externe
Timer2, 16 bits avec pré et post diviseur. Contrôle la période des CCP
Pour ce projets seul sont utilisés les 2 CCP et les 3 minuteries.

Schématique du projet

Voici la schématique du circuit produit avec KiCAD version 4.0.3.

Le montage est fait sur 2 cartes Schmartboard bread/proto 400 points, l'une pour le MCU et l'autre pour l'interface utilisateur. J'ai utilisé 6 broches pour le charlieplexing des LEDs au lieu de 4. Ces broches correspondes aux 6 broches du PORTC disponibles sur ce MCU. Puisqu'il n'y avait pas d'usage pour les 2 broches supplémentaire aussi bien les utilisées. Seule RA0 demeure inutilisée (sauf pour la programmation ICSP).

Assignation des ressources du MCU

ressource utilisation
TIMER0 Cette minuterie 8 bits est configurée pour chronométrer les délais cours par incrément de 4msec. Lorsqu'elle est active cette minuterie génère une interruption à intervalle de 4 millisecondes.
TIMER1 Cette minuterie 16 bits est configurée pour chronométrer les durées en secondes. Lorqu'elle est active cette minuterie génère une interruption à intervalle d'une seconde. C'est la minuterie utilisée pour contrôler la durée de l'infusion.
CCP1 (Capture/Compare/PWM) Ce périphérique est utilisé en mode PWM pour générer des tonalité audio-fréquence. Utilisé par la routine tone.
CCP2 Ce périphérique est utilisé en mode PWM pour génerer les impulsions de contrôle du servomoteur. La période est de 20 msec et la largeur des impulsions varie entre 2,1 et 2,9 msec par incrément de 32µsec.
PORTA RA5 entrée bouton MARCHE/ARRET
RA4 entrée bouton TEMPS
RA2 sortie PWM contrôle servomoteur
RA1 sortie PWM son
PORTC RC0-RC5 E/S 3 états pour le Charlieplexing des LEDS

Le logiciel

Le code source est écris entièrement en MPASM. Les enhanced mid-range possède un jeux de 49 instructions. Cette génération représente une amélioration considérable par rapport au 2 précédentes. Voici quelques comparaisons.

paramètremid rangeenhanced
pile8 niveaux16 niveaux. Peut-être manipulée.
FSRxFSR0 seulementFSR0,FSR1
interruptionsauvegarde/restauration manuel du contextesauvegarde/restauration automatique du contexte
accès RAMsegmentée seulementsegmenté ou linéaire indirecte
adressage indirectpas d'auto incrément/décrément. pas d'index relatifpour les instruction moviw et movwi pré/post incrément/décrément. index relatif.
branchement relatif à PC Pas de branchement relatif. Branchement relatif avec les instructions BRA et BRW
Il est plus intéressant de travailler avec les enhanced mid-range qu'avec les générations précédentes et pour la programmation en C le compilateur peu plus facilement optimiser le code binaire.

ordinogramme de l'application

Voici l'ordinogramme (flowchart) de l'application.

Pour la présentation qui suis référez-vous au fichier mat.asm

Initialisation du MCU

Chaque MCU fourni par Microchip a un fichier *.inc qui lui est associé. La première chose à faire est d'inclure ce fichier avec la directive


include p16f1703.inc
Ensuite il faut configurer les paramètres de fonctionnement du MCU avec la directive __config. Puisque ce MCU a 2 locations de configuration _CONFIG1 et _CONFIG2 il faut une directive pour chacun. L'oscillateur interne est utilisé, le watch dog timer est désactivé et le master clear est activé. Pour la signification des constantes se référer au fichier p16f1703.inc. Elles sont définies à la fin du fichier.

Je définis toujours les constantes, les macros et les variables au début du fichier. Je fais un usage abondant de la directive #define. L'usage de noms symboliques spécifiques à l'application simplifie les mises à jour ultérieures.

Puisque le programme utilise moins de 16 octets de variables elles sont toutes placées dans la section udata_shr ce qui évite d'avoir à utiliser des directives banksel lorsqu'on veut accéder une variable. Il en résulte un code plus compacte et plus rapide. udata_shr correspond aux 16 dernières locations de chaque banque de la mémoire RAM. C'est 16 locations sont communes à toutes les banques. Voilà pourquoi on a pas besoin de la directive banksel pour les accédées.

Lorsqu'un PIC est réinitialisé l'exécution du code commence à l'adresse 0. le vecteur d'interruption lui est à l'adresse 4. On doit donc faire un saut au delà de la routine d'interruption pour aller à init:. J'ai commenté chaque étape de l'initialisation il ne devrait donc pas être facile de suivre le cheminement. Une des fonctions intéressante du PIC16F1703 est le PPS (Peripheral Pin Selsect). Qui permet de décider soit-même sur quelle broche on veut brancher les périphériques logiques, (ça ne s'applique pas aux analogiques, i.e. op amp, comparateurs, entrées ADC). Donc j'ai sélectionné la broche RA1 pour la sortie CCP1 (alarme) et la broche RA2 pour la sortie servomoteur CCP2.

Le TIMER0 est configuré pour générer une interruption à intervalle de 4 millisecondes et le TIMER1 est configuré pour générer une interruption à intervalle d'une seconde. J'explique la sous-routine d'interruption plus bas.

Auto test de mise sous tension

Lorsque la configuration du MCU est complétée une routine d'auto test à l'allumage est appelée. self_test: allume tous les segments de la barre de LEDs l'un après l'autre en commençant par le haut et fait entendre une tonalité différente à chaque segment. Ensuite self_test abaisse le bras et le relève. Ce test n'est effectué qu'une fois lors de la mise sous tension de l'appareil.

mise en sommeil

Après l'exécution de l'auto test le code tombe dans la routine main. Cette routine débute par une mise en sommeil du MCU pour réduire la dépense électrique lorsqu'il n'est pas utilisé. Le MCU utilise la fonction IOC (Iinterrupt On Change) pour sortir le MCU du sommeil. A chaque PORT est associé 2 registres de configuration IOCxP pour détecter les transitions positives (0 -> 5 volt) et IOCxN pour les transitions négatives (5 -> 0 volt). Cette fonction consiste à générer une interruption lorsqu'une broche configurée en entrée logique change d'état. Dans cet application on configure pour que le MCU s'éveille lorsque le bouton MARCHE/ARRET est enfoncé. Alors la broche START_PIN passe de 5 volt à 0 volt. L'interruption n'est cependant pas activée. Ce n'est pas nécessaire. Lorsque le MCU sort du mode sommeil il exécute l'instruction qui suis l'instruction sleep qui l'a fait entrer en mode sommeil.

La configuration IOCAN est désactivée et ensuite la mise en marche est annoncée par un BEEP. Après quoi la routine timeset est appelée.

Ajustement du chronomètre

L'utilisateur doit alors utiliser le bouton TEMPS pour ajuster la durée de l'infusion. Chaque pression du bouton incrémente le temps de 15 secondes. Cette routine fait donc la lecture des 2 boutons et met à jour l'affichage LED. Lorsque le bouton MARCHE/ARRET est enfoncé un branchement vers timeset_exit met fin à cette routine.

infusion

De retour dans la routine main le registre WREG est chargé avec la valeur SERVO_POS_BAS et la routine servo_pos est appelée. Cette routine est responsable du déplacement du bras. Il ne s'agit pas de simplement envoyer la nouvelle valeur de position au servomoteur car le bras descendrait trop rapidement et ça risquerait de produire des éclaboussures. Donc la valeur de la dernière position est conservée dans la variable last_pos et il s'agit de s'approcher de la nouvelle valeur étape par étape en partant de la valeur de last_pos en insérant un délais entre chaque commande. La valeur de ce délais est indiquée par la constante SERVO_DLY.

Lorsque le positionnement est terminé la routine quitte et de retour dans main la routine infusion est appelée. Cette routine est responsable de surveiller le chronomètre, d'afficher la valeur du temps restant et aussi faire la lecture du bouton MARCHE/ARRET a cas ou l'utilisateur annulerait la procédure. Lorsque le temps est expiré ou s'il y a annulation le routine retourne vers main

fin de l'infusion

Une nouvelle commande est envoyée au servomoteur cette fois avec la valeur SERVO_POS_HAUT comme argument dans WREG. De retour de la routine servo_pos, main appelle la routine alarm. La routine alarm: joue la séquence de notes enregistrées dans la table CE3K ensuite retourne vers main. La séquence étant terminée on boucle au début de main et le MCU est remis en sommeil.

sous-routine d'interruption

Les MCU PIC 8 bits n'ont pas de gestionnaire d'interruption. Toutes les interruptions commence à l'adresse 4. Pour savoir qu'elle interruption a été déclenchée il faut vérifier les indicateurs d'interruption. Dans cette application il y a 2 sources d'interruption possible, le TIMER0 et le TIMER1. On commence par vérifier si l'interruption TIMER0 est active en testant l'état du bit T0IE dans INTCON si cette interruption est active on test T0IF qui est aussi dans INTCON pour s'assurer que le TIMER0 est bien la source de l'interruption. Si c'est le cas on branche vers isr_timer0. TIMER0 est responsable de la gestion de la minuterie courte durée. Cette interruption lorsqu'elle est active se produit à intervalle de 4 msec et décrémente la variable msec4. Lorsque msec4 tombe à zéro c'est que le délais est expiré. Dans ce cas l'interruption TIMER0 est désactivée et l'indicateur booléen F_MSEC4 dans la variable flags est remis à zéro.

Si l'interruption a été générée par le TIMER1 le branchement se fait vers isr_timer1. Cette interruption lorsqu'elle est active est déclenchée à intervalle d'une seconde. La variable secondes est décrémentée à chaque interruption et lorsque sa valeur tombe à zéro l'interruption du TIMER1 est désactivée et l'indicateur booléen F_SEC dans la variable flags est mis à zéro.

Les routines qui utilisent l'une ou l'autre des minuteries, doivent les initialiser en appelant start_msec4_tmr pour la minuterie courte durée ou bien start_timer pour démarrer la minuterie longue durée. Ensuite la routine surveille l'état de l'indicateur booléen correspondant dans flags pour savoir quand le délais est expiré.

Pour les enhanced mid-range les registres suivants sont sauvegardés et restaurés automatiquement lors d'une interruption: WREG,STATUS,BSR,PCLATH,FSR0L,FSR0H,FSR1L,FSR1H. Ces registres sont sauvegarder dans les registres xxxx_SHAD situés dans la banque 31.

Utilisations des FSRx

le registre d'index FSR0 est utilisé pour accéder les tables de données en mémoire flash. Le programme utilise 3 tables de données.

tabledescription
LED_CONNCette table indique sur qu'elles broches est branchée la cathode et l'anode de chacun des 10 segments de la barre-LED. Cette table est utilisée par la routine light_segment.
SCALECette table contient les valeurs pour chaque note de la gamme tempérée utilisé par la routine tone. Les tonalités sont générées en utilisant CCP1 en mode PWM. Les valeurs de cette table vont dans PR2 et dans CCP1DCL:CCP1CON{DC1B} pour déterminer la fréquence et le rapport cyclique.
CE3KCette table contient la liste des notes à jouer par la routine alarme. Le premier élément est le nombre de notes. Les autres sont par paire: durée, note.

Le registre d'index FSR1 est utilisé comme pointeur de pile pour créer une pile d'arguments pour les appels de sous-routine. Pour les routines qui n'utilisent qu'un seul argument de 8 bits cette valeur est passée dans le registre WREG. Mais pour les autres les arguments sont passés par la pile des arguments. la variable stack dans le segment udata réserve 16 locations pour cette pile. Cette pile utilise avantageusement les instructions moviw et movwi pour gérer les accès à cette pile. Une série de macro a été définie à cette effet.

macros gestion de la piledescription
pushw empile le contenu du registre WREG
popw dépile dans WREG
dup cré une copie du sommet de la pile, de sorte que la pile grandie de 1 élément et que les 2 éléments au sommet sont identiques.
over copie le 2ième élément de la pile au sommet de celle-ci de sorte que la pile grandie de 1 élément et que la valeur au sommet est identique à la 3ième valeur.

Liste des sous-routines

sous-routine arguments Description
alarm aucun fait jouer la liste des notes de la table CE3K. Appel sous-routine tone.
beep aucun fait entendre un son court lorqu'un bouton est enfoncé. Appel sous-routine tone.
div15 WREG contient le dividende
Divise le contenu de WREG par 15. Le quotient est retourné dans la variable ACAH et le reste dans ACAL.
infusion aucun surveille la minuterie des secondes ainsi que les 2 boutons. Met à jour l'affichage LED selon le temps restant. Appel start_timer, div15, light_segment
init aucun Initialise les périphériques du MCU après la réinitialisation.
isr aucun sous-routine de service des interruptions. Gère les interruptions des TIMER0 et TIMER1.
main aucun boucle principale du programme.
light_segment WREG contient le numéro du segment à allumer Allume le segment indiqué par la valeur indiqué dans WREG. Accède la table LED_CONN.
pause_msec WREG contient la durée de la pause. Suspend l'exécution pour la durée indiquée dans WREG*4 millisecondes. Appel la sous-routine start_msec4_tmr.
self_test aucun auto test lors de la mise sous tension. Appel les sous-routines light_segment,tone,servo_pos.
servo_pos WREG contient la valeur de positionnement. Positionne le servomoteur à la valeur indiqué dans WREG.
start_msec4_tmr WREG contient la durée. Démarre la minuterie courte durée avec la valeur WREG*4 millisecondes
start_timer WREG contient la durée. démarre la minuterie longue durée avec la valeur WREG secondes.
tone arguments passés sur la pile. ( d n -- ) Fait entendre une tonalité. Le sommet de la pile contient l'indice de la note dans la table SCALE et le deuxième élément de la pile indique la durée en multiple de 4 msec. Appel sous-routine pause_msec.

pixdel version 6

$
0
0

Le 6 juin 2012 je publiais sur ce blog un article concernant l'idée du pixdel. Le mot pixdel lui-même est une contraction des mots pixel qui représente un point lumineux sur un écran et DEL qui est l'acronyme de Diode Electro-Luminescente. L'idée originale utilisait un PIC10F202 et une DEL RGB (Red/Green/Blue). Il s'agissait de connecter ces dispositifs sur un bus commun afin de les contrôler individuellement. A l'époque je ne sais pas si les WS8212 existaient. Si c'est le cas j'en ignorais l'existence. Quoi qu'il en soit le pixdel est basé sur une topologie bus1 alors que les WS8212b sont basés sur une topologie chaîne2.

Pixdel version 6

Je viens de développer la verion 6 du pixdel suite à une réflexion sur l'inefficacité du protocole de communication utilisé par les WS8212. En étudiant le protocole de communication des WS8212 je me disait qu'il devait bien y avoir protocole de communication plus efficace que celui-là. La version 6 du pixdel utilise donc comme les W8212 une topologie chaîne puisque l'idée était de tester cette topologie que j'ai imanginé. Je vais donc expliquer comment fonctionne le protocole utilisé avec les WS8212 et ensuite le protocole que j'ai imaginé.

protocole de communication WS8212

La durée d'un bit est de 1,25µSec. Les zéro sont différenciés des 1 par le rapport cyclique. Voici là table des durées selon le datasheet.
Data transfer time (TH+TL=1.25μs±600ns)

T0H0 code ,high voltage time0.4us ±150ns
T1H1 code ,high voltage time0.8us ±150ns
T0L0 code ,low voltage time0.85us ±150ns
T1L1 code ,low voltage time0.45us ±150ns
RESlow voltage timeAbove 50μs

Cette table indique la durée de chaque bit. chaque couleur est contrôlée par un octet il faut donc envoyé 24 bits pour contrôler la couleur d'un WS8212. RES représente un silence obligatoire entre chaque liste de commande. En effet comment un WS8212 sait-il que la commande lui est adressée?

En chaque WS8212 garde le premier paquet de 24 bits qu'il reçoit après un RES et fait suivre tous les autres au suivant. Donc s'il y a 10 WS8212 dans la chaîne et qu'on veut changer la couleur du dixième on doit envoyer une liste de 10x24bits et il ne doit pas y avoir de RES entre chaque groupe 24 bits sinon les WS8212 vont réinitialisés et le premier va garder les 24 bits suivants parce que pour lui se sont les 24 premiers.

Ce protocole de communication est contraignant pour le contrôleur. Non seulement il doit garder en mémoire l'état de chaque WS8212 mais il doit réenvoyé la séquence au complet même si seul le dernier de la chaîne change de couleur.

protocole de communication pixdel version 6

J'ai donc réfléchi à ça en me disant qu'on pouvait surement faire mieux et une solution m'est apparue rapidement. Pourquoi ne pas envoyer un compteur dans l'entête de chaque commande! Voiçi comment ça fonctionne.

D'abord la résolution PWM des pixdels version 6 est de 16 bits/composante (8 bits/composante pour les WS8212) ce qui permet un contrôle très précis de la couleur. Le paquet de commande est donc de 7 octets au lieu de 3. Le compteur de 8 bits plus 3x16 bits pour les composantes rouge/verte/bleue. La communication est en RS-232 à niveau TTL à une vitesse de 115200 BAUD.

format du paquet: COMPTEUR|RH|RL|GH|GL|BH|BL

  1. COMPTEUR, compteur de 8 bits permettant de contrôler une chaîne d'une longueur maximale de 255 pixdels. La valeur 0 est réservée pour les messages de diffusion.
    Si un pixdel reçoit un compteur à 0 il accepte la commande et la retransmet au suivant tel quel. Donc tous les pixdels vont accptés cette commande. Si le compteur est à 1 le pixdel accepte la commande mais ne la retransmet pas. Finalement si le compteur a une valeur entre 2 et 255, le pixdel décrémente le compteur et fait suivre le paquet au suivant.
  2. RH, octet fort de la composante rouge.
  3. RL, octet faible de la composante rouge.
  4. GH, octet fort de la composante verte.
  5. GL, octet faible de la composante verte.
  6. BH, octet fort de la composante bleue.
  7. BL, octet faible de la composante bleue.

Avantages

  • Le contrôleur n'a pas besoin de mémoriser les valeurs de chaque pixdel de la chaîne.
  • N'importe quel pixdel de la chaîne peut-être contrôler par l'envoie d'un seul paquet de 7 octets en initialisant le compteur avec la position du pixdel ciblé dans la chaîne. Par exemple si on veut changer la couleur du 50ième maillon de la chaîne on initialise le compteur à 50.
  • En initialisant le compteur à 0 on peut mettre tous les pixdel de la chaîne dans le même état en envoyant 1 seul paquet de 7 octets.
  • Ce protocole de communication est très souple et peut-être adapté à d'autres applications. Par exemple on pourrait utiliser un compteur de 16 bits pour contrôler une chaîne d'une longueur maximale de 65535 maillons. Dans une autre application la communication pourrait-être faite par SPI,I2C ou autre méthode sérielle.

Démontration

Pour vérifier mon idée j'ai fait un montage sur carte sans soudure comprenant 3 pixdelv6 que j'ai contrôlé à partir mon ordinateur via un port série. Le schéma de chaque pixdelv6 est le suivant:

Le MCU PIC12F1572 est parfait pour cet application puisqu'il possède 3 périphérique PWM ayant une résolution de 16 bits ainsi qu'un périphérique EUSART pour la communication.

photo du montage

Le firware est disponible sur https://github.com/picatout/pixdel6.

Vidéo de démonstration


notes

  1. Dans la toppologie BUS tous les dispositifs sont connectés sur le(s) même(s) fils. Afin d'adresser individuellement chacun d'eux il faut que chacun possède un identifiant unique et que celui-ci soit inclus dans le message. Exemple l'adresse MAC des cartes réseaux. L'adresse MAC est incluse dans l'entête du paquet ethernet.
  2. Dans la topologie en chaîne le message est transmis à un seul dispositif qui à son tour le retransmet au suivant dans la chaîne si le message de lui est pas adressé. Les dispositifs de la chaîne peuvent avoir un identifiant unique ou non. Dans le cas des WS8212b les DEL RGB n'ont pas d'identifiant un autre mécanisme d'adressage est utilisé.

tetris pad

$
0
0
Il est possible de réaliser des jeux vidéo simple même sur petit MCU qui n'a qui 6 E/S et 3.5Ko de flash et 256 octets de RAM. Ce projet en est la démonstration il s'agit du célèbre jeux tetris inventé en 1986 par Alekseï Pajitnov. Au départ j'ai conçu ce jeux dans la perspective de participer à un défi organisé par http://hackaday.com, le 1KB challenge. Mais j'ai échoué à atteindre l'objectif et je n'ai donc pas soumis le projet. En effet je n'ai pas réussi à réduite la taille du programme pour qu'il réponde au critère du 1KO. Toute la documentation et le code source sont sur github. Puisque ce projet était dédié à un site anglophone exceptionnellement tous les commentaires dans le fichier source sont en anglais. Mais je vais en faire une description dans ce qui suis.

Matériel

Le tetris_pad peut-être réalisé économiquement et rapidement. il y a un minimum de composants.

  • 1 PIC12F1572
  • 1 Oscillateur à crystal de 20Mhz CTS MXO45HST
  • 1 porte pile pour pile CR2450
  • 7 mini boutons poussoir à contact momentanés. Robotshop p/n: RB-DFR-448, 5/pkg
  • 2 embase DIP 8 broches. 1 pour le MCU et l'autre pour l'oscillateur. (optionnel).
  • 1 mini commutateur SPDT. Robotshop p/n RB-SPA-155
  • 1 LED 3mm rouge.
  • 2 connecteur phono RCA
  • 1 connecteur 6 broches espacement 100mil. pour brancher le Pickit 3.
  • 1 transistor 2N700.
  • 1 condensateur électrolytique 220µF/25Volt.
  • 3 condensateurs céramique 100nF/16Volt.
  • 1 condensateur céramique 1µF/16Volt.
  • 7 résistances 1Kohm 1/8 watt.
  • 1 résistance 22Kohm 1/8 watt.
  • 1 résistance 470ohm 1/8 watt.
  • 1 résistance 330ohm 1/4 watt.
  • 1 résistance 180ohm 1/4 watt.
  • 1 résistance 10Kohm 1/8 watt.
  • 1 résistance 100Kohm 1/8 watt.
  • 1 résistance 1Mohm 1/8 watt.
  • 1 résistance 620ohm 1/4 watt.
  • 1 résistance 82ohm 1/4 watt.
  • 1 pile bouton au lithium CR2450.
  • 1 carte de prototypage en bakélite de 7cm x 9cm. Robotshop p/n: RB-ADA-229, 10/pkg

schématique

prototype

Plusieurs des composants sont invisibles sur cette photo car en format CMS et soudés directement sur les pastilles qui se trouvent sur l'autre face de la carte.

code source

Le programme est écris en assembleur et occupe 1051 mots flash (1839 octets)dans sa version actuelle. Le fichier source est tetris.asm. Au début du ficher on retrouve les 2 lignes suivantes:


#define SOUND_SUPPORT
#define ANIMATION
Si la ligne qui défini SOUND_SUPPORT est mise en commentaire le code lié à cette fonction ne sera pas assemblé.
Si le ligne qui défini ANIMATION est mise ne commentaire le code d'animation de fin de parti ne sera pas assemblé. j'espérais en supprimant ces 2 éléments optionnels pouvoir répondre au critère du 1KO mais j'en étais encore très loin à environ 1500 octets.

La majorité des constantes utilisées par le programme sont définies entre les lignes 14 et 96.

la pile des arguments

Lorsque je programme les PIC enhanced mid-range en assembleur j'utilise le registre FSR1 comme pointeur pour une pile de passage des arguments aux sous-routines ainsi que pour les variables locales. Pour faciliter l'utilisation de cette pile je cré un ensemble de macros qui se trouve entre les lignes 153 et 217 du fichier tetris.asm.

Structure du progamme

  1. rst: point d'entrée lors de la réinitialisation du MCU. Cette routine fait un saut vers init: qui s'occupe d'initialiser les périphériques.
  2. isr: point d'entrée de la routine de service des interruptions. Il n'y a qu'une seule interruption sur la minuterie du périphérique PWM responsable de générer la synchronisation vidéo. La routine isr: contient aussi un céduleur de tâches de type round robin. lorsque c'est le temps de générer le signal vidéo cette routine appelle la sous-routine video_serialize: responsable d'envoyer les pixels à l'écran.
  3. init: s'occupe de l'initialisation de tous les périphériques avant de passer à game_init:.
  4. game_init: initialise l'environnement du jeux tetris proprement dit avant de débuter la partie au point d'entrée tetris:
  5. tetris:débute la logique du jeux. le jeux s'exécute en boucle jusqu'à la fin de la partie à l'intérieur de game_loop:
  6. A la fin du fichier sont rassemblées les tables de données enregistrées en mémoire programme. On y retrouve les glyphes des chiffres 0-9 ainsi que des lettres utilisées par les labels, table digits. Les glyphes des tetriminos suivent. Les tables pour les 3 textes apparaissant à l'écran. les valeur de périodes pour la gamme tempéré et finalement la partition de la mélodie korobeiniki. Puisque ce jeux a été inventé en Russie cette mélodie qui appartient à son folklore est appropriée.

utilisation de la console

Notez la disposition des boutons. A droite les 4 boutons disposés en losange. Celui du haut fait tourner le tetrimino vers la droite. Celui du bas le fait tourner dans le sens contraire. Les boutons de gauche et de droite sont pour les déplacements horizontal du tetrimino.

Il y a 2 boutons à gauche du pad. Celui du bas s'appelle A et sert à démarrer la partie. La mélodie korobeiniki est jouée en boucle en attente d'une pression sur de bouton. Le bouton au dessus de A est le bouton B. Il a 2 fonctions. lorsque la mélodie joue ce bouton force le silence. Pendant la partie le bouton B sert à faire tomber rapidement un tetrimino lorsqu'on juge qu'il est bien positionné. On peut aussi avorter rapidement une partie en le gardant enfoncé. Lorsque le puit est plein la partie est terminée. Une animation vide le puit vers le bas avant de présenter le message PRESS A pour une nouvelle partie.

Le pointage est compté en puissance de 2. C'est à dire que faire disparaître:
1 ligne vaut 2 points.
2 lignes 4 points.
3 lignes 8 points.
4 lignes 16 points.
L'affichage indique le pointage et le nombre total de lignes qui ont été détruites durant la partie.

Démonstration

Voici un bref vidéo de démonstration de tetris_pad. A la fin on peut attendre le joueur soupiré face à sa piètre performance.

interface pour clavier PS/2

$
0
0

J'utilise régulièrement un clavier dans mes projets et comme j'utilise une variété de MCU je dois réécrire l'interface pour le clavier. J'ai donc décidé de régler ce problème une fois pour toute en créant un module d'interface clavier que je vais inséré dans tous mes projets qui utilisent un clavier. Je sauverai ainsi du temps et de l'espace de code sur le MCU principal du projet. Ce module d'interface est très économique puisqu'il utilise un petit MCU en format DIP-8 soit le PIC12F1572. Le montage est très simple.

  • 1 MCU PIC12F1572
  • 2 condensateurs céramique 100nF/16v
  • 2 résistances 15Kohm 1/4watt.
  • 1 connecteur MINI-DIN 6 broches pour le clavier. On peut aussi utiliser un connecteur USB type A
Le code source est disponible sur https://github.com/Picatout/ps2_rs232

fonctionnement

Le PIC12F1572 reçoit les codes du clavier et fait la conversion en code ASCII qu'il envoie à l'hôte via le périphérique EUSART configuré en mode asynchrone. l'envoie se fait à 9600BAUD sans parité. Ce module d'interface n’accapare donc qu'un seule broche sur le MCU principal ainsi qu'un périphérique USART pour la réception. Le code à écrire sur l'hôte est des plus simple puisqu'il s'agit simplement de recevoir les codes ASCII et lest ranger dans une file d'attente FIFO pour les besoins de l'application. Les touches d'altérations SHIFT,CTRL,ALT,CAPS,NUM sont traitées par le PIC12F1572. Les relâchement de touches sont ignorés.

quelques notes sur l'utilisation des claviers

Les claviers que j'utilise sont des claviers d'ordinateurs personnels soit de type PS/2 ou USB. Les claviers USB adoptent automatiquement l'interface PS/2 lorsque les lignes DAT+ et DAT- sont connectées à des résistances pullup. Dans ce cas DAT+ devient le signal CLOCK et DAT- devient le signal DATA.

diagramme connection interne d'un adapteur USB-A vers MINI-DIN-6.
Même si les claviers indique une alimentation de 5VDC ceux que j'ai essayés fonctionnent très bien à 3VDC. Ce n'est pas vraiment étonnant puisque le MCU qui se trouve dans le clavier est certainement en technologie CMOS, à moins qu'il s'agisse d'un très vieux clavier.

L'interface PS/2 est une interface synchrone, c'est à dire qu'il y a un signal clock et un signal data. L'hôte doit lire le bit lorsque le signal clock est à zéro volt. C'est le clavier qui contrôle le signal clock. Bien qu'il s'agisse d'une interface synchrone elle peut-être utilisée en mode asynchrone car le signal data a le mêm format qu'un signal RS-232. C'est à dire qu'il y a un start bit à 0 suivit de 8 bits de data, d'un bit de parité impaire et d'un stop bit. Tout les claviers que j'ai essayé transmettait à 12,500 BAUD (une valeur non standard). Cependant si le clavier est utilisé en mode asynchrone l'hôte ne peut lui envoyer des commandes. Car il faut savoir que l'interface PS/2 est à double sens. L'hôte peut prendre le contrôle de l'interface en bloquant la ligne clock à 0 pour une durée minimum de 100µsec. L'interface décrite ici utilise l'interface PS/2 complète, c'est à dire que le PIC12F1572 envoie des commandes au clavier, soit pour le réinitialiser soit pour contrôler les LEDs du clavier.

Autre paramètre à considérer, l'interface fonctionne en mode drain ouvert d'où l'utilisation des 2 résistances pullup. Ceci est intéressant car même si le clavier est alimenter à 5 volt et que le MCU est alimenté à 3 volt il n'y a pas de risque d'endommager le MCU. Le seul courant qui passe vers le MCU hôte passe à travers des résistances pullup qui sont de 15Kohm. Supposons que les deux entrées du MCU sont configurées en entrées. Le courant passe du 5volt à travers la résistance de 15Kohm et à travers la diode de protection d'entré du MCU vers le 3volt. Le courant qui va circulé dans cette diode est donc de (5-3)/15000=133µA. Aucun risque d'endommager la diode de protection.

Les broches du PIC12F1572 sont configurables on mode drain ouvert ce qui rend encore plus sécuritaire l'interface entre le MCU et le clavier. On peut donc alimenter le clavier et les 2 résistances en +5VDC et le MCU en +3VDC sans que ça pose problème.

codes ASCII et supplémentaire

La table ASCII standard est limitée à 128 codes. Il n'y a pas de provision pour les touches spéciales du claviers tel que les touches de fonctions, les flèches, etc. Le firmware du PIC12F1572 convertis ces codes en une série de valeurs comprises entre 128 et 255. Pour connaître la liste de ces touches consulter la page github du projet.

ForthEx (partie 1)

$
0
0

Dans cet article je présente un projet que j'ai débuté en septembre 2015 puis mis sur pause pour le reprendre en octobre 2016. Depuis j'y travaille régulièrement de sorte que le projet est maintenant suffisant avancé pour considérer ForthEx, un petit ordinateur basé sur système forth, comme fonctionnel.

Origine du projet

En septembre 2015 j'ai trouvé un document pdf dans l'internet écris par Charles Moore créateur du langage forth. Dans ce document Charles Moore explique la construction d'un système forth à partir de rien (bare metal programming). C'est à dire en programmant la machine d'abord en assembleur puis lorsque le minimum requis en assembleur est fonctionnel continuer le développement en utilisant forth lui-même.

Après avoir lu ce document je me suis dis que ce serais intéressant de tenter cette expérience. Il me fallait donc une base matériel c'est à dire un ordinateur pour faire le travail. J'aurais pu prendre un vieux PC mais dans un vieux PC il y a déjà le BIOS d'installé. Je voulais vraiment partir de zéro au point de vu logiciel. J'ai donc conçu un petit ordinateur simple et peu coûteux en utilisant un MCU 16 bits de Microchip. Nommément le PIC24EP512GP202-I/SP. Il s'agit d'un microcontrôleur 16 bits, le même que j'ai utilisé pour le projet PV16SOG.

À partir de cette plateforme matérielle j'ai commencé à construire le système en assembleur et en forth jusqu'à ce que j'arrive à un système utilisable en autonome.

ForthEx

C'est le nom que j'ai donné à ce petit système forth. Ce nom englobe la plateforme matérielle et le système logiciel embarqué. Les caractéristiques de cet ordinateur sont les suivantes:

  • périphériques:
    • clavier d'ordinateur avec connecteur USB.
    • Sortie vidéo composite NTSC ou PAL monochrome
      mode texte 25 lignes de 64 caractères.
    • port de communication RS-232.
    • sortie audio simple tonalité.
  • stockage persistant:
    • Mémoire FLASH du MCU environ 475Ko disponible pour l'utilisateur.
    • Mémoire EEPROM externe avec interface SPI de 128Ko.
    • Carte SD et SDHC.
  • Extension RAM externe avec interface SPI de 128Ko.
  • système forth incluant presque la totalité du vocabulaire core et core extension du standard ANSI 2012, plus le vocabulaire spécifique à ce système. Bien que le système ne soit pas encore complété le mot WORDS affiche présentement 367 mots. Il y en a plus que ça dans le dictionnaire car certains mots utilisés par le compilateur sont caché à l'utilisateur.

Plateforme matérielle

On a donc le processeur principal PIC24EP512GP202-I/SP. Comme le clavier fonctionne à 5 volt il faut 2 régulateurs de tension 5 volt pour le clavier et le PIC12F1572 et 3,3 volt pour le reste du circuit. Pour le détail de l'interface clavier il faut consulter le projet interface pour clavier ps2. Notez que même si un clavier USB est utilisé il fonctionne en mode PS2. En effet de par la façon dont les lignes D- et D+ sont connectés à des pullup le MCU du clavier reconnaît qu'il s'agit d'une configuration PS2 et non USB.

Ce petit ordinateur est donc très peu coûteux à fabriqué car il utilise un minimum de composants. On peut même laisser tomber certains composants comme l'extension RAM externe et/ou la l'EEPROM externe. Une autre option serait de laisser tomber l'interface pour la carte SD et à la place utilisé seulement des EEPROM SPI enfichable pour le stockage persistant.

Le prototype est assemblé sur une carte à pastille avec trous passants (pastilles sur les 2 faces). Il s'agit d'une carte Vector electonics modèle 8015 de 4" x 6" ( 10cm x 15cm). Ce n'est pas très long à assembler. Le gros du travail c'est l'écriture du système logiciel.

Liste matérielle

Reference

 Value

R11

4k7

R8

120R

R10

680R

P1

ICSP

R7

470R

R6

10K

C7

100nF

SW2

reset

C8

100nF

C11

100nF

C12

47µF

X1

8Mhz

C6

18pF

C4

18pF

C13

100nF

R15

10k

U4

25LC1024

SW1

Power

R17

10k

R13

10K

R5

150R

D2

LED

CON2

BARREL_JACK 2,1mm

C1

47µF

C3

100nF

U1

LD1117v33

J2

RCA_JACK

J1

RCA_JACK

R12

1K

C14

100nF

U5

23LC1024

R16

10k

R9

4k7

C9

10nF

C10

22nF

D3

1N6263

U3

PIC24EP512GP202

Q2

2N3904

R2

47K

D1

1N6263

C2

33µF

Q1

2N3906

R4

10k

R1

3K3

R3

47K

U2

LM7805CT

C5

220nF

CON1

SD_Card

F1

500mA

D4

1N4148

J3

RJ12

R14

10K

R23

10K

R24

10K

R25

10K

D7

1N4148

D6

1N4148

R18

10K

P2

keyboard

C15

100nF

C16

100nF

U6

PIC12F1572

D5

LED

R20

470

P3

ICSP

R19

470

R21

10k

R22

10k

C17

10µF/50v

D8

1N4148

R26

470

Dans la partie 2 je vais débuter la description du système logiciel.


liens

ForthEx (partie 2)

$
0
0

Dans cette partie je décris la structure générale du système logiciel.

structure logicielle

Il s'agissait donc de construire un système à partir de zéro. Pour utiliser le MCU il faut d'abord effectuer une configuration matérielle de celui-ci en fonction de l'usage des différents périphériques. J'ai conçu le système pour entrer le plus rapidement possible dans le système forth mais cependant il y a plusieurs fonctions logicielles qui ne font pas parti du système forth à proprement parler puisque ces fonctions ne sont pas intégrées au fonctionnement de la machine virtuelle forth tel qu'expliqué plus bas dans cet article. On pourrait appeler ces fonctions de base BIOS pour Basic Input Output Services ou encore HAL Hardware Abstraction Layer puisqu'elles sont spécifiques à cette plateforme matérielle. Si on dessine un schéma de la structure logicielle ça ressemble à ceci, l'information circulant entre les couches adjacentes seulement.

Abstraction matérielle

Les routines de service d'interruptions ainsi certaines routines qui peuvent-être appelées par des mots forth mais qui ne sont pas intégrés à la machine virtuelle font partis de cette couche logicielle. Les procédures qui ne font pas partie du système forth sont appelées par l'instruction assembleur call et se termine par l'instruction assembleur return. Les routines en codes qui font parti de la machine virtuelle sont liées les unes aux autres par un système d’enfilage (threading) assuré par une macro appelée NEXT qui est définie dans le fichier macros.inc.

La machine virtuelle

Il s'agit d'une machine virtuelle 16 bits, donc les adresses sont dans l'intervalle {0..65535} et les entiers dans l'intervalle {-32768..32767}. Dans le jargon forth une unité élémentaire de donnée s'appelle une cellule (CELL). ForthEx utilise des cellules de 16 bits. La machine virtuelle est constituée de 3 piles et d'un interpréteur interne qui a pour fonction de lire une liste d'adresses qui correspond au code à exécuter. Les données stockées sur les piles sont en unité cellule. Les entiers doubles (32 bits) occupe donc 2 cellules sur la pile. Il existe des mots spécialisés pour faire de l'arithmétique sur les cellules et s'assurer qu'une adresse est alignée sur le début d'une cellule.

La première pile est la pile des arguments appelée pstack dans le fichier core.s. Cette pile sert à passer les arguments entre les fonctions (appelés mots en forth).

La deuxième pile sert principalement à conserver les adresses de retour pour les appels de mots de haut-niveaux. Cette pile s'appelle rstack dans le fichier core.s

La 3ième pile n'est utilisée que par le compilateur et s'appelle cstack dans le fichier core.s. Le compilateur utilise cette pile pour résoudre des adresses de sauts. En dehors de la compilation cette pile n'est pas utilisée.

En plus de ces 3 piles la machine virtuelle a un certain nombre de registres. La machine virtuelle a donc la structure suivante:

  • IP Instruction Pointer. Joue le même rôle que le compteur ordinal (Program counter) d'un CPU. IP pointe la prochaine adresse de code à exécuter.
  • DSP Data Stack Pointer. Pointeur pour la pile pstack. Pointe à la position de l'avant dernier élément empilé, le dernier élément étant conservé dans le registre T.
  • RSP Return Stack Pointer. Pointeur pour la pile rstack. Pointe l'adresse après le dernier élément empilé. Notez la différence entre le pstack et le rstack. DSP est incrémenté avant d'empiler et décrémenté après le dépilement. RSP est incrémenté après l'empilement et décrémenté avant le dépilement.
  • VP. Variable Pointer. Le système utilise un certain nombre de variables. Ces variables sont rangées en un seul bloc en mémoire RAM. VP pointe sur l'adresse du début du bloc. Les variables système sont référencées par leur position relative à VP.
  • I et LIMIT. Ces 2 registres sont utilisés ensemble par les boucles DO ... LOOP et DO ... +LOOP. I est le compteur de boucle incrémenté à chaque itération de la boucle et LIMIT est la valeur limite du compteur. Lorsque I atteint LIMIT le bouclage se termine.
  • WP Working Pointer. Après l'appel d'un mot ce registre pointe vers le champ des paramètres du mot.
  • T est un registre qui contient la valeur au sommet du pstack.

plan de la mémoire

Ce plan de la mémoire est appelé à varier avec chaque version du système.

Mémoire RAM

  • 0x0000-0x1000 Bloc d'adresse réservés pour les SFR Special Function Register. Les périphériques sont accédés via ce bloc d'adresses. C'est spécifique à ce MCU.
  • 0x1000-0x107Frstack, Pile des retours.
  • 0x1080-0x10BFpstack, Pile des arguments.
  • 0x10C0-0x10FFcstack, Pile de contrôle.
  • 0x1100-0x104FTIB, Terminal Input Buffer. Tampon pour le clavier ou autre source d'entrée.
  • 0x1050-0x109FPAD, Tampon pour le formatage des textes en sortie.
  • 0x10A0-0x10C7 Tampon d'entrée pour le port série.
  • 0x10C8-0x11ED Variables système.
  • 0x11EE-0x1211 Variables et tampon utilisé par le USART du clavier.
  • 0x1212-0x1233 Bloc de variables utilisées par les fonctions HAL.
  • 0x1234-0x12F7 Bloc libre.
  • 0x12F8-0x12FF Variables utilisées par le mécanisme de sauvegarde/restauration d'image boot.
  • 0x1300-0x7FFF Espace données utilisateur, dictionnaire utilisateur. Ce bloc mémoire contient les fonctions, les variables et les constantes définis par l'utilisateur.
  • 0x8000-0xC9FF Mémoire EDS, Extended Data Space, réservée pour l'allocation dynamique.
  • 0xCA00-0xCFFF Mémoire vidéo, contient les caractères affichés à l'écran.

Mémoire FLASH

  • 0x000000-0x000003 vecteur de réinitialisation.
  • 0x000004-0x0001FF Table des vecteurs d'interruptions.
  • 0x000200-0x000229 Code machine _reset.
  • 0x00022A-0x0003A9 Code machine des routines ISR.
  • 0x0003AA-0x00235D Dictionnaire système. Contient les mots définis lors de la création du système.
  • 0x00235E-0x00275D Police de caractères, table ASCII.
  • 0x00275E-0x0027C3 Chaînes de caractères constantes, messages système.
  • 0x0027C4-0x00396D Code machine des mots forth définis avec les macros DEFCODE et HEADLESS.
  • 0x00396E-0x003C82 Code machine fonctions HAL.
  • 0x007800-0x007823 Constantes pour l'initialisation des variables système.
  • 0x008000-0x0557EC Mémoire libre. l'image boot est enregistrée au début de cette plage et peu occupée jusqu'à ~28000 octets.

lexique de la machine virtuelle

D'abord un lexique pour comprendre la machine virtuelle.

  • dictionnaire Le dictionnaire est une base de donnée qui fait le lien entre les noms des routines et l'adresse du code. La structure d'une entrée dans le dictionnaire est comme suis:

    +-----+-----+-----+-----+
    | LFA | NFA | CFA | PFA |
    +-----+-----+-----+-----+
    Le dictionnaire est utilisé par l'interpréteur/compilateur. Une partie du dictionnaire est dans la mémoire FLASH et l'autre correspondant aux mots définis par l'utilisateur est en mémoire RAM.
    • LFA Link Field Address, est le champ dans une entrée dictionnaire qui contient l'adresse du prochain mot. Le dictionnaire étant une liste chaînée. Occupe 2 octets.
    • NFA Name Field Address, contient la chaîne comptée du nom. Le premier octet contient la longueur du nom et les suivants le nom lui-même. Si le nombre d'octets occupés par ce champ est impaire, 1 octet est ajouté pour aligner le CFA sur une adresse paire. Occupe un nombre pair d'octets.
    • CFA Code Field Address, ce champ contient l'adresse du point d'entrée de la routine à exécuter pour ce mot. Occupe 2 octets.
    • PFA Parameter Field Address, ce champ contient les paramètres utilisés par la routine. Occupe 0 ou un nombre quelconque d'octets. Le champ est complété pour assurer une adresse paire sur l'entrée suivante.
  • Interpréteur interne, Une fois qu'une définition est compilée, le code à exécuter est une liste d'adresses lues par l'interpréteur interne ou machine virtuelle. Chacune de ces adresses est appelée XT pour eXecution Token.
  • XT, eXecution Token, est un pointeur qui contient l'adresse du code à exécuter. Le modèle d'exécution de cette machine virtuelle est appellée ITC.
  • ITC, Indirect Threaded Code, est un modèle d'exécution dans lequel le programme est une liste pointeur ou chaque pointeur contient l'adresse de la routine en code machine à exécuter. C'est le modèle d'exécution utilisé par ForthEx.
  • Interpréteur/compilateur, C'est l'interface utilisateur qui analyse la ligne d'entrée fournie par l'utilisateur ou provenant d'un fichier source et qui interprète ou compile le texte lu selon l'état de la variable système STATE.
  • STATE, est la variable système qui indique à l'interpréteur/compilateur si les mots lus dans le flux d'entré doivent-être exécuter immédiatement ou compilés dans une nouvelle entrée du dictionnaire. Lorsque cette variable est à zéro les mots sont interprétés sinon ils sont compilés.
  • Colon Definition, Est un mot définit par :, ce caractère étant appelé colon en anglais. Les Colon definition sont des listes d'adresses qui débutent par l'exécution du code ENTER et se terminent par l'exécution du code EXIT. Pour la machine virtuelle ces 2 mots sont l'équivalent des instructions machine CALL et RETURN respectivement. C'est à dire que ENTER empile la valeur de IP sur rstack avant d'initialiser IP avec la valeur qui est dans le CFA du mot. La dernière adresse est celle de EXIT qui a pour effet de prendre la valeur qui est au sommet de rstack pour la remettre dans IP ce qui correspond à une sortie de sous-routine. donc les colon definition sont comme des sous-routines, tandis que les mots codes sont comme des instructions machine pour la machine virtuelle forth.


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; interpréteur interne
; exécute l'instruction suivante
; de la machine virtuelle
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
.macro NEXT
mov [IP++], WP ; WP=CFA, IP pointe vers item suivant
mov [WP++], W0 ; W0= adresse code, WP=PFA
goto W0 ; saut vers code routine
.endm

Comme on le voit la machine virtuelle est très simple puisqu'elle ne comprend que 3 instructions machine. Chaque mot en code machine doit se terminer par cette macro pour assurer le fonctionnement de la machine virtuelle.

démarrage de la machine virtuelle

Voici le code qui s'exécute lors de la réinitialisation de l'ordinateur. La réinitialisation se produit lors de la mise sous tension de l'ordinateur mais aussi s'il y a une exception logicielle, une commande reboot ou une des combinaisons de touches suivante: CTRL-C pour un warm reset ou CTRL-ALT-DEL pour un cold reset.


; vecteur de réinitialisation du processeur
.section .start.text code address(0x200)
.global __reset
__reset:
clr ANSELA ; désactivation entrées analogiques
; priorité 6 pour _INT1Interrupt
mov #6, W0
ior IPC5
mov #rstack, RSP
mov #pstack, DSP
mov DSP, W0
sub #RSTK_GUARD, W0
mov W0, SPLIM
movpag #1,DSWPAG
btsc RCON,#SWR
bra 1f
; power on reset
movpag #psvpage(_cold),DSRPAG
mov #psvoffset(_cold),IP
NEXT
; réinitialisation logicielle
1: movpag #psvpage(_reboot),DSRPAG
mov #psvoffset(_reboot),IP
NEXT

.text


_reboot:
.word QCOLD,TBRANCH,_cold-$
_warm:
.word LIT,fwarm,FETCH,LIT,_DP,FETCH,LIT,_LATEST,FETCH
.word CLS,CLR_LOW_RAM
.word HARDWARE_INIT,VARS_INIT
.word LATEST,STORE,DP,STORE
.word DUP,LIT,USER_ABORT,EQUAL,ZBRANCH,1f-$
.word DROP,LIT,_user_aborted,BRANCH,8f-$
1: .word DUP,LIT,MATH_EXCEPTION,EQUAL,ZBRANCH,2f-$
.word DROP,LIT,_math_error,BRANCH,8f-$
2: .word DUP,LIT,STACK_EXCEPTION,EQUAL,ZBRANCH,3f-$
.word DROP,LIT,_stack_reset,BRANCH,8f-$
3: .word DROP,LIT,_unknown_reset
8: .word COUNT,TYPE,CR,QUIT

_cold:
.word CLR_RAM,HARDWARE_INIT,VARS_INIT
.word VERSION,COUNT,TYPE,CR
; autochargement système en RAM à partir
; d'une image en FLASH MCU ou EEPROM
.word BOOTDEV,FETCH,BOOT
.word QUIT ; boucle de l'interpréteur

Le code assembleur exécute un minimum de code qui consiste à désactiver les entrées analogiques et à initialiser les pointeurs de piles DSP et RSP ainsi que le compteur ordinal de la machine virtuelle IP. A partir de la macro NEXT c'est la machine virtuelle forth qui contrôle l'exécution.

La machine virtuelle forth a 2 points d'entrés, _cold et _reboot. Le point d'entrée est sélectionné en fonction de l'état dut bit SWR dans le registre RCON du MCU. Si ce bit est à 1 il s'agit d'une réinitialisation logicielle donc IP est initialisé pour exécuter le code _reboot sinon IP est réinitialiser pour exécuter le code _cold.

A partir du moment où la machine virtuelle est en action il n'agit plus d'exécuter directement du code machine mais du code forth. Donc _reboot et _cold sont des mots forth mais sans entête de dictionnaire car l'interpréteur/compilateur n'a pas besoin de les voir. Donc chacun des noms qui suis une directive assembleur .word correspond au CFA d'un mot forth. QCOLD est le CFA du mot défini plus bas:


; est-ce un cold reboot
HEADLESS QCOLD,HWORD
.word LIT,fwarm,FETCH,ZEROEQ,EXIT
HEADLESS est une macro pour définir les mots forth qui ne sont pas dans le dictionnaire. Dans le fichier macros.inc il y a plusieurs macros pour faciliter la définition des mots forth lors de la construction du système. Tous les mots forth qui sont dans la mémoire FLASH du MCU sont définis à l'aide de ces macros. Donc chaque fois qu'il y a dans les fichiers sources une des macros suivantes: HEADLESS, DEFCODE, DEFWORD, DEFUSER, DEFCONST il s'agit d'une macro qui simplifie la création de définitions forth. La lecture des fichiers source révèle donc que la plus grosse part du système est en forth. Bien sur écrire des définitions forth de cette façon est différent que d'écrire des définitions forth pour l'interpréteur/ compilateur par l'utilisateur de l'ordinateur. Pour quelqu'un qui n'est pas habitué cette différence peu prêter à confusion. J'ai passé tellement de temps à définir des mots de cette façon que les premières fois que j'utilisais l'ordinateur il m'arrivais de taper par exemple sur la ligne de commande le mot MINUS au lieu du caractère -.

Utilisation de l'ordinateur

Cet ordinateur fonctionne seulement en mode texte, affichant 25 lignes de 64 caractères en monochrome. La table des caractères utilise le code ASCII qui est un code à 7 bits. Le 8ème bit, le plus significatif, est utilisé pour inverser le caractère à l'écran. C'est à dire que si ce bit est à 1 le caractère est affiché noir sur fond blanc au lieu de blanc sur fond noir. Dans le fichier TVout.S se trouve les mots forth pour l'affichage. On y trouve entre autre le mot TGLCHAR qui inverse le caractère à la position du curseur. Comme les mots SETX et SETY permettent de positionner le curseur il est possible de manipuler l'affichage pour souligner certains mots en les inversant.

Le système n'a pas d'assembleur donc les seuls mots qui peuvent-être définis par l'utilisateur sont des colon definition. Ces définitions sont sauvegardées en mémoire RAM et perdues lorsque l'utilisateur éteint l'ordinateur, à moins qu'il n'utilise une sauvegarde >BOOT.

Sauvegarde >BOOT et BOOT

Le MCU possède 512Ko de mémoire FLASH mais seulement 64Ko sont réservés pour le système forth. Le reste peu donc être utilisé pour la sauvegarde de données utilisateur. Les fichiers flash.s et store.s contiennent des définitions qui permettent de sauvegarder des données dans la mémoire flash. Deux mots sont d'intérêts pour sauvegarder les définitions de l'utilisateur pour qu'elles soient rechargées automatiquement au démarrage. Le mot >BOOT sert à sauvegarder une image des définitions utilisateur et le mot BOOT est utilisé pour recharger cette image en RAM. Le mot BOOT s'exécute automatiquement lors d'un démarrage à froid et récupère l'image s'il y en a une mais il peut-être lancé manuellement. Voici un exemple d'utilisation.


: p2 ( n -- n^^2 ) \ puissance de 2
dup * ;
: p3 ( n -- n^^3 ) \ puissance de 3
dup p2 * ;
\ sauvegarde de l'image RAM
MFLASH >BOOT
Dans cette exemple 2 définitions ont été créées par l'utilisateur. Pour que ces définitions soit sauvegardées en permanence l'utilisateur a décidé de créer une image boot dans la mémoire flash du MCU, de sorte qu'à chaque démarrage cette image sera rechargée en mémoire RAM. MFLASH est le nom du périphérique de sauvegarde. l'image aurait pu être sauvegardée dans l'EEPROM mais dans ce cas il aurait fallu la recharger manuellement avec la commande:

EEPROM BOOT

On peut donc étendre les fonctionnalités du système en créant de nouvelles définitions en RAM et en sauvegardant avec la commande:


MFLASH >BOOT
L'image modifiée sera disponible à chaque démarrage.

démo d'utilisation

Conclusion

Je n'ai pas l'intention de donner un cours complet sur le forth sur ce blog ce serait redondant, de nombreuses ressources sont disponibles dans l'internet ( en anglais du moins) . Ce qu'il me reste à faire c'est d'écrire un lexique complet des mots définis dans forthex. Ce document sera disponible dans le dossier documentation du github.

Le système de base sera sans doute élargie, par exemple par l'ajout d'un gestionnaire de mémoire dynamique ainsi qu'un système de fichiers pour la carte SD. Il faudrait aussi écrire un éditeur de texte.


Liens

magnétron

$
0
0

Le four micro-ondes est tombé en panne. C'est un appareil assez simple, une minuterie électronique, 4 micro-switches pour la sécurité, un ventilateur, un moteur pour la rotation du plateau, un transformateur haute-tension, un diode rectificatrice haute-tension et finalement le magnétron. C'est le seul composant intéressant dans cet appareil et c'est ce dont je vais parler dans cet article.

ATTENTION! Si vous avez envie d'ouvrir un micro-ondes pour en examiner le contenu, sachez qu'il y a des précautions à prendre.
  1. Débranchez l'appareil du secteur avant d'ouvrir le boitier.
  2. Il est possible que le condensateur haute-tension soit encore chargé. Un magnétron ça fonctionne à un voltage d'environ -2500 VDC. Pour éviter l'électrocution déchargez le condensateur en branchant une résistance de 1 Mohm entre la cathode du magnétron et l'anode de celui-ci avec des fils à pinces alligator. Laissez ce circuit en place quelques secondes avant de le retirer.

Schéma bloc d'un micro-ondes

schéma bloc d'un four micro-ondes
magnétron

Un tube à vide qui produit des micro-ondes

Un magnétron ce n'est qu'un tube à vide contenant que 2 électrodes comme les rectificateurs utilisés à l'époque des tubes électroniques, et pourtant il produit des micro-ondes. Alors quel est la différence entre un tube à vide rectificateur et un magnétron?

Attention ça tourne

Comme on peut le constater à partir de la photo, son apparence est très différente des diodes en tube de verre. La partie extérieur c'est l'anode avec les ailettes de refroidissement. Remarquez les 2 disques noirs à chaque extrémité du cylindre d'anode. Ce sont des aimants. Comme dans tout tube à vide la cathode contient un filament chauffant. La chauffe libère des électrons de la surface. Pour que ces électrons soient accélérés vers l'anode il faut un champ électrique. Il faut que l'anode soit positive par rapport à la cathode. Pour des raisons pratique et de sécurité puisque l'anode est un gros bloc de métal à l'extérieur du tube on conserve l'anode à 0 volt en vissant le magnétron au chassie. La cathode par contre étant à l'intérieur du tube est mise à un voltage négatif d'environ -2500 VDC. Donc même si l'anode est à zéro volt elle est positive par rapport à la cathode. Les électrons sont fortement accélérés vers l'anode. C'est là que le fonctionnement diverge d'une diode rectificatrice. Dans un rectificateur les électrons s'en vont directement vers l'anode par le chemin le plus court.

vue schématique d'un magnétron
Comme je l'ai mentionné il y a 2 aimants au extrémités du tube. Il y a donc un champ magnétique perpendiculaire au déplacement des électrons. Ce champ magnétique exerce une force sur les électrons qui les fait déviés de leur trajectoire rectiligne. Les électrons au lieu d'aller directement vers l'anode décrivent une trajectoire en spirale dans l'espace entre la cathode et l'anode. Les électrons subissent donc une accélération et tout électron accéléré émet des ondes électromagnétiques. A la périphérie de l'anode il y a des cavités résonnantes. Lorsque les électrons passent devant ces cavités il se produit un phénomène de résonance. La dimension des cavités est calculée pour que la fréquence de résonance soit de 2 450 MHz. Cette fréquence est choisie parce qu'elle correspond aussi à la fréquence de résonance des molécules d'eau. Comme la nourriture est faite de matière vivante et que toute matière vivante contient de l'eau. En faisant vibrer les molécules d'eau contenues dans la nourriture on produit la chaleur de cuisson.

Cyclotron

Il existe un type d'accélérateur de particule qu'on appelle un cyclotron, si vous étudiez le fonctionnement d'un cyclotron vous allez constater la très grande similitude de fonctionnement entre le cyclotron et le magnétron. Il y a une différence de taille et aussi que dans un cyclotron on utilise les électrons eux-même pour bombarder des cibles plutôt que d'utiliser les ondes électromagnétiques émient par les électrons accélérés.


Swift Forth et SwiftX Forth

$
0
0

Si vous avez envie d'essayer la programmation Forth sur votre ordinateur ou sur votre microcontrôleur préféré la compagnie Forth inc. offre en téléchargement gratuit une version d'évaluation de leur systèmes SwiftForth et SwiftX. Aucune limite de temps.

Forth inc.

Forth incorporated est la compagnie fondée par Chuck Moore1 et Elisabeth Rather2.

SwiftForth

SwifthForth est un système de programmation en Forth natif. C'est à dire pour créer des applications pour le système d'exploitation sur lequel il est installé. Il est disponible pour les plateformes Windows,OSX et Linux. Vous pouvez donc télécharger la version pour votre système d'exploitation préféré et étudier les exemples et écrire vos premières applications Windows,OSX ou Linux en Forth.

SwiftX

SwiftX est la version cross compiler de leur système Forth. C'est à dire que SwiftX permet de créer et compiler des applications pour différent microcontrôleurs. La liste est assez longue, en autre sont supportés les AVR,MSP430,ARM. Il est possible de développer des applications Arduido avec SwiftX.

Allez directement à la page de téléchargement et vérifiez les options disponibles.


  1. Chuck Moore est le créateur du langage Forth.
  2. Elisabeth Rather est la première programmeuse du langage Forth. Elle devait faire la maintenance d'un système écris par Chuch Moore lorsqu'elle a découvert ce curieux langage (What's that mess?) et elle ne disposait d'aucune documentation. Elle a donc entrepris de créer toute la documentation. Plus tard elle s'est associée à Chuck Moore pour créer la compagnie Forth inc.

ForthEx (partie 3)

$
0
0

Depuis le dernier article sur le projet ForthEx, je n'ai cesser d'y travailler et je peux dire qu'à ce point ci le projet est pas mal abouti. ForthEx peut maintenant être contrôlé en remote via le port RS-232 et un émulateur VT102 sur le PC. J'ai créé un éditeur de texte simple et un système de blocs pour la sauvegarde sur EEPROM externe ou carte SD. De plus la documentation html est complète avec description de chacun des 445 mots qui sont dans le dictionnaire en mémoire FLASH du MCU, sans oublier un tutoriel. Le tutoriel consiste en la description du code source d'un jeu classique appellé snake. Voici donc un démo du jeu en action.

Conclusion

Le temps passé sur ce projet m'a permis de mieux connaître le langage Forth au point ou maintenant je peux lire un programme Forth aussi facilement que s'il était écris en C et je n'ai pas eu plus de difficulté à écrire le jeu snake en Forth que j'en aurais eu en C.

Comme n'importe quoi d'autre il suffit d'y mettre le temps et les efforts pour maîtriser ce langage. Ceux qui prétendent que ce langage est plus difficile à comprendre ou lire qu'un autre ne se sont tout simplement donner la peine de l'étudier sérieusement.

détecteur de métal

$
0
0
Dans cet article je décris la construction d'un détecteur de métal construit autour d'un PIC10F322 et d'un oscillateur Colpitts en base commune.

Origine d'un projet

La semaine dernière je sors de la maison pour aller prendre l'allée qui se trouve à l'arrière. J'aperçois mon voisin qui a l'air de chercher quelque chose.
- Salut Jacques!
- Salut Robert! Qu'est-ce que tu cherches?

Il ouvre la main pour me montrer plusieurs vis et clous.
- J'ai fais une crevaison ici hier.
- Ha! Moment d’embarras...

En juin j'ai refais la clôture qui borde cette allée. Hors je n'avais pas ramassé toutes les clous et vis qui y sont tombés. J'aurais du être plus attentif à la récolte des vieux clous et vis. Mais ce n'est pas si facile de les trouver à travers l'herbe et le gravier. Je me suis dis qu'un détecteur de métal serais utile dans cette opération de nettoyage. Plutôt que d'en acheter un j'ai décider de le fabriquer. Projet de fin de semaine.

Schématique

Montage carte

Assemblage final

Mise à l'essaie

Dans ce bref vidéo les objets détectés sont dans l'ordre, une rondelle en acier, 1 pièce de 5 cent en nickel et 1 pièce de 1 cent en cuivre.

Description

Le détecteur de métal est constitué d'un oscillateur Colpitts en montage base commune. Il comprend le transistor Q1 2N3904, l'inductance L1 et les condensateurs C4à C7. R1,R2 ainsi que C2 ne servent qu'à polariser le transistor dans sa zone de conduction. C6 et R3 sont les éléments qui permettent la rétro-action positive entre le collecteur et l'émetteur. Le circuit accordé est formé de L1, C4,C5 et C7. C4 et C7 en parallèles forment l'équivalent d'un condensateur de 4,4nF. Je n'avais pas de 4,7nF en main mais si vous avez un, remplacez C4 et C7 par un seul condensateur de 4,7nF. Une fraction du signal du circuit accordé est renvoyée à l'émetteur de Q1à travers le condensateur C6. La fréquence de cet oscillateur mesurée à l'oscilloscope est de 460Khz. Mais la valeur exacte n'est pas importante car c'est la variation de fréquence que le logiciel va mesurer. La sortie de l'oscillateur est envoyée au microcontrôleur PIC10F322 sur la broche 3, T0CKIà travers C8 et R4. La logique de détection est simple, il s'agit simplement de détecter les variations de fréquence de l'oscillateur causées par la présence prêt de la bobine L1 d'un objet métallique. Dans ce but la minuterie TIMER0 est utilisée pour compter les cycles de l'oscillateur pendant un intervalle de 32 millisecondes a répétition en comparant chaque mesure avec la précédente. Si cette valeur varie dans la même direction 2 mesures consécutives on considère qu'il y a présence d'un objet métalique et l'alarme sonore est activée.

Construction de la bobine L1 et assemblage.

Dans une planche de pin de 3/4" d'épaisseur (19mm) j'ai découpé un disque de 6" (15cm) de diamètre. Avec une lime queue de rat j'ai creusé une cannelure sur toute la circonférence du disque afin d’accueillir le bobinage. Le bobinage est comprend 17 tours de fil émaillé numéro 22 AWG (0,6mm). Mesuré avec un appareil LCR j'obtiens une valeur de 115µH pour cette bobine tel qu'indiqué sur la schématique.

Pour le manche j'ai utilisé une tige de peuplier à section carrée de 1/2" (12,5mm) qui est maintenue au disque avec une vis et de la colle.

Un petit boîtier en contre-plaqué 1/8" (3mm) a été fabriqué et fixé au manche pour contenir le circuit électronique.

Le montage électronique lui-même est fait sur une plaquette de bakélite de 7cm x 9cm à pastille de cuivre sur une seule face.

Description logicielle

Donc le signal de l'oscillateur est capturé à l'entrée T0CKI (broche 3) et les cycles sont comptés par le TIMER0 sur un intervalle de 32 msec. La minuterie TIMER2 est utilisée comme compteur de période pour la génération de la tonalité d'alerte de 500 hertz générée par le périphérique PWM1. La routine débutant à init: initialise les périphériques et active l'interruption sur le TIMER2. Cette minuterie possède un diviseur en sortie qui permet de déclencher l'interruption après un certain nombre de cycles. Le post-diviseur est configuré pour une interruption à tous les 16 cycles de TIMER2. Une fois l’initialisation complétée le logiciel tombe dans une boucle infinie goto $ car la détection se fait à l'intérieur de la routine d'interruption qui débute à ìsr:. À chaque interruption on fait une lecture de TMR0 qui représente le nombre de cycles de l'oscillateur comptés sur une durée de 32 msec. En fait il s'agit du nombre de cycles modulo 256 car on n'a pas besoin du compte complet puisque les variations d'une interruption à l'autre sont nettement inférieures à 256. Pour chaque interruption on conserve cette valeur dans la variable last. La variable run est une variable temporaire qui représente la dernière lecture de TMR0 faite au début de la routine d'interruption. On compare donc cette dernière valeur avec la valeur de last et on incrémente ou décrémente la variable slope en fonction de la différence entre les 2 valeurs. Si run est plus grand que last on incrémente slope car ça signifie que la fréquence de l'oscillateur a augmentée. Au contraire si run est plus petit que lastça signifie que la fréquence à diminuée et donc slope est décrémentée. Si run et last ont la même valeur slope est ramenée à zéro et la tonalité d'alarme est désactivée. Pour que la tonalité d'alarme soit réactivée il faut que la valeur absolue de slope soit égale ou supérieur à la constante TR_LVL. Ce code très simple qui n'occupe que 66 instructions donne de bons résultats.

J'ai testé différentes valeurs pour la durée d'échantillonnage et pour la constante TR_LVL c'est avec ces valeurs que j'obtiens le meilleur résultat.

Technique de balyage

La technique de balayage consiste à tenir le disque de la sonde 1 ou 2 cm au dessus du sol dans le plan horizontal et balayer de gauche à droite ni trop vite ni trop lentement. Avec un peu de pratique on trouve rapidement la bonne vitesse de balayage.

Lorsqu'un objet est détecté il ne faut pas arrêter le balayage de la sonde au dessus de l'objet mais plutôt faire des aller-retour. Un arrêt du balayage permet à l'oscillateur de se stabiliser sur une nouvelle fréquence et donc rend le détecteur silencieux.

Notez que la détection se produit lorsque l'objet est au plus proche du rebord du disque et non en son centre.

Conclusion

De réalisation économique et rapide il ne faut cependant pas s'attendre à ce qu'il est la sensibilité d'un bon détecteur vendu dans le commerce.


  1. sources du projet sur github

minix 3

$
0
0
Aujourd'hui j'ai appris que minix 3 est un système d'exploitation des plus utilisés au monde. En fait même Andrew S. Tanenbaum le créateur de minix l'ignorais jusqu'à tout récemment. Depuis 2006 tous les microprocesseurs Intel Core contiennent un processeur secondaire que le fabriquant appelle Management Engine. Ce processeur fonctionne en dehors du processeur principal et du BIOS avec son propre logiciel et a accès à toutes les fonctionnalité de l'ordinateur même s'il n'y a pas de système d'exploitation installé ou même de disque dur. Il y a eu beaucoup de critiques concernant le management Engine et récemment des hackers ont trouvé une méthode pour le désactiver et par la même occasion étudier le logiciel qu'il utilise. C'est là qu'ils ont découvert qu'il utilise une version customisé par Intel du système d'exploitation minix 3. Puisque les processeurs Intel Core sont les plus utilisés dans les ordinateurs de bureau et les laptops ça signifie que minix 3 est un des systèmes d'exploitations les plus utilisés dans le monde et personne n'était au courant!

Qu'est-ce que minix 3

Minix 3 se distingue des systèmes d'exploitation plus connus comme Windows, OSX et GNU/Linux d'une façon remarquable. Contrairement à ces 3 derniers c'est un système d'exploitation à micro noyau, alors que les 3 autres sont basés sur des noyaux monolithiques.

Noyau monolithique

Tous les systèmes basés sur Unix comme OSX, ainsi que ceux basé sur Linux ou encore le noyau NT4 de Windows possèdent un noyau monolithique. Pour comprendre ce qu'est le noyau d'un système d'exploitation vous pouvez consulter l'article suivant: Qu'est-ce qu'un système d'exploitation. Un noyau monolithique comme Linux est un gros module logiciel comprenant des centaines de milliers de lignes de codes. Plus on ajoute de fonctionnalités plus il grossie. Hors Linux existe depuis longtemps et il est devenu très gros.

Micro noyau

Un micro noyau comme celui de minix au contraire implémente un minimum de fonctionnalité et renvoie tous le reste dans l'espace utilisateur. Alors qu'avec Linux, Unix et NT4 tous les pilotes de périphériques sont liés directement au noyau et fonctionne dans l'espace protégé de celui-ci.

Le problème que tente de résoudre les micro noyaux.

Le principal problème que les micro noyaux essaient de résoudre est celui de la sécurité. En effet plus un système contient de lignes de codes plus il a de chance de contenir des erreurs qui peuvent-être exploités de façon malveillante. Comme le noyau d'un système d'exploitation fonctionne au niveau de privilège le plus élevé du processeur. Les erreurs logicielles qui se trouvent dans son code posent une menace majeure à la sécurité mais aussi à la stabilité du système.

Donc la philosophie du micro noyau est de réduire le code qui tourne au niveau de privilège le plus élevé du processeur pour réduire au minimum le risque d'erreurs logicielles. Mais il y a un inconvénient, celui de la vitesse d'exécution. En effet pour accéder aux périphériques les applications doivent faire un appel au noyau de type syscall pour appeler une fonction matérielle. Un syscall est une exception logicielle ça implique un délais qu'on appelle latence. Prenons un exemple, une application veut écrire un bloc de données dans un fichier sur le disque dur. Dans un système monolithique, l'application fait un syscall en passant l'information requise au noyau. l'interruption qui répond au syscall identifie le type de demande et transmet l'information au pilote du disque dur qui effectue l'opération et le résultat de l'opération est retourné à l'application dans le bloc d'information. Dans un micro noyau le pilote est aussi une application donc pour parler au noyau il doit lui aussi faire un syscall donc chaque transaction entre une application et un périphérique implique 2 systcall. Un pour la requête et un pour la réponse du pilote. On double le nombre de syscall et comme je viens de l'écrire chaque syscall implique un délais de réponse. De plus dans un système d'exploitation chaque application existe dans un espace mémoire virtuel inaccessible aux autres applications. Donc lorsque une application veut envoyer de l'information à un périphérique le noyau fait une copie vers l'espace de l'application vers l'espace du pilote et lorsque le pilote répond le noyau copie la réponse dans l'autre sens. Ça fait beaucopu de données à copier.

Cette façon de faire est très sécuritaire mais très lente. J'ai l'occasion d'expérimenter cette lenteur chaque fois que j'utilise mon PlayBook qui fonctionne avec le système d'exploitation QNX qui est basé sur un micro noyau.

Les recherches se poursuivent pour améliorer la performance des systèmes d'exploitations à micro noyau mais ils ne seront jamais aussi rapides que les systèmes monolithiques. Ils sont utilisés principalement pour leur sécurité mais aussi pour leur modularité qui permet de réduire la taille du système en enlevant simplement les modules qui ne sont pas nécessaires à l'application. C'est sans doute ce qui a incité Intel à utiliser minix 3 pour son Management Engine.

Cette découverte va peut-être intéresser plus de développeurs au projet minix 3 qui pour le moment est plutôt anémique.

abeille laborieuse et luciole désespérée

$
0
0

Introduction

Jusqu'à tout récemment je connaissais Silicon Labs pour leur produits radio-fréquences et je ne savais pas qu'ils vendaient aussi des microcontrôleurs. Il vendent entre autre des MCU 8 bits affublés du nom commercial de busy bee que je traduirais par abeille laborieuse plutôt que abeille occupée comme le suggère un certain traducteur en ligne. Il n'existe pas de version DIP de ces microcontrôleurs par contre il existe une version SOIC-16, le EFM8BB10F8G-A-SOIC-16. Très économique, actuellement 0,86cent chez digikey.ca. Évidemment il me fallait aussi un programmeur que Sillicon Labs appelle USB Debug Adapter. Il existe 2 versions de ce débogueur une pour les MCU 8 bits et une autre pour les MCU 32 bits. D'apparence ils sont identiques sauf pour la couleur, à ne pas confondre.

Présentation des Busy Bee

Comme mentionné en introduction il s'agit de MCU1 8 bits. Ils sont basés sur un CPU1 appelé CIP-51 par Silicon Labs. Il s'agit d'une version modernisé et 100% compatible avec le vénérable CPU d'Intel MCS-51 qui était au coeur des premiers microcontrôleurs mise en marché en 1980, les Intel 8051. Intel a abandonné la commercialisation des i8051 il y a longtemps mais de nombreux fournisseurs ont prie le relais. Les Busy Bee sont donc des descendant direct mais plus performant du i8051. Les Busy Bee fonctionnent jusqu'à 25Mhz. Il y a aussi des Universal Bee pour les application USB ainsi que les Laser Bee qui peuvent fonctionner à 72Mhz. Dans cette introduction il sera question du Busy Bee modèle EFM8BB10F8G-A-SOIC16.

Particularités des MCU de la famille Bee

Le CPU a quelques particularités qu'il est bon de souligner par exemple il utilise les 32 premiers octets de la RAM comme 4 banques de 8 registres. Une seule banque est active à la fois. Pour l'assembleur ces registres sont nommés R0 à R7. l'intérêt d'avoir 4 banques se situe au niveau des appels de sous-routines et surtout des interruptions. Le délais de réponse d'une interruption peut-être réduit si elle n'a pas besoin de sauvegarder les registres sur la pile. Elle peu s'éviter cette tâche en utilisant une autre banque de registres. Autre particularité les adresses RAM entre 32 à 48 sont accessibles par certaines instructions au niveau du bit. Pour ces instructions il ne s'agit pas d'octets mais d'un tableau de 128 bits adressable de 0 à 127. Il faut aussi mentionner que même plus économique des Busy Bee possède un multiplicateur en hardware. Je ne connais aucun autre MCU 8 bits à moins de 1$ qui en possède un.

Première étape

Silicon Labs fournis gratuitement l'environnement de développement appelé simpliciy studio. Il faut créer un compte pour le télécharger. Je l'ai installé sur mon laptop qui est en Windows 10 mais comme vous le verrez sur le site il est aussi disponible pour OSX et Linux.

Une fois le logiciel installé on découvre qu'il utilise le compilateur C/C++ de Keil et qu'il faut enregistrer son installation auprès de Silicon Labs pour bénéficier de toutes les fonctionnalités du compilateur gratuitement. Avant de lancer l'IDE2 ne pas oublier de brancher le USB Debug Adapterà l'ordinateur, ainsi il sera vu par l'IDE.

Simplicity studio

Même si cet environnement s'appelle Simplicity Studio ce n'est pas simple à utiliser comme l'IDE de Arduido. Il faut un certain temps pour se familiariser mais heureusement il y a un tour guidé. C'est basé sur l'environnement Eclipse CDT donc plus facile d'accès si vous avez déjà travaillé avec Eclipse. L'environnement utilise le concept de perspective. Selon la tâche à accomplir on passe d'une perspective à l'autre. Dans Symplicity Studio les boutons pour passer d'une perspective à l'autre sont dans la barre d'outils en haut à droite. Il y en a 5, Launcher, Configurator, Simplicity IDE, C/C++ et Debug. Au premier démarrage de l'application on se retrouve dans la perspective Launcher et par la suite dans la perspective visible lors de la fermeture de l'application.

Ma première tentative de créer un projet fut un échec. J'ai eu l'idée de créer un projet vide. Quand Simplicity Studio dit Empty C project il veut vraiment dire projet vide. Lorsqu'on clique avec le bouton droit de la souris sur le nom du projet dans la perspective Simplicity IDE la fenêtre des propriétés du projet s'ouvre. Cette fenêtre contient plusieurs onglets et de nombreuses options dans chaque onglet. Si vous avez choisi empty C project vous devez définir chacun de ces paramètres. Disons que c'est pour les utilisateurs avancés.

On retourne donc à la perspective Launcher et on clique sur le bouton new solution.


On inscris le nom du MCU sur la ligne sous le bouton new solution, EFM8BB10F8G-A-SOIC16. Un dossier jaune apparaît avec le nom du MCU sous lui. On peut renommé le dossier en cliquant bouton droit dessus. Appelons le luciole désespérée

Maintenant on va cliquer sur le bouton new project.

Le nom du MCU qu'on a sélectionné apparaît, on clique sur le bouton next.
On conserve la sélection par défaut soit Simplicity Configurator Program et on appuie encore sur next.
À cette étape on nomme notre projet, les espaces ne sont pas permis dans le nom: luciole_désespérée donc. next
On garde ça tel quel et on clique sur finish. C'est lent avant de passer automatiquement à la perspective Configurator.

Il s'agit d'un outil de configuration visuel. On nous présente le brochage du composant sélectionné pour ce projet. Pour ce projet on va utilisé seulement la broche 8/P1.3. On clique dessus pour la sélectionner. A droite la fenêtre Properties nous permet de configurer cette broche. Pour ce projet on doit avoir la configuration suivante:

On va brancher une LED3à cette broche on l'a donc nommé ainsi.
En bas de la figure du composant on va maintenant cliquer sur DefaultMode peripherals.
Dans cette nouvelle vue on configure des valeurs par défaut des périphériques. J'ai sélectionné Clock Control et dans les propriétés j'ai choisis pour la propriété Select clock source, Low Frequence Oscillator. Il s'agit d'un oscillateur interne fonctionnant à 80Khz. Pour la propriété Clock Source Divider, j'ai choisi SYSCLK/32.
Ensuite j'ai sélectionné LFOSC
Il s'agit d'activé l'oscillateur et de choisir de diviser sa fréquence par 8 tel qu'indiqué dans la fenêtre properties.
Il nous reste maintenant à désactivé le Watchdog Timer

Problèmes

Lorsqu'on est dans le configurateur et qu'on clique sur PB2 dans le fenêtre Outline la fenêtre properties demeure vide. Hors le registre PB2 est celui qui permet d'activer le crossbar. Le crossbar est le multiplexeur qui permet de sélectionner quel périphérique est relié à quel broche. Il faut qu'il soit activé même si dans cette application on n'utilise aucun périphérique. Heureusement dans la fenêtre Problèmes un avertissement apparaît pour nous dire que le crossbar n'est pas activé. En double cliquant sur cet avertissement la fenêtre propriété du registre PB2 s'affiche et on peut activé le crossbar.

Pour ce projet simple c'est tout ce que nous avons à faire comme configuration mais ça nous évite pas mal de travail de codage manuel. Le configurateur va générer automatiquement le code nécessaire dans le fichier InitDevice.c. Le fichier qui contient l'information de configuration matérielle s'appelle luciole_desespérée.hwconf.

Luciole désespérée

Lorsqu'on travaille pour la première fois avec un MCU il est bon de commencer avec le projet le plus simple qu'on appelle habituellement blinky et qui consiste à faire clignoter une LED. Puisque Silicon Labs a décidé de donner un nom d'insecte à ses MCU, je joue le jeu en nommant mon blinky luciole désespérée. Désespérée parce qu'elle ne se contente pas de clignoter à vitesse régulière mais émet plutôt répétitivement un SOS en morse. Montage super simple pour un projet super simple:

schématique

montage expérimental
Notez que le débogueur n'utilise que 3 fils, GND position 2 sur le connecteur du débogueur, C2CLK position 7 sur le connecteur du débogueur et C2D position 4 sur le connecteur du débogueur. Lors du développement il il n'y a donc que 5 broche du MCU qui sont utilisées, 4=GND,5=+3Volt,6=C2CK,7=C2D et 8=LED. Les broches 6 et 7 sont débranchées lorsque le développement est complété.

Le code source en C

Puisque le configurateur a fait une bonne partie du travail pour nous il ne nous reste que très peu à écrire dans le fichier luciole_desespérée_main.c lui aussi créé par le configurateur.

C'est simple je cré un tableau appelé sos qui contient 4 octets. en fait ce tableau est lu comme une série de bits. Un bit à 0 signifie LED éteinte et un bit à 1 signifie LED allumée. La variable b est incrémentée de 0 à 27 et est utilisée pour lire séquentiellement les bits et lorsque b=28 on réinitialise b à zéro et le cycle recommence. Comme sos est un tableau d'octets on accède le bon octet en divisant b par 8 et le bon bit en prenant le modulo de b par 8. Les bits sont numérotés à l'inverse donc on soustrait le modulo de 7. Le code morse est fait de signaux courts dit et longs dah. Les dah sont 3 fois la longueur des dit. Donc en prenant le signal dit comme unité de temps pour produire un dah il suffit de mettre 3 bits consécutifs à 1. Les 5 derniers bits de la séquence sont a zéro pour produire une pose entre chaque appel.

Pour compiler le projet on utilise le marteau. et pour programmer le MCU avec le fichier binaire on utilise l'icône flèche verte au dessus d'un circuit intégré. Il faut choisir le fichier binaire à programmer.

Le fichier généré utilise 257 octets de mémoire programme et 13 octets de mémoire RAM. On peu demander au compilateur de généner le code assembleur. On va allez dans les propriétés du projet et cocher assembly code dans l'option listing du compilateur Keil.

Maintenant si on recompile on va voir à la fin du fichier luciole_désespérée_main.lst qui se trouve dans le dossier src, le code assembleur. J'ai oublié de mentionner que le configurateur génère 2 configurations une configuration release et une configuration debug. Lorsqu'on modifie les propriétés du projet ça s'applique seulement à la configuration active.

Conclusion

Quelques problèmes se sont présentés lors de cette prise en main de Simplicity Studio.

  • J'ai été capable de créer une variable de type bit mais lorsque j'ai voulu convertir le tableau const char sos[4] en const bit sos[28] le compilateur m'a donné une erreur! Il est possible de créer une variable scalaire de type bit mais pas un vecteur de ce type.
  • J'ai essayé d'imbriquer du code assembleur à l'intérieur du code C sans succès. La simple ligne de code suivante:

    asm("nop");
    suffie pour déplaire au compilateur qui répond avec l'erreur suivante:

    *** ERROR C272 IN LINE 50 OF C:\Users\Jacques\SimplicityStudio\v4_workspace\
    luciole_desespérée\src\luciole_desespérée_main.c:
    '__asm' requires src-control to be active
    Je n'ai pas encore trouvé la solution de ce problème.
  • Lorsque j'essaie de déboguer le programme pour suivre l'exécution en pas à pas la session plante, le programmeur s'appelle pourtant USB Debug Adapter!
    Erreur fatale lorsque j'essaie d'utiliser le débogueur

Bien sur je ne suis encore qu'un néophyte avec cet environnement j'ai encore beaucoup à apprendre.

Petite expérience

J'ai décidé de créer une version plus permanente de la luciole désespérée et de l'alimenter avec une pile lithium CR2032. L'objectif est de voir combien de temps va duré la pile. Le premier décembre à 15:00 EST j'ai mis une pile neuve et je surveille la luciole. Je vais compter le nombre de jours qu'elle va clignoter. Vous avez noté que j'ai inséré une résistance de 1Kohm en série avec la LED pour réduire le courant à 1mA environ. De plus le CPU fonctionne à une fréquence à 312,5Hertz pour réduire la consommation de celui-ci à environ 120µA comparativement à environ 5mA à la configuration par défaut qui utilise l'oscillateur haute fréquence avec un diviseur à 8 ce qui donne Fsys de 3,0625Mhz. Vous avez aussi notez qu'à fréquence de 312,5Hertz je n'ai pas besoin d'un boucle de délais pour prolonger la duré entre chaque bit. En fait à cette fréquence la durée entre chaque bit est d'environ 0,12 seconde. Il résulte donc un code morse facile à lire.


Le montage est fait directement au dos du porte pile. Le MCU est collé à celui-ci avec de la colle chaude et la résistance ainsi que la LED sont collés au dos du MCU avec de la colle cyanate (Creazy glue). D'après mes calculs luciole désespérée devrait clignoter environ 20 jours. Je vais mettre à jour cet article lorsque j'aurai le résultat final.

  1. MCU signifie Micro Controller Unit, tandis que CPU signifie Central Processing Unit. Il ne faut pas confondre les deux. tout MCU a en son coeur un CPU mais ne se limite pas à celui-ci elle possède aussi de la mémoire et des périphériques programmables.
  2. IDEIntegrated Development Environment est une application utilisée pour le développement de logiciel qui contient un éditeur de texte mais aussi le support intégré au compilateur ainsi que d'autre outils nécessaire à la réalisation d'un projet. Il permet donc d'écrire le code source, de le compiler, de l'injecté dans le microcontrôleur et aussi de le déboguer sans avoir à sortir de l'environnement. D'où son nom d'environnement intégré.
  3. LEDLight Emitting Diode ou Diode Electro Luminescente en français.
Viewing all 192 articles
Browse latest View live