viernes, 15 de febrero de 2019
lunes, 4 de febrero de 2019
Instrucción SBRC y SBRS
SBRS(Skip if Bit in Register is Set)
Esta instrucción testea un bit de un registro y salta la siguiente instrucción si el bit es 1
Instrucción SBRS |
SBRS Rr,b 0 ≤ r ≤ 31, 0 ≤ b ≤ 7
SBRC(Skip if Bit in Register is Clear)
Esta instrucción testea un bit de un registro y salta la siguiente instrucción si el bit es 0
Instrucción SBRC |
SBRS Rr,b 0 ≤ r ≤ 31, 0 ≤ b ≤ 7
Ejemplo-Instrucción sbrc |
Ejemplo
------------------------------------------------------------------------------------------------------------------------------------------------------
;Corrimiento de leds de 0-8, si se presiona el pulsador del pin pd7 se encienden todos los leds, si se deja de presionar el corrimiento sigue en el valor último que se dejó antes de presionar el pulsador.
------------------------------------------------------------------------------------------------------------------------------------------------------
código completo
Procedimiento de corrimiento de leds |
Procedimiento de encendido de leds-pulsador presionado |
domingo, 3 de febrero de 2019
Instrucción LPM(Load Program Memory)
La instrucción LPM son las iniciales de "Load Program Memory" que quiere decir que va a cargar en un registro Rd el valor de un byte de dato del Flash Program Memory.
3 maneras de leer dato de program memory a un registro:
- LPM; Carga un Byte apuntado por Z a R0.
- LPM Rn,Z; Carga un Byte apuntado por Z hacia Rn(R0-R31).
- LPM Rn,Z+; Igual que los anteriores pero se incrementa Z despues de cargar el Byte.
Cuando se usa LPM, el registro Z debe contener la dirección de byte de los datos.
La tabla de los posibles valores de Z en valores hexadecimales serían como se muestra en la siguiente imágen:
Volvamos a nuestro ejemplo, al momento de cargar la dirección de TABLE se le desplaza 1 bit a la izquierda, con el fin de que LSB sea cero, de esa forma cargo el Byte bajo.
fuente,fuente2
>>LPM R16,Z;--->va a cargar a en R16 un dato de flash program memory apuntado por Z.
Lo que hace posible que podamos acceder a los 16kword de direcciones es el PC(Program Counter), por ejemplo nuestro atmega32 tiene un PC de 14 bits, eso significa que podemos acceder a 2^14 direcciones que es equivalente a 16384 direcciones(0--16383)=16k
En la siguiente imagen se puede observar mejor como funciona la Instrucción LPM.
Para leer el byte bajo de cada ubicación de memoria de flash nosotros debemos desplazar la dirección 1 bit a la izquierda y colocar un 0 lógico.
LPM Instruction |
En la siguiente imagen se puede observar mejor como funciona la Instrucción LPM.
LPM Instruction |
Ejemplo de uso |
Ejemplo de uso 2 |
¿Por qué *2 ó <<1?
Como pueden ver en la primera imagen, la memoria de programa está organizada en words de 16 bit y el bit menos significativo del puntero Z selecciona si se elegirá el byte bajo (0) o el byte alto (1). Según lo anterior tenemos 15 bits para apuntar a cualquier dirección de flash y 1 bits(LSB) para ELEGIR LA MANERA QUE SE VA A ACCEDER(SEA LA PARTE BAJA O LA PARTE ALTA).
Esta instrucción puede dirigirse a los primeros 2^15 direcciones word = 32768 word= 32KBytes de memoria de programa.
Para que sepas como se guardan los datos en flash te recomiendo que leas el tutorial que realicé tiempo atrás, su nombre es "Ubicando código en la memoria FLASH-ROM".
Una vez que ya has leído te darás cuenta como se guarda cada instrucción de código en flash, en la cual se resumen a la manera de guardar opcodes y operandos, cada línea de código son 16 bits y es porque el ancho de la menoría flash es de 16 bits.
En esta primera tabla se muestran los posibles valores que tomará Z(en binario) cuando apunta a N dirección.
Valores de Z(en binario) |
Para leer el byte alto de cada ubicación de memoria de flash nosotros debemos desplazar la dirección 1 bit a la izquierda y colocar un 1 lógico.
Por ejemplo :
Para acceder al byte bajo de la ubicación 0b0000_0101, debemos de cargar a Z con 0b000_1010.
Para acceder al byte alto de la ubicación 0b0000_0101, debemos de cargar a Z con 0b000_1011.
Para acceder al byte bajo de la ubicación 0b0000_0011, debemos de cargar a Z con 0b000_0110.
Para acceder al byte alto de la ubicación 0b0000_0011, debemos de cargar a Z con 0b000_0111.
En código acceder a la parte baja sería:
LDI ZH, HIGH(ADDRESS FLASH<<1)
LDI ZL, LOW(ADDRESS FLASH<<1)
En código acceder a la parte alta sería:
LDI ZH, HIGH(ADDRESS FLASH<<1|1)
LDI ZL, LOW(ADDRESS FLASH<<1|1)
- EJEMPLOS:
- Si queremos apuntar a la parte baja de la dirección flash(16 bits)=0x0002 --> Z = 0x0004.
- Si queremos apuntar a la parte alta de la dirección flash(16 bits)=0x0002 --> Z = 0x0005.
- Si queremos apuntar a la parte baja de la dirección flash(16 bits)=0x0005 --> Z = 0x000A.
- Si queremos apuntar a la parte alta de la dirección flash(16 bits)=0x0005 --> Z = 0x000B.
LDI ZH, HIGH(TABLE<<1)
LDI ZL, LOW(TABLE<<1)
Por ejemplo si dirección de TABLE es 1111111100000111(16 bits) al desplazar un bit a la izquierda sería 1111111000001110 de esa manera indico que estoy apuntando al Byte bajo para ser leído.
Algunos en vez de desplazar un bit a la izquierda prefieren multiplicarlo *2 que el resultado es el mismo, por ello también es válido haber usado:
LDI ZH, HIGH(TABLE*2)
LDI ZL, LOW(TABLE*2)
- Existe un "puente" entre el bus de datos de la memoria de programa y el bus de datos de la memoria de datos y esto se hace a traves de la instrucción LPM.
- Para acceder a un byte de la memoria del programa se usa el registro Z, que contendrá su dirección.
- El bit 0 del registro Z selecciona el byte alto o bajo de la palabra de 16 bits elegida que se vuelca en R0 u otro registro.
- La instrucción LPM se usa cuando se usan tablas.
- La memoria de programa(ROM CODE) es parte de memoria Flash.
- Cuando se apunta a una dirección de flash para leer el valor de dicha dirección se realiza pensando apuntando a su parte baja o alta de tal dirección.
fuente,fuente2
Big Endian Vs Little Endian
Es simple aunque no es común escuchar sobre esto.
La diferencia entre uno y otro es el orden en que los datos son guardados en las celdas de memoria.
Para ayudar a entender la diferencia entre Big Endian y Little Endian, veremos más de cerca cómo se almacenan los datos en la memoria.
Almacenamiento de datos-Sistema Little Endian
Los procesadores Intel x86,DEC alpha,VAX,AMD siguen este sistema al alamcenar datos en memoria.
Sistema Little Endian |
Almacenamiento de datos-Sistema Big Endian
Los procesadores MIPS, Sparc,Motorola 6800/68k,IBM 360/370 siguen este sistema al alamcenar datos en memoria.
Sistema Big Endian |
Almacenamiento en AVR-Sistema Little Endian
Tabla de datos con Word(.DB-Data Byte)
Si deseamos guardar el dato 0x3F06 a la memoria, y como el valor está en una tabla tipo .DB(Data Byte-cada entrada es de 1 byte) como almaceno el datos en dirección que es de tamaño de una palabra??, pues el proceso es el siguiente:
Almacencamiento en AVR- |
Donde 06 es el byte menos significativo del dato,06 es guardado en el byte más alto de la dirección y 3F que es el byte mas significativo del dato se guarda en el byte mas bajo de la dirección . Como se puede ver el almacenamiento de los datos sigue al modelo de sistema Little Endian.
Cada dirección de memoria esta formado puede almacenar 1 palabra(16 bits) se puede mandar a guardar por cada byte(.DB) o se puede mandar a guardar por cada palabra(.DW)
Tabla de datos con Word(.DW-Data Word)
- Si mandamos el dato 0x0400(word) este dato se divide en 2 byte y se guarda en 27D como 00 04.
- Si mandamos el dato 0x1000(word) este dato se divide en 2 byte y se guarda en 27E como 00 10.
- Si mandamos el dato 0x0D01(word) este dato se divide en 2 byte y se guarda en 27F como 01 0D.
- Si mandamos el dato 0x0802(word) este dato se divide en 2 byte y se guarda en 280 como 02 08.
- Si mandamos el dato 0x0104(word) este dato se divide en 2 byte y se guarda en 281 como 04 01.
.....
Y así se van guardando los datos en la memoria, la forma de almacenamiento es porque el AVR sigue el modelo de Little Endian.
Tabla .DW(Data Word) |
Pero para que necesitamos saber esto??????.
Pues es bueno saber que orden sigue nuestros datos en nuestro avr, sabiendo esto sabremos como recuperar nuestros datos guardados y otras ventajas más que iremos descubriendo.
Tienes alguna duda de este tema, o ¿de qué otros temas quieres que hablemos?, puedes escribirnos a nuestro grupo de Telegram
sábado, 2 de febrero de 2019
Registro de trabajo y Punteros X,Y,Z
Todos los microcontroladores AVR de 8 bits, desde los ATtiny, ATmega y ATxmega tienen 32 registros de trabajo que van desde R0 a R31. Los Registros de Trabajo tienen la función de alojar los datos más inmediatos que el CPU procesa.
A continuación se puede notar, los registros de trabajo. Estos estan divididos de 16 en 16. La diferencia se encuentra en que los 16 primeros (R0-R15) no permiten el uso de la instrucción LDI, que sirve para cargar constantes al registro. Los registros (R16-31), si admiten el LDI, y por general son los más utilizados por este motivo.
Los registros (R26-R31) pueden adicionalmente funcionar como punteros de 16 bits cada uno.
- El puntero X esta formado por los registros R26,R27.
- El puntero Y esta formado por los registros R28,R29.
- El puntero Z esta formado por los registros R30,R31.
Los punteros pueden apuntar a (contener la dirección de) cualquier locación del espacio de RAM. Esto junto con las instrucciones adecuadas conforman el direccionamiento indirecto más potente, muy útil por ejemplo para mover grandes bloques de datos.
Punteros o Apuntadores |
- El AVR tiene los tres últimos pares de registros internos del procesador son usados como punteros de 16 bits al espacio de memoria externa, bajo los nombres X, Y y Z. Esto es un compromiso que se hace en arquitecturas de 8 bits desde los tiempos de Intel 8008.
- Una palabra(word) esta formada por 16 bits.
Suscribirse a:
Entradas (Atom)
Uso del firmware original de la grabadora USBasp AVR en MX-USBASP (clon chino)
Te vendieron un USBisp pensado que es un USBasp?? Hace 2 meses compré un "USBasp" fui a probarlo y no funcionó....pensé me estafar...
-
Para realizar esta conversión primero debemos establecer la cantidad exacta de bits al cual convertir, en este ejemplo vamos a convert...
-
Qué es un Stack? --------------------------------------------------------------------------------------------------------------------------...
-
¿Alguna vez ha usado el término UART solo para que otro ingeniero corrija que no es un UART sino un USART? En ciertas circunstancias, la ...