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' 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:; 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'
;**********************************************************************
; *
; 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