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

projet VPC-32

$
0
0

C'est à la fin des années 70 qu'on a vu apparaître sur le marché les premiers ordinateurs personnels avec un clavier et un interpréteur BASIC, tel que les Apple II, TRS-80 , Commodore PET. Ces premiers ordinateurs personnels utilisaient des microprocesseurs 8 bits tel que les MOS Technologies 6502, Zilog Z80 et Intel 8080. L'acronyme PC (PersonnalComputer) est entré dans le langage courant quelques années plus tard avec le premier IBM-PC. Ces ordinateurs coûtaient chers, en dollars constant le TRS-80 vaudrait aujourd'hui plus de 1200$. Considérant ses faibles capacités c'est ridicule par rapport à ce qu'on pourrait faire avec la technologie d'aujourd'hui.

De nos jours il est possible de fabriquer soi-même son propre ordinateur qui aurait des capacités supérieures à ceux de cette époque pour moins de 50$. Mon projet VPC-32 (Very Personnnal Computer 32 bits) a pour but de fabriquer un ordinateur à très faible coût mais avec des capacités égales ou supérieures à celle du TRS-80 modèle 1 en utilisant un minimum de composants de la technologie moderne. voici un diagramme bloc de l'ordinateur que j'envisage.

Ce diagramme ne représente que l'idée initiale et pourrait évoluer en cours de chemin. A l'époque les programmes étaient enregistrés sur des cassettes audio ou au mieux sur des disquettes 5-1/4" simple face d'une capacité de 170Ko. Le VPC-32 aura quand à lui un lecteur de carte SD, plus rapide et avec une capacité de stockage représentant plusieurs milliers de disquettes.

Donc pour fixer les idées voici les caractéristiques du VPC-32 tel qu'envisagées à ce moment-ci.

  • Microcontrôleur 32 bits PIC32MX150F128B (DIP-28).
  • 1 clavier PS/2 pour la saisie.
  • 1 interface RS-232.
  • 1 sortie vidéo NTSC Blanc/Noir.
  • 1 sortie audio monophonique (PWM).
  • 1 lecteur de carte SD.
  • Affichage texte 28 lignes de 53 caractères.
  • Affichage graphique 320x230 B/N.
  • Un éditeur de texte simple.
  • 1 interpréteur moderne (pas BASIC), FORTH?, PYTHON?, LUA?, AUTRE...

Je vais utiliser le moins de composants possible et ce seront des composants en format pour montage à travers trou de sorte que n'importe quel amateur pourra le fabriquer sur une carte de prototypage à grille de 100mil. Il sera alimenté à 3,3Volt (3,0-3,6Volt). Il pourra donc être alimenté par 2 piles AA ou CC. J'ai choisi le PIC32MX150F128B car c'est le modèle de PIC32MX disponible en DIP-28 qui possède la plus grande capacité mémoire. 128Ko de flash et 32Ko de RAM. La mémoire vidéo à elle seule occupera 9200 octets.

Donc à l'allumage de l'ordinateur la console va présenté l'invite de commande du langage choisi (à déterminer) et l'utilisateur va entrer du code et des commandes en interactif ou lancer l'éditeur de texte.

Je vais présenter une série de chroniques au fur et à mesure que le projet va évolué. Puisque ces derniers temps j'ai travaillé beaucoup sur la génération de signal vidéo NTSC je vais commencer par ça tandis que c'est frais en mémoire.

A cette époque la mémoire FLASH n'existait pas encore et le langage 'C' n'était pas répandu comme aujourd'hui. Le système d'exploitation était entièrement écris en assembleur et inscris dans une mémoire ROM, il n'était donc pas question de flasher une nouvelle version du BIOS(OS). Pour ma part je vais travailler en 'C' en évitant l'assembleur autant que possible.


VPC-32, test vidéo ntsc

$
0
0

J'ai débuté ce projet en faisant des tests de génération de signal vidéo NTSC B/N 320x230. Pourquoi pas 320x240 pour être conforme au standard QVGA?. En principe avec la méthode de scan utilisé on devrait obtenir 240 lignes visibles à l'écran, 262 moins les 20 lignes réservés au vertical retrace. Mais en pratique sur les 2 téléviseurs que j'ai essayé seulement 230 lignes sont visibles à l'écran. Je ne gaspillerai donc pas 400 octets de mémoire RAM pour des lignes qui ne sont pas visibles. Donc le tableau représentant le bitmap vidéo occupe 320x230/8 soit 9200 octets de RAM.

Circuit de test

Voici le circuit utilisé pour faire mes test vidéo. Cette partie du circuit ne devrait pas être modifiée en cours de projet. Le signal vidéo généré est conforme à mes attentes.

La diode D1 n'est pas strictement nécessaire, le circuit fonctionne sans elle, sauf que je constate que la réponse en haute fréquence est meilleure avec cette diode installée. Dans mon image test les lignes verticales les plus étroites se confondent lorsque je l'enlève.

RB7 broche 16 est une entrée de synchronisation pour le signal vidéo généré par un périphérique SPI. Ce signal provient d'un OC en sortie sur la broche 11. Les périphériques SPI sur les PIC32MX peuvent fonctionner en mode frame. Dans ce mode le SPI envoie des octets tant que l'entrée sync est active. Le signal de synchronisation en question est généré par un périphérique OC Output Compare et sert à retarder l'envoie du signal vidéo en début de ligne.

code source

test-NTSC.c

font.h

Les MCU PIC32MX possèdent 4 canaux DMA (Direct Memory AAccess). L'utilisation du DMA pour envoyer les bits vidéo au SPI permet d'accaparer le MCU un temps minimum pour la génération du signal vidéo. En effet le DMA va chercher les octets directement dans la mémoire RAM pour les envoyer au SPI sans intervention du core MCU qui lui pendant ce temps peut s'occuper à d'autres tâches.
Au niveau logiciel ce qui m'a donné de la difficulté c'est d'obtenir un signal avec une bonne synchronisation horizontale. Dans mes premiers essais le démarrage du signal vidéo était déterminer par un délais logiciel. Hors une interruption même au niveau de priorité le plus élevé a un temps de latence variable car le MCU doit compléter l'instruction en cours avant de répondre à l'interruption. Le résultat était des lignes verticales en dent de scie et les caractères étaient déformés. J'ai trouvé la solution de ce problème dans le livre de Lucio Di Jasio, Programming 32-bit Microntrollers in C1. La solution consiste a utiliser le mode frame sur le SPI qui génère le signal vidéo et à déclencher le départ part un signal matériel qui lui ne subit pas de variation temporelle. Pour arriver à ce résultat Jasio utilise la transition montante de l'impulsion de synchronisation horizontale du signal NTSC. Mais comme il doit y avoir un délais d'au minimum 4,7µSec entre la fin de cette impulsion et le début du signal vidéo on doit trouver une façon d'introduire un délais supplémentaire. Pour introduire ce délais Jasio utilise un deuxième canal DMA qui envoie des 0 au SPI. Donc un délais en multiple de 32 bits peut être ajouté en début de ligne avant que le vrai signal vidéo soit envoyé. Sur les PIC32 les canaux DMA peuvent-être mis en chaîne. Donc le premier canal envoie un certain nombre de zéros pour créer un délais et lorsqu'il a terminé sa tâche déclenche le deuxième canal qui lui envoie les vrai bits vidéo au SPI.

Même si le livre de Jasio a été une source d'inspiration j'utilise une méthode différente pour générer le délais. Ma méthode permet une résolution du délais beaucoup plus fine. Cette résolution est en fait celle de la période du signal PBCLK qui alimente le TIMER 2. Donc au lieu d'utiliser un deuxième canal DMA j'utilise un deuxième OC qui est cadencé par le TIMER 2 comme celui qui génère le signal de synchronisation NTSC. J'ai donc 2 signaux de sortie OC en phase, celui sur la broche 14 qui est la synchro NTSC et celui sur la broche 11 qui est la synchro pour déclencher le SPI. Il suffit d'ajuster la constante SPI_DLY pour que la transition montante soit retardée d'au moins 5µsec par rapport à celle de HSYNC pour que le signal vidéo parte au bon moment. Et d'utiliser cette transition montante à la place de celle de HSYNC pour déclencher le SPI.

Avec cette méthode j'obtiens un signal vidéo parfais et je peux ajuster finement la position horizontale simplement en modifiant SPI_DLY. Étant donné la qualité du signal obtenu ce code va probablement demeuré tel quel dans la version finale du projet.


NOTES:
1) Programming 32-bit Microcontrollers in C, Exploring PIC32, Lucio Di Jasio, ed. Newnes

VPC-32 schéma électronique

$
0
0

J'ai complété la version initiale du schéma électronique du VPC-32 et j'ai créé le git du projet.

Dans le dossier ressource se trouve le projet KiCad et un document pdf du schéma électronique.

J'aurais du appellé cet ordinateur VSPC-32 pour Very Simple Personnal Computeur 32 bits. Très simple de conception, une seule feuille KiCad a suffit pour en dessiné le schéma. A part le PIC32MX150F128B il n'y a qu'un seul autre circuit intégré et c'est le régulateur de tension. On pourrait s'en passé si on décidait d'alimenter l'ordinateur avec 2 piles 1,5 Volt en série. Mais à 3 volt on est à la limite inférieure pour fournir l'alimentation positive pour le RS-232 donc 3 piles 1,5Volt avec une diode pour faire chuter la tension à 3,6Volt qui est le maximum pour le PIC32. L'ensemble de ces composants devrait coûté moins de 30$CAN. Le PIC coûte moins de 5$CAN. J'ai utilisé un connecteur RJ-11 pour le RS-232 parce que ça prend moins de place qu'un DB-9 mais je vais peut-être changé ça pour un autre type de connecteur.

Comme on le voit il ne restera que 6 E/S libres qui seront branchées sur un connecteur linéaire de 100mil nommé XBUS sur le schéma.

Présentement je suis en train d'écrire le code pour l'interface clavier. En fait je réutilise le code que j'ai déjà écris pour la série de chroniques sur le MSP430 launchpad. Le changement de plateforme ne requière que quelques changements.

Pour l'interface RS-232 le code a déjà été écris lors de ma série sur la présentation des PIC32MX.

Mais le plus gros du logiciel cependant reste à faire, l'interface pour carte SD, système de fichier FAT32, fonctions graphiques, fonctions audio. L'interpréteur, l'éditeur de texte. J'espère compléter ce projet avant la fin de l'année.

Je devrais être en mesure de faire une mise à jour du dépôt sur github contenant le code pour le clavier et le RS-232 avant la fin de la journée.

VPC-32, casse-tête avec les interruptions

$
0
0

Lors de ma dernière chronique j'écrivais que le code pour la lecture du clavier PS/2 devrait-être terminé dans la journée. Et bien c'est toujours plus long que je le crois au départ. Cette fois ci j'ai eu un sacré casse-tête à résoudre. Mon code vidéo seul fonctionnait bien, mon code clavier seul fonctionnait bien et j'ai ajouter une interruption pour le coretimer qui elle aussi fonctionnait bien seul. Mais lorsque l'interruption du TIMER 2 (vidéo) était active ni le clavier ni le coretimer ne fonctionnait correctement. Malgré une lecture et relecture de la documentation et des recherches dans l'internet je ne voyais toujours pas la solution.

Les registres de l'ombre.

Beau titre non? Ça fait roman d'espionnage. En fait je veux parler des Shadow register set. Le problème avec les micro processeurs qui possèdent un grand nombre de registres est que lors d'une interruption il faut sauvegarder de nombreux registres avant de pouvoir exécuter le code de la routine d'interruption ce qui augmente ce qu'on appelle en anglais interrupt latency. C'est à dire le temps entre le moment où une interruption est déclenchée et le moment ou le code de service de l'interruption est exécuté. Pour régler ce problème les concepteurs de ce type de micro processeur ont eu l'idée d'ajouter un second ensemble (ou plusieurs) de la general registers file de sorte que lorsqu'une interruption se produit le code de service de l'interruption utilise le second ensemble plutôt que l'ensemble des registres utilisé par le code normal. Du coup plus besoin de sauvegarder sur la pile et de restaurer à la fin de l'ISR.

Dans le cas du PIC32MX150F128B il n'y a qu'un seul ensemble de registres secondaire et c'est cette ensemble qu'on appelle Shadow register set. Cette ensemble n'est utilisé que pour les interruptions de priorité 7. Donc dans mon code puisque l'ISR du générateur vidéo NTSC doit avoir la priorité la plus élevé, je l'ai mis au niveaus 7 avec utilisation du Shadow register set. La déclaration est la suivante

void __ISR(_TIMER_2_VECTOR,IPL7SRS) tmr2_isr(void)

IPL7SRS indique au compilateur que cette interruption a le niveau de priorité 7 et utilise le Shadow Register Set(SRS). Il y a 2 autres options SOFT et AUTO. IPLxSOFT signifie que l'ensemble de registre normal est utilisé. IPLxAUTO signifie que le compilateur décide s'il peut utiliser le SRS sinon l'ensemble normal sera utilisé.

Il était évident que le problème que j'avais était causé par l'interruption vidéo, cependant n'ayant pas de débugger en circuit je n'arrivais pas à traquer le bug. Finalement il me vient à l'idée de modifier le code comme ceci pour voir.

void __ISR(_TIMER_2_VECTOR,IPL7AUTO) tmr2_isr(void)

Bingo bug réglé! Pourquoi la première version ne fonctionnait pas? Je n'ai pas eu le temps de fouiller ça mais je suis soulager qu'enfin ça fonctionne.

Beaucoup d'overhead

Pour vous donner une idée du surplus de code généré par le compilateur lorsqu'on choisi l'option IPLxSOFT voici les codes 'C' et assembleur de la première version de l'ISR du coretimer.

Le résultat en assembleur, ahoy! de toutes ces instructions seulement 8 résultent de la compilation du code écris en 'C', le reste c'est de l'overhead.

La documentation explique que lorsqu'une ISR appelle une sous-routine, UpdateCoreTimer() dans ce cas ci, le compilateur n'a pas d'autre choix que de sauvegarder l'ensemble complet des registres généraux sur la pile. Donc pour réduire l'overhead de cette ISR je n'avais d'autre choix que d'éliminer l'appel à UpdateCoreTimer(). J'ai donc modifié le code pour ceci:

Ce qui en assembleur améliore le choses mais ce n'est quand même pas gratuit.

En passant l'ajout de l'interruption pour le coretimer ajoute un faible bruit de fond au signal vidéo. J'ai donc ajouter dans le fichier HardwareProfile.h la ligne #define USE_CORE_TIMER. En mettant en commentaire cette ligne dans le fichier ça supprime l'interruption du coretimer et tout le code associé pour ceux qui voudraient un signal vidéo parfais. L'élimination de ce code signifie qu'il n'y a plus de compteur de millisecondes sys_tick dans le système. Ce compteur est utile pour calculer des délais et des intervalles de temps. Lorsqu'il est présent la routine delay_ms() utilise sys_tick sinon elle utilise la routine delay_us().

Avec tout ça mon code pour le clavier PS/2 n'est pas complété, il me reste encore quelques détails... Ouais! je croise les doigts!

Mise à jour sur https://github.com/Picatout/VPC-32.

VPC-32, pourquoi ça ne fonctionnait pas!

$
0
0

Dans la chronique précédente je parlais du casse-tête que j'ai eu avec les interruptions. J'ai trouvé pourquoi ça ne fonctionnait pas. Les PIC32MX1xxx/2xxx n'ont pas de Shadow Register Set. C'est fou le temps qu'on perd lorsqu'on ne prends pas le temps de lire la documentation au complet.

Depuis la dernière chronique j'ai testé le code pour le clavier PS/2 tout semble OK. J'ai aussi complété la table de caractères dans font.h pour les 127 premiers codes ASCII.

Finalement à la fin de ma dernière chronique je mentionnais que l'interruption du coretimer introduisait du bruit dans le signal vidéo. Je mentionnais aussi dans cette même chronique à quel point l'option IPLxSOFT dans la déclaration des ISR introduit un overhead incroyable lorsque l'ISR appelle une sous-routine. Puisque tmr2_isr utilise l'ensemble de registres normal (n'ayant pas de SRS) et que tmr2_isr appelait la fonction DmaChnEnable() le temps de latenceétait énorme. Ce problème est réglé j'ai simplement remplacé l'appel à la sous-routine DmaChEnable() par une simple affectation au registre DCH0CON. Ce qui a eu pour effet de réduire la latence de tmr2_isr et de faire disparaître le bruit dans le signal vidéo.

DCH0CON |= 128; // remplace DmaChEnable(0);

Je suis prêt maintenant à commencer le travail sur le pilote de périphérique pour la carte SD. Mais avant je dois fabriquer un prototype du VPC-32.

Mise à jour de https://github.com/Picatout/VPC-32.

VPC-32, prototype #1

$
0
0

J'ai complété le montage du prototype #1 du VPC-32 modèle 1. Réussi à faire le montage sur une carte à bandes avec grille de 100mils même si les connecteurs RJ-11, PS/2 et carte SD n'était pas conçus pour ça. Pour le RJ-11 il y a 2 rangés de 3 broches espacées de 100mils avec une distance 100mils entre chaque rangée mais les 2 rangés sont décalées de 50mils. J'ai du percé de petits trous entre ceux déjà existant pour la deuxième rangée. Pour la base SDCard les 7 premiers contacts sont à 100mils mais les autres sont plus rapprochés. Mais comme je ne me sert pas des contacts 8,9, du détecteur de carte et du détecteur de protection contre l'écriture qui sont les contacts rapprochés j'ai pus ignorer ces contacts. Je suis soulagé de ne pas avoir eu à fabriquer un circuit imprimé.

Autres photos sur https://github.com/Picatout/vpc-32/tree/master/resources/prototype

Pour le pilote de carte SD je vais essayé de trouver du code open-source adaptable facilement à ce MCU. C'est la prochaine étape.

Liste matériel

  • 1 carte de prototypage à bandes 4" x 5" (10cm x 12,5cm).
  • C1 électrolytique 47µF/16Volt
  • C2, C3 céramique 22pF
  • C4,C5,C6,C7 céramique 100nF
  • C8 électrolytique 10µF/16Volt
  • C9 céramique 4,7nF
  • C10 céramique 2,2nF
  • D1 diode rectification 1N4001
  • D2 Status LED 2mm vert
  • D3 Power LED 2mm rouge
  • D4,D5 diode commutation 1N4148
  • J1 base carte SD, Digikey P/N A101492CT-ND
  • J2 base miniDIN-6 contact (PS/2), Digikey P/N 5749180-1-ND
  • J3 prise RCA jaune, Digikey P/N CP-1462-1-ND
  • J4 base RJ11, Digikey P/N A31422-ND
  • J5 prise RCA noire, Digikey P/N CP-1459-1-ND
  • K1 (3 contacts), P1 (2 contacts), P3 (5 contacts), barrette contacts 100mils, Digikey P/N SAM1035-50-ND
  • P2 5 contacts) barrette contacts 100mils angle 90degrés
  • Q1 transistor PNP 2N3906
  • Q2 transistror NPN 2N3904
  • R1,R2 résitance 1/4W 5% 51k
  • R3,R4,R6,R11,R15,R17 résistance 1/4W 5% 10k
  • R5,R7 résitance 1/4W 5% 150 ohm
  • R8,R19 résistance 1/4W 5% 1K
  • R9 680R
  • R10 10R
  • R12 120R
  • R13,R14,R16 résistance 1/4W 5% 4k7
  • R18 résistance 1/4W 5% 3k3
  • SW1 bouton contact momentané N/O
  • U1 régulateur de tension 3,3Volt LDO LM3940-3.3
  • U2 Microcontrôleur Microchip PIC32MX150F128B
  • X1 crystal 10Mhz

VPC-32, progression

$
0
0

Cette semaine j'ai travailler sur le code pour la console texte ainsi que sur le système de fichier sur carte SD. Grâce au code emprunté au projet Pinguino j'ai progressé rapidement en ce qui concerne l'accès à la carte SD et au système de fichier FAT. Donc actuellement je suis capable d'utiliser les fonctions de l'API du système FAT qui se trouve dans le fichier ff.c du projet Pinguino. Je n'ai pas tester la fonctionnalité de toute l'interface mais j'arrive à ouvrir un fichier obtenir ses statistiques, lire, me déplacer dans le fichier et le modifier. La carte de 2Go que j'utilise est formatée en FAT16. Je n'arrive pas cependant à utiliser une carte formatée en FAT16 sur mon laptop qui est en Windows 7. La fonction mount() ne reconnaît pas le système de fichier dans ce cas. Je n'ai pas d'ordinateur en Windows xp. Je ne sais si ça fonctionnerais si la carte était formatée sous ce système d'exploitation pas plus sous quel système d'exploitation la carte que j'utilise présentement a été formatée. La différence doit se située au niveau du système de fichier.

Donc je progresse, il me reste à créer la librairie graphique, un shell de commandes basique, l'interpréteur pour le langage (python ou autre) et à intégrer tout ça ensemble. Pour l'intégration je vais peut-être installer un noyau exécutif pour céduler les tâches.

Je suis satisfait du rythme de progression actuel.

dépôt: https://github.com/Picatout/VPC-32

Question quiz

$
0
0

Combien de LEDS peut-on contrôler indépendamment l'un de l'autre avec un MCU qui n'a que 3 E/S comme par exemple le PIC10F200?

Si je vous dis 4 serez-vous sceptique?

J'ai eu un idée et j'ai décidé de la vérifier avec un PIC10F200. Il s'agit d'utiliser GP3 comme sortie pour contrôler un LED en utilisant le Weak Pullup et un transistor. Si on active la résistance Weak pullup sur une entrée, celle-ci est tirée à +5Volt. J'ai fait le test avec un transistor bi-jonction 2N3904 et un transistor MOSFET 2N7000. Dans le cas d'un transistor bi-jonction c'est le courant qui circule dans la base qui commute le transistor. D'après la feuille de spécification du PIC10F200 lorsqu'une entrée est mise à Vss le courant à travers le weak pullup est de 250µA. Si le transistor a un gain de 100 on obtient 25mA de courant au collecteur. En pratique à cause du voltage base-émetteur, le courant dans la base est moindre que ça. Je mesure 2,56 volt au bornes de la résistance de 200 ohm lorsque la LED est allumée ce qui donne 12,8mA. Si je remplace la résistance par 100 ohm, j'obtient 22mA. Le gain du transistor est probablement supérieur à 100.

Avec un transistor MOSFET 2N7000 l'impédance d'entrée de ce type de transistor est très élevée et c'est le voltage qui commute le transistor. Donc lorsqu'on active le pullup le transistor passe en conduction. Cependant il faut utiliser une résistance de 1M entre le gate et Vss pour que la LED s'éteigne lorsqu'on désactive le pullup. Avec ce transistor et la résistance de 100 ohm j'obtiens 23,7mA à travers le LED.

On a donc 4 sorties indépendantes pour contrôler 4 LEDS ou autre chose.


Éclairage DEL

$
0
0

Voici une expérience qui n'a rien à voir avec les MCU. Du moins pas directement bien qu'il y est un MCU utilisé dans le dispositif DEL.

Lors de ma dernière commande chez Digikey j'ai aperçu une publicité pour un dispositif d'éclairage DEL qui se présente sous la forme d'un disque d'aluminium de 33mm de diamètre sur lequel sont soudés 16 LEDS montés en surface et au centre de ces LEDS un MCU qui converti la tension 120VAC en courant DC approprié pour alimenter ces LEDs.

Digikey P/N 897-1146-ND. Le modèle 220VAC est le SMJE3V04W1P3

Ce qui est intéressant c'est que de disque se connecte directement sur le secteur 120VAC/220VAC sans avoir besoin d'un transformateur. C'est donc très compacte. Ce modèle consomme seulement 4,3Watt et produit plus de lumière qu'un fluo-compact de 9Watt.

Pour cette expérience j'ai récupéré le culot d'une empoule à incandescence de 25Watt et un étui de brosse à dent cylindrique. Après avoir cassé l'enveloppe de verre de l'ampoule en faisant attention pour ne pas cassé le pylone de verre qui supporte le filament. J'ai enlevé le filament et soudé 2 bouts de fil aux électrodes qui sortent du pylone en verre. J'ai découpé une section de l'étui de brosse à dent que j'ai collé au culot avec de la colle chaude en faisant glissé les 2 fils à l'intérieur du tube. Les 2 fils ressortent au bout du tube et sont soudés aux contacts N1 et L1 sur le disque DEL. Le disque DEL est ensuite collé au bout du tube de plastique. Ce n'est pas très élégant mais une fois vissé dans ma lampe de bureau c'est masqué par la cloche de la lampe.

Il existe des modèles de ce disque plus puissant, jusqu'à 16Watt. Si j'en juge par la l'intensité lumineuse de la version 4Watt, 16Watt doit produire autant de lumière qu'une ampoule à incandescence de 100Watt. Le gros inconviénent c'est le prix, avec les taxes le modèle 4 watts revient à environ 7$CAN. Mais si on considère la duré de vie qui est d'au moins 10 fois celle d'une empoule à incandescence c'est pas plus cher.

Mise à jour

Mon installation n'a pas durée longtemps, le disque d'aluminium devient trop chaud et la colle a fondue...
Il faudra donc que je fabrique un montage plus fiable.

réflexion sur le PIC10F20x

$
0
0

Bien que le projet VPC-32 prends pas mal de mon temps, depuis plusieurs semaines j'ai pour idée d'écrire un manuel d'introduction à la programmation des MCU en assembleur en utilisant le PIC10F200 dans mes exemples. J'ai fait des recherches et le PIC10F200 est vraiment le MCU le plus simple qu'on puisse trouver sur le marché actuellement. Il ne possède que 2 périphériques: le Watchdog timer et le TIMER1. Il n'a que 7 registres spéciaux, 14 octets de RAM et 256 (255 utilisables) octets de flash. Son jeux d'instructions est limité à 33 qui peuvent donc être mémorisées rapidement. Son format DIP-8 est pratique pour les montages sur plaque de prototypage sans soudure et il est aussi disponible en DFN et SOT23-6 pour les montages compactes. Ça me semble être le MCU idéal pour ce genre d'introduction. J'ai déjà présenté sur ce blog plusieurs petits projets fait avec le PIC10F200 ou PIC10F202. Je songe à quelque chose de plus organisé avec de nombreux exemples. Un livre que je rendrais disponible en format PDF ou ePUB.

Le minimalisme de ce MCU me plaît en même temps que l'idée de faire le maximum avec aussi peu. Je vais continuer à réfléchir à ça mais pour le moment ma priorité est le VPC-32, je suis en train de travailler sur un système FORTH pour ce petit ordinateur à saveur des années 70.

VPC-32, forth et shell

$
0
0

Mon travail sur le VPC-32 progresse. Après avoir étudié plusieurs options et travaillé sur la création d'un système forth personnel écris en assembleur, j'ai laissé tombé ce travail pour adapter DIOS Forth de Lubos Pekny. Comme le travail de M. Pekny est bien fait et entièrement écris en 'C' l'adaptation a été facile.

J'ai ensuite travaillé sur le shell de commande. Les commandes dir, del,copy,ren,forth et more sont maintenant fonctionnelles. Il m'en reste encore 7 à écrire. Je travaillerai ensuite sur l'éditeur de texte.

Le module son est partiellement fonctionnel et permet actuellement de jouer des mélodies mono tonale en arrière plan.

Voici une capture d'écran d'une session forth.

Pour ceux qui ne connaisse pas le language Forth, j'ai simplement défini un nouveau mot dans le dictionnaire qui s'appelle test. Ce test imprime simplement une suite de n nombres à partir de zéro. Le nombre est passé en argument sur la pile de donnée, ici il s'agit d'un nombre 10. En Forth tout est inversé, on empile les arguments ensuite on appelle le mot (fonction).

Pourquoi FORTH n'a jamais été populaire

$
0
0

J'ai choisi DIOS FORTH comme langage de programmation pour le VPC-32 pour 2 raisons:

  1. Adapter DIOS FORTH pour le VPC-32 était la solution la plus simple et exigeant le moins de temps.
  2. J'ai toujours été séduit par l'extrême simplicité de la syntaxe du FORTH.
Ceci dit je n'ai jamais vraiment développer de programmes en FORTH bien que j'ai lu les 2 livres écris par Leo Brodie ainsi que celui de Robert Van Loo intitulé Programmer le FORTH aux éditions Marabout. Je me suis amusé avec ce langage et j'en suis resté là. Pourquoi?

Oui le FORTH a un aspect séduisant par son extrême simplicité. On pourrait dire la même chose de la programmation en assembleur. Mais ça demande aussi plus d'effort. Le problème avec le FORTH est qu'il faut continuellement visualiser l'état de la pile des données. Quand on programme en FORTH il faut en quelque sorte faire le travail fait normalement par le compilateur. On empile les paramètres et ensuite on appelle la fonction. Il faut continuellement s'assurer que la pile est balancée.

Voici un exemple comparant une fonction appellée fiboécrite en python et ensuite en FORTH. J'ai encadré en rouge ce que j'ai saisie à l'écran dans les 2 cas.

D'abord on constate que l'écrite de la version FORTH demande moins de caractères mais pour quelqu'un qui ne connais pas le FORTH ce n'est pas plus compréhensible que du chinois.
dup, swap et over sont des mots qui servent à manipuler les valeurs qui sont sur la pile des arguments (données). dup empile une copie de l'élément qui est au sommet de la pile. swap inter change la position des 2 éléments qui sont au sommet de la pile et finalement over crée une copie du deuxième élément et le place au sommet de la pile. Le . lui remplace le print(n) de python. En python toute cette gymnastique est en partie faite par le compilateur et par une affectation à une variable temporaire: tmp=n1 et ensuite on retransfert tmp dans n0. Tout ça est fait en FORTH par des swap, dup et over. En fait c'est plus efficace en FORTH. Plus efficace mais plus exigeant au niveau du mental.

Voilà pourquoi FORTH n'est jamais devenu un langage populaire. Il est certain qu'à force de le pratiquer on devient plus à l'aise avec ces manipulations mais le fait est que l'apprentissage de python ne demande pas un tel effort au programmeur débutant.

En conclusion je suis en train d'étudier les options qui s'offre à moi dans le but de remplacer DIOS FORTH par un interpréteur python. A moins qu'il y est au final suffisamment d'espace dans la mémoire flash pour les deux langages.

forth sur launchpad

$
0
0

En faisant des recherches sur le langage Forth j'ai découvert quelque chose d'intéressant pour les propriétaires d'un MSP430 launchpad. Ça s'appelle 4e4th. Il s'agit d'un système forth qui fonctionne sur le MCU MSP430G2553 qui vient avec le launchpad de Texas instruments. C'est donc une bonne occasion d'explorer ce langage si vous ne le connaissez pas déjà. Une fois 4e4th installé sur le launchpad on interagit avec celui-ci via une connexion terminal en utilisant un logiciel comme TeraTerm ou autre logiciel d'émulation de terminal. C'est intéressant car ça fonctionne en interactif, on entre des commandes forth et on a le résultat immédiatement.

Installation

La procédure d'installation en anglais est ici. Mais vous pouvez lire ce qui suis si vous préférez. Je suppose ici que vous fonctionnez sous Windows. Je l'ai aussi testé sous linux et ça fonctionne aussi bien mais il faut utiliser un autre logiciel pour programmer l'image dans le MCU.

Au départ on suppose que vous avez un msp430 launchpad avec le MCU G2553 d'installé sur la carte. Vous devez télécharger le fichier HEX de l'image 4e4th.a43. Comme on ne peut programmer cette image à partir de code composer studio on télécharge l'utilitaire FET-Pro430 lite. On dézippe et installe (débrancher le launchpad avant d'installer FET-Pro430).

Sur la carte launchpad mettez les cavaliers TX et RX perpendiculaire aux 3 autres pour que le port sériel soit en hardware plutôt qu'en software. Voir cette photo. Première chose, après l'installation de FET-Pro430 et avoir rebranché le launchpad lancez le gestionnaire de périphériques de Windows et vérifiez sur quel port série est installé le launchpad.

Maintenant lancez FET-Pro430 et allez dans le menu setup - connection/device reset et sélectionnez le port du launchpad:

Dans la fenêtre principale:

  • Cliquez le bouton Open code file et allez chercher le fichier 4e4th.a43
  • Dans le groupe Microcontroller type sélectionnez le MSP430G2553.
  • Cliquez AUTO PROG pour lancez la programmation du launchpad.
  • Lorsque la programmation est complétée, fermez le programme FET-Pro430.

Si tout c'est bien passé les 2 lumières (verte et rouge) sont allumée sur le launchpad. Attention si le programme FET-Pro430 est encore ouvert il se peut qu'elle soit éteintes.

Lancez maintenant votre émulateur de terminal préféré. J'utilise TeraTerm Pro. Configurer le port série (le même qu'utilisé par FET-Pro430) à 9600BAUD 8N1. Lorsque la connexion est établie faite ENTER. le prompt forth OK devrait apparaître dans votre fenêtre terminal. Si c'est le cas vous être prêt à interagir avec le launchpad.

Introduction au forth 4e4th

Dans la fenêtre terminal tapez: green cclr <ENTER>
La LED verte devrait éteindre. Tapez red cclr <ENTER>
La LED rouge devrait éteindre.

Ça suffit pour aujourd'hui. Dans ma prochaine chronique je vais présenter un petit tutoriel 4e4th.

réparation d'un cat's meow

$
0
0

Ma soeur a acheté ce jouet pour son chat. Après un mois d'usage il est tombé en panne. Comme elle l'avais acheté usagé via l'internet, pas de garantie à faire valoir. Donc il s'est retrouvé entre mes mains pour réparation.

En le démontant j'ai constaté la simplicité du petit circuit électronique et j'ai compris rapidement qu'il s'agissait d'un MCU contrôlant le moteur via un pont H fabriqué avec 4 transistors Q1-Q4.

Le MCU était en surchauffe. Kaput! le MCU. IL n'étais pas identifié, le marquage ayant été effacé. Et de toute façon je n'aurais pas eu accès au firmware puisqu'il était kaput! et même s'il ne l'avait pas été... probablement protégé.

J'ai reconstitué le schéma-électronique à partir du circuit imprimé en remplaçant le MCU par celui que j'ai choisi.

J'ai remarqué que l'alimentation est sur les mêmes broches que sur un PIC12Fxxx. J'ai justement en main des PIC12F675 en format 8-SOIC. Pas de problème que je me dis je vais remplacé le MCU et faire ma propre version du Firmware.

J'ai ajouté un connecteur ICSP temporaire pour faire la programmation. Après avoir visionné le vidéo sur le site qui vend ce jouet, Je mis ce que c'est très simple. Le moteur tourne dans une direction et ensuite dans l'autre. La seule variable est la durée de chaque rotation. Voici le code source, seulement 89 instructions machine.

Avant de brancher le moteur je le remplace par des LEDS back to back en série avec un résistance de 1Kohm. Test, tout semble fonctionner. Les LEDS allument en alternance avec une durée variable. Je remplace par un petit moteur. Ha! le moteur ne tourne que dans une seule direction. Un des transistors du pont est défectueux et ne conduit pas suffisamment pour faire tourner le moteur.

Finalement j'ai décidé de refaire aussi le circuit électronique.

J'ai récupéré mon PIC12F675 sur le vieux circuit imprimé et l'ai soudé en dead bug sur le nouveau circuit. J'ai aussi laissé le connecteur ICSP sur le nouveau circuit car il y avait de la place.

Maintenant tout fonctionne correctement. C'est le chat qui va être content, il paraît qu'il aime ce jeux au point de demander à sa maîtresse de le mettre en marche.

mise à jour 2013-10-10

J'ai été un peu cours dans cet article. Entre autre j'ai oublié de mentionner que lorsque j'ai pris la décision de refaire le circuit de contrôle, ce n'est pas tout à fait le circuit original, mis à part le MCU, les transistors ne sont pas les même et la valeur de R1 et R2. Pour Q1 et Q2 j'ai utilisé des ZTX649. Pour Q3 et Q4 j'ai utilisé des ZTX749. Les 4 transistors sont en boitier TO-92. J'ai augmenter la valeur de R1 et R2 à 300 ohm.

Description du schéma

Les 4 transistors forment ce qu'on appelle un H bridge, que j'ai traduit ci-haut par pont en H. En aucun cas GP0 et GP1 ne doivent être à VoH (V output High) en même temps sinon les 4 transistors seront en conduction et on obtient un court-circuit. C'est pour ça que dans le firmware j'arrête le moteur avant de le redémarrer dans l'autre direction. J'ajoute en plus un délais de 20msec avant de repartir le moteur pour laissé le temps à l'énergie accumulé dans le moteur de se dissiper. Donc Lorsque GP1 est à VoH, GP0 est à VoL et vice-versa. Lorsque GP0 est à VoH le transistor Q1 entre en conduction et son collecteur tombe VoL. A partir du collecteur de Q1 la résistance R3 alimente la base de Q3. Puisqu'il s'agit d'un transistor PNP dont l'émetteur est branché au V+ de la batterie, lorsque sa base est à VoL il entre en conduction. On a donc un circuit établi entre V+bat. et v-Bat. en passant par Q3ce le moteur et finalement Q1ce à v-bat. Si on met GP0 à VoL et GP1 à VoH, le même principe s'applique mais cette fois le courant circule de V+bat par Q4ce à travers le moteur et enfin à travers Q2ce. Le courant circule maintenant dans le moteur dans la direction opposé à la situation précédente donc la rotation du moteur est inversée.

Retenez la configuration de ce montage, elle est fréquemment utilisée pour contrôler la direction de rotation d'un moteur.

A noter aussi la présence de R5 et C1. La fonction de ces 2 composants est de filtrer le bruit électronique généré par le moteur qui autrement pourrait nuire au bon fonctionnement du MCU.

J'ai augmenter la valeur des résistances R1 et R2 à 300 ohm en faisant le calcul suivant. Le moteur consomme 150mA (mesuré). le courant dans la base du transistor doit-être de Ice/Hfe. Ice est le courant qui circule entre le collecteur et l'émetteur du transistor et Hfe est le gain DC du transistor. Les transistors utilisés ont un gain minimum de 100. Donc pour obtenir un courant Ice de 150mA il suffit d'injecter 1,5mA dans la base. Ça c'est dans le pire des scénario car le gain typique de ces transistors est en fait de 200. Il suffit donc de calculer R1 et R2 pour que le courant fourni par les sorties GP0 et GP1 soit d'au moins 1,5mA pour que ça fonctionne. On peut se donner une marge de sécurité mais il est inutile d'exagérer. Trop de courant dans la base de Q1 et Q2 n'aurait que pour conséquence de drainer la pile inutilement et de faire chauffé le MCU puisque le courant qui alimente les bases de Q1 et Q2 passe par celui-ci. Il ne faut pas oublier non plus que plus il passe de courant à travers le MCU plus la chute de voltage aux bornes de R5 augmente. Chaque fois que le moteur est démarré le courant à travers le MCU augmente, la chute de voltage à travers R5 aussi et le Vdd du MCU diminue d'autant. Avec 300 ohm pour R1 et R2 le courant qui circule dans la base est approximativement de (4,5-VbeSat-0,7)/(300+47). D'après les spécifications du transistor VbeSat=0,9 et d'après les spécifications du PIC12F675 VoH=Vdd-0,7. Donc (4,5-0,9-0,7)/347=8,3mA. 8,3mA c'est 5 fois plus qu'il n'en faut pour mettre Q1 et Q2 en saturation à 150mA. Ces calculs sont des approximations suffisantes pour cette utilisation.

2013-10-11, Une cliente satisfaite

Ma sœur viens de me téléphoner pour me dire que le cat's meow fonctionne mieux que lorsqu'elle l'a reçu. Il paraît qu'il est plus speedy!!! C'était pas prévu dans la réparation mais si elle de dit :-)

brève introduction à forth (4e4th)

$
0
0

Le premier contact avec un programme écris en forth peut générer un certain mouvement de recul car la syntaxe n'a pas grand chose à voir avec celle des langages les plus courants comme C, pascal, basic ou python. Gardez présent à l'esprit les faits suivants concernant la syntaxe du forth:

  • Le seul séparateur de mot est l'espace
  • un identificateur, que se soit le nom d'un variable, d'une constante ou d'une fonction (mot forth) peut utilisé n'importe quel caractère sauf l'espace.
  • Les arguments s'écrivent avant la fonction (mot forth).
  • En forth un fonction ou sous-routine s'appelle un mot et la définition de chaque mot est conesrvée dans un dictionnaire.

Calculatrice forth

Je présume que vous avez configuré votre launchpad tel que décris dans ma chronique précédente et que présentement l'émulateur de terminal de votre choix est connecté à celui-ci.

Entrez dans le terminal la ligne suivante:

3 4 * . <ENTER>

Après avoir fait la touche <ENTER> le nombre 12 devrait apparaître dans la fenêtre terminal suivit de ok. Lorsque la ligne que vous avez saisie est sans erreur ok s'affiche à la suite du texte que vous avez saisi ou de la réponse s'il y en a une et le curseur passe à la ligne suivante. L'interpréteur est prêt à recevoir une nouvelle commande.

Donc ici on a saisi les paramètres '3', '4', le mot '*' et finalement le mot '.' . On a donc calculé le produit de 3 et 4 et on l'a imprimé. Le mot '.' sert à imprimer le nombre qui est au sommet de la pile des paramètres. Lorsqu'on imprime ainsi la valeur au sommet de la pile cette valeur disparait de la pile, elle est consommée. Mais si on ne l'avait pas imprimée elle serait restée au sommet de la pile. Essayons ceci.

3 4 * <ENTER>
2 / <ENTER>
. <ENTER>

Après la dernière commande le nombre 6 devrait apparaître. Le nombre intermédiaire 12 n'a pas été imprimé car on ne l'a pas demandé. La deuxième ligne de commande a divisé ce nombre qui était au sommet de la pile par 2. Et finalement la troisième ligne a imprimé la valeur au sommet de la pile. Important on ne peut écrire 3 4*2/ chaque mot doit être séparé des autres par un espace. En forth il n'y a aucun mot ou symbole réservé même les chiffres ne sont pas réservés. Je pourrais définir un nouveau mot forth qui s'appellerais '3' et le système l'accepterais. L'embêtant est que le nombre 3 ne pourrait plus être utilisé mais le chiffre 3 pourrait-être inclus dans un autre nombre.

Lorsque forth cherche un mot dans le dictionnaire il commence toujours par le dernier mot qui a été défini donc on peut masquer un mot en le redéfinissant. La première définition demeure dans le dictionnaire mais n'est plus accessible. Forth procède comme suis lorsqu'il analyse la ligne de commande:

  1. A partir de la position courante saute les espaces.
  2. Le premier caractère qui n'est pas un espace est le début du mot suivant.
  3. Avance le curseur jusqu'au premier espace qui suit le mot.
  4. Cherche le mot dans le dictionnaire en commençant par la fin (plus récent).
  5. Si le mot est trouvé l'exécute immédiatement et recommence à 1 jusqu'à ce que toute la ligne de commande est été analysée ou qu'il y est une erreur.
  6. Si le mot n'est pas trouvé essai de le convertir en nombre, s'il réussi il met ce nombre au sommet de la pile des paramètres et retourne au point 1. Sinon affiche une erreur, vide la pile des arguments et retourne à la ligne de commande.

Voici comment évolue la pile des arguments pour la commande que nous avons entré précédemment.


'3' n'est pas dans le dictionnaire mais c'est un nombre donc il est empilé. Idem pour '4'. '*' est trouvé dans le dictionnaire il est exécuté. Ce mot fait le produit des 2 arguments au sommet de la pile et les remplaces par le résultat '12'. '2' est encore un nombre et est empilé. '/' est trouvé dans le dictionnaire et a pour effet de diviser le deuxième élément de la pile par le premier et de les remplacer par le résultat '6'. '.' est trouvé dans le dictionnaire et est exécuté. Il a pour effet d'enlever le nombre au sommet de la pile et de l'imprimer au terminal.

Entrez au terminal les 2 lignes suivantes:

variable j <ENTER>
3 constant trois <ENTER>

On viens de créé une variable nommé j et une constante nommée trois. ici les noms suivent le mot. C'est normal pour certains mots le ou les arguments suivent le mot forth contrairement à ce que j'ai dis plus haut. C'est vrai en autre pour les mots qui ajoute une entrée dans le dictionnaire comme le mot ':' que nous verrons plus loin ainsi que ces 2 là. Donc les noms de constantes et de variables sont aussi conservés dans le dictionnaire.
Entrez les 2 lignes suivantes:

trois . <ENTER>
j . <ENTER>

On a saisi trois qui est le nom d'une constante et sa valeur a été empilé on a ensuite imprimé cette valeur. C'est sans surprise mais que ce passe-t'il avec j? Ce nombre qui c'est imprimé c'est l'adresse mémoire ou la valeur de j est enregistré. Si on avait voulu imprimer la valeur de j il aurait fallu faire:

j @ . <ENTER>

Le mot '@' se prononce fetch et sert à lire la valeur de la variable dont l'adresse est au sommet de la pile. La valeur remplace l'adresse. Comme j n'avait pas été initialisée la valeur imprimée ne signifie pas grand chose non plus.

2 4 * j ! <ENTER>
j @ . <ENTER>

Ceci devrait affiché un 8à l'écran du terminal. Sur la première ligne on a multiplié 2 par 4 ensuite on a enregistré le résultat dans la variable j. Le mot '!' qui se prononce store est le complément de @. Il sert à enregistrer une valeur dans une variable. L'adresse de la variable est au sommet de la pile et la valeur en seconde position. Après l'exécution ces 2 arguments sont disparus de la pile.
Sur la deuxième ligne on a été cherché la valeur de j pour l'imprimer.

maintenant on va voir comment compiler un nouveau mot dans le dictionnaire.

: carre dup * ; ( n|u -- n|u) \ calcule le carré

Le mot ':' sert à définir un nouveau mot dans le dictionnaire. Il est suivit du nom du mot qu'on va définir carre. Ce mot est très simple, il se compose de dup et *. Le mot 'dup' sert à cloner la valeur au sommet de la pile. Après son exécution les 2 premiers éléments de la pile sont donc identiques. Le mot '*' a déjà été présenté. Le mot ';' indique la fin de la définition. Ce qui viens après le point-virgule sont des commentaires. Il y a deux mots pour les commentaires en forth, le mot '(' introduit un commentaire qui est terminé par le délimiteur ')'. Le mot '\' introduit un commentaire qui se termine avec la fin de la ligne. Notez bien que j'ai écris qu'il s'agissait de mots. On doit donc laissé un espace avant et après chacun d'eux. Par contre la parenthèse de droite n'est pas un mot c'est un délimiteur. Cette forme de commentaire est une convention en forth. Le commentaire entre parenthèse décris l'état de la pile avant et après l'exécution du mot. On dit qu'au départ on a un nombre signé 'n' ou non signé 'u' et qu'après l'exécution du mot on a le même type de nombre au sommet de la pile en remplacement du nombre initial. Ici le symbole '|' indique une alternative (c'est l'un ou l'autre). Après ce commentaire un peut utiliser le mot '\' pour donner une brève description de ce que fait ce mot.

Premier programme en forth

Vous vous rappelez sans doute que la première fois que vous avez branché votre carte launchpad les LEDS verte et rouge se sont misent à clignoter en alternance. Mais maintenant qu'on a installé 4e4th dans le MCU ce programme a été écrasé. On va recréer ce programme en forth. Et vous allez être étonnés de la simplicité avec laquelle on fait ça. Mais d'abord entrez les lignes suivantes dans le terminal.

green .s drop drop <ENTER>
red .s 2drop <ENTER>

Je vous présente 5 nouveaux mots. 'green', 'red', '.s', 'drop' et '2drop'.

  • green empile les valeurs 64 et 33. 64 est le masque du bit P1.6 et 33 est l'adresse du port 1. Le LED vert est bien branché sur P1.6
  • red empile les valeurs 1 et 33. 1 est le masque du bit P1.0 et 33 encore un fois l'adresse du port 1. Le LED rouge est bien branché sur P1.0
  • .s est un mot utile pour le débogage. Il imprime le contenu de la pile sans la modifier. Le nombre entre '<' et '>' est le nombre d'éléments qu'il y a sur la pile. Suis les valeurs. La plus profonde à gauche et le sommet à droite.
  • drop jette la valeur qui est au sommet de la pile. Dans le première commande je l'ai utilisé 2 fois car je voulais jeter les 2 valeurs empilées par le mot green
  • 2drop jette les 2 valeurs qui sont au sommets de la pile. Plutôt que d'utiliser 2 fois drop.
Il existe plusieurs mots qui permettent de manipuler les valeurs sur la pile, ils sont parmis les premiers qu'il faut apprendre: swap, rot, over, tuck, nip, etc.
Voyons maintenant notre premier programme forth. Saisissez les lignes suivantes au terminal.

: rouge-vert ( -- ) \ allume en alternance les LEDS rouge et verte <ENTER>
green cclr <ENTER>
red cset <ENTER>
begin green ctoggle red ctoggle <ENTER>
250 ms <ENTER>
s2? until <ENTER>
green cclr red cclr ; <ENTER>
rouge-vert <ENTER>

La majorité des mots utilisés dans cette définition sont spécifique au launchpad et vous ne les retrouverez pas sur une autre plateforme. Donc on difini le mot rouge-vert.

  • cclr Ce mot prend l'adresse du port et le masque qui sont au sommet de la pile et met le(s) bit(s) correspondant(s) à zéro.
  • cset Ce mot prend l'adresse du port et le masque qui sont au sommet de la pile et met le(s) bit(s) correspondant(s) à 1.
  • ctoggle Ce mot prend l'adresse du port et le masque qui sont au sommet de la pile et inverse la valeur de(s) bit(s) correspondant(s).
  • begin Ce mot débute une boucle.
  • until Ce mot termine la boucle si la valeur au sommet de la pile est vrai.
  • s2? Ce mot vérifie l'état du bouton s2 qui est sur la carte et met la valeur vrai au sommet de la pile si le bonton est enfoncé, sinon mais la valeur faux.
  • ms Ce mot créé un délais en millisecondes dont la durée est spécifiée par la valeur au sommet de la pile.

Description du programme

Notre programme est un mot qui s'appelle rouge-vert. On commence par initialisé l'état des LEDs en inverse. Au départ on éteint la verte (ligne 2) et allume la rouge (ligne 3). Ensuite on crée une boucle dans laquelle à chaque cycle on inverse l'état des 2 LEDS (ligne 4). A la ligne 5 on crée un délais de 250 millisecondes. A la ligne 6 on vérifie l'état du bouton s2 qui est sur la carte et on termine la le programme si le bouton est enfoncé. Mais avant de quitter le programme on éteint les 2 LEDS. Une fois qu'un mot est définie dans le dictionnaire il suffit de taper son nom pour l'exécuter.

Conclusion

Si cette brève introduction au forth vous donne le goût d'en savoir plus, vous trouverez dans l'internet tout ce qu'il faut pour satisfaire votre soif de connaissance. Voici quelques liens pour débuter.

  • Vous pouvez télécharger et installer gforth sur votre ordinateur. Ce forth est conforme au standard ANS.
  • Vous pouvez aussi visiter le site Forth Interest Group
  • Les 2 livres de Leo Brodie sont disponible gratuitement dans l'internet. Thinking forth est disponible en PDF et Starting forth peut-être lu en ligne ici.
  • Je ne crois pas qu'il soit encore disponible sinon peut-être dans une bibliothèque publique, Programmer le forth de Robert Van loo aux éditions Marabout est une bonne introduction.

comment fonctionne un UAL

$
0
0

Dans cet article j'explique comment fonctionne l'Unité Arithmétique et Logique d'un microprocesseur. l'UAL (ALU en anglais) est la partie du processeur qui effectue les opérations arithmétiques et logiques sur les données. Les opérations les plus fréquentes sont l'inversion (NOT), le OU (OR), le ET (AND) et le OU exclusif (XOR), l'addition et la soustraction. Référez-vous à la page MCU 101 pour le schéma interne d'un microcontrôleur PIC de base.

Les fonctions logiques de base et leur symbole électronique sont à la page suivante: toute la vérité. Donc pour ces opérations logiques c'est simple il suffit de mettre en parallèle autant de portes logiques qu'il y a de bits dans les mots. Pour un microcontrôleur 8 bits on a donc 8 portes pour chaque opérations, un pour chaque paire de bits.

Pour chaque opération logique il existe un circuit semblable sauf que le ET est remplacé par l'opérateur désiré.

Addition et soustraction

Le circuit logique pour faire des additions est un peu plus complexe. Un additionneur sur 1 bit ressemble à ceci.

Si on regarde les tables de vérité des fonctions logique XOR et AND on comprend comment cet additionneur fonctionne. En effet dans le cas du XOR on a un 1 à la sortie seulement si A ou B a pour valeur 1 mais pas les 2 en même temps. En effet puisque 1+1=2 le bit le moins significatif reste à zéro et on a un report sur le bit suivant plus significatif. C'est le rôle du ET de faire ce report. Cependant puisque l'additionneur doit tenir compte du report du bit de poids faible qui le précède on doit doubler le circuit pour avoir un additionneur complet. Le Cin est le report du bit précédent et le Cout est le report qui va au Cin du bit suivant. Cout est à 1 si A+B=2 ou si Cin+A+B > 1. C'est bien ce que nous dit ce circuit.

Donc pour avoir une addition sur N bits il suffit de reproduire ce circuit N fois en rapportant le Cout vers le Cin du bit de poids plus fort qui suit. C'est à dire Cout0 -> Cin1, Cout1 -> Cin2, etc et le dernier Cout va dans le Carry du registre d'état (STATUS REGISTER) et indique s'il y a eu débordement lors de l'addition.

Pour faire les soustractions le même additionneur est utilisé mais avec un astuce qu'on appelle addition sur complément de 2. Je vais expliquer ce principe en utilisant la base 10 qui nous est plus familière. Supposons que je veux faire la soustraction 7-3=4 mais je n'ai pas de soustracteur alors j'utilise le complément à 10 de 3 et je l'additionne à 7. Le complément est la différence entre le chiffre et sa base. Donc pour 3 le complément est 7. Donc eu lieu de faire une soustraction je fait l'addition 7+7=14. Je ne garde que le 4 ce qui est bien le résultat de 7-3. Oui mais si j'ai 2 digits? 75-31=44. Ici le complément est sur 100 donc pour 31 il s'agit de 69. 75+69=144. Ce principe s'applique à toutes les bases numériques. Donc c'est le même concept en base 2. Pour faire une soustraction en base 2. J'inverse tous les bits de l'opérande qui est soustraite et j'ajoute 1 et ça donne le complément à 2.

En terme de circuit c'est simple, avant d'envoyer l'opérande qui est soustraite à l'additionneur on la fait passer par l'inverseur et de plus le Cin du bit 0 est mis à 1 et on effectue l'addition. Le carry bit du Status register est maintenant à 1 si le nombre soustrait est plus petit ou égal à l'autre nombre sinon il est zéro. Voilà pourquoi la logique du carry bit est inversée lors d'une soustraction par rapport à l'addition. Alors que lors d'une addition 1 dans le Carry indique un débordement, lors d'une soustraction 1 signifie qu'il n'y a pas eu d'emprunt (borrow).

Comment l'opération est sélectionnée

Maintenant comment l'opération indiqué par le code machine est-elle sélectionnée? On utilise des démultiplexeurs et des multiplexeurs. Voici un bloc diagramme avec démultiplexeurs sur les opérandes et un multiplexeur sur la sortie du résultat. Le deuxième shéma n'utilise pas de démultiplexeurs en entrée. les opérandes sont envoyées vers tous les opérateurs et on ne sélectionne que le résultat désiré. Dans le cas d'un PIC puisque W est toujours sélectionné comme une des opérandes on peut le laissé branché en permanence sur une des entrées des opérateurs. Pour l'autre opérande le seul sélecteur est le décodeur d'adresse de la RAM. C'est plus économique comme circuit.

Les signaux Sx sont les entrées de sélection, les bits du code machine qui sélectionne l'opération sont envoyés vers ces entrées. Le nombre d'entrées Sx est le logarithme base 2 du nombre de sorties. S'il y avait plus de 4 sorties il faudrait ajouté une entrée S2 et les portes ET devrait avoir 4 entrées. Il faut une entrée par bit sélecteur plus 1 pour le bit à transférer.

Dans le cas du démultiplexeur le bit d'entrée i est dirigé vers le circuit de la fonction désirée fx en fonction du code présent en S1 et S0.

Dans le cas du multiplexeur l'un des bits d'entrée ix est dirigé vers la sortie dépendant du code présent en S1 et S0.

fonctionnement d'un sélecteur

En réalité la majorité des portes logiques utilisées dans un MCU sont dans les sélecteurs (multiplexeur/démultiplexeur). Les sélecteurs sont basés sur des portes ET. Leur principe de fonctionnement est le suivant.

Si une des entrées d'une porte ET est à zéro la sortie sera bloquée à zéro quelque soit la valeur des autres entrées. Donc dans le schéma ci-haut il suffit qu'une seule des entrée de sélection soit à zéro pour que i ne puisse être transféré à la sortie. Pour la porte ET du haut la valeur inverse de S0 et S1 est utilisé pour contrôler la porte. Donc pour que i puisse contrôler la valeur de sortie de cette porte il faut que S0=0 et S1=0 de sorte que leur inverse est à 1. Pour la porte ET du bas les entrées de contrôle sont S0 et ~S1. Donc pour que i puisse contrôler la sortie il faut que S0=1 et S1=0 de sorte que les 2 entrées de contrôle sont à 1. Avec ce type d'arrangement 1 seule porte est ouverte à la fois. On peut multiplié le nombre d'entrées de contrôles et le principe demeure le même. Pour 2 entrées de contrôle la table de vérité est la suivante.

S1S0f0f1f2f3
00=i000
010=i00
1000=i0
11000=i

Le décodeur d'instruction

Si on regarde comment les instructions sont encodé dans un microcontrôleur PIC de base comme le PIC10F200. Les instructions sont encodées sur 12 bits.

Prenons le premier format appelée byte-oriented file register operations. Le code d'opération est dans les bits 6 à 11. Ça veut dire que ces 6 bits contrôlent un multiplexeur qui sélectionne l'opération. Sur les PIC l'une des opérandes est toujours dans le registre W et l'autre provient d'un file register qui lui est sélectionné par les bits 0 à 4. Le bit 5 d décide de la destination du résultat. Puisque le résultat n'a que 2 destinations possibles 1 seul bit suffit. Ce bit contrôle un démultiplexeur à 2 sorties vers W ou vers F. Le fait qu'une des opérandes est fixe simplifie le circuit puisqu'on n'a pas besoins de sélecteur pour cette opérande et de plus les instructions peuvent-être encodées sur moins de bits. Il n'y a pas de doute que les PIC nécessitent moins de portes logiques que les AtTiny. Je serais curieux de savoir combien de gates il y a dans le core des PIC de base, 3000, 4000 peut-être.

Décodeurs d'adresse mémoire

Qu'il s'agisse de la mémoire flash ou de la RAM il y a 2 bus, 1 pour l'adresse et un pour la donnée. Le bus d'adresse est branché sur le sélecteur et détermine quel cellule mémoire sera connectée au bus de données. Le nombre d'adresses mémoire à sélectionner est trop élevé pour le multiplexeur simple montrer ci-haut. La raison principale est qu'il y a une limite au nombre de porte qu'une sortie peut alimenter. Or on le voie chaque bit sélecteur doit alimenter la moitié des portes. D'autre part il y a aussi une limite au nombre d'entrées qu'une porte ET peut avoir. Pour régler ce problème les sélecteurs de mémoire sont à 2 dimensions ou plus dépendant de la taille de la mémoire. Voici de quoi a l'air un sélecteur à 2 dimensions.

Il y a 2 décodeurs. Un appelé lignes et l'autre colonnes. Les cellules mémoires sont reliées aux 2 décodeurs selon une topologie qui rappelle un plan. Pour qu'une cellule soit sélectionnée il faut que sa ligne et sa colonne le soit. Si la mémoire est trop grosse pour 2 décodeurs on ajoute un troisième décodeur qui lui sélectionne des plans superposés d'où le nom de 3 dimensions. Si on prend le PIC10F200 qui n'a que 256 mots flash, le décodeur doit avoir seulement 2 dimensions avec 4 bits par décodeur. Les bits 0-3 du compteur ordinal vont sur le décodeur de lignes et les bits 4-7 sur le décodeur de colonnes ou vice-versa peut importe.

Conclusion

En conclusion peut importe le nombre de bits du processeur il s'agit simplement de répéter ces circuits le nombre de fois qu'il y a de bits 8, 16, 32, 64 . Si cette introduction vous a plus et que vous avez envie d'en savoir plus il y a cours gratuit sur internet (en anglais) qui s'appelle from NAND to TETRIS

. Ce cours commence avec les portes simples et progresse vers les circuits plus complexe jusqu'au processeur complet et s'accompagne d'un logiciel qui permet de définir les circuits logiques et de les tester dans un simulateur. Très bien fait, c'est une formation 5 étoiles gratuite.

du sable au processeur

$
0
0

Enfant on s'amuse à construire des châteaux de sable, plus tard on l'utilise pour couler le béton des fondations de sa maison mais le sable a d'autres usages, le verre et les circuit-intégrés entre autre. Dans cette chronique je présentes et commente quelques vidéos intéressants que j'ai déniché sur youtube.

Le silicium est le second élément le plus abondant de ce qui constitue la croûte de notre planète. Cependant il n'existe pas à l'état pur. Le plus souvent il se présente sous sa forme oxydé comme la majorité des éléments d'ailleurs. Pour fabriquer des semi-conducteurs il faut du silicium pur à 99.9999999%. Mais cette pureté n'est pas suffisante en elle-même, il faut que le lingo dans lequel sont découpés les disques soit monocristallin. Le vidéo suivant montre comment à partir des pépites de silicium de grade électronique poly-cristallin on fabrique ce lingot très spécial.

Procédé de Czochralski

Les pépites de silicium sont fondues dans un creuset en graphite/quartz. Un petit Crystal de silicium accroché au bout d'une tige est plongé dans ce silicium en fusion. Le creuset tourne dans un sens et la tige dans l'autre. La tige est remontée lentement et le silicium qui s'accroche au cristal initial durci en gardant la même structure cristalline que ce dernier. Le procédé est arrêté lorsqu'il n'y a plus de silicium dans le creuset. On obtient ainsi un lingot cylindrique dont le diamètre varie entre 15cm et 40cm. Le diamètre est fonction de la vitesse à laquelle est remonté la tige.

Une fois le lingot refroidit les extrémités sont coupées et la couche extérieure enlevée. De plus une surface plate est créée sur le cylindre qui va servir de guide pour le reste du procédé. Le lingot est découpé en disques en utilisant un fil d'acier recouvert de grains de diamant. Le fils est enroulé de nombreuse fois sur une série de cylindres d'entrainement avec un espacement régulier entre chaque passage. Le lingot est déposé sur ce lit de fils. Comme le fil est tiré de la bobine débitrice vers la bobine réceptrice il frotte sur le lingot et s'enfonce lentement dans celui-ci. Au final on a les disques de silicium.

Les disques obtenus sont ensuite polis sur les 2 faces pour enlever la surface abimée et les réduire à l'épaisseur désirée. Ils subissent ensuite un traitement dans un bain chimique pour encore nettoyer la surface.

Ensuite les disques de silicium subissent le polissage final. Celui-ci est effectué avec un pâte abrasive dont la granularité est extrêmement fine car la surface des disques ne doit pas avoir d'aspérités supérieures à quelques atomes d'épaisseur. Après cette étape les disques sont prêt à être acheminés vers l'usine de fabrication de circuits intégrés.

Du disque de silicium au Circuit-intégré

Le silicium pur monocristallin est isolant à la température de la pièce, pour en faire un semi-conducteur il faut introduire des impuretés. Pour construire les transistors il faut 2 types de semi-conducteurs P et N. le silicium a 4 électrons de valences et ses 4 électrons sont fixés par la structure du cristal donc le courant ne peut circulé. En ajoutant quelques atomes de phosphore dans la matrice cristalline on libère un électron car le phosphore en a 5 et que seulement 4 participent au liens covalents de la structure cristalline. Ce type de semi-conducteur est dit de type Négatif car il y a un électron qui est libre de se déplacer dans la matrice. Si au contraire on ajoute du bore qui lui à 3 électrons de valence. Il y a un défaut de liaison dans la structure cristalline. Il manque un électron pour assuré le 4ième lien covalent. Ce type de semi-conducteur est dit de type Positif car il y a un ion positif dans la structure qui va attiré un électron vers lui.

Les circuits sont construits par couches successives. La technologie est dite CMOS pour Complementary Metal Oxyde Semiconductor. C'est à dire que chaque porte logique est construite avec 2 transistors à effet de champ complémentaire, PFET et un NFET.

Lorsqu'un des transistor conduit l'autre est bloqué de sorte que le signal de sortie est soit connecté à Vdd ou à Vss. Chaque transistor est construit avec les 2 types de semi-conducteurs. Les PFET on un canal (channel) construit avec le type P et les drains et sources avec le type N. C'est l'inverse pour les NFET.

Pour injecter les ions phosphore ou bore dans la surface de silicium des canons à plasma sont utilisés. D'abord un masque est posé sur le disque et dans ce masque il y a des trous seulement aux endroits on les ions doivent-être implantés. Il y a un masque pour les transistors PFET qui sert à injectés les ions bore pour former les drains et source de ces transistors. Ensuite il y a un masque pour injecter les ions phosphore pour former les drains et sources des transistors NFET. Ensuite une couche isolante d'oxyde de silicium est déposée à la grandeur du disque. A l'étape suivante le masque pour former les gates de tous les transistors est utilisé. Les gates sont en silicium poly cristallin. Ensuite la couche isolante d'oxyde de silicium qui couvre les sources et drains doit-être enlevée pour pouvoir installer les conducteurs qui relient les transistors entre eux pour former le circuit désiré. Il peut y avoir plusieurs couches de conducteurs/isolants superposées car les fils se croisent à la surface comme pour un circuit imprimé.

Fab Intel

Finalement voici un vidéo filmé à l'intérieur d'une usine d'Intel qui fabrique les core I7. Ici il s'agit de disque de 40cm. Le procédé est presqu'entièrement automatisé. Ces usines coûtent plusieurs milliards de dollars Américains à fabriquer. L'air doit-être filtré avec des filtres extrêmement fins afin d'être débarrassée de toutes les poussières.

dissection d'un PIC10F200

$
0
0

Après avoir endommagé un PIC10F200 plutôt que de le mettre directement à la poubelle j'ai décidé d'en faire la dissection. C'était un format PDIP-8. J'ai simplement utilisé une lime pour enelevé l'époxy jusqu'à ce que j'apercoive le die de silicium.

J'ai mesuré la dimension du die avec un micromètre. Le die lui-même est collé sur une languette de cuivre qui fait la longueur du support d'époxy. Si vous avez en main un PIC10F200 en format DIP-8 en observant chaque extrémité vous apercevrai 2 affleurement métallique. Il s'agit des extrémités de ce support de cuivre qui sert de dissipateur de chaleur. On aperçois sur la première photo une des extrémités de ce support de cuivre, l'autre extrémité a été arrachée. Au centre on aperçois le microprocesseur lui-même. Les broches sont tombées mais on aperçois leur emplacement en creux dans l'époxy. La deuxième photo a été prise au microscope 15x. La gravure dans le silicium est beaucoup trop fine pour qu'on aperçoive quoi que ce soit d'intéressant à ce niveau. On aperçois les pads sur lesquels sont soudés les fils qui vont aux broches. I faudrait un très fort grossissement pour apercevoir les tracés. J'ai regardé avec un microscope 300x (je ne pouvais installer de caméra sur ce microscope). A 300x on aperçois seulement les plus grandes structures. Entre autre on vois la région ou est gravé la mémoire flash. Elle apparaît comme 3 rectangles côte à côte.

alimentation variable économique

$
0
0

Voici une petite alimentation variable que j'ai fabriqué à très faible coût grâce à la récupération. Les seuls composants qui ne sont pas de récupération sont le potentiomètre 1K et son bouton, la LED ainsi que les 2 banana jack. Le boitier a été fabriquer à partir des morceaux de plastique récupéré d'une horloge pendule à pile. Le mouvement de l'horloge était dans ce qui m'a servi de base et la face frontale du boitier est un morceau découpé à l'extrémité d'une grande plaque de plastique qui était dernière le pendule. La majorité des composants électroniques ont été récupérés d'un adapteur AC/DC Radio Shack dont le fil était brisé et qui traînait sur une tablette depuis des années. J'ai dessoudé les composants du circuit imprimé original pour les ressouder sur un morceau de carte de prototypage de dimension plus approprié pour le montage sur cette base.

Spécifications de l'alimentation

  • variable de 1,25 à 5,5 volt
  • Courant maximum 500 ma
En utilisant un potentiomètre de 2 Kohm au lieu de 1 Kohm j'aurais pu faire monter le voltage jusqu'à 10Volt mais comme mon intention est d'utiliser celle-ci avec des montages de MCU je n'ai pas besoin de monter à plus de 5 volt. 500 ma c'est peu mais encore là les montages que je fais drainent rarement autant de courant.

Le schéma très simple utilise un régulateur LM317.
Je ne me suis pas donné la peine de fabriquer un couvercle pour couvrir le circuit.
La face frontale me plaît pour un morceau de plastique récupéré c'est pas si mal et le noir se mari bien avec le commutateur récupéré d'une vieille cafetière. À guauche de l'alimentation on aperçoit les 2 parties de la coquille de l'adapteur Radio Shack que j'ai éventré.

Ce qui manque à cette alimentation c'est un indicateur de voltage. Je dois brancher mon multimètre pour l'ajuster. Je songe à y ajouter un petite barre de LED à 10 segments contrôlé par un micro-processeur. J'aurais ainsi un afficheur avec une résolution de 0,5 volt.

LED blanche sur 3 volt

$
0
0

Voulant remplacé l'ampoule à incandescence par une LED blanche dans une lampe de poche fonctionnant sur 2 piles 1,5 volt il fallait pour obtenir l'intensité maximale de la LED rehaussé le voltage car une LED blanche donne son intensité maximale à 3,6 volt. La LED que j'ai utilisé consomme 120mA à 3,6 volt mais le courant tombe à 60ma à 3 volt donc seulement 50% de l'intensité et lorsque les piles faiblissent la chute de courant est encore plus rapide.

J'ai donc conçu le circuit suivant.

note: erreur sur le schéma, L1 est 27µH et non 270µH

Le code source pour faire fonctionner ça n'a que 13 instructions.

Fonctionnement

Il il s'agit d'un boost converter. Lorsque le transistor Q1 conduit le courant dans L1 augmente exponentiellement et avec le courant un champ magnétique est créé. Ce champ magnétique accumule l'énergie. Lorsque Q1 est bloqué le champ magnétique s'effondre ce qui a pour effet de créer un potentiel électrique aux bornes de L1 de polarité inverse à celui lorsque Q1 conduit. Ce voltage s'additionne donc à celui de l'alimentation et à travers la diode D1 charge le condensateur à un voltage supérieur à celui de l'alimentation. Il s'agit d'un transfert d'énergie du champ magnétique de l'inductance au champ électrique du condensateur.

Dans le premier circuit que j'ai fait je n'avais pas mis de contrôle du courant et j'ai brûlé une LED. J'ai donc modifié le circuit pour m'assurer que le courant qui circule dans la LED est limité. la résistance R3 en série avec la LED permet une rétroaction grossière mais néanmoins efficace. Le booster n'est activé que si GP1 est a 0 logique, alors le programme charge l'inductance et envoie une impulsion de boost au condensateur en bloquant Q1 après avoir chargé le champ magnétique de l'inductance. Ensuite le programme attend que le voltage sur GP1 retombe à 0 volt avant d'envoyer une autre impulsion de boost. Ça produit des pics de courant dans la LED mais ça ce fait à environ 50Khz trop rapide pour être perçu par l’œil et de plus R3 a été calculé pour que le courant moyen dans la LED ne dépasse pas les spécifications. Voici de quoi à l'air le voltage aux bornes de R3.

Alimentation à 3 volt. Courant moyen = 0,8v/6,8ohm = 117ma. Cette LED peut tolérée 120ma.
alimentation à 2,5 volt. Courant moyen = 0,66v/6,8ohm = 97ma.

montage

J'ai utilisé un petit morceau de protoboard et un MCU en format SOT23-6. Après avoir cassé le verre de l'ampoule à incandescence, j'ai collé le morceau de protoboard sur la base.

conclusion

L'ampoule à incandescence consommait plus de 500ma alors que la LED en consomme 120mA mettons 130mA pour le circuit au complet. La LED produit une lumière plus intense et sa durée de vie et plusieurs fois supérieure. Au coût actuel des piles je crois que ça valais la peine de faire cette modification. Cependant comme la LED est au bout du circuit imprimée et que la lampe de poche en question a une lentille au centre de la fenêtre la lampe produit maintenant un faisceau large au lieu d'un faisceau étroit. En effet la distance focale de la lentille a été calculé en tenant compte de la distance du filament hors le LED est beaucoup plus prêt de la lentille parce qu'elle est au bout du circuit imprimé et que ce dernier est plus long que l'ampoule originale. Je m'en doutais bien mais il m'était impossible de faire ce montage sur un circuit plus petit et en largeur il fallait que ça passe dans le trou de l'ampoule car la face avant est scellée.

Viewing all 189 articles
Browse latest View live




Latest Images