viernes, 23 de noviembre de 2018

SRAM (SFRs ,GPRs y INTERNAL DATA SRAM)

Los datos de memoria RAM están compuestos por tres partes, las cuales son:
  • GPRs(General Purpose Registers)
Pueden usarse 6 de los 32 registros como tres punteros de registro de direcciones indirectos(de 16-bits) para el direccionamiento del espacio de datos(memoria de datos RAM), proporcionando cálculos de dirección eficaces. También se usa uno de los tres punteros de dirección para observar una tabla de constantes. Estos registros son los registros X,Y y Z.
  • SFRs(Special Function Registers-PORTS I/O)

El espacio  de memoria I/O contiene 64 direcciones para la configuración de funciones periféricas de la CPU como los registros de control, Temporizadores/Contadores, convertidores A/D y otras funciones.

Los registros de I/O deben ser accedidos con su dirección del espacio I/O y no considerando si dirección absoluta.

Cuando se menciona direccion de espacio (I/O) se refiere a las direcciones de los registros I/O que empiezan en $00 y acaban en $3F, cualquiera de los 64 registros SFRs(TWBR-SREG) pueden ser accedidos y se llevados a GPRs(R0-R31) utilizando la instrucción "IN".


SFRs(Registros de Funciones especiales)

Aunque las direcciones de memoria  $20-$5F están reservadas para los registros I/O(SFRs) nosotros podemos acceder a ellas como ubicaciones de I/O con direcciones que empiezan en $00.

De acuerdo con la figura(Resumen de Ram) los Registros I/O también pueden ser referidos como cualquier localidad de SRAM de propósito general, utilizando instrucciones de carga (LD) o almacenamiento (ST), con direcciones en el rango de 0x20 a 0x5F. 

Tratar a los Registros de Propósito General o a los Registros I/O como SRAM de propósito general no es conveniente, porque las instrucciones de acceso a memoria se ejecutan en 2 ciclos de reloj.

Los registros de I/O deben ser aceedidos con su dirección del espacio(I/O) ,no considerando su dirección absoluta.
Dirección absoluta-Dirección de registros dentro de los registros I/O.

Lista de SFRs completos-parte1

Lista de SFRs completos-parte2

Para la lectura de un dirección de un registro SFRs se puede usar la instrucción "IN", teniedo en cuenta que esta instrucción NO usa las drecciones absolutas, usa las direcciones de los registros I/O.
  • INTERNAL DATA SRAM
1K byter de memoria interna puede ser accedida desde la dirección $0060  hasta la dirección $045F son registros que se usan para propositos generales.
Memoria Interna SRAM
RESUMEN DE RAM
La memoria RAM está compuesto por 32 registros generales(GPRs),64 registros de funciones especiales(SFRs) y memoria SRAM(puede variar según el microcontrolador ,algunos son de 1k , 2 k,etc), ejemplo:
En la siguiente figura se muestra la memoria RAM de un Atmega32, que tiene 085F=2143, dirección de [0-->0x85F], aquí está incluido [32 registros GPRs(Dirección 0-->1F)+64 registros SFRs(Dirección 20-->5F)+ Memoria SRAM de 2k=2048(Dirección 60-->85F)].

Según lo dicho anteriormente se concluye que si en la hoja de datos del AVR te dice que la memoria SRAM es de 2Kbytes no considera a (GPRs y SFRs).
Resumen de RAM-Atmega32


Data Memory-Atmega328P-Atmega88
  • Algunos AVR tienen 160 registros de I/O extendidos por ejemplo el Atmega 328P, Atmega88, Atmega168, Atmega 8U2/16U2/32U2 entre otros, aquí se encuentran registros como EIMSK,EICRA(registros de interrupción externa) entre otros .En estos casos la memoria SRAM empieza desde  0x0100 hasta RAMEND(depende del microcontrolador la dirección varia).
  • Pero en el caso de los atmega 32 no tienen estos registros E/S extendidos por ello la memoria SRAM interna empieza desde 60 hex hasta RAMEND(085F).


jueves, 22 de noviembre de 2018

Uso de la instrucción "LDS" y "STS"

LDS(Load Direct from SRAM(data Space)
Se carga Rd con el contenido de lo que está en la dirección K.
Carga Directa del espacio de datos hacia Rd.

Instrucción

Ejemplo

------------------------------------------------------------------------------------------------------------------------------------------------------
;Agregar el contenido de la ubicación de memoria 0x300 hacia la ubicación de memoria 0x302.
------------------------------------------------------------------------------------------------------------------------------------------------------
Código





Importante

Los datos que puedo copiar a través de sus direcciones puede ser cualquier datos de la  SRAM( registros SFRs(I/O registers), SRAM interna o incluso datos de GPRs). es decir hay tres opciones de uso de LDS:
  • Opción1: de SRAM interna a GPRs
      • LDS R20, 0x300,se sabe que direcciones[0x0060,.....,0x045F] le corresponde a datos de SRAM interna.
  • Opción2: de I/O registers a GPRs
      • LDS R20, 0x20 ,se sabe que direcciones[0x0020,.....,0x005F] le corresponden a registros SFRs[TWBR,......,SREG]
  • Opción3: de GPRs a GPRs
      • LDS R20,0x1; R20=R1, se sabe que direcciones [0,.....,1F]  le corresponden a registros de datos [R0,......,R31]
Las direcciones variaran según el microcontrolador AVR que se use, pero la manera de utilizar LDS es la misma.
Haremos mención a la última opción de uso de la LDS:

LDS R20,0x1 ; instrucción copiará el contenido de la ubicación1 (en hexadecimal) dentro de R20, Como sabemos la ubicación o dirección 1 es la memoria de datos es parte de GPRs y la dirección le corresponde a R1, así la instrucción copia R1 a R20.

STS(Store Direct to SRAM)

Almacenamiento Directo hacia el SRAM(espacio de datos)
Guarda un valor en una ubicación de memoria.
Store Rr a ubicación de memoria k.
Instrucción===> STS dirección donde se va a almacenar, el valor a almacenar.
Instrucción
Ejemplo
---------------------------------------------------------------------------------------------------------------------
; cuando el pinb,0 =0 se guarda en la dirección 0x0200 el valor de 0x55
;cuando el pinb,0=1 se guarda el la dirección 0x0200 el valor de 0x10
---------------------------------------------------------------------------------------------------------------------
Guarda el dato 0x55

Guarda el dato 0x10


Diagrama de flujo

Memory

USO DE STS PARA CARGAR REGISTROS DENTRO DE  GPRS

Como podemos ver en la gráfica los registros GPRS forman parte de las primeras direcciones de la memoria de datos.  
Memoria de datos
sus direcciones son:
R0<-0x0000  -  R1<-0x0001  -  R2<-0x0002  -  R3<-0x0003  -  R4<-0x0004
R5<-0x0005  -  R6<-0x0006  -  R7<-0x0007  -  R8<-0x0008  -  R9<-0x0009
R10<-0x000A  -  R11<-0x000B  -  R12<-0x000C  -  R13<-0x000D  -  R14<-0x000E
R15<-0x000F  -  R16<-0x0010  -  R17<-0x0011  -  R18<-0x0012  -  R19<-0x0013  R20<-0x0014  -  R21<-0x0015  -  R22<-0x0016  -  R23<-0x0017  -  R24<-0x0018  R25<-0x0019  -  R26<-0x001A  -  R27<-0x001B  -  R28<-0x001C  -  R29<-0x001D
R30<-0x001E  -  R31<-0x001F

EJEMPLO:
Deseamos guardar en R17 el valor del registro R16. Como sabemos R17 esta en la dirección 0x0011 y R16 se encuentra en la dirección 0x0010.

                                                                                                   Código

                                                                                  Debug

Detalles a tomar en cuenta al usar estos comandos(LDS y STS):
  1. Para ejecutar el comando LDS o STS el CPU utiliza 2 ciclos de maquina.
  2. LDS y STS son instrucciones que ocupan mas código en memoria de programa ya que por ejemplo para pasar datos a una dirección determinada, primero debemos cargar el dato a un registro GPRs y luego recién cargamos a alguna dirección de memoria SRAM.
  3. Trabajar con direcciones y no con nombres es poco tedioso al trabajar.
  4. Las instrucciones LDS y STS no están disponibles en algunos AVRs y eso debemos tener en cuenta si se desea utilizar.



miércoles, 21 de noviembre de 2018

Uso de las instrucciones "BRNE" y "BREQ"

BRNE(Branch if not equal)
Branch if Flag Z=0

BREQ(Branch if equal)
Branch if Flag Z=1

Flag Z
Se pone a 1 cuando una operación lógica o aritmética da cero como resultado.
Se pone a 0 cuando una operación lógica o aritmética da distinto de cero como resultado.

Branch if la variable(de la instrucción anterior) no es igual a cero.

Ejemplo

------------------------------------------------------------------------------------------------------------------------------------------------------
El objetivo de este ejemplo es agregar 3 unidades a r20 10 veces y enviar la suma total al puerto B.
-----------------------------------------------------------------------------------------------------------------------------------------------------

Código
al final de haber pasado los 10 veces el valor de R20 es 30 (0x1E) reflejada en el puertob
Diagrama de Flujo

domingo, 18 de noviembre de 2018

Uso de la instrucción "IN","OUT"

IN( IN from I/O location)

Carga el dato de las ubicaciones de la dirección SFRs-A[I/O(puertos, Timers,Configuration, etc)] hacia registro Rd[GPRs]. A es un byte(8 bits).
Instrucción IN

Trabajar con los registros de entrada salida(I/O) es mas facil, nosostros podemos usar sus nombres en lugar de sus direcciones (I/O). 

Ejemplo

------------------------------------------------------------------------------------------------------------------------------------------------------
;Cargar en R19 el contenido de PIND.
------------------------------------------------------------------------------------------------------------------------------------------------------
IN R19,$030; Se carga R19 con PIND, usando la direccion del registro.
IN R19,PIND; Se carga R19 con PIND,usando el nombre del registro.

Acceso a SFRs usando sus nombres.
OUT( OUT TO I/O location)
Carga un registro GPRs(R0-R31) hacia un Registro SFRs A[I/O(puertos, Timers,Configuration, etc)].

Instrucción OUT
Los registros I/O son referidos por sus direcciones I/O. 

La instrucción "OUT" realiza la operación contraria de la instrucción "IN".

Ejemplo

------------------------------------------------------------------------------------------------------------------------------------------------------
; Copiar PIND hacia PORTA.
------------------------------------------------------------------------------------------------------------------------------------------------------

IN R0,PIND; Se carga R0 con PIND, usando la direccion del registro.
OUT PORTA ,R0; Se carga PORTB con el valor de R0.



Uso de "SBI" y "CBI"

SBI(Set Bit in I/O Register)
Coloca el nivel alto(setea) a un bit de un registro de entrada/salida.

CBI(Clear Bit in I/O Register)
Coloca el nivel bajo(limpia) a un bit de un registro de entrada/salida.

Ejemplo

------------------------------------------------------------------------------------------------------------------------------------------------------
El objetivo de este ejemplo es leer el estado de un bit mediante un switch conectado por el pin PB0 y un led en el pin PB7 que reflejará el estado del PB0.
-----------------------------------------------------------------------------------------------------------------------------------------------------

Código
SBIS=1,SBI portb,7

SBIS=0,CBI portb,7
Diagrama de Flujo
Implementación

sábado, 17 de noviembre de 2018

Uso de la instrucción "SBIC"

SBIC(Skip if Bit in I/O register Cleared)
Esta instrucción permite monitorear el estado de un bit, salta a la siguiente instrucción del código si en el bit del registro es detectado el estado bajo("0").
Esta instrucción trabaja con registros I/O.

Instrucción SBIC
I/O R ≤ 31, 0 ≤ b ≤ 7
Ejemplo:
un switch es conectado a pinb2. Escribir un programa que chequee el estado del switch y ejecute lo siguiente:
  • Si pinb,2=1 enviar la letra "00000000" al puerto D.
  • Si pinb,2=0 enviar la letra "11111111" al puerto D.
Código
Pinb,2=0
Pinb,2=1

En este programa el bucle led_encendido esta en lazo cerrado siempre cuando(pinb2=0) es decir después que se ejecute la instrucción sbic pinb,2 va a ver un salto de linea a la siguiente instrucción de código y de esta manera se omite(rjmp) la bifurcación para salir del bucle y además se carga el valor de 255 y luego se escribe en el puerto D. 
Cuando hay bifurcación(rjmp) se carga el valor de 0 y se escribe en el puerto D



Diagrama de flujo

Implementación

miércoles, 14 de noviembre de 2018

Uso de la instrucción "SBIS"

                                                SBIS(Skip if Bit in I/O register Set)
Esta instrucción permite monitorear el estado de un bit, salta a la siguiente instrucción del código si en el bit del registro es detectado el estado alto("1").
Esta instrucción trabaja con registros I/O.
Instrucción SBIS
I/O R ≤ 31, 0 ≤ b ≤ 7
Código.
En este programa el bucle inicio esta en lazo cerrado siempre cuando(pinb2=1) es decir después que se ejecute  la instrucción sbis pinb,2 va a ver un salto de linea a  la siguiente instrucción de código y de esta manera se omite(rjmp) la bifurcación para salir del bucle y además se carga el valor de 255 y luego se escribe en el puerto D. 
Cuando hay bifurcación(rjmp)  se carga el valor de 0 y se escribe en el puerto D.

pinb2=0. 
pinb2=1


Diagrama de flujo.
Implementación.

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...