TODOPIC
Microcontroladores PIC => Almacén del Assembler => Mensaje iniciado por: frozen en 01 de Noviembre de 2011, 10:22:49
-
Buenos dias a todos. Tengo un problema con el ADC del pic16f877a.
-En proteus cada canal es independiente del otro y por tanto salen los valores binarios por los respectivos puertos.
CANAL 0 --> El valor convertido lo mando al PORTB
CANAL 1 --> El valor convertido lo mando al PORTC
-En circuito montado cuando vario un potenciometro afecta al otro canal.
por ejemplo si pongo el canal0 a GND y el canal1 a 5v salida por el portc es F0h. Eso esta mal ya que debe salir FFh.
Aqui les dejo mi assembler y mi simulacion en proteus. Gracias de antemano.
;****************************
; BY JOEL HUAMAN HUARCAYA
;****************************
;****************************************************************
; PROGRAMA DE CONVIERTE LA SEÑAL ANALOGA DEL CANAL 0 Y CANAL 1
; Y MUESTRA LOS VALORES POR EL PORTB Y PORTC
;****************************************************************
__CONFIG _WDT_OFF&_PWRTE_ON&_HS_OSC&_LVP_OFF&_CP_OFF
LIST P=16F877A
INCLUDE <P16F877A.INC>
INCLUDE <MACROPIC.INC>
CBLOCK 0x20
VOLT
CORRIENTE
ENDC
ORG 0
;--------CONFIGURANDO CANALES DE --------------------------------------------
BANCO 1
clrf TRISC
clrf TRISB
MOV TRISA,0XFF
bsf TRISE,2
BANCO 0
;--------BORRANDO REGISTROS-------------------------------------------------
clrf PORTB
clrf PORTC
call INICIO_ADC ;inicia convertidor
infinito
CANAL 0 ;se selecciona el canal 0
bsf ADCON0,0 ;enciende el convertidor
call muestra_ADC_8 ;en w se obtiene el valor de conversion
movwf VOLT
movwf PORTB
call ret50ms
CANAL 1 ;selecciona el canal 1
bsf ADCON0,0
call muestra_ADC_8 ;en w se obtiene el valor de conversion
movwf CORRIENTE
movwf PORTC
call ret50ms
goto infinito
INCLUDE <conv_ad.ASM>
INCLUDE <RETARDO.ASM>
END
-
aqui les dejo una imagen en proteus funciona bien el ADC pero en protoboard no. :5]
(http://s2.subirimagenes.com/otros/previo/thump_7089702fuente-digital.jpg)
-
has mirado el voltaje que le llega al pin?? Puede que no llege VDD y por eso te marca F0h en vez de FF
-
has mirado el voltaje que le llega al pin?? Puede que no llege VDD y por eso te marca F0h en vez de FF
Si he medido ambos. canal0 4.9v y el otro canal 0v. No me podrias dar un ejemplo q como se cambia de canal correctamente.
En proteus simula correctamente. Pero en mi protoboard el canal0 afecta al canal 1. Pero el canal1 no altera al 0.
-
para tu pic creo que debes hacer un delay para esperar el tiempo de adqusicion con el tiempo de conversion. No se ve el codigo completo muestra_ADC_8.
Lo que te digo es que desde que seleccionas el canal hasta que empiezas la conversion debe haber un retardo (en el datasheet viene el tiempo minimo), este tiempo depende de la impedancia de la fuente, pero si no es un caso critico donde obtengas el voltaje por tiempos le pones un delay considerable y vale.
-
para tu pic creo que debes hacer un delay para esperar el tiempo de adqusicion con el tiempo de conversion. No se ve el codigo completo muestra_ADC_8.
a ver hay te dejo el codigo. Gracias por tu ayuda. Despues de la conversion tengo que esperar un tiempo( le puse 50ms), pero igual.
;----------------------inicializar
INICIO_ADC
BANCO 1
MOV ADCON1,B'00000000' ;CONFIGURA LOS 8 CANALES COMO ANALOGICOS
BANCO 0
clrf ADCON0
bsf ADCON0,7 ;FOSC/32
bcf PIR1,ADIF
return
;----------------------- PARA 8 bits
; la muestra de 8 bits se devuelve en W
muestra_ADC_8
bsf ADCON0,2
btfsc ADCON0,2
goto $-1
movf ADRESH,0
bcf ADCON0,0
bcf PIR1,ADIF
return
cblock
contador1 ;registro usado por retardo
contador2 ;registro usado por retardo
R_VAR1
R_VAR2
R_VAR3
R_VAR4
R_VAR5
endc
;*******************************************************************
t0 equ 0x82 ;constante para generar aprox. 25ms
t4.6ms equ 0x06*4 ;constante para generar 4,6ms
t15.4ms equ 0x14*4 ;constante para generar 15,4ms
t200us equ 0x01 ;constante para generar aprox. 200us
;*******************************************************************
retardo:
clrf contador1 ;aclara contador1
ret decfsz contador1,F ;
goto ret
decfsz contador2,F
goto ret
return
ret50ms: ;RETARDO 50 ms
movlw t0
movwf contador2
call retardo
call retardo
return
BANCO macro x
if x == 0
bcf STATUS,RP0
bcf STATUS,RP1
endif
if x == 1
bsf STATUS,RP0
bcf STATUS,RP1
endif
if x == 2
bcf STATUS,RP0
bsf STATUS,RP1
endif
if x == 3
bsf STATUS,RP0
bsf STATUS,RP1
endif
endm
;**************************************************************CANAL
CANAL macro x
if x==0
bcf ADCON0,3
bcf ADCON0,4
bcf ADCON0,5
endif
if x==1
bsf ADCON0,3
bcf ADCON0,4
bcf ADCON0,5
endif
if x==2
bcf ADCON0,3
bsf ADCON0,4
bcf ADCON0,5
endif
if x==3
bsf ADCON0,3
bsf ADCON0,4
bcf ADCON0,5
endif
if x==4
bcf ADCON0,3
bcf ADCON0,4
bsf ADCON0,5
endif
if x==5
bsf ADCON0,3
bcf ADCON0,4
bsf ADCON0,5
endif
if x==6
bcf ADCON0,3
bsf ADCON0,4
bsf ADCON0,5
endif
if x==7
bsf ADCON0,3
bsf ADCON0,4
bsf ADCON0,5
endif
endm
;************************************************************** mov
MOV macro registro,literal
movlw literal
movwf registro
endm
-
ponle el delay entre el macro CANAL 0, 1 y el adc_muestra
-
ponle el delay entre el macro CANAL 0, 1 y el adc_muestra
infinito
CANAL 0 ;se selecciona el canal 0
call ret50ms ;YA LE AGREGUE AKI EL RETARDO. TE ENTENDI BIEN?
bsf ADCON0,0 ;enciende el convertidor
call muestra_ADC_8 ;en w se obtiene el valor de conversion
movwf VOLT
movwf PORTB
call ret50ms
CANAL 1 ;selecciona el canal 1
call ret50ms ;YA LE AGREGUE AKI EL RETARDO. TE ENTENDI BIEN?
bsf ADCON0,0
call muestra_ADC_8 ;en w se obtiene el valor de conversion
movwf CORRIENTE
movwf PORTC
call ret50ms
goto infinito
-
si, prueba asi, de cuanto es el potenciometro? 1k? 10k?
-
si, prueba asi, de cuanto es el potenciometro? 1k? 10k?
Le 2 potenciometros de5k ( uno para cada canal).
Estoy grabando el pic y probando.
-
si, prueba asi, de cuanto es el potenciometro? 1k? 10k?
Le 2 potenciometros de 5k ( uno para cada canal).
Estoy grabando el pic y probando.
-Lo pobre y solo afecto q ahora es mas lento en convertir. Pero sigue afectando el canal0 al 1.
-
tambien sabes que el resultado de la conversion se guarda en ADRESH y ADRESL no? te lo digo porque en tu codigo solo veo ADRESH
-
tambien sabes que el resultado de la conversion se guarda en ADRESH y ADRESL no? te lo digo porque en tu codigo solo veo ADRESH
Si, pero estoy usandolo a 8bits justificandolo a la izquierda(ADRESH) por eso el ADRESL no influye. Es correcto?. Gracias por ayudarme es que llevo tiempo pensando como solucionar esto y aun no consigo resolver el problema.
-
Le 2 potenciometros de5k ( uno para cada canal).
Estoy grabando el pic y probando.
Pero 5K es mucho, eso hace lenta la conversion, ponle máx 1K o 2 K.
Ahora, si siguen los problemas, podrías dedicar un canal del ADC a descargar el capacitor de muestreo, de esa forma, aceleras la conversión.
Suerte y saludos.
-
tambien podrias provar a usar las interrupciones del ADC. :)
-
si, es correcto, solo se me ocurre que sea fallo del circuito, porque si en el proteus te marcaba bien.
-
Saludos acabo de regresar de estudiar, voy a probar todas sus recomendaciones. Mi circuito esta correcto porque probe el ADC un canal a la vez y funciona bien. El problema esta en mi programa. Dejenme probar. :)
-
No vi como configuras el convertidor AD.
Si por casualidad usaras la referencia externa y esta esta sin conectar a tension, flotara a gusto y por ende la conversion al estar referida a esa referencia, puede ir cambiando bastante entre mediciones.
El simulador no lo ve a eso, mientras que en el circuito si se ve este problema bien claro.
-
No vi como configuras el convertidor AD.
Si por casualidad usaras la referencia externa y esta esta sin conectar a tension, flotara a gusto y por ende la conversion al estar referida a esa referencia, puede ir cambiando bastante entre mediciones.
El simulador no lo ve a eso, mientras que en el circuito si se ve este problema bien claro.
hola MGLSOFT la tension de referencia esta configurada para que sea VCC y -ref para GND. El valor convertido no oscila. Mi problema como ya lo explique es que el canal0 afecta a mi canal1.
-
Hacia tiempo que no leia assembler, pero es como andar en bicicleta, nunca se olvida... :mrgreen: :mrgreen:
Has probado todos los canales y los demas ninguno se interfiere con otro??
Solo el AN0 interfiere al AN1 ??
-
Tuviste en cuenta que el valor de tension en el canal analogico no debe ser inferior a los 2,5 volts ??
Prueba tu codigo a ver como va si el valor en AN0 y AN1 es inferior a ese valor y tambien si no lo es...
-
Hacia tiempo que no leia assembler, pero es como andar en bicicleta, nunca se olvida... :mrgreen: :mrgreen:
Has probado todos los canales y los demas ninguno se interfiere con otro??
Solo el AN0 interfiere al AN1 ??
Perdonen estube buscando potenciometros de 1k. Ahora los cambio. Solo uso 2 canales. AN0 interfiere con AN1. Voy a probar. Usando otro canal.
Gracias por su atencion.
-
Tuviste en cuenta que el valor de tension en el canal analogico no debe ser inferior a los 2,5 volts ??
Prueba tu codigo a ver como va si el valor en AN0 y AN1 es inferior a ese valor y tambien si no lo es...
Disculpa, pero a que te refieres con que el valor de tension no debe de ser inferior a 2.5 voltios en el canal... eso me suena raro, ya que el adc puede muestrear entre vdd y vss.
-
Cambie los potenciometros por 1k, el problema persiste. Ahora voy a cambiar en vez AN1 voy a usar el AN7.
Cambie de canales y tambien sigue igual. :5] :5] :5] :5] :5] :5] :5] :5] :5]
-
Tuviste en cuenta que el valor de tension en el canal analogico no debe ser inferior a los 2,5 volts ??
Prueba tu codigo a ver como va si el valor en AN0 y AN1 es inferior a ese valor y tambien si no lo es...
Disculpa, pero a que te refieres con que el valor de tension no debe de ser inferior a 2.5 voltios en el canal... eso me suena raro, ya que el adc puede muestrear entre vdd y vss.
Disculpen a este viejo olvidadizo, hace mucho que no uso el conversor interno...
Me referia a esto, mil disculpas con el error..
The maximum recommended impedance for analog sources is 2.5 kΩ. As the impedance is decreased, the acquisition time may be decreased. After the analog input channel is selected (changed), this acquisition must be done before the conversion can be started
-
No se usar interrupciones. sino las usaria. En verdad alguien me prodria dar un ejm de como cambiar canales. Trabajando a 8 bit.
-
se que puede ser tonto pero, probaste borrando los registros antes de entrar a la rutina de conversion adc.
-
SI borre los registros ADRESH y ADRESL. Aqui les dejo mi programa. Ya agregue todos los cambios que me recomendaron.
Haber si se toman la molestia de analizarlo.
__CONFIG _WDT_OFF&_PWRTE_ON&_HS_OSC&_LVP_OFF&_CP_OFF
LIST P=16F877A
INCLUDE <P16F877A.INC>
INCLUDE <MACROPIC.INC>
CBLOCK 0x20
VOLT
CORRIENTE
ENDC
ORG 0
;--------CONFIGURANDO --------------------------------------------
BANCO 1
clrf TRISC
clrf TRISB
MOV TRISA,0XFF
bsf TRISE,2
BANCO 0
;--------BORRANDO REGISTROS-------------------------------------------------
clrf PORTB
clrf PORTC
BANCO 1
MOV ADCON1,B'00000000' ;CONFIGURA LOS 8 CANALES COMO ANALOGICOS
BANCO 0
clrf ADCON0
bsf ADCON0,7 ;FOSC/32
bcf PIR1,ADIF ;inicia convertidor
infinito
;CANAL 0
bcf ADCON0,3 ;SELECCIONO CANAL 0 (AN0)
bcf ADCON0,4
bcf ADCON0,5
call ret50ms
bsf ADCON0,0 ;enciende el convertidor
clrf ADRESH
clrf ADRESL
bsf ADCON0,2 ;inicio la conversion
btfsc ADCON0,2 ;pregunto si ya acabo de convertir??
goto $-1 ;no
movf ADRESH,0 ;si,solo uso 8 bits y los muevo a w.
bcf ADCON0,0 ;apago el convertidor
bcf PIR1,ADIF ;limpio la bandera ADIF
movwf VOLT ;lo guardo en el registro VOLT
movwf PORTC ;muestro por el PORTC
call ret50ms ;retardo para descarga del condensador
;CANAL 7
bsf ADCON0,3 ; SELECCIONO EL CANAL 7 (AN7)
bsf ADCON0,4
bsf ADCON0,5
call ret50ms ;otro retardo mas q no se para q lo puse.
bsf ADCON0,0 ;enciende el convertidor
clrf ADRESH
clrf ADRESL
bsf ADCON0,2 ;inicio la conversion
btfsc ADCON0,2 ;pregunto si ya acabo de convertir??
goto $-1 ;no
movf ADRESH,0 ;si,solo uso 8 bits y los muevo a w.
bcf ADCON0,0 ;apago el convertidor
bcf PIR1,ADIF ;limpio la bandera ADIF
movwf CORRIENTE ;lo guardo en el registro CORRIENTE
movwf PORTB ;lo muestro por el PORTB
call ret50ms ;retardo de 50ms
goto infinito
INCLUDE <conv_ad.ASM>
INCLUDE <RETARDO.ASM>
END
-
Me parece que en tu código, enceindes el ADC y luego inicias la conversión.
Esos 50mseg, estarían mejor si los pones luego de encender el ADC.
Otra cosa, no creo que sea necesario apagarlo una vez encendido, basta con que cambies de canal, esperes el prudencial tiempo de adquisicion e inicies la convesión.
El clock del ADC es en base a la tabla del datasheet no???, puede que sea muy corto el TAD del adc por bit.
Cuentas tus resultados.
-
Me parece que en tu código, enceindes el ADC y luego inicias la conversión.
Esos 50mseg, estarían mejor si los pones luego de encender el ADC.
Otra cosa, no creo que sea necesario apagarlo una vez encendido, basta con que cambies de canal, esperes el prudencial tiempo de adquisicion e inicies la convesión.
El clock del ADC es en base a la tabla del datasheet no???, puede que sea muy corto el TAD del adc por bit.
Cuentas tus resultados.
HABER hice los cambios que me dijiste estan subrayados. No se si luego de cambiar de canal tambien necesite retardo??
La frecuencia de mi cristal es de 20Mhz. El datasheet dice que el Tad no debe ser menor que 1.6 micro segundos. Yo tengo entonces Fosc = 20Mhz/32 = 625khz entonces Tad = 1/625khz = 1.6useg. Es correcto?
;--------CONFIGURANDO --------------------------------------------
BANCO 1
clrf TRISC
clrf TRISB
MOV TRISA,0XFF
bsf TRISE,2
BANCO 0
;--------BORRANDO REGISTROS-------------------------------------------------
clrf PORTB
clrf PORTC
BANCO 1
MOV ADCON1,B'00000000' ;CONFIGURA LOS 8 CANALES COMO ANALOGICOS
BANCO 0
clrf ADCON0
bsf ADCON0,7 ;FOSC/32
bcf PIR1,ADIF ;limpio la bandera ADIF
infinito
;CANAL 0
bcf ADCON0,3 ;SELECCIONO CANAL 0 (AN0)
bcf ADCON0,4
bcf ADCON0,5
;call ret50ms aqui debo colocar retardo????
bsf ADCON0,0 ;enciende el convertidor
call ret50ms
clrf ADRESH
clrf ADRESL
bsf ADCON0,2 ;inicio la conversion
btfsc ADCON0,2 ;pregunto si ya acabo de convertir??
goto $-1 ;no
movf ADRESH,0 ;si,solo uso 8 bits y los muevo a w.
bcf PIR1,ADIF ;limpio la bandera ADIF
movwf VOLT ;lo guardo en el registro VOLT
movwf PORTC ;muestro por el PORTC
call ret50ms ;retardo para descarga del condensador
;CANAL 7
bsf ADCON0,3 ; SELECCIONO EL CANAL 7 (AN7)
bsf ADCON0,4
bsf ADCON0,5
;call ret50ms aqui debo colocar retardo????
clrf ADRESH
clrf ADRESL
bsf ADCON0,2 ;inicio la conversion
btfsc ADCON0,2 ;pregunto si ya acabo de convertir??
goto $-1 ;no
movf ADRESH,0 ;si,solo uso 8 bits y los muevo a w.
bcf PIR1,ADIF ;limpio la bandera ADIF
movwf CORRIENTE ;lo guardo en el registro CORRIENTE
movwf PORTB ;lo muestro por el PORTB
call ret50ms ;retardo de 50ms
goto infinito
INCLUDE <conv_ad.ASM>
INCLUDE <RETARDO.ASM>
END
-
Hice los cambios que me dijiste JBQ pero persiste el problema. No se que mas pueda ser. Estoy trabajando el adc a 8 bit justificandolo a la izquierda y usando solo el ADRESH.
En mi protoboard por ejemplo me puse a AN0 a GND y AN7 a VCC y se observa por leds lo siguiente:
PORTC = 00h
PORTB = 5Ch
-
Si te das cuenta tú haces un: clrf ADCON0
y antes mov ADCON1,b'00000000'
con esto estarías configurando a un multiplo de 2Tosc para el TAD, cuando el datasheet recomienda minimo un 64Tosc como TAD para 20 MHz de crystal.
Otro cambio ideal, sería que el encendido del ADC, "bsf ADCON,0"; lo hagas antes de tu loop infinito.
Y donde preguntas que "aqui debo colocar retardo?".... pues si es recomendable, para que se estabilice el capacitor de muestreo.
A ver que pasa con estos cambios.
ANIMO!!!!
-
Si te das cuenta tú haces un: clrf ADCON0
y antes mov ADCON1,b'00000000'
con esto estarías configurando a un multiplo de 2Tosc para el TAD, cuando el datasheet recomienda minimo un 64Tosc como TAD para 20 MHz de crystal.
Otro cambio ideal, sería que el encendido del ADC, "bsf ADCON,0"; lo hagas antes de tu loop infinito.
Y donde preguntas que "aqui debo colocar retardo?".... pues si es recomendable, para que se estabilice el capacitor de muestreo.
A ver que pasa con estos cambios.
ANIMO!!!!
Ya corregui que me dijiste ahora estoy usando un fosc/64. Parece q voy por buen camino gracias a a tu ayuda. Ahora un canal no afecta al otro. Pero por el PORTB (DIGITAL DE AN7) solo se ve los RB0 y RB1 en 1 logico y si varian al mover el potenciometro. Pero los demas leds no encienden. Pareciera que fuesen solo los 2bits de mayor peso.
-
Aqui te dejo los cambios.
__CONFIG _WDT_OFF&_PWRTE_ON&_HS_OSC&_LVP_OFF&_CP_OFF
LIST P=16F877A
INCLUDE <P16F877A.INC>
INCLUDE <MACROPIC.INC>
CBLOCK 0x20
VOLT
CORRIENTE
ENDC
ORG 0
;--------CONFIGURANDO --------------------------------------------
BANCO 1
clrf TRISC
clrf TRISB
MOV TRISA,0XFF
bsf TRISE,2
BANCO 0
;--------BORRANDO REGISTROS-------------------------------------------------
clrf PORTB
clrf PORTC
BANCO 1
MOV ADCON1,B'10000000' ;CONFIGURA LOS 8 CANALES COMO ANALOGICOS
BANCO 0
MOV ADCON0,B'01000000'
bcf PIR1,ADIF ;limpio la bandera ADIF
infinito
;CANAL 0
bcf ADCON0,3 ;SELECCIONO CANAL 0 (AN0)
bcf ADCON0,4
bcf ADCON0,5
call ret50ms ;estabilizar
bsf ADCON0,0 ;enciende el convertidor
call ret50ms
clrf ADRESH
clrf ADRESL
bsf ADCON0,2 ;inicio la conversion
btfsc ADCON0,2 ;pregunto si ya acabo de convertir??
goto $-1 ;no
movf ADRESH,0 ;si,solo uso 8 bits y los muevo a w.
bcf PIR1,ADIF ;limpio la bandera ADIF
movwf VOLT ;lo guardo en el registro VOLT
movwf PORTC ;muestro por el PORTC
call ret50ms ;retardo para descarga del condensador
;CANAL 7
bsf ADCON0,3 ; SELECCIONO EL CANAL 7 (AN7)
bsf ADCON0,4
bsf ADCON0,5
call ret50ms ;estabilizar
clrf ADRESH
clrf ADRESL
bsf ADCON0,2 ;inicio la conversion
btfsc ADCON0,2 ;pregunto si ya acabo de convertir??
goto $-1 ;no
movf ADRESH,0 ;si,solo uso 8 bits y los muevo a w.
bcf PIR1,ADIF ;limpio la bandera ADIF
movwf CORRIENTE ;lo guardo en el registro CORRIENTE
movwf PORTB ;lo muestro por el PORTB
call ret50ms ;retardo de 50ms
goto infinito
INCLUDE <conv_ad.ASM>
INCLUDE <RETARDO.ASM>
END
-
Todavía es muy bajo el TAD... parece que te has confundido y lo has puesto a 8Tosc.
Por lo demás... bueno.. :?.... asi puede funcionar... más orden no le caería bien... ;-)
-
Todavía es muy bajo el TAD... parece que te has confundido y lo has puesto a 8Tosc.
Por lo demás... bueno.. :?.... asi puede funcionar... más orden no le caería bien... ;-)
Si tenias razon estaba configurando mal lo del ADCON1 lo habia puesto al ADCON. JAJA. Gracias por ayuda en serio estoy muy agradecido. Ya lo probe en protoboad y funciona Ok todo. En estod dias estare subiendo mis fotos de mi fuente 0-24v 0-2.5A programable con teclado 4x4.
SALUDO gracias a todos los que me ayudaron. Muy interesante este foro. :-/ :-/ :-/ :-/ :-/ :-/ :-/ :-/ :-/
:) :) :) :) :) :) :) :) :) :) :) :) :) :) Gracias JBQ tu me diste la solucion.