Autor Tema: Conversor A/D con PIC16F76  (Leído 9077 veces)

0 Usuarios y 2 Visitantes están viendo este tema.

Desconectado telojurito

  • PIC12
  • **
  • Mensajes: 55
Re: Conversor A/D con PIC16F76
« Respuesta #15 en: 30 de Octubre de 2008, 02:57:56 »
Hola Chenao,

El valor REAL a leer esta alrededor de 26 vdc y maximo espero tener 30vdc que es el valor que use para el calculo del div de tension. Las lecturas las pretendo dar en formato xx.xx vdc

Muchas gracias

Desconectado Chenao

  • PIC18
  • ****
  • Mensajes: 414
Re: Conversor A/D con PIC16F76
« Respuesta #16 en: 30 de Octubre de 2008, 18:40:59 »

Saludo

Te tengo una posible solución, es poco confiable pero me ha funcionado muy bien y consiste en lo siguiente:

si tienes un numero, por ejemplo 123, para descomponerlo en tres numeros osea 1, 2 y 3 primero lo divides entre 100 y obtienes el 1 al residúo lo divides entre 10 y obtienes el 2 y la residúo que te quede de esta división lo divides entre 1 y obtienes 3, este es un método llamado de binario a BCD pero a 8 bits, es decir, que sólo puedes convertir numeros entre 0 y 255 (D).

Para tu aplicación tendrías que hacer la conversión tanto para la parte entera como para la décimal.

Voy a buscar la rutina y te la mando.

Un saludo desde Pereira - Colombia
Un saludo desde Pereira - Colombia

Desconectado telojurito

  • PIC12
  • **
  • Mensajes: 55
Re: Conversor A/D con PIC16F76
« Respuesta #17 en: 04 de Noviembre de 2008, 20:54:55 »
Pues bueno compañeros,

Ya ha sido muchisimo el avance, finalmente pude realizar la conversión de binario 16 bits a BCD 5 digitos. Después de varias pruebas y utilizando unas rutinas del PICLIST, no quedaban y no quedaban hasta que pensé en sumarle 0x30 a cada resultado de la conversión y encontré que me daban como 0x6x, lo cuál se me hizo raro y probé a despues restarles los mismos 0x30, total, era pa probar...... y EUREEEEEKA, que salen los dígitos por el display.

Probé con otra subrutina e intenté lo mismo y nuevamente obtuve los dígitos en el display.

Estoy adjuntando dos archivos que funcionan en cuanto a lo de mostrar los dígitos pero todavia me falta un detalle:

El conversor ADC no parece funcionar muy bién, me explico....al aplicar la energía parece comenzar a leer el valor por RA0, pero comienza a variar, incrementa luego baja, a veces llega hasta a cero luego sube, se estabiliza un poco y bueno, en general varia mucho. Pensé que era por el convertidor de binario a bcd pero lo intenté con las dos rutinas que mencioné y sucede los mismo. También intente con dos diferentes rutinas del conversor y nada. Incluso pense en ruido en el circuito, ya que después de puente rectificador puse un filtro de 100uF, lo cambié por uno de 1,000uF y nada......

Podrían echarle un vistazo y ayudarme un poco más por favor??????

He de decir que para la multiplicación estoy haciendo el valor leido y guardado en VIN lo multiplico por 0x75 = 117 DEC, dado que es mi factor de conversión o resolución en el divisor de voltaje de entrada por RA0

Señores les agradezco mucho toda la ayuda proporcionada.

Desconectado telojurito

  • PIC12
  • **
  • Mensajes: 55
Re: Conversor A/D con PIC16F76
« Respuesta #18 en: 04 de Noviembre de 2008, 20:55:50 »
Y aquí está el otro archivo

Desconectado telojurito

  • PIC12
  • **
  • Mensajes: 55
Re: Conversor A/D con PIC16F76
« Respuesta #19 en: 04 de Noviembre de 2008, 22:54:58 »
Pensé en poner un video con lo que sucede en el display:

1104_173327.avi - 3.6 Mb

como se puede observar, el valor mostrado varia demasiado y con el Fluke se miden 26.6 volts casi casi estables varia un poco solo un poco, de acuerdo al voltaje de línea.

Yo sospecho de la rutina del conversor AD o creen que pueda ser hardware??????

Saludos

Desconectado BrunoF

  • Administrador
  • DsPIC30
  • *******
  • Mensajes: 3865
Re: Conversor A/D con PIC16F76
« Respuesta #20 en: 05 de Noviembre de 2008, 00:03:39 »
Hola. Te tiro un par de ideas/sugerencias:

*No miré tu rutina, pero podrías intentar aumentar el tiempo de muestreo del conversor AD(si ya no lo estas haciendo), mediante los pines <ADCS2> y <ADCS1:ADCS0>(leer en el datasheet);
*Es altamente recomendado esperar un cierto tiempo antes de realizar la próxima conversión para dar tiempo a que el capacitor interno se descargue completamente;
*Tal vez estés trabajando con el conversor en modo 10 bits, y el ultimo bit es muy inestable, tal vez convenga utilizar al menos un bit menos;
*y por último, pero lo más importante, por lo que he leído en tus comentarios, la impendancia con la que ingresa tu señal a convertir es demasiado alta. La máxima impendancia recomendada para estos modelos de uC es de 2,5kohms, y me parece que el divisor de tensión que utilizás posee una impendancia muy superior. Cuanto menor sea la impendancia mejor responderá el módulo ADC.

Espero haberte ayudado un poco.

Saludos.
« Última modificación: 05 de Noviembre de 2008, 00:05:54 por BrunoF »
"All of the books in the world contain no more information than is broadcast as video in a single large American city in a single year. Not all bits have equal value."  -- Carl Sagan

Sólo responderé a mensajes personales, por asuntos personales. El resto de las consultas DEBEN ser escritas en el foro público. Gracias.

Desconectado telojurito

  • PIC12
  • **
  • Mensajes: 55
Re: Conversor A/D con PIC16F76
« Respuesta #21 en: 05 de Noviembre de 2008, 18:02:35 »
Hola BrunoF,

El muestreo que estoy seleccionando en <ADCS1:ADCS0> = 11 Derivado del oscilador interno del Modulo AD, bit <ADCS2> no existe en el PIC16F76, crees que deba o sería recomendable cambiarlo? Fosc/32, Fosc/8, Fosc/2. Una pregunta aquí, a qué se refieren estos datos y a cuanto corresponderían con un cristal de 8MHz?

En lo del tiempo de espera para la conversión estoy revisando una información que posteo maunix hace tiempo:

http://www.todopic.com.ar/foros/index.php?topic=14529.msg88942#msg88942

El convertidor AD del PIC16F76 es por si mismo diseñado a 8 bits según entiendo, porque no he visto cómo setearlo para 8 o para 10 bits.

Y en cuanto a la impedancia de entrada de la señal me parece importante comentarlo, ya que a lo mejor estoy haciendo mal el diseño desde el hardware. De la fuente que estoy monitoreando utilizo un divisor de tensión con 2 resistencias, el punto medio entre ambas lo llevo directamente a RA0


                                                      /\                        /\
     Vin = 26.6VDC aprox  O----------/   \    /-----o------/    \   /----------O GND
                                                           \/         |              \/
                                                     R1=10K      |        R2=2K
                                                                      |
                                                                      O
                                                                    a RA0

Según el diagrama, la impedancia de entrada al convertidor es de 2Kohms y por lo que me comentas y que se menciona en el datasheet, la máxima impedancia de entrada recomendad es de 10Kohms pero podría intentar con resistencias de menor valor, 5Kohms y 1Kohms por ejemplo.

En este punto mis cálculos son: aunque el voltaje de entrada es de 26.6 volts aprox, pongo como máximo valor 30 volts y como máximo de entrada al convertidor en RA0 5 volts. Si fijo a R1, 5Kohms aplicando

R2 = R1 [ V2 / (V1 - V2) ] = 1Kohm

Entonces mi Vref+ = 5v y mi Vref- = 0v y el valor real Vreal a leer teniendo el valor leido del AD Vadc sería

Vreal = [ (Vref+ - Vref-) / (2^8 - 1)  * Vadc * 6 = 0.117 * Vadc

por 6, porque si 30v es el valor máximo real y 5v el valor máximo de referencia la relación entre los dos valores es de 6.

Hasta aquí es lo que tengo y cómo he desarrolado mi proyecto en cuanto a cálculos, por favor si he cometido algún error en lo anterior, les agradeceré me lo indiquen.

Gracias nuevamente

Desconectado telojurito

  • PIC12
  • **
  • Mensajes: 55
Re: Conversor A/D con PIC16F76
« Respuesta #22 en: 05 de Noviembre de 2008, 21:54:23 »
 :-/ :-/ :-/

Tengo el agrado de comentarles que finalmente logró funcionar este proyecto como se esperaba.....

En cuanto a los tiempos del conversor AD encontré en el datasheet para el 16F76 el TAD es de 4 useg típico y el tiempo de conversión de 9 * TAD lo cual nos da 36 useg, yo puse un retardo antes de disparar ADCON0, 2 o sea GO/DONE de 40 useg.

También encontré que para este PIC, seleccionar el clock interno del conversor RC en ADCON0 o sea 11 para frecuencias mayores de 1MHz es sólo recomendable para la operación SLEEP, entonces según una tabla de ahí mismo dice que

2Tosc Max Freq 1.25MHz
8Tosc Max Freq 5MHz
32Tosc Max Freq 20MHz

entonces tocaba seleccionar 32Tosc.....

Pero aún así no funcionaba correctamente, hasta que decidí cambiar las resistencias del divisor de tensión y me dí cuenta que la segunda resistencia R2 que según iba a GND, estaba a GND del puente de diodos pero ese GND no estaba conectado al del resto del sistema, estaba flotando. A lo que me refiero, es que puse un rectificador por separado al del sistema entero para el monitoreo del voltaje, el cual estaba en 26.6VDC aprox. Lo conecté al GND del 7805 del sistema entero y tan tan..... a funcionar......

No me queda nada más que agradecerles mucho a todos por ayudarme en este proyecto, ya que es la primera vez que trabajo con el convertidor AD, es más, no soy muy asiduo programador pero de vez en cuando se me ocurre algo y me pongo a trabajar en ello, pero como no soy muy frecuente, algunos detalles se olvidan.

Nuevamente muchas gracias

Desconectado BrunoF

  • Administrador
  • DsPIC30
  • *******
  • Mensajes: 3865
Re: Conversor A/D con PIC16F76
« Respuesta #23 en: 06 de Noviembre de 2008, 03:56:59 »
Me alegro telojurito. :)

Y es verdad, fue mi error lo del bit <ADCS2> ya que ni existe en el 16F876. Los cálculos de las resistencias están bien.
Ojo, si no me equivoco el TAD de 4uS es tipico cuando esta configurado con el RC interno del conversor AD.

Si, debías seleccionar FOSC/32 para 8mhz.

Cualquier cosa estamos por acá.

Éxitos
"All of the books in the world contain no more information than is broadcast as video in a single large American city in a single year. Not all bits have equal value."  -- Carl Sagan

Sólo responderé a mensajes personales, por asuntos personales. El resto de las consultas DEBEN ser escritas en el foro público. Gracias.

Desconectado telojurito

  • PIC12
  • **
  • Mensajes: 55
Re: Conversor A/D con PIC16F76
« Respuesta #24 en: 14 de Noviembre de 2008, 21:38:16 »
Estimados amigos,

Una nueva inquietud al respecto con este proyecto.

Sucede que estoy haciendo varias lecturas, cada una cuando presiono un botón que le incorporé al circuito. Presiono el botón y realiza la lectura conversión y todo, la inquietud surge en cuanto a la presentación de los valores en el display a partir de la lectura número 10 que me pone el valor correspondiente de acuerdo al mapa de caracteres del display:

V1=xx.xx
V2=xx.xx
V3=xx.xx
V4=xx.xx
V5=xx.xx
V6=xx.xx
V7=xx.xx
V8=xx.xx
V9=xx.xx
V:=xx.xx en vez de V10
V;=xx.xx en vez de V11

como comenté anteriormente, al valor recibido de la conversión debo restarle 0x30 para que concuerde con el mapa de caracteres y pueda desplecar cada caracter adecuadamente, pero este punto considero que es meramente programación no me imagino como solucionarlo. Alguna idea o secuencia en ensamblador con que me puedan ayyudar?????

Nuevamente gracias

Desconectado telojurito

  • PIC12
  • **
  • Mensajes: 55
Re: Conversor A/D con PIC16F76
« Respuesta #25 en: 14 de Noviembre de 2008, 21:47:03 »
Para ilustrar mejor, la secuencia que estoy utilizando es muy simple dentro de un bucle:

incf   K,1
movlw   0x30
addwf   K,1

movf   K,0
call   LCD_DAT

movlw   0x30
subwf   K,1

cada que realiza esta parte dentro del bucle va incrementando los valores 1,2,3,4,5, etc pero como comentaba, al llegar a 0x0A muestra el valor de (:) del mapa de caracteres y la idea es que muestre el n´mero 10 y así sucesivamente

Desconectado BrunoF

  • Administrador
  • DsPIC30
  • *******
  • Mensajes: 3865
Re: Conversor A/D con PIC16F76
« Respuesta #26 en: 14 de Noviembre de 2008, 22:51:20 »
El siguiente código que hice soporta hasta 999 lecturas

K(deberias renombrar a Uni o parecido para mejor legibilidad) contiene las unidades
Dec contiene las decenas
Cen contiene las centenas

                                         ;Dec y Cen deben ser declaradas en RAM. Las tres variables deben ser inicializadas a cero al iniciar el programa del uC.

                      incf K,1        ;incremento unidades
                      movlw .10
                      xorwf K,W
                      btfss STATUS,Z
                      goto  Muestra

                      clrf  K   
                      incf  Dec,F
                      movlw .10
                      xorwf Dec,W
                      btfss STATUS,Z
                      goto  Muestra

                      clrf  Dec   
                      incf  Cen,F

Muestra           movf  Cen,w
                      btfsc   STATUS,Z
                      goto    MuestraDec

                      addlw 0x30
                      call    LCD_DAT
 
MuestraDec     movf  Dec,w
                      btfsc   STATUS,Z
                      goto    MuestraUni

                      addlw 0x30
                      call    LCD_DAT
                   

MuestraUni      movf  K,w
                      addlw 0x30
                      call    LCD_DAT


Eso sería trabajando en Código BCD. Podría optimizarse.

Saludos.                       
"All of the books in the world contain no more information than is broadcast as video in a single large American city in a single year. Not all bits have equal value."  -- Carl Sagan

Sólo responderé a mensajes personales, por asuntos personales. El resto de las consultas DEBEN ser escritas en el foro público. Gracias.

Desconectado telojurito

  • PIC12
  • **
  • Mensajes: 55
Re: Conversor A/D con PIC16F76
« Respuesta #27 en: 14 de Noviembre de 2008, 23:47:17 »
Nooooo, si de verdad que el que sabe.... sabe!!!!!!!

Mil gracias BrunoF, la secuencia funciona de maravilla, a la perfección. Le hice unas modificaciones en cuanto al incremento de las posiciones cuando cambia a 2 y 3 dígitos, sólo que cuando cambia de 99 a 100 se sigue con la secuencia de sólo dos dígitos, el primero y el tercero el segundo como que se lo vuela, no lo muestra: 10, 11, 12, 13, etc. Aquí esta tu código con las modificaciones que menciono:

         incf   Uni,1         ;incremento unidades
         movlw   .10
         xorwf   Uni,W
         btfss   STATUS,Z
         goto   Muestra

         clrf   Uni
         incf   Dec,F
         movlw   .10
         xorwf   Dec,W
         btfss   STATUS,Z
         goto   Muestra

         clrf   Dec
         incf   Cen,F

Muestra    movf   Cen,w
         btfsc   STATUS,Z
         goto   MuestraDec

         addlw   0x30
         call   LCD_DAT
         call   ADDRESS

MuestraDec   movf   Dec,w
         btfsc   STATUS,Z
         goto   MuestraUni

         addlw   0x30
         call   LCD_DAT
         call   ADDRESS

MuestraUni   movf   Uni,w
         addlw   0x30
         call   LCD_DAT
         call   ADDRESS

Y un último favor, considero que el hacer funcionar algo es importante, pero imprescindible saber cómo se hizo funcionar, podrías explicar un poco la filosofía de tu secuencia? de cómo es que funciona?

Mil gracias nuevamente

Desconectado telojurito

  • PIC12
  • **
  • Mensajes: 55
Re: Conversor A/D con PIC16F76
« Respuesta #28 en: 15 de Noviembre de 2008, 00:12:14 »
Le hice unas pequeñas modificaciones depués de clrf Dec pero nada.... hace exactamente lo mismo, como que falta algo pero no logro entender bién la secuencia.....

         incf   Uni,1         ;incremento unidades
         movlw   .10
         xorwf   Uni,W
         btfss   STATUS,Z
         goto   Muestra

         clrf   Uni
         incf   Dec,F
         movlw   .10
         xorwf   Dec,W
         btfss   STATUS,Z
         goto   Muestra

         clrf   Dec
         incf   Cen,F
         movlw   .10
         xorwf   Cen,W
         btfss   STATUS,Z
         goto   Muestra

Muestra    movf   Cen,w
         btfsc   STATUS,Z
         goto   MuestraDec

         addlw   0x30
         call   LCD_DAT
         call   ADDRESS

MuestraDec   movf   Dec,w
         btfsc   STATUS,Z
         goto   MuestraUni

         addlw   0x30
         call   LCD_DAT
         call   ADDRESS

MuestraUni   movf   Uni,w
         addlw   0x30
         call   LCD_DAT
         call   ADDRESS


Desconectado BrunoF

  • Administrador
  • DsPIC30
  • *******
  • Mensajes: 3865
Re: Conversor A/D con PIC16F76
« Respuesta #29 en: 15 de Noviembre de 2008, 06:57:09 »
Nooooo, si de verdad que el que sabe.... sabe!!!!!!!

Mil gracias BrunoF, la secuencia funciona de maravilla, a la perfección. Le hice unas modificaciones en cuanto al incremento de las posiciones cuando cambia a 2 y 3 dígitos, sólo que cuando cambia de 99 a 100 se sigue con la secuencia de sólo dos dígitos, el primero y el tercero el segundo como que se lo vuela, no lo muestra: 10, 11, 12, 13, etc. Aquí esta tu código con las modificaciones que menciono:

         incf   Uni,1         ;incremento unidades
         movlw   .10
         xorwf   Uni,W
         btfss   STATUS,Z
         goto   Muestra

         clrf   Uni
         incf   Dec,F
         movlw   .10
         xorwf   Dec,W
         btfss   STATUS,Z
         goto   Muestra

         clrf   Dec
         incf   Cen,F

Muestra    movf   Cen,w
         btfsc   STATUS,Z
         goto   MuestraDec

         addlw   0x30
         call   LCD_DAT
         call   ADDRESS

MuestraDec   movf   Dec,w
         btfsc   STATUS,Z
         goto   MuestraUni

         addlw   0x30
         call   LCD_DAT
         call   ADDRESS

MuestraUni   movf   Uni,w
         addlw   0x30
         call   LCD_DAT
         call   ADDRESS

Y un último favor, considero que el hacer funcionar algo es importante, pero imprescindible saber cómo se hizo funcionar, podrías explicar un poco la filosofía de tu secuencia? de cómo es que funciona?

Mil gracias nuevamente

Buenas! Si. Es que me he equivocado un poquiño. Ahí lo soluciono.

         incf   Uni,1         ;incremento unidades
         movlw   .10            ;cargo 10 en W para comparar
         xorwf   Uni,W        ;Si Uni XOR 10 da 0, entonces es hora de incrementar decenas
         btfss   STATUS,Z          ;Dió cero?
         goto   Muestra             ;No. Entonces listo el cálculo. Mostrar

         clrf   Uni                    ;Si. Dió cero y es hora de poner a cero las unidades e
         incf   Dec,F                ;incrementar las decenas
         movlw   .10            ;Ahora cargo 10 en W para comparar
         xorwf   Dec,W       ;Si Dec XOR 10 da cero, entonces es hora de incrementar decenas
         btfss   STATUS,Z          ;Dió cero?
         goto   Muestra             ;No. Entonces fin cálculos

         clrf   Dec                   ;Si. Dió cero. Entonces poner Decenas a cero e
         incf   Cen,F                ;incrementar centenas

Muestra         movf   Cen,w               ;copiar Cen en W(la instruccion movf afecta al flag Z, por lo que si Cen vale cero, Z se pone en alto)
         btfsc   STATUS,Z         ;Z en bajo?(Hay al menos una centena?)
         goto   MuestraDec       ;No. entonces pasar a mostrar decenas

         addlw   0x30         ;Si. Entonces mostrar centenas
         call   LCD_DAT
         call   ADDRESS
                        movf Dec,w               ;Cargar decenas(arregla error previo)
                        goto  HayDecenas      ;Línea para arreglar el error previo. Si al menos exíste una Centena, obligar a mostrar decenas

MuestraDec   movf   Dec,w               ;copiar Dec en W(la instruccion movf afecta al flag Z, por lo que si Dec vale cero, Z se pone en alto)
         btfsc   STATUS,Z         ;Al menos una decena?
         goto   MuestraUni        ;No. Entonces pasar a mostrar unidades

HayDecenas
         addlw   0x30         ;Si. Mostrar Decenas
         call   LCD_DAT
         call   ADDRESS

MuestraUni   movf   Uni,w                ;Mostrar unidades(no es necesario verificarlas. Al menos siempre hay una medición)
         addlw   0x30
         call   LCD_DAT
         call   ADDRESS


Debería arreglar el error que mencionaste. El código que hice antes salió mal sin querer en eso. Es que por ejemplo, mi código se fijaba en si al menos existe una decena para ser mostrada pero 100 por ejemplo, no posee decenas pero si centenas. Mi codigo anterior solo revisaba si existia al menos una decena. Como 100 no posee ninguna decena, no las mostraba. El codigo nuevo lo que hace es que si al menos existe una centena, obliga a mostrar las decenas tambien(en cualquier numero mayor a 100 deberían mostarse siempre las decenas, no?). El error no se propagó a las unidades porque asumí que debían mostrarse siempre.
 El error iba a ocurrir(en realidad lo supongo porque imagino el comportamiento del programa mirando el código) siempre y cuando el número fuese del tipo X0Y con 0<X<10; 0<=Y<10.

Es decir, por ejemplo el error se iba a producir en los números 100,101,102,103,104...200,201,202...300....906,907,908,909.

Espero haya quedado claro.

Una variante que por ahí te gustaría probar para ver cuál te gusta como queda mejor en el LCD es la siguiente:

         incf   Uni,1         ;incremento unidades
         movlw   .10
         xorwf   Uni,W
         btfss   STATUS,Z
         goto   Muestra

         clrf   Uni
         incf   Dec,F
         movlw   .10
         xorwf   Dec,W
         btfss   STATUS,Z
         goto   Muestra

         clrf   Dec
         incf   Cen,F

Muestra             movf   Cen,w
         addlw   0x30
         call   LCD_DAT
         call   ADDRESS

MuestraDec   movf   Dec,w
         addlw   0x30
         call   LCD_DAT
         call   ADDRESS

MuestraUni   movf   Uni,w
         addlw   0x30
         call   LCD_DAT
         call   ADDRESS


Saludos.
"All of the books in the world contain no more information than is broadcast as video in a single large American city in a single year. Not all bits have equal value."  -- Carl Sagan

Sólo responderé a mensajes personales, por asuntos personales. El resto de las consultas DEBEN ser escritas en el foro público. Gracias.


 

anything