mercredi 31 octobre 2012

expérimentation avec PIC10F322, partie 3

Dans cette 3ième partie de mes expérimentations avec le PIC10F322, je l'utilise pour produire des sons. Il y a 2 programmes, soundfx.asm et pwm_synth.asm.
Les 2 programmes utilisent le fichier de macros pic10f322_m.inc

Pour réaliser ces expériences j'ai ajouté un petit potentiomètre de 5K sur la platine d'expérimentation présentée en partie 1 de cette série. Ce potientiomètre sert dans le mode VCO du programme soundfx.asm et dans pwm_synth.asm.

effets sonores

Pour réaliser cette expérience vous avez besoin du matériel suivant:

  • 1 PIC10F322 ou LF322
  • 1 petit haut-parleur
  • 1 résistance de 100 ohm
  • 1 potientiomètre de 5K (la valeur n'est pas critique)
  • 1 bouton à contact momentanée
  • 1 platine d'expérimentation sans soudure
  • 1 programmeur pickit 3 ou équivalent.

Le montage est le suivant:


Pour cette expérience tous les périphériques du PIC10F322 sont utilisés.

  • Le NCO sert de générateur de fréquence audio principal.
  • le PWM1 génère une fréquence audio fixe.
  • la CLC est utilisée pour additionner (mixer) les sorties du NCO et de PWM1
  • la sortie du CLC est connectée à RA2
  • Le convertisseur A/N fait la lecture du potentiomètre sur RA0
  • le timer 2 alimente le PWM
  • le timer 0 est utilisé pour mesurer le temps pour les intervalles.

Le programme a 5 modes de fonctionnement:
  1. Silence
  2. balayage de fréquence
  3. générateur de fréquence contrôlé par un voltage (VCO)
  4. gamme musicale
  5. mélodie

Le bouton branché sur RA3 permet de passer d'un mode à au suivant en boucle.
Le mode balayage de fréquence balaie de 100hz à 5Khz en montant et en descendant.
Ce signal est mélanger avec une fréquence fixe générée par PWM1 avec une fonction "ou exclusif" dans la cellule logique configurable. L'effet produit est très particulier.

Le mode VCO tant qu'à lui produit une fréquence qui est proportionnel au voltage lu sur le potentiomètre. En tournant le potentiomètre on fait varier la fréquence.

Le mode gamme utilise le NCO pour jouer la gamme musicale tempérée dont les valeurs de
fréquences sont inscrites dans la table scale_table.

Finalement le mode mélodie joue la mélodie We gonna fly now, musique thème du film Rocky 1.


synthès analogique par PWM

Le programme pwm_synth.asm est une illustration de l'utilisation de la modulation par largeur d'impulsion pour produire un signal analogique. Pour cette expérience le haut-parleur doit-être branché sur RA1 en série avec une résistance de 100R. Il faut aussi brancher un potentiomètre de 5K ou 10K aux bornes de l'alimentation avec le contact mobile (celui du centre) sur RA2. En tournant ce potentiomètre on sélectionne la note que le programme fait entendre.

Dans cette expérience le MCU est configuré pour fonctionner à sa vitesse maximale de 16Mhz et le canal PWM2 est utilisé pour générer une onde sinusoïdale. La fréquence du PWM est de 31Khz donc inaudible. J'ai utilisé OpenOffice calc pour calculer les valeurs de la table sine_table1. ainsi que les délais de transfert des échantillons au PWM. Ces valeurs détermine la largeur d'impulsion que doit générer le PWM au différents angles du cycle de l'onde et le délais de transmission des échantillons pour chaque fréquence. Il y a 90 échantillons, donc un échantillon à tous les 4 degrés considérant qu'un cycle complet représente 360 degrés. La fréquence de l'onde est déterminée par la vitesse avec laquelle on envoie les échantillons au PWM.

délais = (1/fr)/Ns

délais est le délais entre l'envoie de chaque échantillon au pwm.
fr est la fréquence qui doit-être générée.
Ns est le nombre d'échantillons.

exemple pour générer un fréquence 440hz avec les 90 échantillons de la table sine_table

délais = (1/440)/90 = 0,0023/90 = 25 uSec

les valeurs pour le timer0 sont calculées de la façon suivante.

T0val=256 - délais/Tcy + 9
T0val est la valeur d'initialisation du compteur timer0.
délais est la valeur calculée dans la formule précédente.
Tcy est la période de l'horloge système soit 1/(Fosc/4), ce qui à 16Mhz
donne 250nsec.
9 est le nombre de Tcy qui s'écoule avant que le timer0 ne soit réinitialisé par la routine d'interruption.

pour 440Hz on a donc:

T0val = 256 - 25e-6/250e-9 + 9 = 165

J'ai fait un fine tuning des valeurs en mesurant les fréquence réelle à l'oscilloscope, pour être le plus près possible des valeurs de la gamme tempérée.

On entend clairement la fréquence audio dans le haut-parleur mais si on branche un oscilloscope sur la broche RA1 le signale ressemble à ceci:


Ceci est le signal en p3 sur le schéma ci-bas. Difficile de voir une forme sinusoïdale ici.


Si on remplace le haut-parleur avec ce filtre passe-bas pour éliminer le signal PWM, voici ce qu'on voit à l'oscillope.

Au point 2 le signal PWM n'est pas complètement éliminé il chevauche la fréquence audio.

Au point 1 le signal PWM est à peine visible, il ne reste que la fréquence audio synthétisée.

Dans les années 80 tous les ordinateurs personnels n'avaient pas de carte son, un petit haut-parleur était branché à une sortie numérique et tout ce que l'ordinateur pouvait produire c'était des BEEP en ondes rectangulaires. Jusqu'à ce que quelqu'un est l'idée de créer un pilote de périphérique qui pouvait lire un fichier .WAV et le faire entendre dans le haut-parleur. La technique utilisée était celle décrite dans ce démo synthèse analogique par modulation de largeur d'impulsion.

Il faut faut donc pas s'étonner que les périphériques PWM soit si répandus sur les micro-controlleurs, après les minuteries ce sont les périphériques les plus utilisés sur MCU. Au cours de mes chroniques j'en ai illustrer plusieurs usages:

  • Contrôle de l'intensité lumineuse d'une DEL.
  • Contrôle de la position d'un servo-moteur.
  • Contrôle de la vitesse d'un moteur c.c.
  • Synthèse de signaux analogiques.

Il y a d'autres usages comme par exemple les régulateurs de tension. En fait le PWM est la méthode la plus efficace pour contrôler et produire des signaux analogiques avec du numérique.




NOTES:
1) Notez que pour la table sine_table j'ai utilisé une table da plutôt qu'une table dt. Ce type de table permet d'enregistrer des valeurs plus grandes que 255 dans une location mémoire flash. La mémoire flash étant de 14 bits on peut enregistrer des valeurs de 0 à 16383. j'économise ainsi 90 locations mémoire par rapport à l'utilisation d'une table dt, une réduction de 50%. De plus l'accès dans la routine d'interruption est plus rapide.





dimanche 28 octobre 2012

expérimentation avec PIC10F322, partie 2

Dans cette deuxième expérience avec le MCU PIC10F322 il s'agit de contrôler la vitesse d'un petit moteur en courant continu en utilisant la modulation de largeur d'impulsion, PWM pour son acronyme anglophone. Voici le schéma du circuit utilisé pour cette expérience.


La broche RA1 est la sortie PWM qui contrôle le transistor Q1 qui lui-même contrôle le moteur en mode ON/OFF. De plus l'entrée RA2 est configuré pour une lecture analogique du voltage au collecteur de Q1. Cette lecture permet de savoir si le moteur tourne vraiment ou s'il est bloqué. Dans l'éventualité d'un blocage le moteur est mis à l'arrêt après un certain délais.

principe de fonctionnement

Le moteur est alimenté par des impulsions plutôt que par un voltage continu comme il le devrait dans un usage normal. Ces impulsions sont répétées à une fréquence régulière mais leur durée varie. Plus la durée des impulsions est longue plus le moteur reçois d'énergie donc il tourne plus vite. A cause de l'inertie lorsque l'alimentation du moteur est coupée celui-ci continue à tourner jusqu'à la prochaine impulsion. Du fait de l'inertie du moteur il se fait naturellement une intégration des impulsions et le résultat est équivalent à celui qu'on obtiendrait si on alimentait le moteur avec un courant continu dont on varie le voltage.

Les petits moteurs de ce type sont fabriqués avec 2 aimants permanents qui servent de stator avec un pôle NORD et un SUD. Le rotor lui est constitué d'un bobinage sur une armature ferro-magnétique et forme donc un électro-aimant. Donc lorsque le rotor est alimenté le champ magnétique résultant du passage du courant dans le bobinage du rotor interagit avec celui du stator pour faire tourner le moteur.

Lorsqu'un conducteur se déplace dans un champ magnétique une force électro-motrice est générée dans le conducdeur. C'est le principe de fonctionnement de toute génératrice électrique. Les moteurs n'échappent pas à cette loi de la physique et se comportent aussi comme des générateurs. Donc lorsque le moteur tourne une force électro-motrice est générée dans le rotor. On l'appelle Force Contre Électro-Motrice car sa polarité s'oppose à celle de l'alimentation du moteur. C'est la raison pour laquelle un moteur tire un maximum de courant lorsqu'il est à l'arrêt et que ce courant diminue avec la vitesse car la F.C.É.M. est soustraite du voltage d'alimentation.

Ir = (Valim. - Vf.é.c.m.)/Rrotor
Ir est le courant circulant dans le rotor
Valim est le voltage d'alimentation
Vf.c.é.m. est le voltage généré par la Force Contre Életro Motrice
Rrotor est la résistance du rotor.

Ce qui est intéressant c'est l'usage qu'on peut faire de cette F.C.É.M. Puisqu'on alimente le moteur par impulsions, entre 2 impulsions Q1 ne conduit pas et donc si on mesure le voltage au collecteur de Q1 pendant cette phase ce qu'on obtient c'est

Vcq1 = Valim - Vf.c.é.m

Mais comme je viens de l'expliquer si le moteur ne tourne pas la Vf.c.é.m. est nulle. Donc on peut savoir si le moteur tourne ou pas en mesurant la valeur de ce voltage. C'est ce que fait le programme. Il mesure 16 fois cette valeur pour en faire une moyenne et si ce voltage moyen est plus grand qu'une certaine valeur il considère que le moteur est mécaniquement bloqué et au bout d'un délais il coupe l' alimentation. Si vous fabriquez un petit robot sur roues vous pouvez savoir si le robot bute sur un obstacle simplement en utilisant cette technique, donc pas besoin de détecteur d'obstacle.

Le code source est disponible ici; controle-moteur-cc-pic10f322.asm


jeudi 25 octobre 2012

expérimentation avec le PIC10(L)F322, partie 1

Dernièrement j'ai entrepris d'étudier les particularités du PIC10(L)F3221. J'ai commencé par me fabriquer un platine d'expérimentation. Il y a quelques temps j'ai vue sur le site Hackaday.com2 une platine d'expérimentation conçu avec une platine à oeillets 100mil et un MCU ARM en format QFN. Je me suis dit que le gars qui avait fait ça devait-être très patient. Mais aussi que s'il l'a fait je devrais être capable de le faire aussi. Mais pour un premier essai j'ai choisi un MCU beaucoup plus modeste, soit un PIC10LF322-E/MC en format 8 DFN. Le DFN est semblable au QFN sauf que les contacts ne sont que sur 2 côtés au lieu des 4. Le boitier mesure à peine 2x3 mm et l'espace entre le centre d'un contact et son voisin n'est que de 0,5mm.


La pointe de mon fer à souder fait plus d'un mm au plus étroit, difficile de ne pas faire de pont d'étain entre les contacts. Je me suis donc retrouvé avec 1 pont d'étain de chaque côté qui reliait tous les contacts. Pas de panique, que je me suis dit, la pompe à dessouder va régler ça. Et effectement j'ai réussi à enlever le surplus d'étain simplement avec la pompe à dessouder.

J'ai installé sur la platine côté MCU des broches qui vont me permette de brancher le pickit 3 ainsi que de relier avec des cavaliers les E/S à différents composants comme la LED RGB et le bouton momentané installé sur l'autre face de la platine.




Ma méthode pour souder le MCU est la suivante.

  1. Collé le MCU sur la platine avec une goûte de colle rapide locktite.
  2. Souder 6 fils no. 30 AWG sur les oeillets entourant le MCU.
  3. Couper les fils juste de la longueur nécessaire pour qu'ils touchent le contact qui leur est destiné.
  4. Mettre du tack flux sur les contacts
  5. Souder avec un fil d'étain ultra fin.
  6. Utiliser la pompe à dessouder pour enlever le surplus d'étain qui fait pont entre les contacts
  7. Souder un fil sur la plaque de métal au centre du boitier et à un oeillet qui sera relié au V- de l'alimentation.
schéma de la platine


Des périphériques spéciaux

Le PIC10(L)F322 possèdent des périphériques qu'on ne voit pas souvent sur les MCU:

  • 1 générateur de fréquence numériquement programmable NCO
  • 1 cellule logique configurable CLC
  • 1 générateur d'onde complémentaire CWG

objet de cette expérience:
  • exemple d'utilisation du périphérique CLC
  • exemple d'utilisation du périphérique NCO
  • exemple d'utilisation du périphérique CWG

CLC

Le périphérique CLC est celui qui m'a demandé le plus de réflexion qu'en à l'usage que je pourrais en faire. Dans cette première expérience. J'ai branché l'anode rouge de la LED RGB sur RA0, la verte sur RA1 et le bouton momentané sur RA2. le programme s'appelle ColorSweep car il s'agit de faire varier progressivement l'intensité des 2 couleurs à l'inverse l'une de l'autre. C'est à dire que lorsque l'intensité de l'une augmente celle de l'autre diminue. On a donc un balayage de couleur qui passe progressivement du rouge au vert en passant par le jaune. Mais le logiciel comprend aussi un mode flipflop ou on passe du vert au rouge alternativement sans progression. Le rôle du bouton momentané est de faire passé le logiciel d'un mode à l'autre.

Dans cette expérience le CLC est utilisé pour filter les rebonds du bouton plutôt que ce soit fait en software. Pour configurer le CLC j'ai utilisé l'outil graphique fournis par Microchip: CLC designer. La capture d'écran suivante présente la configuration utilisé.


table de vérités
GATE 1GATE 3
RA2NCOFbRA2NCOFb
001000
010010
100100
110111

Par application du théorème de De Morgan

Fb(GATE 1) = ~RA2 ET ~NCO = ~( RA2 OU NCO )
Fb(GATE 3) = RA2 ET NCO = ~ ( ~RA2 OU ~NCO)

Dans cette configuration la CLC est configuré comme un SR lacth le signal du bouton qui est branché sur RA2 passe par GATE 1 et le gate OU pour atteintre l'entrée S(et) du SR latch. L'entrée R(eset) et activé par un pulse qui provient du périphérique NCO qui est programmé pour produire ce pulse à toutes les 50msec.
Cependant dans le cas d'un SR lacth les entréres S et R ne doivent jamais se retourvé au niveau 1 en même temps sinon l'état de la sortie Q serait imprévisible. Donc j'utilise une configuration logique sur GATE 1 et GATE 3 pour que les 2 signaux se bloquent mutuellements. Cette configuration fait en sorte que pour que le S(et) passe à 1 il faut que les 2 entrées du GATE 1 soient à zéro. Mais je ne veut pas non plus que le pulse en provenance du NCO R(eset) le latch tant que le bouton est enfoncé (RA2=0) la sortie du GATE 3 doit donc passé à 1 seulement lorsque RA2=1 et que la sortie du NCO=1.


NCO

Le générateur de fréquence numériquement programmable utilise un accumulateur, un additionneur et un incrément et est alimenté par un signal d'horloge. A chaque impulsion reçu de l'horloge la valeur de l'incrément est ajouté au contenu de l'accumulateur et lorsque l'accumulateur déborde la sortie du NCO génère un pulse.
La fréquence de ce pulse dépend de la fréquence du signal d'horlogue et de la valeur de l'incrément. Plus l'incrément est petit plus il faut d'additions pour faire déborder l'accumulateur et vice-versa. On modifie donc la fréquence des pulses en modifiant la valeur de l'incrément. Ce pulse de sortie peut-être utilisé pour faire basculer un flipflop. Dans ce mode la sortie du flipflop est une onde carré (duty cycle = 50%) dont la fréquence est la moitié de celle à la sortie NCO. Mais le NCO peut aussi être programmé en mode impulsion. Dans ce cas chaque débordement produit une impulsion dont la durée est programmable de 1 à 128 périodes d'horloge.

Dans cette exemple le NCO est été programmé en mode impulsion dont période de répétition est de 50msec. Sa fonction est de remettre à zéro la sortie du SR latch dans le CLC.


CWG

Le générateur d'onde complémentaire prend simplement à son entrée un signal rectangulaire et produit 2 sorties complémentaires, c'est à dire lorsqu'une sortie est à 1 l'autre est à zéro et vice-versa. Mais en plus il est possible de programmer un temps mort au début et à la fin des changements d'états. Temps mort pendant lequel les 2 sorties sont dans le même état. Ce type de générateur est utile pour généer des signaux en opposition de phase pour alimenter des moteurs pas à pas ou encore des ponts en H et autres applications du genre.

Dans cette exemple je m'en sert en conjonction avec le périphérique PWM1 dont la sortie alimente le CWG pour contrôler l'intensité de 2 LED de façon complémentaire. C'est à dire que lorsque l'intensité de la LED verte augemente celle de la rouge diminue et vice-versa.


le code assembleur pour réaliser cette expérience se retrouve ici.




NOTES:

1) Attention le PicKit 2 ne semble pas en mesure de programmer le PIC10F322, en tout cas ça n'a pas fonctionné pour moi dans mplabx, j'ai du utilisé le pickit 3.

2) Je ne retrouve malheuresement pas cette entrée sur le site.

dimanche 21 octobre 2012

Le diable se cachait encore dans les détails

Hier j'ai passé la journée à travailler sur un projet utilisant un PIC10LF322. Ça implique que je devais lire les 200 pages du datasheet. J'ai fais le montage final avant de débuter la programmation et ensuite en lisant la doc j'ai créé un fichier de macros pour cacher les détails.

Je programme le PIC, je test, ça ne fonctionne pas. Qu'est-ce qui ne va pas au juste? J'essaie de déboger en utilisant le PicKit 3 mais MPLABX1 affiche une erreur d'application lorsque je veux démarrer la session de débogage. Je dois donc travailler autrement. Y a-t-il une erreur dans mon montage? Pour le savoir je programme un autre MCU hors montage. Ça ne fonctionne pas plus. Je fais tourner le programme dans le simulateur et tout se déroule normalement. Finalement j'allume! Le MCU est configuré comme ceci.

__CONFIG  _CP_OFF & _MCLRE_OFF

Ça signifit qu'il utilise un oscillateur externe il aurait fallu que j'utilise la directive suivante:

__CONFIG   _CP_OFF & _MCLRE_OFF & _FOSC_INTOSC
Ca fonctionnait dans le simulateur car celui-ci présume qu'il y a un oscillateur externe en fonction.

Je corrige et je fait un autre essai. Le projet utilise RA0,RA1 et RA3 comme entrée numérique et RA2 comme sortie numérique. Problème, l'entrée RA3 ne fonctionne pas... On dirait que le MCU réinitialise lorsque la broche est mise à zéro. Pourtant comme la config le mentionne bien le master clear est désactivé: _MCLRE_OFF. Le MCU est-il défectueux? Y a-t-il une erreur dans le montage? Encore une fois je fais un test sur un MCU non monté, même problème. Je me replonge dans la documentation et je trouve au paragraphe 3.1 config word le bit no. 8 LVP: Low Voltage Programming enable bit. Ce bit et activé par défaut et s'il est activé l'état du bit 6 MCLRE: ~MCLR/Vpp pin function select bit est ignoré. Ce qui revient à dire que si on ne veut pas utiliser la fonction Master clear sur RA3 on doit-utiliser la directive:

__CONFIG   _CP_OFF & _MCLRE_OFF & _LVP_OFF & _FOSC_INTOSC

Pour désactiver le master clear il faut utiliser les 2 paramètres ensembles.

Mais je n'étais pas au bout de mes peines. j'avais activés les résistances PULLUP dans le registre WPUA mais le MCU se comportait comme si les pullup n'était pas activés. Refouille la documentation, figure 16-1 le registre OPTION_REG bit 7 ~WPUEN est à 1 par défaut mais doit-être à zéro pour que les pullup puissent être activés. L'utilité de ce bit me laisse perplexe.


Imaginez le PIC10LF322 est un des plus simple MCU offert par Microchip et le datasheet en format PDF fait plus de 200 pages. Pour des MCU plus complexes le PDF peut faire 400 ou 500 pages. Et Il faut lire tous les paragraphes pour être certain de ne rien manquer si on ne veut pas perdre son temps sur de faux problèmes. Il faut aussi faire attention aux priorités d'accès au broches d'entrées/sortie. Les entrées/sorties numérique ont toujours la plus faible priorité donc si un périphérique spécial est configuré par défaut pour utiliser une broche même si on configure le registre TRIS pour utiliser cet E/S en numérique ça ne fonctionnera pas. Il d'abord désactiver tous les périphériques qui l'utilise avec une priorité supérieure. Et c'est là l'une des utilités importantes des fichiers de macros, cacher ces détails dans des macros plus simple d'utilisation.

;; bonne configuration pour désactiver le master clear
;; utilisation: __CONFIG   _CP_OFF & _FOSC_INTOSC & _MCLRE_REALLY_OFF
;;
#define _MCLRE_REALLY_OFF ( _MCLRE_OFF & _LVP_OFF )

;;
;; macro pour activer tous les pullup
;;
enable_all_pullup macro
movlw 0xF
movwf WPUA
bcf OPTION_REG, NOT_WPUEN
endm


NOTES:
1) MPLABX est plein de bogues, vive le vieux MPLAP.

samedi 20 octobre 2012

comparaison des familles PIC 8 bits

Microchip présente ses MCU 8 bits en 4 groupes ou familles, baseline, mid-range, enhanced mid-range et extended. Voici un tableau comparatif de ces familles.

famille Nbre d'instructions caractéristiques membres
baseline 33 codées sur 12 bits
Ne supporte pas les interruptions
Pile de retour 2 niveaux
1 seul registre FSR

pic10f2xx
pic12f5xx
pic16f5xx
mid-range 35 codées sur 14 bits
Supporte les interruptions
Pile 4 ou 8 niveaux
1 seul registre FSR

pic10f3xx
pic12f529TxxA1
pic12f6xx
pic16f5271
pic16f6xx
enhanced mid-range 49 codées sur 14 bits
Supporte les interruptions
Pile 16 niveaux
2 registres FSR (FSR0,FSR1)
Adressage relatif via FSRx
auto-incrément décrément sur FSRx
Mécanisme pour accéder la RAM en mode unifié.

pic12f1xxx
pic16f1xxx
Extended 75/83 codées sur 16 bits
Supporte les interruptions
Pile 31 niveaux
Pointeur de pile manipulable
3 registres FSR (FSR0,FSR1,FSR2)
Adressage relatif via FSRx
auto-incréement et décrément sur FSRX
Multiplicateur 8x8 en hardware
Mémoire RAM linéaire

Tous les PIC18
NOTES:
1) les pic12f529TxxA et pic16f527 supportent les interruptions et ont une pile de 4 niveaux on peut donc les considérés comme des midrange.

baseline

C'est la plus ancienne architecture PIC et la plus limitée, bon pour les petits projets nécessitant très peut de code. Par exemple le plus petit et le plus économique MCU est le PIC10F200 avec seulement 255 Mots pour la flash programme et 14 octets de RAM. Parfait pour les lampes de poches multi-fonctions, les distributeurs de parfums qui déclenchent à l'approche d'un personne ou encore les cartes de voeux qui jouent une mélodie lorsqu'on les ouvrent.

midrange

Légère amélioration par rapport au baseline puisqu'on a un support pour les interruptions, plus d'espace programme.

enhanced midrange

Là on commence à avoir des MCU qui ressemblent à quelque chose d'utilisable pour des projets plus complexe. La pile des retours plus large n'est pas le principal avantage mais plutôt les 2 FSR et la possibilité d'adresser la RAM de façon unifié. S'il y a quelque chose de chiant avec les PIC est que la RAM est fracturée en BANK. Avec les enhanced midrange le problème est en partie résolue. En se servant d'un FSR on peut accéder à toute la RAM sans faire de commutation de BANK. Cette architecture introduit aussi l'adressage relatif ce qui facilite l'accès aux membres d'une structure de donnée. Bref ces MCU facilite le travail des compilateurs C. Pour la programmation en C cette famille est à préférer au 2 précédentes.

Extended

Enfin avec l'introduction des PIC18 on peut dire que Microchip a mis sa gamme MCU 8 bit à jour. Les PIC18 n'ont rien à envier aux AVR. Tout est là, linéarisation de la mémoire RAM, 3 registres FSR avec auto-incrément, auto-décrément et adressage relatif. Un jeux d'instruction pensé pour les compilateurs C. Certains modèles permettent d'étendre la mémoire programme en utilisant des PORT E/S pour créé un bus externe. Ce groupe offre la plus grande variété de produits et certains modèlent sont disponibles en format DIL (Dual In Line) enfichable dans les platines sans soudure.





mercredi 10 octobre 2012

ambiance pingpong

Après avoir vu ceci j'ai décidé de me faire une lampe d'ambiance mais tout ce que j'avais en main comme globe c'était des balles de pingpong. Donc mon mood light est en format réduit. Disons que c'est une lampe d'ambiance pour Amster ;-).

En première sur ce blog je vais présenter la version en language C du code avec la version en assembleur. J'ai voulu comparer le code assembleur au code produit par la version gratuite du compilateur XC8 en téléchargement sur le site de Microchip.

schéma électronique



montage




Pour ce montage je n'ai pas utilisé de platine de montage sans soudure. J'ai fait le montage final directement en installant des tie points où j'ai branché les fils pour la programmation. Il s'agit de fils avec une broche à une extrémité que je branche directement dans le PICKIT 2 ou 3 et à l'autre une petite pince.



Pour l'alimentation j'ai simplement empilé 3 piles LR44 qui tiennent ensemble avec du ruban d'électricien. Comme ça si je veux les remplacer je n'ai qu'à enlever le ruban, pas de soudage à faire. Pour prolonger la durée des piles la balle s'éteint au bout d'une minute. Pour la réanimer il suffit de la bouger. Dans ce but j'ai fabriquer une tilt switch de mon cru visible sur la photo du haut. 2 fils à la verticale avec une boucle à l'extrimé. Un de ces fil est relié au V- et l'autre à l'entrée GP3 du MCU. Un 3ième fil les relie ensemble mais sans soudure ce qui donne un contact très instable. Il suffit de bouger la balle pour que le contact soit rompu une fraction de seconde. C'est suffisant pour sortir le MCU du mode sleep grâce à la fonctionalité wake up on pin change.

Le résultat final n'est cependant pas très élégant, il y a place à l'amélioration.

Le scotch tape qui tiens les 2 hémisphères ensemble laisse à désiré et la lumière des DEL n'est pas assé diffusée, d'où le spot blanc au pôle sud.


le logiciel


Comme je l'ai mentionné en introduction j'ai écris 2 versions la première en assembleur comme d'habitude et l'autre en C.

En gros comme le pic10f202 n'a pas de périphérique PWM c'est fait en code dans la sous-routine pwm_control. Ça fonctionne comme ceci:

  1. la sous-routine random génère un nombre de 24 bits qui est utilisé comme couleur RGB
  2. les variables pwm_red, pwm_green et pwm_blue détermine l'intensité de chaque couleur. Lorsque le compteur pwm_cntr arrive à une de ces valeur la couleur correspondante est éteinte. Lorsque le compteur pwm_cntr arrive à zéro le cycle se répète.

  3. Une transition d'une couleur à l'autre se fait progressivement grâce à la procédure transition. Une valeur au hasard est généré dans la variable rnd et ensuite transition amène les valeurs des variables pwm_xxx vers la valeur de la variable rnd.
  4. Lorsque les 3 valeurs pwm_xxx sont égales aux valeurs dans rnd random est appellé à nouveau pour générer une nouvelle valeur dans rnd et le processus de transition recommence.
  5. Le périphérique TMR0 est utilisé avec la variable off_timer comme minuterie. Au bout de 60 seconde les DEL sont éteinte et le MCU est mis en mode sleep
  6. Le MCU est configuré pour sortir du mode sleep lorsque l'état d'une entrée change. Donc la tilt switch et branchée sur GP3 et lorsqu'on brasse la balle l'état sur GP3 est modifié suite à une perte de contanct entre le V- et GP3 et la balle se réanime.

comparaison des codes assembleur et C

Programmer en C est beaucoup plus simple et rapide malheureusement en ce qui concerne le compilateur XC8 en version gratuite le code généré est médiocre. Le code généré par XC8 occupe 339 instructions tandis que la version assembleur en occupe 143.
La fréquence du cycle PWM pour le code assembleur est de 176Hz tandis qu'il tombe à 76hz pour le code généré par XC8. Dans le fenêtre qui affiche le résultat de la compilation de XC8 on nous informe que la version PRO réduirait le code de 144 instructions, Ce qui est encore plus que le code éris en asembleur mais est acceptable compte de tenu des avantages de la programmation en C. Le hic c'est le prix d'une licence PRO 995US$ et la version STANDARD qui optimise moins vaut 495US$. Je crois que je vais continuer à programmer en asembleur.