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

PIC10F322 clap-switch

$
0
0

L'article précédent j'ai présenté un clap switch fait avec un pro trinket. Mais utilisé une carte qui coûte 10US$ pour faire ça c'est comme vouloir tuer une mouche avec un canon. J'ai fait un autre montage en remplacant le pro trinket par le plus petit des MCU, le PIC10F322 de Micrhochip.

schématique

Pour cette démonstration j'ai dessiné un circuit complet à l'usage de ceux qui voudraient réellement fabriquer la chose pour contrôler une lampe par exemple. Pour ma part je n'ai testé que la partie basse tension (microphone + MCU) en utilisant un LED à la place du relais.

Le circuit es conçu pour l'Amérique du nord. Nous utilisons du 120VAC/60hertz et non du 220VAC/50hertz comme en Europe pour l'alimentation électrique des domiciles.

L'entrée analogique est sur RA2 (broche 3 sur format PDIP) et la sortie de contrôle sur RA0 (broche 4 sur PDIP).

code source

Le code source a été écris en mpasm, il ne fait que 128 instructions et utilise 14 octets de RAM, il peut donc être fait avec un PIC10F320 (256i/32RAM).

idée à explorer

Une modification au logiciel permettrait d'utiliser ce circuit comme verrou électronique qui répondrait à un code rythme. Imaginez qu'on mesure le temps entre chaque claquement et qu'on utilise plusieurs clap on obtiendrais une séquence rythmique pouvant être utilisée comme clé pour dé/verrouiller une porte. Le micro serait collé sur la porte et analyserais les toc-toc au lieu des claquements de mains.


PIC10F322 + CLC = triangulaire

$
0
0

J'aime beaucoup le PIC10F322 car je ne connais aucun autre MCU de cette catégorie qui possède autant de fonctionnalités. Voici un exemple des possibilités offertes par ce MCU . Dans ce démo je fais varié l'intensité d'une LED sans utiliser le moindre cycle CPU en utilisant la richesse des périphériques du PIC10F322. En l'occurrence les périphériques suivants sont utilisés.

  1. TIMER2
  2. PWM1
  3. NCO (Numerically Controlled Oscillator)
  4. CLC (Configurable Logic Cell)

Dans ce vidéo on voie la LED pulsée ainsi qu'a l'oscilloscpoe l'onde en sortie PWM1 (tracé bleu) ainsi que l'onde rectangulaire qui alimente la LED (Tracé en jaune).

On voie que le rapport cyclique du signal varie de façon continu selon une fonction triangulaire et pourtant si vous examiner le code source vous ne verrez aucune instruction pour modifier le rapport cyclique du PWM, on voie d'ailleurs à l'oscilloscope qu'il est fixe. En fait une fois les périphériques configurés le programme entre dans une boucle infinie vide.

Code source

programme prnicipal
code généré par CLC designer

Comment ça fonctionne

Ceci est possible grâce à la Cellule Logique Configurable (CLC). Cette cellule est simplement configurée comme un OU exclusif (XOR gate) qui reçoit en entrés 2 ondes carrées avec un rapport cyclique de 50% à une fréquence d'environ 3200 hertz. L'une de ces ondes est générée par PWM1 et l'autre par le NCO. à l'incrément du NCO est ajouté une valeur appelée NCO_OFFSET de sorte que la fréquence de celui-ci est légèrement différente de celle générée par PWM1. Puisque les fréquences sont différentes la phase des signaux glisse l'un par rapport à l'autre. La fonction XOR fait en sorte que la sortie n'est à 1 que lorsque les 2 signaux sont en opposition de phase.

En fait l'intensité de la LED est directement proportionnelle à la différence de phase entre les 2 signaux.

Elle est où l'onde triangulaire?

Pour ceux qui se demandent quel est le rapport avec une onde triangulaire voici une photo prise à l'oscilloscope en remplaçant la LED par ce filtre passe-basse:

On observe ceci à la sortie du filtre:
Mesuré avec les curseurs la fréquence de l'onde triangulaire est de 0,78 hertz. Pour voir plusieurs cycles de l'onde triangulaire J'ai du changer l'échelle de temps sur l'oscilloscope de sorte que les cycles du signal PWM (en bleu) sont confondus.

Conclusion

Il y a ce qu'il faut dans ce MCU pour fabriquer une circuit à verrouillage de phase (PLL). Voici un schéma simplifié d'un tel circuit.

Le VCO est un oscillateur dont la fréquence est contrôlée par un voltage (indiqué Vcont. sur le dessin). Ce type de circuit peut-être utilisé entre autre comme démodulateur FM ou encore pour générer une fréquence arbitraire à partir d'un fréquence de référence. Plusieurs MCU utilisent un PLL pour générer la fréquence qui contrôle le CPU. Dans ce type d'application il faut insérer un diviseur de fréquence entre la sortie du VCO et l'entrée du XOR. de sorte que le VCO fonctionne à une fréquence multiple de la référence.

PIC micro Pascal

$
0
0

La semaine dernière j'ai découvers l’existence d'un compilateur PASCAL pour les microcontrôleurs PIC 8 bits. Ce compilateur s'appelle PIC micro Pascal ou en abrégé PMP. Lorsque je programme des MCU je le fais en assembleur ou en 'C'. Mais comme j'ai programmé en Turbo Pascal et en Delphi par le passé j'ai décidé de mettre ce compilateur au banc d'essai. Pour ce faire j'ai utilisé la version 2.06 qui est encore en version bêta. J'ai d'ailleurs découvers et rapporté un bug régressif1 dans cette version. Je reparlerai de ce bug plus loin dans cet article.

Présentation

L'initiateur et auteur principal de PMP est Philippe Paternotte, la contribution des autres membres de l'équipe consiste principalement en des librairies. Il a écris ce compilateur en Delphi, il s'agit d'une application Windows. PMP est disponible gratuitement mais le code source ne l'est cependant pas. Il ne s'agit pas simplement d'un compilateur mais aussi d'un IDE basé sur Scintilla.

PMP est un sous-ensemble de Turbo Pascal, les principales restrictions étant les suivantes.

  • Ne supporte pas la programmation par objets.
  • Les ARRAY ne peuvent avoir qu'une seule dimension.
  • Ne supporte pas les fonctions et procédures imbriquées.
  • Ne supporte que les RECORD simple, i.e. sans RECORD imbriqués, ni ARRAY ou CASE.
  • Ne supporte qu'un seul niveau d'indirection, i.e. v1^m1^x n'est pas supporté.

PMP ne génère pas de code binaire pour les PIC il génère plutôt un fichier source pour l'assembleur MPASM. Donc MPLAB ou MPLABX doit-être installé avant de procéder à l'installation de PMP. Lors de l'installation PMP recherche mpasm.exe et mplink.exe et doit les trouvés pour fonctionner correctement.

Puisque PMP n'est pas intégré à MPLAB(X), pour flasher le microcontrôleur il faut soit utiliser un outil externe comme Pickit 2 programmer ou ce qui est plus malcommode créer un projet dans MPLAB(X) et y importer le fichier source assembleur généré par PMP. Une autre possibilité est d'utiliser les outils GPUTILS. Dans sa version 2.06 PMP supporte les outils GPUTILS. Pour utiliser GPUTILS sous windows il faut installer mingw32.

En ce qui concerne la documentation qui viens avec PMP elle existe sous forme de fichier PDF et d'un fichier d'aide Windows CHM pour l'aide en ligne.

Installation

L'installation est si simple qu'elle se passe d'explications. Au premier lancement l'IDE demande si on veut associé les fichiers avec l'extension .pmp et .pas avec celle-ci. Sous Windows 7 l'installation se fait dans C:\Program Files (x86)\PMP\V2.0.6. Ce dossier contient un dossier examples.

Premier programme

Mon objectif principal pour ce banc d'essai était de voir si PMP fait une bonne optimisation du code. Dans ce but j'ai réécris le code de mon article intitulé chandelle électronique. J'ai recréé exactement la même structure de programme en Pascal que celle que j'avais en assembleur.

Ce programme utilise un PIC10F202. Ce MCU n'est pas du tout conçu pour supporter la programmation dans un langage de haut niveau comme PASCAL, ce qui rend l'optimisation encore plus difficile. Voici donc le code source créé dans l'IDE de PMP.

Comparaison

usageASMPMPXC8 free
octets RAM91218
code FLASH779094
Les octets de RAM supplémentaires utilisés par PMP sont:
  • __BitStack, 1 octet, sert à sauvegarder les status bits pour la donnée qui est dans __STACK__0.
  • __STACK__0, 1 octet, utilisé comme variable temporaire.
  • __FLAGS, 1 octet, est utilisé pour les variables de type boolean définies dans le programme PASCAL.
La variable __FLAGS n'est pas utilisée puisqu'il n'y a pas de variable booléennes dans le programme. LED ne compte pas car cette variable est définie sur le SFR GPIO. Notez qu'on utilise @ pour définir une variable sur une adresse absolue. donc dans le code

var
LED :boolean @ GPIO.2 ;
Signifie que la LED est sur le BIT 2 du SFR GPIO. Ce qui en assembleur est traduis par:

flicker.LED equ 2 flicker.LED ; Bit 2 in GPIO
Puisque __FLAGS n'est pas utilisée dans ce programme le compilateur aurait du optimiser en supprimant cette variable ainsi que l'instruction clrf __FLAGS dans la section d'initialisation.

Bug régressif dans la version 2.06B

A la ligne 49 du code PASCAL on retrouve la ligne:


if (7<rand_val) then rand_val:= rand_val div 2;
Ce n'est pas le code que j'ai écris au départ mais plutôt:

if (rand_val>7) then rand_val:= rand_val div 2;
Mais pour faire la comparaison le compilateur a généré:

movf flicker.rand_val, W ; Get variable in acc
bsf __BitStack, 0 ; Prepare bit ACC (true)
sublw h'07' ; subtract W to constant
Le problème c'est que l'instruction sublw n'existe pas dans le jeux d'instructions des PIC baseline. Mais simplement en inversant la comparaison le code généré deviens:

movlw h'07'
movwf __STACK__0 ; Push byte
movf flicker.rand_val, W ; Get variable in acc
bsf __BitStack, 0 ; Prepare bit ACC (true)
subwf __STACK__0, W ; Compare to stack byte

Lorsqu'on étudie le code assembleur généré par PMP on comprends rapidement pourquoi ça prend 16% de plus d'instructions. Il semble que toutes les comparaisons sur les variables passe par __BitStack et __STACK__0.

Conclusion

Bien sur ce banc d'essai est bref et je vais certainement poursuivre d'autres expérimentations avec PMP mais ça m'a quand même permis de me faire une idée du prix a payer en terme d'utilisation de l'espace de code. Le résultat est meilleur que celui obtenu avec XC8 version gratuite. Donc pour ceux qui préfère le PASCAL au 'C'ça peut-être intéresssant. Personnellement pour un programme PIC qui a moins de 512 instructions je préfèrerai toujours programmer en assembleur. Donc pour tous les PIC10F, PIC12F qui disposent de 256/512 instructions de FLASH.


NOTES:
1) un bug régressif est un bug qui a été introduit dans la version courante alors que la même fonctionnalité fonctionnait correctement dans une version antérieure.

PIC micro Pascal, test #2

$
0
0

J'ai poursuivi mes expérimentations avec PMP. Cette fois ci j'ai repris le programme ambiance pingpong et j'ai retravaillé les versions assembleur et XC8 et créé une version avec PMP. Ces versions cible le PIC10F200 au lieu du PIC10F202, ce qui réduit la mémoire programme à un maigre 256 location et la RAM à 16 octets. J'ai commencé par la version en 'C' et j'ai vraiment du me creuser les méninges pour que ça rentre dans les 16 octets de RAM car le compilateur XC8 utilise plusieurs octets de RAM supplémentaires en plus de celle définis dans le code source. J'ai finalement réussi à faire entrer ça dans les 16 octets de RAM. Pour la mémoire FLASH il n'y a pas vraiment eu de problème. Dans cet article je présente donc les 3 versions de code, et je compare les ressources utilisées ainsi que la vitesse d'exécution.

Méthode de travail améliorée

Finalement j'ai découverts la méthode la plus pratique pour travailler avec PMP en utilisant MPLABX pour la programmation du MCU. Dans MPLABX je crée un projet et j'importe le fichier assembleur généré par PMP. Chaque fois que PMP recompile le nouveau fichier assembleur ce dernier est automatiquement disponible dans le projet MPLABX et je n'ai qu'à cliquer sur le bouton "Make and program device" dans la barre d'outil de MPLABX pour reprogrammer le MCU. C'est en fait plus simple que d'utiliser le programme PICKIT 2 programmer et ce n'est pas limité au MCU supportés par le PICKIT 2.

Comparaison des ressources

Voici un tableau comparatif des ressources utilisées par chaque version du programme. Boucle/min. est le nombre de fois que la boucle principale du programme s'exécute pendant la minute d'activité. Sans surprise le code assembleur est beaucoup plus rapide.

versionassembleurC (XC8 free)PIC micro Pascal
RAM111615
FLASH101164162
boucles/min.901560005000

Il semble que les résultats pour XC8 et PMP soient très semblable mais en fait le code assembleur généré par PMP serais de 150 instructions et la RAM utilisée serait de 14 octets si ce n'était pas d'un bug dans la version 2.0.6B du compilateur. le code original de transitionétait: Lorsque le bug sera corrigé dans la version finale de PMP 2.0.6 cette version pourra être utilisée. Pour le moment lorsqu'on passe l'élément d'un tableau aux procédures inc() et dec() c'est toujours le premier élément qui est modifié.

Vitesse d'exécution

Si on regarde le code source, on se rends compte que le gros du temps processeur est passé dans la procédure pwm_control. donc plus cette procédure est courte plus la boucle PWM sera rapide. Pour la version écrite en assembleur cette procédure utilise 17 instructions, celle en C est de 28 instructions et finalement pour celle écrite en Pascal est de 32 instructions. Donc même si au total PMP génère un code légèrement plus court que XC8 ce n'est pas le cas pour la procédure pwm_control ce qui explique qu'en terme de vitesse d'exécution ce code est le plus lent des 3.

Code source des 3 version

La constante EXPIRE est choisie en fonction de la vitesse d'exécution de chaque version pour une durée d'activité de 60 secondes. En première approximation EXPIRE = 60/PWM_PERIOD. La période PWM est elle-même en première approximation


PWM_PERIOD= 256*N*Tcy
Tcy = 1µsec
N ~=nombre d'instructions dans la routine pwm_control+
nombre d'instructions supplémentaires dans la boucle
lorsque pwm_cntr<>0.
Pour chaque version j'ai chronométrée la durée d'activité et recalculé la valeur de EXPIRE et chronométré à nouveau avec la valeur calculée pour m'assurer d'une activité de 60 secondes.

Code source version assembleur

Code source version C

Code source version Pascal

questions quiz

$
0
0

Voici un petit programme à tester dans le simulateur de MPLABX en mode pas à pas. Mais avant essayez de deviner le contenu de STATUS après chaque opération suivie du commentaire STATUS=?. Si vous répondez correctement à chaque étape votre compréhension du fonctionnement interne du CPU est excellente.


include p10f200.inc
__config _WDTE_OFF
radix dec
org 0
main_loop
bsf STATUS,0 ; set C bit
bsf STATUS,1 ; set DC bit
bsf STATUS,2 ; set Z bit
clrf STATUS ; Q1, STATUS=?
bsf STATUS,7 ; Q2, STATUS=?
movfw STATUS ; Q3, STATUS=? W=?
movlw 0x78
addwf STATUS,F ; Q4, STATUS=?
movfw STATUS ; Q5, STATUS=? W=?
xorwf STATUS,F ; Q6, STATUS=?
goto main_loop
end
Pour vous aidez dans votre réflexion voici une représentation du registre STATUS des PIC10F20X.

Réponses et explications

  1. STATUS=0x1F. Pensiez-vous que le contenu de STATUS serais mis à zéro? Erreur car certains bits sont en lecture seule : ~TO et ~PD. De plus Z est mis à 1 car l'instruction CLRF affecte ce bit en le mettant à 1. L'ajustement des bits Z,DC et C se fait à la fin de l'opération et l'opération CLRF ne change pas l'état des indicateurs DC et C. Ces deux là était à 1 donc ils le reste. Donc si vous voulez mettre à zéro les 3 indicateurs ne faites pas un CLRF STATUS mais plutôt:

    BCF STATUS,Z
    BCF STATUS,DC
    BCF STATUS,C
  2. STATUS=0x9F. Ce bit est R/W donc il es mis à 1 tel que prévu par l'opération. Les autres bits ne sont pas affectés.
  3. STATUS=0x9B et W=0x9F. C'est normal puisque l'instruction MOVFW affecte la valeur de l'indicateur Z. Celui-ci a été mis à zéro puisque la valeur transféré dans W n'était pas nulle.
  4. STATUS=0x1B. L'addition a bien donnée le résultat escomptée sauf que les indicateurs Z, DC et C ont été ajusté en conséquence de l'addition. Comme toujours les bit en lecture seule de STATUS n'ont pas été modifiés par le résultat et les 3 indicateurs ont écrasés les bit 0-2 du résultat. Si vous voulez vérifier que l'addition donne le résultat escompté remplacé addwf STATUS, F par addwf STATUS, W et vérifier le résultat dans W.
  5. STATUS=0x1B et W=0x1B. Cette fois-ci STATUS n'a pas été modifié par l'opération MOVFW puisque Zétait déjà à zéro.
  6. STATUS=0x1F. l'opération XORWF n'affecte que le bit Z. Ici on a fait une opération xor de la valeur de STATUS avec elle-même. Le résultat d'une telle opération est zéro. Donc le bit Z a été mis à 1. les bits DC et C ne sont pas altérés. Encore une fois les 3 indicateurs écrase les bits 0-2 du résultat. Le bit 4 (~PD) était à 1 et le reste puisqu'il est en lecture seule.

Drain ouvert (open drain)

$
0
0

Certains microcontrôleurs permettent de configurer les sorties numériques en mode open drain. Dans cet article j'explique ce que ça signifie et je donne des exemples d'utilisation.

configuration d'une sortie numérique

Les sorties numériques des MCU sont composées de 2 transistors MOSFET complémentaires montées entre les 2 rails d'alimentation Vdd et Vss comme ceci.

Les transistors MOSFET ont 3 électrodes. Drain, Source, Gate. Le Gate contrôle le passe du courant entre le Drain et la Source. Lorsque Vin est à 1 le transistor P-MOSFET et bloqué et le N-MOSFET conduit, on a donc zéro à la sortie. À l'inverse si Vin est à 0, le transistor P-MOSFET conduit et le N-MOSFET est bloqué de sorte que la sortie est à 1. Il n'y a qu'un seul transistor qui conduit à un instant donné sinon on aurait un court-circuit entre Vdd et Vss.

Drain ouvert

Maintenant si on désactive le transistor P-MOSFET de sorte qu'il n'y a que le transistor N-MOSFET qui peut entré en conduction alors on a que la sortie sur la broche du MCU est en haute impédance lorsque le N-MOSFET est bloqué ou elle est connecté à Vss lorsque le transistor conduit. C'est ce qu'on appelle une configuration Open Drain

Pour désactiver le P-MOSFET on installe un commutateur analogique (analog switch) comme montré sur le schéma ci-bas. Lorsque le signal open drain et actif SW1a conduit et sw1b est bloqué de sorte que le Gate du P-MOSFET est branché à Vdd le rendant inopérant.

Utilité du Drain ouvert

La configuration Open Drain est utile dans diverses situations, partage du bus entre plusieurs dispositifs, adaptation de niveau de tension, alimentation d'une LED par la cathode.

Par exemple il existe des dispositifs qui utilisent un protocole de bus appelé ONE-WIRE. Ces dispositifs n'utilisent qu'un seul fil pour communiquer avec le microcontrôleur et cette communication se fait dans les 2 sens en semi-duplex.

Dans cette application le bus est connecté à Vdd à travers une résistance pullup. Cette application nécessite un configuration Open drain car plus d'un dispositif partage le bus. En effet si les sorties des dispositifs étaient en montage complémentaire et qu'un dispositif plaçait sa sortie à 0 alors qu'un autre a sa sortie à 1 on aurait un court-circuit entre Vdd et Vss. Avec l'open drain le seul chemin vers Vdd est la résistance pullup et le courant entre Vdd et Vss est limité par la valeur de celle-ci.

adaptation de niveau

Toutes les sorties numérique des PIC24FJ64G00x sont configurable en mode open drain. Ces MCU fonctionnent à 3,3 volt. Supposons qu'on veut interfacer un tel MCU avec un affichage LCD qui fonctionne à 5 volt. Pour adapter les niveaux logiques sur le bus de communication il suffit de configurer les sorties du MCU en open-drain et de mettre des résistances pullup sur les lignes du bus. De cette façon lorsque le transistor N-MOSFET à la sortie du MCU est bloqué le niveau à l'entrée du LCD est tiré à 5 volt. Lorsque le transistor N-MOSFET du MCU est en conduction la ligne est tirée à zéro volt. Voici le schéma d'un montage qui utilise cette configuration. Il s'agit du schéma d'un projet dont je parlerai bientôt sur ce blog.

Toutes lignes qui relient le MCU au LCD utilisent des pullups de 10K et sont configurées en open drain sur le MCU. Il s'agit d'un bus sur 4 bits plus 3 lignes de contrôle.

alimentation LED en mode drain ouvert

Lorsqu'une sortie complémentaire commute pendant une fraction de seconde il y a un certain courant qui passe de Vdd à Vss à travers les 2 transistors car la commutation n'est pas instantanée. Cela a 2 effets, une consommation électrique supplémentaire et du bruit sur le bus d'alimentation. Si on alimente des LEDs par la cathode comme dans le schéma ci-bas en configurant les sorties du MCU en open drain on élimine ces 2 problèmes.

PICVisionPortable

$
0
0

J'ai fait plusieurs projets qui généraient un signal vidéo NTSC monochrome. Cette fois ci je voulais expérimenter avec un affichage LCD. PICVisionPortable est une console de jeux rétro monochrome qui utilise un LCD graphique de 128x64. Le MCU est le même que pour le projet PICVision soit un PIC24FJ64GA002. Cependant il n'y a pas que le type d'affichage qui est différent. PVP utilise la même machine virtuelle (avec quelques modifications) que le projet CHIPCON. et supporte aussi la lecture d'une carte SD sur laquelle sont enregistrés les jeux.

caractéristiques

  • MCU PIC24FJ64GA002, 64Ko flash, 8Ko RAM.
  • Affichage LCD passif à rétro-éclairage Robotshop RB-Dfr-177. 128x64 pixels
  • Lecteur de carte SD pour les jeux
  • Haut-parleur intégré. Son avec 2 tonalités simultanés ou bruit blanc.
  • Espace code disponible 4096 octets. Machine virtuelle Super CHIP étendue.
  • Outils disponibles: assembleur, déassembleur et convertisseur vers fichier C pour intégration d'un jeux en mémoire flash
  • Alimentation 4 piles AA.

schéma électronique

Il y avait juste le nombre de broches sur le format DIP-28 pour répondre aux besoins du projet. De plus comme ce MCU permet de configurer les sorties binaire en mode drain ouvert il n'a pas été nécessaire d'utiliser des adaptateurs de niveau de tension entre le module LCD qui fonctionne à 5 volts et le MCU qui lui fonctionne à 3,3 volts.

L'interface utilisateur ne comprend que 5 boutons, les 4 directions et le select. au dessus du select il y a un petit bouton pour réinitialiser la console. A gauche de l'affichage il y a le haut-parleur et le commutateur d'alimentation.


Je voulais que le montage soit le plus simple possible il n'y a donc pas de cristal, il n'est pas nécessaire d'avoir une précision d'horloge.

Pour le connecteur de la carte SD j'ai du fabriquer un petit circuit imprimé. l'empreinte est dans le dossier documents.

Adaptation du jeux LEM que j'avais écris pour le projet CHIPCON.

carte MCU dans le boitier

Tous les composants dans le boitier

Prototype complété

description détaillée

L'affichage est un LCD passif STN a rétro-éclairage par LED acheté chez Robotshop.com/ca. Puisqu'il s'agit d'un LCD passif l'affichage a une persistance longue ce qui produit un effet de trainé dans les animations. Les jeux sont néanmoins jouables. Sur le vidéo suivant ça paraît pire que c'est en réalité à cause des réflexions sur l'écran. Désolé pour la mauvaise qualité de ce vidéo mais je ne suis pas vraiment équiper produire de bons vidéos.

Le PIC24FJ64GA002 possède 8Ko de RAM, 1Ko est réservé pour la mémoire d'affichage et 4Ko pour l'espace jeux. Contrairement à l'émulateur CHIP original les 4Ko sont disponibles pour l'espace code. Les jeux doivent-être écris avec le point d'entré à l'adresse zéro. Les jeux superCHIP existants doivent-être adaptés pour cette console pour les raisons suivantes:

  1. Le point d'entré doit-être à l'adresse zéro et non 512.
  2. Le clavier n'a que 5 boutons, 4 de directionsà gauche et un sélectionà droite.
  3. Ce processeur étant plus rapide les jeux doivent-être ralentis en insérant des délais supplémentaire dans le code.

Dans le dossier tools on retrouve l'assembleur pvpasm, le déassembleur pvpdasm et le convertisseur cvt-chip. Il reste de la place dans la mémoire flash pour y intégrer quelques jeux.

J'ai adapté 5 jeux superCHIP pour cette console et les ai intégrés dans la mémoire flash. Il encore près de 32Ko de flash libre, donc de l'espace pour plusieurs autres jeux.

adaptation de jeux superCHIP

Lorsqu'il n'y a pas de carte SD dans la fente la console affiche la liste des jeux en mémoire flash. Vous pouvez écrire vos propre jeux et les utiliser à partir de la carte SD ou les intégrer dans la mémoire flash du MCU.

Pour trouver des jeux superCHIP existant consultez le site http://www.chip8.com.

L'adaptation se fait en 3 étapes:

  • désassembler le fichier binaire avec l'utilitaire pvpdasm.exe qui est dans le dossier tools du dépôt github.
    exemple: pvpdasm blinky.ch8 blinky.chp
  • Ouvrir dans un éditeur de texte le fichier assembleur .chp. Faire une recherche sur les instructions SKP, SKNP et LD VX, K. remplacer les codes de touches par ceux correspondant aux touches de la console PVP.
    1. UP = 0
    2. DOWN = 1
    3. LEFT = 2
    4. RIGHT = 3
    5. SELECT = 4
    La console PVP est plus rapide qu'une calculatrice HP-48 aussi faut-il introduire des délais aux endroits appropriés. Localiser ces endroits est la partie la plus difficile.
  • Une fois les modifications faites dans l'éditeur, il faut assembler le programme avec pvpasm.exe
    exemple: pvpasm.exe blinky.chp blinky.pvp
Les programmes sauvegardés sur la carte SD doivent avoir l'extension .pvp pour être reconnus par la console.

intégration des jeux dans la mémoire flash

Pour intégrer un jeux dans la mémoire flash du MCU il faut utiliser l'outil cvt-chip.exe qui est dans le dossier tools.
exemple d'utilisation: cvt-chip -pPIC blinky.pvp

le résultat de cette opération est la création de 2 fichiers en langage C. Un fichier blinky.h et un fichier blinky.c. Il faut ajouter ces 2 fichiers au projet MPLABX.

Dans l'exemple donné ici il ajouter dans le fichier main.c
#include "games/BLINKY/blinky.h"

Chaque jeux en mémoire flash a une entrée dans le tableau flash_games[GAMES_COUNT]. Il faut aussi incrémenter la constante GAMES_COUNT.


les champs de la structure sont les suivants:
  • Le nom qui apparaît à l'écran.
  • la constante définie dans le fichier d'entête qui donne le nombre d'octet occupé par le jeux. Dans l'exemple de blinky cette constante s'appelle BLINKY_SIZE.
  • Le nom du tableau (array) contenant le jeux. Celui est aussi défini dans le fichier d'entête créé par cvt-chip.exe
  • le nom du tableau xxxx_info. Ceci est une description du jeux qui est affichée avant que le jeux ne démarre. Par défaut le tableau est vide. La constante NULL peut-être utilisée s'il n'y a pas d'info à afficher.

liens

Oeuf lumineux

$
0
0

Un petit projet qui peut-être mis en œuvre rapidement pour faire la démonstration des possibilités du PIC12F1572. Comme c'est Pâques dimanche prochain un œuf lumineux comme décoration me paraissait pertinent, comme prétexte pour expérimenter avec ce MCU.

PIC12(L)F1572

Voilà un petit MCU disponible en format PDIP-8 qui possède 3 périphériques PWM avec une résolution maximale de 16 bits ce qui est plutôt rare sur les MCU 8 bits. Microchip a conçu ce MCU en pensant plus spécifiquement au contrôle de LED RGB. En effet on peut contrôler directement une LED RGB 20mA/couleur directement à partir des sorties du MCU et ce avec une résolution de 16 bits à une fréquence PWM de 488 hertz. Voici les principales caractéristiques de ce MCU.

  • coeur midrange amélioré. 49 Instructions encodées sur 14 bits. Pile des retours de 16 niveaux manipulable à partir du programme.
  • Mémoire programme de 2K instructions
  • RAM de 256 octets
  • 5 E/S RA0,RA1,RA2,RA4,RA5 et RA3 en entrée seulement
  • 2 minuteries 8 bits et 4 minuteries 16 bits, 3 utilisées par les PWM
  • 1 comparateur analogique
  • 1 convertisseur A/N de 10 bits avec 4 entrées
  • 1 convertisseur N/A de 5 bits
  • 1 EUSART Extended Universal Asynchronous Receiver Transmitter
  • 1 CWG générateur d'onde complémentaire
  • 3 canaux PWM avec résolution de 16 bits avec compteurs indépendants.
Ce qui rend ce MCU intéressant ce sont ses 3 canaux PWM, le programme démo suivant montre l'utilisation la simple de ces PWM pour piloter une LED RGB. Mais ces canaux PWM ont des modes d'utilisation plus sophistiqués comme contrôle de la phase, synchronisation et impulsion unique.

Programme démo

Le montage est très simple et peut-être réalisé rapidement sur une plaquette de prototypage sans soudure.

code source

Lorsque les 3 canaux PWM sont configurés le programme entre dans la boucle principale qui appelle successivement la fonction transition() et delay_ms(10) pour une brève pause entre chaque transition.

La fonction transition() choisie 3 nouvelles valeurs pour les composantes rouge,verte et bleue et ensuite emmène progressivement les registres PWMxDC à cette nouvelle valeur. Le résultat est une transition douce d'une couleur à l'autre ce qui est beaucoup plus agréable à l’œil qu'un changement brutal.

La fonction random() donne les nouvelles valeurs pour les composantes. J'ai découvert ce type de générateur aléatoire lors de ma lecture du livre de Stephen Wolfram, a new kind of science. le générateur utilise un entier non signé de 32 bits (unsigned long long). les règles sont les suivantes.

  1. Si le nombre actuel est impaire il est incrémenté.
  2. On multiplie ce nombre par 3.
  3. On divise le résultat par 2 et on ne garde que le bit le moins significatif.
  4. Le générateur produit des entiers de 16 bits donc pour chaque appel de random() les 3 étapes sont répétés 16 fois.

Vidéo démo

Ce projet est similaire à celui du projet ambiance pingpong mais ce MCU est nettement plus performant et permet une résolution PWM de 16 bits au lieu de 8 bits et une fréquence PWM plus de 4 fois supérieure. La coquille d’œuf diffuse la lumière de la LED beaucoup plus efficacement qu'une balle de pingpong. L'effet est plus agréable à l’œil que ce laisse entrevoir la vidéo qui n'a pas un bon rendu des couleurs.

conclusion

Je n'ai pas fait de montage permanent de ce projet mais le circuit incluant une pile au lithium de 3 volt CR2450 entrerais en entier dans la coquille. A 3 volt il faudrait diminuer la valeur des résistances pour conserver la même intensité.

On peut aussi expérimenter en changeant la valeur du délais dans la boucle principale et peut-être aussi introduire un délais de quelques microsecondes à l'intérieur de la boucle dans la fonction transition().


Oeuf lumineux, montage

$
0
0

Après avoir observé l’œuf lumineux j'ai décidé que ça pouvait remplacer une chandelle au centre d'une table à dîner. J'en ai donc fait un montage sur un bout de planche de chêne de dimensions 19mm x 110mm x 60mm.

couper un oeuf

L'opération la plus délicate est de couper le bout de l’œuf sans fendre ou fragmenter le rebord du trou. J'ai pris un bouchon de contenant de jus que j'ai appliqué sur le gros bout de l’œuf et j'ai utilisé un marqueur pour en tracé la circonférence. Le meilleur outil que j'ai trouvé pour obtenir un bon résultat est un Dremel avec une petite meule.


Il faut appuyer très légèrement en parcourant la circonférence en essayant de percer le moins possible la membrane qui couvre l'intérieur de la coquille.

Le rebord du trou est très fragile, pour éviter qu'il se forme des fissures j'ai appliqué un filet de colle chaude à l'extérieur juste sur le rebord de l'ouverture. Finalement j'ai vernis l’œuf avec de l'uréthane transparent.

L’œuf doit pouvoir entrer par dessus le bouchon qui a été utilisé pour marquer l'ouverture. C'est dans ce bouchon qu'est installé le PIC10F1572 avec la LED. Le bouchon est encastré dans la base en bois mais pas complètement. Il sert à maintenir la coquille en position.

Montage électronique

Pour le montage final j'ai utilisé la technique dead bug et j'ai laissé tomber les résistances entre les anodes de la LED et les sorties du MCU.

Tous tiens ensemble avec de la colle chaude mais je l'ai utilisté aussi comme isolant.

La pile de 9 volts, le régulateur de tension et le commutateur sont monté en dessous. Pour que le commutateur d'alimentation soit fermé il faut que le montage soit posé sur une surface plane, s'il est soulevé l’œuf s'éteint automatiquement.

J'avais suffisamment d'espace pour installer un connecteur pour le programmeur Pickit au cas ou je voudrais modifier le logiciel.

2 consoles de jeux (couleurs) basées sur PIC32MX

$
0
0

Voici une découverte intéressante que je viens de faire. Il s'agit de 2 consoles de jeux couleurs réalisées avec des moyens très simples. Le signal de sortie est NTSC/couleurs. Cet article est une brève présentation de ces consoles pour ceux qui ne comprennent pas l'anglais (ou le japonais). Le seul composant actif de ces 2 consoles est le MCU le reste n'est que résistances, condensateurs, connecteurs et un cristal 3,58Mhz ou 14,3Mhz pour la deuxième. Suivez le lien ci-haut pour visionner le vidéo des 2 consoles en action.

La première console peut-être réalisée avec un de ces MCU PIC32MX150F128B, PIC32MX250F128B, PIC32MX170F256B ou PIC32MX270F256B. Cette console peut aussi fonctionner sur des PIC32MX120F032B ou PIC32MX220F032B car les graphiques sont basées sur des tables de caractères, une technique qui réduit la quantité de mémoire RAM nécessaire pour le tampon vidéo. Ces MCUs étant disponibles en format PDIP-28 cette console peut-être montée sur une carte à bande ou à points, nul besoin d'un circuit imprimé spécifique. La console peut fonctionner sur 2 piles AA ou AAA ou encore avec un adapteur en y ajoutant un régulateur de tension. Il est nécessaire que le cristal utilisée soit à 3,5795345Mhz. Cette fréquence correspond au signal chroma du NTSC/COULEUR. Ces consoles ne peuvent-être réalisées pour les formats PAL ou SECAM car les modes de modulation couleur de ces 2 standards sont différents. L'auteur précise qu'il a réussi a obtenir une résolution de 256x224 pixels à 16 couleurs sur un PIC32MX150F128B. Dans ce mode le tampon vidéo utilise 28Ko de RAM. Le projet a été réalisé avec MPLAB IDE v8.80, et MPLAB C32 C Compiler v2.02 mais ça ne devrait pas être trop difficile d'adapter le code source pour MPLABX et XC32.

La deuxième console utilise un PIC32MX370F512H et permet de fonctionner en mode graphique vrai pour des jeux plus complexe. Ce MCU n'est pas disponible en format PDIP donc le montage est plus complexe à réaliser. Une solution existe cependant sans avoir à fabriquer un circuit imprimé dédié, il s'agirait d'utiliser un MCU au format TQFP-64 et un breakout board comme celui-ci. Une fois le MCU soudé sur le breakout board il est simple de relier celui-ci à une plaquette à points sur laquelle les autres composants sont montés.

Cette deuxième console permet une résolution de 256x256 pixels avec 256 couleurs. Le cristal utilisé est à une fréquence de 14,31818Mhz (4x3,579545Mhz). Ce MCU peut fonctionner jusqu'à 100Mhz et comme on le voit dans la deuxième partie du vidéo avec le jeux VELUDDA, le MCU est suffisamment puissant pour effectuer une rotation temps réel du bitmap vidéo.

Tuteur de code morse

$
0
0

Cet article décris un tuteur de code morse, c'est à dire un petit circuit qui aide à l'apprentissage du code morse.

code morse

Le code morse est un code à rythme, c'est à dire que l'information est encodée dans la durée relatives des éléments, aussi bien la durée des sons que le silence entre ceux-ci porte une signification. Ainsi un son court appelé DIT est l'unité de base du tempo, tous les temps sont relatif à la durée du DIT.

Il y a deux durées sonores et 3 durées de silence.

  • DIT est un son court.
  • DAH est un son long dont la durée est 3 fois celle du DIT.
  • A l'intérieur d'un caractère le silence entre les sons dure 1 DIT.
  • Entre les caractères d'un mot le silence dure 3 DIT.
  • Entre chaque mot le silence dure 5 (Amérique) ou 7 (Europe) DIT.
Le nombre de symboles varie d'un caractère à l'autre. Les caractères les plus utilisés sont plus courts et les moins utilisés plus long.

En Amérique du nord l'apprentissage du MORSE n'est plus requis pour obtenir une licence radio-amateur. Mais lorsque c'était requis un appliquant devait-être en mesure de lire et de produire un message en morse à la vitesse de 5 mots par minute pour obtenir la licence de base. Ce tuteur émet et lit à la vitesse correspondant à 5 mots par minute. C'est la constante DIT définie au début du fichier source qui détermine le tempo, en diminuant sa valeur on accélère le tempo.

Le circuit

Le circuit est réalisé avec un PIC10F322. Il utilise une LED bicolore rouge/verte pour signaler différents états et un petit haut-parleur pour émettre les codes. La clé morse est branchée sur l'entrée RA3. Il s'agit d'une clé simple (straight key).

Le fonctionnement est le suivant, le tuteur émet un caractère et l'élève doit reproduire celui-ci. Si l'élève échoue parce qu'il n'a pas le bon rythme la LED clignote 3 fois en rouge avant de réémettre le même caractère. Si le rythme est bon mais que la séquence n'est pas bonne la LED clignote 4 fois en rouge. Si l'élève réussi à reproduire correctement le code morse la LED allume brièvement en vert avant que le tuteur n'émette le caractère suivant. Pendant l'émission du caractère la LED allume orange et l'élève doit attendre que la LED éteigne avant de commencer à reproduire le code.

Il y a 4 groupes de caractères et le tuteur passe de l'un à l'autre lorsqu'un groupe est complété.

  1. lettres 'A' - 'Z'
  2. chiffres '0' - '9'
  3. ponctuations '!' - '/'
  4. ponctuations ':' - '@'
A l'intérieur de chaque groupe l'ordre est celui de la table ASCII. Si l'élève n'arrive pas à reproduire un caractère il peut sauter au suivant en tenant la clé enfoncée jusqu'à ce que la LED allume rouge. À ce moment l'élève doit relâcher la clé, à la suite de quoi le caractère suivant est émis.

le code source

Une clé fait maison

Après avoir fait des recherches dans l'internet et constater qu'une clé morse même la plus simple de type Straight key coûte plus de 50US$ j'ai décidé d'en fabriquer une avec les matériaux que j'avais sous la main.

Fabrication:
  • base: chêne 60mm x 120mm x 20mm
  • levier: chêne, longueur 90mm, épaisseur 5mm, hauteur 10mm.
  • Un bouton collé avec de la colle chaude à l'extrémité du levier.
  • Appui du levier: petit bloc de chêne, hauteur 22mm, largeur 18mm, profondeur 15mm. Découpé en U.
  • contacts: 2 boulons chromés. Celui vissé dans la base a la tête limée pour formé une surface plate. Les fils son bobiné 3 tours sur ces boulons et soudés.
  • Le ressort de rappel proviens d'un stylo à bille à pointe rétractable. Un trou est percé dans la base pour le maintenir et un petit boulon passe à travers le levier et glisse à l'intérieur du ressort.
  • Un autre boulon à l'autre extrémité du levier passant à travers celui-ci permet d'ajuster la distance entre les contacts. Son extrémité est appuyé sur un autre petit bloc de chêne collé à la base.
  • 2 petites équerres disponibles dans n'importe quelle quincaillerie servent de support aux prises jack 4mm.
  • On ne peut le voir sur la photo mais les points de pivot du levier sont constitués de 2 têtes de vis que j'ai d'abord limé et ensuite rendu concave en utilisant un foret. l'extrémité des vis qui passent à travers le bloc supportant le levier appuient dans la cavité des têtes de vis pour former un pivot stable.

séance d'apprentissage

On ne voit pas correctement les différentes couleurs de la LED indiquant l'état, mais on peut voir que la LED clignote lorsque j'échoue à répéter correctement le code entendu. Au départ j'avais mis une tolérance de 25% sur les durées mais je l'ai augmenter à 50% car c'était trop difficile à 25%. C'est la fonction symb_len qui contrôle la valeur des durées.


références

  1. code morse
  2. alphabet morse
  3. codes Q

CMOS

$
0
0

De nos jours les circuits intégrés logiques sont fabriqués sur des galettes de silicium monocristallin d'une pureté de 99,999 999 99% en utilisant la technologie appellée CMOS. Dans cette article j'explique ce qu'est la technologie CMOS.

Transistor à effet de champ

Le composant actif de l'électronique moderne est le transistor. Les premiers transistors mis en marché étaient basés sur le germanium et étaient de type bipolaires. Mais rapidement le silicium a remplacé le germanium et les transistors à effet de champ ont remplacé les bipolaires. Plus spécifiquement il s'agit de transistors MOSFET ce qui est un acronyme anglophone pour Metal Oxide Semiconductor Field Eeffect Transistor. Il y a 2 types de transistors MOSFET, P-MOSFET et N-MOSFET. Ensemble ils forment une paire complémentaire d'ou l'acronyme anglophone CMOS qui signifie Complementary Metal Oxide Semiconductor.

Complémentaire

Un transistor MOSFET a 3 électrodes, le Drain, la Source et le Gate. Le G est l'électrode de contrôle, c'est à dire qu'elle permet de contrôler le courant qui circule entre le drain et la source. Le semi-conducteur de silicium situé entre le drain et la source s'appelle Channel (canal). Ce canal est séparé du gate par une mince couche d'oxyde de silicium qui est un isolant électrique. Il n'y a donc pas de courant qui circule entre le gate et la source ou le drain. Le contrôle est assuré par le champ électrique entre le gate et le canal créé par la tension appliquée sur le gate.

structure d'un transistor MOSFET

Les transistors MOSFET utilisés dans les circuits logiques sont de type enrichi. Les transistors à enrichissement ne conduisent pas lorsqu'il n'y a aucun voltage entre le gate et la source. C'est parfait pour les circuits logiques, pas de voltage le courant ne passe pas, on applique un voltage et le courant passe, c'est naturellement binaire.

Dépendant de l'élément chimique utilisé pour enrichir1 le canal, le transistor sera de type P ou N. les symboles électroniques sont les suivants:

Les transistors N-MOSFET fonctionnent avec le drain à un voltage positif par rapport à la source et il faut appliquer un voltage positif sur le gate par rapport à la source pour les mettre en conduction.

Les transistor P-MOSFET fonctionnent avec le drain à un voltage négatif par rapport à la source et il faut appliquer un voltage négatif sur le gate par rapport à la source pour les faire conduire.

Une paire complémentaire est contruite comme ceci:

Lorsque l'entrée est au voltage Vss le transistor N-MOSFET est bloqué tandis que le P-MOSFET conduit on a donc à la sortie Vdd. L'inverse se produit lorsque l'entrée est à Vdd, on a donc un inverseur. Ce montage complémentaire est la base de toutes les portes logiques qui construisent un microprocesseur. A titre d'exemple voici le montage d'un NOR GATE:

Tenant que de ce qui est écris au paragraphe précédent vous pouvez comprendre le fonctionnement de ce circuit.

On pourrait très bien construire un ordinateur en utilisant des transistors élémentaires complémentaires comme le 2N700 qui un N-MOSFET et le TP0606N3 qui est un P-MOSFET. Cependant il en faudrait des milliers. James Newman a d'ailleurs entrepris un tel travail, sauf qu'il n'utilise pas de paires complémentaires, seulement des NMOS. Le premiers MCU comme le 6502 du Apple II était construit en NMOS. Mais les 6502 d'ajourd'hui frabriqués par Western Design Center sont en CMOS d'ou le C dans W65C02.

L'avantage du CMOS est la faible consommation de courant. En effet s'il n'y a pas de charge de branchée à la sortie aucun courant ne passe à travers le transistor qui est en conduction. Le courant ne circule entre les 2 transistors qu'au moment de la commutation. Pendant un bref instant les 2 transistors sont en conduction partielle lorsque le voltage sur le gate est à mi-chemin entre Vss et Vdd. Comme le circuit d'un MCU est construit de portes logiques dont les sorties sont branchées sur des entrées d'autres portes logiques, le seul courant qui circule à l'intérieur du MCU est le courant de transition entre 2 états. C'est pour cette raison que lorsqu'on met un MCU en sommeil profond, c'est à dire lorsque le signal clock est arrêté, il ne consomme que des nanoampères.

Ceci explique aussi pourquoi les manufacturiers nous disent de ne pas laisser les entrées flottantes. En effet ces entrées étant à très haute impédance réagissent à tous les champs électromagnétiques environnant ce qui fait commuter les portent d'entrées rapidement de façon aléatoire d'où une consommation accru du micro-contrôleur.


notes

  1. Pour avoir un semi-conducteur de type N on introduit dans le silicium des atomes qui ont 5 électrons de valence comme le phosphore, l'arsenic et l'antimoine. Pour obtenir un semi-conducteur de type P on introduit dans le silicium des atomes qui ont 3 électrons de valence comme le bore et l'indium. Ces éléments sont introduits en très faible quantité .

DEL

$
0
0

DEL acronyme de Diode ElectroLuminescente. La plupart du temps j'utilise l'acronyme anglophone LED. Quel est la différence entre une DEL et une diode rectificatrice? Dans le principe de fonctionnement il n'y en a pas, les deux fonctionnent selon le même principe de mécanique quantique. Dans cet article j'explique la similitude et la différence entre ces deux types de diode.

A la jonction de P et N

A la jonction de semi-conducteurs P et N il se passe un phénomène mystérieux décris par la théorie de la mécanique quantique. Lorsque les électrons traversent cette jonction ils tombent dans des trous et émettent à ce moment un photon. Ces trous ne sont pas des "nids de poules" comme on appelle les trous dans l'asphalte au Québec. Pour que vous puissiez comprendre je vais expliquer ce qu'est une jonction bipolaire dans un semi-conducteur.

Commençons par le tableau périodique. Au dessus de chaque colonne il y a un chiffre romain suivit de la lettre A ou B. Ce chiffre romain correspond au nombre d'électrons de valence. Les électrons de valence sont les électron d'un atome qui participe aux liaisons chimiques. Ces électrons sont faiblement liés au noyau de l'atome et peuvent être libérés de l'emprise de celui-ci facilement. Il y a 3 colonnes qui intéressent les ingénieurs qui fabriquent des composants électroniques à base de semi-conducteurs: 13, 14 et 15. Dans la colonne 14 on retrouve le silicium et le germanium. Dans la colonne 13 le gallium et dans la colonne 15 l'arsenic.

Le silicium a 4 électrons de valence et est utilisé pour fabriquer la majorité des composants semi-conducteurs. Le gallium a 3 électrons de valence et l'arsenic en a 5. Si on forme un cristal avec de l'arséniure de gallium GaAs on obtient un semi-conducteur qui a en moyenne 4 électrons de valence. Les diodes rectificatrices sont fabriquées avec du silicium et les LED qui émettent dans le visible avec de l'arséniure de gallium.

Un semi-conducteur de type P est un semi-conducteur dans lequel a été ajouté un élément qui n'a que 3 électrons de valence. Ce qui a pour effet de créé des trous dans le réseau cristallin. C'est à dire qu'il manque des électrons pour assurer les liaisons atomiques. Le bore et l'indium sont souvent utilisés pour ce rôle.

Un semi-conducteur de type N est un semi-conducteur dans lequel a été ajouté un élément qui possède 5 électrons de valence. Dans ce cas on a un réseau cristallin qui a un surplus d'électrons. Le phosphore est souvent utilisé pour ce rôle.

Les semi-conducteurs de type P sont donc des capteurs d'électrons et les type N sont des donneurs d'électrons.

Dans une chambre à vide ou la galette de silicium ou d'arséniure de gallium est installée on bombarde celle-ci avec des atomes d'impureté, mettons des atomes de bore pour créer un semi-conducteur de type P. Ces atomes de bore s'installent dans le réseau cristallin. Ensuite on bombarde la galette avec des atomes de phosphore mais avec moins d'énergie pour qu'ils s'enfoncent moins profondément. On obtient ainsi une jonction bipolaire PN. C'est à dire une diode1.

Lorsqu'on applique une tension électrique positive sur l'anode par rapport à la cathode les électrons traversent la jonction et viennent combler le manque d'électron. Lorsqu'un électron comble l'absence d'un électron dans le réseau cristallin de type P il perd de l'énergie. En terme quantique il passe à un niveau d'énergie inférieur. Comme l'énergie ne se perd pas cette énergie libérée est émise sous forme de photon, c'est à dire de lumière. La longueur d'onde de ce photon ou si vous préférez sa couleur dépend de la différence d'énergie entre les 2 niveaux.

bandes d'énergie

Dans les conducteurs il y a toujours des électrons dans la bande de conduction. Dans cette bande l'énergie des électrons est plus élevée que dans la bande de valence. dans un semi-conducteur les électrons dans la bande de conduction sont plus rare, c'est pourquoi ils conduisent mal l'électricité. C'est lorsqu'un électron passe de la bande de conduction à la bande de valence qu'il libère le surplus d'énergie sous forme de photon. Dans les diodes au silicium l'énergie est plutôt libérée sous forme de phonon. Un phonon est une vibration qui se propage dan le réseau cristallin.

Barrière de potentiel et niveaux d'énergies

Dans la région à la jonction de la zone P et N il y a une zone appauvrie. Une zone ou l'influence du phosphore et du bore s'annule mutuellement. Cette zone forme une barrière qui empêche le courant de circuler à travers la jonction. Il faut que les électrons possèdent une énergie minimale pour franchir cette barrière. Cette valeur correspond au voltage minimum nécessaire pour que la diode conduise. Pour une diode au silicium c'est environ 0,65 volt. Pour les DEL ça dépend du type de DEL, pour les rouges c'est environ 2,1 volt, 2,4 pour les vertes et 3,4 pour les bleues.

La valeur de cette barrière de potentiel est lié à l'énergie nécessaire pour arracher les électrons au réseau cristallin. Pour les faire sortir de leur trou. L'énergie d'un photon est inversement proportionnel à sa longueur d'onde donc une DEL qui émet de photons bleus a une barrière de potentiel plus élevée qu'une DEL qui émet des photons rouges.

photo-sensibilité

On a dit que lorsqu'un électron tombe dans un trou il émet un photon dont l'énergie égale la différence d'énergie que l'électron dans la bande de conduction avait et celle qu'il a une fois coincé dans le réseau cristallin (bande de valence). Cette différence d'énergie s'appelle bande interdite ou band gap en anglais. Bande interdite parce que l'électron ne peut occupé un niveau d'énergie intermédiaire entre ces 2 niveaux. C'est ça la nature quantique de l'univers subatomique.

Si un électron émet un photon lorsqu'il tombe dans un trou le contraire est aussi vrai. Un photon peut déloger un électron de son trou en lui communiquant son énergie. En conséquence toute DEL est photo-sensible. Connectez un voltmètre aux électrodes d'une DEL et exposez celle-ci à la lumière. vous constaterez qu'il y a un voltage aux bornes de la DEL. couvrez la DEL et le voltage disparait. La jonction absorbe les photons et déloge des électrons du réseau cristallin. Il va sans dire que la DEL est particulièrement sensible à la même longueur d'onde qu'elle émet.

Sens unique

Au fait pourquoi une diode ne conduit que dans un sens? C'est simple les trous n'ont pas de mobilité se sont les électrons qui se déplacent dans le réseau. Si on applique le voltage positif sur la cathode les électrons s'éloignent de la jonction plutôt que de la traverser. la zone appauvrie s'élargie au lieu de se rétrécir. Cependant si le voltage est suffisamment élevé les électrons peuvent-être arrachés du réseau dans la partie P de la diode et traverser la jonction. le voltage ou ce phénomène se produit est la tension de claquage ou breakdown voltage en anglais. Lorsque cette tension est atteinte il se produit un phénomène d'avalanche. C'est à dire que les électrons ainsi délogés du réseau cristallin possèdent suffisamment d'énergie pour à leur tour déloger d'autres électrons. Le courant augmente donc rapidement et si le phénomène n'est pas contrôlé il conduit à la destruction de la diode. Les diodes zener utilisent ce principe d'avalanche.

notes

  1. Notez que bien que j'ai indiqué le bore dans le dessin comme impureté pour le côté P de la jonction en ce qui concerne les DEL l'aluminium et l'indium sont plutôt utilisés. Le bore lui est utilisé avec le silicium. Si vous consultez les feuillets de spécifications des DEL vous verrez des compositions du genre InAlGaP, InGaN/GaN ou GaAlAs. In pour indium colonne 13 donc 3 électrons de valence. Al pour Aluminium aussi dans la colonne 13 donc aussi 3 électrons de valence. N pour azote, colonne 15 donc 5 électrons de valence. As pour Arsenic colonne 15. Le choix des éléments dépend du niveau d'énergie entre la bande de conduction et la bande de valence, ce qui détermine la longueur d'onde.

ionisation et fluorescence

$
0
0

Dans l'article précédent sur les DEL j'expliquais le fonctionnement des DEL par la quantisation des niveaux d'énergies dans les couches électroniques des atomes. Dans cet article je vais expliquer 2 autres phénomènes utilisés en électronique qui sont aussi des phénomènes quantiques. L'ionisation et la fluorescence.

enseigne au néon

Vous connaissez surement ces enseignes lumineuses qu'on appelle communément néon. On peut aussi se procurer sur le marché de petites ampoules au néon servant comme indicateur bien que celles-ci ont largement été remplacées par les DEL. Enseigne ou ampoule le principe de fonctionnement est le même, l'ionisation d'un gaz. Dans une tube ou une ampoule sous vide on introduit un gaz sous faible pression. Dans ce tube il y a 2 électrodes isolées l'une de l'autre. Si on applique un voltage suffisant à ces électrodes il y a production de lumière. Le phénomène est le suivant, le champ électrique arrache les électrons de l'atome. On dit d'un gaz dont les atomes perdu 1 ou plusieurs électrons qu'il est ionisé1. Mais les lois de la physique font en sorte que la matière cherche à se stabiliser au plus bas niveau d'énergie. Les atomes ionisés possèdent un charge positive qui attire les électrons. Ceux-ci retombent donc dans leur position initiale en émettant un photon. l'énergie de se photon donc sa longueur d'onde dépend de la différence d'énergie entre l'électron libre et l'électron capturé par l'atome. Un gaz ionisé n'émet pas une seule fréquence lumineuse mais plusieurs on appelle ces différentes fréquences lumineuse le spectre. Chaque élément chimique possède son propre spectre lumineux qui l'identifie de façon unique. C'est en faisant cette analyse spectrale que les astronomes parviennent à identifier les éléments chimiques qui composent les étoiles et l'atmosphère des autres planètes. Le néon semble orange ou rouge à l’œil parce que c'est la longueur d'onde dominante de son spectre. Si on remplace le néon par un autre gaz la couleur sera différente. Une enseigne au néon qui n'est pas rouge n'est pas en réalité une enseigne au néon mais contient plutôt un autre gaz et l'intérieur du tube est recouvert d'une substance chimique fluorescente. Les petites ampoules néon émettent une lumière orange mais si on augmente le voltage elle deviennent rouges. Si vous alimenter une ampoule néon en courant direct la luminosité sera centrée autour d'une seule des 2 électrodes, la plus positive car les électrons émis par l'autre électrode doivent avoir suffisamment d'énergie cinétique pour ionizer le gaz. Les électrons gagnent en vitesse en se déplaçant vers l'électrode positive. En courant alternatif la luminosité est centrée autour des 2 électrodes car les électrons se déplacent alternativement dans les 2 directions.

Neon light.jpg
« Neon light ». Sous licence CC BY-SA 3.0 via Wikimedia Commons.

indicateur neon A1A

Fluorescence

La première calculatrice que j'ai acheté dans les années 70 était de marque Rockwell et avait un affichage VFD Vacuum Fluorescent Display. A l'intérieur d'un tube de verre dans lequel on a fait le vide il y a plusieurs électrodes. Une cathode qui émet des électrons et des anodes recouvertes d'une substance chimique fluorescente. Entre la cathode et les anodes il y a aussi une grille. Cet agencement est semblable au tube électronique appelé triode sauf qu'il n'est pas conçu pour amplifier un signal mais pour émettre de la lumière. Donc un voltage positif sur une anode attire les électrons générés par la cathode ces électrons accélérés viennent frapper la substance chimique qui est sur l'anode. L'énergie de ces électrons ce communique aux électrons de la substance chimique qui sautent à un niveau d'énergie supérieur. Mais comme dans le cas d'un gaz ionisé les électrons retombent à leur niveau d'énergie initiale en émettant un photon.

Dans un VFD il y a une anode par segment d'affichage. Par exemple s'il s'agit d'une calculatrice on a 8 segments par chiffre en incluant le point pour les décimales. Chaque anode doit-être contrôlée individuellement. En fait l'affichage est multiplexée. C'est à dire qu'il y a une cathode par chiffre et seulement 8 électrodes partagées par tous les chiffres. Un seul chiffre est allumé à la fois. La persistance rétinienne nous fait croire qu'ils sont tous allumés simultanément. La grille elle sert a contrôler l'intensité de l'affichage. Si on applique un voltage négatif sur la grille il y aura moins d'électrons qui passeront de la cathode aux anodes.

Tube fluorescent

Qu'il s'agisse de fluo-compact ou de tube fluorescent le principe est le même et combine 2 principes l'ionisation d'un gaz et la fluorescence/phosphorescence2.

Leuchtstofflampen-chtaube050409.jpg
« Leuchtstofflampen-chtaube050409 » par Christian Taube. Sous licence CC BY-SA 2.0 de via Wikimedia Commons.

02 Spiral CFL Bulb 2010-03-08 (black back).jpg
« 02 Spiral CFL Bulb 2010-03-08 (black back) » par Sun LadderTravail personnel. Sous licence CC BY-SA 3.0 via Wikimedia Commons.

Dans le tube il y a une faible pression de vapeur de mercure. Le champ électrique ionise le gaz mercure. Le gaz ionisé a un spectre qui émet principalement dans le violet et l'ultraviolet. l'intérieur du tube, comme pour les enseignes au néon de couleur variées, est recouvert d'une substance chimique fluorescente. Cette substance capte les photons ultraviolet et réémet dans le visible. Le spectre lumineux émis dépend de(s) substances utilisé(es). En passant les DEL blanches sont en fait des DEL bleues recouverte elle aussi d'une substance fluorescence. Lorsqu'on achète des tubes fluorescent ou des fluocompacte l'embalage spécifie le spectre d'émission par une température, 2700°, 3000°, etc. Cette température correspond à un autre concept de la mécanique quantique appelé émission du corps noir. Une basse température correspond à un éclaire plus jaune (doux) et une haute température à un éclairage plus bleu (dur). Un éclairage daylight correspond à un spectre d'émission qui se rapproche de celui-du soleil.

notes

  1. Lorsqu'un gaz contient suffisamment d'atomes ionisés pour devenir un conducteur électrique on parle alors de plasma. C'est ce qui se produit lors d'un orage électrique.
  2. Pour comprendre la différence entre fluorescence et phosphorescence voir l'article wikipédia.

3D xpoint

$
0
0

Depuis 10 ans Intel et Micron travaillent conjointement sur un projet commun et voilà qu'ils on annoncés hier la mise en marché prochaine de cette nouvelle technologie. Il s'agit d'une mémoire persistance appellée 3D xpoint qui offre des performances nettement supérieure à la mémoire flash. Pour le moment cette mémoire n'est disponible que pour les manufacturiers pour essais et développement de produits. Mais elle devrais-être disponible chez les distributeurs de composants dès 2016.

De quoi s'agit-il?

Il n'y a pas grand détail mais à la lecture de l'annonce faites par Intel et cet article sur le site de la BBC, je crois comprendre qu'il s'agit d'une technologie de type memristor. Il n'y a pas de transistors ce qui permet une plus grande densité. Chaque bit de mémoire est constitué simplement d'un certain type de cristal dont la résistance varie lorsqu'un courant passe à travers celui-ci. Cette variation de résistance persiste après que le courant a cessé. Il s'agit donc d'une mémoire permanente.

Avantages

Par rapport à la mémoire flash cette mémoire a plusieurs avantages.

  • 1000 fois plus rapide que la mémoire flash NAND. Donc un MCU qui utiliserais ce type de mémoire pour stocker son programme ne serait pas limité à 40Mhz comme c'est le cas actuellement. Actuellement les MCU dont le core fonctionne au delà de 40Mhz utilisent des wait state et une forme de mémoire cache pour l'accès programme.
  • 1000 fois plus durable que la mémoire flash NAND. Donc un MCU qui utiliserais cette mémoire au lieu de la flash pourrait être reprogrammé un nombre illimité de fois sans crainte d'user la mémoire programme. Donc une application pourrait utiliser la mémoire programme pour stocker des données.
Donc en pratique sur un MCU il ne serait plus nécessaire de faire la distinction entre mémoire programme et mémoire RAM. En utilisant un coeur de type Von Neumann et seulement de la mémoire 3D xpoint on obtiendrais une mémoire totalement unifiée pour le MCU et l'état du système serait conservée en cas de rupture d'alimentation.

J'ai hâte de voir si les manufacturiers de MCU vont adopter cette technologie sous licence pour leur MCUs. Déjà Texas Instruments offre quelque chose dans le même genre avec sa propre technologie FRAM. La FRAM (Ferro Magnetic RAM) est une technologie différente du 3D xpoint mais qui est elle aussi persistance, plus endurante et plus rapide que la FLASH.

Il reste à voir à quel coût cette technologie sera disponible. Si c'est le même coût que la mémoire FRAM de TI les MCUs l'utilisant seront plus coûteux que ceux utilisant la mémoire NAND FLASH.


comprendre les pointeurs

$
0
0

Lorsque j'ai appris le langage C il y a longtemps l'un des concepts qui m'a donné le plus de difficulté est celui concernant l'usage des variables pointeurs. Cet article est à l'usage de ceux qui débutent en C est qui auraient la même difficulté.

coup d’œil sur les registres interne d'un MCU

Prenons un MCU quelconque, par exemple un PIC12F1822. Si on regarde le modèle de programmation du cœur de ce MCU on voit ceci.

Les registres FSR0 et FSR1 sont ce qu'on appelle des registres d'index, c'est à dire des variables pointeurs. Supposons qu'on écris un programme en mpasm et qu'on veut initialiser la RAM commune à zéro que fait-on?


;sous-routine pour effacer ram commune 0x70-0x7f
clear_common_ram:
;initialistion du pointeur
clrf FSR0H
movlw H'70'
movwf FSR0
clrf WREG
clear_loop:
movwi, FSR0++ ; adressage indirect avec post-incrément
btfss FSR0,7
bra clr_loop
return ; terminé car FSR0==0x80
On pourrais aussi faire ceci sur un PIC baseline:

;sous-routine pour effacer ram commune 0x70-0x7f
clear_common_ram:
movlw H'70'
movwf FSR0
clear_loop:
clrf FSR0 ; adressage indirect
incf FSR0,F ; incrémente le pointeur
btfss FSR0,7
bra clr_loop
return ; terminé car FSR0==0x80
On a mis 0 dans le registre WREG et on transfert cette valeur dans toutes les localisations RAM entre 0x70 et 0x7F. Pour ce faire on se sert du registre d'index FSR0. FSR0 est une variable pointeur. FSR0 ne contient pas un entier mais une adresse et cette adresse indique où on veut mettre la valeur de WREG. l'instruction movwi FSR0++ effectue 2 opérations. D'abord elle transfert le contenu de WREG qui est zéro à l'adresse RAM indiquée par le contenu de FSR0 et deuxièmement incrémente de 1 la valeur de FSR0 pour pointé à l'adresse suivante. Le programme boucle sur clear_loop tant que le bit 7 de FSR0 est à 0 car si le bit 7 est à 1 c'est que FSR0 pointe sur une adresse après 0x7F.

la même chose en C

répétons le même programme en C


void clear_common_ram(){
char *p;
p=(char*)0x70;
while(((int)p&0x80)==0){
*p++=0;
}
}

variable pointeur

Dans tout langage de programmation une variable est une adresse en mémoire dans laquelle une information est conservée. Dans l'exemple ci-haut p ne fait pas exception, c'est une adresse mémoire dans laquelle on va garder une information mais cette information n'est pas un char mais une adresse qui indique un autre endroit en mémoire ou est conservé une donnée de type char. Ça a peut-être l'air plus compliqué que la version mpasm mais c'est presque la même chose. Lorsqu'on déclare la variable p l'étoile * avant le p informe le compilateur que cette variable va contenir une autre adresse et non un char.

l'instruction *p++=0; indique qu'on veut modifier le contenu de l'adresse pointée par p et non le contenu de p lui-même. Ici l'étoile * n'a pas la même signification que lorsqu'on déclare la variable. Elle signifie plutôt un adressage indirect. Dans de nombreux assembleurs l'adressage indirect (par pointeur) est indiqué par le nom du registre qui sert de pointeur entre crochet comme ceci:


LOAD R0,[R15]
Ce qui signifie met la valeur qui se trouve à l'adresse indiquée par le contenu de R15 dans R0. Donc ici R0 est une variable ordinaire tandis que R15 est une variable pointeur (registre d'indexation ou d'indirection).

Quand le programme compilé va s'exécuter, il va aller chercher la valeur de p et la mettre dans FSR0 ou FSR1. ensuite il va mettre WREGà zéro et effectuée une boucle très semblable à celle d'écrite ci-haut dans la version mpsasm.

J'ai fait un test dans MPLAPX en compilant avec XC8 free (pas d'optimisation) voici le résultat dans le disassembly listing


11: void clear_common_ram(){
12: char *p;
13: p=(char*)0x70;
07ED 3070 MOVLW 0x70
07EE 00F0 MOVWF __pcstackCOMMON
07EF 3000 MOVLW 0x0
07F0 00F1 MOVWF 0x71
14: while(((int)p&0x80)==0){
07F1 1BF0 BTFSC __pcstackCOMMON, 0x7
07F2 0008 RETURN
07FC 2FF1 GOTO 0x7F1
15: *p++=0;
07F3 0870 MOVF __pcstackCOMMON, W
07F4 0086 MOVWF FSR1
07F5 0871 MOVF 0x71, W
07F6 0087 MOVWF FSR1H
07F7 0181 CLRF INDF1
07F8 3001 MOVLW 0x1
07F9 07F0 ADDWF __pcstackCOMMON, F
07FA 3000 MOVLW 0x0
07FB 3DF1 ADDWFC 0x71, F
16: }
17: }
Ça a l'air plus compliqué sans optimisation! __pcstackCOMMON est une pseudo-pile créé par le compilateur. On peut s'en passer et simplifier ça. Il n'est pas nécessaire non plus de stocker le pointeur FSR1 sur la pile __pcstackCOMMON.

clear_common_ram:
; initialisation du pointeur p
; le compilateur a choisi FSR1 comme pointeur
; les FSR du PIC12F1822 sont de 16 bits
movlw 0x70
movwf FSR1L
movlw 0
movwf FSR1H
clear_loop:
btfsc FSR1L,7
return
clrf INDF1
; fsr1 a 16 bits, incrément par addition de 1
movlw 1
addwf FSR1L
movlw 0
addwfc FSR1H
goto clear_loop

Lorsqu'on déclare un tableau en C i.e. char tableau[10];, le compilateur va aussi utiliser un registre d'index pour atteindre les éléments de ce tableau, i.e. b=tableau[2]; se traduis en assembleur par:


;initialise le pointeur
movlw LOW tableau
movwf FSR0L
movlw HIGH tableau
movwf FSR0H
;va cherché la valeur dans le 3ième élément du tableau.
moviw 2[FSR0]; WREG=indirection:[FSR0+2]
movwf b ; assigne cette valeur à b

adresse d'une variable ordinaire

Si l'étoile avant le nom d'un pointeur sert à indiquer une indirection,on dit déréférencer, comment fait on pour obtenir l'adresse mémoire où est stocké le contenu d'une variable ordinaire:


int b=0, *p;

p=&b;
*p=34; // que contient b?
Le symbole & est utilisé pour indiquer l'adresse de la variable et non son contenu. donc dans cette exemple p contient l'adresse de la variable b. Et lorsqu'on déréférence p pour y assigner la valeur 34 et bien la valeur de la variable b devient 34 car p pointe vers b.

Que ferais-je sans toi

En effet comment ferait-on sans pointeurs pour adresser un tableau ou n'importe qu'elle étendu de mémoire? J'espère donc que cette présentation a clarifié la question des pointeurs.

Arduino sketch et C++

$
0
0

Cette Article est une réaction à l'article d'Elliot Williams paru sur Hackaday.com le 28 juillet 2015. La question est la suivante: est-ce qu'un sketch Arduino est un programme C++?

L'argument d'Elliot Williams est que derrière la scène, l'environnement Arduino est basé sur C++ et que la syntaxe des sketch Arduino est la même que la syntaxe de C++. Un sketch Arduino est simplement pré-traité pour y apporter les éléments manquants pour en faire un programme C++ compilable par GCC.

Arduino refence

Jetons un coup d'oeil au manuel de référence du langage Arduino. En effet tous les éléments de la syntaxe sont les même que ceux du C++. Mais est-il question ce classes, objets, etc? non.

Le langage Arduino est un sous-ensemble du langage C++. Un sous-ensemble d'un ensemble n'est pas l'ensemble lui-même.

Si on ajoute des éléments du C++ qui ne sont pas dans la référence du langage Arduino comme par exemple des classes d'objets et des instances d'objets, le script va compiler correctement donc c'est du C++ dit M. Williams.

Personnellement je considère que tout fichier qui a besoin d'être pré-traité avant d'être compiler avec gcc n'est pas du C++ à proprement parler même si les éléments manquant peuvent-être ajoutés manuellement dans le fichier sketch. par exemple les prototypes de fonctions ne sont pas requis dans la référence du langage Arduino mais ils le sont par C/C++. Arduino utilise donc un pré-traitement qui lui est propre et qui sert entre autre à ajouter ces prototypes de fonctions ainsi qu'à ajouter un #include pour la librairie Arduino.

exemple

Voici un exemple d'un sketch Arduino auquel j'ai ajouter une classe C++. le pré-traitement Arduino transforme le sketch en fichieer .cpp suivant:

On voit que le pré-traitement ajoute des directives #line ainsi que la directive #include "Arduino.h" ainsi que les prototypes void setup(); et void loop();

Pourquoi est-ce que j'insiste sur ces détails? A cause de la philosophie d'Arduino. Arduino a été créé pour simplifier l'utilisation des microcontrôleurs pour les rendre accessibles aux non spécialistes. C'est ce qui fait tout l'intérêt d'Arduino. Les spécialistes n'utilisent généralement pas Arduino, car ils n'en ont tout simplement bas besoin et pour eux l'IDE Arduino est d'une utilisation frustrante car cet environnement simplifié n'offre pas les outils auxquels ils sont habituer.

Donc lorsque certains comme M. Williams, veulent expliquer aux utilisateurs d'Arduino qu'en fait ceci c'est du C++ alors moi je dis qu'ils non pas compris l'objet du projet Arduino: garder ça le plus simple possible pour que les amateurs puisse utiliser la plateforme avec une difficulté d'apprentissage minimisée. Si éventuellement ces amateurs deviennent des professionnels ils n'auront plus besoin d'Arduino.

trivia

$
0
0

Combien coûtait un disque dur de 26Mo en 1980?

réponse: 4995US$

Cette information me viens d'une publicité parue à la page 53 de BYTEédition du mois d'août 19801. La publicité qualifie ce prix de HARD BARGAIN. Toute une aubaine! Et ce sont des dollars de 1980. Si on tiens compte de l'inflation en me fiant à l'information trouvé ici, ça ferais en dollars d'aujourd'hui 14 350US$2.


notes

  1. Cette édition de BYTE consacré à FORTH peut-être téléchargée à partir de ce lien.
  2. Pour l'année 1980 j'ai utilisé le ratio <inflation ajusted $>/<nominal $> * 4995

Tétéviseur conformiste

$
0
0

J'ai conçu plusieurs projets générant un signal NTSC monochrome et les ai branchés sur 3 téléviseurs différents avec succès. Mais voilà que dernièrement j'ai du remplacé mon téléviseur par un de modèle RCA. Comme cette semaine j'ai repris le projet CHIPcon dans le but de remplacer le clavier hexadécimal par un joystick Atari 2600. Je branche CHIPcon v2 sur mon téléviseur RCA... pas de vidéo! Pourtant il fonctionne très bien sur mon petit moniteur de développement. Je n'ai pas été long à figurer d'où provenait le problème.

Standard NTSC

En fait la sortie NTSC que j'utilise n'est pas conforme au standard. Il s'agit d'une version simplifiée appellée balayage progressif sans alternance de champ (field). De plus la synchronisation verticale est aussi simplifiée et consiste à simplement rallonger l'impulsion de synchronisation pour les lignes 1 à 3.

Le standard NTSC lui définie une alternance de field pair et impair. Chaque field ayant chacun 262,5 lignes pour un total de 525 lignes par image puisque les lignes des champs pair et impaire sont inter-lacées. Ceci a pour but d'éviter le scintillement de l'image tout en réduisant la bande passante requise par le signal vidéo puisqu'il n'y a que 262,5 lignes de transmise par champ. Chaque champ n'est affiché que 30 fois par seconde en alternance pair/impair même si le balayage vertical est à la fréquence de 60 fois par seconde. Astucieux!

Dans la version que j'utilise il n'y a que 262 lignes répétées 60 fois par secondes sans inter-lacement.

Solution au problème

Heureusement la solution à ce problème était simple et consistait à une modification de la routine d'interruption vidéo ISR(TIMER1_COMPB_vect) située dans le fichier tvout.c Voici la version originale présentée dans CHIPcon et la version conforme à NTSC corrigée pour CHIPcon v2.

NTSC balayage progressif

NTSC conforme

Notez que ceci n'augmente pas la résolution verticale qui demeure à 2621 lignes puisque le même video_buffer est utilisé pour les 2 champs pair et impair.

conclusion

La morale de cette histoire est que si vous voulez que votre projet fonctionne sur tous les téléviseurs il vaut mieux qu'il se conforme au standard NTSC, car on ne sais jamais quand on aura affaire à un téléviseur pointilleux.


NOTES:

  1. Les 262 lignes ne sont pas toutes visibles, 21 de ces lignes font partie du vertical retrace. De plus sur les téléviseurs que j'ai essayé il y a environ 230 lignes visibles en balayage progressif. En respectant le standard et en utilisant l'entre-lacement on obtiendrait donc 460 lignes au coup d'un buffer vidéo 2 fois plus grand.

NTSC et Parkinson

$
0
0

Dans l'article précédent intitulé téléviseur conformiste je présentait un problème et sa solution concernant la génération d'un signal NTSC sur ATmega328P. Mais la solution présentée n'était pas optimum, il y avait un tremblement dans l'image. Aujourd'hui j'ai réglé ce problème et dans cet article j'explique la cause de ce tremblement et la solution que j'ai apportée.

Vidéo avant la correction du problème on voit le tremblement de l'image surtout apparent sur la ligne verticale à droite de l'écran.

Vidéo après correction du problème. Maintenant l'image est très stable. Il n'y a plus de Parkinson.

La gigue d'interruption

J'ai tapé dans google search: traduire: interrupt jitter et c'est la traduction que j'ai obtenu!

Le générateur de signal NTSC utilise une interruption pour modifier les paramètres du signal PWM qui génère la synchronisation mais aussi pour déterminer quand il est temps d'envoyer les pixels vidéo pour chaque ligne visible à l'écran. En ce qui concerne la synchronisation l'interrupt jitter n'affecte pas son fonctionnement puisque cette synchronisation utilise le compteur TCNT1 dont le fonctionnement est indépendant des interruptions. Par contre pour l'envoie des pixels vidéo il y a une influence. Il est primordial que l'envoie du signal vidéo débute toujours au même instant à chaque ligne ainsi qu'à chaque répétion de frame.

Le problème est que le temps de réponse de l'interruption est variable car il est influencé par la durée de l'exécution de l'instruction machine en cours au moment où se produit l'interruption. En effet le MCU doit attendre la fin de l'instruction en cours avant de répondre à l'interruption. Hors sur les AVR le temps d'exécution d'une instruction varie entre 1 et 4 cycles. La durée d'un pixel dans ce générateur vidéo est de 6 cycles machines. Donc une fluctuation de 4 cycles sur le départ de la ligne vidéo c'est 2/3 de pixel en largeur. C'est cette fluctuation qu'on perçoit dans l'image.

Comment régler ce problème

Comme je l'ai dit le fonctionnement du compteur TCNT1 est indépendant des interruptions on peut donc se fier à son fonctionnement pour avoir l'heure juste, si je peut dire. Dans cette application le compteur est cadencé à la même fréquence que le coeur du MCU. Donc lorsqu'il est temps de générer les pixels vidéo d'une ligne sa valeur est toujours la même à 4 cycles près. Le code assembleur que j'ai ajouté lit l'octet faible de TCNT1 qui est un compteur de 16 bits et ne garde que les 2 bits les plus faibles, donc cette valeur peut variée de 0 à 3 du au jitter. Je prends pour cible la valeur 3 et si le compte est inférieur à 3 on ajoute autant d'instruction NOP que nécessaire pour que lorsque le programme arrive au code qui génère le vidéo le compte de TCNT1 soit toujours le même. Puisque c'est TCNT1 qui détermine le début de la ligne vidéo, à compte égal de celui-ci on est à la même position sur la ligne vidéo.

Pour obtenir un timing précis j'ai du écrire le code en embedded assembly. Voici le code ajouté à la routine d'interruption vidéo TIMER1_COMPB_vect dans tvout.c.


asm(// élimination de la gigue d'interuption (jitter)
"ldi r30,lo8(jit)\n"
"ldi r31,hi8(jit)\n"
"clc\n"
"ror r31\n"
"ror r30\n"
"lds r24,0x84\n"
"andi r24,3\n"
"add r30,r24\n"
"adc r31,r1\n"
"ijmp\n"
"jit:"
"nop\n"
"nop\n"
"nop\n"
"nop\n"
);
Ce code fonctionne de la façon suivante. l'adresse de l'étiquette jit (Just In Time) est chargée dans le registre d'index Z qui est en fait la concaténation des registres R31:R30 pour former un pointeur de 16 bits. Les 3 instructions suivantes divisent cette valeur par 2 parce que cette adresse est celle d'un octet mais le compteur ordinal du ATmega328P lui pointe sur des mots de 16 bits. Autrement dit si l'adresse de jit est 21590 en mémoire flash, pour que le PC pointe cette adresse il doit contenir 10795. Une fois le pointeur Z ajusté à la valeur désirée. On fait la lecture de l'octet faible de TCNT1 qui se trouve à l'adresse 0x84 et on met cette valeur dans le registre R24. L'instruction andi r24,3à pour but de mettre tous les bits de R24à zéro sauf les 2 plus faibles. On a maintenant dans R24 un nombre entre 0 et 3. On additionne ce nombre à la valeur dans le registre d'index Z. L'instruction ijmp prend la valeur dans Z et la transfert dans PC (le pointeur d'instruction). Si R24 contenait 0 l'instruction qui sera exécutée après le ijmp sera celle exactement à l'adresse jit. Si R24 contenait 1 l'instruction qui sera exécutée après le ijmp sera à l'adresse jit+2, etc. jit+2 parce que n'oubliez pas que le PC adresse des mots de 16 bits et non des octets et comme chaque instruction NOP occupe 2 octets on a le bon alignement.

Au bout du compte lorsque le PC arrive à l'instruction qui suis le dernier NOP, le compteur TNCT1 a toujours la même valeur puisqu'il est incrémenté au même rythme que le compteur ordinal (pointeur d'instruction).

routine TIMER1_COMPB_vect

Voici la routine d'interruption au complet. Je rappelle que ceci fait parti du projet open sourde CHIPcon v2.

Viewing all 192 articles
Browse latest View live