Autor Tema: Una manito por favor  (Leído 49135 veces)

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

Desconectado BrunoF

  • Administrador
  • DsPIC30
  • *******
  • Mensajes: 3865
Re: Una manito por favor
« Respuesta #45 en: 14 de Mayo de 2009, 16:18:24 »
Bueno, me hiciste acordar de algo.

Mis rutinas eran para una 24LC08, no se si micro usaba esa o una 24LC256. Te comento porque yo enmascaro los bits que la 08 no usaba! Ojo con eso!

Cuando tenga un tiempo la miro mas en detalle.

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 BrunoF

  • Administrador
  • DsPIC30
  • *******
  • Mensajes: 3865
Re: Una manito por favor
« Respuesta #46 en: 14 de Mayo de 2009, 16:20:18 »
P.D. Desde el comienzo siempre he dicho que no conozco a NADIE que programando en ASM se haya llevado gratis el I2C. Siempre se reniega...:D
"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 BrunoF

  • Administrador
  • DsPIC30
  • *******
  • Mensajes: 3865
Re: Una manito por favor
« Respuesta #47 en: 14 de Mayo de 2009, 16:43:22 »
Ah! Y otra cosita...Pasame la declaración de las variables RAM de tu programa.
"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 marvicdigital

  • Colaborador
  • PIC18
  • *****
  • Mensajes: 311
Re: Una manito por favor
« Respuesta #48 en: 14 de Mayo de 2009, 16:54:36 »
P.D. Desde el comienzo siempre he dicho que no conozco a NADIE que programando en ASM se haya llevado gratis el I2C. Siempre se reniega...:D

 :D :D :D  me hiciste reír...el asunto era que yo quería ser el primero en llevármelo gratis ,pero ni modo en otra vida será  :D :mrgreen:

Las variables:

Código: [Seleccionar]
CBLOCK 020H
COL0
COL1 ;BYTE PARA  COLUMNAS
COL2
COL3
COL4
COL5
COL6
COL7
COL8
COL9
COL10
COL11
COL12
COL13
COL14
COL15
COL16
COL17
COL18
COL19
COL20
COL21
COL22
COL23
COL24
COL25
COL26
COL27
COL28
COL29
COL30
COL31
COL32
; CUANDO SE SUMEN LAS RESTANTES COLUMNAS DEBEMOS LLEGAR HASTA COL80
ESPACIO
FORMAR
VECES
DATOS
TEMPORAL
AUXILIAR
FILAS
LETRA
COLUMNAS
PALABRA
IC2DATA
ELEMENTO
SUBELEMENTO
TMPL
TMPH
TMPSUB
DIRL
DIRH
DEMOELEMENTO
DEMOSUBELEMENTO
DEMOTMPL
DEMOTMPH
DEMOTMPSUB
DEMODIRL
DEMODIRH
MENSAJE
ORACION
HADDEEPROM
LADDEEPROM
FLAGEE
ENDC

Una pregunta con respecto a este punto, cuando llegue a la memoria 07fh o sea ,ocupe la RAM para los 96 registros generales de la primera página como es la instrucción para pasar a la dirección 0A0H, ya que hice el intento de ponerle CBLOCK  0A0H -- registros ..endc  y al compilar me dio error, quedé de investigar ese punto apenas llegue a requerirlo, pero ahora que estamos puestos..no me vendría mal una explicación.  :)

Saludos y gracias BrunoF



Desconectado BrunoF

  • Administrador
  • DsPIC30
  • *******
  • Mensajes: 3865
Re: Una manito por favor
« Respuesta #49 en: 14 de Mayo de 2009, 17:12:32 »
P.D. Desde el comienzo siempre he dicho que no conozco a NADIE que programando en ASM se haya llevado gratis el I2C. Siempre se reniega...:D

 :D :D :D  me hiciste reír...el asunto era que yo quería ser el primero en llevármelo gratis ,pero ni modo en otra vida será  :D :mrgreen:

:D :D es que es así. es el precio q hay que pagar por programar en ASM y poder controlarlo todo...:D :D

Las variables:

Código: [Seleccionar]
CBLOCK 020H
COL0
COL1 ;BYTE PARA  COLUMNAS
COL2
COL3
COL4
COL5
COL6
COL7
COL8
COL9
COL10
COL11
COL12
COL13
COL14
COL15
COL16
COL17
COL18
COL19
COL20
COL21
COL22
COL23
COL24
COL25
COL26
COL27
COL28
COL29
COL30
COL31
COL32
; CUANDO SE SUMEN LAS RESTANTES COLUMNAS DEBEMOS LLEGAR HASTA COL80
ESPACIO
FORMAR
VECES
DATOS
TEMPORAL
AUXILIAR
FILAS
LETRA
COLUMNAS
PALABRA
IC2DATA
ELEMENTO
SUBELEMENTO
TMPL
TMPH
TMPSUB
DIRL
DIRH
DEMOELEMENTO
DEMOSUBELEMENTO
DEMOTMPL
DEMOTMPH
DEMOTMPSUB
DEMODIRL
DEMODIRH
MENSAJE
ORACION
HADDEEPROM
LADDEEPROM
FLAGEE
ENDC

Una pregunta con respecto a este punto, cuando llegue a la memoria 07fh o sea ,ocupe la RAM para los 96 registros generales de la primera página como es la instrucción para pasar a la dirección 0A0H, ya que hice el intento de ponerle CBLOCK  0A0H -- registros ..endc  y al compilar me dio error, quedé de investigar ese punto apenas llegue a requerirlo, pero ahora que estamos puestos..no me vendría mal una explicación.  :)

Saludos y gracias BrunoF

CBLOCK es para declararlas y deberías poder declarar mas allá de la 0x7F.
Para acceder a variables RAM de otros bancos, se usa la MACRO: BANKSEL nombre_variable
Ejemplo:

tolon equ 0x40
tilin   equ 0x80

;......
;en programa:
     banksel tilin
     movf tilin,w
     banksel tolon
     movwf tolon



el MPASM reemplaza las etiquetas pasadas por su posición ram declarada:
     banksel 0x80
     movf tilin,w
     banksel 0x40
     movwf tolon

luego reemplaza las MACROs BANKSEL por dos instrucciones bcf/bsf STATUS,RP0 y bcf/bsf STATUS,RP1 segun el valor de memoria argumentado:

    bsf       STATUS,RP0                       ;banksel 0x80
    bcf       STATUS,RP0                       
    movf tilin,w
    bcf       STATUS,RP0                       ;banksel 0x40
    bcf       STATUS,RP0                       
    movwf tolon

P.D. Las posiciones RAM [0x70;0x7F] se comparten entre todos los bancos(los 4), Esto quiere decir que no hace falta cambiar de banco para acceder a ellas.Entonces: tip: aprovecha bien esas 16 posiciones y usalas para variables que uses masivamente a lo largo del programa. Te vas a ahorrar muchas BANKSEL(mucha FLASH y legibilidad).

Capiche?

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 Cryn

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 4169
Re: Una manito por favor
« Respuesta #50 en: 14 de Mayo de 2009, 17:37:02 »
Hola Bruno, un pregunta...

el buffer de 80bits de este ejemplo se modifica según los datos de cada fila, cierto?

Hola! El buffer es de 80 bytes. Un byte por columna, un bit por LED. No entendí lo de modificar los datos según cada fila.

si se desea hacer algunos efectos, por ejemplo solo desplazar un texto, si ya tengo un mensaje cargado para desplazar una columna se debe rotar el buffer en cada fila, si voy en el décimo desplazamiento debo rotar 10 veces el buffer cada vez que lleguen los datos de una fila.

Ah! Creo que logré entender algo...Bien. Tu has utilizado otro método. Mi propuesta "destruye" los datos a medida que van siendo reemplazados por otros. En mi algoritmo, cuando roto, voy destruyendo columna por columna, aunque debería ser ocupada por nuevos datos. Si entendí bien, lo que hacés es almacenar los datos originales, sin transformaciones, y luego realizar las transformaciones necesarias para generar el resultado que deberá ser mostrado en pantalla. No está mal. Técnicamente funciona. Lo que pasa es que deberías asegurarte en ese caso que todos los efectos que hagas se puedan realizar en tiempos breves, y no sean acumulativos de manera tal que cada vez demanden mayor tiempo de procesado.

Yo no llegué a explicarle a marvicdigital que hay una optimización más a la hora de rotar el buffer, sea hacia arriba, abajo, derecha o izquierda, y se basa en usar punteros. Un puntero que indique la primer columna del buffer, y otro que indique la primer fila del mísmo.

Lo explayo un poco(caso de rotaciones hacia la izq y der):

Cuando comienza el programa, el puntero de columnas apuntará a la posición donde se encuentre COL1. El algoritmo de refresco "mostrará" fila x fila los valores, comenzando desde lo que el puntero le indique, es decir, desde COL1 hasta COL32 en el programa de marvicdigital. Ahora, si yo quisiera rotar un lugar a la derecha el buffer, usando punteros, puedo sencillamente sólo cambiar el puntero, haciendo que ahora apunte a la posición donde está COL2. El algoritmo de refresco comenzará a refrescar las filas comenzando desde COL2 hasta COL1, que será la última. Fijemonos que usando punteros, el tiempo que se requiere para procesar los datos se minimiza. Sólo cambiamos el valor del puntero, para que luego la rutina de refresco se adapte a ello.
En tu caso, esto resolvería las 10 rotaciones. Sólo deberías incrementar o decrementar el puntero en 10 unidades. SIEMPRE TENIENDO EN CUENTA QUE EL BUFFER ES CICLICO. CUANDO TERMINA, HAY QUE VOLVER A RECORRERLO DESDE EL PRINCIPIO Y VICEVERSA.

Lo que yo hice fue usar excesiva RAM :(, creándome en CCS un arreglo bidimensional o matriz que emula a mi matriz de leds, si tengo por ejemplo 40 columnas tendré una matriz[40][8] y ahí cargo los datos los roto, los animo y hago quizá todo, lo más complicado creo que serán algunos algoritmos para efectos llamativos, y muestro los datos fila por fila de mi matriz[40][8] cargando a los registros byte por byte.

Crees que es un desperdicio de ram? o como se hace solo con uno o dos buffers?

un saludo.

no me especificaste si la matriz de [40][8] son bits o bytes. Si son bits, no hay desperdicio. Si son bytes y no estás usando tonalidades de color(es decir, sólo enciendes o apagas el LED(biestado))  entonces sí habría desperdicio ya que de 8 bits por LED solo usas 1. Ten en cuenta que si puedes hacer lo mísmo con una matriz de una sóla dimension, todos los accesos y operaciones son más rápidas que con matrices de más dimensiones.

Podés usar un solo buffer sin problemas si se cumple con lo que dije más arriba. Un doble buffer da 100% de seguridad, porque te permite modificar a gusto sin tener que preocuparte por si los datos se están refrescando o no mientras estás todavía realizando modificaciones al buffer. Si tenés la posibilidad de crear dos buffers, te recomiendo que lo hagas, especialmente si deseas agregarle efectos que puedan requerir de mucho tiempo para procesarlos.

Como ya mencioné, el peligro de hacer sólo un buffer es que como dependemos de nuestro buffer interno para poder ir refrescando las filas en el cartel, puede suceder que se visualicen en los LEDs los cambios que vamos realizando en el buffer. Y no es posible esperar a que termine de procesarlos para visualizarlos, porque sino mientras no podríamos refrescar las filas. Un solo buffer significa que compartimos el buffer para visualizarlo y para modificarlo.

Un saludo.

Saludos, disculpa por responder después de tanto tiempo, y si usé la matriz [6][8] de bytes, me equivoque, no es de 40 la matriz; ésta representa en el programa del micro a la matriz física. Aclarar que la matriz de leds física está formada de matrices pequeñas de 8x8 en total solo tengo 5 matrices de 8x8, la 6ta posición de la matriz en soft lo uso como temporal. Ya que comencé por desplazar el mensaje de derecha a izquierda, y coloque esta 6 posición para que la 1ra letra aparezca primeramente en esta virtual, y exista un espacio entre el fin e inicio del mensaje cuando este termine de pasar.

Les menciono los pasos y muestro algunas imágenes de lo que hago, y al menos lo que ví en otros mensajes, quizá en idea general vaya por buen camino, pero en el uso de la matriz en soft quizá no sea lo mejor, y todavía no logro entenderlo sin usar la matriz y usar solamente unos cuantos buffers y lograr todos los efectos que uno puede ver en estos letreritos tan vistosos.

1. Tengo mi mensaje guardado en ASCII
2. Leo la primera letra del mensaje y la decodifico en sus 8 bytes que tiene, los 8 bytes resultantes los almaceno en la última posición de la matriz (uso caracteres de 8x8).
3. muestro el contenido de la matriz[6][8] que inicialmente esta cargada solamente con la 1ra letra del mensaje (sus 8 bytes), por tanto como tengo físicamente 5 matrices de leds no se verá nada.
4. muestro varias veces el contenido de la matriz[6][8], para que el mensaje no pase demasiado rápido.
lo muestro fila por fila: 1ro cargo los registros con los datos
  • [0], [1][0], [2][0]... [4][0], ya no muestro el [5][8] pues es "mi matriz física virtual". Después cargo el siguiente dato de las filas
  • [1], [1][1], [2][1]... [4][1] y así sucesivamente hasta terminar las filas todo refrescado en un tiempo corto por el TMR0, y nuevamente mostrar la fila 1 para repetir ello una determinada cantidad de veces, para que el mensaje tenga cierta pausa, mientras más veces repita la muestra del mismo mensaje será más lento, y por el contrario mientras menos, será más rápido

5. roto todos los bytes de la matriz[6][8] a la izquierda.
6. vuelvo a mostrar el contenido de la matriz de la misma manera, pero ahora ya aparecerá la primera columna de la primera letra en la matriz física, los leds correspondientes estarán encendidos
y así sucesivamente hasta mostrar todas las letras del mensaje.

Les muestro unas cuantas imágenes de lo que creo ya todos lo conocemos.

primera fila:


segunda:


tercera:


cuarta:


quinta:


sexta:


septima:


octava


mensaje que se obtiene visualmente:


Esa es la idea que plasme en código, pero fue esencialmente pensando en solo desplazar el mensaje de der a izq, pero ahora hay tantos efectos que hay como que el mensaje se desplace hacia arriba o abajo o que desaparezca columna por columna desde la izq o der o desde el medio hacia ambos lados y bueno nose, supongo que con bastante código (algoritmos) se podrá lograr estos efectos usando la matriz[6][8] que tengo en RAM, pero seguramente es lo menos efectivo como mencionó Bruno.

Todavía no logro entender muy bien donde van los punteros y como sabes que letra apunta el puntero si esta almacenado en ascii y debes decodificar primeramente...

como lo haces tu? o como debería ser?

un saludo y muchas gracias por la ayuda, y disculpas que me entrometa en el hilo, pero quizá esto también pueda ayudar a alguien que tenga un problema parecido al mío.

pd. Felicidades marvicdigital por el cartel, te ha quedado muy bien, se ve bien en el video
.

Desconectado marvicdigital

  • Colaborador
  • PIC18
  • *****
  • Mensajes: 311
Re: Una manito por favor
« Respuesta #51 en: 14 de Mayo de 2009, 18:04:17 »
Gracias BrunoF, tus explicaciones son monumentales..y ahora como vez el código del I2C?..ya tengo hasta dolor de cabeza..voy a repazar algunos PDF sobre los 16F87X a ver si encuentro el detallito  :D  no creo que sea máscara por que no le he hecho ninguna AND ..bueno..seguire mirando..por que ya hice una prueba y me graba datos, lo que no logro hacer es que me los lea  :?

En fín..el módulo MSSP debe estar burlandose de mí.. :D




Saludos.

Desconectado BrunoF

  • Administrador
  • DsPIC30
  • *******
  • Mensajes: 3865
Re: Una manito por favor
« Respuesta #52 en: 14 de Mayo de 2009, 18:37:43 »
Hola Cryn!

Creo que entiendo tu método. El problema de usar arreglos bidimensionales es que tenés dos dimensiones que recorrer contra una sola. Es mucho más sencillo con una sola dimension. Más rápido el código, los punteros y los efectos luego.

Entonces, si vos tenés 40 columnas de cartel efectivos, y 8 bytes más para buffer temporal, podrías usar una matriz de 48 bytes.

//(esto es en C marvic)

//Ej:
#DEFINE    COLUMNAS 40
#DEFINE    TMPBUFF      8
char BufferA[COLUMNAS+TMPBUFF];

A ver, creo que acá está el problema. La idea es transformar los caracteres en gráfico. Vos tendrás almacenado el código ASCII de cada caracter a mostrar, junto con la tabla de cada uno que contendrá los valores(8 bytes) de los LEDs correspondientes.

Cuando tenés que ir llenando el buffer, andá volcando(copiando) todos los valores(8 bytes) de cada caracter en el mísmo(en el buffer) y descartá el caracter original. Te olvidás por completo porque ya está volcado en el buffer. Ahora el caracter es en realidad 8 columnas de LEDs. Un mero gráfico.

La rutina para mostrar los LEDs sólo refresca lo que va encontrando en las primeras 40 columnas de tu buffer. Ahora, podés usar un "puntero" para agilizar las rotaciones.El puntero es el encargado de indicarle a la rutina de refresco cuál es la primera columna del buffer a refrescar.

Acá te pego mi rutina de refresco para un cartel que estoy programando precisamente en estos días.Te declaro y explíco antes las variables involucradas:
 
int1 BuffActual;   //0 o 1. Indica el buffer actual que se deberá mostrar. En el otro se trabajará. INICIALIZADO A 0.
int8 Inicio;         // Es mi "puntero" que aunque no es un puntero REAL, sirve para recorrer la matriz e indicar cuál es la primer columna a refrescar. INICIALIZADO A 0.
//DATA,CLOCK y STROBE están asociados a 3 pines que son los que comandan los 74HC4094.
int8 FilaActual    //Contiene el valor del puerto(PORTD en mi caso) que controla las filas para indicar cuál es la fila actual a refrescar.(son 7 filas en total).INICIALIZADO A 1.

Código: C
  1. void display_refrescar(void){
  2.    char i;
  3.    if(!BuffActual){
  4.       for(i=Inicio-1;i!=255;i--){
  5.         output_low(DATA);
  6.         if(Buffer1[i] & FilaActual) output_high(DATA);
  7.         output_high(CLOCK);
  8.         output_low(CLOCK);
  9.       }
  10.       for(i=COLUMNAS-1;i!=Inicio-1;i--){
  11.         output_low(DATA);
  12.         if(Buffer1[i] & FilaActual) output_high(DATA);
  13.         output_high(CLOCK);
  14.         output_low(CLOCK);
  15.       }
  16.    }else{
  17.       for(i=Inicio-1;i!=255;i--){
  18.         output_low(DATA);
  19.         if(Buffer2[i] & FilaActual) output_high(DATA);
  20.         output_high(CLOCK);  
  21.         output_low(CLOCK);
  22.       }
  23.       for(i=COLUMNAS-1;i!=Inicio-1;i--){
  24.         output_low(DATA);
  25.         if(Buffer2[i] & FilaActual) output_high(DATA);
  26.         output_high(CLOCK);
  27.         output_low(CLOCK);
  28.       }
  29.    }
  30.  
  31.    PORTD=255;     //apagar todo
  32.    output_high(STROBE);    //efectivizar datos
  33.    output_low(STROBE);
  34.    PORTD=FilaActual^255; //en la simulación necesito invertir la lógica porque no uso los ULN porque as+i ahorro procesado del micro de la PC al simular.
  35.    rotate_left(&FilaActual,1); //roto para indicar próxima fila
  36.    if(FilaActual==128){        //me fijo si ya excedí la 7ma fila.
  37.       FilaActual=1;               //Si, entonces indicar que la próxima a refrescar será la primera
  38.       NewFrame=1;             //e indicar que es un buen momento para producir un cambio visible en el programa(porque es justo cuando he terminado de refrescar todas las filas)
  39.    }else{
  40.       NewFrame=0;            //si no excedí la 7ma fila, indicar que no es buen momento para cambiar algo visible(como intercambiar buffers...)
  41.    }
  42. }

Ahora, usando esta forma, rotar lo que se muestra en el display es sumamente sencillo. Por ejemplo, para rotar lo que muestro a la izquierda en una posición(columna), sólo hago:

Código: C
  1. void rotar_izq(){
  2.     Inicio++;                      //incremento el "puntero" que le indica a la subrutina de refresco cuál es la primer columna a refrescar
  3.     if(Inicio==COLUMNAS){  //me aseguro de que Inicio no se me "escape" de las dimensiones del Buffer. Hacer un buffer ciclico. Reacomodar si es necesario.
  4.         Inicio=0;                  //Se fue de los límites del Buffer, y como es cíclico,vuelvo al principio del buffer.
  5.     }
  6. }

Y el buffer rotará su contenido sobre si mísmo.

Como no tengo programa para capturar video con la PC, te dejo la simulación con el .hex. Necesitás una versión nueva del Proteus, porque mi cartel va por USB(aunque actualmente envía y recibe datos, no participa del soft realmente).

Un saludo.
"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 BrunoF

  • Administrador
  • DsPIC30
  • *******
  • Mensajes: 3865
Re: Una manito por favor
« Respuesta #53 en: 14 de Mayo de 2009, 18:40:12 »
Gracias BrunoF, tus explicaciones son monumentales..y ahora como vez el código del I2C?..ya tengo hasta dolor de cabeza..voy a repazar algunos PDF sobre los 16F87X a ver si encuentro el detallito  :D  no creo que sea máscara por que no le he hecho ninguna AND ..bueno..seguire mirando..por que ya hice una prueba y me graba datos, lo que no logro hacer es que me los lea  :?

En fín..el módulo MSSP debe estar burlandose de mí.. :D




Saludos.


Buena imagen! :D :D

Quiero decir que YO hacía una máscara e inyectaba bits en mi rutina de la 24LC08 usando AND e IOR. Por ahi estás arrastrando eso a la 24LC256...

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 marvicdigital

  • Colaborador
  • PIC18
  • *****
  • Mensajes: 311
Re: Una manito por favor
« Respuesta #54 en: 14 de Mayo de 2009, 22:16:01 »
Bueno creo que encontré mi falla, no la he probado por que estoy analizando primero, pero para empezar estas lineas:


Código: [Seleccionar]
MOVLW         B'10100000'
PAGESELW         TRANSMITIR_DATO_I2C
CALL                 TRANSMITIR_DATO_I2C
MOVF         HADDEEPROM,W                           ;[color=red]CARGO W CON EL REGISTRO HADDEEPROM[/color]
PAGESELW         TRANSMITIR_DATO_I2C
CALL                 TRANSMITIR_DATO_I2C
MOVF         LADDEEPROM,W
PAGESELW         TRANSMITIR_DATO_I2C
CALL                 TRANSMITIR_DATO_I2C

Y en el .INC tengo la rutina de transmitir_dato_I2C asi:

Código: [Seleccionar]
TRANSMITIR_DATO_I2C

BCF             FLAGEE,0
PAGESEL        I2C_IDLE        ;INICIALIZAR FLAG COMO "ERROR"
    CALL             I2C_IDLE
    MOVF             IC2DATA,W          ;MOVER DATO A W           ;[color=red]Aca se pierde el valor que traía W[/color]
    MOVWF            SSPBUF          ;CARGAR DATO EN BUFFER I2C
    BSF             STATUS,RP0      ;BANCO 1

Ahora si creo que debe funcionar la cosa..voy a probar y ya cuento..a lo mejor encuentro más errores monumentales  :D

Saludos

Edit 1:  Listo problema resuelto, ese era todo el stop que tenía, también aclaro una cosa que pueda servir para muchos, voy a dar un ejemplo y explico:

Código: [Seleccionar]
LOOP_EE
       
   PAGESEL CONFIG_TRANSMISION_I2C ;DIRECCIÓN Y LECTURA DE LA MEMORIA EEPROM
   CALL         CONFIG_TRANSMISION_I2C
   CLRF          IC2DATA
   CLRF         PALABRA
   PAGESEL BIT_START_I2C
   CALL         BIT_START_I2C
            ...
            ....
            ...
            GOTO            LOOP_EE

Si escribo estas lineas asi, el programa no ejecuta la instrucción siguiente al GOTO, osea la de CALL Config_transmision_I2C, por alguna razón que desconozco  el PCLTAH toma otro valor y el PC simplemente se pierde, la verdad no se por qué, eso también fue la causa de mis problemas a la hora de leer la memoria, para que este fallo no se presente se le debe agregar un par de NOP quedando asi:


Código: [Seleccionar]
LOOP_EE
           NOP
           NOP
   PAGESEL CONFIG_TRANSMISION_I2C ;DIRECCIÓN Y LECTURA DE LA MEMORIA EEPROM
   CALL         CONFIG_TRANSMISION_I2C
   CLRF          IC2DATA
   CLRF         PALABRA
   PAGESEL BIT_START_I2C
   CALL         BIT_START_I2C
            ...
            ....
            ...
            GOTO            LOOP_EE

Veo que a pesar de tener configurado el bus a una velocidad superior a 330KHZ al acceder a la memoria aleatoriamente en pantalla veo como el movimiento de las letras se ve alterado, mostrándome como un frenado hasta que termine de leer las direcciones que configure en mi rutina y luego ya es normal, pero es por que ya no hay lectura de la memoria EEprom....supongo que puede ser que hay parte del código que hay que depurar para evitar esto...pero por ahora decidí acceder a la memoria secuencialmente y hago una rutinita donde me detecte un carcater especifico que de por terminada la lectura de la memoria, y según el datasheet de la 24LC256, la dirección queda guardad internamente en un buffer, para cuando accedamos de nuevo seguir en la dirección + 1 y asi hasta la dirección 7FFF que es cuando retorna a la dirección 0000h, para que volviera al inicio decido hacer la rutina de lectura aleatoria de la memoria pero apuntando inicialmente a la dirección 7FFFH y luego leo , y vuelvo a la lectura secuencial, ..Esta es una forma correcta de hacerlo, o pueden existir varias alternativas?

Saludos



« Última modificación: 14 de Mayo de 2009, 23:59:27 por marvicdigital »

Desconectado BrunoF

  • Administrador
  • DsPIC30
  • *******
  • Mensajes: 3865
Re: Una manito por favor
« Respuesta #55 en: 15 de Mayo de 2009, 01:52:02 »
Hola marvic. Me alegro que funcione.

Leerla secuencialmente es una de las mejores maneras. Podrías leer de a varias posiciones x vez también(no recuerdo como se llamaba este modo de acceso).
Con respecto a los NOP que tuviste que agregar...No. Si trabajas más allá de los 2k Words de flash, cuando hagas un call o un goto tenés que tener cuidado con los bits que determinan la pagina a la que queres ir.

Usá PAGESEL también antes de hacer un goto. Ejemplo: PAGESEL LOOP_EE y luego el GOTO LOOP_EE.

Los NOPs se me ocurren que pueden estar funcionando porque justo agregadolos estás evitando que se cruce alguna página del uC.
Habria que ver donde ubica en la memoria flash cada linea(desde el MPLAB esto se hace en el menu View->Disassembly listing una vez que se ha creado con exito el archivo .hex).

Un saludo.
"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 marvicdigital

  • Colaborador
  • PIC18
  • *****
  • Mensajes: 311
Re: Una manito por favor
« Respuesta #56 en: 15 de Mayo de 2009, 08:27:43 »
Hola marvic. Me alegro que funcione.

Leerla secuencialmente es una de las mejores maneras. Podrías leer de a varias posiciones x vez también(no recuerdo como se llamaba este modo de acceso).
Con respecto a los NOP que tuviste que agregar...No. Si trabajas más allá de los 2k Words de flash, cuando hagas un call o un goto tenés que tener cuidado con los bits que determinan la pagina a la que queres ir.

Usá PAGESEL también antes de hacer un goto. Ejemplo: PAGESEL LOOP_EE y luego el GOTO LOOP_EE.

Los NOPs se me ocurren que pueden estar funcionando porque justo agregadolos estás evitando que se cruce alguna página del uC.
Habria que ver donde ubica en la memoria flash cada linea(desde el MPLAB esto se hace en el menu View->Disassembly listing una vez que se ha creado con exito el archivo .hex).

Un saludo.


Gracias , BrunoF, sin tus apreciadas explicaciones y ayudas no hubiera sido posible haberlo hecho tan pronto  :-/ y con respecto a lo de PAGESEL antes de un goto , entonces como se haría en este caso?

Código: [Seleccionar]
           BTFSS        PREGUNTA,1
           GOTO         FALSO
           GOTO         VERDADERO

Porque según lo que entiendo el MPASM hace una selección de página con PAGESEL ...no se si me estoy haciendo un lío... :lol:

Saludos

Edit: Bueno hice la prueba agregando los NOP y sin problema alguno, pero al hacer esto:

Código: [Seleccionar]
BTFSS        PREGUNTA,1
          PAGESEL    FALSO
          GOTO         FALSO
           GOTO         VERDADERO

Simplemente no funciona, es es obvio por eso la conveniencia de agregar un NOP antes de empezar la rutina que estamos llamando con GOTO..aclaro que la memoria en donde está escrito mi ejemplo es en la 2067  :D si..es que debo borrar un montón de pruebas que estoy haciendo para los efectos..vamos basurita, ripio, limaduras o bueno eso que sobra cuando se está armando tiestos  :mrgreen:  (Depurar)

Saludos
« Última modificación: 15 de Mayo de 2009, 09:25:34 por marvicdigital »

Desconectado BrunoF

  • Administrador
  • DsPIC30
  • *******
  • Mensajes: 3865
Re: Una manito por favor
« Respuesta #57 en: 15 de Mayo de 2009, 14:25:59 »
Código: [Seleccionar]
           BTFSS        PREGUNTA,1
           GOTO         FALSO
           GOTO         VERDADERO

Porque según lo que entiendo el MPASM hace una selección de página con PAGESEL ...no se si me estoy haciendo un lío... :lol:

Saludos

No podes en ese caso hacerlo tan sencillo. En un uC como el que estás usando,  hay 4 páginas en la FLASH:
desde la posición 0x0000 hasta la 0x07FF página 0
desde la posición 0x0800 hasta la 0x0FFF página 1
desde la posición 0x1000 hasta la 0x17FF página 2
desde la posición 0x1800 hasta la 0x1FFF página 3

Cuando vos empezás a usar más allá de la página 1, tenés que tener cuidado con la paginación.Esto NO significa que es extremadamente necesario tener que estar constantemente haciendo PAGESEL antes de un CALL o un GOTO. Sólo deberías usarlo cuando sabés que hay un cambio de página. Es decir, por ejemplo, si estás actualmente en la página 1 y querés ir a una subrutina o etiqueta de la página 2. Si la subrutina o etiqueta a la que querés ir se encuentra en la mísma página no hace falta hacer el PAGESEL.

Entonces, lo que se hace para ahorrarse dolores de cabeza y problemas paginando sin sentido o teniendo problemas de cruce de páginas es ésto: se usa la directiva ORG para indicarle al compilador desde dónde comenzarán a ubicarse en la FLASH las líneas de código debajo de ésta(la directiva ORG).

Resumidamente te lo explíco:

          ORG 0x0000     ;indico que ahora empiezo desde pagina 0
Reset
         .......
Interr
         .......
Inicio
         .......

         ORG  0x0800     ;indico que ahora empiezo desde pagina 1
Rutinas_I2C
         .......
         .......
         .......
Otras_Rutinas
         .......
         .......
         .......

         ORG  0x1000     ;indico que ahora empiezo desde pagina 2
Algoritmos_Efectos_Cartel
         .......
         .......
         .......
         .......
         .......
       
         ORG  0x1800     ;indico que ahora empiezo desde pagina 3
Tablas
         .......
         ....... 
         .......
         .......

De esta manera, por ejemplo, puedo asegurarme que, por ejemplo, las "Rutinas_I2C" no necesiten realizar un PAGESEL cuando se llaman entre ellas, ya que están dentro de la mísma página.
Esta es la ventaja de "moduralizar" los grupos importantes de rutinas para evitar problemas y lineas de codigo sin sentido.


Edit: Bueno hice la prueba agregando los NOP y sin problema alguno, pero al hacer esto:

Código: [Seleccionar]
          BTFSS        PREGUNTA,1
          PAGESEL    FALSO
          GOTO         FALSO
           GOTO         VERDADERO

Simplemente no funciona, es es obvio por eso la conveniencia de agregar un NOP antes de empezar la rutina que estamos llamando con GOTO..aclaro que la memoria en donde está escrito mi ejemplo es en la 2067  :D si..es que debo borrar un montón de pruebas que estoy haciendo para los efectos..vamos basurita, ripio, limaduras o bueno eso que sobra cuando se está armando tiestos  :mrgreen:  (Depurar)

Saludos


Hacer:

Código: [Seleccionar]
          BTFSS        PREGUNTA,1
          PAGESEL    FALSO
          GOTO         FALSO
           GOTO         VERDADERO

 termina siendo:
Código: [Seleccionar]
          BTFSS        PREGUNTA,1
          BCF/BSF     PCLATH,3
          BCF/BSF     PCLATH,4
          GOTO         FALSO
           GOTO         VERDADERO

Por lo que en realidad el salto no hace obviamente lo que querés. Ahora, si respetás lo que acabo de explicar arriba de modularizar un poco, podrías directamente no necesitar hacer el PAGESEL si FALSO y VERDADERO se encuentran en la mísma página en la que estás actualmente al querer ir.
Si aún así, si no te encuentras en la mísma página que FALSO y VERDADERO, pero FALSO y VERDADERO se encuentran entre sí ubicadas en la mísma página, podés hacer directamente ésto:


Código: [Seleccionar]
          PAGESEL    FALSO  ;BANKSEL VERDADERO también funcionaría porque sería exáctamente lo mísmo por estar en la mísma página
          BTFSS        PREGUNTA,1
          GOTO         FALSO
           GOTO         VERDADERO
« Última modificación: 15 de Mayo de 2009, 15:12:26 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 BrunoF

  • Administrador
  • DsPIC30
  • *******
  • Mensajes: 3865
Re: Una manito por favor
« Respuesta #58 en: 15 de Mayo de 2009, 14:29:44 »
P.D: Fijate que me hablás de posición 2067. En las posiciones 2047 a 2048 se produce un cambio de página. Probablemente ahí puede que haya problemas. Intentá modularizando como dije.
"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 MLO__

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 4581
Re: Una manito por favor
« Respuesta #59 en: 15 de Mayo de 2009, 16:07:11 »
Hola.

Que pena entrometerme, pero, segun las imagenes que puso Cryn, veo que por matriz de led hay una letra ..... en el codigo que yo hice, dejo un espacio solo de una columna entre letra y letra, pero al maximo que he llegado es a 32 columnas, esto debido a que no hay mas variables mas grandes que int32 ....

Lo que yo hago es cargar las letras una a una segun el mensaje en un arreglo de int32, en mi caso como son 7 filas, sera un arreglo de 7 int32. Luego en otro arreglo de int32 auxiliar voy cargando cada una de las filas y las despliego con el shift_left();.

No he tenido tiempo de arreglar mi matriz a mas leds, queria hacerla -o quiero hacerla de 7x64 al menos- pero ando liado con el espacio!!!!

Que sugerencia me das Bruno?

Saludos
El papel lo aguanta todo