Programa de conversión A/D con Pic 16f877/A

Saludos amigos.
Tengo ya bastante tiempo trabajando para poder aprender a utilizar el conversor de este pic, decidí colocar un potenciometro en Rao para visualizar los valores en binario por medio de una lcd. He realizado esta rutina muchas veces siguiendo los pasos del datasheep y leyendo en varias paginas de interne, al momento de probar esta rutina en proteus 8 el valor del adc aparece como 00000, al momento de hacerlo en fisico el valor del adc se pone loco y aumenta y disminuye sin yo mover el potenciometro entre valores de 350 y 260, cuando quito el cable que me conecta el ra0 con el pin variable del potenciometro estos valores siguen apareciendo, creo que no deberia. no se si alguien me puede pasar un ejemplo para ver como hacen la conversion y guiarme.

anexo el diagrama y el codigo para ver si alguien me puede ayudar, he intentado de todo, ya no se que podra ser :confused:

agradezco a quien pueda ayudarme:apreton:
Tienes varios errores en tu programa, sobre todo en la configuración del ADC y en la adquisición de datos.
Te adjunto el código corregido y funcionando físicamente, también incluyendo la simulación.
Las partes de código que estaban mal las comenté y lo que añadí al código lo podrás notar porque está escrito con minúsculas.
De esa forma podrás notar que es lo que estabas haciendo mal y que fue lo que modifiqué para que funcionara.

También realicé algunas mejoras al programa en la parte de los mensajes para la pantalla.

Saludos.
 

Adjuntos

  • 16F877A ADC 10 Bits.rar
    22.8 KB · Visitas: 64
Última edición:
Gracias por la ayuda tenia tiempo con esa rutina y nada que me daba. gracias gracias, agradecido, voy a revisarla y cualquier cosa te aviso.
 
Disculpa una pregunta que es eso al comienzo del programa que dice errorlevel. -302?
y me puedes explicar un poquito como funciona la instrucción retlw si no es mucha molestia todavía no logro entenderla muy bien. Ahh y otro cosita, estoy intentando de cambiar los pines donde estas conectado los , RS, RW y E de la pantalla, porque donde los tenia necesito esos pines para hacer una comunicación serial, y los quise colocar los 3 en el puerto E , esto se puede?, por que los configure como digitales y salida, y la pantalla no enciende, ( si no vera la posibilidad de ponerlos en otro pines). Gracias por toda la ayuda que me has brindado.GRACIAS.
 
Disculpa una pregunta que es eso al comienzo del programa que dice errorlevel. -302?
Describiré sin muchos detalles, ya que hay mucha información sobre esto.

ERRORLEVEL:
Activa o desactiva los mensajes que manda el compilador.
Estos mensajes se guardan en el archivo *.err y también se muestran en la ventana Output/ Build
En este caso, al poner ERRORLEVEL -302 ya no se muestran los mensajes que dicen...
Register in operand not in bank 0. Ensure that bank bits are correct.
Con + se activan y con - se desactivan. Los códigos de error y advertencias se encuentran en la ayuda de MPASM.
¿me puedes explicar un poquito como funciona la instrucción retlw si no es mucha molestia? todavía no logro entenderla muy bien.
RETLW: W retorna con el valor cargado en la línea que asigna PCL
Por ejemplo:
ADDWF PCL,F --> Se va sumando el puntero.
PCL = 1 -->> RETLW = "H" --> W retorna con la letra H
PCL = 2 -->> RETLW = "O" --> W retorna con la letra O
PCL = 3 -->> RETLW = "L" --> W retorna con la letra L
PCL = 4 -->> RETLW = "A" --> W retorna con la letra A
estoy intentando de cambiar los pines donde estas conectado los , RS, RW y E de la pantalla, porque donde los tenia necesito esos pines para hacer una comunicación serial, y los quise colocar los 3 en el puerto E , esto se puede?, por que los configure como digitales y salida, y la pantalla no enciende
Si se puede, y si no te funciona debes buscar una rutina más elaborada para controlar la pantalla, pues la que estás usando no tiene los tiempos correctos en la configuración.
Busca aquí en el foro, existen algunas que funcionan bien, y lo puedes hacer con 4 bits.

Fe de erratas:
En la rutina CONFIG_ADC puse lo siguiente...
movlw b'00000111'
movwf OPTION_REG ; Desactivar los comparadores analógicos.

Lo correcto debe ser...
movlw b'10000000'
movwf OPTION_REG ; Limpiar el registro OPTION_REG y sin resistores pull-up

Suerte.
 
Última edición:
Gracias nuevamente despejaste mis dudas, eternamente agradecido, decide no colocarlos en el puerto E los coloque en otros pines del C y me funciona perfectamente, cuidado de no ser los Tx y Rx. Buscare esas rutinas para aprender mas. Ahora voy con la comunicación serial y un reloj en tiempo real con TMR 1 :D. Gracias amigo tal vez te ladillo un poquito cuando este ahogado con lo que me viene jajaja. Gracias amigo. :)
 
Hola a todos! Tengo un inconveniente y agradeciera su ayuda.
Ya he hecho el código del conversor, pero antes de mandarlo al LCD quiero que la salida se aprecie en leds y al momento de simularlo en proteus para el voltaje máximo (5v) se prenden casi todos los LEDs menos uno (RD0)
O si no cuando el voltaje es mínimo (0v) todos los LEDs están apagados excepto uno (también RD0).
¿Quisiera saber si tienen idea de por qué ocurre eso? Gracias.

Código:
////////////////////CODIGO//////////////////////////

#include <htc.h>
#ifndef _XTAL_FREQ
    #define _XTAL_FREQ 10000000
#endif
#include "adc.h"
#include "lcd.h"

void MCU_init(){
    TRISA = 0XFF;
    PORTD = 0X00;
    TRISD = 0X00;
}

void conv_voltaje(){
    int vmax = 5; float v_lcd;
    __delay_us(20);
    adc_read(1);
    __delay_us(10);
    PORTD = ADRESH;
    //v_lcd = PORTD*vmax/255;
}

void main(){
    MCU_init();
    lcd_init();
    while(1){
        conv_voltaje();
    }
}

///////////////////////////////////////////////////////////

Les dejo el código por si es necesario. Uso HI-TECH
 
Hola a todos! Tengo un inconveniente y agradeciera su ayuda.
Ya he hecho el código del conversor, pero antes de mandarlo al LCD quiero que la salida se aprecie en leds y al momento de simularlo en proteus para el voltaje máximo (5v) se prenden casi todos los LEDs menos uno (RD0)
O si no cuando el voltaje es mínimo (0v) todos los LEDs están apagados excepto uno (también RD0).
¿Quisiera saber si tienen idea de por qué ocurre eso? Gracias.
Adjunto un código trabajando el ADC a 8 Bits, también incluyo la simulación.

Se manda el valor leído al puerto C sobre unos LED's y también se muestra el valor en una pantalla LCD 16x2.

Nota:
La modificación al código para realizar una lectura de 10 bits no es complicada.

Suerte.
 

Adjuntos

  • PIC16F877A ADC 8 Bits + LEDS + LCD 16x2.rar
    30.5 KB · Visitas: 77
Última edición:
Hola a todos, perdón por revivir el tema pero no quería abrir uno nuevo para sólo hacer una consulta.

Estoy trabajando con el ADC del PIC16F887, de 10 bits de resolución. Con ésto, obtengo aproximada y teóricamente una lectura mínima de 0,1%.
Estaba pensando en alguna forma de mantener el error constante al ir variando las mediciones pero me parece que se me va en complejidad.

Por eso estaba pensando en, por ejemplo, en colocar un divisor resistivo al pin de +Vref y cambiar la referencia segúna la medida se encuentre por encima (Vdd) o por debajo (Vdd/2) de la zona media de mediciones.

Es viable esto? Puede traer algún problema en las mediciones?

Saludos!
 
Si colocas un divisor resistivo para modificar Vref, estará sujeto a los cambios en VDD.
Por eso es recomendable usar un regulador ajustable, por ejemplo un TL431.
Aún así, no creo que eso mejore el error, ya que eso es parte de conversor.
Lo que si lograrás cambiar será el rango del voltaje análogo a la entrada.
Que para 5 V será: (5 / 1024) = 4.8 mV por paso. Y limitando el rango de entrada con Vref a 2.5 V estaría a la mitad. 2.4 mV por paso.
 
Atrás
Arriba