Advertisement
Guest User

Untitled

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