;**************************************** ;* LCD_INIT.ASM * ;**************************************** ; ; Routines indispensables à la mise en route d'un afficheur LCD en mode 4 Bits. ; Pour l'adapter sur une autre config (port d'entrées / sorties) voir ci dessous ; les équivalences (EQU) et Defininitions de termes (DEFINE). ; ;************************************************************************************* ;* Equivalences et Définitions de termes * ;************************************************************************************* ; ; Reservation en RAM ; CBLOCK 0x030 ; MSD:1 ; Temporary register, Holds Most Significant Digit of BIN to BCD conversion LSD:1 ; Temporary register, Holds Least Significant Digit of BIN to BCD conversion TEMP_LCD:1 ; Temporary register CHAR:1 ; Temporary register, Holds value to send to LCD module. ENDC ;Fin de la zone ; ; Attention aux masques, il faudra les intervertir si l'on travaille sur des bits de poids fort ; d'un port de PIC. ; MASQUE_L EQU 0x0F ; Masque pour les 4 LSB pour un afficheur géré sur 4 bits MASQUE_H EQU 0xF0 ; Masque pour les 4 MSB pour un afficheur géré sur 4 bits ; ;**************************************** ;* Caractères de commande LCD * ;**************************************** ; CLR_DISP EQU 0x01 ; Clear the Display CURS_HOME EQU 0x02 ; Remettre le curseur au début (attente de 1,5ms) ENTRY_DEC EQU 0x04 ; Set Entry Mode DECrement, No shift ENTRY_DEC_S EQU 0x05 ; ENTRY_INC EQU 0x06 ; Set Entry Mode Increment, No shift ENTRY_INC_S EQU 0x07 ; DISP_OFF EQU 0x08 ; Display off DISP_ON EQU 0x0C ; Display on DISP_ON_C EQU 0x0E ; Display on, Cursor on DISP_ON_B EQU 0x0F ; Display on, Cursor on, Blink cursor CURS_DISPl_CL EQU 0x10 ; Shift the cursor to the Left CURS_DISPl_CR EQU 0x14 ; Shift the cursor to the Right CURS_DISPl_SL EQU 0x18 ; Shift the entire display to the Left CURS_DISPl_SR EQU 0x1C ; Shift the entire display to the Right ; FUNC_SET EQU 0x20 ; Code Function Set à additionner avec les valeurs ci-dessous. DL_8 EQU 0x10 ; Data Lenght 8 bits DL_4 EQU 0x00 ; Data Lenght 4 bits N_DISP_LIN1 EQU 0x00 ; Number of Display Line (si =0: 1 ligne, si = 80: 2 lignes) N_DISP_LIN2 EQU 0x08 ; Number of Display Line (si =0: 1 ligne, si = 80: 2 lignes) CHAR_FONT57 EQU 0x00 ; Si N_DISP_LIN1, on peut avoir 5*7 point matriciel CHAR_FONT510 EQU 0x04 ; Si N_DISP_LIN1, on peut avoir 5*10 point matriciel jamais ; ; avec N_DISP_LIN2. ; ;**************************************** ;* Afficheur 1 ligne 16 caractères. * ;**************************************** ; ; La ligne est divisée en 2 zones de 8 caractères et les adresses du digit 8 à 9 ne se suivent pas. ; A1L_DIGIT0 EQU 0x80 ; Least Significant 7-bit are for address < 0xc0 A1L_DIGIT9 EQU 0xC0 ; Least Significant 6-bit are for address ; ; Entrée de config LCD affectée aux différents port du 16F84 sur ma carte automate. ; LCD_DATA EQU PORTA ; de RA0 à RA3 ; #DEFINE E PORTB,4 ; Sur PORTC RB4, Enable ; Le LCD est toujours sur Write. #DEFINE RS PORTB,5 ; Sur PORTB RB5, Register Select ; ;************************************************************************************* ;* Routines nécessaires à l'afficheur LCD TEMPO diverses * ;************************************************************************************* ; WAIT_15ms MOVLW 10 GOTO W4MS WAIT_4ms MOVLW 3 ; 3 * 1,5ms = 4,5ms W4MS MOVWF TEMP_LCD B4ms CALL WAIT_1_5ms ; Pour ces tempos, on peut se permettre DECFSZ TEMP_LCD, F ; plusieurs CALL (ce n'est qu'au début) GOTO B4ms ; RETURN ; WAIT_1_5ms MOVLW 150 ; 150 * 100 µs = 1,5ms MOVWF LSD B15ms CALL BUSY_WAIT ; Pour ces tempos, on peut se permettre DECFSZ LSD, F ; plusieurs CALL (ce n'est qu'au début) GOTO B15ms ; RETURN ; BUSY_WAIT ; une attente de 100µs suffira MOVLW 25 ; en décimal (par défaut pour le compilateur) MOVWF MSD ; l'instruction fait 1 µs (Quartz 4MHz) Boucle1 NOP DECFSZ MSD, F ; GOTO Boucle1 ; RETURN ; ; ;******************************************************************* ;* SEND_CHAR - Sends character to LCD * ;* This routine splits the character into the upper and lower * ;* nibbles and sends them to the LCD, upper nibble first. * ;* The data is transmitted on the PORT<3:0> pins * ;* La différence entre envoi de caractère et de commande * ;* correspond au bit RS * ;******************************************************************* ; SEND_CMD BCF RS ; Set LCD to command mode GOTO SEND SEND_CHAR BSF RS ; Set LCD to data mode SEND MOVWF CHAR ; Character to be sent is in W CALL BUSY_WAIT ; Wait for LCD to be ready (100 µs) SWAPF CHAR,w ANDLW MASQUE_L ; Get upper nibble MOVWF MSD ; 4 bits de poids fort dans MSD MOVF LCD_DATA,w ; on doit conserver les valeurs de RA4 et RA5 ANDLW MASQUE_H IORWF MSD,w ; le résultat à nouveau dans w MOVWF LCD_DATA ; Send data to LCD ; BCF RW ; Set LCD to write BSF E ; toggle E for LCD BCF E MOVF CHAR,w ANDLW MASQUE_L ; Get lower nibble MOVWF MSD ; 4 bits de poids fort dans MSD MOVF LCD_DATA,w ; on doit conserver les valeurs de RA4 et RA5 ANDLW MASQUE_H IORWF MSD,w ; le résultat à nouveau dans w MOVWF LCD_DATA ; Send data to LCD BSF E ; toggle E for LCD BCF E RETURN ; INIT_LCD BCF E BCF RS ; Set LCD for Command mode ; BCF RW ; Write mode ; call WAIT_15ms ; tempo de 15ms movlw MASQUE_H andwf LCD_DATA,f movlw 0x03 ; Commande de mise en route iorwf LCD_DATA,f BSF E ; Set E high BCF E ; Set E low ; call WAIT_4ms ; tempo de 4ms BSF E ; Set E high (en fait le port a déjà l'info) BCF E ; Set E low ; call BUSY_WAIT ; 100µs BSF E ; Set E high (en fait le port a déjà l'info) BCF E ; Set E low ; call BUSY_WAIT ; 100µs movlw MASQUE_H andwf LCD_DATA,f movlw 0x02 ; On indique le mode 4 bits iorwf LCD_DATA,f BSF E ; Set E high BCF E ; Set E low ; call BUSY_WAIT ; 100µs ; RETURN ; INIT_DISPLAY movlw FUNC_SET+DL_4+N_DISP_LIN2 ; Commande 4 bits, 2 lignes CALL SEND_CMD ; Send This command to the Display Module ; MOVLW DISP_OFF ; Display Off (recommendation constructeur) CALL SEND_CMD ; MOVLW DISP_ON ; Display On, Cursor On CALL SEND_CMD ; Send This command to the Display Module ; MOVLW ENTRY_INC ; Set Entry Mode Inc., No shift CALL SEND_CMD ; Send This command to the Display Module FIN_INIT_DISPLAY RETURN