sábado, 18 de septiembre de 2010

MACROS

Macros: Las macros asignan un nombre simbólico a un bloque de sentencias fuente. Luego se puede usar dicho nombre para representar esas sentencias. Opcionalmente se pueden definir parámetros para representar argumentos para la macro.


Las macros de definen así:


.MACRO      nombre_de_la_macro
..... instrucciones a ejecutar
.ENMACRO


Un ejemplo de su uso puede ser las instrucciones del inicio de pila.


 Cuando se quiera iniciar la pila solamente hay que colocar INICIA_PILA.


Ya que no se cuenta con una instrucción para Adherir un Inmediato a un Registro (Rn +k), pero sí la instrucción que resta (Rn-k), podemos crear una macro que realice esta operación.


Esta macro de nombre "ADDI"  resta al registro que es identificado por "@0"  el negativo del inmediato "@1", esto es @0 - (-(@1)) = @0 + @1 .  Si queremos sumarle al Registro R19=127 el inmediato 46.
Luego de esto R19=127+46 = 173

Ahora para hacer más manejable el código podemos crear un archivo que incluya todas nuestras macros. Nuestras subrutinas también las pondremos en otro archivo.




Nuestro proyecto final queda.



viernes, 17 de septiembre de 2010

ENLACES DE AYUDA..... SOS

DATA SHEET:

                  


Para mayor detalle sobre las instrucciones ver la hoja de datos de cada uC. También pueden usar la ayuda del AVR STUDIO ( Help --> Assembler Help ).
                              

jueves, 16 de septiembre de 2010

La Pila, llamadas a subrutinas y retardos por software

En esta entrada hablaré de una muy importante como lo es el Stack o Pila, así como de las instrucciones, ya conocidas, PUSH y POP, las llamadas a subrutinas y cómo generar retardos por software.

//*****************************************************************************************************
//*****************************************************************************************************
La Pila en Atmel: Esta estructura es diferente a la de otros uC (por ejemplo los PIC) ya que no cuenta con un hardware dedicado, esto es porque tenemos la libertad de usar toda la capacidad de la RAM ( por ejemplo en un atmega324p tendríamos  como máximo 2K posiciones de pila) . Para poder usar la pila ésta debe ser definida al inicio de cada programa en el cual se use instrucciones como: (RCALL, ICALL, CALL, PUSH, POP, RET, RETI).  La declaración de la pila se hará colocando el valor de inicio de la misma en los registros SPH y SPL (Stack Pointer High y Stack Pointer Low). El valor del SP irá decrementando a medida se llena la pila, y aumentará a medida se va liberando. 
Particularmente recomiendo iniciar el SP a la posición final de la RAM, así no tendremos problemas con las posiciones de memoria que usemos como variables.




En el ejemplo mostrado arriba se puede ver cómo definir la pila a la posición final de la RAM. RAMEND ( Fin de la RAM) es una constante que se encuentra definida en .include "mxdef.inc"  y es diferente para cada uC. Por ejemplo en el atmega8 RAMEND=0x45F=1119.
1119 bytes es mayor que 1K=1024bytes, esto es ya que en la RAM están los 32 Registros de trabajo con los que cuenta este uC además de los registro de entradas/salidas  que sumados dan 0x5F=95 bytes. 32 (registros) + 63(reg i/o) + 1024(SRAM) = 1119 bytes.

LDI R17,HIGH(RAMEND) // R17 <-- 0x04
- Carga Inmediato al registro R17, la funcion HIGH nos devuelve el byte alto de RAMEND= 0x45F 
---> HIGH(RAMEND)= 0x04
LDI R16,LOW(RAMEND)   // R16<-- 0x5F
OUT SPH,R17 // Pone R17 en SPH
OUT SPL,R16               //  Pone R16 en SPL

Finalmente la pila queda definida : SP=0x45F.

RETARDOS:
~~~~~~~~~~
Crear rutinas de retardos siempre es necesario, para ello crearemos una rutina general que nos permita obtener retardos en ms.
    
La idea general es anidar rutinas de este tipo.



Por ejemplo: si tenemos f=16MHz y queremos una rutina de 1ms. 
1ms= (V)(X+4)/16MHz--> para V=250, X=60. X=60 significa que nuestra rutina tendrá 60 instrucciones NOP, para evitar esto aplicaremos el paso anterior a 60 --> 60=(V1)(X1+4) --> V1=12 y X1=1; finalmente obtenemos una rutina que para f=16MHz demora 1ms.

 
Si queremos hacer esto aún más general tendremos que anidar lo anterior en otro bucle, obteniendo lo siguiente:

Para usar esta rutina tendremos que cargar el valor del retardo en R20 y  llamar a la etiqueta RETms.

El siguiente programa hará parpadear un led con algunos retardos.



Si este ejemplo lo simulan con AVR Studio o Proteus pueden ver cómo en el final de la RAM se irán guardando los valores del PC al llamar a la rutina de retardo.

Aquí podemos ver el inicial valor de SP.


Aquí vemos PC=0x000008, en la siguiente instrucción PC=0x000009 se guardará en la última posición de la RAM o memoria de datos
 


Aquí PC saltó a la etiqueta  RETms y la dirección 0x000009 se guardó en el final de la RAM.





domingo, 12 de septiembre de 2010

Depurar codigo en Proteus

Bueno amigos, esta es una parte muy importante del diseño con uC's ( sin importar el fabricante) y una de mis favoritas, esto ya que mediante el uso de Proteus el ahorro de tiempo  es muy alto, Particularmente me ayuda a corregir algunos  errores que pueda cometer en la programación...

//********************************************************************************************************
//********************************************************************************************************
1.- Lo primero que se debe hacer es implementar el circuito con el uC que se quiera usar para la depuración.


2.- Se debe ir a la pestaña Source y dar click en Add/Remove Source files.. 


3.- Se mostrará la siguiente ventana la cual nos permitirá adherir el archivo .asm, para ello daremos click en New. 


4.- La siguiente ventana nos permitirá dirigirnos a la carpeta donde se encuentra el archivo con el código a depurar, en nuestro caso es el archivo LED.asm.


5.- Nuevamente se nos mostrará la ventana del paso 3 pero esta vez el archivo LED.asm ya se encuentra cargado. Daremos click en OK.

Ahora podemos ver el archivo LED.asm en la pestaña Source.



6.- Damos click en Build All, esto compilará nuestro archivo (ya que proteus tiene dentro de sus herramientas el compilador de avr).

Luego se nos mostrará una ventana con el resumen de la compilacion.

7.- Ahora presionamos Clrl+F12 para iniciar el proceso de depuración. Veremos lo siguiente, aquí se puede apreciar una ventana la cual contiene el código a depurar.


En la pestaña Debug encontramos otras opciones que más adelante nos permitirán obtener mas información en el proceso de depuración.

8.- Por último usando la tecla F11 podemos seguir paso a paso la ejecución del código.





miércoles, 8 de septiembre de 2010

Mi Primer Proyecto -ATMEGA8 Y AVR STUDIO 4

Bueno amigos, creo yo que esto es la más básico que se puede enseñar.. así que sin más que  decir veremos cómo prender un led usando un botón con un atmega8.
Antes de ir con el código, mostraré cómo crear un proyecto con el avr studio.
Para ello ya deben tener  instalado el AVR STUDIO, si aún no lo descargan, lo pueden hacer desde este enlace AVR STUDIO 4.18  o desde este otro  AVR STUDIO 4.17
·······> http://www.atmel.com/dyn/resources/prod_documents/AvrStudio4Setup.exe

Antes de pasar al código, les mostraré cómo crear un proyecto:

La primera ventana con las que encontrarán después de abrir el avr studio será la siguiente y en la cual seleccionaremos New Project.



Luego en la siguiente ventana se nos pedirá darle un nombre a nuestro proyecto, así como dónde se desea guardar dicho proyecto; también se nos pregunta si deseamos crear una carpeta específica para nuestro proyecto, la cual llevará el nombre del mismo. Luego daremos click en Next.


En esta ventana se nos pide seleccionar la plataforma de depuración y el dispositivo con el cual trabajaremos. En nuestro caso seleccionaremos la plataforma AVR Simulator y el dispositivo ATmega8. Luego daremos click en Finish.


Por fin nos encontramos en nuestro entorno de trabajo. 


Ahora si podemos iniciar con la programación....


El programa que se muestra como primer ejemplo es el siguiente:



Este programa deberá ser ensamblado usando cualquiera de los siguientes botones : el segundo de estos no permite ensamblar y hacer la simulación de programa.


Explicación de código:

 .include "m8def.inc" --> Contiene todas la definiciones de registros y otros datos del m8=ATmega8, si se trabajará con un ATmega1284p se colocaría  .include "m1284pdef.inc"

.cseg --> O segmento de código, Indica que lo que sigue es el programa que ira en la flash. También existe .eseg o segmento de eeprom (para datos que irán en la eeprom) y .dseg o segmento de datos(para datos que irán en la ram).

.org 0x0000 RJMP INICIO -->Es la primera dirección o la dirección de inicio del programa ( esto siempre debe estar presente para poderle indicar a uC dónde debe ir al iniciar el programa). En nuestro caso haremos un salto incondicional (RJMP INICIO) a la etiqueta INICIO:

SBI DDRB,PB1 --> O Setear Bit en registro I/O permite configurar el pin PB1 como salida. Cada puerto de I/O cuenta con 3 registros: DDRx permite configurar entradas ("1") y salidas ("0"); PORTx permite poner la salida a "1" ó "0" cuando el pin es salida y también permite habilitar("1") la resistencia pull up de dicho pin o deshabilitarla("0") cuando el pin es entrada; PINx permite leer el estado del pin.

//**************************************************************************************
SBIC  PINB,PB0 --> Salta si Bit en registro I/O es Clear 
CBI   PORTB,PB1-->Clear Bit en registro I/O
SBIS  PINB,PB0 -->Salta si Bit en registro I/O está Seteado 
SBI   PORTB,PB1 --> Setear Bit en registro I/O
RJMP BUCLE_INFINITO --> Salto incondicional a la etiqueta BUCLE_INFINITO:
.............................................................
Con esto termino mi primer pequeño ejemplo, espero sea de ayuda... Jonathan r s f 


lunes, 6 de septiembre de 2010

Hablando de Atmega's

Espero esto ayude a los colegas Electrónicos que tienen deseos de aprender a programar microcontroladores de la marca Atmel, especialmente los famosos ATMEGA8 , ATMEGA16, ATMEGA32, ATMEGA64, ATMEGA128, ATMEGA164P, ATMEGA324P. Cito dichos microcontroladores ya que tengo la fortuna de haberlos programado.
Me animé a escribir sobre dichos uC's ya que la información que encontré cuando inicie con el ATMEGA8 fue muy pobre, los libros que son muy pocos no me ayudaron en nada, así que solo emprendí la tarea de aprender a usar las más de 130, y muy buenas, instrucciones con las que cuentan estos uC's...