Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- ; ____ __ _ _ _ _ ____ __
- ;/ ___) / _\ ( \/ )/ )( \( __)( )
- ;\___ \/ \/ \/ \) \/ ( ) _) / (_/\
- ;(____/\_/\_/\_)(_/\____/(____)\____/
- ;
- ; Microcontroladores, 2017.2
- ; Atividade 2 - Unidade 3
- ; Samuel Silveira Pordeus - 11400947
- #INCLUDE <p16f628a.inc>
- ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- ;* ARQUIVOS DE DEFINICOES *
- ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- ; DEFINICOES
- __CONFIG _FOSC_INTOSCCLK & _WDTE_ON & _PWRTE_OFF & _MCLRE_ON & _BOREN_ON & _LVP_OFF & _CPD_OFF & _CP_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 BANK2 BCF STATUS, RP1 ; SETA BANK 2 DE MEMORIA
- #DEFINE BANK3 BSF STATUS, RP1 ; SETA BANK 3 DE MEMORIA
- ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- ;* 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
- ESPERA_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
- IDLE_LCD01 ; Contadores auxiliares
- IDLE_LCD02
- DIVISOR ; Divisor
- DIV_VALUE ; Resultado da divisão
- ; Variáveis das funções do LCD
- DIV_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 0x40
- 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 0x2140
- DE "Samuel\0"
- ORG 0x2150
- 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ções do DHT11
- ; 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
- BANK1
- BCF TRISA, RA0
- BANK0
- BSF PORTA, RA0
- GOTO LCD
- DIVIDE
- ; Divide o valor em W pelo valor em DIVSR
- ; Retorna o resultado em DIV_VALUE e resto em W
- MOVWF DIV_AUX ; Salva o dividendo em um auxiliar e
- CLRF DIV_VALUE ; limpa o resultado de divisões anteriores
- MOVLW .0
- DIV_LOOP
- MOVFW DIVISOR ; Copia o valor do divisor para W
- SUBWF DIV_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 DIV_AUX ; Caso o resultado seja positivo ainda, atualiza
- INCF DIV_VALUE ; o dividendo e incrementa o resultado
- GOTO DIV_LOOP ; e volta para o loop.
- TERMINA_DIV
- MOVFW DIV_AUX ; No final da divisão o resto está no auxiliar,
- RETURN ; copia para o work e retorna a função.
- ; Funções da EEPROM
- LE_EEPROM
- ;LER DADO DA EEPROM, CUJO ENDEREÇO É INDICADO EM W
- ;DADO LIDO RETORNA EM W
- ANDLW .127 ;LIMITA ENDEREÇO MAX. 127
- BANK2
- BANK1
- MOVWF EEADR ;INDICA O END. DE LEITURA
- BSF EECON1, RD ;INICIA O PROCESSO DE LEITURA
- MOVFW EEDATA ;COLOCA DADO LIDO EM W
- BANK0
- RETURN
- GRAVA_EEPROM
- ;ESCREVE DADO (DADO) NA EEPROM, CUJO ENDEREÇO É INDICADO EM W
- ANDLW .127 ;LIMITA ENDEREÇO MAX. 127
- BANK2
- BANK1
- MOVWF EEADR
- MOVFW DATA_EE
- MOVWF EEDATA
- BSF EECON1, WREN ;HABILITA ESCRITA
- BCF INTCON, GIE ;DESLIGA INTERRUPÇÕES
- MOVLW B'01010101';DESBLOQUEIA ESCRITA
- MOVWF EECON2
- MOVLW B'10101010'
- MOVWF EECON2
- BSF EECON1, WR ;INICIA ESCRITA
- AGUARDA
- BTFSC EECON1,WR ; TERMINOU?
- GOTO AGUARDA
- BSF INTCON,GIE ; HABILITA INTERRUPÇÕES
- BANK0 ; POSICIONA PARA BANK 0
- RETURN
- ; Funções do LCD
- ; Função que limpa os dados do LCD no modo 4 BITS
- LCD_CLEAR
- BCF PORTB, RB2 ; Ligamos a escrita escrita no display
- BCF PORTB, RB1 ; e ativamos o modo de instrução
- CLRF TRISB
- BSF PORTB, RB0
- BCF PORTB, RB0
- MOVLW B'00010000'
- MOVWF TRISB
- BSF PORTB, RB0
- BCF PORTB, RB0
- RETURN ; Retorna à função que a chamou
- ; Função que liga o LCD no modo 4 BITS
- LCD_ON
- ; Liga o LCD (APENAS PARA 4 BITS!)
- BCF PORTB, RB2 ; Ligamos a escrita escrita no display
- BCF PORTB, RB1 ; e ativamos o modo de instrução
- CLRF TRISB ; Desligamos o display
- BSF PORTB, RB0
- BCF PORTB, RB0
- MOVLW B'11000000'
- MOVWF TRISB
- BSF PORTB, RB0
- BCF PORTB, RB0
- RETURN ; Retorna à função que a chamou
- LCD_OFF
- ; Desliga o LCD (APENAS PARA 4 BITS!)
- BCF PORTB, RB2 ; Ligamos a escrita escrita no display
- BCF PORTB, RB1 ; e ativamos o modo de instrução
- CLRF TRISB ; Desligamos o display
- BSF PORTB, RB0
- BCF PORTB, RB0
- MOVLW B'10000000'
- MOVWF TRISB
- BSF PORTB, RB0
- BCF PORTB, RB0
- RETURN ; Retorna à função que a chamou
- LCD_CHOOSE_LINE
- ; Envia o cohteúdo do work ao LCD onde for indicado pelo LCD_LINE
- MOVWF DIV_AUX ; Salvamos o valor
- MOVFW LCD_LINE ; Checamos qual linha utilizaremos
- SUBLW .1
- BTFSC STATUS, Z ; Verificamos se o resultado da subtração é 0
- GOTO LINE1 ;Caso seja, a linha é 1
- MOVFW LCD_LINE
- SUBLW .2
- BTFSC STATUS, Z ; Verificamos se o resultado da subtração é 0
- GOTO LINE2 ; Caso seja, a linha é 1
- RETURN ; Caso não seja nennhum dos dois casos, retornamos
- LINE1 ; Cursor -> linha 1
- MOVLW 0x00
- GOTO LCD_SEND ; Apontamos para o início do display
- LINE2 ; Cursor -> linha 2
- MOVLW 0x40
- ; Apontamos para o início da 2ª linha do display
- LCD_SEND
- ; Aqui configuramos o envio para o LCD, seguindo as orientações do fabricante
- ANDLW B'11110000'; Fazemos um AND para pegar os bits mais significativos
- MOVWF TRISB
- ; Configuramos bit a bit:
- BSF TRISB, RB7 ; Endereçamento
- BCF PORTB, RB1 ; Modo de instrução
- BCF PORTB, RB2 ; Modo de escrita
- BSF PORTB, RB0 ; O dado no PORTB será lido pelo display
- BCF PORTB, RB0 ; Desativa o enable para terminar escrita
- CLRF TRISB ; Limpamos o TRISB
- BSF PORTB, RB0 ; Habilitamos a escrita com enable.
- BCF PORTB, RB0 ; Desabilitamos a escrita com enable.
- CALL LCD_ESPERA
- MOVFW DIV_AUX ; Copia a variável auxiliar da string para o work
- MOVWF FSR ; e do work para o FSR
- LOOP_STR
- MOVFW INDF
- SUBLW '\0'
- BTFSC STATUS, Z
- RETURN
- MOVFW INDF ; Seleciona os 4 primeiros bits utilizando um AND
- ANDLW B'11110000'
- MOVWF TRISB
- BSF PORTB, RB1 ; Configura LCD para envio de dados
- BCF PORTB, RB2 ; Habilita escrita
- ; Habilita e desabilita o envio
- BSF PORTB, RB0
- BCF PORTB, RB0
- MOVFW INDF ; Seleciona novamente o caractere
- SWAPF INDF, W ; Troca seus nibbles e seleciona o 2º
- ANDLW B'11110000'
- MOVWF TRISB ; Manda o valor para a porta
- BSF PORTB, RB1 ; Configura LCD para envio de dados
- BCF PORTB, RB2 ; Habilita escrita
- ; Habilita e desabilita o envio
- BSF PORTB, RB0
- BCF PORTB, RB0
- CALL LCD_ESPERA
- INCF FSR ; Incrementa o ponteiro da string
- GOTO LOOP_STR ; e volta para o loop de leitura da string.
- ; Transforma o valor decimal de duas casas em W em string e o escreve
- ; na posição indicada em STR_POSITION.
- STRINGFY
- 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_VALUE ; 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 DIV_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
- ; Função de espera ocupada para escrita do display
- LCD_ESPERA
- BSF PORTB, RB2 ; Ativa modo de leitura no diplay
- BCF PORTB, RB1 ; Seleciona modo de instrução
- BANK2
- BANK1
- MOVLW B'11110000'
- MOVWF TRISB ; Configura RB7 - RB4 como entrada
- BANK0
- READ_WAIT
- BSF PORTB, RB0 ; Habilita a leitura.
- MOVFW PORTB ; Copia o valor da leitura (primeiro nibble).
- BCF PORTB, RB0 ; Desabilita a leitura.
- ANDLW B'11110000' ; Pega o nibble certo,
- MOVWF ENTRADA ; e salva seu valor.
- BSF PORTB, RB2 ; Ativa modo de leitura no diplay
- BSF PORTB, RB0 ; Habilita a leitura novamente.
- MOVFW PORTB ; Copia o valor da leitura (segundo nibble).
- BCF PORTB, RB0 ; Desabilita a leitura.
- ANDLW B'11110000' ; Pega o nibble certo,
- SWAPF ENTRADA ; troca os nibles do dado salvo, para
- IORWF ENTRADA ; poder salvar seu valor.
- SWAPF ENTRADA ; Troca novamente os nibbles para salvar na ordem certa.
- BTFSC ENTRADA, 7 ; Verifica o bit 7 do dado lido: caso o bit seja 1,
- GOTO READ_WAIT ; significa que o display está ocupado, e realiza
- ; outra leitura, até o display ficar disponível.
- BANK2 ; Caso contrário, a porta está livre e a espera termina.
- BANK1 ; Muda para o banco 1, para alterar o TRISB.
- CLRF TRISB ; Define o port B todo como saída.
- BANK0 ; Volta para o banco 0.
- RETURN
- ; Inicialização do display LCD com 4 bits
- LCD_INICIALIZACAO
- BCF PORTB, RB2 ; Habilitamos escrita no display
- BCF PORTB, RB1 ; e selecionamos modo de instrução.
- ; Faremos aqui uma espera ocupada utilizando IDLE_LCD01 e 02
- ; utilizando a estrutura em forma de laços de repetição.
- ; No LCD01 levamos 772us, utilizaremos este em conjunto com o LCD 2, pois
- ; precisamos esperar mais de 15ms para que o LCD inicialize corretamente.
- MOVLW .235
- MOVWF IDLE_LCD01
- INCFSZ IDLE_LCD01 ; Cada ciclo leva aproximadamente 770us
- GOTO $+2
- GOTO $+4
- ; IDLE_LCD01 * (255-235) = 770us * 20 = 15.4ms
- INCFSZ IDLE_LCD02
- GOTO $-1
- GOTO $-5 ; Utilizando o IDLE_LCD02, com 20 iterações passaremos de 15ms
- ; Continuaremos o processo descrito no datasheet do fabricante do display.
- MOVLW B'00110000'; Realizaremos o processo utilizando o 0011
- MOVWF PORTB ; nas portas DB7DB4.
- BSF PORTB, RB0 ; Ativamos e desativamos a leitura
- BCF PORTB, RB0
- MOVLW .249 ; Depois, repetindo o procedimento da etapa anterior
- MOVWF IDLE_LCD01 ; será realizada uma espera ocupada de 4.1ms
- INCFSZ IDLE_LCD01 ; Cada ciclo leva aproximadamente 770us
- GOTO $+2
- GOTO $+4
- ; IDLE_LCD01 * (255-249) = 770us * 6 = 4.6ms
- INCFSZ IDLE_LCD02
- GOTO $-1
- GOTO $-5 ; utilizando o IDLE_LCD02, com 6 iterações passaremos de 4ms
- ; Gravando a informação na porta B.
- BSF PORTB, RB0
- BCF PORTB, RB0
- ; Mais uma espera será realizada, repetindo o procedimento da etapa anterior
- ; Desta vez só o IDLE_LCD01 é necessário, pois serão 100us
- MOVLW .215
- MOVWF IDLE_LCD01
- INCFSZ IDLE_LCD01
- GOTO $-1
- BSF PORTB, RB0 ; Novamente gravamos a informação na porta B.
- BCF PORTB, RB0
- CALL LCD_ESPERA
- MOVLW B'00100000' ; Seguindo as orientações do fabricante
- MOVWF TRISB ; Gravaremos 0010 no display
- BSF PORTB, RB0
- BCF PORTB, RB0
- CALL LCD_ESPERA
- ; Display LCD configurado no modo 4 BITS
- MOVLW B'00100000'
- MOVWF TRISB
- BSF PORTB, RB0
- BCF PORTB, RB0
- MOVLW B'10000000' ; Modo de duas linhas
- MOVWF TRISB
- BSF PORTB, RB0
- BCF PORTB, RB0
- CALL LCD_ESPERA
- ; Desligamos o display
- CALL LCD_OFF
- CALL LCD_ESPERA
- ; Limpamos o conteúdo
- CALL LCD_CLEAR
- CALL LCD_ESPERA
- ; Preparamos o modo de entrada
- CLRF TRISB
- BSF PORTB, RB0
- BCF PORTB, RB0
- MOVLW B'01100000'
- MOVWF TRISB
- BSF PORTB, RB0
- BCF PORTB, RB0
- CALL LCD_ESPERA
- CALL LCD_ON
- CALL LCD_ESPERA
- RETURN
- ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- ;* INICIO DO PROGRAMA *
- ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- INICIO
- BANK0
- CLRF PORTB
- CLRF PORTA
- MOVLW B'00000111'
- MOVWF CMCON
- BANK1
- MOVLW B'00000010'
- MOVWF TRISA
- MOVLW B'00000000'
- MOVWF TRISB
- MOVLW B'10001111'
- MOVWF OPTION_REG
- MOVLW B'00000000'
- MOVWF INTCON
- BANK0
- BSF PORTB, RA0
- ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- ;* 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 ESPERA_AUX
- CLRF OVERFLOW
- CLRF PORTB
- BSF PORTA, RA0 ;GARANTE A PORTA EM 1, POIS QUANDO FOR ZERO JA SERA O SINAL PRA O SENSOR TRANSMITIR
- BTFSS STATUS, NOT_TO
- GOTO MAIN
- MOVLW 0x55 ; Inincializa a os ponteiros com as posições na string
- MOVWF TEMP_PTR ; TEMP_PTR = 0x45
- MOVLW 0x5D
- MOVWF UR_PTR ; UR_PTR = 0x4D
- MOVLW 0x40 ; Começa a leitura da primeira string (autor) na posição
- MOVWF FSR ; 0x30 para copiar da EEPROM para a RAM.
- READ_STR01
- MOVFW FSR ; Copia a o ponteiro para o work
- CALL LE_EEPROM ; 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_STR01 ; Em caso negativo, volta para o loop para ler o próximo
- ; caractere.
- MOVLW 0x50 ; 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_STR02
- MOVFW FSR ; Copia a o ponteiro para o work
- CALL LE_EEPROM ; 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_STR02 ; Em caso negativo, volta para o loop para ler o próximo
- ; caractere.
- CALL LCD_INICIALIZACAO ; 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 0x40 ; Enviamos a posição da primeira string para a
- CALL LCD_CHOOSE_LINE ; função LCD_CHOOSE_LINE, que escreve a string na linha dada.
- ; Como essa primeira linha é constante, não varia,
- ; ela é apenas enviada uma vez.
- GOTO MAIN
- ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- ;* ROTINA PRINCIPAL *
- ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- MAIN
- CLRWDT ; Por padrão, reinicia a contagem do WatchDog no início.
- CLRF OVERFLOW
- CLRF ESPERA_AUX
- BCF PORTA, RA0 ; Colocamos RA0 em 0 e logo em seguida aguardamos 18ms
- ; Função utiliza duas variáveis auxiliares, ESPERA_AUX e OVERFLOW
- ; para obter o tempo de 18ms que necessitamos esperar para o DHT11
- ; conseguir detectar o sinal.
- ITER_ESPERA
- INCF ESPERA_AUX ; Incrementamos ESPERA_AUX
- MOVFW ESPERA_AUX
- SUBLW .0
- BTFSC STATUS, Z ; Verificamos se há estouro (ESPERA_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 0x50 ; Enviamos a posição da string de dados para a
- CALL LCD_CHOOSE_LINE ; função LCD_CHOOSE_LINE, que escreve a string na linha dada.
- SLEEP ; Ao terminar, colocamos o PIC para dormir e economizar energia.
- NOP
- ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- ;* FIM DO PROGRAMA *
- ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- END
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement