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