Paso 3: Bit Banging y ahorrar algunos ciclos de reloj más
800khz en un Mhz 16 AVR es de 20 ciclos de reloj.
20 ciclos de reloj en un AVR es un montón. No estamos hablando sobre PIC12 / 16C aquí con 4 garrapatas por instrucción y solamente un registro real. El AVR mucho por el reloj ciclo. Si no hubo el requisito a barajar el orden RGB el AVR podría hacer este trabajo serial sin romper un sudor.
De hecho lo único que el AVR no brilla en es cambiar las brocas en registros I/O. Esto toma dos ciclos de reloj como se muestra en los detalles de las siguientes instrucciones de OSE. La CPU tiene que leer el registro, modificar y escribir de nuevo. Es una de las instrucciones de ramificación no pocos del AVR para tomar dos relojes. (Nota: el AVR XMega ha solucionado este problema y ahora está a sólo 1 reloj)
Usando esta instrucción en rutas críticas de tiempo no es divertido como alanos código demostrada. Tuvo que saltar y saltar en el lugar para igualar las longitudes de trayectoria.
SBRC r19, 7; prueba Hola poco claro
rjmp 3f ; cierto, saltar pin Hola -> lo
CBI % [puerto], [pin]; falso, pin Hola -> lo
3: sbrc r19, 7; tal retraso de ambos caminos de código
rjmp 4f
4: nop ; retardo de tiempo del pulso
Así que si las instrucciones reales de CBI y SBI van a tomar 2 ciclos de reloj de todos modos y luego tienes que perder 2 ciclos de reloj para igualar las longitudes de camino, por qué no sólo modificar leer escribo a ti mismo. Esto le llevará 3 ciclos total.
EN R16, PortX; Leer el estado actual del registro
R16 ORI, PinX; Establecer el bit x alto
A PortX, R16; Escribir el nuevo valor al registro
Lo siguiente que puedes hacer para ahorrar tiempo es todo fuera del bucle que se puede mover. Porque este código es utilizando el 100% del tiempo de CPU, hay no hay riesgo de la cosa va a cambiar PortX. También porque ningún otro código se está ejecutando podemos utilizar tantos registros de CPU como nos gusta.
Y así IN-ción y AND/OR-ción fuera del bucle.
EN PinLo, PortX; Hacer una copia del byte en PortX
ANDI PinLo, 0xFE; Modificar para que sea el valor de escribir hacer pin lo
EN PinHi, PortX; Hacer una copia del byte en PortX
PinHi ORI, 0 x 01; Modificar para que sea el valor de escribir hacer pin Hola
Bucle:
bla
bla
a PortX, PinLo; Configurar el pin de salida baja
bla
bla
rjmp ciclo:
Esto ha hecho todo el cambio cambio, serial de bits, bit contando y bucle toma solamente 9 relojes. Esto deja libres 11 relojes para carga de datos y arrastrando los pies.
Otra vez sería un montón de tiempo si no fuera por lo de RGB. Debido a lo de RGB podemos no sólo tratamos a cada byte leído como el próximo a salir. Tenemos que tomar una decisión sobre dónde guardar el byte recién leído en un búfer y donde a partir de un búfer para obtener el siguiente byte a enviar.
Aquí es donde la instrucción del IJMP viene al rescate. Arriba se muestra la página del conjunto de instrucciones del AVR. Nosotros estamos utilizando como una declaración de caso/interruptor en una máquina de Estados de software. En cada estado podemos establecer lo que debería ser el estado siguiente sin tener que hacer cualquier evaluación.
Podemos hacer esto porque siempre sabemos qué color el octeto siguiente va a ser
Si actualmente estamos procesando el byte rojo el siguiente byte será verde
Si actualmente estamos procesando el byte verde el siguiente byte será azul
Si actualmente estamos procesando el byte azul el siguiente byte será rojo
por ejemplo. En el estado rojo simplemente podemos decir
ESTADO = VERDE
No tenemos que decir
Si (algo) luego estado = estado más verde = azul
Esto ahorra unos relojes al no tener que evaluar algo.
El código completo se muestra como una imagen aquí. Otra vez mandame un PM Si quieres que por correo electrónico a usted.
Los comentarios en el código son ojala lo suficiente hasta que alguien familiarizado con el AVR-ASM entenderlo.