; Eu configurei o PIC para trabalhar na resolução máxima do conversor, ou seja, 10 bit
s com o resultado da conversão justificado à direita. O que o meu programa tem que f azer é muito simples: ele lê a tensão analógica presente no canal AN0/RA0 do PIC e, se e la ultrapassar 3V, um led ligado ao pino RB7 acende; se ela estiver abaixo de 3V , o led não acende. É uma simples comparação de maior ou menor e leitura do canal 0 do c onversor AD. ; Lembrando que, 3V convertido para digital de 10 bits é 614 (decimal) ou 10011001 10 (binário) ou 0x266 (hexadecimal). #INCLUDE <P16F876.INC> ;arquivo de definições para o PIC em questão __CONFIG _BODEN_OFF & _CP_OFF & _PWRTE_ON & _WDT_OFF & _LVP_OFF & _HS_OSC CBLOCK 0x0070 ;endereço inicial da memória do usuário ADH ADL ENDC ;fim do bloco de memória #DEFINE BANK0 BCF STATUS,RP0 ;seleciona banco 0 da memória RAM #DEFINE BANK1 BSF STATUS,RP0 ;seleciona banco 1 da memória RAM #DEFINE LED PORTB,1
ORG 0x0000 ;endereço inicial de processamento
GOTO INICIO ORG 0x0004 ;endereço inicial de interrupção RETFIE ;retorna da interrupção ; INICIO DO PROGRAMA INICIO BANK1 MOVLW B'10001110' ;ra0 como entrada analógica e resultado justificado à direita MOVWF ADCON1 MOVLW B'00000001' MOVWF TRISA ;define todo o porta como saida, exceto RA0 MOVLW B'00000000' MOVWF TRISB ;define todo o portb como saida MOVLW B'00000000' MOVWF TRISC ;define todo o portc como saida MOVLW B'10001000' MOVWF OPTION_REG ;prescaler 1:1 no wdt ;demais configurações irrelevantes MOVLW B'00000000' MOVWF INTCON ;interrupções desativadas BANK0 ;altera para o banco 0 MOVLW B'11000001' ;canal 0, clock interno , AD ligado MOVWF ADCON0 CALL DELAY ; ROTINA PRINCIPAL MAIN CLRF PORTA ;limpa o porta CLRF PORTB ;limpa o portb CLRF PORTC ;limpa o portc CLRF ADH CLRF ADL BANKSEL ADRESL CLRF ADRESL ;limpa parte baixa do registrador do AD BANKSEL ADRESH CLRF ADRESH ;limpa parte alta do registrador do AD GOTO LE_AD ;chama sub-rotina que lê o conversor AD LE_AD BANKSEL ADCON0 BSF ADCON0,GO ;inicia conversão BTFSC ADCON0,GO ;terminou a conversão? GOTO $-1 ;Não.Então, aguarda terminar BANKSEL ADRESH MOVF ADRESH,W MOVWF ADH ;Guarda resultado (2 bits) BANKSEL ADRESL MOVF ADRESL,W MOVWF ADL ;Guarda resultado (8 bits). Total de 10 bits. COMPARA ;Se AD for menor do que 614, led não acende. Se AD for maior do que 614, l ed acende ;Em base hexadecimal: 614 = 0x266 = 1001100110 (10 bits). ;Justificado à direita: ;ADRESL: 01100110 e ADRESH: 00000010. BCF STATUS,C ;apaga bit de carry do registrador status MOVLW 0x02 SUBWF ADH,W ;Após esta operação, W = ADH - W BTFSS STATUS,C ;Testa carry. Qual o resultado? GOTO MENOR ;Negativo. Então, ADH < 0x02. Desvia ;Positivo. Então, ADH >= 0x02. Desvia BCF STATUS,C MOVLW 0x66 SUBWF ADL,W ;Após esta operação, W = ADL - W BTFSS STATUS,C ;Testa carry. Qual resultado? GOTO MENOR ;Negativo. Então, ADL < 0x66. Desvia GOTO MAIOR ;Positivo. Então, ADL >= 0x66. Desvia MENOR BANKSEL PORTB ;seleciona o banco correto para o portb BCF LED ;limpa bit RB1 GOTO LE_AD ;desvia para ler AD novamente MAIOR BANKEL PORTB ;seleciona o banco correto para o portb BSF LED ;seta bit RB1 GOTO LE_AD ;desvia para ler AD novamente DELAY ;### SUB-ROTINA DE DELAY DE 80us ### ;Fosc = 20MHz => (Tosc = 20MHz/4 = 5MHz => 1/5MHz = 200ns) ;(255 * 200ns) + (150 * 200ns) = 81us CLRF TMR0 ;limpa o tmr0 BCF INTCON,T0IF ;limpa flag da int. do tmr0 BTFSS INTCON,T0IF ;timer 0 >= 255? GOTO $-1 ;não, retorna ;sim, terminou CLRF TMR0 ;limpa o tmr0 BCF INTCON,T0IF ;apaga flag da int. do tmr0 MOVLW (.255-.150) MOVWF TMR0 ;carrega tmr0 com 105 BTFSS INTCON,T0IF ;timer 0 >= 255? GOTO $-1 ;não, retorna ;sim, terminou RETURN ;retorna à pilha END ;fim do programa ;=============================================================================== ============