TABLA ADDWF CP ; CONTADOR DE PROGRAMA
RETLW 0E,11,11,11,11,11,11,0E ; EL CERO EN DONDE EL PRIMER HEXADECIMAL ES LA FILA DE ABAJOHola a todos.
Quiero hacerme un pasamensajes , y quiero hacerlo de 8x80, pero claro, como es la primera vez que toco este tema, me puse a investigar, leer PDFs, buscar en los foros, pero me he hecho un lío y quiero estar seguro si entendí la teoría sobre como hacer esto.
Lo primero, es que existen 2 formas básicas de hacerlo, la una es mediante barrido por columnas y la otra barrido por filas; la primera tiene la desventaja de que entre más largo sea el letrero más tiempo lleva el refresco, y para evitar parapadeos se debe aumentar la velocidad del escaneo, y esto se traduce en una disminución de la intensidad del led...por favor si estoy equivocado me corrigen.. :mrgreen:; la otra y que veo que es la mas utilizada es el barrido por Filas, al ser menos cantidad, en mi caso solo 8; se pueden dejar más tiempo encendidos los leds, esto supone un aumento en el brillo de los mismos, pero al mismo tiempo un aumento de consumo de corriente ya que si estuviera encendido todo el cartel tendríamos el consumo de los 80 leds(para mi caso), claro esto es solucionable. Hasta acá voy bien?
Ahora la parte que me tiene más inseguro de si la entendí o no, la parte del software, como uso solo ASM, pues me olvido de ejemplos que he visto en C, que por el camino que voy, me tocará aprenderlo si o si. Algunos ejemplos que he visto de ASM, pues para ser franco, hay momentos donde me pierdo, debe ser por eso que todos los códigos y rutinas que he hecho las hago desde cero, y hasta ahora no he hecho un copy, paste 8).
Bueno a lo básico generar un Cero en la matriz para comenzar, a ver si entendí:
- Lo primero, debo saber como quiero que me muestre el cero la matriz, pues para mi gusto sin los leds de las esquinas, para que se vea algo redondo y no cuadrado.
- Ahora la matriz la tengo asi: cátodos como columnas y los ánodos como filas; un caracter se forma por 8 filas por 5 columnas
- Con la configuración anterior entonces he de suponer que pongo a rotar un 1 por las filas, esta rotación debe ir sincronizada con los datos en las columnas, para el caso del cero sería asi:
De abajo hacia arriba el escaneo de las filas, osea formar el dígito en la matriz desde la fila de abajo
Fila 8 <0>
Fila 7 <0>
Fila 6 <0>
Fila 5 <0>
Fila 4 <0>
Fila 3 <0>
Fila 2 <0>
Fila 1 <1>
5 Columnas <10001> ; sería la parte baja del cero
Siguiente escaneo, rotar el 1 en las filas, eso si, dejo el anterior dato con un tiempo suficiente como para que se vean bien los leds y que no halla parpadeo en el panel.
Fila 8 <0>
Fila 7 <0>
Fila 6 <0>
Fila 5 <0>
Fila 4 <0>
Fila 3 <0>
Fila 2 <1>
Fila 1 <0>
5 Columnas <01110> ;
Y los mismos 5 bits para la columna hasta llegar a la fila 8, donde sería igual a la fila 1...si me he hecho entender?..perdonenme si hay mucha chachara, pero quiero estar seguro si entendí bien o no la teoría.
Ahora, he leido algunas tablas, con los bits que formas cada caracter, pero estas tablas bien organizadas las he visto en C, y yo quiero preguntar si es posible hacer una tabla como la que escribo a continuación para el ejemplo anterior, osea el cero:Código: [Seleccionar]TABLA ADDWF CP ; CONTADOR DE PROGRAMA
RETLW 0E,11,11,11,11,11,11,0E ; EL CERO EN DONDE EL PRIMER HEXADECIMAL ES LA FILA DE ABAJO
He visto algo similar, pero en C, no se si en ASM se pueda hacer lo mismo, por que me gustaría más asi, que escribir linea por linea hasta formar el cero(en mi ejemplo) y también por llevar un orden y hacer modificaciones más fácil.
Eso era todo, cuando comience a hacerlo iré pidiendo más ayuda, como por ejemplo el desplazamiento, agregarle algunos efectos y cositas de esas que uno llega hacer cuando se entiende muy bien esto :-)
Por favor me disculpan todo este texto aburridor, pero quiero que me guíen bien y me corrijan para poder empezar :-)
Saludos
Un cero estaría conformado así:
0 1 1 1 0
1 0 0 0 1
1 0 0 0 1
1 0 0 0 1
1 0 0 0 1
1 0 0 0 1
1 0 0 0 1
0 1 1 1 0
Te conviene declarar al cero de manera vertical. Suponiendo que la fila de más abajo es la fila 1 y le asignamos el bit de menor peso, el cero estaría formado por 5 bytes(al igual que el resto de los símbolos si decides usar 5 columnas de ancho para todos(aunque no lo recomiendo)). Estos bytes serían:
0b01111110
0b10000001
0b10000001
0b10000001
0b01111110
O lo que es lo mísmo, en tabla y en hexadecimal:Código: ASM
TABLA ADDWF PCL, F RETLW 0x7E,0x81,0x81,0x81,0x7E
He diseñado más de 5 modelos de diversas características, y la forma más eficaz es utilizar un buffer para almacenar los datos. En tu caso de 8x80 sería un buffer de 80 bytes. Cada byte representa una columna del cartel. Esto simplifica mucho las operaciones, y optimiza la velocidad de procesado. También te recomiendo que utilices una variable para definir cuál es el primer byte a mostrar de los 80 de manera que si cambias el valor de esa variable, puedas rotar internamente el buffer de manera simple, y lograr efectos de rotaciones de manera sencilla y rápida.
Con respecto al refresco, debería ser por filas. Si bien el consumo en 80 leds asciende a 1.6A, creo que es más que justificable. Una fuente de 12V@2A no es cara.
Cualquier cosa preguntas.
Un saludo.
Por que no me recomiendas usar las 5 columnas para formar los caracteres? , cuál sería la mejor opción, ya que tu tienes más experiencia, un consejo tuyo me serviría mucho :)No te recomiendo que hagas todos los caracteres de 5 columnas. algunos caracteres deberían ocupar más de 5 columnas, como una 'M' o una 'W' y otros menos, como una 'l' o 'i' etc. Lo que queres hacer vos es una tipografía de tipo fixed size, y la verdad que 8 leds en vertical no dan la suficiente resolución como para crear una tipografia fixed decente a mi parecer.
Y otra que no comprendí por que usar 5 Bytes si lo que se quiere hacer es un barrido por filas, no serían 8 bytes? perdoná, si soy algo cabeza dura, pero me perdí en ese punto de tu valiosa respuesta :shock:
Como buffer te refieres a un registro de desplazamiento como el CD4094? puedo usar este para mi cartel? o cuál me recomendarías?
Y como te comenté arriba, me perdí con lo de los bytes por caracter; según lo que entiendo los bytes deberían salir por el puerto que controle las filas, esto seria hacer rotar un cero por todas las 80 columnas y yo entiendo esto como barrido por columnas..no se..me confundo a veces :D
Saludos y mil gracias
Por que no me recomiendas usar las 5 columnas para formar los caracteres? , cuál sería la mejor opción, ya que tu tienes más experiencia, un consejo tuyo me serviría mucho :)No te recomiendo que hagas todos los caracteres de 5 columnas. algunos caracteres deberían ocupar más de 5 columnas, como una 'M' o una 'W' y otros menos, como una 'l' o 'i' etc. Lo que queres hacer vos es una tipografía de tipo fixed size, y la verdad que 8 leds en vertical no dan la suficiente resolución como para crear una tipografia fixed decente a mi parecer.Y otra que no comprendí por que usar 5 Bytes si lo que se quiere hacer es un barrido por filas, no serían 8 bytes? perdoná, si soy algo cabeza dura, pero me perdí en ese punto de tu valiosa respuesta :shock:
El caracter '0' que tomamos como ejemplo es un mal ejemplo, porque si lo miras verás que es completamente simétrico en X e Y. Voy a poner otro ejemplo, con un caracter no simétrico como el: '4'
1 0 0 0 1
1 0 0 0 1
1 0 0 0 1
0 1 1 1 1
0 0 0 0 1
0 0 0 0 1
0 0 0 0 1
0 0 0 0 1
cuyos bytes serían: 0x07, 0x08, 0x08, 0x08, 0xFF.
supongamos ahora que en la pantalla visualizo 5 '4':(y asumo una matriz de 8x30)
1 0 0 0 1 0 1 0 0 0 1 0 1 0 0 0 1 0 1 0 0 0 1 0 1 0 0 0 1 0
1 0 0 0 1 0 1 0 0 0 1 0 1 0 0 0 1 0 1 0 0 0 1 0 1 0 0 0 1 0
1 0 0 0 1 0 1 0 0 0 1 0 1 0 0 0 1 0 1 0 0 0 1 0 1 0 0 0 1 0
0 1 1 1 1 0 0 1 1 1 1 0 0 1 1 1 1 0 0 1 1 1 1 0 0 1 1 1 1 0
0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0
0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0
0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0
0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0
El refresco sería por filas, y sería así:
Primer fila:
1 0 0 0 1 0 1 0 0 0 1 0 1 0 0 0 1 0 1 0 0 0 1 0 1 0 0 0 1 0
luego la segunda:
1 0 0 0 1 0 1 0 0 0 1 0 1 0 0 0 1 0 1 0 0 0 1 0 1 0 0 0 1 0
....
y así sucesivamente las 6 restantes.Como buffer te refieres a un registro de desplazamiento como el CD4094? puedo usar este para mi cartel? o cuál me recomendarías?
Y como te comenté arriba, me perdí con lo de los bytes por caracter; según lo que entiendo los bytes deberían salir por el puerto que controle las filas, esto seria hacer rotar un cero por todas las 80 columnas y yo entiendo esto como barrido por columnas..no se..me confundo a veces :D
Saludos y mil gracias
No, yo me refería aun buffer INTERNO. utilizando RAM del PIC. 80 bytes en tu caso. Los CD4094 son excelentes para esto.
Para mostrar la primer fila de leds, debes enviar a los 4094(encargados de las columnas) la secuencia: 1 0 0 0 1 0 1 0 0 0 1 0 1 0 0 0 1 0 1 0 0 0 1 0 1 0 0 0 1 0
y luego encender el ánodo de la primer fila.
Para enviar cada uno de los bytes de la trama 1 0 0 0 1 0 1 0 0 0 1 0 1 0 0 0 1 0 1 0 0 0 1 0 1 0 0 0 1 0, deberás utilizar una mascara(que será 0x80 para la fila1, 0x40 para la fila 2, 0x20 para la 3, 0x10 para la 4ta, 0x08 para la 5ta...etc) e ir haciendo una AND entre cada byte del buffer y la máscara. Si el resultado da distinto de cero, entonces envías un 1. caso contrario envías un cero(a los 4094).
Las rotaciones deberían realizarse utilizando un buffer interno. No en los 4094...
Saludos.
Hola Marvic.
Tiene que ser en asm? yo he hecho de esos letreritos pero en C. Cualquier cosa me avisas.
Saludos
El caracter '0' que tomamos como ejemplo es un mal ejemplo, porque si lo miras verás que es completamente simétrico en X e Y. Voy a poner otro ejemplo, con un caracter no simétrico como el: '4'
1 0 0 0 1
1 0 0 0 1
1 0 0 0 1
0 1 1 1 1
0 0 0 0 1
0 0 0 0 1
0 0 0 0 1
0 0 0 0 1
cuyos bytes serían: 0x07, 0x08, 0x08, 0x08, 0xFF.
FORMAR_LETRA ;letra A , de 8x6
ADDWF PCL,1
RETLW B'011110'
RETLW B'111111'
RETLW B'110011'
RETLW B'110011'
RETLW B'111111'
RETLW B'110011'
RETLW B'110011'
RETLW B'110011'
FORMAR_LETRA ;letra A , de 8x6
ADDWF PCL,1
RETLW B'11111110'
RETLW B'11111111'
RETLW B'00010011'
RETLW B'00010011'
RETLW B'11111111'
RETLW B'11111110'
Es asi maestro ? :g) me disculpas si te llamo maestro pero en mi país toda persona que comparte sus sabios conocimientos y nos enseña algo mas le llamamos asi como una forma de aprecio, reconocimiento y de que está por encima de nosotros en cultura..en este caso en como hacer los publik :-).
Una última cosa, la otra vez tuve un programa en donde podía crear los caracteres para las matrices de 8x8 o cualquier otro tamaño, y te daba el resultado en hexadecimal por columnas o filas para formar dicho caracter, el problema es que no recuerdo el nombre el programa y mucho menos en donde ubicarlo..si alguien sabe de esto, pues le agradecería mucho su valiosa información.
Claro! Es así. La AND enmascara los bits para ver si tienes que inyectar un 1 o un 0 a los 4094. Por eso si tienes 80 columnas esto se hace 80 veces. También se podría hacer horizontal como tu hacías al principio, pero fijate que desperdicias 2bits por cada fila, quiere decir que en esa laetra ya has desperdiciado 2 bytes. Imaginate en más letras...
Los 80 registros son exactamente los 8x80 leds. Los almacenas como bits. Un bit = 1 led. Entonces tu solo mandas a los 4094 lo que haya en estos 80 bytes(registros). Esto es un BUFFER, porque almacenas los datos temporalmente allí. Hacerlo con un buffer te permite que te despreocupes por la parte de salida a pantalla. Cuando tu modifiques un bit del buffer, como la salida lee el buffer, lo mostrará a la hora de refrescarse en pantalla.
Si lo quieres hacer realmente bien, en mis programas yo uso lo que se llama "double buffering" y esto sería agregar otro buffer más(80 registros).
Entonces, vas alternando de buffer. Usas uno(es decir, lo muestras en los 4094) y mientras trabajas(modificas los valores de los leds(bits)) en el otro para el próximo cuadro. Una vez que terminaste de modificarlo, indicas que usarás el otro buffer, y comienzas a trabajar en el otro nuevamente para luego volver a intercalarlos.
Entonces, por un lado tienes que hacer una rutina con un tiempo base(usando un timer seria lo mejor). Cuando ocurra la interrupcion del timer, refrescas la próxima fila.
Un double buffer no se justifica si todas las operaciones que piensas hacer, como rotaciones horizontales, verticales o cualquier otra no llevan más tiempo que el del timer. Esto quiere decir que un buffer doble no es estrictamente necesario si tu algoritmo siempre logra modificar el buffer entre dos refrescos de filas del programa.
Otra cosa más: Si usás un sólo buffer y tus modificaciones se hacen entre el refresco de dos filas, asegurate que sea inmediatamente luego de refrescar la última(fila) y antes de comenzar la primera(fila) nuevamente.
Si usas double buffer, alterná los buffer después de refrescar la ultima fila.
Esto se hace para no mezclar los cuadros. Si no lo hacés y:
*Sin usar doble buffer, tu rutina de modificacion necesita mas tiempo que el tiempo entre refrescos de fila;
*O si bien lográs hacer las modifcaciones entre refrescos de filas pero no lo hacés después de refrescar la última fila y antes de refrescar la primera;
*O bien usando doble buffer intercalás buffer en un momento distinto al de después de refrescar la última fila y antes de la primera;
vas a obtener una visualización distorcionada, como el siguiente ejemplo que te pongo sería ante una rotación a la izquierda:
(http://www.todopic.com.ar/foros/index.php?action=dlattach;topic=25723.0;attach=9047)
Así que a tener cuidado con esas cosas.
ROTAR_IZQUIERDA
MOVF COL31,W
MOVWF COL32
MOVF COL30,W
MOVWF COL31
MOVF COL29,W
MOVWF COL30
MOVF COL28,W
MOVWF COL29
MOVF COL27,W
MOVWF COL28
MOVF COL26,W
MOVWF COL27Y asi hasta la primera columna.Bueno, hoy al principio del hilo creo que te dije que deberías reservar 80 bytes de memoria consecutivos. Resultaría de importancia saber qué pic estás usando, ya que depende mucho del pic utilizado la distribución de memoria RAM del buffer.
Yo te lo voy a explicar como para un 16F877A y utilizando el banco1 del pic para el buffer, por lo que el buffer abarcaría desde la posición 0xA0 a la 0xEF inclusive(intervalo [0xA0;0xEF]).
El registro FSR permite direccionar indirectamente 256 posiciones RAM del PIC.Como estos PICs tienen más de 256 posiciones de memoria, el registro FSR tiene un noveno bit, que selecciona entre los bancos 0-1 o 2-3 de la memoria. Para verlo mas facil, la direccion a la que apunta el registro está conformada por:
bit8 bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0
STATUS,IRP FSR,7 FSR,6 FSR,5 FSR,4 FSR,3 FSR,2 FSR,1 FSR,0
Esto significa que, para acceder a los banco 0-1 debemos asegurar el bit STATUS,IRP a 0. Luego accederemos a los registros de dichos bancos usando solo el FSR.
El programa no es dificil. Para rotar de izq a der usando direccionamiento indirecto deberías hacer:
Código: ASM
#define inicio_buffer 0xA0 #define tamanio_buffer .80
Y la función:Código: ASM
if tamanio_buffer<2 error "El buffer es demasiado pequeño!!!!" movlw inicio_buffer + tamanio_buffer - 2 ;en mi caso sería 0xA0 + .80 - 2 = 0x7E movwf FSR otra_rot_der movf INDF,W incf FSR,F movwf INDF decf FSR,F decf FSR,F movlw inicio_buffer-1 xorwf FSR,W btfss STATUS,Z goto otra_rot_der incf FSR,F clrf INDF ;listo
Para rotar a la izquierda, el algoritmo es un poco mas sencillo y similar al anterior, solo que recorres de izquierda a derecha el buffer.
Saludos
ROTAR_IZQUIERDA
MOVLW COL31
MOVWF FSR
OTRA_ROT_IZQ
MOVF INDF,W
INCF FSR,F
MOVWF INDF
DECF FSR,F
DECF FSR,F
MOVLW COL1-1
XORWF FSR,W
BTFSS STATUS,Z
GOTO OTRA_ROT_IZQ
RETURN Santo Dios!..en serio este texto tuyo enseñándome a usar el FSR e INDF más allá de lo que uno encuentra en los datasheets es sublime..de verdad que estoy muy agradecido contigo, ojala estuviera en tu país y te invitaba a un buen Whisky, ese montón de lineas que describía arriba quedaron resumidas en esto:Código: [Seleccionar]ROTAR_IZQUIERDA
MOVLW COL31
MOVWF FSR
OTRA_ROT_IZQ
MOVF INDF,W
INCF FSR,F
MOVWF INDF
DECF FSR,F
DECF FSR,F
MOVLW COL1-1
XORWF FSR,W
BTFSS STATUS,Z
GOTO OTRA_ROT_IZQ
RETURN
Pasar de 160 lineas de código a solo 12, es que aún no me la creo..de verdad que muchas gracias, y ahora aprendí algo más usar MOVLW COL-1 es que para mi eso es nuevo, en los tutoriales sobre ASM, para PIC no he visto hacer eso, por eso me limito mucho a la hora de hacer un código;
si me puedes decir algún libro o web que tenga todos esos truquitos, o información bien completa sobre ASM te lo agradecería ..claro si me sigues perdonando el ser tan abusivo :mrgreen:...de verdad muchas gracias...y no use el <if tamaño_del_buffer <2 error.... por que para ser franco tampoco sabía que se podía hacer eso..de verdad estoy muy contento de aprender esto hoy, más allá de que ahora tenga el cartel corriendo de derecha a izquierda me tiene más contento lo primero :-) :-) :-) :-) :-) :mrgreen:
Ahh quiero aclarar que por ahora uso solo 32 columnas, mientras aprendo, pero esta semana le sumo las otras columnas, y estoy usando el PIC16F877A..que adivinaste, se que puede ser muy grande pero como quiero implementar teclado de PC, RS232, RTC, memoria 24LC256 y que tenga varios efectos pues la memoria fue la que me llamó la atención :g).
Otra anotación es que a cada letra le estoy poniendo al final de los hexadecimales que la forman el 000H y asi poder avisar cuando se debe cargar el próximo caracter y a eso le sumamos que nos queda con una columna de espacio entre caracteres, no se si esa sea una buena forma ya que al ver letras como la M o la W que se llevan más columnas o la I pues es una buena forma de ahorrar columnas...o se puede hacer de otra forma mucho más técnica?..
hola
solo queria comentar que yo ya e realizado lo que quiere marvic
http://micros.mforos.com/1149907/8023880-desarrollo-panel-90x8-16f877a-24lc256-ds1307-con-usb/
espero que le sirva como referencia para hacer su panel
SAludos :mrgreen:
Hola Bruno, un pregunta...
el buffer de 80bits de este ejemplo se modifica según los datos de cada fila, cierto?
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.
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.
hola
solo queria comentar que yo ya e realizado lo que quiere marvic
http://micros.mforos.com/1149907/8023880-desarrollo-panel-90x8-16f877a-24lc256-ds1307-con-usb/
espero que le sirva como referencia para hacer su panel
SAludos :mrgreen:
INICIO
BSF STATUS,RP0
CLRF TRISC
CLRF TRISB
CLRF OPTION_REG
BCF STATUS,RP0
;BCF STATUS,IRP
LOOP_INICIO
MOVLW 0FFH
MOVWF PORTB
BCF LOAD ;LOAD DE EL CD4094
MOVLW .32
MOVWF COLUMNAS
MOVLW COL1
MOVWF FSR
CEROS_COLUMNAS ;BORRO TODAS LAS COLUMNAS PARA EMPEZAR LIMPIA LA PANTALLA
CLRF INDF
DECFSZ COLUMNAS
GOTO SEGUIR_BORRANDO
GOTO SIGUIENTE_FASE
SEGUIR_BORRANDO
INCF FSR,1
GOTO CEROS_COLUMNAS
SIGUIENTE_FASE
CLRF LETRA
MOVF LETRA,W
CALL A ;tabla para la letra A
MOVWF COL1
METER_COLUMNAS
CALL PANTALLAZO ;MUESTRA EN PANTALLA VARIAS VECES LA MISMA COLUMNA
CALL ROTAR_IZQUIERDA ;ANTES DE DESPLAZARLALA Y ASI DARLE VELOCIDAD AL DESPLAZAMIENTO
INCF LETRA
MOVF LETRA,W
CALL A ;SIGUIENTE VALOR HEXADECIMAL DE LA LETRA A
MOVWF COL1 ;CARGO COL1 CON EL NUEVO VALOR HEXADECIMAL
XORLW 000H ;MIRO SI YA TERMINO LOS VALORES QUE FORMAN LA LETRA
BTFSS STATUS,Z
GOTO METER_COLUMNAS ; SI NO VOY A MOSTRAR COL1 CON EL NUEVO VALOR
CALL ESPACIOS_BLANCO ;SI TERMINO DE LEER LA LETRA A, ENTONCES LLENO DE ESPACIOS PARA QUE
GOTO SIGUIENTE_FASE ;SEA VEA EFECTO DE DESPLAZAMIENTO. SOLO A MODO DE PRUEBA
A ADDWF PCL,1 ;letra A , de 8x6
RETLW B'11111110'
RETLW B'11111111'
RETLW B'00010011'
RETLW B'00010011'
RETLW B'11111111'
RETLW B'11111110'
RETLW 000H
INCLUDE CD4094.INC
INCLUDE RETARDOS.INC
ENDCódigo: [Seleccionar]INICIO
BSF STATUS,RP0
CLRF TRISC
CLRF TRISB
CLRF OPTION_REG
BCF STATUS,RP0
;BCF STATUS,IRP
LOOP_INICIO
MOVLW 0FFH
MOVWF PORTB
BCF LOAD ;LOAD DE EL CD4094
MOVLW .32
MOVWF COLUMNAS
MOVLW COL1
MOVWF FSR
CEROS_COLUMNAS ;BORRO TODAS LAS COLUMNAS PARA EMPEZAR LIMPIA LA PANTALLA
CLRF INDF
DECFSZ COLUMNAS
GOTO SEGUIR_BORRANDO
GOTO SIGUIENTE_FASE
SEGUIR_BORRANDO
INCF FSR,1
GOTO CEROS_COLUMNAS
SIGUIENTE_FASE
CLRF LETRA
MOVF LETRA,W
CALL A ;tabla para la letra A
MOVWF COL1
METER_COLUMNAS
CALL PANTALLAZO ;MUESTRA EN PANTALLA VARIAS VECES LA MISMA COLUMNA
CALL ROTAR_IZQUIERDA ;ANTES DE DESPLAZARLALA Y ASI DARLE VELOCIDAD AL DESPLAZAMIENTO
INCF LETRA
MOVF LETRA,W
CALL A ;SIGUIENTE VALOR HEXADECIMAL DE LA LETRA A
MOVWF COL1 ;CARGO COL1 CON EL NUEVO VALOR HEXADECIMAL
XORLW 000H ;MIRO SI YA TERMINO LOS VALORES QUE FORMAN LA LETRA
BTFSS STATUS,Z
GOTO METER_COLUMNAS ; SI NO VOY A MOSTRAR COL1 CON EL NUEVO VALOR
CALL ESPACIOS_BLANCO ;SI TERMINO DE LEER LA LETRA A, ENTONCES LLENO DE ESPACIOS PARA QUE
GOTO SIGUIENTE_FASE ;SEA VEA EFECTO DE DESPLAZAMIENTO. SOLO A MODO DE PRUEBA
A ADDWF PCL,1 ;letra A , de 8x6
RETLW B'11111110'
RETLW B'11111111'
RETLW B'00010011'
RETLW B'00010011'
RETLW B'11111111'
RETLW B'11111110'
RETLW 000H
INCLUDE CD4094.INC
INCLUDE RETARDOS.INC
END
If the program memory size is less than
2K-words, then the above precaution is
not necessary.
El usuario no debe preocuparse por precargar el PCLATH en dos sitaciones:
Si el uC no posee más de 2kWords de memoria Flash;
O si en el código creado por el usuario, no se utiliza la memoria FLASH más allá de la posición 2047(0x7FF).
PAGESEL PANTALLAZO
CALL PANTALLAZOPAGESELW A
MOVF LETRA,W
CALL A ;Tabla que forma la letra A
MOVWF COL1Pero al leer el espectacular tutorial de ASM desde cero de LEON_PIC dice lo siguiente:CitarEl usuario no debe preocuparse por precargar el PCLATH en dos sitaciones:
Si el uC no posee más de 2kWords de memoria Flash;
O si en el código creado por el usuario, no se utiliza la memoria FLASH más allá de la posición 2047(0x7FF).
La diferencia entre ambos es si el uC no posee más de 2k Words, y como este PIC16f877A tiene 8k pues tome las precauciones del caso y puse lo siguiente antes de cada Call Rutina :Código: [Seleccionar]PAGESEL PANTALLAZO
CALL PANTALLAZO
Se que la rutina está en la primera página y que al ejecutar RETURN el PCLATH queda con esa página grabada, le puse el PAGESEL antes de cada CALL por seguridad y a pesar de que no me he pasado del primer banco de la memoria Flash me seguía dando el problema y me tocó hacer lo siguiente antes de llamar la Tabla A:Código: [Seleccionar]PAGESELW A
MOVF LETRA,W
CALL A ;Tabla que forma la letra A
MOVWF COL1
Y así resolví mi problema de reinicio y ya veo los caracteres moverse de izquierda a derecha sin problema.
Ojala le sirva a todos los que puedan tener el mismo problema, y el consejo que doy es asegurar esos registros que al reiniciar sus bits puedan tomar cualquier valor asegurarlos con escribirle el valor que necesitan para su funcionamiento, y leer el una y otra vez el espectacular tutorial de LEONPIC :-)
Ahora a seguir..ya tengo texto corriendo, vamos lo básico, ahora me queda implementar las tablas completas para los caracteres y lo voy hacer mediante código ASCII, osea leo la memoria en donde tengo guardado el valor ASCII para cada caracter y ese valor es el que llamo para que me genere el caracter, con tanta memoria disponible :mrgreen:
Saludos
LEER_EEPROM
MOVF DATO,W ;MUEVO EL DATO DE LA EEPROM A W PRIMERA LETRA 66(B)
MOVWF ASCII
CALL CARACTER_ASCII ;ES EN ESTE PUNTO DONDE TENGO LA DUDA, SE PUEDE HACER ALGO PARECIDO?
Hola. No, lo que pretendés hacer no es posible ni en ASM ni en ningún lenguaje de programación con los que he trabajado. No podés variar en tiempo de ejecución el nombre de la etiqueta a llamar de la manera que exponés.
Podés hacer una tabla que conduzca a otra tabla.
Como no vi esto en el foro y por ahí le sirve a muchos, he posteado la solución aquí: Ejemplos en Assembler - PIC16F876 (http://www.todopic.com.ar/foros/index.php?topic=12918.msg211575#msg211575) porque puede servirle a otros.
El algoritmo puede resultar dificil, pero no puedo simplificarlo mucho mas que eso sin tener que despilfarrar más ROM.
Un saludo.
Muy chulo Marvic.
Que LEDs usaste? chorro o normal? La fuente de los LEDs es por aparte o dejaste los mismos 5v?
20k!!!!
Que tamaño tienen?
La verdad que te ha quedado "belisísima"!!!
Te felicito muchísimo. Y la verdad que ha sido un honor explicarte, porque has aprendido rápido y te has preocupado por entenderlo y dedicarle tiempo..
Con respecto a la memoria, si estás usando codigo ASCII para almacenar los datos, sí, podés ir guardando caracter x caracter y luego ir leyendolos. Yo personalmente prefiero hacer un buffer más, para ir leyendo la memoria e ir volcando al buffer en el PIC, como para siempre tener datos rapido sin peligros de tener que esperar al I2C o algo.
Mi primer cartel tenía 2 buffers para visualizar, y un tercer buffer para ir leyendo y tomando los datos de la I2C.
He hecho un ejemplo para la 24LC256 acá en el foro. Buscalo en el almacen del assembler, o bien entrando a mi perfil y buscando los temas creados por mi(esta mal, dice mostrar los ultimos IR o algo asi)
Un saludo y felicitaciones!
Y si, ya había leído el post donde está el ejemplo del I2C...ahora mi pregunta es , si en el mismo bus puedo poner el RTC y la memoria 24LC256, es que recuerdo haber leído qeu solo se podía poner una de estas en un bus, pero no se si se podrá conectar adicional con un DS1307...y de nuevo mil gracias por tus ejemplos y compartirlos con todos..
Y hablando de compartir, hice una tabla en excel para crear caracteres y otras cositas más en una matrix de 8x8, cuando seleccionas los puntos que formaran el caracter o el gráfico y le pones 1 para indicar que encienden y el solo te genera la cadena de hex para que se agregue a los RETLW o DT
...
Los hex que genera son de las columnas y la primera fila es el bit más bajo, si a alguien le interesa lo subo y si quieren que le agregue algo más me pueden decir y cuando tenga un tiempito lo hago y lo subo.
LEER_EEPROM
CLRF HADDEEPROM
CLRF LADDEEPROM
LOOP_EE
CLRF IC2DATA ;BUFFER 1
CLRF PALABRA ;BUFFER 2 QUE ES EL LEE LA RUTINA DE PANTALLA
PAGESELW CONFIG_TRANSMISION_I2C
CALL CONFIG_TRANSMISION_I2C
PAGESELW BIT_START_I2C
CALL BIT_START_I2C
MOVLW B'10100000' ;BYTE CONTROL
PAGESELW TRANSMITIR_DATO_I2C
CALL TRANSMITIR_DATO_I2C
PAGESELW I2C_SENDACK
CALL I2C_SENDACK
MOVF HADDEEPROM,W ;DIRECCION ALTA
PAGESELW TRANSMITIR_DATO_I2C
CALL TRANSMITIR_DATO_I2C
PAGESELW I2C_SENDACK
CALL I2C_SENDACK
MOVF LADDEEPROM,W
PAGESELW TRANSMITIR_DATO_I2C
CALL TRANSMITIR_DATO_I2C
PAGESELW I2C_SENDACK
CALL I2C_SENDACK
PAGESELW RESTART_I2C
CALL RESTART_I2C
PAGESELW BIT_START_I2C
CALL BIT_START_I2C
MOVLW B'10100001' ;ENVÍO EL CONTROL BYTE PERO CON 1
PAGESELW TRANSMITIR_DATO_I2C
CALL TRANSMITIR_DATO_I2C
PAGESELW I2C_SENDACK
CALL I2C_SENDACK
PAGESELW RECIBIR_DATO_I2C
CALL RECIBIR_DATO_I2C
PAGESELW BIT_STOP_I2C
CALL BIT_STOP_I2C
MOVF IC2DATA,W
;MOVLW .65 ;para hacer pruebas retiro el ";" y funciona bien
MOVWF PALABRA ;con el valor constante .65
MOVLW .32 ;esta resta es para la tabla con los hex en ascii
SUBWF PALABRA,F
NOP
PAGESELW SIGUIENTE_FASE
CALL SIGUIENTE_FASE ;siguiente fase es el bloque donde muestro PALABRA en pantalla
PAGESELW ESPACIOS_BLANCO
CALL ESPACIOS_BLANCO ;luego de mostrar la letra A le sumo espacios en blanco a la derecha
GOTO LEER_EEPROM
INCLUDE I2C.INCCONFIG_TRANSMISION_I2C
BSF STATUS,RP0 ; SELECIONO LA PAGINA 1 DE LA MEMORIA
BSF TRISC,4
BSF TRISC,3
MOVLW .2
MOVWF SSPADD ; CARGAS 02H EN EL REGISTRO SSPADD LA VELOCIDAD DE
CLRF SSPSTAT ;TRANSMISION SERA DE 333 KHZ con 4MHZ en el X-tal
BCF STATUS,RP0 ; SELECIONO LA PAGINA 0 DE LA MEMORIA
MOVLW B'00101000'
MOVWF SSPCON ; PERMITES LA CONFIGURACION SERIE DE LOS PINES SDA Y SCL.
CLRF PIR1
PAGESELW I2C_IDLE
CALL I2C_IDLE
RETURN
BIT_START_I2C
PAGESELW I2C_IDLE
CALL I2C_IDLE
BSF STATUS,RP0 ; SELECIONO LA PAGINA 1 DE LA MEMORIA
BSF SSPCON2,SEN
BTFSC SSPCON2,SEN
GOTO $-1 ; LANZAMOS EL BIT DE START.
BCF STATUS,RP0 ; SELECIONO LA PAGINA 0 DE LA MEMORIA
BTFSS PIR1,SSPIF
GOTO $-1
BCF PIR1,SSPIF
RETURN
TRANSMITIR_DATO_I2C
MOVWF IC2DATA
BCF FLAGEE,0
;PAGESELW I2C_IDLE
CALL I2C_IDLE
MOVF IC2DATA,W
MOVWF SSPBUF ; TRANSMITIMOS EL DATO AL ESCLAVO
BSF STATUS,RP0 ;BANCO 1
BTFSC SSPSTAT,R_W ;ESPERAR A QUE TERMINE EL ENVIO
GOTO $-1
BTFSS SSPCON2,ACKSTAT ;CHECKEAR ACK
GOTO OKACK
BSF SSPCON2,PEN ;ERROR ACK. ENVIAR STOP
BCF STATUS,RP0 ;BANCO 0
RETURN ;VOLVER CON FLAG= 0 ERROR
OKACK
BCF STATUS,RP0 ;BANCO 0
BTFSS PIR1,SSPIF ;ESPERAR FINALIZACION DEL NOVENO CLOCK
GOTO $-1
BCF PIR1,SSPIF
BSF FLAGEE,0
RETURN
RECIBIR_DATO_I2C
PAGESELW I2C_IDLE
CALL I2C_IDLE
BCF PIR1,SSPIF
BSF STATUS,RP0 ; SELECIONO LA PAGINA 1 DE LA MEMORIA
BSF SSPCON2,RCEN
BTFSC SSPCON2,RCEN
GOTO $-1
BTFSS SSPSTAT,BF ;PERMITO LA RECEPCION DE DATOS
GOTO $-1
BCF STATUS,RP0 ; SELECIONO LA PAGINA 0 DE LA MEMORIA
MOVF SSPBUF,W
MOVWF IC2DATA
RETURN
BIT_STOP_I2C
BSF STATUS,RP0 ; SELECIONO LA PAGINA 1 DE LA MEMORIA
BSF SSPCON2,PEN
BCF STATUS,RP0 ; SELECIONO LA PAGINA 0 DE LA MEMORIA
RETURN
RESTART_I2C
BSF STATUS,RP0
BSF SSPCON2,RSEN
BTFSC SSPCON2,RSEN
GOTO $-1
BCF STATUS,RP0
VOLVER
RETURN
I2C_IDLE
BSF STATUS,RP0 ;BANCO 1
BTFSC SSPSTAT,R_W
GOTO $-1
MOVF SSPCON2,W
ANDLW 0X1F
BTFSS STATUS,Z
GOTO $-3
BCF STATUS,RP0 ;BANCO 0
RETURN
I2C_SENDACK
BSF STATUS,RP0 ;BANCO 1
BCF SSPCON2,ACKDT
BSF SSPCON2,ACKEN
BCF STATUS,RP0 ;BANCO 0
RETURN
I2C_SENDNACK
BSF STATUS,RP0 ;BANCO 1
BSF SSPCON2,ACKDT
BSF SSPCON2,ACKEN
BCF STATUS,RP0 ;BANCO 0
RETURNHola.
No entré en detalle en el código, pero si mal no recuerdo y por lo que estoy mirando(nuevamente) en el gráfico que posteas, los ACK y NACK son enviados por la memoria, no por el uC. Si estás mandandolos vos, estás pegandole una linda mareada al bus IC2.
Saludos.
LEER_EEPROM
PAGESELW CONFIG_TRANSMISION_I2C
CALL CONFIG_TRANSMISION_I2C
CLRF HADDEEPROM ;DIRECCIÓN Y LECTURA DE LA MEMORIA EEPROM
CLRF LADDEEPROM
LOOP_EE
CLRF IC2DATA
CLRF PALABRA
PAGESELW BIT_START_I2C
CALL BIT_START_I2C
MOVLW B'10100000'
PAGESELW TRANSMITIR_DATO_I2C
CALL TRANSMITIR_DATO_I2C
MOVF HADDEEPROM,W
PAGESELW TRANSMITIR_DATO_I2C
CALL TRANSMITIR_DATO_I2C
MOVF LADDEEPROM,W
PAGESELW TRANSMITIR_DATO_I2C
CALL TRANSMITIR_DATO_I2C
PAGESEL RESTART_I2C
CALL RESTART_I2C
MOVLW B'10100001'
PAGESELW TRANSMITIR_DATO_I2C
CALL TRANSMITIR_DATO_I2C
PAGESELW RECIBIR_DATO_I2C
CALL RECIBIR_DATO_I2C
CALL I2C_SENDNACK
CALL BIT_STOP_I2C
MOVF IC2DATA,W ;EL IC2DATA NO RETORNA CON EL VALOR DE LA PRIMERA MEMORIA
;MOVLW .65 ;SI HABILITO ESTA LINEA ME MUESTRA EL CARACTER A LA PANTALLA
MOVWF PALABRA ;UNA Y OTRA VEZ, CADA VEZ QUE PASA POR ACÁ
MOVLW .32
SUBWF PALABRA,F
NOP
PAGESELW SIGUIENTE_FASE
CALL SIGUIENTE_FASE ;RUTINA DE MUESTRA DE PANTALLA
PAGESELW ESPACIOS_BLANCO
CALL ESPACIOS_BLANCO ;ROTA EL CARACTER HASTA DESAPARECER DE LA PANTALLA
GOTO LOOP_EE ;VUELVO A MOSTRAR CONFIG_TRANSMISION_I2C
MOVLW B'00101000'
MOVWF SSPCON
BSF STATUS,RP0 ; SELECIONO LA PAGINA 1 DE LA MEMORIA
BSF TRISC,4
BSF TRISC,3
MOVLW .9
MOVWF SSPADD ; CARGAS 02H EN EL REGISTRO SSPADD LA VELOCIDAD DE
CLRF SSPSTAT ;TRANSMISION SERA DE 333 KHZ
BCF STATUS,RP0 ; SELECIONO LA PAGINA 0 DE LA MEMORIA
CLRF PIR1
PAGESEL I2C_IDLE
CALL I2C_IDLE
RETURN ; PERMITES LA CONFIGURACION SERIE DE LOS PINES SDA Y SCL.
BIT_START_I2C
PAGESEL I2C_IDLE
CALL I2C_IDLE
BSF STATUS,RP0 ;BANCO 1
BSF SSPCON2,SEN
BTFSC SSPCON2,SEN
GOTO $-1
BCF STATUS,RP0 ;BANCO 0
BTFSS PIR1,SSPIF
GOTO $-1
BCF PIR1,SSPIF
RETURN
TRANSMITIR_DATO_I2C
BCF FLAGEE,0
PAGESEL I2C_IDLE ;INICIALIZAR FLAG COMO "ERROR"
CALL I2C_IDLE
MOVF IC2DATA,W ;MOVER DATO A W
MOVWF SSPBUF ;CARGAR DATO EN BUFFER I2C
BSF STATUS,RP0 ;BANCO 1
BTFSC SSPSTAT,R_W ;ESPERAR A QUE TERMINE EL ENVIO
GOTO $-1
BTFSS SSPCON2,ACKSTAT ;CHECKEAR ACK
GOTO OKACK
BSF SSPCON2,PEN ;ERROR ACK. ENVIAR STOP
BCF STATUS,RP0 ;BANCO 0
RETURN ;VOLVER CON FLAG= 0 ERROR
OKACK
BCF STATUS,RP0 ;BANCO 0
BTFSS PIR1,SSPIF ;ESPERAR FINALIZACION DEL NOVENO CLOCK
GOTO $-1
BCF PIR1,SSPIF
BSF FLAGEE,0 ;VOLVER CON FLAG = 1 OK!
RETURN ;VOLVER CON FLAG= 0 ERROR
RECIBIR_DATO_I2C
PAGESEL I2C_IDLE
CALL I2C_IDLE
BSF STATUS,RP0 ;BANCO 1
BSF SSPCON2,RCEN ;ACTIVAR MODO LECTURA
BTFSC SSPCON2,RCEN ;TERMINO LA RECEPCION?
GOTO $-1 ;NO, ESPERAR
BTFSS SSPSTAT,BF ;DATO DISPONIBLE EN SSPBUF PARA SER LEIDOS?
GOTO $-1 ;NO, ESPERAR
BCF STATUS,RP0 ;BANCO 0
MOVF SSPBUF,W
MOVWF IC2DATA
RETURN
BIT_STOP_I2C
BSF STATUS,RP0 ; SELECIONO LA PAGINA 1 DE LA MEMORIA
BSF SSPCON2,PEN
BCF STATUS,RP0
RETURN ; SELECIONO LA PAGINA 0 DE LA MEMORIA
RESTART_I2C
BSF STATUS,RP0
BSF SSPCON2,RSEN
BTFSC SSPCON2,RSEN
GOTO $-1
BCF STATUS,RP0
VOLVER RETURN
I2C_IDLE
BSF STATUS,RP0 ;BANCO 1
BTFSC SSPSTAT,R_W
GOTO $-1
MOVF SSPCON2,W
ANDLW 0X1F
BTFSS STATUS,Z
GOTO $-3
BCF STATUS,RP0 ;BANCO 0
RETURN
I2C_SENDACK
BSF STATUS,RP0 ;BANCO 1
BCF SSPCON2,ACKDT
BSF SSPCON2,ACKEN
BCF STATUS,RP0 ;BANCO 0
RETURN
I2C_SENDNACK
BSF STATUS,RP0 ;BANCO 1
BSF SSPCON2,ACKDT
BSF SSPCON2,ACKEN
BCF STATUS,RP0 ;BANCO 0
RETURNHola. Los PAGESELW son MACROs que utilizan el registro de trabajo(W). Te está ensuciando los datos. Cambiá los PAGESELW por PAGESEL en tu rutina.
Saludos.
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
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
ENDCP.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
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.
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
(http://glenclous.files.wordpress.com/2008/12/nelson-simpsons.jpg)
Saludos.
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_I2CTRANSMITIR_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 1LOOP_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_EELOOP_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_EEHola 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.
BTFSS PREGUNTA,1
GOTO FALSO
GOTO VERDADEROBTFSS PREGUNTA,1
PAGESEL FALSO
GOTO FALSO
GOTO VERDADEROCó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
BTFSS PREGUNTA,1
PAGESEL FALSO
GOTO FALSO
GOTO VERDADERO BTFSS PREGUNTA,1
BCF/BSF PCLATH,3
BCF/BSF PCLATH,4
GOTO FALSO
GOTO VERDADERO 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
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
Código: ASM
org 0x05h comienza en la posición 005h de la memoria flash goto inicio ..... ........ .. . INICIO pagesel retardo call retardo PAGESEL INICIO BTFSS registro,4 goto inicio pagesel banco3 call banco3 ... .. .. .. org 0x0100 retardo pagesel retardo retardo_loop decfsz...... ..... ......... return
hola marvicdigital, que buenas rutinas, gracias
aprovechando que usas dos dispositivos I2C, cuando quieres leer la hora que dirección mandas? y para la memoria?
en la memoria se puede cambiar la dirección con los pines de A0 A1 A2??
saludos
Ehh...No se si está en el hilo..
Pero, la programo en real time:Código: ASM
;Envio de un byte. LSB a MSB. Recibe byte a enviar SEND_BYTE_4094_LSB_FIRST mowf TEMP movlw .8 movwf CONT LOOP_LSB rrf TEMP,F bcf DATA btfsc STATUS,C bsf DATA bsf CLOCK bcf CLOCK decfsz CONT,F goto LOOP_LSB ;falta pulso strobe si queres efectivizar cambios return ;Envio de un byte. MSB a LSB. Recibe byte a enviar SEND_BYTE_4094_MSB_FIRST movwf TEMP ;estaba como mowf.. movlw .8 movwf CONT LOOP_MSB rlf TEMP,F bcf DATA btfsc STATUS,C bsf DATA bsf CLOCK bcf CLOCK decfsz CONT,F goto LOOP_MSB ;falta pulso strobe si queres efectivizar cambios return ;Envio de un bit por columna. ;Recorre indirectamente el buffer de columnas ;Recibe mascara a aplicar(fila actual) ;Ej. 0x01 para fila 1, 0x02 para fila 2, 0x04 para fila 3... SEND_BIT_PER_COL movwf MASC movlw COL1 movwf FSR LOOP_BPC bcf DATA movf INDF,W andwf MASC,W btfss STATUS,Z bsf DATA bsf CLOCK bcf CLOCK incf FSR,F movf FSR,W xorlw COL80+1 ;o la direccion RAM de la ultima columna ;(cuidado si dir COL80==0xFF) btfss STATUS,Z goto LOOP_BCP bsf STROBE bcf STROBE return
si, así lo hacía yo, colocando una letra por matriz.
Pero con la pequeña charla que me dio Bruno manejaré de otra manera los datos, para hacerlo con punteros, pues me ha convencido que es la mejor manera para poder lograr varios efectos y hacerlos de la manera más sencilla posible.
podrías usar entonces dos int32 y tu cartel llegará a 64 columnas :mrgreen: y al rotar el carrie excesivo pasa a la cola del otro byte y el carrie de ese byte al primero, pero Bruno te dirá que mejor guardes los datos por columnas uses un buffer y en estos ordenes de una manera diferente los datos recibidos, pues todos los últimos bits de los bytes de tu buffer serán la primera fila, del cartel, todos los bits6 serán la segunda y así sucesivamente hasta la 7ma u 8va fila. Todos los bits 7 los vas mandando de ocho en ocho a los registros y tienes los datos para cada fila. Los punteros te ayudarán a tener un desplazamineto y otros efectos más eficientemente según las experiencias de Bruno.
Ahora solo queda hacer algo de código, que personalmente estoy en eso, solo que dejo unos pequeños pendientes y me pongo a full a trabajar con esto.
Un saludo.
los vas mandando de ocho en ocho a los registros y tienes los datos para cada filaa: Lo envías directamente del arreglo buffer y aprovechas el uso de una variable extra para encender las filas, en realidad haces una AND con 0b00000001 para la primera fila por ejemplo y ese mismo se usa para encender el transistor, no hace falta tener los datos de 8 en 8 bits, se lo envía directamente.
Buen trabajo suky, te ha quedado muy bueno el caballo, y el tuyo si corre, no esta patinando :DJajajaja! Corre hasta por ahí nomas, en suelo de aceite! :D
como hiciste el caballo? lo dibujaste tu a mano desde cero??
ahora un peatoncito caminando jeje, hagamos semáforos peatonales :mrgreen::D
te quedó muy bueno el caballo, cuantos datos usa?
Muy chulo suky ... muy buena la animacion ...No el mensaje es estático en un buffer, para lograr el efecto de desplazamiento solo utilizo una variable que actúa como puntero. Siguiendo los concejos de BrunoF :mrgreen:
La carga del texto es dinamica? o la tienes guardada en los bufers tambien?
Saludos
Bueno, viendo los trabajos que han realizado Cryn, MLO_, marvidigital entre otros me dedique a diseñar un publik :mrgreen: . Para el mensaje cree un buffer que contiene en cada elemento las columnas del mensaje (Siguiendo el consejo de BrunoF en este post) y un buffer que contiene la sección del mensaje a visualizar en el cartel de leds. Para manejar la visualización se utiliza una variable que funcionaria como puntero, que indica la posición de la primer columna ha visualizar. También le agregue la animación de un caballo galopando, esta fue la principal motivación de realizar el publik, aquí hay un video que encontré en youtube: Caballo Galopando (http://www.youtube.com/watch?v=_nNMDVDU4kE)
La animación se coloco después del mensaje, y con el uso de 3 buffer adicionales que tienen precargados los frames se crea la escena de animación. Estos buffer se copian en el buffer del mensaje cada cierto tiempo para crear el efecto de animación.
Les muestro un video de la simulación:
Quiero seguir agregándoles cosas y hacerlo realidad :roll:
Saludos!
Pd: Gracias MLO_ por la data del software para realizar el video!
La verdad que te ha quedado "belisísima"!!!
Te felicito muchísimo. Y la verdad que ha sido un honor explicarte, porque has aprendido rápido y te has preocupado por entenderlo y dedicarle tiempo..
Con respecto a la memoria, si estás usando codigo ASCII para almacenar los datos, sí, podés ir guardando caracter x caracter y luego ir leyendolos. Yo personalmente prefiero hacer un buffer más, para ir leyendo la memoria e ir volcando al buffer en el PIC, como para siempre tener datos rapido sin peligros de tener que esperar al I2C o algo.
Mi primer cartel tenía 2 buffers para visualizar, y un tercer buffer para ir leyendo y tomando los datos de la I2C.
He hecho un ejemplo para la 24LC256 acá en el foro. Buscalo en el almacen del assembler, o bien entrando a mi perfil y buscando los temas creados por mi(esta mal, dice mostrar los ultimos IR o algo asi)
Un saludo y felicitaciones!
Gracias BrunoF por tus palabras, me motivan más a seguir subiendo en conocimientos.
Y si, ya había leído el post donde está el ejemplo del I2C...ahora mi pregunta es , si en el mismo bus puedo poner el RTC y la memoria 24LC256, es que recuerdo haber leído qeu solo se podía poner una de estas en un bus, pero no se si se podrá conectar adicional con un DS1307...y de nuevo mil gracias por tus ejemplos y compartirlos con todos..
Y hablando de compartir, hice una tabla en excel para crear caracteres y otras cositas más en una matrix de 8x8, cuando seleccionas los puntos que formaran el caracter o el gráfico y le pones 1 para indicar que encienden y el solo te genera la cadena de hex para que se agregue a los RETLW o DT
por ejemplo:
una copa de cocktail(se escribe así? )
(http://img.photobucket.com/albums/v672/marvicdigital/PStwo/imagen2.jpg)
(http://img.photobucket.com/albums/v672/marvicdigital/PStwo/imagen1.jpg)
Los hex que genera son de las columnas y la primera fila es el bit más bajo, si a alguien le interesa lo subo y si quieren que le agregue algo más me pueden decir y cuando tenga un tiempito lo hago y lo subo.
Saludos
Hola a todos.
Quiero hacerme un pasamensajes , y quiero hacerlo de 8x80, pero claro, como es la primera vez que toco este tema, me puse a investigar, leer PDFs, buscar en los foros, pero me he hecho un lío y quiero estar seguro si entendí la teoría sobre como hacer esto.
Lo primero, es que existen 2 formas básicas de hacerlo, la una es mediante barrido por columnas y la otra barrido por filas; la primera tiene la desventaja de que entre más largo sea el letrero más tiempo lleva el refresco, y para evitar parapadeos se debe aumentar la velocidad del escaneo, y esto se traduce en una disminución de la intensidad del led...por favor si estoy equivocado me corrigen.. :mrgreen:; la otra y que veo que es la mas utilizada es el barrido por Filas, al ser menos cantidad, en mi caso solo 8; se pueden dejar más tiempo encendidos los leds, esto supone un aumento en el brillo de los mismos, pero al mismo tiempo un aumento de consumo de corriente ya que si estuviera encendido todo el cartel tendríamos el consumo de los 80 leds(para mi caso), claro esto es solucionable. Hasta acá voy bien?
se ve que esta el lo mismo que yooooo,,
muy bien fantastico yo tengo uno de 5 filas por55 colmnas asi esta bien¡¡¡¡¡ lo tengo en codewarrior
{0b10111101,
0b10111101,
0b10111101, //1
0b10000001,
0b11111111,
0b10000001,
0b11101111,
0b11101111, //2
0b11101111,
0b11111111,
0b10000001,
0b10111111,
0b10000001, //3
0b11111101,
0b10000001,
0b10000001,
0b11001111,
0b11001111, //4
0b11001111,
0b10111111,
0b11111111,
0b10000001,
0b10111101, //5
0b10000001,
0b11111111,
0b10000011,
0b10111111,
0b10000011, //6
0b11111101,
0b10000011,
0b10000001,
0b10111111,
0b10000001, //7
0b10111111,
0b10000001};
Si.Ahora la parte que me tiene más inseguro de si la entendí o no, la parte del software, como uso solo ASM, pues me olvido de ejemplos que he visto en C, que por el camino que voy, me tocará aprenderlo si o si. Algunos ejemplos que he visto de ASM, pues para ser franco, hay momentos donde me pierdo, debe ser por eso que todos los códigos y rutinas que he hecho las hago desde cero, y hasta ahora no he hecho un copy, paste 8).
Bueno a lo básico generar un Cero en la matriz para comenzar, a ver si entendí:
- Lo primero, debo saber como quiero que me muestre el cero la matriz, pues para mi gusto sin los leds de las esquinas, para que se vea algo redondo y no cuadrado.
- Ahora la matriz la tengo asi: cátodos como columnas y los ánodos como filas; un caracter se forma por 8 filas por 5 columnas
- Con la configuración anterior entonces he de suponer que pongo a rotar un 1 por las filas, esta rotación debe ir sincronizada con los datos en las columnas, para el caso del cero sería asi:
De abajo hacia arriba el escaneo de las filas, osea formar el dígito en la matriz desde la fila de abajo
Fila 8 <0>
Fila 7 <0>
Fila 6 <0>
Fila 5 <0>
Fila 4 <0>
Fila 3 <0>
Fila 2 <0>
Fila 1 <1>
5 Columnas <10001> ; sería la parte baja del cero
Siguiente escaneo, rotar el 1 en las filas, eso si, dejo el anterior dato con un tiempo suficiente como para que se vean bien los leds y que no halla parpadeo en el panel.
Fila 8 <0>
Fila 7 <0>
Fila 6 <0>
Fila 5 <0>
Fila 4 <0>
Fila 3 <0>
Fila 2 <1>
Fila 1 <0>
5 Columnas <01110> ;
Y los mismos 5 bits para la columna hasta llegar a la fila 8, donde sería igual a la fila 1...si me he hecho entender?..perdonenme si hay mucha chachara, pero quiero estar seguro si entendí bien o no la teoría.
Ahora, he leido algunas tablas, con los bits que formas cada caracter, pero estas tablas bien organizadas las he visto en C, y yo quiero preguntar si es posible hacer una tabla como la que escribo a continuación para el ejemplo anterior, osea el cero:Código: [Seleccionar]TABLA ADDWF CP ; CONTADOR DE PROGRAMA
RETLW 0E,11,11,11,11,11,11,0E ; EL CERO EN DONDE EL PRIMER HEXADECIMAL ES LA FILA DE ABAJO
He visto algo similar, pero en C, no se si en ASM se pueda hacer lo mismo, por que me gustaría más asi, que escribir linea por linea hasta formar el cero(en mi ejemplo) y también por llevar un orden y hacer modificaciones más fácil.
Un cero estaría conformado así:
0 1 1 1 0
1 0 0 0 1
1 0 0 0 1
1 0 0 0 1
1 0 0 0 1
1 0 0 0 1
1 0 0 0 1
0 1 1 1 0
Te conviene declarar al cero de manera vertical. Suponiendo que la fila de más abajo es la fila 1 y le asignamos el bit de menor peso, el cero estaría formado por 5 bytes(al igual que el resto de los símbolos si decides usar 5 columnas de ancho para todos(aunque no lo recomiendo)). Estos bytes serían:
0b01111110
0b10000001
0b10000001
0b10000001
0b01111110
O lo que es lo mísmo, en tabla y en hexadecimal:Código: ASM
TABLA ADDWF PCL, F RETLW 0x7E,0x81,0x81,0x81,0x7EEso era todo, cuando comience a hacerlo iré pidiendo más ayuda, como por ejemplo el desplazamiento, agregarle algunos efectos y cositas de esas que uno llega hacer cuando se entiende muy bien esto :-)
Por favor me disculpan todo este texto aburridor, pero quiero que me guíen bien y me corrijan para poder empezar :-)
Saludos
He diseñado más de 5 modelos de diversas características, y la forma más eficaz es utilizar un buffer para almacenar los datos. En tu caso de 8x80 sería un buffer de 80 bytes. Cada byte representa una columna del cartel. Esto simplifica mucho las operaciones, y optimiza la velocidad de procesado. También te recomiendo que utilices una variable para definir cuál es el primer byte a mostrar de los 80 de manera que si cambias el valor de esa variable, puedas rotar internamente el buffer de manera simple, y lograr efectos de rotaciones de manera sencilla y rápida.
Con respecto al refresco, debería ser por filas. Si bien el consumo en 80 leds asciende a 1.6A, creo que es más que justificable. Una fuente de 12V@2A no es cara.
Cualquier cosa preguntas.
Un saludo.
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.
maestro bruno ya tengo una letra perfecta pero no se como dividirlas en cada matriz.tengo 7 matrices de 5x8 puntos es decir el cartel es de 56 columnas y 5 filas aca tengo el codi
go
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.
gallo961, tendrías que editar el mensaje para sacar tu pregunta fuera de la cita, sino no se entiende nada ;-)
Saludos!