Autor Tema: Problema PIC16F73 tablas largas y bancos 0, 1, 2, 3  (Leído 2891 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado tuxfriend

  • PIC10
  • *
  • Mensajes: 4
Problema PIC16F73 tablas largas y bancos 0, 1, 2, 3
« en: 20 de Abril de 2011, 05:10:11 »
Saludos a la comunidad:

Este es el primer post, espero estar publicando en el lugar adecuado. Voy al grano; estoy haciendo una rutina con un PIC 16F73 en la que deseo leer datos del convertidor A/D, pasar ese dato a una tabla y la tabla debe devolverme el resultado para luego expresarlo en un conjunto de display, concretamente en 3. El asunto va más o menos, ya he logrado hacer las conversiones A/D y puedo expresar en 3 display's de 7 segmentos valores de 0 a 255 (ya que la resolución del convertidor es de 8 bit's), pero yo necesito expresar valores de 0 a 500, (esto me obliga a trabajar con conversiones a 16 bit's) lo cual he logrado hacer para expresar estos valores en pruebas preliminares, (por ejemplo multiplico el resultado de la conversión por dos y puedo expresar valores de 0 a 510 en variaciones de 2 en dos). Si tomo como referencia el voltaje de alimentación de la fuente (5V). tengo un error de 100mV (ya que la lectura final con 5V seria 255x2=510). En pocas palabras necesito que el pic se porte como un voltímetro en el rango de 0V a 5V.

Mis preguntas:
¿puedo almacenar una tabla grande de 255 valores referenciales en la memoria (creo que debo partirla en bancos de 128 ya que los bancos no almacenan mas de eso, pero está la duda allí)?

¿cómo hago para organizar la tabla en otro banco de memoria y poderla llamar para luego regresar y ejecutar las otras operaciones de conversión y resultado en el banco inicial?


He hecho diversas pruebas y el programa siempre se me vuelve loco en lo que me paso de la dirección 100, he tratado de arrancar en otras localidades y nada. Estuve buscando en el foro cosas parecidas pero no consigo un buen norte para llegar a este resultado. Inclusive he hecho simulaciones y el simulador me da un error de volcado que no termino de orientar mis soluciones. he colocado cambio de estado en los bit's RP0 y RP1 para pasar de banco y hacer llamados y nada de nada.

Siempre he programado en assembler y lo prefiero para poder entender mejor lo que estoy haciendo. Utilizo mplab con el programador propic2 que tengo en el protoboard. Cristal de 4Mhz. y la entrada RA0 como entrada analógica que funciona perfectamente cuando el programa trabaja sin usar la tabla grande, la tabla de conversión para el display de 7 segmento funciona bien los números se expresan bien.

Ha una cantidad de variables declaradas para el manejo de cada display de 7 segmentos pero puedo reducirlas, ya hice algunas pruebas y cuando las tablas son extensas viene el colapso y el programa no trabaja, inclusive intente colocar una directriz ORG en zonas como org 100, 200 0x11h, para ponerla en otro lugar del mapa de memoria y no logro que trabaje correctamente.

Agradecido por cualquier orientación al respecto y disculpen si hay demasiadas consultas al respecto.

Tuxfriend.

P. D: el orden de los procesos es:

INICIO
Configuro puertos
Voy a ciclo de de arranque
Hago conversión (tengo un potenciometro conectado en la entrada RA0 para hacer las variaciones).
Llamo a tabla de expresión en lcd
Llamo a rutina de salida en lcd con retardos para poder ver los números
retorno a la conversión (están incluida las limpiezas de variables una vez que retorno).
FIN

Desconectado hector.ar

  • PIC10
  • *
  • Mensajes: 22
Re: Problema PIC16F73 tablas largas y bancos 0, 1, 2, 3
« Respuesta #1 en: 20 de Abril de 2011, 08:27:40 »
No entiendo para que necesitas la tabla.
Tu puedes hacer, digamos, una 500 mediciones e ir sumandolas a una variable, cuando llegas a la medicion Nro 500 divides por 250 y tienes el valor doble (para rango 0 a 512) del promedio, y ese es el valor a mostrar, luego repites el proceso. Lo único que necesitas son las librerias aritmeticas (en assembler) que se bajan de la de la página de microchip que te permites hacer operaciones matematicas con coma flotante.
Pero una alternativa mucho mas simple es que uses otro PIC: el 16F876A tiene ADC de 10 bits !, es decir resolucion de 0 a 1023, que por lo que cuentas te sobra. Y si quieres mas resolucion tienes que pasarte a la serie mejorada: el PIC18F2553 tiene resolucion de 12 bits, es decir 0 a 4095, como un buen multimetro digital!
Saludos!
Héctor

Desconectado tuxfriend

  • PIC10
  • *
  • Mensajes: 4
Re: Problema PIC16F73 tablas largas y bancos 0, 1, 2, 3
« Respuesta #2 en: 21 de Abril de 2011, 00:27:48 »
Saludos:

Agradecido por tus líneas de antemano.

El cambio de PIC no lo tengo considerado, digamos que es un reto tratar de lograrlo en este modelito.
La tabla la requiero para dar los valores más exactos posibles respecto a la medición. Puedo arreglar tomar un número de muestras y promediarlas para sacar un valor más cercano al real ya que sería el método correcto como mencionaste, pero ese promedio se hace en funcion de un valor ya obtenido que represente el voltaje, me explico y aclaro respecto a tus lineas:

Obtener el valor doble es mucho más sencillo en 16 bit's para valores positivos exclusivamente , que afortunadamente es lo que necesito trabajar para una aplicación limitada, sencillamente hago una rotación a la izquierda en 16 bit's y obtengo exactamente el mismo resultado que me describistes con lo de las muestras y sin tanto rollo, (rotar a la izquierda en binario es multiplicar por dos) de hecho eso lo logré expresar. El problema que tengo es que el convertidor da salidas de 0 a 255, y esto debe servirme para representar rangos de 0 a 5 voltios. Si quiero ser exacto o lo más cercano posible al valor debo hacer una equivalencia correcta de esta lectura a o que está presente en la entrada analógica, pongo una pequeña tablita de muestra con tres decimales de precisión  y dos también para que se note el detalle:

valor   3 dec   2 dec   variación si fuera ideal
0   0,000   0,00   0,020
1   0,020   0,02   0,020
2   0,039   0,04   0,020
3   0,059   0,06   0,020
4   0,078   0,08   0,020
5   0,098   0,10   0,020
6   0,118   0,12   0,020
7   0,137   0,14   0,020
8   0,157   0,16   0,020
9   0,176   0,18   0,020
10   0,196   0,20   0,020
11   0,216   0,22   0,020
12   0,235   0,24   0,020
13   0,255   0,25   0,020
14   0,275   0,27   0,020
15   0,294   0,29   0,020
16   0,314   0,31   0,020
17   0,333   0,33   0,020
18   0,353   0,35   0,020
19   0,373   0,37   0,020
20   0,392   0,39   0,020
21   0,412   0,41   0,020

Si yo tomo variaciones exactas de 002 por cada valor del convertidor, al final cuando se llegue a 255, yo tendría una salida de 510 (255 x 2) que represento como 5,10 voltios pero eso es un error ya que la alimentación máxima del sistema será de 5,00, entonces, lo que pensé, fue hacer una tabla para almacenar los valores con dos decimales de precisión, ya que lo que puse de ejemplo arriba con dos decimales puedo devolverlo para un valor determinado del convertidor y así puedo darle algo exactitud a la representación de la medida (dentro de las imprecisiones de una resolución de 8 bit's).

Ejemplo: el convertidor entrega 15 como valor de lectura, yo llamo a la tabla y esta me devuelve como resultado un 029 (no un 30 como sería si multiplicara por 2, producto del error en los decimales) que convierto luego a bcd en 16 bit's y mando al display de 7 segmentos como un 0.29 Voltios. Nota: pareciera que la diferencia de 0.01 no se nota pero en valores altos el error al final es de 100mV y es imperdonable si queremos hacer las cosas como se debe aunque sea tedioso el uso de tablas.

Ese es un poco el asunto y por eso pensé en las tablas, obviamente debo almacenarlas en dos bancos ya que solo dispongo de 128 bytes por banco pero el problema es que no estoy claro en como llamar a una rutina que está en otro banco y luego regresarme para procesar la información de la manera correcta.

Espero no haberme extendido mucho con el planteamiento y mis disculpas si hubo alguna cosa que no comprendi en tu explicación...

Tuxfriend.
« Última modificación: 21 de Abril de 2011, 00:31:20 por tuxfriend »

Desconectado hector.ar

  • PIC10
  • *
  • Mensajes: 22
Re: Problema PIC16F73 tablas largas y bancos 0, 1, 2, 3
« Respuesta #3 en: 21 de Abril de 2011, 14:23:58 »
Gracias por la aclaracion.
Creo que el problema tambien lo puedes resolver usando las rutinas aritmeticas, si el lugar de multiplicar por 2 multiplicas por 1,96 tendras una lectura de 500 para 5 voltios.
Adjunto las rutinas de coma flotante (como una calculadora), que las puedes incluir con un INCLUDE. Al principio del archivo hay un encabezamiento que detalla el uso de cada funcion. Si te interesa y tenes dudas te puedo ayudar, pues suelo utilizarla.
Saludos!
Héctor


Desconectado todopic

  • Administrador
  • DsPIC30
  • *******
  • Mensajes: 3495
    • http://www.todopicelectronica.com.ar
Re: Problema PIC16F73 tablas largas y bancos 0, 1, 2, 3
« Respuesta #4 en: 21 de Abril de 2011, 16:33:34 »
Hola, te recomiendo este post, tienes lo que necesitas para manejar grandes tablas  http://www.todopic.com.ar/foros/index.php?topic=12918.0
Firmat - Santa Fe - Argentina

www.TodoPic.net

Solo se tiran piedras, al arbol que tiene frutos...

Desconectado tuxfriend

  • PIC10
  • *
  • Mensajes: 4
Re: Problema PIC16F73 tablas largas y bancos 0, 1, 2, 3
« Respuesta #5 en: 21 de Abril de 2011, 23:03:22 »
Saludos de nuevo:

Antes que nada agradecido por sus prontas respuestas.

Efectivamente se puede solucionar con rutinas aritméticas, pero como siempre, yo voy de picapiedra a la optimización poco a poco jejeje. Iré modificando el programa confrome vayan resultando las cosas ya que tengo que implementar varias rutinitas para este proyecto dentro del mismo programa.

Les comento que ya he logrado resolver el inconveniente, tenía que ver con el contador de programa y el pclath, los cuales se volcaban y terminaban colgando el programa. El forista y admnistrador todopic se me adelantó a esta publicación y otra en la que aparecen las explicaciones de como manejar tablas en otras direcciones de la memoria y en las que iba a direccionar a las personas que leyeran este apartado para dar como resuelto, al menos por tablas, este inconveniente (por desconocimiento mio de paso y el tiempo que tenía sin programar).

Dejo los enlaces en los cuales está incluido el sugerido por todopic:

http://www.todopic.com.ar/foros/index.php?topic=12918.0  (agradecido con el forista maunix por el tiempo dedicado a esa publicación...!!!)

http://www.todopic.com.ar/foros/index.php?topic=15513.0 (agradecido también con el fosrista Franc749 por el codigo sugerido en ese apartado el cual pude implementar 100% a efectos de este voltímetro a base de tablas luego de la sugerencia de maunix en la que se puede optimizar las instrucciones para que no importe en que parte del mapa de memoria comience la tabla siempre y cuando no pase de 254 valores)

Para complementar un poco lo que hice fue lo siguiente:

Hice una tabla en la directriz org 500h y otra en la directriz org 600h
Realicé la conversión A/D y el resultado lo almacene en dos variables (8bit's ya que es la resolución, los 16 bit's los hago manualmente con la parte alta para valores de 256 para arriba ya que hay que expresar valores de 0 a 500)
Una vez determinada que tabla iba a usar me pasé de banco en la memoria mediante la asignación de la dirección en los bit's más significativos del pc que está en el pclath (aquí estaba mi falla), llamé a mi tabla y una vez limpio el pclath (para volver al banco de memoria baja) asigné el resultado en una varable para luego convertir a BCD y mandar al display de 7 segmento.

Poco a poco cuando vaya implementando cada una de las rutinas que restan a la aplicación iré optimizando con las sugerencias ofrecidas.

Gracias hector.ar, tendré en consideración las rutinas aritmética ya que so las optimas para resolver estos casos. Valen oro en este foro jejeje.

Tuxfriend.

P. D: Una optimización y alternativa para hacer un código de voltimetro aplicable a cualquier situación, estaría basada en tener en cuenta el rango de voltajes en el que va a trabajar el voltímetro así como la reslución del A/D para luego automáticamente por medio de una formula asignar valores y rango de variación por dato en el convertidor. En este caso, lo estoy a haciendo de 0 a 5 voltios con una resolución de 8 bit's lo que da una variación de 0.0196 voltios por cada paso del convertidor (allí está el valor sugerdo por hector.ar de 1,96 solo desplazaríamos la coma para trabajar con valores enteros y nos quedamos con los datos significativos).
« Última modificación: 21 de Abril de 2011, 23:29:45 por tuxfriend »


 

anything