;***************************************************************************************************** ; ; FREQ_METER_TINY ; ; FREQUENCIMETRO COM VISUALIZAÇÃO EM LCD USANDO TECNICA 'LARIOS' DE MULTIPLEXAÇÃO POR REDE RC ; E USANDO APENAS 3 FIOS PARA LIGAÇÃO COM LCD . ; MICROCONTROLADOR USADO: PIC 12F629 DE APENAS 8 PINOS ; USA CRISTAL DE 4 MHZ PARA ESTABILIZAÇÃO DE FREQUENCIA . ; ; INICIO DO PROJETO: 05/06/2012 TERMINO:10/06/2012 ; ; SITE : LARIOS.TECNOLOGIA.WS ; BY CLÁUDIO LÁRIOS ; OBS. FINS DIDÁTICOS: NÃO TENTE RODAR EM SIMULADOR COMO O 'PROTEUS' QUE NÃO IRÁ FUNCIONAR. ; DEVERÁ SER FEITA MONTAGEM COM COMPONENTES REAIS E EM ALGUNS CASOS, DEVIDO A TOLERANCIA DOS COMPONENTES ; TERÁ QUE SER FEITO AJUSTES. ; ;***************************************************************************************************** #INCLUDE ; ARQUIVO PADRAO __CONFIG _BODEN_ON & _CP_OFF & _PWRTE_ON & _WDT_OFF & _MCLRE_ON & _XT_OSC ;_INTRC_OSC_NOCLKOUT ERRORLEVEL -302 ;SUPRIME A MENSAGEM DE ERRO DO BANCO 0 ;PAGINACAO DE MEMORIA; #DEFINE BANK0 BCF STATUS,RP0 ;SETA BANK0 DE MEMORIA #DEFINE BANK1 BSF STATUS,RP0 ;SETA BANK1 ;VARIAVEIS NA RAM CBLOCK 0X20 ;ENDERECO INICIAL DE MEMORIA TEMP,TEMP1,CONT,CONT1,LC,LC1,FLAGS,TMR_UH,TMR_UL,TMR_H,TMR_L,C0,C1,C2,C3,RES4,RES3,RES2,RES1,RES0,RAU,T1 tmpLcdRegister,tmpLcdRegister1,AUX,CONTP ENDC ;LCD Control lines #DEFINE FLCD_RS FLAGS,0 ; FLAG RS comando/dado #DEFINE LCD_E GPIO,1 ;Enable + RESISTOR 18K COM CAPACITOR A MASSA DE 100nF AO 'RS' #DEFINE EPZ1 FLAGS,2 ; FLAG ESCONDE ZERO A ESQUERDA ;LCD data line bus #DEFINE LCD_DB6 GPIO,0 ;LCD data line DB6 + RESISTOR 18K COM CAPACITOR A MASSA DE 100nF AO 'DB4' #DEFINE LCD_DB7 GPIO,2 ;LCD data line DB7 + RESISTOR 18K COM CAPACITOR A MASSA DE 100nF AO 'DB5' ;CONSTANTES OUT EQU B'11000' ;LCD COMANDOS: LINHA1 EQU 0X80 ;ESCREVE NA LINHA SUPERIOR LINHA2 EQU 0XC0 ;ESCREVE NA LINHA INFERIOR ORG 0X00 GOTO INICIO ;................................................................................................ ; ORG 0X04 RETFIE ; INICIO DO PROGRAMA INICIO CLRWDT clrf GPIO MOVLW .7 MOVWF CMCON ;DESLIGA COMPARADORES LIBERANDO AS IO'S CLRF FLAGS BANK1 MOVLW B'11000' ;ACERTA ENTRADA/SAIDAS MOVWF TRISIO MOVLW B'100111' MOVWF WPU ;PULL UP'S DESATIVADO MOVLW B'10110111' ;TIMER 0 COM PRESCALLER EM /255 MOVWF OPTION_REG BANK0 MAIN1 CALL LcdInit ;INICIALIZAÇÃO DO LCD MOVLW 'F' ;MOSTRA TITULO DO APARELHO 'FREQ_METER_TINY' CALL ED MOVLW 'R' CALL ED MOVLW 'E' CALL ED MOVLW 'Q' CALL ED MOVLW '_' CALL ED MOVLW 'M' CALL ED MOVLW 'E' CALL ED MOVLW 'T' CALL ED MOVLW 'E' CALL ED MOVLW 'R' CALL ED MOVLW '_' CALL ED MOVLW 'T' CALL ED MOVLW 'I' CALL ED MOVLW 'N' CALL ED MOVLW 'Y' CALL ED MOVLW 0XC0 CALL EC MOVLW 'L' ;MOSTRA O SITE 'LARIOS_TECNOLOGIA.WS' CALL ED MOVLW 'A' CALL ED MOVLW 'R' CALL ED MOVLW 'I' CALL ED MOVLW '0' CALL ED MOVLW 'S' CALL ED MOVLW '.' CALL ED MOVLW 'T' CALL ED MOVLW 'E' CALL ED MOVLW 'C' CALL ED MOVLW 'N' CALL ED MOVLW 'O' CALL ED MOVLW 'L' CALL ED MOVLW '.' CALL ED MOVLW 'W' CALL ED MOVLW 'S' CALL ED MOVLW .10 ;TEMPO DE APRESENTAÇÃO DO TITULO CALL DELAYW CALL LcdClear ;APAGA DISPLAY ;====================================================================== ;INICIA A MEDIÇÃO USANDO O TEMPO DE 1 SEGUNDO PARA A CONTAGEM MED_FREQ CLRF TMR_L ;LIMPA REGISTRADORES DE CONTAGEM DA FREQUENCIA CLRF TMR_H CLRF TMR_UL CLRF TMR_UH BANK1 bsf TRISIO,2 ;vira entrada no pino 5 BANK0 CLRF GPIO CLRF TMR0 ;PREVINE MUDANÇA DO FLAG COINCIDENTE AS PRÓXIMAS INSTRUÇÕES BCF INTCON,2 ;APAGA FLAG OV TIMER0 CLRF TMR0 ;INICIA A MEDIÇÃO call T1SEG ;tempo de leitura da frequencia DE 1SEG BANK1 bcf TRISIO,2 ;vira SAIDA '0' no pino 5 (PARANDO A CONTAGEM) BANK0 movlw .2 ;Wait 2 ms (DESCARGA DE CAPACITOR EM 'RS') CALL LcdDelay movfw TMR0 ;SALVA CONTAGEM DO TIMER 0 movwf TMR_H ;NO CONTADOR TMR_H ;===================================================== ; EXTRAI O CONTEUDO DO PRESCALLER VP4 BANK1 BCF OPTION_REG,5 ;PULSA ENTRE CLOCK INTERNO E ENTRADA ATERRADA BSF OPTION_REG,5 BANK0 INCF TMR_L,F INCF TMR_L,F MOVFW TMR_H SUBWF TMR0,W ;COMPARA SE HOUVE INCREMENTO EM TMR0 BTFSC STATUS,Z GOTO VP4 ;NÃO HOUVE, RETORNA PARA PULSAR MAIS UMA VEZ MOVFW TMR_L ;TMR_L ESTÁ COM O VALOR QUE FALTOU PARA CHEGAR EM '0' SUBLW .0 MOVWF TMR_L ;ACERTA PARA O VALOR REAL CONTADO NO PRESCALLER ;============================================================ ; INICIA A CONVERSÃO HEX/DEC MOVFW TMR_L ;HOUVE ,CARREGA PARA OS REGISTRADORES DO CONVERSOR HEXA/DEC MOVWF C0 MOVFW TMR_H MOVWF C1 MOVFW TMR_UL MOVWF C2 MOVFW TMR_UH MOVWF C3 CALL BCD_TO_DEC ;CONVERTE HEXA DOS CONTADORES PARA DECIMAL CALL SHOW_LCD ;ENVIA PARA O LCD GOTO MED_FREQ ;RETORNA PARA NOVA MEDIÇÃO ;================================================================================= ; ROTINAS DE DELAYS ;================================================================================= DELAY2 MOVLW .20 DELAYW MOVWF TEMP VJ1 call LcdDelay1 DECFSZ TEMP,F GOTO VJ1 DELAY1 LcdDelay1 MOVLW .255 ;DELAY PARA VISUALIZAÇAO DELAY LcdDelay CLRWDT NOP movwf LC+1 ;duas variáveis em uma LcdDelayLoop CLRWDT decfsz LC+0,F ;dec. o prim. cont. goto LcdDelayLoop decfsz LC+1,F ;dec. o seg. cont. goto LcdDelayLoop return WAIT_WMSEC movwf LC+1 WAITSET movlw .250 movwf LC WAITLOOP decfsz LC,F goto WAITLOOP decfsz LC+1,F goto WAITSET return ;===================================================== WAIT_uS movwf LC WAIT_uS_A decfsz LC, F goto WAIT_uS_A return ;================================================================================= ;Rotinas de controle do LCD ;================================================================================= LcdInit bcf LCD_E ;Disabled LCD bcf LCD_DB6 ;0011->48 bcf LCD_DB7 movlw .30 ;Wait 30 ms call LcdDelay ;envia 0011 0x03 por 3 vezes e depois o 0010 0x02 por 1 vez para modo 4 bits bsf LCD_DB6 ;0011->48 bsf LCD_DB7 MOVLW .250 ;min=.150 (achado por tentativa e erro) CALL WAIT_uS bcf LCD_DB6 ;0011->48 bcf LCD_DB7 bsf LCD_E ;Enables LCD NOP bcf LCD_E ;Disabled LCD nop bsf LCD_E ;Enables LCD NOP bcf LCD_E ;Disabled LCD nop bsf LCD_E ;Enables LCD NOP bcf LCD_E ;Disabled LCD movlw .1 ;Wait 1ms call LcdDelay bcf LCD_DB6 ;0011->48 bsf LCD_DB7 ;TORNA DB5 =1 POR TEMPO movlw .250 ;Wait 2 ms CALL WAIT_uS BCF LCD_DB7 call LcdPulse_E bcf LCD_E ;Disabled LCD bcf LCD_DB6 ;0011->48 bcf LCD_DB7 movlw .1 call LcdDelay movlw 28H ;Set 4 bit data bus length call LcdSendCommand movlw 06H ;Entry mode set, increment, no shift call LcdSendCommand ; movlw 0DH ;Display ON, Cursor ON, Blink ON ; movlw 0FH ;Display ON, Cursor ALTERADO ON, Blink ON ; movlw 0EH ;Display ON, Cursor ON, Blink OFF movlw 0CH ;Display ON, Cursor OFF, Blink OFF call LcdSendCommand LcdClear movlw 01H ;clear display call LcdSendCommand movlw .2 ;Wait 2 ms call LcdDelay CLRWDT return ;=========================================================================== ED LcdSendData bsf FLCD_RS ;seta flag para indicar 'dado' GOTO XENV LINE2 MOVLW 0XC0 ;opção para linha2 EC LcdSendCommand bcf FLCD_RS ;reseta flag para indicar 'comando' XENV call LcdSendByte return LcdSendByte CLRWDT movwf tmpLcdRegister ;salva dado/comando a enviar movlw OUT call TRISIOX bcf LCD_E BCF LCD_DB7 BCF LCD_DB6 ;DESCARREGA CAPACITORES movlw .1 ;AGUARDA 1 MS P/ DESCARGA COMPLETA QUANDO EM 'IN' call LcdDelay btfsc tmpLcdRegister,4 bsf LCD_DB6 btfsc tmpLcdRegister,5 bsf LCD_DB7 BTFSC FLCD_RS ;flag rs bsf LCD_E ;Enables LCD MOVLW .250 ;tempo para carga dos capacitores -> min=.150 (achado por tentativa e erro) CALL WAIT_uS BCF LCD_DB6 btfsc tmpLcdRegister,6 bsf LCD_DB6 bcf LCD_DB7 btfsc tmpLcdRegister,7 bsf LCD_DB7 call LcdPulse_E ;envia um 1° nible ;--------------------------------------------------------------------- btfsc tmpLcdRegister,0 bsf LCD_DB6 btfsc tmpLcdRegister,1 bsf LCD_DB7 BTFSC FLCD_RS ;flag rs bsf LCD_E ;Enables LCD MOVLW .250 ;tempo para carga dos capacitores -> min=.150 (achado por tentativa e erro) CALL WAIT_uS bcf LCD_DB6 btfsc tmpLcdRegister,2 bsf LCD_DB6 bcf LCD_DB7 btfsc tmpLcdRegister,3 bsf LCD_DB7 call LcdPulse_E ;envia um 2° nible return ;================================================================================= LcdPulse_E bsf LCD_E ;Enables LCD CLRWDT NOP bcf LCD_E ;Disabled LCD BCF LCD_DB7 BCF LCD_DB6 ;DESCARREGA CAPACITORES movlw .1 ;Wait 2ms call LcdDelay return ;======================================================================================== TRISIOX BANK1 ;TROCA DE BANCO MOVWF TRISIO ;ENTRADA OU SAIDA BANK0 RETURN ;========================================================================================== ; ROTINA DE CONVERSÃO HEXA PARA DECIMAL HEXA EM C0,C1,C2,C3 E DECIMAL EM RES0,RES1,RES2,RES3,RES4 BCD_TO_DEC: MOVLW 20H MOVWF LC CLRF RES0 ;ZERA RESULTADOS CLRF RES1 CLRF RES2 CLRF RES3 CLRF RES4 VOLTA: BCF STATUS,C RLF C0,F ;DESLOCA PARA ESQUERDA C0,C1,RES0,1,2 RLF C1,F RLF C2,F RLF C3,F RLF RES0,F RLF RES1,F RLF RES2,F RLF RES3,F RLF RES4,F DECFSZ LC,F GOTO S45 GOTO FIM S45: CLRWDT MOVLW 03H ADDWF RES4,W MOVWF RAU BTFSS RAU,3 GOTO S1B MOVWF RES4 S1B: MOVLW 30H ADDWF RES4,W MOVWF RAU BTFSS RAU,7 GOTO S2B MOVWF RES4 S2B: MOVLW 03H ADDWF RES3,W MOVWF RAU BTFSS RAU,3 GOTO S1A MOVWF RES3 S1A: MOVLW 30H ADDWF RES3,W MOVWF RAU BTFSS RAU,7 GOTO S2A MOVWF RES3 S2A: MOVLW 03H ADDWF RES2,W MOVWF RAU BTFSS RAU,3 GOTO S1 MOVWF RES2 S1: MOVLW 30H ADDWF RES2,W MOVWF RAU BTFSS RAU,7 GOTO S2 MOVWF RES2 S2: MOVLW 03H ADDWF RES1,W MOVWF RAU BTFSS RAU,3 GOTO S10 MOVWF RES1 S10: MOVLW 30H ADDWF RES1,W MOVWF RAU BTFSS RAU,7 GOTO S20 MOVWF RES1 S20: MOVLW 03H ADDWF RES0,W MOVWF RAU BTFSS RAU,3 GOTO S11 MOVWF RES0 S11: MOVLW 30H ADDWF RES0,W MOVWF RAU BTFSS RAU,7 GOTO S21 MOVWF RES0 S21: GOTO VOLTA FIM: RETURN ;======================================================================== SHOW_LCD ;MOSTRA PALAVRA 'FREQUENCIA:' CLRWDT MOVLW LINHA1 CALL EC MOVLW ' ' CALL ED MOVLW ' ' CALL ED MOVLW ' ' CALL ED MOVLW 'F' CALL ED MOVLW 'R' CALL ED MOVLW 'E' CALL ED MOVLW 'Q' CALL ED MOVLW 'U' CALL ED MOVLW 'E' CALL ED MOVLW 'N' CALL ED MOVLW 'C' CALL ED MOVLW 'I' CALL ED MOVLW 'A' CALL ED MOVLW ':' CALL ED MOVLW ' ' CALL ED MOVLW ' ' CALL ED MOVLW LINHA2 ;MUDA DE LINHA DO LCD CALL EC MOVLW .10 MOVWF TEMP1 ;QUANTIDADE DE CARACTERES POSSIVÉIS DE SEREM APRESENTADOS (1 NIBLLE) MOVLW RES4 MOVWF FSR ; ENDEREÇO INICIAL DO CONTADOR A SER MOSTRADO CLRF CONTP ;ZERA CONTADOR PARA INDICAR MOMENTO DE INSERÇÃO DO PONTO '.' V2A CLRWDT MOVFW CONTP XORLW .4 BTFSS STATUS,Z ;TESTA SE HORA DE MOSTRA O '.'(PONTO) GOTO SNORM BTFSS EPZ1 ;TESTA SE JÁ APARECEU DIGITO DIFERENTES DE '0' GOTO NNEC ;AINDA NÃO APARECEU, SOMENTE ZEROS A ESQUERDA MOVLW '.' ;JÁ APARECEU. MOSTRAR PONTO CALL LcdSendData ;ENVIA PARA LCD NNEC CLRF CONTP ;ZERA CONTADOR INCF CONTP,F ;INCREMENTA PARA ACERTAR NO LUGAR CERTO O PROXIMO PONTO SNORM MOVLW '0' MOVWF AUX ;VALOR PARA COMPARAÇÃO MOVFW INDF ;PEGA VALOR PELO END.FSR MOVWF TEMP ;PEGA UM NIBLE POR VEZ PARA APRESENTAR BTFSS TEMP1,0 ;PAR= PULA NIBLE LOW SWAPF TEMP,F ;IMPAR= SWAPF NIBLE HIGH DO DADO MOVFW TEMP CALL BIN_ASC ;CONVERTE PARA ASCII ANTES DE ENVIAR PARA LCD XORWF AUX,F ;TESTA PARA VER SE É UM '0'(ZERO) BTFSS STATUS,Z GOTO ENVJ ;DIFERENTE DE ZERO BTFSS EPZ1 ; TESTA SE ULTIMO CARACTER FOI DIFERENTE DE ZERO MOVLW ' ' ; FOI ZERO,ENVIA ESPAÇO ' ' ENVJ1 CALL LcdSendData ;DIFERENTE DE '0',ENVIA '0' ,POIS JÁ NÃO É A ESQUERDA DE UM NUMERO BTFSC TEMP1,0 INCF FSR,F INCF CONTP,F DECFSZ TEMP1,F GOTO V2A MOVLW ' ' ;ENVIA ESPAÇO P/ LIMPEZA DE RESIDUOS DE LEITURA ANTERIOR COM 2 PONTOS CALL ED MOVLW ' ' ;ENVIA ESPAÇO CALL ED BTFSC EPZ1 GOTO SFJ MOVLW 0XC9 CALL EC MOVLW '0' ;MOSTRA ZERO ('0') NO RESULTADO , POIS ESTÁ SEM SINAL NA ENTRADA CALL ED SFJ MOVLW 0XCD ;envia a palavra 'hz' na posição 0xcd CALL EC MOVLW 'h' CALL ED MOVLW 'z' CALL ED MOVLW ' ' CALL ED BCF EPZ1 ;APAGA FLAG DE ZEROS A ESQUERDA RETURN ENVJ BSF EPZ1 ;SETA FLAG GOTO ENVJ1 ;================================================ ; rotina de conversão de decimal para ascii BIN_ASC ANDLW 0X0F ;LIMITA 0-F ADDLW 0XF6 BTFSC STATUS,C ADDLW 0X07 ADDLW 0X3A RETURN ;======================================================================== ; rotina de delay de 1 seg com verificação de overflow do timer 0 ;======================================================================== T1SEG MOVLW 0XFF MOVWF CONT1 VG1 MOVLW .185 MOVWF T1 VG CLRWDT DECFSZ CONT1,F GOTO VJ DECFSZ T1,F GOTO VG MOVLW .255 MOVWF CONT1 VG2 GOTO $+1 CLRWDT GOTO $+1 GOTO $+1 NOP DECFSZ CONT1,F GOTO VJA CLRWDT MOVLW .55 MOVWF T1 VG3 DECFSZ T1,F GOTO VJB NOP GOTO $+1 GOTO $+1 GOTO $+1 GOTO $+1 GOTO $+1 GOTO $+1 GOTO $+1 GOTO $+1 NOP RETURN VJ CALL TESTA ;veriica se houve um 'overflow' do timer 0 GOTO VG VJA CALL TESTA GOTO VG2 VJB CALL TESTA GOTO VG3 ;------------------------------------------ ; ROTINA DE TESTE DE OVERFLOW DO TIMER 0 TESTA BTFSS INTCON,2 ; FLAG DE OVER TMR0 GOTO VJ1X BCF INTCON,2 INCFSZ TMR_UL,F GOTO VJ2X INCF TMR_UH,F GOTO VJ3X ;SEQUENCIA DE RETORNO QUE GARANTEM SEMPRE O MESMO TEMPO TOTAL VJ1X NOP NOP NOP VJ2X NOP NOP VJ3X NOP NOP VJ4X CLRWDT RETURN END