Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #INCLUDE <p16f628a.inc>
- ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- ;* ARQUIVOS DE DEFINICOES *
- ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- ; DEFINICOES
- __CONFIG _BODEN_OFF & _CP_OFF & _PWRTE_ON & _WDT_ON & _MCLRE_ON & _INTRC_OSC_CLKOUT & _LVP_OFF
- ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- ;* PAGINACAO DE MEMORIA *
- ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- ;DEFINICAO DE COMANDOS DE USUARIO PARA ALTERACAO DA PAGINA DE MEMORIA
- ;DEFINICAO DOS BANCOS
- #DEFINE BANK0 BCF STATUS, RP0 ; SETA BANK 0 DE MEMORIA
- #DEFINE BANK1 BSF STATUS, RP0 ; SETA BANK 1 DE MEMORIA
- #DEFINE BANKA BCF STATUS, RP1 ; SETA O BANK A
- #DEFINE BANKB BSF STATUS, RP1
- ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- ;* VARIÁVEIS *
- ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- ; DEFINICAO DOS NOMES E ENDERECOS DE TODAS AS VARIAVEIS UTILIZADAS
- ; PELO SISTEMA
- CBLOCK 0x20 ;ENDERECO INICIAL DA MEMORIA DE USUARIO
- W_TEMP ;REGISTRADORES TEMPORARIOS PARA USO
- STATUS_TEMP ;JUNTO AS INTERRUPCOES
- ;NOVAS VARIAVEIS
- ESPERAPTR_AUX ; Variáveis utilizadas no cálculo do sinal do DHT11
- OVERFLOW
- BYTES_COUNT ; Contador para identificar quantos bytes temos (0-4)
- BITS_COUNT ; Contador para identificar quantos bits temos (0-8)
- TIME_HIGH ; Mede o tempo em HIGH do sinal
- TEMP_INT ; Temperatura - inteiro - Valor exibido no display
- TEMP_DEC ; Temperatura - decimal
- UMI_INT ; Umidade - inteiro - Valor exibido no display
- UMI_DEC ; Umidade - decimal
- ENTRADA ; Recebe os 8 bits que serão associados às variáveis
- COUNT0 ; Contadores auxiliares
- COUNT1
- COUNT2
- DIVISOR ; Divisor
- DIV_TEMP ; Resultado da divisão
- ; Variáveis das funções do LCD
- PTR_AUX ; Auxiliar
- DATA_EE ; Dado para escrita na EEPROM
- STR_VALUE ; Valor a ser convertido em string
- STR_COMP ; Complemento para a string
- STR_POSITION ; Posição de escrita da string em Stringfy
- LCD_LINE ; Linha indicada para inserção no LCD
- ENDC ;FIM DO BLOCO DE MEMORIA
- CBLOCK 0x30
- AUTHOR: .16 ; String p/ nome do autor (16 pos) - Addr 0x30
- INFO: .20 ; String da segunda linha (temp e ur, 20 pos) - Addr 0x40
- ; Ponteiros para o fim das strings
- TEMP_PTR ; Ponteiro para a posição da temperatura no string 0x45
- UR_PTR ; Ponteiro para a posição da umidade no string 0x4D
- ENDC
- ;*******************************************************************************
- ; Constantes do Programa
- ;*******************************************************************************
- ORG 0x2130
- DE "Johannes\0"
- ORG 0x2140
- DE "Temp= C UR= %\0"
- ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- ;* VETOR DE RESET *
- ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- ORG 0x00 ;ENDERE?O INICIAL DE PROCESSAMENTO
- GOTO INICIO
- ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- ;* INÍCIO DA INTERRUPÇÃO *
- ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- ; ENDERECO DE DESVIO DAS INTERRUPCOES. A PRIMEIRA TAREFA E SALVAR OS
- ; VALORES DE "W" E "STATUS" PARA RECUPERACAO FUTURA
- ORG 0x04 ;ENDEREÇO INICIAL DA INTERRUPÇÃO
- MOVWF W_TEMP ;COPIA W PARA W_TEMP
- SWAPF STATUS,W
- BCF STATUS,RP0
- MOVWF STATUS_TEMP ;COPIA STATUS PARA STATUS_TEMP
- ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- ;* ROTINA DE SAÍDA DA INTERRUPÇÃO *
- ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- ; OS VALORES DE "W" E "STATUS" DEVEM SER RECUPERADOS ANTES DE
- ; RETORNAR DA INTERRUPÇÃO
- SAI_INT
- SWAPF STATUS_TEMP,W
- MOVWF STATUS ;MOVE STATUS_TEMP PARA STATUS
- SWAPF W_TEMP,F
- SWAPF W_TEMP,W ;MOVE W_TEMP PARA W
- RETFIE
- ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- ;* ROTINAS E SUBROTINAS *
- ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- ; CADA ROTINA OU SUBROTINA DEVE POSSUIR A DESCRIÇÃO DE FUNCIONAMENTO
- ; E UM NOME COERENTE AS SUAS FUNÇÕES.
- ; Função que verifica quantos bytes já foram lidos e seleciona a variável
- ; associada a este número que será selecionada para alocar o conteúdo do sinal
- ; Como receberemos 4 bytes contendo: Umidade inteira e decimal, Temperatura inteira e decimal
- ; O primeiro byte será umidade inteira
- ; O 2º será umidade decimal
- ; O 3º será temperatura inteira
- ; O 4º será temperatura decimal
- SELECIONA_VARIAVEL
- MOVLW .1
- SUBWF BYTES_COUNT, W
- BTFSC STATUS, Z ; Caso (Nº de bytes - 1) seja = 0
- GOTO UMIDADE_INTEIRA ; Vamos associar o valor de ENTRADA à umidade inteira
- MOVLW .2
- SUBWF BYTES_COUNT, W
- BTFSC STATUS, Z ; Caso (Nº de bytes - 2) seja = 0
- GOTO UMIDADE_DECIMAL ; Vamos associar o valor de ENTRADA à umidade decimal
- MOVLW .3
- SUBWF BYTES_COUNT, W
- BTFSC STATUS, Z ; Caso (Nº de bytes - 3) seja = 0
- GOTO TEMPERATURA_INTEIRA ; Vamos associar o valor de ENTRADA à umidade inteira
- MOVLW .4
- SUBWF BYTES_COUNT, W
- BTFSC STATUS, Z ; Caso (Nº de bytes - 4) seja = 0
- GOTO TEMPERATURA_DECIMAL ; Vamos associar o valor de ENTRADA à umidade inteira
- GOTO LEITURA
- ;ATRIBUICAO NAS VARIAVEIS DE PARTES INTEIRAS E DECIMAIS
- UMIDADE_INTEIRA
- MOVFW ENTRADA
- MOVWF UMI_INT
- GOTO LEITURA
- UMIDADE_DECIMAL
- MOVFW ENTRADA
- MOVWF UMI_DEC
- GOTO LEITURA
- TEMPERATURA_INTEIRA
- MOVFW ENTRADA
- MOVWF TEMP_INT
- GOTO LEITURA
- TEMPERATURA_DECIMAL
- MOVFW ENTRADA
- MOVWF TEMP_DEC
- GOTO LCD
- DIVIDE
- ; Divide o valor em W pelo valor em DIVSR
- ; Retorna o resultado em DIV_TEMP e resto em W
- MOVWF PTR_AUX ; Salva o dividendo em um auxiliar e
- CLRF DIV_TEMP ; limpa o resultado de divisões anteriores
- MOVLW .0
- DIV_LOOP
- MOVFW DIVISOR ; Copia o valor do divisor para W
- SUBWF PTR_AUX, W ; (dividendo - divisor) subtrai o valor do divisor
- BTFSS STATUS, C ; e verifica se o reultado da operação é positivo
- GOTO TERMINA_DIV ; Se o resultado é negativo, a divisão termina.
- MOVWF PTR_AUX ; Caso o resultado seja positivo ainda, atualiza
- INCF DIV_TEMP ; o dividendo e incrementa o resultado
- GOTO DIV_LOOP ; e volta para o loop.
- TERMINA_DIV
- MOVFW PTR_AUX ; No final da divisão o resto está no auxiliar,
- RETURN ; copia para o work e retorna a função.
- ; _____ ______ __ __ ______ __ __ __ __ ________ ______
- ; | \ / \ | \ | \ / \ | \ | \| \ | \| \ / \
- ; \$$$$$| $$$$$$\| $$ | $$| $$$$$$\| $$\ | $$| $$\ | $$| $$$$$$$$| $$$$$$\
- ; | $$| $$ | $$| $$__| $$| $$__| $$| $$$\| $$| $$$\| $$| $$__ | $$___\$$
- ; __ | $$| $$ | $$| $$ $$| $$ $$| $$$$\ $$| $$$$\ $$| $$ \ \$$ \
- ;| \ | $$| $$ | $$| $$$$$$$$| $$$$$$$$| $$\$$ $$| $$\$$ $$| $$$$$ _\$$$$$$\
- ;| $$__| $$| $$__/ $$| $$ | $$| $$ | $$| $$ \$$$$| $$ \$$$$| $$_____ | \__| $$
- ; \$$ $$ \$$ $$| $$ | $$| $$ | $$| $$ \$$$| $$ \$$$| $$ \ \$$ $$
- ; \$$$$$$ \$$$$$$ \$$ \$$ \$$ \$$ \$$ \$$ \$$ \$$ \$$$$$$$$ \$$$$$$
- EE_READ
- ; Lê o dado da EEPROM, endereço indicado em W
- ; Dado lido retornado em W
- ANDLW .127 ; Limita endereço max em 127
- BANKA
- BANK1
- MOVWF EEADR ; Endereço para leitura
- BSF EECON1, RD ; Inicia leitura
- MOVFW EEDATA ; Retorna o valor lido para W
- BANK0
- RETURN
- EE_WRITE
- ; Escreve dado (DATA_EE) na EEPROM, cujo endereço é indicado em W
- ANDLW .127 ; Limita endereço max em 127
- BANKA
- BANK1
- MOVWF EEADR
- MOVFW DATA_EE
- MOVWF EEDATA
- BSF EECON1, WREN ; Habilita escrita
- BCF INTCON, GIE ; Desliga Interrupções
- MOVLW 0x55 ; Sequência necessária
- MOVWF EECON2
- MOVLW 0xAA
- MOVWF EECON2
- BSF EECON1, WR ; Inicia a escrita
- BTFSC EECON1, WR ; Espera o término da operação
- GOTO $-1
- BSF INTCON, GIE ; Habilita interrupções
- BANK0
- RETURN
- STRINGFY
- ; Transforma o valor decimal de duas casas em W em string e o escreve
- ; na posição indicada em STR_POSITION.
- MOVWF STR_VALUE ; Copiamos o valor para um auxiliar
- MOVLW .10 ; Dividimos então o número por 10, para pegar os dígitos
- MOVWF DIVISOR
- MOVFW STR_VALUE
- CALL DIVIDE ; Chamada da divisão
- MOVFW STR_POSITION ; Apontamos para a posição de gravação desada
- MOVWF FSR ; acessando indiretamente por FSR e INDF
- MOVFW DIV_TEMP ; O dígito mais significativo é o resultado da divisão
- ADDLW '0' ; por 10, e vem primeiro. Para que seu valor seja
- MOVWF INDF ; Convertido em string, somamos o valor do dígito ao
- ; valor correspondente ao 0 na tabela ascii.
- INCF FSR ; Incrementamos o ponteiro para salvar o outro dígito,
- MOVFW PTR_AUX ; menos significativo, resto da divisão (em _aux).
- ADDLW '0' ; Novamente somamos ao valor do char 0,
- MOVWF INDF ; e escrevemos de definitivo na string.
- RETURN
- LCD_INIT_4
- ; Subrotina de inicialização do display LCD com configuração de 4-bits
- BCF PORTB, RB2 ; Habilitamos escrita no display
- BCF PORTB, RB1 ; e selecionamos modo de instrução.
- MOVLW .235 ; Primeiro é realizada uma espera ocupada de 15ms (no min),
- MOVWF COUNT0 ; para que o LCD inicialize e espere a entrada.
- INCFSZ COUNT0 ; Cada contagem desse contador leva 772us em conjunto com o
- GOTO $+2 ; contador2 (abaixo), 19 deve ser suficiente para passar de
- GOTO $+4 ; 15ms.
- INCFSZ COUNT1 ; Cada contagem desse contador leva 3us,
- GOTO $-1 ; o que implica numa contagem total de aprox. 767us, com
- GOTO $-5 ; os jumps ocasionais.
- MOVLW B'00110000' ; Como especificado no datasheet, para inicializar o
- MOVWF PORTB ; LCD com 4 bits passamos 0b0011 nas portas DB7DB4.
- BSF PORTB, RB0 ; Ativamos a leitura por 1us
- BCF PORTB, RB0 ; e depois desativamos
- MOVLW .249 ; Depois é realizada uma espera ocupada de 4.1ms.
- MOVWF COUNT0
- INCFSZ COUNT0 ; Cada contagem desse contador leva 772us em conjunto com o
- GOTO $+2 ; contador2 (abaixo), 6 deve ser suficiente para passar de
- GOTO $+4 ; 4.1ms.
- INCFSZ COUNT1 ; Cada contagem desse contador leva 3us,
- GOTO $-1 ; o que implica numa contagem total de aprox. 767us, com
- GOTO $-5 ; os jumps ocasionais.
- BSF PORTB, RB0 ; Novamente gravamos a informação na porta do LCD.
- BCF PORTB, RB0
- MOVLW .221 ; Agora é realizada outra espera, dessa vez de 100us.
- MOVWF COUNT0
- INCFSZ COUNT0 ; Cada contagem desse contador leva 3us,
- GOTO $-1 ; 33 contagens é o suficiente para ~100us.
- BSF PORTB, RB0 ; Novamente gravamos a informação na porta do LCD.
- BCF PORTB, RB0
- MOVLW B'00100000' ; Agora gravamos 0b0010 no display, como parte do
- MOVWF TRISB ; protocolo de inicialização para utilizar 4 bits.
- BSF PORTB, RB0
- BCF PORTB, RB0
- MOVLW .242 ; Espera de no min 40us entre instruções
- MOVWF COUNT0
- INCFSZ COUNT0 ; Cada contagem desse contador leva 3us,
- GOTO $-1 ; 13 contagens é o suficiente para ~40us.
- ; Function Set
- MOVLW B'00100000' ; Defimos então o display para funcionar com 4 bits
- MOVWF TRISB
- BSF PORTB, RB0
- BCF PORTB, RB0
- MOVLW B'00110000' ; E então configuramos para utilizar duas linhas
- MOVWF TRISB ; e caracteres 5x7.
- BSF PORTB, RB0
- BCF PORTB, RB0
- MOVLW .242 ; Espera de no min 40us entre instruções
- MOVWF COUNT0
- INCFSZ COUNT0 ; Cada contagem desse contador leva 3us,
- GOTO $-1 ; 13 contagens é o suficiente para ~40us.
- ; Display off
- CALL LCD_OFF
- MOVLW .242 ; Espera de no min 40us entre instruções
- MOVWF COUNT0
- INCFSZ COUNT0 ; Cada contagem desse contador leva 3us,
- GOTO $-1 ; 13 contagens é o suficiente para ~40us.
- ; Clear display
- CALL LCD_CLEAR
- MOVLW .242 ; Espera de no min 40us entre instruções
- MOVWF COUNT0
- INCFSZ COUNT0 ; Cada contagem desse contador leva 3us,
- GOTO $-1 ; 13 contagens é o suficiente para ~40us.
- ; Entry Mode config
- CLRF TRISB ; Configurando modo de incremento, sem shift do display.
- BSF PORTB, RB0
- BCF PORTB, RB0
- MOVLW B'01100000'
- MOVWF TRISB
- BSF PORTB, RB0
- BCF PORTB, RB0
- MOVLW .242 ; Espera de no min 40us entre instruções
- MOVWF COUNT0
- INCFSZ COUNT0 ; Cada contagem desse contador leva 3us,
- GOTO $-1 ; 13 contagens é o suficiente para ~40us.
- RETURN
- LCD_OFF
- ; Desliga o LCD (APENAS PARA 4 BITS!)
- BCF PORTB, RB2 ; Habilitamos escrita no display
- BCF PORTB, RB1 ; e selecionamos modo de instrução.
- CLRF TRISB ; Desligamos o display com o byte 0b00001000
- BSF PORTB, RB0
- BCF PORTB, RB0
- MOVLW B'10000000'
- MOVWF TRISB
- BSF PORTB, RB0
- BCF PORTB, RB0
- RETURN
- LCD_CLEAR
- ; Limpa os dados mostrados no LCD (APENAS PARA 4 BITS!)
- BCF PORTB, RB2 ; Habilitamos escrita no display
- BCF PORTB, RB1 ; e selecionamos modo de instrução.
- CLRF TRISB ; Limpamos o display com o byte 0b00000001
- BSF PORTB, RB0
- BCF PORTB, RB0
- MOVLW B'00010000'
- MOVWF TRISB
- BSF PORTB, RB0
- BCF PORTB, RB0
- RETURN
- LCDLCD_LINE
- ; Envia a string em W para o display LCD na linha indicada em LCD_LINE (1 ou 2)
- MOVWF PTR_AUX ; Salvamos temporariamente o string
- MOVFW LCD_LINE ; Verificamos se LCD_LINE é 1 ou 2
- SUBLW .1
- BTFSC STATUS, Z ; Sutraindo por 1, verificamos se o resultado é 0
- GOTO LINE1 ; se for, a linha é 1
- MOVFW LCD_LINE
- SUBLW .2
- BTFSC STATUS, Z ; Sutraindo por 2, verificamos se o resultado é 0
- GOTO LINE2 ; se for, a linha é 2
- RETURN ; Caso nada se aplique, retorna
- LINE1
- MOVLW 0x00 ; Configurando a posição do cursor
- GOTO LCD_SEND ; para o início do display
- LINE2
- MOVLW 0x40 ; Configurando a posição do cursor
- ; para o início da segunda linha
- LCD_SEND
- ANDLW 0xF0 ; Com um AND pegamos o nibble mais significativo
- MOVWF TRISB ; e escrevemos para o lcd.
- BSF TRISB, RB7 ; O bit7 do display é 1 para instrução de endereçamento
- BCF PORTB, RB1 ; Ativamos o modo de instrução
- BCF PORTB, RB2 ; e escrita.
- BSF PORTB, RB0 ; Com o enable o dado no PORTB pode ser lido pelo LCD
- BCF PORTB, RB0 ; Desativa o enable para terminar escrita
- CLRF TRISB ; O nibble menos sig. é sempre 0, então limpa TRISB
- BSF PORTB, RB0 ; Abilita escrita com enable.
- BCF PORTB, RB0 ; Desabilita escrita com enable.
- MOVFW PTR_AUX ; Copia o ponteiro da string para
- MOVWF FSR ; ponteiro de endereçamento indireto
- LOOP_STR
- MOVFW INDF
- SUBLW '\0'
- BTFSC STATUS, Z
- RETURN
- MOVFW INDF ; Seleciona o primeiro nibble do caractere com AND
- ANDLW 0xF0
- MOVWF TRISB ; Manda o valor para a porta
- BSF PORTB, RB1 ; Configura LCD para envio de dados
- BCF PORTB, RB2 ; Configura modo de escrita
- BSF PORTB, RB0 ; Abilita o envio
- BCF PORTB, RB0 ; Desabilita o envio
- MOVFW INDF ; Seleciona novamente o caractere
- SWAPF INDF, W ; Troca seus nibbles
- ANDLW 0xF0 ; e seleciona o segundo nibble (agora primeiro, trocado).
- MOVWF TRISB ; Manda o valor para a porta
- BSF PORTB, RB1 ; Configura LCD para envio de dados
- BCF PORTB, RB2 ; Configura modo de escrita
- BSF PORTB, RB0 ; Abilita o envio
- BCF PORTB, RB0 ; Desabilita o envio
- INCF FSR ; Incrementa o ponteiro da string
- GOTO LOOP_STR ; e volta para o loop de leitura da string.
- ;ROTINA QUE COLOCA O CONTROLADOR EM MODO SLEEP
- DORME
- BANK1
- BCF TRISA, 0
- BANK0
- BSF PORTA, RA0
- SLEEP
- NOP
- ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- ;* INICIO DO PROGRAMA *
- ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- INICIO
- BANK1
- MOVLW B'00000010'
- MOVWF TRISA
- MOVLW B'00000000'
- MOVWF TRISB
- MOVLW B'10001111'
- MOVWF OPTION_REG
- MOVLW B'00000000'
- MOVWF INTCON
- BANK0
- MOVLW B'00000111'
- MOVWF CMCON
- ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- ;* INICIALIZACAO DAS VARIÁVEIS *
- ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- ;LIMPA AS VARIAVEIS
- CLRF TIME_HIGH
- CLRF BITS_COUNT
- CLRF BYTES_COUNT
- CLRF ENTRADA
- CLRF UMI_INT
- CLRF UMI_DEC
- CLRF TEMP_INT
- CLRF TEMP_DEC
- CLRF ESPERAPTR_AUX
- CLRF OVERFLOW
- CLRF PORTB
- MOVLW 0x45 ; Inincializa a os ponteiros com as posições na string
- MOVWF TEMP_PTR ; TEMP_PTR = 0x45
- MOVLW 0x4D
- MOVWF UR_PTR ; UR_PTR = 0x4D
- MOVLW 0x30 ; Começa a leitura da primeira string (autor) na posição
- MOVWF FSR ; 0x30 para copiar da EEPROM para a RAM.
- READ_NAME
- MOVFW FSR ; Copia a o ponteiro para o work
- CALL EE_READ ; e lê a posição correspondente na EEPROM.
- MOVWF INDF ; Copia o caractere lido para a RAM, na posição apontada
- INCF FSR ; em FSR, e incrementa o ponteiro para o prox char.
- SUBLW '\0' ; Subtraimos pelo caractere '\0' (término)
- BTFSS STATUS, Z ; para verificar se a string chegou ao fim.
- GOTO READ_NAME ; Em caso negativo, volta para o loop para ler o próximo
- ; caractere.
- MOVLW 0x40 ; Agora vamos ler a segunda string (segunda linha) salva na
- MOVWF FSR ; posição 0x40 da EEPROM e escrever na mesma posição na RAM.
- READ_TEXT1
- MOVFW FSR ; Copia a o ponteiro para o work
- CALL EE_READ ; e lê a posição correspondente na EEPROM.
- MOVWF INDF ; Copia o caractere lido para a RAM, na posição apontada
- INCF FSR ; em FSR, e incrementa o ponteiro para o prox char.
- SUBLW '\0' ; Subtraimos pelo caractere '\0' (término)
- BTFSS STATUS, Z ; para verificar se a string chegou ao fim.
- GOTO READ_TEXT1 ; Em caso negativo, volta para o loop para ler o próximo
- ; caractere.
- CALL LCD_INIT_4 ; Por fim, executamos a rotina de inicialização do LCD
- ; configurando-o para utilizar 4 bits.
- MOVLW .1 ; Definimos a primeira linha para escrita no display.
- MOVWF LCD_LINE
- MOVLW 0x30 ; Enviamos a posição da primeira string para a
- CALL LCDLCD_LINE ; função LCDLCD_LINE, que escreve a string na linha dada.
- ; Como essa primeira linha é constante, não varia,
- ; ela é apenas enviada uma vez.
- BSF PORTA, RA0 ;GARANTE A PORTA EM 1, POIS QUANDO FOR ZERO JA SERA O SINAL PRA O SENSOR TRANSMITIR
- GOTO MAIN
- ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- ;* ROTINA PRINCIPAL *
- ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- MAIN
- CLRWDT ; Por padrão, reinicia a contagem do WatchDog no início.
- ESPERA_OCUPADA ; Espera ocupada do WDT
- BTFSS STATUS, 4 ;VERIFICA SE O POWER-ON FOI CAUSADO PELO WDT
- GOTO ESPERA ;CASO TENHA SIDO, VAI PRA ESPERA
- GOTO DORME ;CASO NAO, VOLTA A DORMIR
- ESPERA
- BCF PORTA, RA0 ; Colocamos RA0 em 0 e logo em seguida aguardamos 18ms
- ; Função utiliza duas variáveis auxiliares, ESPERAPTR_AUX e OVERFLOW
- ; para obter o tempo de 18ms que necessitamos esperar para o DHT11
- ; conseguir detectar o sinal.
- ITER_ESPERA
- INCF ESPERAPTR_AUX ; Incrementamos ESPERAPTR_AUX
- BTFSC STATUS, C ; Verificamos se há estouro (ESPERAPTR_AUX > 255)
- INCF OVERFLOW ; Caso seja, incrementamos OVERFLOW
- MOVLW .8 ; Movemos 8 ao work
- SUBWF OVERFLOW, W ; Subtraímos OVERFLOW por work
- BTFSS STATUS, Z ; Se for diferente de zero (OVERFLOW != 8)
- GOTO ITER_ESPERA ; realizamos mais uma iteração
- GOTO PRE_LEITURA ; Na última iteração teremos um tempo de aproximadamente 18.400us
- ; Após aguardamos os 18ms estabelecidos pelo fabricante, iremos configurar a
- ; porta RA0 como porta de entrada.
- PRE_LEITURA
- BSF PORTA, RA0 ; Colocamos o sinal da porta RA0 como 1, para sinalizar entrada
- BANK1
- BSF TRISA, 0 ; Configuramos a RA0 como entrada no TRISA
- BANK0
- IDLE_WAIT_1
- BTFSC PORTA, RA0 ; Aguardando o DHT11 jogar o sinal de RA0 para 0
- GOTO IDLE_WAIT_1 ; Enquanto não ocorrer, fazemos uma espera ocupada
- IDLE_WAIT_2
- BTFSS PORTA, RA0 ; Esperamos o momento em que o DHT11 sobe o RA0
- GOTO IDLE_WAIT_2 ; Enquanto não ocorrer, fazemos uma espera ocupada
- PREPARA_TRANSMISSAO
- BTFSC PORTA, RA0 ; Aguardamos a porta ir pra zero, que irá sinalizar
- ; o começo da transmissão de dados.
- GOTO PREPARA_TRANSMISSAO
- GOTO LEITURA ; Quando tivermos o fim do pulso, vamos à função de leitura
- ; Função que armazena os dados transmitidos
- LEITURA
- CLRF BITS_COUNT ; Limpamos o contador de BITS da variável
- INCF BYTES_COUNT ; Contamos quantas variáveis (bytes) foram lidas
- LEITURA_BIT
- BTFSS PORTA, RA0 ; Verificamos se o sinal é zero
- GOTO LEITURA_BIT ; Caso seja, continuamos a espera ocupada
- INCF BITS_COUNT ; Caso não seja, incrementamos o contador de bits e iremos interpretar o valor
- ITER_LEITURA ; Iremos iterar para interpretar o sinal BIT a BIT
- ; TIME_HIGH armazena o tempo em que o sinal esteve em alta (HIGH)
- ; se esteve de 26-28 uS, o sinal é 0, se esteve por 70 uS, o sinal é 1
- INCF TIME_HIGH ; Incrementamos CONTA_lEITURA
- BTFSC PORTA, RA0 ; Enquanto o sinal estiver em alta, iremos
- GOTO ITER_LEITURA ; retornar ao início desta função e incrementar TIME_HIGH novamente
- ; O número 10 foi escolhido de forma empírica após perceber que se tiver
- ; menos do que 10 ciclos o valor a ser armazenado é 0, caso contrário é 1
- MOVLW .10 ; Movemos 10 ao work para verificar se o número armazenado é um 0 ou 1
- SUBWF TIME_HIGH, W ; Subtraímos TIME_HIGH por W
- BTFSC STATUS, C ; Seguimos a lógica descrita acima checando o carry para conferir o valor.
- BSF ENTRADA, 0
- CLRF TIME_HIGH ; Fim da leitura do BIT
- MOVLW .8
- SUBWF BITS_COUNT, W ; Verificamos se o BIT contado foi o último
- BTFSC STATUS, Z
- GOTO SELECIONA_VARIAVEL ; Caso tenha sido, salvaremos o valor do byte na variável
- RLF ENTRADA, 1 ; Caso não seja, empurramos o BIT pra esquerda
- GOTO LEITURA_BIT ; Vamos à leitura do próximo bit
- ; _____ ______ __ __ ______ __ __ __ __ ________ ______
- ; | \ / \ | \ | \ / \ | \ | \| \ | \| \ / \
- ; \$$$$$| $$$$$$\| $$ | $$| $$$$$$\| $$\ | $$| $$\ | $$| $$$$$$$$| $$$$$$\
- ; | $$| $$ | $$| $$__| $$| $$__| $$| $$$\| $$| $$$\| $$| $$__ | $$___\$$
- ; __ | $$| $$ | $$| $$ $$| $$ $$| $$$$\ $$| $$$$\ $$| $$ \ \$$ \
- ;| \ | $$| $$ | $$| $$$$$$$$| $$$$$$$$| $$\$$ $$| $$\$$ $$| $$$$$ _\$$$$$$\
- ;| $$__| $$| $$__/ $$| $$ | $$| $$ | $$| $$ \$$$$| $$ \$$$$| $$_____ | \__| $$
- ; \$$ $$ \$$ $$| $$ | $$| $$ | $$| $$ \$$$| $$ \$$$| $$ \ \$$ $$
- ; \$$$$$$ \$$$$$$ \$$ \$$ \$$ \$$ \$$ \$$ \$$ \$$ \$$$$$$$$ \$$$$$$
- LCD
- MOVFW TEMP_PTR ; Copiamos o ponteiro para a posição da temperatura
- MOVWF STR_POSITION ; no string de informação para a função STRINGFY
- MOVFW TEMP_INT ; que insere a informação lida de temperatura na
- CALL STRINGFY ; posição designada da string.
- MOVFW UR_PTR ; Copiamos o ponteiro para a posição da umidade
- MOVWF STR_POSITION ; no string de informação para a função STRINGFY
- MOVFW UMI_INT ; que insere a informação lida de umidade na
- CALL STRINGFY ; posição designada da string.
- MOVLW .2 ; Definimos linha 2 para escrita de dados no display.
- MOVWF LCD_LINE
- MOVLW 0x40 ; Enviamos a posição da string de dados para a
- CALL LCDLCD_LINE ; função LCDLCD_LINE, que escreve a string na linha dada.
- CALL DORME ; Finalizando a operação, o microcontrolador é configurado para
- GOTO $ ; adormecer, economizando energia. É despertado pelo WDT depois.
- ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- ;* FIM DO PROGRAMA *
- ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- END
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement