http://micropic.free.fr
La programmation des PICs
Vous trouverez sur cette page la description du programmateur pour les microcontroleurs Pic 16F84 et 16F877 que j'ai réalisé.



Voici le schéma électrique de ce programmateur ( origine D. Tait )

Schéma electrique

Le circuit imprimé que j'ai réalisé , il fait 3,14 pouces de coté ( environ 8 cm * 8 cm )

circuit imprime

Il faudra retoucher le typon avant de l'imprimer , l'exportation de Corel draw n'étant pas géniale et la compression JPEG n'arrange pas les choses !

voici le plan d'implantation :

implantation

et la liste des composants :

D1,D7 : leds 3mm rouge
D2 : led 3mm verte
D3,D4,D5,D6 : diodes 1N4007
C1,C2,C4,C5 : condensateurs 100NF 63V
C3 : condensateur chimique 100uF
IC1 : régulateur 78L05
IC2 : régulateur 78L08
IC3 : 74LS05 + 1 support 14 broches
IC4 : 16F84 + 1 support 18 broches tulipe ( ou un support FIN si vous avez les moyens ! )
T1,T2 : transistor BC557
R1,R2,R3,R4,R5 : résistances 4,7Kohms
R6,R7,R8,R9 : résistances 10Kohms
ne pas oublier le strap entre R6 et C4


Différences par rapport au schéma de D. Tait :
  • rajout de la résistance de Pull-Up R9 ( certains ports parallèles n'ont pas de résistances de Pull Up intégrées )
    ( peut fonctionner sans , cela dépend de votre port parallèle )
  • rajout des condensateurs de découplage sur le pic et sur 74LS05
    ( les 2 que j'ai fabriqué fonctionnent sans , mais il vaut mieux être prévoyant )
  • rajout de la led D7 pour signaler la présence du 5 Volts sur le PIC
    ( pas indispensable , mais on est sur qu'il n'y a plus de tensions sur le PIC au moment de l'enlever )
  • changement du pont de diodes en 4 diodes 1N4007
    ( c'est ce que j'avais en stock )
NOTA : pour programmer le 16F877 , il faut réaliser un adaptateur avec la correspondance suivante :

16F84 16F877 16F876 Fonction
5 12 & 31 8 & 9 masse
14 11 & 32 20 +5V
4 1 1 Reset
12 39 39 Clock
13 40 40 Data


j'ai réaliser 2 programmateurs avec ce circuit , donc il n'y a pas de problème au niveau du circuit

Le premier que j'ai réalisé est un prototype , mais il fonctionne sans problème.


ainsi que l'inévitable soft qui l'accompage :
soft


Ce soft est encore en version béta , merci de m'écrire si vous trouvez des bugs ( version actuelle : 1.0 ).
Ce logiciel n'est pas uniquement destiné au 16F84 et 16F877 : dans la mesure ou il ne programme que les octets utilisés , il peut programmer d'autres types de micro , par exemple des 16F83 , ou 16F876.
Modifier les variables To et Ti pour s'adapter aux timing des 16F84a.
Ces 2 variables devront également être modifiés suivant d'autres paramètres : vitesse de l'ordinateur , applications tournant en tache de fond , ...
Baisser la valeur de ces 2 variables tant qu'il n'y a pas de problèmes de programmation.
A partir de la version 1.0 , la configuration du logiciel est automatiquement sauvegardée dans un fichier .ini .









Voici un résumé des notions de base pour la programmation des Pic :

Structure du fichier source ( .asm ):
1ere colonne : label
2eme colonne : instruction
3 eme colonne : commentaire

La compilation donne les fichiers suivants :

fichier .lst ( utilisé par le simulateur )
fichier .hex ( code machine a utiliser avec le programmateur )


Les 35 instructions du pic 16F84 :

f = registre d'adresse 7 bits
k = valeur immédiate 8 bits ( 0 à 255 )
d = 0 : destination = W
d = 1 : destination = f


mnémonique Instructions sur les registres ( octets ) bits modifiés
ADDWF f,dd:=W+fC,DC,Z
ANDWF f,dd:=W AND fZ
CLRF ff:=0Z
CLRWW:=0Z
COMF f,d d:=NOT(f) Z
DECF f,dd:=f-1Z
DECFSZ f,dd:=f-1 ; Skip if Zero.
INCF f,dd:=f+1Z
INCFSZ f,dd:=f+1 ; Skip if Zero.
IORWF f,dd:=W OR fZ
MOVF f,dd:=f ( permet de savoir si f=0 en faisant MOVF f,1 )z
MOVWF fW:=f.
NOPn'éffectue aucune opération.
RLF f,dd=f SHL 1 C
RRF f,dd=f SHR 1 C
SUBWF f,dd:= f-W ( en complement à 2 --> d:=f + not (W) +1 )C,DC,Z
SWAPF f,dd:= f[4..7] <--> f[0..3] ( inverse les quartets ).
XORWF f,dd:= W XOR fZ

mnémonique Instructions sur les registres ( bit par bit ) bits modifiés
BCF f,bf[b]:=0 ( mets à 0 le bit b de f ).
BSF f,bf[b]:=1 ( mets à 1 le bit b de f ).
BTFSC f,bteste le bit b de f ; Skip if Clear ( 0 ).
BTFSS f,bteste le bit b de f ; Skip if Set ( 1 ).

mnémonique Instructions de contrôle bits modifiés
ADDLW kW:=W+kC,DC,Z
ANDLW kW:=W AND kZ
CALL kappele un sous programme.
CLRWDTremet à 0 le timer du chien de gardeTO,PD
GOTO kse branche à l'adresse k.
IORLW kW:=W OR kZ
MOVLW kW:=k.
RETFIEfin d'une interruption.
RETLW kw:=k , puis effectue un retour de sous programme.
RETURNeffectue un retour de sous programme.
SLEEPplace le circuit en mode sommeil et stoppe l'oscillateurTO,PD
SUBLW kW:=W-kC,DC,Z
XORLW kW:=W XOR kZ

moyens mémotechnique pour se rappeler des commandes :
le F ( comme File register ) indique un registre
le L ( comme litéral ) indique une valeur immédiate


les différents registres utilisés sur le pic :
  • registre F0 ou F80 [INDF] : registre pour adressage indirect
    - toute instruction qui adresse le registre F0 pointera sur les données adressée par le registre FSR
    - lire le registre 0 renvoie toujours 0
    - écrire dans le registre 0 effectuera un NOP ( en modifiant le registre STATUS )
    - une adresse indirecte est obtenue en concaténant FSR ( bits 0 à 7 ) avec le bit IRP de STATUS ( bit 7 )

  • registre F01 [ RTCC] : compteur temps réel
    - Compteur du Timer 0

  • registre F02 ou F82 [ PCL ] : bits de poids faible du compteur de programme
    - Contient les bits de poids faible de l'adresse en cours d'execution

  • registre F03 ou F83 [ STATUS ] : registre de status
    • bit 7 : IRP (Indirect register Page )
      si 0 = page 0,1 ( 00H à FFH )
      si 1 = page 1,2 ( 100H à 1FFH )

    • bits 6 et 5 : RP1 et RP0 ( register Page )
      si 00 = Page 0 (00h - 7Fh
      si 01 = Page 1 (80h - FFh)
      si 10 = Page 2 (100h - 17Fh)
      si 11 = Page 3 (180h - 1FFh)

    • bit 4 : TO ( Time Out )
      si 1 = alimentation du pic en cours ( également mis à 1 par CLRWDT et SLEEP )
      si 0 = remis a 0 par le time-out du watchdog

    • bit 3: PD ( Power Down )
      si 1 = alimentation du pic en cours ( également mis à 1 par CLRWDT )
      si 0 = remis a 0 par SLEEP

    • bit 2 : Z ( Zero )
      si 1 = la derniere opération logique ou arithmétique à donné un resultat égal à 0
      si 0 = la derniere opération logique ou arithmétique à donné un resultat différent de 0

    • bit 1 : DC ( Digit Carry )
      si 1 = débordement du bit 4 sur le bit 5
      si 0 = pas de débordement du bit 4
      ( sert pour les calculs BCD )

    • bit 0 : C ( Carry )
      si 1 = débordement du bit le plus significatif
      si 0 = pas de débordement du bit le plus significatif

  • registre F04 ou F84 [ FSR ] : registre d'adressage indirect
    -à utiliser avec le registre F00

  • registre F05 [ PORTA ] : registre d'adressage du port A
    -contrôle les directions du port A ( RA0 à RA4 )
    -RA0 à RA3 sont bidirectionnels
    -RA4 est une sortie à collecteur ouvert

  • registre F06 [ PORTB ] : registre d'adressage du port B
    -contrôle les directions du port B ( RB0 à RB7 )
    -les port RB4 à RB7 peuvent générer une interruption RBIF
    -les interruptions peuvent être réinialisée en employant la methode suivante :
    • interdire les interruptions en mettant à 0 le registre RBIE
    • remettre à 0 le bit RBIF

  • registre F08 [ EEDATA ] : registre qui contient la donnée a écrire ou à lire dans la mémoire EEPROM
    -à utiliser avec EEADR , EECON1 et EECON2

  • registre F09 [ EEADR ] : registre qui contient l'adresse à acceder dans la mémoire EEPROM
    -à utiliser avec EEDATA , EECON1 et EECON2

  • registre F0A ou F8A [ PCLATCH ] :bits de poids fort du compteur de programme
    - à utiliser lors de la commutation des pages programme

  • registre F0B ou F8B [ INTCON ] : registre de contrôle des interruptions
    • bit 7 : GIE ( Global Interrupt Enable )
      si 1 = interruptions activées
      si 0 = interruptions désactivés

    • bit 6 : EEIE ( Eeprom Interrupt Enable )
      si 1 = interruptions EEIF activées
      si 0 = interruptions EEIF désactivés

    • bit 5 : T0IE ( Timer 0 Interrupt Enable )
      si 1 = interruptions du Timer 0 activées
      si 0 = interruptions du Timer 0 désactivés

    • bit 4 : INTE ( INTerrupt Enable )
      si 1 = interruptions activées sur RB0
      si 0 = interruptions désactivés sur RB0

    • bit 3 : RBIE ( RBif Interrupt Enable )
      si 1 = interruptions activées sur le changement d'état des port RB4 à RB7
      si 0 = interruptions désactivés sur le changement d'état des port RB4 à RB7

    • bit 2 : T0IF ( Timer 0 Interrupt Flag )
      si 1 = débordement du Timer 0
      si 0 = doit être remis à 0 par programmation

    • bit 1 : INTF ( INTerrupt Flag )
      si 1 = une interruption vient de se produire sur RB0
      si 0 = doit être remis à 0 par programmation

    • bit 0 : RBIF ( RB port change Interrupt flag )
      si 1 = un changement d'état vient de se produire sur l'un port RB4 à RB7
      si 0 = doit être remis à 0 par programmation


  • registre F81 [ OPTION ] : registre de contrôle du diviseur , des interruptions externes et des pull-ups du port B
    • bit 7 : RBPU ( Port B Pull Up )
      si 1 = résistances de Pull-Up du port B désactivées
      si 0 = résistances de Pull-Up du port B activées

    • bit 6 : INTEDG ( INTerrupt EDGe )
      si 1 = interruption sur RB0 sur font montant
      si 0 = interruption sur RB0 sur font descendant

    • bit 5 : T0CS ( Timer 0 Clock Source )
      si 1 = Horloge présente sur RA4
      si 0 = Horloge interne du PIC

    • bit 4 : T0SE ( Timer 0 Source Edge)
      si 1 = interruption sur RA4 sur font descendant
      si 0 = interruption sur RA4 sur font montant

    • bit 3 : PSA ( PreScaler Assignment bit )
      si 1 = le prescaler est assigné au Watchdog
      si 0 = le prescaler est assigné au TIMER0

    • bit 2,1,0 : PS2 à PS0 ( Prescaler rate Select bits )
      Bits 2 à 0TMR0WDT
      000/2/1
      001/4/2
      010/8/4
      011 /16/8
      100/32/16
      101/64 /32
      110/128/64
      111/256/128

  • registre F85 [ TRISA ] : registre de contrôle du port A
    - bit a 0 , défini la sortie correspondante en sortie
    - bit a 1 , défini la sortie correspondante en entrée

  • registre F86 [ TRISB ] : registre de contrôle du port A
    - bit a 0 , défini la sortie correspondante en sortie
    - bit a 1 , défini la sortie correspondante en entrée

  • registre F88 [ EECON1 ] : registre de contrôle pour la mémoire EEPROM
    - à utiliser lors d'une lecture ou écriture dans la mémoire EEPROM

  • registre F88 [ EECON2 ] : registre de contrôle pour la mémoire EEPROM
    - à utiliser lors d'une lecture ou écriture dans la mémoire EEPROM



Rappel des caractéristiques :
- 1K de mémoire programme ( = 1024 instructions de 14bits )
- 68 octets de RAM
- 64 octets D'EEPROM
- 25 mA maxi sur une entée RA ou RB
- 20 mA maxi sur une sortie RA ou RB
- PORT A : 80 mA maxi en entrée
- PORT A : 50 mA maxi en sortie
- PORT B : 150 mA maxi en entrée
- PORT B : 100 mA maxi en sortie
- 10 MHz maxi ( 20 pour la version 'A' )


La durée d'une instruction est égale à la l'inverse du quart de la fréquence :
ex : 1 MHz --> T = 4 / 1 --> T=4µs
ex : 4 MHz --> T = 4 / 4 --> T=1µs
ex : 8 MHz --> T = 4 / 8 --> T=0.5 µs

oscillateur RC à 5V, 25°C
C R F variation
20pF 5K4.61 MHz25%
20pF 10K2.66 MHz24%
20pF 100K311 KHz39%
100pF 5K1.34 MHz21%
100pF 10K756 KHz18%
100pF 100K82.8 KHz28%
300pF 5K428 KHz13%
300pF 10K243 KHz13%
300pF 100K26.2 KHz23%

Le PIC16F84 commence toujours à l'adresse 0000H ( à l'allumage ou lors d'un reset ).
Lorsqu'il y a une interruption le pic va à l'adresse 0004H ( si les interruptions sont validées ).

Decimal D'100'
Hexadecimal H'9f' '0x9f
Octal O'777'
Binaire B'00111001'
ASCII A'C' 'C'



commençons par un exemple simple :

RB0 = un interrupteur
RB1 = une led
on appuie sur l'interrupteur , la led s'allume

label instruction commentaire

#include p16f84.inc ; spécifie au compilateur les définitions à utiliser
;
ORG 0000 ; indique que l'instruction qui suit sera stoquée à l'adresse 0000H
;
; dévalider toutes les interruptions
startmovlw 00H; reset de tous les bits du registre d'interruption
movwf INTCON; intcon = registre d'interruption
bsf STATUS,RP0; sélection de la bank 1 pour accéder a TRISB ( bit 5 de STATUS a 1 )
;
; configurer le port B
movlw B'00000001'; bits 1 du port b en entrée ( 0=sortie ) , les autres en sortie
movwf TRISB; on écris W dans TRISB
bcf STATUS,RP0; on remet la bank 0 pour accéder plus tard à PORTB
;
boucle btfss PORTB,0; teste si on appuie sur l'inter
goto boucle; sinon on boucle
bsf PORTB,1; on allume la led
;
boucle1btfsc PORTB,0; teste si on relache l'inter
goto boucle1; sinon on boucle
bcf PORTB,1; on eteind la led
goto boucle; on recommence le cycle
end

savegarder ce programme sous le nom prog1.asm

procédure à suivre pour compiler le programme :
  • charger le programme de compilation MPASM depuis le site de microchip :
  • configurer de la façon suivante :
  • Radix : hexadecimal
  • Warning Levels : All mesages
  • Hex Ouput : INHX8M
  • Generated Files : error Files et List Files
  • case sensitive : non cochée
  • Macro expension : default
  • Processor : 16F84
  • Tab Size : 8
  • Save setting on exit : cochée
  • selectionner le fichier dans 'Source File Name' : prog1.asm
  • cliquer sur Assemble
  • une fenêtre s'ouvre et affiche le résultat ( normalement 0 errors ! )
  • le fichier prog1.hex est généré dans le même répertoire


il faut maintenant transférer le fichier.hex dans le pic

  • brancher le programmateur sur le PC ( personnellement je n'eteind pas le PC , mais il est conseillé de le faire )
  • mettre le PIC sur le programmateur (vérifier que les deux leds rouges sont éteintes avant de l'insérer )
  • alimenter le programmateur
  • lancer le programme PicFlash.exe
  • cliquer sur "Load Prog" selectionner le fichier à charger ( ici prog1.hex )
  • Positionner "Devices" sur "16F84"
  • Décocher "Watchdog" , "Power" et "Protect"
  • et enfin cliquer sur "Ecriture Prog" lancer la programmation du PIC


si tout s'est bien passé , après une dizaine de secondes , le programme affiche 'Ecriture Programme terminée'
vérifier que les deux leds rouges sont éteintes et enlever le pic du programmateur

Si des erreurs de programmation surviennent , cela peut être du aux tempos internes du programme.
Dans ce cas , augmenter les valeurs de "To" et "Ti".

tester le pic avec le montage suivant :





maintenant que ce premier exemple fonctionne , continuons en entrant un peu plus dans les détails:
nous allons décrire le squelette du programme qui nous servira pour tout les programmes qui vont suivrent

label instruction commentaire
; squelette du programme
include p16f84.inc ; spécifie au compilateur les définitions à utiliser
processor 16f84 ; indique au compilateur quel microcontrôleur est utilisé
radix dec ; indique au compilateur que le format par défaut des nombres est décimal
;
; définitions des variables en ram
org 0x0C; indique que le code qui va suivre sera stocké à l'adresse $0C ( adresse pour les variables )
a1res 01; reserve 1 octet pour la variable a1
a2res 01; reserve 1 octet pour la variable a2
;
; définitions des données de la mémoire eeprom
org 0x2100; indique que le code qui va suivre sera stocké à l'adresse $2100 ( adresse pour les données eeprom )
de '(c) 2000 offset; chaine de caractères memorisée en eeprom
de 0; fin des données eeprom
;
org 0x00; point de départ du programme ( ou après un reset )
goto start;
;
org 0x04; point de départ des interruptions
retfi; ou goto xxxx si les interruptions sont utilisées
;
startmovlw 00H; reset de tous les bits du registre d'interruption
movwf INTCON; intcon = registre d'interruption
;
bsf STATUS,RP0; sélection de la bank 1 pour accéder a TRISA et TRISB ( bit 5 de STATUS à 1 )
; configurer le port A
movlw B'00000000'; tout le port B en sortie ( 0=sortie , 1=entrée)
movwf TRISA; on écris W dans TRISB
; configurer le port B
movlw B'00000001'; bits 1 du port b en entrée ( 0=sortie ) , les autres en sortie
movwf TRISB; on écris W dans TRISB
bcf STATUS,RP0; on remet la bank 0 pour accéder plus tard à PORTA et PORTB
;
suiteentrer à partir d'ici le code du programme


© 1999-2004 Philippe Brégea