jueves, 15 de diciembre de 2011

SET CLOCK(SCK) de programación del USBasp con SinaProg 2.0

El USBasp tiene 12 posibles frecuencia de programación, estas son:

1.5 MHz, 750 KHz, 375 KHz, 187.5 KHz, 93.75 KHz, 32 KHz, 16 KHz, 8 KHz, 4 KHz, 2 KHz, 1 KHz y 500 Hz.

Para poder acceder a esas velocidades usando el SinaProg, que a su vez usa el avrdude, debemos modificar el archivo Speed.txt.

El Sinaprog 2.0 lo pueden descargar de este enlace SinaProg 2.0 .

Y en este otro enlace se encuentran los pasos para realizar la modificación. PASOS.
No pongo imagenes ya que en el pdf se encuentra todo lo necesario.

Un saludo y Felices Fiestas…!!!

domingo, 27 de noviembre de 2011

EEPROM INTERNA DE LOS ATMEGA

En este post mostraré un pequeño ejemplo sobre la lectura y escritura de la eeprom interna de los atmega.
En el ejemplo trabajo con un mega8, pero el código es fácilmente aplicable a otros ATmega.

El mega8 tiene 512 Bytes en su eeprom (este tamaño varia con cada dispositivo). Su eeprom solamente permite, además de leer, borrar y escribir en una sola operación (la cual demora 8.5 milisegundo aprox), esto en comparación con otros ATmega que permiten solamente borrar, solamente escribir y borrar, y escribir en una misma operación, ósea permiten realizar tareas separadas lo cual puede ayudar a reducir tiempo de escritura.

Bueno, vamos con el programa y explicaré algunas cositas.

Primero un par de macros nuevas que usaré.
Esta primera macro espera hasta que el bit indicado sea 0.

macro1

Esta espera a que el bit sea 1.

macro2

Ahora la primera parte del programa.

ima1

Aquí usaremos el uart para enviar algunos datos, la velocidad será de 9600.
Si queremos iniciar la eeprom con algunos datos tenemos que declararlos. La declaración de los datos y la separación de espacios de la eeprom inicia con “eseg” (segmento de eeprom).

.org    0x000    .db    0x00,0x01,0x02,0x03,0x04 –> Esta parte de código asignará los valores en hexadecimal a las posiciones de memoria iniciadas en 0x000.
.org    0x010    .db    "hola mundo" –> Esta otra parte también asignará los valores a las posiciones iniciando en 0x010.
.org    0x020    .db    0x30,0x31,0x32,0x33,0x34 –> Aquí la asignación inicia en 0x20 y termina en 0x24,
.db "ING. ELECTRONICA"—> Para esta parte no se da un inicio u origen, pero por encontrarse debajo de la asignación anterior que terminó en 0x24, ésta tendrá su inicio en 0x25.
.org    0x50
    data_eeprom_10:    .byte    10     // separa 10 Bytes iniciando en 0x50.
    data_eeprom_5:     .byte     5      // separa 5  Bytes iniciando en 0x5A.
    data_eeprom_16:   .byte     16    // separa 16 Bytes iniciando en 0x5F.

La eeprom cuenta con 3 registros:
EEAR(EEARH:EEARL): Es el registro donde se debe escribir la dirección del byte que se quiere leer o escribir.
EEDR : Es el registro del cual se leerá el dato en una operación de lectura, y en él se debe poner el dato en una operación de escritura.
EECR: Es el registro donde se encuentran los bits de configuración. Aquí se indicara que operación se desea realizar.

Las rutinas de lectura y escritura son mostradas abajo, en ellas lo primero que hay que hacer es esperar a que termine la operación anterior de escritura (si es que la hubiera). Antes de llamar a la rutina la dirección para leer debe estar en X y el dato retorna en R16, y para escribir la dirección la dirección está en Y y el dato en R16. R16,X y Y pueden ser cambiado a cualquier otro registro.

ima4

En la parte principal de programa se inicia la pila y se configura el uart.


En el programa encontramos tres bucles.
En el primer bucle se leerán los datos que inician en la dirección X=0x10 (“hola mundo”), estos datos se enviarán por el uart y también se irán guardando en la posición Y=data_eeprom_10.
Luego hay un saldo de línea.

El funcionamientos de los otros dos bucles es similar al primero.
Aquí están las rutinas de salto de línea y de envió de datos por el uart.

ima3

Ahora… luego de escribir todo este programa y compilarlo obtenemos como salida un archivo .eep.

panel

En este archivo se encuentran, en formato intel hex, todos los datos de para iniciar nuestra eeprom, este archivo se debe grabar en nuestro microcontrolador después de grabar la flash.

eefile

Al abrir el archivo EEPROM.eep veremos lo mostrado en la imagen superior. El formato es intel y allí podemos ver las posiciones de memoria y cada uno de los bytes.

Ahora simularemos esto en proteus.

p1

Para cargar nuestros datos a la eeprom  interna debemos hacer doble click sobre el ATMEGA8.
En la ventana que nos aparece debemos ir hasta “Advanced Properties” y seleccionar “Initial Contents of Data EEPROM” y luego en la parte derecha (usando el icono de carpeta) debemos seleccionar nuestro archivo con los datos iniciales.

p2

Luego cuando iniciemos nuestra simulación veremos en la eeprom del ATmega lo siguiente.

p4

Si no les aparece lo anterior, y cada vez que quieran resetear la data guardada en la eeprom, deben hacer click en “Reset Persistent Data”…Esto borra todo el contenido de las eeprom’s que se encuentren en la simulación.
p3

Cuando ejecutemos nuestro programa veremos lo siguiente.

p5
p6

Ahora… y seguro se preguntan como transformo mi archivo EEPROM.eep a EEPROM.bin (es el tipo de archivo en el cual debe estar la data incial para la eeprom)--- proteus no permite cargar los datos iniciales desde el .eep.

Para esto pueden usar el “avr-objcopy.exe”, este ejecutable los pueden encontrar dentro de su instalación del avr gcc, se encuentra dentro de una carpeta de nombre bin.
Hay que usar la ventana de comando para hacer la conversión. Un ejemplo seria así.

>avr-objcopy.exe –I ihex ruta_del_archivo_hex.hex –O binary nombre_del_archivo_de_salida.bin

O mas fácil aun, pueden usar este programita que me tome la molestia de hacer en visual C#. Si no lo pueden ejecutar deben instalar en netframework 3.5.

programa

Este programa le pasa los parámetros correctos al “avr-objcopy.exe” para crear el archivo binario. El ejecutable de esta aplicación debe estar en la misma carpeta que el “avr-objcopy.exe”.

Si abren el archivo binario verán los siguiente.

eebin

En esta oportunidad además de este programita muy útil, también compartiré los archivos EEPROM.asm, macros.inc, EEPROM.eep, EEPROM.bin.

El link: EEPROM

Bueno, espero esto les ayude… Hasta pronto.

sábado, 1 de octubre de 2011

Boot Loader en ATmega

Primero un saludo a mis lectores, hace mucho que no escribo.

En este post hablare del bootloader y les daré el código para que ustedes puedan usarlo y editarlo a voluntad.

¿Qué es un bootloader?
En el mundo de los uC un bootloader es un pequeño programa que grabado previamente en un área especial de la flash, la zona o área de booteo, nos permitirá la actualización de la flash.  Es decir que una vez que el uC tiene el bootloader ya no necesitarás un programador para volver a actualizar tus aplicaciones.
Esta zona de booteo se encuentra siempre al final de la flash, y su tamaño puede variar entre 4 valores (que dependerán del tamaño de la flash). La elección del tamaño de ésta área se debe realizar en los fuses como se muestra en la siguiente figura.


boot


Se puede ver que se definen dos áreas, la de Aplicación y la de Booteo. En la sección de aplicación es donde normalmente colocamos nuestro código (inicia en la dirección 0x0000 de la flash).

Todos los periféricos funcionan igual en las dos áreas, pero en el área de booteo sí se puede usar la instrucción SPM (SPM - Store Program Memory). Esta instrucción es la que nos permitirá modificar la flash.
La flash esta dividida en páginas (el tamaño de la página dependerá del uC), por ejemplo un ATmega8 tiene 128 página y cada página es de 32 palabras ó 64 bytes, esto es 128*64 =8KB de flash.
Un ATmega128 tiene (512 páginas)*(256 bytes/página)=128KB.
Todos esos números los encuentran en las hojas de datos.

La programación de la flash se realiza página a página y hay dos métodos para hacerlo, el método que uso yo, y que es el método que se encuentra en el ejemplo de las hojas de datos, consiste en borrar la página, poner los bytes correspondientes a esa página en el buffer de la flash y ejecutar el comando de programación… esto es algo que se debe repetir para cada página.

El bootloader puede recibir los datos para la programación por cualquier medio que le sea posible(UART, SPI, I2C, USB, ETHERNET…etc), éste bootloader lo realiza por el UART.

El funcionamiento del programa es el siguiente:
  1. El programa testea un pin del uC,
1.1  si es ‘1’ salta a la dirección cero de la flash y ejecutará nuestra aplicación ( si ésta existe).
1.2  si es ‘0’ se inicia la ejecución de bootloader.
2.      El programa configura el uart. F_CPU y BAUD pueden ser cambiados y adecuados a las necesidades de cada persona.
3.      Luego espera todos los datos de una página.
4.      Entre los datos se encuentra la dirección de la página a grabar, con este dato se borra la página correspondiente, se llena el buffer de la flash con los datos (que no son otra cosa que las instrucciones de nuestra aplicación) y por último se ejecuta el comando para programar.
El programa puede ser adaptado fácilmente a otros uC’s, esto ya que las macros ayudan mucho al momento de realizar las operaciones con los registros.

¿Y cómo envío por el uart el bendito código de mi programa ?

Para esto desarrollé un pequeño programa en visual C#.


programa


El programa es muy sencillo de manejar, solamente hay que buscar el firmware de nuestra aplicación, buscar el puerto por lo cual descargaremos, seleccionar la velocidad (debe ser igual a BAUD del bootloader), seleccionar el dispositivo y por ultimo dar click en el botón “Program”.
En este caso no les puedo poner una simulación en proteus ya que éste no soporta la característica de auto-programación.

El bootloader no ocupa mucho espacio de la flash, es por ello que el inicio de código lo hago en FIRSTBOOTSTART. FIRSTBOOTSTART es un número que cambia con cada uC, su valor lo pueden encontrar en el archivo “m#def.inc” de cada uC.

Cuando programen el bootloader los fuses deben incluir: BOOTZS =11 y BOOTRST=0 . Lo primero es para que el área de booteo sea la menor y lo segundo le indicará que después de cada reset inicie en la dirección de booteo indicada (en este caso iniciará en la dirección FIRSTBOOTSTART).
Luego ya no necesitarán llevar su programador a todas partes… basta con usar el puerto serie para realizar esta actualización.

Espero esto les ayude… también espero sus comentario para la mejora del programa.
El código fuente lo pueden descargar aquí: BOOT_JRSF
El programa en C"# : BOOT_Downloader … si no pueden abrirlo quizá necesiten instalar el netframework 3.5.
Si alguien quiere el código fuente del programa hecho en C# aquí lo tiene : BOOT …. Esta demás decir que deben tener instalado Visual Studio 2008 para abrir esto, o por lo menos Visual C# 2008 Express.

ver: USBasp bootloader

sábado, 9 de julio de 2011

RTC DS1307 Y ATMEGA8


Ver I2C + RTC DS3231 usando C

En éste post mostraré un programa que permite configurar un DS1307. Como sabemos el DS1307 se comunica por I2C.
El programa tiene dos partes que son ejecutadas por dos interrupciones.

En la interrupción del timer 1, que se ejecutará cada 1000ms (1seg), leerá la hora y fecha del DS1307 y se mostrará en un LCD.

Por el uart llega información que permite leer ó escribir el DS1307.
La información para escribir(configurarlo a una hora y fecha determinada) consta de 8 bytes que son:

| CABECERA(1) | COMANDO(1) | HORA(1) | MIN(1) | SEG(1) | FECHA(1) | MES(1) | AÑO(1) |

La cabecera es 0xBA
El comando puede ser ‘W’(0x57) para escribir y ‘R’(0x52) para leer.
El resto de datos deben estar en BCD.
Un ejemplo de esto es: BA 57 12 21 08 08 07 11
Donde la hora es 12:21:08 y la fecha es 08/07/11.

En el caso que se quiera leer solamente hay que enviar BA 52 y la respuesta a esto será por ejemplo BA 57 12 30 12 08 07 11 , donde se indica que la hora leída es 12:30:12 08/07/11

El esquema es el siguiente:

sch (Small)

Ahora mostraré las macros usadas.
  
mac2

mac3

mac4

mac5

mac6

Ahora las rutinas para I2C y DS1307.

i2c1

i2c3

i2c4

Como ya sabemos cada esclavo que se conecta al bus I2C debe tener una dirección y en éste caso la dirección del DS1307 es 0b1101000 + el bit de R/W, es por ello que para escritura se envía D0 y para lectura D1.

Ahora las rutinas del UART.

u1

u2

u3

u4

u5

Por último el mensaje principal.
Hay que tener en cuenta que se esta usando el RC interno.

main1

main2

main3

En el siguiente video se muestra el funcionamiento del programa.


El programa que se muestra para configurar el DS1307 lo hice en visual C#, éste programa lo pueden descargar de éste enlace RTC_DS1307.
Si no lo pueden abrir instalen netframework 3.5.

sábado, 11 de junio de 2011

CRC KERMIT Y CCITT EN ATMEGA

Cuando se tiene aplicaciones que involucran transmisión de datos siempre es importante tener un medio para detectar errores o para verificar la integridad de dicha información, es aquí donde entra a tallar el Chequeo de Redundancia Cíclica (CRC).

En éste post mostrare un par de rutinas para hacer el calculo del CRC KERMIT Y CRC CCITT en assembler de ATMEL.

Los resultados pueden ser chequeados en On-line CRC calculation

Aquí no hay mucho que decir así que pasare a mostrar las rutinas.

CRC1

Aqui hay dos buques que calcularan el crc de la cadena de texto (“JONATHAN RAUL SEMINARIO”) que se encuentra en la memoria de programa.

CRC2

CRC3

Las rutinas son muy similares, tienen la misma cantidad de instrucciones (22 instrucciones) y son ejecutadas en la misma cantidad de ciclos de instrucción(28 c.i). Si trabajamos con un XTAL=16MHz nos tomará 1.75us calcular el crc de cada byte.


Bueno, eso es todo en éste post…bye !!!

domingo, 5 de junio de 2011

Input Capture Unit


El timer1 incorpora una unidad de captura la cual puede capturar eventos externos y darnos un tiempo referencial en el cual estos ocurrieron.
La señal que indica el evento puede ser aplicado al pin ICP1 o vía la unidad de comparación analógica. El tiempo que es capturado puede ser usado para medir frecuencia, duty-cycle u alguna otra característica de la señal aplicada.

En el siguiente gráfico de muestra el diagrama de bloques de la unidad de captura.

bloques

Se puede ver que las entradas pueden ser el pin ICP1 o el comparador analógico. LA unidad también cuenta con un modulo de cancelación de ruido el cual tomará 4 muestras de la señal y si las 4 son iguales la señal será valida. También ésta el modulo de detección de flanco que nos permite seleccionar entre los flancos de subida(‘1’) o bajada(‘0’).
Cuando el evento ocurre los 16bits del contador TCNT1 son escritos al registro ICR1, también  en éste mismo instante se generará un interrupción( siempre que se activen los flag’s TICIE1 en el registro TIMSK y I en SREG.

En éste post usaré la unidad de captura para medir la frecuencia de una señal cuadrada.
El principio de medición consiste en capturar el valor de cuenta del timer1 (TCNT1) en un periodo de la señal a medir, luego con el valor de la captura , la frecuencia a la que trabaja el uC y conociendo el pre-escaler usado podremos fácilmente encontrar la frecuencia de la señal.

Por ejemplo: Si se trabaja con una F_CPU=16MHz, el valor capturado es ICR1=0x08BB y el pre-escaler usado es 64, entonces la frecuencia de la señal es:

image

Aplicando los datos a la formula:

image

Ahora pasaré a mostrar el código. Hay algunas macros y rutinas que ya he mostrado en post anteriores pero las estoy volviendo a mostrar.

Primero mostrare las macros.






m24

Ahora mostraré la rutinas de conversión de binario a ascii.

binascii1

binascii2

Ahora la rutinas para manejo del LCD.

lcd1

lcd2

lcd3

Las rutina de retardo que es usado junto a las macros delay_ms y delay_us.

retardo

La rutina para efectuar la división.

div1

div2

Y por último el código principal.






main23


main24

El funcionamiento del programa es como sigue.
  • Se configura los periféricos, se habilita la interrupción y se espera a que ésta ocurra.

  • Cuando ocurra la interrupción por captura el programa saltará a la rutina “CAPTURA_EVEN”, aquí tomará el valor capturado y lo pondrá en dos registros(R19:R18=ICR1H:ICR1L).
  • Se verificara si el timer se ha desbordado, en caso de ser así se mostrará un mensaje indicado que aquella es una frecuencia que no se puede medir(“fuera de rango”).

  • Si no se ha desbordado se calculará la frecuencia, con la formula ya antes mostrada, y se guardará en FRECASCII.

  • Luego del calculo de mostrará la frecuencia en el LCD.

  • Se espera 300ms y luego se espera al siguiente flanco de subida para iniciar la siguiente captura de datos (la medida de la frecuencia se toma entre dos francos de subida).
Hay que tener presente que con este método no se puede medir frecuencias muy altas, mientras mayor es la frecuencia mayor es el error en la medición. En un próximo post  mostraré como usar el mismo timer para hacer medidas de frecuencias mas altas.
Espero este pequeño ejemplo le ayude..!!!

Ahora un video del programa en funcionamiento.