Le PIC16F628A

Il existe plusieurs modèles de PIC, nous nous intéresserons au classique PIC16F628A en boîtier DIP18, pour environs 1€
, c'est pas cher et surtout faible consommation...

L'horloge interne est à 4MHz, et la fréquence externe maximale est donnée à 20Mhz, soit 1 cycle d’horloge de 50ns et un temps par instruction de 4x50ns soit 200ns.
En effet chaque instruction demande 4 cycles d’horloge de la CPU pour être exécutée.
Attention, cela dépend aussi du type d’instructions : pour cela voir le tableau récapitulatif du jeu d’instruction du composant.
Le PIC16F628A possède un compteur de programme de 13 bits capable d'adresser un espace de mémoire de programme de 8 K x 14.
Seuls les premiers 2K x 14 (0000h-07FFh) pour lePIC16F628A sont mis en œuvre physiquement.
Les modèles de PIC Un PIC est généralement identifié par une référence de la forme suivante : xx(L)XXyy-zz
PICxx famille du composant, actuellement  « 12, 14, 16, 17 et 18 ».
 L tolérance plus importante de la plage de tension
 XXtype de mémoire programme
 CEPROM ou EEPROM
 CRPROM
 FFlash
 yy Identificateur.
 zz vitesse maximale du quartz de pilotage.

Tableau comparatif

  Mem prog en octetsRAM
en octets
EEPROM en octetsFmax
en MHz
E / SBoîtier
12C508512x1225-468 broches
16C72A2048x14128-202228 broches
16F841024x146864201318 broches
16F6282028x14224128201618 broches
16F8768192x14368256202228 broches
16F8778192x14368256203340 broches
La Mémoire/registres La mémoire de données est divisée en quatre banques, qui contiennent les registres GPR (GeneralPurpose Registers) et les registres SFR (Special Function Registers).
Les SFR sont situés dans les 32 premiers emplacements de chaque banque.
Des registres à usage général sont implémentés en tant que RAM statique dans chaque banque.
Registre à usage général disponible dans chacune des quatre banques.
Bank00x20-0x7F
Bank10xA0-0xFF
Bank20x120-0x14F, 0x170-0x17F
Bank30x1F0-0x1FF
Les adresses 0xF0-0xFF, 0x170-0x17F et 0x1F0-0x1FF sont implémentées en tant que RAM commune et mappées aux adresses 0x70-0x7F.
Le tableau ci-dessous explique comment accéder aux quatre banques de registres via les bits de registre d'état RP1 et RP0
BankRP1RP0
000
101
210
311

exemple:
  BSF STATUS, RP0 ;Bank 1
  BCF STATUS, RP0 ;Return to Bank 0
  
Le fichier de registre est organisé en 224 x 8 dans le PIC16F628A.
Chaque accès est accessible directement ou indirectement par le biais du registre de sélection de fichier FSR.
Banque0Banque1Banque2Banque3
Adr.NomAdr.NomAdr.NomAdr.Nom
00hIndirect addr.80hIndirect addr.100hIndirect addr.180hIndirect addr.
01hTMR081hOPTION_REG101hTMR0181hOPTION_REG
02hPCL82hPCL102hPCL182hPCL
03hSTATUS83hSTATUS103hSTATUS183hSTATUS
04hFSR84hFSR104hFSR184hFSR
05hPORTA86hTRISA105h--185h--
06hPORTB86hTRISB106hPORTB186hTRISB
07h--87h--107h--187h--
08h--88h--108h--188h--
09h--89h--109h--189h--
0AhPCLATH8AhPCLATH10AhPCLATH18AhPCLATH
0BhINTCON8BhINTCON10BhINTCON18BhINTCON
0ChPIR18ChPIE110Ch--18Ch--
0Dh--8Dh--10Dh--18Dh--
0EhTMR1L8EhPCON10Eh--18Eh--
0FhTMR1H8Fh--10Fh--18Fh--
10hT1CON90h--    
11hTMR291h--
12hT2CON92hPR2
13h--93h--
14h--94h--
15hCCPR1L95h--
16hCCPR1H96h--
17hCCP1CON97h--
18hRCSTA98hTXSTA
19hTXREG99hSPBRG
1AhRCREG9AhEEDATA
1Bh--9BhEEADR
1Ch--9ChEECON1
1Dh--9DhEECON2
1Eh--9Eh--
1FhCMCON9FhVRCON
20h



6Fh
General
Purpose
Register
80 octets
A0h



EFh
General
Purpose
Register
80 octets
120h

14Fh
General
Purpose
Register
48 octets
150h

16Fh
--
70h - 7Fh16 octetsF0h - FFhidem
70h-7fh
170h - 17Fhidem
70h-7fh
1F0h - 1FFhidem
70h-7fh
Les registres spéciaux
SPECIAL REGISTERS SUMMARY
BANK 0
AddressNameBit 7Bit 6 Bit 5 Bit 4 Bit 3 Bit 2 Bit 1 Bit 0Value on
POR
Reset(1)
00hINDFAddressing this location uses contents of FSR to address data memory (not a physical register)xxxx xxxx
01hTMR0Timer0 Module’s Registerxxxx xxxx
02hPCLProgram Counter’s (PC) Least Significant Byte0000 0000
03hSTATUSIRPRP1RP0TOPDZDCC0001 1xxx
04hFSRIndirect Data Memory Address Pointerxxxx xxxx
05hPORTARA7RA6RA5RA4RA3RA2RA1RA0xxxx 0000
06hPORTBRB7RB6RB5RB4RB3RB2RB1RB0xxxx xxxx
07h Unimplemented
08h Unimplemented
09h Unimplemented
0AhPCLATHWrite Buffer for upper 5 bits of Program Counter ---0 0000
0BhINTCONGIEPEIET0IEINTERBIET0IFINTFRBIF0000 000x
0ChPIR1EEIFCMIFRCIFTXIFCCP1IFTMR2IFTMR1IF0000-000
0Dh Unimplemented
0EhTMR1LHolding Register for the Least Significant Byte of the 16-bit TMR1 Registerxxxx xxxx
0FhTMR1H Holding Register for the Most Significant Byte of the 16-bit TMR1 Registerxxxx xxxx
10hT1CONT1CKPS1T1CKPS0T1OSCENT1SYNCTMR1CSTMR1ON--00 0000
11hTMR2TMR2 Module’s Register0000 0000
12hT2CONTOUTPS3TOUTPS2TOUTPS1TOUTPS0TMR2ONT2CKPS1T2CKPS0 -000 0000
13h Unimplemented
14h Unimplemented
15hCCPR1LCapture/Compare/PWM Register (LSB)xxxx xxxx
16hCCPR1HCapture/Compare/PWM Register (MSB)xxxx xxxx
17hCCP1CONCCP1XCCP1YCCP1M3CCP1M2CCP1M1CCP1M0 --00 0000
18hRCSTASPENRX9SRENCRENADENFERROERRRX9D0000 000x
19hTXREGUSART Transmit Data Register0000 0000
1AhRCREGUSART Receive Data Register0000 0000
1Bh Unimplemented
1Ch Unimplemented
1Dh Unimplemented
1Eh Unimplemented
1FhCMCONC2OUTC1OUTC2INVC1INVCISCM2CM1CM00000 0000
BANK 1
AddressNameBit 7Bit 6 Bit 5 Bit 4 Bit 3 Bit 2 Bit 1 Bit 0Value on
POR
Reset(1)
80hINDFAddressing this location uses contents of FSR to address data memory (not a physicalregister)xxxx xxxx
81hOPTIONRBPUINTEDGT0CST0SEPSAPS2PS1PS01111 1111
82hPCLProgram Counter’s (PC) Least Significant Byte0000 0000
83hSTATUSIRPRP1RP0TOPDZDCC0001 1xxx
84hFSRIndirect Data Memory Address Pointerxxxx xxxx
85hTRISATRISA7TRISA6TRISA5TRISA4TRISA3TRISA2TRISA1TRISA01111 1111
86hTRISBTRISB7TRISB6TRISB5TRISB4TRISB3TRISB2TRISB1TRISB01111 1111
87h Unimplemented
88h Unimplemented
89h Unimplemented
8AhPCLATHWrite Buffer for upper 5 bits of Program Counter ---0 0000
8BhINTCONGIEPEIET0IEINTERBIET0IFINTFRBIF0000 000x
8ChPIE1EEIECMIERCIETXIECCP1IETMR2IETMR1IE0000-000
8Dh Unimplemented
8EhPCONOSCFPORBOR---- 1-0x
8Fh Unimplemented
90h Unimplemented
91h Unimplemented
92hPR2Timer2 Period Register1111 1111
93h Unimplemented
94h Unimplemented
95h Unimplemented
96h Unimplemented
97h Unimplemented
98hTXSTACSRCTX9TXENSYNCBRGHTRMTTX9D 0000-010
99hSPBRGBaud Rate Generator Register0000 0000
9AhEEDATAEEPROM Data Registerxxxx xxxx
9BhEEADREEPROM Address Registerxxxx xxxx
9ChEECON1WRERRWRENWRRD---- x000
9DhEECON2EEPROM Control Register 2 (not a physical register) ---- ----
9Eh Unimplemented
9FhVRCONVRENVROEVRRVR3VR2VR1VR0 000- 0000
BANK 2
AddressNameBit 7Bit 6 Bit 5 Bit 4 Bit 3 Bit 2 Bit 1 Bit 0Value on
POR
Reset(1)
100hINDFAddressing this location uses contents of FSR to address data memory (not a physical register)xxxx xxxx
101hTMR0Timer0 Module’s Registerxxxx xxxx
102hPCLProgram Counter’s (PC) Least Significant Byte0000 0000
103hSTATUSIRPRP1RP0TOPDZDCC0001 1xxx
104hFSRIndirect Data Memory Address Pointerxxxx xxxx
105h Unimplemented
106hPORTBRB7RB6RB5RB4RB3RB2RB1RB0xxxx xxxx
107h Unimplemented
108h Unimplemented
109h Unimplemented
10AhPCLATHWrite Buffer for upper 5 bits of Program Counter ---0 0000
10BhINTCONGIEPEIET0IEINTERBIET0IFINTFRBIF0000 000x
10Ch Unimplemented
10Dh Unimplemented
10Eh Unimplemented
10Fh Unimplemented
110h Unimplemented
111h Unimplemented
112h Unimplemented
113h Unimplemented
114h Unimplemented
115h Unimplemented
116h Unimplemented
117h Unimplemented
118h Unimplemented
119h Unimplemented
11Ah Unimplemented
11Bh Unimplemented
11Ch Unimplemented
11Dh Unimplemented
11Eh Unimplemented
11Fh Unimplemented
BANK 3
AddressNameBit 7Bit 6 Bit 5 Bit 4 Bit 3 Bit 2 Bit 1 Bit 0Value on
POR
Reset(1)
180hINDFAddressing this location uses contents of FSR to address data memory (not a physical register)xxxx xxxx
181hOPTIONRBPUINTEDGT0CST0SEPSAPS2PS1PS01111 1111
182hPCLProgram Counter’s (PC) Least Significant Byte0000 0000
183hSTATUSIRPRP1RP0TOPDZDCC0001 1xxx
184hFSRIndirect Data Memory Address Pointerxxxx xxxx
185h Unimplemented
186hTRISBTRISB7TRISB6TRISB5TRISB4TRISB3TRISB2TRISB1TRISB01111 1111
187h Unimplemented
188h Unimplemented
189h Unimplemented
18AhPCLATHWrite Buffer for upper 5 bits of Program Counter ---0 0000
18BhINTCONGIEPEIET0IEINTERBIET0IFINTFRBIF0000 000x
18Ch Unimplemented
18Dh Unimplemented
18Eh Unimplemented
18Fh Unimplemented
190h Unimplemented
191h Unimplemented
192h Unimplemented
193h Unimplemented
194h Unimplemented
195h Unimplemented
196h Unimplemented
197h Unimplemented
198h Unimplemented
199h Unimplemented
19Ah Unimplemented
19Bh Unimplemented
19Ch Unimplemented
19Dh Unimplemented
19Eh Unimplemented
19Fh Unimplemented
Détails des registres spéciaux
On remarque que les registres sont définis sur deux pages dont nous expliquerons l'accès au cours du paragraphe sur le registre STATUS.
STATUS : Registre d'état
Bit76543210
0x03, 0x83, 0x103, 0x183IRPRP1RP0TOPDZDCC
Read/WriteR/WR/WR/WRRR/WR/WR/W
Initial Value00011xxx

IRP Permet également l'adressage mais, ce bit est inutile pour le PIC16F84.
IRP Enregistrer le bit de sélection de banque (utilisé pour l'adressage indirect)
si IRP=1 alors Bank 2, 3 (100h-1FFh)
si IRP=0 alors Bank 0, 1 (00h-FFh)
Le RP0 et le RP1 sont les bits permettant d’avoir accès au tableau de programmation et aux différents espaces mémoires.
RP1RP0BANKAdresse
0000x00 à 0x7F
0110x80 à 0xFF
1020x100 à 0x17F
1130x180 à 0x1FF

TO : bit de time-out. Ce bit est à 1 après démarrage ou l'instruction CLRWDT, ou SLEEP.
bit à 0 après Watchdog.
PD : bit de power-down. Ce bit est à 1 après démarrage ou l'instruction CLRWDT.
bit à 0 après exécution de la commande SLEEP.

Z flag Zero
DC Digit Carry/Borrow bit (ADDWF, ADDLW,SUBLW,SUBWF instructions) (for Borrow the polarity is reversed) 1 = Un report du 4ème bit de poids faible
0 = Aucun report du 4ème bit de poids faible
C Carry/Borrow bit (ADDWF, ADDLW,SUBLW,SUBWF instructions) 1 = Un report du bit le plus significatif s'est produit
0 = Aucun report de bit n'a eu lieu


OPTION_REG : Registre de configuration de périphériques
Bit76543210
0x81-0x181RBPUINTEDGT0CST0SEPSAPS2PS1PS0
Read/WriteR/WR/WR/WR/WR/WR/WR/WR/W
Initial Value11111111

RBPU : Port B, Pull-up. Ce bit à 0 permet la validation des résistances de tirage.
INTEDG : Type de front pour l'interruption, "0" front montant, "1" front descendant.
T0CS TMR0 Clock Source Select bit
1 = Transition on RA4/T0CKI/CMP2 pin
0 = Internal instruction cycle clock (CLKOUT)

T0SE TMR0 Source Edge Select bit
1 = Increment on high-to-low transition on RA4/T0CKI/CMP2 pin
0 = Increment on low-to-high transition on RA4/T0CKI/CMP2 pin

PSA : PreScaler Assignement:
1 = Prescaler is assigned to the WDT
0 = Prescaler is assigned to the Timer0 module


La cadence de comptage est égale à la fréquence Fosc/4 si le bit TOCS (TMRO Clock Source) est à 0.
Cette cadence est celle du signal appliqué à TOCKI si le bit TOCS est à 1.
De plus, le bit TOSE (TMRO Source Edge) permet de choisir si l'incrémentation a lieu sur un front descendant si TOSE = 0 et montant si TOSE = 1.
Exemple :Si nous utilisons un quartz à 4 MHz. Fosc/ 4 a donc une valeur de 1 MHz. Si TOCS = 0, la cadence de comptage est de 1 million d'incrémentations par seconde.
  • Prédiviseur actif (PSA = 0)
    PS2PS1PS0Diviseur TMR0Diviseur WDT
    0001:21:1
    0011:41:2
    0101:81:4
    0111:161:8
    1001:321:16
    1011:641:32
    1101:1281:64
    1111:2561:128

  • INTCON – INTERRUPT CONTROL REGISTER
    Bit76543210
    0x0B, 0x8B, 0x10B, 0x18BGIEPEIET0IEINTERBIET0IFINTFRBIF
    Read/WriteR/WR/WR/WR/WR/WR/WR/WR/W
    Initial Value0000000x

    GIE Bit d'activation d'interruption globale
    1 = Active toutes les interruptions non masquées
    0 = Désactive toutes les interruptions
    PEIE Bit d'activation d'interruption périphérique
    1 = Active toutes les interruptions périphériques non masquées
    0 = Désactive toutes les interruptions périphériques
    T0IE Bit d'activation d'interruption de débordement TMR0
    1 = Active l'interruption TMR0
    0 = Désactive l'interruption TMR0
    INTE RB0/INT bit d'activation d'interruption externe
    1 = Active l’interruption externe RB0/INT
    0 = Désactive l'interruption externe RB0/INT
    RBIE Bit d'activation d'interruption de changement de port RB
    1 = Active l'interruption de changement de port RB
    0 = Désactive l'interruption de changement de port RB
    T0IF Indicateur d'interruption de débordement TMR0
    1 = Le registre TMR0 a débordé (doit être effacé dans le logiciel)
    0 = Le registre TMR0 n'a pas débordé
    INTF RB0/INT Bit de flag d'interruption externe
    1 = L’interruption externe RB0/INT s’est produite (doit être effacée dans le logiciel)
    0 = L'interruption externe RB0/INT n'a pas eu lieu
    RBIF Bit indicateur d'interruption de changement de port RB
    1 = Quand au moins une des broches RB <7: 4> change d'état (doit être effacée dans le logiciel)
    0 = Aucune des broches RB <7: 4> n'a changé d'état


    PCON – POWER CONTROL REGISTER
    Bit76543210
    0x8E----OSCF-PORBOR
    Read/WriteRRRRR/WRR/WR/W
    Initial Value0000100x

    OSCF INTOSC Oscillator Frequency bit
    1 = 4 MHz typical
    0 = 48 kHz typical
    POR Power-on Reset Status bit
    1 = Aucune réinitialisation à la mise sous tension n'a eu lieu
    0 = Une réinitialisation à la mise sous tension s'est produite (doit être définie dans le logiciel après la réinitialisation à la mise sous tension)
    BOR Panne de réinitialisation de la panne
    1 = Aucune remise à zéro n'a eu lieu
    0 = Une panne de réinitialisation s'est produite (doit être définie dans le logiciel après qu'une panne de réinitialisation se produise)

    Remarque : la patte RA4 doit être définie en entrée dans le cas du compteur d’évènements. INDF (00h - 80h) : Utilise le contenu de FSR pour l'accès indirect à la mémoire
    FSR (04h - 84h) : Permet l'adressage indirect


    CMCON – COMPARATOR CONFIGURATION REGISTER
    Bit76543210
    0x1FC2OUTC1OUTC2INVC1INVCISCM2CM1CM0
    Read/WriteRRR/WR/WR/WR/WR/WR/W
    Initial Value00001000

    C2OUT Comparator 2 Output bit
    When C2INV = 0: 1 = C2 VIN+ > C2 VIN-, 0 = C2 VIN+ < C2 VIN-
    When C2INV = 1: 1 = C2 VIN+ < C2 VIN-, 0 = C2 VIN+ > C2 VIN-
    C1OUT Comparator 1 Output bit
    When C1INV = 0: 1 = C1 VIN+ > C1 VIN-, 0 = C1 VIN+ < C1 VIN-
    When C1INV = 1: 1 = C1 VIN+ < C1 VIN-, 0 = C1 VIN+ > C1 VIN-
    C2INV Comparator 2 Output Inversion bit
    1 = C2 Output inverted
    0 = C2 Output not inverted
    C1INV Comparator 1 Output Inversion bit
    1= C1 Output inverted
    0= C1 Output not inverted
    CIS Comparator Input Switch bit
    When CM<2:0> = 001 Then:
    1= C1 VIN- connects to RA3
    0= C1 VIN- connects to RA0
    When CM<2:0> = 010 Then:
    1 = C1 VIN- connects to RA3
    C2 VIN- connects to RA2
    0 = C1 VIN- connects to RA0
    C2 VIN- connects to RA1
    CM<2:0> Comparator Mode bits
    shows the comparator modes and CM<2:0> bit settings
    Les entrées/Sorties

    Les registres d'entrées/sorties

    13 broches configurables, réparties sur deux ports : le port A et le port B
    Remarque : On ne peut affecter que deux valeurs différentes de configuration à chaque patte : un ‘1’ pour la mettre en entrée, ou un ‘0’ pour une sortie.

    Le port A possède 5 broches (nommées RA1 à RA4), mais la quatrième, également appelée TOCKI peut servir pour une éventuelle temporisation externe.

    Le port B, lui, possède 8 broches (de RB0 à RB7) ; mais la broche RB0 peut également servir comme interruption.
    La broche 4, le MCLR, sert à indiquer au PIC s’il est en fonctionnement normal (un ‘1’ logique) ou alors s’il est en cours de programmation (un ‘0’ logique).

    Cette broche sert également à un éventuel Reset du PIC.
    Ne reste que 4 broches :

    Ainsi, des 2 mA de consommation en fonctionnement normal, il peut passer à 10μA en fonction veille ou sommeil.
    Remarque : il faut cependant savoir que le PIC peut fournir jusqu’à 20 mA par sortie, soit, si tous les ports sont en sortie, un débit de 260 mA.
    Il est aisé de comprendre alors que les 2 mA sont une consommation moyenne et que celle-ci varie selon l'utilisation du PIC

    CLRF PORTA   ;Initialiser PORTA en réglant les bits en sortie
                
    MOVLW 0x07  ;Désactiver les comparateurs et
    MOVWF CMCON ;activer les broches pour les fonctions d'E/S sans inversion
    BCF STATUS, RP1 ;RP1=0
    BSF STATUS, RP0 ;RP0=1  ->BANK1
    MOVLW 0x1F  ;Valeur utilisée pour initialiser la direction des données
    MOVWF TRISA ;Définissez RA <4: 0> comme entrée TRISA <5> toujours comme «1».
                ;TRISA <7: 6> dépend du mode de l’oscillateur
    
    Les instructions
    Opérande Descriptions Nombre de cycles Registres impactés
    ADDWFf,d Somme W et f 1 C,DC,Z
    ANDWFf,d Et logique de W et f 1 Z
    CLRFf Efface f 1 Z
    CLRW  Efface W 1 Z
    COMFf,d Complément à 2 de f 1 Z
    DECFf,d Décrémente f 1 Z
    DECFSZf,d Décrémente f et saute si le résultat est 0 1 (2) 
    INCFf,d Incrémente f 1 Z
    INCFSZf,d Incrémente f et saute si le résultat est 0 1 (2) 
    IORWFf,d Ou logique entre W et f 1 Z
    MOVFf,d Placer dans f 1 
    MOVWFf,/td> Placer W dans f 1 
    NOP  Instruction vide 1 Z
    RLFf,d Rotation de bit à gauche avec injection dans la retenue 1 C
    RRFf,d Rotation de bit à droite avec injection dans la retenue 1 C
    SUBWFf,d Soustrait W de f 1 C,DC,Z
    SWAPFf,d Inversion des 4 bits haut et bas 1 
    XORWFf,d OU exclusif logique entre W et f 1 Z
         
    BCFf,d Efface un bit dans f 1 
    BSFf,d Place un bit dans f 1 
    BTFSCf,d Vérifie l'état d'un bit dans f et saute s'il est nulle 1 (2) 
    BTFSSf,d Vérifie l'état d'un bit dans f et saute s'il est 1 1 (2) 
         
    ADDLWK Ajoute une valeur littérale à W 1 C,DC,Z
    ANDLWK Et logique d'une valeur littérale avec W 1 Z
    CALLK Appelle une sous fonction 2 
    CLRWDT  Efface le chien de garde 1 TO,PD
    GOTOK Aller à l'adresse du programme 2 
    IORLWK Ou logique d'une valeur littérale et W 1 Z
    MOVLWK Placer une valeur littérale dans W 1 
    RETFIE  Retour d'une interruption 2 
    RETLWK Retourne une valeur littérale dans W 2 
    RETURN  Retour d'une sous fonction 2 
    SLEEP  Entre dans le mode stand bye, s'endort 1 TO,PD
    SUBLWK Soustrait W d'une valeur littérale 1 C,DC,Z
    XORLWK Ou exclusif logique d'une valeur littérale et W 1 Z

    La colonne de droite présente les registres ou bit de ces registres impactés par l’appel de l’instruction :

    Note : tous ces bits sont situés dans le registre de statut à l’adresse 0x03 (3 en hexadécimal)
    Exemple de programme Write to DATA EEPROM :
    BCF STATUS, RP1     
    BSF STATUS, RP0     ;RP1=0 RP0=1 ->BANK1
    BSF EECON1, WREN    ;Enable write   WREN=1 Permet les cycles d'écriture
    BCF INTCON, GIE     ;Disable INTs. GIE: Global Interrupt Enable bit, 0 = Disables all interrupts
    BTFSC INTCON,GIE    ;Vérifie l'état du bit GIE dans INTCON et saute s'il est nulle
    GOTO $-2            ;sinon recommence
    MOVLW 55h           ;
    MOVWF EECON2        ;Write 55h EECON2=0x55
    MOVLW AAh           ;
    MOVWF EECON2        ;Write AAh  EECON2=0xAA
    BSF EECON1,WR       ;Set WR bit
                        ;begin write
    BSF INTCON, GIE     ;Enable INTs.
    BCF EECON1, WREN    ;Disable write
    

    Read DATA EEPROM :
    BCF STATUS, RP1 
    BSF STATUS, RP0     ;RP1=0 RP0=1 ->BANK1
    MOVLW DATA_EE_ADDR   ;W=DATA_EE_ADDR
    MOVWF EEADR         ;Address to read
    BSF EECON1, RD      ;EE Read
    MOVF EEDATA, W      ;EEDATA=W
    BCF STATUS, RP0     ;RP1=0 RP0=0 ->BANK0
    

    Here’s a PIC ASM code that sends a character ‘A’ out of the serial port of the PIC16F877A at a baud rate of 9600 :
    INCLUDE 
     
     cblock 0x20
     char0
     COUNT1
     COUNT2
     endc 
     
    ORG 0x00
    goto init
     
    init bsf STATUS, RP0   ;bank 1
     ;---CONFIGURE SPBRG FOR DESIRED BAUD RATE
     movlw D'25'   ;baud rate =  9600bps
     movwf SPBRG   ;at 4MHZ
    ;---CONFIGURE TXSTA
     movlw B'00100100'
     movwf TXSTA
    ;Configures TXSTA as 8 bit transmission, transmit enabled, async mode, high speed baud rate
     bcf STATUS, RP0   ;bank 0
     movlw B'10000000'
     movwf RCSTA   ;enable serial port receive
     
     movlw 0x41
     movwf char0   ;put A (ascii code 0x41) character to char0 register
     
    main movf char0, W
     movwf TXREG   ;place the A character to TXREG
     goto wthere
     goto main
     
    wthere btfss TXSTA, TRMT ;check if TRMT is empty
        	goto wthere   ;if not, check again
     bcf STATUS, RP0   ;bank 0, if TRMT is empty then the character has been sent
     return
     
     end
     

    Receiving Data using Assembly
     INCLUDE 
     
    org 0x00
    goto start
     
    start bsf STATUS, RP0
          movlw .103     ;baud rate =  9600bps at 4MHZ
          movwf SPBRG   
          movlw 0x24
          movwf TXSTA
          clrf TRISB
          bcf STATUS, RP0
          movlw 0x90
          movwf RCSTA
     
    main  btfss PIR1, RCIF
          goto main
          movf RCREG, W
          movwf PORTB
          goto main
       

    PWM led
    PROCESSOR '16F876A'
    	INCLUDE 
    
    	__CONFIG _XT_OSC & _WDT_OFF & _PWRTE_OFF & _CP_OFF & _LVP_OFF & _BODEN_OFF
    
    	CBLOCK 0x20
    	D1
    	D2
    	FADE_STATE ;IF = 0x00 INCREMENT CCPR1L ELSE DECREMENT CCPR1L
    	ENDC
    	
    	ORG 0x0000
    INIT:
    	;PWM PERIOD = [(PR2)+1] * 4 * TOSC * (TMR2 PRESCALE VALUE) ;PR2 = TMR2 PERIOD REGISTER, TOSC = PIC CLOCK PERIOD (FOSC = 1 / TOSC)
    	;PWM DUTY CYCLE = (CCPR1L:CCP1CON<5:4>) * TOSC * (TMR2 PRESCALE VALUE)
    	
    	;;;SET PWM FREQUENCY;;;
    	BSF STATUS, RP0 ;SELECT BANK 01
    	MOVLW D'128'    ;SET PR2 TO 128 DECIMAL SO THE PWM PERIOD = 2064uS => PWM FREQUENCY = 484Hz
    	MOVWF PR2       ;PR2=128
    	BCF STATUS, RP0 ;SELECT BANK 00
    	
    	;;;SET PWM STARTING DUTY CYCLE;;;
    	CLRF CCPR1L
    
    	MOVLW B'00001100' ;SET PWM MODE, BITS 5 AND 4 ARE THE TWO LSBs OF THE 10BIT DUTY CYCLE REGISTER (CCPR1L:CCP1CON<5:4>)
    	MOVWF CCP1CON
    	
    	;;;SET PWM PIN TO OUTPUT MODE;;;
    	BSF STATUS, RP0     ;SELECT BANK 01
    	BCF TRISC, 2        ;SET RC2 AS OUTPUT, TO USE FOR PWM
    	BCF STATUS, RP0     ;SELECT BANK 00
    	
    	;;;SET TIMER 2 PRESCALE VALUE;;;
    	;PRESCALE = 16 SO THE PWM PERIOD = 2064uS => PWM FREQUENCY = 484Hz
    	MOVLW B'00000010'
    	MOVWF T2CON
    	
    	;;;CLEAR TIMER 2 MODULE;;;
    	CLRF TMR2
    	
    	;;;ENABLE TIMER 2 MODULE;;;
    	BSF T2CON, TMR2ON
    	
    	CLRF FADE_STATE
    	
    MAIN:
    	CALL DELAY
    	MOVLW 0x00
    	IORWF FADE_STATE, W
    	
    	BTFSS STATUS, Z ;IF FADE_STATE == 0 GOTO INC_CCPR1L
    	GOTO DEC_CCPR1L ;ELSE GOTO DEC_CCPR1L
    	
    INC_CCPR1L:
    	INCFSZ CCPR1L ;INCREMENT CCPR1L
    	GOTO MAIN
    	GOTO CHANGE_STATE_0 ;IF WE HAVE AN OVERFLOW GOTO CHANGE_STATE
    	
    DEC_CCPR1L:
    	DECFSZ CCPR1L ;DECREMENT CCPR1L
    	GOTO MAIN
    	;IF WE HAVE AN OVERFLOW GOTO CHANGE_STATE
    	
    CHANGE_STATE:
    	COMF FADE_STATE, F ;TOGLE FADE_STATE BITS
    	INCFSZ CCPR1L
    	GOTO MAIN
    	
    CHANGE_STATE_0:
    	COMF FADE_STATE, F ;TOGLE FADE_STATE BITS
    	DECFSZ CCPR1L
    	GOTO MAIN
    	
    
    DELAY
    	;9993 CYCLES
    	MOVLW	0xCE    ;               1 cy
    	MOVWF	D1      ;D1=0xCE .206   1 cy
    	MOVLW	0x08    ;               1 cy
    	MOVWF	D2      ;D2=0x08        1 cy
    DELAY_0
    	DECFSZ	D1, F   ;Décrémente D1 et saute si le résultat est 0, 1 cycle si non, 2 si oui
    	GOTO	$ + 2   ;sinon boucle   en 4 cycles 0xCE 207*5+4=1039
    	DECFSZ	D2, F   ;Décrémente D2 et saute si le résultat est 0, 1 cycle si non, 2 si oui
    	GOTO	DELAY_0 ;sinon boucle   en 2 cycles (1039+3)*9=9378
                        
    	;3 CYCLES
    	GOTO	$ + 1
    	NOP
    
    	;4 CYCLES (INCLUDING CALL)
    	RETURN
    	
    	END
    

    La pile

    Ce terme désigne les emplacements mémoire où sont empilées les adresses de retour lors des appels à des sous-programmes. La pile ne comportant que 8 niveaux, il ne faut pas imbriquer plus de 8 sous-programmes.