Enabling conversion on other AN ports (Assembly)

Thread Starter

Dragnovith

Joined Apr 16, 2021
21
Hello, I am trying to implement a weight sensor. Tension simulates weight, and I've already made a sensor which is working. But when I try to enable conversion on the other sensors, ie the other AN ports, it doesn't recognize when I call adcon1,adcon2, etc. I appreciate if you can help me.
1630325422953.png
Follow the code below (the comments are in Brazilian-Portuguese, sorry) .
Anything I can transcribe into English
1630325422953.png
Code:
PROCESSOR 16F877A   ;primeira linha é o tipo de processador

#include <p16f877a.inc>

__CONFIG _CP_OFF & _WDT_OFF & _PWRTE_ON & _XT_OSC


D0 equ 0x21 ;---UN
D1 equ 0x22 ;---DEZ
T0 equ 0x24 ;---CENTENA
TEMP1 equ 0x25
TEMP2 EQU 0X26
z EQU 0X27
PORTC EQU 07
TRISC EQU 87

#DEFINE ENABLE                PORTD,0
#DEFINE RS                    PORTD,1
#DEFINE bank0 BCF STATUS,RP0
#DEFINE bank1 BSF STATUS,RP0

org 0x00   ;vetor de reset
goto Main  ;após o reset, começa na função principal

org 0x04   ;vetor de interrupção
goto Main  ; vai pra main

;-----------------------------------------------------------
;        TABELA DE MEDIDA
;-----------------------------------------------------------

TABELA_TEMP              
    ADDWF        PCL  
    RETLW    b'00000000'
    RETLW    b'00000001'
    RETLW    b'00000010'
    RETLW    b'00000011'
    RETLW    b'00000100'
    RETLW    b'00000101'
    RETLW    b'00000110'
    RETLW    b'00000111'
    RETLW    b'00001000'
    RETLW    b'00001001'
    RETLW    b'00001010'
    RETLW    b'00001011'
    RETLW    b'00001100'
    RETLW    b'00001101'
    RETLW    b'00001110'
    RETLW    b'00001111'
    RETLW    b'00010000'
    RETLW    b'00010001'
    RETLW    b'00010010'
    RETLW    b'00010011'
    RETLW    b'00010100'
    RETLW    b'00010101'
    RETLW    b'00010110'
    RETLW    b'00010111'
    RETLW    b'00011000'
    RETLW    b'00011001'
    RETLW    b'00011010'
    RETLW    b'00011011'
    RETLW    b'00011100'
    RETLW    b'00011101'
    RETLW    b'00011110'
    RETLW    b'00011111'
    RETLW    b'00100000'
    RETLW    b'00100001'
    RETLW    b'00100010'
    RETLW    b'00100011'
    RETLW    b'00100100'
    RETLW    b'00100101'
    RETLW    b'00100110'
    RETLW    b'00100111'
    RETLW    b'00101000'
    RETLW    b'00101001'
    RETLW    b'00101001'
    RETLW    b'00101010'
    RETLW    b'00101011'
    RETLW    b'00101100'
    RETLW    b'00101101'
    RETLW    b'00101110'
    RETLW    b'00101111'
    RETLW    b'00110000'
    RETLW    b'00110001'
    RETLW    b'00110010'

;-----------------------------------------------------------
;        TABELA PARA O LCD
;-----------------------------------------------------------

TABELA_LCD        ;para mostrar o caractere em asc no display      
    ADDWF        PCL  
    RETLW '0'
    RETLW '1'
    RETLW '2'
    RETLW '3'
    RETLW '4'
    RETLW '5'
    RETLW '6'
    RETLW '7'
    RETLW '8'
    RETLW '9'

;-----------------------------------------------------------
;                MAIN
;-----------------------------------------------------------
Main
        bank1       ;     MUDA BANCO MEMORIA 1
        MOVLW   B'10000000'
;              1-UU----     Alinhado a direita  
;              -0UU----     FSC/  
;              --UU0000     Todas analogicas  
        MOVWF   ADCON1
    ;BSF        PIE1, ADIE        
        MOVLW   B'00000000'
    MOVWF   TRISB            
        MOVLW   B'00000000'
    MOVWF   TRISD            
        MOVLW   B'11111111'
    MOVWF   TRISA          
    MOVLW   B'00000000'    
;              --------      
        MOVWF   OPTION_REG    
        MOVLW    B'00000111' ; Desabilita os comparadores          
    MOVWF    CMCON          
   
    bank0       ; BANCO DE MEMORIA 0
        MOVLW   B'00000001' ; Configura ADC
;              00----U-    FSC/8  
;              -------1    Liga o conversor  
;              --000---    Canal AN0 entrada
    MOVWF   ADCON0

    MOVLW   B'00000000'  
    MOVWF   INTCON

        CLRF    PORTB      
    CLRF    D0
    CLRF    D1

;-----------------------------------------------------------
;            CONFIGURA LCD
;-----------------------------------------------------------

LCD_IN
    CALL DELAY20
    BCF RS ;SELECIONA O DISPLAY PARA COMANDOS
    MOVLW 0X30 ;ESCREVE COMANDO 0X3O PARA INICIALIZACAO
    CALL ESCREVE

    CALL DELAY20
    MOVLW 0X30 ;ESCREVE COMANDO 0X3O PARA INICIALIZACAO
    CALL ESCREVE
    MOVLW 0X30
    CALL ESCREVE
    MOVLW B'00111000' ;ESCREVE COMANDO PARA INTERFACE D E 8 VAIS DE DADOS
    CALL ESCREVE
    MOVLW B'00000001'
    CALL ESCREVE ;ESCREVE COMANDO PARA LIMPAR TODO O DISPLAY
   
    CALL DELAY20 ;DELAY DE 8MS
    MOVLW B'00001100'
    CALL ESCREVE ;ESCREVE COMANDO PARA LIGAR O DISPLAY SEM CURSOR
    MOVLW B'00000110'
    CALL ESCREVE ;ESCREVE COMANDO PARA INCREMENTAR AUTOMATICA A DIREITA
    BSF RS ;SELECIONA O DISPLAY PARA DADOS

    GOTO    INICIO  

;-----------------------------------------------------------
;            INICIO
;-----------------------------------------------------------

INICIO
    CALL     MEDIDA
    CALL     BIN_DEC

;-----------------------------------------------------------
;        CONDIÇÃO IF ELSE
;-----------------------------------------------------------
   
    MOVLW d'3' ; WREG = 3
    MOVWF z ; Z = WREG
    MOVF z, W ; WREG = Z
    SUBWF D1, W ; WREG = D1 - WREG
    BTFSC STATUS, C ; SE D1<Z, ENTÃO C NÃO DEVE SER DEFINIDO
    GOTO TRANSITO_FECHADO
    ; SE CHEGOU AQUI, SIGNIFICA QUE D1<Z
    bank0  
    BCF RS ;SELECIONA O DISPLAY PARA COMANDOS
    MOVLW B'00000001'
    CALL ESCREVE ;ESCREVE COMANDO PARA LIMPAR TODO O DISPLAY
    BSF RS ;SELECIONA O DISPLAY PARA DADOS
    CALL DELAY1
    MOVLW 'S'    ;  
    CALL ESCREVE      
    MOVLW 'I'    ;  
    CALL ESCREVE      
    MOVLW 'G'    ;  
    CALL ESCREVE      
    MOVLW 'A'    ;  
    CALL ESCREVE
    MOVLW ' '    ;  
    CALL ESCREVE
    MOVLW 'D'    ;  
    CALL ESCREVE
    MOVLW 'E'    ;  
    CALL ESCREVE
    MOVLW 'V'    ;  
    CALL ESCREVE                          
    MOVLW 'A'    ;  
    CALL ESCREVE      
    MOVLW 'G'    ;  
    CALL ESCREVE
    MOVLW 'A'    ;  
    CALL ESCREVE
    MOVLW 'R'    ;  
    CALL ESCREVE                          
   
    ; ACIONAMENTO E DESLIGAMENTO DOS LEDS
    BSF STATUS, 5; SELECIONA BANCO 1
    CLRF TRISC ; TRISC = 0
    BCF STATUS,5; SELECIONA BANCO 0

    BCF PORTC,1    ; PORTC RC1 = 0
    BSF PORTC, 0     ; PORTC RC0 = 1
    CALL DELAY1
    BCF PORTC,0    ; PORTC RCO = 0

    goto INICIO      ;loop

    GOTO continuacao
   
TRANSITO_FECHADO
   
    ; SE CHEGOU AQUI, SIGNIFICA QUE D1>Z
    bank0
    BCF RS; SELECIONA O DISPLAY PARA COMANDOS
    MOVLW B'00000001'
    CALL ESCREVE ;ESCREVE COMANDO PARA LIMPAR TODO O DISPLAY
    BSF RS ;SELECIONA O DISPLAY PARA DADOS
    CALL DELAY1
    MOVLW 'T'    ;  
    CALL ESCREVE      
    MOVLW 'R'    ;  
    CALL ESCREVE      
    MOVLW 'A'    ;  
    CALL ESCREVE      
    MOVLW 'N'    ;  
    CALL ESCREVE
    MOVLW 'S'    ;  
    CALL ESCREVE
    MOVLW 'I'    ;  
    CALL ESCREVE
    MOVLW 'T'    ;  
    CALL ESCREVE
    MOVLW 'O'    ;
    CALL ESCREVE

    MOVLW 'F'    ;
    CALL ESCREVE
    MOVLW 'E'    ;
    CALL ESCREVE
    MOVLW 'C'    ;
    CALL ESCREVE
    MOVLW 'H'    ;
    CALL ESCREVE
    MOVLW 'A'    ;
    CALL ESCREVE
    MOVLW 'D'    ;
    CALL ESCREVE
    MOVLW 'O'    ;  

    ; ACIONAMENTO E DESLIGAMENTO DOS LEDS
    BSF STATUS, 5; SELECIONA BANCO 1
    CLRF TRISC ; TRISC = 0
    BCF STATUS,5; SELECIONA BANCO 0
    BSF PORTC,1    ; PORTC RC1 = 1
    BCF PORTC,0    ; PORTC RCO = 0

    goto INICIO      ;loop

continuacao

;-----------------------------------------------------------
;        INICIO DA CONVERSAO
;-----------------------------------------------------------

MEDIDA
    ; AN0 - PESO
    bank1
    BSF        ADCON1,7        ;Justifica a Direita
    bank0
    BCF        ADCON0,3        ;--0Seta AN0 para Leitura
    BCF        ADCON0,4        ;-00
    BCF        ADCON0,5        ;000
    CALL    DELAY20        ;Espera 30us
    BSF        ADCON0,2            ;Inicia a Conversao
    CALL    FIM_CONVERSAO    ;Verifica o fim da conversao
    bank1
    MOVFW    ADRESL            ;Copia o valor convertido para W
    bank0
    MOVWF    T0                ;Envia o valor convertido para T0
    BCF        STATUS,C
    RRF        T0,1            ;Divide por 2
    MOVFW T0
    CALL TABELA_TEMP
    MOVWF T0
    RETURN

FIM_CONVERSAO
        BTFSC ADCON0, 2
        GOTO FIM_CONVERSAO
        RETURN

;-----------------------------------------------------------
;        ROTINA ESCREVE
;-----------------------------------------------------------

ESCREVE
    MOVWF PORTB ;ATUALIZA O DISPLAY
    NOP ;PERDE 1 CICLO DE MAQIUNA PARA ESTABILIZACAO (1us)
    BSF ENABLE ;ENVIA UM PULSO DE HABILITACAO (ENABLE) PARA O DISPLAY
    GOTO $+1
    BCF ENABLE
    CALL DELAY1 ;DELAY DE 8ms
    RETURN ;RETORNA PARA ULTIMA INSTRUCAO

;-----------------------------------------------------------
;            BIN PARA DEC
;-----------------------------------------------------------

BIN_DEC
    MOVFW T0
    MOVWF D0
    CLRF D1
BIN_DEC1
    MOVLW D'100'
    SUBWF D0,W
    BTFSS STATUS,C
    GOTO BIN_DEC2
    MOVWF D0
BIN_DEC2
    MOVLW D'10'
    SUBWF D0,W
    BTFSS STATUS,C
    RETURN
    MOVWF D0
    INCF D1,F
    GOTO BIN_DEC2

;-----------------------------------------------------------
;            DELAYS
;-----------------------------------------------------------

DELAY20
    MOVLW D'200'
    MOVWF TEMP2  
L2:
    MOVLW D'30'
    MOVWF TEMP1
L1:
    DECFSZ TEMP1, 1
    GOTO L1
    DECFSZ TEMP2, 1
    GOTO L2
    RETURN
DELAY1
    MOVLW D'10'
    MOVWF TEMP2  
L3:
    MOVLW D'30'
    MOVWF TEMP1
L4:
    DECFSZ TEMP1, 1
    GOTO L4
    DECFSZ TEMP2, 1
    GOTO L3
    RETURN
end

;-----------------------------------------------------------
;            FIM DO CÓDIGO
;-----------------------------------------------------------
 

LesJones

Joined Jan 8, 2017
3,506
You do not seem to be setting the channel select bits (Bits 3, 4. 5) in ADCON0. I can see in your code where you clear these 3 bits (Selecting channel 0.) but you never seem to set them to select another channel.

Les.
 

Thread Starter

Dragnovith

Joined Apr 16, 2021
21
You do not seem to be setting the channel select bits (Bits 3, 4. 5) in ADCON0. I can see in your code where you clear these 3 bits (Selecting channel 0.) but you never seem to set them to select another channel.

Les.
Could you tell me the line of code? I don't understand very well.
 

LesJones

Joined Jan 8, 2017
3,506
Where you clear all the channel select bits to select channel 0 you set the pattern for the channel that you want to select.
BCF ADCON0,3 ;--0Seta AN0 para Leitura
BCF ADCON0,4 ;-00
BCF ADCON0,5 ;000

So for channel 1
BSF ADCON0,3 ;--0Seta AN0 para Leitura
BCF ADCON0,4 ;-00
BCF ADCON0,5 ;000

So for channel 2
BCF ADCON0,3 ;--0Seta AN0 para Leitura
BSF ADCON0,4 ;-00
BCF ADCON0,5 ;000

So for channel 7
BSF ADCON0,3 ;--0Seta AN0 para Leitura
BSF ADCON0,4 ;-00
BSF ADCON0,5 ;000

If I was writing the code I would have a subroutine for reading the ADC.
I would pass the channel number to the routine in the W register.
The subroutine would left shift the value from the W register to the correct bit positions of the channel select bits.
It would then clear the channel select bits in ADCON0
It would then do a logical OR of the shifted channel number with ADCON0.

Les.
 

Thread Starter

Dragnovith

Joined Apr 16, 2021
21
[/QUOTE]
Where you clear all the channel select bits to select channel 0 you set the pattern for the channel that you want to select.
BCF ADCON0,3 ;--0Seta AN0 para Leitura
BCF ADCON0,4 ;-00
BCF ADCON0,5 ;000

So for channel 1
BSF ADCON0,3 ;--0Seta AN0 para Leitura
BCF ADCON0,4 ;-00
BCF ADCON0,5 ;000

So for channel 2
BCF ADCON0,3 ;--0Seta AN0 para Leitura
BSF ADCON0,4 ;-00
BCF ADCON0,5 ;000

So for channel 7
BSF ADCON0,3 ;--0Seta AN0 para Leitura
BSF ADCON0,4 ;-00
BSF ADCON0,5 ;000

If I was writing the code I would have a subroutine for reading the ADC.
I would pass the channel number to the routine in the W register.
The subroutine would left shift the value from the W register to the correct bit positions of the channel select bits.
It would then clear the channel select bits in ADCON0
It would then do a logical OR of the shifted channel number with ADCON0.

Les.
All right, I think I get it.

When creating the subroutine to read the ADC, will I have to create one for each analog port or can I use the same one for all?

I say this because I need to check through the OR (my idea) if all the sensors are above 30. So I would have to create other variables like D0, D1 and T0 that are respectively of the unit, ten and hundred of the sensor.
So I believe that I have to call a routine for each AN1,AN2 and AN3.

Code:
MEDIDA
    ; AN0 - PESO
    READ_AN0:
        bank0
        BCF     ADCON0,3        ; --0 Seta AN0 para Leitura
        BCF     ADCON0,4        ; -00
    READ_ADC:
        BCF     ADCON0,5        ; 0xx
        CALL    DELAY20         ; Espera 30us
        BSF     ADCON0,2        ; Inicia a Conversao
        CALL    FIM_CONVERSAO   ; Verifica o fim da conversao
        bank1
        MOVFW   ADRESL          ; Copia o valor convertido para W
        bank0
        MOVWF   T0              ; Envia o valor convertido para T0
        BCF     STATUS,C
        RRF     T0,1            ; Divide por 2
        MOVFW   T0
        CALL    TABELA_TEMP
        MOVWF   T0
        RETURN
   
    READ_AN1:
        bank0
        BSF     ADCON0,3        ; --1 Seta AN1 para Leitura
        BCF     ADCON0,4        ; -01
        goto    READ_ADC
       
    READ_AN2:
        bank0
        BCF     ADCON0,3        ; --0 Seta AN2 para Leitura
        BSF     ADCON0,4        ; -10
        goto    READ_ADC
       
    READ_AN3:
        bank0
        BSF     ADCON0,3        ; --1 Seta AN3 para Leitura
        BSF     ADCON0,4        ; -11
        goto    READ_ADC
       
    FIM_CONVERSAO
        BTFSC   ADCON0,2
        GOTO    FIM_CONVERSAO
        RETURN
 

LesJones

Joined Jan 8, 2017
3,506
You can do it as you have shown in post #5.

I think it is better to set W (Or a variable )to the ADC channel number and then call a common subroutine to read the ADC which will use the value of W (Or the variable) to read that channel number.

This is some code I wrote for a PIC16F88.
Code:
;Subroutines

Read_Analog:            ;Channel number will be in AD_Channel (Bits 0 - 2)
                ;Result returned in "W"

    RLF    AD_Channel    ;Move bits to required position (Bits 5 -3)    ;1 cycle
    RLF    AD_Channel    ;1 cycle
    RLF    AD_Channel    ;1 cycle
    BCF    ADCON0, 3    ;1 cycle
    BCF    ADCON0, 4    ;1 cycle
    BCF    ADCON0, 5    ;1 cycle
    MOVF    AD_Channel, W    ;1 cycle
    IORWF    ADCON0, F    ;Select channel    ;1 cycle

    MOVLW    D'40'        ;1 cycle            64 decimal
    MOVWF    AD_Delay    ; acquisition time  1 cycle

Dec_AD_delay:                        ;loop is 3 cycles long (64 x 3 = 192
    DECFSZ    AD_Delay,f    ;1 cycle  (2 on exit)
    GOTO    Dec_AD_delay    ;2 cycles
    BSF        ADCON0,2        ; GO/DONE bit start conversion
WAIT_AD_Ready:
    BTFSC    ADCON0,2        ; conversion complete when cleared ~11 cycles
    GOTO    WAIT_AD_Ready
    MOVF    ADRESH,w
    RETURN        ;2 cycles


[/code}
In the above code I passed the channel number to the subroutine in a variable called " AD_Channel "
I only needed an 8 bit value so I just copied ADRESH to W. You may also need the other 2 bits of the full 10 bit value. these will be in ADRESL.
Don't forget to configure the way the 10 bits are justified between ADRESH and ADRESL when you initialise the ADC settings.

Les.
 

Thread Starter

Dragnovith

Joined Apr 16, 2021
21
Interesting, thanks!

I'm almost done with the code, I have to make some adjustments. I wanted the sensor to activate the transito_fechado when one of the LM35 values passed 30, but the condition was reversed. This was the condition I tried to apply:

IF ELSE CONDITION
Code:
;-----------------------------------------------------------
;        CONDIÇÃO IF ELSE
;-----------------------------------------------------------
    
    MOVLW d'3' ; WREG = 3
    MOVWF z ; Z = WREG
    MOVF z, W ; WREG = Z
    SUBWF D1, W ; WREG = D3 - WREG
    BTFSS STATUS, C ; SE D1<Z, ENTÃO C NÃO DEVE SER DEFINIDO
    GOTO TRANSITO_ABERTO
; SE CHEGOU AQUI SIGNIFICA QUE D1>=3
; TESTE SE D3>=3
    MOVLW d'3' ; WREG = 3
    MOVWF z ; Z = WREG
    MOVF z, W ; WREG = Z
    SUBWF D3, W ; WREG = D3 - WREG
    BTFSS STATUS, C ; SE D3<Z, ENTÃO C NÃO DEVE SER DEFINIDO
    GOTO TRANSITO_ABERTO
; SE CHEGOU AQUI SIGNIFICA QUE D3>=3
; TESTE SE D5 >= 5
    MOVLW d'3' ; WREG = 3
    MOVWF z ; Z = WREG
    MOVF z, W ; WREG = Z
    SUBWF D5, W ; WREG = D5 - WREG
    BTFSS STATUS, C ; SE D5<Z, ENTÃO C NÃO DEVE SER DEFINIDO
    GOTO TRANSITO_ABERTO
; SE CHEGOU AQUI SIGNIFICA QUE D5>=3
; TESTE SE D7>=3
    MOVLW d'3' ; WREG = 3
    MOVWF z ; Z = WREG
    MOVF z, W ; WREG = Z
    SUBWF D7, W ; WREG = D7 - WREG
    BTFSS STATUS, C ; SE D7<Z, ENTÃO C NÃO DEVE SER DEFINIDO
    GOTO TRANSITO_ABERTO
; SE CHEGOU AQUI SIGNIFICA QUE D7>=3
; E VAI ABRIR O TRANSITO
TRANSITO_FECHADO
    bank0   
    BCF RS ;SELECIONA O DISPLAY PARA COMANDOS
    MOVLW B'00000001'
    CALL ESCREVE ;ESCREVE COMANDO PARA LIMPAR TODO O DISPLAY
    BSF RS ;SELECIONA O DISPLAY PARA DADOS
    CALL DELAY1
    MOVLW 'T'    ;   
    CALL ESCREVE       
    MOVLW 'R'    ;   
    CALL ESCREVE       
    MOVLW 'A'    ;   
    CALL ESCREVE       
    MOVLW 'N'    ;   
    CALL ESCREVE
    MOVLW 'S'    ;   
    CALL ESCREVE
    MOVLW 'I'    ;   
    CALL ESCREVE
    MOVLW 'T'    ;   
    CALL ESCREVE
    MOVLW 'O'    ;
    CALL ESCREVE
    MOVLW 'G'    ;
    CALL ESCREVE
    MOVLW 'F'    ;
    CALL ESCREVE
    MOVLW 'E'    ;
    CALL ESCREVE
    MOVLW 'C'    ;   
    CALL ESCREVE
    MOVLW 'H'    ;   
    CALL ESCREVE
    MOVLW 'A'    ;
    CALL ESCREVE
    MOVLW 'D'    ;
    CALL ESCREVE
    MOVLW 'O'    ;

                  
    
    ; ACIONAMENTO E DESLIGAMENTO DOS LEDS
    BSF STATUS, 5; SELECIONA BANCO 1
    CLRF TRISC ; TRISC = 0
    BCF STATUS,5; SELECIONA BANCO 0
    BSF PORTC,1    ; PORTC RC1 = 1
    BCF PORTC,0    ; PORTC RCO = 0

    goto INICIO      ;loop

    continuacao
    
TRANSITO_ABERTO
    
    ; SE CHEGOU AQUI, SIGNIFICA QUE D1>Z
    bank0
    BCF RS; SELECIONA O DISPLAY PARA COMANDOS
    MOVLW B'00000001'
    CALL ESCREVE ;ESCREVE COMANDO PARA LIMPAR TODO O DISPLAY
    BSF RS ;SELECIONA O DISPLAY PARA DADOS
    CALL DELAY1
    MOVLW 'S'    ;   
    CALL ESCREVE       
    MOVLW 'I'    ;   
    CALL ESCREVE       
    MOVLW 'G'    ;   
    CALL ESCREVE       
    MOVLW 'A'    ;   
    CALL ESCREVE
    MOVLW 'D'    ;   
    CALL ESCREVE
    MOVLW 'E'    ;   
    CALL ESCREVE
    MOVLW 'V'    ;   
    CALL ESCREVE
    MOVLW 'A'    ;   
    CALL ESCREVE                           
    MOVLW 'G'    ;   
    CALL ESCREVE       
    MOVLW 'A'    ;   
    CALL ESCREVE
    MOVLW 'R'    ;         

    ; ACIONAMENTO E DESLIGAMENTO DOS LEDS
    BSF STATUS, 5; SELECIONA BANCO 1
    CLRF TRISC ; TRISC = 0
    BCF STATUS,5; SELECIONA BANCO 0

    BCF PORTC,1    ; PORTC RC1 = 0
    BSF PORTC, 0     ; PORTC RC0 = 1
    CALL DELAY20
    BCF PORTC,0    ; PORTC RCO = 0

    goto INICIO      ;loop

    GOTO continuacao
COMPLETE CODE
Code:
PROCESSOR 16F877A   ;primeira linha é o tipo de processador

#include <p16f877a.inc>

__CONFIG _CP_OFF & _WDT_OFF & _PWRTE_ON & _XT_OSC


D0 equ 0x21 ;---UN SENSOR 1
D1 equ 0x22 ;---DEZ SENSOR 1
T0 equ 0x24 ;---CENTENA
T1 equ 0x28 ;---CENTENA
T2 equ 0x29 ;---CENTENA
T3 equ 0x30 ;---CENTENA
D2 equ 0x31 ;---UN SENSOR 2
D3 equ 0x32 ;---DEZ SENSOR 2
D4 equ 0x33 ;---UN SENSOR 2
D5 equ 0x34 ;---DEZ SENSOR 2
D6 equ 0x35 ;---UN SENSOR 2
D7 equ 0x36 ;---DEZ SENSOR 2
TEMP1 equ 0x25
TEMP2 EQU 0X26
z EQU 0X27
PORTC EQU 07
TRISC EQU 87

#DEFINE ENABLE                PORTD,0
#DEFINE RS                    PORTD,1
#DEFINE bank0 BCF STATUS,RP0
#DEFINE bank1 BSF STATUS,RP0

org 0x00   ;vetor de reset
goto Main  ;após o reset, começa na função principal

org 0x04   ;vetor de interrupção
goto Main  ; vai pra main

;-----------------------------------------------------------
;        TABELA DE MEDIDA
;-----------------------------------------------------------

TABELA_TEMP               
    ADDWF        PCL   
    RETLW    b'00000000'
    RETLW    b'00000001'
    RETLW    b'00000010'
    RETLW    b'00000011'
    RETLW    b'00000100'
    RETLW    b'00000101'
    RETLW    b'00000110'
    RETLW    b'00000111'
    RETLW    b'00001000'
    RETLW    b'00001001'
    RETLW    b'00001010'
    RETLW    b'00001011'
    RETLW    b'00001100'
    RETLW    b'00001101'
    RETLW    b'00001110'
    RETLW    b'00001111'
    RETLW    b'00010000'
    RETLW    b'00010001'
    RETLW    b'00010010'
    RETLW    b'00010011'
    RETLW    b'00010100'
    RETLW    b'00010101'
    RETLW    b'00010110'
    RETLW    b'00010111'
    RETLW    b'00011000'
    RETLW    b'00011001'
    RETLW    b'00011010'
    RETLW    b'00011011'
    RETLW    b'00011100'
    RETLW    b'00011101'
    RETLW    b'00011110'
    RETLW    b'00011111'
    RETLW    b'00100000'
    RETLW    b'00100001'
    RETLW    b'00100010'
    RETLW    b'00100011'
    RETLW    b'00100100'
    RETLW    b'00100101'
    RETLW    b'00100110'
    RETLW    b'00100111'
    RETLW    b'00101000'
    RETLW    b'00101001'
    RETLW    b'00101001'
    RETLW    b'00101010'
    RETLW    b'00101011'
    RETLW    b'00101100'
    RETLW    b'00101101'
    RETLW    b'00101110'
    RETLW    b'00101111'
    RETLW    b'00110000'
    RETLW    b'00110001'
    RETLW    b'00110010'

;-----------------------------------------------------------
;        TABELA PARA O LCD
;-----------------------------------------------------------

TABELA_LCD        ;para mostrar o caractere em asc no display       
    ADDWF        PCL   
    RETLW '0'
    RETLW '1'
    RETLW '2'
    RETLW '3'
    RETLW '4'
    RETLW '5'
    RETLW '6'
    RETLW '7'
    RETLW '8'
    RETLW '9'

;-----------------------------------------------------------
;                MAIN
;-----------------------------------------------------------
Main
       bank1       ;     MUDA BANCO MEMORIA 1
        MOVLW   B'10000000'
;              1-UU----     Alinhado a direita   
;              -0UU----     FSC/   
;              --UU0000     Todas analogicas   
       MOVWF   ADCON1    ;   
        MOVLW   B'00000000'
    MOVWF   TRISB             
        MOVLW   B'00000000'
    MOVWF   TRISD             
        MOVLW   B'11111111'
    MOVWF   TRISA           
    MOVLW   B'00000000'     
;              --------       
        MOVWF   OPTION_REG     
        MOVLW    B'00000111' ; Desabilita os comparadores           
    MOVWF    CMCON           
    
    bank0       ; BANCO DE MEMORIA 0
        MOVLW   B'00000001' ; Configura ADC
;              00----U-    FSC/8   
;              -------1    Liga o conversor   
;              --000---    Canal AN0 entrada
    MOVWF   ADCON0

    MOVLW   B'00000000'   
    MOVWF   INTCON

        CLRF    PORTB       
    CLRF    D0
    CLRF    D1
    CLRF    D2
    CLRF    D3
    CLRF    D4
    CLRF    D5
    CLRF    D6
    CLRF    D7

;-----------------------------------------------------------
;            CONFIGURA LCD
;-----------------------------------------------------------

LCD_IN
    CALL DELAY20
    BCF RS ;SELECIONA O DISPLAY PARA COMANDOS
    MOVLW 0X30 ;ESCREVE COMANDO 0X3O PARA INICIALIZACAO
    CALL ESCREVE

    CALL DELAY20
    MOVLW 0X30 ;ESCREVE COMANDO 0X3O PARA INICIALIZACAO
    CALL ESCREVE
    MOVLW 0X30
    CALL ESCREVE
    MOVLW B'00111000' ;ESCREVE COMANDO PARA INTERFACE D E 8 VAIS DE DADOS
    CALL ESCREVE
    MOVLW B'00000001'
    CALL ESCREVE ;ESCREVE COMANDO PARA LIMPAR TODO O DISPLAY
    
    CALL DELAY20 ;DELAY DE 8MS
    MOVLW B'00001100'
    CALL ESCREVE ;ESCREVE COMANDO PARA LIGAR O DISPLAY SEM CURSOR
    MOVLW B'00000110'
    CALL ESCREVE ;ESCREVE COMANDO PARA INCREMENTAR AUTOMATICA A DIREITA
    BSF RS ;SELECIONA O DISPLAY PARA DADOS

    GOTO    INICIO   

;-----------------------------------------------------------
;            INICIO
;-----------------------------------------------------------

INICIO
    CALL     MEDIDA
    CALL     BIN_DEC_AN0
    CALL     MEDIDA1
    CALL     BIN_DEC_AN1
    CALL     MEDIDA2
    CALL     BIN_DEC_AN2
    CALL     MEDIDA3
    CALL     BIN_DEC_AN3

;-----------------------------------------------------------
;        CONDIÇÃO IF ELSE
;-----------------------------------------------------------
    
    MOVLW d'3' ; WREG = 3
    MOVWF z ; Z = WREG
    MOVF z, W ; WREG = Z
    SUBWF D1, W ; WREG = D3 - WREG
    BTFSS STATUS, C ; SE D1<Z, ENTÃO C NÃO DEVE SER DEFINIDO
    GOTO TRANSITO_ABERTO
; SE CHEGOU AQUI SIGNIFICA QUE D1>=3
; TESTE SE D3>=3
    MOVLW d'3' ; WREG = 3
    MOVWF z ; Z = WREG
    MOVF z, W ; WREG = Z
    SUBWF D3, W ; WREG = D3 - WREG
    BTFSS STATUS, C ; SE D3<Z, ENTÃO C NÃO DEVE SER DEFINIDO
    GOTO TRANSITO_ABERTO
; SE CHEGOU AQUI SIGNIFICA QUE D3>=3
; TESTE SE D5 >= 5
    MOVLW d'3' ; WREG = 3
    MOVWF z ; Z = WREG
    MOVF z, W ; WREG = Z
    SUBWF D5, W ; WREG = D5 - WREG
    BTFSS STATUS, C ; SE D5<Z, ENTÃO C NÃO DEVE SER DEFINIDO
    GOTO TRANSITO_ABERTO
; SE CHEGOU AQUI SIGNIFICA QUE D5>=3
; TESTE SE D7>=3
    MOVLW d'3' ; WREG = 3
    MOVWF z ; Z = WREG
    MOVF z, W ; WREG = Z
    SUBWF D7, W ; WREG = D7 - WREG
    BTFSS STATUS, C ; SE D7<Z, ENTÃO C NÃO DEVE SER DEFINIDO
    GOTO TRANSITO_ABERTO
; SE CHEGOU AQUI SIGNIFICA QUE D7>=3
; E VAI ABRIR O TRANSITO
TRANSITO_FECHADO
    bank0   
    BCF RS ;SELECIONA O DISPLAY PARA COMANDOS
    MOVLW B'00000001'
    CALL ESCREVE ;ESCREVE COMANDO PARA LIMPAR TODO O DISPLAY
    BSF RS ;SELECIONA O DISPLAY PARA DADOS
    CALL DELAY1
    MOVLW 'T'    ;   
    CALL ESCREVE       
    MOVLW 'R'    ;   
    CALL ESCREVE       
    MOVLW 'A'    ;   
    CALL ESCREVE       
    MOVLW 'N'    ;   
    CALL ESCREVE
    MOVLW 'S'    ;   
    CALL ESCREVE
    MOVLW 'I'    ;   
    CALL ESCREVE
    MOVLW 'T'    ;   
    CALL ESCREVE
    MOVLW 'O'    ;
    CALL ESCREVE
    MOVLW 'G'    ;
    CALL ESCREVE
    MOVLW 'F'    ;
    CALL ESCREVE
    MOVLW 'E'    ;
    CALL ESCREVE
    MOVLW 'C'    ;   
    CALL ESCREVE
    MOVLW 'H'    ;   
    CALL ESCREVE
    MOVLW 'A'    ;
    CALL ESCREVE
    MOVLW 'D'    ;
    CALL ESCREVE
    MOVLW 'O'    ;

                  
    
    ; ACIONAMENTO E DESLIGAMENTO DOS LEDS
    BSF STATUS, 5; SELECIONA BANCO 1
    CLRF TRISC ; TRISC = 0
    BCF STATUS,5; SELECIONA BANCO 0
    BSF PORTC,1    ; PORTC RC1 = 1
    BCF PORTC,0    ; PORTC RCO = 0

    goto INICIO      ;loop

    continuacao
    
TRANSITO_ABERTO
    
    ; SE CHEGOU AQUI, SIGNIFICA QUE D1>Z
    bank0
    BCF RS; SELECIONA O DISPLAY PARA COMANDOS
    MOVLW B'00000001'
    CALL ESCREVE ;ESCREVE COMANDO PARA LIMPAR TODO O DISPLAY
    BSF RS ;SELECIONA O DISPLAY PARA DADOS
    CALL DELAY1
    MOVLW 'S'    ;   
    CALL ESCREVE       
    MOVLW 'I'    ;   
    CALL ESCREVE       
    MOVLW 'G'    ;   
    CALL ESCREVE       
    MOVLW 'A'    ;   
    CALL ESCREVE
    MOVLW 'D'    ;   
    CALL ESCREVE
    MOVLW 'E'    ;   
    CALL ESCREVE
    MOVLW 'V'    ;   
    CALL ESCREVE
    MOVLW 'A'    ;   
    CALL ESCREVE                           
    MOVLW 'G'    ;   
    CALL ESCREVE       
    MOVLW 'A'    ;   
    CALL ESCREVE
    MOVLW 'R'    ;         

    ; ACIONAMENTO E DESLIGAMENTO DOS LEDS
    BSF STATUS, 5; SELECIONA BANCO 1
    CLRF TRISC ; TRISC = 0
    BCF STATUS,5; SELECIONA BANCO 0

    BCF PORTC,1    ; PORTC RC1 = 0
    BSF PORTC, 0     ; PORTC RC0 = 1
    CALL DELAY20
    BCF PORTC,0    ; PORTC RCO = 0

    goto INICIO      ;loop

    GOTO continuacao

;-----------------------------------------------------------
; INICIO DA CONVERSAO => CONVERSION START
;-----------------------------------------------------------

    MEDIDA
    ; AN0 - PESO
    ; LER AN0
        bank0
        BCF     ADCON0,3        ; --0 Seta AN0 para Leitura
        BCF     ADCON0,4        ; -00
    ; LER ADC
        BCF     ADCON0,5        ; 0xx
        CALL    DELAY20         ; Espera 30us
        BSF     ADCON0,2        ; Inicia a Conversao
        CALL    FIM_CONVERSAO   ; Verifica o fim da conversao
        bank1
        MOVFW   ADRESL          ; Copia o valor convertido para W
        bank0
        MOVWF   T0              ; Envia o valor convertido para T0
        BCF     STATUS,C
        RRF     T0,1            ; Divide por 2
        MOVFW   T0
        CALL    TABELA_TEMP
        MOVWF   T0
        RETURN
    
    MEDIDA1
    ; AN1 - PESO
    ; LER AN1
        bank0
        BSF     ADCON0,3        ; --1 Seta AN1 para Leitura
        BCF     ADCON0,4        ; -01
    ; LER ADC
        BCF     ADCON0,5        ; 0xx
        CALL    DELAY20         ; Espera 30us
        BSF     ADCON0,2        ; Inicia a Conversao
        CALL    FIM_CONVERSAO   ; Verifica o fim da conversao
        bank1
        MOVFW   ADRESL          ; Copia o valor convertido para W
        bank0
        MOVWF   T1              ; Envia o valor convertido para T0
        BCF     STATUS,C
        RRF     T1,1            ; Divide por 2
        MOVFW   T1
        CALL    TABELA_TEMP
        MOVWF   T1
        RETURN
        
    MEDIDA2
    ; AN2 - PESO
    ; LER AN2
        bank0
        BCF     ADCON0,3        ; --0 Seta AN2 para Leitura
        BSF     ADCON0,4        ; -10
        CALL DELAY20   
    ; LER ADC
        BCF     ADCON0,5        ; 0xx
        CALL    DELAY20         ; Espera 30us
        BSF     ADCON0,2        ; Inicia a Conversao
        CALL    FIM_CONVERSAO   ; Verifica o fim da conversao
        bank1
        MOVFW   ADRESL          ; Copia o valor convertido para W
        bank0
        MOVWF   T2              ; Envia o valor convertido para T0
        BCF     STATUS,C
        RRF     T2,1            ; Divide por 2
        MOVFW   T2
        CALL    TABELA_TEMP
        MOVWF   T2
        RETURN
        
    MEDIDA3
    ; AN3 - PESO
    ; LER AN3
        bank0
        BSF     ADCON0,3        ; --1 Seta AN3 para Leitura
        BSF     ADCON0,4        ; -11
        CALL DELAY20
    ; LER ADC
        BCF     ADCON0,5        ; 0xx
        CALL    DELAY20         ; Espera 30us
        BSF     ADCON0,2        ; Inicia a Conversao
        CALL    FIM_CONVERSAO   ; Verifica o fim da conversao
        bank1
        MOVFW   ADRESL          ; Copia o valor convertido para W
        bank0
        MOVWF   T3             ; Envia o valor convertido para T0
        BCF     STATUS,C
        RRF     T3,1            ; Divide por 2
        MOVFW   T3
        CALL    TABELA_TEMP
        MOVWF   T3
        RETURN
        
    FIM_CONVERSAO
        BTFSC   ADCON0,2
        GOTO    FIM_CONVERSAO
        RETURN

;-----------------------------------------------------------
;        ROTINA ESCREVE
;-----------------------------------------------------------

ESCREVE
    MOVWF PORTB ;ATUALIZA O DISPLAY
    NOP ;PERDE 1 CICLO DE MAQIUNA PARA ESTABILIZACAO (1us)
    BSF ENABLE ;ENVIA UM PULSO DE HABILITACAO (ENABLE) PARA O DISPLAY
    GOTO $+1
    BCF ENABLE
    CALL DELAY1 ;DELAY DE 8ms
    RETURN ;RETORNA PARA ULTIMA INSTRUCAO

;-----------------------------------------------------------
;            BIN PARA DEC
;-----------------------------------------------------------
; AN0
BIN_DEC_AN0
    MOVFW T0
    MOVWF D0
    CLRF D1
    
BIN_DEC1_AN0
    MOVLW D'100'
    SUBWF D0,W
    BTFSS STATUS,C
    GOTO BIN_DEC2_AN0
    MOVWF D0
    
BIN_DEC2_AN0
    MOVLW D'10'
    SUBWF D0,W
    BTFSS STATUS,C
    RETURN
    MOVWF D0
    INCF D1,F
    GOTO BIN_DEC2_AN0
; AN1
BIN_DEC_AN1
    MOVFW T1
    MOVWF D2
    CLRF D3
    
BIN_DEC1_AN1
    MOVLW D'100'
    SUBWF D2,W
    BTFSS STATUS,C
    GOTO BIN_DEC2_AN1
    MOVWF D2
    
BIN_DEC2_AN1
    MOVLW D'10'
    SUBWF D2,W
    BTFSS STATUS,C
    RETURN
    MOVWF D2
    INCF D3,F
    GOTO BIN_DEC2_AN1
; AN2
BIN_DEC_AN2
    MOVFW T2
    MOVWF D4
    CLRF D5
    
BIN_DEC1_AN2
    MOVLW D'100'
    SUBWF D4,W
    BTFSS STATUS,C
    GOTO BIN_DEC2_AN2
    MOVWF D4
    
BIN_DEC2_AN2
    MOVLW D'10'
    SUBWF D4,W
    BTFSS STATUS,C
    RETURN
    MOVWF D4
    INCF D5,F
    GOTO BIN_DEC2_AN2
; AN2
BIN_DEC_AN3
    MOVFW T3
    MOVWF D6
    CLRF D7
    
BIN_DEC1_AN3
    MOVLW D'100'
    SUBWF D6,W
    BTFSS STATUS,C
    GOTO BIN_DEC2_AN3
    MOVWF D6
    
BIN_DEC2_AN3
    MOVLW D'10'
    SUBWF D6,W
    BTFSS STATUS,C
    RETURN
    MOVWF D6
    INCF D7,F
    GOTO BIN_DEC2_AN3
;-----------------------------------------------------------
;            DELAYS
;-----------------------------------------------------------

DELAY20
    MOVLW D'200'
    MOVWF TEMP2   
L2:
    MOVLW D'30'
    MOVWF TEMP1
L1:
    DECFSZ TEMP1, 1
    GOTO L1
    DECFSZ TEMP2, 1
    GOTO L2
    RETURN
DELAY1
    MOVLW D'10'
    MOVWF TEMP2   
L3:
    MOVLW D'30'
    MOVWF TEMP1
L4:
    DECFSZ TEMP1, 1
    GOTO L4
    DECFSZ TEMP2, 1
    GOTO L3
    RETURN
end

;-----------------------------------------------------------
;            FIM DO CÓDIGO
;-----------------------------------------------------------
 

Thread Starter

Dragnovith

Joined Apr 16, 2021
21
You can do it as you have shown in post #5.

I think it is better to set W (Or a variable )to the ADC channel number and then call a common subroutine to read the ADC which will use the value of W (Or the variable) to read that channel number.

This is some code I wrote for a PIC16F88.
Code:
;Subroutines

Read_Analog:            ;Channel number will be in AD_Channel (Bits 0 - 2)
                ;Result returned in "W"

    RLF    AD_Channel    ;Move bits to required position (Bits 5 -3)    ;1 cycle
    RLF    AD_Channel    ;1 cycle
    RLF    AD_Channel    ;1 cycle
    BCF    ADCON0, 3    ;1 cycle
    BCF    ADCON0, 4    ;1 cycle
    BCF    ADCON0, 5    ;1 cycle
    MOVF    AD_Channel, W    ;1 cycle
    IORWF    ADCON0, F    ;Select channel    ;1 cycle

    MOVLW    D'40'        ;1 cycle            64 decimal
    MOVWF    AD_Delay    ; acquisition time  1 cycle

Dec_AD_delay:                        ;loop is 3 cycles long (64 x 3 = 192
    DECFSZ    AD_Delay,f    ;1 cycle  (2 on exit)
    GOTO    Dec_AD_delay    ;2 cycles
    BSF        ADCON0,2        ; GO/DONE bit start conversion
WAIT_AD_Ready:
    BTFSC    ADCON0,2        ; conversion complete when cleared ~11 cycles
    GOTO    WAIT_AD_Ready
    MOVF    ADRESH,w
    RETURN        ;2 cycles


[/code}
In the above code I passed the channel number to the subroutine in a variable called " AD_Channel "
I only needed an 8 bit value so I just copied ADRESH to W. You may also need the other 2 bits of the full 10 bit value. these will be in ADRESL.
Don't forget to configure the way the 10 bits are justified between ADRESH and ADRESL when you initialise the ADC settings.

Les.
It's working now, thank you very much for your help. You having sent me the way the channel change works helped me a lot.
 
Top