lunes, 30 de mayo de 2011

TIMER 1

En éste post mostraré un pequeño ejemplo de como configurar el timer 1 (16 bits) para tener una gran variedad de bases de tiempo, las cuales pueden ser usadas para generar retardos, pulsos a una determinada frecuencia, etc.

Programa : TIMER

Sin mas preámbulo pasaré a mostrar las macros usadas.


A ésta macro solamente hay que indicarle el tiempo con el cual se quiere configurar el timer (en ms).
El pre-escaler del timer se puede cambiar modificando CSN.

macros2

MOVIF pone un inmediato en la RAM, ya sea en el espacio de datos o en el espacio de registro especiales.

El programa principal es el siguiente:

main1

Esta parte configura dos pines como salidas (PB0 y PB1), también configura el TIMER 1 a 100ms, configura el pre-escaler del timer y por ultimo habilita la interrupción por desborde u overflow.

main2

Cada vez que el timer se desborda se conmutará los pines PB0 y PB1, y también hay que volver a configurar el timer.

En el siguiente video se muestra el funcionamiento del programa.


sábado, 21 de mayo de 2011

Manejo del WDT

A diferencia de otros uC’s en los ATmega el WDT se puede habilitar y deshabilitar por programa, pudiendo cambiar el tiempo de reset a voluntad.

En éste post mostraré como habilitar y deshabilitar el Watch Dog Timer en cualquier ATmega.

En nuestro archivo de macros tenemos que agregar el siguiente codigo. (Link al programa)

wdt1

Estas definiciones no son aplicables a todos los ATmega, en un ATmega8 solamente de puede llegar a 2 segundos mientras que en un ATmega324P se puede llegar hasta 8 segundos.

wdt2

La macro anterior permite habilitar el wdt.

wdt3

La macro anterior permite deshabilitar el wdt.

Ahora mostrare en sencillo ejemplo de su uso.

wdt4

sábado, 2 de abril de 2011

I2C en ATmega8

En éste post mostrare un par de ejemplos de como usar el bus i2c para escribir y leer datos en una memoria EEPROM serial (24C16).
La memoria 24C16 tiene una capacidad de 2048 bytes agrupados en 8 páginas de 256 bytes cada una.
Todos los esclavos del bus i2c tienen una dirección la cual les permite ser seleccionados; en el caso de estas memorias seriales la dirección es en parte configurable o fija, esto dependerá del fabricante. En el siguiente gráfico se muestra dos memorias de fabricantes distintos.

Programas

eeproms

La primera es una memoria de ATMEL, la cual permite configurar parte de la dirección mediante los pines A2, A1 y A0; los bits B2B1B0 son usados para seleccionar la pagina de la dentro de la memoria.
La otra es una memoria de FAIRCHILD, ésta ya trae parte de dirección fija(1010), los bit A2A1A0 permiten seleccionar la pagina de la memoria a la cual se accederá.
La velocidad del reloj para esto dispositivos se indica en sus hojas de datos, en los ejemplos usaremos 100KHz. Para configurar dicha velocidad se usa la siguiente formula, la cual se puede encontrar en el manual de del uC que se usara, yo la obtuve del manual del ATmega8.
 formula

La forma de escribir  datos es la siguiente:

write

Se inicia la transmisión con un “START”, luego se selecciona el esclavo “DEVICE ADDRESS” en modo de escritura “0”, después del “ACK” enviado por el esclavo se enviara la dirección donde se escribirá “WORD ADDRESS”, por último se envía el dato a escribir. Hay que cada ciclo de escritura tiene una duración, éste tiempo dependerá del dispositivo.

La forma de leer datos es la siguiente:

read

Se inicia la transmisión con un “START”, luego se selecciona el esclavo “DEVICE ADDRESS” en modo de escritura “0”, después del “ACK” enviado por el esclavo se enviara la dirección donde se leerá “WORD ADDRESS”, nuevamente se envía un “START” o también conocido como “RESTART”, por último se lee el dato.

Bueno, como ya es costumbre mostrare las macros que usare en estos ejemplos.

macros

Ahora mostrare las rutinas para iniciar y usar el bus i2c.

rutinasi2c1

rutinasi2c2

rutinasi2c3

Ahora el un sencillo ejemplo se escritura y lectura de algunos datos en una EEPROM.

i2c1

El ejemplo no hace otra cosa que escribir algunos datos a partir de la dirección 0x05 de la pagina 0, luego los leerá.

El circuito es el siguiente:

simu_0

Con el uso de debuger i2c se puede ver la transferencia de datos:

simu_2

El final la memoria debe quedar así:

simu_1

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

El segundo ejemplo consiste en enviarle al ATmega8, por el uart, un comando para que éste lea o escriba en la EEPROM.

‘W’+PAGINA+DIRECCIÓN+DATO se usara para escribir en la EEPROM.
‘R’+PAGINA+DIRECCIÓN se usara para leer en la EEPROM.

Por ejemplo si se envía por el uart ‘W’ 0x06 0x66 0x99 el uC escribirá en la dirección 0x66 de la pagina 6 el dato 0x99. Y si enviamos ‘R’ 0x03 0x79 estaremos leyendo el datos que esta guardado en la posición 0x79 de la pagina 3.

Agregaremos algunas rutinas al archivo RUTINAS_I2C.asm:

rutinasi2c4

Las rutinas usadas en el uart son las siguientes:

uart1

uart2

El programa principal es mostrado a continuación.

i2c2

Ahora les mostrare un vídeo con el funcionamiento del programa anterior.

En el vídeo se escribe 0x99 en la dirección 0x66 de la página 6 (dirección absoluta en la memoria es 6*0x100 + 0x66 = 0x666), luego éste dato es leído. También se escribe 0x58 en la posición 0x67 de la misma página.

viernes, 18 de marzo de 2011

Manejando Display 7-seg

Ahora mostrare un sencillo programa que muestra una cuenta ascendente de cuatro dígitos, que se almacenan en memoria (CUENTA1:CUENTA2:CUENTA3:CUENTA4), en 4 displays de 7-segmentos.

Link Programa

Agregaremos una macro más a nuestro archivo macros.inc:

MACRO

MOVIF toma un inmediato (@1) y lo guarda en una posición de memoria (@0).

El programa tiene dos rutinas, una llamada muestra y otra llamada incrementa.

Muestra toma cada dígito y lo envía a su respectivo display. También genera un retardo antes de pasar el siguiente display, ya que esto permite visualizar el dígito.

Incrementa va aumentando en 1 el valor de la cuenta, la cuenta será de 0-9999.

prog1

prog2

El circuito en el cual se usan displays con ánodo común es el mostrado abajo.

DISPLAY

En el siguiente vídeo se muestra la simulación del programa, aunque no se aprecia muy bien debido al programa de captura.


lunes, 7 de marzo de 2011

ADC - Analog-to-digital Converter

El ADC en los ATmega, cómo en otros uC´s de 8bits, tiene una resolución máxima de 10bits. Dependiendo de el uC se encontrara un número diferente de canales simples o diferenciales.
La formula clásica para convertir el valor que se obtiene de los registros ADCH:ADCL es:

Vin=5*(ADCH:ADCL )/1024

5/1042 es aproximadamente 48828e-7, entonces Vin=((ADCH:ADCL )*48828)e-7.

Ahora mostrare un ejemplo de la configuración del ADC en un ATmega324P.
Agregaremos unas macros a las nuestro archivo macros.inc:

macros

La macro “PUTM” no hace otra cosa que obtener el valor de una posición de la ram y enviarlo al LCD.
Las otras dos macros realizan una multiplicación como es indicado. Estas se usan para multiplicar ((ADCH:ADCL )*48828).
También se ha usado una rutina para convertir el resultado de la multiplicación a código ascii, esto es para poderlo mostrar en el lcd.

ascii

Antes de llamar a esta rutina Z debe apuntar al dato que se quiere convertir (LSB), Y debe apuntar a la posición de la ram donde se quiere guardar los datos en ascii (MSB).

El programa principal es el siguiente:





SELEC_CH recibe en R16 el canal que se muestreara, luego de escoger el canal se habilita el conversor (ADEN) y se inicia la conversión (ADSC).
ESPERA_ADC esperará hasta el final de la conversión.
CALCULA_VOL obtiene los 10 bits de la conversión en R17:R16 y lo multiplica con R19:R18=48828, luego ese valor convertido la convierte a código ascii y lo pone en la ram (Y=0x0100).
El resultado de la simulación es el mostrado:

fig1

En la ram se puede ver uno de los valores en ascii (000023486268=23486268). La coma decimal debe correr 7 posiciones (debido al factor e-7), entonces el voltaje es 2.34862.


martes, 1 de marzo de 2011

“delay_ms(ms)” y “delay_us(us)” para cualquier frecuencia

En un post anterior mostré como generar una rutina de retardos en milisegundos, ésta rutina funcionaba muy bien pero el problema era volver a calcular valores para una frecuencia diferente.
Ahora mostrare otra rutina que junto con sus macros permiten tener retardos en milisegundos y microsegundos, pero a diferencia de la anterior ya no hay que calcular valores para generar los retardos, solamente se deberá cambiar la frecuencia a la cual se trabajara (F_CPU).

Esta rutinas pueden soportar valores de 0-65535. Descarga

Las rutinas y las macros son las siguientes:

macros

retardo

Su uso es muy sencillo, aquí se muestra:

main

Los resultados los puede ver en la parte izquierda del simulador.

cpu

Espero éste sencillo ejemplo les sea útil.

sábado, 19 de febrero de 2011

KEYPAD Y LCD

En el post anterior les mostré las rutinas para en manejo de un LCD y algunos ejemplos del manejo de dichas rutinas. Descargar

Ahora les mostrare la rutina de escaneo de un KEYPAD 4x4 y mostrar la tecla presionada en el LCD.
Editando esta línea “.EQU    PUERTO_KEY = PORTA” se puede cambiar el puerto que se usara para el KEYPAD. Al final de de éste archivo se encuentra la tabla con los valores ASCII de cada tecla. La rutina espera que la tecla sea soltada y retorna el valor en R16.

keypad

Además de las macros usadas en el post anterior usaremos ésta otra macro:

macros1

Ahora mostrare un ejemplo de su funcionamiento.

keypadeje

Esta rutina muestra los mensajes MENSAJE_1, MENSAJE_2, MENSAJE_3 y MENSAJE_4 y luego de esperar una tecla limpia el LCD, luego posiciona el puntero del LCD a la línea 1 y espera una tecla y la muestra. Luego de 20 teclas pasara a la siguiente línea.

key1

key2

La siguiente figura muestra como usar otro tipo de teclado.

key3

En el programa solamente deberán cambiar lo siguiente.

key4

Eso es todo por ahora, espero estos ejemplos los ayuden.


miércoles, 16 de febrero de 2011

MANEJO DE LCD ALFANUMERICO

Teniendo en cuenta la importancia que tiene mostrar determinada información cuando se hace diseños en base a uC´s  hoy les daré las rutinas necesarias para el manejo de un LCD y algunos ejemplos de su uso. Descargar
En la siguiente figura se muestran las macros que se usaran mas adelante.

macros

- SETZ setea un valor al puntero Z (ZH:ZL ó R31:R30).
- PUTC imprime un carácter.
- PUTV imprime el valor de un registro.
- CMD_LCD envía un comando al LCD.
- PRINTF_LCD imprime un string ( debe estar almacenado en la flash ). Éste string debe terminar en un 0.

Ahora pasare a mostrar la rutina de comunicación con el LCD.

En ésta primera parte de la rutina de muestra las definiciones de algunas variables y algunas constantes. Cuando se quiera usar un puerto diferente del predefinido ( PORTC ) solamente se debe cambiar esta línea “PUERTO_LCD = PORTC”, aquí se deberá poner el puerto que se usara para manejar el LCD.

lcd1

En la siguiente figura se muestra lo restante del archivo LCD.asm.

lcd2

En éste momento no tengo mucho tiempo para explicar estas rutinas, si tienen alguna pregunta por favor escríbanme.
Tanto las rutinas del archivo LCD.asm como el programa principal necesitan la rutinas de retardo, en éste caso pueden usar las rutinas dadas en post pasados ( si no la encuentran me escriben y les enviare el archivo RETARDOS.asm).
Pasaremos a mostrar unos ejemplos muy sencillos del uso de estas rutinas.

ej1

En la simulación veremos lo siguiente:

figej1

En el siguiente ejemplo se llena el LCD con parte del codigo ASCII.

ej2

El ejecución del ejemplo anterior nos mostrara los siguiente:

figej2

Por último mostrare un ejemplo en el cual se imprimirá un string definido en la flash.

ej3

Luego de la simulación veremos los siguiente:

figej3

Buenos amigos, espero les sea útil la información…