TODOPIC

Microcontroladores PIC => Almacén del Assembler => Mensaje iniciado por: Marttyn en 12 de Abril de 2014, 20:18:22

Título: Me ayudan a reducir UNA instruccion de este codigo?
Publicado por: Marttyn en 12 de Abril de 2014, 20:18:22
Hola!
Estoy portando una libreria de Arduino a CCS, pero los tiempos son muy criticos y creo que debo utilizar assembler para no pasarme ni una instruccion.
La libreria es para controlar los famosos LEDs WS2812. Son unos LEDs RGB que unicamente necesitan un pin de datos para mostrar un color de 24bits. Se pueden conectar en serie al estilo "daisy chain" y formar tiras, permitiendo controlar mas de 600 LEDs RGB con un refresco de 50Hz, utilizando solo 1 pin del PIC.
Todo gracias a que CADA LED incluye un IC que decodifica la trama de datos recibida.
Esta trama de datos tiene unos tiempos muy especificos:
-Cada byte dura 10uS
-Cada bit dura 1.25uS
-Un bit CERO se representa con 0.25uS en high y 1uS en low
-Un bit UNO se representa con 0.875uS en high y 0.375uS en low

32Mhz de velocidad de micro es lo minimo que podemos usar para conseguir estos tiempos. Quizas algun experto se le ocurra como usar una velocidad menor, pero de momento no es necesario.
-Los 32Mhz nos dan 8MIPS que equivalen a instrucciones de 0.125uS
-Esto permite utilizar 10 ciclos de reloj para cada bit que enviamos.

El codigo assembler seria:
Código: ASM
  1. ;b -> es el byte que estamos enviando
  2. ;Contador -> cuenta cuantos bytes quedan por enviar
  3. ;bit7 ---
  4.    152  BSF PORTA, 0    ;A0 = true
  5.    153  BTFSS b, 0x7    ;salto si el bit7 de "b" es 1
  6.    154    BCF PORTA, 0  ;A0 = false
  7.    155  GOTO 0x156              ;nop nop
  8.    156  GOTO 0x157              ;nop nop
  9.    157  BCF PORTA, 0    ;A0 = false
  10.    158  GOTO 0x159              ;nop nop
  11. ;bit6 ---
  12.    159  BSF PORTA, 0
  13.    15A  BTFSS b, 0x6
  14.    15B    BCF PORTA, 0
  15.    15C  GOTO 0x15d
  16.    15D  GOTO 0x15e
  17.    15E  BCF PORTA, 0
  18.    15F  GOTO 0x160
  19. ;bit5 ---
  20.    160  BSF PORTA, 0
  21.    161  BTFSS b, 0x5
  22.    162    BCF PORTA, 0
  23.    163  GOTO 0x164
  24.    164  GOTO 0x165
  25.    165  BCF PORTA, 0
  26.    166  GOTO 0x167
  27. ;bit4 ---
  28.    167  BSF PORTA, 0
  29.    168  BTFSS b, 0x4
  30.    169    BCF PORTA, 0
  31.    16A  GOTO 0x16b
  32.    16B  GOTO 0x16c
  33.    16C  BCF PORTA, 0
  34.    16D  GOTO 0x16e
  35. ;bit3 ---
  36.    16E  BSF PORTA, 0
  37.    16F  BTFSS b, 0x3
  38.    170    BCF PORTA, 0
  39.    171  GOTO 0x172
  40.    172  GOTO 0x173
  41.    173  BCF PORTA, 0
  42.    174  GOTO 0x175
  43. ;bit2 ---
  44.    175  BSF PORTA, 0
  45.    176  BTFSS b, 0x2
  46.    177    BCF PORTA, 0
  47.    178  GOTO 0x179
  48.    179  GOTO 0x17a
  49.    17A  BCF PORTA, 0
  50.    17B  GOTO 0x17c
  51. ;bit1 ---
  52.    17C  BSF PORTA, 0
  53.    17D  BTFSS b, 0x1
  54.    17E    BCF PORTA, 0
  55.    17F  GOTO 0x180
  56.    180  GOTO 0x181
  57.    181  BCF PORTA, 0
  58.    182  GOTO 0x183
  59. ;bit0 ---
  60.    183  BSF PORTA, 0
  61.    184  BTFSS b, 0
  62.    185    BCF PORTA, 0
  63.    186  GOTO 0x187
  64.    187  GOTO 0x188
  65.    188  BCF PORTA, 0
  66.    189  DECFSZ Contador, F
  67.    18A  GOTO 0x152

El proceso de envio de bits es igual para todos, por lo que el codigo es basicamente el mismo, repetido 8 veces (una por cada bit). El problema esta en la linea 189 y 18A, al enviar el ultimo bit luego tengo que hacer un salto al inicio de la rutina para continuar enviando el siguiente byte. En ese ultimo bit que envio, utilizo 11 ciclos en vez de 10.
Algun experto podria recomendarme algun truquito para mantenerme dentro de los 10 ciclos necesarios?

Una vez haya podido solucionar esto, lo siguiente que me gustaria mejorar es que este codigo funciona siempre que "Contador" sea 1 byte, es decir, que no se envien mas de 255 bytes. Pero si Contador fueran 2 bytes/int16/long la instruccion DECFSZ no sirve directamente, sino que habria que hacer algo de magia con assembler de la que no tengo idea de como usar, y menos dentro de los tiempos estos tan apretados.

Eternamente agradecido al que me pueda echar una mano!  :mrgreen:
Título: Re: Me ayudan a reducir UNA instruccion de este codigo?
Publicado por: AngelGris en 12 de Abril de 2014, 20:37:48
  ¿Probaste reemplazando el goto 187 de la línea 186 por un nop?

  De esa manera ahorras un ciclo en la línea 186 y lo utilizas en la 18A.
Título: Re: Me ayudan a reducir UNA instruccion de este codigo?
Publicado por: BrunoF en 12 de Abril de 2014, 22:32:00
Hola,

con qué micro estás trabajando? Para saber qué instrucciones hay disponibles para usar. Lo que te dice AngelGris te va a servir para ahorrarte un ciclo. No veo que hayas contemplado cargar a la variable b con el próximo Byte a enviar dentro de los tiempos acotados.

Saludos!
Título: Re: Me ayudan a reducir UNA instruccion de este codigo?
Publicado por: Nocturno en 13 de Abril de 2014, 02:06:21
Me suscribo al hilo. No conocía esos leds pero se ven la mar de interesantes.
Título: Re: Me ayudan a reducir UNA instruccion de este codigo?
Publicado por: Marttyn en 13 de Abril de 2014, 05:58:15
Gracias AngelCris, pero los momentos "clave" de cada bit, donde hay que cambiar de nivel el pin, son (contando de 0 a 9 los ciclos): el 0 que pone a high, el 2 que pone a low si el bit es 0, y el 7 que pone a low en todos los casos.
Se podria usar otra " logica", pero los momentos clave deben ser esos. Si cambiamos el goto por un nop reducimos una instruccion, pero cambiamos de lugar el cambio de nivel.

Bruno, estoy usando un enhanced mid range, que tienen las instruciones ampliadas. El 12F1840, 16F1823, etc.
Tienes razon! No inclui la carga de la variable b!!!
En CCS la realizo como b = *punt++;
Que punt es la direccion (puntero) donde tengo todos los valores "en fila" que tengo que enviar.
Y *punt es el valor contenido en dicha direccion.
HELP! Donde voy a realizar la carga de b? No hay espacio :(
Título: Re: Me ayudan a reducir UNA instruccion de este codigo?
Publicado por: MerLiNz en 13 de Abril de 2014, 12:39:33
Te digo una forma mas sencilla que acabo de ver, por hardware. Usa el SPI, ponlo a 4Mhz y a volar, solo tendras que escribirlos sin utilizar el CLK.


Por cierto, muy interesante esos leds, no sabia que existia algo asi.
Título: Re: Me ayudan a reducir UNA instruccion de este codigo?
Publicado por: planeta9999 en 13 de Abril de 2014, 13:58:49


Muy chulos esos LED, no los conocía, me voy a pedir una tira a los chinos, para probarlos. Me planteo rediseñar algunos de mis circuitos que usan el TLC5940, con un sistema de barrido por filas-columnas, por esos led WS2812b, lástima que nos los hagan en tamaño 3528, aunque supongo que será imposible meter el controlador en un led tan pequeño.

Título: Re: Me ayudan a reducir UNA instruccion de este codigo?
Publicado por: Leon Pic en 13 de Abril de 2014, 14:04:16
Entre Byte y Byte a enviar ¿cuanto tiempo disponés?

Título: Re: Me ayudan a reducir UNA instruccion de este codigo?
Publicado por: tapi8 en 13 de Abril de 2014, 14:17:29
Citar
HELP! Donde voy a realizar la carga de b? No hay espacio

Tienes que aprovechar todos esos "goto" para cargar "b" asi como para "decf Contador" y posiblemente apuntar en un "flag" si este llego a 0, de manera que en el ultimo bit, puedas chequear ese flag y saber con antelacion si tienes que seguir o no, incluso hacer el chequeo en el penultimo, y crear "dos ultimos envios" uno si no se acaba la transmision y otro si se acaba.
Título: Re: Me ayudan a reducir UNA instruccion de este codigo?
Publicado por: migsantiago en 13 de Abril de 2014, 14:35:21
Qué tal Marttyn

Hice un código pequeño... hace tiempo que no tocaba asm, disculpa si se me va algo. Está hecho con base en un t de 1.25us y los tiempos on-off que mencionas.

La rutina que pongo deberás repetirla 3 veces... cambiando byte0 por byte1 y count0 por count1, sucesivamente. Esta rutina te ahorrará mas ROM que la que buscabas. No la repites bit por bit, más bien la repites byte por byte.

Por favor pruébala y me dices... yo la probé en SanSIM (jaja mi cuaderno) y parece que hace algo.

Saludos

Código: [Seleccionar]
; inicializa tus 3 bytes
movlw "dato0"
movwf byte0
movlw "dato1"
movwf byte1
movlw "dato2"
movwf byte2

; Antes de entrar, carga W con el primer byte, aquí aún no comienza el t a correr
movf byte0, w

; También antes de entrar carga una variable en 8, es el contador de cuántos bit ya mandamos por cada byte
movlw 8
movwf count0
movlw 8
movwf count1
movlw 8
movwf count2

; Aquí empieza el contador de t de 1.25us

BYTE0_Enviar:
;0 - 0ns
; Levanta el bit (siempre pasa)
bsf PORTA.0

;1 - 125ns
; Mantenlo otros 125ns
nop

;2 - 250ns
; Baja el bit si es que bit0 de W es un cero y escríbelo en PORTA.0
; Si no, se queda un 1 en PORTA.0
andwf PORTA.0, f

;3 - 375ns
; Rota el byte actual una vez a la derecha y guárdalo en byte0
rrf byte0, f

;4 - 500ns
; Mueve byte0 a W
movf byte0, w

;5 - 625ns
;
nop

;6 - 750ns
; Baja el bit PORTA.0, sin importar que haya habido en el puerto
bcf PORTA.0

;7 - 875ns
; Decrementa el contador y si ya es 0, entonces carga el siguiente byte
decfsz count0

;8 - 1000ns
; Si llega aquí, entonces seguimos en el byte actual, hay que ir al siguiente bit
goto BYTE0_Enviar

;9 - 1125ns
; Si llega aquí, es porque decfsz ya fue cero
movf byte1, w

; Rutina de byte1

...
Título: Re: Me ayudan a reducir UNA instruccion de este codigo?
Publicado por: Darkman_A en 13 de Abril de 2014, 14:55:12
Hola Marttyn.
Dado que parece que estas corto de tiempo mi primera idea seria aumentaria los MIPS eliigiendo otro micro.
Es que estas muy jugado con los tiempos de las instrucciones. Como vos mismo indicas estas manejando tiemps de 2 instrucciones o 7 instrucciones. Estas muy jugasdo. Si resolves esto que consultas es probable que te "salte" otro problema en otro lado, como el que estas viendo de no darte los tiempos para cargar el valor a mostrar en los leds.
Antes de tener un ACV o un infarto es lo que yo haria ( cambiar el micro )  :P y si vale la pena luego, con mas tiempo, optimizaria el codigo. ¿Que opinas de un PIC 18F4550 a 48 Mhz?.  (nombro este porque es el que tengo y estoy usando ........  :) )
Saludos.

Nota: Hoy es domingo.... vacio y "Postales del fin del mundo" Malbec- Syrah..... no me pidas que piense en assembler  ...... :) :) :) :) :)
Título: Re: Me ayudan a reducir UNA instruccion de este codigo?
Publicado por: BrunoF en 13 de Abril de 2014, 16:17:55
Podés utilizar un FSR para acceder a la memoria indirectamente. En este caso por los micros que me mencionaste no vale la pena pensar en que podés enviar más de 256 bytes, siendo que ninguno de los tiene siquiera más de 256 bytes de memoria RAM. Si llegás a necesitarlo, avisame y lo vemos.

Código: ASM
  1. ;Cargar valor de Contador (si Contador == 0 al ingresar, se enviarán 256 bytes!)
  2.         ;se puede hacer en Código C directamente      
  3.  
  4.         ;cargar dirección del inicio del array en registro FSR0
  5.         MOVLW   LOW     array[0]
  6.         MOVWF   FSR0L
  7.         MOVLW   HIGH array[0]
  8.         MOVWF   FSR0H
  9.        
  10.        ;envio de datos
  11. SENDDATA:
  12.         BSF             PORTA, 0        ;A0 = true
  13.         BTFSS   INDF0, 7        ;salto si el bit7 de "b" es 1
  14.         BCF             PORTA, 0        ;A0 = false
  15.         GOTO    $+1             ;nop nop
  16.         GOTO    $+1             ;nop nop
  17.         BCF             PORTA, 0        ;A0 = false
  18.         GOTO    $+1
  19.  
  20.         BSF             PORTA, 0        ;A0 = true
  21.         BTFSS   INDF0, 6        ;salto si el bit6 de "b" es 1
  22.         BCF             PORTA, 0        ;A0 = false
  23.         GOTO    $+1             ;nop nop
  24.         GOTO    $+1             ;nop nop
  25.         BCF             PORTA, 0        ;A0 = false
  26.         GOTO    $+1
  27.  
  28.         BSF             PORTA, 0        ;A0 = true
  29.         BTFSS   INDF0, 5        ;salto si el bit5 de "b" es 1
  30.         BCF             PORTA, 0        ;A0 = false
  31.         GOTO    $+1             ;nop nop
  32.         GOTO    $+1             ;nop nop
  33.         BCF             PORTA, 0        ;A0 = false
  34.         GOTO    $+1
  35.  
  36.         BSF             PORTA, 0        ;A0 = true
  37.         BTFSS   INDF0, 4        ;salto si el bit4 de "b" es 1
  38.         BCF             PORTA, 0        ;A0 = false
  39.         GOTO    $+1             ;nop nop
  40.         GOTO    $+1             ;nop nop
  41.         BCF             PORTA, 0        ;A0 = false
  42.         GOTO    $+1
  43.  
  44.         BSF             PORTA, 0        ;A0 = true
  45.         BTFSS   INDF0, 3        ;salto si el bit3 de "b" es 1
  46.         BCF             PORTA, 0        ;A0 = false
  47.         GOTO    $+1             ;nop nop
  48.         GOTO    $+1             ;nop nop
  49.         BCF             PORTA, 0        ;A0 = false
  50.         GOTO    $+1
  51.  
  52.         BSF             PORTA, 0        ;A0 = true
  53.         BTFSS   INDF0, 2        ;salto si el bit2 de "b" es 1
  54.         BCF             PORTA, 0        ;A0 = false
  55.         GOTO    $+1             ;nop nop
  56.         GOTO    $+1             ;nop nop
  57.         BCF             PORTA, 0        ;A0 = false
  58.         GOTO    $+1
  59.  
  60.         BSF             PORTA, 0        ;A0 = true
  61.         BTFSS   INDF0, 1        ;salto si el bit1 de "b" es 1
  62.         BCF             PORTA, 0        ;A0 = false
  63.         GOTO    $+1             ;nop nop
  64.         GOTO    $+1             ;nop nop
  65.         BCF             PORTA, 0        ;A0 = false
  66.         GOTO    $+1
  67.  
  68.         BSF     PORTA, 0        ;A0 = true
  69.         BTFSS   INDF0, 0        ;salto si el bit0 de "b" es 1
  70.         BCF     PORTA, 0        ;A0 = false
  71.         DECFSZ  Contador,F      ;decrementar contador de bytes enviados,si es cero, listo.
  72.         GOTO    $+2             ;nop nop
  73.         GOTO    DONE            ;todo enviado. Salir
  74.         ADDFSR  FSR0,1          ;incrementar puntero
  75.         BCF             PORTA, 0        ;A0 = false
  76.         GOTO    SENDDATA
  77.  
  78. DONE:
Título: Re: Me ayudan a reducir UNA instruccion de este codigo?
Publicado por: Nocturno en 14 de Abril de 2014, 01:47:44
Si como dice Merlinz funcionan bien por SPI, yo no le daría más vueltas.

Aquí hay alguien que también lo hace por SPI:
http://hypnocube.com/2013/12/design-and-implementation-of-serial-led-gadgets/
Título: Re: Me ayudan a reducir UNA instruccion de este codigo?
Publicado por: Marttyn en 14 de Abril de 2014, 10:51:03
Te digo una forma mas sencilla que acabo de ver, por hardware. Usa el SPI, ponlo a 4Mhz y a volar, solo tendras que escribirlos sin utilizar el CLK.
Aquí hay alguien que también lo hace por SPI:
http://hypnocube.com/2013/12/design-and-implementation-of-serial-led-gadgets/

Gracias Merlinz y Noc, ya he probado con SPI y he obtenido los PEORES tiempos, ya que entre bit y bit transcurria una eternidad. Quizas por que lo estaba haciendo con CCS y no optimice el codigo, deberia probar nuevamente, ver como lo traduce a ASM y ver donde se puede optimizar.
Que conste que por SPI no estamos enviando los bytes, sino que cada byte enviado por SPI corresponde a un bit de datos de los 24 que debo enviar por cada led.

Muy chulos esos LED, no los conocía, me voy a pedir una tira a los chinos, para probarlos. Me planteo rediseñar algunos de mis circuitos que usan el TLC5940, con un sistema de barrido por filas-columnas, por esos led WS2812b, lástima que nos los hagan en tamaño 3528, aunque supongo que será imposible meter el controlador en un led tan pequeño.

Seguro que lo pueden hacer en 3528, el chip que tiene dentro es enano!
(http://www.adafruit.com/images/1200x900/1655-03.jpg)


Entre Byte y Byte a enviar ¿cuanto tiempo disponés?
Entre byte y byte no hay tiempo, se envia todo seguido. Tampoco hay tiempo entre bit y bit. Si quieres enviar datos para 10 leds necesitas 30 bytes (3 bytes por cada led, uno para cada color). Que serian 240 bits a enviar. Todos seguidos.
Luego de haber enviado tu trama de datos tienes que esperar 50uS antes de enviar la siguiente.

Citar
HELP! Donde voy a realizar la carga de b? No hay espacio

Tienes que aprovechar todos esos "goto" para cargar "b" asi como para "decf Contador" y posiblemente apuntar en un "flag" si este llego a 0, de manera que en el ultimo bit, puedas chequear ese flag y saber con antelacion si tienes que seguir o no, incluso hacer el chequeo en el penultimo, y crear "dos ultimos envios" uno si no se acaba la transmision y otro si se acaba.
Me gusta esta forma de pensar de ASM. La programacion en C y en ASM es muy diferente, y mi cerebro piensa en C, y esas cosas que dices tienen mucho sentido, pero no soy capaz de que se me ocurra algo asi a mi. jaja

Hola Marttyn.
Dado que parece que estas corto de tiempo mi primera idea seria aumentaria los MIPS eliigiendo otro micro.
Es que estas muy jugado con los tiempos de las instrucciones. Como vos mismo indicas estas manejando tiemps de 2 instrucciones o 7 instrucciones. Estas muy jugasdo. Si resolves esto que consultas es probable que te "salte" otro problema en otro lado, como el que estas viendo de no darte los tiempos para cargar el valor a mostrar en los leds.
Antes de tener un ACV o un infarto es lo que yo haria ( cambiar el micro )  :P y si vale la pena luego, con mas tiempo, optimizaria el codigo. ¿Que opinas de un PIC 18F4550 a 48 Mhz?.  (nombro este porque es el que tengo y estoy usando ........  :) )
Saludos.

Nota: Hoy es domingo.... vacio y "Postales del fin del mundo" Malbec- Syrah..... no me pidas que piense en assembler  ...... :) :) :) :) :)
Estoy intentando hacer una libreria, por lo que quiero intentar con 32Mhz para poder usarla con micros de la familia 12F o 16F. Luego que funcione con micros mas potentes no sera un problema

Podés utilizar un FSR para acceder a la memoria indirectamente. En este caso por los micros que me mencionaste no vale la pena pensar en que podés enviar más de 256 bytes, siendo que ninguno de los tiene siquiera más de 256 bytes de memoria RAM. Si llegás a necesitarlo, avisame y lo vemos.

Fantastico Bruno! Tengo que estudiar un poco el codigo con el datasheet en la mano para ver si lo entiendo bien :)
Ya he notado que solo disponemos de 256 bytes de RAM en los micros que te dije. En ellos no podre usar mas de unos 80 LEDs ya que no tendria suficiente memoria. Pero como decia antes, me gustaria hacer una libreria para poder usarla en varios PICs, por lo que seria interesante ampliarle el contador.

Qué tal Marttyn

Hice un código pequeño... hace tiempo que no tocaba asm, disculpa si se me va algo. Está hecho con base en un t de 1.25us y los tiempos on-off que mencionas.

La rutina que pongo deberás repetirla 3 veces... cambiando byte0 por byte1 y count0 por count1, sucesivamente. Esta rutina te ahorrará mas ROM que la que buscabas. No la repites bit por bit, más bien la repites byte por byte.

Por favor pruébala y me dices... yo la probé en SanSIM (jaja mi cuaderno) y parece que hace algo.

Mig, probare y estudiare tu codigo tambien. La verdad no se que funcionara mejor, si el tuyo o el de bruno. Buscare la forma mas optima para que consuma menos recursos. Me gustaria correr este codigo en micros pequeños.

Esta tarde hare pruebas con el Saleae a ver que tiempos obtengo, tanto con SPI como con el ASM de Bruno y Mig.
Seguro que todos funcionaran, lo tendre dificil para elegir  :mrgreen:
Muchas gracias a todos por los consejos!
Título: Re: Me ayudan a reducir UNA instruccion de este codigo?
Publicado por: planeta9999 en 14 de Abril de 2014, 12:59:19

Muy chulos esos LED, no los conocía, me voy a pedir una tira a los chinos, para probarlos. Me planteo rediseñar algunos de mis circuitos que usan el TLC5940, con un sistema de barrido por filas-columnas, por esos led WS2812b, lástima que nos los hagan en tamaño 3528, aunque supongo que será imposible meter el controlador en un led tan pequeño.

Seguro que lo pueden hacer en 3528, el chip que tiene dentro es enano!



Ojalá los hagan, de momento parece que solo están en 5050, algo grandes para calzarlos en uno de mis diseños.

Lo que si he visto, y ya lo he pedido a los chinos, además de unos cuando WS2811 y WS2812, son los LED con controlador WS2801, este va con 4 hilos, y al enviar la señal de reloj por separado, parece que son mucho más fáciles de controlar que los WS2811-WS2812, aunque el controlador no va integrado dentro del LED, pero lo venden en tiras y en placas redondas con 3, 4, 6 y 12 SMD 5050.


Suerte con el proyecto, ya he visto buscando por Google, algunos proyectos con AVR y los WS2812, y parece que terminan combinando ensamblador con C, para poder enviar los datos con la precisión que requiere ese controlador, sino no hay manera.


Título: Re: Me ayudan a reducir UNA instruccion de este codigo?
Publicado por: tapi8 en 14 de Abril de 2014, 13:19:12
Citar
Me gusta esta forma de pensar de ASM. La programacion en C y en ASM es muy diferente, y mi cerebro piensa en C, y esas cosas que dices tienen mucho sentido, pero no soy capaz de que se me ocurra algo asi a mi. jaja

Fijate que todos esos "goto" no hacen nada, en el primer bit que envias puedes decrementar "Contador" con esta instruccion "decf" sin comparar si es 0, ya que contador te cuenta bytes, da igual donde decrementes. despues en otro bit el segundo por ejemplo lo mueves a W haciendo un movf y chequeas STATUS,Z para saber si llego a 0, si STATUS,Z esta a 1 quiere decir que Contador es 0, lo apuntas en un "flag que te creas tu, para chequearlo en el ultimo bit que envias, cargar el siguiente byte a transmitir, lo haces en el ultimo bit a enviar, despues de chequear si es 1 o 0:

183   BSF PORTA, 061.   
184   BTFSS b, 062.   
185     BCF PORTA, 063.   
186   GOTO 0x18764.  ;aqui ya chequeaste el ultimo bit,   
187   GOTO 0x18865. 
 
188   BCF PORTA, 066.   
189   DECFSZ Contador, F67.   
18A   GOTO 0x152


183   BSF PORTA, 0 
184   BTFSS b, 062.   
185     BCF PORTA, 0   
186   movf   "siguiente byte"     ; en vez del goto
              movwf   b                        ;estas dos instrucciones ocupan loo mismos ciclos que "goto"
              btfsc     "FLAG"                 ;este flag lo tienes que traer mirado de antes, indicara si Contador" es 0 
              goto      "acabo transmision"   ;si viene aqui Contador=0, acaba trama de transmision

188   BCF PORTA, 066.   
18A   GOTO 0x152

Tal y como esta solo se iria un ciclo (0,125nS) en el ultimo bit del ultimo byte de la transmision.

Si me das un dia te lo hago entero, si quieres.
Título: Re: Me ayudan a reducir UNA instruccion de este codigo?
Publicado por: MerLiNz en 14 de Abril de 2014, 15:15:17
debes utilizar SPI por hardware no por software, por hardware nunca tendras error de tiempos puesto que es el propio CLK del procesador
Título: Re: Me ayudan a reducir UNA instruccion de este codigo?
Publicado por: BrunoF en 14 de Abril de 2014, 15:39:45
El link que ha publicado Nocturno es muy interesante. Lo he leído casi todo, y por lo que leí, no utilizan el SPI para este modelo de LEDs. Utilizan instrucciones de procesador e incluso emiten hasta 16 tramas de bits simultáneas para poder repartir las cascadas de LEDs. También se mencionan aspectos preocupantes cuando se intenta utilizar largas cascadas de LEDs. Parece que los tiempos recomendados no son los ideales cuando la cascada es muy grande.

En fin, los LEDs se ven muy interesantes.

El uso del SPI puede ahorrar algun tiempo del CPU, aunque requeriría de al menos @ 8Mbps por parte módulo SSP, y creo que se volvería especialmente útil si el módulo SSP del microcontrolador en cuestión tuviese una FIFO para poder cargar varios elementos a la vez y despreocuparnos del envío durante un tiempo. Caso contrario te la pasarás cargando el buffer de envío.

Algo interesante es que utilizaron el FT232H para sacar datos de la PC, que promete 12Mbps de transmición USB a serie, y parece que lo cumple a rajatabla, sin perder un sólo bit. A tener en cuenta para poder transmitir 1.5MBps desde la PC.

Saludos!
Título: Re: Me ayudan a reducir UNA instruccion de este codigo?
Publicado por: Picuino en 14 de Abril de 2014, 16:45:25
He leído el datasheet y todos los tiempos tienen un margen de +-150ns.

Uno lógico:   
    700ns alto +-150ns
    600ns bajo +-150ns

Cero lógico:
    350ns alto +-150ns
    800ns bajo +-150ns

Hay margen para meter una instrucción más o para quitar una instrucción.

Saludos.
Título: Re: Me ayudan a reducir UNA instruccion de este codigo?
Publicado por: Marttyn en 14 de Abril de 2014, 21:52:48
Lo he terminado!!!  :-/
Bueno, mejor dicho, he comenzado!
Ya tengo la base sobre la que trabajar para ir haciendo la libreria un poco mas completa.
A falta de medir tiempos con el analizador logico o el osciloscopio, el resultado es funcional:
(http://i299.photobucket.com/albums/mm317/Marttyn/Electronica/E0B4C55C-FA69-4C5E-BC7A-FF29BB81CC0E.jpg)

Gracias tapi por el ofrecimiento, creo que ya esta solucionado esto.

Merlinz, si que use SPI por hardware, pero como dice Bruno, a falta de una FIFO de envio, me consumia todo el tiempo cargando valores al SPI y por eso debe ser que me daba tan malos tiempos.

Bruno, al final termine usando tu codigo pasado en gran parte a CCS, porque hay instrucciones que no las agarraba en ASM como el ADDFSR o el GOTO $+2, o el BRA 2.

Perdon Mig, me fue mas facil entender el codigo de Bruno y opte por ese. Aunque es verdad que tu codigo parece ocupar menos ROM. Deberia estudiarlo.

Picu, es verdad que los tiempos que muestra el datasheet no son exactamente como comente al principio, pero me base en una libreria para Arduino desarrollada por Adafruit. Ellos usaron estos tiempos, y su libreria la usan cientos o miles de personas sin queja. Asi que opte por imitar sus tiempos, que no se muy bien como llegaron a ellos, pero les funcionan :)

La libreria la colgue en el foro de C: http://www.todopic.com.ar/foros/index.php?topic=42622.0
El que programe en assembler y quiera probar estos leds, puede usar el codigo que propuso Bruno que es el que implemente en la libreria.

El problema que estoy teniendo es encontrar un bloque de memoria libre y consecutiva para manejar los leds.
En un PIC 12F1822 con 128 bytes de RAM solo pude manejar 10 LEDs (30 bytes) usando la funcion "malloc()" para encontrar bloques de memoria.
Tengo que investigar como "defragmentar" la memoria para tener un bloque consecutivo mas grande y aprovechar mejor la RAM.
Con Arduino pude manejar sin problemas una tira de 240 LEDs. Acaso Arduino va a ser mejor que un PIC?!!  :D

Gracias a todos por la ayuda y los consejos prestados!
Título: Re: Me ayudan a reducir UNA instruccion de este codigo?
Publicado por: BrunoF en 15 de Abril de 2014, 00:16:35
Hola Martyyn,

me alegro que el código funcione!

Un detalle: Ojo que hacer FSR0L++ no es igual a hacer ADDFSR FSR0,1

la instrucción ADDFSR incrementa el registro FSR0, considerándolo como un registro de 16 bits. Es decir que si desborda FSR0L, automáticamente incrementa FSR0H, cosa que FSR0L++ no hace.

Saludos!


Título: Re: Me ayudan a reducir UNA instruccion de este codigo?
Publicado por: Marttyn en 15 de Abril de 2014, 04:50:24
Gracias Bruno por el comentario. Eso ya lo tenia previsto. Pero por suerte el compilador lo traduce como ADDFSR FSR0, 1
Título: Re: Me ayudan a reducir UNA instruccion de este codigo?
Publicado por: MerLiNz en 15 de Abril de 2014, 07:13:21
pasate a dspic y tendras SPI con DMA, imagina lo sencillo que te seria.
Título: Re: Me ayudan a reducir UNA instruccion de este codigo?
Publicado por: Marttyn en 15 de Abril de 2014, 07:17:37
 :D :D
Si, seguro, y ademas tendria RAM de sobra...
Pero por coste, tamaño y facilidad de uso quiero hacerlos funcionar con esto:
(http://www.dr-iguana.com/prj_ThirdEye/images/pic12F1840.jpg)

EDITO: me picaba la curiosidad, y encontre el PIC16F1788, que en formato QFN ocupa solo 6x6mm, y tiene 2K de ram, lo que es suficiente para manejar mas de 600 leds sin problema... :)
http://www.microchip.com/wwwproducts/Devices.aspx?product=PIC16F1788
Título: Re: Me ayudan a reducir UNA instruccion de este codigo?
Publicado por: tapi8 en 15 de Abril de 2014, 13:15:46
Citar
EDITO: me picaba la curiosidad, y encontre el PIC16F1788, que en formato QFN ocupa solo 6x6mm, y tiene 2K de ram, lo que es suficiente para manejar mas de 600 leds sin problema...

Vaya pepino de 16F, impresionante, 11 canales de ADC de 12bits, todavia no me llegan para algo que quiero hacer pero empieza a parecerse a lo que quiero, usando dos ya me llegaria, del resto me va sobrasidisimo de todo.
Título: Re: Me ayudan a reducir UNA instruccion de este codigo?
Publicado por: migsantiago en 15 de Abril de 2014, 21:33:54
Hola Marttyn, a veces es mejor la legibilidad que la optimización. No te preocupes, un saludo!!  ;-)