Advertisement
Guest User

Untitled

a guest
Jun 1st, 2018
246
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Pic 16 25.39 KB | None | 0 0
  1. #INCLUDE <p16f628a.inc>
  2.  
  3. ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  4. ;*                     ARQUIVOS DE DEFINICOES                      *
  5. ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  6. ; DEFINICOES   
  7. __CONFIG _BODEN_OFF & _CP_OFF & _PWRTE_ON & _WDT_ON & _MCLRE_ON & _INTRC_OSC_CLKOUT & _LVP_OFF
  8.    
  9. ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  10. ;*                    PAGINACAO DE MEMORIA                         *
  11. ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  12. ;DEFINICAO DE COMANDOS DE USUARIO PARA ALTERACAO DA PAGINA DE MEMORIA
  13. ;DEFINICAO DOS BANCOS
  14. #DEFINE     BANK0   BCF STATUS, RP0 ; SETA BANK 0 DE MEMORIA
  15. #DEFINE     BANK1   BSF STATUS, RP0 ; SETA BANK 1 DE MEMORIA
  16. #DEFINE     BANKA   BCF STATUS, RP1 ; SETA O BANK A
  17. #DEFINE     BANKB   BSF STATUS, RP1
  18.    
  19. ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  20. ;*                         VARIÁVEIS                               *
  21. ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  22. ; DEFINICAO DOS NOMES E ENDERECOS DE TODAS AS VARIAVEIS UTILIZADAS
  23. ; PELO SISTEMA
  24.  
  25.     CBLOCK  0x20    ;ENDERECO INICIAL DA MEMORIA DE USUARIO
  26.         W_TEMP      ;REGISTRADORES TEMPORARIOS PARA USO
  27.         STATUS_TEMP ;JUNTO AS INTERRUPCOES
  28.  
  29.         ;NOVAS VARIAVEIS
  30.         ESPERAPTR_AUX ; Variáveis utilizadas no cálculo do sinal do DHT11
  31.         OVERFLOW
  32.        
  33.         BYTES_COUNT ; Contador para identificar quantos bytes temos (0-4)
  34.         BITS_COUNT  ; Contador para identificar quantos bits temos  (0-8)
  35.         TIME_HIGH   ; Mede o tempo em HIGH do sinal
  36.         TEMP_INT    ; Temperatura - inteiro - Valor exibido no display
  37.         TEMP_DEC    ; Temperatura - decimal    
  38.         UMI_INT     ; Umidade - inteiro - Valor exibido no display
  39.         UMI_DEC     ; Umidade - decimal
  40.         ENTRADA     ; Recebe os 8 bits que serão associados às variáveis
  41.        
  42.         COUNT0      ; Contadores auxiliares
  43.         COUNT1
  44.         COUNT2
  45.        
  46.         DIVISOR      ; Divisor
  47.         DIV_TEMP     ; Resultado da divisão
  48.  
  49.         ; Variáveis das funções do LCD
  50.         PTR_AUX      ; Auxiliar
  51.         DATA_EE      ; Dado para escrita na EEPROM
  52.         STR_VALUE    ; Valor a ser convertido em string
  53.         STR_COMP     ; Complemento para a string
  54.         STR_POSITION ; Posição de escrita da string em Stringfy
  55.         LCD_LINE     ; Linha indicada para inserção no LCD
  56.        
  57.     ENDC            ;FIM DO BLOCO DE MEMORIA
  58.    
  59.     CBLOCK  0x30
  60.         AUTHOR: .16 ; String p/ nome do autor (16 pos) - Addr 0x30
  61.         INFO: .20  ; String da segunda linha (temp e ur, 20 pos) - Addr 0x40
  62.  
  63.         ; Ponteiros para o fim das strings
  64.         TEMP_PTR    ; Ponteiro para a posição da temperatura no string 0x45
  65.         UR_PTR      ; Ponteiro para a posição da umidade no string 0x4D
  66.     ENDC
  67.  
  68. ;*******************************************************************************
  69. ; Constantes do Programa
  70. ;*******************************************************************************
  71.  
  72.     ORG 0x2130
  73.     DE  "Johannes\0"
  74.    
  75.     ORG 0x2140
  76.     DE  "Temp=  C  UR=  %\0"    
  77.    
  78. ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  79. ;*                       VETOR DE RESET                            *
  80. ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  81.    
  82.    
  83.         ORG 0x00            ;ENDERE?O INICIAL DE PROCESSAMENTO
  84.     GOTO    INICIO
  85.    
  86. ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  87. ;*                    INÍCIO DA INTERRUPÇÃO                        *
  88. ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  89. ; ENDERECO DE DESVIO DAS INTERRUPCOES. A PRIMEIRA TAREFA E SALVAR OS
  90. ; VALORES DE "W" E "STATUS" PARA RECUPERACAO FUTURA
  91.  
  92.     ORG 0x04        ;ENDEREÇO INICIAL DA INTERRUPÇÃO
  93.     MOVWF   W_TEMP      ;COPIA W PARA W_TEMP
  94.     SWAPF   STATUS,W
  95.     BCF     STATUS,RP0
  96.     MOVWF   STATUS_TEMP ;COPIA STATUS PARA STATUS_TEMP
  97.    
  98.    
  99. ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  100. ;*                 ROTINA DE SAÍDA DA INTERRUPÇÃO                  *
  101. ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  102. ; OS VALORES DE "W" E "STATUS" DEVEM SER RECUPERADOS ANTES DE
  103. ; RETORNAR DA INTERRUPÇÃO
  104.  
  105. SAI_INT
  106.     SWAPF   STATUS_TEMP,W
  107.     MOVWF   STATUS      ;MOVE STATUS_TEMP PARA STATUS
  108.     SWAPF   W_TEMP,F
  109.     SWAPF   W_TEMP,W    ;MOVE W_TEMP PARA W
  110.     RETFIE
  111.  
  112.    
  113. ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  114. ;*                   ROTINAS E SUBROTINAS                      *
  115. ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  116. ; CADA ROTINA OU SUBROTINA DEVE POSSUIR A DESCRIÇÃO DE FUNCIONAMENTO
  117. ; E UM NOME COERENTE AS SUAS FUNÇÕES.
  118.    
  119.  
  120. ; Função que verifica quantos bytes já foram lidos e seleciona a variável
  121. ; associada a este número que será selecionada para alocar o conteúdo do sinal
  122. ; Como receberemos 4 bytes contendo: Umidade inteira e decimal, Temperatura inteira e decimal
  123. ; O primeiro byte será umidade inteira
  124. ;        O 2º será umidade decimal
  125. ;        O 3º será temperatura inteira
  126. ;        O 4º será temperatura decimal
  127.  
  128. SELECIONA_VARIAVEL         
  129.     MOVLW .1
  130.     SUBWF BYTES_COUNT, W    
  131.     BTFSC STATUS, Z     ; Caso (Nº de bytes - 1) seja = 0
  132.     GOTO UMIDADE_INTEIRA    ; Vamos associar o valor de ENTRADA à umidade inteira
  133.  
  134.     MOVLW .2
  135.     SUBWF BYTES_COUNT, W
  136.     BTFSC STATUS, Z     ; Caso (Nº de bytes - 2) seja = 0
  137.     GOTO UMIDADE_DECIMAL    ; Vamos associar o valor de ENTRADA à umidade decimal
  138.  
  139.     MOVLW .3
  140.     SUBWF BYTES_COUNT, W
  141.     BTFSC STATUS, Z      ; Caso (Nº de bytes - 3) seja = 0
  142.     GOTO TEMPERATURA_INTEIRA ; Vamos associar o valor de ENTRADA à umidade inteira
  143.  
  144.     MOVLW  .4
  145.     SUBWF BYTES_COUNT, W
  146.     BTFSC STATUS, Z      ; Caso (Nº de bytes - 4) seja = 0
  147.     GOTO TEMPERATURA_DECIMAL ; Vamos associar o valor de ENTRADA à umidade inteira
  148.  
  149.     GOTO LEITURA
  150.  
  151. ;ATRIBUICAO NAS VARIAVEIS DE PARTES INTEIRAS E DECIMAIS
  152. UMIDADE_INTEIRA
  153.     MOVFW ENTRADA
  154.     MOVWF UMI_INT
  155.     GOTO LEITURA
  156.    
  157. UMIDADE_DECIMAL
  158.     MOVFW ENTRADA
  159.     MOVWF UMI_DEC
  160.     GOTO LEITURA
  161.    
  162. TEMPERATURA_INTEIRA
  163.     MOVFW ENTRADA
  164.     MOVWF TEMP_INT
  165.     GOTO LEITURA
  166.  
  167. TEMPERATURA_DECIMAL
  168.     MOVFW ENTRADA
  169.     MOVWF TEMP_DEC
  170.     GOTO LCD
  171.  
  172. DIVIDE
  173.     ; Divide o valor em W pelo valor em DIVSR
  174.     ; Retorna o resultado em DIV_TEMP e resto em W
  175.     MOVWF PTR_AUX        ; Salva o dividendo em um auxiliar e
  176.     CLRF DIV_TEMP        ; limpa o resultado de divisões anteriores
  177.     MOVLW .0
  178.    
  179.     DIV_LOOP
  180.     MOVFW DIVISOR       ; Copia o valor do divisor para W
  181.     SUBWF PTR_AUX, W      ; (dividendo - divisor) subtrai o valor do divisor
  182.     BTFSS STATUS, C    ; e verifica se o reultado da operação é positivo
  183.     GOTO TERMINA_DIV  ; Se o resultado é negativo, a divisão termina.
  184.    
  185.     MOVWF PTR_AUX        ; Caso o resultado seja positivo ainda, atualiza
  186.     INCF DIV_TEMP        ; o dividendo e incrementa o resultado
  187.     GOTO DIV_LOOP    ; e volta para o loop.
  188.    
  189.     TERMINA_DIV
  190.     MOVFW PTR_AUX        ; No final da divisão o resto está no auxiliar,
  191.     RETURN          ; copia para o work e retorna a função.  
  192.    
  193. ;    _____   ______   __    __   ______   __    __  __    __  ________   ______  
  194. ;   |     \ /      \ |  \  |  \ /      \ |  \  |  \|  \  |  \|        \ /      \
  195. ;    \$$$$$|  $$$$$$\| $$  | $$|  $$$$$$\| $$\ | $$| $$\ | $$| $$$$$$$$|  $$$$$$\
  196. ;      | $$| $$  | $$| $$__| $$| $$__| $$| $$$\| $$| $$$\| $$| $$__    | $$___\$$
  197. ; __   | $$| $$  | $$| $$    $$| $$    $$| $$$$\ $$| $$$$\ $$| $$  \    \$$    \
  198. ;|  \  | $$| $$  | $$| $$$$$$$$| $$$$$$$$| $$\$$ $$| $$\$$ $$| $$$$$    _\$$$$$$\
  199. ;| $$__| $$| $$__/ $$| $$  | $$| $$  | $$| $$ \$$$$| $$ \$$$$| $$_____ |  \__| $$
  200. ; \$$    $$ \$$    $$| $$  | $$| $$  | $$| $$  \$$$| $$  \$$$| $$     \ \$$    $$
  201. ;  \$$$$$$   \$$$$$$  \$$   \$$ \$$   \$$ \$$   \$$ \$$   \$$ \$$$$$$$$  \$$$$$$
  202.    
  203. EE_READ
  204.     ; Lê o dado da EEPROM, endereço indicado em W
  205.     ; Dado lido retornado em W
  206.     ANDLW   .127    ; Limita endereço max em 127
  207.    
  208.     BANKA
  209.     BANK1
  210.     MOVWF EEADR       ; Endereço para leitura
  211.     BSF EECON1, RD  ; Inicia leitura
  212.     MOVFW EEDATA      ; Retorna o valor lido para W
  213.     BANK0
  214.     RETURN
  215.  
  216.  
  217. EE_WRITE
  218.     ; Escreve dado (DATA_EE) na EEPROM, cujo endereço é indicado em W
  219.     ANDLW   .127    ; Limita endereço max em 127
  220.    
  221.     BANKA
  222.     BANK1
  223.     MOVWF EEADR
  224.     MOVFW DATA_EE
  225.     MOVWF EEDATA
  226.     BSF EECON1, WREN    ; Habilita escrita
  227.     BCF INTCON, GIE ; Desliga Interrupções
  228.    
  229.     MOVLW 0x55        ; Sequência necessária
  230.     MOVWF EECON2
  231.     MOVLW 0xAA
  232.     MOVWF EECON2
  233.     BSF EECON1, WR  ; Inicia a escrita
  234.  
  235.     BTFSC EECON1, WR  ; Espera o término da operação
  236.     GOTO $-1
  237.    
  238.     BSF INTCON, GIE ; Habilita interrupções
  239.     BANK0
  240.     RETURN
  241.  
  242.  
  243. STRINGFY
  244.     ; Transforma o valor decimal de duas casas em W em string e o escreve
  245.     ; na posição indicada em STR_POSITION.
  246.     MOVWF   STR_VALUE    ; Copiamos o valor para um auxiliar
  247.     MOVLW   .10 ; Dividimos então o número por 10, para pegar os dígitos
  248.     MOVWF   DIVISOR
  249.     MOVFW   STR_VALUE
  250.     CALL    DIVIDE  ; Chamada da divisão
  251.  
  252.     MOVFW   STR_POSITION ; Apontamos para a posição de gravação desada
  253.     MOVWF   FSR ; acessando indiretamente por FSR e INDF
  254.  
  255.     MOVFW   DIV_TEMP    ; O dígito mais significativo é o resultado da divisão
  256.     ADDLW   '0' ; por 10, e vem primeiro. Para que seu valor seja
  257.     MOVWF   INDF    ; Convertido em string, somamos o valor do dígito ao
  258.             ; valor correspondente ao 0 na tabela ascii.
  259.  
  260.     INCF    FSR ; Incrementamos o ponteiro para salvar o outro dígito,
  261.     MOVFW   PTR_AUX    ; menos significativo, resto da divisão (em _aux).
  262.     ADDLW   '0' ; Novamente somamos ao valor do char 0,
  263.     MOVWF   INDF    ; e escrevemos de definitivo na string.
  264.  
  265.     RETURN
  266.  
  267.  
  268. LCD_INIT_4
  269.     ; Subrotina de inicialização do display LCD com configuração de 4-bits
  270.     BCF     PORTB, RB2  ; Habilitamos escrita no display
  271.     BCF     PORTB, RB1  ; e selecionamos modo de instrução.
  272.     MOVLW   .235    ; Primeiro é realizada uma espera ocupada de 15ms (no min),
  273.     MOVWF   COUNT0  ; para que o LCD inicialize e espere a entrada.
  274.    
  275.     INCFSZ  COUNT0  ; Cada contagem desse contador leva 772us em conjunto com o
  276.     GOTO    $+2     ; contador2 (abaixo), 19 deve ser suficiente para passar de
  277.     GOTO    $+4     ; 15ms.
  278.  
  279.     INCFSZ  COUNT1  ; Cada contagem desse contador leva 3us,
  280.     GOTO    $-1     ; o que implica numa contagem total de aprox. 767us, com
  281.     GOTO    $-5     ; os jumps ocasionais.
  282.    
  283.     MOVLW   B'00110000' ; Como especificado no datasheet, para inicializar o
  284.     MOVWF   PORTB   ; LCD com 4 bits passamos 0b0011 nas portas DB7DB4.
  285.     BSF     PORTB, RB0   ; Ativamos a leitura por 1us
  286.     BCF     PORTB, RB0   ; e depois desativamos
  287.    
  288.     MOVLW   .249    ; Depois é realizada uma espera ocupada de 4.1ms.
  289.     MOVWF   COUNT0
  290.    
  291.     INCFSZ  COUNT0  ; Cada contagem desse contador leva 772us em conjunto com o
  292.     GOTO    $+2     ; contador2 (abaixo), 6 deve ser suficiente para passar de
  293.     GOTO    $+4     ; 4.1ms.
  294.  
  295.     INCFSZ  COUNT1  ; Cada contagem desse contador leva 3us,
  296.     GOTO    $-1     ; o que implica numa contagem total de aprox. 767us, com
  297.     GOTO    $-5     ; os jumps ocasionais.
  298.    
  299.     BSF     PORTB, RB0   ; Novamente gravamos a informação na porta do LCD.
  300.     BCF     PORTB, RB0
  301.    
  302.     MOVLW   .221    ; Agora é realizada outra espera, dessa vez de 100us.
  303.     MOVWF   COUNT0
  304.     INCFSZ  COUNT0  ; Cada contagem desse contador leva 3us,
  305.     GOTO    $-1     ; 33 contagens é o suficiente para ~100us.
  306.    
  307.     BSF     PORTB, RB0   ; Novamente gravamos a informação na porta do LCD.
  308.     BCF     PORTB, RB0
  309.    
  310.     MOVLW   B'00100000' ; Agora gravamos 0b0010 no display, como parte do
  311.     MOVWF   TRISB   ; protocolo de inicialização para utilizar 4 bits.
  312.     BSF     PORTB, RB0
  313.     BCF     PORTB, RB0
  314.    
  315.     MOVLW   .242    ; Espera de no min 40us entre instruções
  316.     MOVWF   COUNT0
  317.     INCFSZ  COUNT0  ; Cada contagem desse contador leva 3us,
  318.     GOTO    $-1     ; 13 contagens é o suficiente para ~40us.
  319.    
  320.     ; Function Set
  321.     MOVLW   B'00100000' ; Defimos então o display para funcionar com 4 bits
  322.     MOVWF   TRISB
  323.     BSF     PORTB, RB0
  324.     BCF     PORTB, RB0
  325.     MOVLW   B'00110000' ; E então configuramos para utilizar duas linhas
  326.     MOVWF   TRISB   ; e caracteres 5x7.
  327.     BSF     PORTB, RB0
  328.     BCF     PORTB, RB0
  329.    
  330.     MOVLW   .242    ; Espera de no min 40us entre instruções
  331.     MOVWF   COUNT0
  332.     INCFSZ  COUNT0  ; Cada contagem desse contador leva 3us,
  333.     GOTO    $-1     ; 13 contagens é o suficiente para ~40us.
  334.    
  335.     ; Display off
  336.     CALL    LCD_OFF
  337.     MOVLW   .242    ; Espera de no min 40us entre instruções
  338.     MOVWF   COUNT0
  339.     INCFSZ  COUNT0  ; Cada contagem desse contador leva 3us,
  340.     GOTO    $-1     ; 13 contagens é o suficiente para ~40us.
  341.    
  342.     ; Clear display
  343.     CALL    LCD_CLEAR
  344.     MOVLW   .242    ; Espera de no min 40us entre instruções
  345.     MOVWF   COUNT0
  346.     INCFSZ  COUNT0  ; Cada contagem desse contador leva 3us,
  347.     GOTO    $-1     ; 13 contagens é o suficiente para ~40us.
  348.    
  349.     ; Entry Mode config
  350.     CLRF    TRISB   ; Configurando modo de incremento, sem shift do display.
  351.     BSF     PORTB, RB0
  352.     BCF     PORTB, RB0
  353.     MOVLW   B'01100000'
  354.     MOVWF   TRISB
  355.     BSF     PORTB, RB0
  356.     BCF     PORTB, RB0
  357.    
  358.     MOVLW   .242    ; Espera de no min 40us entre instruções
  359.     MOVWF   COUNT0
  360.     INCFSZ  COUNT0  ; Cada contagem desse contador leva 3us,
  361.     GOTO    $-1     ; 13 contagens é o suficiente para ~40us.
  362.    
  363.     RETURN
  364.  
  365.  
  366. LCD_OFF
  367.     ; Desliga o LCD (APENAS PARA 4 BITS!)
  368.     BCF     PORTB, RB2  ; Habilitamos escrita no display
  369.     BCF     PORTB, RB1  ; e selecionamos modo de instrução.
  370.    
  371.     CLRF    TRISB   ; Desligamos o display com o byte 0b00001000
  372.     BSF     PORTB, RB0
  373.     BCF     PORTB, RB0
  374.    
  375.     MOVLW   B'10000000'
  376.     MOVWF   TRISB
  377.     BSF     PORTB, RB0
  378.     BCF     PORTB, RB0
  379.     RETURN
  380.  
  381.  
  382. LCD_CLEAR
  383.     ; Limpa os dados mostrados no LCD (APENAS PARA 4 BITS!)
  384.     BCF     PORTB, RB2  ; Habilitamos escrita no display
  385.     BCF     PORTB, RB1  ; e selecionamos modo de instrução.
  386.    
  387.     CLRF    TRISB   ; Limpamos o display com o byte 0b00000001
  388.     BSF     PORTB, RB0
  389.     BCF     PORTB, RB0
  390.    
  391.     MOVLW   B'00010000'
  392.     MOVWF   TRISB
  393.     BSF     PORTB, RB0
  394.     BCF     PORTB, RB0
  395.     RETURN
  396.  
  397.  
  398. LCDLCD_LINE
  399.     ; Envia a string em W para o display LCD na linha indicada em LCD_LINE (1 ou 2)
  400.     MOVWF   PTR_AUX    ; Salvamos temporariamente o string
  401.    
  402.     MOVFW   LCD_LINE   ; Verificamos se LCD_LINE é 1 ou 2
  403.     SUBLW   .1
  404.     BTFSC   STATUS, Z   ; Sutraindo por 1, verificamos se o resultado é 0
  405.     GOTO    LINE1   ; se for, a linha é 1
  406.    
  407.     MOVFW   LCD_LINE
  408.     SUBLW   .2
  409.     BTFSC   STATUS, Z   ; Sutraindo por 2, verificamos se o resultado é 0
  410.     GOTO    LINE2   ; se for, a linha é 2
  411.    
  412.     RETURN  ; Caso nada se aplique, retorna
  413.    
  414. LINE1
  415.     MOVLW   0x00    ; Configurando a posição do cursor
  416.     GOTO    LCD_SEND    ; para o início do display
  417.    
  418. LINE2
  419.     MOVLW   0x40    ; Configurando a posição do cursor
  420.             ; para o início da segunda linha
  421.    
  422. LCD_SEND
  423.     ANDLW   0xF0    ; Com um AND pegamos o nibble mais significativo
  424.     MOVWF   TRISB   ; e escrevemos para o lcd.
  425.     BSF     TRISB, RB7  ; O bit7 do display é 1 para instrução de endereçamento
  426.     BCF     PORTB, RB1  ; Ativamos o modo de instrução
  427.     BCF     PORTB, RB2  ; e escrita.
  428.     BSF     PORTB, RB0   ; Com o enable o dado no PORTB pode ser lido pelo LCD
  429.     BCF     PORTB, RB0   ; Desativa o enable para terminar escrita
  430.    
  431.     CLRF    TRISB   ; O nibble menos sig. é sempre 0, então limpa TRISB
  432.     BSF     PORTB, RB0   ; Abilita escrita com enable.
  433.     BCF     PORTB, RB0   ; Desabilita escrita com enable.
  434.    
  435.     MOVFW   PTR_AUX    ; Copia o ponteiro da string para
  436.     MOVWF   FSR     ; ponteiro de endereçamento indireto
  437.    
  438. LOOP_STR
  439.     MOVFW   INDF
  440.     SUBLW   '\0'
  441.     BTFSC   STATUS, Z
  442.     RETURN
  443.    
  444.     MOVFW   INDF    ; Seleciona o primeiro nibble do caractere com AND
  445.     ANDLW   0xF0
  446.     MOVWF   TRISB   ; Manda o valor para a porta
  447.     BSF     PORTB, RB1  ; Configura LCD para envio de dados
  448.     BCF     PORTB, RB2  ; Configura modo de escrita
  449.    
  450.     BSF     PORTB, RB0   ; Abilita o envio
  451.     BCF     PORTB, RB0   ; Desabilita o envio
  452.    
  453.     MOVFW   INDF    ; Seleciona novamente o caractere
  454.     SWAPF   INDF, W ; Troca seus nibbles
  455.     ANDLW   0xF0    ; e seleciona o segundo nibble (agora primeiro, trocado).
  456.     MOVWF   TRISB   ; Manda o valor para a porta
  457.     BSF     PORTB, RB1  ; Configura LCD para envio de dados
  458.     BCF     PORTB, RB2  ; Configura modo de escrita
  459.    
  460.     BSF     PORTB, RB0   ; Abilita o envio
  461.     BCF     PORTB, RB0   ; Desabilita o envio
  462.    
  463.     INCF    FSR     ; Incrementa o ponteiro da string
  464.     GOTO    LOOP_STR    ; e volta para o loop de leitura da string.
  465.    
  466. ;ROTINA QUE COLOCA O CONTROLADOR EM MODO SLEEP
  467. DORME  
  468.     BANK1
  469.     BCF TRISA, 0       
  470.     BANK0  
  471.     BSF PORTA, RA0
  472.     SLEEP
  473.     NOP
  474.    
  475. ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  476. ;*                     INICIO DO PROGRAMA                          *
  477. ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  478.  
  479. INICIO
  480.     BANK1
  481.     MOVLW   B'00000010'
  482.     MOVWF   TRISA
  483.     MOVLW   B'00000000'
  484.     MOVWF   TRISB
  485.     MOVLW   B'10001111'
  486.     MOVWF   OPTION_REG
  487.     MOVLW   B'00000000'
  488.     MOVWF   INTCON
  489.    
  490.     BANK0
  491.     MOVLW   B'00000111'
  492.     MOVWF   CMCON
  493.    
  494.    
  495.    
  496. ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  497. ;*                     INICIALIZACAO DAS VARIÁVEIS                 *
  498. ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  499.  
  500.     ;LIMPA AS VARIAVEIS
  501.     CLRF    TIME_HIGH
  502.     CLRF    BITS_COUNT
  503.     CLRF    BYTES_COUNT
  504.     CLRF    ENTRADA
  505.     CLRF    UMI_INT
  506.     CLRF    UMI_DEC
  507.     CLRF    TEMP_INT
  508.     CLRF    TEMP_DEC
  509.     CLRF    ESPERAPTR_AUX
  510.     CLRF    OVERFLOW
  511.     CLRF    PORTB
  512.  
  513.     MOVLW   0x45    ; Inincializa a os ponteiros com as posições na string
  514.     MOVWF   TEMP_PTR    ; TEMP_PTR = 0x45
  515.     MOVLW   0x4D
  516.     MOVWF   UR_PTR  ; UR_PTR = 0x4D
  517.  
  518.     MOVLW   0x30    ; Começa a leitura da primeira string (autor) na posição
  519.     MOVWF   FSR     ; 0x30 para copiar da EEPROM para a RAM.
  520.  
  521.     READ_NAME
  522.     MOVFW   FSR     ; Copia a o ponteiro para o work
  523.     CALL    EE_READ ; e lê a posição correspondente na EEPROM.
  524.     MOVWF   INDF    ; Copia o caractere lido para a RAM, na posição apontada
  525.     INCF    FSR     ; em FSR, e incrementa o ponteiro para o prox char.
  526.     SUBLW   '\0'    ; Subtraimos pelo caractere '\0' (término)
  527.     BTFSS   STATUS, Z   ; para verificar se a string chegou ao fim.
  528.     GOTO    READ_NAME   ; Em caso negativo, volta para o loop para ler o próximo
  529.         ; caractere.
  530.  
  531.     MOVLW   0x40    ; Agora vamos ler a segunda string (segunda linha) salva na
  532.     MOVWF   FSR     ; posição 0x40 da EEPROM e escrever na mesma posição na RAM.
  533.  
  534.     READ_TEXT1
  535.     MOVFW   FSR     ; Copia a o ponteiro para o work
  536.     CALL    EE_READ ; e lê a posição correspondente na EEPROM.
  537.     MOVWF   INDF    ; Copia o caractere lido para a RAM, na posição apontada
  538.     INCF    FSR     ; em FSR, e incrementa o ponteiro para o prox char.
  539.     SUBLW   '\0'    ; Subtraimos pelo caractere '\0' (término)
  540.     BTFSS   STATUS, Z   ; para verificar se a string chegou ao fim.
  541.     GOTO    READ_TEXT1  ; Em caso negativo, volta para o loop para ler o próximo
  542.         ; caractere.
  543.  
  544.     CALL    LCD_INIT_4  ; Por fim, executamos a rotina de inicialização do LCD
  545.         ; configurando-o para utilizar 4 bits.
  546.  
  547.     MOVLW   .1      ; Definimos a primeira linha para escrita no display.
  548.     MOVWF   LCD_LINE
  549.     MOVLW   0x30    ; Enviamos a posição da primeira string para a
  550.     CALL    LCDLCD_LINE    ; função LCDLCD_LINE, que escreve a string na linha dada.
  551.         ; Como essa primeira linha é constante, não varia,
  552.         ; ela é apenas enviada uma vez.
  553.  
  554.    
  555.     BSF PORTA, RA0  ;GARANTE A PORTA EM 1, POIS QUANDO FOR ZERO JA SERA O SINAL PRA O SENSOR TRANSMITIR
  556.     GOTO MAIN
  557.        
  558.        
  559. ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  560. ;*                     ROTINA PRINCIPAL                            *
  561. ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  562.    
  563. MAIN
  564.     CLRWDT  ; Por padrão, reinicia a contagem do WatchDog no início.
  565.    
  566.     ESPERA_OCUPADA  ; Espera ocupada do WDT
  567.     BTFSS   STATUS, 4   ;VERIFICA SE O POWER-ON FOI CAUSADO PELO WDT
  568.     GOTO    ESPERA      ;CASO TENHA SIDO, VAI PRA ESPERA
  569.     GOTO    DORME       ;CASO NAO, VOLTA A DORMIR
  570.    
  571.     ESPERA
  572.     BCF PORTA, RA0  ; Colocamos RA0 em 0 e logo em seguida aguardamos 18ms
  573.     ; Função utiliza duas variáveis auxiliares, ESPERAPTR_AUX e OVERFLOW
  574.     ; para obter o tempo de 18ms que necessitamos esperar para o DHT11
  575.     ; conseguir detectar o sinal.
  576.     ITER_ESPERA        
  577.         INCF ESPERAPTR_AUX      ; Incrementamos ESPERAPTR_AUX
  578.         BTFSC STATUS, C     ; Verificamos se há estouro (ESPERAPTR_AUX > 255)
  579.         INCF OVERFLOW       ; Caso seja, incrementamos OVERFLOW
  580.         MOVLW .8            ; Movemos 8 ao work
  581.         SUBWF OVERFLOW, W       ; Subtraímos OVERFLOW por work
  582.         BTFSS STATUS, Z     ; Se for diferente de zero (OVERFLOW != 8)
  583.         GOTO ITER_ESPERA        ; realizamos mais uma iteração
  584.         GOTO PRE_LEITURA        ; Na última iteração teremos um tempo de aproximadamente 18.400us
  585.  
  586.     ; Após aguardamos os 18ms estabelecidos pelo fabricante, iremos configurar a
  587.     ; porta RA0 como porta de entrada.
  588.     PRE_LEITURA        
  589.     BSF PORTA, RA0  ; Colocamos o sinal da porta RA0 como 1, para sinalizar entrada
  590.     BANK1
  591.     BSF TRISA, 0    ; Configuramos a RA0 como entrada no TRISA
  592.     BANK0
  593.     IDLE_WAIT_1
  594.     BTFSC PORTA, RA0    ; Aguardando o DHT11 jogar o sinal de RA0 para 0
  595.     GOTO IDLE_WAIT_1    ; Enquanto não ocorrer, fazemos uma espera ocupada
  596.     IDLE_WAIT_2
  597.     BTFSS PORTA, RA0    ; Esperamos o momento em que o DHT11 sobe o RA0
  598.     GOTO IDLE_WAIT_2    ; Enquanto não ocorrer, fazemos uma espera ocupada
  599.     PREPARA_TRANSMISSAO
  600.     BTFSC PORTA, RA0    ; Aguardamos a porta ir pra zero, que irá sinalizar
  601.                 ; o começo da transmissão de dados.
  602.     GOTO PREPARA_TRANSMISSAO       
  603.     GOTO LEITURA        ; Quando tivermos o fim do pulso, vamos à função de leitura
  604.  
  605.    
  606.     ; Função que armazena os dados transmitidos
  607.     LEITURA
  608.         CLRF BITS_COUNT   ; Limpamos o contador de BITS da variável
  609.         INCF BYTES_COUNT  ; Contamos quantas variáveis (bytes) foram lidas
  610.     LEITURA_BIT            
  611.         BTFSS PORTA, RA0  ; Verificamos se o sinal é zero
  612.         GOTO LEITURA_BIT ; Caso seja, continuamos a espera ocupada
  613.         INCF BITS_COUNT   ; Caso não seja, incrementamos o contador de bits e iremos interpretar o valor
  614.  
  615.     ITER_LEITURA    ; Iremos iterar para interpretar o sinal BIT a BIT
  616.         ; TIME_HIGH armazena o tempo em que o sinal esteve em alta (HIGH)
  617.         ; se esteve de 26-28 uS, o sinal é 0, se esteve por 70 uS, o sinal é 1
  618.         INCF TIME_HIGH  ; Incrementamos CONTA_lEITURA
  619.        
  620.         BTFSC PORTA, RA0    ; Enquanto o sinal estiver em alta, iremos
  621.         GOTO ITER_LEITURA   ; retornar ao início desta função e incrementar TIME_HIGH novamente
  622.         ; O número 10 foi escolhido de forma empírica após perceber que se tiver
  623.         ; menos do que 10 ciclos o valor a ser armazenado é 0, caso contrário é 1
  624.        
  625.         MOVLW .10 ; Movemos 10 ao work para verificar se o número armazenado é um 0 ou 1
  626.         SUBWF TIME_HIGH, W    ; Subtraímos TIME_HIGH por W
  627.         BTFSC STATUS, C     ; Seguimos a lógica descrita acima checando o carry para conferir o valor.
  628.         BSF ENTRADA, 0     
  629.         CLRF TIME_HIGH      ; Fim da leitura do BIT
  630.  
  631.         MOVLW .8           
  632.         SUBWF BITS_COUNT, W ; Verificamos se o BIT contado foi o último
  633.         BTFSC STATUS, Z
  634.         GOTO SELECIONA_VARIAVEL ; Caso tenha sido, salvaremos o valor do byte na variável
  635.         RLF ENTRADA, 1  ; Caso não seja, empurramos o BIT pra esquerda
  636.         GOTO LEITURA_BIT    ; Vamos à leitura do próximo bit
  637.  
  638.    
  639. ;    _____   ______   __    __   ______   __    __  __    __  ________   ______  
  640. ;   |     \ /      \ |  \  |  \ /      \ |  \  |  \|  \  |  \|        \ /      \
  641. ;    \$$$$$|  $$$$$$\| $$  | $$|  $$$$$$\| $$\ | $$| $$\ | $$| $$$$$$$$|  $$$$$$\
  642. ;      | $$| $$  | $$| $$__| $$| $$__| $$| $$$\| $$| $$$\| $$| $$__    | $$___\$$
  643. ; __   | $$| $$  | $$| $$    $$| $$    $$| $$$$\ $$| $$$$\ $$| $$  \    \$$    \
  644. ;|  \  | $$| $$  | $$| $$$$$$$$| $$$$$$$$| $$\$$ $$| $$\$$ $$| $$$$$    _\$$$$$$\
  645. ;| $$__| $$| $$__/ $$| $$  | $$| $$  | $$| $$ \$$$$| $$ \$$$$| $$_____ |  \__| $$
  646. ; \$$    $$ \$$    $$| $$  | $$| $$  | $$| $$  \$$$| $$  \$$$| $$     \ \$$    $$
  647. ;  \$$$$$$   \$$$$$$  \$$   \$$ \$$   \$$ \$$   \$$ \$$   \$$ \$$$$$$$$  \$$$$$$
  648.  
  649.     LCD
  650.     MOVFW   TEMP_PTR    ; Copiamos o ponteiro para a posição da temperatura
  651.     MOVWF   STR_POSITION        ; no string de informação para a função STRINGFY
  652.     MOVFW   TEMP_INT ; que insere a informação lida de temperatura na
  653.     CALL    STRINGFY    ; posição designada da string.
  654.  
  655.     MOVFW   UR_PTR      ; Copiamos o ponteiro para a posição da umidade
  656.     MOVWF   STR_POSITION        ; no string de informação para a função STRINGFY
  657.     MOVFW   UMI_INT     ; que insere a informação lida de umidade na
  658.     CALL    STRINGFY    ; posição designada da string.
  659.  
  660.     MOVLW   .2      ; Definimos linha 2 para escrita de dados no display.
  661.     MOVWF   LCD_LINE
  662.     MOVLW   0x40        ; Enviamos a posição da string de dados para a
  663.     CALL    LCDLCD_LINE    ; função LCDLCD_LINE, que escreve a string na linha dada.
  664.  
  665.     CALL DORME   ; Finalizando a operação, o microcontrolador é configurado para
  666.     GOTO    $   ; adormecer, economizando energia. É despertado pelo WDT depois.
  667. ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  668. ;*                       FIM DO PROGRAMA                           *
  669. ;* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  670.    
  671.     END
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement