tag:blogger.com,1999:blog-71234349718048294652024-02-19T10:56:43.023-08:00AVR PERUAVR PERUjrsfhttp://www.blogger.com/profile/04364143443693071318noreply@blogger.comBlogger43125tag:blogger.com,1999:blog-7123434971804829465.post-26468806660373591192017-08-12T14:15:00.001-07:002018-02-09T07:17:53.394-08:00Introducción a la escritura de código en C para XMEGA (AVR1000)<br />
<h1 align="justify">
1. Introducción</h1>
<div align="justify">
Cortos tiempo de desarrollo y requerimientos de productos electrónicos de alta calidad han hecho de los lenguajes de programación de alto nivel un requisito. La principal razón es que los lenfuajes de alto nivel hacen más facil el mantenimiento y la reutilización del código debido a la gran portabilidad y legibilidad.</div>
<div align="justify">
La simple elección del lenguaje de programación no asegura una alta legibilidad y reusabilidad; el buen estilo de codificación sí. Así pues, los perifericos XMEGA, los archivos cabecera y los controladores estan diseñados teniendo esto en cuenta.</div>
<div align="justify">
El lenguaje de programacíón mas ampliamente usado para microcontroladores AVR es C, y esta nota de aplicación (AVR1000) se enfoca en la programación en C. Para proporcionar soporte a muchos de los compiladores de C para AVR disponibles los ejemplos son en la medida de lomposible escritos en ANSI C. Algunos de los ejemplo son especificados para IAR Embedded Workbench, pera la idea y metodos pueden ser uados para otros compiladores con cambios menores.</div>
<div align="justify">
<br /></div>
<blockquote>
<div align="center">
Ejemplo de codificación – AVR GCC</div>
</blockquote>
<div align="justify">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhg0uqEyrQ0rsevGYLXYSmUBJTcU8LpTKdeecj46E1pG740Q6kfY8YUE4ihq_vjhyphenhyphen5aNDvEI18lQv1Tl0_vRzE5SN5Fni4wEQYBfgkx2F_JJCyN1Wq9BZuYw6wQ_44xZh2wr3eOlZDA8HLr/s1600-h/image%255B4%255D"><img alt="image" border="0" height="345" src="https://lh3.googleusercontent.com/-YIODvt3mSMk/WY9v8-gXCEI/AAAAAAAAAdg/rFDASkjlyvw1DSsiPViJiec7Q46TRo7EQCHMYCw/image_thumb%255B2%255D?imgmax=800" style="background-image: none; border-bottom: 0px; border-left: 0px; border-right: 0px; border-top: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="image" width="467" /></a></div>
<div align="justify">
<br /></div>
<div align="justify">
<br /></div>
<div align="justify">
<span style="color: lime;"><b>Link: <a href="https://drive.google.com/file/d/0B3OsL7DPo1s0VzkyaGE2R2ZnM1k/view?usp=sharing" target="_blank"><span style="color: lime;">EJEMPLOS XMEGA</span></a></b></span></div>
<div align="justify">
<span style="color: lime;"><b><a href="https://drive.google.com/drive/folders/0B3OsL7DPo1s0cHdtSlZpTVF5ajA?usp=sharing" target="_blank"><span style="color: lime;">...EJMPLOS</span></a></b></span></div>
<h1 align="justify">
2. Módulos XMEGA</h1>
<div align="justify">
Un AVR XMEGA esta compuesto de varios bloques básicos. Un CPU AVR, SRAM, Flash, EEPROM, y una serie de perifericos. Esos bloques son llamados “tipos de módulo”. Un XMEGA puede tener una o más instancias de un tipo de módulo dado. Todas las instancias de un tipo de módulo tienen las mismas características y funciones.</div>
<div align="justify">
Algunos de los módulos pueden ser un subconjunto de otros tipos de módulos. Estos módulos heredan un subconjunto de características del módulo superior, todas las características heredadas son completamente compatibles. Esto se aplica por ejemplo a los timer y puertos de entrada y salida. Un subconjunto de módulos para un timer significa que este tiene menos canales de captura y comparación que un timer completo. Similarmente, un puerto IO puede tener menos de ocho pines.</div>
<div align="justify">
Un tipo de módulo puede ser un “USART”, mientras una instancia de este tipo puede ser “USARTC0”, donde el sufijo C0 indica que la instancia es el USART 0 en el puerto C. Cada módulo tiene un número de registros que contienen bits de control o de estado. Todos los módulos de un tipo dado contienen el mismo conjunto (o subconjunto) de registros, y todos estos registros contienen el mismo conjunto (o subconjunto) de bits de control y estado.</div>
<div align="justify">
<br /></div>
<div align="center">
Tipo de módulo, instancias, registros y bits.<a href="https://lh3.googleusercontent.com/-Vvasmg06VM0/WY9v9dNKBtI/AAAAAAAAAdk/MS95kWjbEpUWJnvrK_tr7z0KX2XCgXNtwCHMYCw/s1600-h/image%255B9%255D"><img alt="image" border="0" height="513" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiXSrg6TqDfTDzFSIte2hIy9J5RM9JxHPDPoavh-4Xij1UZ_HKeRIc4A8JR31QaCIvukPLUcyzD_LnSjSajTcf8cVwW0ZnRYGVq5YNQFhQ4u03PUfJTo8rNjeZBwC_j3t-42tk6pRxvcbC8/?imgmax=800" style="background-image: none; border-bottom: 0px; border-left: 0px; border-right: 0px; border-top: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="image" width="763" /></a></div>
<div align="justify">
<br /></div>
<div align="justify">
Cada módulo tiene una dirección base fija en el mapa de memoria I/O y todos los registros contenidos en el módulo tienen direcciones de desplazamiento fijas relativas a dirección base del módulo. De esta manera, cada registro no sólo tendrá una dirección absoluta en el espacio de memoria, sino también una dirección relativa definida por un offset. Los desplazamientos de las direcciones de registros son iguales para todas las instancias de un tipo de módulo, simplificando la tarea de escribir controladores que puedan ser usados para todos los módulos de un tipo específico.</div>
<div align="justify">
<br /></div>
<h2 align="justify">
2.1 Convención de nomenclatura de registros</h2>
<div align="justify">
<br /></div>
<div align="justify">
Los registros están divididos en registros de control, registros de estado y registros de datos y el nombre de dichos registros refleja esto.</div>
<div align="justify">
Un registro de control de propósito general del módulo es llamado <span style="font-family: Courier New;">CTRL</span>. Sí existen múltiples registrol de control en un módulo ellos tendrán un caracter como sufijo. En este caso el registro de control será llamado <span style="font-family: Courier New;">CTRLA, CTRLB, CTRLC</span> etc. Esto también aplica a los registros de estado (<span style="font-family: Courier New;">STATUS</span>).</div>
<div align="justify">
Para registros que tienen una función específica el nombre de estos refleja esta funcionalidad. Por ejemplo, un registro de control que controla los niveles de interrupción de un módulo es llamado <span style="font-family: Courier New;">INTCTRL</span>.</div>
<div align="justify">
Ya que el bus de datos AVR es de 8bits, los registros mas grandes son implementados usando varios registros de 8 bits. Para un registro de 16 bits, el alto (High) y bajo (Low) son accesados agregando una “H” o “L” respectivamente al nombre del registro. Por ejemplo, el registro de cuenta de 16 bits del Timer/Counter son llamados <span style="font-family: Courier New;">CNT</span>. Los dos bytes son llamados <span style="font-family: Courier New;">CNTL</span> y <span style="font-family: Courier New;">CNTH</span>.</div>
<div align="justify">
Para registros más grandes que 16 bits, los bytes son numerados desde el byte menos significativo. Por ejemplo, el registro de calibración de 32 bits del ADC es llamado <span style="font-family: Courier New;">CAL</span>. Los cuatro bytes son llamados <span style="font-family: Courier New;">CAL0, CAL1, CAL2 y CAL3</span> (desde el menos al más significativo). Muchos de los compiladores de C ofrecen un manejo automatico en el acceso a multiples bytes. En el caso del timer el nombre <span style="font-family: Courier New;">CNT</span>, sin sufijos “H” o “L”, puede ser usado para realizar un acceso al registro de cuenta (<span style="font-family: Courier New;">CNT</span>). Esto también se aplica en el caso de los registros de 32 bits.</div>
<div align="justify">
<br /></div>
<h2 align="justify">
2.2 Convención de nomenclatura de bits</h2>
<div align="justify">
<br /></div>
<div align="justify">
Los bits en los registros pueden tener una función individual o ser parte de un grupo de bits que tienen una función conjunta: Un bit individual puede ser un bit que habilita un módulo, ej. el USART ENABLE bit. Un grupo de bits puede consistir de dos o más bits que juntos seleccionan una configuración especifica del módulo al cual pertenecen. Un grupo de bits ofrecen hasta 2^n posibles opciones, donde n es el número de bits en el grupo. Los dos bits que controlan el nivel de interrupción de recepción completa del <span style="font-family: Courier New;">USART</span>, <span style="font-family: Courier New;">RXINTLVL[1:0],</span> es un ejemplo de un grupo de bits. Esos dos bits ofrecen las siguientes secciones:</div>
<div align="justify">
<br /></div>
<div align="center">
<em>Bits RXINTLVL y los correspondientes niveles de interrupción</em><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiZoRDGCfDuMKf2R2feNyugubVbLYBr__6wJ2LiRiyw80b8Q5PZ0SM6Rtq1mt-8Om1nvKIf09ZORuh5f3RgtjsXuHMhCNGWZQiI1pf3pWFPF00pv1bg-xIB9-ZhqyTJ57cNlDQQbySqnLBj/s1600-h/image14%255B1%255D"><img alt="image" border="0" height="146" src="https://lh3.googleusercontent.com/-n_49avUoIM4/WZccwHnRWFI/AAAAAAAAAgQ/lCTHhLk4pVkmrq20v4QsoUBf_C94r6u6gCHMYCw/image14_thumb?imgmax=800" style="background-image: none; border-bottom: 0px; border-left: 0px; border-right: 0px; border-top: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="image" width="644" /></a></div>
<div align="justify">
<br /></div>
<div align="justify">
Solamente los bits que forman parte de un grupo tendrán como sufijo un número. El registro de control D de un Timer/Counter tiene dos grupos de bits. <span style="font-family: Courier New;">EVACT</span> y <span style="font-family: Courier New;">EVSEL</span>. Los bits de esos grupos tienen un número como sufijo, mientras que el bit <span style="font-family: Courier New;">EVDLY</span>, que no forma parte de un grupo, no tiene sufijo.</div>
<div align="justify">
<br /></div>
<div align="center">
<a href="https://lh3.googleusercontent.com/--kVayefBxvY/WZXru5D1RaI/AAAAAAAAAeU/-ecGJji_mJwwSeGHcWLFus_zB3OiifcBQCHMYCw/s1600-h/image%255B5%255D"><img alt="image" border="0" height="67" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh5uKbvUokFdt5wu4f9AXamP0IMPGiAM2kgbhoBRfo1hL-anhn4LJmDZMdt5HvTe8ZVHme3N4ZndC5IAWgl99MufzHDQSd86R5dEpt9c8oSY9K6Y97-19S_GhxM-SUjZw_mhmmOxq2cSetq/?imgmax=800" style="background-image: none; border-bottom: 0px; border-left: 0px; border-right: 0px; border-top: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="image" width="644" /></a></div>
<div align="justify">
<br /></div>
<div align="justify">
<br /></div>
<h1 align="justify">
3. Escribiendo código en C para XMEGA</h1>
<div align="justify">
La siguiente sección se enfoca en como escribir código en C para XMEGA. Los ejemplos muestras como hacer el código altamente legible y portable entre los diferentes dispositivos XMEGA. Los ejemplos también pueden ser usados como una guía para escribir código que sea fácil de escribir y mantener.</div>
<div align="justify">
Los módulos XMEGA se encuentran en bloques dedicados y continuos en el espacio de memoria y se pueden ver como unidades encapsuladas. Esto se refleja en la forma en que se acceden a los módulos cuando se codifica en C: Los módulos son encapsulados usando estructuras en C, en las que están contenidos todos los registros del módulo. La siguiente figura muestra una ilustración de esto.</div>
<div align="justify">
<br /></div>
<blockquote>
<div align="center">
<em>Modulos puestos en bloques dedicados en el espacio de memoria.</em><a href="https://lh3.googleusercontent.com/-Uk5s1zXl57c/WZcQT_FJeqI/AAAAAAAAAes/hHs7fG-RCB8aEzyWyzGpBDWkjS8eB3YAACHMYCw/s1600-h/image%255B10%255D"><img alt="image" border="0" height="600" src="https://lh3.googleusercontent.com/-gu1OeCd3jnA/WZcQU1SvB4I/AAAAAAAAAew/NbseP5xZ-zAoMgICs4GJ4CGgH74-9AZfQCHMYCw/image_thumb%255B5%255D?imgmax=800" style="background-image: none; border-bottom: 0px; border-left: 0px; border-right: 0px; border-top: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="image" width="391" /></a></div>
</blockquote>
<div align="justify">
<br /></div>
<div align="justify">
Debemos notar que algunos registros no tienen una asociación directa con módulos. Aquellos registros no estan encapsulados en estructuras, ya que las estructuras son usadas para asociar registros con un módulo.</div>
<div align="justify">
Para grandes proyectos, las estructuras de los modulos proporcionan una ventaja, no sólo la legibilidad, sino también porque los compiladores pueden reutilizar los driver y por lo tanto generar un código muy compacto. </div>
<div align="justify">
<br /></div>
<h2 align="justify">
3.1 Archivos cabecera XMEGA</h2>
<div align="justify">
Un archivos de cabecera dedicado esta disponible para cada dispositivo XMEGA. Si el dispositivo que se usará es especificado en la configuración del proyecto (asumiendo que usamos Atmel Studio), el compilador se encargará de incluir automáticamente el archivo cabecera correcto siempre que se incluya el archivo de dispositivo como se muestra en la soguiente figura.</div>
<div align="justify">
<br /></div>
<div align="center">
<a href="https://lh3.googleusercontent.com/-dLG4ppUiK0I/WZcabveuq4I/AAAAAAAAAfI/nv-mripDPOwoq4l-Pj-JqXOsogVi3w6SQCHMYCw/s1600-h/image%255B19%255D"><img alt="image" border="0" height="35" src="https://lh3.googleusercontent.com/-1Ukuxr9ePTI/WZcacExKKCI/AAAAAAAAAfM/rQs57IAv-ecDAHI56MYJd0aIZ2cKwA4_gCHMYCw/image_thumb%255B10%255D?imgmax=800" style="background-image: none; border-bottom: 0px; border-left: 0px; border-right: 0px; border-top: 0px; display: inline; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="image" width="192" /></a></div>
<div align="justify">
La ventaja de esto es que si el dispositivo cambia, no será necesario cambiar los archivos de origen, sólo la configuración del proyecto.</div>
<div align="justify">
<br /></div>
<h2 align="justify">
3.2 Registros en los módulos</h2>
<div align="justify">
El mapa de entradas/salidas esta dispuesto de modo tal que todos los registros para un módulo periférico dado se coloquen en un bloque de memoria continua. Los registros pertenecientes a diferentes modulos no son mezclados. Esto hace posible organizar todos los módulos periféricos en estructuras. Donde la dirección de la estructura define l dirección base del módulo. Todos los registros pertenecientes a un módulo son elementos de la estructura del módulo.</div>
<div align="justify">
Un ejemplo es módulo “USART”. El tipo estructura y la declaración para este módulo son mostradas en las siguientes figuras.</div>
<div align="justify">
<br /></div>
<div align="center">
<em>Declaración de tipo de módulo<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh9IG9YpJYCKqJ_FnJBqNjhTJymXogjqnH6FXgEJ1jcv44McchkzfG92yOHr-TnTagLSfjbj8RnSvXHlAsE4syBpC0Z4aCA8WYtxNace8OXzyYSxi35cA-jImL3qjODv-UqjP8r9Zh8saQd/s1600-h/image%255B44%255D"><img alt="image" border="0" height="292" src="https://lh3.googleusercontent.com/-dx-ym3RDacE/WZcadNW6frI/AAAAAAAAAfU/0faDraowde41iIRaW4_qwyW_nO53YvQxgCHMYCw/image_thumb%255B25%255D?imgmax=800" style="background-image: none; border-bottom: 0px; border-left: 0px; border-right: 0px; border-top: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="image" width="513" /></a></em></div>
<div align="center">
<br /></div>
<div align="center">
<em>Declaración de módulo(se instancia cada USART)<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiCHcwMQRlzHv1JBxGJA_JUTAQ0PACpOLpzG_8BykXopcvFBeVwo-rhKQDBRApWN5InEpmMYCB7r-n0Ykc8oN7AjMLrV2VY8uzLNpt_zjRudKm7-2nC6FaFy6MRn_mZoO8LhvcdgbGX8cAr/s1600-h/image%255B49%255D"><img alt="image" border="0" height="358" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhXLS21L1FNzyx8YlcwE6UlDXtw2B1iWZZalrMZfqIDcNO5W2iUB0jkyN59gPw2ieqlgQsm6iG_dvo2IOjri2eeDAQaInsUaSLUCPLi4ulNadSsRYnpMx7CguA81wEmjr3pLrxzxujsS7EM/?imgmax=800" style="background-image: none; border-bottom: 0px; border-left: 0px; border-right: 0px; border-top: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="image" width="409" /></a></em></div>
<div align="center">
<br /></div>
<div align="center">
<em>Uso de la estructura</em><em><a href="https://lh3.googleusercontent.com/-i_bigXGnnM4/WZcaf7nrC_I/AAAAAAAAAfg/ZZZL9TCRO-0L_D3USqioLnvfXCHL9-qdwCHMYCw/s1600-h/image%255B54%255D"><img alt="image" border="0" height="82" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEizl25AO0AnAum3VyS4WaKAd71tDwDK-s-Xjx8RqdV-UPCT-_AUAIQ49XJdal0Lc6QWRBod_yQuFcPWSwVoP4fgJ136e0OrqAKaI5r068f4FHHjna5qxM0gRfccHpjp4vuBn-RfwQugbjj2/?imgmax=800" style="background-image: none; border-bottom: 0px; border-left: 0px; border-right: 0px; border-top: 0px; display: inline; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="image" width="559" /></a></em></div>
<div align="center">
<br /></div>
<div align="center">
<br /></div>
<h2 align="justify">
3.2.1 Registros multibytes en módulos.</h2>
<div align="justify">
Algunos registros son usados conjuntamente con otros registros para representar valores de 16 y 32 bits. Como ejemplo de esto es la declaración de la estructura <span style="font-family: Courier New;">ADC</span> de la siguiente figura.</div>
<div align="justify">
<br /></div>
<div align="center">
<em>Declaración del tipo de módulo ADC</em><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhQBKyrTkNyY0JSkX1iYHpamPU2Z78WP5w5Je1fImz7A7zkQr0sxG37qkT8-kGeaj4aI1bteGw0lOHzs98t-842hDV1sWWNc-FRDclbyJ-5oXk0r68HeQtPYF_Vp3vZWb_EHS_pFBTICGzM/s1600-h/image%255B59%255D"><img alt="image" border="0" height="668" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhpX6HkdwMMNnZzpmDce2F-ZTmxB3kFGE9RSNp_JOjlLVDFrYN_EoWJsdJLBFUfAl_8FnyRBlkWds9mKuG8KvWfbEnH1wdvdnBc6TPSADmjsB6e6q2JwFi5dxh4mOP45Wuj_FeR78Mv1TbU/?imgmax=800" style="background-image: none; border-bottom: 0px; border-left: 0px; border-right: 0px; border-top: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="image" width="435" /></a></div>
<br />
<div align="justify">
En la figura anterior, los registros de resultado de cada canal <span style="font-family: Courier New;">CH0RES, CH1RES, CH2RES, CH3RES</span>, y el registro de comparación <span style="font-family: Courier New;">CMP</span>, son valores de 16 bits. Ellos son declarados usando la macro _<span style="font-family: Courier New;">WORDREGISTER</span> la cual es mostrada en la siguiente figura. </div>
<br />
<div align="center">
<span style="font-family: Courier New;">Macro _WORDREGISTER</span> <a href="https://lh3.googleusercontent.com/-QjEPcjTJrrM/WZcb_eZiqvI/AAAAAAAAAf8/HR_dzFGLiDAo2tFz92N5uPdKK5Vk-ifpgCHMYCw/s1600-h/image%255B68%255D"><img alt="image" border="0" height="231" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh9l8bBQhK7BWqTbLSPc9JPaiv71aQh32hk1iq2wp0OHcr-XAvN6-yLBCHz7-hQJ4CH9ym7ojBN-b0ewThzb16Et_MLp8V_U5_HqtrvtoiDf_Up9GY2c901GzBeqsBq36oQkowji-T9wPxm/?imgmax=800" style="background-image: none; border-bottom: 0px; border-left: 0px; border-right: 0px; border-top: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="image" width="339" /></a></div>
<br />
En la siguiente figura registro de cuenta, <span style="font-family: Courier New;">CNT</span>, es un valor de 32 bits y es declarado usando la macro _<span style="font-family: Courier New;">DWORDREGISTER.</span><br />
<br />
<div align="center">
<em>Declaración de tipo de modulo RTC32_struct</em><a href="https://lh3.googleusercontent.com/-8XV6d2LP8PE/WZstOmK6KqI/AAAAAAAAAg8/6ZvErJickaAlEw1t7jI_f85dx6FPdxzoACHMYCw/s1600-h/image%255B5%255D"><img alt="image" border="0" height="191" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhBrMfbiDXiUmvCbK61jMKB6W-mnHeN4mzm8oeB2Pb1WA3Pvgg8j-3P_3XL6niCxqRliigwJ9eIT0hDaxexSYnbVS7WPeFekB0q7T2nIC4X65dcjD9kduuYVFjf_A-TSDOFhw7mCjYzST_H/?imgmax=800" style="background-image: none; border-bottom: 0px; border-left: 0px; border-right: 0px; border-top: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="image" width="603" /></a></div>
<br />
<div align="center">
<span style="font-family: Courier New;">Macro _DWORDREGISTER</span> <a href="https://lh3.googleusercontent.com/-EkYymFV_kUk/WZccBQC2ECI/AAAAAAAAAgE/V57U9QO5wCUm9v7CXitncouddRMGPEkrACHMYCw/s1600-h/image%255B69%255D"><img alt="image" border="0" height="261" src="https://lh3.googleusercontent.com/-R43VEamJdqQ/WZccBx5gS4I/AAAAAAAAAgI/Kva8DWVH7E0wcM7IVqZR_j9NcgqWxv3OACHMYCw/image_thumb%255B40%255D?imgmax=800" style="background-image: none; border-bottom: 0px; border-left: 0px; border-right: 0px; border-top: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="image" width="346" /></a></div>
<br />
<div align="justify">
Como se ha visto, la macro <span style="font-family: Courier New;">WORDREGISTER</span> usa los sufijos “H” y “L” para para los bytes altos y bajos respectivamente. La macro usa números como sufijos para indicar el orden de los bytes. Tanto los registros de 16 como los de 32 bits pueden ser accesados en modo 16/32 bits sin usar el sufijo como se muestra en la siguiente figura.</div>
<br />
<div align="center">
<em>Uso de registros de 8, 16 y 32 bits.</em><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhEshVyeXaf4LGUvG_ZVX-Hyrr7mq8O31KXAXTWflNFR1eOVPVwelKUMhRcFKXev-YMWA9ol330lt7_FC74I9sqDWdgI1DNFin50BPwM4pbVwwYgtLtM5Gn_ThdXjQEQ2S5WnRmxtOmk3f_/s1600-h/image%255B10%255D"><img alt="image" border="0" height="134" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgEqoxOhqyZqpCm_Mziwa2h95F_W_Kxj2MFR_VkJi61X_FiWVZNMmH4LxBso7OnDOlKn0JwMLwIL_qPpWuNon1RFsi1Wnh_Pqi7F2D42MWuoJ_b_gsyk0y5d5l03-2sYmP_R-lkpXBjCbQC/?imgmax=800" style="background-image: none; border-bottom: 0px; border-left: 0px; border-right: 0px; border-top: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="image" width="460" /></a></div>
<br />
<br />
<h2>
3.3 Direccionamiento de módulos.</h2>
<div align="justify">
Las definiciones de todos los módulos periféricos son encontradas en el archivo cabecera del dispositivo. La dirección para el módulo es especificada en ANSI C para tener compatibilidad con muchos de los compiladores disponibles. En la siguiente figura se muestra las definiciones de los ADC para los puertos A y B. Aquí se puede ver como las instancias de los módulos son desreferenciados a una dirección absoluta en la memoria, la cual coincide con la dirección base de la instancia del módulo. Los punteros al módulo son predefinidos en los archivos cabecera de cada XMEGA, por lo tanto ya no es necesario agregar estas definiciones a nuestro código.</div>
<div align="center">
<br /></div>
<div align="center">
<em>Definición de módulos ADC</em><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj7BunNBb18JE8eNHVJ9kJgOT3pZb1NgYo9Bsoi3QO64e9i-c6UyJx4YPFolhcRuNly_ZjrG4_G4OJOSV1mf4OtWBPBMZVOYaxEqsZ2x7JRe5t6aTGlGROYn1ghqtOudhsVoBVJnfElwYwS/s1600-h/image%255B15%255D"><img alt="image" border="0" height="46" src="https://lh3.googleusercontent.com/-9B1Td3ZeJ4g/WZstROzZmxI/AAAAAAAAAhQ/r--Y0OUlvnMBQgScPSkvC1w8LCWLX2WGwCHMYCw/image_thumb%255B8%255D?imgmax=800" style="background-image: none; border-bottom: 0px; border-left: 0px; border-right: 0px; border-top: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="image" width="682" /></a></div>
<br />
<h2>
3.4 Máscaras de bits y máscaras de grupos de bits.</h2>
<div align="justify">
Los bits en los registros pueden ser manipulados usando máscaras predefinidas, o alternativamente la posición de los bits. No se recomiendo usar la posición de los bits. Las máscaras de bits predefinidas estan relacionadas a bits individuales, denominados máscara de bits o grupo de bits.</div>
<div align="justify">
Una máscara de bit es usada tanto cuando se setea o limpia un bit. Una máscara de grupo es principalmente usada cuando limpiamos múltiples bits en un grupo. El seteo de multiples bits que forman parte de un grupo es cubierno en la sección 3.5.</div>
<br />
<h3>
3.4.1 Mascara de bit (Bit Mask).</h3>
<div align="justify">
Considere el registro de control del Timer D, <span style="font-family: Courier New;">CTRLD</span>. Los grupos de bit, los nombres de bit, las posiciones de los bits y las máscaras de bit de este registro se pueden ver en la siguiente tabla.</div>
<br />
<div align="center">
<em>Grupos de bit, nombres de bit, posiciones y máscaras de bit para los bits del registro <span style="font-family: Courier New;">CTRLD</span>.</em><a href="https://lh3.googleusercontent.com/-xhFcwI9t1Qs/WZ4cAlmd2II/AAAAAAAAAho/GJ3j5ZrgD1Yapkqef-C9pw7cUJoyuYn0gCHMYCw/s1600-h/image%255B6%255D"><img alt="image" border="0" height="80" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjiPFjkA3kEYTalvQfjQlEe-5MAheOoknV81Ol-ZH1mByPDTEENZEx9iOLeivrGYl9rfB__4gJaFptq_vISGNuQQzA0_4f10KX8xDUpoA1S0EMVyXxgfP2FCYGsCRQVuhLnzbqw8Z4Xr23m/?imgmax=800" style="background-image: none; border-bottom: 0px; border-left: 0px; border-right: 0px; border-top: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="image" width="640" /></a></div>
<div align="justify">
Ya que el nombre de los bits necesita ser único para que el compilador pueda manejarlos, todos los bits estan prefijados con el nombre del módulo al cual pertenecen. En muchos casos, el nombre del tipo del módulo esta abreviado. Para todas las definiciones de bits relacionadas con los módulos Timer/Counter, los nombres de los bits tienen un prefijo “<span style="font-family: Courier New;">TC_</span>”.</div>
<div align="justify">
Para diferenciar entre las máscaras de bit y las posiciones de los bits se agrega un sufijo. Para una máscara de bit, el sufijo es “<span style="font-family: Courier New;">_bm</span>”. El nombre de la máscara de bit para el bit <span style="font-family: Courier New;">EVDLY</span> es <span style="font-family: Courier New;">TC_EVDLY_bm</span>. El código mostrado en la siguiente figura usa una máscara de bit. El bit <span style="font-family: Courier New;">EVDLY</span> en el registro <span style="font-family: Courier New;">CTRLD</span> del Timer/Counter <span style="font-family: Courier New;">D0</span> es seteado sin alterar los otros bits del registro.</div>
<br />
<div align="center">
<em>Uso de la máscara de bit</em><a href="https://lh3.googleusercontent.com/-_pgqVjmVa-c/WZ4cQHxltZI/AAAAAAAAAhw/jLfbLFMyzUw7ywIIte7LymAsq2LsPzjaQCHMYCw/s1600-h/image%255B11%255D"><img alt="image" border="0" height="30" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjmUPLJOyTiAtqazdICy_H4ZQJlLpRW0YtATEgsLW_n1pgz4KlaRhCsdPg_6UeGw9Dz4OD4jgtdZrzzY8_7SCZV213J70aQIal1EifogMQOiQV1EdUtvsKdafNEVv3upZUDRfflURg6EaDC/?imgmax=800" style="background-image: none; border-bottom: 0px; border-left: 0px; border-right: 0px; border-top: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="image" width="229" /></a></div>
<br />
<h3>
3.4.2 Máscara de grupo de bits.</h3>
<div align="justify">
Muchas funciones son controladas por un grupo de bits. Los bits <span style="font-family: Courier New;">EVACT[2:0]</span> y <span style="font-family: Courier New;">EVSEL[3:0]</span> son grupos de bits en el registro <span style="font-family: Courier New;">CTRLD</span> del Timer/Counter. Los valores de esos bits seleccionan una configuración específica. </div>
Cuando cambiamos bits en un grupo de bits, a menudo se requiere limpiar el grupo de bits antes de asignar un nuevo valor. Para decirlo de otro modo: No es suficiente con setear los bits que deben ser seteados, también se requiere limpiar los bits que deben ser limpiados. Para que esto sea fácil se definen las máscaras de grupos de bits. Las máscaras de grupo usan el mismo nombre como los bits en el grupo de bits y un sufijo “<span style="font-family: Courier New;">_gm</span>”.<br />
<div align="justify">
El código de la siguiente figura muestra como la máscara de grupo se relaciona con las máscaras de bit. En realidad, los valores de máscara de grupo se precalculados en los archivos cabecera, entonces el compilador no necesita calcular la misma constante una y otra vez.</div>
<div align="justify">
<br /></div>
<div align="center">
<em>Relación entre máscara de grupo y máscara de bit.</em><a href="https://lh3.googleusercontent.com/-bc-7vGibuvE/WZ4glNa5rWI/AAAAAAAAAiA/UGcgsjwLN9os44Y8uZEGLyhBaweQuC0WQCHMYCw/s1600-h/image%255B16%255D"><img alt="image" border="0" height="150" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjj90jXPSL5p92il6NCIajbZHLmar7XKW02mTZ8pOYhQvtMY3EFT1Jerp19t0xlBzFOCNhX6_5T1Z9w_Fx2C2wLFY9rnYFCqwsl55q7DM4FtyrFJOtj1pfucywycjwAKXH4pKEkJx_3niwK/?imgmax=800" style="background-image: none; border-bottom: 0px; border-left: 0px; border-right: 0px; border-top: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="image" width="511" /></a></div>
<br />
La máscara de grupo de bits esta principalmente destinada para borrar una configuración antigua antes de escribir la nueva. En el código de la siguiente figura de muestra como hacerlo. El código limpia el grupo de bits EVACT en el registro CTRLD del Timer/Counter D0.<br />
<br />
<div align="center">
<em>Uso de máscara de grupo</em><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgI5xSf-FZom6awRohfTavkUhYyo7jVV2dUmaRc3tnuiocIFTk2BZkobeoR2_YEWp-7GC4VvsHXwjsHYgjYdCIXCTsqZ1lEI-h3U4tsRWeUkab-0Ud5KO9HyMo3LtfsSw6lRfILmtm8fbjp/s1600-h/image%255B5%255D"><img alt="image" border="0" height="30" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgGUJd2GjtxIfa6zyNq1z-oKS1HtwU9UxRI0NHRqEMH1jOg6wEPoeCfiPufR-uXmvBhTdXQmT-vhVSfLjo1Amb1qnNi0kAz0Mrt-jyJS2o5Y8p-2wcSRUBjgJHzrqmQA-dSUaxi_7d1Z5IC/?imgmax=800" style="background-image: none; border-bottom: 0px; border-left: 0px; border-right: 0px; border-top: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="image" width="543" /></a></div>
<br />
<h2>
3.5 Máscara de configuración de grupo de bits</h2>
<br />
<div align="justify">
A menudo se requiere consultar la hoja de datos para investigar cual patrón de bits necesita ser usado cuando seteamos un grupo de bits para una configuración especifica. Esto también se aplica a las lecturas o depuración del código. Para incrementar la legibilidad y minimizar la probabilidad de setear bits incorrectamente, es que se encuentran disponibles las máscaras de configuración de grupo.</div>
<div align="justify">
El nombre de una máscara de configuración de grupo es concatenado al módulo tipo, al nombre del grupo de bits, a una descripción de la configuración y un sufijo “_gc”, indicando que este es un grupo de configuración. Un ejemplo de esto es mostrado en la siguiente figura.</div>
<div align="justify">
<br /></div>
<div align="center">
Composición del nombre del grupo de configuración<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh9fu7GSYr1q1uIf2pOnnEUC_Sfj9_XFvLC-pAd5VQ1xb3_jg92kKLeDfhS8FVbi_BoN5yFOSbF_zkcBqtYx9YQEHhCupDdPiJX0HacNnPdFwalvq4jaryID-JCmSihgy5o5m00ZJhEtB_g/s1600-h/image%255B10%255D"><img alt="image" border="0" height="158" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiTUNFXjGKMirYNvdezGJ7lSM1S_0R-tyBFN9prDwo1AWBwUioZUqKIzF-5TmGaDhhiQm7-KVZCeo6ox9SASoLJGw6bZqU0SUNCmRcpVviDJSS85dyNfVeusWNev84r76v1SW2kXb05FBKv/?imgmax=800" style="background-image: none; border-bottom: 0px; border-left: 0px; border-right: 0px; border-top: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="image" width="548" /></a></div>
<br />
Inspeccionando la figura anterior podemos ver que esta es usada para seleccionar una configuración para los bits RXCINTLVL en el módulo USART. Este grupo selecciona un nivel de interrupción alto (HI) . <br />
El grupo de bits para los niveles de interrupción por recepción completa está compuesto de dos bits, RXINTLVL[1:0]. La siguiente tabla muestra las configuraciones disponibles para este grupo. Los nombres de las configuraciones son “OFF”, “LO”, “MED” y “HI”. Estos nombres hacen más fácil la escritura y el mantenimiento del código. <br />
<br />
<div align="center">
<em>Bits RXINTLVL y su correspondiente nivel de interrupción</em><a href="https://lh3.googleusercontent.com/-LQLQo7T4iqQ/WaBzF6krtKI/AAAAAAAAAio/GmnXHrP9M8oUDNbrk8cDkIicMIBkiDMegCHMYCw/s1600-h/image%255B15%255D"><img alt="image" border="0" height="152" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjZAU2E7MyKt15UCul9EtVoU5p0b94SUZBU7Ruy7kaw3icHfkaiTdRxt5gIz0UgwW8sekLAOpWWjQzIpIBRTxxv2bzxdNQ2ZdzdRVuPJteZex0aAZVVIZHiutfnB66dL4A7ruOJvIxjHh1d/?imgmax=800" style="background-image: none; border-bottom: 0px; border-left: 0px; border-right: 0px; border-top: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="image" width="710" /></a></div>
<br />
<div align="justify">
Para cambiar un grupo de bits a una configuración nueva, el grupo de bits de configuración (_gc) es típicamente usado junto con la máscara de grupo de bits (_gm), esto con el fin de asegurarse que la configuración vieja sea borrada primero. En la siguiente figura se aprecia un ejemplo de esto. Aquí se limpian los bits de nivel se interrupción para luego seleccionar un nuevo nivel (nivel medio).</div>
<br />
<div align="center">
<em>Cambiando un grupo de configuración</em><a href="https://lh3.googleusercontent.com/-3W78-B5dhRY/WaBzHoVKYxI/AAAAAAAAAiw/44Lubhsp0x47LctB5zGQD2IqTviOPTvGACHMYCw/s1600-h/image%255B20%255D"><img alt="image" border="0" height="26" src="https://lh3.googleusercontent.com/-FgPrXFxRNVI/WaBzI5c160I/AAAAAAAAAi0/k5qqkJ3Da4kvbjvUjI_WannoRygrKzdggCHMYCw/image_thumb%255B11%255D?imgmax=800" style="background-image: none; border-bottom: 0px; border-left: 0px; border-right: 0px; border-top: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="image" width="684" /></a></div>
<br />
<div align="justify">
El uso de la máscara de grupo para limpiar no es siempre requerida, el código mostrado en la siguiente figura muestra como todos los niveles de interrupción del USARTC0 pueden ser configurados a la vez. Recepción completa, transmisión completa y la interrupción por registro de datos vacío con seteadas a niveles medio, off y bajo respectivamente.</div>
<br />
<div align="center">
<em>Seteando todas las interrupciones a la vez</em><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiXydEcQw-N3UNoZlmLgSZ_rdTB2APtlQEpdy7YBcAaCyvpHvl9B85JZ95FaONqlzNES4OP1PGRIOcJ6_9vni7KW92KdAsmK9Z2xY6VGvqNTkOtbEKBXzyJVt-GLYAxF8YNeHLBKAtiaTXT/s1600-h/image%255B26%255D"><img alt="image" border="0" height="31" src="https://lh3.googleusercontent.com/-D2QRn6OpmaE/WaBzJ8AtECI/AAAAAAAAAi8/OtUJvJ2GbrEZEWSWvfkZGRx5zAqpGYq3wCHMYCw/image_thumb%255B15%255D?imgmax=800" style="background-image: none; border-bottom: 0px; border-left: 0px; border-right: 0px; border-top: 0px; display: inline; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="image" width="734" /></a></div>
<br />
<br />
<h3>
3.5.1 Enumeración de máscara de configuración de grupo</h3>
<div align="justify">
A diferencia de las máscaras de bit (_bm) y máscaras de grupo (_gm), las máscaras de configuración de grupo son definidas usando enumeradores. Un enumerador es definido para cada grupo de bits. El enumerador para el grupo USART RXCINTLVL es mostrado en la siguiente figura.</div>
<div align="center">
<em>Enumerador USART RXCINTLVL</em><a href="https://lh3.googleusercontent.com/-aPvuZr_dgV0/WaBzKR60bUI/AAAAAAAAAjA/MKc8Pw2DGM0D7hwe7WsrFDMDo-9Dw59ygCHMYCw/s1600-h/image%255B31%255D"><img alt="image" border="0" height="149" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgIohyphenhyphenlzkHhp84JFd1Idv-ipHqeZUNVzD4LJbt9y-q5TxHGh0Xe0qYN9h6xvf4fVVVHI3CtPgrhSk1EtJh9jp5sQtbprojqHBKFXnqs0jSXM8wLGAHCvbld_rFxLgskiKNMSC31POtr6zAi/?imgmax=800" style="background-image: none; border-bottom: 0px; border-left: 0px; border-right: 0px; border-top: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="image" width="545" /></a></div>
<br />
<br />
<h2>
3.6 Llamadas a funciones y módulos</h2>
<div align="justify">
Cuando escribimos drivers para un módulo tipo que tiene múltiples instancias, el hecho de que todas las instancias tenga el mismo mapa de memoria puede utilizarse para hacer que el driver sea reutilizable para todas las instancias del mismo módulo. Si el driver toma un argumento tipo puntero, apuntando a la instancia del módulo, el driver se puede utilizar para todos los módulos de este tipo.</div>
<div align="justify">
La función para inicializar y acceder a los m´dulos Timer/Counter puede ser compartida por todas las instancias del módulo. Aunque hay una pequeña sobre carga en pasar el puntero del módulo a las funciones, el tamaño total del código a menudo se reducira ya que el código es reusado para todas las instancias de cada módulo. Incluso mas importantes, el tiempo de desarrollo, el costo de mantenimiento, y la portabilidad pueden ser mejoradas usando este enfoque.</div>
<div align="justify">
El código de la siguiente figura muestra una función que usa un puntero a un módulo para seleccionar una fuente de clock para cualquier Timer/Counter.</div>
<div align="justify">
<br /></div>
<div align="center">
<em>Ejemplo de función usando un puntero a la instancia de un módulo</em><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg627cLqcNH5RQeuG3M37guB0gsiKKGXPGhDStcUnWsijjWAUjnj-v8vjT0lE0siPOAwUakOErAfJPOYER2vSlR5cjsh5W3S_PYJOQTNBA3uNfjtt7jbShLJNew3EkoyWs6rxZrkJr7P8PI/s1600-h/image%255B44%255D"><img alt="image" border="0" height="85" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi8m83MgEh7PtIi3d-hV6xwDQCpWMuP1JfCyl-bJ6pRPCK89UKRcW1s9BYqdpfHY0GpfUDRgHXLXX5d0DzEfjUgPs6uPu-1M1bhrwKJUnhG1F0MbRVseFCRxhwe9kB-onRdZB47wpdUzToN/?imgmax=800" style="background-image: none; border-bottom: 0px; border-left: 0px; border-right: 0px; border-top: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="image" width="618" /></a></div>
<br />
<div align="justify">
La función anterior toma dos argumentos: un puntero a módulo de tipo <span style="font-family: Courier New;">TC0_t</span>, y un grupo de configuración de tipo <span style="font-family: Courier New;">TC_CLKSEL_t</span>. El código en la función usa el puntero al módulo Timer/Counter para acceder al registro <span style="font-family: Courier New;">CTRLA</span> y setear el nuevo clock.</div>
<div align="justify">
El código de la siguiente figura muestra como la función puede ser usada para configurar diferentes módulos Timer/Counter con diferentes fuentes de clock.</div>
<br />
<div align="center">
<em>Llamadas a la función que toma puntero a módulo como parámetro</em><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg587aFKpSrWt4amORzeuvpFA16IMG-JU-hDfGbjCVIeGSV2PECBPSuYuy1GnYSVADhg5nY_P2Ypo4WBVgVY5btOkKM3YvpI1m04iJOT9v_yCZ-1EHtYDHUfaXWXOeUZUPbBX0hmcGVZZrR/s1600-h/image%255B43%255D"><img alt="image" border="0" height="82" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgHFb0oRX4zbx90u4qPOOFj8f25_Y_mltbbDcj7C416bDZr_oDHK2__ZRobLPtdUvOpqCHNcTCI7rgmFp-9K4SS6R-ZD8B-tWPddxYYVDW-lRir1R3Jw4SQYVBgaLl03l3WL06CueFxu8nT/?imgmax=800" style="background-image: none; border-bottom: 0px; border-left: 0px; border-right: 0px; border-top: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="image" width="422" /></a></div>
<br />
<h1>
4. Sumario</h1>
Para referencia, una vista general de los difentes sufijos usados se muestran en la siguiente tabla.<br />
<br />
<a href="https://lh3.googleusercontent.com/-dwauAJJnbjg/WaBzNOQrsGI/AAAAAAAAAjY/yelOCmK_NBA4n7xNJMJiz5NsIx0sRcK6wCHMYCw/s1600-h/image%255B49%255D"><img alt="image" border="0" height="152" src="https://lh3.googleusercontent.com/-qJCn7QLuyaU/WaBzN3wkTeI/AAAAAAAAAjc/XCfQfYUnPEMDO60X_rPm3r3YGh5fqcEjwCHMYCw/image_thumb%255B28%255D?imgmax=800" style="background-image: none; border-bottom: 0px; border-left: 0px; border-right: 0px; border-top: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="image" width="541" /></a><br />
<br />
<br />
<br />
…..escribiendo…..<br />
<br />
Anonymoushttp://www.blogger.com/profile/14023938257857442019noreply@blogger.com0tag:blogger.com,1999:blog-7123434971804829465.post-86454553326590368862017-08-10T11:18:00.000-07:002017-08-12T09:38:16.068-07:00Empezando con XMEGA (AVR1005)<div align="center">
<br /></div>
<h1>
1. Introducción:</h1>
<div align="justify">
<br />
Desde que Atmel (ahora microchip) amplio su portafolio de productos con la familia XMEGA surgieron muchas preguntas, si esta es una nueva arquitectura, cómo transferir los conocimientos de megaAVR a AVR XMEGA, etc. Aquí trataremos brevemente las similitudes y diferencias entre las dos familias, y proporcionaremos una visión general de las herramientas disponibles. <br />
<br /></div>
<div align="justify">
Los usuario de AVR ocasionalmente mencionaron que ellos querían dispositivos con un menor consumo de potencia, periféricos más potentes, más timers, DMA, multiples niveles de interrupción, más memoria y un mejor rendimiento del CPU. Bien, con XMEGA ahora tienes todo esto, Adicionalmente tienes el sistema de eventos (Event System), motor de encriptación (Crypto Engine), ADC y DAC de 12-bit, calibración de los osciladores en tiempo real, chequeo CRC, y otras características. <br />
<br /></div>
<div align="justify">
Adicionalmente, los periféricos dentro de una familia son similares y están organizados de la misma manera para todos los miembros de la familia, haciendo que portar código de un XMEGA a otro sea una tarea sencilla. </div>
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjqQRsjkBL1dsbkwqh2WjYnhtg0nQtpQewEYOWlqs9qkzWipktZvjpxPBLKD-r5oFN-TN7Hei4KG_nhs-UerMcj9Xcry_I3X1JcIoEn5O93ss5XUkjtSlz1zNA92sPEf9grLDP5bzq0DDE/s1600/chip_grafico_arquitetura-avr-900x811.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="811" data-original-width="900" height="576" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjqQRsjkBL1dsbkwqh2WjYnhtg0nQtpQewEYOWlqs9qkzWipktZvjpxPBLKD-r5oFN-TN7Hei4KG_nhs-UerMcj9Xcry_I3X1JcIoEn5O93ss5XUkjtSlz1zNA92sPEf9grLDP5bzq0DDE/s640/chip_grafico_arquitetura-avr-900x811.png" width="640" /></a></div>
<div style="text-align: center;">
<br /></div>
<br />
<h1>
2. Introducción a XMEGA(diferencias y similitudes con los megaAVR) </h1>
<div align="justify">
<br />
Esencialmente el XMEGA es un AVR de 8 bits. XMEGA usa la arquitectura y CPU AVR, pero con características adicionales y periféricos mejorados. XMEGA usa el mismo conjunto de instrucciones, las mismas herramientas de desarrollo y compiladores que megaAVR. El CPU puede funcionar más rápido que antes y con un voltaje más bajo. </div>
<br />
<br />
<h2>
2.1 Preguntas comunes acerca de XMEGA</h2>
<div>
<br /></div>
<ul>
<li> <div align="justify">
XMEGA y megaAVR no son compatible en pines. Esto no fue posible de alcanzar debido al deseo de hacer el dispositivo más modular. </div>
<div align="justify">
<br /></div>
</li>
<li>XMEGA opera con voltajes desde 1.6V hasta 3.6V. Esto se debe en parte al proceso de fabricación, el cual es seleccionado desde el punto de vista del bajo consumo de energía. La operación a 5V no es posible. El menor voltaje de funcionamiento no significa un menor rendimiento del CPU ya que XMEGA puede correr hasta 32MHz desde los 2.7V.</li>
</ul>
<h2>
</h2>
<h2>
2.2 Estructuras y migración</h2>
<div align="justify">
<br />
Los XMEGA están estructurados para fácilmente portar entre dispositivos. Por ejemplo, PORTA y PORTB serán dedicados a las interfaces analógicas ADC y DAC o a dos Comparadores Analogicos. PORTC, D y E serán para interfaces seriales. También, todos los módulos están definidos en estructuras (<span style="font-family: "courier new";">typedef struct</span>). Esto quiere decir que para acceder a los registros del ADC se debe hacer mediante la estructura ADC. Además, dado que el ADC es definido es una estructura, la idea es que esta estructura será la misma para todos los dispositivos de la misma familia. Entonces sí tu empezaste con un ATxmega64A4, debería ser una tarea sencilla migrar a un ATxmega128A4 o un ATxmega256A1; ya que tu estas usando la misma estructura y así tu puedes usar el exactamente el mismo código. Con megaAVR no podemos hacer una estructura de un módulo para definir todos ellos ya que los diferentes dispositivos podrían tener diferentes diseños.<br />
<br /></div>
<div align="justify">
Las familias XMEGA son distinguibles por una letra: La primera familia es ATxmega[###]A[#](Familia A). Antes de la letra de la familia se encuentra un número el cual representa el tamaño de la memoria flash, y después de la letra de la familia encontraras otro número que será el ID de la familia, el cual identifica dispositivos individuales. Dispositivos con el mismo ID tiene exactamente las mismas características y el mismo número de pines pero pueden estar disponibles en diferentes tamaños de memoria. <br />
<br /></div>
<div align="justify">
<br /></div>
<h2 align="justify">
2.3 Manual y Hoja de datos</h2>
<div align="justify">
<br />
La estructura de los XMEGA hace posible hacer un gran manual para describir todos los módulos y periféricos dentro de una familia. Los detalles que harán un dispositivo diferente otro, como características y periféricos disponibles serán descritos en una pequeña hoja de datos. <br />
<br /></div>
<div align="center">
<br /></div>
<div align="center">
Hoja de datos</div>
<div align="center">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjW9MnpOklu5oDQ4i1JiRu_1YnBmmsf6eRp6TNMgILXli1PLEL2oEsINwzSP_nkDRYj54Gk28OUdj9vcx5PvX6Fw3X8j7lWfaZQY6KPnmWO4RoZzuAF4Wsxg7phV5BBkRA7SDk_WhLJJReq/s1600-h/image8"><img alt="image" border="0" height="67" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjNX6cqPoJ1PvrINHHVRRHms5IS4muWwK0jf2jbTZIUXKK-X0uNMw4uF4shV4bbk8FKYyo_muNm53uZZYtwHmdilEFSAfdZ4I6zQhEHAbz0-Fh0hCoVB0YTIIxPPKKjMocYT_PEvwAX5iWv/?imgmax=800" style="background-image: none; border-bottom: 0px; border-left: 0px; border-right: 0px; border-top: 0px; display: inline; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="image" width="246" /></a><br />
<br /></div>
<div align="center">
Manual</div>
<div align="center">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgwLplj9QhdOPqfBPEp8Lm4_LkQ6jDSIXsruVtrNHKRP3DGAT4oxXFm16YKj-leDAnkOOo73s2jRbB-DyjpUsG-X6dc2tw1E4RwzRcN6BQ-1yRKSe-lZCozarQD7ee9EbCzbiOl5mN8UuOZ/s1600-h/image9"><img alt="image" border="0" height="74" src="https://lh3.googleusercontent.com/-mZ31ZTyYgP0/WXOTQK_p-fI/AAAAAAAAAcc/cd4bk7tfBQEQxHqqlbDK7GbxBG_TU-dIgCHMYCw/image_thumb5?imgmax=800" style="background-image: none; border-bottom: 0px; border-left: 0px; border-right: 0px; border-top: 0px; display: inline; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="image" width="246" /></a></div>
<br />
<div align="justify">
<br />
Por ejemplo, se podrían recopilar todas las funciones descritas para todos los dispositivos A1, A3 y A4 en la familia XMEGA-A. Así pues el manual XMEGA A es un documento profundo para todos los módulos que están disponibles en la familia A. Por otro lado la hoja de datos para la sub familia A3 que no son comunes con A1 y A4. </div>
<br />
<br />
<h2>
2.4 Sistema de eventos (Event System)</h2>
<div align="justify">
<br />
El sistema de eventos es un características totalmente nueva de los XMEGA. No encontraras Event System in megaAVR. El sistema de eventos es comunicación entre los periféricos del XMEGA. Un canal de eventos no es un bus, sino un canal dedicado en el que sólo se puede señalar un evento a la vez. Ya que los eventos están en un canal dedicado, estos serán muy predecibles y rápidos. Realmente, habrá un máximo de 2 ciclos de reloj. Con los eventos, el CPU no está involucrado y no hay interrupciones (ISRs). Finalmente, el sistema de eventos es extremadamente poderoso ya que este no ocupa el CPU y puede ahorrar energía e incrementar el rendimiento en el sistema debido a que se reduce el número de interrupciones. <br />
<br /></div>
<br />
<div align="center">
XMEGA Event System trata sobre la comunicación entre perifericos</div>
<blockquote>
<div align="center">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiuYKOyJFeIFrE0tMyA788wYMO4PN51fwrrskZqlnPr4lmTIyo-d1YB2aRafxtQBjUrhpcdZ8wOLTmPDpVRyS3NhNPI2-CBP6B_isRRwN6GFtt-NnU1Rp-O60IRNkLHExKiDmOL__oHe01b/s1600-h/image5"><img alt="image" border="0" height="241" src="https://lh3.googleusercontent.com/-zxVK0lxLBcI/WXOTRR0b5oI/AAAAAAAAAck/yOxbmII1QX0vEQh5LAiUXkCicw-ovr4WwCHMYCw/image_thumb2?imgmax=800" style="background-image: none; border-bottom: 0px; border-left: 0px; border-right: 0px; border-top: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="image" width="398" /></a></div>
</blockquote>
<br />
<div align="justify">
<br />
Veamos un ejemplo. Tu puede por ejemplo usar el sistema de eventos para enlazar dos timer de 16 bits y obtener uno de 32 bits. O puedes usar un evento para sincronizar dos módulos. Por ejemplo, puedes usar el evento de cambio para realizar un conversión con el ADC y una captura de la entrada con el timer para obtener el tiempo exacto de cada conversión. Aún más, otro ejemplo podría ser permitir que un evento dispare conversiones ADC para muestrear música desde un micrófono y cuando la conversión se haya completado el DMA copiará los datos a la RAM. Cuando el usuario presione un switch se generará un evento que copiará los bytes al DAC para reproducir lo previamente grabado. Todo esto se puede hacer estando el XMEGA en modo sleep. </div>
<div align="justify">
<br />
<br />
<br /></div>
<h2 align="justify">
2.5 Segunda Generación PicoPower</h2>
<div align="justify">
<br /></div>
<div align="justify">
Los XMEGA llevan la tecnología PicoPower al siguiente nivel. Todos los XMEGA son probados para operar a 1.6V. Eso significa que todos los periféricos y módulos que pueden correr a 3.6V también pueden correr a 1.6V. Un menor voltaje implica un menor consumo de corriente. Hay nuevos diseños para el watchdog para el circuito Brown Out (BOD). El watchdog corre típicamente con 1uA. La corriente de consumo para el BOD es también de 1uA. De todos las características de bajo consumo, quizá la mejor sería reducir el tiempo en modo activo y remplazar este trabajando más a menudo en IDLE modo usando el DMA y el Sistema de eventos. </div>
<div align="justify">
<br />
<br /></div>
<h2 align="justify">
2.6 Sistema de reloj</h2>
<div align="justify">
<br />
La fuente de reloj y frecuencia pueden ser cambiadas mientras el XMEGA está funcionando. Se puede seleccionar un oscilador interno(RC) de 2MHz y uno de 32MHz. El RC de 2MHz es la fuente de reloj por defecto cuando el XMEGA inicia. Este inicia rápidamente en contraste a cristales externos y resonadores cerámicos los cuales necesitan bastante tiempo para empezar a oscilar. El dispositivo puede comenzar ejecutando el código de inicialización mientras el oscilador externo se estabiliza. Una vez que el oscilador externo está listo para ser usado el cambio de fuente de reloj debe ser realizado por el programa. La frecuencia de reloj puede ser cambiada en cualquier momento mediante el uso del PLL y prescalers. <br />
<br /></div>
<div align="justify">
Si usamos el PLL interno, la señal de reloj puede ser multiplicada (x1, x2, x3,…, x31). Tú puedes incrementar la señal de reloj principal (max 32MHz) o incrementa la velocidad de los periféricos, por ejemplo se puede alcanzar 128MHz como señal de entrada de un Timer/Counter para obtener un señal PWM con alta resolución. <br />
<br /></div>
<div align="justify">
Adicionalmente, el “Monitor de fallas de la fuente de reloj externa” puede detectar si la señal de reloj falla(ej: debido a daño físico del cristal) y automáticamente cambiar al RC interno de 2MHz. </div>
<div align="justify">
<br />
<br /></div>
<h2 align="justify">
2.7 Controlador de Interrupciones Multinivel.</h2>
<div align="justify">
<br />
Ya que los XMEGA tiene más fuentes de interrupción que un megaAVR, se ha adicionó un controlador de interrupciones multinivel. Esto facilita el manejo de muchas fuentes de interrupciones de manera oportuna de acuerdo con las prioridades establecidas. Si por ejemplo una fuente de interrupción con una alta frecuencia es atendida con tanta frecuencia que las otras interrupciones en el mismo nivel no son atendidas, entonces puede ser buena idea bajar la prioridad de la primera fuente de interrupción, ósea la de alta frecuencia. </div>
<div align="justify">
<br /></div>
<h2 align="justify">
</h2>
<h2 align="justify">
2.8 Principales Funciones Analogicas.</h2>
<div align="justify">
<br />
Con XMEGA se introducen algunas características importantes para un MCU de 8 bits. Tanto el ADC como el DAC y tienen una resolución de 12 bits. El ADC puede alcanzar hasta 2 millones de muestras por segundo. También hay una característica llamada “event or interrupt on conversion complete”, la cual sólo generará una interrupción de conversión completa cuando el resultado se encuentre por debajo o por encima de un cierto límite. <br />
<br /></div>
<div align="justify">
El DAC puede dar dos salidas incluso cuando sólo se usa un módulo. Esto es gracias a que se cuenta con un circuito separado de muestreo y retención que permitirá, por ejemplo, una salida estéreo con sólo un DAC. <br />
<br /></div>
<div align="justify">
El Comparador Analógico (AC) tiene una nueva característica llamada “windows mode”(modo ventana) cuando se usan dos módulos AC a la vez. Entonces, tu puedes ingresar dos limites (nivel bajo y alto) y la señal de entrada a ser comparada. El resultado estaría debajo, dentro o sobre la ventana. El resultado la comparación también se puede reflejar en un pin de salida. </div>
<div align="justify">
<br />
<br /></div>
<h2 align="justify">
2.9 Interfaz de Bus Externo (EBI).</h2>
<div align="justify">
<br />
El EBI disponible en XMEGA soporta memorias hasta de 16MB. Son soportadas las memorias SRAM y SDRAM. Las memorias SDRAM son de bajo costo y gran capacidad, pero no es posible combinarlas con otras unidades mapeadas que requieran una interfaz de bus tipo SRAM. Debido al soporte para grandes memorias, el tiempo de ejecución de cada instrucción que accede a memorias ha cambiado ligeramente. Además, cuando se compila para memorias de gran capacidad el tipo de dato usado para direccionar cambia de 16bits a 24bits.</div>
<div align="justify">
<br />
<br /></div>
<h2 align="justify">
2.10 Motor de Encriptación (Crypto Engine).</h2>
<div align="justify">
<br />
Para la comunicación con protocolos, ya sea alámbrico o inalámbrico, la encriptación de la información es necesaria para una comunicación segura. <br />
<br /></div>
<div align="justify">
XMEGA implementa tanto AES como DES, y puede realizar tanto la encriptación como la desencriptación. AES es un hardware que libera al CPU de toda la carga. Este módulo puede proveer 1.25Mbps de comunicación encriptada con una llave de 128bits. </div>
<div align="justify">
</div>
<div align="justify">
<br /></div>
<div align="justify">
<br />
<br /></div>
<h1 align="justify">
3 Que herramientas usar?.</h1>
<div align="justify">
<br />
<br /></div>
<div align="justify">
Para la escritura de código se puede usar el ya muy conocido Atmel Studio. Se recomienda leer la nota de aplicación AVR1000 (Getting Started Writing C-code for XMEGA) que es una introducción al estilo de codificación que se ha elegido y también describe como acceder a los periféricos. </div>
Los programadores/depuradores recomendados son el ATMEL-Ice ó el JTAGICE3 (ya no está en producción). <br />
<br />
<br />
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<iframe allowfullscreen="" class="YOUTUBE-iframe-video" data-thumbnail-src="https://i.ytimg.com/vi/IAX_eZklI1c/0.jpg" frameborder="0" height="266" src="https://www.youtube.com/embed/IAX_eZklI1c?feature=player_embedded" width="320"></iframe></div>
<div style="text-align: center;">
<br /></div>
<br />Anonymoushttp://www.blogger.com/profile/14023938257857442019noreply@blogger.com1tag:blogger.com,1999:blog-7123434971804829465.post-25607761720004461952017-04-17T16:58:00.003-07:002017-04-17T16:58:53.990-07:00CREANDO COMPONENTE ISIS - PROTEUS<br />
<div class="separator" style="clear: both; text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: justify;">
El video muestra la creación de un componente(FT232HL). El componente es creado para la creación de PCBs, no para simulaciones.</div>
<div class="separator" style="clear: both; text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<iframe width="320" height="266" class="YOUTUBE-iframe-video" data-thumbnail-src="https://i.ytimg.com/vi/fgti0EJZ-_8/0.jpg" src="https://www.youtube.com/embed/fgti0EJZ-_8?feature=player_embedded" frameborder="0" allowfullscreen></iframe></div>
<br />Anonymoushttp://www.blogger.com/profile/14023938257857442019noreply@blogger.com2tag:blogger.com,1999:blog-7123434971804829465.post-3514539412915467702017-04-17T16:56:00.001-07:002017-04-17T16:56:23.183-07:00RING BUFFER UART - ATmega328p<br />
<div class="separator" style="clear: both; text-align: center;">
<u><b>PARTE 1</b></u></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<iframe width="320" height="266" class="YOUTUBE-iframe-video" data-thumbnail-src="https://i.ytimg.com/vi/zaHU1tzAZE0/0.jpg" src="https://www.youtube.com/embed/zaHU1tzAZE0?feature=player_embedded" frameborder="0" allowfullscreen></iframe></div>
<br />
<br />
<div style="text-align: center;">
<br /></div>
<div style="text-align: center;">
<b><u>PARTE 2</u></b></div>
<div style="text-align: center;">
<b><u><br /></u></b></div>
<div class="separator" style="clear: both; text-align: center;">
<iframe width="320" height="266" class="YOUTUBE-iframe-video" data-thumbnail-src="https://i.ytimg.com/vi/rq1sUr8UMlg/0.jpg" src="https://www.youtube.com/embed/rq1sUr8UMlg?feature=player_embedded" frameborder="0" allowfullscreen></iframe></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
<span style="color: lime; font-size: large;">Link: <a href="https://drive.google.com/open?id=0B3OsL7DPo1s0TXlJM1AwaFo0UUE"><span style="color: lime;">EJEMPLO</span></a></span></div>
<div style="text-align: center;">
<b><u><br /></u></b></div>
jrsfhttp://www.blogger.com/profile/04364143443693071318noreply@blogger.com0tag:blogger.com,1999:blog-7123434971804829465.post-52455956545411606112016-03-28T13:06:00.000-07:002016-08-08T09:37:27.802-07:00I2C + RTC DS3231 usando C<br />
En el siguiente post mostraré cómo leer y escribir, mediante I2C, un rtc DS3231 de Maxim integrated.<br />
<br />
<div align="justify">
El DS3231 es un RTC serial con una exactitud muy alta gracias a su oscilador interno de 32KHz que es compensado ante los cambios de temperatura (TCXO u Osciladores de Cristal Compensados por Temperatura). La hoja de datos nos dice que podemos tener una exactitud de ±2ppm que podemos traducir en unos 126 seg por año.</div>
<div align="justify">
</div>
<div align="justify">
La lectura y escritura de registros del DS3231 se realiza mediante la interfaz I2C a una velocidad de 400KHz.<br />
<br /></div>
<div align="justify">
</div>
<div align="justify">
El ejemplo presentado en este post es para un ATmega32, pero puede ser fácilmente adaptado a otros microcontroladores. </div>
<div align="justify">
</div>
<div align="justify">
En este post anterior (<a href="http://avrperu.blogspot.pe/2011/04/i2c-en-atmega8.html"><strong><span style="color: lime;">I2C con ATmega8</span></strong></a>) se explica el funcionamiento del bus I2C, aquí sólo mostraré y explicare las librerías I2C y RTC necesarias para la escritura y lectura del DS3231.<br />
<br />
<br /></div>
<div align="justify">
</div>
<div align="justify">
</div>
<div align="justify">
</div>
<div align="justify">
<strong><em><u>I2C ATmega</u></em></strong><br />
<strong><em><u><br /></u></em></strong></div>
<div align="justify">
</div>
<div align="justify">
</div>
<div align="justify">
El ATmega32 cuenta con 4 registros los cuales son mostrados en la figura 1 y que debemos conocer . En ellos se configura la velocidad del bus, se controla el bus, se tiene acceso a los estados del bus y de puede leer/escribir los datos recibidos/enviados.<br />
<br /></div>
<div align="justify">
</div>
<div align="justify">
</div>
<div align="center">
Figura 1.<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhNWI2ha0O04eZrAUuECnkpEe7Rv4_mtcyt9aR9zow_Se9V8y1kKDMSSN0WuOe0GKXAAPo5F8Fsb6jw5hFbnjh47aBh5KFq-23OqP3U3uaSm9fXQjBoPORCxPpl5EOX3pIYhVbst8aWvTzT/s1600-h/image%25255B12%25255D.png"><img alt="image" border="0" height="91" src="https://lh3.googleusercontent.com/-d-KInuxjPyI/Vvl9JYcyJbI/AAAAAAAAAW8/L7MpMOpbTgQ/image_thumb%25255B6%25255D.png?imgmax=800" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="image" width="209" /></a></div>
<br />
<strong><em><u></u></em></strong><br />
<strong><em><span style="font-size: small;"><u>PARTE 1.</u> Files I2C</span></em></strong><br />
<strong><em><span style="font-size: small;"></span></em></strong><br />
<strong><em><u>file i2c.h.</u></em></strong> Contiene las definiciones necesarias para configurar el bus I2C.<br />
<ul>
<li>En la figura 2 se calculan los posibles valores del registro <span style="font-family: "courier new";">TWBR</span> en base a la velocidad del bus I2C (400KHz). </li>
</ul>
<br />
<div align="center">
Figura 2.<a href="https://lh3.googleusercontent.com/-nz4xaHlBZFs/Vvl9JxoEWnI/AAAAAAAAAXA/pbV2EvHxJ6E/s1600-h/image%25255B22%25255D.png"><img alt="image" border="0" height="152" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjtVKFB0dotTs-hwuqpYEbMSeCCxnCHqKiEDDH9QAfL00NozppihC_cQZMsT86zBCPE40YhOhWq15ZpT2sWiRkdI_yHDZVtfHePPtfQmtB69ObokuH38xYkXS45coCKVk4ZUTqOKEDULPi-/?imgmax=800" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="image" width="352" /></a></div>
<br />
<ul>
<li>En la figura 3 se selecciona el correcto valor del registro <span style="font-family: "courier new";">TWBR</span> y de los bits de pre-escaler (<span style="font-family: "courier new";">TWPSX</span>). </li>
</ul>
<br />
<div align="center">
Figura 3.<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjd5tczds6n37D20cvgZYM7i8GhL6tK5anBcz_wh9br3HlMWgiHiLt-SOFYtvj35uZ4d3ActYLT_Sh49cwNk38miKXvctMlhHzUapBg1Fg1eX0s7_cSiP4QtQI-JJ1TN8TL9AB85mWXtGot/s1600-h/image%25255B27%25255D.png"><img alt="image" border="0" height="276" src="https://lh3.googleusercontent.com/-qxaRvc1Djec/Vvl9LEqAsHI/AAAAAAAAAXM/Aci0cLpGV8E/image_thumb%25255B15%25255D.png?imgmax=800" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="image" width="260" /></a></div>
<br />
<ul>
<li>En la figura 4 se crean los prototipos de las funciones necesarias para el manejo del bus. </li>
</ul>
<br />
<div align="center">
Figura 4.<a href="https://lh3.googleusercontent.com/-OIR4uxoxVRI/Vvl9LsUSvzI/AAAAAAAAAXQ/DE9KSijLEYg/s1600-h/image%25255B47%25255D.png"><img alt="image" border="0" height="114" src="https://lh3.googleusercontent.com/-jufgQgNdVyk/Vvl9MFBLtoI/AAAAAAAAAXU/ZlpHRvu_X30/image_thumb%25255B31%25255D.png?imgmax=800" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="image" width="272" /></a></div>
<br />
<br />
<br />
<strong><em><u>file i2c.c</u></em></strong> Contiene la implementación de las funciones declaradas en el archivo de cabecera .h.<br />
<br />
<ul>
<li>En <span style="font-family: "courier new";">I2C_Init</span> se configura la velocidad del bus I2C. </li>
</ul>
<div align="center">
</div>
<div align="center">
<br />
Figura 5.<a href="https://lh3.googleusercontent.com/-SgJ__PHAL2s/Vvl9ManZbZI/AAAAAAAAAXY/nvoIz_qwi84/s1600-h/image%25255B76%25255D.png"><img alt="image" border="0" height="86" src="https://lh3.googleusercontent.com/-j-1yVR9t-t8/Vvl9OO10I5I/AAAAAAAAAXc/6_0vf3n6kfM/image_thumb%25255B50%25255D.png?imgmax=800" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="image" width="201" /></a></div>
<br />
<ul>
<li> <div align="justify">
<span style="font-family: "courier new";">I2C_Start</span> envía una condición de start y espera que el envío se haya realizado. Retorna un 1 si el envío fue satisfactorio.</div>
</li>
<li> <div align="justify">
<span style="font-family: "courier new";">I2C_ReStart</span> envía una nueva condición de start y espera que el envío se haya realizado. Retorna un 1 si el envío fue satisfactorio.</div>
</li>
</ul>
<br />
<div align="center">
Figura 6.<a href="https://lh3.googleusercontent.com/-LvQCDntkUYI/Vvl9OuqqeaI/AAAAAAAAAXg/vSi34WOwlSI/s1600-h/image%25255B79%25255D.png"><img alt="image" border="0" height="411" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh7igA89zaAW7tjcZwbYcPtcZayzirXPaq7k4_5Q9k58lSvJ0PNhyphenhyphenb4q6oXOGn436zSQSmfEqlKENQ-K5W9vPLdMKkDFFS_nilIvELv_Qyp4djyz2rupN3syidOukAt9ZoBxael2KmaDOTS/?imgmax=800" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="image" width="368" /></a></div>
<br />
<br />
<ul>
<li> <div align="justify">
<span style="font-family: "courier new";">I2C_Stop</span> envía una condición de stop y espera a que se haya ejecutado.</div>
</li>
</ul>
<div align="center">
</div>
<div align="center">
<br />
Figura 7.<a href="https://lh3.googleusercontent.com/-ZxM_ok0lGDg/Vvl9PhOteGI/AAAAAAAAAXo/eZRm2GuVJcg/s1600-h/image%25255B82%25255D.png"><br /><img alt="image" border="0" height="91" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiWrGrnt9j1DBNThqlg8x622ekhge4OuyYrHeDCssuMRkb6aolLFrtCQ2fAE547UCXf8mmaHx-ZGnS7kflIqWog6wMAOQ2iD91pTPSsRTANFEZNg608Mx32uWU9hfv4olfhrgw-nExBmy8y/?imgmax=800" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="image" width="367" /></a><br />
<br /></div>
<ul>
<li> <div align="justify">
<div style="text-align: justify;">
<span style="font-family: "courier new";">I2C_Write</span> envía el dato hacia el esclavo y retorna un 1 si el envío fue realizado y se ha recibido un ACK. </div>
</div>
</li>
</ul>
<br />
<div align="center">
Figura 8.</div>
<div align="center">
<span style="color: #14da14;"></span><a href="https://lh3.googleusercontent.com/-6QLQJc6dHpE/Vvl9QuTeBcI/AAAAAAAAAXw/_qbXjI1yRog/s1600-h/image%25255B84%25255D.png"><img alt="image" border="0" height="218" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhF_kZA-ZPDzJQwOxumATx8cVp8Gzf06wC_oQrN3so36UpiquvJIaUrXQTooLeEbVYV00AC5wiadPChSKeFskbcVNOKHwoZ0RHedv5cbVOIjAAL-e72zqdmDvNBW-o73iSLf7M-80VDtR7a/?imgmax=800" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="image" width="343" /></a><br />
<br /></div>
<ul>
<li> <div align="justify">
I2C_Read espera que el bus se encuentre habilitado para iniciar una lectura y enviar un ACK o NACK de acuerdo al valor de la variable ACK_NACK.</div>
</li>
</ul>
<div align="center">
<br />
Figura 9.<a href="https://lh3.googleusercontent.com/-sQlDGe_3JIM/Vvl9RsjljnI/AAAAAAAAAX4/AOeksRCKiU0/s1600-h/image%25255B86%25255D.png"><img alt="image" border="0" height="175" src="https://lh3.googleusercontent.com/-4aF1i1niOqU/Vvl9R4f3MbI/AAAAAAAAAX8/JE3uBJK7rE4/image_thumb%25255B60%25255D.png?imgmax=800" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="image" width="642" /></a></div>
<br />
<br />
<br />
<strong><em><span style="font-size: small;"><u>PARTE 2.</u> Files RTC</span></em></strong><br />
<br />
Antes de empezar con los files rtc.h y rtc.c explicaré brevemente lo que son las <strong><em>estructuras y las uniones</em></strong>.<br />
<ul>
<li> <div align="justify">
Una estructura es un agrupamiento de variables bajo un nombre común. Estos agrupamientos pueden contener diferentes tipos de datos. Para definir una estructura se hace uso de la palabra reservada “struct”.</div>
</li>
</ul>
<table border="1" cellpadding="2" cellspacing="0" style="width: 888px;"> <tbody>
<tr> <td valign="top" width="557"><div align="justify">
<span style="font-family: "courier new";">La estructura ejemplo contiene 3 miembros de diferente tipo (uint8_t, int16_t y un array int8_t).</span></div>
<div align="justify">
<span style="font-family: "courier new";">La declaración de variable de tipo estructura es como sigue:</span></div>
<div align="justify">
<span style="font-family: "courier new";"><em>struct ejemplo var1</em>: Aquí “var1” es una variable del tipo estructura ejemplo.</span></div>
</td> <td valign="top" width="329"><span style="font-family: "courier new";">struct ejemplo<br />{<br /> uint8_t c;<br /> int16_t i;<br /> int8_t k[4];<br />};</span></td></tr>
<tr> <td valign="top" width="557"><div align="justify">
<span style="font-family: "courier new";">Para acceder a los miembros de la estructura se hace uso del operador punto (.).</span></div>
</td> <td valign="top" width="329"><span style="font-family: "courier new";">var1.c; var.i; var1.k[0], var1.k[1], var1.k[2] y var1.k[3].</span></td></tr>
<tr> <td valign="top" width="557"><div align="justify">
<span style="font-family: "courier new";">Algo mas sencillo al momento de crear estructuras es la declaración de un alias usando la palabra cable “<b>typedef</b>”. Con esto evitaremos poner “<em>struct ejemplo</em>” cada ve que se quiera declarar una nueva variable.</span></div>
<div align="justify">
<span style="font-family: "courier new";">Será suficiente colocar <em>“ejemplo var2”.</em></span></div>
</td> <td valign="top" width="329"><span style="font-family: "courier new";">typedef struct<br />{<br /> uint8_t c;<br /> int16_t i;<br /> int8_t k[4];<br />}ejemplo;</span></td></tr>
<tr> <td valign="top" width="557"><div align="justify">
<span style="font-family: "courier new";">Las estructuras también pueden ser punteros y apuntadas por punteros tan igual como las tipos nativos (char, int, etc). En estos casos se accede a los miembros mediante el operador fecha (-&amp;gt;).</span></div>
</td> <td valign="top" width="329"><span style="font-family: "courier new";">variable: </span><span style="font-family: "courier new";"><em>ejemplo var1.</em>puntero: ejemplo *pt= &amp;amp;var1;<br />uso: pt-&amp;gt;c; pt-&amp;gt;i; pt-&amp;gt;k[0], pt-&amp;gt;k[1], pt-&amp;gt;k[2] y pt-&amp;gt;k[3]. </span></td></tr>
</tbody></table>
<br />
<br />
<ul>
<li> <div align="justify">
Una union es similar a una estructura, pero estas difieren en que cada elemento en las estructuras tiene un espacio de memoria mientras en las uniones todos los elementos ocupan el mismo espacio de memoria. El tamaño de la unión depende del miembro mas grande.</div>
</li>
</ul>
<table border="1" cellpadding="2" cellspacing="0" style="width: 880px;"> <tbody>
<tr> <td valign="top" width="600"><div align="justify">
<span style="font-family: "courier new";">La union mostrada en la parte derecha ocupa sólo 4 bytes. <br />Después de la asignación los valores quedan distribuidos como en la siguiente figura en donde e<span style="font-family: "courier new";">l byte mas significativo esta último ya que ATmel usa little endian.</span><br /> <a href="https://lh3.googleusercontent.com/-Je5Xae2aK5o/Vvm8ItztJpI/AAAAAAAAAYM/ZnL-MWzRRLQ/s1600-h/image%25255B14%25255D.png"><img alt="image" border="0" height="98" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiypwiDbwCXMblxCREwoOBJbGE5EcrVGpqKIvuLtu2p1Bm5rN8Y24PpY8pBFpLYcvhdXmoohSd2auNnC8nQD5f3Qbiq-K1OTBu0NERIIAkekyKb_XtcQaaE7NxRa2dWYiDeVYHNXNu-l3Di/?imgmax=800" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: inline; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="image" width="306" /></a><br />El usuario verá las variables como en la siguiente figura.</span></div>
<div align="justify">
<span style="font-family: "courier new";"></span><span style="font-family: "courier new";"><br /> <a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg_ITiYjvXE_JSRbKBwVMHJdEcNl8PThnNUcAT4lkwkS0NSiY3_oDI6vNSi86HojutcvHhuYu7Pm2uphSBGzWvIvq_lL5TItE_5BpbeAyT0b39WTSOKqK_G5JgvQCTCk0gTaQ7SGsPKYCqO/s1600-h/image%25255B12%25255D.png"><img alt="image" border="0" height="71" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg7v6RD_3Q6CNHWxsRbwjzzl3XTFK7Qq0Yf013k83NEFVAEjcrcua-yXylbc2FUVRa5Z_4bkp2XgQi5H30h3vZuh8KFJr_0dr3NWf4PX40jKOXLMBB4sZU6cD6FqOZZgWVPAQNPWwi3IWlt/?imgmax=800" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: inline; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="image" width="367" /></a></span></div>
</td> <td valign="top" width="278"><span style="font-family: "courier new";"><br />Creación:</span><br />
<span style="font-family: "courier new";"> typedef union <br /> {<br /> uint8_t u8;<br /> uint16_t u16;<br /> uint32_t u32;<br /> }ejemplo;</span><br />
<span style="font-family: "courier new";"><br />Declaración:</span><br />
<span style="font-family: "courier new";"> ejemplo var1;</span><br />
<span style="font-family: "courier new";"><br />Asignación:</span><br />
<span style="font-family: "courier new";"> var1.u32 = 0x01234567</span> </td></tr>
</tbody></table>
<ul> <div align="justify">
</div>
<div align="justify">
</div>
</ul>
<br />
Ahora si pasaremos a los archivos rtc.<br />
<br />
<strong><em><u>file rtc.h</u></em></strong><br />
<ul>
<li>En la figura 10 se crean las estructuras para hora y fecha. También hay una tercera estructura (<span style="font-family: "courier new";">RTC_t</span>) que esta conformada por las estructuras <span style="font-family: "courier new";">Hora_t</span> y <span style="font-family: "courier new";">Fecha_t</span>. </li>
</ul>
<div align="center">
<br />
Figura 10.<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiVuFwF87kG-EQdNtDytFofEaU7-azuFUF-jUS7EeIOuug9fOOQh5EETdF98cQpiLVOtdv-AGIk3wACWQw_LXJe7xIda65ORaUz2nwLdFfz0zuNweme1Sy5T6sMazU2sWZeZE9YZo9oS0SA/s1600-h/image%25255B28%25255D.png"><img alt="image" border="0" height="363" src="https://lh3.googleusercontent.com/-5mfKi8VQMMM/VvnfPqCzLOI/AAAAAAAAAYs/bkb_vwoYFRo/image_thumb%25255B20%25255D.png?imgmax=800" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="image" width="275" /></a></div>
<br />
<ul>
<li> <div align="justify">
En la figura 11 se definen las direcciones de los registros internos de DS3231. También una mascara para filtrar los datos leídos desde el DS3231. Finalmente, y ya que la dirección del DS3231 es <span style="font-family: "courier new";">0b1101000,</span> se define <span style="font-family: "courier new";">DS3231_READ</span> y <span style="font-family: "courier new";">DS3231_WRITE</span> para las lecturas y escrituras desde y hacia el RTC.</div>
</li>
</ul>
<div align="center">
<br />
Figura 11.<a href="https://lh3.googleusercontent.com/-asuGc3ITUOE/VvnfQHtFwJI/AAAAAAAAAYw/R9jL-J9Ty7s/s1600-h/image%25255B33%25255D.png"><img alt="image" border="0" height="311" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgbfEAO2xSoNrMIoN1l6LfeyFdHXOiTPyJO5CmT3dPicFeiiscipcy_3y4FYl2AIgQZxQs1GsCLpfgDmeG-nd_0Fb0N5e2jnYFWuu427GY4hg8AzMv5opZ5qjGDTr6i6liIlJRB75mn7osJ/?imgmax=800" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="image" width="348" /></a></div>
<br />
<ul>
<li> <div align="justify">
En la figura 12 se declaran los prototipos de las funciones para leer/escribir el RTC. Las 6 últimas funciones tienen un puntero a estructura(Hora_t, Fecha_t y RTC_t) .</div>
</li>
</ul>
<div align="center">
<br />
Figura 12.<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEikLiDKxXPM54iKXMExMaFyKGCx3AljU_HcVMcn3F3eygeeh30lN6AxCr8I7Zwvby5EY0SybbKHW9LG8veGCXA7Asz1th4Qt0L7xKimOm-qh_xLjz-CA8sWIQFbSqpwtDPaNlkJRx4UWGI9/s1600-h/image%25255B38%25255D.png"><img alt="image" border="0" height="203" src="https://lh3.googleusercontent.com/-AJFr8lwdxdY/VvnfSOP56RI/AAAAAAAAAY8/ek8zdzx9f0A/image_thumb%25255B26%25255D.png?imgmax=800" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="image" width="343" /></a></div>
<br />
<strong><em><u><br /></u></em></strong>
<strong><em><u>file rtc.c</u></em></strong><br />
<div align="justify">
</div>
<ul>
<li> <div align="justify">
<span style="font-family: "courier new";">RTC_Init</span> sólo inicializa el bus I2C.</div>
</li>
</ul>
<div align="center">
<br />
Figura 13.<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhUQnua2WX5Zgy88UAvCOaVOaocUgIdmEgjSFjUkepzFcnTIpwv4kcvdGR2pZgihNVz3mBuThij0dRVX2aRTj4XfcKMxZB5XnEWPLBqgSd9y9IF2GW0fGw5ProGG34MDAYpBFnz9xRaTkab/s1600-h/image%25255B72%25255D.png"><img alt="image" border="0" height="68" src="https://lh3.googleusercontent.com/-KRELv7SgQSQ/VvnfTTfC-0I/AAAAAAAAAZE/4U-0kWCDco8/image_thumb%25255B46%25255D.png?imgmax=800" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="image" width="143" /></a><br />
<br /></div>
<div align="center">
</div>
<ul>
<li> <div align="justify">
En la figura 14 se muestran las funciones de lectura/escritura para cualquier registro del DS3231.</div>
</li>
</ul>
<div align="center">
<br />
Figura 14.<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjap8_O7h-PrENrHF1Du3PvCYsQNtSvw7tbpIJ3nZbONP0ywtb55TNh9H2g9-ZAxYXbOB6voysjbz8EkEYimpSXVgjYHUynheoJxla-3zVGmm3AsjYORgQ0E4h4u0FgvmVdD9ZxJnkuSpOx/s1600-h/image%25255B74%25255D.png"><img alt="image" border="0" height="360" src="https://lh3.googleusercontent.com/-j_8cTpa-OLE/VvnfUjoAWwI/AAAAAAAAAZM/fIQRml4oeuI/image_thumb%25255B48%25255D.png?imgmax=800" style="background-image: none; border-width: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="image" width="412" /></a><br />
<br /></div>
<div align="center">
</div>
<ul>
<li> <div align="justify">
<span style="font-family: "courier new";">RTC_SetHora</span> escribe una nueva hora en el DS3231. La nueva hora proviene de una estructura del tipo <span style="font-family: "courier new";">Hora_t</span>. Del mismo modo <span style="font-family: "courier new";">RTC_SetFecha</span> escribe una nueva fecha en el DS3231.</div>
</li>
</ul>
<div align="center">
<br />
Figura 15.<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhKkfTYzpIwJHb25S97KJF0iCGTTma0o-Eg2sd1Qoh0OM1Av4s4t__GjwRg8MyWAzUIcchpP63A46lr8JurjvHbslxCeMDDLSYS3rdm6yu9BVZu9To9338AHne92iTtRgqWNoRyP_v4R_3S/s1600-h/image%25255B78%25255D.png"><img alt="image" border="0" height="352" src="https://lh3.googleusercontent.com/-5VG8uQUu2FE/VvnfV_1gtNI/AAAAAAAAAZU/fLRhj4yne2o/image_thumb%25255B52%25255D.png?imgmax=800" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="image" width="296" /></a><br />
<br /></div>
<div align="center">
</div>
<ul>
<li> <div align="justify">
<span style="font-family: "courier new";">RTC_GetHora</span> leer la hora del DS3231 y lo guarda en una estructura del tipo <span style="font-family: "courier new";">Hora_t</span> que es apuntada por el puntero hora. <span style="font-family: "courier new";">RTC_GetFecha</span> hace una tarea similar con la fecha.</div>
</li>
</ul>
<div align="center">
<br />
Figura 16.<a href="https://lh3.googleusercontent.com/-eLjzN15kzro/VvnfWQH3VXI/AAAAAAAAAZY/a2aub2xQXmw/s1600-h/image%25255B86%25255D.png"><img alt="image" border="0" height="425" src="https://lh3.googleusercontent.com/-AhszYwd4gns/VvnfXJmGXRI/AAAAAAAAAZc/FpLlgq9bejk/image_thumb%25255B60%25255D.png?imgmax=800" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="image" width="407" /></a><br />
<br /></div>
<div align="center">
</div>
<ul>
<li> <div align="justify">
<span style="font-family: "courier new";">RTC_GetTime</span> hace uso de las funciones ya mencionadas para leer la hora y la fecha y guardarla en la estructura apuntada por el puntero <span style="font-family: "courier new";">rtc</span> de tipo <span style="font-family: "courier new";">RTC_t. RTC_SetTime </span><span style="font-family: "arial";">se encarga de escribir la hora y fecha de manera similar.</span></div>
</li>
</ul>
<div align="center">
<br />
Figura 17.<a href="https://lh3.googleusercontent.com/-g2jUExENtlc/VvnfX1bGhXI/AAAAAAAAAZg/WRQk60M2MBs/s1600-h/image%25255B84%25255D.png"><img alt="image" border="0" height="189" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiROG6Z1NKWR7IPIEG39PHgqzGsO-nnv5rpJXtY9tIXSvm-AmwcshlnNkCq25X8uD0o_wy1J_cPwD-fuThzSciqdObm7X-bVIe1hTq7iK0CfCba9UEnTQ3BYnPGZ7XWSG_OmNZhS3HI_hEh/?imgmax=800" style="border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="image" width="261" /></a></div>
<br />
<strong><em><span style="font-size: small;"><u><br /></u></span></em></strong>
<strong><em><span style="font-size: small;"><u><br /></u></span></em></strong>
<strong><em><span style="font-size: small;"><u>PARTE 3.</u> main</span></em></strong><br />
<strong><em><span style="font-size: small;"></span></em></strong><br />
En el main se configura el uart para enviar/recibir la hora y la fecha hacia/desde un programa hecho en Visual C#.<br />
También se configura una interrupción cada 1 segundo para leer el DS3231. <br />
<div align="center">
<br /></div>
<div align="center">
Figura 18.<a href="https://lh3.googleusercontent.com/-xX8NjGHcxco/VvoyZk81qqI/AAAAAAAAAZ0/vuo_ZR2GN0k/s1600-h/image%25255B32%25255D.png"><img alt="image" border="0" height="198" src="https://lh3.googleusercontent.com/-YiAX5hAekI0/Vvoyao_5aBI/AAAAAAAAAZ4/_FTY7NUEML8/image_thumb%25255B19%25255D.png?imgmax=800" style="background-image: none; border-bottom: 0px; border-left: 0px; border-right: 0px; border-top: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="image" width="377" /></a></div>
<br />
<br />
Aquí presento el programa.<br />
<div align="center">
<br /></div>
<ul>
<li> <div align="justify">
En la figura 19 se muestran los includes que necesita el main.</div>
</li>
</ul>
<div align="center">
<br />
Figura 19.<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh2qAlML5OvXT4j0N2Kx9Zdh5cnpIE80bDPOKKBOLvZbEba7BO7RNzkvtSDSUItToODhgsVq4zvuQHwVeKQOpbasz1wZ5dos9jH8tfZuQ76zg3pJ-2sVr6B1LOQysDuZpt0QAPWh-Ad2Lyz/s1600-h/image%25255B17%25255D.png"><img alt="image" border="0" height="87" src="https://lh3.googleusercontent.com/-p2mKF34p-BQ/VvoybrGmqeI/AAAAAAAAAaA/LH1QyRt7V3Q/image_thumb%25255B8%25255D.png?imgmax=800" style="border-bottom: 0px; border-left: 0px; border-right: 0px; border-top: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="image" width="267" /></a></div>
<br />
<ul>
<li> <div align="justify">
En la figura 20 se muestra la definición de la union <span style="font-family: "courier new";">TRAMA_t</span> que une una estructura y un array de 10 elementos. Este nuevo tipo de dato (<span style="font-family: "courier new";">TRAMA_t</span>) servirá para el envío y recepción de información hacia y desde el programa en la PC. En la linea 28 se crea la variable <span style="font-family: "courier new";">“tx_trama”</span>.</div>
</li>
<li> <div align="justify">
En la linea 27 se declaran dos variables(<span style="font-family: "courier new";">rtc y rx_rtc</span>) del tipo <span style="font-family: "courier new";">RTC_t</span>. En la variable rtc se almacena la hora y fecha leidas del DS3231 cada 1 segundo. <span style="font-family: "courier new";">rx_rtc</span> sirve para almacenar la hora y fecha recibidas desde el programa en la PC antes de ser enviadas al DS3231.</div>
</li>
<li> <div align="justify">
Las variables <span style="font-family: "courier new";">update_rtc</span> y <span style="font-family: "courier new";">send_rtc</span> son actualizadas en la interrupción del uart y sirven para actualizar el DS3231 o enviar la hora y fecha hacia la PC.</div>
</li>
<div align="justify">
</div>
</ul>
<div align="center">
<br />
Figura 20.<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjrd_rKWo6qncw-Y1zF36Q0BQrnVAalTIL1uD7Jwo0DgJL10fNDJZPvns5sF7ZSb61pdyRhwNJh3crXh1pN_COZ8SgQ13Hjq8QB4lxi0YERWDCdaaTJfyHYTMm0zhVVY6ZAjcwNQ-6IqNVB/s1600-h/image%25255B41%25255D.png"><img alt="image" border="0" height="325" src="https://lh3.googleusercontent.com/-irCIvmBlpp8/VvoydEkrvWI/AAAAAAAAAaI/FgqxP7LopeQ/image_thumb%25255B28%25255D.png?imgmax=800" style="background-image: none; border-bottom: 0px; border-left: 0px; border-right: 0px; border-top: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="image" width="295" /></a></div>
<br />
<ul>
<li>En las lineas 37-40 (Figura 21) se configura el uart.</li>
<li>En las lineas 42-44 se configura la interrupción del timer1 cada 1 segundo.</li>
<li>En las lineas 48 y 49 se inicializan las variables <span style="font-family: "courier new";">update_rtc y send_rtc</span>.</li>
<li>También se inicializa la variable tx_trama y se activa el bit de interrupción global.</li>
</ul>
<br />
<div align="center">
Figura 21.<a href="https://lh3.googleusercontent.com/-yt79uLb2phw/Vvoyd5D7soI/AAAAAAAAAaM/18r5ewMpbc4/s1600-h/image%25255B27%25255D.png"><img alt="image" border="0" height="341" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgOm7AhOGXkKcC-bYQZ4VlEuEJZLvheedkLbZQD_wo6UUv8LlZjOHlJOf7nEfwbQHG-oeQikEME12H2QUPUlqdeVozNjZEd3XyZzKC7rPQP4mYkXeCnwKCxIXXpkzXIJQWqpDksBQ8W2Fr7/?imgmax=800" style="background-image: none; border-bottom: 0px; border-left: 0px; border-right: 0px; border-top: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="image" width="383" /></a></div>
<br />
<ul>
<li> <div align="justify">
Sí el programa de la PC envía una nueva actualización para el RTC esta será guardada en rx_rtc (en la interrupción por recepción) y el RTC será actualizado en el while. También se enviará la hora y fecha actual hacia el PC si es requerido.</div>
</li>
</ul>
<br />
<div align="center">
Figura 22.<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjbysASSEI5abTwNZBEIjHESxCEPsBikDPmE1R7BzL9iwTL5bj51kS4ugHzE8TA_tyiJfo_3KN1XaF5_5oVDe0Or2oAH9fFDDN6h6fdOf8zQ2x73gLBetxxuicTIHwrNrrM7mySqJe1ujv1/s1600-h/image%25255B46%25255D.png"><img alt="image" border="0" height="306" src="https://lh3.googleusercontent.com/-DLPs2r-radA/VvoyhElkYbI/AAAAAAAAAaY/HHgTnfRWj1A/image_thumb%25255B31%25255D.png?imgmax=800" style="background-image: none; border-bottom: 0px; border-left: 0px; border-right: 0px; border-top: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="image" width="469" /></a></div>
<br />
<ul>
<li> <div align="justify">
En la figura 23 se muestra la interrupción por recepción del uart. Aquí se reciben todos los datos, se hace un chequeo de integridad de los datos y de acuerdo al comando de lectura (<span style="font-family: "courier new";">‘R’</span>) o escritura (<span style="font-family: "courier new";">‘W’</span>) se actualizará las variables ‘<span style="font-family: "courier new";">update_rtc’</span> y ‘<span style="font-family: "courier new";">send rtc’</span>.</div>
</li>
</ul>
<div align="center">
<br />
Figura 23.<a href="https://lh3.googleusercontent.com/-5yQqS5E3RoM/VvrOOK-mByI/AAAAAAAAAas/e_PpKa5D-7A/s1600-h/image%25255B61%25255D.png"><img alt="image" border="0" height="512" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjAIxyZYHJV3Ka4UEy1-yZ0-Zp7RQ7dGYZrAsFEiM1QzEx1FZzYuBvp9SvipE8gmSPaFVbWuIO1JOQRdu2yPo5TO5nnrrKbAxdSjEYyepO0HyRLyJTCVKYwZvRA_sWWeN5q3KwztNXV-qKT/?imgmax=800" style="background-image: none; border-bottom: 0px; border-left: 0px; border-right: 0px; border-top: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="image" width="578" /></a></div>
<br />
<ul>
<li> <div align="justify">
Finalmente, en la interrupción del timer1 se lee la hora y fecha del rtc. También se muestran las funciones del lectura y escritura en el uart.</div>
</li>
</ul>
<br />
<div align="center">
Figura 24.<a href="https://lh3.googleusercontent.com/-gtm-GaZRA1M/VvrOPGKorGI/AAAAAAAAAa0/tnjJtHiAer8/s1600-h/image%25255B64%25255D.png"><img alt="image" border="0" height="272" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjDvHBD-qQzxC2wfzLJTmH_CuBPdqbuqDcBLFYAUaAhBMLvjRvr-hca8hrPfynlIG28iMGAlx7FycBUzSO6nhuqZxTCI6bC8S_6rsNsKNM36J44bl2vhOMKc-PSihIcEltSEPVoG73t1rEN/?imgmax=800" style="background-image: none; border-bottom: 0px; border-left: 0px; border-right: 0px; border-top: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="image" width="300" /></a></div>
<br />
<br />
Enlaces de programas:<br />
<br />
<a href="http://adf.ly/12709021/rtc-ds3231"><span style="color: lime; font-size: small;"><strong>Programa RTC DS3231</strong></span></a><br />
<span style="color: lime; font-size: medium;"><strong><a href="http://adf.ly/12709021/horafechaexe"><span style="color: lime;">HORA+FECHA.exe</span></a></strong></span><br />
<span style="color: lime; font-size: medium;"><br /></span>
<span style="color: lime; font-size: medium;"><br /></span>
<br />
<div class="separator" style="clear: both; text-align: center;">
<iframe allowfullscreen="" class="YOUTUBE-iframe-video" data-thumbnail-src="https://i.ytimg.com/vi/Pp0Vsmc-xys/0.jpg" frameborder="0" height="266" src="https://www.youtube.com/embed/Pp0Vsmc-xys?feature=player_embedded" width="320"></iframe></div>
<br />
<br />Anonymoushttp://www.blogger.com/profile/14023938257857442019noreply@blogger.com7tag:blogger.com,1999:blog-7123434971804829465.post-89574744175894614632016-03-12T21:54:00.000-08:002016-03-22T22:17:16.394-07:00Primer proyecto con Atmel Studio 7<div>
<br /></div>
<div align="justify">
</div>
<div align="justify">
Para iniciar la programación de uC AVR necesitamos instalar la Plataforma Integrada de Desarrollo (IDP) de ATmel, me refiero al Atmel Studio 7.</div>
<div align="justify">
Aquí el enlace para la descarga : <a href="https://secure.atmel.com/secure/DownloadThankYou.aspx?target=%2fsecure%2fDownloadHelper.ashx%3ftarget%3dtcm%3a26-80771%26redirect%3dy%26formtype%3dSoftware+Download%26formUri%3dtcm%3a26-41757"><span style="color: lime;">Atmel Studio 7.0.790</span></a></div>
<div align="justify">
</div>
<div align="justify">
Instalado el software, pasaremos a crear nuestro primer proyecto. </div>
<div align="justify">
Una vez abierto el software, en la parte izquierda veremos la figura 1 donde debemos dar click en “New Project”.<br />
<br />
<br /></div>
<div align="justify">
</div>
<div align="center">
<em>Figura 1.</em><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjt1TfGP9k8JcymDhVUGcYQW9lP1KfqAVcJyaZUapWFmdreSX6ab2_6-BZ8pJKfnRicE163do2mM_Sy0K96vMjfgoaUhFWHueS9ePsM1-CkMjVyk2yujOlNSwrLxFRunJAN_3VTs3pRPBsp/s1600-h/image97.png"><img alt="image" border="0" height="102" src="https://lh3.googleusercontent.com/-Au3XXAiIWs0/VuT_SX5XQuI/AAAAAAAAATw/wMh2ozER4EQ/image_thumb71.png?imgmax=800" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="image" width="179" /></a></div>
<div align="center">
</div>
<div align="justify">
<br />
<br /></div>
<div align="justify">
Luego debemos seleccionar el tipo de proyecto y el lenguaje (C, C++, ASM). En este ejemplo usaremos el lenguaje C como lo vemos en la figura 2.</div>
<div align="justify">
<br />
<br /></div>
<div align="center">
<em>Figura 2.</em><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjOBBN1fjnXlT__T8ERgnGgnlGA0wtzt0YUwzxReNNd8wdhGUMKZI2epWEUjVz_wCNW7_uFkwa6ADT3KKjaEApRm_4aUh7VxsRzoLT6JPME_4MeW3q2993G3Fk_j2VCuwHNhhKpi6aNN3BN/s1600-h/image93.png"><img alt="image" border="0" height="84" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEimJlWdAis5LZcx5qwZXPLt6_vAl11GfqNHoy_4jeKv21nenweNTEdTI6n9b1H07_ayUqnLzk6oLr97OOQq6BKPvcbW7-aWXHvcb0_y0DKmwkB_2nQL1VMZmeOgP9ryQ4qch6qA_e7HHf3x/?imgmax=800" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="image" width="655" /></a></div>
<div align="center">
</div>
<div align="justify">
<br />
<br />
<br /></div>
<div align="justify">
Una vez seleccionado el lenguaje, debemos darle un nombre al proyecto, en nuestro caso lo llamaremos “First_project” (Figura 3). El software creará una carpeta con el nombre del proyecto en la ruta “C:\Users\user\Documents\Atmel Studio”.<br />
<br /></div>
<div align="center">
</div>
<div align="center">
<em>Figura 3.</em><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgrV_c3r08SSH_jYwoZ84aSBDj3M097J-TBRD7N6YPwH5qF0XZAfIE584zHJPRK7DSiIZ3kWdsBriSln3o2B4tQXdM8j2GB__o91rMTAgAgCrSbazM0KmeAVp8_0PEwqiWetmZLIQnU6dxN/s1600-h/image61.png"><img alt="image" border="0" height="27" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhlX-u-oyBO5sjW0ysYwS5n_nVEv4X1ONQtBCT5AhvEw2IhndAs4TyGXPFuIPEtjlxIcuyeDw8lIHSPc0pB3UoxYO0J6A_Uvn9FVjv3ghMieWlV5_8Qpl3cFtY45EXgWKidXIlcRWzUXi7z/?imgmax=800" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="image" width="262" /></a></div>
<div align="justify">
<br />
<br /></div>
<div align="justify">
Ahora debemos seleccionar el dispositivo que deseamos usar, en este caso seleccionamos el ATmega32.<br />
<br /></div>
<div align="center">
</div>
<div align="center">
<em>Figura 4.</em><a href="https://lh3.googleusercontent.com/-PFcT7d2fWDY/VuT_U8FF_RI/AAAAAAAAAUE/iJSQS5jd3j0/s1600-h/image89.png"><img alt="image" border="0" height="167" src="https://lh3.googleusercontent.com/-b1oDUjgmjfM/VuT_VT7jwxI/AAAAAAAAAUI/aWs8aGQO2d8/image_thumb63.png?imgmax=800" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="image" width="442" /></a></div>
<div align="center">
</div>
<div align="justify">
<br />
<br /></div>
<div align="justify">
<br />
A la derecha de la misma ventana veremos (figura 4) veremos una lista de las herramientas de depuración y programación que se pueden usar en el microcontrolador seleccionado. También un enlace a la hoja de datos del dispositivo (Figura 5). <br />
<br /></div>
<div align="center">
</div>
<div align="center">
<em>Figura 5.</em><a href="https://lh3.googleusercontent.com/-tRyUq9D_nMI/VuT_WWN99tI/AAAAAAAAAUM/6hQYXVLnmP4/s1600-h/image86.png"><img alt="image" border="0" height="439" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi8EyO63H3PWG8VsPnfR7JUrKvtijlWPBrwSJyLKO5RBsyiyK5KMSs_rqmmkiYZPsGCv-Bq5wGRf9B4LdX_HeWWauUqzMODhPsE_g1i992zfFEa_QNCsxF_F4Mw8E5IvpS5BxcuYb4ADarZ/?imgmax=800" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="image" width="148" /></a></div>
<div align="center">
</div>
<div align="justify">
</div>
<div align="justify">
<br />
<br />
Luego de dar click en en botón aceptar veremos el archivo main.c tal como en la figura 6. Aquí es donde debemos escribir nuestro programa. <br />
<br /></div>
<div align="center">
</div>
<div align="center">
<em>Figura 6.</em><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEik8uaOehoTxVWck-O13cZkBBRGP-HgXJ_BU93VP5C2eFQt94K-x-6M_497rtVYtoLxNuZrdV6LTXW8MXkzrZ4nj2ato-28DFV831ogpmY7YdUzVniXtEm3Wz6Ir_YqWZ6vuLcWgZYFFq2q/s1600-h/image83.png"><img alt="image" border="0" height="285" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhgBjtZzwx7ZmajlI0PhGoxxK8Wi5w7dsCCtCubabnRGU75NvPJz0xxwHeR8BnWU7YpQM13c6sUtbM3ujNlmQVBUS5dufSSpAtTDONaBO__PyXDIlCA9ntV8qrw_y7sdS68QFwBGazG7Igm/?imgmax=800" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="image" width="404" /></a></div>
<div align="center">
</div>
<div align="justify">
<br />
<br />
<br /></div>
<div align="justify">
En la figura 7 se muestra la aplicación desarrollada. En esta programa se tendrán dos entradas para dos pulsadores en el puerto B, y dos salidas para dos leds en el puerto D.<br />
<br /></div>
<ul>
<li> <div style="text-align: justify;">
En 11 se declaran dos variables de tipo unsigned char (uint8_t) para guardar en estado actual y el estado pasado de un pin de entrada.</div>
</li>
<li> <div style="text-align: justify;">
En 15 se ponen los el puerto B como entradas.</div>
</li>
<li> <div style="text-align: justify;">
En 16 activamos las resistencias pull up de los pines PB0 y PB1.</div>
</li>
<li> <div style="text-align: justify;">
En 17 se ponen los pines PD7 y PD3 como salidas para los led.</div>
</li>
<li> <div style="text-align: justify;">
En 20 preguntamos sí el pin PB0 fue presionado</div>
</li>
<li> <div style="text-align: justify;">
En 21 se pondrá a 1 el pin PD7 sí PB0 es 0. El código de la linea 22 es igual al de la linea 21.</div>
</li>
<li> <div style="text-align: justify;">
En 24 se pondr’a a 0 el pin PD7 si PB0 es 1. El código de la linea 25 es igual al de la linea 24.</div>
</li>
<li> <div style="text-align: justify;">
En 27 se guarda el valor anterior del pin PB1.</div>
</li>
<li> <div style="text-align: justify;">
En 28 se guarda el valor actual del pin PB1.</div>
</li>
<li> <div style="text-align: justify;">
En 29 se pregunta sí ocurrió un flanco de subida.</div>
</li>
<li> <div style="text-align: justify;">
En 31 se conmuta, usando un <span style="font-family: "courier new";">xor (^),</span> el pin PD3. El código de la linea 32 es igual al de la linea 31.</div>
</li>
</ul>
<br />
<div align="center">
<em>Figura 7.</em><a href="https://lh3.googleusercontent.com/-xFbREzy-t8Y/VuT_ZFSxAuI/AAAAAAAAAUc/XAn7zeSDyQg/s1600-h/image74.png"><img alt="image" border="0" height="473" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgWR4vjHJmO1RULt0YVkHLVgyzZEMXHTgnYthk3y3GYMDb3VTrRDsPReULsM8DWbPOH0wn-uW2bdmOYNCD_pOWNzfSXmRgiG7wXMCR5-qb2yDXgt3Tjuw9ngDGzDa5DsWj7s-kV7EgITAv0/?imgmax=800" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="image" width="660" /></a></div>
<div align="center">
</div>
<div align="justify">
</div>
<div align="justify">
<br />
<br />
En C podemos usar el operador <span style="font-family: "courier new";">:?</span>, y gracias a esto podemos reducir las lineas 20 a 25 por el código de la figura 8. </div>
<div align="justify">
<br />
<br />
<br /></div>
<div align="center">
<em>Figura 8.</em><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEinoVpwp2uFdS4FWO7jdvjvF1ijcHpCj57hANKv_7uwT8pfRnVI0SsJcIIrqZBVF0Mj8jaYHlZC8PkAQ87qYh5Y-b3_gZTOrECx2oMFPs8Ca1f6FMYJ0fvT-HyueP0WqCFZSKUaYVdlqT5m/s1600-h/image58.png"><img alt="image" border="0" height="17" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgQLFqmYbrn25bpPSK6rzK2cVCqQNn5R2pH7cNx5hYj4M5sgOUvQwq4kUQjWQVXz8p4SSjafHTThnqRxT4_cywVULsntWz_MIPE5u1yIrnRDWwXheNb53yNNPZZTqHEjW2CGRr5V64HeDkg/?imgmax=800" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="image" width="568" /></a></div>
<div align="center">
<br />
<br />
<br /></div>
<div align="justify">
En la figura 9 se muestra la equivalencia entre un <span style="font-family: "courier new";">if-else</span> y el operador <span style="font-family: "courier new";">:?.</span></div>
<div align="center">
</div>
<div align="center">
<em><br /></em>
<em>Figura 9.<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhnOIMshMYw_y2ZNyklAhUofMg_lo7d3biOBvUB3hp9WpVMy1Ahov4aoiVNDvTJxt-m8kWdnV9iZr6bIc4783HL2O4dZRvzh9u1SfumaiZZiV7Ga2VFuEHiCpgZt3FxAGUXZPslombejZkN/s1600-h/image%25255B5%25255D.png"><img alt="image" border="0" height="101" src="https://lh3.googleusercontent.com/-TbBDiZv1cI4/VuYbDGSipUI/AAAAAAAAAVs/ejNr3nLIDxs/image_thumb%25255B2%25255D.png?imgmax=800" style="background-image: none; border-bottom: 0px; border-left: 0px; border-right: 0px; border-top: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="image" width="551" /></a></em></div>
<div align="center">
</div>
<div align="left">
<br />
<br />
<br /></div>
<div align="left">
Luego debemos compilar el programa usando el botón de la figura 10.<br />
<br /></div>
<div align="center">
<em>Figura 10.</em><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiP7Ug5JSTSTMFWlpPGSjNJaF_OYDBZwmVPKtXDLvvuyXHgUSmlYfBaumw40mWbW1I3QurFtynxzszii84b6dlsfyMJa55IfLNVphZd7UmKJ6tIjOQHvewo7OYf7LbJTtmXsSs0b1cKzoTu/s1600-h/image109.png"><img alt="image" border="0" height="32" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEguPeirNIBadGOp_FR6biRAzluM6ndj5xjjKtzcwHQJnpsAidzqFdc4RpRZumMaNeqjNywGBJLJzWA3S0rM_Q1RPt8Y60eTHs1tVhv3AM622tNcnoBhk1NHJCH97ZJ8R5R-6pLPpHLjD9gE/?imgmax=800" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="image" width="60" /></a></div>
<div align="center">
</div>
<div align="justify">
</div>
<div align="justify">
<br />
<br />
Finalmente, tendremos como salida el archivo .hex (Figura 11) para poder programar nuestro microcontrolador.<br />
<br /></div>
<div align="justify">
</div>
<div align="center">
<em>Figura 11.</em><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjpbRByrlmA3a2dSTytTP4QxFXmH8QnL0Ea3xbwPFH4gdQ_bL5dWQsmLGcZcRApa9JZE_HUNX5gZsR8akpCazZbMJUGrRBIZ_Q9xxX7EY6EwzHsYx7TpSnjEioHv8UM7l_4EaZJa71H1a5-/s1600-h/image70.png"><img alt="image" border="0" height="247" src="https://lh3.googleusercontent.com/-HPGh-XuwKqM/VuT_eX9bewI/AAAAAAAAAVA/EAUiafW7LYQ/image_thumb44.png?imgmax=800" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="image" width="226" /></a></div>
<br />
<br />
<br />
<a href="http://adf.ly/12709021/first-project"><span style="color: lime; font-size: large;">Link Proyecto</span></a><br />
<br />
<hr />
<div align="left">
<br />
<br /></div>
<div align="left">
Si queremos ver la numeración de lineas en nuestro ventana de edición tenemos que ir a Tools>Options (Figura 12).</div>
<div align="left">
</div>
<div align="center">
<em>Figura 12.</em><a href="https://lh3.googleusercontent.com/-fF0c1VvlNSw/VuT_e-ab7YI/AAAAAAAAAVE/7xjHvotQEjc/s1600-h/image101.png"><img alt="image" border="0" height="323" src="https://lh3.googleusercontent.com/-JrnePty4RQM/VuT_fZTq3QI/AAAAAAAAAVI/vMMe764HGdY/image_thumb72.png?imgmax=800" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="image" width="309" /></a></div>
<br />
<br />
Luego en “All Languages” seleccionamos “Line numbers” (Figura 13).<br />
<br />
<div align="center">
<em>Figura 13.</em><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj9TRaTavYHVHx6gY9LgiVAKjziahXkHoBNnvkL6Im7ZWTbP8AoOq7vcE1j6pN0Z4QYq2siqw5oc7ESNSNRLP9FpCM_s-GuYinUhiKrgN7I9j30GQvr1zOsq242ff93SZhPOW_IByXTMmc8/s1600-h/image105.png"><img alt="image" border="0" height="375" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgjXyVUOyKvlj05-6I1eARPskDF3vklsKTvuCdBkjOVNmMpS1_NrxCqcMlDRRynOe_IBLhVT6edfdTnQG_TDXBGn8daRPc-k8OczBYIY6fswzBIzTstkbFok6RAJDQYVIo5F4g7VxHes4yG/?imgmax=800" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="image" width="649" /></a><br />
<br />
<div style="text-align: justify;">
</div>
<div style="text-align: justify;">
Espero este post sea útil.</div>
<div style="text-align: justify;">
Hasta la próxima.</div>
<div style="text-align: justify;">
</div>
</div>
Anonymoushttp://www.blogger.com/profile/14023938257857442019noreply@blogger.com5tag:blogger.com,1999:blog-7123434971804829465.post-59364797440690287812016-03-11T18:52:00.000-08:002016-03-16T16:52:52.790-07:00Bootloader USBasp<br />
<div align="justify">
Ya muchos conocemos el programador USBasp (gracias a Thomas Fischl) y lo bien que funciona este. El USBasp debe ser uno de los programadores mas conocidos para descargar código a un ATmega, esto gracias a que usa un muy económico ATmega8, que aun no teniendo puerto USB, es capaz de trabajar con una gran cantidad de dispositivos. … y lo mejor de todo: “Es gratis”. </div>
Personalmente lo vengo usando desde el año 2010. Ahora tengo un AVRISPmk2(al parecer ya descontinuado) y un JTAGICE3 (que ya fue remplazado por el Atmel-ICE) y aún en algunas ocasiones uso mi USBasp. <br />
<br />
Bueno, es este post mostraré cómo usar el “USBasp“ como bootloader. <br />
<br />
<div style="text-align: justify;">
Un programador USBasp consta básicamente de un ATmega8 que ha sido programado, en la sección de aplicación de su flash, con un código que permite comunicación USB (low speed 1.5Mbps) con el programador y programar otros uCs. Los anteriormente descrito se muestra en la figura 1, donde la sección de booteo del uC (ATmega8) no es usada. </div>
<br />
<div align="center">
<em>Figura 1.</em><a href="https://lh3.googleusercontent.com/-xXQ4z8oJT_I/VuJF0peNwaI/AAAAAAAAAQY/Eyz2z2aHjkU/s1600-h/image%25255B67%25255D.png"><em><img alt="image" border="0" height="454" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEih1upzYZKSynR6xK2GWzZKxyEHZAtBPsPOs4vc0KhAsz-nRVmiUNmzDrFsOQ_d5gX26hxlPnoZZABM2XlfwaHgDJPgizfEQeCNMZYdPEvUZD6eROnebCHEDWf2jlznpsvhjuNczZIiA8ue/?imgmax=800" style="display: block; float: none; margin-left: auto; margin-right: auto;" title="image" width="701" /></em></a> </div>
<br />
<br />
Pero cuando hablamos de usar el “USBasp” cómo bootloader tendremos un esquema similar a la figura 2. Aquí, el código, “USBasp” , que realizará la comunicación con el programa en la PC (ej. AVRDUDE) es localizado en la sección de booteo de la flash, y es este código el que nos permite poner nuestra aplicación en la sección de aplicación de la flash (usando instrucciones SPM y LPM). <br />
Es decir que no necesitaremos un programador USBasp ya que este lo tendremos integrado en el mismo uC. Lo mejor de todo es que lo podemos poner un diferentes uCs y con diferentes osciladores. Personalmente ya lo he probado con ATmega8 (a 12 y 16MHz), ATmega32(a 12 y 16MHz) y ATmega324P (a 12,16 y 20 MHz). <br />
<br />
<div align="center">
<em>Figura 2.</em><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgC1nziNiG3ShifRy1gRYCRSrRSigJ7Aorzh0AvRae6efSjUXxcxy7qIjWnUBDgifpqPgCSNj2WUPHLEs_lnzTEBWQKpIBOaydwtaeP8adNIgpD9qAsjHd6VkKGV7P53A_wh1ms_-5Kardm/s1600-h/image%25255B71%25255D.png"><img alt="image" border="0" height="456" src="https://lh3.googleusercontent.com/-VLM6uHNjVP8/VuJF3Fj-DII/AAAAAAAAAQk/uIzXoEQh1_M/image_thumb%25255B53%25255D.png?imgmax=800" style="display: block; float: none; margin-left: auto; margin-right: auto;" title="image" width="583" /></a> </div>
<br />
El hardware necesario los muestro en la figura 3. Aquí se debe tener algunas consideraciones tales como. <br />
<ul>
<li>D+ debe necesariamente ir conectado al pin INT0. </li>
<li>D- puede ser cualquier pin del puerto D. </li>
<li>El jumper para iniciar el bootloader puede ser cualquier pin.</li>
</ul>
<br />
<div align="center">
<div style="text-align: center;">
<em>Figura 3.</em></div>
<div style="text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiNg-F4g4dKV2RSMczLke-whWZBOBLbE3x-9SfkNZahyvOkVOMM1BCS9xxVpq6BI4kzChnpntI6CGc8oVCTXV-yEa-cspT6SqQbB0elVbcsAZLsiPXGO2uXJSaE1QXeRU0SeC5lr8B4W4Bw/s1600-h/image%25255B26%25255D.png"><img alt="image" border="0" height="337" src="https://lh3.googleusercontent.com/-Ua9K324d6JI/VuJF4pxO0QI/AAAAAAAAAQs/7Q8UQNLPw18/image_thumb%25255B20%25255D.png?imgmax=800" title="image" width="814" /></a> </div>
</div>
<br />
<br />
En la figura 4 se muestra el diagrama del flujo del bootloader. <br />
<div style="text-align: justify;">
Despues de un reset se inicia en bootloader y este se ejecutara sí: </div>
<ul>
<li> La fuente de reset es externa (MCUCSR & (1 << EXTRF)).<br />
</li>
<li> Si el jumper esta colocado ((PINB & (1 << JUMPER_BIT)) == 0).</li>
</ul>
<div style="text-align: justify;">
En otras palabras, para ejecutar el bootloader hay que colocar el jumper y presionar el boton de reset. </div>
Para salir del bootloader sólo hay que quitar el jumper. <br />
<br />
<ul></ul>
<div align="center">
<em>Figura 4.</em><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiyS7Tr0sqlTDdXlnMe_9R15jI_l8_iabTj1hPYyDsuA8xgKm7VPP4XHq_FvahTWs2aDc-jZdFblREKWESoPLo9qx_4sIZ7Jzhe-s1dYGHafrA1i-B-CW-HEOD_vsoSetLQcgH2TfGz_Vdj/s1600-h/image%25255B8%25255D.png"><img alt="image" border="0" height="497" src="https://lh3.googleusercontent.com/-fXzgN7Abr3U/VuJmzt9-QAI/AAAAAAAAARA/u0aUeqvjMZU/image_thumb%25255B6%25255D.png?imgmax=800" style="display: block; float: none; margin-left: auto; margin-right: auto;" title="image" width="371" /></a> </div>
<br />
<br />
Antes de programar el bootoalder debemos debemos modificar los siguientes fuses. <br />
<ul>
<li> En High Fuse debemos seleccionar una de las secciones que tengan como mínimo 1024 words (2048 bytes) ya que el bootloader ocupa más de 1900 bytes. También debemos seleccionar “Boot Reset Enable” para que el programa inicie en la sección de booteo y no en la de aplicación. Para ATmega8 recomiendo 0xC8.<br />
</li>
<li> En Low Fuses debemos seleccionar alguna de las opciones Ext. Crystal/Resonator High Freq. Para un ATmega8 recomiendo 0xFF.</li>
</ul>
<em> </em><br />
<div align="center">
<em><br /></em></div>
<em></em><br />
<div style="text-align: center;">
<em><em>Figura 5.</em></em></div>
<em>
</em><a href="https://lh3.googleusercontent.com/-RmsU_sXaHoU/VuJm0JLX7dI/AAAAAAAAARE/UEniMu_P_i0/s1600-h/image%25255B19%25255D.png"><img alt="image" border="0" height="257" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj9jXg_tA4XeDPpw2yQfB8oILYDhFOIaunq_Q7E29KnI_B-awUyXvLLtTJ4OQYEYJ-vySwtPBFEtXELDdeTdrGqBh5oHE4gokdpHTOu_o2BLczbOh4O8jXJhup9qCZF-BMUn0cdgXDgsg4o/?imgmax=800" style="display: block; float: none; margin-left: auto; margin-right: auto; text-align: center;" title="image" width="514" /></a><br />
<div style="text-align: center;">
</div>
En la figura 6 se muestra el mapa de memoria de la sección de booteo de un ATmega8. Como ya se dijo antes, de esta usaremos mas de 1900 bytes, por ello en los fuses se seleccionará la mayor área. <br />
<br />
<div align="center">
<em>Figura 6.</em><a href="https://lh3.googleusercontent.com/-UQ8CIsgePiA/VuNiwx_82aI/AAAAAAAAARY/HN-WmSGWMLI/s1600-h/image%25255B18%25255D.png"><img alt="image" border="0" height="432" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEizzCzliNuKK6hCYJn8g-6U13nGnN84HNManc0-cSZT6CTyYv1jKt6be7ugnIPK-14OLtewcg3tCsgpH1IxW6oDM8uDehr2XQGkyoNZa-Crjy0cKDvLWwirdj9K1T_WJ9wJBF1s_RtZh1To/?imgmax=800" style="display: block; float: none; margin-left: auto; margin-right: auto;" title="image" width="494" /></a></div>
<strong><em><u><br /></u></em></strong>
<strong><em><u> </u></em></strong><strong><em><u>SOFTWARE</u></em></strong><br />
<strong><em><u><br /></u></em></strong> <br />
El código original lo pueden encontrar en el siguiente enlace <a href="https://www.obdev.at/products/vusb/usbasploader.html"><em><strong>link</strong></em></a>. <br />
<div align="justify">
Aquí les dejo el proyecto en ATMEL STUDIO 7 <a href="http://adf.ly/12709021/usbasp-boot"><strong><em>USBasp-boot</em></strong></a>. El proyecto esta configurado para un ATmega8 a 12MHz, pero puede ser cambiado facilmente a otros dispositivos. </div>
<div align="justify">
Las modificaciones necesarias para usarlo con otros dispositivos son las siguientes: </div>
<ul>
<li> <div align="justify">
Sí se quiere usar otras frecuencias de oscilador debemos hacer el cambio en Toolchain>Symbols. Las frecuencia pueden ser de 12,15,16,18 y 20 MHz. En las figuras 7 y 8 se muestran los lugares donde se deben realizar los cambios de frecuencia.</div>
</li>
</ul>
<em> </em><br />
<div align="center">
<em><br /></em></div>
<em></em><br />
<div style="text-align: center;">
<em><em>Figura 7.</em></em></div>
<em>
</em><a href="https://lh3.googleusercontent.com/-tACFQgN_0X4/VuNiy8TZ-1I/AAAAAAAAARg/Hwjl9UnS2Yk/s1600-h/image%25255B8%25255D.png"><img alt="image" border="0" height="164" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjT28dP77_6KneCktk2irrqTEg1IvOfvwVgU1BbNsSbYknjeksO2hgIK2xDdVRDxhm6G_qIurXOqXmcnIty0dXapLuaZmlVzYX6m4NH4x7tzVCIJDSp-axtJOtum_KrF2_AF82cSu6wAMB-/?imgmax=800" style="display: block; float: none; margin-left: auto; margin-right: auto; text-align: center;" title="image" width="533" /></a><br />
<em> </em><br />
<div style="text-align: center;">
<em><br /></em></div>
<em></em><br />
<div style="text-align: center;">
<em><em>Figura 8.</em></em></div>
<em>
</em><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi-Uflkbk2tT8a4MUYYcFWdcZvDWLJ35CFcL0iSNvyg7KQ3SbSvSFuyp_wbIG8t1EP0ZVahACFjFlbCnfdfu8AziUog88HdD10zP6e-MufCXLAcp3RS-cdERZI8i6zGvhLEHhNDvvsDVFOZ/s1600-h/image%25255B33%25255D.png"><img alt="image" border="0" height="155" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhHqDXiF5_pSI-WxXTvp4j0jB-GB46LxZprYFe9A7-mdgCvPdnBO-syZkrDOmw_Sgst7vsm_DO2m1uWU5KFvTuF6SDvTuFoOKGPWGdS5-6G1FBoei6ZZCWjnCHeq5nnFMf3lJpq-mLpmjxm/?imgmax=800" style="display: block; float: none; margin-left: auto; margin-right: auto; text-align: center;" title="image" width="481" /></a><br />
<div style="text-align: center;">
</div>
<div align="justify">
También debemos decirle al compilador que el código generado debe iniciar en el sección de booteo seleccionada en los High Fuses. En el ejemplo de la figura 5 se selecciono “Boot start address=0x0C00” donde 0xC00 es la dirección, en words, de inicio de la sección de booteo. </div>
Tenemos dos formas de reasignar el inicio del código: <br />
<div style="text-align: justify;">
En la figura 9 se hace la reasignación usando el inicio de la dirección en words (0x0C00). </div>
En la figura 10 se hace la reasignación usando el inicio de la dirección en bytes (0x1800). <br />
Nosotros debemos seleccionar sóla una de las dos formas (Figura 9 o 10). <br />
Hay que tener en cuenta que 0x0C00 words = 0x1800 bytes. <br />
<div align="center">
<em></em> </div>
<div align="center">
<em>Figura 9.</em><a href="https://lh3.googleusercontent.com/-KrGSACVJBlA/VuNi1BA2AsI/AAAAAAAAARw/L2LCRSnoS9Y/s1600-h/image%25255B58%25255D.png"><img alt="image" border="0" height="98" src="https://lh3.googleusercontent.com/-N6qnbSxfL-8/VuNi1jAQBXI/AAAAAAAAAR0/hsmqeVMCYf4/image_thumb%25255B39%25255D.png?imgmax=800" style="display: block; float: none; margin-left: auto; margin-right: auto;" title="image" width="351" /></a> </div>
<div align="center">
<em></em> </div>
<div align="center">
<em>Figura 10.</em><a href="https://lh3.googleusercontent.com/-W39l9wPocMw/VuNi2HJ5hVI/AAAAAAAAAR4/r3oCoO7AoMg/s1600-h/image%25255B61%25255D.png"><img alt="image" border="0" height="72" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEixZyDaUtwghtz7XZX5OZCwZYGczzWzp6gJpEG6_4hTU_Nn-WKcPDdCSFt_bcs8ESKoXibHT4d0sM51WB3xmZeE1LGHKrLpn8X4XxFd8SypEeWtkX8u3r_zfzUrXHLYBJ8v_XRJh_5AdJ_D/?imgmax=800" style="display: block; float: none; margin-left: auto; margin-right: auto;" title="image" width="399" /></a> </div>
<br />
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
En la figura 11 se muestra parte del código generado. Aquí vemos que el inicio es en la dirección 0x1080 (para 2014 bytes). Cuando el código generado es para la sección de aplicación la dirección de inicio es 0x0000. </div>
<div align="center">
<em></em> </div>
<div align="center">
<em>Figura 11.</em><a href="https://lh3.googleusercontent.com/-k07DpZO6phI/VuN6-46hmII/AAAAAAAAASM/wcmU_urEMHg/s1600-h/image%25255B76%25255D.png"><img alt="image" border="0" height="105" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh4a_M50hzRmDstclNxdN1vcRLlE-OzutpVGsHsg_r_iUpvF5G1d3si1P8lVdBy3Vh4aO_ieU2RP_7LzR29fAFocPqvU-f9btiDdPYS04-kZN23d5V0-RudCwVzpjR4wX5ffA2jioSZBK6t/?imgmax=800" style="display: block; float: none; margin-left: auto; margin-right: auto;" title="image" width="389" /></a> </div>
<br />
<br />
En la figura 12 se indica que el se usará PD3 para conectar D- del USB. Esto lo podemos cambiar a algún otro pin en el mismo puerto. <br />
<br />
<div align="center">
<em>Figura 12<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjymU9GogAwFpCxzlMP3MTkEhdPE8UpiC6NwUKId_qgpnR4n2d_4OJjGYep3uEhuxQW9feP3YxJyd2wAkdoPA-6t-yu8k0uFdCcjblwlNNL5UvnBE49a8-MxP-4NT2zriGMuBAra_8r2Euu/s1600-h/image%25255B102%25255D.png">.<img alt="image" border="0" height="63" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhgSPWzLBA12MkyCj7GzvHGYHRJkh18FOmySxH-5Kl9yYK-g6rJFF2ZqojCPESkMwPPlJihyphenhyphenCmEewjc5W189bQFgOoEqd7dFXxkzRiNBdzLMntp_l8GoeOQgd6WvMxw8XhOto9-pq-FdW65/?imgmax=800" style="display: block; float: none; margin-left: auto; margin-right: auto;" title="image" width="439" /></a></em> </div>
<br />
<br />
En la figura 13 se indica el pin que se usará para el jumper de inicio del bootloader. Este puede ser cualquier pin que no se esté usando. <br />
<br />
<div align="center">
<em>Figura 13<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEguMK4eYzwtm-SOZVYHxBFAgKFNWqEyMVcmhkzuMFb5cCbf_YIJdoFZu0YvqgB3VaCehEmh0qKTNXwkAFzmRkhlU9VhNRXsYPfQ9tfvHWYh_HjkCGMSlsAHWc3DfQ0flQsMdtCyoXWyNsKh/s1600-h/image%25255B107%25255D.png">.<img alt="image" border="0" height="69" src="https://lh3.googleusercontent.com/-uK7y9qsiV9M/VuN7C6gBoVI/AAAAAAAAASg/Z77gt7t7iiI/image_thumb%25255B72%25255D.png?imgmax=800" style="display: block; float: none; margin-left: auto; margin-right: auto;" title="image" width="417" /></a></em> </div>
<br />
<br />
En la figura 14 se activa la resistencia pull up correspondiente al pin del jumper. <br />
<br />
<div align="center">
<em>Figura 14</em><a href="https://lh3.googleusercontent.com/-pSgeEJfQggk/VuN7Dm8lfvI/AAAAAAAAASk/O9BuPMR6erM/s1600-h/image%25255B94%25255D.png">.<img alt="image" border="0" height="62" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj2inbWeB05-DX_oF9UnxYPIvjobvv6zRXjvUK9rZ8xuwAbShlLbQOA2LlxL-PydHp1gQbpGznpAi6L8geC6KcUqjk6NW7pF3PA4OA9gtg9uq4QIxpGozJW1_cAeusNgO6VtkbbQGx87nAL/?imgmax=800" style="display: block; float: none; margin-left: auto; margin-right: auto;" title="image" width="551" /></a> </div>
<br />
<br />
En la figura 15 se evalúa la condición para permanecer o salir del área de booteo. <br />
<br />
<div align="center">
<em>Figura 15</em><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhiruu6xg722t9ZYSsgdBKPWfZEthH4J0JVcRUUKoP2Z8ixI4fAWh83CzDY4uXiTGOUcfnX2vEy-f3s7FD7vjE-f8P6pAItBjxCTVr7NMgtUUZOuHZIP0Cd4sR9XJiFFYKI00BVdO5MJfcI/s1600-h/image%25255B93%25255D.png">.<img alt="image" border="0" height="70" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEimBJO5IkrjtlpuX3g2QXWq_HcAY95WeN3bmfCQUTRvxIlunvUX6mp-Xd1OZzA3SBSbv4Fo1nc2Ghla5axjSwl05Z_8pPTJlZBRu2kbjFMuc3iiEDw6lp_vxh5jAFKvZmOOp11vdWKbZPCZ/?imgmax=800" style="display: block; float: none; margin-left: auto; margin-right: auto;" title="image" width="590" /></a> </div>
<br />
<br />
En los caso de la figura 14 y 15 se pueden usar el pin y el puerto que se deseé. <br />
Si el ATmega que queremos usar no se encontrase en la lista de la figura 16 corresponde agregarlo con sus respectivos “SIGNATURE BYTES”. <br />
<br />
<div align="center">
<em>Figura 16.</em><a href="https://lh3.googleusercontent.com/-FCyhAL4BaiY/VuN7Gz-mF5I/AAAAAAAAAS0/qAh57cPU9mk/s1600-h/image%25255B118%25255D.png"><img alt="image" border="0" height="397" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjHgvR6Q9NgdHuSL18EuCTsO6enntcjw1ISzWZUWpBIlsm3K65-dtBX7gJCJkVjoZOiNidWINLXkQOhe4YjZIZil2jEvetEpLYhG89vJ0QJcyfQaPhGSVsRe8lzLtNgZtoOClJ2N3nFq6c4/?imgmax=800" style="display: block; float: none; margin-left: auto; margin-right: auto;" title="image" width="663" /></a> </div>
<strong></strong> <br />
<br />
<strong>El proyecto es para un ATmega8, cómo cambiamos de dispositivo ?</strong> <br />
<strong></strong> <br />
<ul>
<li>Damos click en l icono <a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj6PZQlVr2rZIfCN2zMb__6Mes2x45JJsQX9Qoe_c4a5nm9OEtA3FS_RY_M35Aoj6tH2k3coZ3tcB37Wv-P1rBi4shW51Z5S08begGIzo1F6FaxC7cOG803AM6_LPkly6yWGUaHtUFIyg8V/s1600-h/image%25255B122%25255D.png"><img alt="image" border="0" height="35" src="https://lh3.googleusercontent.com/-zAfHe5hf5Yw/VuN7JS0Z64I/AAAAAAAAATA/gyg8Rb0VYgw/image_thumb%25255B83%25255D.png?imgmax=800" title="image" width="92" /></a></li>
</ul>
<ul>
<li>Click en “Change Device…” <a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj4DPg7xwOLEV6KhGOkXlPYMo4QZ6sHcgNU4AD_T4Rn56FSMOLSvVn5fz9zT2kkdtrTbZQx_P0ixWbuFUhkxPlOzPoojUXKT6rCDV33VAoMC5YieeN1mUjO7qr3CXNV_grqFkW5jkZBd87r/s1600-h/image%25255B136%25255D.png"><img alt="image" border="0" height="34" src="https://lh3.googleusercontent.com/-t59wEVNM6AU/VuN7KuSk9-I/AAAAAAAAATI/whCAQkB6ew0/image_thumb%25255B91%25255D.png?imgmax=800" title="image" width="342" /></a></li>
</ul>
<ul>
<li>Seleccionamos el nuevo dispositivo. <a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh-gEgWMLzOiGJxxMT8sAY9D59I2KZVj5gvvG9TO7huwElJAA4Cav-wVItpFvQfI7JU6-kIt3tlvJU20fnKSfns9obWhsHlUFyMUxuxsMXxIj1U2mD_RCeYIGaQG-x0i56VfWstQHsdjDIZ/s1600-h/image%25255B137%25255D.png"><img alt="image" border="0" height="159" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiYJOY_cupk6tT14_7K61gNJmLp8Ou1ozAJJ7EhuwjZPdnJwGafYzKaWvAB2ruRs9xDDT8VLeEtUK6PcPznDAOQopzmOsqvPHheejsfMT4EtHcWbS7w9BIo6rwdgeh3ZcIx7NSun9Nrea47/?imgmax=800" title="image" width="297" /></a></li>
</ul>
<ul>
<li> Ya habremos cambiado nuestro nuevo dispositivo. <a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgO1dPdSJwuCizEYcVio7wzVuEjzaF4w2UQEjNJUOUhC4niuuJMUZNJ0QY_zWVPpRlH1VrzuUo9GOF0VVvUyMFdsQqD-yqfpnEND5O0ZYGSRKlDnlFPXl4Zk7Nrs4ccz_fXieZFLLJS93-y/s1600-h/image%25255B135%25255D.png"><img alt="image" border="0" height="34" src="https://lh3.googleusercontent.com/-jKEU58YPwDs/VuN7OQFsjWI/AAAAAAAAATY/07DKKlKuc5Y/image_thumb%25255B90%25255D.png?imgmax=800" title="image" width="86" /></a><br />
</li>
<li> Luego sólo queda compilar y tendremos el .hex del bootloader para poder programarlo.</li>
</ul>
<div style="text-align: justify;">
Finalmente, y cuando el bootolader se encuentre instalado, podremos usar programas como SinaProg para descargar nuestra aplicación sin afectar el bootloader. </div>
hay que resaltar que el bootloader no permite hacer cambio de los fuses. <br />
En resumen: <br />
<ol>
<li> Preparar el hardware (figura 3).<br />
</li>
<li> <div align="justify">
Con un programador cualquiera cambiar los fuses del uC (figura 5).</div>
</li>
<li style="text-align: justify;"> Hacer los cambios en el software, sólo si son requeridos: F_CPU (figuras 7 y 8), .text (figura 9 ó 10), D- (figura 12), JUMPER_BIT (figura 13), PORT/PIN JUMPER (figuras 14 y 15).<br />
</li>
<li> Agregar un nuevo uC si falta (figura 16).</li>
</ol>
<br />
Espero que esto les sea de utilidad, ya que no necesitar un programador puede ser muy útil.<br />
<br />
<br />
<br />
<br />Anonymoushttp://www.blogger.com/profile/14023938257857442019noreply@blogger.com0tag:blogger.com,1999:blog-7123434971804829465.post-38113738147231934152016-03-03T15:54:00.000-08:002017-05-23T10:03:26.147-07:00Control, PID, de velocidad con ATmega<br />
<br />
Este post será dedicado al control de velocidad de un pequeño motor DC usando el algoritmo PID.<br />
El esquema general a desarrollar se muestra a continuación (Figura 1).<br />
<br />
<div align="center">
<em>Figura 1.</em></div>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiIz0fZ5P6a3ux0cY7M4np4aSoKnOohq8Y9wjFPdsYUGP084_uZNCuvsnVthzUzr0aI_kZLh8x3BmFL4GLvrrcblnJWL_Fzhcn2uURgwwsakfdBI-pLSlXIrImS2ZLNCubBUKDq387usYQw/s1600-h/pid1%25255B3%25255D.png"><img alt="pid1" border="0" height="333" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgb-9333RTozSECzDMO4DbcWM4wrsyhbpeoKbP-dCADI6-kufzwO0NbuMlcuXpoLtyY3_eobiWete1yxHr67UAgL4syLYDgfq1klaycd01RXFV0AmA8pVHQQn3RHD-5LsdgmzalJfNxzllz/?imgmax=800" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: inline; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="pid1" width="893" /></a><br />
<br />
El algoritmo será implementado en un ATmega32. Este microcontrolador recibirá, por el puerto serie, órdenes desde una interfaz gráfica hecha en visual c# (Figura 2). <br />
<br />
El programa en la PC permitirá enviar hacia el controlador(ATmega32) el SetPoint(SP), Kp(Ganancia proporcional), Ti(Tiempo integrativo en seg) y OUT cuando se seleccione modo manual. También permitirá graficar PV, SP y OUT. PV, SP y OUT son escalados de 0 a 100.<br />
<br />
<div align="center">
</div>
<div align="center">
<em>Figura 2.</em></div>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj6d1lZT8Ug75S2y_dLxm_bBX6kIvkJXvU1UP5mS6TD0ga1AQNi-VsKJbhSkQYXSpWVgOw_QWqhCpNdCU2tqL6ihpinuwlMhLSMCIhE-Dg1RmahsxEggWzqILG2uwGyWgzBvXXivUVsXopT/s1600-h/PID%25255B1%25255D.png"><img alt="PID" border="0" height="452" src="https://lh3.googleusercontent.com/-CCBqSd7i8d8/VtyhSp027MI/AAAAAAAAAOA/uAyF6KSSQ98/PID_thumb%25255B1%25255D.png?imgmax=800" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: inline; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="PID" width="897" /></a><br />
<br />
<br />
<strong><u>DEL SOFTWARE (en el controlador mega32).</u></strong><br />
<br />
Del uC usaremos:<br />
<br />
<ul>
<li>Los pines PD0 y PD1 (INT0 e INT1) para leer las salidas(A y B) del encoder tal como en un post anterior. </li>
<li>El UART para recibir, mediante interrupción, SP,Kp,Ti y OUT(en modo manual) y para enviar PV y OUT(en modo automático). </li>
<li>El Timer1 para generar una interrupción cada 100ms que permitirá ejecutar el algoritmo de control y hacer el envío de datos a la PC. </li>
<li>El Timer2 para generar una señal PWM equivalente a la salida (OUT) del controlador. La salida será por el pin PD7/OC2. </li>
</ul>
<br />
El programa funcionará a una frecuencia de 7.3728MHz y el UART a 115200bps tal como se muestra en la figura 3.<br />
<br />
<div align="center">
<em>Figura 3.</em></div>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgszNeXRhBiWyqZPEmWc8ru6TZt2DMkAjEKENBBZ28dLMYlObGVNpqWlZAxhOQsvTGl1U0byNDw-2wdFnAJITq4suFGr6UnBL2lfw0ZYfTAIC8JE_J1N0xgzmWx08jHJlyHVX0WbdSj78CI/s1600-h/image%25255B4%25255D.png"><img alt="image" border="0" height="57" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgPSH7Cc-_qqVRwhSTp0OiKwSnj4gAu72BxLg7wGViGxv4YNnCI1wiRLGXjsFHbLF5-QqZNB3C5bgV9HgI3ltS4xTfRMPoafWNMRbyKuglb755kwkqnxoAz0dDdPP4VC8LjXsPDmQKSBL1T/?imgmax=800" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="image" width="149" /></a><br />
<br />
<br />
Se usaran las uniones de la figura 4. <span style="font-family: "courier new";">TRAMA_t</span> es para la recepción y envío de datos hacia/desde la PC y <span style="font-family: "courier new";">States_t</span> para el manejo de los estados del encoder. <br />
<br />
<div align="center">
<em>Figura 4.</em></div>
<a href="https://lh3.googleusercontent.com/-K68Te6WVB6c/VtsEHHrvCmI/AAAAAAAAALU/FpPT7oovlVs/s1600-h/image%25255B9%25255D.png"><img alt="image" border="0" height="471" src="https://lh3.googleusercontent.com/-TWKoKPkJujw/VtsEIABNMNI/AAAAAAAAALY/240XoBxm8q0/image_thumb%25255B6%25255D.png?imgmax=800" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="image" width="245" /></a><br />
Las variables a usar son:<br />
<div align="center">
<em><br /></em></div>
<div align="center">
<em>Figura 5.</em></div>
<div align="center">
<a href="https://lh3.googleusercontent.com/-DK_O_XwxvIY/VtoEPDDvcjI/AAAAAAAAAKY/Rba9MHgH4uE/s1600-h/image%25255B4%25255D.png"><img alt="image" border="0" height="57" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi6_U64M1PfPPpLdfhcKEy48FMTqi-_cclN7M3CT4rUitAsr9sNUFfdhss3VEErPIE-ZK9ZMYT60PJwmTIsjXDBnllAPKPSdwoVuRtAn5K5UlB879nBp2ek1ZRWW1zdiuK1aBBkBqFvF2nC/?imgmax=800" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: inline; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="image" width="221" /></a></div>
<div align="justify">
<span style="font-family: "courier new";"><br /></span><span style="font-family: "courier new";"></span>
<br />
<a name='more'></a><span style="font-family: "courier new";"><br /></span></div>
<div align="justify">
<span style="font-family: "courier new";">count </span><span style="font-family: "arial";">para contar los pulsos del encoder.</span></div>
<div align="justify">
<span style="font-family: "courier new";">e[2] </span><span style="font-family: "arial";">para almacenar el error actual (SP – PV) y el error pasado. </span></div>
<div align="justify">
<span style="font-family: "courier new";">u[2] </span><span style="font-family: "arial";">para almacenar la salida actual del algoritmo (OUT) y la salida pasada.</span></div>
<div align="justify">
</div>
<div align="justify">
</div>
<div align="justify">
Se define algunas constantes como:</div>
<div align="justify">
</div>
<div align="center">
<br />
Figura 6.</div>
<div align="justify">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjYE81owazT_umf2EKasCq_ODeWJngQsc6EuaMyitbVU78jzwQ8SzQM3jmpcNfEAdkjRo-fIp8Zn0HrsYmXaftYubrnTSIRdwpne9hltSU3_3tcAq5eGaSk4s07XVMJ_1Pag_vxGVVvIQtH/s1600-h/image%25255B8%25255D.png"><img alt="image" border="0" height="69" src="https://lh3.googleusercontent.com/-LIZDutJN4uY/VtoEQik1i4I/AAAAAAAAAKk/xGn2KjChqe0/image_thumb%25255B3%25255D.png?imgmax=800" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="image" width="215" /></a></div>
<div align="justify">
</div>
<div align="justify">
<span style="font-family: "courier new";"><br /></span><span style="font-family: "courier new";"><br /></span><span style="font-family: "courier new";"><span style="font-family: "courier new";">PV_MAX y PV_MIN : </span><span style="font-family: inherit;">Son los valores máximos y mínimos de </span><span style="font-family: "arial";">PV </span><span style="font-family: inherit;">medidos cuando</span><span style="font-family: "arial";"> OUT </span><span style="font-family: inherit;">es llevado de</span><span style="font-family: "arial";"> 0 a 100%. </span><span style="font-family: inherit;">Los usaremos para escalar el</span><span style="font-family: "arial";"> PV medido a un PV de 0-100% </span><span style="font-family: inherit;">antes de ingresar al algoritmo de control.</span><span style="font-family: "courier new";"> </span><br /><span style="font-family: "courier new";">OUT_MAX y OUT_MIN : </span><span style="font-family: inherit;"><span style="font-family: "arial";">Valores máximos y mínimos en porcentaje de la salida del controlador. Nos servirá para acotar la salida del algoritmo de control.</span> </span></span><span style="font-family: "courier new";"> </span></div>
<div align="justify">
Es decir que el algoritmo PI tendrá como entradas (SP y PV) en escala de 0 a 100 y la salida (OUT) también será de 0 a 100. PV es llevado de 0-100 antes de entrar al PI. OUT sale del PI escalado de 0-100 y debe ser escalado de 0-255 antes de ponerlo en la salida PWM.</div>
<div align="justify">
</div>
<div align="justify">
Los includes a usar son:</div>
<div align="center">
<em><br /></em><em>Figura 7.</em></div>
<div align="justify">
<a href="https://lh3.googleusercontent.com/-3yz4OYg1J2k/VtoG3Q7HnWI/AAAAAAAAAKw/cxmZkyT-Emg/s1600-h/image%25255B12%25255D.png"><img alt="image" border="0" height="104" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi1QNofH22jNzmMuYA3UFMPfW7Zloo5-6Q43OJtvPK4ImmYHw8aSjVCb6SQdAUm2TKf0hHFX1qx3EvfgqHAPkNImlyRVphrblq8wSjd4-tFwlsahALVh24bjc9OuSffhnXfOS74UFm2U3-x/?imgmax=800" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="image" width="223" /></a></div>
<div align="justify">
</div>
<div align="justify">
<br />
<br />
Hay dos funciones que usaremos par leer y escribir en el uart, sus prototipos están en la figura 8. Estos prototipos deben ir antes del main.</div>
<div align="justify">
</div>
<div align="center">
<em><br /></em><em>Figura 8.</em></div>
<div align="justify">
<a href="https://lh3.googleusercontent.com/-C3AB7S7snPo/VtoG4jr1TGI/AAAAAAAAAK4/-nRAcgDp00U/s1600-h/image%25255B21%25255D.png"><img alt="image" border="0" height="38" src="https://lh3.googleusercontent.com/-FPUl61mYHHg/VtoG5ImxiCI/AAAAAAAAAK8/QX3JwDcLWVM/image_thumb%25255B10%25255D.png?imgmax=800" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="image" width="239" /></a></div>
<div align="justify">
</div>
<div align="justify">
<br />
<br />
En la figura 9 se muestra el main. Aquí se configura el uart activando la transmisión, recepción e interrupción por recepción. También se configuran las entradas para el encoder, el Timer1 para que genere interrupciones cada 100ms y la salida PWM por el PINC0 usando el TIMER2. </div>
<div align="justify">
Luego de la configuración se activa el bit de interrupción global y se espera en un bucle infinito.</div>
<div align="justify">
</div>
<div align="center">
<em><br /></em><em>Figura 9.</em></div>
<div align="justify">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgFUdSlzNX8qSMhSdbtigE_Q4oOP8rigEnB3wVVKcFBWY9OMNvruOiD1AZlkh2G-obZWifuwPYEFamymDvBFyMwild3z7KQsLDE0NbJ_BPG1_eSCLHAIbpzJk7_Um0jrLbS9m39a65uuCyn/s1600-h/image22%25255B3%25255D.png"><img alt="image" border="0" height="410" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjeS5qmvTCMdefx7fCUxyezslkwciKDsLlf1-sJ6wyFcq3cB86fXVLeCJWVSDHBgvXUlm3ma2Jn-aEYMp1EhIZFad2OpWh3NsxRPRUvGMIW-w_STMoq5cfCoVmpWFMhF3Ay3FfUmTVVKutj/?imgmax=800" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="image" width="353" /></a></div>
<div align="justify">
</div>
<div align="justify">
</div>
<div align="justify">
</div>
<div align="justify">
<br />
<br />
En la figura 10 se muestran las funciones para leer y escribir datos por el uart.</div>
<div align="justify">
</div>
<div align="justify">
</div>
<div align="center">
<em><br /></em><em>Figura 10.</em></div>
<div align="justify">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgqD4wjayyX_TMuaoOPL8Kh3KjVZC9T4KmjxpHitHwl2qomdrqgsfvr8agiQgdTAMlZi1KwKh-Ap96tDCdCMiyuJXJgJVvQjU0HRn9XhNxyymlBGNzniS7CdiJVZscN83TIlP4N4gWD4OjF/s1600-h/image38.png"><img alt="image" border="0" height="188" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi2TrLnjWw9kpVdGB6r1Y-zxr-LqmO6dsf7X43GmgtDiyFUzFxEvOi4qdqopYjcYvQ2LJEOHSoRsuMjoVBHJhISkbNmqTkRn9RgXgfio0LLLHvcNQcbyWJWNmzQ2qelzW9GxXs8edpBUuV-/?imgmax=800" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="image" width="267" /></a></div>
<div align="justify">
</div>
<div align="justify">
</div>
<div align="justify">
</div>
<div align="justify">
<br />
<br />
En la figura 11 se muestra la interrupción por recepción del uart. Los datos son recibidos/transmitidos, de acuerdo a la estructura <span style="font-family: "courier new";">TRAMA_t,</span> con una cabecera (0xAB), un cuerpo con valores y parámetros correspondientes al control y un chequeo de integridad, que no es otra cosa que la suma de todos los bytes anteriores.<br />
<br /></div>
<div align="justify">
Aquí se crea una variable local (<span style="font-family: "courier new";">dtt</span>) del tipo <span style="font-family: "courier new";">TRAMA_t</span> para almacenar los datos recibidos. La variable <em><span style="font-family: "courier new";">sum</span></em> permite chequear la integridad de los datos recibidos. </div>
<div align="justify">
Si el chequeo de integridad es correcto, los datos de la variable local <span style="font-family: "courier new";">dtt</span> son copiados a la variable global <span style="font-family: "courier new";">dt</span>.</div>
<div align="justify">
</div>
<div align="center">
</div>
<div align="center">
<br />
Figura 11.</div>
<div align="justify">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg2C_TGx1tS7YogS5Cj940Lr0S4dQvYDMFhPbBGicXhNfGGMO9rLSZvkIJuRLxW5-rnE_qCKbrDMmI3Saj0_yjkvvMO6ptMRJH3pKR-mE5oCsLr-ZjQhMdClm9-MwoJxvrqwtlJfCF29GPN/s1600-h/image35.png"><img alt="image" border="0" height="305" src="https://lh3.googleusercontent.com/-ZEdq9MswX_o/VtulEQOWnbI/AAAAAAAAAL0/v9Q03vteQ9I/image_thumb24.png?imgmax=800" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="image" width="450" /></a></div>
<div align="justify">
</div>
<div align="justify">
</div>
<div align="justify">
</div>
<div align="justify">
<br />
<br />
En la figura 12 se muestra las interrupciones de los pines PD2 y PD3. Aquí se leen las entradas del encoder como ya se explico en un post anterior. En retardo, <span style="font-family: "courier new";">_delay_ms(20)</span>, se debe a que el encoder que estoy usando genera algunos rebotes cuando cambia de estado, caso contrario, este retardo no sería necesario. El valor de las cuentas es almacenado en <span style="font-family: "courier new";">count</span>.</div>
<div align="center">
</div>
<div align="center">
<em><br /></em><em>Figura 12.</em></div>
<div align="justify">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgsG4a0kbumg7anKGYAktmcV_V-CuJOUeIBuQmTjli2NHfZiHxR4kr5sEX-ikxwA6NzN2uu1IoRt3KOazizVx3IPjePu07vNeg4pUL8C9yzd-bTILy8oEg07mVjQjdmMazBnoUQ8oioC-On/s1600-h/image33.png"><img alt="image" border="0" height="264" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhJNz0PihjZVGyptn_ozoq3hcOBYNjrAGOh1qIG4pKAS1LMYzP6NQNJdEGhtJmz8Sbh1wV3lbFzZHCkAMZ-dW_hAoLdLNZ5bx_acyU3Gp-Yx0nCIy0ROA8Eem4JAhtMMG8xP2ChrUbw8buQ/?imgmax=800" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="image" width="593" /></a></div>
<div align="justify">
</div>
<div align="justify">
</div>
<div align="justify">
</div>
<div align="justify">
</div>
<div align="justify">
</div>
<div align="justify">
</div>
<div align="justify">
</div>
<div align="justify">
</div>
<div align="justify">
</div>
<div align="justify">
</div>
<div align="justify">
</div>
<div align="justify">
</div>
<div align="justify">
</div>
<div align="justify">
</div>
<div align="justify">
</div>
<div align="justify">
</div>
<div align="justify">
</div>
<div align="justify">
</div>
<div align="justify">
</div>
<div align="justify">
</div>
<div align="justify">
</div>
<div align="justify">
<br />
<br /></div>
<div align="justify">
Antes de pasar al código del algoritmo de control… un poco de matemática:</div>
<div align="justify">
</div>
<div align="justify">
</div>
<div align="justify">
</div>
<div align="left">
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgZcTn5EEgfMAnYE0cpfuiyRsH4maY8AMGj-4mhaCQnkNp8ekwFBOvIiAsuPWETr2VJ2cUMiM-wQAb8Ues32sudBS1oksSk3wCDp2izO1v4h7T4HLCwzuZgIHD5dQXp70CBTdokRdz63GOS/s1600-h/image%25255B4%25255D.png"><img alt="image" border="0" height="46" src="https://lh3.googleusercontent.com/-dd9vH4mEEK0/VtyhVC8hIfI/AAAAAAAAAOQ/teW63TBoYBg/image_thumb%25255B3%25255D.png?imgmax=800" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="image" width="354" /></a></div>
<div align="left">
</div>
<div align="justify">
</div>
<div align="justify">
<br />
Tengo que asumir que todos ya conocen la ecuación 1. Trabajaremos con esta ecuación para llegar a una forma discreta aproximada de la misma, la cual implementaremos en nuestro uC.</div>
<div align="left">
</div>
<div align="left">
</div>
<div align="left">
<br />
Primero, derivamos la ecuación 1 y tenemos:</div>
<div align="left">
</div>
<div align="left">
</div>
<div align="left">
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj-3gxzizhbaWUtBsPd_pEICWwO3sF8EU3_OZ8alaou9xjIN9DwbF7wn8UNQD3UAH5pJswBsZBp_rGbVhH4KIYBJqUipQJIDylieIZP_NxMIQhsaEru_okn6ytoskMBpset1Fr16aqMcvVf/s1600-h/image%25255B8%25255D.png"><img alt="image" border="0" height="53" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjjOYcgSsWyf3dd-KZdBHNWLppwftrMea8hkdN2Yo7boY0naTJeq8-MULnI2p-xRde5_K0awhFbSrOaO6vPN_wrUYpKOSGqppRL52uStFcizHNHhuy48W2bZjtU5ey-bAgKrSVrwqBRs2xN/?imgmax=800" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="image" width="367" /></a><br />
<br />
Ahora haremos las siguientes aproximaciones (ec3, ec4 y ec5):</div>
<div align="left">
</div>
<div align="left">
</div>
<div align="left">
<br />
<a href="https://lh3.googleusercontent.com/-g56YLCHWV9k/VtyhXEZQNRI/AAAAAAAAAOc/7JxmaArBKrc/s1600-h/image%25255B11%25255D.png"><img alt="image" border="0" height="58" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiCjVP2LLfdJJuANcsACF8kfdeujiCcH1Gb1JPqPgn_B91EuBOdbInXkzHjYYb6tNd-zvT004egzLtv423OsoguwcC6FzlAJhSHmE9L1F6zZPvH-L70vWmeXv2T_1fJt0uhedPXfu-3bE6I/?imgmax=800" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="image" width="323" /></a></div>
<div align="center">
</div>
<div align="center">
</div>
<div align="center">
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjMzQj0ywiLkhUK_2dL93jLimufjcc0uOXeexR13iWuTOcal3Lietkm2JogY0iF90gkDfFnMcy24KlbSVEyHTgp7xV_1hsART9YiUG_dTHDK0R2OhXY9_8kZbkYcU1UVEaMoOxyqqnhGnH0/s1600-h/image%25255B15%25255D.png"><img alt="image" border="0" height="57" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgBVe5y7kGlWaMexP-f-xqaUTaj6o3c7NDjkM18syv3UOqUJsbdPkjxoxqg4KmuxEQJa_JALeY7gHnS16A-tfL-w31d7VNlyY85dpa8SclsUdRcXxhm06xcqK4ndPxxD5B37T-IiNCTH_Tb/?imgmax=800" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: inline; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="image" width="323" /></a></div>
<div align="center">
</div>
<div align="center">
</div>
<div align="center">
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi_O2k3_Xky_E3tgk7lwkKlrWOUrxaLgRqitCvdrxWwPItWzKnGbDMtWsSeJcrc8ryDhJt3s3gHfDpzyLqrhfFNe20v32r3s6NEjo34gq4dST2-szCAUqeQ38QzTvTdJkyXj1R6VkwJgjie/s1600-h/image%25255B18%25255D.png"><img alt="image" border="0" height="133" src="https://lh3.googleusercontent.com/-1M2IQaOECoE/Vtyhas8oNBI/AAAAAAAAAOw/sbLVRmzs5ZQ/image_thumb%25255B17%25255D.png?imgmax=800" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: inline; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="image" width="605" /></a><br />
<br /></div>
<div align="center">
</div>
<div align="center">
</div>
<div align="justify">
</div>
<div align="justify">
Reemplazando 3, 4 y 5 en 2.<br />
<br /></div>
<div align="justify">
</div>
<div align="justify">
</div>
<div align="justify">
<a href="https://lh3.googleusercontent.com/-m0iJwkfq1Hw/VtyhbQb2E_I/AAAAAAAAAO0/G9E6OWni8T4/s1600-h/image%25255B22%25255D.png"><img alt="image" border="0" height="67" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiNq1E5A-R1dVTfZeV2ne-BsaBnTsc9VLp_5ouJGJD4kPEzgJGp1I9DE1wGk8EQngEKoQ3mY70yzV19Zr5RVtwV_UrTic_KMjhQKkbPze3QS3SSdzUrd-6jTsG_aYaxMODfJyM-6vZ9RMam/?imgmax=800" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="image" width="658" /></a></div>
<div align="center">
</div>
<div align="center">
</div>
<div align="justify">
</div>
<div align="justify">
<br />
Operando 6 tenemos:<br />
<br /></div>
<div align="justify">
</div>
<div align="justify">
</div>
<div align="justify">
<a href="https://lh3.googleusercontent.com/-wef-jX14BZw/VtyhegykF1I/AAAAAAAAAO8/al2to7pgkQA/s1600-h/image%25255B25%25255D.png"><img alt="image" border="0" height="55" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhjsc9vaJnAZKD-MSp78BPLaHP5-Nm-_jRLhtgsanECHbeV3jGzi-k1iA8Ii9L9z2rtrBTHDr-FI9ZLn2QIUL5zuAWWWx7kcEXhw_hqnPXcY-maz0VZLUTsZ68ilmHcMdBToKmQb9LATa_C/?imgmax=800" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="image" width="658" /></a></div>
<div align="center">
</div>
<div align="justify">
</div>
<div align="justify">
<br />
En 7 vemos una ecuación del PID discreto para un<em> T</em> (Tiempo de muestreo) lo suficientemente pequeño.</div>
<div align="justify">
</div>
<div align="justify">
<br />
En nuestro caso, para el control del motor, es suficiente con un PI, así que solamente usaremos la ecuación 8.</div>
<div align="justify">
</div>
<div align="justify">
</div>
<div align="justify">
<br />
<a href="https://lh3.googleusercontent.com/-gFU07uyd4zA/Vtyhgaq-vII/AAAAAAAAAPE/fhtFWw5MY54/s1600-h/image%25255B29%25255D.png"><img alt="image" border="0" height="31" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiwoYdz7QZ-dyClQijhUEfIQjaJ7S3NOTMJ0lNvhs41c2jxAOWMhU26zx5uAiUEO1xahpVVlmaBaErlwrpZZmGjZsRmakgWy-t1-monhyphenhyphenB3TIj4XvgIgQJpiBRpjfEReeyVi1SkwJ3cbIUC/?imgmax=800" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="image" width="422" /></a></div>
<div align="justify">
</div>
<div align="justify">
</div>
<div align="justify">
<br />
Dejando 8 en función de <em>T</em> y <em>Kp </em>tenemos:</div>
<div align="justify">
</div>
<div align="justify">
</div>
<div align="justify">
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgARa07zmkd2BkXSZBetNzuPo_f9ZZ3UpifpCuaRqqifgM2bb7TTDmgGqgouWs6n_dhlfaU6E-EmH-Gn0svjOm2xMHNEuZmfwTid-ihNnsTDmYFpHwF8Oa4tyG1YDAT_lfkSyRLCQlOA7m2/s1600-h/image%25255B32%25255D.png"><img alt="image" border="0" height="58" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg88Ze5ZM65Gc2_8lJxBkzS6HmrquouRfiqlMRaIqQ3iAdT0_B4TvHjPD4tZIftLLV0cZZt-FQYPu4Px_JwzSO3qmDCt_OD13GjKSIb38td9Do36mp1mW1sOPvQnJ5UZFpiYuGNWEzFsI0T/?imgmax=800" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="image" width="437" /></a></div>
<div align="center">
</div>
<div align="justify">
</div>
<div align="justify">
</div>
<div align="justify">
<br />
La ecuación 9 será la ecuación a implementar. <em>Kp </em>(Constante proporcional), <em>Ti </em>(Tiempo integrativo en seg) y <em>SP</em> (Set point)son enviados desde la interfaz gráfica en la PC. </div>
<div align="justify">
</div>
<div align="justify">
</div>
<div align="justify">
<br />
En la figura 13 se muestra la interrupción del timer 1. Esta interrupción ocurre cada 100ms, y es aquí donde se ejecuta nuestro algoritmo, por lo tanto <em>T=0.1seg.</em><br />
<em><br /></em></div>
<div align="justify">
</div>
<div align="justify">
</div>
<div align="justify">
</div>
<table border="0" cellpadding="2" cellspacing="0" style="width: 901px;"> <tbody>
<tr> <td valign="top" width="528"><div align="center">
<em>Figura 13.</em><br />
<a href="https://lh3.googleusercontent.com/-oS3IoZHATds/VtyhkGwVRPI/AAAAAAAAAPU/tft9A0Uhbco/s1600-h/image%25255B34%25255D.png"><img alt="image" border="0" height="610" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh5Dwf1Qf7wxbPuskNz7_xFRvAJgfWKJAS7JaNZ6AMP9xBzKcHF-WDN9TbYbKJrgHamvxGSlLK4W0hRvy1b7LpUuCN9AkudhLZMPS62v67GSZLKJCl6uReo8dtwbknNL49wEbxhNcefvZ42/?imgmax=800" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: inline; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="image" width="522" /></a></div>
<div align="center">
</div>
</td> <td valign="top" width="371"><div align="justify">
</div>
<div align="justify">
</div>
<div align="justify">
</div>
<div align="justify">
</div>
<div align="justify">
<span style="font-size: xx-small;"><span style="font-size: xx-small;"><span style="font-size: small;"><span style="font-family: "courier new";"><br /></span></span></span></span>
<span style="font-size: xx-small;"><span style="font-size: xx-small;"><span style="font-size: small;"><span style="font-family: "courier new";"><br /></span></span></span></span>
<span style="font-size: xx-small;"><span style="font-size: xx-small;"><span style="font-size: small;"><span style="font-family: "courier new";">* sum</span> </span><span style="font-size: small;">almacena de suma de los bytes antes de enviarlos al PC.</span></span></span></div>
<div align="justify">
<span style="font-size: small;"></span></div>
<div align="justify">
<span style="font-size: xx-small;"><span style="font-size: xx-small;"><span style="font-size: small;"><span style="font-family: "courier new";">* Kp</span> y <span style="font-family: "courier new";">Ti</span> son los valores reales de estos parámetros, ya que desde la PC vienen multiplicados por 100. En las lineas 87 y 88 son calculados.</span></span></span></div>
<div align="justify">
<span style="font-size: small;"></span></div>
<div align="justify">
<span style="font-size: xx-small;"><span style="font-size: small;">* <span style="font-family: "courier new";">85</span>.- se escala PV para que a la entrada del PI todo este en la escala de 0 a 100. En <span style="font-family: "courier new";">PV_MAX</span> es obtenido poniendo el <span style="font-family: "courier new";">OUT</span> al máximo en lazo abierto. Luego <span style="font-family: "courier new";">count</span> es llegado a 0 para iniciar una nueva cuenta.</span></span></div>
<div align="justify">
<span style="font-size: small;"></span></div>
<div align="justify">
<span style="font-size: xx-small;"><span style="font-size: small;">* <span style="font-family: "courier new";">90</span>.- se pregunta si estamos en modo automático para poder ejecutar el algoritmo.</span></span></div>
<div align="justify">
<span style="font-size: small;"></span></div>
<div align="justify">
<span style="font-size: xx-small;"><span style="font-size: xx-small;"><span style="font-size: small;">* <span style="font-family: "courier new";">92</span>.-Se calcula el error actual. El SP es una valor de 0 a 100. La multiplicación por 1.0 es para convertir de uint16_t a double.</span></span></span></div>
<div align="justify">
<span style="font-size: small;"></span></div>
<div align="justify">
<span style="font-size: xx-small;"><span style="font-size: xx-small;"><span style="font-size: small;">* <span style="font-family: "courier new";">93</span>.- Se calcula la salida <span style="font-family: "courier new";">u[0]</span> del controlador. El 0.1 es el tiempo de muestreo T=0.1seg.</span></span></span></div>
<div align="justify">
<span style="font-size: small;"></span></div>
<div align="justify">
<span style="font-size: xx-small;"><span style="font-size: xx-small;"><span style="font-size: small;">* <span style="font-family: "courier new";">95-98.-</span> Se guardan los valores de error y de la salida del <span style="font-family: "courier new";">PI</span>, y también se limita la salida del <span style="font-family: "courier new";">PI</span> al <span style="font-family: "courier new";">OUT_MAX</span> que en este caso es 100.</span></span></span></div>
<div align="justify">
<span style="font-size: small;"></span></div>
<div align="justify">
<span style="font-size: xx-small;"><span style="font-size: xx-small;"><span style="font-size: small;">* <span style="font-family: "courier new";">99</span>.- <span style="font-family: "courier new";">dt.OUT</span> es el valor que será enviado a la PC.</span></span></span></div>
<div align="justify">
<span style="font-size: small;"></span></div>
<div align="justify">
<span style="font-size: xx-small;"><span style="font-size: xx-small;"><span style="font-size: small;">* <span style="font-family: "courier new";">100</span>.- Se escala la salida <span style="font-family: "courier new";">u[0],</span> que esta de 0 a 100, a un valor adecuado. En nuestro caso, el PWM generado por <span style="font-family: "courier new";">OCR2=[0 hasta 120]</span> no genera movimiento en el motor. Este valor no debe paso 255 ya que <span style="font-family: "courier new";">OCR2</span> es un registro de 8 bits.</span></span></span></div>
<div align="justify">
<span style="font-size: small;"></span></div>
<div align="justify">
<span style="font-size: xx-small;"><span style="font-size: xx-small;"><span style="font-size: small;">* 104.- Se hace el mismo escalamiento, pero usando el valor enviado desde la PC en modo manual.</span></span></span></div>
<div align="justify">
<span style="font-size: small;"></span></div>
<div align="justify">
<span style="font-size: xx-small;"><span style="font-size: xx-small;"><span style="font-size: small;">* <span style="font-family: "courier new";">107-113</span>.- Finalmente, se envían los datos con su chequeo de integridad, hacia el PC para ser graficados.</span></span></span></div>
</td></tr>
</tbody></table>
<div align="center">
</div>
<div align="justify">
</div>
<div align="center">
</div>
<div align="center">
</div>
<div align="left">
</div>
<div align="left">
</div>
<div align="left">
</div>
<div align="left">
<br />
El software, en la PC, permite cambiar el <span style="font-family: "courier new";">SP, Kp, Ti, y OUT </span><span style="font-family: "arial";">mediante los slide de la figura 14.</span><br />
<span style="font-family: "arial";"><br /></span></div>
<div align="left">
</div>
<div align="center">
<em>Figura 14.</em></div>
<div align="left">
<a href="https://lh3.googleusercontent.com/-65GgsypN40o/VtyoFta7MuI/AAAAAAAAAPs/qDnZS0paBaE/s1600-h/image%25255B43%25255D.png"><img alt="image" border="0" height="460" src="https://lh3.googleusercontent.com/-bMMABdv1hTw/VtyoGMJ1t-I/AAAAAAAAAPw/9sh2m2ec0xs/image_thumb%25255B38%25255D.png?imgmax=800" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="image" width="275" /></a></div>
<div align="left">
</div>
<div align="left">
</div>
<div align="left">
<br />
El programa también permite seleccionar entre automático y manual.</div>
<div align="left">
</div>
<div align="center">
<em><br /></em><em>Figura 15.</em></div>
<div align="left">
<a href="https://lh3.googleusercontent.com/-wh6pRkAIQlU/VtyoG19vliI/AAAAAAAAAP0/CbWrkYCZT1E/s1600-h/image%25255B48%25255D.png"><img alt="image" border="0" height="457" src="https://lh3.googleusercontent.com/-9dimqSxUhQg/VtyoHXLGbtI/AAAAAAAAAP4/WY2IdX0w41w/image_thumb%25255B41%25255D.png?imgmax=800" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="image" width="775" /></a></div>
<div align="left">
</div>
<div align="left">
</div>
<div align="left">
</div>
<div align="left">
<br />
<br />
<b><i><u><span style="font-size: large;">Descargas:</span></u></i></b></div>
<div align="left">
<a href="http://adf.ly/12709021/pid-as7"><span style="font-size: x-small;"><span style="color: lime; font-size: large;">PROGRAMA ATMEL STUDIO 7</span></span></a></div>
<div align="left">
<a href="http://adf.ly/12709021/pid-exe-vs2010"><span style="font-size: x-small;"><span style="color: lime; font-size: large;">Ejecutable Programa PC</span></span></a></div>
<div align="left">
<a href="http://adf.ly/12709021/pid-project-vs2010"><span style="font-size: x-small;"><span style="color: lime; font-size: large;">Projecto visual studio 2010</span></span></a></div>
<div align="center">
</div>
<div align="center">
</div>
<div align="center">
</div>
<div align="center">
<br />
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<iframe allowfullscreen="" class="YOUTUBE-iframe-video" data-thumbnail-src="https://i.ytimg.com/vi/M2ih1RnYLjk/0.jpg" frameborder="0" height="266" src="https://www.youtube.com/embed/M2ih1RnYLjk?feature=player_embedded" width="320"></iframe></div>
<br /></div>
Anonymoushttp://www.blogger.com/profile/14023938257857442019noreply@blogger.com1tag:blogger.com,1999:blog-7123434971804829465.post-69396965663247989372016-03-01T23:29:00.000-08:002016-03-14T13:16:42.337-07:00App Inventor + Led ATmega<br />
Aquí les dejo un vídeo de cómo hacer una aplicación en el app inventor.<br />
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<iframe allowfullscreen="" class="YOUTUBE-iframe-video" data-thumbnail-src="https://i.ytimg.com/vi/jh25Y9R3dFU/0.jpg" frameborder="0" height="266" src="https://www.youtube.com/embed/jh25Y9R3dFU?feature=player_embedded" width="320"></iframe></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: justify;">
Los programas los pueden descargar aquí:</div>
<div class="separator" style="clear: both; text-align: justify;">
<a href="http://adf.ly/1Xg00i" target="_blank"><b><span style="color: lime; font-size: large;">APK para el celular</span></b></a></div>
<div class="separator" style="clear: both; text-align: justify;">
<a href="http://adf.ly/1XfzzE" target="_blank"><b><span style="color: lime; font-size: large;">Programa, puede ser editado desde el app inventor</span></b></a></div>
<div class="separator" style="clear: both; text-align: justify;">
<a href="http://adf.ly/1Xfzwz"><span style="font-size: medium;"><strong>Programa ATmea32-AS7</strong></span></a></div>
<div class="separator" style="clear: both; text-align: justify;">
<span style="color: yellow;"><br /></span></div>
<br />
<br />
Se usó un modulo HC-06, ATmega32 y un programado USBasp.<br />
<br />
<div align="center">
<a href="https://lh3.googleusercontent.com/-5zy7KiknWeA/VtaTkCZhq1I/AAAAAAAAAGw/2dOOmkMmc5E/s1600-h/image%25255B11%25255D.png"><img alt="image" border="0" height="208" src="https://lh3.googleusercontent.com/-k7XzNze84wg/VtaTlZ3ZxmI/AAAAAAAAAG0/sJqisNWfpEg/image_thumb%25255B5%25255D.png?imgmax=800" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: inline; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="image" width="240" /></a></div>
<br />
<br />
El programa envía 3 comandos: CMD1, CMD2, y CMD3.<br />
<br />
El CMD1 y 2 son enviados con una orden, 0 ó 1, para apagar o encender un led. <br />
Se envía CMD10 y CMD11 para apagar y encender un led rojo. Para el led verde se envía CMD20 y CMD21. <br />
<div align="justify">
También se envía el CMD3 acompañado de un número, entre 0 y 255, para cambiar la intensidad de luz de un tercer led amarillo usando PWM.</div>
Los tres comando llevan al final un salto de linea (\n) como fin de trama.<br />
<br />
El programa final se ve como en la siguiente figura:<br />
<br />
<br />
<a href="https://lh3.googleusercontent.com/-r7-zT75-oso/VtaTl9GqviI/AAAAAAAAAG4/R3gRq-to9NU/s1600-h/Screenshot_2016-03-02-01-57-30%25255B3%25255D.png"><img alt="Screenshot_2016-03-02-01-57-30" border="0" height="484" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhh2w_5uIWt0PZcrPj2hW_GWBBpw3NJhyphenhyphenVpFvjNC4TCH0jVgSCOJAuwgGm7ekEXkwoOmyBnvTAXhT-QmDDBEz6X8eHvzcWkJ-4AVUrWdf2I8EDz4fbyccLPBGG6x5xgFu7nlSPmRuke3GXK/?imgmax=800" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="Screenshot_2016-03-02-01-57-30" width="292" /></a><br />
<br />
<br />
Breve explicación:<br />
<br />
<div align="justify">
Cada vez que se presione un botón BTNGreen, y si hay conexión con el modulo bluetooth, el programa enviara CMD20 ó CMD21 de acuerdo a la variable green_status. También se cambia el color y texto del botón.<br />
<br /></div>
<div align="justify">
</div>
<div align="justify">
</div>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjKeAdxLOU5hDnnCvAfPXR0V_N2_5m2vKnh4o3dV0bR97Yi9KCGlDw8QAbEN4qeVbofAkkXaF2eZ5mCIFmHoljj8HK8CdINdok68sOvGP5LJNA8btkwmLcm_ro_LRoPyUXqF4kEHuBMtVId/s1600-h/image%25255B4%25255D.png"><img alt="image" border="0" height="417" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiSsfjkuc-2-C9hZZskmEzYpO1SDvmJ1Ks7SQRAncIPYlfv7qZOn0XYcEvjem-IyS2idnHrK7VounWPfI_GZsVMXIyS-8gooBnVwYdFdMhZUwR5r452L22g7Zv-EhNiTRx9eapKAkMBrRG3/?imgmax=800" style="border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="image" width="564" /></a><br />
<br />
<br />
<a name='more'></a><br />
<br />
Las operaciones con el botón BTNRed son similares al botón anterior.<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhURMBBJm1YONIABA2Lq5UOQlATHL3PDR9GG7fPWrGRzJK_i5g4Py-SYw_gQI8pFd-a1o0Dcs460O8SPe1W2vdMO6bFvEdk5cko_h6rkCANEZZUgPg1gkmq4n8uQ47PZvKJNUtwrS4juKw4/s1600-h/image%25255B16%25255D.png"><img alt="image" border="0" height="419" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiAzRf9mxqfeEAI5Xc13Q4zoR-SVz5vpdR_8DfTubnMY4Nq0Ie-BZpu9LPweN__YAQthmm27KZI2A2VJ9XZ3BsdSYfIQzRSmbx6jjVuGHb6SAo5jkYaXMHX6NJfM49TNxrciBSgKsudYFyQ/?imgmax=800" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="image" width="524" /></a><br />
<br />
<br />
Cada vez que cambie el valor del slide, y si el dispositivo se encuentra conectado, se enviará el comando 3 (CMD3) con el respectivo valor indicado por el slide. También se muestra en valor del slide en un cuadro de texto<br />
<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg15gvqrYxH8mcqAYHUHYxAkNn3hGRj4cSSOq2wRbmpdE5kyZPKgM_eD2uVBF5NfgaC7klJGw8gXuJiqQ2z_OFyQUVOANMnSYmLGgv7iMQUyEWzAYJrLM9FmSJbxjsg4t6YOwIp5zbTDuhs/s1600-h/image%25255B22%25255D.png"><img alt="image" border="0" height="254" src="https://lh3.googleusercontent.com/-SW12WF0K2XU/VtaTpmwK8mI/AAAAAAAAAHU/L8oK_Wgm9Vk/image_thumb%25255B12%25255D.png?imgmax=800" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="image" width="471" /></a><br />
<br />
<div align="justify">
</div>
<div align="justify">
Cuando el botón para conectar se presione, se desconectará el dispositivo en caso se encuentre conectado ó se mostrará una lista (List) con los dispositivos vinculados (si el dispositivo no se encuentra vinculado hay que hacerlo previamente) para poder realizar la conexión.</div>
<div align="justify">
</div>
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhHmw_zzjJjEIJZtWN-Jid6QnAOkPxdhWeUVYBliVjx_laZZBGFGx6S2S6KGsongpT1F_xdLMrKzOof8kvm5hSboklO7wClCmD0vSXV8f7Eg8wc2ZLgflaT7u9mjhuKsFf2hOdSxInpt5c3/s1600-h/image%25255B27%25255D.png"><img alt="image" border="0" height="183" src="https://lh3.googleusercontent.com/-x_KO2gvm_BM/VtaTqk8g2VI/AAAAAAAAAHc/TTATzQkuAA4/image_thumb%25255B15%25255D.png?imgmax=800" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="image" width="534" /></a><br />
<br />
<div align="justify">
</div>
<div align="justify">
Antes de mostrar la lista, y solamente cuando el bluetooth de nuestro teléfono esté activado, esta se llenará con los dispositivos vinculados al teléfono.</div>
<div align="justify">
</div>
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgelXjBGT70ZQeCgaq4G1li7QxE5EqXlRLhkNUM25B-8GsKkk0Q4JFlaHj3kT2edN_jmIqCGbwm-JG3Gpu_UQNsrO5Y_h3WDXgy-sn1bsmi_b4apwM0cFtpCAETqI1SP-Tzes_5jSXgGRHY/s1600-h/image%25255B37%25255D.png"><img alt="image" border="0" height="246" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjd_8umu3uyWe7ibwTYJRkEm-Vv4yzhbgibcDkSHBDENTM-Xsbv5EcO-azX98r7R3Cq_vo_tnonaB9F4ziFbOXk0Jy4HnL7oK7EC19mxUiwr2mOI_gz79Imxf1YtO7IeZes7gEriXGGVWyz/?imgmax=800" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="image" width="542" /></a><br />
<br />
Finalmente, después de seleccionar un dispositivo el programa intentará realizar la conexión con el HC-06.<br />
<br />
<div align="center">
<a href="https://lh3.googleusercontent.com/-vG6avKmH2Tk/VtaTr-9y5qI/AAAAAAAAAHo/FAE414EsG_I/s1600-h/image%25255B36%25255D.png"><img alt="image" border="0" height="238" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgQlVpJhBScPU0xRKGrjxGD5hK18T0UBTOTkkYlR88p_UcSFNrFlMXgJpSwqISF7Q-6KKpzZlNTIymWkXmvZRdjWe0IeYBvjmiYQ8G8TFjotCIAMr-NB7l8ZknY_Fj2CWbikh6GegBzjXzb/?imgmax=800" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: inline; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="image" width="578" /></a></div>
<br />
<br />
<br />
Programa completo:<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg0YYVs1kYngQxaUfXpIB3Ro9RbwhFCnLTSAJvhXFyuxGy3y4dNszeS2boRBJoDP3buUiYwt6uAyC7gzSO0GBTPNveHhIZwgodpnnII4zvlbyMkm5uyD6ID2VGGxBDelO_yrcYEe3GO0GaX/s1600-h/led%25255B3%25255D.png"><img alt="led" border="0" height="484" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjS3TrXvtgzeByM6HADxOZQOifGzvjcEYyGWvr7qD5KF9RztxY5Pc76IsB0P7fCW3kNeU6xH1POcxHjuIJtb7avXVr3_9xEHjxkScrmMMbee1mPpY_GFS3T8C56j-UkWLmGFWNnWubePJL1/?imgmax=800" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="led" width="552" /></a>Anonymoushttp://www.blogger.com/profile/14023938257857442019noreply@blogger.com0tag:blogger.com,1999:blog-7123434971804829465.post-90659301718398694282016-02-24T17:41:00.000-08:002016-03-11T14:28:05.527-08:00Encoder + ATmega32<div>
<br /></div>
<div align="justify">
En este post desarrollaré un programa para leer las entradas de un tipo encoder incremental en cuadratura.<br />
<br /></div>
<div align="justify">
</div>
<div align="justify">
La señal en cuadratura se caracteriza por tener dos señales cuadradas que se encuentras desfasadas 90° una con respecto a la otra. Esto es mostrado en la figura “<strong><em><u>Señales del encoder</u></em></strong>”. </div>
<div align="justify">
</div>
<div align="justify">
El movimiento rotacional puede ser medido contando los flancos que produce cada una de las señales. La relación de fase entre las dos señales determina la dirección de rotación. Cuando en giro es horario la señal QDPH0 (Comúnmente encontrada como A) adelanta a QDPH90 (B) en 90°. En el sentido antihorario ocurre exactamente lo contrario.</div>
<div>
<br /></div>
<div align="center">
<strong><em><u>Fig. 1 Señales del encoder</u></em></strong></div>
<div align="center">
<strong><em><u><br /></u></em></strong></div>
<a href="https://lh3.googleusercontent.com/-FvFVWNFkxrI/Vs5XcHu4FoI/AAAAAAAAAEY/G2AUMPmzuj0/s1600-h/Sin%252520t%2525C3%2525ADtulo%25255B4%25255D.png"><img alt="Sin título" border="0" height="336" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjahd1B5vmt6OD8B8sWiKyVnU4XswGpbc9-BTracAiEwR5ZmyxGesiUmdybV9jeojsnLDdfNUSoKX13wBBa_e3khYtoY44Xwf7Dp38LaAHFNJx-MkJJSsgAcWEgkuBu0T6xjsPaA1j2liKX/?imgmax=800" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="Sin título" width="664" /></a><br />
<br />
<div align="justify">
</div>
<div align="justify">
Para nuestro ejemplo conectaremos las salidas CLK(A) y DT(B) de un encoder, como el mostrado en Fig.2, a las entradas PD2(INT0) y PD3(INT1) de un ATmega32. El encoder y el uC son alimentado con 5Volt.</div>
<div>
<br /></div>
<div align="center">
<em><u><strong>Fig. 2 Encoder</strong></u></em></div>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgS-4RnvqQ47m52ARSuoEA9Ud65NjNaPTP-f_tDNucAziuvqQZzQj7-3CqGnjHfH3WW37nNaNdd1kFtDgKyb3h0I7x7JuVDgb84Bq-YS7-r32UGJq2olYS8EfJZJWnxu2jbHJtu4pHyI8nf/s1600-h/encoder-module-ky-040-1%25255B3%25255D.jpg"><img alt="encoder-module-ky-040-1" border="0" height="225" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEif7oP-ISZd8XaZzZtH_3i8JJVfDo95ASnUv23lJb_9ZhRm8jUn9FRtJI_goXSwpfalsgF3Hi6007aih91pI2eZWwxangnJUq4JtUkDWHiOBX-vuW4PS797Gqr0Yg-qR92q1blxJVFy-Cpz/?imgmax=800" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="encoder-module-ky-040-1" width="225" /></a><br />
<br />
<div align="justify">
El ejemplo es muy sencillo y puede funcionar con una lectura constante (en while) de las señales A y B, usando una interrupción para la señal A ó usando dos interrupciones para las señales A y B.</div>
<div>
<br /></div>
<div align="justify">
Primero, y luego de crear el proyecto, debemos declarar la velocidad del CPU (F_CPU es necesaria para las rutinas _delay…) y la del UART si fuera necesario. Aquí muestro una imagen de mi configuración.</div>
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiByDTYt5KLtLCsyiKLKc_AE74EEsJ76-YBlEdD676mqM422GjT2ox0uWuyTSmOGKequc2v92NYlFTWW4tuj5Tjf2F8aPZk_GqJbM4Jw-Ehl6IrF0s1GWgs3i24MDanxgWQtbzGTPCygYz0/s1600-h/image%25255B9%25255D.png"><img alt="image" border="0" height="122" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgCx9FDGezUnrqxGSzoA6jpk72yOVmCV6Zuz0lMk17L4O38Pv3vsNaY3VhTUrDO3l03EMSyGCVEeY_9wX43yKh4tn0sQnouT91NXqxAeL2-qMHxmUkfh8KthKmbDrCiJsO-f9c12O8CEK0i/?imgmax=800" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="image" width="411" /></a><br />
<br />
<br />
Bueno, aquí el programa.<br />
<br />
Includes:<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg82eB0LPNUShvc-MzK9LeaJqNfEGlnMBYCDJk0LbNYZ3blsGxfwCmdnz-ivh8b3dOLWhEeIiHE8CLoUCjayJ0Eo3qtUG_ek1FBVh_xML2RapnfXVJ53Vm9tQeludUYzpuZnz7-z-Awo1lE/s1600-h/image%25255B18%25255D.png"><img alt="image" border="0" height="87" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh0XgJvSLGmrivRR1rr_85Cd0uYCdTuPshrMylsV05IHawHGXaECn4Oupaeb1IHW3ifaI6WJphQ8362fqIEP4_SP3GYaFpV9YMLTJESM2w-fiojYB_skUujWaihfc5H_eln-OyRHOb62B1M/?imgmax=800" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="image" width="268" /></a><br />
<br />
Variables a usar:<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj7earyqCC42p7yHYPtHFjz5ZbUg1pELs6T6u7V_BhJJhvwb_XT6ze70jTOTOhgSzLbNak_3U8bzFAZLwokOkDVQh-x1xjwPnm6HKFVYYCThQnu7-c95CpXNZa7lMEMiBiusyvgRW3fufIc/s1600-h/image%25255B13%25255D.png"><img alt="image" border="0" height="239" src="https://lh3.googleusercontent.com/-oLLGBR4yI48/Vs5XjBG0yNI/AAAAAAAAAE8/fiwHoV-bUC8/image_thumb%25255B6%25255D.png?imgmax=800" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="image" width="309" /></a><br />
<br />
14.- Se declara una variable global del tipo <em>int32_t (cuenta)</em> para que almacene las cuentas del encoder. Esta tiene que ser del tipo <em>volatile</em> para poder usarla sin problemas en las interrupciones.<br />
15.- <em>cambio</em> las usaremos como un flag que nos indica que en valor de <em>cuenta</em> ha cambiado.<br />
<div style="text-align: justify;">
16.- str[30] almacenara un string que será enviado por el puesto serie.</div>
18-26.- Se crea una nuevo tipo de dato(<em>States_t</em>) para almacenar el estado actual del encoder (S0) y el estado anterior (S1). <br />
27.- Se crea la variable <em>enc</em> que es del tipo <em>States_t.</em><br />
<br />
<a name='more'></a><br />
<br />
<br />
<a href="https://lh3.googleusercontent.com/-_FuNioZ8u6I/Vs5Xjn9u_HI/AAAAAAAAAFA/NKn6n72zKBA/s1600-h/image%25255B23%25255D.png"><img alt="image" border="0" height="171" src="https://lh3.googleusercontent.com/-q_N4YWmHtm4/Vs5XlGbGm3I/AAAAAAAAAFE/ZQY0bZxoMqA/image_thumb%25255B12%25255D.png?imgmax=800" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="image" width="587" /></a><br />
<br />
35-38.- Se configura el UART del ATmega32.<br />
40.- Se activa las resistencias pull-up de las entradas usadas para leer el encoder.<br />
41.- Se configura la detección de cambio de estado en las interrupciones external INT0 e INT1.<br />
42.- Se activa las interrupciones INT0 e INT1.<br />
<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjE3NEfpu6FiwdqGzUh4SWehK1c_Knz2K7nKDcy3cXiKEUtJ5zcyxY6X9zKZ3hw5fHhQua8B_Ptn4S7hWNSGPIKkrB1-kXs0ovNoVZjACkGQL2xd3HLF4G6CaCWGEnZ_45rs8-2W6wMSIvl/s1600-h/image%25255B29%25255D.png"><img alt="image" border="0" height="185" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjUxjetfa7BFGqM0mCsjt8pAmXMMLA-kXRlA0BiAL-Y1B-p3IJXYgZvw72N75PyQruQWcP2DIAvm-jBFqG4A7wO5iKAz3h7TYp_IWGPtm-Txg2-6u8ufRb4RmOP-Ci0wAodgrxTk2zq-ZVB/?imgmax=800" style="border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="image" width="451" /></a><br />
<br />
44-54.- Se activa las interrupciones globales y se espera en un cambio de los estados para enviar un mensaje por el UART.<br />
<br />
Aquí la función para enviar los datos por el puerto serie:<br />
<br />
<a href="https://lh3.googleusercontent.com/-QhrMpojuILc/Vs5XnkWItYI/AAAAAAAAAFQ/wI6MTRNoxlg/s1600-h/image%25255B41%25255D.png"><img alt="image" border="0" height="139" src="https://lh3.googleusercontent.com/-ksEpm7QyeCo/Vs5XoXzJhOI/AAAAAAAAAFU/sZPmdMEEQtA/image_thumb%25255B24%25255D.png?imgmax=800" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="image" width="301" /></a><br />
<br />
En la siguiente imagen se muestran las interrupciones:<br />
<br />
<a href="https://lh3.googleusercontent.com/-6g1TIMuXG7o/Vs5XpDpAlPI/AAAAAAAAAFY/RKHNmJUy35I/s1600-h/image%25255B75%25255D.png"><img alt="image" border="0" height="24" src="https://lh3.googleusercontent.com/--tFuBDXuPLY/Vs5Xp0yqw6I/AAAAAAAAAFc/eckDwibG07U/image_thumb%25255B46%25255D.png?imgmax=800" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="image" width="352" /></a><br />
<br />
<div align="justify">
81.- Es la interrupción INT1, y no vemos código ya que el atributo <em>ISR_ALIASOF </em>le dice al compilador que en el vector de interrupción correspondiente a INT1 ponga un salto a INT0.</div>
Esto lo podemos verificar viendo el manual y el programa desensamblado.<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjr0Jb1tBLx954CkemrcYY_cSu0RG7vU94RmxESlyhA5rOfHrDW51fb2R4La-gY0LFX_TUObU3JOMCs8WjUKrfYTFynsAQeFIwgcv-KrDUvBasJSJk3J8O6iNx3Xpkx8PNH_07N-1-zjOCD/s1600-h/image%25255B60%25255D.png"><img alt="image" border="0" height="61" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgHd2xodhLOKSlBdUUI1QemtB9qTPcl1HygN7vzMQfI1yOhza2KR1yUGVdYn7A4GrbuHqIg074sfbSgA2mS_QG1kJsNlkCxXbygSZ7kjrYhphJCWmzOS1EkH0EVp-XIdiZ78EnVYGNGnQOR/?imgmax=800" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="image" width="400" /></a><br />
<br />
<a href="https://lh3.googleusercontent.com/-MMH2mfmWjlQ/Vs5Xrv9GnTI/AAAAAAAAAFo/G3Fcg4Vsy-g/s1600-h/image%25255B65%25255D.png"><img alt="image" border="0" height="99" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiaywKFHCkwygjYuPu30oZ0OIGnrPUQNceuc060ec8Qj0oNWyVi9joNlSEnrjLiNhS6MbbUw5lgKRNPBuo9NRFILEKYhOODa9M1QuayTEhNlSblX-dRqKagAbZdtf4YjQNWZyil7Lm5vpi7/?imgmax=800" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="image" width="324" /></a><br />
<br />
<div align="justify">
Vemos que el manual nos indica que INT0 esta asociada a la dirección 0x002 y INT1 a 0x004. En la segunda imagen vemos que el compilador generó un JMP a la dirección 0x00000049 en los dos casos. Es decir, que cuando se generen INT0 ó INT1, el programa ejecutará la misma rutina.<br />
<br /></div>
<div align="justify">
</div>
<div align="justify">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhhKYXXet1enmDBh9knHMx32ms9BHOKr_XdFx-24NtTGLysBMW-fXVb-W0Uw1tMqE4rbPZEKgKavE_gnI4JeInWE30hbSJcaZqEva-CLEGnFauW1srnB5iEcEonFe2ICq2s5fy8qRP0pd5M/s1600-h/image%25255B84%25255D.png"><img alt="image" border="0" height="288" src="https://lh3.googleusercontent.com/-oVle87Q0uoM/Vs5XtoKctxI/AAAAAAAAAF0/EnRcS0RdECQ/image_thumb%25255B50%25255D.png?imgmax=800" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="image" width="627" /></a></div>
<br />
<br />
En INT0 primero pondremos un retardo para evitar algún rebote.<br />
85.- Salvamos el estado anterior(<em>enc.s1</em>) antes de obtener el nuevo estado de las señales A y B.<br />
86.- Leemos las entradas A y B. También los desplazamos para usar los 2 bits menos significativos. Si los pines usados hubieran sido PIN5 y PIN6 el corrimiento hubiera sido así: >>5.<br />
Gracias a que la variable <em>enc </em>es una unión(como se muestra en figura inferior) podemos usar <em>enc.s </em>para hacer comparaciones del estado actual y el anterior en una sola variable.<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiZykQ9iHj0j08pQMuLMqITv6_u3fpkfABT_f2aPnGEknXeK3U8lCkD_c2oCpulGKG8GImm2etJiMDvURWHxHRqMN_uhVhJH-KX7riuYdLZ1fgti2Mj_sICrfVWK-xKLbp0JkXLGtdsLn7E/s1600-h/image%25255B89%25255D.png"><img alt="image" border="0" height="62" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhH3DHnkSTQ_-ITlbk7cj56RIvyzobHSR0iLMbBWHGYlLQDrsEwgUba0_PCFdFNYudtEBvjX3H2iP1r33YmIHB7YUIp-fY9LaDDtEE3BVKDNylwVDrNGC9PNTtLfuveQ38VRRr-cU7Lbe1_/?imgmax=800" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="image" width="261" /></a><br />
<br />
<div align="justify">
Si consideramos la <strong><em><u>Fig. 1 Señales del encoder,</u></em></strong> podemos conocer los estados pasados y actuales para cada sentido de giro, es decir que en sentido horario tendremos <em>enc.s0 = 0, 2, 3, 1</em> como posibles estados actuales y <em>enc.s1 = 2, 3, 1, 0</em> como posibles estados anteriores. Si los combinamos tendremos <em>enc.s = 0x02, 0x23, 0x31 y 0x10.</em></div>
<div align="justify">
Algo similar ocurre en el sentido antihorario. Tendremos <em>enc.s0 = 1, 3, 2, 0</em> como posibles estados actuales y <em>enc.s1 = 3</em><em>, 2, 0, 1</em> como posibles estados anteriores. Si los combinamos tendremos <em>enc.s = 0x13, 0x32, 0x20 y 0x01.</em></div>
<div align="justify">
</div>
<div align="justify">
Así que comparando solamente <em>enc.s ,</em>que contiene tanto el estado actual como el anterior, podremos conocer la dirección del giro. </div>
<div align="justify">
De esta manera se consigue tener la más alta resolución del encoder, ya que se evalúan todos sus estados posibles.<br />
<br /></div>
<div align="justify">
</div>
<div align="justify">
</div>
<div align="justify">
Esta es la salida que se debe visualizar:<br />
<br /></div>
<div align="justify">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj6kyf85Z9biDi9H6i6mLG1tkJil_2KkV_vQJrSMFoxJtL4xNQc1U2L41GnSkyXJJtWhv9GTFKzIC75Y8_FxZ2X2bGZeXV8e-afmsjV9okqBE6uFs4lOYk-Nx-XrtcrMietHSJkC-YRvgbz/s1600-h/image%25255B4%25255D.png"><img alt="image" border="0" height="239" src="https://lh3.googleusercontent.com/-49xwlg-oEQU/Vs5eDBU5XgI/AAAAAAAAAGc/bVgU229E6k0/image_thumb%25255B2%25255D.png?imgmax=800" style="background-image: none; border-bottom: 0px; border-left: 0px; border-right: 0px; border-top: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="image" width="119" /></a></div>
<br />
<hr />
<br />
<br />
<div style="text-align: justify;">
Ahora bien, si sólo disponemos de un pin de interrupción externo, debemos hacer algunos cambios en los estados, ya que no se podrían evaluar todos, es decir que perderíamos la mitad de los estados y con ello la resolución del encoder seria la mitad de la que obtuvimos usando INT0 e INT1.</div>
El cambio solamente seria el siguiente:<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgfqjv9Q4uO-ZzRzDaTF5ifnDdH2jAsiNzUF4YJf20zrR6eYB2GSxQfBpNteZmdk0cSm83yBpPENrryJM49sV6GYxkZAaOTKbbI9NH5FROpGRZTFq2WLQ4iQWxzCp9GPVVSFMy9Yw9DQDoV/s1600-h/image%25255B94%25255D.png"><img alt="image" border="0" height="152" src="https://lh3.googleusercontent.com/-Je5eiySpkwU/Vs5XwbRLz3I/AAAAAAAAAGE/VNstyUf0p6g/image_thumb%25255B56%25255D.png?imgmax=800" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="image" width="284" /></a><br />
<div align="justify">
</div>
<div style="text-align: justify;">
Como se ve en la imagen, los estados se redujeron ya que, sólo tenemos un pin que nos genera interrupción.<br />
<br /></div>
<div style="text-align: justify;">
Este código puede ser fácilmente adaptado para que funcione en un bucle, pero la idea de usar interrupciones es quitarle carga a la CPU.<br />
<br /></div>
<div style="text-align: justify;">
</div>
<div style="text-align: justify;">
Bueno, espero que les sea de utilidad, aquí les dejo el enlace para la descarga del programa. <br />
<a href="http://adf.ly/12709021/encoder" target="_blank"><b><span style="color: lime; font-size: large;">Encoder_mega32</span></b></a></div>
Anonymoushttp://www.blogger.com/profile/14023938257857442019noreply@blogger.com2tag:blogger.com,1999:blog-7123434971804829465.post-44883050926641017932016-02-21T15:54:00.000-08:002016-03-11T14:32:28.804-08:00Excel, SerialPort y AVR<br />
<div style="text-align: justify;">
En este pequeño post les presento un video donde realizo la lectura del dos sensores (fototransistor y termistor tipo ntc) mediante el ADC de un XMEGA. Los datos leidos por el ADC son enviados mediante el puerto serie y al ser recibidos son graficados en excel.</div>
<br />
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<iframe allowfullscreen="" class="YOUTUBE-iframe-video" data-thumbnail-src="https://i.ytimg.com/vi/CEkfKLS2Vjg/0.jpg" frameborder="0" height="266" src="https://www.youtube.com/embed/CEkfKLS2Vjg?feature=player_embedded" width="320"></iframe></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: justify;">
Tener en cuenta que las modificaciones para recibir cantidades diferentes de bytes deben ser hechas en esta parte del código. Esto dependerá del número de bytes que se desean recibir (... > 4) .</div>
<div class="separator" style="clear: both; text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgZLvp7DzG1Rs8YY1R3ucj6eSmSnt7bBjIJ3XoafWlUSwsH7BH9A_lJIbeLrve0o6eDS6iDM1OKqMz-dHhaCDJUUlTODPBdqdByNkybGjYGFt3QDbQGwIi0OTqiy2Hc1rykzrEPn5LDr-3h/s1600/Sin+t%25C3%25ADtulo.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgZLvp7DzG1Rs8YY1R3ucj6eSmSnt7bBjIJ3XoafWlUSwsH7BH9A_lJIbeLrve0o6eDS6iDM1OKqMz-dHhaCDJUUlTODPBdqdByNkybGjYGFt3QDbQGwIi0OTqiy2Hc1rykzrEPn5LDr-3h/s1600/Sin+t%25C3%25ADtulo.png" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: justify;">
<br /></div>
<br />
<br />
<a href="http://adf.ly/1XHveg"><span style="color: lime; font-size: large;">Descarga excel y ocx</span></a>Anonymoushttp://www.blogger.com/profile/14023938257857442019noreply@blogger.com0tag:blogger.com,1999:blog-7123434971804829465.post-22634209048722369112015-04-22T09:38:00.001-07:002016-04-12T21:01:49.221-07:00OBTENER DATOS DEL ADC Y TRANSMITIRLOS POR EL UART<div class="separator" style="clear: both; text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: justify;">
En este video muestro como configurar el el ADC y el UART, como obtener los datos de la conversión en sus diferentes canales y luego transmitirlos. También veremos como realizar la simulación en proteus. Todo esta escrito en C y se usa el Atmel Studio 6.2.</div>
<div class="separator" style="clear: both; text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<br /><iframe width="320" height="266" class="YOUTUBE-iframe-video" data-thumbnail-src="https://i.ytimg.com/vi/yLjv8TM5E2M/0.jpg" src="https://www.youtube.com/embed/yLjv8TM5E2M?feature=player_embedded" frameborder="0" allowfullscreen></iframe></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: justify;">
Espero este video sea de utilidad. </div>
<div class="separator" style="clear: both; text-align: justify;">
<a href="http://adf.ly/1X5nB5"><span style="color: lime;">Dercarga programa</span></a></div>
<div class="separator" style="clear: both; text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: justify;">
Saludos.</div>
<br />jrsfhttp://www.blogger.com/profile/04364143443693071318noreply@blogger.com0tag:blogger.com,1999:blog-7123434971804829465.post-22203695868599562202014-08-15T15:28:00.000-07:002016-03-07T22:56:31.523-08:00FAT + SD Card + ATmega128<br />
<br />
En este post mostraré como usar la librería FatFs ( Generic FAT File System Module) la cual podemos encontrar en el sitio web <span style="color: lime;"><b><a href="http://adf.ly/1X5oNw" target="_blank">FatFs</a>.</b></span><br />
Para este fin usaremos una tarjeta de prueba con ATmega128, un adaptador para microSD, un RTC DS3231 y una tarjeta microSD Samsung de 16GB clase 10.<br />
<br />
Aqui el programa final : <a href="http://adf.ly/1X5pMr"><span style="color: lime;"><b>Programa</b></span></a><br />
<br />
<a href="http://lh4.ggpht.com/-0YYaqv5nTNc/U-6GOAaR6YI/AAAAAAAAHWg/FexB3ZwI5Sc/s1600-h/STK12864__V20_Side_M%25255B5%25255D.jpg"><img align="left" alt="" border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhupbgP-rMtrVglMgy8bq7izUdtCTIM4thgDI2Z3N_JAguyQsj5Vh9Xa7Xz9F1wzfQUWbA-Lffquhd5fADi2Trj2Z8ZxaEnc736Lb1kx9D2aucxji356syjs4HsgaLqicKEKmsR6b5ijxY/?imgmax=800" height="203" style="background-image: none; border-width: 0px; display: inline; float: left; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="" width="217" /></a> <a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiMVwC45bIuJAlIQj_FMQBDgLtEzgITAdPHkRjGpMLZqxkszu0nWKXxhiilF8NP9eB3gE2Egop4ThZZ9hAqEVHYwbXWO7tuYmVUziEye58iTuU3oJbo_NisEUHOYtaUyKTPjseD6Kfd1o4/s1600-h/SKU146934b%25255B9%25255D.jpg"><img alt="SKU146934b" border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEigjZJZpXVGYlea3ll5eU90v7YULUKWXQnFEOFK3YtvdwIT7y4pUZC4SmvMJmZvz99kySo5rKSQOTFZd_z4LcAkeqFv1nNxqdyNbl22isiWKzDE4DWq_l5ODx7sC6RnjtiYzbBrHDI0kSQ/?imgmax=800" height="205" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: inline; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="SKU146934b" width="192" /></a> <a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgJFkPUd0jVK585NyJTgr5zlEvg12qpG59jfCA238Kd11-dQ1MgNmwSPVOa69aR78zRyyxl1M0WrFqvzmpUV12YHk_NrNiRZejTHCcVcw2M24z60uK3WWUwHVglSLNydMsO1Auw9XMJ3mw/s1600-h/images%25255B9%25255D.jpg"><img alt="images" border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhF_TKdxQBUzvG2N8YjRmO1Sh7CSozk2X9E0JkJGpdQ5gSDVHRdXRRz5Yec3MHzoc4QrzC2s__iMHo4Eox2fYOccCFokBi_4LDpR5ufKU-Ccn3ECg_yhwCNDYc2rv7q0rMI5yjTPHGqc5k/?imgmax=800" height="205" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: inline; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="images" width="191" /></a><br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgjNN8rBfaToqu8srVXlMJdisNcREviZp3VOjEjPBodg4lBxVJ6375JdE4vfbqdYC5qFbmsqc6L33G71qxicMCn0tO4VNCayV3grPizf3VyD63krlZKKRmCDRtssQcFtpp9vgOmbYSBCm4/s1600-h/samsungcards-m%25255B12%25255D.jpg"><img alt="samsungcards-m" border="0" src="http://lh4.ggpht.com/-YJlfvOjCfqQ/U-6GWTigLwI/AAAAAAAAHXY/X-nsiLLqEMg/samsungcards-m_thumb%25255B4%25255D.jpg?imgmax=800" height="139" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="samsungcards-m" width="185" /></a><br />
<br />
<br />
El ATmega128 corre con un cristal de 7.3728MHz.<br />
<div style="text-align: justify;">
El RTC es para obtener la fecha y hora al momento de crear y modificar los archivos creados. </div>
El adaptador de microSD se comunica mediante SPI, tiene 6 señales (CS, MISO,MOSI,SCK,VCC y GND).<br />
La tarjeta fue previamente formateada con FAT32.<br />
En las pruebas se obtuvo velocidades de escritura de 148KB/s (más de 1Mb/s).<br />
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgSB-MGg4rf7LofjxbGsGccNBpkI929dE_6TZSNwYeskO8p_GuzwLT0UEzdeWDvJJF3Wd4HupRgPA5K3N9t5KdQGNJZQfNsqDyz1werLBNaVB4bjNyaXNNhD_roz5dahHl9d2D4iYAzc_I/s1600/20140815_191022.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="480" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgSB-MGg4rf7LofjxbGsGccNBpkI929dE_6TZSNwYeskO8p_GuzwLT0UEzdeWDvJJF3Wd4HupRgPA5K3N9t5KdQGNJZQfNsqDyz1werLBNaVB4bjNyaXNNhD_roz5dahHl9d2D4iYAzc_I/s1600/20140815_191022.jpg" width="640" /></a></div>
<div style="text-align: center;">
<br /></div>
<br />
<a name='more'></a><br /><br />
Los archivos de ejemplo, para varias marcas de microcontroladores, se pueden descargar en este link <a href="http://adf.ly/1X5oWT" target="_blank"><span style="color: lime;">SAMPLES</span></a>, y es en base a la carpeta <em>avr_complex </em>que se desarrolló este post.<br />
Primero escribiremos las rutinas I2C para el RTC DS3231. <br />
Aquí se presentan los archivos i2c.h y i2c.c.<br />
<br />
<br />
<table border="1" cellpadding="2" cellspacing="0" style="width: 816px;"> <tbody>
<tr> <td valign="top" width="408"><span style="color: cyan; font-family: "courier new";">/*<br />* i2c.h<br />*<br />* Created: 04/08/2014 11:50:27 p.m.<br />* Author: Jonathan<br />*/ </span><br />
<span style="color: cyan; font-family: "courier new";">#ifndef I2C_H_<br />#define I2C_H_</span><br />
<span style="color: cyan; font-family: "courier new";"><br /></span>
<span style="color: cyan; font-family: "courier new";">#include <avr/io.h><br />#include <util/twi.h></span><br />
<span style="color: cyan; font-family: "courier new";"><br /></span>
<span style="color: cyan; font-family: "courier new";">#define F_SCL 100000UL</span><br />
<span style="color: cyan; font-family: "courier new";">#define TWBRX0 (((F_CPU/F_SCL)-16)/2)<br />#define TWBRX1 TWBRX0/4<br />#define TWBRX2 TWBRX0/16<br />#define TWBRX3 TWBRX0/64</span><br />
<br />
<span style="color: cyan; font-family: "courier new";">#if (TWBRX0<=0xFF)<br /> #define TWBRX TWBRX0<br /> #define TWPSX 0<br />#elif (TWBRX1<=0xFF)</span></td> <td valign="top" width="406"><span style="color: cyan; font-family: "courier new";">#define TWBRX TWBRX1<br /> #define TWPSX 1<br />#elif (TWBRX2<=0xFF)<br /> #define TWBRX TWBRX2<br /> #define TWPSX 2<br />#elif (TWBRX3<=0xFF)<br /> #define TWBRX TWBRX3<br /> #define TWPSX 3<br />#else<br /> #define TWBRX 0<br /> #define TWPSX 0 <br />#endif</span><br />
<span style="color: cyan; font-family: "courier new";">#define NACK 0<br />#define ACK 1</span><br />
<br />
<span style="color: cyan; font-family: "courier new";"> void I2C_Init(void); <br /> uint8_t I2C_Start(void);<br /> uint8_t I2C_ReStart(void);<br /> void I2C_Stop(void);<br /> uint8_t I2C_Write(uint8_t );<br /> uint8_t I2C_Read(uint8_t ); </span><br />
<span style="color: cyan; font-family: "courier new";">#endif /* I2C_H_ */</span></td></tr>
</tbody></table>
<br />
<table border="1" cellpadding="2" cellspacing="0" style="width: 833px;"> <tbody>
<tr> <td valign="top" width="411"><span style="color: cyan; font-family: "courier new";">/*<br />* i2c.c<br />*<br />* Created: 04/08/2014 11:52:16 p.m.<br />* Author: Jonathan<br />*/ </span><br />
<span style="color: cyan; font-family: "courier new";"><br /></span>
<span style="color: cyan; font-family: "courier new";">#include <stdio.h><br />#include "i2c.h"</span><br />
<span style="color: cyan; font-family: "courier new";"><br /></span>
<span style="color: cyan; font-family: "courier new";">void I2C_Init(void)<br />{<br /> TWBR = TWBRX;<br /> TWSR = TWPSX;<br /> TWAR = 0x00;<br /> TWCR = (1<<TWEN);<br /> DDRD &=~(1<<PIND0 | 1<<PIND1);<br /> PORTD |= 1<<PIND0 | 1<<PIND1;<br />}</span><br />
<span style="color: cyan; font-family: "courier new";"><br /></span>
<span style="color: cyan; font-family: "courier new";">uint8_t I2C_Start( void )<br />{<br /> TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN);<br /> <br /> while (!(TWCR & (1<<TWINT))){}<br /> <br /> if ((TWSR & 0xF8) != TW_START)<br /> return 0;<br /> <br /> return 1;<br />}</span><br />
<span style="color: cyan; font-family: "courier new";"><br /></span>
<span style="color: cyan; font-family: "courier new";">uint8_t I2C_ReStart( void )<br />{<br /> TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN);<br /> <br /> while (!(TWCR & (1<<TWINT)));</span></td> <td valign="top" width="420"><span style="color: cyan; font-family: "courier new";">if ((TWSR & 0xF8) != TW_REP_START)<br /> return 0;<br /> <br /> return 1;<br />}</span><br />
<span style="color: cyan; font-family: "courier new";"><br /></span>
<span style="color: cyan; font-family: "courier new";">void I2C_Stop( void )<br />{<br /> TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWSTO);<br /> <br /> while(TWCR & (1<<TWSTO));<br />}</span><br />
<span style="color: cyan; font-family: "courier new";"><br /></span>
<span style="color: cyan; font-family: "courier new";">uint8_t I2C_Write( uint8_t data)<br />{<br /> TWDR = data; <br /> <br /> TWCR = (1<<TWINT)|(1<<TWEN) ;<br /> <br /> while (!(TWCR & (1<<TWINT)));<br /> <br /> if ((TWSR & 0xF8) != TW_MT_SLA_ACK)<br /> return 0;<br /> <br /> return 1;<br />}</span><br />
<span style="color: cyan; font-family: "courier new";"><br /></span>
<span style="color: cyan; font-family: "courier new";">uint8_t I2C_Read( uint8_t ACK_NACK)<br />{<br /> while (!(TWCR & (1<<TWINT)));<br /> <br /> TWCR = (ACK_NACK)?((1<<TWINT)|(1<<TWEN)|<br /> (1<<TWEA)):((1<<TWINT)|(1<<TWEN));<br /> <br /> while (!(TWCR & (1<<TWINT))){}<br /> <br /> return TWDR;<br />}</span></td></tr>
</tbody></table>
<br />
<br />
<br />
Ahora los archivos DS3231.h y DS3231.c.<br />
<br />
<table border="1" cellpadding="2" cellspacing="0" style="width: 832px;"> <tbody>
<tr> <td valign="top" width="412"><span style="color: cyan; font-family: "courier new";">/*<br />* DS3231.h<br />* Created: 05/08/2014 12:03:19 a.m.<br />* Author: Jonathan<br />*/ </span><br />
<span style="color: cyan; font-family: "courier new";"><br /></span>
<span style="color: cyan; font-family: "courier new";">#ifndef DS3231_H_<br />#define DS3231_H_</span><br />
<span style="color: cyan; font-family: "courier new";"><br /></span>
<span style="color: cyan; font-family: "courier new";">#include "I2C.h"<br />#include "integer.h"</span><br />
<span style="color: cyan; font-family: "courier new";"><br /></span>
<span style="color: cyan; font-family: "courier new";">typedef struct {<br /> WORD year; /* 2000..2099 */<br /> BYTE month; /* 1..12 */<br /> BYTE mday; /* 1.. 31 */<br /> BYTE wday; /* 1..7 */<br /> BYTE hour; /* 0..23 */<br /> BYTE min; /* 0..59 */<br /> BYTE sec; /* 0..59 */<br />} RTC_t;</span><br />
<span style="color: cyan; font-family: "courier new";"><br /></span>
<span style="color: cyan; font-family: "courier new";">#define DS3231_SECONDS 0x00 <br />#define DS3231_MINUTES 0x01<br />#define DS3231_HOURS 0x02<br />#define DS3231_WEEKDAYS 0x03<br />#define DS3231_DAYS 0x04</span></td> <td valign="top" width="418"><span style="color: cyan; font-family: "courier new";">#define DS3231_MONTHS 0x05<br />#define DS3231_YEARS 0x06</span><br />
<span style="color: cyan; font-family: "courier new";"><br /></span>
<span style="color: cyan; font-family: "courier new";">#define MASK_SEC 0B01111111<br />#define MASK_MIN 0B01111111<br />#define MASK_HORA 0B00111111<br />#define MASK_DIA 0B00111111<br />#define MASK_MES 0B00011111<br />#define MASK_ANIO 0B11111111</span><br />
<span style="color: cyan; font-family: "courier new";"><br /></span>
<span style="color: cyan; font-family: "courier new";">#define DS3231_READ 0xD1<br />#define DS3231_WRITE 0xD0</span><br />
<span style="color: cyan; font-family: "courier new";"><br /></span>
<span style="color: cyan; font-family: "courier new";">#define BCD2BIN(val) (((val)&0x0F)+((val)>>4)*10)<br />#define BIN2BCD(val) ((((val)/10)<<4)+(val)%10)</span><br />
<span style="color: cyan; font-family: "courier new";"><br /></span>
<span style="color: cyan; font-family: "courier new";">void DS3231_Init();<br />void RTC_GetTime(RTC_t *);<br />void RTC_SetTime(RTC_t *); <br />void DS3231_SetHora (uint8_t *);<br />void DS3231_GetHora (uint8_t *);<br />void DS3231_SetFecha(uint8_t *);<br />void DS3231_GetFech(uint8_t ); <br />uint8_t DS3231_GetReg(uint8_t );<br />void DS3231_SetReg(uint8_t , uint8_t );</span><br />
<span style="color: cyan; font-family: "courier new";"><br /></span>
<span style="color: cyan; font-family: "courier new";">#endif /* DS3231_H_ */</span></td></tr>
</tbody></table>
<br />
<table border="1" cellpadding="2" cellspacing="0" style="width: 832px;"> <tbody>
<tr> <td valign="top" width="395"><span style="color: cyan; font-family: "courier new";">/*<br />* DS3231.c<br />*<br />* Created: 05/08/2014 12:16:47 a.m.<br />* Author: Jonathan<br />*/ </span><br />
<span style="color: cyan; font-family: "courier new";"><br />#include <util/delay.h><br />#include "DS3231.h"</span><br />
<br />
<span style="color: cyan; font-family: "courier new";">void DS3231_Init()<br />{<br /> I2C_Init(); <br />}</span><br />
<span style="color: cyan; font-family: "courier new";"><br /></span>
<span style="color: cyan; font-family: "courier new";">void DS3231_SetHora (uint8_t *data)<br />{<br /> I2C_Start();<br /> I2C_Write(DS3231_WRITE);<br /> I2C_Write(DS3231_SECONDS);<br /> I2C_Write(data[2]);<br /> I2C_Write(data[1]);<br /> I2C_Write(data[0]);<br /> I2C_Stop(); <br />}<br /> <br />void DS3231_GetHora (uint8_t *data)<br />{<br /> I2C_Start();<br /> I2C_Write(DS3231_WRITE);<br /> I2C_Write(DS3231_SECONDS);<br /> I2C_ReStart();<br /> I2C_Write(DS3231_READ);<br /> data[2] = (I2C_Read(ACK))& MASK_SEC;<br /> data[1] = (I2C_Read(ACK))& MASK_MIN;<br /> data[0] = (I2C_Read(NACK))& MASK_HORA;<br /> I2C_Stop();<br />}</span><br />
<span style="color: cyan; font-family: "courier new";"><br /></span>
<span style="color: cyan; font-family: "courier new";">void DS3231_SetFecha(uint8_t *data)<br />{<br /> I2C_Start();<br /> I2C_Write(DS3231_WRITE);<br /> I2C_Write(DS3231_DAYS);<br /> I2C_Write(data[0]);<br /> I2C_Write(data[1]);<br /> I2C_Write(data[2]);<br /> I2C_Stop();<br />}<br /> <br />void DS3231_GetFecha(uint8_t *data)<br />{<br /> I2C_Start();<br /> I2C_Write(DS3231_WRITE);<br /> I2C_Write(DS3231_DAYS);<br /> I2C_ReStart();<br /> I2C_Write(DS3231_READ);<br /> data[0] = (I2C_Read(ACK)) & MASK_DIA;</span></td> <td valign="top" width="435"><span style="color: cyan; font-family: "courier new";"> data[1] = (I2C_Read(ACK)) & MASK_MES;<br /> data[2] = (I2C_Read(NACK)) & MASK_ANIO;<br /> I2C_Stop();<br />}</span><br />
<span style="color: cyan; font-family: "courier new";"><br /></span>
<span style="color: cyan; font-family: "courier new";">uint8_t DS3231_GetReg(uint8_t address )<br />{<br /> uint8_t ret;<br /> I2C_Start();<br /> I2C_Write(DS3231_WRITE);<br /> I2C_Write(address);<br /> I2C_ReStart();<br /> I2C_Write(DS3231_READ);<br /> ret = I2C_Read(NACK);<br /> I2C_Stop(); <br /> return ret;<br />}</span><br />
<span style="color: cyan; font-family: "courier new";"><br /></span>
<span style="color: cyan; font-family: "courier new";">void DS3231_SetReg( uint8_t address, uint8_t val )<br />{<br /> I2C_Start();<br /> I2C_Write(DS3231_WRITE);<br /> I2C_Write(address);<br /> I2C_Write(val);<br /> I2C_Stop();<br /> _delay_ms(1);<br />}</span><br />
<span style="color: cyan; font-family: "courier new";"><br /></span>
<span style="color: cyan; font-family: "courier new";">void RTC_SetTime( RTC_t *rtc )<br />{<br /> I2C_Start();<br /> I2C_Write(DS3231_WRITE);<br /> I2C_Write(DS3231_SECONDS);<br /> I2C_Write(BIN2BCD(rtc->sec));<br /> I2C_Write(BIN2BCD(rtc->min));<br /> I2C_Write(BIN2BCD(rtc->hour));<br /> I2C_Write(BIN2BCD(rtc->wday));<br /> I2C_Write(BIN2BCD(rtc->mday));<br /> I2C_Write(BIN2BCD(rtc->month));<br /> I2C_Write(BIN2BCD(rtc->year));<br /> I2C_Stop();<br />}</span><br />
<span style="color: cyan; font-family: "courier new";"><br /></span>
<span style="color: cyan; font-family: "courier new";">void RTC_GetTime( RTC_t *rtc )<br />{<br /> uint8_t buf[7];<br /> <br /> DS3231_GetHora(&buf[0]);<br /> DS3231_GetFecha(&buf[4]);<br /> <br /> rtc->sec = (buf[2]&0x0F) + ((buf[2]>>4)&7)*10;<br /> rtc->min = (buf[1]&0x0F) + (buf[1]>>4)*10;<br /> rtc->hour = (buf[0]&0x0F) + ((buf[0]>>4)&3)*10;<br /> rtc->wday = (buf[3]&0x07);<br /> rtc->mday = (buf[4]&0x0F) + ((buf[4]>>4)&3)*10;<br /> rtc->month = (buf[5]&0x0F) + ((buf[5]>>4)&1)*10;<br /> rtc->year = 2000+(buf[6]&0x0F) + (buf[6]>>4)*10;<br />}</span></td></tr>
</tbody></table>
<br />
<div align="justify">
Hasta ahora, y con las rutinas escritas, ya podemos comunicarnos con el RTC. Vale mencionar que estas rutinas puedes ser fácilmente modificadas para ser usadas con otros RTC como DS1307 ó PCF8563. También debemos decir que el RTC no es necesario para el funcionamiento de FatFs, pero en ausencia de éste la hora y fecha de creación y modificación de los archivos generados será nula.</div>
<br />
Ahora pasaremos a ver los archivos FatFs. Como dije antes, esto lo haremos usando los archivos de la carpeta “<em>avrcomplex</em>”. Como este ejemplo está hecho para un ATmega64, nosotros podemos usarlo sin mayores cambios para un ATmega128. Si quisiéramos usar este ejemplo con algún otro uC debemos realizar modificaciones en el archivo “mmc_avr.c”, específicamente en las rutinas “Power Control” y “Transmit/Receive data from/to MMC via SPI ”, ya que estas depende del uC usado.<br />
<br />
De todos los archivos que se encuentran aquí sólo necesitaremos:<br />
<br />
- integer.h<br />
- ccsbcs_avr.c<br />
- mmc_avr.c<br />
- diskio.h<br />
- ffconf.h<br />
- ff.h y ff.c<br />
<br />
Adicionalmente los archivos creados i2c.h, i2c.c, DS3231.h y DS3231.c.<br />
<br />
En el archivos “ffconf.h” debemos realizar las siguientes modificaciones.<br />
<br />
- Poner _FS_TINY a 0.<br />
- _CODE_PAGE a 850.<br />
- _USE_LFN a 2.<br />
<br />
Si nuestro adaptador no tiene “power control” debemos eliminar los bloques indicados con “Remove this block if no socket power control” en “power_on” y “power_off” dentro de mmc_avr.<br />
Si no tiene pin “card detect” o “Write Protect” debemos comentar el siguiente código en “disk_timerproc” dentro de mmc_avr.c.<br />
<br />
<table border="1" cellpadding="2" cellspacing="0" style="width: 486px;"> <tbody>
<tr> <td valign="top" width="484"> <span style="font-family: "courier new";">if (MMC_WP) /* Write protected */<br /> s |= STA_PROTECT;<br /> else /* Write enabled */<br /> s &= ~STA_PROTECT;<br /><br /> if (MMC_CD) /* Card inserted */<br /> s &= ~STA_NODISK;<br /> else /* Socket empty */<br /> s |= (STA_NODISK | STA_NOINIT);</span></td></tr>
</tbody></table>
<br />
<br />
Con estos cambios estaremos listo para escribir la aplicación principal, para ello escribiremos un mensaje simple en un archivo de texto.<br />
<br />
<table border="1" cellpadding="2" cellspacing="0" style="width: 805px;"> <tbody>
<tr> <td valign="top" width="803"><span style="color: #80ffff; font-family: "courier new";">/*<br />* Prueba_1.c<br />*<br />* Created: 04/08/2014 11:49:54 p.m.<br />* Author: Jonathan<br />*/ </span><br />
<span style="color: #80ffff; font-family: "courier new";"><br /></span>
<span style="color: #80ffff; font-family: "courier new";">#include <avr/io.h><br />#include <util/delay.h><br />#include <avr/interrupt.h><br />#include "DS3231.h"<br />#include "ff.h"<br />#include "diskio.h"</span><br />
<span style="color: #80ffff; font-family: "courier new";"><br /></span>
<span style="color: #80ffff; font-family: "courier new";">FATFS fs;<br />FIL file;<br />FRESULT resul;</span><br />
<span style="color: #80ffff; font-family: "courier new";">DRESULT dst;</span><br />
<span style="color: #80ffff; font-family: "courier new";">VUINT Timer;<br />UINT temp; <br />char setup_file[] = "0:ARCHIVO_0.txt";<br />char cadena[] = ".......DATOS A ESCRIBIR...";<br />RTC_t rtc_;</span><br />
<span style="color: #80ffff; font-family: "courier new";"><br /></span>
<span style="color: #80ffff; font-family: "courier new";">int main(void)<br />{ <br /> _delay_ms(1000);<br /> DS3231_Init(); <br /> <br /> OCR2 = (F_CPU/1024/100)-1;<br /> TCCR2 = 1<<WGM21 | 1<<CS22 | 1<<CS20;<br /> TIMSK |= 1<<OCIE2;<br /> </span><br />
<span style="color: #80ffff; font-family: "courier new";"> // 15/08/2014 10:23:00<br /> //rtc_.mday = 15;<br /> //rtc_.month = 8;<br /> //rtc_.year = 14;<br /> //rtc_.hour = 10;<br /> //rtc_.min = 23;<br /> //rtc_.sec = 0;<br /> //RTC_SetTime(&rtc_); <br /> <br /> sei(); <br /> <br /> dst = disk_initialize(0);<br /> resul = f_mount(&fs,(char const *)setup_file,1);<br /> resul = f_open(&file,(char const *)setup_file, FA_CREATE_ALWAYS | FA_WRITE); <br /> resul = f_write(&file,cadena,sizeof(cadena),&temp); <br /> f_close(&file); <br /> <br /> while(1)<br /> { <br /> RTC_GetTime(&rtc); <br /> _delay_ms(1000);<br /> }<br />}</span><br />
<br />
<span style="color: #80ffff; font-family: "courier new";">//***************************************************************************</span><br />
<span style="color: #80ffff; font-family: "courier new";"><br /></span>
<span style="color: #80ffff; font-family: "courier new";">ISR(TIMER2_COMP_vect)<br />{<br /> Timer++; <br /> disk_timerproc(); <br />}</span><br />
<br />
<span style="color: #80ffff; font-family: "courier new";">DWORD get_fattime (void)<br />{<br /> RTC_t rtc;</span><br />
<span style="color: #80ffff; font-family: "courier new";"> RTC_GetTime(&rtc);<br /> <br /> return ((DWORD)(rtc.year - 1980) << 25)<br /> | ((DWORD)rtc.month << 21)<br /> | ((DWORD)rtc.mday << 16)<br /> | ((DWORD)rtc.hour << 11)<br /> | ((DWORD)rtc.min << 5)<br /> | ((DWORD)rtc.sec >> 1);</span><br />
<span style="color: #80ffff; font-family: "courier new";">}</span></td></tr>
</tbody></table>
<br />
<div align="justify">
El código Anterior debería generar un archivo de nombre “ARCHIVO_0.txt” con el texto “.......DATOS A ESCRIBIR...” dentro del mismo.</div>
Si el RTC fue configurado anteriormente a la hora y fecha correctos, podríamos verificar esto en el archivo generado.<br />
<div align="justify">
Si aún no fue configurado, se puede usar el código comentado para poner la hora y fecha correcta. Luego debemos volver a comentar esa parte del código.</div>
<div align="justify">
Tener presente que el Timer2 es configurado para generar interrupciones cada 10ms, las cuales son necesarias para la libreria Fat.</div>
<div align="justify">
<br /></div>
<div align="justify">
Por último escribiremos 1MByte de datos para verificar la velocidad de escritura que podemos alcanzar. Para ello usaremos el Timer0, éste generará interrupciones cada 100us, y en cada interrupción se incrementará la variable “time”. Al iniciar la escritura guardaremos time en t0, y al terminar la escritura obtendremos el tiempo transcurrido en t1 = time – t0, luego calcularemos el tiempo tomado para escribir los 2048*512 bytes y lo escribiremos al final del archivo.</div>
<div align="justify">
<br /></div>
<table border="1" cellpadding="2" cellspacing="0" style="width: 797px;"> <tbody>
<tr> <td valign="top" width="795"><span style="color: #80ffff; font-family: "courier new";">/*<br />* Prueba_2.c<br />*<br />* Created: 04/08/2014 11:49:54 p.m.<br />* Author: Jonathan<br />*/ </span><br />
<span style="color: #80ffff; font-family: "courier new";"><br /></span>
<span style="color: #80ffff; font-family: "courier new";">#include <avr/io.h><br />#include <util/delay.h><br />#include <avr/interrupt.h><br />#include <stdio.h><br />#include "DS3231.h"<br />#include "ff.h"<br />#include "diskio.h"</span><br />
<span style="color: #80ffff; font-family: "courier new";"><br /></span>
<span style="color: #80ffff; font-family: "courier new";">FATFS fs;<br />FIL file;<br />FRESULT resul;</span><br />
<span style="color: #80ffff; font-family: "courier new";">DRESULT dst;</span><br />
<span style="color: #80ffff; font-family: "courier new";"><br /></span>
<span style="color: #80ffff; font-family: "courier new";">VUINT Timer;<br />UINT temp; <br />char setup_file[] = "0:ARCHIVO_0.txt";<br />RTC_t rtc_;<br />char datos[512]; <br />volatile uint32_t time,t0,t1; </span><br />
<span style="color: #80ffff; font-family: "courier new";"><br /></span>
<span style="color: #80ffff; font-family: "courier new";">int main(void)<br />{ <br /> _delay_ms(1000);<br /> DS3231_Init(); <br /> <br /> OCR2 = (F_CPU/1024/100)-1;<br /> TCCR2 = 1<<WGM21 | 1<<CS22 | 1<<CS20;<br /> TIMSK |= 1<<OCIE2;<br /> <br /> OCR0 = (F_CPU/8/10000)-1;<br /> TCCR0 = 1<<WGM21 | 0<<CS02 | 1<<CS01 | 0<<CS00;<br /> TIMSK |= 1<<OCIE0;<br /> <br /> sei(); <br /> <br /> dst = disk_initialize(0);<br /> resul = f_mount(&fs,(char const *)setup_file,1);<br /> resul = f_open(&file,(char const *)setup_file, FA_CREATE_ALWAYS | FA_WRITE); <br /> <br /> for (uint16_t i=0; i<512; i++)<br /> { <br /> datos[i]=i;<br /> }</span><br />
<span style="color: #80ffff; font-family: "courier new";"> t0 = time;<br /> <br /> for (uint16_t i=0; i<2048; i++) // 2048*512 = 1MB <br /> {<br /> f_write(&file,datos,sizeof(datos),&temp); <br /> }<br /> t1=time - t0;<br /> float rate = 1024.0*10000.0/t1;<br /> char rate_s[15];<br /> sprintf(&rate_s,"\r\n%f KBs",rate); <br /> f_write(&file,rate_s,15,&temp);<br /> f_close(&file); <br /> <br /> while(1)<br /> { <br /> RTC_GetTime(&rtc); <br /> _delay_ms(1000);<br /> }<br />}</span><br />
<span style="color: #80ffff; font-family: "courier new";">//******************************************************************************<br />//******************************************************************************</span><br />
<span style="color: #80ffff; font-family: "courier new";"><br /></span>
<span style="color: #80ffff; font-family: "courier new";">ISR(TIMER2_COMP_vect)<br />{<br /> Timer++; <br /> disk_timerproc(); <br />}</span><br />
<span style="color: #80ffff; font-family: "courier new";"><br /></span>
<span style="color: #80ffff; font-family: "courier new";">ISR(TIMER0_COMP_vect)<br />{ <br /> time++;<br />}</span><br />
<span style="color: #80ffff; font-family: "courier new";"><br /></span>
<span style="color: #80ffff; font-family: "courier new";">DWORD get_fattime (void)<br />{<br /> RTC_t rtc;</span><br />
<span style="color: #80ffff; font-family: "courier new";"> RTC_GetTime(&rtc);<br /> <br /> return ((DWORD)(rtc.year - 1980) << 25)<br /> | ((DWORD)rtc.month << 21)<br /> | ((DWORD)rtc.mday << 16)<br /> | ((DWORD)rtc.hour << 11)<br /> | ((DWORD)rtc.min << 5)<br /> | ((DWORD)rtc.sec >> 1);</span><br />
<span style="color: #80ffff; font-family: "courier new";">}</span></td></tr>
</tbody></table>
<br />
<br />
El resultado final se vera así:<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhaDCi6odv68SR-IcZHiPN7IZ9WOtgXftlZDcKPnHh2LS_Urb3Un2o9Na5SJrzEsprNd9R0rg16nx3_spLotR_pNT51G4K7PDxsreJb_x0jnpbgz54AhB9lXiDp9K0xmadL9y1Ur9Jt0xI/s1600-h/archivo%25255B8%25255D.png"><img alt="archivo" border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhBXZHe_iCLko_Kmho368px8Dqi2vx1ffKGtDkVe80qsz7xY22JQo5h4yYbpvBpjzjqnezbKJsbKcNGB2zjgCtUz8QxEzIZ0M-QuYQZeqbsa8nJxC_vzFDi7wotHwbMR5nrUUvJBP-nGMU/?imgmax=800" height="292" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="archivo" width="755" /></a><br />
<br />
<br />
Aquí vemos que la velocidad de escritura fue de 148KB/s.<br />
<br />
Espero que esto sea de su ayuda. Hasta la próxima.<br />
<br />
Saludos.jrsfhttp://www.blogger.com/profile/04364143443693071318noreply@blogger.com11tag:blogger.com,1999:blog-7123434971804829465.post-34379128551791525932014-06-27T14:32:00.000-07:002016-03-07T22:56:46.639-08:00MASTER SPI CON DMA – ATXMEGA<h1 align="center">
</h1>
En este post mostraré como usar el DMA para quitarle carga al CPU y acelerar las transferencias del SPI en modo master.<br />
<div align="justify">
Debemos tener en cuenta que según el manual de los XMEGA esto no es posible. “No es posible” ya que no hay un evento que pueda disparar la transferencia de datos, solo existe el evento de recepción de datos ( <span style="background-color: black; color: #e316e9;"></span><span style="color: #e316e9;">DMA_CH_TRIGSRC_SPIC_gc</span> para el SPI C).</div>
<div align="justify">
<br /></div>
<div align="justify">
Pero gracias a que el DMA tiene cuatro canales y que se puede establecer prioridades de los cuatro canales es que se puede implementar la transferencia por SPI usando el DMA. </div>
<div align="justify">
<br /></div>
<div align="justify">
Aquí el ejemplo: <a href="http://adf.ly/12709021/spi-xmega">http://adf.ly/12709021/spi-xmega</a></div>
<div align="justify">
<br /></div>
<div align="justify">
<br /></div>
<div align="justify">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhxJoyX4mWpy7TlTzgdkpdCg9CKkLphzizZw3M4EkH8WdXAamkX0mgM0P1ayfpB-sJmzKZ1-9jPnw4qpEHEW5LiHL0lsXSFuJSoqX3yNNGiEN1HqopdMqwgDrJnhkifXgZ6I0xrzZtBkMk/s1600-h/image%25255B9%25255D.png"><img alt="image" border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgTZvHXVQ2oPwyAGo10tSpS2pkMHQ2pFUyqyeBsi_A8CRVVnhbV_BKUnf5VVt85OSNPCf8P2zCrOqFB5R5IR4YMIlozQ3ZIe20k6c2aQ1ZczenOsFkyM94p1pFGIEL1YAgirt9-DPh5H60/?imgmax=800" height="179" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="image" width="454" /></a></div>
<div align="justify">
<br /></div>
<div align="justify">
Rx y Tx son los vectores a transmitir y recibir.</div>
<div align="justify">
<br /></div>
<div align="justify">
Habilitamos el DMA y establecemos la prioridad de los canales. La prioridad debe ser establecida ya que el CH0(Rx) y CH1(Tx) serán usados con el mismo evento, y debemos sacar el datos recibido antes de enviar el nuevo dato.</div>
<div align="justify">
<br /></div>
<div align="justify">
<br /></div>
<div align="justify">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiEyT9FjrDIhoKr-IJq6h0a1Qaui-7W0XNJKpC4tVIyJDC_mP7YMEDhOmz8CfFaXqZvXw3UVbl9JIHH4OPBgpBlCYHjZ0iTHAHgyP7mxjppWIQXJlDQL5oc9gTcAoYRNg5zIEuud-jRdWs/s1600-h/image%25255B14%25255D.png"><img alt="image" border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjAVA2mkYvIV824bwcz7ZfTBXgIoEntFRmWLfvwZfE8Q5yZk5BowNL823aQ8B1UVMatX_HTPDb50_Byhe_4pF_dsEBTbGsXSWYAUJHdWYHZoTftKIWpOn98w9VnLRfOee0a3XkIm7wyP9Q/?imgmax=800" height="165" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="image" width="490" /></a></div>
<div align="justify">
<br /></div>
<div align="justify">
<br /></div>
<div align="justify">
Configuramos el CH0 para recibir los datos por el SPIC. Los datos recibimos se guardan en Rx.</div>
<div align="justify">
<br /></div>
<div align="justify">
<br /></div>
<div align="justify">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj5VFeE3HUpdi092UILZ5vQm2_986q6GWyBcM1Lb0ZIFvJIzv-Ck8Zb2xudF3HxZ56fNiRx6Oo-HZlNhsut6bpvrzigsWTp28bglXRSwm-Kd_I2PnPI0G-aED05u5N3T_drZwyoasL5Gzg/s1600-h/image%25255B62%25255D.png"><img alt="image" border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjZnQxxJi8BJZffDlgkxCigSJXqo5IdWKAguUSVain8Y-IBoxuEBSfueBeBC75h1SEz96-Lwb68ZjLpEMG9J1e_0NcvglpwWidzIhzTj6yPOiRuyK7WfWEOWIbAwj0_BlhK_oRIKRnzcl0/?imgmax=800" height="171" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="image" width="496" /></a></div>
<div align="justify">
<br /></div>
<div align="justify">
Configuramos el CH1 para transmitir los datos por el SPIC. Los datos trasmitidos se sacaran de Tx. Rx y Tx deben ser de la misma longitud. Pero TRFCNT se configura con un dato menos(desde Tx[1] hasta Tx[12]) ya que Tx[0] se usara para disparar la transferencia.</div>
<div align="justify">
<br /></div>
<div align="justify">
<br />
<a name='more'></a><br /></div>
<div align="justify">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgWsg3S6RDQSVsjXh_Ai8ivU6hbto-Xnqm9LwhJFII-TCEhuPDczqVIurbsds4_3dj-kp7uJD8cQ3CNBjmjiB1SA17gPEr0NjuJdq48Vw-dqPi1cCPfgVaUSnYktPJzbz_blkkeZ7FFJJo/s1600-h/image%25255B32%25255D.png"><img alt="image" border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhfowhCHMWnp-8ayFv87MlobAcdJWQaqdvPVr6KKkAlTT54nTIEA9V7Eji_xGXWbQTFJqnJnpMowqXIwpgW_8FBB8bMQujx2EdvNIuGl0YFqRBi83SBSkaflPAgGzHP-i1EUIUEE6CIvlA/?imgmax=800" height="70" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="image" width="337" /></a></div>
<div align="justify">
<br /></div>
<div align="justify">
Se configura los pines MISO, MOSI, SCK y SS. Tambien Configuramos el SPI.</div>
<div align="justify">
<br /></div>
<div align="justify">
<br /></div>
<div align="justify">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhEKDPk6Qm0r917dhIhfKBgpavH7dCK4BZ6bfRZnCKUlVqi4Nc6VP88uHM5tj-RTAf64PyHan469jixSJzFMH4osgIqClF2eqCdQT0TlkqnOOFSzIKx83hO7Ix-gDHpnX80PgYGni2_bTM/s1600-h/image%25255B33%25255D.png"><img alt="image" border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj1tij_n8Llf8J5HWEcIVd9Ey6He7hEy7GCk0TKK0nBlEcMx4HPLaY8HAlCQaEVe0_3rJkhTRX58GHpVLbIos-4Hz55ZtqlbJDl-PNN5JY6XYcCV8T7DXJJp9E0WwEANB_4fpYV6134bbI/?imgmax=800" height="36" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="image" width="290" /></a></div>
<div align="justify">
<br /></div>
<div align="justify">
Habilitamos los canales CH0 y CH1.</div>
<div align="justify">
<br /></div>
<div align="justify">
<br /></div>
<div align="justify">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhbJbWWRALl-CIsAi8f_FL-0U57lTrfrhU-OOH-cq-gwtPwsLyra5TIHnQDCjFejKYxoafUthLZ7MgO7G-Fkz5_NwTF8bouFpJIr7SUAADKHjhra3LDMYvr7yBXMuoD3GjWGHX0QCNrUMk/s1600-h/image%25255B34%25255D.png"><img alt="image" border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEirp3jER_gU73mDXQ0FVRodc3xx5tYcTszy1GNk3KkivzmxDrnqF2x337AdVRWopfBqYGNb1xKQTzY_AuVsd23yHQXKPGU0ZrzA84jKJCOwb4SUTKvJZ1K6EC1YgbTLwRECYcuviFSWVW4/?imgmax=800" height="119" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="image" width="385" /></a></div>
<br />
Ponemos el SS a cero.<br />
<div align="justify">
Ponemos el primer dato a transmitir (Tx[0]) en el registro de datos. Esto dispara la transmisión de todos los datos. Cuando termine de salir el primer dato también debería haber llegado el primer dato y esto activara la transferencia del DMA. Gracias a la prioridad establecida al inicio, primero en CH0 guardara el dato recibido y luego el CH1 pondrá en el registro de salida el nuevo dato a enviar.</div>
<div align="justify">
Esto continuara hasta que se reciban todos los bytes.</div>
<div align="justify">
Se espera a que termine la transmisión y ponemos SS a uno.</div>
<div align="justify">
<br /></div>
<div align="justify">
<br /></div>
<div align="justify">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhl0OT29WsrtJzj6QQaxcwVzmrn2SvnvDVh3pWvpBTWxdm2jibwV_acYGAh7ETcolA42FMB_54fHZKd4uHvg-CdINSy4_zm5CHybyHHMqikh169s8_dz3oxX6tzqpW6GJUesDyaW9oRN1Q/s1600-h/image%25255B48%25255D.png"><img alt="image" border="0" src="http://lh3.ggpht.com/-BrptfC7UMLk/U63gTd5owQI/AAAAAAAAHSQ/T1_Pnze4pZk/image_thumb%25255B30%25255D.png?imgmax=800" height="215" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="image" width="853" /></a></div>
<div align="justify">
<br /></div>
<div align="justify">
Arriba se muestra la imagen de SCK y MOSI.</div>
<div align="justify">
<br /></div>
<div align="justify">
Lo mostrado arriba funciona, pero personalmente no me gusta el tiempo de retardo que existe entre byte y byte. Al parecer esto se debe a que el SPI solo tiene un buffer.</div>
<div align="justify">
<br /></div>
<div align="justify">
<br /></div>
<div align="justify">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjELP6T86m0kSD-IQmVH_EeBaNKNjL_PjtcqNveZ4urQl1RLiTco1pa-JavFh5gZhXpZavDKG2cETF4vTdyyPLLPEc2rZSd3jmJ4qiIpJ4-VvwTCyi6oH2Ib3bl4AwdjImbjkU-b1Uf1vk/s1600-h/image%25255B52%25255D.png"><img alt="image" border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhk8H33aQzSKRqTNh1JgdNUozFA9zFacazgNAZeWiFg1Sp70QlCMYoLepIDwm6PQh9THbXtoEPjGf4ZhwmfyH6NGt-ZXgdNwJmofWVys8hHtrETPUDMNK5MnwA7M5jZh_tgdNvPTrqV_V8/?imgmax=800" height="224" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="image" width="521" /></a></div>
<br />
Esto se puede apreciar con mejor claridad en la imagen anterior, y esto puede reducir la velocidad efectiva del SPI.<br />
<br />
<br />
<br />
Para evitar este problema la solución puede ser usar el USART en modo MASTER SPI. Tener en cuenta que en este modo si se hay dos eventos para disparar la transmisión y recepción.<br />
<br />
Aquí el código:<br />
<br />
- La primera parte es la misma.<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEik0CoW3Hf1BFjgtHDA3huC-IIzlpoQP7wElBB7r5b691DJFe-E-EcZ96bElEgsiodI3iDsoJ_kYpMiE7Bt7Q911yPDj60KhN3FvCpuHi_EI5WPaMY2dIuOaSqNUGmq9c_iWbrYIq7SSaE/s1600-h/image%25255B67%25255D.png"><img alt="image" border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjy-Z_pUHES9E720e_Ko_-K-aks3th2ude6ctxswcPMJt2blPgIsdLWTgYh03OHtIHlCg2RRlX7I6lVQ_g05jkpy5tGpDe8mgcCebTjz8NW3J6BGES6owKiJvfLCCzgQL1KehMa_7UnJ1I/?imgmax=800" height="166" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="image" width="487" /></a><br />
<br />
Se configura el CH0 para recibir los datos, para ellos se usa el evento RXC.<br />
<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiiMFNiVcH_5sEkh34TP0qYoVQ3tMECsmh9WWGiY-4NbL5POIukoFawgl04ZsQI_K-iIpT73OswvgWNH3d3Jzg0GpkUmIF4m8BBlLkMzGCvf8fToncwG2hfffxrTDIGm1TZO7d7fpuTteA/s1600-h/image%25255B72%25255D.png"><img alt="image" border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh2WuHJlIF1Hb2q8haD7-rKqzbPb7N_M6b7FEX64XVxL521gECq_Gzwl5OLAOcUTriVJcFidM-FtK4D1FfBQJiasVgLT8D6NC7e-uAS2JxvWgkf2DoZC_pIxxj6fb5sPmis1liYUDuwNhA/?imgmax=800" height="162" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="image" width="487" /></a><br />
<br />
Mediante CH1 se transmitirá los datos de Tx. Se usará la evento DRE.<br />
<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi3j-OKP7OlbBN_uim_CqRgv18xXiJGHj46rtTLff2pW7xycol6_CRdJi5__tE70zK16F5cPxRNhulLhAkdaQcCv0izzOg38_N-OxK4QXYZ9yvsJvBlz_dTzh6mn_GyH5EOsjOcYikQX5I/s1600-h/image%25255B87%25255D.png"><img alt="image" border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjZfdLaEqbYC0ACjz8ycZLq9AqVKTEs1QeezwIyVBap1UX_YIBTauQC430KMiNir69Lc2yjzF_pOtakECeizFekaOcLi5K9rNs_Gu1Rp-_gOjlHGyeyYMJUF3LWHFYblWPT9tcT1V_e2os/?imgmax=800" height="81" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="image" width="380" /></a><br />
<br />
Se configura los pines Tx, Rx y SCK, también el USART en modo MASTER SPI y se habilita la Transmisión y Recepción.<br />
<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEijMg4-5b3BNJkZ5YdloW_EgZy81PSzxeEYjbvmMCq_PL4rzEjnLnUNGoMeFMF3sdbYLwx9OXHnDYqnbaE8wo8wyOpbiIn7RPg4YTizD820_6P0gocBjo1716NC3wn_gMF4VXy1OSiNMC4/s1600-h/image%25255B97%25255D.png"><img alt="image" border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhG4UkqRbJQUiw9uQi4TXojAzyJClEpgICaO8gBZv29PIyzD-WwPu980JPJmE7BApBNXkaQMFF_ko2cJMsl4yIGMGRMsS64bpqWg1-aX9fY1PLo0JIaHzJTTl5ksefo5nCWTCL8ana6kBY/?imgmax=800" height="133" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="image" width="385" /></a><br />
<br />
Ponemos el SS a cero y habilitamos CH0 y CH1 del DMA.<br />
<div align="justify">
Se espera a que termine la transmisión y ponemos SS a uno</div>
<br />
Ahora, y gracias a los tres niveles de buffer del USART, ya no veremos retardos entre la salida de bytes.<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg3l7fwJ_YoAcWAOInEoZ0T6JebsSuQeQN4UAcsGY0EwvUqVZv1wOvZzow-FwbjvZzfC-5ml7QPQgdgR4inR6G5z6HSvlkUDzJEBFp8cg54dZsRymQXxNQjjlb0cxI9XQNNoJfJlzjbYX4/s1600-h/image%25255B102%25255D.png"><img alt="image" border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiwVwRx-UiMLIbcCAyOvh7w2E2ziceLWe8SY8qrFHpotWO_q8mPyNRr08Ec3thxOvc99Y-DrwwkDg38jylc6d1eAtW263NtKH8Bu5Gw742Wa1jZqWKlTJrQf2t8g2JgLwsuzjsWEJmyLQk/?imgmax=800" height="215" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="image" width="632" /></a><br />
<br />
<br />
Bueno, espero esto les ayude.<br />
<br />
Hasta pronto !.<br />
<br />jrsfhttp://www.blogger.com/profile/04364143443693071318noreply@blogger.com0tag:blogger.com,1999:blog-7123434971804829465.post-11011938096784598722013-11-18T15:31:00.000-08:002016-03-07T22:57:36.584-08:00USBasp y ATMEL STUDIO 6.X<h2 style="text-align: center;">
<span style="font-size: x-large;">USBasp y ATMEL STUDIO 6.X</span></h2>
<div>
<br /></div>
<div style="text-align: justify;">
En este post mostrare como configurar el ATMEL STUDIO para que nos permita usar nuestro USBasp.</div>
<div>
<br /></div>
<div style="text-align: justify;">
Lo primero es ir a la pestaña Tools->External Tools....</div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhNZC4vQaaJgaXOLUKDi_ikA8zjr7Ps7cuLB9TzVheO-kWmh5NeUjP4vFNC7hF2WvG-W6c6IYejymAGiDNWOxujtnxHEJbWxVL4iDZu6nXtQ-MMgoqFmsD_daqb33RynbTVI7pMXYaNAGg/s1600/Sin+t%C3%ADtulo5.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhNZC4vQaaJgaXOLUKDi_ikA8zjr7Ps7cuLB9TzVheO-kWmh5NeUjP4vFNC7hF2WvG-W6c6IYejymAGiDNWOxujtnxHEJbWxVL4iDZu6nXtQ-MMgoqFmsD_daqb33RynbTVI7pMXYaNAGg/s1600/Sin+t%C3%ADtulo5.png" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: justify;">
Ya dentro debemos llenar algunos parámetros:</div>
<div class="separator" style="clear: both; text-align: justify;">
Title: Debe contener el nombre de nuestra elección, en este caso pondremos USBasp.</div>
<div class="separator" style="clear: both; text-align: justify;">
Command: Debe contener la ruta del avrdude.exe.</div>
<div class="separator" style="clear: both; text-align: justify;">
Arguments: Debe contener los argumentos soportados por el avrdude para realizar la programación.</div>
<div>
<br /></div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiv7y_IAAIYXDlel0FdVvnNGzD2lYHwhZ3pMfXzPBuQ95BPlIzGH_y_p12wZJ7GszGeB2KtbGdT7KgvUTml8ytja2QE5d2my3_AUW7eyxhXzdRsDC0OjdaZrJhGQDmc_LFYn9iLjg58gm4/s1600/external+tool.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiv7y_IAAIYXDlel0FdVvnNGzD2lYHwhZ3pMfXzPBuQ95BPlIzGH_y_p12wZJ7GszGeB2KtbGdT7KgvUTml8ytja2QE5d2my3_AUW7eyxhXzdRsDC0OjdaZrJhGQDmc_LFYn9iLjg58gm4/s1600/external+tool.png" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: justify;">
La opción "Arguments" debe tener el siguiente texto:</div>
<div class="separator" style="clear: both; text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhoQwQkh0YdibiMw2IRdQT49c6g4mxT4I5oFOMtsGD-yOvzc4G76ZXBv-9II2LrafZ8IZ4O8ggNo17SwqmNnCJHJJa2EIe3Isq7Rt4_dFeO1tn03xDYHt-yz8yK-b_PUslLJ2NMcRURSEI/s1600/external+tool2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhoQwQkh0YdibiMw2IRdQT49c6g4mxT4I5oFOMtsGD-yOvzc4G76ZXBv-9II2LrafZ8IZ4O8ggNo17SwqmNnCJHJJa2EIe3Isq7Rt4_dFeO1tn03xDYHt-yz8yK-b_PUslLJ2NMcRURSEI/s1600/external+tool2.png" /></a><br />
<div class="separator" style="clear: both; text-align: justify;">
-c usbasp : Le indica al avrdude que se usara el programador USBasp(esto no se debe cambiar).</div>
<div class="separator" style="clear: both; text-align: justify;">
-p ATMEGA328P: Indica el uC que se usara, esto se puede cambiar para cada dispositivo.</div>
<div class="separator" style="clear: both; text-align: justify;">
-U flash:w...:Indica la ruta del archivo ".hex" a programar (esto no se debe cambiar).</div>
<div>
<br /></div>
<div>
Al final nos aparecerá un nuevo botón</div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj3H1VQjaOuG1oEMHvc_aFDF5KJBNQTXrdZwWDTC4krRpVMMe9_E6C9NRhJtXOMMdq2Pk1TabcGxfbCPBnjENN6Va0ps-P-L-e4gykAifOb4n_uttv3SIxuthrm4t8Y7VR-CRzVsJMFVKU/s1600/ima1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em; text-align: center;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj3H1VQjaOuG1oEMHvc_aFDF5KJBNQTXrdZwWDTC4krRpVMMe9_E6C9NRhJtXOMMdq2Pk1TabcGxfbCPBnjENN6Va0ps-P-L-e4gykAifOb4n_uttv3SIxuthrm4t8Y7VR-CRzVsJMFVKU/s1600/ima1.png" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: justify;">
Si damos click en el botón "USBasp" obtendremos.</div>
<div class="separator" style="clear: both; text-align: justify;">
</div>
<a name='more'></a><br /><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgVirPpCnB036qIZFjsr9sBZK7v79AFMS_VNCix2646NLUu-PtIhiTsL71qQ4rW42KEoThdRyLh7WRMaR7onCNArlwXVi9yIIC2Cs76ti9tJN62RW1bcA8rWanvXmkHbztFvD-P9HXiE1A/s1600/external+tool1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="339" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgVirPpCnB036qIZFjsr9sBZK7v79AFMS_VNCix2646NLUu-PtIhiTsL71qQ4rW42KEoThdRyLh7WRMaR7onCNArlwXVi9yIIC2Cs76ti9tJN62RW1bcA8rWanvXmkHbztFvD-P9HXiE1A/s640/external+tool1.png" width="640" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: justify;">
Ahora, si queremos tener un botón de acceso rápido en la barra de herramientas debemos ir a "Tools->Customize...".</div>
<div class="separator" style="clear: both; text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjd1pbR4V9KgJbxkE6MIZKT7Agv-eYQstkG8rOahRLK1qLAdBtCHcqsTqb9ykQ1OqF9RB-7z0RNIMFbH8AWcMEtgN3A97DBx3N6Jf8zAVN_730aqw8gDwlMJr0nClaF5kmjTxqEcFEzjS4/s1600/Sin+t%C3%ADtulo5.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjd1pbR4V9KgJbxkE6MIZKT7Agv-eYQstkG8rOahRLK1qLAdBtCHcqsTqb9ykQ1OqF9RB-7z0RNIMFbH8AWcMEtgN3A97DBx3N6Jf8zAVN_730aqw8gDwlMJr0nClaF5kmjTxqEcFEzjS4/s1600/Sin+t%C3%ADtulo5.png" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: justify;">
Aquí debemos agregar el USBasp.</div>
<div class="separator" style="clear: both; text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjZlc4fL3SYKRhGNwpGHRJQhQpfONueIif6Uab2V73A6FVoz7SflaxNkTM3U0BA4mlqFpvOxNXXdRY5il6AddAs33GhQyMKSoJMpkO2Z3h8I738wRgcNsqNqmbdj9Jh_4OfBLBitYr21J0/s1600/Sin+t%C3%ADtulo5.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjZlc4fL3SYKRhGNwpGHRJQhQpfONueIif6Uab2V73A6FVoz7SflaxNkTM3U0BA4mlqFpvOxNXXdRY5il6AddAs33GhQyMKSoJMpkO2Z3h8I738wRgcNsqNqmbdj9Jh_4OfBLBitYr21J0/s1600/Sin+t%C3%ADtulo5.png" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: justify;">
En la misma ventana, en "Commands" debemos seleccionar "Toolbar->USBasp" y dar click en el botón "Add Command..." </div>
<div class="separator" style="clear: both; text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg4VLolslu_7PEWD5Yv6EvgH1WQq_6jPL0c-oZt2ENX9L5vdYfZSpCq6QwbIUo9JcL446aCwAkI60OxYLbEskh_vaSZDpciF5gWrQewYt7KwRVIF_kBvsntmnxBy8Yl4apFsjg_jxXG394/s1600/Sin+t%C3%ADtulo5.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg4VLolslu_7PEWD5Yv6EvgH1WQq_6jPL0c-oZt2ENX9L5vdYfZSpCq6QwbIUo9JcL446aCwAkI60OxYLbEskh_vaSZDpciF5gWrQewYt7KwRVIF_kBvsntmnxBy8Yl4apFsjg_jxXG394/s1600/Sin+t%C3%ADtulo5.png" /></a></div>
<div class="separator" style="clear: both; text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: justify;">
Luego nos aparecera otra ventana donde debemos seleccionar "Tools" en "Categories:" y "External Command1" en "Commands:".</div>
<div class="separator" style="clear: both; text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjUgqmYcwTimIdyds3fEoVoWdvHwCcbPpH3uqCyUFnEb28j5dO46due45KJrV7LxuOpgQ-1_LbYvFMcsdvhiENaEVz2G1Ev6HUf8Rg3rQB9IgJ2LRWC0lCAXjFiW24mH8ZSebE8mfLvKx8/s1600/Sin+t%C3%ADtulo5.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjUgqmYcwTimIdyds3fEoVoWdvHwCcbPpH3uqCyUFnEb28j5dO46due45KJrV7LxuOpgQ-1_LbYvFMcsdvhiENaEVz2G1Ev6HUf8Rg3rQB9IgJ2LRWC0lCAXjFiW24mH8ZSebE8mfLvKx8/s1600/Sin+t%C3%ADtulo5.png" /></a></div>
<div class="separator" style="clear: both; text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: justify;">
El resultado final será:</div>
<div class="separator" style="clear: both; text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi5AFewy-Z3CQkG8DMuhw7zHpCwbP-8NCnlW7Vo33X5DJy22Ms1VLhyqX_TTZ4mVRAjL-ErmOuODGGjqx2pViz4yQKarHzBjHgvAH_PzHZwskVPq9WalnUTfTfFYgfsi_atHiyqN1uWSc4/s1600/Sin+t%C3%ADtulo5.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi5AFewy-Z3CQkG8DMuhw7zHpCwbP-8NCnlW7Vo33X5DJy22Ms1VLhyqX_TTZ4mVRAjL-ErmOuODGGjqx2pViz4yQKarHzBjHgvAH_PzHZwskVPq9WalnUTfTfFYgfsi_atHiyqN1uWSc4/s1600/Sin+t%C3%ADtulo5.png" /></a></div>
<div class="separator" style="clear: both; text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: justify;">
Con este botón podremos programar usando el USBasp sin problemas.</div>
<div class="separator" style="clear: both; text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: justify;">
Espero esto les ayude.</div>
<div class="separator" style="clear: both; text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: justify;">
Saludos.</div>
<div class="separator" style="clear: both; text-align: justify;">
<br /></div>
<div class="separator" style="clear: both; text-align: justify;">
Aquí el vídeo paso a paso de como hacer la configuración..</div>
<div class="separator" style="clear: both; text-align: justify;">
<br /></div>
<div style="text-align: center;">
<iframe allowfullscreen="" class="YOUTUBE-iframe-video" data-thumbnail-src="https://i.ytimg.com/vi/ukyS-psPpzE/0.jpg" frameborder="0" height="266" src="https://www.youtube.com/embed/ukyS-psPpzE?feature=player_embedded" width="320"></iframe></div>
<br />
<div>
</div>
jrsfhttp://www.blogger.com/profile/04364143443693071318noreply@blogger.com5tag:blogger.com,1999:blog-7123434971804829465.post-19941921661783971302013-08-08T13:55:00.000-07:002016-03-07T22:57:51.327-08:00Funcionamiento del Acelerómetro ADLX345<br />
<br />
<div align="justify">
En este post mostrare un ejemplo de como poner en funcionamiento el acelerómetro digital de 3 ejes ADLX345.</div>
<div align="justify">
</div>
<div align="justify">
Este acelerómetro cuenta con una resolución de 13 bits, y puede medir hasta ±16 g. La salida digital es de 16 bits en complemento a dos y puede ser obtenida mediante los protocolos SPI ó I2C.</div>
<div align="justify">
</div>
<div align="center">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiUBWwHcYHjYzJXWxoRBn4SIGggTVi2YfXvrE-2llraJ-M4XPMu0BEfrx0HvFTer26Kdf2JrdqGybgvDuJykSTqgFpMLlVvaBjKomgp0a6U0lDh9lAC9EwWBG9UOGZKbQACmqCZe0MlVZA/s1600-h/ADXL345%25255B3%25255D.jpg"><img alt="ADXL345" border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg_dRQnwbS37kH-0mrZaLwiZArqZ9p9xFe8mi42blFKUe-R3KLe-73kxV_eWurjaUGipvChkbMpDI8sywACh7net0JgmoC5yAthVXyRJqyxlO_s8Fcanp4pg_OHHexbm8NzmloIxPLQQ_8/?imgmax=800" height="180" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: inline; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="ADXL345" width="240" /></a></div>
<div align="center">
</div>
<div align="justify">
Al ADLX345 se puede encontrar en aplicaciones móviles. Este puede medir la aceleración estática de la gravedad para medir indirectamente inclinaciones, también se puede medir la aceleración dinámica producto de un movimiento o choque. Su alta resolución (3.9mg/LSB) permite medir cambios en inclinación menores a 1.0°. </div>
<div align="justify">
</div>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg3Jyn6TeSBaNGuH-Q9HrCwwQ8Hx-ji722cpxMxi80syZzUCd2TgEzh0Ka_afsD1nhBf8anS9VD-M4OUBf0bSfdudXoPZzTxkbST7tKSRxT2l4nAFbeOZwq3cGS1XW3W3I0HnTGAVWMhHk/s1600-h/ADXL345_image%25255B7%25255D.jpg"><img alt="ADXL345_image" border="0" src="http://lh4.ggpht.com/-McNcHMryYfY/UgQEuU7OCxI/AAAAAAAAFqQ/Gwzwaxz5xzA/ADXL345_image_thumb%25255B2%25255D.jpg?imgmax=800" height="133" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="ADXL345_image" width="240" /></a><br />
<br />
<div align="justify">
El ejemplo es desarrollado usando C++ en el ATMEL STUDIO 6.1. Se usa el protocolo I2C con dirección de esclavo 0x53 (pin ALT ADDRESS a GND). </div>
Para configurar el ADLX345 hay que realizar tres operaciones básicas en tres de sus registros.<br />
1.- En el registro 0x31—DATA_FORMAT— se debe configurar la resolución de bits y el rango de medición.<br />
2.- En el registro 0x2C—BW_RATE— se debe configurar el ancho de banda y la velocidad de salida de los datos.<br />
3.- En los registro 0x1E, 0x1F, 0x20—OFSX, OFSY, OFSZ— se debe setear offset par cada eje.<br />
Antes de realizar estas operaciones ponemos en ADLX345 en standby, y al finalizar volver al modo de medición.<br />
Luego se leerán los registros de datos y se enviaran hacia el computador.<br />
<br />
Aquí se muestra un ejemplo del programa.<br />
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjfcGZ1rWP04JLCEXxLg_ELYMJeeTHbs7M9LxH39KxkRVX_3Wf-jnYdiUeYwW19ZzYU1V19X6prOJRXh_koPXomYyG1_aX9hyphenhyphen556FdtltWWpH4rB28w-CZa40Xuvu_8fVDBC1pmYvh7HHI/s1600/acel+cpp.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjfcGZ1rWP04JLCEXxLg_ELYMJeeTHbs7M9LxH39KxkRVX_3Wf-jnYdiUeYwW19ZzYU1V19X6prOJRXh_koPXomYyG1_aX9hyphenhyphen556FdtltWWpH4rB28w-CZa40Xuvu_8fVDBC1pmYvh7HHI/s1600/acel+cpp.png" /></a></div>
<br />
<br />
<a name='more'></a><br /><br />
Los datos pueden ser leídos con cualquier programa que tenga acceso al puerto serie (tal como hyperterminal). <br />
<br />
<div align="justify">
Para recibir los datos y hacer los cálculos de gravedades y ángulos de inclinación desarrolle un programa en visual c#, el que se muestra abajo. Aquí se pueden ver los datos recibidos, la cantidad de gravedad en cada eje, y la inclinación de los tres ejes con respecto a la gravedad. </div>
<div align="justify">
</div>
<div align="justify">
</div>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi1tr3VNcaLio-PzA3Un4mvh7W1JK39n_SyGZfUT1_DBcSY5UxnwVth5KwVz6YRNQnp5dpQjxDuSUt-ieX-ai7zw403kl64P5e4tnegQIXviYfJbzDDpLq3TPrd0HYaHp_hMTMZ7nILaYU/s1600-h/ADXL345%25255B7%25255D.jpg"><img alt="ADXL345" border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjbxnla0QU1jkkEKDWrrm7Bk5mMCFTswzF2R7cIXNLtnrzndbEiNBf3ROlv51uOqLi_qEOKlwVtSQcio8JcUKXfjBrD1bVojwop8PJSycepmav2oH5BbZLS2J9_JhwgRF1prZ9kqUxtOss/?imgmax=800" height="665" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="ADXL345" width="530" /></a><br />
<br />
<br />
Los cálculos se realizan como sigue:<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi2EUsLBu6lTn19K3XIOF9GhYU6SxAqt2QjrfHMVchTzexu5r13pgQOrinYx1YXtCJepnZz2jwd6W7Ghi6iIXmnitHRRinUQbdsS2AE-1hi_gkz4kTctjlPF7w8G6CwvCP5ClMfnBZvCyI/s1600-h/image%25255B7%25255D.png"><img alt="image" border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEijbBSe_O2sR9qaNn7G17a1NZho6rOWu625pJ2S2C858V5fvxFsgNSvmd9bev2vDit1BldJyOVQSu9fCGJDJFc8DVLdoH3QddG1B4FiZUmTHBcm8i9qhJDgLsMnEOdJg3Q1MukVOLwEzIE/?imgmax=800" height="57" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="image" width="177" /></a><br />
<br />
El Factor depende de la resolución y rango con que se configuro el dispositivo. Por ejemplo para 10 bits de resolución y ±2g de rango el factor es 0.00390625.<br />
<br />
<div align="center">
<a href="http://lh4.ggpht.com/-pmAVtCrgtrA/UgQE-fkmDeI/AAAAAAAAFrI/1xLQNkbij6U/s1600-h/image%25255B11%25255D.png"><img alt="image" border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEic36z0JeddHedCfSMz1NIyJ0XHy1rZnlKQO2ZtzUuvIHeV25i_fj82P9GNXpOYhWpHuCUSGsowdZ3bcTuOAdiOLWF8y_CR6_ZFi6P-lwuZ0nFJOybTtFk3cLBX9vld69fga50a0Wi4zis/?imgmax=800" height="97" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: inline; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="image" width="158" /></a></div>
<div align="justify">
</div>
<div align="justify">
Las componentes, en gravedades, de cada eje están dadas por las ecuaciones anteriores. Xout, Yout y Zout son los datos, en complemento a dos, obtenidos del ADLX345. Por ejemplo si Xout=44, Yout=200, Zout=161 entonces Gx=0.171875, Gy=0.78125, Gz=0.62890625.</div>
<div align="justify">
</div>
<div align="center">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhlVxNM6xrUEKdJTNX1d-GzWIiigKh4dIy54qKa7EA0zaMUi8vczYbIYr1SGnEoxW8QJhr6wE8G9a50kDhCFUOcAdSnkza1r3mpGHbFRDx2gGuMi8pVYsvdWf_GtBQ7tReCiMIDR8I9pbQ/s1600-h/image%25255B15%25255D.png"><img alt="image" border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgFmSyoO3nHXxjF7QenZBwZl9hyphenhyphen8kSqf_0e8PiqMli4Im1afW8_v0G_0iyWxHOqm0XpH_Oi9MhtMFBOLEjZ53N1pYaQ7vL5zGUhI_acJ0S3-lUm4w1L6E43aYCk4ZCBlPhO_PkC9mnFgEE/?imgmax=800" height="32" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: inline; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="image" width="219" /></a></div>
<div align="center">
</div>
<div align="justify">
La resultante de éstas componentes, usando la ecuación anterior, debe ser 1g. Usando los datos anteriores G=1.017553758.</div>
<div align="justify">
</div>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiKfPIHcvjBytKPRBt9PWbVcn5AkoOPsWpbjZD0Sb3-Kv2WYBZkTPhyphenhyphen4XcitP1zMFV_N4NOUSaYj_i8K8NvrMLuTZmt71SMF6qHVyRdRqOwiExSYzpOEGUrhZH9TyAw2oKrS6HyqZppahI/s1600-h/image%25255B20%25255D.png"><img alt="image" border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg-UK54QhhWW_Z69_086yGOZiOMXwkIbEFCzC_zSDZSnqBEwXsDPGEIys-mSwc7bmGtqfgNI7V8yG6NHajqpnBOtnndrGlQPVWvqIR8-0I0rosgdObNx2RExXJDtfk3IaQ2vhtIaDINv-0/?imgmax=800" height="170" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="image" width="382" /></a><br />
<div align="justify">
</div>
<div align="justify">
Los respectivos ángulos de inclinación, con respecto a la vertical o a la gravedad, de cada eje son calculados usando las ecuaciones anteriores. Usando los datos anteriores los ángulos de inclinación de cada eje son 9.89°, 51.37° y 38.96°.</div>
<div align="justify">
</div>
<div align="justify">
</div>
<div align="justify">
<strong><span style="font-size: medium;"><u><em>COMO CALIBRAR EL ADLX345</em></u></span></strong></div>
<div align="justify">
</div>
<div align="justify">
El procedimiento de calibración del ADLX345 es muy sencillo, solo debemos colocar el acelerómetro en posición horizontal ( es decir, que toda la gravedad se encuentre sobre el eje Z). En esta posición se debe tomar una cierta cantidad de datos, pueden ser 100 o 200 datos, luego se debe promediar los datos correspondientes a cada eje. </div>
<div align="justify">
</div>
<div align="justify">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj_Fil417j9fNqo3W2dKlcNsKhCl85TpVj3BwMS4G78-bXsXWkhh0AsTev8t_FJUygmHX5eYewf9gtNKrM50DLfvo73ZpWcjg1OGdLQ2oHthtpYJrTTHmrhbXkA347FTU4Y-MZbzsr0hBU/s1600-h/image%25255B5%25255D.png"><img alt="image" border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj8DeBW23ycr8vg27cjhBqe-5XhN7JPOFYffuBCMU93PXoaWF1TGYz6ktD-RtQ-YGpXARHhEfMxsMlVQfJ-SlwFFcCaQYLriF91uwKTrGTrnmEytM_p8U7k9Dq6M0Wc2SFRfIyoaRmOxZE/?imgmax=800" height="62" style="background-image: none; border-bottom: 0px; border-left: 0px; border-right: 0px; border-top: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="image" width="326" /></a></div>
<div align="justify">
</div>
<div align="justify">
</div>
<div align="justify">
El valor que se debe aplicar a los registros de calibración se calculan como sigue:</div>
<div align="justify">
</div>
<div align="justify">
</div>
<div align="justify">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjGbKOwr24uSwB7z-nRekZihLJpFAioPyJ06kx4frz2uZUs3FfxOyY6uuKrFi82w-78k32Xlh_yVb4oWsiDc2vLGhQ-mO0stsdLTTWHG3mDPmb-eBd9tYzqZwNN95GqcxqPDLm7UsKeDn0/s1600-h/image%25255B15%25255D.png"><img alt="image" border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhIa_UHK6ZojxewKD90EStcb4VjiNbHSuWpbcq07gUA676vQ_IttS4s3zvouekEqscglZUyCCMafvvDqx2gj-qoJF_M0HPicybiO5FSYbkMhNGc4HWcgCqojHeNuvSM4EOzqMS061imCoY/?imgmax=800" height="66" style="background-image: none; border-bottom: 0px; border-left: 0px; border-right: 0px; border-top: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="image" width="436" /></a></div>
<div align="justify">
</div>
<div align="justify">
</div>
<div align="justify">
Espero este post los ayude en algo.</div>
<div align="justify">
</div>
<div align="justify">
Hasta pronto !!!.</div>
<div align="justify">
</div>
<div align="justify">
<span style="color: blue;"><a href="http://adf.ly/12709021/acelerometros-csharp">Programa Visual C#</a></span><br />
<a href="http://adf.ly/12709021/acelerometros"><span style="color: blue;">Programa Atmel Studio</span></a></div>
jrsfhttp://www.blogger.com/profile/04364143443693071318noreply@blogger.com0tag:blogger.com,1999:blog-7123434971804829465.post-38524712803463391842012-06-12T22:10:00.000-07:002016-03-22T21:28:14.126-07:00Formas de bloquear y desbloquear un ATmega8<div align="justify">
</div>
<div align="justify">
Bloquear un ATmega es algo muy común cuando se inicia con estos micros. En mi primera semana con los ATmega8 llegue a bloquear hasta 4, pero felizmente logre desbloquearlos.<br />
<br /></div>
<div align="justify">
</div>
<div align="justify">
Aquí presento algunos consejos que son obtenidos en base a la experiencia, espero esto ayude a algunos.</div>
<div align="justify">
</div>
<div align="justify">
Un problema no tan común, pero que les podría ocurrir (por desconocimiento) es deshabilitar el reset. Esto puede ocurrir programando el fuse "Reset Disable(Enable PC6 as i/o pin);"RSTDISBL=0". Este fuse se encuentre el High Fuse.<br />
<br /></div>
<div align="justify">
</div>
<div align="justify">
Hacer esto cuando se programa mediante SPI bloqueara el uC. Luego de esto no se podrá realizar ninguna operación con un programador SPI. La literatura indica usar un PPHV (Programador Paralelo de Alto Voltaje) para habilitar nuevamente el Reset. Personalmente nunca cometí este error.</div>
<div align="justify">
</div>
<div align="justify">
</div>
<div align="justify">
<div style="text-align: left;">
<a href="http://adf.ly/1X5qew"><span style="color: lime;">Manipulating the RSTDISBL fuse</span></a>
</div>
<br />
Ahora el problema mas común, bloquearlo por no escoger el oscilador correcto. Todos estos fuses los encontramos en Low Fuse.<br />
<br /></div>
<div align="justify">
</div>
<div align="justify">
Tener presente que Low Fuse esta compuesto por.<br />
<br /></div>
<div align="justify">
</div>
<div align="justify">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjyDPpVqYQE9AEP6LksnPIJ6TEOJd5ta-zTvS8RsRcuFq7Wb-ofzKi3A-W1pF76g-G2nvWwhc5Otjbjks6waZWILrpatEbedi1q7Z5tup4gdN1-Y9shw345d2f6VUfxfKaHVVObj1o9Hl8/s1600-h/LF%25255B5%25255D.jpg"><img alt="LF" border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh2uuZdp-galGr6BCHZZgtCA3npkW3DmA0DNHG5idW5n0eYBJBPPGPgdIbK0Dasc7eiOh7aXWzJMzzdsDaeKTRL47Y9XFSD5OtuWGBlZ2niLTkxVCn2MKaqI8UMxdLU70KIC-pzxide2FM/?imgmax=800" height="45" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="LF" width="386" /></a></div>
<div align="justify">
</div>
<div align="justify">
<br />
Donde…</div>
<div align="justify">
BODLEVEL : Permite seleccionar el nivel del BOD.</div>
<div align="justify">
BODEN: Permite habilitar el BOD.<br />
<br /></div>
<div align="justify">
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgLf3TJTRaFmotN9ZdPh_1T_KQr711WZuMldyZWYQ4k-7nMdGVQSRlDp2LcslEdG3lpbXgssogABStq-f6XRAtSHBigBQuFr5CWF-2-_aQZgwtIfWq6okQ9QAYeOqm2U7OyosvaCdI0hZY/s1600/BOD.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgLf3TJTRaFmotN9ZdPh_1T_KQr711WZuMldyZWYQ4k-7nMdGVQSRlDp2LcslEdG3lpbXgssogABStq-f6XRAtSHBigBQuFr5CWF-2-_aQZgwtIfWq6okQ9QAYeOqm2U7OyosvaCdI0hZY/s1600/BOD.jpg" /></a></div>
<div>
<br /></div>
</div>
<div align="justify">
SUT: Permite escoger un retardo (en ms) para el inicio del programa, esto después de haber energizado.</div>
<div align="justify">
CKSEL: Permite escoger entre los diferentes tipos de fuentes de reloj.</div>
<div align="justify">
</div>
<div align="justify">
</div>
<div align="justify">
<br />
<br />
- Si programamos Ext. Clock [CKSEL=0000]:Aplicando una señal de [4MHz-6MHz] al pin XTAL1 deberíamos poder trabajar sin problemas.<br />
<br /></div>
<div align="justify">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgRDZTXjkqcc6jDK72lrtWSXNpu7z3ucFiUehs3LZ-PwnUvMNRMfwm8bMGEcWvOl7LBuqrpZC54DXB6lhVp6eVeBaKWoj2iyk3Q6-bKT9mRw5R3UEyGN5P3hvXc1OyZCOTbdwGRWEg5sWk/s1600/EXT_CLOCK.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgRDZTXjkqcc6jDK72lrtWSXNpu7z3ucFiUehs3LZ-PwnUvMNRMfwm8bMGEcWvOl7LBuqrpZC54DXB6lhVp6eVeBaKWoj2iyk3Q6-bKT9mRw5R3UEyGN5P3hvXc1OyZCOTbdwGRWEg5sWk/s1600/EXT_CLOCK.jpg" /></a></div>
<div align="justify">
</div>
<div align="justify">
<br />
<br />
- Si programamos Int. RC Osc [CKSEL=0001 hasta CKSEL=0100] : Con este oscilador no deberían tener problemas, solamente tener en cuenta que la frecuencia de programación ISP debe ser menor a 1/4 la frecuencia RC. Es decir que si escogemos RC=2MHz nuestra frecuencia ISP debe ser menor a 500KHz.</div>
<div align="justify">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjz_4TI_yrZJk_kK-HkJcLhFCQ0iB6GnkMmNQTG5z6bb6AteLWRXvg7s82vVL5yKtHCeO-X_uMQQoSS86ywdJhyphenhyphenl2TIoe5c65LK6dUTezY2B_RyY9t94k3hyaoO1siU3NPM8d-DRpz2SrA/s1600/INT_RC.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjz_4TI_yrZJk_kK-HkJcLhFCQ0iB6GnkMmNQTG5z6bb6AteLWRXvg7s82vVL5yKtHCeO-X_uMQQoSS86ywdJhyphenhyphenl2TIoe5c65LK6dUTezY2B_RyY9t94k3hyaoO1siU3NPM8d-DRpz2SrA/s1600/INT_RC.jpg" /></a></div>
<div align="justify">
<br /></div>
<div align="justify">
<br />
- Si programamos Ext. RC Osc[CKSEL=0101 hasta CKSEL=1000]: Aplicando una señal de [4MHz-6MHz] al pin XTAL1 deberíamos poder trabajar sin problemas, o al menos poder cambiar a otro tipo de oscilador.</div>
<div align="justify">
<br />
<a name='more'></a><br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiM0FyA_QFbmItd3BZBBow7ofoQu7Xc3f9Oj4Vc5k36y2JMfHHvF8OS5RIWvvU5ukVoOTBlrTRwLkcgIaw5MP886yjpTx_n8vetZ86hxuRhNECfxje4ddl2t53_gF7YNR5G5YYDgVWl9Pw/s1600/EXT_RC.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiM0FyA_QFbmItd3BZBBow7ofoQu7Xc3f9Oj4Vc5k36y2JMfHHvF8OS5RIWvvU5ukVoOTBlrTRwLkcgIaw5MP886yjpTx_n8vetZ86hxuRhNECfxje4ddl2t53_gF7YNR5G5YYDgVWl9Pw/s1600/EXT_RC.jpg" /></a></div>
<div align="justify">
<br /></div>
<div align="justify">
<br />
- Si programamos Ext. Low-Freq. Crystal [CKSEL=1001] : En teoría deberíamos poner un cristal de 32768Hz, pero generando una señal de similar frecuencia y aplicándola a XTAL1 es suficiente. Recordar que la frecuencia ISP debe ser menor a 1/4. Si aplicamos 32.768KHz la frecuencia ISP debe ser menos a 8KHz.</div>
<div align="justify">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhTOBy-StUOTc3azeiso0a29bMwKjFoxfNnK3FXuFsjEacS89qev2IPZshptFmZ4OgWP3-kBA1NWwgWHb1jym8NiERIGIEtL99kPgpqW6t7U8Jx6P2MBnEv-LVkwAPKGuxQb0qVqAdw0eI/s1600/EXT_LOW_FREQ.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhTOBy-StUOTc3azeiso0a29bMwKjFoxfNnK3FXuFsjEacS89qev2IPZshptFmZ4OgWP3-kBA1NWwgWHb1jym8NiERIGIEtL99kPgpqW6t7U8Jx6P2MBnEv-LVkwAPKGuxQb0qVqAdw0eI/s1600/EXT_LOW_FREQ.jpg" /></a></div>
<div align="justify">
<br /></div>
<div align="justify">
<br />
- Si programamos Ext. Crystal/Resonator[CKSEL=1010 hasta CKSEL=1111]: Aplicando una señal de [4MHz-6MHz] al pin XTAL1 deberíamos poder trabajar sin problemas.<br />
<br /></div>
<div align="justify">
</div>
<div align="justify">
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhA_weYFa3v96t6CwDM-QWgLuAYwAimPDGdFGpOYg2lf_HuLLeRuxtIqb-stzQByzh0INmg-hLTsJQ0WD9IMvT6IE0lz1tlveI7M4UG2EM2jnTKdL0d5mugT6ZOgZYapHAbOyxHlFO-PIQ/s1600/EXT_CRYST.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhA_weYFa3v96t6CwDM-QWgLuAYwAimPDGdFGpOYg2lf_HuLLeRuxtIqb-stzQByzh0INmg-hLTsJQ0WD9IMvT6IE0lz1tlveI7M4UG2EM2jnTKdL0d5mugT6ZOgZYapHAbOyxHlFO-PIQ/s1600/EXT_CRYST.jpg" /></a></div>
</div>
<div align="justify">
<br />
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<iframe width="320" height="266" class="YOUTUBE-iframe-video" data-thumbnail-src="https://i.ytimg.com/vi/3JAFedULcdQ/0.jpg" src="https://www.youtube.com/embed/3JAFedULcdQ?feature=player_embedded" frameborder="0" allowfullscreen></iframe></div>
<br />
<br />
<h4>
<b><u>Consideraciones</u>:</b></h4>
<br />
- Todas las pruebas fueron hechas usando un ATmega8, un programador USBasp y el programa SinaProg 2.<br />
- Las frecuencia de 32.768KHz y 6MHz fueron generadas por otro uC y aplicadas al pin XTAL1 del uC que se quería programar. Las frecuencia fueron generadas usando el Timer1 en modo CTC.</div>
<div align="justify">
Configuración del Timer1:</div>
<div align="justify">
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhqgpQIUS1SEczl5WBtE5asa5Qa39XwJBqQnFCF23ZJF8GjEE0rqGDhoeUSAavAx-g3nOpwNfh3qV-dJkNIjxpCOKyZKdUNqEDHVToNIBln9F2ZRSgMDd7sc0dKnobPJ36iCNnR289XAo0/s1600/FFF.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="98" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhqgpQIUS1SEczl5WBtE5asa5Qa39XwJBqQnFCF23ZJF8GjEE0rqGDhoeUSAavAx-g3nOpwNfh3qV-dJkNIjxpCOKyZKdUNqEDHVToNIBln9F2ZRSgMDd7sc0dKnobPJ36iCNnR289XAo0/s320/FFF.jpg" width="320" /></a></div>
<div>
<br /></div>
</div>
<div align="justify">
0x0000 Para generar 6MHz con F_CPU=12MHz y N=1.</div>
<div align="justify">
</div>
<div align="justify">
Formula para Calcular OCR1A :<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjwvumb3jr17KBoOiWwn-_UakBr_ZsycdKUAMfe5nuVpqXlAf-B50s93FAr6HwTJIUqRJ10NUnP-AA0wTXWZkvLcltKLLLAeTA32KLKR5RyQh4Hg9Exze2Mw9sPOxkfPexUfm0kOGFp9Tk/s1600/FFF1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjwvumb3jr17KBoOiWwn-_UakBr_ZsycdKUAMfe5nuVpqXlAf-B50s93FAr6HwTJIUqRJ10NUnP-AA0wTXWZkvLcltKLLLAeTA32KLKR5RyQh4Hg9Exze2Mw9sPOxkfPexUfm0kOGFp9Tk/s1600/FFF1.jpg" /></a></div>
<div>
<br /></div>
</div>
<div align="justify">
</div>
<div align="justify">
Bueno, espero esto les sea util</div>
<div align="justify">
</div>
<div align="justify">
Saludos…!!!</div>
jrsfhttp://www.blogger.com/profile/04364143443693071318noreply@blogger.com16tag:blogger.com,1999:blog-7123434971804829465.post-73111653817211587262011-12-15T09:21:00.000-08:002016-02-17T17:16:48.554-08:00SET CLOCK(SCK) de programación del USBasp con SinaProg 2.0El USBasp tiene 12 posibles frecuencia de programación, estas son:<br />
<br />
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.<br />
<br />
Para poder acceder a esas velocidades usando el SinaProg, que a su vez usa el avrdude, debemos modificar el archivo Speed.txt.<br />
<br />
El Sinaprog 2.0 lo pueden descargar de este enlace <a href="http://adf.ly/1X5qp2" target="_blank">SinaProg 2.0</a> .<br />
<br />
Y en este otro enlace se encuentran los pasos para realizar la modificación. <a href="http://adf.ly/1X5r9B" target="_blank">PASOS</a>.<br />
No pongo imagenes ya que en el pdf se encuentra todo lo necesario.<br />
<br />
Un saludo y Felices Fiestas…!!!jrsfhttp://www.blogger.com/profile/04364143443693071318noreply@blogger.com0tag:blogger.com,1999:blog-7123434971804829465.post-87344085457906963242011-11-27T20:26:00.000-08:002016-03-03T13:14:47.507-08:00EEPROM INTERNA DE LOS ATMEGAEn este post mostraré un pequeño ejemplo sobre la lectura y escritura de la eeprom interna de los atmega.<br />
<div align="justify">
En el ejemplo trabajo con un mega8, pero el código es fácilmente aplicable a otros ATmega.</div>
<div align="justify">
<br /></div>
<div align="justify">
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.</div>
<div align="justify">
<br /></div>
Bueno, vamos con el programa y explicaré algunas cositas.<br />
<br />
Primero un par de macros nuevas que usaré.<br />
Esta primera macro espera hasta que el bit indicado sea 0.<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgrfahBIJurFVS2Az4UO2GbY1-dZy3rQLFkrl32z1BYkDM-qSNbFxX7FSDMVkXVkp1IbkmdGlZ7w48ATbS8Rvtb-DmPIpFP-eIWWpd7z4QhCP2uzLUC5_XK9mGuoHcSaiU0v79xdChAEUI/s1600-h/macro1%25255B4%25255D.jpg"><img alt="macro1" border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjfmu5qem2S_CbGracC4SlEHDks71QpsfPSH9eFs4uZADXxyoiE_8rBtO-gDoC-jAsGSrVNTqZdfAHlPe6xRN5UAe4fUc3vzKKfbJvL9AgkzA9EYkz_q_ldvVytO_Qvu-TSSKXbwgukgKM/?imgmax=800" height="395" style="background-image: none; border-bottom: 0px; border-left: 0px; border-right: 0px; border-top: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="macro1" width="393" /></a><br />
<br />
Esta espera a que el bit sea 1.<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhXAYZcVa7zeZ5eYowZvD_-8I6XoUrf_OPAYd6oTwvptCxdIenZJlxQcbdvJ1A4G5shF6HrG7v_JqrCDpuQuenySoE3xbhhrpTeylNwgTMhkkqhHxJbX7v0BUjig4U8XzbLzu-YIcebx18/s1600-h/macro2%25255B4%25255D.jpg"><img alt="macro2" border="0" src="http://lh6.ggpht.com/-zr5_iBZT9dA/TtMLUxeD2-I/AAAAAAAAAiM/L84hQj--dGM/macro2_thumb%25255B2%25255D.jpg?imgmax=800" height="404" style="background-image: none; border-bottom: 0px; border-left: 0px; border-right: 0px; border-top: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="macro2" width="372" /></a><br />
<br />
Ahora la primera parte del programa.<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjNE16Mq1Pp25xulbiOHGG_5pN_2Q8isqWUH4FH7FqohUwHPJr3knYxZ-LmeVTFLr6h3f_Yp8DbYkxSbt9KJqIy9mbLcUkr3tip_18nUSD_8LAGRHWuicd7AOnbNrnziuT09M5p-Tc2iCw/s1600-h/ima1%25255B4%25255D.jpg"><img alt="ima1" border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhFqcLk6LvCG_jCFeyBY6SAj8IjOpH0y4V4PdkReuLXIW4n5VQJUdl7zyualYwTDBw7l_pDh59SlCqNivQ7eMFBvCucpKobX4NcuSvhX449D811r_OtalW_oB8lSHEhwqtZrtimC31rXwY/?imgmax=800" height="430" style="background-image: none; border-bottom: 0px; border-left: 0px; border-right: 0px; border-top: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="ima1" width="471" /></a><br />
<br />
Aquí usaremos el uart para enviar algunos datos, la velocidad será de 9600.<br />
<div align="justify">
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).</div>
<div align="justify">
<br /></div>
<div align="justify">
.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.</div>
<div align="justify">
.org 0x010 .db "hola mundo" –> Esta otra parte también asignará los valores a las posiciones iniciando en 0x010.</div>
.org 0x020 .db 0x30,0x31,0x32,0x33,0x34 –> Aquí la asignación inicia en 0x20 y termina en 0x24, <br />
<div align="justify">
.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.</div>
.org 0x50<br />
data_eeprom_10: .byte 10 // separa 10 Bytes iniciando en 0x50.<br />
data_eeprom_5: .byte 5 // separa 5 Bytes iniciando en 0x5A.<br />
data_eeprom_16: .byte 16 // separa 16 Bytes iniciando en 0x5F.<br />
<br />
La eeprom cuenta con 3 registros:<br />
EEAR(EEARH:EEARL): Es el registro donde se debe escribir la dirección del byte que se quiere leer o escribir.<br />
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.<br />
<div align="justify">
EECR: Es el registro donde se encuentran los bits de configuración. Aquí se indicara que operación se desea realizar.</div>
<div align="justify">
<br /></div>
<div align="justify">
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.</div>
<div align="justify">
<br /></div>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjQ8KKIy9rv8cZaBbbTl54Gj7yEvrxO_b3s0osMQMedgAqkCaG8c5zfJ0YVmmZQmlG5Ux1jOePlIdEIDTPmBOGY9mIVctMS5Gt0v8LLTneV-33oz_nhYYcCYcb_UVlXCqzDKFSSPYzbeLo/s1600-h/ima4%25255B4%25255D.jpg"><img alt="ima4" border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjZzrNPkb0fahqWTtKt9P_VNofTNIdWlCWh-lagldoyvgysedoxhLhn60S496NgYlp9kSH5Uhuc4QcXl-VcuH1sZLZ6Xf_HNKNBc0fLGOxO6KgcvEVoo1NDx8Mf6CoNc3IIX4OU50BT0DU/?imgmax=800" height="417" style="background-image: none; border: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="ima4" width="310" /></a><br />
<br />
En la parte principal de programa se inicia la pila y se configura el uart.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh0NoVM6Ug2dFsmJQ4pGmRAhZCYqlw48rwOPPJNM1kUWsZ7kxE0-1WqeezdCrP2T1PdZMjGn0ygJmw0T1m2Sg_71Qf9l5zwfnk5nGNPqJBNRiofR-rhu6IvUTtq4hOpbS6FMHqrw6NbQh4/s1600/ima2.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh0NoVM6Ug2dFsmJQ4pGmRAhZCYqlw48rwOPPJNM1kUWsZ7kxE0-1WqeezdCrP2T1PdZMjGn0ygJmw0T1m2Sg_71Qf9l5zwfnk5nGNPqJBNRiofR-rhu6IvUTtq4hOpbS6FMHqrw6NbQh4/s1600/ima2.jpg" /></a></div>
<br />
En el programa encontramos tres bucles. <br />
<div align="justify">
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.</div>
<div align="justify">
Luego hay un saldo de línea.</div>
<div align="justify">
<br /></div>
<div align="justify">
El funcionamientos de los otros dos bucles es similar al primero.</div>
<div align="justify">
Aquí están las rutinas de salto de línea y de envió de datos por el uart.</div>
<div align="justify">
<br /></div>
<div align="justify">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjTvRH324c9EkQo0_5GBdJFVIqVDMcsALEt_bXqhQgHQyo2u5Z1qiyjyTdODVhZTJ3XIUVaymCuHsgug_zXjiQT0zoBlLoAk_V0EKyS8B2nUOVzW-qNMdGkEs9V2UrVs-WsOQsxZdbYhOs/s1600-h/ima3%25255B4%25255D.jpg"><img alt="ima3" border="0" src="http://lh3.ggpht.com/-8_ikBVeNVjI/TtMLh9cQXQI/AAAAAAAAAjM/PiscsAq7hdE/ima3_thumb%25255B2%25255D.jpg?imgmax=800" height="319" style="background-image: none; border-bottom: 0px; border-left: 0px; border-right: 0px; border-top: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="ima3" width="450" /></a></div>
<div align="justify">
<br /></div>
Ahora… luego de escribir todo este programa y compilarlo obtenemos como salida un archivo .eep.<br />
<br />
<a href="http://lh3.ggpht.com/-kS5KSRX8FE8/TtMLibwKtQI/AAAAAAAAAjU/8B0vcU7Mn18/s1600-h/panel%25255B4%25255D.jpg"><img alt="panel" border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjMSXO3NY5GKLFOjDsl2Ut4G-i80DL1BpGXdG3Rl0vBFy-_X5FASzvFxXLCSeNhiOC4dKWVCFlOmfPdJxZKCreY3JReQ-rAjona3Rg1AKm5H0JKb_lMAwiMk03yCPFxIAlaB4IHAfBoOV0/?imgmax=800" height="245" style="background-image: none; border-bottom: 0px; border-left: 0px; border-right: 0px; border-top: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="panel" width="168" /></a><br />
<br />
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.<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi7iJ6W4foFeWMRIDFK_Rl_5378Uz5gEbF-gA8gLj6YwK7eqWDnOZlN7Cu0fG51z1HqQxW6h8LTeCvIKSeB7CMrPfr7RiwouKUs-tHMhXdjROZ2zjXFfhYPiuiikzUCd_k3m7oTqOfGdJw/s1600-h/eefile%25255B4%25255D.jpg"><img alt="eefile" border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgIgKh-nu3s_pKZkdaAHGr7FFolnCbDSoNR8kEpCD1a70l-Z_Ml2TOgiVAAcHmm4lBtKiJCIsiHxCS9hQi-r9wSuSeNGDk-vMWris-D09YSSMRVxGGTm-0qTeLaXqyMHTgrBbpblDiO-NU/?imgmax=800" height="160" style="background-image: none; border-bottom: 0px; border-left: 0px; border-right: 0px; border-top: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="eefile" width="421" /></a><br />
<br />
<div align="justify">
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.</div>
<div align="justify">
<br /></div>
<div align="justify">
Ahora simularemos esto en proteus.</div>
<div align="justify">
<br /></div>
<div align="justify">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgJiWqB0oxqwlIQ3Wzqzb6PtJE7QO7d2Ap2ohyphenhyphenU0R3JkHjFApTf0ECNS_kN2xfsTfV52nmEDTuiF8OjaHFPs6Rgakh3UT1A2r0WG3QkU1QfZqfx1PWQBx2ijsSR4H-kUrBnQBd4aKjo47E/s1600-h/p1%25255B4%25255D.jpg"><img alt="p1" border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhz3V9q54Vchz0-PwK7WyJz6mUJ6v64jbz2YRVLXov7acEbSJq3Ssr2SD_ngUlz0I3VzkdN91N9usTAO4fIatwy53OL1xpLfFnWh2nm-A0J3yVY_AlaRY02n6zdkBnh8rP4L8_PhmDu2_I/?imgmax=800" height="267" style="background-image: none; border-bottom: 0px; border-left: 0px; border-right: 0px; border-top: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="p1" width="574" /></a></div>
<div align="justify">
<br /></div>
Para cargar nuestros datos a la eeprom interna debemos hacer doble click sobre el ATMEGA8.<br />
<div align="justify">
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.</div>
<div align="justify">
<br /></div>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh7iq7O-h6H8ZYhRGA5a1a95RmvEeUqweXJt1l37vqCKFYJAiF-Z_XXPcewEvDoe01fTVHeVKAI_2NXZy66uqCitUSyZR3TmAWPSFV_BH4Ywu15jMgAQTEW-7XZWuPNFyBXarGDXTlLUpI/s1600-h/p2%25255B4%25255D.jpg"><img alt="p2" border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjvt_o-Xo4dOuzVZS2p9rIgMhtnHGcbYghwe0lwjmkLOflLUs1z6AIR8_J2Tixt6eZBwkD4KV1B_KqoZQJndTGbiLboVqw0jpudJdeRjuvSC67A7LlBS4dVacMiwNfJ04Euieip7ogpqcs/?imgmax=800" height="50" style="background-image: none; border-bottom: 0px; border-left: 0px; border-right: 0px; border-top: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="p2" width="462" /></a><br />
<br />
Luego cuando iniciemos nuestra simulación veremos en la eeprom del ATmega lo siguiente.<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEijZg_YtBDhH4naNLXHu-sZs6SaPlsHerzu7GV4dWAGNIo9vWUmIDI_S_o_dOQWWWVFt0cP3OZcGjj-JF7CVV5PrYj2KpDH-gOr9ocwc7eDA7BPuT-t2NmubrDtnDtJvwq2iiXs7rhPYAI/s1600-h/p4%25255B4%25255D.jpg"><img alt="p4" border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj3b1sTddDDBnjb_PiZX3n2_vRw2x11xRLvzgNKv2XZoYyJVsqdw1G1jvm_1z3PvdtRTVqyLxPOaYAMOdGZ7YCgIetBUbIhkcGwI_ySrAfSOYFsgVvVZhiRlus57Nhtqd3SegA2vTOWwLE/?imgmax=800" height="188" style="background-image: none; border-bottom: 0px; border-left: 0px; border-right: 0px; border-top: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="p4" width="324" /></a><br />
<br />
<div align="justify">
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.</div>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjMcxQuLP8aChV3hFhnERX6o6kbbE3gLYP1b-TWYIswTy5oBSbRe-1zHUUFJPJurTF0NxCplzjtEukXm0J240MkrgUgoBNIbwmfknaK0-TyQB1aX4qnwLXI0RnqJUZ3Jhkxj6kbhtMkaGY/s1600-h/p3%25255B5%25255D.jpg"><img alt="p3" border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiCWcLGjq1j8a8nnHulW-6RlM9myUACMV8OkD4qc7vZLSl1d8BFY3-tMy5psnpe76pX0kNWw_8rJkZyqg3Bx1M-1q2EMVcoIMGsRmXnAap5CYBg8XuLch61EOuc6x47mPZ90gY-NwksSD0/?imgmax=800" height="438" style="background-image: none; border-bottom: 0px; border-left: 0px; border-right: 0px; border-top: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="p3" width="289" /></a><br />
<br />
Cuando ejecutemos nuestro programa veremos lo siguiente.<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEja51OzIJy0GqsXzOasu3okO5j3GzjOeUCzqVx4ueOdQt1AiptPxR-NF5tLdt_fPCarK2DxY_tHObhhDzyC8hCN5Wl8E3kCB-pNtRL8h4uiD4-VWFzLfmY8FeFkD-C5QuyQGCsA6QKoohM/s1600-h/p5%25255B3%25255D.jpg"><img alt="p5" border="0" src="http://lh5.ggpht.com/-nP8JUcrwCHM/TtMLtKlZD3I/AAAAAAAAAk8/StY6uo_gTlA/p5_thumb%25255B1%25255D.jpg?imgmax=800" height="351" style="background-image: none; border-bottom: 0px; border-left: 0px; border-right: 0px; border-top: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="p5" width="331" /></a><br />
<div align="center">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi34WPmvlxtQ8ZZg1RWNyq3LB5zKhGCOUDoBbMv8X2BWM2YJCO9s2dnHGMX-9DkPRYBiYr1q_L-EQOPZWOYrTEigNY1i-oxgt722tKe6eb5wXQ3-SzWvDfB1iCU-WW3UMNI90rymsxUIKE/s1600-h/p6%25255B3%25255D.jpg"><img alt="p6" border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj-X2to-O20o7BLvjklcD_AXmUzPCi9YfHFcTkLH0i41zkMWn5QOUf7ZJ1pF7C5X75MJcDMOEAHkdJqLs-8viHgDr9L_1U_5ZRNgbzP1Hj9vre8x969ESln8GeoPPHI_hsboGl1vNcuNPs/?imgmax=800" height="376" style="background-image: none; border-bottom: 0px; border-left: 0px; border-right: 0px; border-top: 0px; display: inline; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="p6" width="333" /></a></div>
<div align="center">
<br /></div>
<div align="justify">
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.</div>
<div align="justify">
<br /></div>
<div align="justify">
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.</div>
<div align="justify">
Hay que usar la ventana de comando para hacer la conversión. Un ejemplo seria así.</div>
<div align="justify">
<br /></div>
<div align="justify">
<span style="font-family: "courier new";">>avr-objcopy.exe –I ihex ruta_del_archivo_hex.hex –O binary nombre_del_archivo_de_salida.bin</span></div>
<div align="justify">
<span style="font-family: "courier new";"><br />
</span></div>
<div align="justify">
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.</div>
<div align="justify">
<br /></div>
<div align="justify">
<a href="http://lh3.ggpht.com/-Yi8efk7VliM/TtMLwo6Be7I/AAAAAAAAAlU/74r3qYiEfAc/s1600-h/programa%25255B4%25255D.jpg"><img alt="programa" border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhXkY4KIfbSI-8xV6HCumjw3RzHX8lQpMqtwTxl2uyGZcSz2IaKnZvporxGJemSfPlLoTPlmN2_eQeXZCcWjAhYXzyu5P8tUeieWGVKSAAcEWbRsT9evoLQBqOU5Dbj5I4kAvX-zqHJ2xc/?imgmax=800" height="178" style="background-image: none; border-bottom: 0px; border-left: 0px; border-right: 0px; border-top: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="programa" width="598" /></a></div>
<div align="justify">
<br /></div>
<div align="justify">
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”. </div>
<div align="justify">
<br /></div>
<div align="justify">
Si abren el archivo binario verán los siguiente.</div>
<div align="justify">
<br /></div>
<div align="justify">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgkAtIYMFbgQ82Y5oyc-Y9JI0xj_4gUpyo0Ay8B4oYqTXPoo6hv3Brfg17pGlzhAaeFl-prxtOi8_XqFDyVSMghHdZ0kBmyWbuORFy2S15ZD5ZMZa736Ux4XgEheFZum8b3A0O2qEnpwXs/s1600-h/eebin%25255B4%25255D.jpg"><img alt="eebin" border="0" src="http://lh4.ggpht.com/-_9DQupuIARI/TtMLyVKHxWI/AAAAAAAAAls/1E0vkSJA5d0/eebin_thumb%25255B2%25255D.jpg?imgmax=800" height="116" style="background-image: none; border-bottom: 0px; border-left: 0px; border-right: 0px; border-top: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="eebin" width="476" /></a></div>
<div align="justify">
<br /></div>
En esta oportunidad además de este programita muy útil, también compartiré los archivos EEPROM.asm, macros.inc, EEPROM.eep, EEPROM.bin.<br />
<br />
El link: <a href="http://adf.ly/1X5sj8" target="_blank"><span class="Apple-style-span" style="color: lime;">EEPROM</span></a><br />
<br />
Bueno, espero esto les ayude… Hasta pronto.jrsfhttp://www.blogger.com/profile/04364143443693071318noreply@blogger.com8tag:blogger.com,1999:blog-7123434971804829465.post-54786056609635228382011-10-01T20:08:00.001-07:002016-03-16T13:29:45.287-07:00Boot Loader en ATmega<div style="text-align: justify;">
Primero un saludo a mis lectores, hace mucho que no escribo.<br />
<br /></div>
<div style="text-align: justify;">
En este post hablare del bootloader y les daré el código para que ustedes puedan usarlo y editarlo a voluntad.<br />
<br /></div>
<div style="text-align: justify;">
</div>
<div style="text-align: justify;">
¿Qué es un bootloader?</div>
<div style="text-align: justify;">
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.</div>
<div style="text-align: justify;">
</div>
<div style="text-align: justify;">
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.<br />
<br /></div>
<br />
<a href="http://lh5.ggpht.com/-IriA7AuOhic/TofVo1TWVzI/AAAAAAAAAcU/1HxJPLIxzHg/s1600-h/boot%25255B6%25255D.jpg"><img alt="boot" border="0" src="http://lh6.ggpht.com/-aMeVhxnZxDg/TofVq48314I/AAAAAAAAAcY/86vkxSXiLU4/boot_thumb%25255B4%25255D.jpg?imgmax=800" height="638" style="border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: block; float: none; margin-left: auto; margin-right: auto;" title="boot" width="605" /></a> <br />
<br />
<br />
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).<br />
<br />
<div style="text-align: justify;">
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. </div>
<div style="text-align: justify;">
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.</div>
<div style="text-align: justify;">
Un ATmega128 tiene (512 páginas)*(256 bytes/página)=128KB.</div>
<div style="text-align: justify;">
Todos esos números los encuentran en las hojas de datos.</div>
<div>
<br /></div>
<div style="text-align: justify;">
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.</div>
<div style="text-align: justify;">
<br />
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.</div>
<div style="text-align: justify;">
<br />
El funcionamiento del programa es el siguiente:</div>
<ol>
<li style="text-align: justify;">El programa testea un pin del uC, </li>
</ol>
<blockquote>
<div style="text-align: justify;">
1.1 si es ‘1’ salta a la dirección cero de la flash y ejecutará nuestra aplicación ( si ésta existe).</div>
<div style="text-align: justify;">
1.2 si es ‘0’ se inicia la ejecución de bootloader.</div>
</blockquote>
<div style="text-align: left;">
2. El programa configura el uart. F_CPU y BAUD pueden ser cambiados y adecuados a las necesidades de cada persona.</div>
<div style="text-align: left;">
3. Luego espera todos los datos de una página.</div>
<div style="text-align: justify;">
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.</div>
<div style="text-align: left;">
</div>
<div style="text-align: justify;">
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.</div>
<div style="text-align: justify;">
<br />
¿Y cómo envío por el uart el bendito código de mi programa ?<br />
<br /></div>
<div style="text-align: left;">
Para esto desarrollé un pequeño programa en visual C#.<br />
<br />
<br /></div>
<div align="left">
</div>
<div align="left">
<a href="http://lh5.ggpht.com/-IjwvcVUHjIg/TofVrWc8G6I/AAAAAAAAAcc/iDQT95XruGw/s1600-h/programa%25255B8%25255D.jpg"><img alt="programa" border="0" src="http://lh3.ggpht.com/-rlRDKVPSCic/TofVswdMeCI/AAAAAAAAAcg/N18123xsTak/programa_thumb%25255B4%25255D.jpg?imgmax=800" height="279" style="border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: block; float: none; margin-left: auto; margin-right: auto;" title="programa" width="385" /></a> </div>
<div align="left">
</div>
<div style="text-align: justify;">
<br />
<br />
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”.</div>
<div style="text-align: left;">
En este caso no les puedo poner una simulación en proteus ya que éste no soporta la característica de auto-programación.</div>
<div style="text-align: left;">
</div>
<div style="text-align: justify;">
<br />
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. </div>
<div style="text-align: left;">
</div>
<div style="text-align: justify;">
<br />
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).</div>
<div style="text-align: justify;">
Luego ya no necesitarán llevar su programador a todas partes… basta con usar el puerto serie para realizar esta actualización.</div>
<div align="left">
</div>
<div style="text-align: justify;">
<br />
Espero esto les ayude… también espero sus comentario para la mejora del programa.</div>
<div align="left">
</div>
<div align="left">
El código fuente lo pueden descargar aquí: <a href="https://drive.google.com/open?id=0B4FYvkQ9y2zAWTVQd3FXRHNDWFU"><span class="Apple-style-span" style="color: lime;">BOOT_JRSF</span></a></div>
<div style="text-align: justify;">
El programa en C"# : <a href="https://drive.google.com/open?id=0B4FYvkQ9y2zAWTVQd3FXRHNDWFU">BOOT_Downloader</a> … si no pueden abrirlo quizá necesiten instalar el netframework 3.5.</div>
<div style="text-align: left;">
Si alguien quiere el código fuente del programa hecho en C# aquí lo tiene : <a href="https://drive.google.com/open?id=0B4FYvkQ9y2zAWTVQd3FXRHNDWFU">BOOT</a> …. Esta demás decir que deben tener instalado Visual Studio 2008 para abrir esto, o por lo menos Visual C# 2008 Express.<br />
<br />
<span style="color: lime; font-size: large;">ver: <a href="http://avrperu.blogspot.pe/2016/03/bootloader-usbasp_11.html"><span style="color: lime;">USBasp bootloader</span></a></span></div>
jrsfhttp://www.blogger.com/profile/04364143443693071318noreply@blogger.com18tag:blogger.com,1999:blog-7123434971804829465.post-48741932693916576622011-07-09T15:06:00.000-07:002016-04-14T10:46:54.088-07:00RTC DS1307 Y ATMEGA8<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
<a href="http://avrperu.blogspot.pe/2016/03/i2c-rtc-ds3231-usando-c.html" target="_blank"><span style="color: lime;"><b>Ver I2C + RTC DS3231 usando C</b></span></a><br />
<br />
En éste post mostraré un programa que permite configurar un DS1307. Como sabemos el DS1307 se comunica por I2C.</div>
<div style="text-align: justify;">
El programa tiene dos partes que son ejecutadas por dos interrupciones.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
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.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
Por el uart llega información que permite leer ó escribir el DS1307. </div>
<div style="text-align: justify;">
La información para escribir(configurarlo a una hora y fecha determinada) consta de 8 bytes que son: </div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
| CABECERA(1) | COMANDO(1) | HORA(1) | MIN(1) | SEG(1) | FECHA(1) | MES(1) | AÑO(1) |</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
La cabecera es 0xBA</div>
<div style="text-align: justify;">
El comando puede ser ‘W’(0x57) para escribir y ‘R’(0x52) para leer.</div>
<div style="text-align: justify;">
El resto de datos deben estar en BCD.</div>
<div style="text-align: justify;">
Un ejemplo de esto es: BA 57 12 21 08 08 07 11</div>
<div style="text-align: justify;">
Donde la hora es 12:21:08 y la fecha es 08/07/11.</div>
<div style="text-align: justify;">
<br /></div>
<div style="text-align: justify;">
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</div>
<div style="text-align: justify;">
<br /></div>
El esquema es el siguiente:<br />
<br />
<a href="http://lh3.ggpht.com/-ReKZONWCzSI/ThjJf38HjFI/AAAAAAAAAYA/E4uY4uLZqNM/s1600-h/sch-Small4.jpg"><img alt="sch (Small)" border="0" src="http://lh3.ggpht.com/-40JC3tz8sxQ/ThjJhYKpiAI/AAAAAAAAAYE/Pe_FybbAAVU/sch-Small_thumb2.jpg?imgmax=800" height="480" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="sch (Small)" width="636" /></a><br />
<br />
Ahora mostraré las macros usadas.<br />
<div align="center">
</div>
<div align="center">
<a href="http://lh4.ggpht.com/-pLmIew8Bf9U/ThjJlm8B8uI/AAAAAAAAAYQ/QYXLKVrVqoQ/s1600-h/mac24.jpg"><img alt="mac2" border="0" src="http://lh5.ggpht.com/-oRuovy6JWds/ThjJm_k5F6I/AAAAAAAAAYU/JKxhsROepD4/mac2_thumb2.jpg?imgmax=800" height="551" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: inline; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="mac2" width="413" /></a></div>
<div align="center">
<br /></div>
<div align="center">
<a href="http://lh6.ggpht.com/-obc9278W9XI/ThjJoZDkcVI/AAAAAAAAAYY/N1K8BwHpcbw/s1600-h/mac34.jpg"><img alt="mac3" border="0" src="http://lh6.ggpht.com/-1dWRx-Ikn5g/ThjJprvzVbI/AAAAAAAAAYc/QzdEwIqlJP0/mac3_thumb2.jpg?imgmax=800" height="537" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: inline; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="mac3" width="412" /></a></div>
<div align="center">
<br /></div>
<div align="center">
<a href="http://lh5.ggpht.com/-fymqy_9C2U0/ThjJqyEZuKI/AAAAAAAAAYg/dlSxImR88mg/s1600-h/mac44.jpg"><img alt="mac4" border="0" src="http://lh5.ggpht.com/-wy4T_PGiSZs/ThjJsYZLj7I/AAAAAAAAAYk/ITxM0wA_h1Y/mac4_thumb2.jpg?imgmax=800" height="551" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: inline; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="mac4" width="412" /></a></div>
<div align="center">
<br /></div>
<div align="center">
<a href="http://lh5.ggpht.com/-0BfxYXqq92Y/ThjJtkH6LoI/AAAAAAAAAYo/DR-OSlaCL08/s1600-h/mac54.jpg"><img alt="mac5" border="0" src="http://lh6.ggpht.com/-AUww-c1Nh78/ThjJvNT1kNI/AAAAAAAAAYs/RmwGMZ5PRKI/mac5_thumb2.jpg?imgmax=800" height="541" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: inline; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="mac5" width="412" /></a></div>
<div align="center">
<br /></div>
<div align="center">
<a href="http://lh4.ggpht.com/-lipXDfEO-GI/ThjJwjfFyuI/AAAAAAAAAYw/0MX8QCAIPBg/s1600-h/mac64.jpg"><img alt="mac6" border="0" src="http://lh5.ggpht.com/-GvAb3oowmCI/ThjJyTUv0hI/AAAAAAAAAY0/S6NgvcL6Ibg/mac6_thumb2.jpg?imgmax=800" height="470" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: inline; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="mac6" width="543" /></a></div>
<br />
Ahora las rutinas para I2C y DS1307.<br />
<br />
<div align="center">
<a href="http://lh4.ggpht.com/-dcN2QOAZJ1Y/ThjJz3k4_YI/AAAAAAAAAY4/gSdIx5qsYpo/s1600-h/i2c14.jpg"><img alt="i2c1" border="0" src="http://lh4.ggpht.com/-bzfhYFvnE2s/ThjJ15LEZAI/AAAAAAAAAY8/Hd_-XPhYk5E/i2c1_thumb2.jpg?imgmax=800" height="517" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: inline; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="i2c1" width="513" /></a></div>
<div align="center">
<br /></div>
<div align="center">
<a href="http://lh6.ggpht.com/-fIQJsJRhPWU/ThjJ8HS5adI/AAAAAAAAAZI/31KRx-jmWK0/s1600-h/i2c33.jpg"><img alt="i2c3" border="0" src="http://lh6.ggpht.com/-b4SSktdNmwo/ThjJ90hWlzI/AAAAAAAAAZM/B_OR8H3U6fY/i2c3_thumb1.jpg?imgmax=800" height="592" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: inline; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="i2c3" width="513" /></a></div>
<div align="center">
<br /></div>
<div align="center">
<a href="http://lh5.ggpht.com/-X38ZE6gcfcM/ThjKAQ4HhII/AAAAAAAAAZQ/tUuflv-FPRE/s1600-h/i2c43.jpg"><img alt="i2c4" border="0" src="http://lh6.ggpht.com/-9c-97do4rsw/ThjKCvyb3sI/AAAAAAAAAZU/Tgxcqe9WEq0/i2c4_thumb1.jpg?imgmax=800" height="541" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: inline; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="i2c4" width="740" /></a></div>
<br />
<div style="text-align: justify;">
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.</div>
<br />
Ahora las rutinas del UART.<br />
<br />
<div align="center">
<a href="http://lh4.ggpht.com/-IHNuDXrnIaI/ThjKDySsLaI/AAAAAAAAAZY/SGVa83VGo4I/s1600-h/u14.jpg"><img alt="u1" border="0" src="http://lh5.ggpht.com/-b7k-cWAmlzQ/ThjKFDb4QSI/AAAAAAAAAZc/RSiUuUwuEkU/u1_thumb2.jpg?imgmax=800" height="380" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: inline; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="u1" width="498" /></a></div>
<div align="center">
<br /></div>
<div align="center">
<a href="http://lh4.ggpht.com/-qBNL9ZqEmY0/ThjKGpAhPZI/AAAAAAAAAZg/j1fI1Mg7NFg/s1600-h/u24.jpg"><img alt="u2" border="0" src="http://lh4.ggpht.com/-2cMFsii4_2U/ThjKIEc_RaI/AAAAAAAAAZk/DxS_V_h7sj4/u2_thumb2.jpg?imgmax=800" height="506" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: inline; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="u2" width="371" /></a></div>
<div align="center">
<br /></div>
<div align="center">
<a href="http://lh5.ggpht.com/-ha3Cwol1Kqg/ThjKJZADUiI/AAAAAAAAAZo/dnpH3ePG6KM/s1600-h/u34.jpg"><img alt="u3" border="0" src="http://lh4.ggpht.com/-6cT_6tCNw50/ThjKKuQ9_xI/AAAAAAAAAZs/DLNBLQrErEU/u3_thumb2.jpg?imgmax=800" height="509" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: inline; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="u3" width="372" /></a></div>
<div align="center">
<br /></div>
<div align="center">
<a href="http://lh6.ggpht.com/--aGHcJ8pNvQ/ThjKMGPVFtI/AAAAAAAAAZw/gL9sfost2OU/s1600-h/u44.jpg"><img alt="u4" border="0" src="http://lh4.ggpht.com/-pCeEG_AIxds/ThjKNuXpASI/AAAAAAAAAZ0/mwVkWcou1Ak/u4_thumb2.jpg?imgmax=800" height="508" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: inline; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="u4" width="370" /></a></div>
<div align="center">
<br />
<a href="http://lh3.ggpht.com/-0Z2KfiUAY0A/ThjKOtKoZTI/AAAAAAAAAZ4/Z7D78M-V7QI/s1600-h/u54.jpg"><img alt="u5" border="0" src="http://lh5.ggpht.com/-cFvv8xb8374/ThjKQCNAuSI/AAAAAAAAAZ8/P7dGqWZfzAc/u5_thumb2.jpg?imgmax=800" height="396" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="u5" width="370" /></a></div>
<br />
Por último el mensaje principal.<br />
Hay que tener en cuenta que se esta usando el RC interno.<br />
<br />
<div align="center">
<a href="http://lh4.ggpht.com/-JJFd6baAwow/ThjKRWAqMUI/AAAAAAAAAaA/umg99HvU5OE/s1600-h/main1%25255B4%25255D.jpg"><img alt="main1" border="0" src="http://lh4.ggpht.com/-5zukVbbW5EU/ThjKSzxMwdI/AAAAAAAAAaE/e0IDDLXV6P8/main1_thumb%25255B2%25255D.jpg?imgmax=800" height="524" style="background-image: none; border-bottom: 0px; border-left: 0px; border-right: 0px; border-top: 0px; display: inline; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="main1" width="382" /></a></div>
<div align="center">
<br /></div>
<div align="center">
<a href="http://lh4.ggpht.com/-ym-pGI8wCe8/ThjKUdfuh7I/AAAAAAAAAaI/ggO_ZIzaVt0/s1600-h/main2%25255B4%25255D.jpg"><img alt="main2" border="0" src="http://lh6.ggpht.com/-CsXefkMakWI/ThjKV74KKMI/AAAAAAAAAaM/li6mN4lkYvM/main2_thumb%25255B2%25255D.jpg?imgmax=800" height="523" style="background-image: none; border-bottom-color: initial; border-bottom-style: initial; border-bottom-width: 0px; border-left-color: initial; border-left-style: initial; border-left-width: 0px; border-right-color: initial; border-right-style: initial; border-right-width: 0px; border-top-color: initial; border-top-style: initial; border-top-width: 0px; display: inline; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="main2" width="381" /></a></div>
<div align="center">
<br /></div>
<div align="center">
<a href="http://lh3.ggpht.com/-XHvse6OQ0PM/ThjKXU-xtcI/AAAAAAAAAaQ/OAqFQCetJvs/s1600-h/main3%25255B4%25255D.jpg"><img alt="main3" border="0" src="http://lh6.ggpht.com/-kHZtlNplYL0/ThjKZJ59GCI/AAAAAAAAAaU/KK29khfGQ1o/main3_thumb%25255B2%25255D.jpg?imgmax=800" height="521" style="background-image: none; border-bottom: 0px; border-left: 0px; border-right: 0px; border-top: 0px; display: inline; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="main3" width="381" /></a></div>
<br />
En el siguiente video se muestra el funcionamiento del programa.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<iframe allowfullscreen='allowfullscreen' webkitallowfullscreen='webkitallowfullscreen' mozallowfullscreen='mozallowfullscreen' width='320' height='266' src='https://www.blogger.com/video.g?token=AD6v5dxMOpqcYJYD7ba4sY3nZkt5vFKYpHcbGI4EPjtOyjbYDguhjkqxtV37QWExU3j-0Drz4uQWIgSu4ZlJrmVsIg' class='b-hbp-video b-uploaded' frameborder='0'></iframe></div>
<div style="text-align: center;">
<br /></div>
<div style="text-align: justify;">
El programa que se muestra para configurar el DS1307 lo hice en visual C#, éste programa lo pueden descargar de éste enlace <a href="http://adf.ly/1X5un0"><span class="Apple-style-span" style="color: lime;">RTC_DS1307</span></a>.<br />
Si no lo pueden abrir instalen netframework 3.5.</div>
<div style="text-align: justify;">
<br /></div>
jrsfhttp://www.blogger.com/profile/04364143443693071318noreply@blogger.com11tag:blogger.com,1999:blog-7123434971804829465.post-4636428497322365412011-06-11T18:11:00.000-07:002011-06-11T18:17:46.179-07:00CRC KERMIT Y CCITT EN ATMEGACuando 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).<br />
<br />
En éste post mostrare un par de rutinas para hacer el calculo del CRC KERMIT Y CRC CCITT en assembler de ATMEL.<br />
<br />
Los resultados pueden ser chequeados en <a href="http://www.lammertbies.nl/comm/info/crc-calculation.html"><span class="Apple-style-span" style="color: lime;">On-line CRC calculation</span></a><br />
<br />
Aquí no hay mucho que decir así que pasare a mostrar las rutinas.<br />
<br />
<a href="http://lh3.ggpht.com/-unTtPB91G8I/TfQQsd6FShI/AAAAAAAAAXk/AWWfWdc2j3A/s1600-h/CRC1%25255B4%25255D.jpg"><img alt="CRC1" border="0" height="348" src="http://lh4.ggpht.com/-O6ldh8cKeq4/TfQQt8I46BI/AAAAAAAAAXo/Oczzc8VKOXQ/CRC1_thumb%25255B2%25255D.jpg?imgmax=800" style="background-image: none; border-bottom: 0px; border-left: 0px; border-right: 0px; border-top: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="CRC1" width="566" /></a><br />
<br />
Aqui hay dos buques que calcularan el crc de la cadena de texto (“JONATHAN RAUL SEMINARIO”) que se encuentra en la memoria de programa.<br />
<br />
<a href="http://lh6.ggpht.com/-6M4dkefdjrU/TfQQvazUicI/AAAAAAAAAXs/qo-6lp03zAQ/s1600-h/CRC2%25255B5%25255D.jpg"><img alt="CRC2" border="0" height="485" src="http://lh3.ggpht.com/-eE3QeybjF1o/TfQQxBmmu8I/AAAAAAAAAXw/GWetwziCh6Y/CRC2_thumb%25255B3%25255D.jpg?imgmax=800" style="background-image: none; border-bottom: 0px; border-left: 0px; border-right: 0px; border-top: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="CRC2" width="390" /></a><br />
<br />
<a href="http://lh6.ggpht.com/-2gDoMFCzXCg/TfQQyt8vU0I/AAAAAAAAAX0/KIWGz3Qw51k/s1600-h/CRC3%25255B4%25255D.jpg"><img alt="CRC3" border="0" height="524" src="http://lh5.ggpht.com/-8FsW0QrHvig/TfQQ0I_w0BI/AAAAAAAAAX4/t3OYy1ibJGc/CRC3_thumb%25255B2%25255D.jpg?imgmax=800" style="background-image: none; border-bottom: 0px; border-left: 0px; border-right: 0px; border-top: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="CRC3" width="403" /></a><br />
<div align="justify"><br />
</div><div align="justify">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.</div><div align="justify"><br />
</div><div class="separator" style="clear: both; text-align: center;"><iframe allowfullscreen='allowfullscreen' webkitallowfullscreen='webkitallowfullscreen' mozallowfullscreen='mozallowfullscreen' width='320' height='266' src='https://www.blogger.com/video.g?token=AD6v5dwU4N65jch8zCmd72rVJWJ7Kv4wdaPDIZuFPYSmCusBzy0vCslm3Wr78FwNsrN3qda1_JU-HHrG7B95MbCX4A' class='b-hbp-video b-uploaded' frameborder='0'></iframe></div><div align="justify"><br />
</div><div align="justify">Bueno, eso es todo en éste post…bye !!!</div>jrsfhttp://www.blogger.com/profile/04364143443693071318noreply@blogger.com4tag:blogger.com,1999:blog-7123434971804829465.post-70040360766402255982011-06-05T14:48:00.000-07:002011-06-07T07:47:53.252-07:00Input Capture Unit<div style="text-align: justify;"><br />
</div><div style="text-align: justify;">El timer1 incorpora una unidad de captura la cual puede capturar eventos externos y darnos un tiempo referencial en el cual estos ocurrieron.</div><div style="text-align: justify;">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.</div><div style="text-align: justify;"><br />
</div><div style="text-align: justify;">En el siguiente gráfico de muestra el diagrama de bloques de la unidad de captura.</div><div style="text-align: justify;"><br />
</div><div style="text-align: justify;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiPTheGRShQt0vhQZ7F0JDzhJNThZoWOYQmQdF_fVSWxIcqX761kn_ZtGfgzj7Y2a0tKsoQVEQnJz_g_v2ASe-B2Ox0vUMAHPAku4eG4TkpntA9jIm47oarBtty3t4XxiRyAoXhdkVDlu4/s1600-h/bloques%25255B5%25255D.jpg"><img alt="bloques" border="0" height="392" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgFkX52ZMToIupevf1ZZqAPF3OQBDQkremY3K2BFtf2whIJpsiTpV3qBhe1h-AR7-k-CfEF3UmLXKVuCN9SuPaEQJpCqcLFht00f68FpYu8GXLwQEvW-kjWdWg8zc6bSnCYFrZjhzHxeVw/?imgmax=800" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: center;" title="bloques" width="589" /></a></div><div style="text-align: justify;"><br />
</div><div style="text-align: justify;">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’).</div><div style="text-align: justify;">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.</div><div style="text-align: justify;"><br />
</div><div style="text-align: justify;">En éste post usaré la unidad de captura para medir la frecuencia de una señal cuadrada.</div><div style="text-align: justify;">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.</div><div style="text-align: justify;"><br />
</div><div style="text-align: justify;">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:</div><div style="text-align: justify;"><br />
</div><div style="text-align: justify;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEggpPgftc6QQEt-Woi8pToX037TlBC2b46lfcItF9x60VyuXLfBcrUgWJMEjzJueRTP0079FcVeJ4HcppHB0gBhIZ97SeEaP2r8UethQU-gQQu2qK5KE7s9Gg-2pmN2QQ79c_rGTsw4FLU/s1600-h/image%25255B3%25255D.png"><img alt="image" border="0" height="56" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhV4GZ4SRRb4d239Q9axSWmnnwQkheRS-9xLRuZSLdKw1wOFToVF4Xkg6LDv6pKqLU4LBHtL9V6idv1OZxC0upzSqH_iSQLLw55fB7b5N8iH9DAE4RrlaZlYu9GB3EwJAaMniyXtC1wH_c/?imgmax=800" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="image" width="187" /></a></div><div style="text-align: justify;"><br />
</div><div style="text-align: justify;">Aplicando los datos a la formula:</div><div style="text-align: justify;"><br />
</div><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgo4N0QI-hh_vGPWr6Gvfdk3YKd9OKirdk4j3V9RgFfxxhJfcovh0o_0ZMTdppgXvOpZWdkIUgx7p5ZxSQ2evd2AMYApk_bDAUCIWR96Y3vuieqDnvhpxeANe8PZ2Zbu9m_e_ZOPDPHdmw/s1600-h/image%25255B7%25255D.png"><img alt="image" border="0" height="47" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj6KsML3d33x61hpY8RcMMm6V5pbFBKOaAZHmzy4hy7ueGSXv61UewbtziW3xYvINZBd2yQLYXoffAl5ZD5Qg4YPQug7CfV_WbzZoDBFSqpi-7pZAjOL4ai_bH1psrzZao6A51eCEFo17c/?imgmax=800" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: justify;" title="image" width="165" /></a><br />
<div style="text-align: justify;"><br />
</div><div style="text-align: justify;">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.</div><div style="text-align: justify;"><br />
</div><div style="text-align: justify;">Primero mostrare las macros.</div><div style="text-align: justify;"><br />
</div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhjhm_JCRSl_JKqCrNbwhpBjsxk18cXUrqiIlDeWmdGGsyFp9SzeVEcWmivQXjh7po8uAgC_XViIyl_afupjlydny8FxcKXLtxnqSErP85MOznd-NhU-gk1OJYlz5fFh4Yg73pA2q6jPsA/s1600/m21.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhjhm_JCRSl_JKqCrNbwhpBjsxk18cXUrqiIlDeWmdGGsyFp9SzeVEcWmivQXjh7po8uAgC_XViIyl_afupjlydny8FxcKXLtxnqSErP85MOznd-NhU-gk1OJYlz5fFh4Yg73pA2q6jPsA/s1600/m21.jpg" /></a></div><div style="text-align: justify;"><br />
</div><br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgYZHPjioDbPop2sGBoEXjkD2sSPAIKqeMVNJfe1ALdT27Bq4-pCjky02HWkveLJHSaWmjiNKQetRKHvKKIIC4qZIzdYCeyLLbN0Mw1-vH4pyq6OsHuAOVhQrJNlp4tp0tzi6t8cenpJa0/s1600/m22.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgYZHPjioDbPop2sGBoEXjkD2sSPAIKqeMVNJfe1ALdT27Bq4-pCjky02HWkveLJHSaWmjiNKQetRKHvKKIIC4qZIzdYCeyLLbN0Mw1-vH4pyq6OsHuAOVhQrJNlp4tp0tzi6t8cenpJa0/s1600/m22.jpg" /></a></div><div style="text-align: justify;"><br />
</div><br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh5Kspg84VduupSmc9MG0m3kh_R0P9yDNA65f5Blv16FUFUbOCmN54rqihcohF9IKaXzex9yykxc7SWKE7A_9FbaTB9N53c9bcHj8rPEe_IMzvt7EPJvhRl0_sKE2Fia44T8hUAqggga7o/s1600/m23.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh5Kspg84VduupSmc9MG0m3kh_R0P9yDNA65f5Blv16FUFUbOCmN54rqihcohF9IKaXzex9yykxc7SWKE7A_9FbaTB9N53c9bcHj8rPEe_IMzvt7EPJvhRl0_sKE2Fia44T8hUAqggga7o/s1600/m23.jpg" /></a></div><div style="text-align: justify;"><br />
</div><a href="http://lh5.ggpht.com/-G04tofjgT-g/TevxE-LW-MI/AAAAAAAAAVU/Vojol2iu-Mk/s1600-h/m24%25255B4%25255D.jpg"><img alt="m24" border="0" height="296" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhZ_bRAH7EGx4U7UASFIutc9-vb5J35rRhTo4Plyf4XpglGcf_J79U9pskAdJ4vSaobGRNpdtvFi5YrmySu8lHF-8Ev-ep4B28a8flO58KtwFBeReFgw8lEq4OOQlGfNPzbA8GpQWBPG30/?imgmax=800" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: justify;" title="m24" width="420" /></a><br />
<div style="text-align: justify;"><br />
</div><div style="text-align: justify;">Ahora mostraré la rutinas de conversión de binario a ascii.</div><div style="text-align: justify;"><br />
</div><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjVaLlEtTCARoiEmilLXEr5co6fmWNXarK-hUtttkNF0UrIPWNN4koYFQCCsbm1VeEdtztZB64Ya1Nunz9yc9C3OuK5R6ZoyKfSTZgStNKvTpJpQEG522UvxDHy30PYmadJpopVH8cqXhg/s1600-h/binascii1%25255B4%25255D.jpg"><img alt="binascii1" border="0" height="504" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgAukW9Iu-YVyaw-chmMGQGxmXaONr9YSVzR1UvWJGBONS-xgXJvypU-J-qN_RlFIzhGT0FZHneV1FasyRgnvKt2hDFjrR50KFhfeSfk_uyFEx8KzsQryQjzFpm8SnkzRJppiomYdfbLxc/?imgmax=800" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: center;" title="binascii1" width="675" /></a><br />
<div style="text-align: justify;"><br />
</div><div style="text-align: justify;"><div style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhAOi-5uFxCG3smSb4IJQbl9N9VQYMCwTtWXEXmFH9EBoKjf_38FcOvTZLWIszw7JeMdzqEyC-I5qe-FbJyqmH5yqnlapmTxDIzmZBYlZPnbIHuspRuTM4AvGO_hqreW7XqLiV09xqn4jU/s1600-h/binascii2%25255B7%25255D.jpg"><img alt="binascii2" border="0" height="465" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEip1OeBh5aolWAKZu21CxNnXpB6EvYIGfOngNn1bsqmOGnMw5DnY1MNyw7PBTx91YxDKZtnSIaEuR511qo5BP5H0D9ufIQpGjDVHzCKxsC1g79bQFdIoB7U7e-KZeGRWb167foYBMo-9yI/?imgmax=800" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: inline; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="binascii2" width="652" /></a></div></div><div style="text-align: justify;"><br />
</div><div style="text-align: justify;">Ahora la rutinas para manejo del LCD.</div><div style="text-align: justify;"><br />
</div><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjyu1RIbOx3eJ6aA5i0RoMnGPrkXJQ9rboE6AweQM7VQzM-RrVzAhrL08oA7A2Ii9JCVPEsYqKh1dqcVKS2Oc_P_5rVeTVVCq68lKy9QhrKYE9hwt14a5fA2INzYsSDDNyDxInO_LPaoXo/s1600-h/lcd1%25255B4%25255D.jpg"><img alt="lcd1" border="0" height="518" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgmy3g0-s624gNT10sbFTb6esgNEZM9vGwU9TaCIkPjQ-FPwyYOEcmpthAnwHSO8ZC8YpYbU-75Gq3ZZKkWXn0wrflArv8SVyPUEjL6cyQ2kyLhUOh31ryfAvM851fG-WurUqEPrCodu6U/?imgmax=800" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: center;" title="lcd1" width="613" /></a><br />
<div style="text-align: justify;"><br />
</div><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjOC7H3F0_ZtDNMImrEkaWxp7g9cdZTbEGyvR1tneamg73qUpav3_nZv9rJJ6ij0iWlLDz9OcKIyncn0OsnwZID4VqClLb1Rtujt8aLOLD9BMOeL62lkkJMiKTQRfCeMcX3Gmbyp7gQ4pY/s1600-h/lcd2%25255B4%25255D.jpg"><img alt="lcd2" border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhHDDoQIt_-qsyOyQfCBm1OEx4EKoZedTGFJcbdOH-JkCVYEI6r63gDdxVe2nonoPKl3Le150FMIxeJQkygvYoAIf_D1nb3mAKiRSlW-mOuVGHlOQtwfHr_tWrNXm9Bz5X8vLbaYrqhiDA/?imgmax=800" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: center;" title="lcd2" /></a><br />
<div style="text-align: justify;"><br />
</div><div style="text-align: justify;"><div style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgu49EbBWQBAqaDeYjyTqnyDd08-DftJDqS2r-yGjpW2KWbvf_-H7qnez_EocpKnYs4Z65vS0AFtHbIqg6zmOwdzEarCuD5Ecm4ilQZ4WTdcSEAE_Hy5DlHAcHeD-sPKCqWwnD31p7nZfg/s1600-h/lcd3%25255B4%25255D.jpg"><img alt="lcd3" border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjkUrpHPvydWAeEdL4OEDS2Ec-VJgrTp735kiXRfP6WQ25bdm5aBrhiD0Z_XYbn5OUt1WNCr_fxhp57773Bpwu0bLcMRscyEqJBMKDJnjo3Se41gMAcKzbNcZRSoqyI6AB2nXAvrfgpiNw/?imgmax=800" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: inline; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="lcd3" /></a></div></div><div style="text-align: justify;"><br />
</div><div style="text-align: justify;">Las rutina de retardo que es usado junto a las macros delay_ms y delay_us.</div><div style="text-align: justify;"><br />
</div><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgu1G9Sm8PVBCuLBVhHNSJakCwmQBv7dX1CyHKZA0i3YWE7rZIGo4HaX2MzlEn1oOhtB3RIjQdtC8jox9woS3vnc5WA6SGnfXFZSbmM59EQUzwV4msaGyZ-395zAjE6MJp3qPVM4Q7Uh3s/s1600-h/retardo%25255B5%25255D.jpg"><img alt="retardo" border="0" height="449" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhJ4dToCoCERa_08C7qsur7LVs7m-SE9Ksnx1GwZgUrg3kAJ294EFmRcG5Kx1YH54_4CYWr3Bc0lb4l5F0uyE88j-aMvTHlnMXSpvRNafvs6w2Y4ZXYuO7VBoXyV2wz0ld8_gh9Jo66SmQ/?imgmax=800" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: justify;" title="retardo" width="365" /></a><br />
<div style="text-align: justify;"><br />
</div><div style="text-align: justify;">La rutina para efectuar la división.</div><div style="text-align: justify;"><br />
</div><div style="text-align: justify;"><div style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi1to1Rkbcb8GG8miXyC1wH7EF-YC1zGKgUyGany79dxiN-c4y9449OdADLFBJxILtGWhI-8eRFBGPY4xFttJ8jI1TPrZ3U-wGhiP51ODKO6iCHz9BgnpobUeAkqAihuILPM2qxpGjc3TU/s1600-h/div1%25255B4%25255D.jpg"><img alt="div1" border="0" height="512" src="http://lh4.ggpht.com/-Nn4jT0NOWIk/Tevxd8h9_7I/AAAAAAAAAWQ/P3TQ7Ds2XhQ/div1_thumb%25255B2%25255D.jpg?imgmax=800" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: inline; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="div1" width="738" /></a></div></div><div style="text-align: justify;"><br />
</div><a href="http://lh6.ggpht.com/-KJl6tV3sNCs/TevxfAief_I/AAAAAAAAAWU/vunZBiLZDuo/s1600-h/div2%25255B4%25255D.jpg"><img alt="div2" border="0" height="512" src="http://lh3.ggpht.com/-5zRGDYsY7kk/Tevxhf6uQQI/AAAAAAAAAWY/KsyGJUcMMxA/div2_thumb%25255B2%25255D.jpg?imgmax=800" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: justify;" title="div2" width="370" /></a><br />
<div style="text-align: justify;"><br />
</div><div style="text-align: justify;">Y por último el código principal.<br />
<br />
</div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhJV21RCflsXdoBZuhWtRt898e-NxaazIuxBbBjzFiH3ArYjFTuyg5KRw8gP8DHuTl3wPbF0QkkFocS3Vq_ocu_slFNryYYOhOTeCVOjRuMIGDtWzkmfBCqajW-ckl_hIW1LxaH66dIKAs/s1600/main21.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhJV21RCflsXdoBZuhWtRt898e-NxaazIuxBbBjzFiH3ArYjFTuyg5KRw8gP8DHuTl3wPbF0QkkFocS3Vq_ocu_slFNryYYOhOTeCVOjRuMIGDtWzkmfBCqajW-ckl_hIW1LxaH66dIKAs/s1600/main21.jpg" /></a></div><div style="text-align: justify;"><br />
</div><br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhlt1rPh6UhxXzHIrwld3nUAWl2h7fRWizcC7bFx9afJxfAkAwP3tvGqLb1c5NqZnu-qq3hqfIgjM6KrF6AIIlXLplrNYhKUqcngYXW704Vz8ySMWJznOBZqyHtt1hPbFTdUd8-hjHazwY/s1600/main22.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhlt1rPh6UhxXzHIrwld3nUAWl2h7fRWizcC7bFx9afJxfAkAwP3tvGqLb1c5NqZnu-qq3hqfIgjM6KrF6AIIlXLplrNYhKUqcngYXW704Vz8ySMWJznOBZqyHtt1hPbFTdUd8-hjHazwY/s1600/main22.jpg" /></a></div><div style="text-align: justify;"><br />
<br />
</div><br />
<div class="separator" style="clear: both; text-align: center;"><a href="http://lh3.ggpht.com/-zIyHAm_hug4/TevxqfyOMTI/AAAAAAAAAWs/rBVes1qkJZI/s1600-h/main23%25255B6%25255D.jpg" style="margin-left: 1em; margin-right: 1em;"><img alt="main23" border="0" src="http://lh4.ggpht.com/-pTJHK9h3BFI/TevxrmyC3MI/AAAAAAAAAWw/cnF9taP1Iz4/main23_thumb%25255B4%25255D.jpg?imgmax=800" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: center;" title="main23" /></a></div><br />
<div style="text-align: justify;"><br />
</div><a href="http://lh3.ggpht.com/-cce49ipQ7TQ/TevxtPwnsKI/AAAAAAAAAW0/eSY5NVS8VWM/s1600-h/main24%25255B4%25255D.jpg"><img alt="main24" border="0" height="322" src="http://lh5.ggpht.com/-rqkMLovOm0k/Tevxug7zzqI/AAAAAAAAAW4/YuECCDhNWFI/main24_thumb%25255B2%25255D.jpg?imgmax=800" style="background-image: none; border-bottom-width: 0px; border-left-width: 0px; border-right-width: 0px; border-top-width: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: justify;" title="main24" width="452" /></a><br />
<div style="text-align: justify;"><br />
</div><div style="text-align: justify;">El funcionamiento del programa es como sigue.</div><ul><li> <div style="text-align: justify;">Se configura los periféricos, se habilita la interrupción y se espera a que ésta ocurra.<br />
<br />
</div></li>
<li> <div style="text-align: justify;">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).</div></li>
</ul><ul><li> <div style="text-align: justify;">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”).<br />
<br />
</div></li>
<li> <div style="text-align: justify;">Si no se ha desbordado se calculará la frecuencia, con la formula ya antes mostrada, y se guardará en FRECASCII.<br />
<br />
</div></li>
<li> <div style="text-align: justify;">Luego del calculo de mostrará la frecuencia en el LCD.<br />
<br />
</div></li>
<li> <div style="text-align: justify;">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).</div></li>
</ul><div style="text-align: justify;">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.</div><div style="text-align: justify;">Espero este pequeño ejemplo le ayude..!!!</div><div align="justify"><br />
</div><div align="justify">Ahora un video del programa en funcionamiento.</div><div align="justify"><br />
</div><div class="separator" style="clear: both; text-align: center;"><iframe allowfullscreen='allowfullscreen' webkitallowfullscreen='webkitallowfullscreen' mozallowfullscreen='mozallowfullscreen' width='320' height='266' src='https://www.blogger.com/video.g?token=AD6v5dyybNrTApjZzDUp95kgt83dGbj4tJ2BH5fi-FJtvl3q54sfQAyBwOu0RKjlbSFl5tbXXod0cnqhJNOaQnnh8g' class='b-hbp-video b-uploaded' frameborder='0'></iframe></div><div class="separator" style="clear: both; text-align: center;"></div><div align="justify"><br />
</div><ul><div align="justify"></div></ul>jrsfhttp://www.blogger.com/profile/04364143443693071318noreply@blogger.com15tag:blogger.com,1999:blog-7123434971804829465.post-44856754230328216782011-05-30T21:55:00.000-07:002016-02-17T18:22:32.493-08:00TIMER 1<div align="justify">
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.</div>
<div align="justify">
<br />
Programa : <a href="http://adf.ly/1X5zIu">TIMER</a><br />
<br /></div>
<div align="justify">
Sin mas preámbulo pasaré a mostrar las macros usadas.</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg36qRU_3r0nRaLY_fHyB3HCFnfqjWXeSKkzS7dTppMq5Kkjh0CO4aR99uFHYste3tlnEii1hiu9CJy1WbU9mSYJQhneDVQENXkrIHE5Xelb5vFflONXM4nFAATzhw9kgTPgFH7In_hlok/s1600/macros1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg36qRU_3r0nRaLY_fHyB3HCFnfqjWXeSKkzS7dTppMq5Kkjh0CO4aR99uFHYste3tlnEii1hiu9CJy1WbU9mSYJQhneDVQENXkrIHE5Xelb5vFflONXM4nFAATzhw9kgTPgFH7In_hlok/s1600/macros1.jpg" /></a></div>
<br />
<div align="justify">
A ésta macro solamente hay que indicarle el tiempo con el cual se quiere configurar el timer (en ms).</div>
El pre-escaler del timer se puede cambiar modificando CSN.<br />
<br />
<a href="http://lh3.ggpht.com/-I7RwILHme6w/TeRzpMh24uI/AAAAAAAAAUA/iTna42FSOGs/s1600-h/macros2%25255B4%25255D.jpg"><img alt="macros2" border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgPJm0h_u1kNITw3lgYSXtRzi-OR8Sx966k0WI-tIy87pXimIMXELj-KAS3Zc6JOGN9Y5kTYOylic0DgiMBPdddLFvo2N2tZ72jJIy2uaK614FnUyr2NHmudesrghViUWQGQGKHvjU9IPM/?imgmax=800" height="381" style="background-image: none; border-bottom: 0px; border-left: 0px; border-right: 0px; border-top: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="macros2" width="415" /></a><br />
<div align="justify">
<br /></div>
<div align="justify">
MOVIF pone un inmediato en la RAM, ya sea en el espacio de datos o en el espacio de registro especiales.</div>
<div align="justify">
<br />
El programa principal es el siguiente:</div>
<div align="justify">
<br /></div>
<div align="justify">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh_BrO9dyauiPJMxPVfGKi_SFGaLC2sX17AbmlkSfDJJrBPKvSmoBT_qPdpViSnhP3Kg9r5vjPaodfmvoWv-Eof8TJ2K9Oy47HbeFjg-qCvcRje2i-bWRoAdJEmx9lXGH31DicJTD9R5I4/s1600-h/main1%25255B4%25255D.jpg"><img alt="main1" border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj5bufhhER1eBNBn4UZkjMFjSKILcUautk62zSvCOpWnLE2XZNjeRIy2CQzvgLyueNgka6im3UQzeMejhWVbNMxw6s7xpdPpM04JPcq0q63zisYIr6TniBzj4gGeD6ZvN6r22Sbo_IThTU/?imgmax=800" height="392" style="background-image: none; border-bottom: 0px; border-left: 0px; border-right: 0px; border-top: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="main1" width="351" /></a></div>
<br />
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.<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjAiZflUleXQjTP4sJLMw5Xpoy_renlRzvICqZ5gv2Qgg6q75H0ifu1WRotx433fXdQZQgtc3PAoN1HMtQbhE-3su5D2r-ThDdJdPVUPq9yYd17NZHOZ27355pZjvOZYEeK2cwKfCkmsac/s1600-h/main2%25255B4%25255D.jpg"><img alt="main2" border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjdePBUykuAY_2f2p81_Z2AhdjWrO-bWKmbJyw_c7k2qwHLSGZnor5dw6eQTTz7HZw43ddXbpIapZ0NzwvsJecWj3nSD5Mtm5mBIHHQBETiPzw5jOgTgOGWXdJFWnYd_j5NVeoTrFs9BQg/?imgmax=800" height="329" style="background-image: none; border-bottom: 0px; border-left: 0px; border-right: 0px; border-top: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="main2" width="343" /></a><br />
<div align="justify">
<br /></div>
<div align="justify">
Cada vez que el timer se desborda se conmutará los pines PB0 y PB1, y también hay que volver a configurar el timer.</div>
<div align="justify">
<br /></div>
<div align="justify">
En el siguiente video se muestra el funcionamiento del programa.</div>
<div align="justify">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<iframe allowfullscreen='allowfullscreen' webkitallowfullscreen='webkitallowfullscreen' mozallowfullscreen='mozallowfullscreen' width='320' height='266' src='https://www.blogger.com/video.g?token=AD6v5dx_YCWQeq9nJBjFe1cBn0SFXVQ0JxVQtkqTSpt6hjEap7FdfhCxIs9C9cgb4Y6HRRNJbpAB3irknUmmPt3sdg' class='b-hbp-video b-uploaded' frameborder='0'></iframe></div>
<div style="text-align: justify;">
<br /></div>
jrsfhttp://www.blogger.com/profile/04364143443693071318noreply@blogger.com5tag:blogger.com,1999:blog-7123434971804829465.post-81567823981740485932011-05-21T20:21:00.000-07:002016-02-17T18:35:45.796-08:00Manejo del WDT<div align="justify">
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. </div>
<div align="justify">
<br /></div>
<div align="justify">
En éste post mostraré como habilitar y deshabilitar el Watch Dog Timer en cualquier ATmega. </div>
<div align="justify">
<br /></div>
<div align="justify">
En nuestro archivo de macros tenemos que agregar el siguiente codigo. (<a href="http://adf.ly/1X60ei">Link al programa</a>)</div>
<div align="justify">
<br /></div>
<div align="justify">
<a href="http://lh3.ggpht.com/_b2YvfJ-3yxM/Tdh_w1DzMcI/AAAAAAAAATY/ChoXrj-_M5w/s1600-h/wdt1%5B4%5D.jpg"><img alt="wdt1" border="0" src="http://lh5.ggpht.com/_b2YvfJ-3yxM/Tdh_yLs0LcI/AAAAAAAAATc/sWaa4A4oogY/wdt1_thumb%5B2%5D.jpg?imgmax=800" height="280" style="background-image: none; border-bottom: 0px; border-left: 0px; border-right: 0px; border-top: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="wdt1" width="411" /></a></div>
<br />
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.<br />
<br />
<a href="http://lh6.ggpht.com/_b2YvfJ-3yxM/Tdh_zVRgyiI/AAAAAAAAATg/8DZbQ8KJKhk/s1600-h/wdt2%5B4%5D.jpg"><img alt="wdt2" border="0" src="http://lh6.ggpht.com/_b2YvfJ-3yxM/Tdh_0bKAxlI/AAAAAAAAATk/-r9jkYppfvA/wdt2_thumb%5B2%5D.jpg?imgmax=800" height="341" style="background-image: none; border-bottom: 0px; border-left: 0px; border-right: 0px; border-top: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="wdt2" width="414" /></a><br />
<br />
La macro anterior permite habilitar el wdt.<br />
<br />
<a href="http://lh4.ggpht.com/_b2YvfJ-3yxM/Tdh_1SfeNCI/AAAAAAAAATo/W-mrNu2XVwo/s1600-h/wdt3%5B4%5D.jpg"><img alt="wdt3" border="0" src="http://lh4.ggpht.com/_b2YvfJ-3yxM/Tdh_23bwX_I/AAAAAAAAATs/52BVNwRwvtU/wdt3_thumb%5B2%5D.jpg?imgmax=800" height="314" style="background-image: none; border-bottom: 0px; border-left: 0px; border-right: 0px; border-top: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="wdt3" width="411" /></a><br />
<br />
La macro anterior permite deshabilitar el wdt.<br />
<br />
Ahora mostrare en sencillo ejemplo de su uso.<br />
<br />
<a href="http://lh6.ggpht.com/_b2YvfJ-3yxM/Tdh_4KQx4BI/AAAAAAAAATw/zsHPCz0CzDE/s1600-h/wdt4%5B9%5D.jpg"><img alt="wdt4" border="0" src="http://lh6.ggpht.com/_b2YvfJ-3yxM/Tdh_5ucvTgI/AAAAAAAAAT0/pYz-vqEy0tk/wdt4_thumb%5B5%5D.jpg?imgmax=800" height="398" style="background-image: none; border-bottom: 0px; border-left: 0px; border-right: 0px; border-top: 0px; display: block; float: none; margin-left: auto; margin-right: auto; padding-left: 0px; padding-right: 0px; padding-top: 0px;" title="wdt4" width="363" /></a>jrsfhttp://www.blogger.com/profile/04364143443693071318noreply@blogger.com0