TODOPIC
Microcontroladores PIC => Todo en microcontroladores PIC => Mensaje iniciado por: peter2006 en 16 de Diciembre de 2006, 13:48:52
-
Tengo un proyecto con el 16F877A que usa una entrada analogica AN0 que toma datos de un potenciometro, funcionaba bien pero de repente algo cambio y no da lecturas en todo el recorrido del potenciometro, solo lee en la parte final con lo cual pierde mucha sencibilidad.
Puede ser que se haya estropeado la entrada o cambie algo en el programa sin darme cuenta?
El programa esta en CCS.
Gracias.
-
MUY MUY dificil que alguien te pueda ayudar sin mayores datos.
Si cambiaste algo para mal en el programa, como saberlo??
Si esta mal tu circuito, como saberlo??
Si bien yo no se CSS, lo que si se, es que se necesita mas informacion para que alguien te pueda ayudar.
Saludos
-
Sube el código y como dice el amigo veguepic, da más datos.
Feliz Navidad!!! ;)
-
Perdon por ser tan impreciso, la parte de la inicialización es la siguiente:
#include <16F877A.h>
#device *=16
#device adc=8
#use delay(clock=20000000)
#fuses NOWDT,HS, NOPUT, NOPROTECT, NODEBUG, NOBROWNOUT, NOLVP, NOCPD, NOWRT
#ZERO_RAM
// VARIABLES
// definiciones básicas
#byte porta= 0x05
#byte portb= 0x06
#byte portc= 0x07
#byte portd= 0x08
#byte porte= 0x09
#byte trisa= 0x85
#byte trisb= 0x86
#byte trisc= 0x87
#byte trisd= 0x88
#byte trise= 0x89
porta= 0b00000000; set_tris_a (0b10000000);
portb= 0b00000000; set_tris_b (0b11111001);
portc= 0b00000000; set_tris_c (0b00000000);
portd= 0b00000000; set_tris_d (0b00000000);
porte= 0b00000000; set_tris_e (0b11101111);
setup_adc_ports(AN0);
setup_adc(ADC_CLOCK_INTERNAL);
setup_adc(ADC_CLOCK_DIV_32);
setup_psp(PSP_DISABLED);
setup_spi(FALSE);
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DIV_BY_4,250,10);
setup_comparator(NC_NC_NC_NC);
setup_vref(FALSE);
set_adc_channel(0);
el circuito es simple, el cursor del pote esta comectado a la entada AN0 y la resistencia a los 5V y el neutro.
Luego leo el AN0 con read_adc() para obtener un valor entre 0 y 255
Gracias.
-
Hola peter2006, no conosco mucho de CCS, pero de lo que estoy seguro es:
setup_adc(ADC_CLOCK_INTERNAL);
setup_adc(ADC_CLOCK_DIV_32);
Si usas clock interno no usas el DIV_32, por velocidad por supuesto te conviene el DIV_32
El otro tema es que estes usando un potenciometro de valor muy alto, yo te recomendaría que el valor del mismo no sea superior a 1K, caso contrario seguro podrá hacerte el problema que comentas.
Un saludo y espero tus comentarios.
Atte. CARLOS.
-
El CCS para hacer A/D con el 877 no permite cambiar el bit de justificacion de la lectura (ADCON1,ADFM), y por defecto sale a la izquierda, con lo que pierdes los dos ultimos bits de LSB.
La verdad es que no se como se puede cambiar, intenté modificar las librerias para que viese el cambio en el bit y no habia manera. Casi estoy seguro que tu problema viene por ahi. Ademas tu mismo dices que haces una conversion de 0 a 255, y no hasta 1024. Si te pasa lo que creo que te pasa, el A/D está haciendo conversion de 4 a 1024, ya que por la justificacion hacia la izquierda, utiliza los primeros 8 bits (MSB).
Coincido con Chaly, no uses un potenciometro tan grande. Usa uno de 1K o menos si puede ser, y si es multivuelta mejor que mejor. Ah y que el potenciometro sea lineal, no logaritmico, sino vas a volver al 877 loco perdio jajajaj
Hasta luego maj@@@@@@@@@@@s
-
Puede que también se te haya hecho un corto en algún cable del potenciómetro y se haya quemado el carbón del mismo, es muy común.
-
Hola Deimos, si el CCS usa el ADC por defecto con justificación a la izquierda no es un problema, ya que la lectura igual saguirá siendo correcta pero de 0 a 255 por lo tanto no creo que ese sea el motivo del error, es lo mismo que usar el convertidor en 10 bit y el resultado dividirlo por 4, nada más que eso. Por lo tanto sería imposible que la lectura sea de 4 a 1023 (1024 son 11 bits).
Un saludo.
Atte. CARLOS.
-
Gracias a todos por sus aportes, ya me pongo a probarlos y les comento.
Saludos.
-
Chaly no me has interpretado bien.
Pongamos que hago una lectura de 1100001111. Ese el el valor de la lectura en binario.
Si cojo los 8 MSB me sale 11000011
Si cojo los 8 LSB me sale 00001111
Cogiendo los 8 MSB, no se me pondrá a 1 el primer bit hasta que no salga como minimo un 4. Por eso digo que con MSB's solo veré de 4 a 1023 (tienes razon con 11 bits para 1024, queria decir 1023 en mi anterior mensaje). Cogiendo los 8 LSB's veré solo de 0 a 255.
La diferencia que veo es que
1023-4=1019 combinaciones
0-255=255 combinaciones
Vaya es como yo lo veo. Quizas me esté equivocando.
Dews!!!
-
Hola Deimos, entonces tienes un concepto mal interpretado, porque con 8 bit nunca tendrás más de 256 convinaciones posibles, no importa que sean los 8MSB o los 8LSB, siempre son 8 bits y no hay más de 256
Pasemos a tú ejemplo:
Si cojo los 8 MSB me sale 11000011 = que en definitiva no es más que 195 en decimal
Si cojo los 8 LSB me sale 00001111 = que en definitiva no es más que 15 en decimal
Tienes razon que con los MSB veras de 4 a 1023 (en realidad de 0 a 1023) del valor real del convertidor A/D, pero recuerda que con los MSB tienes que dividir por 4 el valor real, por lo tanto también tienes 256 convinaciones.
La diferencia que veo es que
1023-4=1019 combinaciones
0-255=255 combinaciones
En la realidad los cálculos son los siguientes:
1023 - 0 = 1024 / 4 = 256 convinaciones posibles
255 - 0 = 256 convinaciones posibles
Con la diferencia que si tomas los LSB tendrás 4 escalas de 256 convinaciones en todo el rango del vref, pero si tomas los MSB tendrás una escala de 256 convinaciones para todo el rango del vref.
Por consiguiente la unica solucion haceptable si deseas trabajar con solo 8 bits es qye tomes los MSB, ya que si tomas los LSB para un mismo resultado puedes tener asta 4 valores de tensiones posibles.
Espero se me entienda lo que quiero explicarte, un saludo.
Atte. CARLOS.
-
Hola chaly29 creo que ya comprendo. Divides entre 4 porque sabes que pierdes los 2 bits LSB y por eso solo es buena 1 de cada 4 combinaciones.
Tienes razon que con los MSB veras de 4 a 1023 (en realidad de 0 a 1023) del valor real del convertidor A/D, pero recuerda que con los MSB tienes que dividir por 4 el valor real, por lo tanto también tienes 256 convinaciones.
La diferencia que veo es que
1023-4=1019 combinaciones
0-255=255 combinaciones
En la realidad los cálculos son los siguientes:
1023 - 0 = 1024 / 4 = 256 convinaciones posibles
255 - 0 = 256 convinaciones posibles
Con la diferencia que si tomas los LSB tendrás 4 escalas de 256 convinaciones en todo el rango del vref, pero si tomas los MSB tendrás una escala de 256 convinaciones para todo el rango del vref.
Por consiguiente la unica solucion haceptable si deseas trabajar con solo 8 bits es qye tomes los MSB, ya que si tomas los LSB para un mismo resultado puedes tener asta 4 valores de tensiones posibles.
Es posible que por eso el CCS tenga configurado el bit ADCON1,ADFM=1(justificación por la izquierda)? Porque ya expliqué que intenté cambiarle la librería para que me hiciese la justificación por la derecha y no hubo manera humana.
Gracias por la aclaración chaly.
Dewssssss
-
Hola Deimos, las librerías del CCS no las conosco, pero para cambiar la justificación del convertidor tienes que setear el bit 7 del registro ADCON1.
Con 0 lo justificas a la izquierda y con 1 a la derecha.
Espero te sea de ayuda, pero realmente no comprendo para que deseas cambiar ese parámetro, ya que justificado a la derecha no es muy usado.
Un saludo.
Atte. CARLOS.
-
Hola Deimos, las librerías del CCS no las conosco, pero para cambiar la justificación del convertidor tienes que setear el bit 7 del registro ADCON1.
Con 0 lo justificas a la izquierda y con 1 a la derecha.
Espero te sea de ayuda, pero realmente no comprendo para que deseas cambiar ese parámetro, ya que justificado a la derecha no es muy usado.
Un humilde aporte
1) Si se quiere usar precisión de 8 bits -> usar justificación izquierda y leer el ADRESH
2) Si se queire usar precisión de 10 bits -> usar justificación derecha y leer ambos registros.
Saludos
-
Con el pote de 1k mejoro la lectura, ahora quisiera complicar un poco mas el tema, si conecto un sensor LM35 para medir temperatura me da lecturas que fluctuan mucho y no varia al calentar el sensor se queda variando entre 27 y 36 la lectura del puerto, me podrian aconsejar como medir una temperatura.
Gracias.
-
Hola peter2006, te recomendaría que bajases este .pdf en el que encontrarás gran cantidad de circuitos y entre ellos uno que grafica la conexión de un LM35
http://www.todopic.com.ar/foros/index.php?topic=13389.msg77677#msg77677
Un saludo.
Atte. CARLOS.
-
Chaly lo que me cuentas ya lo conozco pero gracias igualmente. Intenté cambiar el bit para hacer un par de pruebas, pero vaya, que no es algo me urge ahora mismo.
peter2006 mi consejo. Bájate el datasheet del LM35 directamente de la web de www.national.com y verás al final del datasheets ejemplos para suprimir el ruido, que es lo que te hace variar la señal. Coincido con chaly en que tienes un conflicto entre el clock del sistema y el div32. Pienso que no es aconsejable leer muy rápido una temperatura, que suele tener una curva bastante lenta. Si lees muy rápido puede fluctuarte más.
Por cierto a que tensión tienes Vref en el PIC????
Salu2
-
No se si se han fijado o si no tenga problema, pero en el código veo que se selecciona como entrada análoga AN0 y en el tris este pin se pone como salida:
porta= 0b00000000; set_tris_a (0b10000000); //Aca se esta configurando como salida el PIN A0
portb= 0b00000000; set_tris_b (0b11111001);
portc= 0b00000000; set_tris_c (0b00000000);
portd= 0b00000000; set_tris_d (0b00000000);
porte= 0b00000000; set_tris_e (0b11101111);
setup_adc_ports(AN0); //Aca se selecciona A0 como entrada análoga, pero arriba este pin estaba como salida.
No se si el compilador al configurar el conversor a/d configure tambien los puertos, pero creo que para el tris a deberia ser:
set_tris_a (0b00000001);
saludos.
-
Hola dhmejia, no se como será el CCS, pero por ejemplo en asembler por más que configures el puerto como salida, si lo tienes comfigurado como AN0 este pasará indefectiblemente a ser entrada.
Un saludo.
Atte. CARLOS.
-
Hola dhmejia, no se como será el CCS, pero por ejemplo en asembler por más que configures el puerto como salida, si lo tienes comfigurado como AN0 este pasará indefectiblemente a ser entrada.
Un saludo.
Atte. CARLOS.
Yo creo que es algo que hay que probar, me refiero a ver qué hace realmente esa función.
Si la función en cuestión simplemente selecciona el canal AN0 del A/D eso no lo hará entrada.
No importa si seleccionamos el canal AN0 , si el pin está como salida, será salida.
Ahora bien, si la función en cuestión, también setea el correspondiente bit del registro TRISA, entonces si, quedará como entrada.
Yo que tu dhmejia haría 2 cosas.
1) Simularía paso a paso y vería que hace bien la función
2) Si no estas seguro, puedes postear el código ASM generado por ese trozo de código y te echamos una mano así aclaramos el asunto.
Saludos
-
Hola maunix, creo que no me as entendido, si se setea el ADCON0 de manera tal que el pin 0 del puerto A sea análogo, por más que selecciones el A0 como entrada o salida digital este seguirá siendo entrada análoga, por lo tanto no influye el estado del TRISA
Un saludo.
Atte. CARLOS.
-
Coincido con Charly, ya que lo e experimentado, por defecto en el 877 el puerto A esta como entradas analogicas, y por mas que cambien la conf del TRISA, ese sigue configurado como entrada analogica hasta que configure en el ADCON0 el puerto a como salidas digitales, despues de eso si responde a la conf del TRISA.
Saludos
-
Hola maunix, creo que no me as entendido, si se setea el ADCON0 de manera tal que el pin 0 del puerto A sea análogo, por más que selecciones el A0 como entrada o salida digital este seguirá siendo entrada análoga, por lo tanto no influye el estado del TRISA
Un saludo.
Atte. CARLOS.
Si Carlos, creo que entendí tu punto, pero también creo que estas equivocado.
Hay ocasiones en que uno por ejemplo necesita solo 2 canales A/D y por ahí el salto en la configuración es 0, 1 o 3 canales. Entonces ese 3er canal uno si quiere lo puede usar como salida. Al usarlo como salida, no funciona como un pin analógico sino como digital.
También lo he comprobado personalmente con más de un pic y funciona de maravillas.
El conversor analógico funciona por separado del registro tris. Por ejemplo, si el pin está como digital y se lo manda a convertir, el resultado será la conversión de la tensión del mismo.
Si el pin está como salida y tiramos una conversión analógica, el conversor convertirá el valor de salida del pin.
Saludos
-
Coincido con Charly, ya que lo e experimentado, por defecto en el 877 el puerto A esta como entradas analogicas, y por mas que cambien la conf del TRISA, ese sigue configurado como entrada analogica hasta que configure en el ADCON0 el puerto a como salidas digitales, despues de eso si responde a la conf del TRISA.
Saludos
Al ponerlo como salida, ya no hace efecto lo que hayas seteado en el ADCON.
-
Hola maunix,
Si Carlos, creo que entendí tu punto, pero también creo que estas equivocado.
Hay ocasiones en que uno por ejemplo necesita solo 2 canales A/D y por ahí el salto en la configuración es 0, 1 o 3 canales. Entonces ese 3er canal uno si quiere lo puede usar como salida. Al usarlo como salida, no funciona como un pin analógico sino como digital.
También lo he comprobado personalmente con más de un pic y funciona de maravillas.
El conversor analógico funciona por separado del registro tris. Por ejemplo, si el pin está como digital y se lo manda a convertir, el resultado será la conversión de la tensión del mismo.
Si el pin está como salida y tiramos una conversión analógica, el conversor convertirá el valor de salida del pin.
Creo que estas confundido, si el pin está configurado como analogo, nunca funcionará como digital, no importando la cantidad de pines que esten en analogos.
Y si un pin esta como salida digital y lo configuras como entrada analoga no te podría medir la tensión que tenía como salida, ya que esta a dejado de existir como tal.
Verifica lo que comento y verás la verdad.
Un saludo.
Atte. CARLOS.
-
Bueno, pera resolver esto nada mejor que ir a la hoja de datos de un pic, en este caso tome la del 16f877a
(http://www.todopic.com.ar/foros/index.php?action=dlattach;topic=15182.0;attach=3134;image)
Según lo que entiendo con mi pobre ingles donde esat resaltado con el cuadro rojo, es que el registro TRISA controla la dirección del puerto aun cuando se estan usando como entradas analogicas, y que el usuario vede asegurar los bit del registro TRISA como tales para las entradas analogicas.
Así que me rectifico, y ahora haciendo memoria, recuedo que no era que estando configuradas como entradas no me daba bola el TRISA, sino que al intentar escribir no pasa nada, es como cuando esta conf como entrada y escribimos en ese pin, no pasa nada. Por ende como dice maunix se podría llegar a medir el valor de la entrada digital, pero config como salida y tratar de escribir en el pueto configurado como analogico no se que pasaría, y creo que la mejor forma de probarlo es en un pic de verdad, porque puede que en los simuladores no hallan tenido en cuenta eso, es algo raro que esta muy al limite del hadware del pic.
Por dar un ejemplo, si en asembler pnes dos instrucciones eguidas de BCF o BSF, en el simulador no pasa nada, lo hace perfecto, pero en el pic, toma solo la segunda
Saludos
-
Carlos, yo hablaba de algo que comprobé por mi mismo y lo he usado en más de una ocasión. De hecho tengo una aplicación que usé un pin como salida porque me quedaba muy cómodo para el pcb y está funcionando de esa forma hasta hoy en día.
De todas formas, me interesa lo que expones y si tienes algún ejemplo práctico en que haya sucedido lo que dices lo podríamos ensayar. :)
Gracias carcass (sergio) por tu confianza :-) , en cuanto a mi forma de ser no me jacto de tener la razón, simplemente trato de remitirme a lo estrictamente técnico buscando ser lo más objetivo posible y buscando de no ofender a nadie con mi redacción.
En tu caso, tal vez no te anduvo el PORTE no porque estuviera como analógico y lo uses como salida sino porque lo más probable es que hayas tenido habilitado el PSP (también se configura con el TRISE) , pero más allá de eso, lo que les he comentado es porque lo he probado por mí mismo, y lo tengo usando!! :)
Esteca55, exactamente... no he inventado la pólvora, simplemente leo el datasheet y lo interpreto como a mí me parece. Más allá del recuadro en rojo, si te fijas en el esquemático de conexionado del puerto, verás que la entrada analógica funciona en analógica solamente al ser entrada ya que la compuerta AND unida al TRIS, se encarga de esto.
Carlos, por último hablando del uso del conversor en general, te extraigo una parte del datasheet del 16F87xA a ver si lo interpretas como yo, tal vez sea yo el equivocado.
11.3 Configuring Analog Port Pins
The ADCON1 and TRIS registers control the operation of the A/D port pins. The port pins that are desired as analog inputs must have their corresponding TRIS bits set (input).
If the TRIS bit is cleared (output), the digital output level (VOH or VOL) will be converted.
The A/D operation is independent of the state of the CHS2:CHS0 bits and the TRIS bits.
Note 1: When reading the port register, any pin configured as an analog input channel will read as cleared (a low level). Pins configured as digital inputs will convert an analog input. Analog levels on a digitally configured input will not affect the conversion accuracy.
2: Analog levels on any pin that is defined as a digital input (including the AN7:AN0 pins) may cause the input buffer to consume current that is out of the device specifications.
Esto en rojo es una aclaración ya que si usamos el pin como entrada digital y le inyectamos un voltage analógico como decir 2.5V el consumo de corriente puede dañar al pic.
-
Hola maunix, como todo buen porfiado, acabo de probar lo que comentas en la vida real, e incluso en el proteus y es tal cual tú lo dices (aunque en el proteus los resultados tienen un pequeño de error), toda entrada analoga puede ser usada como salida digital.
Publicamente pido disculpas por el mal entendido.
Y lamentablemente tanto para carcass como para mí, hemos dejado pines sin usar por no leer adecuadamente los datasheet o realizar las pruebas adecuadamente :?
Mil disculpas a todos y a maunix gracias por la nueva enseñanza.
Un saludo.
Atte. CARLOS.
-
Mil disculpas a todos y a maunix gracias por la nueva enseñanza.
Carlos, no hace falta tus disculpas.
Yo entiendo que estabas convencido de lo que opinabas, no lo decías solo por el fin de discutir :) y te considero una persona de bien 8)
A veces estos mal entendidos de uno y otro hacen que algún tercero pueda aclarar su punto de vista, así que bienvenido sean!!
Y creo que la mentalidad forera es el hoy por tí y mañana por mi, y eso es lo bueno de los foros que tienen la onda genial que tiene éste.
Un abrazo desde córdoba.
-
No se si se han fijado o si no tenga problema, pero en el código veo que se selecciona como entrada análoga AN0 y en el tris este pin se pone como salida:
porta= 0b00000000; set_tris_a (0b10000000); //Aca se esta configurando como salida el PIN A0
portb= 0b00000000; set_tris_b (0b11111001);
portc= 0b00000000; set_tris_c (0b00000000);
portd= 0b00000000; set_tris_d (0b00000000);
porte= 0b00000000; set_tris_e (0b11101111);
setup_adc_ports(AN0); //Aca se selecciona A0 como entrada análoga, pero arriba este pin estaba como salida.
No se si el compilador al configurar el conversor a/d configure tambien los puertos, pero creo que para el tris a deberia ser:
set_tris_a (0b00000001);
saludos.
Finalmente se hizo la luz en este tema, luego de configurar el tris como indico dhmejia comenzo a funcionar perfecto con el LM35 el potenciometro y cualqier otra cosa que varie la tension en el AN0.
MUCHAS GRACIAS...................
-
Hola peter2006 , me alegra que lo hallas conseguido, felicidades.
Un saludo.
Atte. CARLOS.