ON 20030326@8:26:10 PM at page: http://www.piclist.com/techref/microchip/mplab/msg302.htm JMN-EFP-786 James Newton removed post 37705.4952083333 |Delete 'm_issaka@hotmail.com asks:
I'm come from quebec , so , sorry for my english. I'm new to pic programming so i'd like to know if u can help to unmistify some of the mysteries that i have. I'm trying to build a apparel that , would count the number or person in room using a laser at the door. So i'm using a pic16f877 , to count and to send the numbre of personne to a LCD So i took a program on the net and trying to modify it , but , it's not working. Maybe my basics aren't that good. What i try to do in the program, is to se the portb as an entry and the portd as an output. So when my laser will be hide by a person , the laser' s receptor will send to the potb(rb0) an impulsion. that will be count in a variable of the program(mavariable) , and then send this to the lcd. do you think that you can lokk over my code and tell me what i'm doing wrong? it's note very long,. thank u, for your answer ;********************************************************************** ; * ; Test LCD sur un 16F877 - 20 Mhz * ; + Methode pour un printf * ; + Methode pour un affichage decimal * ; + affichage d'une conversion A/N * ; + affichage du nombre de client * ; * ; * ;********************************************************************** ; * ; Files required: rien * ; * ; * ;********************************************************************** ; * ; Notes: Quartz 20 Mhz * ; * ; * ;********************************************************************** list p=16F877 ; list directive to define processor #include ; processor specific variable definitions __CONFIG _CP_OFF & _WDT_OFF & _PWRTE_ON & _HS_OSC ; Pas de code protege, pas de watch hdog timer, delai de demarrage, horloge HS. ; Brochage du PIC sur la carte : ; ; Port | Broche | E/S | Nom | Description ; | | | | Port D affecté à la commande de LCD ; RD0 | 19 | S | RS | Sortie Broche RS du LCD ; RD1 | 20 | S | R/W | Sortie Broche Read/write du LCD ; RD2 | 21 | S | E | Sortie broche Enable du LCD ; RD3 | 22 | | | NC ; RD4 | 27 | S | DB4 | Sortie bit 4 du LCD ; RD5 | 28 | S | DB5 | Sortie bit 5 du LCD ; RD6 | 29 | S | DB6 | Sortie bit 6 du LCD ; RD7 | 30 | S | DB7 | Sortie bit 7 du LCD ;********************************************************************** ; * ; I/O Defines * ; * ; * ;********************************************************************** ENTREE_DATA_PORT EQU PORTB ; le port des recepteurs ENTREE_DATA_TRIS EQU TRISD ; la config du port des recepteurs LCD_DATA_PORT EQU PORTD ; le port du LCD LCD_DATA_TRIS EQU TRISD ; la config du port du LCD LCD_RS EQU 0 ; Sortie Broche RS du LCD LCD_RS_VALUE EQU 1 ;correspond a 1 en decimal LCD_RW EQU 1 ; Sortie Broche Read/write du LCD LCD_E EQU 2 ; Sortie broche Enable du LCD ;********************************************************************** ; * ; autres Defines * ; * ; * ;********************************************************************** ;***** Ram Init DebutRamInit EQU 0x20 ; Debut de la RAM pour initialisation FinRamInit EQU 0x7F ; FIN de la RAM pour initialisation ;***** LCD Config LCD_SET_MATRIX EQU 0 ; 1 -> Matrices de 5*11, 0 -> Matrices de 5*8 (defaut 0) LCD_SET_DISPLAY EQU 1 ; 1 -> Display LCD On, 0 -> Display LCD Off (defaut 1) LCD_SET_CURSOR EQU 1 ; 1 -> Cursor On, 0 -> Cursor Off (defaut 1) LCD_SET_BLINK EQU 0 ; 1 -> blink character at cursor position On, 0 -> Off (defaut 0) LCD_SET_DIRECT EQU 1 ; 1 -> to the right, 0 -> to the left (defaut 1) LCD_SET_SCROLL EQU 0 ; 1 -> Scroll display, 0 -> do not scroll (defaut 0) ;********************************************************************** ; * ; Variables * ; * ; * ;********************************************************************** ;***** Variable de temporisation tempo50µ EQU 0x20 ; Variable tempo 50 µs tempo10ms EQU 0x21 ; Variable tempo 10 ms tempo1s EQU 0x22 ; Variable tempo 1s ;***** LCD Var LCD_TEMP EQU 0x23 ; Variable temporaire pour le LCD LCD_CHAR EQU 0x24 ; Variable temporaire pour les caracteres du LCD LCD_CHAR_HEXA EQU 0x25 ; Variable temporaire pour les nombres hexadecimaux du LCD LCD_CMP_PRINTF EQU 0x26 ; Compteur pour le printf ;***** variable de nombre de personne****** mavariable EQU 0x27 lasercoupe equ 1 ;**************************************************************** DEBUT ORG 0x000 ; processor reset vector GOTO main ; go to beginning of program ;********************************************************************** ; * ; Interruption Timer * ; * ; * ;********************************************************************** ORG 0x004 ; interrupt vector location ; Ici on s'en sert pas ! RETFIE ; return from interrupt ;********************************************************************** ; * ; Programme Main * ; * ; * ;********************************************************************** main ;***** initialisations CALL InitRAM ; on intialise toute la RAM CALL InitIO ; On intialise les ports d'E/S CALL LCD_INIT ; Affichage de Fribotte ; ancienne methode ... toujours utilisable ! ; MOVLW "N" ; CALL LCD_SEND_CHAR ; MOVLW "O" ; CALL LCD_SEND_CHAR ; MOVLW "M" ; CALL LCD_SEND_CHAR ; MOVLW "B" ; CALL LCD_SEND_CHAR ; MOVLW "R" ; CALL LCD_SEND_CHAR ; MOVLW "E" ; CALL LCD_SEND_CHAR ; affichage de Nombre CALL LCD_LOCATE_LINE0 MOVLW Printf_Nombre CALL LCD_PRINTF CALL LCD_PRINT_SPACE ; CALL LCD_LOCATE_LINE1 ; affichage du nombre de client ; a faire ici. valeur par defaut zero MOVLW "0" CALL LCD_SEND_CHAR ; pause de 1 s CALL Wait1s CALL LCD_CLEAR CLRW MOVF mavariable,W; verifie si c pas les addresses que tu verifies. BoucleAttenteDePassage btfsc PORTB,lasercoupe ; saute l'instruction suivante si laser coupé b $-1 ; saut à l'instruction précédente incf mavariable , f btfss PORTB,lasercoupe ; saute l'instruction suivante si laser relaché b $-1 ; saut à l'instruction précédente CALL LCD_LOCATE_LINE0 MOVLW Printf_Nombre CALL LCD_PRINTF CALL LCD_PRINT_SPACE ; CALL LCD_LOCATE_LINE1 ; affichage du nombre de client ; a faire ici. valeur par defaut zero MOVLW mavariable CALL LCD_SEND_CHAR CALL LCD_CLEAR GOTO BoucleAttenteDePassage ; boucle *****va-t-elle pas bloquer l'execution du reste?** ;********************************************************************** ; * ; Conversion A/N * ; * ; * ;********************************************************************** ConversionAN ; initialisation faut-il un ******* return **********? BSF STATUS, RP0 ; Bank 1 selectonnee MOVLW b'00001110' ; select RA0 MOVWF ADCON1 ; as analog inputs BCF STATUS, RP0 ; Bank 0 selectonnee MOVLW b'10000001' ; Select; RC osc, Ch2 MOVWF ADCON0 ; turn on A/D Convert CALL Wait100µs ; provide necessary samplig time BSF ADCON0, 2 ; Start new A/D conversion loop BTFSC ADCON0, 2 ; A/D over ? GOTO loop ; no then loop CALL LCD_LOCATE_LINE0 MOVF ADRESH, W CALL LCD_SEND_DECI ; print high bit of the result CALL LCD_PRINT_SPACE CALL LCD_PRINT_SPACE BSF STATUS, RP0 ; Bank 1 selectonnee MOVF ADRESL, W BCF STATUS, RP0 ; Bank 0 selectonnee CALL LCD_SEND_DECI ; print low bit of the result GOTO Convert ; boucle ;********************************************************************** ; * ; Les pauses a 20Mhz * ; * ; * ;********************************************************************** ;***** Attente de 1 s (exactement 1.00204 s) Wait1s MOVLW D'99' ; 99 fois MOVWF tempo1s ; stockage dans la variable tempo1s T1sboucle CALL Wait10ms DECFSZ tempo1s,1 ; décremente et test GOTO T1sboucle ; on boucle tant que <>0 RETURN ;***** Attente de 15 ms (exactement 14.99 ms) Wait15ms MOVLW D'149' ; 149 fois MOVWF tempo10ms ; stockage dans la variable tempo10ms T15msboucle CALL Wait100µs DECFSZ tempo10ms,1 ; décremente et test GOTO T15msboucle ; on boucle tant que <>0 RETURN ;***** Attente de 10 ms (exactement 10.02 ms) Wait10ms MOVLW D'198' ; 198 fois MOVWF tempo10ms ; stockage dans la variable tempo10ms T10msboucle CALL Wait50µs DECFSZ tempo10ms,1 ; décremente et test GOTO T10msboucle ; on boucle tant que <>0 RETURN ;***** Attente de 1.5 ms (exactement ? ms) Wait1.5ms MOVLW D'29' ; 29 fois MOVWF tempo10ms ; stockage dans la variable tempo10ms T1.5msboucle CALL Wait50µs DECFSZ tempo10ms,1 ; décremente et test GOTO T1.5msboucle ; on boucle tant que <>0 RETURN ;***** Attente de 100 µs (exactement, en comptant le temps d'appel) Wait100µs MOVLW D'165' ; 165 fois MOVWF tempo50µ ; stockage dans la variable tempo50µ T100µsboucle DECFSZ tempo50µ,1 ; décremente et test GOTO T100µsboucle ; on boucle tant que <>0 0.2*3=0.6 µs en tout RETURN ;***** Attente de 50 µs (exactement, en comptant le temps d'appel) Wait50µs NOP NOP MOVLW D'81' ; 81 fois MOVWF tempo50µ ; stockage dans la variable tempo50µ T50µsboucle DECFSZ tempo50µ,1 ; décremente et test GOTO T50µsboucle ; on boucle tant que <>0 0.2*3=0.6 µs en tout RETURN ;***** Attente de 1 µs (exactement, en comptant le temps d'appel) Wait1µs NOP RETURN ;********************************************************************** ; * ; Programmes de gestion de l'afficheur LCD * ; * ; * ;********************************************************************** LCD_INIT CLRF LCD_DATA_PORT ; effacement du LCD_DATA_PORT ; Selectionne le LCD_DATA_PORT en sortie BSF STATUS, RP0 ; Bank 1 selectonnee CLRF LCD_DATA_TRIS ; Port en sortie BCF STATUS, RP0 ; Bank 0 selectonnee CALL Wait15ms ; attente de 15ms pour que le LCD boote ; system set (premier) MOVLW B'00110000' ; Demande du mode 4 bit CALL LCD_SEND CALL LCD_SEND CALL LCD_SEND MOVLW B'00100000' ; Demande du mode 4 bit CALL LCD_SEND ; System set (deuxieme) + reglage de la taille des matrices MOVLW B'00100000' CALL LCD_SEND MOVLW B'10000000' + LCD_SET_MATRIX * B'01000000' CALL LCD_SEND ; Set ON/OFF MOVLW B'00000000' CALL LCD_SEND ; Display off, cursor off, blink off MOVLW B'10000000' + LCD_SET_DISPLAY * B'01000000' + LCD_SET_CURSOR * B'00100000' + LCD_SET_BLINK * B'00010000' CALL LCD_SEND CALL LCD_CLEAR ; Clear screen ; Set entry mode MOVLW B'00000000' CALL LCD_SEND ; Increment cursor to the right. when writing, don't shift screen MOVLW B'01000000' + LCD_SET_DIRECT * B'00100000' + LCD_SET_SCROLL * B'00010000' CALL LCD_SEND RETURN ; Envois d'une donnee sur le LCD. Passee en parametre dans W LCD_SEND_NO_WAIT MOVWF LCD_TEMP ; On met W sans LCD_TEMP MOVF LCD_TEMP, W ; mise sur le port D de la donnee MOVWF LCD_DATA_PORT ; / NOP BSF LCD_DATA_PORT,LCD_E ; mise à 1 de E (validation) NOP NOP NOP ; delai de 450 ns a respecter ... BCF LCD_DATA_PORT,LCD_E ; mise à 0 de E RETURN ; Envois d'une donnee sur le LCD. Passee en parametre dans W ; Attente de 40 µs mini ensuite LCD_SEND CALL LCD_SEND_NO_WAIT CALL Wait50µs ; on attends plus de 40us (prise en compte de la commande, et attente de la fin de celle-ci) RETURN ; Envois d'un caractere ASCII sur le LCD. Passe en parametre dans W LCD_SEND_CHAR MOVWF LCD_CHAR ; On met W sans LCD_CHAR ANDLW 0xF0 ; masquage des bit de poids faible ADDLW LCD_RS_VALUE ; on y ajoute LCD_RS_VALUE CALL LCD_SEND_NO_WAIT ; on envoit a l'afficheur SWAPF LCD_CHAR, W ; passage des bits de poids faibles en poids fort ANDLW 0xF0 ; masquage des bit de poids faible ADDLW LCD_RS_VALUE ; on y ajoute LCD_RS_VALUE CALL LCD_SEND ; on envoit a l'afficheur ; fini RETURN ; Envois d'un nombre sur le LCD, ecrit en hexa. Passe en parametre dans W LCD_SEND_HEXA SWAPF LCD_CHAR_HEXA, W ; On met W sans LCD_CHAR_HEXA, ; passage des bits de poids faibles en poids fort ANDLW 0xF0 ; masquage des bit de poids faible ADDLW 6 ; on y ajoute 6 MOVWF LCD_TEMP ; On met W sans LCD_TEMP BTFSC LCD_TEMP, 4 ; si le bit 3 est a 1 ADDLW "A"-"9"-1 ; on ajoute le code ascii de A moins celui de 0 ADDLW "0" - 6 ; on ajoute le code ascii de 0, moins les 5 ; on a maintenant le code ascii dans W CALL LCD_SEND_CHAR ; qu'on affiche ... MOVF LCD_CHAR_HEXA, W ; on remet LCD_CHAR_HEXA dans W ANDLW 0x0F ; masquage des bit de poids forts ADDLW 6 ; on y ajoute 6 MOVWF LCD_TEMP ; On met W sans LCD_TEMP BTFSC LCD_TEMP, 4 ; si le bit 3 est a 1 ADDLW "A"-"9"-1 ; on ajoute le code ascii de A moins celui de 0 ADDLW "0" - 6 ; on ajoute le code ascii de 0, moins les 6 ; on a maintenant le code ascii dans W CALL LCD_SEND_CHAR ; qu'on affiche ... RETURN ; ; Envois d'un octet sur le LCD, ecrit en decimal toujours sur 3 chiffres. Passe en parametre dans W ; LCD_SEND_DECI MOVWF LCD_CHAR_HEXA ; On met W sans LCD_CHAR_HEXA, ; Calcul des centaines MOVLW "0" ; On met le code ascii de 0 dans LCD_CHAR MOVWF LCD_CHAR ; " LCD_SEND_DECIMAL_100 MOVF LCD_CHAR_HEXA, W ADDLW -D'100' BTFSS STATUS, C GOTO $ + 4 INCF LCD_CHAR, F MOVWF LCD_CHAR_HEXA GOTO LCD_SEND_DECIMAL_100 ; Affiche les centaines MOVF LCD_CHAR, W CALL LCD_SEND_CHAR ; Calcul des dixaines MOVLW "0" ; On met le code ascii de 0 dans LCD_CHAR MOVWF LCD_CHAR ; " LCD_SEND_DECIMAL_10 MOVF LCD_CHAR_HEXA, W ADDLW -D'10' BTFSS STATUS, C GOTO $ + 4 INCF LCD_CHAR, F MOVWF LCD_CHAR_HEXA GOTO LCD_SEND_DECIMAL_10 ; Affiche les dixaines MOVF LCD_CHAR, W CALL LCD_SEND_CHAR MOVLW "0" ; On met le code ascii de 0 dans LCD_CHAR MOVWF LCD_CHAR ; " ; Calcul des unitees LCD_SEND_DECIMAL_1 MOVF LCD_CHAR_HEXA, W ADDLW -D'1' BTFSS STATUS, C GOTO $ + 4 INCF LCD_CHAR, F MOVWF LCD_CHAR_HEXA GOTO LCD_SEND_DECIMAL_1 ; Affiche les unitees MOVF LCD_CHAR, W CALL LCD_SEND_CHAR ; Fini ! RETURN ; ; Envois d'un octet sur le LCD, ecrit en binaire toujours sur 8 0 ou 1. Passe en parametre dans W ; LCD_SEND_BIN MOVWF LCD_CHAR_HEXA ; On met W sans LCD_CHAR_HEXA, ; generation de code automatique avec MPLAB VARIABLE I I = D'7' while I >= 0 MOVLW "0" ; On met le code ascii de 0 dans W BTFSC LCD_CHAR_HEXA, I ; si le bit I est a 1; MOVLW "1" ; On met le code ascii de 1 dans W CALL LCD_SEND_CHAR I-- endW RETURN ; Efface l'ecran LCD LCD_CLEAR MOVLW 0 CALL LCD_SEND_NO_WAIT MOVLW D'16' CALL LCD_SEND ; envoit de la commande pour effacer CALL Wait1.5ms ; on attends plus de 1.64 ms CALL Wait100µs CALL Wait100µs RETURN ; Scroll de l'ecran LCD LCD_SCROLL MOVLW D'16' CALL LCD_SEND_NO_WAIT MOVLW D'128' CALL LCD_SEND ; envoit de la commande pour le scroll RETURN ; LOCATE de l'ecran LCD, avec la position dans W. 64 positions par lignes ; 0 debut de la premiere ligne ; 64 debut de la deuxieme ligne LCD_LOCATE MOVWF LCD_CHAR ; On met W sans LCD_CHAR ANDLW 0xF0 ; masquage des bit de poids faible ADDLW D'128' ; on y ajoute 128 CALL LCD_SEND_NO_WAIT ; on envoit a l'afficheur SWAPF LCD_CHAR, W ; On remet LCD_CHAR dans W ; passage des bits de poids faibles en poids fort ANDLW 0xF0 ; masquage des bit de poids faible CALL LCD_SEND ; on envoit a l'afficheur ; fini RETURN ; Place le curseur en debut de la 1ere ligne LCD_LOCATE_LINE0 MOVLW D'0' CALL LCD_LOCATE RETURN ; Place le curseur en debut de la 2eme ligne LCD_LOCATE_LINE1 MOVLW D'64' CALL LCD_LOCATE RETURN ; Place le curseur en debut de la 3eme ligne LCD_LOCATE_LINE2 MOVLW D'20' CALL LCD_LOCATE RETURN ; Place le curseur en debut de la 4eme ligne LCD_LOCATE_LINE3 MOVLW D'84' CALL LCD_LOCATE RETURN ; affiche un espace LCD_PRINT_SPACE MOVLW " " CALL LCD_SEND_CHAR RETURN ;********************************************************************** ; ; Fonction Printf %s ; avec en parametre W le numero du printf a afficher (defini par des EQU) ; Definitions des printfs en fin de programmes ; ;********************************************************************** LCD_PRINTF MOVWF LCD_CMP_PRINTF ; on met W dans LCD_AFF_PRINTF qui contient le printf a afficher ; initialisation de EEADRH et de EEADR BSF STATUS, RP1 BCF STATUS, RP0 ; Bank 2 MOVLW High Printf_START MOVWF EEADRH ; MSBytes of Program address to read MOVLW Low Printf_START MOVWF EEADR ; LSByte of program address to read LCD_PRINTF_boucle BSF STATUS, RP0 ; BSF STATUS, RP1 ; Bank 3 BSF EECON1, EEPGD ; Point to PROGRAM memory BSF EECON1, RD ; EEPROM read NOP NOP ; Memory is read in the next 2 cycles BCF STATUS, RP0 ; bank 2 MOVF EEDATA, W ; W = LSByte of Program EEDATA ; MOVF EEDATH, W ; W = MSByte of Program EEDATA -> pas utile ici BCF STATUS, RP1 BCF STATUS, RP0 ; Bank 0 BTFSC STATUS, Z ; Si W = 0 va en LCD_PRINTF_Null GOTO LCD_PRINTF_Null DECFSZ LCD_CMP_PRINTF, F ; on decremente LCD_CMP_PRINTF GOTO LCD_PRINTF_Next_add ; si il est different de 0, donc de 1 avant decrementation, on va en LCD_PRINTF_Next_add ; sinon il faut afficher le caractere qui est toujours dans W CALL LCD_SEND_CHAR GOTO LCD_PRINTF_Next_add LCD_PRINTF_Null DECFSZ LCD_CMP_PRINTF, F GOTO LCD_PRINTF_Next RETURN LCD_PRINTF_Next_add INCF LCD_CMP_PRINTF, F ; on reajoute 1 a LCD_CMP_PRINTF LCD_PRINTF_Next BSF STATUS, RP1 BCF STATUS, RP0 ; Bank 2 INCF EEADR, F ; ajoute 1 a l'adresse de lecture BTFSC STATUS, Z INCF EEADRH, F ; si = 0, on ajoute 1 au poid fort MOVLW High Printf_STOP SUBWF EEADRH,W BTFSS STATUS, Z GOTO LCD_PRINTF_Next2 ; si EEADRH != High Printf_STOP on continue MOVLW low Printf_STOP SUBWF EEADR,W BTFSS STATUS, Z GOTO LCD_PRINTF_Next2 ; si EEADR != low Printf_STOP on continue ; Fin du printf BCF STATUS, RP1 BCF STATUS, RP0 ; Bank 0 RETURN LCD_PRINTF_Next2 BCF STATUS, RP1 BCF STATUS, RP0 ; Bank 0 GOTO LCD_PRINTF_boucle ;********************************************************************** ; * ; Initialisation de l'ensemble de la RAM * ; * ; * ;********************************************************************** InitRAM MOVLW DebutRamInit ; De DebutRamInit MOVWF FSR ; Pointeur dans la RAM Boucle0Ram CLRF INDF ; Efface la zone pointee INCF FSR,F ; incremente le pointer MOVF FSR,W ; on compare FSR a FinRamInit SUBLW FinRamInit BTFSC STATUS,C GOTO Boucle0Ram ; Jusqu'a ce que FinRamInit RETURN ;********************************************************************** ; * ; Initialisation des ports d'E/S * ; * ; * ;********************************************************************** InitIO CLRF PORTD ; Initialise le port D CLRF PORTB ; Initialise le port B BSF STATUS, RP0 ; Bank 1 selectonnee MOVLW 0x0 ; Port RD7-RD0 en sortie MOVWF TRISD ; / MOVLW B'00000001' ; MOVWF TRISB ; seul rb0 en entree BCF STATUS, RP0 ; Bank 0 selectonnee RETURN ;********************************************************************** ; ; Les printf definis (1 mot par caractere). ; Places à la fin du programme ; ;********************************************************************** Printf_START VARIABLE PRINTF_CMP = 1 ; Variable MPLAB (pas d'existence en assembleur) pour trouver le bon printf. Printf_Nombre EQU PRINTF_CMP PRINTF_CMP++ DT "Nombre",0 Printf_STOP ;********************************************************************** ; * ; Fin * ; * ; * ;********************************************************************** END ; directive 'end of program'
' ON 20030326@8:27:22 PM at page: http://www.piclist.com/techref/microchip/mplab/msg302.htm JMN-EFP-786 James Newton removed post 37705.4970717593 |Delete 'm_issaka@hotmail.com shares this code:
;**********************************************************************
;   								      *
;	Test LCD sur un 16F877 - 20 Mhz				      *
;	+ Methode pour un printf				      *
;	+ Methode pour un affichage decimal			      *
;	+ affichage d'une conversion A/N			      *
;   + affichage du nombre de  client                                                      *
;								      *
;							              *

;**********************************************************************
;                                                                     *
;    Files required: rien                                             *
;                                                                     *
;                                                                     *
;**********************************************************************
;                                                                     *
;    Notes: Quartz 20 Mhz                                             *
;                                                                     *
;                                                                     *
;**********************************************************************


	list      p=16F877             ; list directive to define processor
	#include <p16F877.inc>         ; processor specific variable definitions

	__CONFIG   _CP_OFF & _WDT_OFF & _PWRTE_ON & _HS_OSC
; Pas de code protege, pas de watch hdog timer, delai de demarrage, horloge HS.


;  Brochage du PIC sur la carte :
;
;  Port | Broche | E/S | Nom             | Description
;       |        |     |                 | Port D affecté à la commande de LCD
;  RD0  |    19  |  S  | RS		 | Sortie Broche RS du LCD 
;  RD1  |    20  |  S  | R/W		 | Sortie Broche Read/write du LCD
;  RD2  |    21  |  S  | E		 | Sortie broche Enable du LCD
;  RD3  |    22  |     |                 | NC
;  RD4  |    27  |  S  | DB4 		 | Sortie bit 4 du LCD
;  RD5  |    28  |  S  | DB5             | Sortie bit 5 du LCD
;  RD6  |    29  |  S  | DB6  		 | Sortie bit 6 du LCD
;  RD7  |    30  |  S  | DB7		 | Sortie bit 7 du LCD


;**********************************************************************
;                                                                     *
;   I/O	Defines	                                                      *
;                                                                     *
;                                                                     *
;**********************************************************************


ENTREE_DATA_PORT EQU PORTB      ; le port des recepteurs
ENTREE_DATA_TRIS	EQU	TRISD	; la config du port des recepteurs



LCD_DATA_PORT	EQU	PORTD		; le port du LCD
LCD_DATA_TRIS	EQU	TRISD		; la config du port du LCD

LCD_RS		EQU	0		; Sortie Broche RS du LCD 
LCD_RS_VALUE	EQU	1	;correspond a 1 en decimal
LCD_RW		EQU	1		; Sortie Broche Read/write du LCD
LCD_E		EQU	2		; Sortie broche Enable du LCD


;**********************************************************************
;                                                                     *
;   autres Defines	                                              *
;                                                                     *
;                                                                     *
;**********************************************************************


;***** Ram Init
DebutRamInit	EQU	0x20		; Debut de la RAM pour initialisation
FinRamInit	EQU	0x7F		; FIN de la RAM pour initialisation

;***** LCD Config
LCD_SET_MATRIX	EQU	0		; 1 -> Matrices de 5*11, 0 -> Matrices de 5*8 (defaut 0)
LCD_SET_DISPLAY	EQU	1		; 1 -> Display LCD On, 0 -> Display LCD Off (defaut 1)
LCD_SET_CURSOR	EQU	1		; 1 -> Cursor On, 0 -> Cursor Off (defaut 1)
LCD_SET_BLINK	EQU	0		; 1 -> blink character at cursor position On, 0 -> Off (defaut 0)
LCD_SET_DIRECT	EQU	1		; 1 -> to the right, 0 -> to the left (defaut 1)
LCD_SET_SCROLL	EQU	0		; 1 -> Scroll display, 0 -> do not scroll (defaut 0)

					



;**********************************************************************
;                                                                     *
;    Variables                                                        *
;                                                                     *
;                                                                     *
;**********************************************************************

;***** Variable de temporisation
tempo50µ	EQU	0x20		; Variable tempo 50 µs
tempo10ms	EQU	0x21		; Variable tempo 10 ms
tempo1s		EQU	0x22		; Variable tempo 1s

;***** LCD Var
LCD_TEMP	    EQU	0x23		; Variable temporaire pour le LCD
LCD_CHAR	    EQU	0x24		; Variable temporaire pour les caracteres du LCD
LCD_CHAR_HEXA	EQU	0x25		; Variable temporaire pour les nombres hexadecimaux du LCD
LCD_CMP_PRINTF	EQU	0x26		; Compteur pour le printf

;***** variable de nombre de personne******
mavariable      EQU 0x27
lasercoupe      equ 1

;**************************************************************** DEBUT
		ORG     0x000           ; processor reset vector
  		GOTO    main            ; go to beginning of program


;**********************************************************************
;                                                                     *
;    Interruption Timer                                               *
;                                                                     *
;                                                                     *
;**********************************************************************

		ORG     0x004           ; interrupt vector location
					; Ici on s'en sert pas !
		RETFIE                  ; return from interrupt



;**********************************************************************
;                                                                     *
;    Programme Main                                                   *
;                                                                     *
;                                                                     *
;**********************************************************************


main


;***** initialisations
		CALL	InitRAM		; on intialise toute la RAM
		CALL	InitIO		; On intialise les ports d'E/S

		CALL	LCD_INIT

		; Affichage de Fribotte

; 	ancienne methode ... toujours utilisable !
;		MOVLW	"N"		
;		CALL	LCD_SEND_CHAR	
;		MOVLW	"O"		
;		CALL	LCD_SEND_CHAR	
;		MOVLW	"M"		
;		CALL	LCD_SEND_CHAR	
;		MOVLW	"B"		
;		CALL	LCD_SEND_CHAR	
;		MOVLW	"R"		
;		CALL	LCD_SEND_CHAR	
;		MOVLW	"E"		
;		CALL	LCD_SEND_CHAR	


		; affichage de Nombre

		CALL LCD_LOCATE_LINE0

		MOVLW	Printf_Nombre
		CALL	LCD_PRINTF
		CALL	LCD_PRINT_SPACE


;		CALL LCD_LOCATE_LINE1

		; affichage du nombre de client
;         a faire ici. valeur par defaut zero
		MOVLW	"0"		
		CALL	LCD_SEND_CHAR




		; pause de 1 s
		CALL	Wait1s
		CALL	LCD_CLEAR

		CLRW
        MOVF mavariable,W; verifie si c pas les addresses que tu verifies.

BoucleAttenteDePassage
     
        btfsc	PORTB,lasercoupe	; saute l'instruction suivante si laser coupé
       	b	$-1		; saut à l'instruction précédente
		incf mavariable , f 
		btfss	PORTB,lasercoupe	; saute l'instruction suivante si laser relaché
		b	$-1		; saut à l'instruction précédente
		CALL LCD_LOCATE_LINE0

		MOVLW	Printf_Nombre
		CALL	LCD_PRINTF
		CALL	LCD_PRINT_SPACE


;		CALL LCD_LOCATE_LINE1

		; affichage du nombre de client
;         a faire ici. valeur par defaut zero
		MOVLW	mavariable
		CALL	LCD_SEND_CHAR



		CALL	LCD_CLEAR
	GOTO	BoucleAttenteDePassage			; boucle  *****va-t-elle pas bloquer l'execution du reste?**

	


;**********************************************************************
;                                                                     *
;    Conversion A/N			                  	      *
;                                                                     *
;                                                                     *
;**********************************************************************

ConversionAN
  
	; initialisation faut-il un ******* return **********?

		BSF	STATUS, RP0	; Bank 1 selectonnee
		MOVLW	b'00001110'	; select RA0
		MOVWF	ADCON1		; as analog inputs
		BCF	STATUS, RP0	; Bank 0 selectonnee

		MOVLW	b'10000001'	; Select; RC osc, Ch2
		MOVWF	ADCON0		; turn on A/D

Convert		CALL	Wait100µs	; provide necessary samplig time

		BSF	ADCON0, 2	; Start new A/D conversion
	
loop
		BTFSC	ADCON0, 2	; A/D over ?
		GOTO	loop		; no then loop

		CALL 	LCD_LOCATE_LINE0

		MOVF	ADRESH, W
		CALL	LCD_SEND_DECI	; print high bit of the result

		CALL	LCD_PRINT_SPACE
		CALL	LCD_PRINT_SPACE

		BSF	STATUS, RP0	; Bank 1 selectonnee
		MOVF	ADRESL, W
		BCF	STATUS, RP0	; Bank 0 selectonnee
		CALL	LCD_SEND_DECI	; print low bit of the result

	GOTO	Convert			; boucle



;**********************************************************************
;                                                                     *
;    Les pauses a 20Mhz			                  	      *
;                                                                     *
;                                                                     *
;**********************************************************************


;***** Attente de 1 s (exactement 1.00204 s)
Wait1s
		MOVLW	D'99'		;	99 fois
		MOVWF	tempo1s		; stockage dans la variable tempo1s
T1sboucle	CALL	Wait10ms
		DECFSZ	tempo1s,1	; décremente et test
		GOTO	T1sboucle	; on boucle tant que <>0  
		RETURN

;***** Attente de 15 ms (exactement 14.99 ms)
Wait15ms
		MOVLW	D'149'		;	149 fois
		MOVWF	tempo10ms	; stockage dans la variable tempo10ms
T15msboucle	CALL	Wait100µs
		DECFSZ	tempo10ms,1	; décremente et test
		GOTO	T15msboucle	; on boucle tant que <>0
		RETURN


;***** Attente de 10 ms (exactement 10.02 ms)
Wait10ms
		MOVLW	D'198'		;	198 fois
		MOVWF	tempo10ms	; stockage dans la variable tempo10ms
T10msboucle	CALL	Wait50µs
		DECFSZ	tempo10ms,1	; décremente et test
		GOTO	T10msboucle	; on boucle tant que <>0
		RETURN

;***** Attente de 1.5 ms (exactement ? ms)
Wait1.5ms
		MOVLW	D'29'		;	29 fois
		MOVWF	tempo10ms	; stockage dans la variable tempo10ms
T1.5msboucle	CALL	Wait50µs
		DECFSZ	tempo10ms,1	; décremente et test
		GOTO	T1.5msboucle	; on boucle tant que <>0
		RETURN

;***** Attente de 100 µs (exactement, en comptant le temps d'appel)
Wait100µs	
		MOVLW	D'165'		;	165 fois
		MOVWF	tempo50µ	; stockage dans la variable tempo50µ
T100µsboucle	DECFSZ	tempo50µ,1	; décremente et test
		GOTO	T100µsboucle	; on boucle tant que <>0  0.2*3=0.6 µs en tout
		RETURN


;***** Attente de 50 µs (exactement, en comptant le temps d'appel)
Wait50µs	NOP
		NOP
		MOVLW	D'81'		;	81 fois
		MOVWF	tempo50µ	; stockage dans la variable tempo50µ
T50µsboucle	DECFSZ	tempo50µ,1	; décremente et test
		GOTO	T50µsboucle	; on boucle tant que <>0  0.2*3=0.6 µs en tout
		RETURN


;***** Attente de 1 µs (exactement, en comptant le temps d'appel)
Wait1µs		NOP
		RETURN


;**********************************************************************
;                                                                     *
;    Programmes de gestion de l'afficheur LCD                  	      *
;                                                                     *
;                                                                     *
;**********************************************************************

LCD_INIT
	CLRF	LCD_DATA_PORT	; effacement du LCD_DATA_PORT

	; Selectionne le LCD_DATA_PORT en sortie

	BSF	STATUS, RP0	; Bank 1 selectonnee
	CLRF	LCD_DATA_TRIS	; Port en sortie
	BCF 	STATUS,	RP0	; Bank 0 selectonnee

	CALL	Wait15ms	; attente de 15ms pour que le LCD boote

	; system set (premier)

	MOVLW	B'00110000'	; Demande du mode 4 bit
	CALL	LCD_SEND
	CALL	LCD_SEND
	CALL	LCD_SEND
	MOVLW	B'00100000'	; Demande du mode 4 bit
	CALL	LCD_SEND	

	; System set (deuxieme) + reglage de la taille des matrices
	MOVLW	B'00100000'
	CALL	LCD_SEND
	MOVLW	B'10000000' + LCD_SET_MATRIX * B'01000000'
	CALL 	LCD_SEND
			
	; Set ON/OFF
	MOVLW	B'00000000'
	CALL 	LCD_SEND
	; Display off, cursor off, blink off
	MOVLW	B'10000000' + LCD_SET_DISPLAY * B'01000000' + LCD_SET_CURSOR * B'00100000' + LCD_SET_BLINK * B'00010000'
	CALL 	LCD_SEND

	CALL 	LCD_CLEAR	; Clear screen	

	; Set entry mode
	MOVLW	B'00000000'
	CALL 	LCD_SEND
	; Increment cursor to the right. when writing, don't shift screen
	MOVLW	B'01000000' + LCD_SET_DIRECT * B'00100000' + LCD_SET_SCROLL * B'00010000'
	CALL 	LCD_SEND

	RETURN


;	Envois d'une donnee sur le LCD. Passee en parametre dans W
LCD_SEND_NO_WAIT
	MOVWF	LCD_TEMP		; On met W sans LCD_TEMP

	MOVF	LCD_TEMP, W		; mise sur le port D de la donnee
	MOVWF	LCD_DATA_PORT		;	/
	NOP
	BSF	LCD_DATA_PORT,LCD_E	; mise à 1 de E (validation)
	NOP
	NOP
	NOP				; delai de 450 ns a respecter ...
	BCF	LCD_DATA_PORT,LCD_E	; mise à 0 de E

	RETURN

;	Envois d'une donnee sur le LCD. Passee en parametre dans W
;	Attente de 40 µs mini ensuite
LCD_SEND

	CALL	LCD_SEND_NO_WAIT

	CALL	Wait50µs		; on attends plus de 40us (prise en compte de la commande, et attente de la fin de celle-ci)

	RETURN


;	Envois d'un caractere ASCII sur le LCD. Passe en parametre dans W
LCD_SEND_CHAR
	MOVWF	LCD_CHAR		; On met W sans LCD_CHAR

	ANDLW	0xF0			; masquage des bit de poids faible
	ADDLW	LCD_RS_VALUE		; on y ajoute LCD_RS_VALUE
	CALL	LCD_SEND_NO_WAIT	; on envoit a l'afficheur


	SWAPF	LCD_CHAR, W			; passage des bits de poids faibles en poids fort
	ANDLW	0xF0			; masquage des bit de poids faible
	ADDLW	LCD_RS_VALUE		; on y ajoute LCD_RS_VALUE			

	CALL	LCD_SEND		; on envoit a l'afficheur
	
	; fini

	RETURN


;	Envois d'un nombre sur le LCD, ecrit en hexa. Passe en parametre dans W
LCD_SEND_HEXA

	SWAPF	LCD_CHAR_HEXA, W	; On met W sans LCD_CHAR_HEXA, 
					; passage des bits de poids faibles en poids fort
	ANDLW	0xF0			; masquage des bit de poids faible
	
	ADDLW	6			; on y ajoute 6
	MOVWF	LCD_TEMP		; On met W sans LCD_TEMP
	BTFSC	LCD_TEMP, 4			; si le bit 3 est a 1
	ADDLW	"A"-"9"-1		; on ajoute le code ascii de A moins celui de 0
	ADDLW	"0" - 6 		; on ajoute le code ascii de 0, moins les 5
					; 	on a maintenant le code ascii dans W
	CALL	LCD_SEND_CHAR		; qu'on affiche ...

	MOVF	LCD_CHAR_HEXA, W	; on remet LCD_CHAR_HEXA dans W
	ANDLW	0x0F			; masquage des bit de poids forts
	ADDLW	6			; on y ajoute 6
	MOVWF	LCD_TEMP		; On met W sans LCD_TEMP
	BTFSC	LCD_TEMP, 4			; si le bit 3 est a 1
	ADDLW	"A"-"9"-1		; on ajoute le code ascii de A moins celui de 0
	ADDLW	"0" - 6 		; on ajoute le code ascii de 0, moins les 6
					; 	on a maintenant le code ascii dans W
	CALL	LCD_SEND_CHAR		; qu'on affiche ...
	
	RETURN	

;
;	Envois d'un octet sur le LCD, ecrit en decimal toujours sur 3 chiffres. Passe en parametre dans W
;
LCD_SEND_DECI

	MOVWF	LCD_CHAR_HEXA		; On met W sans LCD_CHAR_HEXA, 

	; Calcul des centaines

	MOVLW	"0"			; On met le code ascii de 0 dans LCD_CHAR
	MOVWF	LCD_CHAR		;	"

LCD_SEND_DECIMAL_100
	MOVF	LCD_CHAR_HEXA, W
	ADDLW	-D'100'
	BTFSS	STATUS, C
	GOTO	$ + 4
	INCF	LCD_CHAR, F
	MOVWF	LCD_CHAR_HEXA
	GOTO	LCD_SEND_DECIMAL_100

	; Affiche les centaines
	MOVF	LCD_CHAR, W
	CALL	LCD_SEND_CHAR
		
	; Calcul des dixaines

	MOVLW	"0"			; On met le code ascii de 0 dans LCD_CHAR
	MOVWF	LCD_CHAR		;	"
	
LCD_SEND_DECIMAL_10
	MOVF	LCD_CHAR_HEXA, W
	ADDLW	-D'10'
	BTFSS	STATUS, C
	GOTO	$ + 4
	INCF	LCD_CHAR, F
	MOVWF	LCD_CHAR_HEXA
	GOTO	LCD_SEND_DECIMAL_10

	; Affiche les dixaines
	MOVF	LCD_CHAR, W
	CALL	LCD_SEND_CHAR

	MOVLW	"0"			; On met le code ascii de 0 dans LCD_CHAR
	MOVWF	LCD_CHAR		;	"

	; Calcul des unitees

LCD_SEND_DECIMAL_1
	MOVF	LCD_CHAR_HEXA, W
	ADDLW	-D'1'
	BTFSS	STATUS, C
	GOTO	$ + 4
	INCF	LCD_CHAR, F
	MOVWF	LCD_CHAR_HEXA
	GOTO	LCD_SEND_DECIMAL_1

	; Affiche les unitees
	MOVF	LCD_CHAR, W
	CALL	LCD_SEND_CHAR	

	; Fini !
	RETURN	


;
;	Envois d'un octet sur le LCD, ecrit en binaire toujours sur 8 0 ou 1. Passe en parametre dans W
;
LCD_SEND_BIN
	MOVWF	LCD_CHAR_HEXA		; On met W sans LCD_CHAR_HEXA, 

	; generation de code automatique avec MPLAB
	VARIABLE	I
I = D'7'

	while I >= 0
	
		MOVLW	"0"			; On met le code ascii de 0 dans W
		BTFSC	LCD_CHAR_HEXA, I	; si le bit I est a 1;
		MOVLW	"1"			; On met le code ascii de 1 dans W
		CALL	LCD_SEND_CHAR	

I--
	endW
	
	RETURN

	
; Efface l'ecran LCD	
LCD_CLEAR

	MOVLW	0
	CALL	LCD_SEND_NO_WAIT

	MOVLW	D'16'
	CALL	LCD_SEND		; envoit de la commande pour effacer

	CALL	Wait1.5ms		; on attends plus de 1.64 ms
	CALL	Wait100µs
	CALL	Wait100µs

	RETURN

; Scroll de l'ecran LCD	
LCD_SCROLL

	MOVLW	D'16'
	CALL	LCD_SEND_NO_WAIT

	MOVLW	D'128'
	CALL	LCD_SEND		; envoit de la commande pour le scroll

	RETURN

; LOCATE de l'ecran LCD, avec la position dans W. 64 positions par lignes
;	0 debut de la premiere ligne
;	64 debut de la deuxieme ligne
LCD_LOCATE

	MOVWF	LCD_CHAR		; On met W sans LCD_CHAR

	ANDLW	0xF0			; masquage des bit de poids faible
	ADDLW	D'128'			; on y ajoute 128
	CALL	LCD_SEND_NO_WAIT	; on envoit a l'afficheur

	SWAPF	LCD_CHAR, W		; On remet LCD_CHAR dans W
					; passage des bits de poids faibles en poids fort

	ANDLW	0xF0			; masquage des bit de poids faible
	CALL	LCD_SEND		; on envoit a l'afficheur
	
	; fini

	RETURN


; Place le curseur en debut de la 1ere ligne
LCD_LOCATE_LINE0

	MOVLW	D'0'
	CALL	LCD_LOCATE

	RETURN


; Place le curseur en debut de la 2eme ligne
LCD_LOCATE_LINE1

	MOVLW	D'64'
	CALL	LCD_LOCATE

	RETURN

; Place le curseur en debut de la 3eme ligne
LCD_LOCATE_LINE2

	MOVLW	D'20'
	CALL	LCD_LOCATE

	RETURN

; Place le curseur en debut de la 4eme ligne
LCD_LOCATE_LINE3

	MOVLW	D'84'
	CALL	LCD_LOCATE

	RETURN

; affiche un espace
LCD_PRINT_SPACE
	MOVLW	" "
	CALL	LCD_SEND_CHAR
	RETURN
	


;**********************************************************************
;
; Fonction Printf %s
; avec en parametre W le numero du printf a afficher (defini par des EQU)
; Definitions des printfs en fin de programmes
;
;**********************************************************************
LCD_PRINTF

	MOVWF	LCD_CMP_PRINTF	; on met W dans LCD_AFF_PRINTF qui contient le printf a afficher

	; initialisation de EEADRH et de EEADR

	BSF	STATUS, RP1
	BCF	STATUS, RP0	; Bank 2

	MOVLW	High Printf_START	
	MOVWF	EEADRH		; MSBytes of Program address to read
		
	MOVLW	Low Printf_START
	MOVWF	EEADR		; LSByte of program address to read

LCD_PRINTF_boucle
	BSF	STATUS, RP0	; 
	BSF	STATUS, RP1	; Bank 3

	BSF	EECON1, EEPGD	; Point to PROGRAM memory

	BSF	EECON1, RD	; EEPROM read
	NOP
	NOP			; Memory is read in the next 2 cycles

	BCF	STATUS, RP0	; bank 2

	MOVF 	EEDATA, W	; W = LSByte of Program EEDATA
;	MOVF 	EEDATH, W	; W = MSByte of Program EEDATA -> pas utile ici
		
	BCF	STATUS, RP1
	BCF	STATUS, RP0	; Bank 0
	
	BTFSC	STATUS, Z	; Si W = 0 va en LCD_PRINTF_Null
	GOTO	LCD_PRINTF_Null

	DECFSZ	LCD_CMP_PRINTF, F ; on decremente LCD_CMP_PRINTF
	GOTO 	LCD_PRINTF_Next_add  ; si il est different de 0, donc de 1 avant decrementation, on va en LCD_PRINTF_Next_add
				  ; sinon il faut afficher le caractere qui est toujours dans W

	CALL	LCD_SEND_CHAR	

	GOTO 	LCD_PRINTF_Next_add

LCD_PRINTF_Null

	DECFSZ	LCD_CMP_PRINTF, F
	GOTO	LCD_PRINTF_Next
	RETURN

LCD_PRINTF_Next_add
	INCF	LCD_CMP_PRINTF, F ; on reajoute 1 a LCD_CMP_PRINTF
		
LCD_PRINTF_Next

	BSF	STATUS, RP1
	BCF	STATUS, RP0	; Bank 2

	INCF	EEADR, F	; ajoute 1 a l'adresse de lecture
	BTFSC	STATUS, Z
	INCF	EEADRH, F	; si = 0, on ajoute 1 au poid fort

	MOVLW	High Printf_STOP
	SUBWF	EEADRH,W
	BTFSS	STATUS, Z
	GOTO	LCD_PRINTF_Next2 ; si EEADRH != High Printf_STOP on continue
	
	MOVLW	low Printf_STOP
	SUBWF	EEADR,W
	BTFSS	STATUS, Z
	GOTO	LCD_PRINTF_Next2 ; si EEADR != low Printf_STOP on continue

	; Fin du printf
	BCF	STATUS, RP1
	BCF	STATUS, RP0	; Bank 0
	RETURN
	

LCD_PRINTF_Next2

	BCF	STATUS, RP1 
	BCF	STATUS, RP0	; Bank 0
	GOTO	LCD_PRINTF_boucle
	




;**********************************************************************
;                                                                     *
;    Initialisation de l'ensemble de la RAM                   	      *
;                                                                     *
;                                                                     *
;**********************************************************************


InitRAM				
		MOVLW	DebutRamInit	; De DebutRamInit
	        MOVWF	FSR       	; Pointeur dans la RAM
Boucle0Ram    	CLRF 	INDF       	; Efface la zone pointee
        	INCF 	FSR,F        	; incremente le pointer
		MOVF	FSR,W		; on compare FSR a FinRamInit
		SUBLW	FinRamInit
		BTFSC	STATUS,C
		GOTO	Boucle0Ram	; Jusqu'a ce que FinRamInit
		
	RETURN

;**********************************************************************
;                                                                     *
;    Initialisation des ports d'E/S                           	      *
;                                                                     *
;                                                                     *
;**********************************************************************


InitIO
	CLRF	PORTD		; Initialise le port D
	CLRF	PORTB		; Initialise le port B
	BSF	STATUS, RP0	; Bank 1 selectonnee
	MOVLW	0x0		; Port RD7-RD0 en sortie
	MOVWF	TRISD		;	/
	MOVLW	B'00000001' ; 
	MOVWF	TRISB		; seul rb0 en entree
	BCF 	STATUS,	RP0	; Bank 0 selectonnee
	RETURN



;**********************************************************************
;
; Les printf definis (1 mot par caractere).
;  Places à la fin du programme
;
;**********************************************************************

Printf_START 	

	VARIABLE	PRINTF_CMP =	1	; Variable MPLAB (pas d'existence en assembleur) pour trouver le bon printf.

Printf_Nombre 	EQU	PRINTF_CMP
PRINTF_CMP++
	DT 	"Nombre",0


Printf_STOP

;**********************************************************************
;                                                                     *
;    Fin				                              *
;                                                                     *
;                                                                     *
;**********************************************************************


	END                     ; directive 'end of program'

' ON 20030326@8:28:42 PM at page: http://www.piclist.com/techref/microchip/mplab/msg302.htm JMN-EFP-786 James Newton edited the page. Difference: http://www.piclist.com/techref/diff.asp?url=H:\techref\microchip\mplab\msg302.htm&version=9 ON 20030326@8:29:55 PM at page: http://www.piclist.com/techref/microchip/mplab/msg302.htm JMN-EFP-786 James Newton edited the page. Difference: http://www.piclist.com/techref/diff.asp?url=H:\techref\microchip\mplab\msg302.htm&version=10