Está en la página 1de 12

RESPUESTAS PARA AVR

¿Porqué usar R16 y cómo usar los registros de propósito general?

Puedes usar cualquier registro del R0 al R31 (dos bancos de registros de usuario que van de R0 al
R15 y de R16 a R31), pero dependiendo de la instrucción a usar a veces solo se usan los registros
R16 al R31, en otras instrucciones puedes usar todos los registros.

Como las instrucciones LDI que son las más usadas trabajan sólo con los registros R16 al R31,
pues empiezas a usar el R16, aunque puedes usar cualquier otro, como ejemplo: LDI R28,$FF, ó
LDI R16, $FF.

¿Pero porqué usar desde el inicio a R16 y no cualquier otro?

Un buen programador habitualmente empieza a usar R16 para configurar al AVR, después en a
zona del Main puedes seguir usando R16, y luego R17, así sucesivamente.

Un mal programador podrá usar un registro cada vez que escribe una nueva línea de código, y de
esta forma –aunque no es un error de sintaxis, se habrá terminado todos los registros muy rápido.

Un buen programador le saca provecho a cada registro, los usa lo más posible.

Un buen uso de los registros es este: por ejemplo, R16 se usa para toda la configuración de AVR;
se usa para almacenar datos no muy importantes como cargar registros de configuración; a R16
muchos programadores lo apodan como TEMP (de temporal).

R17 lo puedes usar para anidar datos de máscaras o lectura de puertos, R18 para conteos, etc.

R0 al R5 para hacer retardos.

Todo esto son ejemplos de cómo puedes usar los registros.

Un buen programador con experiencia se dará cuenta si un código lo escribió alguien que sabe o
no programar con tan sólo ver cómo administraste los registros. Claro, saberlos administrar
requiere de experiencia, algo que irás adquiriendo con la práctica.

En códigos muy largos, normalmente ya usaste todos los registros, por lo que se quedan con los
brazos cruzados porque ya no tienen de donde sacar más registros, siendo el caso, hay otras
técnicas que te ayudarán a usar otras herramientas como la memoria SRAM.

A veces hay que imprimir el código y literal, en el piso vas marcando para qué usas cada registro y
si se puede usar en otro lado sin que interfiera con su aplicación o se cruce con alguna otra función
en otra parte del código –algo, repito, que irás adquiriendo con la práctica.

Registros Stack Pointer SPL y SPH

Cuando ya estás usando instrucciones de salto como RCALL, es necesario configurar la posición
del cursor (memorizarla) ya que en las subrutinas de salto el cursor puede no regresar a dónde
debe y se irá a cualquier otro lado, para evitar esto, se configura a lo que se le llama como Stack
Pointer (SP).

El SP dependiendo del modelo del AVR puede ser de 8 ó 16-bits; en el caso del ATtiny2313 el SP
es de 8-bits, y en el caso del ATmega8515 es de 16-bits. Para saber de cuántos bits es el SP en un
modelo en particular, deberás abrir el manual de ese AVR y checarlo.

Cómo el SP usa la parte más baja de la memoria SRAM, a esta región se le llama RAMEND (final
de la RAM), cuyo valor no conocemos (a menos que abras el manual y lo verifiques), pero como
no lo conocemos, una forma práctica es usar la palabra exclusiva RAMEND que va a extraer el
valor de la memoria SRAM baja.

El valor de RAMEND puede ser de 8 ó 16-bits (como ya se mencionó), para extraer el valor de
RAMEND se usa un byte bajo y un byte alto con las directivas LOW y HIGH, por lo que para el
ATtiny2313 se usa (porque su SP es de 8-bits):

LOW(RAMEND)

Y para el ATmega8515 se usa (porque su SP es de 16-bits):

LOW(RAMEND)
HIGH(RAMEND)

El uso constante del SP hace que se vaya usando la memoria SRAM de forma regresiva, por lo
que ocupará más localidades de memoria de la SRAM.

Hay otras técnicas más avanzadas para fijar la posición del cursor en la SRAM en otra dirección
que no sea la baja, o mantener al SP en unas cuantas posiciones, pero esto demanda mucha más
experiencia.

¿Qué tipo de programador usar?

Puedes usar cualquier programador siempre y cuando las especificaciones de ese programador
digan que puede programar el modelo de AVR que deseas programar, para ello, pregúntale al
proveedor la lista de AVR’s que se pueden programar con su programador y en qué versión de
AVR Studio funciona, ya que, hay programadores que pueden trabajar en cualquier versión y otros
más modernos sólo con el ATMEL Studio 7.

Comprar libros

El libro 1 en electrónico está en venta por la página oficial de AlfaOmega tanto físico como la
versión electrónica.

Esta es la liga:

https://www.alfaomega.com.mx/default/catalogsearch/result/?q=curso+practico+para+programaci
on+de+AVR
El libro 2 en electrónico está en venta por Amazon y el físico yo lo auto-publico y te lo puedo
mandar:

Esta es la liga para adquirir el libro 2 en electrónico formato Kindle:

https://www.amazon.com/Curso-Pr%C3%A1ctico-para-Programaci%C3%B3n-AVR-
ebook/dp/B08LD289K2/ref=sr_1_1?dchild=1&keywords=ernesto+paredes+martinez&qid=16154
35209&sr=8-1

El libro 3 aun no lo termino, pero ya pronto.

Yo tengo los libros físicos en $500 pesos más envío.

En caso de que en tu país no se pueda accesar a la compra del libro, entonces notifícame y te paso
al responsable directo de Alfa Ogema para que se pongan de acuerdo.

Contenido de libro 1 y 2

El curso 1 está pensado para que aprendas a programar el AVR, también vienen varios proyectos.

El curso 2 está pensado para continuar aprendiendo a usar el AVR y vienen proyectos más
avanzados.

Este es el contenido del libro 1 y 2:

Curso 1
https://www.youtube.com/watch?v=1YU41qfwLlQ

Curso 2
https://www.youtube.com/watch?v=vMxx4KvcaJ4&t=327s

Ocasionalmente subo a mi canal de Youtube cupones de descuento para los cursos de UDEMY

Porqué no funciona el UART en Proteus?

En el protoboard (aplicación real) el UART si funciona, sin embargo, en Proteus a veces no


funciona como debería… no manda datos.

Es un problema de simulación, el cual he tratado de hacer varios ajustes a ver si se deja pero aún
no encuentro una solución… hay que seguir trabajando en ello.

También cuando quieres simular LCD en Proteus no funciona, solución que ya encontré, pero para
UART todavía no.
Migrar de un código a otro

Se puede migrar cualquier código a cualquier AVR sólo basta que se usen los nombres de sus
registros de configuración correspondientes de un AVR a otro. La lógica es la misma.

En mis libros uso normalmente el M8515 y TN2313 porque son los denominados clásicos, y el
M328p lo usamos después porque es más avanzado. Es más fácil aprender AVR con los clásicos y
luego migrar al M328p que al revés.

En el caso del M328p como tiene una extensión de memoria hay también un cambio de
instrucciones para algunos registros de configuración (IN, OUT, por LDS, STS).

Para darte un ejemplo de cómo migrar un código al Mega328p te dejo este video:

https://www.youtube.com/watch?v=ciU3H3tFlhM&t=137s

Así que sí puedes trabajar el libro 1 y 2 y migrar al M328p...el libro 2 tiene más proyectos para M328p

Kit de programación

El Kit consta de una tarjeta para programar varios modelos de AVR y un programador clon
AVRISP MKII:

1. (AVR’s clásicos) AT90S2313 y AT90S8515,


2. MEGA16
3. MEGA8515
4. MEGA8535
5. TINY12
6. TINY13
7. TINY15
8. TINY22
9. TINY25
10. TINY45
11. TINY85
12. TINY2313
13. MEGA32
14. MEGA8
15. MEGA48
16. MEGA88
17. MEGA168
18. MEGA328P

El programador MKII puede trabajar muchos modelos de AVR.

La tarjeta programadora ayuda a que por medio de un zócalo ZIF es más práctico quitar y poner el
AVR para programarlo en segundos y evitar un corto circuito en caso de querer manipular
directamente el conector del programador con jumpers hacia el protoboard.
El AVRISP MKII se supone que puede trabajar con la versión AVR Studio 4 pero rara vez
funciona (depende del Windows y de otras características), pero trabaja perfectamente con el
ATMEL Studio 7 sin ningún problema.

Revisa el manual en la siguiente liga para que veas las funciones del Kit:

https://1drv.ms/b/s!AufbM-Rqu-11h_5HZWFUnm5iOgtinQ

El Kit cuesta:
Libro 1 ó 2 + Tarjeta programadora + AVRISP MKII +M328p por $2,300.00 mn más envío.

Ya no funciona el programador en AVR Studio

Si estas usando el AVR Studio 4 con el programador AVRSIP y deja de funcionar, puede ser el
driver del programador, hay que desinstalarlo y volverlo a instalar.

Si estas usando el AVR Studio 4 con el programador MKII y deja de funcionar, puede ser el driver
del programador, hay que desinstalarlo y volverlo a instalar. Pero en ocasiones puede ser alguna
actualización de Windows que corrompió la comunicación con el MKII. Para tal falla aun no
encuentro la solución.

Si estas usando el ATMEL Studio 7 con el programador AVRSIP no permite que funcione debido
a que la versión 7 pide programadores más modernos como el MKII.
Si en la versión 7 deja de funcionar el MKII, hay que desinstalar el driver y volverlo a instalar.

solución
https://www.youtube.com/watch?v=cCfZ-qTPv10

Problemas en la ventana de Watch ATMEL Studio 7

The other suggestion could be to use 'Add Watch' to the variables so that it can be seen in the
watch window.

Or you can migrate to the MPLAB X IDE for better debugging experience.

https://www.microchip.com/en-us/development-tools-tools-and-software/mplab-x-ide

Install the MPLAB X IDE and import this Atmel studio project to the MPLAB X directly and then
you can debug it from MPLAB X IDE.

En la V7 ya no es amigable el uso de la ventana Watch a comparación de la V4 que es muy


amigable (basta con escribir el nombre del registro a visualizar).

En el caso de la V7, ya no funciona de la misma forma que en la V4, por lo que hay que escribir
ahora como “apuntador” usando el ASTERISCO y la dirección del registro a visualizar:
Por ejemplo, si deseamos visualizar el TCNT0, escribiremos en la ventana de Watch:

*(BY 0x52)

Trabajar con el M328p en todos los proyectos?

Este AVR posee algunos cambios de programación debido a que contiene una extensión en la
memoria interna ciertas instrucciones han sido reemplazadas; según el manual del Atmega328p,
algunas instrucciones cómo “IN”, “OUT”, “SBIS”, “SBIC”, “CBI”, and “SBI” deben ser
reemplazadas por instrucciones que permitan el acceso a la parte extendida de entrada salida I/O.
Típicamente, “LDS” y “STS” serán combinadas por “SBRS”, “SBRC”, “SBR”, y “CBR”.

Si usáramos las instrucciones tradicionales IN-OUT para cargar registros de propósito general,
para leer o cargar datos de registros I/O, es posible que en algunas líneas de código se observe
“error: Operand 1 out of frange: 0xc0”, el número de operando que aparece en el
error y la dirección (que en este caso se presentó 0xc0), dependerá de la instrucción usada y del
registro I/O usado, por ejemplo, hay ciertas instrucciones que funcionarán con OUT, pero habrá
otras que lo harán con STS, cómo en este caso; si de la línea de código que expresa “STS
UCSR0A,R16” cambiamos la instrucción STS por OUT (que era la instrucción común), el error
de operando se mostrará (que es el ejemplo anterior de 0xc0). Observando el código de este
proyecto, iremos denotando la sustitución de las instrucciones.

Para el caso de la instrucción “IN” se usará “LDS” (LDS R30,ADCL).

En el manual del ATmega328p, en cada registro se muestra una dirección de Offset, que indica la
dirección de error que será desplegada en la ventana Build del AVR Studio 4.0, por esto, es
necesario que cuando usemos el ATmega328p estemos compilado constantemente el estado de la
ventana Build.

En algunos casos, aunque en la ventana de Build no aparezcan errores, es importante que hagamos
la simulación y verifiquemos en el árbol de funciones del AVR (columna derecha del AVR Studio
4.0) si los registros de propósito general y de I/O se cargan debidamente, en ocasiones, los
registros no se cargan debidamente, ello indica que la instrucción usada en esa línea de código no
tiene la instrucción correcta (aunque no marque error en la ventana Build). El ATmega328p es
muy quisquilloso en este sentido.

Para la carga del Stack Pointer, carga de registros DDRx, y carga de registros de usuario (R00-
R31), podemos seguir usando LDI y OUT:
Este es el programa para leer el movimiento de acelerómetro analógico:

;PROGRAMA QUE LEE EL MOVIMIENTO DE UN ACELERÓMETRO ANALOGICO


;LAS LECTURAS SERÁN HECHAS POR EL CONVERTIDOR A/D DEL ATMEGA328p
.INCLUDE "M328PDEF.INC"
.CSEG
.ORG 0

LDI R16,LOW(RAMEND)
OUT SPL,R16
LDI R16,HIGH(RAMEND)
OUT SPH,R16

LDI R16,0b0000_0110 ;PUERTOS SI LO CONFIGURO IGUAL


OUT DDRB,R16

LDI R16,0b0111_0000
OUT DDRD,R16

;CONFIGURACIÓN DE USART

LDI R16,0<<U2X0
STS UCSR0A,R16 ;UART YA NO ES "OUT" SINO "STS

LDI R16,1<<TXEN0|0<<RXEN0|0<<UCSZ02
STS UCSR0B,R16

LDI R16,0<<UMSEL01|0<<UMSEL00|0<<UPM01|0<<UPM00|0<<USBS0|1<<UCSZ01|1<<UCSZ00
STS UCSR0C,R16

LDI R16,51 ;PARA 9600 BAUDS A 8MHZ


STS UBRR0L,R16

LDI R16,0
STS UBRR0H,R16

;****PWM***
// PWM FAST MODE

LDI R16, 1<<COM0A1|0<<COM0A0|0<<COM0B1|0<<COM0B0|1<<WGM01|1<<WGM00


OUT TCCR0A,R16 ;Clear OC0A on Compare Match...REG. OCR0A (SALIDA
OC0A)

// PWM MODE -- NO PRESCALING CLK....REG. OCR0A (SALIDA OC0A)

LDI R16, 0<<WGM02|0<<CS02|0<<CS01|1<<CS00


OUT TCCR0B,R16

LDI R16, 1<<COM1A1|0<<COM1A0|1<<COM1B1|0<<COM1B0|0<<WGM11|1<<WGM10


;Clear OC1A/OC1B on Compare Match (Set output to low level)...PWM 8-BITS
STS TCCR1A,R16

LDI R16, 0<<WGM13|1<<WGM12|0<<CS12|0<<CS11|1<<CS10


STS TCCR1B,R16

;**********

;**** REGISTRO DE SELECCION DE CANAL Y REFERENCIA ***

LDI R16,1<<ADEN|1<<ADSC|1<<ADATE|0<<ADPS2|1<<ADPS1|1<<ADPS0
STS ADCSRA,R16 ;SE USA "STS" EN LUGAR DE "OUT"

LDI R16,0<<ACME|0<<ADTS2|0<<ADTS1|0<<ADTS0 ;FREE RUNNING


STS ADCSRB,R16 ;SE USA "STS" EN LUGAR DE "OUT"

LDI R16,1<<ADC0D|1<<ADC1D|1<<ADC2D
STS DIDR0,R16 ;SE USA "STS" EN LUGAR DE "OUT"

;**** COMIENZA PROGRAMA PRINCIPAL ***

LEER_MOVIMIENTO:

;PARA LECTURA DEL EJE-Z


LDI R16,0<<REFS1|0<<REFS0|0<<ADLAR|0<<MUX3|0<<MUX2|0<<MUX1|0<<MUX0
STS ADMUX,R16 ;SE USA "STS" EN LUGAR DE "OUT"

LDS R30,ADCL ;SE USA "LDS" EN LUGAR DE "IN"...8-Bits


LDS R29,ADCH ;SE USA "LDS" EN LUGAR DE "IN"...2-Bits

RCALL UART_LISTO
RCALL LETRA_Z
RCALL UART_LISTO
RCALL SIGNO_IGUAL

RCALL UART_LISTO
STS UDR0,R30 ;UART DATA

RCALL UART_LISTO
STS UDR0,R29 ;UART DATA

RCALL UART_LISTO
LDI R16,' '
STS UDR0,R16 ;UART DATA
;********************
;RED
;LDI R16,0
;STS OCR0A,R16

OUT OCR0A,R30 ;PIN 12

RCALL UN_SEGUNDO

;********************

;PARA LECTURA DEL EJE-Y


LDI R16,0<<REFS1|0<<REFS0|0<<ADLAR|0<<MUX3|0<<MUX2|0<<MUX1|1<<MUX0
STS ADMUX,R16

LDS R30,ADCL ;SE USA "LDS" EN LUGAR DE "IN"...8-Bits


LDS R29,ADCH ;SE USA "LDS" EN LUGAR DE "IN"...2-Bits

RCALL UART_LISTO
RCALL LETRA_Y
RCALL UART_LISTO
RCALL SIGNO_IGUAL

RCALL UART_LISTO
STS UDR0,R30 ;UART DATA

RCALL UART_LISTO
STS UDR0,R29 ;UART DATA

RCALL UART_LISTO
LDI R16,' '
STS UDR0,R16 ;UART DATA
;********************
;GREEN
;LDI R16,0
;STS OCR1AL,R16

STS OCR1AL,R30 ;PIN 15

RCALL UN_SEGUNDO

USART_Receive:
; Wait for data to be received
LDS r16, UCSR0A
sbrs r16, RXC0
rjmp USART_Receive
RET

;LDS r16, UDR0

USART_Transmit:
; Wait for empty transmit buffer
LDS R18, UCSR0A
SBRS R18, UDRE0
rjmp USART_Transmit
RET

Que significan los operandos del “SET SUMMARY2”

Ese "set summary" en realidad es un compilado de set de instrucciones que usan los AVR. Para
que lo entiendas mejor, abre el AVR Studio 4, abre cualquier proyecto, pulsa F1 (ayuda) y cuando
se abra la nueva ventana de ayuda te va a aparecer una columna de instrucciones (izquierda). por
ejemplo, dale 2 clicks a la instrucción ADD (ADD - Add without Carry) y te aparece esto:

Significa:

Rd es "Regiter destiny" (registro destino)

Rr es "Regiter root" (resgitro origen)


La sintaxis "ADD Rd,Rr" significa entonces que si tienes "ADD R16,R17" ...R17 (origen) se
sumará a R16 y el resultado queda en R16(destiny).

La sintaxis "0<d<31 , 0<r<31" significa que puedes usar para el registro destiny de R0 a R31, y
para el registro "root" puedes usar del R0 al R31

Instrucciones como BREQ

te aparece esto:

en este caso "K" significa la posición a la que quieres saltar (BREQ k seria entonces "salta a la
etiqueta "k").

-64<k<+63

significa que esa etiqueta o salto solo se puede dar 64 lineas abajo del código o 63 lineas arriba del
codigo.

Intrucciones como "RJMP" puede salta 2k (2mil) lineas arriba o abajo de donde se invoca.

Intrucciones como "LD" implica a registros concatenado de 16-bits llamados registros X,Y y Z
respectivamente.

Entonces

X+

-X

Y+

-Y

Z+

-Z

implica que son post-incremento (+) o pre-decremento (-)


es decir, cada vez que usas un "+z" estas diciendo que la dirección actual del registro Z se
incrementó en "uno", etc.

Con estas bases que te explico trata de decifrar los demás operandos, ya que explicarte todos sería
explicarte cada instrucción y son un buen.

¿Cómo se calculan los valores del decremento para el Delay?

Para hacer retardos existen varias formas o técnicas:

1) Técnica por decremento de registros.

Las subrutinas que comparto en los cursos las he editado desde hace mucho atrás, a ciencia cierta
yo he sido más intuitivo (a prueba y error) para hacer el ajuste de las subrutinas por el método de
decremento de registros. De los cuales tengo varios que siempre se usan. En esta técnica
normalmente se usan de 2 a 5 registros y con la simulación vas ajustando los valores.

2) Técnica por T/C

Una segunda técnica que si requiere cálculo y es muy precisa es usando los T/C (sea el cero o el
uno). Usamos esta fórmula:

T deseado
valor del TCNTx =
TAVR * Pr e − escalamien to

Entonces, por ejemplo:

Si deseamos hacer un retardo de 2 segundos, vamos a ver cuál T/C conviene y qué pre-
escalamiento (o sin pre-escalamiento). Supongamos que usaremos un AVR a una frecuencia de
oscilación de 8Mhz, entonces:

1 1
T= = = 0.125 x10 −6
F 8Mhz

Entonces, veremos si el valor del TCNTx está dentro de su rango (255 para el T/C0 y 65535 para
el T/C1), si no lo está, usaremos el pre-escalamiento:

T deseado 2seg
valor del TCNTx = = = 16000000
TAVR * Pr e − escalamien to 0.125 x10 −6 *1

Como 16,000,000 es un valor más alto de 65535 entones usaremos pre-escalamiento (nos
conviene usar el pre-escalamiento de 256 ya que menor no nos sirve):

T deseado 2seg
valor del TCNTx = = = 62500
TAVR * Pr e − escalamien to 0.125 x10 −6 * 256

Esto significa que el TCNT1 se cargará a 62,500 y usando el comparativo (o por interrupción por
desbordamiento) cuando el TCNT1 llegue a 62,500 ya hemos hecho un retardo de 2 segundos.
Esta fórmula aplica para retardos de mili-segundos por ejemplo.

3) Otras técnicas

Para retardos más grandes, se puede usar un ciclo FOR, o se pueden concatenar más registros de
propósito general al T/C0 o al T/C1 para incrementar el valor del TCNTx.

Qué hacer cuando no se puede ejecutar el programa (“Bloqueado por el administrador”)

Windows toma gestión sobre los programas a instalar, en ocasiones muestra un cuadro de diálogo
diciendo que el ADMINISTRADOR ha bloqueado la aplicación, lo cual es FALSO, por
consigiente hay que configurar en REGEDIT una secuencia para que se pueda instalar un
programa (AVR Studio):

Equipo\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\
System>> ENABLE LUA (cambiar el valor de 1 a 0) >>>> reiniciar la PC y ejecutar
nuevamente el instalador del programa.

También podría gustarte