;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** ;* DISPLAY LCD (8bits+ busy flag) * ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** ;* DESCRIÇÃO DO ARQUIVO * ;*--------------------------------------------------------------------------------------* ;* MANIPULAÇÃO DE UM DISPLAY LCD 16X2. * ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** ;* ÁREA DE IDENTIFICAÇÃO * ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** ;*criado por revenido * ;*baseado nos projetos: * ;* DE SOUZA, DAVID JOSÉ, DESBRAVANDO O PIC (PIC16F628), ED. ÉRICA, 8° EDIÇÃO. * ;* controle de display Hitachi 2 linhas 16 colunas com PIC - Marcio Jose Soares (ARNE)* ;* http://www.arnerobotics.com.br/eletronica/Microcontrolador_PIC_pratica_6.htm * ; ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** ;* ARQUIVOS DE DEFINIÇÕES * ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** #INCLUDE ;ARQUIVO PADRÃO MICROCHIP PARA 16F628A ; CONFIGURAÇÃO DO CONTROLADOR (FUSES OU FUSÍVEIS) (PROCURAR NO DATASHEET COMO "CONFIGURATION WORD") __CONFIG _XT_OSC & _WDT_OFF & _PWRTE_ON & _MCLRE_ON & _BODEN_ON & _LVP_OFF & _DATA_CP_OFF & _CP_OFF radix dec ;diretiva. decimal.| radix hex ;A numeração sem indicação é interpretada como hexadecimal errorlevel -302 ;suprime os avisos warning 302 ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** ;* PAGINAÇÃO DE MEMÓRIA * ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** ;DEFINIÇÃO DE COMANDOS DE USUÁRIO PARA ALTERAÇÃO DA PÁGINA DE MEMÓRIA #DEFINE BANK0 BCF STATUS,RP0 ;SETA BANK 0 DE MEMÓRIA #DEFINE BANK1 BSF STATUS,RP0 ;SETA BANK 1 DE MEMÓRIA ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** ;* VARIÁVEIS * ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** ;DEFINIÇÃO DOS NOMES E ENDEREÇÕS DE TODAS AS VARIÁVEIS UTILIZADAS PELO SISTEMA CBLOCK 0X20 ; ENDEREÇO INICIAL MEMÓRIA USO GERAL CHAR ;variavel para caracter W_TEMP ;variavel para interrupt STATUS_TEMP ;variavel para interrupt PULSOSEG ;ARMAZENA OS PULSOS ATÉ FORMAR UM SEGUNDO SEGUNDOS ;ARMAZENA OS SEGUNDOS MINUTOS ; " " MINUTOS HORAS ; " " HORAS count ;controle para impressão das mensagens no lcd count1 ;VARIÁVEIS DO DELAY counta ;VARIÁVEIS DO DELAY countb ;VARIÁVEIS DO DELAY VARPOS1 ;VARIAVEL ARMAZENA NUMERO CONVERTIDO PARA COLOCAR NO LCD VARPOS2 ;VARIAVEL ARMAZENA NUMERO CONVERTIDO PARA COLOCAR NO LCD NUMBIN ;VARIÁVEL A SER CONVERTIDA PARA COLOCAR NO LCD VARAUX ;VARIÁVEL AUXILIAR TEMP1 ;VARIÁVEL AUXILIAR DA FUNÇÃO DELAY1MS ENDC ; FIM BLOCO MEMÓRIA USO GERAL ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** ;* CONSTANTES * ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** ;DEFINIÇÃO DE TODAS AS CONSTANTES UTILIZADAS PELO SISTEMA LCD_CNTL EQU PORTA ;port de controle para display LCD_DATA EQU PORTB ;port de dados para o display E EQU 1 ;controles do display RS EQU 3 ;porta A RW EQU 2 STEP EQU .10 ;decremento do CONVERTEBYTE STEP2 EQU .5 ;decremento da msg2 ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** ;* SAÍDAS * ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** #DEFINE RA0 PORTA,0 ; ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** ;* VETOR DE RESET * ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** ORG 0X00 ; ENDEREÇO INICIAL DO CÓDIGO. diretiva. define o endereço que o compilador inicie a alocar o dado ou instrução seguinte. Esta area coincide a area de RAM do PIC definida pela Micrchip como FILE REGISTER. GOTO SET_UP ; VAI PAr INÍCIO DO SET_UP CONTROLADOR ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** ;* INICIO DA INTERRUPÇÃO * ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** ORG 0X04 ; ENDEREÇO INICIAL DA INTERRUPÇÃO. diretiva. GOTO INTERRUCAO ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** ;* INICIALIZAÇÃO DAS VARIÁVEIS * ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** VARIAVEIS CLRF PORTA ; COLOCA ZERO NO REGISTRO PORTA CLRF PORTB ; COLOCA ZERO NO REGISTRO PORTB CLRF CHAR ;variavel para caracter CLRF SEGUNDOS ;armazena segundos CLRF MINUTOS ;armazena minutos CLRF HORAS ;horas CLRF PULSOSEG CLRF VARPOS1 CLRF VARPOS2 CLRF NUMBIN clrf count ;set counter register to zero clrf count1 ;set counter register to zero movlw .125 ; movwf PULSOSEG ;HORAS=12 call Delay255 ;aguarda display inicializar call DISPLAY_INIT ;inicializa display CALL MSG1 CALL DELAY1MS ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** ;* ROTINA PRINCIPAL * ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** MAIN CALL ATUALIZA movlw 0x01 call SEND_CMD ;apaga display CALL MSGHORAS ;PRIMEIRA LINHA ESCREVE HORAS, MIN, SEG. movlw 0xC0 ;muda de linha call SEND_CMD CALL MSG2 ;SEGUNDA LINHA ILUSTRA OS SEGUNDOS CALL DELAY1MS CALL DELAY1MS CALL DELAY1MS ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** ;* FIM ROTINA PRINCIPAL * ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** GOTO MAIN ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** ;* ROTINAS SECUNDÁRIAS * ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** ;*************************************************************** ;ATUALIZA MINUTOS E HORAS DE ACORDO COM OS SEGUNDOS (INCREMENTADO NA INTERRUPÇÃO) ;*************************************************************** ATUALIZA ;compara segundos com 60 para incrementar minutos ou não. MOVF SEGUNDOS,W ;COLOCA SEGUNDOS EM W XORLW .60 ;APLICA XOR ENTRE SEGUNDOS E 60 PARA TESTAR IGUALDADE. SE FOREM ;IGUAIS, O RESULTADO SERÁ ZERO BTFSS STATUS,Z ;RESULTOU EM ZERO? GOTO FIMCALCULA ;NÃO, RETORNA SEM AFETAR CONT. ;SIM, ZERA SEGUNDOS E INC MINUTOS CLRF SEGUNDOS INCF MINUTOS,F ;ENTÃO INCREMENTA MINUTOS. ;compara minutos com 60 para incrementar horas ou não. MOVF MINUTOS,W ;COLOCA MINUTOS EM W XORLW .60 ;APLICA XOR ENTRE MINUTOS E 60 PARA TESTAR IGUALDADE. SE FOREM ;IGUAIS, O RESULTADO SERÁ ZERO BTFSS STATUS,Z ;RESULTOU EM ZERO? GOTO FIMCALCULA ;NÃO, RETORNA SEM AFETAR CONT. ;SIM, ZERA MINUTOS E INC HORAS CLRF MINUTOS INCF HORAS,F ;ENTÃO INCREMENTA MINUTOS. ;compara HORAS com 24 para ZERAR HORAS OU NÃO. MOVF HORAS,W ;COLOCA HORAS EM W XORLW .24 ;APLICA XOR ENTRE HORAS E 24 PARA TESTAR IGUALDADE. SE FOREM ;IGUAIS, O RESULTADO SERÁ ZERO BTFSS STATUS,Z ;RESULTOU EM ZERO? GOTO FIMCALCULA ;NÃO, RETORNA SEM AFETAR CONT. ;SIM, ZERA HORAS CLRF HORAS ;ENTÃO INCREMENTA MINUTOS. FIMCALCULA RETURN ;*************************************************************** ;envia mensagem das horas para display. ;*************************************************************** ;mensagem: HORA:MINUTOS:SEGUNDOS (dois digitos cada) MSGHORAS MOVF HORAS,W ; MOVWF NUMBIN ;CONVERTE SEGUNDOS EM NUMERO BINÁRIO CALL CONVERTEBYTE;CONVERTE NUMERO EM UNIDADE E DEZENA PARA COLOCA-LO NO LCD. MOVF VARPOS1,W call SEND_CHAR ;ENVIA NÚMERO... MOVF VARPOS2,W call SEND_CHAR ;ENVIA NÚMERO... movlw ':' call SEND_CHAR MOVF MINUTOS,W ; movwf NUMBIN ;CONVERTE SEGUNDOS EM NUMERO BINÁRIO CALL CONVERTEBYTE;CONVERTE NUMERO EM UNIDADE E DEZENA PARA COLOCA-LO NO LCD. MOVF VARPOS1,W call SEND_CHAR ;ENVIA NÚMERO... MOVF VARPOS2,W call SEND_CHAR ;ENVIA NÚMERO... movlw ':' call SEND_CHAR MOVF SEGUNDOS,W ; movwf NUMBIN ;CONVERTE SEGUNDOS EM NUMERO BINÁRIO CALL CONVERTEBYTE;CONVERTE NUMERO EM UNIDADE E DEZENA PARA COLOCA-LO NO LCD. MOVF VARPOS1,W call SEND_CHAR ;ENVIA NÚMERO... MOVF VARPOS2,W call SEND_CHAR ;ENVIA NÚMERO... RETURN ;RETORNA ;*************************************************************** ;envia mensagem2 para display. COLOCA QUADRADOS DE ACORDO COM SEGUNDOS. ;*************************************************************** ;mensagem: ilustra segundos. MSG2 clrf count ;set counter register to zero clrf count1 ;set counter register to zero MOVF SEGUNDOS,W ;COLOCA SEGUNDOS EM W. movwf count ;SEGUNDOS CONVERTE11 MOVLW STEP2 ;MOVE O VALOR MÍNIMO PARA W SUBWF count,W ;SUBTRAI O VALOR DE W (10) DE VARPOS2 BTFSS STATUS,C ;TESTA CARRY. RESULTADO NEGATIVO? GOTO CONVERTE21 ;NÃO, ENTÃO CONTA >= MIN ;SIM, ENTÃO CONTA < MIN MOVWF count INCF count1,F ; GOTO CONVERTE11 CONVERTE21 ;FINAL DA CONVERSÃO. MOVF count1,W ;COLOCA SEGUNDOS EM W. XORLW .0 ;APLICA XOR ENTRE count1 E 12 PARA TESTAR IGUALDADE. SE FOREM ;IGUAIS, O RESULTADO SERÁ ZERO BTFSC STATUS,Z ;RESULTOU EM ZERO? GOTO FIMMSG2 ;SIM, RETORNA SEM AFETAR CONT. PRINTAGAIN movlw 0xFF call SEND_CHAR DECF count1 btfsc STATUS, Z goto FIMMSG2 goto PRINTAGAIN FIMMSG2 retlw 0x00 ;*************************************************************** ;envia mensagem1 para display ;*************************************************************** ;mensagem: Hello... MSG1 clrf count ;set counter register to zero Message movf count, w ;put counter value in W call Text ;get a character from the text table xorlw 0x00 ;is it a zero? btfsc STATUS, Z goto FIMMSG1 call SEND_CHAR CALL Delay255 incf count, f goto Message FIMMSG1 retlw 0x00 Text addwf PCL, f retlw 'H' retlw 'e' retlw 'l' retlw 'l' retlw 'o' retlw '.' retlw '.' retlw '.' retlw 0x00 ;############################################################################ ;# CONVERTE INFORMAÇÃO DE 1 BYTE EM NÚMERO VISÍVEL NO LCD ;############################################################################ CONVERTEBYTE ; ENTRAR COM AS VARIÁVEIS A SEREM CONVERTIDAS ; NUMBIN É A VARIÁVEL A SER CONVERTIDA, EM BINÁRIO ; VARPOS1 É A UNIDADE EM NÚMERO DECIMAL ; VARPOS2 É A DEZENA EM NÚMERO DECIMAL CLRF VARPOS1 CLRF VARPOS2 MOVF NUMBIN,W MOVWF VARPOS2 CONVERTE1 MOVLW STEP ;MOVE O VALOR MÍNIMO PARA W SUBWF VARPOS2,W ;SUBTRAI O VALOR DE W (10) DE VARPOS2 BTFSS STATUS,C ;TESTA CARRY. RESULTADO NEGATIVO? GOTO CONVERTE2 ;NÃO, ENTÃO CONTA >= MIN ;SIM, ENTÃO CONTA < MIN MOVWF VARPOS2 INCF VARPOS1,F ; GOTO CONVERTE1 CONVERTE2 ;FINAL DA CONVERSÃO. MOVLW 0x30 ADDWF VARPOS1,F ; AJUSTA P/ESCRITA EM CARACTER ASC II ADDWF VARPOS2,F ; AJUSTA P/ESCRITA EM CACACTER ASC II RETURN ;******************************************************************* ; Inicializa o display ; caracter 5x7, 2 linhas, cursor ligado, mensagem fixa ;******************************************************************* ; DISPLAY_INIT: MOVLW 0x038 ; Comando para interface 8-bits call SEND_CMD MOVLW 0x00E ; liga display CALL SEND_CMD ; MOVLW 0x006 ; incrementa display CALL SEND_CMD ; MOVLW 0x001 ; apaga display CALL SEND_CMD ; retlw 0x00 ; volta ;***************************************************************** ;* SEND_CHAR - envia caracter que esta no registro W para o LCD * ;* Esta rotina envia todo caracter pelo port * ;* O dado eh trasmitido pelo PORTB<7:0> pins * ;***************************************************************** ; SEND_CHAR: MOVWF CHAR ; caracter em W CALL BUSY_CHECK ; espere ate que o display esteje pronto BCF LCD_CNTL, RW ; seta o LCD em modelo leitura BSF LCD_CNTL, RS ; seta o LCD em modo dados BSF LCD_CNTL, E ; inverte E para o LCD MOVF CHAR, w MOVWF LCD_DATA ; envie o dado para o LCD BCF LCD_CNTL, E retlw 0x00 ;************************************************************** ;* SEND_CND - envia comando contido no registro W para LCD * ;* esta rotina insere o dados completo no PORT * ;* o dado eh transmitido pelo pinos do PORT<7:0> * ;************************************************************** SEND_CMD: MOVWF CHAR ; Comando a enviar em W CALL BUSY_CHECK ; aguarde ate que o display esteje pronto BCF LCD_CNTL, RW ; seta o LCD em modo leitura BCF LCD_CNTL, RS ; seta o LCD em modo comando BSF LCD_CNTL, E ; inverte E para LCD MOVF CHAR, w MOVWF LCD_DATA ; envie o dado para o LCD BCF LCD_CNTL, E retlw 0x00 ;************************************************************** ;* Esta rotina checa o busy flag, retorna quando livre * ;* Afeta: * ;* TEMP - retorna com endereco busy * ;************************************************************** ; BUSY_CHECK: BSF STATUS,RP0 ; Seleciona registro da pagina 1 MOVLW 0xFF ; Seta port B para entrada MOVWF TRISB BCF STATUS, RP0 ; Seleciona Registro da pagina 0 BCF LCD_CNTL, RS ; Seta LCD para modo comando BSF LCD_CNTL, RW ; Setup para ler busy flag BSF LCD_CNTL, E ; Seta E high MOVF LCD_DATA, w ; le o busy flag, endereco DDram BCF LCD_CNTL, E ; Seta E low andlw 0x80 btfss STATUS, Z goto BUSY_CHECK lcdnobusy: BCF LCD_CNTL, RW BSF STATUS, RP0 ; Seleciona registro pagina 1 MOVLW 0x00 ; seta novamente port B como saida MOVWF TRISB ; Seta port_D para saida BCF STATUS, RP0 ; Seleciona registro pagina 0 retlw 0x00 ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** ;* ROTINAS SECUNDÁRIAS - DELAYS * ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** ;ROTINAS DE DELAYS Delay255 movlw 0xff ;delay 255 mS goto d0 Delay100 movlw d'100' ;delay 100mS goto d0 Delay50 movlw d'50' ;delay 50mS goto d0 Delay20 movlw d'20' ;delay 20mS goto d0 Delay5 movlw 0x05 ;delay 5.000 ms (4 MHz clock) d0 movwf count1 d1 movlw 0xC7 ;delay 1mS movwf counta movlw 0x01 movwf countb Delay_0 decfsz counta, f goto $+2 decfsz countb, f goto Delay_0 decfsz count1 ,f goto d1 retlw 0x00 DELAY1MS ;ROTINA DE 1ms MOVLW .250 ; MOVWF TEMP1 ;INICIA TEMP1 COM 250 DL_1 NOP ;PERDE UM CICLO SEM EFETUAR AÇÃO DECFSZ TEMP1,F ;DECREMENTA O CONTADOR TEMP1. ACABOU? GOTO DL_1 ;NÃO, CONTINUA ESPERANDO RETURN ;MAIS 6 CICLOS SERÃO GASTOS NAS INSTRUÇÕES CALL, RETURN E NA INICIALIZAÇÃO DO TEMP1 ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** ;* SET UP DO MICROCONTROLADOR * ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** SET_UP BANK0 ;ALTERA PARA O BANCO 0 MOVLW B'00000111' MOVWF CMCON ;DEFINE O MODO DE OPERAÇÃO DO COMPARADOR ANALÓGICO BANK1 ;ALTERA PARA O BANCO 1 MOVLW B'11000000' MOVWF TRISA ;0=SAÍDAS 1=ENTRADAS MOVLW B'00000000' MOVWF TRISB ;DEFINE TODO O PORTB COMO SAÍDA MOVLW B'10000101' ;'10000111' MOVWF OPTION_REG ; MOVLW B'10100000' MOVWF INTCON ;HABILITADA SOMENTE A INTERRUPÇÃO TMR0 ;CHAVE GERAL DAS INTERRUÇÕES LIGADA BANK0 ;RETORNA PARA O BANCO 0 bcf LCD_CNTL,E bcf LCD_CNTL,RW bcf LCD_CNTL,RS GOTO VARIAVEIS ;VAI PARA VARIÁVEIS ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** ;* PROGRAMA DA INTERRUPÇÃO * ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** INTERRUCAO MOVWF W_TEMP ;SALVA W EM W_TEMP SWAPF STATUS,W MOVWF STATUS_TEMP ;SALVA STATUS EM STATUS_TEMP BTFSS INTCON,T0IF ;É INTERRUPÇÃO DE TMR0? GOTO SAI_INT ;NÃO, SAI SE AÇÃO ;SIM BANK0 ;ESTE FOI COLOCADO GRAÇAS AO Moley ;VER: http://forum.clubedohardware.com.br/pic-16f628a-lcd/1096320 ; ESTA ROTINA IRÁ CONTAR O TEMPO, E QUANDO PASSAR 1 SEGUNDO, A VARI- ; ÁVEL "TEMPO" SERÁ DECREMENTADA. ; 1 SEGUNDO = 64us (PRESCALER) X 125 (TMR0) X 125 (TEMP1) BCF INTCON,T0IF ;LIMPA FLAG DA INT. MOVLW .256-.125 MOVWF TMR0 ;REINICIA TMR0 decfsz PULSOSEG,F ;DECREMENTA O CONTADOR DE PULSOS DE SEGUNDOS. goto SAI_INT ;PULSOSEG=O? NÃO, SAI FORA... ;SIM, PULSOSEG=0, ENTÃO: MOVLW .125 MOVWF PULSOSEG ;REINICIALIZA PULSOSEG INCF SEGUNDOS,F ;INCREMENTA SEGUNDOS ;TESTE PARA VER SE INTERRUPT ESTÁ FUNCIONANDO. BTFSS RA0 GOTO TESTE1 GOTO TESTE2 TESTE3 ;*FIM DA INTERRUPÇÃO SAI_INT SWAPF STATUS_TEMP,W MOVWF STATUS ;RECUPERA STATUS SWAPF W_TEMP,F SWAPF W_TEMP,W ;RECUPERA W RETFIE ; RETORNA DA INTERRUPÇÃO ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** ;* SUB PROGRAMA PARA VER SE INTERRUPT ESTÁ FUNCIONANDO * ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** ;SE O LED DO RA0 PISCAR ESTÁ FUNCIOANDO A INTERRUPÇÃO. TESTE1 BSF RA0 ;soh pra saber se a interrupção está funcionando... GOTO TESTE3 TESTE2 BCF RA0 ;desliga o led GOTO TESTE3 ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** ;* FIM DO PROGRAMA * ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** END ;OBRIGATÓRIO