Kit Educativo Propeller Fundamentos Versión 1.1.1 Por Andy Lindsay Traducido por Oscar Villarreal GARANTÍA Parallax Inc. garantiza sus productos contra defectos en materiales y fabricación por un periodo de 90 días a partir de la recepción del producto. Si el producto tiene un defecto, Parallax Inc. a su conveniencia reparará o remplazará la mercancía o reembolsara el monto de la compra. Antes de regresar un producto a Parallax se debe llamar a Parallax y obtener un número de RMA (Autorización de Regreso de Material). Para regresar la mercancía a Parallax escriba el número de RMA es la parte exterior de la caja. Por favor incluya la siguiente información con la mercancía a regresar: Nombre, Número de Teléfono, Dirección de envío y una descripción del problema. Parallax regresara el producto o su reemplazo usando el mismo método de envío que se utilizo para enviar el producto a Parallax. 14-DÍAS DE GARANTÍA PARA REGRESO DEL DINERO Si dentro de los 14 días de haber recibido el producto usted decide que no es útil para sus necesidades usted puede regresar el producto y obtener el un reembolso completo. Parallax Inc. Regresara el precio del producto excluyendo costos de envío y/o manejo. Esta garantía no es válida si el producto ha sido alterado o dañado. Vea la sección de Garantía mencionada en el párrafo anterior para instrucciones de regresará del producto a Parallax. DERECHOS RESERVADOS Y MARCAS REGISTRADAS Esta documentación está protegida bajo derechos reservados © 2006-2009 por Parallax Inc. Al obtener una copia electrónica o impresa de esta documentación o el software usted está de acuerdo en utilizarla exclusivamente con productos Parallax. Cualquier otro uso no es permitido y puede representar una violación a los derechos de autor de Parallax lo cual es legalmente castigable de acuerdo a las reglas federales de derechos de autor o a las leyes de propiedad intelectual. Cualquier duplicado de esta documentación para usos comerciales está expresamente prohibido por Parallax Inc. Duplicados para uso educativo es permitido sujeto a las siguientes condiciones de duplicado: Parallax Inc. otorga al usuario el derecho condicional de descargar electrónicamente, duplicar y distribuir este texto sin permiso de Parallax Inc. Este derecho se basa en las siguientes condiciones: el texto o cualquier porción incluida no puede ser utilizada para fines comerciales, puede ser duplicada únicamente con fines educativos cuando es utilizado únicamente en conjunto con productos Parallax y el usuario puede recuperar del estudiante únicamente el costo generado por generar el duplicado. Este texto está disponible en formato impreso en Parallax Inc. Debido a que los textos son impresos por volumen el precio al consumidor es comúnmente menor al que normalmente se realizan en cualquier otro lugar de copiado. Propeller, Penguin y Spin son marcas de Parallax Inc. BASIC Stamp, Stamps in Class, Boe-Bot, SumoBot, Scribbler, Toddler y SX-Key son marcas registradas de Parallax Inc. Si decide utilizar cualquiera de las marcas de Parallax Inc. en tu página web o en material impreso se debe establecer que las marcas son marcas registradas de Parallax Inc. cada vez que se muestre la marca en el documento escrito o en la página web. Otros nombres de productos contenidos en este documento son marcas o marcas registradas de sus respectivos dueños. ISBN 9781928982555 1.1.0-09.03.06-HKTP ESTIPULACIONES DE REPONSABILIDAD LEGAL Parallax Inc. no se hace responsable por incidentes especiales o daños resultantes de cualquier violación de garantía o cualquier otra teoría legal incluyendo perdidas de ganancias, tiempo perdido, daños o reemplazos de equipo o propiedad, así como cualquier costo de recuperación, reprogramación o reproducción de cualquier dato almacenado en o usado con los productos Parallax.. Parallax Inc. tampoco es responsable por daños personales incluyendo vida o salud resultante por el uso de cualquiera de nuestros productos. Usted toma completa responsabilidad de su aplicación en los micro controladores Propeller. LISTAS DE DISCUSIONES EN INTERNET Mantenemos foros de discusión activos en internet para gente interesada en los productos Parallax. Estas listas son accesibles desde www.parallax.com a través de Soporte-Menú de Foros de discusión (Support → Discussion Forums menu). Estos son foros que operamos de nuestro sitio web: Propeller chip – Esta lista es específicamente para nuestros clientes que utilizan Propeller chips y productos. • BASIC Stamp – Esta lista es utilizada ampliamente por ingenieros, aficionados y estudiantes que comparten sus proyectos de BASIC Stamp y responden preguntas. • Stamps in Class® – Creado para educadores y estudiantes, los suscriptores discuten el uso de la serie de tutoriales Stamps in Class en sus cursos. Esta lista proporciona una oportunidad para ambos educadores y estudiantes para obtener respuestas de sus preguntas. • Parallax Educadores – Un foro privado exclusivo para educadores y aquellos que contribuyen al desarrollo de materiales educativos para Stamps in Class y Propeller. Parallax creó este grupo para obtener retroalimentación de nuestros materiales educativos y así proporcionar un lugar para educadores que desean desarrollar y compartir recursos de clase. • Robotics – Diseñado para robots Parallax, este foro tiene la intención de abrir diálogos para aquellas personas entusiastas en robótica. Los temas incluyen ensamble, código fuente, expansiones y actualizaciones de manuales. En este foro se discute acerca del Boe-Bot®, Toddler®, SumoBot®, Scribbler® and PenguinTM. • SX Microcontrollers and SX-Key – Discusión de la programación del micro controlador SX con lenguaje ensamblador Parallax, herramientas SX-Key® y compiladores BASIC y C. • Javelin Stamp – Discusión de aplicaciones y diseño usando Javelin Stamp, un modulo de Parallax que se programa usando un lenguaje una versión de Java de Sun Microsystems®. ERRATA A pesar de que se realizó un gran esfuerzo para lograr la precisión de nuestros textos podría existir algún error. Si encuentra un error por favor envíenos la información a través de un correo electrónico a editor@parallax.com. Continuamente mejoraremos nuestros materiales educativos y la documentación, de igual forma revisaremos nuestros textos. Ocasionalmente una lista de erratas con la lista de errores para un documento especifico será publicada en nuestro sitio web www.parallax.com. Por favor verifique constantemente las páginas de los productos individuales para encontrar el archivo de erratas correspondiente. Tabla de Contenidos Índice PREFACIO ............................................................................................................................................. 5 1: INTRODUCCIÓN AL MICRO CONTROLADOR PROPELLER ......................................................... 7 El Micro controlador Propeller............................................................................................................ 7 El Kit Educativo Propeller................................................................................................................. 13 Practicas para el Kit Educativo Propeller ......................................................................................... 15 2: PROGRAMAS, DOCUMENTACIÓN Y RECURSOS ....................................................................... 17 Descarga de Software y Documentación......................................................................................... 17 Instalar la Terminal Serial Parallax .................................................................................................. 18 Sitios Web útiles............................................................................................................................... 18 Recursos y Soporte Técnico ............................................................................................................ 18 3: INICIO Y PRUEBAS PARA PLATAFORMA PE 40-PIN DIP ........................................................... 19 La Plataforma PE ............................................................................................................................. 19 Descripción General......................................................................................................................... 23 Inventario de Equipo y Partes .......................................................................................................... 24 Ensamble de las placas de prueba .................................................................................................. 25 Configuración y Reguladores de Voltaje de la Plataforma PE ........................................................ 27 Prueba del cableado de la Plataforma PE ....................................................................................... 29 Conexión del chip Propeller y la EEPROM ...................................................................................... 30 Cargar el programa y probar los pins de E/S................................................................................... 32 Antes de cambiar o ajustar circuitos ................................................................................................ 37 Regulador de Fuente de Poder Propeller – ¡Es importante!............................................................ 37 Solución de problemas para el arranque de la Plataforma PE de 40 pins-DIP............................... 39 4: PRACTICA BÁSICA DE E/S Y TIEMPO .......................................................................................... 45 Introducción...................................................................................................................................... 45 Lista de partes y esquemas ............................................................................................................. 45 Nomenclatura del Propeller.............................................................................................................. 46 Luces encendidas con Direcciones y Salidas de Bits de Registro .................................................. 47 Operaciones en grupos de Pins E/S ................................................................................................ 49 Leyendo una Entrada, Controlando una Salida ............................................................................... 50 Retrasos de tiempo con el reloj del sistema .................................................................................... 51 Configuración del Reloj del Sistema y Eventos de Tiempo ............................................................. 53 Mas Operaciones de Registros de Salida........................................................................................ 55 Comandos condicionales de Repeat ............................................................................................... 57 Operaciones en Posiciones y Pre – Post Posiciones de Operadores ............................................. 58 Vocabulario de operadores .............................................................................................................. 60 Moviendo el desplegado de LED ..................................................................................................... 61 Ejemplo de Variable ......................................................................................................................... 62 Aplicaciones de tiempo .................................................................................................................... 64 Tiempo de Estudio ........................................................................................................................... 66 5: PRACTICAS DE MÉTODOS Y COGS............................................................................................. 69 Introducción...................................................................................................................................... 69 Lista de partes y esquemas ............................................................................................................. 69 Definiendo un comportamiento de Método con variables locales ................................................... 70 Llamando un Método........................................................................................................................ 70 Pasando Parámetros........................................................................................................................ 71 Indexando Identificación del Cog ..................................................................................................... 78 Tiempo de Estudio ........................................................................................................................... 80 Kit Educativo de Practicas Propeller: Fundamentos · Página 3 Tabla de Contenidos 6: PRACTICA DE OBJETOS ............................................................................................................... 83 Introducción ..................................................................................................................................... 83 Equipo, Partes y Esquemas ............................................................................................................ 84 Revisión de la llamada a método..................................................................................................... 85 Llamando Métodos en otros Objetos con la Notación Dot .............................................................. 85 Objetos que pueden iniciar Procesos en Cogs ............................................................................... 88 Reglas para Métodos Start y Stop en Librerías de Objetos ............................................................ 92 Comentarios de Documentación ..................................................................................................... 92 Métodos Públicos vs. Privados........................................................................................................ 95 Ejemplo de Múltiples Objetos .......................................................................................................... 96 Comunicación Chip Propeller – PC Terminal .................................................................................. 97 FullDuplexSerial y otros objetos de la Librería .............................................................................. 102 Enviando valores de la Terminal Serial Parallax al chip Propeller ................................................ 105 Pantalla de Estado de Pin E/S....................................................................................................... 107 Terminal LED Output Control ........................................................................................................ 109 El Bloque DAT y Paso de Direcciones .......................................................................................... 110 Los Objetos Float y FloatString ..................................................................................................... 112 Objetos que usan Direcciones Variables....................................................................................... 113 Pasando Direcciones de Inicio a Objetos que trabajan con Lista de Variables ............................ 116 Tiempo de Estudio......................................................................................................................... 118 7: MÓDULOS CONTADORES Y APLICACIONES DE CIRCUITOS ................................................ 123 Introducción ................................................................................................................................... 123 Como trabajan los Módulos Contadores ....................................................................................... 124 Midiendo Descarga RC con un Detector de Modo Positivo .......................................................... 124 Conversión D/A – Controlando luminosidad del LED con Modos DUTY ...................................... 133 Registros de Propósito Especial.................................................................................................... 138 Generando Tonos en Piezospeaker con Modo NCO.................................................................... 141 Aplicaciones Objeto IR y Detección de Distancia con modos NCO y DUTY ................................ 151 Contando Cambios con Modos POSEDGE y NEGEDGE ............................................................ 157 PWM con Modos NCO .................................................................................................................. 160 Prueba y Muestra PWM – Agrega un Objeto, Cog y Par de Contadores ..................................... 164 Modos PLL para Aplicaciones de Alta Frecuencia ........................................................................ 171 Detección de Metal con Modos Detectores PLL, POS y un Circuito LC ....................................... 176 Tiempo de Estudio......................................................................................................................... 184 APÉNDICE A: LISTA DE OBJETOS CÓDIGO.................................................................................. 191 FullDuplexSerialPlus.spin .............................................................................................................. 191 SquareWave.spin .......................................................................................................................... 198 APÉNDICE B: SOLUCIONES DE ESTUDIOS .................................................................................. 199 Soluciones de la Practica E/S y Tiempo........................................................................................ 199 Soluciones al Estudio de la Practica Métodos y Cogs .................................................................. 205 Soluciones al Estudio de la Practica de Objetos ........................................................................... 207 Soluciones al Estudio de Módulos Contadores y Aplicaciones de Circuitos................................. 213 APÉNDICE C: LISTA DE COMPONENTES KIT PE ......................................................................... 223 APÉNDICE D: DIAGRAMA DE BLOQUE DEL MICRO CONTROLADOR ....................................... 225 APÉNDICE E: LM2940CT-5.0 LÍMITE DE CORRIENTE .................................................................. 226 Pagina 4 · Kit Educativo de Prácticas Propeller: Fundamentos Prefacio Prefacio Debido a que el micro controlador Propeller es un paquete DIP de 40 pins tiene sentido obtener un kit de componentes para uso con el Propeller en placas de prueba. Los circuitos de soporte para el Propeller, incluyendo memorias EEPROM, reguladores de voltaje, cristales osciladores, y herramientas de programación Propeller se encuentran en versiones que pueden ser conectadas a Placas de prueba así que porque no?. Tiene sentido desde el punto de vista de colegas y punto de vista de universidades proporcionar un kit que los estudiantes puedan adquirir, que es reusable, con un micro controlador que sobresale en una amplia gama de electrónicos, robótica y proyectos de sistemas integrados. Con esto en mente el PE DIP Plus Kit se ofrece como un paquete que incluye el micro controlador Propeller “mas” todos los otros componentes que puedes necesitar para hacerlo funcionar. El PE DIP Plus Kit tiene sentido para los compañeros que ya han utilizado placas de prueba y tienen alguna experiencia, pero que pasa con aquellos estudiantes que apenas completaron la clase de Que es un Micro controlador y su interés es alcanzar también el chip Propeller y su kit como tutorial? Con estos estudiantes en mente otro paquete de partes se ensamblo al igual que una serie de actividades que se ofrecen para trabajar con el Micro controlador Propeller. El paquete de partes termino con el nombre de Proyecto PE y las actividades del mismo es el Kit de Practicas PE El Kit de Prácticas PE se escribió primordialmente para colegas y estudiantes de universidades que tienen conocimientos previos y experiencia en programación y electrónica, preferentemente con micro controladores. Los temas introductorios incluyen: • • • • • Básicos de micro controladores tales como control de Entradas/Salidas y manejo del reloj Programación en tópicos como operadores, llamadas y objetos, así como direcciones variables Control de Multiprocesadores Programados Interacciones Micro controlador-Circuitos con luces indicadoras, botones de presión circuitos sensores de ambiente y que pueden ser medidos con circuitos RC, circuitos de frecuencia y circuitos selectores de frecuencia Tópicos avanzados que incluyen utilización de módulos contadores para desarrollar tareas en el fondo La intención de esta colección de Kit de Practicas PE es dar al lector un buen comienzo con la programación del chip Propeller y el uso en sus proyectos. Sin embargo este libro es solo un comienzo. Con el Kit de Practicas PE se introduce a todos los aspectos del micro controlador Propeller, adicionalmente existen practicas disponibles en línea. Más practicas y aplicaciones serán publicadas periódicamente. Este texto también incluye referencias a la riqueza de información disponible para el chip Propeller en el Manual de Propeller, Hoja de Datos Propeller, Foros de Propeller y Cambio de Objetos Propeller así como ejemplos para utilizar estos recursos. El lector es especialmente alentado a utilizar el Manual Propeller como una referencia mientras va a través de estos laboratorios. El contenido del Manual Propeller y el índice servirán de referencia para obtener más información acerca de cualquier tema introducido en estos laboratorios. Kit Educativo de Practicas Propeller: Fundamentos · Página 5 Prefacio Existe un foro para el Kit Educativo Propeller en forums.parallax.com con enlaces a las discusiones sobre cada laboratorio. Se invita al lector a utilizar este recurso para enviar preguntas sobre temas en los laboratorios Kit PE, así como comentarios y sugerencias. Parallax recopila estos comentarios y los incorpora en las futuras revisiones de cada laboratorio. Además, si usted (o sus alumnos) realizaron algún buen experimento con el Kit de PE, se publicara su proyecto documentado en los foros para que otros puedan ver lo que hizo y cómo lo hizo. Reconocimientos Parallaxianos: • Autor: Andy Lindsay, Ingeniero de Aplicaciones • Portada: Jennifer Jacobs, Director de Arte • Edición: Stephanie Lindsay, Editor Tecnico • Ilustraciones: Andy Lindsay, con ayuda de Rich Allred, Gerente de Producción • Fotografía: Rich Allred • Revisión: Jessica Uelmen, Asociado de Educación Comunidad Parallax – gracias a: • Aaron Klapheck por sus comentarios en el código ilustrado cog variable bookkeeping en el tema avanzado: dentro de métodos Start y Stop en la sección del laboratorio de objetos. • Estudiantes de la Universidad de California Davis y la Universidad Estatal de California en Sacramento quienes utilizaron el Kit PE en sus proyectos y propusieron grandes preguntas y presentaron reportes de errores. • Steve Nicholson por su crítica incisiva y profunda de los primeros borradores del Kit de Laboratorios PE. • Traducción al Español: Oscar Villarreal – FIX Ingeniería Pagina 6 · Kit Educativo de Prácticas Propeller: Fundamentos 1: Introducción al Microcontrolador Propeller 1: Introducción al Micro controlador Propeller Este capítulo proporciona datos generales del micro controlador Propeller y alguna información introductoria a las prácticas de Laboratorio y el Kit Educativo Propeller. Información más detallada del micro controlador Propeller, su arquitectura y lenguajes de programación pueden encontrarse en el Manual de Propeller y la Hoja de Datos del Propeller. Ambos están disponibles en la liga de descargas en www.parallax.com/Propeller. El Micro controlador Propeller El Micro controlador Propeller mostrado en la Figura 1-1 (a) es un chip sencillo con ocho procesadores integrados de 32 bits llamados cogs. En otras palabras los cogs pueden funcionar simultáneamente, pero la forma de trabajar ya sea independiente o en conjunto es definida en el programa. Algunos grupos de cogs pueden ser programados para trabajar juntos, mientras que otros trabajan en tareas independientes. Un sistema configurable de reloj proporciona a los cogs la misma señal de reloj (hasta 80MHz). La Figura 1-1 (b) muestra como cada cog toma su turno en la opción exclusiva del acceso leer/escribir de la memoria principal del chip Propeller a través del Hub. El acceso exclusivo leer/escribir es importante porque significa que dos cogs no pueden intentar modificar el mismo dato en memoria al mismo tiempo. También previene que un cog lea una dirección particular de memoria mientras que otro lo está escribiendo. Así el acceso exclusivo asegura que nunca existirán conflictos de acceso que puedan alterar los datos. Figura 1-1: Paquete de Micro controlador Propeller e interacciones Hub - Cog (a) Micro controladores Propeller en paquete de 40-pins DIP, TSOP y QFN (b) Extracto del diagrama de bloque del Propeller que describe la interacción de Hub y Cog. Ver Apéndice D: Diagrama de Bloque del 32 KB de la memoria principal del chip Propeller es RAM y se utiliza para el programa y almacenamiento de datos, otros 32KB son ROM y almacena útiles tablas tales como registro, anti registro, seno y tablas de caracteres gráficos. La ROM también almacena el código de arranque que es usado por el Cog 0 al inicializar e interpretar el código que cualquier cog puede usar para buscar y Kit Educativo de Practicas Propeller: Fundamentos · Página 7 Generalidades del Microcontrolador Propeller ejecutar alguna aplicación de la memoria principal. Cada cog tiene la habilidad de leer los estados de cualquiera o todos los 32 pins de Entrada/Salida del chip Propeller así como establecer sus direcciones y estados de salidas en cualquier momento. El diseño único de multiprocesamiento del chip Propeller genera una variedad de aplicaciones del micro controlador relativamente simples que de otra forma serian difíciles. Por ejemplo, los procesadores se pueden asignar a entradas de audio, salidas de audio, ratón, teclado y quizá TV o Pantalla LCD para crear un sistema de computo basado en micro controladores con procesadores de sobra para trabajar en tareas más convencionales tales como el monitoreo de entradas, sensores y control de salidas y actuadores. La Figura 1-2 (a) muestra un chip Propeller generador de una imagen de video que podría ser utilizada en algún tipo de aplicación. El Propeller también sobresale como controlador robótico, con la habilidad de asignar procesadores a tareas tales como control de motores DC a través de PWM, video procesador, matriz de sensores de vigilancia y alta velocidad de comunicación con robots cercanos y/o Computadoras Personales. La Figura 1-2 (b) muestra un ejemplo de un Robot Balanceado con sensores de video, el prototipo inicial fue desarrollado con un Kit Educativo Propeller. A pesar de que el chip Propeller es muy poderoso no significa que es difícil de usar. El chip Propeller se presenta de una manera manejable para proyectos simples tales como indicador de luces, botones, sensores, bocinas, actuadores y pantallas pequeñas encontrados en diseños comunes. Usted podrá ver algunos ejemplos de tales circuitos en el siguiente Kit Educacional de Laboratorio Propeller. Figura 1-2: Ejemplos de Aplicaciones (a) El Micro controlador Propeller genera graficas para mostrar en pantalla. Esta aplicación también usa un ratón estándar PS/2 para controlar las graficas (no mostrado). (b) Robot De Balance Hanno Sander, el prototipo inicial fue desarrollado con el Kit Educativo Propeller y el programa ViewPort. Foto cortesía de mydancebot.com. Aplicaciones con el chip Propeller Los programas para el Propeller son escritos usando una Computadora para posteriormente cargarlo en el chip típicamente a través de una conexión USB. Los lenguajes que soporta la herramienta de Programación incluyen lenguajes de alto nivel llamado Spin y lenguaje ensamblador de bajo nivel. Las aplicaciones desarrolladas en lenguaje Spin pueden contener opcionalmente código de lenguaje ensamblador. Estas aplicaciones se guardan en la computadora como archivos .spin Pagina 8 · Kit Educativo de Prácticas Propeller: Fundamentos 1: Introducción al Microcontrolador Propeller L Otros lenguajes de programación han sido desarrollados para programar el chip Propeller. Algunos son gratuitos y están disponibles a través de los recursos como los foros Parallax, otros están disponibles y pueden ser comprados o se puede obtener una versión limitada a través del sitio Parallax o con otras compañías que venden compiladores. Antes de que un cog pueda comenzar a ejecutar una aplicación Spin tiene que cargar un intérprete en memoria desde la ROM del chip Propeller (Figura 1-3 a). Las aplicaciones Spin son almacenadas en la memoria RAM principal como fichas lo cual hace que el cog vaya repetidamente a buscar y ejecutar (Figura 1-3 b & c). Algunos ejemplos de acciones del cog pueden basarse en los valores de las fichas como se muestra en la Figura 1-3 (c). Incluyen lectura/escritura a los registros de configuración, variables y pines de entrada/salida así como lectura de ROM. Los cogs pueden ejecutar códigos de maquina generados por lenguaje ensamblador. Como se muestra en la Figure 1-4, estos códigos de maquina son cargados en los cogs de 2KB (512 longs) de memoria RAM y ejecutados en alta velocidad, hasta 20 millones de instrucciones por Segundo (MIPS). La RAM del cog no utilizado por instrucciones maquina puede proporcionar memoria de alta velocidad para el cog con cuatro ciclos de reloj (50ns a 80MHz) por lectura/escritura. Figura 1-3: Cog Interpretando Lenguaje Spin (Hub) Memoria Principal (Hub) Memoria Principal 32 Configuracion KB R A M 32 KB R O M (Hub) Memoria Principal Configuracion Aplicacion R A M Pila + VAR Conjunto de Caracteres Buscar/Ejecutar Registro, Antiregistro y Tablas Arranque Interprete (a) Interprete cargado en el cog desde la memoria ROM principal a través del Hub Aplicacion R O M R A M Pila+ VAR Conjunto de Caracteres COG Configuracion Arranque Interprete (b) El Cog busca la ficha desde la memoria RAM principal Pila + VAR Conjunto de Caracteres COG Registro, Antiregistro y Tablas Aplicacion R O M Registro, Antiregistro y Tablas Arranque Interprete COG E/S (c) El Cog ejecuta la ficha. Ejemplos incluyen RAM, E/S o Lectura/Escritura o Lectura ROM Un Cog Ejecutando lenguaje ensamblador puede accesar de igual forma a la memoria principal del Propeller a través del Hub. El Hub garantiza el acceso a la memoria principal a los Cogs cada 16 ciclos de reloj. Dependiendo de cuando el Cog decide verificar la memoria principal el tiempo de acceso puede ser entre 7 y 22 ciclos de reloj lo cual equivale, al peor escenario de tiempo de acceso a la memoria, a 275ns a 80 MHz. Después del primer acceso el lenguaje ensamblador puede sincronizarse con el Cog alternándose en una ventana de acceso a la memoria principal manteniendo los subsecuentes accesos a un ciclo fijo de 16 ciclos de reloj (200ns). Kit Educativo de Practicas Propeller: Fundamentos · Página 9 Generalidades del Microcontrolador Propeller (Hub) Memoria Principal Configuracion R A M Aplicacion Conjunto de Caracteres R O M 4 ciclos de reloj Pila + VAR Registro, Antiregistro y Tablas Arranque Interprete ASM 7 a 22 Ciclos de reloj, 16 ciclos una vez sincronizado Cog RAM 2 KB (512 largo) Figure 1-4: Cog Ejecutando Lenguaje Ensamblador COG Debido a que cada Cog tiene acceso a la memoria principal RAM del chip Propeller los Cogs pueden trabajar en conjunto intercambiando información. El lenguaje Spin tiene características incorporadas para pasar direcciones de una o más variables usadas en código a otros objetos y Cogs. Esto hace la cooperación entre Cogs muy sencilla. El código en un Cog puede ejecutar código en otro Cog y pasarle una o más direcciones variables (ver Figure 1-5). Estas direcciones variables pueden ser utilizadas por dos Cogs para intercambiar información. Main (Hub) Memory Configuracion R A M Aplicacion Pila + VAR COG Figure 1-5: Dos (o más) Cogs trabajando en conjunto a través de memoria compartida. Conjunto de Caracteres R O M COG Registro, Antiregistro y Tablas Arranque Interprete Los Cogs del chip Propeller están numerados del Cog 0 al Cog 7. Una vez que la aplicación se carga en el chip Propeller este carga un intérprete en Cog 0 y este interprete comienza a ejecutar las fichas del código Spin almacenadas en la memoria principal. Entonces los comandos en el código Spin pueden ejecutar bloques de código (que puede ser Spin o Lenguaje Ensamblador) en otros Cogs como muestra la Figure 1-6. El código ejecutado por otros Cogs puede ejecutar otros Cogs no importando si es Spin o Código Ensamblador y ambos lenguajes pueden parar otros Cogs para poner fin a procesos innecesarios o incluso para sustituirlos con otros diferentes. Pagina 10 · Kit Educativo de Prácticas Propeller: Fundamentos 1: Introducción al Microcontrolador Propeller 2 1 0 COG COG 3 COG COG 4 Figure 1-6: Arranque de Cogs El código en un Cog puede poner en marcha otros Cogs el cual puede poner en marcha otros… Los Cogs también pueden parar otros Cogs para liberarlos y usarlos en otras tareas. COG Escribiendo Código de Aplicaciones Spin es un lenguaje de programación basado en objetos. Los objetos son diseñados para construir bloques o una aplicación y cada archivo .spin puede ser considerado un objeto. Mientras que la aplicación puede ser desarrollada como un objeto simple (un programa), las aplicaciones son comúnmente una colección de objetos. Estos objetos pueden proporcionar una variedad de servicios. En los ejemplos se incluyen soluciones que de otra forma complicaría el código, la comunicación con los periféricos, control de actuadores y monitoreo de sensores. Esta construcción de objetos bloque son distribuidos a través del objeto de intercambio Propeller (obex.parallax.com) y también en el archivo de librería en la herramienta de programación Propeller. Incorporando estos objetos preescritos en una aplicación puede reducir su complejidad y tiempo de desarrollo significativamente. La Figura 1-7 muestra como los objetos se pueden utilizar como aplicaciones al construir bloques, en este caso, para un robot que mantiene una distancia entre si y un objeto que esta sensando. El código de aplicación en el siguiente objeto Robot.spin hace que el uso de objetos pre-escritos para detección infrarroja (IR Detector.pin) controle los cálculos del sistema (PID.spin) y controle el motor (Servo Control.spin) Note que estos objetos pre-escritos pueden usar otros objetos por turnos para hacer sus tareas. En vez de generar objetos para hacer trabajos en tu aplicación puede también escribirlos como borradores y si se convierten en útiles puede enviarlos para que se publiquen en el Intercambio de Objetos Propeller en obex.parallax.com. Kit Educativo de Practicas Propeller: Fundamentos · Página 11 Generalidades del Microcontrolador Propeller Archivo Objecto Arranca un cog Solo Codigo Spin Figura 1-7: Construcción de Bloques Objetos para Aplicaciones Arranca un cog Spin + Ensamblador En la Figura 1-7, el objeto Following Robot.spin se identifica como archivo objeto inicial. Este archivo es la primera línea de código ejecutable donde el chip Propeller comienza cuando la aplicación corre. En cada caso el Cog 0 arranca y comienza ejecutando código del objeto superior. Nuestro objeto superior en el ejemplo Following Robot.spin contiene código que inicializa 3 objetos debajo del, convirtiéndolo en “objeto padre” de los tres. Dos de estos tres bloques en su turno inicializan un “objeto hijo” construyendo bloques de sí mismos. Dos de los bloques objetos construidos inicializan Cogs adicionales para hacer sus tareas así que un total de tres Cogs se utilizan en esta aplicación. Independientemente de si un objeto padre comienza un Cog en Spin o Ensamblador los objetos hijos tienen un sistema integrado y documentación que proporciona una interface simple con su padre para controlar o monitorear. A pesar de que no se muestra en la figura recuerde de la Figure 1-6 que un objeto puede inicializar más de un Cog. También un objeto puede inicializar un proceso en un Cog y puede terminarlo nuevamente para dejarlo disponible a otros objetos. A pesar de que cualquier objeto puede inicializar y detener un Cog es una buena práctica hacer responsable de parar al Cog al Objeto que lo inicializo. Como se ejecuta el código en el chip Propeller La herramienta de programación Parallax puede utilizarse para desarrollar aplicaciones en el chip Propeller. Cuando una aplicación se carga en el chip Propeller el código Spin se compila en los ficheros y el Código Ensamblador opcional se compila en códigos maquina. La herramienta Propeller transfiere la aplicación al chip Propeller típicamente con una conexión serie USB. El programador puede escoger cargarlo directamente en la memoria RAM principal del chip Propeller o en una EEPROM (Memoria de Solo Lectura Eléctricamente Borrable Programable por sus siglas en Ingles). Como se muestra en la Figura 1-8, si el programa se carga directamente en la RAM el chip Propeller lo ejecuta inmediatamente. Si el programa se carga en la EEPROM el chip copia la información a la RAM antes de comenzar la ejecución. Pagina 12 · Kit Educativo de Prácticas Propeller: Fundamentos 1: Introducción al Microcontrolador Propeller Figura 1-8: Cargando un Programa en RAM o EEPROM Codigo Propeller Codigo Propeller Copia a EEPROM Carga de EEPROM después limpia. Seria sobre USB Serie sobre USB (a) Cargar Programa directo en RAM Propeller (b) Cargar el Programa en EEPROM Cargar programas de una Computadora a la RAM toma alrededor de 1 segundo mientras que la carga de programas a EEPROM toma algunos segundos (abajo de 10 segundos en la mayoría de los casos). Mientras que cargar programas en RAM puede ser más rápido para probar resultados de cambios durante el diseño del código los programas deberían estar cargados en EEPROM cuando la aplicación es finalizada o si se espera que comience después de un ciclo de encendido o re inicialización. Los programas cargados en RAM son volátiles, lo que significa que se pueden borrar por una interrupción de corriente o reinicializado del chip Propeller. En contraste los programas cargados en EEPROM no son volátiles. Después de un ciclo de encendido el chip Propeller copia el programa de la EEPROM en la RAM y comienza a ejecutarse nuevamente El Kit Educativo Propeller El Kit Educativo Propeller (PE) es un sistema de desarrollo completo de micro controlador Propeller que puede usarse para proyectos y productos prototipo. Este kit incluye partes para proyectos y están documentados en el kit de prácticas PE. Estas prácticas le ayudaran a aprender cómo desarrollar aplicaciones con el micro controlador Propeller. Figura 1-9: Kit Educativo Propeller (Versión 40-Pin DIP) Kit Educativo de Practicas Propeller: Fundamentos · Página 13 Generalidades del Microcontrolador Propeller El Kit PE viene en dos versiones diferentes: 40-Pin DIP y PropStick USB. Ambos cuentan con un sistema para conectar a placas de prueba con las siguientes partes montadas en ellos: • • • • • • • • Micro controlador Propeller Reguladores de Voltaje 5.0 V y 3.3 V EEPROM para almacenamiento de programas no volátiles Cristal externo oscilador de 5.00 MHz para señal precisa Botón de reinicio para arranques manuales Indicador de Potencia LED Batería 9 V para conectar a placas de prueba Conexión USB-Serie para descargas y comunicación bidireccional con la computadora En conjunto, las placas de interconexión con el micro controlador Propeller montado se les refieren en este documento como Plataforma PE. La Plataforma PE con el kit de 40-pins DIP se muestra en la Figura 1-10 (a). Con esta plataforma, cada parte y circuito en la lista mencionada arriba se conecta directamente en la placa de prueba. Aunque para esta versión de la plataforma PE se toma un poco de tiempo construirla y probarla la ventaja es que cualquier parte puede ser reemplazada a un bajo costo. La Plataforma PE con la Conexión USB se muestra en la Figura 1-10 (a). La conexión USB es un pequeño circuito impreso con versiones de montaje de superficie de todas las partes y circuitos listados (excepto el circuito regulador de 5V). La tarjeta tiene pins por lo que puede ser conectada en la tarjeta de prueba. Mientras que este arreglo hace más rápida la conexión de la Plataforma PE para comenzar a trabajar puede ser relativamente costoso reemplazar la conexión USB en vez de los componentes individuales si alguna vez se dañan. Figura 1-10: Plataformas PE (a) Versión 40-pin DIP (b) Versión conexión USB Pagina 14 · Kit Educativo de Prácticas Propeller: Fundamentos 1: Introducción al Microcontrolador Propeller Practicas para el Kit Educativo Propeller Las prácticas del Kit Educativo Propeller están incluidas en este texto y de igual forma existen prácticas adicionales disponibles para descargar desde www.parallax.com. Las prácticas en este texto muestran como conectar circuitos al micro controlador Propeller y como escribir programas para interactuar con los circuitos. Los programas también utilizan algunas características del lenguaje Spin así como algunas capacidades de multiprocesamiento del micro controlador. Prerrequisitos En estas prácticas se asume experiencia previa con micro controlador. A pesar de que las prácticas incluyen diagramas de conexión para el arranque y prueba el resto no. Como mínimo deberá tener experiencia construyendo circuitos a partir de esquemáticos así como experiencia en lenguaje de programación de algún micro controlador o computadora. L Recursos para principiantes: Para una introducción de cómo construir circuitos, micro controlador, programación y mucho mas “antes de una experiencia con micro controladores” puede probar el Kit de actividades BASIC Stamp o el Kit Descubriendo BASIC Stamp. Ambos kits tienen todo lo que usted necesita para comenzar incluyendo un micro controlador BASIC Stamp 2, tarjeta de prueba, el nivel básico de Que es un Micro controlador? y partes para cada actividad. El texto Que es un micro controlador? está disponible gratuitamente en formato PDF desde www.parallax.com y ambos kits están disponibles a la venta desde el sitio web o con algún distribuidor. Para encontrar algún distribuidor cerca de usted verifique la lista de distribuidores bajo la categoría de Compañía en el sitio web de Parallax. Practicas del Kit PE en este texto • • • • • • Programas Documentación y Recursos – Descargue la documentación y el programa, instale el programa. Inicio y Pruebas para Plataforma PE 40-Pin DIP – Preparación del equipo. Si usted tiene la versión USB en el kit PE, utilice el método alternativo. Es gratuito descargándolo de la página de producto en www.parallax.com. Practica básica de E/S y tiempo – Como configurar las E/S del chip Propeller, señales de entrada a monitor, señales de transmisión de salida y coordinación los eventos basado en el sistema de reloj. Practicas de Métodos y Cogs – Como escribir métodos en Spin y arranque de métodos opcionales en uno o más de los chips Propeller (procesadores). Objectos – Como utilizar objetos pre-escritos para simplificar tareas y como escribir objetos. Módulos Contadores y Aplicaciones de Circuitos – Como emplear los módulos contadores generados en cada Cog para desarrollar procesos de control y medición que requieren tiempo preciso. (Cada Cog tiene dos módulos contadores que pueden funcionar en paralelo con la secuencia del programa). Las últimas cuatro practicas (E/S, Tiempo, Módulos Contadores y Aplicaciones de Circuitos) tienen preguntas, ejercicios y proyectos al final de cada capítulo con respuestas en el Apéndice B: , empezando en la pagina 199. Para mejores resultados inserte manualmente los ejemplos de código según vaya avanzando en las prácticas. Con esto va a darle tiempo a su mente para examinar cada línea de código junto con los conceptos y técnicas introducidas en las diversas secciones de cada laboratorio. Kit Educativo de Practicas Propeller: Fundamentos · Página 15 Generalidades del Microcontrolador Propeller Mas practicas del Kit PE y aplicaciones en línea Para encontrar practicas adicionales y aplicaciones para desarrollar en los conceptos de este libro visite forums.parallax.com → Propeller → Propeller Education Kit labs. Usted encontrara ligas a archivos PDF y discusiones de cada una de las practicas en este texto así como material adicional, como la practica Extractos de ViewPort mostrada en la Figura 1-11. Algunas de estas prácticas utilizan partes del Kit PE y otras requieren partes adicionales las cuales puede encontrar en su mayoría en Parallax o con algún otro proveedor de componentes electrónicos. Figura 1-11: Practica Extractos de ViewPort Señales de Osciloscopio y Analizador de Espectro generadas por un micrófono mientras alguien esta silbando. El micro controlador Propeller muestrea estas señales y las envía el programa ViewPort en la Computadora Personal. Esta es una de las actividades que aparecen en las prácticas de ViewPort. Pagina 16 · Kit Educativo de Prácticas Propeller: Fundamentos 2: Programas, Documentación y Recursos 2: Programas, Documentación y Recursos Las herramientas de programación Propeller y la terminal serial Parallax mostradas en la Figure 2-1 son descargas gratuitas desde www.parallax.com. Usted necesitara estas herramientas para escribir programas y lograr una comunicación bidireccional entre la Computadora Personal y el chip Propeller. En la misma página junto con la herramienta de programación usted encontrara diferentes documentos de referencia y los programas ejemplos para estas prácticas. Este capítulo incluye instrucciones para descarga e inicialización de estos productos así como apuntadores a otros recursos útiles para desarrollar proyectos y prototipos con micro controladores Propeller. Figure 2-1: Herramienta Propeller y Terminal Serial Parallax Descarga de Software y Documentación En esta práctica usted usara la herramienta de programación Propeller, la Terminal Serial Parallax y el Manual de Propeller. Estos elementos junto con la hoja de datos del micro controlador Propeller están en una sola página en www.parallax.com. 3 Ir a www.parallax.com/go/PEKit → Downloads & Resources. 3 Descargar los siguientes componentes y colocarlos en una carpeta adecuada. o Propeller Tool Software v1.2 o mas nueva. Requerimientos del sistema: Windows 2000/XP/Vista y un puerto USB disponible. o Programa Parallax Serial Terminal o Manual Propeller o Hoja de Datos Propeller o Código Fuente – para Practicas del Kit Educacional Propeller: Fundamentos (.zip) o Libro – Practicas Educativas Propeller: Fundamentos (.pdf) o Si usted está utilizando la versión PropStick USB del kit de PE, asegúrese de localizar a su instalación independiente y prácticas en formato PDF Una de las herramientas Propeller incluida por defecto en el Kit PE es el controlador USB para programación/comunicación/depuración. Cuando instala la herramienta de programación automáticamente se instalaran los controladores que necesitara para comunicarse con la herramienta de programación Propeller en su Computadora. Estos son controladores FTDI’s VCP USB para Windows 2000/XP/Vista/7. Usted también podrá obtener los controladores desde www.ftdichip.com. 3 Instale la herramienta de programación cargando el programa de arranque y siguiendo las instrucciones. Cuando usted se encuentre en el paso de instalar las opciones de controladores mostrado abajo asegúrese de marcar la casilla Instalar/Actualizar automáticamente controladores. Kit Educativo de Practicas Propeller: Fundamentos · Página 17 Programas, Documentación y Recursos ! Deje esta casilla marcada! Usted podrá observar este paso durante la instalación del Software Propeller. El controlador opcional se requiere para estas prácticas. Es necesario para los circuitos Serial sobre USB construidos en el Propeller Plug y USB PropStick ! Instalar la Terminal Serial Parallax La terminal serial Parallax es una aplicación ejecutable independiente que puede ser utilizada para intercambiar mensajes con el chip Propeller mientras está corriendo. Además de mejorar algunos de los ejemplos del Kit PE con mensajes de texto para indicar el estado y los valores, también puede ser útil para registro de datos rudimentarios y la depuración. A pesar de que es una aplicación independiente, es conveniente realizar una sola copia de la misma y colocar un enlace al lado del programa que va a utilizar para abrir la herramienta de programación del Propeller. 3 Desempaque la Terminal Serial Parallax en la carpeta donde se instalo la herramienta de programación Propeller. La localización por defecto en la Versión 1.2 es C:\Program Files\Parallax Inc\Propeller Tool v1.2. 3 Genere un icono de inicio a la Terminal Serial Parallax junto al icono de inicio de la herramienta de programación Parallax. Sitios Web útiles Además de www.parallax.com/go/pekit, hay un par de sitios web donde puede obtener respuestas tanto a las preguntas como a los objetos para reducir el tiempo de desarrollo en proyectos Propeller. • Página principal del Propeller chip: www.parallax.com/Propeller. • Intercambio de Objetos: http://obex.parallax.com • Foro del Chip Propeller: http://forums.parallax.com → Propeller Recursos y Soporte Técnico Parallax Inc. ofrece diversos caminos para soporte técnico: • Correo Electrónico: support@parallax.com • Fax: (916) 624-8003 • Teléfono: Llame gratis dentro de U.S: (888) 99-STAMP; o (916) 624-8333. Por favor llame entre 7:00 am y 5:00 pm Hora del Pacifico o en su defecto deje un mensaje. • Foros: http://forums.parallax.com/forums/. Aquí encontrara un foro activo dedicado al chip Propeller frecuentado por clientes y empleados de Parallax. Pagina 18 · Kit Educativo de Prácticas Propeller: Fundamentos 3: Configuración y Prácticas de Laboratorio 3: Inicio y Pruebas para Plataforma PE 40-Pin DIP Este es el programa de instalación y Prueba para la versión 40-pin DIP del Kit PE. 3 Si usted tiene la versión del Kit PE 40-Pin DIP (#32305) continúe aquí. 3 Si usted tiene la versión PropStick USB del Kit PE (#32306) verifique la versión impresa de instalación y pruebas del PropStick USB incluida con su Kit. También existe una descarga gratuita del producto 32306 en www.parallax.com La Plataforma PE El Kit Educativo Propeller (PE) que se muestra en la Figura 3-1 es una gran herramienta prototipo para proyectos de electrónica y robótica. Es también un punto de arranque para aprender los básicos de la programación del micro controlador Propeller para ser integrado como el cerebro de computadora en su próximo invento. Esta práctica lo introduce a la Plataforma PE, sus componentes y características y lo guía a través del ensamble y prueba de su Plataforma PE. Figura 3-1: Kit Plataforma PE (Versión 40-Pin DIP) La Plataforma PE que se muestra en la Figura 3-1 es un arreglo de placas de prueba conectado entre sí con el micro controlador Propeller, circuitos de soporte y componentes montados en el centro. Cada proyecto construido a la derecha o izquierda será adyacente a los pins de E/S del Propeller para fácil acceso. Cada tarjeta de prueba tiene conectores de voltaje en ambos lados por lo que cada punto a tierra y 3.3 V están junto a la placa. Este arreglo hace a la mayoría de los circuitos sencillos de conectar y analizar. También minimiza el espagueti de cables y problemas de que pueden ocurrir. Kit Educativo de Practicas Propeller: Fundamentos · Página 19 Configuración y Prácticas de Laboratorio Componentes de la Plataforma PE y Características La Figura 3-2 muestra los mayores componentes de la plataforma de 40-Pin DIP PE incluyendo: • • • • • • • • Micro controlador Propeller con calcomanía de mapa de pins incluido. Batería 9 V con conector a placa de prueba Reguladores 5.0 V y 3.3 V Indicador LED Botón para reinicio manual de programa Cristal Oscilador Externo de 5.00 MHz para señal de reloj preciso EEPROM de 32 KB no volátil para almacenamiento de programas Herramienta de conexión Propeller de programación y comunicación para descargas y comunicación bidireccional con la Computadora Personal. Figura 3-2: Componentes del Kit de la Plataforma PE Bateria 9V con conector a placa de prueba Regulador de Voltaje 3.3 V Cable USB Regulador de Voltaje 5.0 V Indicador LED Herramienta de Comunicacion y Programacion Propeller Boton de Reinicio Microcontrolador Propeller + Calcomania del Mapa de Pins EEPROM de 32 KB Cristal Oscilador de 5 MHz Micro controlador Propeller Un micro controlador Propeller en un paquete de 40-Pins DIP proporciona un cerebro amigable para la Plataforma PE. Este increíble micro controlador tiene ocho procesadores, llamados Cogs, su sistema de reloj puede correr hasta 80MHz y cada Cog puede ejecutar hasta 20 millones de instrucciones por segundo (MIPS). Cada Cog toma su turno de acceso a la memoria principal del chip Propeller. Este acceso de memoria combinado con los lenguaje Spin (Alto Nivel) y Ensamblador (Bajo Nivel) creados especialmente para el Propeller hace la escritura de código muy simple y directa. Si usted ha escrito una subrutina en BASIC y una subrutina “Call” (o una función de C y la función “Call”, o un método Java y el método “Call”) hacer que un procesador ejecute esa subrutina, función o método toma solo dos pasos más. Usted verá muchos ejemplos en estas prácticas del Kit PE. Hoja de Datos y Manual del Propeller L La hoja de Datos del Propeller proporciona una descripción completa del micro controlador Propeller y el Manual explica la programación del chip y el lenguaje a detalle. Ambos están disponibles para descarga en formato PDF desde www.parallax.com La versión impresa del Manual Propeller también está disponible a la venta en el sitio web de Parallax (#122-32000). Pagina 20 · Kit Educativo de Prácticas Propeller: Fundamentos 3: Configuración y Prácticas de Laboratorio Botón de Reinicio El Botón de reinicio se puede presionar y soltar para reiniciar la ejecución de un programa. También se puede presionar y sostener para finalizar la ejecución. Cuando se suelta el chip Propeller cargara el programa almacenado en la plataforma EEPROM y reiniciara desde el principio. Batería 9 V para el conector de las placas de prueba Este pequeño componente proporciona una conexión de la fuente de poder a la tarjeta de prueba. El voltaje DC recomendado a través de VIN-VSS es de 6 a 9.5VDC y la fuente de poder recomendada para VIN-VSS incluye: • • Baterías alcalinas de 9 V Baterías recargables de 9 V (rangos de voltajes incluyen 9V, 8.4V y 7.2 V) Siempre desconecte la batería del conector y almacene por separado. Las Baterías de 9V nunca deberán almacenarse en la caja de plástico del Kit PE ya que las partes sueltas podrían causar corto en las terminales. La Batería de 9V deberá desconectarse del conector de la placa de prueba y debe almacenarse donde las terminales no pueden causar corto a través de cualquier objeto metálico o algún otro material conductivo. L “Wall Warts”: Este término describe comúnmente los transformadores DC que se conectan a través de contactos AC y normalmente proporcionan un voltaje mucho más alto de lo que se menciona. Si va a usar una conexión de este tipo es conveniente escoger una que esta regulada a 6V DC con una capacidad de corriente de 500 mA o más. El Kit PE DIP Plus incluye un capacitor de 47uF que puede ser colocado a través de la entrada de la batería en la placa de prueba para proporcionar la capacitancia de entrada requerida por la el regulador de Voltaje de la Plataforma PE debido a la línea de suministro de la conexión. Regulador 5.0 V El regulador de National Semiconductor LM2940CT-5.0 está incluido en la Plataforma PE para proporcionar 5V a los componentes tales como detector infrarrojo introducido en los módulos contadores y prácticas. Una resistencia en serie (típicamente 10kΩ) deberá estar conectada entre la salida 5V y el pin de entrada del Propeller el cual es 3.3V. El regulador de 5V también sirve como etapa intermediaria entre la batería y el regulador 3.3V que alimenta al chip Propeller. El regulador de voltaje LM2940 está diseñado para proporcionar 400mA de corriente usando una batería de 9V en laboratorio (a temperatura ambiente). Este presupuesto de corriente puede variar con el voltaje y la temperatura. Por ejemplo si el voltaje se reduce de 9V a 7.5V la corriente se incrementa cerca de los 700mA a temperatura ambiente. Otro ejemplo es si el voltaje es de 9V pero la temperatura sube a 40º C la corriente caerá hasta aproximadamente 350mA. Más información: L • • Apéndice E: LM2940CT-5.0 Límite de Corriente a partir de la página 226 se incluyen ecuaciones que puede usar para predecir las Corrientes del Regulador de 5V bajo varias condiciones de temperatura y voltaje. La hoja de datos del LM2940CT disponible en www.national.com, tiene mucho más información, incluyendo apuntadores para agregar disipadores de calor para incrementar su funcionalidad mejorando la habilidad de disipar el calor. Regulador 3.3 V Este regulador de National Semiconductor LM2937ET-3.3 puede obtener hasta 400 mA del LM2940 (Regulador 5V) a temperatura ambiente y proporcionar 3.3V al sistema con 360mA de corriente. Considere que si usted tiene un circuito de 5V que consume potencia, esta se restara de los 400mA de la salida del regulador el cual otorgara una menor cantidad de corriente al regulador de 3.3V y a su vez este proporcionara menor corriente al resto del sistema. Kit Educativo de Practicas Propeller: Fundamentos · Página 21 Configuración y Prácticas de Laboratorio Indicador LED Esta luz se ilumina para indicar que el sistema esta energizado. También puede indicar baterías bajas, cortos circuitos y hasta puede indicar si la herramienta de comunicación Propeller está conectada. Según conexiones en esta práctica consume hasta 12mA. Después de completar esta práctica usted puede usar una resistencia mayor para una menor iluminación y menor consumo de corriente. Cristal Oscilador de 5.00 MHz El cristal oscilador de 5.00 MHz proporciona una señal precisa de reloj al chip Propeller que se puede usar para aplicaciones sensitivas al tiempo tales como comunicación serial, mediciones RC y Servo Control. El chip Propeller tiene un circuito integrado de bucle cerrado que puede utilizar la señal de reloj de 5MHz para generar frecuencias de 5, 10, 40 y hasta 80MHz El oscilador de 5MHz puede ser reemplazado con una variedad de otros osciladores. Algunos ejemplos incluyen un oscilador programable y un cristal de 60MHz. El chip Propeller tiene integrado un oscilador RC que puede usarse en modo rápido o lento (aproximadamente 12MHz y 20kHz respectivamente). El oscilador interno no es tan preciso como el de 5MHz así que si su proyecto contiene tareas sensitivas al tiempo tales como comunicación serial, modulación de pulso para servo control o generación de señales de TV asegúrese de utilizar el oscilador externo. EEPROM de 32 KB La plataforma PE de almacenamiento de datos y programa es no volátil, lo cual significa que no puede borrarse al presionar y soltar el botón de reinicio o desconectando la fuente de poder. Esta memoria EEPROM no debe tratarse como RAM ya que cada una de sus celdas de memoria es útil solo para 1 millón de ciclos de lecto/escritura. Después de eso las celdas se desgastan y no serán confiables para almacenar valores. Así que si un programa modifica una EEPROM cada segundo esta se gastara en tan solo 11.6 días. De otra forma si la celda se modifica cada 10 minutos servirá por hasta 19 años. L EEPROM: Memoria de Solo Lectura Borrable y Programable Eléctricamente (Por siglas en ingles) RAM: Memoria de Acceso Aleatorio. Tenga en cuenta que su aplicación puede usar la memoria principal del chip Propeller (de la cual 32KB son RAM) para escribir infinitamente a cualquier frecuencia. Por lo tanto puede usar la EEPROM como respaldo de datos que la aplicación necesite posteriormente, especialmente si los datos se utilizaran después de reconectar la fuente de poder. La aplicación de solicitud de registro de datos EEPROM (disponible en www.parallax.com → Propeller → Downloads & Articles) presenta un objeto para respaldar periódicamente los valores almacenados en RAM a la EEPROM. Herramienta de Programación y Comunicación Propeller El Propeller Plug proporciona una conexión Serial sobre USB entre en chip Propeller y la Computadora para programar, comunicar y limpiar. El LED azul indica la recepción de mensajes desde la Computadora, mientras que el LED rojo indica los mensajes transmitidos a la PC. El chip FTDI etiquetado como FT232 en el modulo convierte la señal USB de la computadora en señales seriales de 3.3Vpara el chip Propeller y viceversa. En el lado de la computadora un controlador de puerto virtual COM proporcionado por FTDI se incluye con la herramienta de programación Propeller. Fuera de ser necesario para cargar programas en el chip Propeller, el puerto virtual hace conveniente la comunicación con programas seriales tales como la Terminal Serial Parallax. Pagina 22 · Kit Educativo de Prácticas Propeller: Fundamentos 3: Configuración y Prácticas de Laboratorio Más información del Puerto virtual COM L Después de instalar el Puerto virtual COM de FTDI a través de la herramienta Propeller cualquier Propeller Plug que se conecte a uno de los puertos USB aparecerá como “USB Puerto serie (COMxx)” en la lista del Administrador de Puertos de Windows (COM y LPT). El controlador FTDI convierte los datos colocados en el puerto serial a USB y lo envía al chip FT232 en el Propeller Plug y los mensajes del FT232 se convierten en datos seriales y se almacenan en el puerto COM de recepción. Los programas de comunicación serial tales como la Terminal Serial Parallax utilizan esta forma de comunicación para intercambiar información con los dispositivos seriales periféricos. Prerrequisitos Por favor siga las instrucciones en el programa, documentación y recursos que comienzan en la página 17 antes de continuar aquí. Descripción General En estas prácticas usted ensamblara la plataforma PE Versión 40-Pin DIP) siguiendo los pasos listados abajo. Es importante seguir las instrucciones en cada paso cuidadosamente, especialmente porque usted conectara su propia plataforma (en la placa de prueba) en vez de solo conectar el micro controlador Propeller. • • • • • • • • • • Inventario de Equipo y Partes Ensamble de las placas de prueba Configuración y Reguladores de Voltaje de la Plataforma PE Prueba del cableado de la Plataforma PE Conexión del chip Propeller y la EEPROM Conectar el Propeller Plug a la Computadora y a la Plataforma PE Conecte la Prueba de Cargar el programa y probar los pins de E/S Solución de problemas para el arranque de la Plataforma PE de 40 pins-DIP (si es necesario) Debido a que la Plataforma PE será el sistema micro controlador en el corazón de las prácticas del Kit PE, todas las conexiones eléctricas deberán probarse antes de continuar con las prácticas. Seguir estos pasos le ayudara a descartar posibles errores de conexiones que pueden pasar fácilmente inadvertidos durante el ensamble de los circuitos de la Plataforma PE y causar problemas inesperados mas tarde. Kit Educativo de Practicas Propeller: Fundamentos · Página 23 Configuración y Prácticas de Laboratorio Inventario de Equipo y Partes Requerido: • Computadora con Microsoft Windows 2000, XP, o Vista y un Puerto USB disponible • Batería alcalina de 9V (Para esta configuración y pruebas utilice una batería alcalina nueva) • Los kits PE que se encuentran listados en las tablas siguientes: Set de Placas de Prueba (#700-32305), Propeller Plug (#32201), y Kit Propeller DIP Plus (130-32305) Opcional pero útil: • Pinzas pequeñas y cortadoras/peladoras de cable • Multímetro (DC + AC Voltímetro y Óhmetro) • Osciloscopio Digital, similares al Osciloscopio USB de Parallax (#28014) • Brazalete y Tapete antiestático Precauciones ESD: Las Descargas Electrostáticas (ESD) pueden dañar los circuitos integrados (ICs) de este kit. Si usted tiene un brazalete y tapete úselo. Si no los tiene una manera conveniente de eliminar cargas estáticas periódicamente es con el chasis de una Computadora conectada a tierra física. La parte del chasis típicamente expuesta es la parte trasera. El monitor y equipos periféricos normalmente están conectados al marco metálico con tornillos. Toque el marco expuesto (no los puertos) antes de abrir una bolsa antiestática y posteriormente hágalo mientras maneja las partes. ! Estos son algunos consejos para reducir la posibilidad de una descarga en las partes del kit PE: Evite tocar los pins en los Circuitos Integrados. Maneje los circuitos en sus bolsas o cajas. Si usted sabe que su área de trabajo es propensa a cargas estáticas busque otra área de trabajo con menos problemas de estática. De igual forma si usted observa que un suéter genera cargas en una silla no utilice ese suéter mientras traba con la Plataforma PE. 3 Junte los componentes mencionados en la Tabla 3-1, Tabla 3-2, y la Tabla 3-3. 3 Abra la bolsa de partes del Proyecto PE y verifique su contenido contra la lista de partes de la Tabla C-2 del Apéndice C: Lista de Componentes kit PE. Tabla 3-1: Set de Placas de Prueba (#700-32305) 700-00077 3 Placa de Prueba, 12x30 Conexiones, 3.19" x 1.65" 700-00081 4 Placa de Prueba, 2x24 Conexiones, 3.19" x 0.5" Tabla 3-2: Propeller Plug (#32201) 32201 1 Propeller Plug 805-0010 1 Cable Retráctil USB A a Mini B Pagina 24 · Kit Educativo de Prácticas Propeller: Fundamentos 3: Configuración y Prácticas de Laboratorio Tabla 3-3: Kit Propeller DIP Plus (130-32305) Número de Parte Cantidad 571-32305 1 Conexión de Batería 9V 201-01085 2 Capacitor, Electrolítico, 6.3 V, 1000 µF 201-04740 1 Capacitor, Electrolítico, 25 V, 0.47 µF 150-01011 1 Resistencia, CF, 5%, 1/4 watt, 100 Ω 150-01030 1 Resistencia, CF, 5%, 1/4 watt, 10 kΩ 251-05000 1 Cristal 5.00 MHz, 20 pF, HC-49/µs 350-00001 1 LED Verde T1 ¾ 400-00002 1 Botón – normalmente abierto 451-00302 1 Conector 2-pin m/m 451-00406 1 Conector extendido 90º m/m 4 pin espaciado de 0.1” 601-00513 1 Regulador 3.3 V, Paquete TO92 601-00506 1 Regulador 5.0 V, Paquete TO92 602-00032 1 EEPROM 32 kB, DIP-8 800-00016 6 Bolsa de 10 cables Puente Chip Propeller P8X32A - 40 pin DIP Descripción Mapa engomado para Propeller DIP P8X32A-D40 1 120-00003 1 Partes y cantidades sujetas a cambio sin previo aviso. Ensamble de las placas de prueba Las tres placas de 12-columnas x 30 renglones mostradas en la Figura 3-3 tienen conexiones y sus posiciones pueden ser descritas por (letras en columnas, números en renglones). Cada columna tiene una letra en la parte superior e inferior de la placa y cada renglón tiene un número a sus lados. Dos ejemplos de coordenadas en la placa son (K,3) en el centro y (C,7) en la derecha. Cada placa es organizada en renglones de 6 conexiones, todas las conexiones en cada renglón de seis están conectados por un conductor metálico bajo de ellos. Así que para conectar dos cables o más solo conéctelos en el mismo renglón. Kit Educativo de Practicas Propeller: Fundamentos · Página 25 Configuración y Prácticas de Laboratorio 3 Usando los entrelazados conecte las placas de prueba como se muestra en la Figura 3-3. Figura 3-3: Placas de Prueba Cada grupo de seis esta conectado electricamente. Ejemplo de coordenada: (K, 3) en el centro Ejemplo de coordenada: (C, 7) en la derecha Dos grupos de 12 conexiones en cada linea roja esta conectado electricamente L Todos las 24 conexiones de cada linea negra estan conectados electricamente Ejemplo de coordenada: (Negro, 22) a la mitad del conector de potencia Ejemplo de coordenada: (Rojo, 28)a la derecha del conector de potencia Véalo a color y acercamiento: Este archivo está disponible gratuitamente en formato PDF en la página del producto Kit Educativo Propeller (32305) en www.parallax.com. Usted también puede usar Adobe Acrobat Reader para realizar acercamientos de las regiones de diagramas y pueden ser útiles para verificar las conexiones. Pegamento de soporte – no exponer. Las placas tienen un pegamento para soporte cubierto con papel cera. No despegue el papel encerado a menos que usted vaya a pegar las placas a una superficie permanente tales como un metal o una caja de proyecto. VSS y GND; VDD y 3.3V: El pin de tierra del chip Propeller se menciona como VSS en el manual Propeller y VDD es +3.3V Cada placa en la Figura 3-3 está alineada en ambos lados por un conector de 2 columnas x 24 renglones. Estas columnas son las conexiones de potencia y están indicados en Negro y Rojo y los renglones son identificados por números. Ejemplos de coordenadas son (Negro, 22) en la mitad del conector de potencia y (Rojo, 28) en la derecha. En cada conector de potencia en la Figura 3-3 todos los 24 conectores de la línea vertical negra estas eléctricamente conectados. Estos conectores típicamente sirven como una tierra común y cada uno de estas columnas es conectada a la terminal negativa de la batería. Cada conector de potencia tiene grupos de 12 conexiones denotados por 2 líneas rojas verticales. Las doce superiores junto a la línea roja están agrupadas en conjunto pero no están conectadas a las doce bajas de la siguiente línea roja. La ruptura en la línea roja indica la ruptura de continuidad. El diseño de la placa esta de esta forma Pagina 26 · Kit Educativo de Prácticas Propeller: Fundamentos 3: Configuración y Prácticas de Laboratorio para acomodar dos diferentes voltajes en el mismo conector de potencia. Esta característica no se utiliza por el momento así que se realiza un corto en todos los conectores positivos con cables y luego se conecta a la salida del regulador de 3.3 V para proporcionar potencia a la Plataforma PE. Configuración y Reguladores de Voltaje de la Plataforma PE El diagrama de la Plataforma PE que se muestra en la Figura 3-4 se ensamblara en partes. En esta sección usted lo configurara y probara sin batería, Propeller Plug, chip Propeller o 24LC256 EEPROM. Después algunas pruebas eléctricas para verificar el cableado, usted conectara y probara cada componente. Siguiendo este procedimiento usted minimizara la posibilidad de dañar algún componente debido a un error de cableado. Figura 3-4: Diagrama – Kit Propeller DIP Plus La Figura 3-5 muestra el cableado que usara para el diagrama en la Figura 3-5. Note que el chip Propeller, EEPROM 24LC256, el Propeller Plug y la batería no están conectados. Note también que la placa en el cableado es justo, con todos los cables cortados a la medida para estar alineados con la superficie de la placa. Esto hará más fácil de identificar y remover cableado en proyectos sin necesidad de preocuparse de desconectar una parte o cable que es parte integral de la Plataforma PE 3 Asegúrese que la placa está orientada para que los números y letras indicados en la placa coincidan con las coordenadas de la Figura 3-5. Kit Educativo de Practicas Propeller: Fundamentos · Página 27 Configuración y Prácticas de Laboratorio 3 Conecte los cables y componentes exactamente como se muestra en la Figura 3-5. Asegúrese que todos los cables embonan correctamente en las conexiones. Si accidentalmente corto un cable más pequeño y tiene un contacto ligero tire el cable y coloque uno Nuevo, usted tiene que cortar a la medida correcta. 3 El ánodo del LED debe estar conectado al (Rojo, 10) y su cátodo a (L,10). El cátodo es el que está más cerca de la parte plana en la parte opuesta a la superficie redonda del LED 3 La Resistencia entre (K, 9) y (K, 10) es de 100 Ω (café-negro-café) y es una resistencia en serie con el LED de potencia 3 La Resistencia entre (D, 5) y (D, 9) es de 10 Ω (café, negro, naranja) y 3 La resistencia entre (D, 5) y (D, 9) es 10 kΩ (café-negro-naranja), y mantendrá en alto uno de los pins de la EEPROM. Figura 3-5: Cableado– Kit Propeller DIP Plus antes de conectar los ICs Verificando el cableado Es importante eliminar cualquier error antes de conectar la fuente de poder a la Plataforma PE. Verificando dos veces su cableado y haciendo un par de pruebas, usted puede muchas veces observar algún error que de otra forma puede causar un problema al sistema, no trabajar o incluso dañar algunos componentes. Aunque las partes de la Plataforma PE no son costosas, a menos que tenga más a la mano, esperar para obtener nuevas partes puede ser un retraso inconveniente. 3 Haga una impresión de la Figura 3-5 y verifique cada conexión marcando sobre cada punto su cableado observando que las coordenadas coincidan con las coordenadas para cada conexión mostrada en la figura. Pagina 28 · Kit Educativo de Prácticas Propeller: Fundamentos 3: Configuración y Prácticas de Laboratorio 3 La terminal positiva de la Batería de 9V deberá conectarse en el centro de la placa (L, 1) y su terminal negativa conectarse en (L, 2) 3 El regulador de Voltaje LM2940-5.0 en los sockets (J, 1-3) deberá conectarse de tal forma que la etiqueta en la cara negra este orientado a la izquierda y el disipador de calor de metal este orientado a la derecha. 3 El regulador de Voltaje LM2937-3.3 en los sockets (H, 3-5) deberá conectarse de tal forma que la etiqueta en la cara negra esta orientada a la izquierda y el metal disipador de calor este orientado a la derecha. 3 Verifique que la salida del regulador LM2940 5V se conecte al capacitor y que la terminal negativa del capacitor (vea el signo menos “-“ en el capacitor) esté conectada a (Negro, 1) y que la salida del Regulador LM2937 esté conectado al capacitor y la salida del capacitor esté conectado a cualquier posición en (J, 6) o (J, 7) ! PRECAUCION: El voltaje invertido en un capacitor electrolítico puede causar su ruptura o en algunos casos explotar. La terminal negativa de un capacitor electrolítico (marcada con un signo negativo) deberá estar conectada siempre a un menor voltaje que el de la terminal positiva. 3 Verifique que el ánodo del LED esté conectado a (Rojo, 10) y que su cátodo (indicado por un pin más corto en la parte plana del encapsulado) se conecta a (L, 10) Prueba del cableado de la Plataforma PE Esta sección muestra una lista de puntos de prueba que con un multímetro puede verificar que: • • • Los reguladores de voltaje están cableados correctamente y que trabajan apropiadamente Los voltajes distribuidos en los rieles son correctos Los voltajes están direccionados correctamente a las conexiones para proporcionar potencia al chip Propeller y al a EEPROM 3 Si usted tiene un multímetro los puntos de prueba se mencionan a continuación: Puntos de prueba con batería desconectada Continuidad La mayoría de los multímetros ofrecen la opción de continuidad la cual permite probar bajas resistencias. El símbolo de continuidad es típicamente un diodo con un punto que emite ondas de sonido, indicando que si el medidor detecta baja resistencia sonara un timbre. Si su medidor no tiene el modo de continuidad considere que medidas debajo de 1 Ω es una indicación de continuidad. Las medidas de Resistencia tienden a variar con la longitud del cable. Por ejemplo la resistencia entre (Rojo, 30) en el extremo izquierdo y (Rojo, 30) en el extremo derecho quizá este en el rango de 0.5 Ω, mientras que si mide dos puntos en el mismo conector de potencia quizá no detecte medición. La medición dependerá de la calibración de su multímetro y la resistencia de prueba. Usted puede encontrar el punto de cero ohms juntando las puntas de su multímetro. Si un punto de prueba falla durante la prueba de continuidad, busque cables faltantes y conexiones sueltos en el centro de la placa y los rieles. Kit Educativo de Practicas Propeller: Fundamentos · Página 29 Configuración y Prácticas de Laboratorio 3 En el conector de la batería de la terminal negativa a las columnas NEGRAS en las cuatro conexiones. (La terminal negativa en el conector de la batería es la del diámetro más pequeño y que está más cerca de los cables) 3 La terminal positiva del conector de la batería al centro de la placa (G,1) 3 La terminal negativa del conector de la batería a los siguientes puntos: (G,19), (G,20), (F,22), (D, 4), (G, 6, 7, 8, 9), (G, 2) y (K, 4) 3 (I, 5) a (ROJO, 13) y (Rojo, 18) en las cuatro conexiones de potencia 3 (ROJO, 18) a: (F, 19), (G, 22), (B, 5,), y (B, 6). Prueba con batería conectada Si su voltímetro es preciso los voltajes medidos estarán típicamente en el rango de ± 0.1 VDC. Algunos voltímetros más económicos tienen menor precisión. Si usted está usando un voltímetro económico o uno que desconoce el historial quizá identifique algunas variaciones mayores durante las mediciones. L El Capacitor 0.47 µF deberá ser colocado en la entrada de 9V si usted está utilizando una fuente de poder que se conecta a la pared, o cualquier cable que sea más largo que el adaptador para conectar la batería de 9V proporcionado en el kit. 3 Conecte una batería alcalina de 9V nueva o una recién cargada al conector de Batería de la Plataforma PE. El LED deberá brillar. Si el LED no brilla o esta naranja en vez de verde desconecte la batería inmediatamente y revise los pasos de solución de problemas (2) en la página 39 Voltaje DC 3 Prueba el voltaje entre los cuatro rieles de potencia Rojo/Negro. El voltaje entre (ROJO ,13) y (NEGRO, 13) deberá medir 3.3VDC en cada uno de los cuatro conectores. Si el voltaje por el contrario esta alrededor de los 4V o mayor desconecte inmediatamente y revise el punto (11) de la solución de problemas en la pagina 42. Si el voltaje es incorrecto diríjase a la solución de problemas (3) en la página 49 3 Repita la prueba para 3.3VDC en (ROJO, 18) y (NEGRO, 13). 3 (I, 1) en centro de la placa a (NEGRO, cualquiera): igual que voltaje en terminales de batería. 3 (G, 3) en el centro de la placa a (NEGRO, cualquiera): 5VDC. Si el voltaje esta alrededor de los 6V o es mayor desconecte inmediatamente y diríjase a la solución de problemas (11) en la página 42 Conexión del chip Propeller y la EEPROM En la Figure 3-6 se muestra el dibujo de la Plataforma PE una vez que el chip Propeller y la EEPROM han sido conectados. 3 Desconecte la batería del conector para los siguientes pasos. 3 Identifique la muesca de referencia en el chip Propeller y la calcomanía del mapa, compare la orientación con la muesca entre el chip y el mapa en la Figure 3-6. (La muesca de referencia es un semicírculo entre el Pin 0 y el Pin 31 en el mapa y deberá coincidir con la muesca física en el chip Propeller.) 3 Coloque el mapa del chip Propeller asegurándose que la muesca de referencia en la calcomanía está orientada en la misma dirección que la muesca en el chip. 3 Asegúrese que cada pin está alineado con la conexión correcta en la placa de prueba donde será instalado. Pagina 30 · Kit Educativo de Prácticas Propeller: Fundamentos 3: Configuración y Prácticas de Laboratorio 3 Coloque el chip Propeller en la placa de prueba, verifique su orientación contra la Figure 3-6. Presione firmemente con ambos pulgares. 3 Localice la muesca de referencia en la EEPROM 24LC256 y oriéntelo como se muestra en la Figure 3-6 y presiónelo. La muesca de referencia deberá estar entre los Pins que están entre los conectores (F, 6) y (G, 6) Figure 3-6: Dibujo del Cableado – Kit Propeller DIP Plus Conectar el Propeller Plug a la Computadora y a la Plataforma PE La herramienta de programación Propeller debe estar cargada en su computadora antes de comenzar. 3 Si usted no ha hecho esto, antes de continuar aquí complete los pasos de Programa, Documentación y Recursos comenzando en la pagina 17. La primera vez que usted conecta el Propeller Plug a su Computadora con el cable USB deben suceder dos cosas: 1) El Propeller Plug Serial transmite y Recibe, los LED deberán titilar brevemente. 2) El sistema operativo Windows deberá desplegar el mensaje “Encontró Nuevo Dispositivo” – USB Puerto Serial seguido por “Encontró nuevo dispositivo – Su nuevo dispositivo está instalado y listo para usar. Cada vez que reconecte su Propeller Plug a la Computadora, los LEDs de comunicación deberán titilar, pero Windows típicamente ya no desplegara los mensajes de instalación del puerto serial. 3 La batería debe estar desconectada Kit Educativo de Practicas Propeller: Fundamentos · Página 31 Configuración y Prácticas de Laboratorio 3 Conecte el Propeller Plug a su computadora con el cable USB y verifique que ambos LEDs de comunicación (Rojo y Azul) están titilando brevemente inmediatamente después de que usted hizo la conexión. 3 Ahora, Conecte el Propeller Plug al conector de 4 posiciones en su Plataforma PE con las partes orientadas hacia arriba como se muestra en la Figure 3-6. 3 Verifique que el indicador LED que está conectado en (ROJO, 10) y (L, 10) brilla ligeramente. Quizá tendrá que ver por encima del domo del LED para observar si brilla. Si el LED no brilla ligeramente no continúe con el siguiente paso; en vez de seguir vaya al paso (5) en la solución de problemas de la pagina 40. Conecte la Batería Cuando usted conecta la batería el LED que brillaba ligeramente cuando usted conecto el Propeller Plug ahora deberá estar brillando. Esto indica que el Regulador 3.3V de la Plataforma PE está proporcionando potencia al chip Propeller, a la EEPROM y a los conectores que están junto a las tiras rojas en los conectores de potencia. 3 Conecte la batería al clip como se muestra en la Figure 3-6. El LED de la Plataforma PE deberá iluminarse brillante. Si no sucede desconecte la batería inmediatamente y vaya a la solución de problemas (4) en la pagina 40. Lo mismo aplica si el LED verde obtiene una tonalidad anaranjada. 3 Si usted tiene un voltímetro, verifique el voltaje en el conector rojo y negro. Deberá medir 3.3VDC. Si el voltaje es incorrecto desconecte la batería y vaya a la solución de problemas (3) en la pagina 40. 3 Verifique el voltaje AC en los conectores rojo y negro. Deberá existir únicamente alrededor de 50mV de Voltaje AC. Para Voltajes AC mayores de 300mV vaya a la solución de problemas (11) en la página 42 Prueba de Comunicación La característica de identificación de Hardware en la herramienta de programación Propeller puede usarse para verificar la comunicación entre la PC y el chip Propeller. 3 3 3 3 3 Asegúrese que la batería está conectada. Verifique que el cable de USB conecta la PC al conector del Propeller. Verifique que el conector Propeller está conectado al conector de 4 pins (etiqueta hacia abajo) Abra el programa Propeller, Presione en Menú y seleccione Identify Hardware…(o F7). Si la herramienta reporta, “Propeller Chip versión 1 found on COM…”, continúe a la siguiente sección (Cargar el programa y probar los pins E/S) De otra forma vaya a la solución de problemas (6) en la pagina 41 y solución de problemas (1) en la pagina 37. Cargar el programa y probar los pins de E/S Estas pruebas son importantes antes de continuar con las prácticas del Kit PE. Un ejemplo de un problema que estas pruebas pueden interceptar es un pin E/S doblado en el chip Propeller. Ocasionalmente uno de los pins se dobla debajo del chip en vez de estar conectado en la placa. Puede ser difícil de identificar visualmente pero si un pin de E/S no identifica entrada o salida de control esta prueba puede identificar el problema rápidamente. De otra forma podrá tomar mucho tiempo buscar un error en la aplicación o el código antes de descubrir que el problema es un pin doblado. Así que realice las pruebas. No tomara mucho tiempo y podrá ahorrarle mucho tiempo después. Pagina 32 · Kit Educativo de Prácticas Propeller: Fundamentos 3: Configuración y Prácticas de Laboratorio Partes para el circuito de prueba de pins E/S 3 Abra la bolsa de partes del proyecto PE y verifique su contenido contra la lista de partes en la Tabla C-2 en el Apéndice C: Lista de Componentes kit PE. 3 Para los siguientes circuitos reúna las siguientes partes de la bolsa del Proyecto PE (1) LED – Rojo Verde o Amarillo (1) Resistencia – 100 Ω (café-negro-café) (1) Resistencia – 10 kΩ (café-negro-naranja) (1) Botón pulsador (4) Alambres de conexión Construir el circuito de prueba El circuito que se muestra en la Figure 3-7 y la Figure 3-8 le proporcionara la idea de prueba para los pins de E/S como entradas y salidas en el chip Propeller. Si alguna de las instrucciones en la lista de no funciona vaya a la solución de problemas (9) en la pagina 41. Comience por verificar que el circuito LED es correcto y que todos los conectores de potencia están proporcionando 3.3V como sigue: 3 Desconecte la batería del clip. 3 Construya el circuito que se muestra en la Figure 3-7 y la Figure 3-8. 3 Reconecte la batería al conector. El circuito del LED puede probarse conectándolo a uno de los conectores de los rieles de potencia ROJOS, el cual proporcionara 3.3 VDC. 3 Desconecte el alambre del LED de (L, 14) en la Figure 3-8, y conéctelo en (ROJO, 13) en el conector de potencia que está entre el centro y la izquierda de las placas. El LED deberá encender. Si no sucede esto verifique su cableado. Primero asegúrese que el LED no está conectador al revés. Su parte más corta (Ánodo) deberá estar conectado en el socket siguiente a la línea negra en el conector de potencia de la izquierda. Figure 3-7: Esquema del circuito de prueba Kit Educativo de Practicas Propeller: Fundamentos · Página 33 Configuración y Prácticas de Laboratorio Figure 3-8: Diagrama del cableado del circuito de prueba Este circuito del LED puede usarse para probar y asegurarse que todos los rieles ROJOS de potencia están conectados a la fuente de 3.3 V. Si usted ya realizo esta prueba con un voltímetro puede brincarse esta parte. 3 Desconecte el cable de (ROJO, 13) y conéctelo en (ROJO, 12) en el conector de potencia de la izquierda. El LED deberá encender nuevamente. Repita para (ROJO, 18) en la izquierda y (ROJO, 18) en el conector del centro. El LED deberá encender en cada punto de prueba. Si no sucede verifique su placa contra el diagrama de cableado en la Figure 3-8 en busca de cables faltantes entre los conectores de potencia ROJOS. Después de probar los circuitos LED y los conectores de potencia el LED deberá reconectarse al pin I/O del Propeller para que pueda ser utilizado en conjunto con el programa para indicar que los pins E/S están funcionando apropiadamente como salidas. 3 Reconecte el circuito LED al chip Propeller P3 E/S pin (L, 14) como en la Figure 3-8. Programa de prueba – PushbuttonLedTest.spin Como está escrito PushbuttonLedTest.spin hace parpadear en LED conectado a cualquiera de las E/S en el chip Propeller del lado izquierdo (P0 a P15). El rango de parpadeo del LED depende si el botón pulsador conectado a P18 se presiona (10Hz) o no (2Hz). El cable que conecta P3 al LED puede usarse para probar cada pin de E/S. Por ejemplo si ese cable está conectado a (L, 11) confirma que P0 está funcionando como una salida y hace que el LED parpadee. Conecte el cable a (L, 12) y esto confirma que P1 está funcionando y así hasta P15 (L, 30) Usted puede usar el mapa en el chip Propeller para identificar rápidamente los pins de E/S. E/S es una abreviatura para Entrada/Salida. L La dirección y el estado de cada E/S son controlados por el programa. En los programas puede modificarse la dirección y el estado de cada pin individual de E/S así como de grupos de pins en cualquier momento Pagina 34 · Kit Educativo de Prácticas Propeller: Fundamentos 3: Configuración y Prácticas de Laboratorio Si el LED parpadea a 2 HZ mientras que el botón pulsador se presiona y parpadea a 10 HZ después de que se suelta esto confirma que P18 está funcionando como Entrada. El programa puede modificarse y el cable conectado de P18 al pulsador puede moverse a cada pin de E/S en el lado derecho del chip Propeller para probar esos pins como Entradas. Después de que todas las Salidas en la izquierda del chip Propeller y todas las Entradas del lado derecho se probaron, el botón pulsador puede moverse a la izquierda y el LED a la derecha. Así esta prueba puede repetirse para verificar que todas las E/S en la izquierda funcionan como Entradas y los pins de la derecha como Salidas. Cargar PushButtonLedTest.spin en la EEPROM Usted puede cargar este programa en la EEPROM de la Plataforma PE presionando el menú Run, seleccionando Compile Current, y luego Load EEPROM (F11). Después de que se carga el programa en la EEPROM, el chip Propeller lo copia de la EEPROM en su memoria principal RAM y uno de los procesadores del chip Propeller lo ejecuta. (Si usted desconecta y reconecta la potencia o presiona y suelta el botón de arranque de la Plataforma PE el chip Propeller volverá a cargar el programa de la EEPROM a la memoria principal y correrá nuevamente desde el principio). 3 Abra el archivo PushbuttonLedTest.spin en la herramienta propeller o escríbalo. Si lo escribe tenga cuidado de escribir cada línea exactamente como se muestra. 3 Presione el menú Run de la herramienta Propeller y seleccione Compile Current → Load EEPROM (F11). La ventana de comunicación Propeller aparecerá brevemente y mostrara el progreso de la carga del programa. Si se cierra después del mensaje “Verifying EEPROM” entonces cargo correctamente. Kit Educativo de Practicas Propeller: Fundamentos · Página 35 Configuración y Prácticas de Laboratorio 3 Si en cambio se abre una ventana que dice “EEPROM programming error...” vaya a solución de problemas (8) en la pagina 41. 3 Verifique que el LED conectado a P3 parpadea encendido/apagado rápidamente a 10Hz 3 Presione y sostenga el botón pulsador y verifique que el LED parpadea más lento a solo 2 Hz. 3 Si todo funciono como se anticipaba pase a la prueba de pins E/S mostrada abajo. Si no funciono vaya a solución de problemas (9) en la pagina 41. Prueba de Pins E/S Use el mapa de pines en el chip Propeller para localizar los pins E/S. Si alguno de estas pruebas indican que los pins E/S fallan vaya a solución de problemas (10) en la pagina 42. El primer paso es usar el circuito LED para verificar que cada pin de E/S en la izquierda del chip Propeller funciona como salida. 3 Desconecte el final del cable que está en (L, 14) y úselo para probar de P0 a P15. De (L, 11) a (L, 18) y de (L, 23) a (L, 30). Cada pin de E/S deberá hacer que el LED parpadee. Después, use el botón pulsador para verificar que cada pin de E/S que está al lado derecho del chip Propeller funciona como entrada. 3 Presione y sostenga el botón pulsador a la derecha de la placa. El circuito LED en la izquierda de la placa deberá parpadear a 2Hz en vez de 10Hz. 3 Desconecte la batería del clip. 3 Desconecte el cable del botón pulsador en (A, 28) en el centro de la placa y conéctelo en P16 (A,30) 3 Modifique el programa para monitorear P16 en vez de P18 cambiando la directiva PUSHBUTTON CON en el objeto PushButtonLedTest.spin de 18 a 16. 3 Reconecte la batería al clip 3 Cargue el programa modificado en la RAM presionando el menú Run y seleccionando Compile Current → Load RAM (F10). 3 Verifique que el botón pulsador, ahora conectado a P16, controla la frecuencia del LED. 3 Repita este procedimiento para P17, P19, P20 y así hasta P27. L Cargar RAM (F10) vs. Cargar EEPROM (F11): La herramienta de programación Propeller Cargar RAM es rápida pero el programa se borra cada que la corriente se corta o el botón de reinicio se presiona. Después de un reinicio el chip Propeller cargara el programa que más recientemente se cargo en EEPROM y comenzara a ejecutarlo. Los programas cargados en EEPROM no se borran pero toma un poco más de tiempo cargarlos. Como la prueba del botón pulsador requiere estar cambiando t recargando el programa en el chip Propeller ahorra mucho tiempo usar la carga en memoria RAM. Que sucede con la prueba de P28..P31? Estas E/S del Propeller están cableados al FTDI USB chip serial y a la memoria EEPROM. Si usted pudo realizar la carga a la EEPROM significa que estas E/S son funcionales. Es cierto que estos pins pueden usarse en algunos circuitos usted deberá asegurarse que la aplicación no dañara y no podrá ser dañada por los otros circuitos conectados a P28…P31. Vea la Figura 3-4 en la pagina 27 para detalles. Para la mayor parte las prácticas del kit PE no usaran estas E/S para aplicaciones de circuitos. Hasta este punto la mitad de las E/S del chip Propeller se han probado como salidas y la otra mitad se han probado como entradas. Antes de mover la prueba a circuitos opuestos de la placa es una buena idea cargar un programa vacio en la EEPROM de la Plataforma PE para que el chip Propeller no envíe señales incorrectas a los pins de E/S. La corriente deberá desconectarse cuando se cambia el circuito. Para asegurarse que el programa vacio corre automáticamente cuando la corriente se conecta deberá cargarse en EEPROM usando F11. 3 Cargar este programa (DoNothing.spin) en la EEPROM (F11): Pagina 36 · Kit Educativo de Prácticas Propeller: Fundamentos 3: Configuración y Prácticas de Laboratorio '' File: DoNothing.spin PUB main ' Método main vacío Ahora la corriente puede desconectarse, el botón pulsador puede moverse al lado izquierdo de la placa y el circuito LED puede moverse al lado derecho de la placa de prueba. 3 3 3 3 3 3 3 3 Desconecte la batería y el cable USB. Mueva el circuito LED a la derecha de la placa de prueba y conéctelo a P16. Mueva el botón pulsador del lado izquierdo de la placa de prueba y conéctelo a P15. Modifique el objeto PushbuttonLedTest.spin como sigue: o Cambie la directiva LEDs_START CON de 0 a 16. o Cambie la directiva LEDs_END CON de 15 a 27. o Cambie la directiva PUSHBUTTON CON a 15. Reconecte el cable USB y la batería. Cargue el programa objeto modificado PushbuttonLedTest.spin en EEPROM usando F11. Repita las pruebas de salida LED para P16 hasta P27 Repita las pruebas de entrada del botón pulsador empezando en P15, luego P14 y así hasta P0. Recuerde modificar el código y luego cargar la RAM usando F10 entre cada prueba. Antes de cambiar o ajustar circuitos El programa DoNothing.spin hace que todas las E/S se programen como entradas asegurando que no puede enviar inadvertidamente una señal alta (3.3V) a un circuito que está enviando una señal baja (0V) o viceversa. Cuando usted ha terminado de probar es una buena idea cargar el programa objeto DoNothing.spin en la EEPROM así su chip Propeller no puede dañar el siguiente circuito que se conecta. De hecho hágalo un hábito. Siempre cargue DoNothing.spin en EEPROM usando F11 antes de desconectar la corriente y construir un circuito Nuevo o hacer cambios al existente. 3 Ahora cargue DoNothing.spin en EEPROM (F11). Cuando usted reconecte la corriente DoNothing.spin se cargara automáticamente de la EEPROM a la memoria principal del Propeller y el chip Propeller lo ejecutara. Esto programara los pins E/S como entradas por defecto. Entonces cuando el programa termine el chip Propeller se va a modo de bajo consumo. Esto protege al Propeller y a su circuito al momento de encenderlo nuevamente hasta que cargue el programa para su nuevo circuito en el chip Propeller Regulador de Fuente de Poder Propeller – ¡Es importante! Una fuente de poder es importante porque diferentes aplicaciones de circuitos y subsistemas dependen de ella. Cualquier fluctuación en la fuente de voltaje se pasará directamente en fluctuaciones de las señales altas 3.3 V enviadas por los pis E/S del Propeller. También se pasaran en fluctuaciones en el voltaje de disparo de los pins E/S los cuales son aproximadamente ½ de los 3.3 V de la fuente de poder. Cuando se aplica un voltaje al pin E/S para activar un pin E/S como Entrada el Propeller lo interpreta como binario-1 si el voltaje esta por encima del punto de disparo o binario-0 si esta por debajo. Las señales de los pins E/S del Propeller se usan también en una variedad de aplicaciones análogo-digital (medidas de voltaje) y digital-análogo (síntesis de voltaje). Así que cualquier fluctuación de voltaje que afecte la salida alta y niveles de disparo de entrada reducirá la precisión de medición y síntesis de voltaje. Kit Educativo de Practicas Propeller: Fundamentos · Página 37 Configuración y Prácticas de Laboratorio Los productos y prototipos de circuitos impresos diseñados con chips Propeller típicamente tienen varias características que mejoran la estabilidad del voltaje de entrada. El regulador de voltaje de salida esta muy cerca de las entradas del chip Propeller, los 3.3V y pins de Tierra. Dependiendo del diagrama quizá pueda observar las etiquetas Vdd y Vss. Las pistas de metal en la tarjeta que conectan el regulador de voltaje a las entradas del Propeller son típicamente más anchas que otras pistas que transmiten señales. Ya que los conductores de metal tienen poca resistencia, estas medidas minimizan la resistencia entre la salida del regulador de voltaje y las entradas del chip Propeller. Esto a su vez mejora la estabilidad de la fuente de poder minimizando las fluctuaciones de voltaje que pueden ocurrir si el consumo de corriente en el Propeller cambia, lo cual puede suceder cuando inicia un procesador y los pins E/S que manejan cargas encienden y apagan. Se pueden conectar capacitores entre la fuente de entrada del chip Propeller para proporcionar protección adicional de fluctuaciones de voltaje y mejorar aun mas la estabilidad. Mejore la estabilidad de la Fuente de Poder del Kit En comparación con las tarjetas de productos y prototipos, la distancia entre la salida del regulador de voltaje y las entradas del Propeller es mayor y puede reducir la estabilidad del voltaje proporcionado a las entradas del chip Propeller. Esto es malo. El remedio es simple y solo requiere dos capacitores y dos cables. Eso es bueno. Los cables conectan la fuente de entrada en lados opuestos del chip para asegurar que los niveles de voltaje proporcionados son idénticos en ambas terminales. Los capacitores se colocan entre las entradas de 3.3 V y la Tierra en ambos lados del chip Propeller para filtrar cualquier fluctuación ocasionada por líneas largas de fuentes. Lista de Partes: (1) Plataforma construida y probada del Kit PE – Versión 40-Pin DIP (2) Cables Puente (2) Capacitores – 0.1 μF Procedimiento: La Figura 3-6 muestra los puentes y las conexiones del capacitor. Los pins 3.3 V del chip Propeller están conectados entre si con un cable puente y los pins de Tierra están conectados con otro cable puente. Capacitores de 0.1 μF se conectan entre los pins 3.3 V y Tierra en ambos lados. 3 Desconecte la fuente de poder y el Puerto de programación 3 Corte los cables puentes para reducir cualquier exceso de longitud cuando se conecten como se muestra en la Figura 3-6. 3 Use un cable rojo para conectar (J, 22) a (D, 19). 3 Use un cable negro para conectar (J, 20) a (D, 22). 3 Conecte las terminales del capacitor 0.1 μF en (K, 22) y (J, 19). 3 Conecte las terminales del otro capacitor 0.1 μF en (B, 19) y (B, 22). 3 Verifique sus conexiones. 3 Reconecte la fuente de poder y el Puerto de programación. Pagina 38 · Kit Educativo de Prácticas Propeller: Fundamentos 3: Configuración y Prácticas de Laboratorio Figura 3-6: Conexión de entrada y capacitores filtro para la Plataforma PE 40-Pin DIP Solución de problemas para el arranque de la Plataforma PE de 40 pins-DIP (1) Conexión de programación y Puerto Serial a. Cuando conecte el Propeller Plug al Puerto USB los LED rojo y azul junto al mini USB del Propeller Plug deberán parpadear brevemente. Si no sucede intente un puerto diferente. Si ninguno de los puertos responde contacte a Soporte Técnico en Parallax . (Vea los recursos de Soporte Técnico en la página 18) b. Corra la herramienta Propeller, presione el menú Run y seleccione Identify Hardware (F7). Si usted obtiene el mensaje que se muestra en la Figura 3-9: i. Asegúrese que el cable USB está conectado al Propeller Plug y al puerto USB de la computadora. ii. Verifique las siguientes conexiones en su plataforma PE: (D, 3) a (D, 10), (F, 10) a (F, 21), (B, 1) a (B, 12), and (C, 2) a (C, 11) iii. También asegúrese que la batería está conectada y que el LED verde de la Plataforma PE esta brillando ligeramente. Después presione F7 nuevamente. iv. Si eso no corrige el problema intente conectar el cable a un Puerto diferente en su computadora. Figura 3-9: Mensaje de error de comunicación c. Si aun tiene el mensaje de la Figura 3-9 después de asegurarse que el cable del USB está conectado: i. Presione el botón Edit Ports en el mensaje de error. La lista de búsqueda de puerto serial aparecerá. Usted puede acezar esta utilidad presionando el menú Edit y seleccionando Preferences (F5). Presione el tabulador Operation y luego presione el botón Edit Ports. Kit Educativo de Practicas Propeller: Fundamentos · Página 39 Configuración y Prácticas de Laboratorio ii. Deje el cable USB conectado en el Propeller Plug y desconecte y conecte el cable USB en el puerto de la computadora. Espere 20 segundos entre desconectar y conectar el cable USB. La lista deberá actualizarse y mostrar un nuevo “USB Serial Port”como el COM46 que se muestra en la Figura 3-10. iii. Si este aparece en un gris ligero presione el botón derecho y seleccione Include Port (COMX), o en algunos casos Re-Include Port. Figura 3-10: Lista de búsqueda de Puerto Serial d. Si la lista de búsqueda del Puerto Serial busca y reconoce ese puerto vaya a www.parallax.com y presione en la liga del instalador de controladores USB en la parte de debajo de la pagina después siga las instrucciones para solución de problemas. e. Si la herramienta de programación Propeller aun despliega el mensaje de “No Propeller chip found…” utilice el administrador de dispositivos para localizar el puerto serial USB. i. Para acezar la Lista de Puertos de administrador de dispositivos de Windows, presione el botón derecho en Mi Computadora y seleccione Propiedades. Presione la pestaña de Hardware y presione el botón de Administrador de Dispositivos. En el Administrador de Dispositivos presione el + que esta junto a Puertos (COM y LPT). ii. Cada vez que conecte el cable USB deberá aparecer una referencia en el Puerto Serial (COMXX) como se muestra en la Figura 3-11. Cada vez que desconecte el cable que conecta el Propeller Plug a la Computadora la referencia debe desaparecer. Por ejemplo el administrador de dispositivos abajo muestra el Puerto Serial USB (COM46) lo cual indica que el Propeller Plug está conectado a COM46. Pagina 40 · Kit Educativo de Prácticas Propeller: Fundamentos 3: Configuración y Prácticas de Laboratorio Figura 3-11: Lista de Puertos en el Administrador de Dispositivos f. iii. Si el Puerto Serial USB no aparece en la lista de puertos (COM y LPT) pero el administrador de dispositivos parece refrescarse cada que se conecta o desconecta el cable USB: 1. Esta indicando que el Propeller Plug se conecto en la computadora y se hizo un intento de instalar los controladores manualmente antes de que el la herramienta de programación y el controlador se instalaran. Busque la lista para encontrar el controlador que se agrega cada vez que usted conecta el Propeller Plug. Cuando lo encuentre desinstálelo. Usted puede hacer esto al presionar el botón derecho mientras esta sobre el controlador y seleccionando desinstalar. 2. Desconecte el Propeller Plug. Antes de conectarlo nuevamente asegúrese que se instalo el controlador USB FTDI. La manera más sencilla de hacerlo es desinstalar y reinstalar la herramienta Propeller. 3. Cuando reinstala la herramienta de programación Propeller: a. Asegúrese que la instalación de controladores USB esta marcado! Para mayor información vea la sección de Descarga de Programas y Documentación en la pagina 17. b. Después de que reinstalo el programa el controlador correcto se instalara automáticamente cuando conecte el Propeller Plug a la computadora. Asegúrese de dejar la batería desconectada cuando conecte el Propeller Plug a la computadora con el cable USB por primera vez. Contacte a Soporte Técnico de Parallax (Vea pagina 18.) (2) Si el LED de la Plataforma PE no enciende o si brilla anaranjado cuando la batería se desconecto: a. Si el LED se enciende anaranjado: i. Verifique si hay corto entre el cátodo del LED y tierra. El LED deberá tener una resistencia en serie entre su cátodo (L, 10) y tierra (NEGRO, 9). La resistencia deberá conectar (K, 9) a (K, 10). ii. Asegúrese que el voltaje en el ánodo del LED (ROJO, 10) es 3.3V. b. Si el LED no encendió quizá esté conectado al revés. Verifique que el cátodo está conectado a la resistencia y el ánodo conectado a la fuente de 3.3V. En términos de la Figura 3-5 en la página 28 el pin que sale de la parte plana de la base cilíndrica del LED deberá estar conectado en (L, 10). El otro lado (punta ánodo) deberá estar conectado a (ROJO, 10). Para detalles vea Verificando Conexiones de Cableado en la página 28. Kit Educativo de Practicas Propeller: Fundamentos · Página 41 Configuración y Prácticas de Laboratorio c. Asegúrese que la terminal (+) de la batería este conectada a (L, 1) y su terminal (-) esté conectada a (L, 2). d. Podría existir un error de cableado que ocasione un corto circuito de la fuente de poder a tierra. Si usted no tiene multímetro comience a verificar visualmente su cableado. Con un multímetro usted puede verificar resistencia entre la terminal negativa de la batería y las 3 fuentes positivas. Asegúrese de desconectar el cable USB y la batería antes de hacer la prueba de resistencia. iii. Comience a medir la Resistencia entre la conexión 3.3V y la terminal negativa de la batería. Por ejemplo pruebe entre los puntos (ROJO, 13) y (J, 4) en el centro de la placa de prueba. iv. Repita la medición de Resistencia entre la terminal negativo (J, 4) y la salida del regulador de 5V (G, 3) así como (J, 4) y la entrada de la batería (G, 1). Si alguna de estas resistencias mide menos de 10 Ω, es fuente de voltaje puede estar hacienda corto a tierra. v. Contacte a Soporte Técnico de Parallax (vea pagina 18.) (3) Si el voltaje entre las conexiones (ROJO-NEGRO) no es 3.3V: a. Si su medidor es un modelo de baja confiabilidad o se le ha dado uso rudo verifíquelo contra una fuente conocida de voltaje antes de confiar en sus mediciones. b. Repita la Verificación de Conexiones de Cables empezando en la página 28, cuidadosamente continúe hasta las conexiones de la Batería en la página 32, ponga atención a los detalles esperando que pueda encontrar a algún error. Estas pruebas pueden llevar a una variedad de problemas incluyendo cortos entre las fuentes de 5V y/o 9V (4) Si el LED de encendido no se ilumina cuando conecta la batería después de conectar el chip Propeller pero si encendía en pruebas anteriores: a. Verifique errores en los pins: Si un cable termina en un renglón que se comparte con el chip Propeller o con el pin de la EEPROM 24LC256 es un punto sospechoso. Asegúrese que las coordenadas son idénticas a la Figura 3-5 de la pagina 28 y la Figure 3-6 de la pagina 31. b. Remueva el chip Propeller y la EEPROM 24LC256 de la placa de prueba y repita la verificación de cableado de la pagina 28. Continúe detalladamente hasta las conexiones de la batería en la pagina 32 y quizá pueda detectar algún error esta vez. c. Contacte a Soporte Técnico de Parallax (vea pagina 18). (5) Si el LED de encendido no brilla ligeramente después de conectar el Propeller Plug al conector de 4 pins en la Plataforma PE y de conectar a la computadora con el cable USB: a. Verifique que la Resistencia en el circuito LED es de 100 Ω (café, negro, café). b. Verifique que el ánodo del LED de encendido está conectado en (ROJO, 10) y el cátodo conectado a (L, 10). El cátodo es el pin con la parte plana en la base cilíndrica del encapsulado. d. Intente conectar a otros puertos USB en su computadora. e. Intente con otro LED verde de las partes de su kit PE. El pin largo (ánodo) deberá conectarse a (ROJO, 10) y el pin corto (cátodo) a (L, 10). f. Verifique el cableado contra la Figura 3-5 de la pagina 28, y la Figure 3-6 de la pagina 31. g. Remueva el chip Propeller y la EEPROM de la placa de prueba y repita la prueba del cableado de la Plataforma PE de la pagina 29. Continúe hasta la conexión de la batería en la pagina 32 y quizá usted detecte un problema esta vez. h. Contacte a Soporte Técnico de Parallax (vea pagina 18). (6) Causas comunes del mensaje “No Propeller Chip found…” son: Pagina 42 · Kit Educativo de Prácticas Propeller: Fundamentos 3: Configuración y Prácticas de Laboratorio a. Batería desconectada. Conecte la batería. b. Batería descargada, la batería tiene que volver a cargarse. c. El cable USB no está conectando el Propeller Plug a la computadora. Asegúrese que ambas terminales están conectadas. d. El Propeller Plug no está conectado al conector de 4 pins o está conectado al revés. La conexión deberá ser con los componentes hacia arriba (etiqueta hacia abajo). e. Conexión USB dañada o gastada. La mayoría de las computadoras tienen más de una conexión USB, intente con otro puerto. f. El chip Propeller o la EEPROM 24LC256 no están conectadas totalmente. La parte de abajo del chip Propeller y la EEPROM deben estar tocando la placa de prueba. Si no es así asegúrese que todos los pins están alineados con los hoyos en la placa de prueba y presione los componentes firmemente. g. El controlador USB FTDI USB no está instalado. Vea el punto (1) de esta sección. h. Fuentes de poder – Si usted no verifico los voltajes con un multímetro es hora de hacerlo. (Vea la prueba de cableado de la Plataforma PE en la página 29). Si los voltajes son incorrectos vea el punto (3). i. El Propeller Plug esta invertido. El pin 1 y el indicador de semicírculo que está en la etiqueta del chip Propeller y que se muestra en la Figure 3-6 de la pagina 31 debe estar en el renglón 11 no en el renglón 30. Verifique también que la muesca impresa coincide con la muesca física del chip Propeller, ambos deben estar orientados al renglón 11. j. Cable USB defectuoso. Use otro cable si usted tiene un cable extra USB A a mini B. (7) Si la prueba del circuito LED no enciende cuando conecta el puente en (ROJO, 13): a. La polaridad del LED puede estar invertida. Asegúrese que el cátodo del LED esta conectodo al conector de potencia que esta junto a la línea negra. b. Si él LE no encendió cuando probo el conector de potencia en la izquierda asegúrese que el puente conecta la columna roja en el conector de en medio con la columna de potencia en el conector de la izquierda. (8) Si usted ve un mensaje “EEPROM programming error…” cuando usa la herramienta de Load EEPROM en la herramienta Propeller: a. Observe si el cable USB esta suelto y las conexiones de la batería. b. Si el problema persiste intente otro Puerto USB c. Si usted tiene un cable extra USB A a mini B úselo. d. El chip Propeller quizá no esté bien conectado. Vea conexión del chip Propeller y EEPROM en la pagina 30. e. Verifique las siguientes conexiones: (A, 8) a (A, 14), (A, 9) a (A, 13), (BLACK, 9) a (L, 9), (H, 6) a (H, 7), (I, 7) a (I, 8), (H, 8) a (H, 9), (E, 4) a (E, 7), (RED, 6) a (A, 6), y la resistencia de 10 kΩ entre (D, 5) y (D, 9). Vea la Figure 3-6 de la pagina 31. f. Asegúrese que la 24LC256 no está invertida. La muesca de referencia en el chip debe estar entre (F, 6) y (G, 6). g. Si el problema persiste contacte a Soporte Técnico de Parallax (Vea pagina 18.) (9) Si el programa se descarga pero el circuito LED no parpadea: a. Si ingreso el programa manualmente entonces descárguelo directamente la pagina del kit Educativo Propeller. Ábralo con la herramienta de programación y use F11 para descargarlo a la EEPROM. Esto eliminara la posibilidad de haber escrito un error. b. Si el LED no comienza a parpadear asegúrese que el oscilador está conectado. (Vea la Figura 3-2 de la página 20 del cristal de 5.00 MHz y verifique que los conectores están colocados en las posiciones correctas) c. Remueva el oscilador y conecte nuevamente para realizar la prueba otra vez. Kit Educativo de Practicas Propeller: Fundamentos · Página 43 Configuración y Prácticas de Laboratorio d. Cambie la línea de programa en PushButtonLedTestv1.0.spin de _clkmode = xtal1 + pll16x a _clkmode = xtal1 + pll8x. Si este cambio hace que la luz comience a parpadear cambie el programa otra vez a pll16x, cargue este programa original en el chip Propeller para ver que la luz parpadea nuevamente. Si este no es el caso comuníquese a Soporte Técnico Parallax (Ver página 18). (10) Los pins de E/S del chip Propeller se prueban antes de enviar. Si la prueba de LED o Botón Pulsador indican que hay un pin dañado: a. Asegúrese de verificar que el pin no está doblado debajo del encapsulado y que se conecto mal a la placa. b. Intente tocar el pin de E/S con el pin del LED. Si la luz comienza a parpadear con este contacto eléctrico pero no cuando está conectado en el socket: i. Nuevamente verifique que el pin no está doblado debajo del encapsulado. ii. Desconecte el chip Propeller y verifique que el pin no está doblado. iii. Si tiene un multímetro haga la prueba de continuidad entre el conector de E/S donde estaba conectado y el conector donde el cable estaba conectado. Si no hay continuidad por favor contacte a Soporte Técnico Parallax (Ver página 18) c. Si la continuidad en la placa de prueba está bien y el pin no está doblado conecte nuevamente el chip en la placa y prueba todos los pins de E/S y tome nota de cual funciona y cual no. También tome notas de cualquier evento que observe durante la prueba y contacte a Soporte Técnico Parallax. (Ver recursos en página 18) d. Por favor vea la póliza de garantía en www.parallax.com para más información de reemplazo del modulo con pins E/S dañados. (11) 4 VDC o mas entre (ROJO, cualquiera) y (NEGRO, cualquiera) o 6 VDC o mas entre (G, 3) a (Negro, cualquiera). a. Uno de los capacitores de 1000 µF quizá no esté bien conectado. Esto lo indican las mediciones de voltaje DC que están entre 1 a 2.5V sobre lo que debería estar. i. Asegúrese que las puntas del capacitor están conectadas en los lugares correctos. ii. Asegúrese que las puntas del capacitor son lo suficientemente largas y están haciendo suficiente contacto en los conectores. b. Si el voltaje entre (G, 3) y (NEGRO, cualquiera) es de 9V quizá hay un corto entre las terminales positivas (G,,L, 1) y (G..L, 3). c. Si el voltaje entre (ROJO, cualquiera) y (NEGRO, cualquiera) es 9 V quizá hay un corto entre las terminales positivas de la batería (G..L, 1) a cualquiera de (G..L, 6) o uno de los conectores rojos de potencia. d. Si el problema persiste contacte a Soporte Técnico de Parallax (Vea pagina 18). Pagina 44 · Kit Educativo de Prácticas Propeller: Fundamentos 4: Práctica básica de E/S y tiempo 4: Practica básica de E/S y tiempo Introducción La mayoría de aplicaciones en micro controladores requiere de una lectura de entrada, toma de decisiones y control de salidas. También hay una tendencia a ser sensibles al tiempo, con el micro controlador determinando cuando las entradas son monitoreadas y las salidas actualizadas. Los circuitos de botones pulsadores en esta práctica le darán ejemplos sencillos de aplicaciones que puede monitorear con los pins de E/S del Propeller. Del mismo módulos circuitos LED le darán un sencillo y efectivo significado del monitoreo de pins de E/S en el Propeller y los eventos de tiempo. Aunque la práctica del botón pulsador y el ejemplo del LED pueden parecer simples, están hechos para presentar claramente un número importante de técnicas de código que serán usadas y reusadas en otras prácticas. Esta es una lista de ejemplos de aplicaciones y de técnicas de código: • • • • • • • • • • • Encender un LED – Asignar direcciones de E/S y estados de Salidas Encender grupos de LEDs – Asignar grupos de E/S Estado de botón pulsador con LED – Monitorea una entrada y establece una salida de acuerdo Estado de un grupo de botones pulsadores con LED – E/S paralelas, monitorear un grupo de entradas y escribir a un grupo de salidas Señales sincronizadas Encendido/Apagado de LED – Evento de tiempo basado en un registro que cuenta los segundos del reloj Configurar el reloj del sistema Propeller – Escoger una fuente de reloj y configurar el multiplicador de de frecuencia Ciclo de Fase Cerrada (Phase Locked Loop) del chip Propeller. Desplegar patrones Encendido/Apagado – Introducción a mas operadores Spin que son usados comúnmente en registros de E/S Desplegar conteos binarios – Introducción a varios tipos de operadores y ejecución de bloques de código de ciclos condicionales Cambiar desplegados de luz – Ejecución de bloques de código y cambio de operaciones Cambiar desplegados de luz con botón pulsador-rango controlado de refrescado – Variables globales y locales y mas ejecución de cloques de código Desplegado de Hora normal en segundos– Introducción a eventos de tiempo sincronizados que funcionan independientemente de otras tareas dadas a un Cog Pre requisitos para la practica • Inicialización y prueba Lista de partes y esquemas Esta práctica utilizara seis circuitos LED y tres circuitos de botones pulsadores. (6) LEDs – diversos colores (6) Resistencia – 100 Ω (3) Resistencia – 10 kΩ (3) Botón Pulsador – Normalmente abierto (Misceláneos) cables de unión 3 Construir el circuito que se muestra en la Figura 4-1. Kit Educativo de Practicas Propeller: Fundamentos · Página 45 Práctica básica de E/S y tiempo Figura 4-1: Circuitos de Botón Pulsador y LED Nomenclatura del Propeller La documentación del micro controlador Propeller frecuentemente hace referencia a Cogs, Spin, Objetos, Métodos y variables Globales y Locales. Esta es una breve explicación de cada término: • Cog – Un procesador dentro de un chip Propeller. El chip Propeller tiene ocho Cogs, lo que hace posible que desarrolle diversas tareas en paralelo. El Propeller es como un súper micro controlador con 8 procesadores de alta velocidad de 32 bits dentro de él. Cada procesador interno (Cog) tiene acceso a los pins de E/S del chip Propeller y a los 32KB de RAM global. Cada Cog tiene sus 2KB de RAM que puede usar en código Spin o Ensamblador. • Lenguaje Spin – El lenguaje Spin es un lenguaje de programación de alto nivel creado por Parallax para el chip Propeller. Los Cogs que ejecutan el código lo hacen cargando un intérprete Spin de la ROM del chip Propeller. Este interprete obtiene y ejecuta los comandos Spin que son almacenados en la memoria global RAM del chip Propeller • Los Cogs del Propeller pueden programarse en lenguaje ensamblador de bajo nivel– Spin de alto nivel le dice a un Cog que hacer y Ensamblador de bajo nivel le dice cómo hacerlo. El lenguaje ensamblador genera código maquina que reside en la RAM del Cog y lo ejecuta directamente el Cog. Los programas en lenguaje ensamblador hacen posible escribir código que optimiza el desempeño del Cog, sin embargo requiere un entendimiento profundo de la arquitectura del chip Propeller. El kit fundamental PE se enfoca en programación Spin. • Método – Un bloque ejecutable de comandos Spin que tiene nombre, regla de acceso y puede como opción crear variables locales (temporalmente), recibir parámetros y regresar un valor. • Variables Globales y Locales – Las variables Globales están disponibles para todos los métodos en un objeto dado y reservan espacio variable como “long” en una aplicación que está corriendo. Las variables Locales están definidas en un método, solo puede ser usada dentro de ese método y solo existe mientras el método ejecuta comandos. Cuando termina, la memoria de esa variable local queda disponible para otros métodos y sus variables locales. Las Variables Globales y Locales se definen con sintaxis diferente. • Objeto – Un Bloque de aplicación de todo el código dado en un archivo .spin. Algunas aplicaciones Propeller usan solo un objeto pero la mayoría usa varios. Los objetos tienen una variedad de usos dependiendo parcialmente de como se escribieron y parcialmente en cómo se configuraron y son utilizados por otros objetos. Algunos objetos sirven como objetos de primera categoría que proporcionan un punto de inicio donde el primer comando en una aplicación dada se ejecuta. Otros objetos son escritos para proporcionar una librería de métodos útiles para objetos iniciales u otros objetos a utilizar. Pagina 46 · Kit Educativo de Prácticas Propeller: Fundamentos 4: Práctica básica de E/S y tiempo Los objetos se pueden escribir para usar solo un Cog o puede incluir código que inicializa uno o más Cogs. Algunos objetos tienen métodos que proporcionan datos para intercambiar información con procesos en otros Cogs. Algunos objetos pueden incluso hacer múltiples copias de otros objetos y darle a cada uno diferentes tareas. Los objetos pueden usar otros objetos los cuales pueden usar todavía otros objetos. En aplicaciones más complejas un conjunto de objetos forman una relación funcional que se ve como una estructura de archivos en la herramienta Propeller. Los ejemplos en esta práctica solo cubren objetos sencillos usando solo un método. En futuras prácticas se presentaran varias técnicas de construcción de bloques para usar en múltiples objetos y métodos en una aplicación así como aplicaciones multiprocesos usando varios Cogs. Como los objetos en esta práctica son sencillos muchos de ellos se modificaran para construir bloques para otros objetos en proyectos futuros. Luces encendidas con Direcciones y Salidas de Bits de Registro El objeto LedOnP4 que se muestra a continuación contiene un método llamado LedOn con comandos que indican al Cog en el chip Propeller para poner el pin P4 E/S en alto. Esto en su momento ocasiona que el LED en el circuito conectado a P4 emita luz. 3 Cargue LedOnP4 en RAM pulsando Run →Compile Current →Load RAM (o presione F10). '' File: LedOnP4.spin PUB LedOn dira[4] := 1 outa[4] := 1 repeat programa ' Declaración de método ' Asigna P4 a Salida ' Asigna P4 alto ' Esta operación previene que termine el Como trabaja LedOnP4.spin La primera línea en el programa es un comentario de documentación. Los comentarios de línea sencilla se denotan por dos apostrofes (no comillas) a la izquierda del texto de documentación. 3 Seleccione el botón “Documentation” sobre el código en el editor Propeller. Mientras que comandos como dira :=… y repeat no muestran modo de documentación, observe que en el texto a la derecha del doble apostrofe si aparecen. Observe también que los comentarios de nodocumentación en el código es precedido por apostrofes sencillos y no aparecen en modo de certificación. 3 Seleccione otras opciones y observe que muestran y que no muestran los elementos del objeto. L Comentarios de bloque: También existen comentarios de documentación de bloques que pueden extenderse varias líneas. Estos tienen que comenzar y terminar con dobles llaves como: {{Comentarios de documentación del bloque}}. Los comentarios de no-documentación también pueden extenderse varias líneas comenzando y terminando con llaves sencillas como: {Comentario de bloque de no-documentación}. Todos los comandos de lenguaje Spin que ejecuta el chip Propeller tienen que ser controlados con un bloque método. Cada bloque método tiene que declararse con al menos una regla de acceso y un nombre. Las reglas de acceso y los nombres de método se revisaran a detalle en otras prácticas, por ahora solo tenga en mente que PUB LedOn está declarado bloque método con una regla de acceso público (PUB) y el nombre LedOn. Kit Educativo de Practicas Propeller: Fundamentos · Página 47 Práctica básica de E/S y tiempo L Resaltar texto o no? En los párrafos de discusión la fuente usada en la herramienta Propeller se usa también para todo el texto que es parte de un programa. Las porciones de texto que son operadores o palabras reservadas estarán resaltadas. Las porciones que son definidas por el usuario tales como métodos, variables y nombres de constantes y valores no deberán estar resaltadas. Esto imita la sintaxis de la herramienta Propeller al remarcar el esquema Spin. Las listas de código y sobrantes no se les dan el resaltado. Para ver la versión de sintaxis completa véala en la herramienta Propeller con el Esquema Spin. Vaya a Edit→ Preferences→ Appearance para encontrar el menú Syntax Highlighting Scheme. El registro dira es uno de varios registros de propósito especial en la RAM del Cog; usted puede leer y escribir al registro dira el cual almacena direcciones de E/S para cada pin de E/S. Un 1 en un registro dira asigna el pin E/S como salida; un 0 como entrada. El símbolo “:=” es el operador de asignación; el comando dira[4] := 1 asigna el valor de 1 al Bit 4 del registro dira lo cual hace P4 una salida. Cuando un pin de E/S es asignado como salida, el valor de su bit en el registro outa asigna el pin en alto (3.3V) con un 1 o bajo (0V) con un 0. El comando outa[4] := 1 asigna el pin E/S P4 en alto. Como el circuito LED en P4 termina en tierra el resultado es que el LED emite luz. L E/S compartidas entre Cogs? Cada Cog tiene su propia salida E/S (outa) y su registro de dirección E/S (dira). Debido a que sus aplicaciones usan un solo Cog no tiene que preocuparse por dos Cogs intentando usar el mismo pin de E/S para diferentes propósitos al mismo tiempo. Cuando varios Cogs se utilizan en una aplicación cada dirección de pin E/S y estado de salida es el “cableado-OR” de los Cogs. Como trabajo esto lógicamente se describe en la sección Pin E/S en el Capítulo 1 del Manual Propeller. El comando repeat es uno de los comandos condicionales del lenguaje Spin. Puede hacer que un bloque de comandos se ejecute repetidamente basado en varias condiciones. Para que repeat afecte un cierto bloque de comandos tiene que estar debajo de ellos y contener al menos una línea de espacio. El siguiente comando después de repeat que no tiene espacio no es parte del bloque y será el siguiente comando a ejecutar después de que el ciclo repeat se complete. Como no hay nada debajo del comando repeat en el objeto LedOnP4 solo se repite continuamente. Este comando se necesita para prevenir que el chip Propeller vaya a modo de bajo consumo después de que se queda sin comandos por ejecutar. Si el comando repeat no estuviera ahí el LED encendería muy brevemente como para verlo y después el chip se pondría en modo de bajo consumo. Para nuestros ojos parecería que nada sucedió. Modificando LedOnP4 En una línea se puede hacer más de una asignación: 3 Remplace esto: dira[4] := 1 outa[4] := 1 ...con esto: dira[4] := outa[4] := 1 Por supuesto usted también puede expandir el método LedOn para que corra en más de un LED. 3 Modifique el método LedOn como se muestra aquí para encender los LEDs en P4 y P5: PUB LedOn dira[4] := outa[4] := 1 dira[5] := outa[5] := 1 repeat Pagina 48 · Kit Educativo de Prácticas Propeller: Fundamentos 4: Práctica básica de E/S y tiempo Si el comando repeat no estuviera al final del método los LEDs se apagarían tan rápido que no sería posible verlos en ningún momento. Solo un osciloscopio o ciertos circuitos externos podrían observar el breve estado de “Encendido”. 3 Intente correr el programa con el comando repeat comentado, colocando un apostrofe a su izquierda. 3 Si usted tiene un osciloscopio, prográmelo para capturar una señal sencilla y vea como puede detectar la señal. Operaciones en grupos de Pins E/S El lenguaje Spin tiene provisiones para asignar valores a grupos de bits en los registros dira y outa. En vez de usar un solo digito entre los corchetes seguidos de el comando outa, dos valores separados por dos puntos pueden usarse para denotar un grupo de bits. El numero binario indicador % proporciona una forma conveniente de definir el patrón del bit que es asignado al grupo de bits en el registro outa o dira. Por ejemplo dira[4..9] := %111111 colocara de los bits 4 al 9 en el registro dira (como salidas). Otro ejemplo outa[4..9] := %101010 activa P4, limpia P5, active P6 y así sucesivamente. El resultado puede ser que los LEDs conectados a P4, P6, P8 se enciendan mientras los otros están apagados. 3 Cargue GroupIoSet.spin en la RAM (F10). 3 Verifique que los LEDs en P4, P6 y P8 encienden. '' File: GroupIoSet.spin PUB LedsOn dira[4..9] := %111111 outa[4..9] := %101010 repeat Modificando GroupIoSet.spin Observe que outa[4..9] := %101010 hace que el estado del bit de registro 4 outa se ponga en (1) el bit 5 limpio (0) y así sucesivamente. Si los valores del grupo de pins inicial y final se cambian el mismo patrón hará que el bit 9 se ponga en (1), el bit 8 limpio (0) y así sucesivamente. 3 Remplace outa[4..9] := %101010 …con esto outa[9..4] := %101010 3 Cargue el programa en la RAM del chip Propeller y verifique que los LEDs tienen el patrón inverso. No importa qué valor esta en el bit de registro outa si su bit de registro dira es cero. Esto es porque las funciones de los pins E/S están definidos como entrada en vez de salida cuando el registro dira está limpio. Un pin de E/S funcionando como entrada detecta una señal alta o baja en vez de enviarlas. Mientras un pin se configura como salida envía 3.3 o 0V, un pin configurado como entrada no transmite nada ya que solo esta monitoreando el voltaje aplicado al pin. Kit Educativo de Practicas Propeller: Fundamentos · Página 49 Práctica básica de E/S y tiempo Un pin de E/S configurado como salida alta conectado a un LED hace que el LED encienda cuando se aplica 3.3V al circuito. Como la otra terminal del LED está conectada a tierra (0V) la presión eléctrica a través del circuito LED hace que la corriente fluya en el circuito lo cual hace que la luz encienda. Un pin de E/S configurado como salida baja apagara el circuito del LED porque aplica 0 V al circuito. Con 0 V en ambas terminales del circuito no hay presión eléctrica por lo que no fluye la corriente y las luces se quedan apagadas. La luz se queda apagada también cuando el pin E/S se configura como entrada pero esto sucede por otra razón. Un pin de E/S configurado como entrada no aplica voltaje ya que esta sensando el voltaje aplicado por el circuito. El resultado es que el LED se queda apagado. Como un pin de E/S configurado como entrada no aplica ningún voltaje al circuito no importa qué valor esta en el bit de registro outa correspondiente. El circuito de LED conectado a ese pin se mantendrá apagado. Aquí un ejemplo que configura todos los bits en outa[4..9] pero no en todos los bits dira[4..9]. El LED conectado a P6 y P7 no prenderán porque sus pins E/S se están configurados como entradas con ceros en el registro dira. 3 Configurar todos los bits outa[4..9]. outa[4..9] := %111111 3 Limpiar los bits 6 7 7 en dira[4..9]. dira[4..9] := %110011 3 Cargar la modificación del programa en la RAM del chip Propeller y verificar que los bits puestos a 1 en outa[6] y outa[7] no pueden prender los LEDs en P6 y P7 porque sus pins fueron configurados para entradas con ceros en dira[6] y dira[7]. Leyendo una Entrada, Controlando una Salida El registro ina es un registro de solo lectura en la RAM del cog donde los bits almacenan el estado de cada pin de E/S. Cuando un pin de E/S es configurado como salida su registro ina reportara el mismo valor que el registro outa ya que el registro ina indica voltaje alto-bajo con 1 y 0. Si por el contrario el pin de E/S es una entrada su registro ina se actualiza dependiendo del voltaje aplicado a él. Si en los pins de E/S hay un voltaje arriba de 1.65 V se observa una entrada lógica y el registro ina almacena un 1 de otra forma almacena un 0. El registro ina se actualiza con el estado de voltaje de los pins de E/S cada vez que el comando ina se usa para leer este registro. El botón pulsador conectado a P21 aplicara 3.3V a P21 cuando se presione o 0V cuando no se presione. En el objeto ButtonToLed dira[21]es puesto a 0 haciendo el pin E/S P21 una entrada. Así almacenara un 1 si el botón P21 se presiona o un 0 si no se presiona. Asignando repetidamente el valor almacenado en ina[21] a outa[6] el método ButtonLed hace que el LED en P6 encienda cada que el botón en P21 se presiona. Note que también el comando outa[6] := ina[21] se incluye bajo el comando repeat lo cual hace que esta línea se ejecute una y otra vez. 3 Cargue ButtonToLed.spin en la RAM. 3 Presione y suelte el botón conectado a P21 y verifique que el LED conectado a P6 enciende mientras el botón se mantiene presionado. '' Archivo: ButtonToLed.spin '' Led refleja el estado del botón pulsador. PUB ButtonLed dira[6] := 1 dira[21] := 0 repeat outa[6] := ina[21] ' Pushbutton/Led Method ' ' ' ' P6 → P21 → ciclo Copia Pagina 50 · Kit Educativo de Prácticas Propeller: Fundamentos salida entrada (este comando es redundante) sin fin entrada P21 a P6 4: Práctica básica de E/S y tiempo Leer Múltiples Entradas, Controlar Múltiples Salidas Un grupo de bits puede copiarse del registro ina al outa con un comando como outa[6..4] := ina[21..23]. El comando dira[6] := 1 también tendrá que cambiarse a dira[6..4] := %111 antes de que los botones enciendan los LEDs. 3 Guarde una copia de ButtonToLed y modifíquelo para hacer que los botones P23, P22 y P21 enciendan los LEDs P4, P5 y P6 respectivamente. Sugerencia: Usted solo necesita el comando outa. 3 Intente invertir el orden de los pins en outa[6..4]. Como afecta esto a la forma en que el botón ingresa al mapa de las salidas de los LEDs? Que sucede si invierte el orden de los bits en ina[21..23] ? Retrasos de tiempo con el reloj del sistema Ciertas operaciones con E/S son mucho más fáciles de estudiar con el código que controla el tiempo de ciertos eventos como cuando un LED enciende o cuánto tiempo se presiono un botón. Los tres constructores de bloques básicos para un evento de tiempo en Spin son: • • cnt – un registro en el chip Propeller que cuenta los ciclos de reloj del sistema. clkfreq – un comando que regresa al chip Propeller la frecuencia del reloj en Hz. Otra forma • útil de pensarse es como el valor que almacena el número de ciclos de reloj en un segundo. waitcnt – un comando que espera a que el registro cnt tenga un cierto valor. El comando waitcnt espera a que el registro cnt alcance el valor entre paréntesis. Para controlar el tiempo que waitcnt espera es mejor sumar el numero de ciclos de reloj del sistema que han pasado al número de ciclos de reloj que usted quiere que cnt espere. El ejemplo suma clkfreq, el número de ciclos de reloj en un segundo, al valor actual de cnt. El resultado de la suma entre paréntesis es el valor que el registro cnt alcanzara 1 segundo después. Cuando el registro cnt alcanza ese valor waitcnt deja al programa moverse al siguiente comando. waitcnt(clkfreq + cnt) ' espera por 1 s. Para calcular retrasos que duran fracciones de segundos simplemente divida clkfreq por un valor antes de sumarlo al registro cnt. Por ejemplo, aquí está un comando waitcnt que retrasa una tercera parte de un segundo y otro que retrasa por 1ms. waitcnt(clkfreq/3 + cnt) waitcnt(clkfreq/1000 + cnt) ' espera 1/3 s ' espera 1 ms El objeto LedOnOffP4.spin usa el comando waitcnt para encender P4, esperar ¼ s, apagar P4 y esperar 3/4s. El LED prende y apaga a 1 Hz y estará prendido el 25% del tiempo. '' Archivo: LedOnOffP4.spin PUB LedOnOff dira[4] := 1 repeat outa[4] := 1 waitcnt(clkfreq/4 + cnt) outa[4] := 0 waitcnt(clkfreq/4*3 + cnt) Kit Educativo de Practicas Propeller: Fundamentos · Página 51 Práctica básica de E/S y tiempo 3 Cargue el objeto LedOnOffP4 en la RAM del chip Propeller y verifique que la luz prende y apaga cada segundo por ¼ encendido y ¾ apagado. Recuerde que el indentado es importante! La Figura 4-2 muestra un error común que puede ocasionar resultados inesperados. En la izquierda las cuatro líneas bajo el comando repeat están mas indentadas que repeat. Esto significa que están anidadas en el comando repeat y los cuatro comandos se repetirán. En la derecha las líneas bajo repeat no están indentadas. Estas están al mismo nivel que el comando repeat. En este caso el programa nunca llega a ellas porque el ciclo repeat no hace nada. Note que las líneas sombreadas que conectan la “r” en repeat a los comandos debajo de ella. Estas líneas indican los comandos en el bloque en el que opera repeat. Para habilitar esta función en el software Propeller presione Edit y seleccione Preferences. Debajo de la tabla Appearance seleccione la opcion Show Block Group Indicators o use el acceso rápido Ctrl +I ! Figura 4-2: Bloque de Código Repeat Este ciclo repeat repite cuatro comandos Los comandos bajo repeat no están indentados así que no son parte del ciclo repeat. Dentro de waitcnt(clkfreq + cnt) Cuando se usa Run → Compile Current → Load… para cargar un objeto la herramienta Propeller examina algunas declaraciones constantes que configuran el sistema de reloj del chip Propeller. Si el objeto no tiene estas constantes de reloj el software Propeller almacena valores por defecto en el registro CLK del chip Propeller el cual está programado para usar el oscilador interno RC en modo rápido (aproximadamente 12 MHz) para el reloj del sistema. Con el reloj de sistema por defecto a 12MHz la instrucción waitcnt(clkfreq + cnt) es equivalente a la instrucción waitcnt(12_000_000 + cnt). La Figura 4-3 muestra como waitcnt(12_000_000 + cnt) espera para que el registro cnt acumule 12 millones más de ciclos de reloj que cuando el comando waitcnt comienza. Tenga en mente que el registro cnt se ha estado incrementando con cada ciclo de reloj desde que el chip Propeller se reencendió. En este ejemplo cnt alcanzo los 50,000,008 ciclos de reloj cuando waitcnt se ejecuto. Así el valor cnt que waitcnt espera es 12,000,000 +50,000,008 = 62,000,008. Por lo tanto el Cog que ejecuta waitcnt(12_000_000 + cnt) no se le permite moverse al siguiente comando hasta que el registro cnt alcanza los 62,000,008 ciclos de reloj. Pagina 52 · Kit Educativo de Prácticas Propeller: Fundamentos 4: Práctica básica de E/S y tiempo Figura 4-3: El Comando waitcnt y el Registro cnt Configuración del Reloj del Sistema y Eventos de Tiempo Hasta este punto nuestros programas han usado el reloj interno por defecto de 12 MHZ del chip Propeller. Vamos a modificarlo para usar el oscilador externo de 5 MHz en nuestro circuito de la Plataforma PE. Ambos, Spin y Ensamblador Propeller tienen provisiones para declarar constantes que configuran el sistema de reloj y se aseguran que los objetos conozcan cual es su frecuencia de operación. El bloque de asignación CON define una sección del código para declarar la configuración del Propeller así como las símbolos de las constantes globales para usar en el programa. Declaraciones similares a las del bloque CON pueden agregarse al objeto origen para configurar el sistema de reloj del chip Propeller. Este conjunto de declaraciones hará que el reloj del sistema del chip Propeller corra a una velocidad límite de 80MHz CON _xinfreq = 5_000_000 _clkmode = xtal1 + pll16x La línea _xinfreq = 5_000_000 define la frecuencia esperada del oscilador externo el cual en el caso de la Plataforma PE es 5.00 MHz. La línea _clkmode = xtal1 + pll16x hace que el compilador Spin en la herramienta Propeller programe ciertos bits del registro CLK del chip cuando descarga el programa. (Vea Manual del Propeller para mayor información) El modo de reloj xtal1 configura ciertos pins XO y XI con características para trabajar con cristales externos en el rango de 4 a 16 MHz La frecuencia del cristal externo proporciona la señal de entrada del reloj el cual el circuito PLL (phase-locked loop) del chip Propeller multiplica por el reloj del sistema. pll16x es un modo de reloj pre-definido que hace que el circuito PLL multiplique la frecuencia de 5 MHz por 16 para entregar al sistema una señal de reloj de 80MHz. La constante pll8x puede usarse con el mismo oscilador para correr el sistema de reloj del chip Propeller a 40MHz. La constante pll4x hará que el chip Propeller corra a 20MHz y así sucesivamente. La lista completa para declaraciones de constantes validas _clkmode puede encontrarse en el Manual Propeller de Referencia de Lenguaje Spin en la sección _CLKMODE. Kit Educativo de Practicas Propeller: Fundamentos · Página 53 Práctica básica de E/S y tiempo Precisión del Cristal El reloj interno RC del chip Propeller sirve para aplicaciones no sensitivas al tiempo tales como control de salidas basadas en entradas y luces parpadeando. Para aplicaciones que son sensitivas al tiempo como comunicación serial, generación de tonos, servo control y temporizadores el chip Propeller puede conectarse a cristales osciladores y otras señales de alta precisión a través de sus pins XI y XO. L El oscilador interno del chip Propeller en su modo por defecto RCFAST es el que usa el chip Propeller si el programa no especifica otra fuente o modo. La frecuencia nominal del oscilador es 12MHz, pero es una frecuencia actual que puede caer en el rango de 8 a 20 MHz. Esto es un error de +66 a -33%. Nuevamente, para aplicaciones que no requiere tiempo preciso es suficiente. Por otro lado una aplicación como comunicación serial asíncrona puede tolerar únicamente 5% de error y eso es sumando los errores del transmisor y el receptor. En diseños prácticos será mejor apostar por un error menor del 1%. Usando un cristal oscilador externo para la fuente de reloj en el chip Propeller la frecuencia puede estar dentro de esta tolerancia e incluso en tolerancias de diseños de temporizadores. La Plataforma PE tiene un cristal de cuarzo de ESC Inc. HC-49US conectado a los pins XI y XO del chip Propeller que puede usarse en la mayoría de aplicaciones sensitivas al tiempo. La hoja de datos para esta parte menciona una tolerancia de +/- 30 PPM que significa +/- 30 ciclo de reloj en un millón. Eso es un porcentaje de error de +/- 0.003%. Obviamente es más que preciso para una comunicación serial asíncrona y también para servo control y generación de tonos. No es necesariamente ideal para relojes; el error de este cristal puede hacer que una alarma de reloj gane o pierda 2.808s por día. Esto puede ser suficiente para relojes que se verifican continuamente con un reloj atómico para actualizarse. Tenga en mente que para hacer que el chip Propeller funcione con precisión de reloj de pulso solo necesita un oscilador más preciso La hoja de datos del HC-49US también tiene límites para temperatura (+/- 50PPM) y desgaste (+/- 5 PPM por año). Incluso después de 5 años en su rango de -10 + 70ºC el máximo error podría ser 105PPM lo cual está todavía en control, pero nuevamente, una alarma de reloj podría ganar o perder 9 s por día. Como clkfreq almacena la frecuencia del reloj del sistema el código objeto puede confiar en él para el tiempo sin importar la configuración del reloj del sistema. El comando clkfreq regresa el numero de ciclos por segundo basado en la configuración del sistema. Por ejemplo, este bloque CON usa _xinfreq = 5_000_000 y _clkmode = xtal1 + pll16x, por lo que clkfreq regresa el valor de 5,000,000 × 16, que equivale a 80,000,000. ConstantBlinkRate.spin puede configurarse a una variedad de rangos de reloj del sistema para demostrar como clkfreq mantiene constantes de tiempo sin importar la frecuencia del reloj. 3 Cargue ConstantBlinkRate.spin en la RMA del chip Propeller (F10). El reloj del sistema correrá a 80 MHz. 3 Verifique que rango del parpadeo es de 1 Hz 3 Modifique la declaración de la constante _clkmode para leer _clkmode = xtal1 + pll8x y hacer que el sistema corra a 40MHz y cargue el programa en la RAM (F10) '' File: ConstantBlinkRate.spin CON _xinfreq = 5_000_000 _clkmode = xtal1 + pll16x PUB LedOnOff dira[4] := 1 repeat outa[4] := 1 waitcnt(clkfreq/2 + cnt) outa[4] := 0 waitcnt(clkfreq/2 + cnt) El reloj de sistema del Propeller trabaja ahora a 40MHz. El LED está parpadeando a 1Hz todavía? 3 Repita para pll4x, pll2x, y pll1x. No deberá cambiar el rango de parpadeo a ninguna de estas frecuencias del reloj del sistema. Pagina 54 · Kit Educativo de Prácticas Propeller: Fundamentos 4: Práctica básica de E/S y tiempo Temporizar con clkfreq vs. Temporizar con Constantes Vamos a decir que un valor constante es usado en vez de clkfreq para hacer que el programa trabaje de una forma a una frecuencia del reloj del sistema particular. Que sucede cuando la frecuencia del reloj del sistema del chip Propeller cambia? 3 Guarde una copia del objeto ConstantBlinkRate como BlinkRatesWithConstants.spin. 3 Asegúrese que el multiplicador PLL está en pll1x para que el reloj corra a 5MHz. 3 Para una señal de encendido/apagado de 1Hz cambie ambas instancias clkfreq/2con 2_500_000. (La herramienta Propeller acepta guión bajo, pero no comas, el números largos para hacerlos más legibles) 3 Cargue el objeto en la RAM del chip Propeller y verifique que el LED parpadea a 1 Hz. 3 Después, cambia el multiplicador PLL a pll2x. Cargue el objeto modificado en la RAM del Propeller. La luz parpadea dos veces más rápido? Intente pll4x, pll8x, y pll16x. Cuando un valor constante se usa en vez de clkfreq un cambio en el reloj del sistema ocasiona un cambio en el evento del tiempo. Esto es porque los objetos deben usar clkfreq cuando se necesita un cambio esperado, especialmente para objetos diseñados para usarse en otros objetos. De esta forma el programador puede escoger la mejor frecuencia de reloj para la aplicación sin tener que preocuparse acerca si algún objeto de la aplicación se comportara diferente. Mas Operaciones de Registros de Salida En la sección Operaciones en grupos de Pins E/S, se asignaron valores binarios a los grupos de bits en los registros dira y outa. Hay muchas formas de recortar y trucos para manipular valores en grupos de E/S que usted verá en ejemplos de códigos publicados. Los Operadores Post-Activo “~~” y Post-Limpio “~” Debajo hay dos ejemplos que hacen lo mismo. Mientras que el objeto a la izquierda usa técnicas vistas anteriormente para activar o limpiar todos los bits en dira[4..9]y outa[4..9],el de la derecha lo hace diferente con los operadores Post-Activo “~~”y Post-Limpio “~”. Estos operadores son útiles cuando todos los bits de un cierto rango tienen que activarse o limpiarse. ''Archivo: LedsOnOff.spin ''Todos los LEDs encendidos ''1/4s y apagados 3/4s. PUB BlinkLeds ''Archivo: LedsOnOffAgain.spin ''Todos los LEDs encendidos ''1/4s y apagados 3/4s con Post ''Activo/Limpio PUB BlinkLeds dira[4..9] := %111111 dira[4..9]~~ repeat repeat outa[4..9] := %111111 waitcnt(clkfreq/4 + cnt) outa[4..9] := %000000 waitcnt(clkfreq/4*3 + cnt) outa[4..9]~~ waitcnt(clkfreq/4 + cnt) outa[4..9]~ waitcnt(clkfreq/4*3 + cnt) 3 Cargue cada programa en la RAM del chip Propeller y verifique que son idénticos. 3 Analice como el Operador Post-Activo reemplaza := %111111 y el Post-Limpio remplaza := %000000. Kit Educativo de Practicas Propeller: Fundamentos · Página 55 Práctica básica de E/S y tiempo 3 Intente modificar ambos programas para que solo afecte P4..P7. Note que los operadores Post-Activo y Post-Limpio requieren menos mantenimiento ya que automáticamente activa o limpia todos los bits en el rango especificado. El Operador inteligente NO “!” Aquí hay otros dos ejemplos de programas que hacen lo mismo. Esta vez ambos alternan patrones en los LEDs. El de la izquierda tiene operadores familiares asignados en el ciclo repeat. El de la derecha inicializa el valor outa[4..9] antes del ciclo repeat. Después en el ciclo repeat usa el operador NO “!” en outa[4..9]. Si outa[4..9] almacena%100001 el comando !outa[4..9] invierte todos los bits (los 1’s se hacen 0’s, los 0’s se hacen 1’s). Por lo que el resultado de !outa[4..9] será %011110. 3 Cargue cada objeto en la RAM del chip Propeller y verifique que son idénticos. 3 Intente duplicar la frecuencia en cada objeto. ''Archivo: LedsOnOff50Percent.spin ''Leds alternan ''encendido/apagado el 50% del ''tiempo ''Archivo: LedsOnOff50PercentAgain.spin ''!Leds alternan ''encendido/apagado el 50% del ''tiempo con el operador ! PUB BlinkLeds PUB BlinkLeds dira[4..9]~~ repeat dira[4..9]~~ outa[4..9] := %100001 repeat outa[4..9] := %100001 waitcnt(clkfreq/4 + cnt) outa[4..9] := %011110 waitcnt(clkfreq/4 + cnt) !outa[4..9] waitcnt(clkfreq/4 + cnt) Patrones de Bit de Registro como valor Binario Un rango de bits en un registro puede escribirse como dígitos o como número binario. Por ejemplo en la instrucción outa[9..4] := %000000 recuerde que % es el indicador de numero binario, %000000 es un numero binario de 6 bits con valor de cero. Se pueden hacer operaciones con este valor y colocar el resultado nuevamente en el registro. El objeto IncrementOuta agrega 1 a outa[9..4] cada vez que se repite el ciclo. El resultado será la siguiente secuencia de valores binarios desplegados en los LEDs: Valor Binario Equivalente Decimal %000000 0 %000001 1 %000010 2 %000011 3 %000100 4 %000101 5 etc… %111101 61 %111110 62 %111111 63 3 Cargue IncrementOuta.spin en la RAM. Pagina 56 · Kit Educativo de Prácticas Propeller: Fundamentos 4: Práctica básica de E/S y tiempo '' Archivo: IncrementOuta.spin PUB BlinkLeds dira[9..4]~~ outa[9..4]~ repeat waitcnt(clkfreq/2 + cnt) outa[9..4] := outa[9..4] + 1 'cambia a (clkfreq + cnt) para alentar el ciclo El ciclo comienza al poner los pins E/S como salida con dira[9..4]~~. Después outa[9..4]~ limpia todos los bits en el registro outa rango 9..4 a %000000 cero binario. La primera vez a través del ciclo repeat se suma 1, el equivalente a outa[9..4] := %000001, lo cual hace que el LED en P4 se encienda. Como el ciclo se repite indefinidamente el patrón de LEDs pasa por cada posible permutación. El Operador de incremento “++” El operador de incremento “++”puede usarse en vez de + 1 para incrementar un valor. El comando outa[9..4]++ es equivalente a outa[9..4] := outa[9..4] + 1 3 Modifique el comando outa en el ciclo repeat para usar solo outa[9..4]++. 3 Cargue el objeto modificado en la RAM. Se comportan igual los LEDs? Comandos condicionales de Repeat Las opciones de sintaxis para repeat hacen posible especificar el número de veces a repetir un bloque de comandos. También puede repetirse until o while una o más condiciones existan, incluso intercambiar un valor variable de un valor from de inicio a un valor final a con la opcion del Delta step. 3 Lea la explicación en la sección REPEAT de la Referencia de Lenguaje Spin del Manual Propeller si lo encuentra útil. Vamos a modificar IncrementOuta.spin para detenerlo después que el último valor (%111111 = 63) ha sido desplegado. Para limitar el ciclo a 63 solo agregue una expresión de conteo al comando repeat como este: repeat 63 3 Guarde IncrementOuta.spin como BinaryCount.spin. 3 Agregue el valor de contador 63 después del comando repeat. 3 Para dejar los LEDs encendidos al terminar el bloque repeat agregue un segundo comando repeat debajo del bloque. Asegúrese que no está más indentado que el primer repeat. 3 Cargue el objeto BinaryCount en la RAM del chip Propeller y verifique que los LEDs encienden de acuerdo a la secuencia de valores binarios. Existen diferentes formas de modificar el ciclo repeat para contar hasta cierto valor y parar. Aquí hay algunas variaciones de ciclos repeat que cuentan a decimal 20 (binario %010100); el segundo ejemplo usa el operador igual a “==”, el tercero usa en operador menor que “<” repeat 20 repeat until outa[9..4] == 20 repeat while outa[9..4] < 20 ' Repite el ciclo 20 veces ' Repite hasta que outa[9..4] es igual a 20 ' Repite mientras outa[9..4] es menor que 20 Kit Educativo de Practicas Propeller: Fundamentos · Página 57 Práctica básica de E/S y tiempo Operaciones en Posiciones y Pre – Post Posiciones de Operadores (11 formas diferentes de contar hasta 20) El comando outa[9..4]++ puede removerse del bloque de código en el ciclo repeat e incrementarse justo dentro de las condiciones del comando repeat. El objeto IncrementUntilCondition.spin muestra un ejemplo que cuenta hasta 20 sin incrementar outa[9..4] con el ++ en la condición del ciclo repeat. '' Archivo: IncrementUntilCondition.spin PUB BlinkLeds dira[4..9]~~ repeat until outa[9..4]++ == 19 waitcnt(clkfreq/2 + cnt) repeat L outa y dira inician en cero cuando comienza el programa, así que no se necesita incluir outa[9..4]~. 3 Cargue IncrementUntilCondition.spin en el Propeller y verifique que cuenta hasta 20. Note que el ciclo se repite hasta 19 pero el programa de cuenta hasta 20. Otra forma de usar ++ en la condición del ciclo repeat es ponerlo antes de outa[9..4], como este: repeat until ++outa[9..4] == 20 Modifique el comando repeat del objeto IncrementUntilCondition con esta condición hecha until ++outa[9..4] == 20. Verifique que aun para al contar hasta 20. Cuál es la diferencia? Si ++ se pone a la izquierda del outa[9..4], típicamente se llama PreIncremento y la operación se desarrolla antes de evaluar la condición ++outa[9..4] ==. (El operador “--” puesto a la izquierda se llama Pre-Decremento). Igualmente si ++ o -- se coloca a la derecha de outa[9..4], se llama típicamente Post-Incremento o Post-Decremento y la operación se desarrolla después de evaluar la condición. Con repeat until outa[9..4]++ == 19, el ciclo de retrasa en waitcnt cuando outa[9..4] almacena 0, 1, 2…19. Cuando outa[9..4] almacena 19, el ciclo no repite el waitcnt. Sin embargo como postincremento sucede después de evaluar la condición otro uno se agrega al outa[9..4] aun cuando el ciclo no se repite de nuevo. Con repeat until ++outa[9..4] == 20 el ciclo se pre-incrementa, así que el primer retraso no sucede hasta después de que outa[9..4] brinca a 1. El siguiente retraso sucede después de 2, 3 y así hasta 19. Cuando outa[9..4] se convierte en 20 el comando ya no se ejecuta por lo que el ultimo valor en tiene un 20. En vez de repetir hasta que una condición es verdadera un ciclo se puede repetir mientras una condición es verdadera. Aquí hay ejemplos de conteos hasta 20 usando la condición while con operadores Post y Pre Incrementos sumando 1 a outa[9..4]: Pagina 58 · Kit Educativo de Prácticas Propeller: Fundamentos 4: Práctica básica de E/S y tiempo repeat while outa[9..4]++ < 19 ' Repite mientras outa[9..4] post' incrementado es menor que 19. repeat while ++outa[9..4] < 20 ' Repite mientras outa[9..4] pre' incrementado es menor que 20. Note que el ciclo post-incrementado cuenta hasta 20, repitiendo mientras outa[9..4] es menor que 19, pero la versión pre-incrementada repite mientras outa[9..4]es menor que 20. Note que con repeat while…el operador “<” menor que se usa en vez del operador “==” igual que. Estas dos formas demuestran la distinción entre repetir hasta que algo es igual a un valor lo que es diferente a repetir mientras algo es menor que un valor. Por supuesto, usted puede usar el operador “=<” igual o menor que o incluso el operador no igual que “<>”. Aquí tenemos ejemplos de esos; en todos los casos los LEDs pararan en binario 20. repeat while outa[9..4]++ =< 18 repeat while ++outa[9..4] =< 19 repeat while ++outa[9..4] <> 20 'Repite mientras [9..4] post'incrementado es menor '18 'Repite mientras outa[9..4] pre'incrementado es menor que 19 que o igual a 'Repite mientras outa[9..4] pre'incrementado no es igual a 20 Mayor que “>” o incluso Igual que o Mayor que “=>” pueden usarse también con repeat until… repeat until outa[9..4]++ > 18 repeat until ++outa[9..4] > 19 repeat until ++outa[9..4] => 20 repeat until outa[9..4]++ => 19 'Repite hasta que outa[9..4] post'incrementado es mayor que 18 'Repite hasta que outa[9..4] pre'incrementado es mayor que 19 'Repite hasta que outa[9..4] pre- es 'incrementado es igual que o mayor a '20 'Repite hasta que outa[9..4] post'incrementado es igual que o mayor a '19 3 Analice cada uno de los comandos repeat y pruebe cada uno en al objeto IncrementUntilCondition. Si usted todavía tiene preguntas acerca de esto, no se preocupe por el momento. El punto de esta sección es demostrar que hay una variedad de formas para hacer comparaciones e incrementar valores. Otras prácticas incluirán mejores formas de desplegar cada ciclo para que usted pueda probar en cada intento. Mas variaciones Repeat con From...To... (Otras 3 formas de contra hasta 20) Aquí hay una condición mas para repeat, repitiendo outa[9..4] de un valor a otro valor. Con cada repetición del ciclo, esta forma de repeat automáticamente suma 1 a la cuenta cada vez. Fíjese en el fragmento de abajo. La primera vez a través del ciclo outa[9..4] empieza en 0. La segunda vez se suma automáticamente 1 y la condición se verifica para asegurarse que outa[9..4] es mayor que o igual a 0 o menos que o igual a 19. Se suma 1 cada vez que se repite el ciclo. Después del ciclo donde outa[9..4] es igual a 19 se suma 1 a outa[9..4] haciéndolo 20. Como 20 no está en el rango “de 0 a 19” el código en el ciclo no se ejecuta. Kit Educativo de Practicas Propeller: Fundamentos · Página 59 Práctica básica de E/S y tiempo repeat outa[9..4] from 0 a 19 'Suma 1 a outa[9..4] con cada 'repetición, empieza en 0 y cuenta 'hasta 19. Aquí se muestra un comando repeat que ofrece una función similar usando and. Prueba dos condiciones, ambas deben ser verdaderas para que el ciclo se repita. Aquí necesitamos incrementar con el ciclo bloque: repeat while (outa[9..4] => 0) and (outa[9..4] =< 19) outa[9..4]++ Otra punto importante de la forma repeat…from…a… es que usted puede usar un argumento step. Por ejemplo si usted quiere repetir el ciclo con outa[9..4] a todos los valores pares y salir del ciclo dejando outa[9..4] en 20, aquí tiene una forma de hacerlo: Repeat outa[9..4] from 0 a 18 step 2 3 Pruebe las variaciones de los comandos repeat en esta sección para el objeto IncrementUntilCondition. Vocabulario de operadores Los operadores Unarios tienen un operando. Por ejemplo el operador “-” en la expresión -1 es un operador unario y 1 es el operando. Los operadores binarios tienen dos operandos; por ejemplo el operador menos “-” en la expresión x - y es un operador binario y x y y son operandos. Operadores normales tales como suma “+” opera en sus operandos y proporciona un resultado para el resto de la expresión sin afectar a los operandos. Algunos operadores que hemos utilizado como :=, ~~, ~, y ! son operadores de asignación. Los operadores unarios de asignación tales como ~ , ~~, y ++ escriben el resultado de la operación de regreso al operando mientras que los operadores binarios de asignación tales como := asignan el resultado al operando de la izquierda inmediata. En ambos casos el resultado está disponible para uso en el resto de la expresión. Los operadores de transferencia a la derecha “>>” y transferencia a la izquierda“<<” toman el patrón binario del valor en el primer operando y lo mueven a la derecha o izquierda por el numero de bits especificado en el Segundo operando y regresa el valor creado por el nuevo patrón de bit. Si una forma de asignación (>>= o <<=) se usa, el valor original es sobrescrito con el resultado. Los operadores de transferencia son parte de un grupo más grande, el de Operadores de Bits Inteligentes el cual realiza diversas manipulaciones de bits. El operador inteligente NO “!” que vimos anteriormente es un ejemplo. Algunos operadores normales y de asignación tienen características adicionales de ser Operadores de Comparación. Un Operador de Comparación regresa verdad (-1) si los valores en ambos lados del operador hacen la expresión verdadera o falso (0) si los valores en ambos lados hacen la expresión falsa. (Estos operadores de comparación binaria también se les llama Operadores Booleanos; también hay un operador booleano unario, NOT) Bloques condicionales con if Como muchos lenguajes de programación, Spin tiene un comando if que permite ejecutar un bloque de código condicionalmente, basado en el resultado de una prueba. Un comando if puede usarse por sí mismo o como parte de una serie más compleja de decisiones cuando se combina con elseif, elseifnot y else. Los Operadores de Comparación son útiles para probar condiciones en una declaración. Pagina 60 · Kit Educativo de Prácticas Propeller: Fundamentos 4: Práctica básica de E/S y tiempo if outa[9..4] == 0 outa[9..4] := %100000 waitcnt(clkfreq/10 + cnt) Si la condición es verdadera el bloque de código debajo (una línea en este caso) se ejecutara. De otra forma el programa se brincara hasta el siguiente comando que este en el mismo nivel de indentacion que la declaración if (aquí es waitcnt). Moviendo el desplegado de LED El siguiente objeto ejemplo ShiftRightP9toP4.spin, usa diferentes tipos de operadores para producir eficientemente el movimiento de un patrón de luces con nuestro circuito de 6 LED. 3 Cargue ShiftRightP9toP4 en la RAM del chip Propeller. 3 Oriente su plataforma para que parezca que las luces se mueven de izquierda a derecha una y otra vez. 3 Verifique que el patrón empieza en P9 y termina en P14 antes de repetir. '' Archivo: ShiftRightP9toP4.spin '' Demuestra el operador de movimiento a la derecha y la declaración if PUB ShiftLedsLeft dira[9..4] ~~ repeat if outa[9..4] == 0 outa[9..4] := %100000 waitcnt(clkfreq/10 + cnt) outa[9..4] >>= 1 Cada vez que pasa el ciclo repeat, el comando if [9..4] == 0 usa el operador == para comparar contra el valor 0. Si la expresión es verdadera el resultado de la comparación es -1. Si es falsa el resultado es 0. Recuerde que por regla outa[9..4] inicializa en cero así que outa[9..4] == 0 se evalúa como verdadero la primera vez que pasa por el ciclo repeat. Esto hace que la sentencia if ejecute el comando outa[9..4] := %100000, el cual enciende el LED en P9. Después de la pausa de 1/10s, >>= (el operador de asignación mover a la derecha) toma el bit en outa[9..4] y lo mueve a su derecha un bit con la siguiente instrucción: outa[9..4] >>= 1. El bit de la derecha que estaba en outa[4] se elimina y la vacante que se crea en outa[9] se llena con un 0. Por ejemplo si outa[9..4] almacena %011000 antes de outa[9..4] >>= 1, almacenara %001100 después. Si el comando fuera outa[9..4] >>= 3, el resultado sería %000011 Cada vez que el ciclo se repite el comando outa[9..4] >>= 1 mueve el patrón a la derecha, generando un ciclo %100000. %010000, %001000,…%000001, %000000. Cuando outa[9..4] tiene %000000 el comando if ve que outa[9..4] almacena un 0, por lo que almacena %100000 en outa[9..4] y el movimiento de la luz en el LED se repite. 3 Pruebe al cambiar el Segundo operando en la operación de mover a la derecha de 1 a 2 para hacer que el patrón en outa[9..4] se mueva dos bits a la vez. Usted deberá estar viendo parpadear cada dos LED de izquierda a derecha. Kit Educativo de Practicas Propeller: Fundamentos · Página 61 Práctica básica de E/S y tiempo Ejemplo de Variable El objeto ButtonShiftSpeed que se muestra abajo es una versión extendida de ShiftRightP9toP4 que le permite usar los botones para controlar la velocidad a la cual el LED cambiara su posición a la derecha. Si usted sostiene el botón P21 la velocidad baja; si sostiene el botón en P22 la velocidad sube. El control de velocidad se hace posible al almacenar un valor en una variable. El patrón que se mueve también es almacenado en una variable, haciendo posible un numero de patrones que no se pueden alcanzar desarrollando operaciones de movimiento en los bits en outa[9..4]. 3 Cargue ButtonShiftSpeed.spin en la RAM. 3 Intente presionar P22 y observe el cambio en el comportamiento del LED, después presione el botón P21. '' Archivo: ButtonShiftSpeed.spin '' El LED se mueve de izquierda a derecha a velocidad variable presionando los botones. VAR Byte pattern, divide PUB ShiftLedsLeft dira[9..4] ~~ divide := 5 repeat if pattern == 0 pattern := %11000000 if ina[22] == 1 divide ++ divide <#= 254 elseif ina[21] == 1 divide -divide #>= 1 waitcnt(clkfreq/divide + cnt) outa[9..4] := pattern pattern >>= 1 ButtonShiftSpeed tiene un bloque variable (VAR) que declara dos variables de un byte, pattern y divide. La variable pattern almacena el patrón del bit que se manipula y se copia a outa[9..4], y divide almacena un valor que divide a clkfreq para un retraso de longitud variable Byte es una de las tres opciones para declarar variables y puede almacenar un valor desde 0 hasta 255. Otras opciones son word (0 a 65535) y long (-2,147,483,648 a 2,147,483,647). Pueden declararse arreglos de variables especificando el número de elementos en corchetes a la derecha del nombre de la variable. Por ejemplo myBytes[20] será un arreglo de 20 elementos de nombre myBytes. Esto pone a disposición las variables myBytes[0], myBytes[1], myBytes[2],…, myBytes[18], y myBytes[19]. El primer bloque if en el ciclo repeat se comporta similar al del objeto ShiftRightP9toP4. En vez de outa[9..4], la sentencia if examina el contenido de la variable pattern y si es cero la siguiente línea reasigna a pattern el valor de %11000000. Pagina 62 · Kit Educativo de Prácticas Propeller: Fundamentos 4: Práctica básica de E/S y tiempo Los operadores Limite Mínimo “#>” y Limite Máximo “<#” Spin tiene operadores Limite Mínimo “#>” y Limite Máximo “<#” que pueden usarse para mantener el valor de variables dentro de un rango deseado ya que son redefinidas por otras expresiones. En nuestro objeto ejemplo, la segunda sentencia if en el ciclo repeat es parte de una sentencia if…elseif… que verifica el estado del botón pulsador. Si el botón P22 se presiona divide se incrementa en 1 con divide ++, y divide está limitado a 254 con <#=, la forma de asignar el operador de límite máximo. Si el resultado de divide ++ es 255 la siguiente línea divide <#= 254 reduce su valor nuevamente a 254. Esto previene que el valor de divide pase a 0 lo cual es importante porque divide tiene que dividirse entre clkfreq en el comando waitcnt posteriormente en el ciclo repeat. Si P21 se presiona en vez de P22 la variable divide se decrementa con --, la cual resta 1 de divide. El operador de asignación #>= se usa para asegurarse que divide nunca será menor que 1, nuevamente previniendo de llegar al 0. Después de que la sentencia if…elseif… verifica el estado del botón y decrementa o incrementa la variable divide si alguno de los botones se presiono se ejecuta la función waitcnt(clkfreq/divide + cnt) para esperar un tiempo. Note que conforme divide es mayor waitcnt es menor. Después de que el retraso waitcnt, que es controlado por la variable divide, pattern se almacena en outa con outa[9..4] := pattern. Por último la variable pattern se mueve a la derecha en 1 la siguiente vez que se realiza el ciclo. Comparación entre Operaciones y Condiciones Los operadores de comparación regresan un verdadero (-1) o falso (0). Cuando se usa en los bloques if y repeat el código especificado se ejecuta s la condición en no-cero. Siendo este el caso puede usarse if ina[22] en vez de if ina[22] == 1. El código funciona igual pero con menos procesamiento ya que se salta la operación de comparación. Cuando se presiona el botón la condición en if ina[22] == 1 regresa un -1 ya que ina[22] almacena un 1 haciendo la comparación verdadera. Usando solo if ina[22] aun se ejecuta el bloque de código cuando se presiona el botón ya que ina[22] almacena 1, el cual es no-cero, haciendo que el bloque de código se ejecute. Cuando el botón no se presiona ina[22] almacena un 0 y ina[22] == 1 regresa un falso (0). En cualquiera de los casos la condición de if es 0 así que el código debajo de if ina[22] == 0 o if ina[22] se salta. 3 Cambie if ina[22] == 1…elseif ina[21] == 1 a if ina[22]…elseif ina[21]…, y verifique que el programa modificado todavía funciona. Variables Locales Mientras que todos los ejemplos de objetos en estas prácticas usan solo un método, los objetos frecuentemente tienen más de un método y las aplicaciones típicamente son colecciones de diversos objetos. Los métodos en las aplicaciones de paso de control de programa y parámetros opcionales van y vienen entre otros métodos del mismo objeto y también en otros métodos en otros objetos. Para preparar el trabajo con métodos múltiples en las siguientes prácticas veamos como un método puede crear una variable local. Las variables declaradas en la sección VAR de un objeto son globales para el objeto, lo que significa que todos los métodos en un objeto pueden usarlas. Cada método en un objeto también puede declarar variables locales para uso propio. Estas variables locales duran mientras se ejecuta el método. Si el método corre fuera de sus comandos y pasa el control del programa al comando que lo llamo, el nombre de la variable local y la memoria quedan disponibles para usarse por otras variables. Kit Educativo de Practicas Propeller: Fundamentos · Página 63 Práctica básica de E/S y tiempo Las dos variables globales en el objeto ButtonShiftSpeed se pueden reemplazar con variables locales como sigue: 3 Remueva el bloque VAR (incluyendo su declaración de byte variable). 3 Agregue el símbolo pipa a la derecha del bloque de declaración de método seguido por los dos nombres de variables separados por comas, pruebe si el programa funciona igual. PUB ShiftLedsLeft | pattern, divide Las variables pattern y divide ahora son locales, lo que significa que otros métodos en el objeto no pueden usarlas; ya que nuestro objeto aquí solo tiene un método no hay consecuencias. Hay otra diferencia. Cuando usábamos la sintaxis del bloque VAR, teníamos la opcion de definir nuestras variables globales como byte, Word o Long. Sin embargo las variables locales se definen automáticamente como Long y no hay opcion para tamaños de byte o Word en variables locales. Aplicaciones de tiempo Para aplicaciones de reloj y tiempo es importante eliminar todos los errores posibles excepto por la precisión del cristal oscilador. Observe los dos objetos que desarrollan tareas de reloj. Asumiendo que usted tiene un cristal muy preciso el programa a la izquierda tiene un serio problema! El problema es que cada vez que se repite el ciclo, el ciclo de reloj transcurrido durante la ejecución de los comandos en el ciclo no se cuentan, y esto retraso desconocido se acumula junto con clkfreq + cnt. Así que el numero de segundos de la variable seconds estará desfasada y crecerá significativamente cada día mucha más que el solo error inducido por el rango del cristal +/- PPM. ''Archivo: TimekeepingBad.spin ''Archivo: TimekeepingGood.spin CON CON _xinfreq = 5_000_000 _clkmode = xtal1 + pll1x _xinfreq = 5_000_000 _clkmode = xtal1 + pll1x VAR VAR long seconds, dT, T long seconds PUB BadTimeCount PUB GoodTimeCount dira[4]~~ dira[9..4]~~ repeat waitcnt(clkfreq + cnt) seconds ++ ! outa[4] dT := clkfreq T := cnt repeat T += dT waitcnt(T) seconds ++ outa[9..4] := seconds El programa a la derecha resuelve el problema agregando dos variables: T and dT. Un incremento de tiempo se coloca con dT := clkfreq lo cual hace que dT iguale el numero de ciclos en un segundo. Un tiempo particular de inicio se marca con T := cnt. Dentro del ciclo el siguiente valor de cnt que waitcnt tiene que esperar se calcula con T += dT. (Usted puede usar T := T + dT) sumando dT a T al pasar por el ciclo genera una diferencia precisa del valor original marcado en el valor de T. Con este sistema cada nuevo valor para waitcnt es exactamente el valor de 1 segundo. No importa cuántas tareas se ejecuten entre las ejecuciones del comando waitcnt, siempre y cuando se complete en menos de un segundo. Así que el programa de la derecha nunca perderá ciclos de reloj y mantendrá Pagina 64 · Kit Educativo de Prácticas Propeller: Fundamentos 4: Práctica básica de E/S y tiempo una constante de 1 s basado en que será tan bueno como la señal que el chip Propeller obtiene de su cristal oscilador externo. Consejo: En TimeKeepingGood.spin, dos líneas: L T += dT waitcnt(T) Pueden reemplazarse con esta línea: waitcnt(T += dT). 3 Pruebe ambos objetos. Sin un osciloscopio no deberá observar una diferencia notable. 3 Agregue un retraso de .7 s al final de cada objeto (dentro de caca ciclo repeat). El objeto en la izquierda ahora repetirá cada 1.7 s; el de la derecha deberá repetir aun cada 1 s. En vez de un retraso imagine cuantas otras tareas puede realizar el chip Propeller en cada Segundo y aun mantener una base de tiempo precisa! Varios múltiplos de un tiempo dado pueden tener diferentes usos en diferentes aplicaciones. Por ejemplo estos objetos tienen segundos como tiempo base, pero quizá estamos interesados en minutos y horas. Hay 60 segundos en un minuto, 3,600 segundos en una hora y 86,400 segundos en un día. Vamos a decir que la aplicación corre al conteo de seconds. Una forma de determinar si ha transcurrido un segundo es dividir seconds por 60 para ver si hay algún recordatorio. El operador Modulus “//” regresa un recordatorio de problemas de división. Conforme pasa el segundo, el resultado de seconds // 60 es 0 cuando seconds es 0, 60, 120, 180, y así sucesivamente. El resto del tiempo Modulus regresa el sobrante. Por ejemplo, cuando seconds es 121 el resultado de seconds // 60 es 1. Cuando seconds es 125 el resultado de seconds // 60 es 5 y así sucesivamente. Siendo este el caso tenemos una expresión que incrementa la variable minutes cada que otros 60 segundos transcurren: if seconds // 60 == 0 minutes ++ Otro ejemplo con hours: if seconds // 3600 == 0 hours ++ Por cada hora que pasa minutes se deberá poner en cero cada que llegue a 60. Un ejemplo de un if anidado que expande el cálculo previo de minutes: if seconds // 60 == 0 minutes ++ if minutes == 60 minutes := 0 El objeto TimeCounter mostrado abajo usa tiempo sincronizado y corre segundos totales con el operador Modulus para rastreo de segundos, minutos, horas y días basado en el contador seconds. El valor de seconds se despliega en binario con los 6 circuitos LED. Estudie este programa cuidadosamente porque contiene las claves para esta práctica que incrementa un tiempo basado en presionar un botón por diferente duración. También tiene la clave para otro proyecto en el cual los LEDs parpadean a diferente ritmo usando Cogs múltiples. (Cuando use Cogs múltiples en otras prácticas será mucho más fácil!) Kit Educativo de Practicas Propeller: Fundamentos · Página 65 Práctica básica de E/S y tiempo 3 Cargue TimeCounter.spin en la EEPROM, y verifique que el incremento del conteo LED es cada 1 s. 3 Modifique el código para que el ultimo comando copie el valor que tiene minutes en outa[9..4], y verifique que el LED incrementa cada minuto. ''Archivo: TimeCounter.spin CON _xinfreq = 5_000_000 _clkmode = xtal1 + pll1x VAR Long seconds, minutes, hours, days, dT, T PUB GoodTimeCount dira[9..4]~~ dT := clkfreq T := cnt repeat T += dT waitcnt(T) seconds++ if seconds // 60 == 0 minutes++ if minutes == 60 minutes := 0 if seconds // 3600 == 0 hours++ if hours == 24 hours := 0 if seconds // 86400 == 0 days++ outa[9..4] := seconds Eventualmente la variable seconds alcanzara la limitación de almacenamiento. Por ejemplo cuando llegue a 2,147,483,647, el siguiente valor será -2,147843,648, y después -2,147,843,647, 2,147,843,646, y así hasta -2, -1. Así que cuanto tardara el contador seconds en llegar a 2,147,483,647? La respuesta es 68 años. Si esto es aun un problema para su aplicación considere limpiar el contador seconds cada año. Tiempo de Estudio Preguntas 1) Cuantos procesadores tiene el micro controlador Propeller del kit PE? 2) Cuanta memoria global RAM tiene el micro controlador Propeller? 3) Cuál es el suministro de voltaje del chip Propeller? Como se relaciona esto al estado alto o bajo de los pins de E/S? 4) Donde almacena el código Spin el chip Propeller y como se ejecuta? 5) Cuáles son las diferencias entre ejecutar código Spin y código Ensamblador? 6) Cuál es la diferencia entre un método y un objeto? Pagina 66 · Kit Educativo de Prácticas Propeller: Fundamentos 4: Práctica básica de E/S y tiempo 7) Que es un objeto tope? 8) Que determinan los bits en los registros dira y outa? 9) Sin argumentos especiales el comando repeat repite un cloque de código indefinidamente. Que tipos de argumentos opcionales se usaron en esta práctica y como limitaban el número de repeticiones? 10) Cual comando Spin usado con waitcnt hace posible controlar el tiempo sin conocer la frecuencia del chip Propeller por adelantado? 11) Si los comandos están bajo el comando repeat, como determina si se repetirán o no en el ciclo? 12) Cual fue el significado más frecuente de calcular un valor para el comando waitcnt y con cual registro hace que el comando waitcnt que compare este valor? 13) Cuál es la diferencia entre _xinfreq y _clkmode? 14) Que hace el circuito de fase cerrada a la señal de reloj del cristal? 15) Por qué es tan importante usar fracciones de clkfreq y no un valor constante para retrasos? 16) Cual señal de reloj es más precisa, el reloj RC interno del chip Propeller o un cristal externo? 17) Que registros controlan la dirección y salida de los pins E/S? Si un pin E/S se coloca como entrada, que valor de registros cambiaran mientras corre la aplicación y como son los valores que regresa determinados por el Propeller? 18) Cuál es la diferencia entre la sintaxis dira/outa/ina que se refiere a un bit sencillo en el registro y la sintaxis que denota un grupo de bits? 19) Que indicador proporciona una forma conveniente de asignar un grupo de valores de bits a un grupo de bits en el registro dira/outa/ina? 20) Como responde un pin E/S si hay un 0 en su bit de registro dira y un 1 en su bit de registro outa? 21) Si los bits en dira o outa no son inicializados cual es su valor inicial por defecto? 22) Que operadores de asignación se presentaron en esta práctica? 23) Que operadores de comparación se usaron en esta práctica? 24) Cuál es la diferencia entre los operadores := y ==? 25) Son necesarios los operadores de comparación para las condiciones if? 26) Cuáles son los dos diferentes alcances que una variable puede tener en un objeto? 27) Cuáles son los tres tamaños de variables que pueden declararse? Que rango de números puede tener cada una? Se ve afectado el tamaño de la variable debido a su alcance? 28) Como se declara una variable local en un método? Qué carácter se necesita para declarar más de una variable local? Ejercicios 1) Escriba una sola línea de código que programe P8 a P12 como salida alta. 2) Escriba comandos para programar P9 y P13 a P15 como salidas. P9 deberá ser salida alta y P13 a P15 deberá ser baja. 3) Escriba un comando único de inicialización para programar P0 a P2 como salida y P3 a P8 como entrada. 4) Escriba un bloque repeat que cambie el estado de P8 y P9 cada 1/100 s. Cada que P8 está encendido P9 deberá estar apagado y viceversa. 5) Escriba un ciclo repeat que programe P0 a P7 al estado opuesto censado por P8 a P15. Puede consultar el manual Propeller para ver cuál es la mejor opcion de operadores de asignación. 6) Escriba un bloque CON para hacer que el reloj del sistema del chip Propeller corra a 10MHz 7) Escriba un código para un retraso de 5 segundos. 8) Escriba un código que programe P5 a P11 alto por 3 segundos, después programe P6, P8 y P10 bajo. Asuma que los bits dira han sido programados Kit Educativo de Practicas Propeller: Fundamentos · Página 67 Práctica básica de E/S y tiempo 9) Escriba un método llamado LightsOn con un ciclo repeat que encienda P4el primer segundo, P5 el segundo, P6 el tercero y así hasta P9. Asuma que las direcciones de los pin E/S no han sido programados. Asegúrese que las luces se vayan quedando encendidas. 10) Escriba un método que encienda un LED conectado a P27 por 5 s si se presiona un botón conectado a P0, incluso si el botón se suelta antes de 5 s. No asuma que las direcciones E/S han sido programadas. Asegúrese de apagar P27 después de los 5 s. 11) Escriba un método de conteo regresivo de 1 segundo que se despliegue de P4 a P9. Deberá contar de 59 a 0 en binario. 12) Escriba un método de conteo regresivo de 1 segundo que se despliegue de P4 a P9. Deberá contar de 59 a 0 en binario una y otra vez indefinidamente. 13) Escriba un método llamado PushTwoStart que requiere que presione los botones conectados a P21 y P23 al mismo tiempo para empezar la aplicación. Por ahora la aplicación puede al menos encender un LED y dejarlo encendido. 14) Escriba un método llamado PushTwoStart que requiere que presione los botones conectados a P21 y P23 al mismo tiempo para empezar la aplicación. La aplicación deberá contar regresivamente de 59 a 0 usando P9 a P4. Proyectos 1) Conecte LED rojos a P4 y P7, Amarillos en P5 y P8 y verdes en P6 y P9. Asuma que un set de LED está apuntando en ambas direcciones en la calle norte-sur y el otro está apuntando en la calle este-oeste. Escriba un objeto controlador no-activado (uno que siga un patrón sin que verifique si hay carros en las intersecciones). 2) Repita el objeto previo pero asuma que la calle norte-sur está muy transitada y colóquelo en verde mientras que la calle este-oeste tiene un sensor que se activa para que la luz cambie. 3) Use un Cog sencillo para hacer que el LED parpadee a diferentes rangos (esto es más sencillo con múltiples Cogs como pudo observar en las últimas prácticas). Haga que P4 parpadee a 1 Hz, P5 a 2 Hz, P6 a 3 Hz, P7 a 7Hz, P8 a 12 Hz y P9 a 13 Hz. 4) Los botones que programan una alarma de reloj típicamente incrementan o decrementan el tiempo despacio hasta que usted ha detenido el botón por un par de segundos; después de eso el tiempo se incrementa/decrementa mas rápido. Los botones de la alarma de reloj también lo dejan incrementar/decrementar si presiona y suelta rápidamente el botón. Escriba una aplicación que lo deje incrementar o decrementar un contador binario de minutos (de o a 59) con los botones P21 y P23. Si usted detiene el botón, los primeros diez minutos incrementa/decrementa cada ½ s pero si continua presionando el botón los minutos se incrementaran 6 veces más rápido. Use P9 a P4 para desplegar el conteo binario de los minutos. 5) Extienda el proyecto 4 modificando el objeto para que tenga un contador regresivo que se programe con P21 y P23 y se inicie con el botón P22. Pagina 68 · Kit Educativo de Prácticas Propeller: Fundamentos 5: Prácticas de Métodos y Cogs 5: Practicas de Métodos y Cogs Introducción Los objetos son organizados en bloques de código llamados métodos. En Spin se pueden usar nombres de métodos para pasar el control de programa y opcionalmente valores de parámetros de un método a otro. Cuando un método usa otro nombre de método para pasarle el control de programa se llama llamada método. Cuando el método llamado corre los comandos automáticamente regresa el control del programa y un resultado a la línea de código en el método que se le llamo. Dependiendo de cómo se escribe el método también puede recibir uno o más parámetros cuando se llama. Usos comunes para valores de parámetros incluyen configuración, definir el comportamiento de los métodos y valores de entrada para cálculos. Los métodos también pueden iniciarse en Cogs separados para que sus comandos se procesen en paralelo con comandos en otros métodos. El lenguaje Spin tiene comandos para iniciar métodos en Cogs, identificar Cogs y detener Cogs. Cuando los métodos se inician en Cogs se tienen que declarar variables globales para asignar memoria para los métodos y almacenar direcciones de regreso, valores de regreso, parámetros y valores usados en cálculos. Esta memoria normalmente se conoce como espacio de pila. Esta práctica muestra técnicas para escribir métodos, llamar métodos, pasar parámetros a métodos y regresar valores de métodos. También muestra cómo usar llamadas a métodos en comandos que inician instancias de métodos en Cogs separados así como una introducción a que tanto espacio de pila se necesita para uno o más métodos Spin que se ejecutan por un Cog. Prerrequisitos para la Práctica • Configuración y Prueba • Básicos de E/S y tiempo Lista de partes y esquemas Esta práctica usa seis circuitos LED y tres circuitos de botones pulsadores (6) LEDs – diferentes colores (6) Resistencias – 100 Ω (3) Resistencias – 10 kΩ (3) Botones Pulsadores – normalmente abierto (misc) cables puente 3 Construir el circuito mostrado en la Figura 5-1. Kit Educativo de Practicas Propeller: Fundamentos · Página 69 Prácticas de Métodos y Cogs Figura 5-1: Esquema de botones pulsadores LED Definiendo un comportamiento de Método con variables locales El objeto AnotherBlinker muestra el uso de tres variables, pin, rate, y reps, para definir el comportamiento encendido/apagado de su ciclo repeat de LED. Con las variables actuales programadas hace que P4 parpadee a 3 Hz por 9 repeticiones encendido/apagado. Como el ciclo repeat solo cambia el estado del LED (en vez de un ciclo completo) el objeto necesita dos veces más el numero de estados de cambio y la mitad del retraso especificado entre cada cambio de estado. Así la variable reps se multiplica * 2 en vez de solo reps y también el comando waitcnt utiliza rate/2 en vez de rate para el rango de parpadeo de 3Hz. 3 Corra el objeto AnotherBlinker.spin y verifique que hace que el LED P4 parpadee a 3Hz por 9 repeticiones. 3 Pruebe una variedad de valores para pin, rate y reps y verifique que definen correctamente el comportamiento del ciclo repeat. '' AnotherBlinker.spin PUB Blink | pin, rate, reps pin := 4 rate := clkfreq/3 reps := 9 dira[pin]~~ outa[pin]~ repeat reps * 2 waitcnt(rate/2 + cnt) !outa[pin] Llamando un Método El método Blink se usa nuevamente en el siguiente objeto ejemplo CallBlink, junto con otro método llamado Main. La Figure 5-2 muestra como el método Blink se llama desde el método Main. La ejecución del programa comienza en Main, en el primer bloque PUB. Cuando el programa llega a la línea Blink en el método Main el control del programa pasa al método Blink. Esta es una versión pequeña de una llamada de método. Cuando el método Blink termina de parpadear el LED 9 veces el Pagina 70 · Kit Educativo de Prácticas Propeller: Fundamentos 5: Prácticas de Métodos y Cogs control del programa regresa al método Blink en el método Main. Eso es el regreso de método o simplemente regreso. Vamos a dar un vistazo al método Main del objeto CallBlink. Comienza por encender el LED en P9 para hacer saber al usuario que puede presionar el botón P23. El ciclo repeat until ina[23] se repite hasta que P23 se presiona y el programa se mueve apagando el LED P9 con outa[9] := 0. Entonces llama al método Blink el cual hace parpadear P4 a 3Hz 9 veces y luego regresa. El siguiente comando es waitcnt(clkfreq/2*3 + cnt) el cual detiene por 3/2 s. Después el otro ciclo repeat comienza su siguiente iteración. A ese punto el LED P9 se enciende nuevamente indicando que el botón P23 puede disparar nuevamente la secuencia de 9 repeticiones a 3 Hz en P4. 3 3 3 3 Cargue el objeto CallBlink.spin en el chip Propeller. Cuando el LED P9 se enciende presione/suelte el botón en P23. Espere a que P9 encienda nuevamente después de que P4 ha parpadeado 9 veces. Presione/Suelte el botón P23 para reiniciar la secuencia otra vez. Figure 5-2: Llamando un Método '' CallBlink.spin PUB Main Llamada de Método repeat outa[9] := dira[9] := 1 repeat until ina[23] Siguiente outa[9] := 0 Comando Blink waitcnt(clkfreq/2*3 + cnt) PUB Blink | pin, rate, reps pin := 4 rate := clkfreq/3 reps := 9 Regreso de Método dira[pin]~~ outa[pin]~ repeat reps * 2 waitcnt(rate/2 + cnt) !outa[pin] Pasando Parámetros El método Blink que acabamos de usar programa los valores de sus variables locales pin, rate, y reps con instrucciones individuales var :=. Para hacer métodos más flexibles y eficientes de usar el valor de sus variables locales pueden definirse en la llamada de método en vez del método mismo. La Figura 5-3 muestra cómo funciona el objeto BlinkWithParams. La declaración del método modificado Blink ahora es: Blink( pin, rate, reps). El grupo de variables locales entre paréntesis se llama lista de parámetros. Note como el método Blink llamado en el método BlinkTest también tiene su lista de parámetros. Estos valores de parámetros se pasan a las variables locales en la declaración de la lista de parámetros del método BlinkTest. En este caso el BlinkTest pasa 4 a pin, clkfreq/3 a rate y 9 a reps. El resultado es el mismo que en el objeto AnotherBlinker, pero ahora el código en un método puede pasar valores a variables locales en otro método. 3 Cargue BlinkWithParams.spin en el chip Propeller y verifique que el resultado es el mismo que el objeto previo AnotherBlinker. 3 Ajuste valores de parámetro en la llamada a método para ajustar el comportamiento de Blink Kit Educativo de Practicas Propeller: Fundamentos · Página 71 Prácticas de Métodos y Cogs Figura 5-3: Pasando Parámetros '' BlinkWithParams.spin PUB BlinkTest Blink(4, clkfreq/3, 9) PUB Blink(pin,rate,reps) dira[pin]~~ outa[pin]~ repeat reps * 2 waitcnt(rate/2 + cnt) !outa[pin] Los métodos pueden reusarse con diferentes valores de parámetros en cada llamada de método; aquí se llama Blink tres veces con diferentes parámetros y una pausa de 1 s en medio. PUB BlinkTest Blink(4, clkfreq/3, 9) waitcnt(clkfreq + cnt) Blink(5, clkfreq/7, 21) waitcnt(clkfreq + cnt) Blink(6, clkfreq/11, 39) Aquí hay otro ejemplo en el que prende un LED diferente cada que se presiona y suelta en botón. Esta es una variación del método Main del objeto CallBlink, con una variable local llamada led y un ciclo repeat que programa la variable a 4, 5, …, 8, 9, 4, 5, …8, 9, …. Una llamada de método actualizada Blink pasa el valor en la variable al parámetro pin del método Blink. Como led cambia con cada iteración del ciclo repeat, la variable pin recibirá un valor diferente cada que se llama a Blink. ¿El resultado? Cada vez que se presiona en botón (después que enciende P9) un LED diferente parpadeara a 3 Hz 9 veces. PUB BlinkTest | led repeat repeat led from 4 a 9 outa[9] := dira[9] := 1 repeat until ina[23] outa[9] := 0 Blink(led, clkfreq/3, 9) waitcnt(clkfreq/2*3 + cnt) La variable local led del método BlinkTest se pudo haber llamado pin porque es una variable local ya que solo el método BlinkTest la usa. El código en el método Blink tiene también una variable local pin, pero nuevamente, solo el código en el método Blink estará pendiente del valor de la variable pin. 3 Pruebe las dos versiones modificadas BlinkTest en discusión y asegúrese que hace sentido. 3 Intente cambiar los parámetros para que el LED P4 parpadee 4 veces, P5 5 veces y así sucesivamente. Pagina 72 · Kit Educativo de Prácticas Propeller: Fundamentos 5: Prácticas de Métodos y Cogs Arrancando métodos en los Cogs Todos los métodos en los objetos hasta este punto se han ejecutado en un solo Cog del chip Propeller, el Cog 0. Cada vez que el método Blink se llamaba, era llamado en secuencia, por lo que solo un LED parpadeaba a la vez. El método Blink puede arrancar en diferentes Cogs, cada uno con diferentes parámetros para hacer que los LEDs parpadeen simultáneamente. El objeto BlinkWithCogs mostrado en la Figura 5-4 muestra cómo hacer esto con los 3 comandos cognew. El primer método en el objeto superior automáticamente arranca en el Cog 0 por lo que el método Blink del objeto BlinkWithCogs arranca en el Cog 0. Se ejecutan 3 comandos cognew y se queda sin instrucciones por lo que el Cog 0 se apaga. Mientras tanto los otros 2 Cogs se iniciaron cada uno correo por 3 segundos. Después de que el último Cog se queda sin instrucciones el chip Propeller se va a bajo consumo. Figura 5-4: Arrancando métodos en Cogs con pase de parámetros '' BlinkWithCogs.spin VAR long stack[30] Arranque en Cog 1 Arranque en Cog 2 Cog 0 Comandos LaunchBlinkerCogs PUB LaunchBlinkCogs Arranque en Cog 3 cognew(Blink(4, clkfreq/3, 9), @stack[0]) cognew(Blink(5, clkfreq/7, 21), @stack[10]) cognew(Blink(6, clkfreq/11, 39), @stack[20]) PUB Blink( pin, rate, reps) dira[pin]~~ outa[pin]~ repeat reps * 2 waitcnt(rate/2 + cnt) !outa[pin] Cog 1 Blinker(4, clkfreq/3, 9) RAM @stack[0] Cog 2 Blinker(5, clkfreq/7, 21) RAM @stack[10] Cog 3 Blinker(6, clkfreq/11, 39) RAM @stack[20] Mientras que el Cog 0 accesa RAM global no usada que viene después del código de programa para almacenar direcciones de regreso en llamadas de método, variables locales y cálculos de expresiones intermedias, otros Cogs que ejecutan métodos Spin deben tener variables para ellos. Tal espacio variable reservado en RAM global para esas actividades temporales se llama espacio de pila y los datos almacenados en cualquier momento es la pila. Note que el objeto BlinkWithCogs en la Figura 5-4 tiene una declaración variable de pila long stack[30]. Esto declara un arreglo de variables long llamadas stack con 30 elementos [0], stack[1], stack[2], …, stack[28], stack[29]. El comando cognew(Blink(4, clkfreq/3, 9), @stack[0])llama al método Blink en el siguiente Cog disponible con los parámetros 4, clkfreq/3, y 9 lo cual sucede en el Cog 1. El argumento @stack[0] pasa la dirección del arreglo stack[0] al Cog 1. Así el Cog 1 inicia ejecutando Blink(4, clkfreq/3, 9) usando stack[0] y hacia arriba el regreso de dirección, variables locales y cálculos intermedios. El comando cognew(Blink(5, clkfreq/7, 21), @stack[10]) inicia Blink(5, clkfreq/7, 21) en el Cog 2 con un apuntador a la dirección stack[10] en RAM para usar desde stack[10] hacia arriba. Luego cognew(Blink(6, clkfreq/11, 39), @stack[20]) hace lo mismo con diferentes parámetros de método y diferente dirección en el arreglo stack. Kit Educativo de Practicas Propeller: Fundamentos · Página 73 Prácticas de Métodos y Cogs 3 Cargue el objeto BlinkWithCogs en el chip Propeller y verifique que los tres LED parpadean a diferentes frecuencias al mismo tiempo (en vez de secuencialmente) 3 Examine el programa y haga notas de los nuevos elementos. La RAM no usada que el Cog 0 usa para su pila puede verse en la ventana de Información del Objeto mostrado en la Figura 5-5 (F8 muestra Hex). El color gris en la parte superior muestra códigos de inicialización que inician el Objeto superior en un Cog, programa el registro de reloj del chip Propeller y otras tareas. La memoria roja almacena el código de programa Spin, el amarillo indica el espacio global variable (el arreglo de 30-variables long). Lo que sigue en azul es RAM no usada de la cual puede usarse para la pila del Cog 0. La dirección inicial RAM del Cog 0 es hexadecimal 00F0. Figura 5-5: Ventana de Información del Objeto Primera dirección RAM no usada para la pila del Cog 0 Parando Cogs Con el comando cognew, el chip Propeller siempre busca el siguiente Cog disponible y lo empieza automáticamente. En el objeto BlinkWithCogs el patrón de asignación de Cogs es predecible: el primer comando cognew inicia Blink(4, clkfeq/3, 9)en el Cog 1 Blink(5, clkfreq/7, 21) en el Cog 2, y Blink(6, clkfreq/11, 39) en el Cog 3. L Elija su Cog: En vez de usar el siguiente Cog disponible usted puede especificar cual Cog desea usar para inicializar usando el comando coginit en vez de cognew. Por ejemplo, este comando iniciara el método en el Cog 6: coginit(6, Blink(4, clkfreq/3, 9), @stack[0]) El comando cogstop puede usarse para parar cada uno de los Cogs. Un ejemplo con cada parámetro programado para que el objeto mantenga parpadeando el LED hasta que se repita un millón de veces. Después de 3 segundos de retraso el comando cogstop apagara cada Cog en intervalos de un segundo usando el numero de Cog, así ninguno de los métodos se cierra hasta ejecutarse un millón de veces. Pagina 74 · Kit Educativo de Prácticas Propeller: Fundamentos 5: Prácticas de Métodos y Cogs PUB LaunchBlinkCogs cognew(Blink(4, cognew(Blink(5, cognew(Blink(6, waitcnt(clkfreq cogstop(1) waitcnt(clkfreq cogstop(2) waitcnt(clkfreq cogstop(3) clkfreq/3, 1_000_000), @stack[0]) clkfreq/7, 1_000_000), @stack[10]) clkfreq/11, 1_000_000), @stack[20]) * 3 + cnt) + cnt) + cnt) Con algunos trucos de indexación, los Cogs pueden incluso iniciarse y apagarse con ciclos repeat. Abajo se muestra un ejemplo que usa una variable local index en un ciclo repeat para definir los pins E/S, un arreglo stack e identificación de Cogs. Hace lo mismo que la versión modificada del método LaunchBlinkCogs. Note que la variable local index se declara con el símbolo de pipa. Así repeat index from 0 to 2 incrementa index cada vez que pasa por los tres comandos cognew. Cuando index es 0 el parámetro de pin del método Blink es 0 + 4, pasando 4 al parámetro de pin del método Blink. En la segunda vez index es 1, por lo que pin se convierte en 5, y la tercera vez pin es 6. Para la secuencia clkfreq de 3, 7, 11 con valores de index de 0, 1, y 2 (index * 4) + 3 llena la ecuación. Para 0, 10 y 20 como elemento de arreglo, index * 10 completa la ecuación. Para detener los Cogs 1, 2 y 3 el segundo ciclo repeat cambia index de 1 a 3. La primera vez es index es 1 así que se cogstop(index) se convierte en cogstop(1). La segunda vez index es 2, así cogstop(2), y la tercera vez index es 3 resultando en cogstop(3). PUB LaunchBlinkCogs | index repeat index from 0 to 2 cognew(Blink(index + 4, clkfreq/((index*4) + 3), 1_000_000), @stack[index * 10]) waitcnt(clkfreq * 3 + cnt) repeat index from 1 to 3 cogstop(index) waitcnt(clkfreq + cnt) 3 Pruebe las versiones modificadas de los métodos LaunchBlinkCogs. Los objetos pueden escribirse para monitorear que Cog se está ejecutando en un cierto método. Un avance es discutido en la sección Indexación de Identificaciones de Cogs en la página 78. Otros avances se mostraran en futuras prácticas de objetos. ¿Cuánto espacio de Pila para iniciar un Método en un Cog? Abajo se muestra una lista del numero longs de que cada método agrega a su pila cuando se llama. • • • • • 2 – direcciones de regreso 1 – regreso de resultado Numero de parámetros del método Numero de variables locales Espacio de trabajo para expresiones de cálculo intermedias Asuma que tiene un objeto con tres métodos: A, B y C. Cuando el método A llama al método B la pila crecerá conteniendo dos grupos de longs, uno para el método A y otro para el método B. Si el método B llama al método C habrá un tercero. Cuando el método C regresa la pila se reducirá a dos grupos. Kit Educativo de Practicas Propeller: Fundamentos · Página 75 Prácticas de Métodos y Cogs El área de trabajo es para almacenar valores que existen durante ciertas tareas y evaluaciones de expresiones. Por ejemplo el método de Blink repeat reps * 2 usa el área de trabajo de dos formas. La primera en la expresión reps * 2 empuja dos elementos a la pila: el valor almacenado por reps y 2. Después del cálculo * el 2 sale de la pila y el resultado del cálculo se almacena en un elemento sencillo. Este elemento se queda en la pila hasta que se termina el ciclo repeat. Dentro del ciclo repeat reps * 2 ocurren dos expansiones y contracciones similares de la pila con waitcnt(rate/2 + cnt), el primero con rate/2 y nuevamente cuando el resultado de rate/2 se suma a cnt. En el caso del método Blink lo más que usa de área de trabajo y cálculos de expresiones intermedias es 3 longs: uno para detener el resultado de reps * 2 hasta que el ciclo repeat se completa, y dos más para los diversos cálculos con operadores binarios como multiplicar (*) y dividir (/). Conociendo esto podemos verificar el número de variables long que el Cog necesita en la pila para ejecutar el método listado abajo. Así el total de espacio de pila (ej., número de variables long) que necesita un Cog para ejecutar el método Blink es 10. • • 2 – Regresos de direcciones 1 – Resultado variable (cada método tiene esto incluido, aun cuando no se especifica un valor de regreso. (Esto se analizara en la siguiente sección) • 3 – Parámetros pin, freq, y reps • 1 – Variable local time • 3 – Áreas de espacio para cálculo. -----------------------------------------------• 10 – Total Como se menciono anteriormente un Cog necesita suficiente espacio para toda la memoria que puede usar junto con el espacio de pila que cualquier método llama. Algunos métodos tendrán llamadas de métodos anidados donde un método A llama a un método B que a su vez llama un método C. Todos esos métodos necesitan memoria de pila asignada si el método A es el que se inicio en el Cog. L Errar en el lado de la precaución: La mejor forma de asignar espacio de pila para el Cog que inicia un método Spin es tener precaución y declarar mucho más memoria de lo que piensa que necesitara. Así usted puede usar un objeto en la librería de la herramienta Propeller (la carpeta donde se localiza el archivo Propeller.exe) que se llama Stack Length.spin para encontrar cuantas variables esta actualmente usando el método. La práctica de objetos revisara un proyecto que usa el objeto Stack Length para verificar el número de variables Long requeridas por un método Spin que se inicia en un Cog. Declarar un arreglo variable long llamado stack en un bloque de código de objeto VAR es una forma de asignar extra RAM para el Cog que correrá el interprete Spin. El nombre del arreglo no tiene que ser stack; solo tiene que ser un nombre que el lenguaje Spin pueda usar como nombre de variable. Los nombres blinkStack o methodStack también funcionan, siempre y cuando el nombre que se escoge es aquel cuya dirección se pasa al Cog por el comando cognew. Recuerde que el operador @ a la izquierda del nombre de variable es el que especifica la dirección RAM de la variable global. L Acerca de _STACK: El lenguaje Spin tiene también una constante _stack opcional que puede usarse en un bloque CON. Es una constante programable de una sola vez para especificar el espacio de pila de la aplicación. Lea más acerca de esto en la sección de referencia de Lenguaje Spin en el manual del Propeller. Llamada de Método y el Resultado Variable Cada método público y privado tiene integrada una local variable predefinida llamada result. Cada vez que se llama un método su result variable se inicializa a cero. Luego, el valor de result puede Pagina 76 · Kit Educativo de Prácticas Propeller: Fundamentos 5: Prácticas de Métodos y Cogs definirse por el código en el método. Cuando ese método termina de ejecutarse se regresa el valor actual de result. A este punto esa llamada de método puede usarse como un valor (siendo el valor de result) en expresiones. Cuando una llamada de método aparece en una expresión el método se ejecuta para obtener el valor de result antes de que la expresión es evaluada. L Acerca de llamada de método en Expresiones: Una llamada de método puede usarse en expresiones al igual que un valor, incluyendo condiciones, comparaciones y operadores normales. Sin embargo esto excluye operaciones que intentan cambiarlo. Por lo tanto una llamada a método no puede usarse con operadores de asignación unarios o como operando “objetivo” del lado izquierdo de n operador de asignación binario. Una forma práctica de usar esta característica nos permite tomar un valor definido por un proceso en un método y tenerlo disponible para uso por otros métodos. Nuestro ejemplo ButtonBlink.spin usa tres métodos para demostrar Main, Blink, y ButtonTime. En esta aplicación presionando y soltando un botón en P23 hará que un LED en P4 parpadee 10 veces (usando el método Blink) y la frecuencia se determina por cuánto tiempo se presiona el botón usando el método ButtonTime. Figura 5-6: Usando un Resultado de Método Variable (Paso 3) El resultado del método ButtonTime se asigna a la variable time del método principal (Paso 4) time se usa en lallamada a método Blink '' ButtonBlink.spin PUB Main | time Repeat time := ButtonTime(23) Blink(4, time, 10) PUB Blink(pin, rate, reps) dira[pin]~~ outa[pin]~ (Paso 1) La llamada de método ButtonTime pasa 23 al parámetro pin de ButtonTime (Paso 5) El método Blink recive time como valor a usar en su parámetro rate repeat reps * 2 waitcnt(rate/2 + cnt) !outa[pin] (Paso 2) El método ButtonTime define la variable result y regresa este valor a la llamada de método PUB ButtonTime(pin) | t1, t2 repeat until ina[pin] t1 := cnt repeat while ina[pin] t2 := cnt result := t2 - t1 Observe la Figura 5-6. el método Main de ButtonBlink declara solo una variable, time. Contiene solo dos llamadas de métodos en el ciclo repeat. En el primero ButtonTime(23) llama al método ButtonTime y pasa el valor 23 a su parámetro pin (Paso 1). El código en ButtonTime define el valor de su variable result, la cual representa que tanto tiempo se presiono P23. Este valor se regresa al punto de la llamada de método (Paso 2). La expresión time := ButtonTime(23) asigna el valor regresado por la llamada de método ButtonTime a la variable time del método Main (Paso 3). Luego time está listo para usarse en la siguiente llamada de método Blink (4, time, 10) (Paso 4) como el valor a pasar al parámetro rate del método Blink (Paso 5). 3 Cargue ButtonBlinkTime en el chip Propeller. Kit Educativo de Practicas Propeller: Fundamentos · Página 77 Prácticas de Métodos y Cogs 3 Presione y suelte el botón y observe que el LED parpadea 10 veces a una frecuencia determinada por el tiempo que se sostiene el botón. 3 Después de que el LED termina de parpadear presione y suelte el botón en un tiempo diferente. 3 Intente varios tiempos desde presionar y soltar rápidamente hasta presionar por varios segundos. Especificando Valores de Regreso Declaraciones de métodos públicos y privados ofrecen la opcion de nombrar el valor de regreso (Definiciones en el Manual Propeller Rvalue en el PUB y Sintaxis PRI). Cuando se especifica un valor de regreso solo proporciona un alias a la variable result del método. Este nombre alias es practico especialmente para documentar el código pero no es requerido. A continuación hay una versión modificada del método ButtonTime que demuestra cómo se puede usar regresar un valor en vez de una variable result. Aquí se agrego :dt a la declaración del método y en la última línea ahora dice dt := t2 – t1en vez de result := t2 – t1. Tenga en mente que dt es solo un alias de la variable local result. Así desde el punto de vista de la llamada de método este método aun funciona idénticamente que el objeto original ButtonBlink. PUB ButtonTime(pin) : dt | t1, t2 regreso ' Alias opcional especificado para el valor de repeat until ina[pin] t1 := cnt repeat while ina[pin] t2 := cnt dt := t2 - t1 ' Automáticamente se regresa el valor almacenado por dt 3 Haga una copia del objeto ButtonBlink en un nuevo tabulador. 3 Substituya esta versión modificada del método ButtonTime en la copia del objeto ButtonBlink y verifique que trabaja igual. 3 Utilice el sumario y vistas de documentación para comparar los dos objetos En la versión modificada de ButtonBlink usted debe ver el valor de regreso dt incluido en el sumario y la vista de documentación. Hacer un hábito en definir valores de regreso cuando se declaran métodos que pueden llamarse dentro de la expresión hará más fácil entender y reusar sus objetos. Indexando Identificación del Cog Como se menciono anteriormente los objetos no pueden predecir necesariamente cual Cog será iniciado en un método. El comando cognew regresa la identificación del Cog donde se ejecuta un método. Cada vez que un método se inicia en un Cog nuevo la identificación del Cog que regresa el comando cognew puede almacenarse en una variable. Esto hace posible rastrear que hace cada Cog. El objeto CogStartStopWithButton demuestra como rastrear los Cogs con un arreglo variable en una aplicación que inicia un Nuevo Cog cada vez que el botón se presiona y se suelta. Usa el mismo método ButtonTime del objeto ejemplo anterior para medir el tiempo que el botón se presiono. Luego inicia el método Blink en un nuevo Cog con la medida time determinando la frecuencia de parpadeo. El resultado es una aplicación donde cada vez que se presiona y se suéltale botón otro LED comienza a parpadear a la frecuencia que coincide con el tiempo que se presiono el botón. Después de seis veces que se presiona/suelta las siguientes seis veces apagaran los Cogs en sentido contrario. Como el arranque y paro esta anidado en un ciclo repeat sin condiciones cuando se presione el botón P23 13 veces el ciclo comenzara con el mismo efecto que el de la primera vez. Pagina 78 · Kit Educativo de Prácticas Propeller: Fundamentos 5: Prácticas de Métodos y Cogs 3 Cargue CogStartStopWithButton.spin en el chip Propeller y use el botón P23 para iniciar el método Blink en los otros seis Cogs. 3 Presione por diversos tiempos para que el LED obviamente parpadee a diferente frecuencia 3 Asegúrese de presionar/soltar el botón P23 al menos 12 veces para iniciar y después apagar los Cogs del 1 al 7. '' Archivo: CogStartStopWithButton.spin '' Inicia métodos en Cogs y detiene Cogs en las estructuras de ciclo que '' avanzan por pulsación de botón VAR long stack[60] PUB ButtonBlinkTime | time, index, cog[6] repeat repeat index from 0 to 5 time := ButtonTime(23) cog[index] := cognew(Blink(index + 4, time, 1_000_000), @stack[index * 10]) repeat index from 5 to 0 ButtonTime(23) cogstop(cog[index]) PUB Blink( pin, rate, reps) dira[pin]~~ outa[pin]~ repeat reps * 2 waitcnt(rate/2 + cnt) !outa[pin] PUB ButtonTime(pin) : delta | time1, time2 repeat until ina[pin] == 1 time1 := cnt repeat until ina[pin] == 0 time2 := cnt delta := time2 - time1 Dentro de ButtonBlinkTime El método ButtonBlinkTime del objeto CogStartStopWithButton se declara con ocho variables locales: time, index, y un arreglo llamado cog con seis elementos. El comando repeat bajo la declaración del método repite el resto de los comandos en el método ya que están indentados. Debido a que este comando repeat no tiene condiciones el resto de los comandos en el método se repiten indefinidamente. PUB ButtonBlinkTime | time, index, cog[6] repeat El primer ciclo anidado repeat incrementa la variable index de 0 a 5 cada vez. El primer comando que repite es time := ButtonTime(23), el cual tiene un nuevo lapso de tiempo por la presión del botón Kit Educativo de Practicas Propeller: Fundamentos · Página 79 Prácticas de Métodos y Cogs cada vez que se llama. La siguiente línea cog[index] := cognew… inicia Blink(index + 4, time, 1_000_000) en un nuevo Cog. El comando cognew regresa el numero de Cog, el cual se almacena en cog[index]. La primera vez index es igual a 0 así el comando se hace cog[0] := cognew(Blink(4, time, 1_000_000), @stack[0]). La segunda vez cog[1] := cognew(Blink(5, time, 1_000_000), @stack[10]). La tercera cog[2] := cognew(Blink(6, time, 1_000_000), @stack[20]), y así sucesivamente. Así cog[0], cog[1], hasta cog[5], cada uno almacena la identificación del Cog para cada Cog en la cual se inician diferentes versiones de Blink. repeat index from 0 to 5 time := ButtonTime(23) cog[index] := cognew(Blink(index + 4, time, 1_000_000), @stack[index * 10]) Después de presionar/soltar seis veces entra a este ciclo repeat. Observe como se llama al método ButtonTime, pero su valor de regreso no se almacena en la variable time. Eso es porque el método se usa únicamente para esperar por la siguiente vez que se presiona/suelta el botón para poder apagar el siguiente Cog. Como no se hace nada con su valor de regreso entonces no necesita almacenarse en la variable time. Este ciclo repeat va de 5 a 0. La primera vez que hace el ciclo apagara el Cog que tiene su identificación almacenada en cog[5]. La segunda vez apagara el Cog con la identificación en cog[4], y así sucesivamente hasta el cog[0],. repeat index from 5 to 0 ButtonTime(23) cogstop(cog[index]) Tiempo de Estudio Preguntas 1) ¿Qué sucede si un método que fue llamado se queda sin comandos? 2) ¿Cuántos parámetros se pueden pasar a un método? 3) ¿Cuántos valores tiene un regreso de método? 4) ¿Cómo se determina el valor que regresa un método? 5) ¿Cuales dos argumentos necesita cognew para iniciar un método en un nuevo cog? 6) ¿Cuál es la diferencia entre la Pila del Cog 0 y las pilas de otros Cogs? 7) ¿Cuál es la diferencia entre cognew y coginit? 8) ¿Cómo puede detener un Cog? 9) ¿Cuando se llama un método que valores se copian a la pila del Cog? 10) ¿Qué puede suceder en la pila conforme se ejecutan los comandos en un método? 11) ¿Qué le pasa a la Pila durante las llamadas de métodos anidados? 12) ¿Cuál es la mejor forma de evitar problemas con la pila cuando estas iniciando un método prototipo que corre en un Cog? 13) ¿Qué característica del comando cognew hace posible que el programa pueda rastrear que proceso está corriendo en un Cog? 14) ¿Es posible iniciar Cogs sucesivos en un ciclo? Ejercicios 1) Escriba una declaración pública para un método de nombre SquareWave que espera parámetros de nombre pin, tHigh, y tCycle, regresa success y tiene variables locales tC and tH. 2) Escriba una llamada al método del ejercicio #1. Programe el Pin a 24, el tiempo en alto de 1/2000 de la frecuencia del sistema de reloj y el tiempo de ciclo 1/100 de la frecuencia del reloj. Almacene el resultado en una variable de nombre yesNo. Pagina 80 · Kit Educativo de Prácticas Propeller: Fundamentos 5: Prácticas de Métodos y Cogs 3) Aparte 40 nombres long en un Cog separado de nombre swStack para prototipo del método SquareWave. 4) Declare una variable de nombre para almacenar la identificación del Cog donde se corre el método SquareWave. 5) Inicie el método SquareWave en un Cog Nuevo y almacene la identificación del Cog en la variable swCog con la dirección de arranque de la variable swStack. 6) Corra el método SquareWave en el Cog 5. 7) Modifique la declaración de la variable swStack para iniciar tres copias del método SquareWave en Cogs separados. Recuerde esto es para prototipo y el espacio de pila no requerida será acomodado después (En la práctica de objetos) 8) Modifique la declaración de la variable swCog para almacenar tres identificaciones de Cogs diferentes, 9) Inicie tres copias del método SquareWave en Cogs separados. Aquí hay una lista de parámetros para cada método SquareWave: (1) 5, clkfreq/20, clkfreq/10, (2) 6, clkfreq/100, clkfreq/5, (3) 9, clkfreq/1000, clkfreq/2000. Proyectos 1) Haga el prototipo del método SquareWave descrito en la sección de ejercicios. Asegúrese de incorporar las técnicas de código para prevenir inexactitudes debido al tiempo de ejecución de comandos de los cuales se hablo en la práctica de E/S y tiempo. (Tenga en cuenta que hay mejores formas de desarrollar ondas cuadradas que serán revisadas en prácticas de Contadores y Lenguaje Ensamblador) 2) Escriba un programa para probar el método SquareWave usando diversas características de la sección de ejercicios. 3) Más experimentos: Quizá haya notado que el Pin 9 brilla poco. Si usted decrementa el término tHigh incrementando el denominador será más bajo. Si incrementa el término tHigh decrementando el denominador entonces brillara mas. Asegúrese que tHigh es más pequeño que tCycle, de otra forma el programa no trabajara como se pretende. Inténtelo. Kit Educativo de Practicas Propeller: Fundamentos · Página 81 Prácticas de Métodos y Cogs Pagina 82 · Kit Educativo de Prácticas Propeller: Fundamentos 6: Práctica de Objetos 6: Practica de Objetos Introducción En prácticas anteriores todas las aplicaciones de ejemplos de código eran para objetos individuales. Sin embargo las aplicaciones son organizadas en colecciones de objetos. Cada aplicación tiene un objeto superior, el cual es donde se inicia la ejecución del código. Los objetos superiores pueden declarar y llamar a métodos en uno o más objetos. Esos objetos pueden en su turno declarar y llamar métodos en otros objetos y así sucesivamente… Muchos objetos son incorporados en aplicaciones diseñadas para simplificar desarrollos. Algunos de estos objetos son colecciones de métodos prácticos que han sido publicados por lo que tareas comunes de código no tiene que ser hechas desde el principio. Otros objetos administran procesos que son iniciados en Cogs. Estos usualmente cubren las tareas observadas en la práctica de métodos y Cogs, incluyendo declaración de valores de pila y rastreo de en que cog se inicio el proceso. Estos objetos que administran Cogs también tienen métodos de arranque y paro de procesos. Hay diferentes fuentes donde puede obtener objetos útiles que pueden ser incorporados en su aplicación, incluyendo la librería de la herramienta Propeller. El intercambio e objetos en obex.parallax.com y el foro del chip Propeller en los foros forums.parallax.com. Cada objeto tiene documentación típicamente que explica como incorporarlo en su aplicación junto con uno o más ejemplos de archivos superiores que demuestran como declarar el objeto y llamar su método. Además de usar los objetos pre-escritos usted querrá modificar un objeto existente para usarlo de acuerdo a su aplicación o incluso escribir un objeto particular. Si usted escribe un objeto que soluciona un problema o desarrolla una tarea que no está disponible en otro lado considere publicarla en el Intercambio de Objetos Propeller. Esta práctica lo guía a través de escrituras de varios objetos y la incorporación de ellos es sus aplicaciones. Algunos objetos son solo colecciones de métodos útiles mientras que otros administran procesos iniciados en Cogs. Algunos de los objetos serán escritos desde el principio y otros usaran la librería Propeller como recurso. Los ejemplos de aplicaciones lo guiara a través de: • • • • • • • Llamar métodos en otros objetos Usar objetos que inician procesos en Cogs Escribir código que llama un método de un objeto basado en su documentación Escribir documentación de objetos y esquemáticos Usar objetos de la Librería Propeller de Objetos Accesar valores y variables por su dirección de memoria Usar objetos para iniciar Cogs que leen y/o actualizan las variables de los objetos padre Prerrequisitos para la Practica • Configuración y Prueba • E/S y Tiempo • Métodos y Cogs Kit Educativo de Practicas Propeller: Fundamentos · Página 83 Práctica de Objetos Equipo, Partes y Esquemas Aun cuando el circuito es el mismo que se uso en prácticas anteriores hay algunos cambios. Primero, el esquemático mostrado en la Figura 6-1 se dibujo usando la fuente Parallax y la tabla de caracteres de la herramienta Propeller, lo cual es un importante componente en la documentación de objetos. Segundo, algunos de los ejemplos de código le permiten monitorear y controlar elementos del circuito desde su PC con el programa incluido en esta práctica que se llama Terminal Serial Parallax (PST.exe). Las aplicaciones Propeller que se comunican serialmente con la Terminal Serial Parallax lo harán con la ayuda de un objeto llamado FullDuplexSerial.spin. 3 Usted puede accesar la tabla de caracteres presionando Help y seleccionando View Character Chart. Figura 6-1: Esquemático (Dibujado con el Programa de la Herramienta Propeller) Pagina 84 · Kit Educativo de Prácticas Propeller: Fundamentos 6: Práctica de Objetos Revisión de la llamada a método El objeto ButtonBlink de abajo es un ejemplo de la práctica de Métodos y Cogs. Cada vez que presiona y suelta el botón conectado a P23 el objeto mide el tiempo aproximado que se presiono y usa este valor para determinar el periodo completo de encendido/apagado, después el LED parpadea diez veces. (El botón de eliminación de rebotes no se requiere con los botones del PE kit). El objeto cumple estas tareas llamando otros métodos en el mismo objeto. El código en el método Main llama al método ButtonTime para medir el tiempo que se presiono el botón. Cuando ButtonTime regresa un valor el método Blink se llama, con uno de los parámetros siendo el resultado de la medición de ButtonTime. 3 Cargue ButtonBlink.spin en el chip Propeller y pruébelo para asegurarse que puede usar el botón en P23 para programar el periodo de parpadeo del LED '' ButtonBlink.spin PUB Main | time Repeat time := ButtonTime(23) Blink(4, time, 10) PUB Blink(pin, rate, reps) dira[pin]~~ outa[pin]~ repeat reps * 2 waitcnt(rate/2 + cnt) !outa[pin] PUB ButtonTime(pin) : dt | t1, t2 repeat until ina[pin] t1 := cnt repeat while ina[pin] t2 := cnt dt := t2 - t1 Llamando Métodos en otros Objetos con la Notación Dot Los métodos ButtonTime y Blink del objeto ButtonBlink nos dan un ejemplo simple del código que puede ser útil en diferentes aplicaciones. Estos métodos pueden almacenarse en archivos objetos separados y después cualquier objeto que lo necesite para hacer parpadear un LED o medir una pulsación de un botón puede accesar estos métodos siguiendo estos dos pasos: 1) Declarar el objeto en un código de bloque OBJ, y dar un apodo al archivo del objeto. 2) Use ObjectNickname.MethodName para llamar al método del objeto. L Lo que se llama Notación Dot aquí se refiere como “referencia método-objeto” en el Manual Propeller. Kit Educativo de Practicas Propeller: Fundamentos · Página 85 Práctica de Objetos La Figura 6-2 muestra un ejemplo de cómo funciona. Los métodos ButtonTime y Blink se movieron a un objeto llamado ButtonAndBlink. Para tener acceso a los métodos públicos del objeto ButtonAndBlink el objeto DotNotationExample tiene que empezar declarando el objeto ButtonAndBlink y darle un apodo. Estas declaraciones de objetos se hacen en el código de bloque OBJ del objeto DotNotationExample. La declaración PbLed : "ButtonAndBlink" le da un apodo PbLed al objeto ButtonAndBlink. La declaración PbLed hace posible para el objeto DotNotationExample llamar métodos en el objeto ButtonAndBlink usando la notación ApodoObjeto.Nombre Método. Así DotNotationExample usa time := PbLed.ButtonTime(23) para llamar el método ButtonTime de ButtonAndBlink, pasa el parámetro 23 y asigna el resultado regresado a la variable time. DotNotationExample también usa el comando PbLed.Blink(4, time, 20) para pasar 4, el valor almacenado en la variable time y 20 al método Blink de ButtonAndBlink. Ubicación de archivos: Un objeto tiene que estar ya sea en el mismo archivo con el objeto que lo está declarando o en el mismo archivo que el archivo Propeller Tool.exe. Los objetos almacenados con la herramienta Propeller comúnmente se refiere como librería de objetos. L Figura 6-2: Llamando Métodos en otros Objetos con la Notación Dot 'File: DotNotationExample.spin Declaracion de Objeto OBJ PbLed : "ButtonAndBlink" PUB Main | time repeat time := PbLed.ButtonTime(23) PbLed.Blink(4, time, 20) Llamada a método con ApodoObjeto.NombreMetodo '' Archivo: ButtonAndBlink.spin '' Objeto Ejemplo con dos metodos PUB ButtonTime(pin): delta | time1, time2 repeat until ina[pin] == 1 time1 := cnt repeat until ina[pin] == 0 time2 := cnt delta := time2 - time1 PUB Blink( pin, rate, reps) dira[pin]~~ outa[pin]~ repeat reps * 2 waitcnt(rate/2 + cnt) !outa[pin] 3 Cargue el objeto DotNotationExample en el chip Propeller. Si usted está ingresando el código manualmente asegúrese que ambos archivos están en el mismo directorio. También el nombre del archivo del objeto ButtonAndBlink debe ser ButtonAndBlink.spin. 3 Verifique que el programa hace lo mismo que el objeto del ejemplo anterior (ButtonBlink). 3 Siga los pasos en la Figura 5-4 y asegúrese que está claro como ButtonAndBlink obtiene un apodo en la sección OBJ y como se usa ese apodo por DotNotationExample para la llamada de método en el objeto ButtonAndBlink. 3 Compare DotNotationExample.spin con el objeto ejemplo anterior (ButtonBlink). Organización de Objetos Los objetos pueden declarar objetos que pueden a su vez declarar otros objetos. Es importante examinar las relaciones entre objetos padres con sus hijos, nietos y así sucesivamente. Hay un par de formas para examinar esos árboles familiares de objetos. Primero vamos a ver las relaciones en la ventana de Información del Objeto con la característica Compilar de la Herramienta Propeller: Pagina 86 · Kit Educativo de Prácticas Propeller: Fundamentos 6: Práctica de Objetos 3 En menú Run de la herramienta Propeller seleccione Compile Current → View Info (F8). Observe que la cadena de comando se muestra en la ventana de la información del objeto en la esquina superior izquierda. En esta ventana puede hacer click en cada carpeta para ver cuanta memoria ocupa en la memoria RAM global. También puede presionar dos veces en la carpeta para abrir el archive Spin que contiene el código. Como la aplicación DotNotationExample declaro a ButtonAndBlink el código ButtonAndBlink ahora es parte de DotNotationExample por lo que este parece tener más código que ButtonAndBlink en la ventana de información, aun cuando tiene mucho menos código escrito. Figura 6-3: Ventana de Información del Objeto Después de cerrar la ventana de información la misma vista del objeto se podrá ver en la esquina izquierda superior de la herramienta Propeller (ver Figura 6-4). El objeto se puede abrir presionando sobre él. También puede ver un objeto en modo de documentación al presionar el botón derecho del ratón sobre la carpeta. Puede presionar el botón izquierdo para regresar al modo de vista completa. Figura 6-4: Herramienta Propeller con Vista del Objeto (Ventana Superior Izquierda) Kit Educativo de Practicas Propeller: Fundamentos · Página 87 Práctica de Objetos Objetos que pueden iniciar Procesos en Cogs En la práctica de métodos nos tomo varios pasos para escribir un programa que inicia un método en un Cog. En primer lugar tenían que declararse variables adicionales para darle al Co su memoria de pila y rastrear cual Cog corría un proceso antes de poder usar los comandos cognew o cogstart. También se requería una variable que almacena la identificación de los Cogs para escoger el Cog apropiado por si el programa tenía que parar un proceso después de iniciarlo. Los objetos que inician procesos en los Cogs pueden cuidar todos los detalles por usted. Por ejemplo tenemos un objeto superior que declara dos hijos de nombre Button y Blinker. El objeto Blinker tiene un método Start que inicializa el método Blink en un Cog nuevo y todas las variables que las acompaña. De esta forma todo lo que tiene que hacer el objeto superior es llamar al método Start del objeto Blinker. {{ Archivo superior: CogObjectExample.spin Parpadea un LED 20 veces. El periodo de parpadeo del LED se determina Por qué tanto tiempo se presiono el botón en P23 }} OBJ Blinker : "Blinker" Button : "Button" PUB ButtonBlinkTime | time repeat time := Button.Time(23) Blinker.Start(4, time, 20) A diferencia del objeto DotNotationExample usted no tendrá que esperar a que el LED parpadee 20 veces antes de presionar el botón nuevamente para cambiar el periodo (para las siguientes 20 veces). Hay dos razones. La primera porque el objeto Blinker automáticamente inicia el proceso de parpadeo del LED en un Cog nuevo. Esto libera al Cog 0 para que siga monitoreando el botón mientras que el Cog 1 hace parpadear el LED. La segunda el método Start del objeto Blinker automáticamente para cualquier proceso que este corriendo antes de iniciar uno nuevo. De esta forma tan pronto como se toma el tiempo con Button.Time(23) el método Blinker.Start para cualquier proceso (Cog) que pudiera estar corriendo antes de iniciar el nuevo proceso. 3 Si está usando archivos .spin pre-escritos disponibles para este texto (ver la pagina 17) todos están en la misma carpeta. Si usted está escribiendo el código asegúrese de guardar los tres archivos en la misma carpeta. Los objetos que tiene que guardar son CogObjectExample (arriba), Blinker, y Button (ambos abajo). 3 Cargue CogObjectExample en el chip Propeller. 3 Intente presionar y soltar el botón en P23 para que haga parpadear el LED despacio. 3 Antes del parpadeo 20 presione y suelte rápidamente el botón en P23. El LED deberá parpadear más rápido inmediatamente. Dentro del Objeto Blinker Construir cloques de objetos que inician procesos en Cogs se escriben típicamente para cuidar la mayoría de los detalles de grabación del Cog. Todos los objetos padres es declarar el objeto y luego inicializar el objeto llamando el método Start del objeto o detenerlo llamando el método Stop. Por ejemplo el objeto Blinker, mostrado abajo, tiene el arreglo de variables necesarias en la pila del Cog Pagina 88 · Kit Educativo de Prácticas Propeller: Fundamentos 6: Práctica de Objetos para las operaciones mientras se ejecuta el método Blink en otro Cog. También tiene una variable llamada cog para mantener el historial de en cual Cog se inicio el método Blink. El objeto Blinker tiene los métodos Start y Stop para iniciar el ahora método familiar Blink en un nuevo Cog y detenerlo nuevamente. Cuando el método Start inicia el método Blink en un nuevo Cog toma la identificación del Cog que regresa cognew, agrega 1 y copia el valor del resultado en la variable cog. El valor que regresa el método Start en la variable success también es cog ID + 1 el cual el objeto padre trata como un valor booleano. Al final como este valor es no-cero significa que el proceso se inicio con éxito. Si el valor es cero significa que el Cog no se inicializo. Esto sucede típicamente cuando los ocho Cogs del chip Propeller están en uso. El método Stop del objeto Blinker. Spin puede llamarse para detener el proceso. Cuando se llama usa el valor almacenado en la variable cog (menos 1) para obtener la identificación correcta del Cog que detendrá el Cog donde el método Start inicio el método Blink. {{ Archivo: Blinker. Spin Ejemplo de administración del Cog para el proceso de parpadeo de LED. SCHEMATIC ─────────────────────────────── 100 ω LED pin ──────────┐ GND ─────────────────────────────── }} VAR long stack[10] 'Espacio de Pila del Cog byte cog 'Identificación del Cog PUB Start(pin, rate, reps) : success {{Inicia nuevo proceso blinking en Cog Nuevo; regresa True si tiene éxito. Parámetros: pin La E/S conectada al circuito LED → ver esquemático rate Ciclo encendido/apagado definido por el numero de ciclos de reloj reps El numero de ciclos de encendido/apagado }} Stop success := (cog := cognew(Blink(pin, rate, reps), @stack) + 1) PUB Stop ''Detiene el proceso blinking, si existe. if cog cogstop(cog~ - 1) PUB Blink(pin, rate, reps) {{Parpadea un circuito LED conectado al pin a una frecuencia dada por reps. Parámetros: pin La E/S conectada al circuito LED → ver esquemático rate Tiempo de ciclo de encendido/apagado definido por ciclo de reloj reps el número de ciclos de encendido/apagado }} dira[pin]~~ outa[pin]~ repeat reps * 2 waitcnt(rate/2 + cnt) !outa[pin] Kit Educativo de Practicas Propeller: Fundamentos · Página 89 Práctica de Objetos Los métodos Start y Stop mostrados en este objeto es el alcance recomendado para objetos que administran Cogs. La lista de parámetros del método Start debería tener todos los parámetros que el proceso necesita para iniciarse en un Cog. Note que esos valores se pasan al método del objeto Blink a través de la llamada en el comando cognew. Los métodos Start y Stop se usan por convención en objetos que inician procesos en nuevos Cogs. Si está usando un objeto con métodos Start y Stop puede esperar que el método Start del objeto inicie el proceso en un nuevo Cog por usted y que el método Stop detenga el proceso y libere un Cog. Si está escribiendo código que depende de objetos construidos en bloques con métodos Start y Stop su principal problema será llamar al método Start desde un objeto padre y pasar los parámetros correctos. Estos parámetros se explican en los comentarios de documentación los cuales se revisaran en la sección de Comentarios de en la página 90. Los métodos Start y Stop también rastrean en cual Cog se inicio el proceso (el método Blink en el caso de Blinker. Spin). Si todos los Cogs están en uso el método Start regresa un 0; de otra forma regresa la identificación del Cog + 1 lo cual es un no-cero. Esto simplifica el trabajo del de verificar y encontrar si el método Start inicio correctamente el proceso en el nuevo Cog. Especialmente si el objeto padre ha llamado a métodos Start de otros objetos, todos los cogs del chip Propeller pueden estar trabajando en otras tareas al mismo tiempo. Por ejemplo el objeto padre puede verificar si el método Start del objeto Blinker se desempeño correctamente como: if Blinker.Start 'Inserte el código si se inicio correctamente else 'Inserte código aquí si fallo la inicialización El código indexado debajo de la sentencia if se ejecuta si Blinker.Start indica que se inicio exitosamente el cog al regresar un no-cero. Si el método Blinker.Start regresa un cero indica que no fue posible iniciar el cog, lo cual puede suceder si todos los Cogs están ocupados. En este caso el código debajo de la condición else indentada se ejecutara. Una práctica común entre autores de bloques de objetos es copiar y pegar el ejemplo y Stop de los métodos del Manual Propeller o de este texto en los objetos que escriben. Después ajustan la lista de parámetros del método Start y la documentación necesaria. No solo hacen los ejemplos de los métodos Start y Stop de acuerdo a la convención de los métodos Start y Stop en la librería de objetos discutidos en la página 90, ellos combinan la correcta contabilidad con valores de regreso nocero para indicar el progreso. Si está interesado en como ellos hacen esto ponga atención a la siguiente sección. De otra forma brínquese la sección El Objeto Button que empieza en la pagina 89. Área Avanzada: Dentro de los métodos Start y Stop Cuando un método Spin se inicia desde otro Cog, además del arreglo de pila necesita declarar una variable cog en el objeto Blinker. Esta variable global es accesible para todos los métodos en el objeto, así el método Start puede almacenar un valor en esta variable que corresponde al Cog que fue ejecutado, y el método Stop puede accesar esta variable si necesita saber cual Cog detener. VAR long stack[10] byte cog 'Cog stack space 'Cog ID El comando cognew en el método Start regresa la identificación del Cog. El valor del Cog puede ser de 0 a 7 si se inicia adecuadamente y -1 si falla al iniciar. Como -1 es un no-cero los métodos Start y Stop tienen que hacer más trabajo de administración para rastrear el numero de Cog que está Pagina 90 · Kit Educativo de Prácticas Propeller: Fundamentos 6: Práctica de Objetos corriendo el proceso (en caso de que su código decida parar después) mientras aun regresa valores que indican la inicialización del Cog (no-cero) o el fallo de inicio (0). En caso de que el objeto padre llame al método Start dos veces seguidas sin llamar al método Stop la primer cosa que hace el método Start es llamar al método Stop. Después el método Start usa el comando cognew para iniciar el método Blink en un nuevo Cog. El comando cognew regresa el valor del Cog o -1 si no hay Cogs disponibles. En la extrema derecha se suma 1 al valor de regreso cognew y este valor se almacena en ambas variables cog y success. Recuerde que en este punto cog y success almacenan la Identificación de Cog + 1, lo cual es 0 si el método Blink no se inicio en un Cog y un no-cero si el comando cognew tuvo éxito. PUB Start(pin, rate, reps) : success {{...}} Stop success := (cog := cognew(Blink(pin, rate, reps), @stack) + 1) ' ' │ │ └─ Cog ID (0 a 7) o -1 si fallo iniciar Cog ' │ └─ Cog ID + 1 (1 a 8) o 0 (-1 + 1) Si fallo iniciar Cog ' └─ Mismo valor del Cog, usado para que el objeto superior pueda usar el comando : Lo primero que hizo el método Start fue llamar al método Stop. Recuerde: La variable del Cog almacena 0 si su proceso (El método Blink) no está corriendo en otro Cog, o Identificación del Cog + 1 si el proceso de administración del objeto esta activo. Si el Cog no se inicio o si el método Stop se llamo la variable cog almacenara un 0. En este caso se saltara el código debajo de la condición if y el método Stop regresara sin tomar otra acción. Si en vez de esto la variable cog almacena la Identificación + 1 la condición if empieza restando 1 de la variable cog de esta forma regresamos al valor de Identificación del Cog. El comando cogstop usa este valor para detener el Cog adecuado, el cual es el que se inicio por el método Start en un tiempo anterior. La última cosa que el método Stop hace es usar el operador Post-Limpiar ~ para dejar Cog en cero para que todo funcione correctamente la próxima vez que se llame a un método Start o Stop. Pub Stop '' ... ' ┌─ 0 si no se ha iniciado un cog por el método start, ' 1 a 8 si se inicio un Cog por el método Start if cog cogStop(cog~ - 1) ' ' └─ Orden de operaciones: ' 1. cog (Cog ID + 1) - 1 = Cog ID. ' 2. Detiene el cog con el Cog ID. El Objeto Button CogObjectExample también usa el objeto Button el cual hasta el momento tiene solo un método, pero puede expandirse en una colección de métodos útiles. Note que esta versión del objeto Button no inicia ningún proceso nuevo en Cogs así que no tiene un método Start o Stop. Todo lo que hace el objeto Button se hace en el mismo Cog del objeto que lo llama. Este objeto podría modificarse en diversas formas. Por ejemplo se podría agregar otro método relacionado con botón. El objeto podría modificarse para trabajar con un botón o grupo de botones. Podría agregarse un método Init o Config para programar el objeto y monitorear automáticamente un botón o grupo de botones. El objeto podría también modificarse para monitorear estos botones en un Cog separado, pero en ese caso se deberían agregar los métodos Start y Stop. Kit Educativo de Practicas Propeller: Fundamentos · Página 91 Práctica de Objetos '' Archivo: Button.spin '' Comienza un objeto útil. PUB Time(pin) : delta | time1, time2 repeat until ina[pin] == 1 time1 := cnt repeat until ina[pin] == 0 time2 := cnt delta := time2 - time1 Reglas para Métodos Start y Stop en Librerías de Objetos Si un objeto se diseña como bloque de construcción para iniciar otros objetos en un Cog este deberá tener métodos Start y Stop. El método Start cuidara de iniciar el Cog. Si inicia un método spin en un Cog nuevo el método Start usa el comando cognew para pasar la llamada a método y la dirección de la variable global del arreglo de pila del objeto al Cog. También graba el Cog en el que el método se inicio con una de las variables globales del objeto, típicamente un byte variable de nombre cog. El método Stop encuentra cual Cog necesita detenerse verificando la misma variable cog. La regla del método Start y Stop en objetos de construcción de bloques que inician Cogs fue establecida por Parallax para mantener una línea de usuario simple y consistente. También ofrece al diseñador del objeto un lugar para cuidar del espacio de pila y numero de Cog para el objeto. Si usted usa un objeto de la librería Parallax o del intercambio de Objetos Propeller que inicia un Cog, este deberá tener los métodos Start y Stop que cuidan de estos detalles. Así todo lo que sus aplicaciones tienen que hacer es llamar al método Start del objeto y pasar los parámetros que necesita. La librería de objetos cuida de lo demás y debe proporcionar métodos y comentarios de documentación que simplifiquen el monitoreo y control del proceso que está ocurriendo en el Cog que se inicio. L Nunca use cognew o coginit para iniciar un método que está en otro objeto. Los comandos connew y coginit solo pueden iniciarse en un método spin en un nuevo cogsi está en el mismo objeto que el comando. Esta es otra razón por la cual construir objetos de construcción de bloques que inician cogs deberá contener siempre los métodos start y stop. El comando cognew se localiza en el método start del objeto asegurándose que está en el mismo objeto que el metodo que se iniciara en otro cog. Muchos objetos útiles no necesitan iniciar un cog. Cuando el objeto padre llama a su método solo hacen algo útil en el mismo cog. En algunos casos estos objetos tienen variables que necesitan ser configuradas antes de que el objeto pueda proporcionar servicio. El nombre de método recomendado para configurar variables de objetos si no inicia un cog es Init o Config. No use el nombre de método start en este tipo de objetos porque podría llevarlo a pensar que inicia un cog. Del mismo modo no use start como nombre de método al principio del código de su aplicación. En su lugar utilice en método Go si nada más descriptivo viene a su mente. Comentarios de Documentación La Figura 6-5 muestra la primera parte del objeto Blinker desplegado en vista de documentación. Para ver el objeto en esta modalidad asegúrese que está en el tabulador activo (presione el tabulador con el nombre de archivo Blinker), después presione el botón de radio Documentation justo arriba del código. Recuerde de la practica E/S y tiempo que una línea sencilla de comentarios de documentación es precedida por dos apostrofes: ''comment, y que los comentarios de documentación que ocupan más de una línea se inician y terminan con dobles llaves: {{comments}}. De un vistazo a los comentarios de documentación en modo de fuente completa y compárelos con los comentarios en modo de documentación. Pagina 92 · Kit Educativo de Prácticas Propeller: Fundamentos 6: Práctica de Objetos La vista en modo de documentación agrega automáticamente alguna información que está en los comentarios de documentación. Primero está la línea de información del objeto, el cual es una lista de las declaraciones del método público del objeto incluyendo el nombre del método, lista de parámetros y valores de regreso. Esto le da al programador una vista d los métodos del objeto. Con esto en mente es importante escoger nombres descriptivos para un método de objeto, parámetros de método y valores de regreso. El modo de documentación también proporciona cuanta memoria agregara el objeto a un programa y cuanto toma para las variables. Estas por supuesto son importantes para características de vista rápida. Figura 6-5: Vista de Documentación El modo de vista de documentación también inserta cada declaración de método (sin variables locales no se usan como parámetros o variables de regreso). Note como también aparecen los comentarios de documentación debajo de la declaración del método y lo que hace el método, que información deberán recibir sus parámetros y que regresar. Cada documentación de método público deberá tener suficiente información para un programador sin tener que mover de regreso a la vista completa y hacer ingenieria inversa al método y tratar de adivinar que es lo que hace. Esta es otra buena razón para escoger los nombres de métodos y parámetros cuidadosamente ya que ayudara a hacer los comentarios más concisos. Con los comentarios de documentación debajo de cada declaración de método público explique qué hace el método. Explique cada parámetro, empiece con su nombre e incluya cualquier información adicional acerca de los valores que el parámetro tiene que recibir. Haga lo mismo para valores de regreso. 3 Intente agregar un comentario de documentación de bloque justo abajo del método ButtonBlinkTime del objeto CogObjectExample y verifique que la documentación aparece debajo de la declaración del método en el modo de vista de documentación. Figura 6-6: Mas vista de documentación Kit Educativo de Practicas Propeller: Fundamentos · Página 93 Práctica de Objetos Dibujando esquemáticos La fuente Parallax tiene símbolos para dibujar esquemáticos y deberán usarse para documentar los circuitos para los que los objetos fueron diseñados. La herramienta de caracteres se muestra en la Figura 6-7. Además de los símbolos para dibujar esquemáticos tiene símbolos para diagramas de tiempo , operadores matemáticos ± + - × ÷ = ≈ √ ¹ ² ³, y símbolos griegos para cantidades y medidas ω μ δ σ π. 3 3 3 3 Presione Help y seleccione View Character Chart. Presione el botón symbolic Order Coloque el curso en un área de comentario en el objeto Presione varios caracteres en la grafica y observe que aparecen en el objeto. Figura 6-7: Herramienta Propeller Mapa de Caracteres Los archivos que involucran circuitos deberán tener esquemáticos para que también el circuito pueda hacerse y probarse. Por ejemplo el esquemático mostrado en la Figura 6-8 puede agregarse para CogObjectExample. El botón puede ser engañoso. La grafica que se muestra en la Figura 6-8, muestra el orden regular (presione el botón Standard Order). En este orden el carácter 0 es el superior izquierdo, carácter 1 el siguiente y así sucesivamente hasta llegar al carácter 255 en la inferior derecha. Esta es una lista de los caracteres que necesitara: Botón: LED: 19, 23, 24, 27, 144, 145, 152, 186, 188 19, 24, 36, 144, 145, 158, 166, 168, 169, 189, 190 3 Intente agregar el esquemático mostrado en la Figura 6-8 a su copia de CogObjectExample. Pagina 94 · Kit Educativo de Prácticas Propeller: Fundamentos 6: Práctica de Objetos Figura 6-8: Dibujando esquemáticos con el mapa de caracteres Métodos Públicos vs. Privados El objeto Blinker está escrito para que su objeto padre pueda llamar al método Start o Blink. Para este objeto particular es útil porque hay veces que el programador puede no querer permitir que el parpadeo de 20 LED se interrumpa. En este caso en vez de llamar al método Start el objeto padre llama al método Blink directamente. 3 Modifique una copia de CogObjectExample para que llame al método Blink del objeto Blinker en vez del método Start. La versión modificada no lo dejara interrumpir el parpadeo del LED para reiniciar una nueva frecuencia. Esto porque todo el código se ejecuta en el mismo Cog mientras que la versión no modificada le permite llamar al método Start en cualquier momento ya que el parpadeo del LED sucede en otro Cog. Así mientras el Cog está ocupado parpadeando el LED no se monitorea el botón. Algunos objetos se escriben para tener métodos públicos (PUB) que pueden llamarse por otros objetos y métodos privados (PRI) que solo pueden llamarse por otro método en el mismo objeto. Los métodos privados tienden a ser los que ayudan al objeto a hacer su trabajo, pero no son hechos para llamarse por otros objetos. Por ejemplo algunas veces una tarea compleja se separa en diversos métodos. Un método público puede recibir parámetros y luego llamar métodos privados en una cierta secuencia. Especialmente si llamando a esos métodos en la secuencia incorrecta podría llevar a resultados indeseables, esos otros métodos deberían ser privados. Kit Educativo de Practicas Propeller: Fundamentos · Página 95 Práctica de Objetos Con el método Blink del objeto Blinker no hay razón actual para hacerlo privado fuera de examinar que sucede cuando un objeto padre intenta llamar otro método privado de objeto. 3 Cambie el método Blink del objeto Blinker de PUB a PRI. 3 Intente correr la copia modificada de CogObjectExample y observe los mensajes de error. Esto demuestra que el método Blink no puede accesarse por otro objeto ya que es privado. 3 Corra la copia no modificada (la cual solo llama al método publico Start, no al método privado Blink) y verifique que aun trabaja apropiadamente. Esto demuestra como el método privado Blink aun puede ser accesado del mismo objeto (Blinker) por su método Start. Ejemplo de Múltiples Objetos Los objetos Spin que inician y administran uno o más cogs para un proceso dado son escritos típicamente para una sola copia del proceso. Si la aplicación necesita más de una copia de los procesos corriendo actualmente simplemente se puede declarar más de una copia del objeto. Por ejemplo el chip Propeller puede controlar una pantalla de TV con un cog, pero cada objeto TV solo controla una pantalla de TV. Si la aplicación necesita controlar más de una TV entonces se declaran más de una copia del objeto TV. ¿Copias múltiples de Objetos? No hay Problema! L No hay penalizaciones para el espacio de código por declarar múltiples objetos. El compilador de la herramienta Propeller los optimiza así que solo se ejecuta el código una vez por todas las copias de los objetos. La única penalización para declarar más de una copia del mismo objeto es que habrá más de una copia de variables globales que declara el objeto, un paquete por cada objeto. Como más o menos se necesitan el mismo número de variables extras por una aplicación dada para hacer el mismo trabajo sin objetos, realmente no es una penalización. El objeto MultiCogObjectExample demuestra cómo se pueden iniciar múltiples copias de un objeto que administra un proceso con un arreglo de objeto. Al igual que las variables, los objetos pueden declararse como arreglos. En este ejemplo seis copias del objeto Bliker se declaran en el bloque OBJ con Blinker[6] : Blinker. Las seis copias de Blinker pueden indexarse también de la misma forma que los arreglos de variables con Blinker[0], Blinker[1], y así sucesivamente hasta Blinker[5]. En MultiCogObjectExample un ciclo repeat incrementa una variable index, por lo que Blinker[index].Start… llama sucesivamente cada método Start del objeto. El objeto MultiCogObjectExample es funcionalmente equivalente al objeto CogStartStopWithButton de la practica Métodos y Cogs. Cuando el programa corre cada vez que se presiona/suelta el boton en P23 inicia un nuevo Cog que hace parpadear sucesivamente los LEDs (conectados de P4 a P9) a rangos determinados por la duración del tiempo que se presiona el botón. De la primera a la sexta vez que se presiona el botón inicia el proceso de parpadeo de LED en nuevos cogs, de la séptima a la decimo segunda detiene cada cog en sentido contrario al que se arrancaron. 3 Cargue el objeto MultiCogObjectExample.spin en el chip Propeller 3 Presione y suelte el botón P23 seis veces sucesivas (cada una con diferente duración) y verifique que los seis cogs se iniciaron correctamente. 3 Presione y suelte el botón en P23 seis veces más y verifique que cada proceso de parpadeo se detiene en orden inverso. Pagina 96 · Kit Educativo de Prácticas Propeller: Fundamentos 6: Práctica de Objetos ''Archivo superior: MultiCogObjectExample.spin OBJ Blinker[6] : "Blinker" Button : "Button" PUB ButtonBlinkTime | time, index repeat repeat index from 0 to 5 time := Button.Time(23) Blinker[index].Start(index + 4, time, 1_000_000) repeat index from 5 to 0 Button.Time(23) Blinker[index].Stop Comunicación Chip Propeller – PC Terminal Es realmente conveniente para diversas aplicaciones poder intercambiar caracteres y valores con el micro controlador utilizando el programa PC terminal. Algunos ejemplos incluyen monitoreo de la computadora y circuitos controlados, mediciones de sensores y enviar y recibir información de diagnósticos para pruebas de sistemas y depurado. La comunicación Terminal/Chip Propeller involucra un programa en la Computadora y el código del micro controlador. Para la computadora utilizaremos el programa Parallax Serial Terminal el cual se verá a continuación. Para el código del micro controlador haremos uso de objetos que atienden señales eléctricas y conversiones entre valores binarios y sus representaciones en carácter para poder enfocarnos en aplicaciones de escritura. Conforme desarrolle aplicaciones que hagan uso de objetos de comunicación serial considere como esos objetos disponibles simplifican la escritura de programas. Se da un ejemplo de cómo usando objetos de la Librería Propeller, Intercambio de Objetos Propeller y el foro del Chip Propeller hace posible hacer mucho con unas pocas líneas de código. Terminal Serial Parallax El programa de la terminal serial Parallax (PST.exe) mostrado en la Figura 6-9 es una herramienta adecuada para la comunicación chip Propeller/Computadora. Muestra texto y mensajes numéricos del chip Propeller y también permite enviar mensajes similares al chip Propeller. 3 Si aun no lo ha hecho vaya a Programas, Documentación y Recursos (página 17) Y siga las instrucciones para descargar y preparar la Terminal Serial Parallax. Este programa tiene una ventana de transmisión que envía los caracteres que usted teclea al chip Propeller y una ventana de recepción que muestra los caracteres que son enviados por el chip Propeller. Tiene menús para el Puerto de Comunicación y la Velocidad de Transmisión así como indicadores de actividad y selectores de controles para los diversos canales (TX, RX, etc). También hay un selector Echo On que esta seleccionado automáticamente para que los caracteres que ingresan a la ventana de transmisión también aparezcan en la ventana de recepción. Kit Educativo de Practicas Propeller: Fundamentos · Página 97 Práctica de Objetos En la parte derecha inferior de la ventana de la Terminal Serial Parallax hay botones de control que: • • • • Muestran y editan preferencias (Prefs) Limpian la ventana de la terminal (Clear) Detienen el desplegado de datos de entrada (Pause) Habilitan o Deshabilitan la conexión al Puerto serial Parallax (Disable/Enable) Figura 6-9: Terminal Serial Parallax Ventana de Transmision Ventana de Recepcion El botón para habilitar/deshabilitar en la Terminal Serial Parallax en la parte inferior derecha es importante. (Vea la Figura 6-10). Cuando despliega Disable significa que la terminal está conectada al puerto serial. Cuando presiona el botón Disable la terminal serial Parallax libera el puerto serial para que la herramienta lo pueda usar y cargar un programa en el chip Propeller. Mientras que la Terminal Serial esta deshabilitada el botón muestra Enable. Después que cargo el programa usted puede presiona el botón Enable para regresar a la comunicación entre la Terminal y el chip Propeller. Programar automáticamente Habilitar/Deshabilitar L En Prefs → Serial Port Selection por defecto las opciones Automatically Disable y Wait for Busy están seleccionadas. Con estos parámetros usted puede presionar en el programa de la herramienta Propeller, cargar un programa e inmediatamente presionar el botón Enable para reconectar. No hay necesidad de presionar Disable antes de cambiar la herramienta a carga de programa porque la Terminal Parallax se desconectara automáticamente tan pronto como usted presione otra ventana. De igual forma usted no tiene que esperar a terminar de cargar el programa antes de presionar Enable. Usted puede presionarlo tan pronto ha comenzado a cargar el programa y la Terminal Serial Parallax detecta que el puerto serial aun está ocupado y espera a que la herramienta Propeller termine de cargar el programa antes de reconectarse. Figura 6-10: Conectado vs. Desconectado (al/del el Puerto de Comunicación) Conectado al Puerto serial y comunicandose con el chip Propeller. Desconectado del Puerto Serial para que la herramienta Propeller pueda cargar el programa. Pagina 98 · Kit Educativo de Prácticas Propeller: Fundamentos 6: Práctica de Objetos Usted puede presionar en el botón Prefs de la terminal serial Parallax para ver la apariencia y tabuladores mostrados en la Figura 6-11. Las preferencias Appearance le permiten definir los colores, letras y otros formatos. Las preferencias Fuction le permiten seleccionar funciones especiales para caracteres ASCII no imprimibles. Deje todo seleccionado para estas prácticas ya que los usaremos para limpiar pantallas, mostrar regresos, etc… Figura 6-11: Preferencias de Apariencia y Funciones Lo mejor es dejar todo seleccionado en ambas categorías. La característica Automatically Disable hace que la Terminal Parallax este deshabilitada automáticamente para liberar el puerto serie para cargar el programa cada vez que presione la herramienta Propeller. Wait for busy port… hace que la Terminal Parallax espere hasta 10 segundos si presiona el botón Enable antes de que la herramienta Propeller haya terminado de cargar el programa. (No hay problema con Load RAM (F10) pero Load EEPROM (F11) puede tomar algunos segundos). Si estas características no fueron seleccionadas usted tendrá que presionar manualmente Disable antes de cargar un programa y esperar a que el programa termine de cargar antes de presionar Enable para reconectar. Cuando deshabilitar el parámetro Automatically disable…: El parámetro Automatically disable… es muy conveniente para modificar el código con la Herramienta Propeller y observar los resultados en la Terminal Serial Parallax. EL evento que dispara el automático Disable es el hecho de que usted presione en otra ventana L Digamos que en vez de estar cambiando de ida y vuelta entre la Terminal Parallax y algún otro programa tal como una hoja de datos para análisis de medición de un sensor con el parámetro Automatically disable… cada vez que presione en otra ventana la Terminal Serial automáticamente se desconecta del puerto serial y cualquier mensaje enviado por el chip Propeller no se mantendrá o mostrara. Para hacer que la Terminal Parallax mantenga la conexión del Puerto serial mientras usted trabaja con otra ventana deshabilite el parámetro Automatically disable… Así la terminal Parallax se mantendrá conectada puerto serial y continuara mostrando los mensajes actualizados independientemente de en que ventana este trabajando. Tenga en cuenta que con este parámetro no seleccionado usted tendrá que presionar manualmente el botón Disable antes de cargar un programa y Enable después de que el programa se cargo. El botón de edición de puertos en la Figura 6-11 abre la lista de puertos serial. Usted puede mover entradas en la lista arriba y abajo para cambiar el orden en el que aparecen en el menú de la terminal Parallax. Usted también puede presionar con el botón derecho para incluir o excluir la entrada o incluso crear reglas para incluir o excluir puertos basado en el texto de la columna de descripción. Kit Educativo de Practicas Propeller: Fundamentos · Página 99 Práctica de Objetos Mensajes de Prueba en la Terminal Serial Parallax La Figura 6-12 muestra la aplicación HelloFullDuplexSerial en la izquierda y los mensajes repetidos que envía a la Terminal Serial Parallax en la derecha. El programa HelloFullDuplexSerial declara el objeto FullDuplexSerial y usa sus metodos para enviar mensajes a la terminal Parallax. Primero llama al método start del objeto FullDuplexSerial con start y luego repetidamente llama el método str (string) con Debug.str en un ciclo repeat. Vamos a probar primero y luego ver más de cerca al objeto FullDuplexSerial, sus características y métodos. Figura 6-12: Usando el objeto FullDuplexSerial para mostrar mensajes en la terminal Parallax La primera vez que abre la Terminal Serial Parallax (PST.exe) necesitara programar (Com Port) igual que el utilizado por la herramienta Propeller para cargar programas en el chip Propeller. También tendrá que seleccionar el Baud Rate igual al que usa el programa Spin. Después de eso solo cargue la característica Load EEPROM de la herramienta Propeller para cargar el programa en la EEPROM del chip Propeller y presione el botón Enable de la Terminal Serial Parallax para ver los mensajes 3 Abra HelloFullDuplexSerial.spin con la Herramienta de Programación Propeller 3 Abra la Terminal Serial Parallax (presione dos veces en PST.exe para correrlo) 3 Conecte la batería a su Plataforma PE y verifique que está conectada a la computadora con el cable USB. 3 En la herramienta Propeller presione Run, y seleccione Identify Hardware… (F7). Tome nota del COM port donde se encontró el chip Propeller. 3 Introduzca el COM port en el campo de la izquierda inferior de la Terminal Parallax, asegúrese que es el mismo que encontró en el paso anterior. 3 Verifique el parámetro baudrate en la llamada a método Debug.start para encontrar la velocidad de transmisión (Actualmente es 57600). 3 Coloque la velocidad de transmisión en la terminal Parallax para que sean iguales (a 57600). 3 En la herramienta Propeller use F11 para cargar HelloFullDuplexSerial.spin en la EEPROM del chip Propeller. 3 En la Terminal Parallax presione el botón Enable para iniciar el desplegado de mensajes del chip Propeller. Pagina 100 · Kit Educativo de Prácticas Propeller: Fundamentos 6: Práctica de Objetos ''HelloFullDuplexSerial.spin ''Prueba de mensaje a la Terminal Serial Parallax. CON _clkmode = xtal1 + pll16x _xinfreq = 5_000_000 OBJ Debug: "FullDuplexSerial" PUB TestMessages ''Envia mensajes de prueba a la Terminal Serial Parallax. Debug.start(31, 30, 0, 57600) repeat Debug.str(string("This is a test message!", 13)) waitcnt(clkfreq + cnt) ¡NOTA IMPORTANTE CUANDO EL CHIP PROPELLER NO ESTE CONECTADO A LA COMPUTADORA! Si el chip Propeller está corriendo una aplicación pero no está conectado a la Computadora el código que intenta enviar mensajes a la Computadora puede ocasionar que el chip se reinicie por el convertidor Serial a USB ! El convertidor USB serial normalmente toma su corriente del Puerto USB. Si el convertidor USB-Serial esta desconectado del puerto USB su chip convertidor FTDI USB-serial deberá estar apagado. Sin embargo si el Propeller intenta enviar mensajes a la Computadora la señal de voltaje puede proporcionar suficiente potencia para alimentar el chip FTDI brevemente. Cuando esto sucede una de las primeras cosas que hace es activar la línea DTR que en su turno reinicia el chip Propeller. La solución para la versión DIP 40-Pin del kit PE es simple. Solo desconecte el Propeller de su conector de 4 pins para remover el convertidor serial del sistema. Esto previene la intención de enviar cualquier mensaje inadvertidamente a una Computadora ocasionando que el chip FTDI reinicie el chip Propeller. Debido a que el modulo PropStick USB tiene su convertidor USB-Serial FTDI integrado requiere de una solución diferente. Antes de correr alguna aplicación que no está conectada a la Computadora con el cable USB asegúrese de remover todo el código que intente enviar mensajes a la Computadora. Esto previene que la aplicación misteriosamente se reinicie cuando la Plataforma PE no está conectada a la Computadora. Cambiando Velocidad de Transmisión Si la velocidad de transmisión es la misma usted puede seleccionar la velocidad que mejor funcione para su aplicación. Por ejemplo usted puede cambiar la velocidad de 57.6 a 115.2 kbps como sigue: 3 En la herramienta Propeller modifique la llamada a método start del objeto HelloFullDuplexSerial para que pase el valor de 115200 al parámetro baudrate del método start del objeto FullDuplexSerial como sigue: Debug.start(31, 30, 0, 115200) 3 3 3 3 3 Cargue la versión modificada de HelloFullDuplexSerial en el chip Propeller. Escoja 115200 en la Terminal Serial Parallax del menú Baud Rate. Presione el botón Enable en la Terminal Serial Parallax Verifique que con la nueva velocidad los mensajes aun se muestran en pantalla. Asegúrese de cambiar los parámetros de regreso a 57600 en ambos programas y antes de continuar asegúrese que aun trabajan. Kit Educativo de Practicas Propeller: Fundamentos · Página 101 Práctica de Objetos FullDuplexSerial y otros objetos de la Librería El objeto FullDuplexSerial simplifica mayormente el intercambio de datos entre el Propeller y componentes Periféricos que se comunican con protocolos seriales asíncronos como RS232. Solo unos ejemplos de equipos que pueden conectarse al Propeller incluyen Computadoras, otros micro controladores, módems, el LCD Parallax y el modulo Pink Ethernet. L Comunicación Serial: Para mayor información acerca de comunicación serial asíncrona vea los artículos de Comunicación Serial y RS232 en Wiki pedía. Serial-sobre-USB: Para mayor información acerca de la forma en la que el chip FT232 en el Propeller Plug y el ProStick USB envía datos seriales sobre una conexión USB vea la versión de Programación y Prueba del PropStick USB. Como se menciono anteriormente un código en un objeto puede declarar otro objeto si: • • Los dos objetos están en la misma carpeta El objeto a ser declarado esta en la misma carpeta que la Herramienta Propeller El objeto en la misma carpeta con la herramienta Propeller es llamado Liberia de objetos. Para ver el contenido de la librería Propeller: 3 Presione en el menú entre la esquina superior izquierda y la mitad la ventana como se muestra en la Figura 6-13 y seleccione Propeller Library. Los objetos de la librería propeller aparecerán en la ventana baja de la izquierda. Note que en la Figura 6-13 el icono siguiente a FullDuplexSerial en la herramienta esta de color azul en vez de amarillo. Esto indica que es un archivo residente de la librería Propeller. Usted también puede ver estos archivos usando el Explorador de Windows. Asumiendo una instalación por defecto la ruta deberá ser C:\Program Files\Parallax Inc\Propeller Tool v1.2. Figura 6-13: Código que declara una Librería Objeto Cuando usa una librería objeto la primera tarea es examinar sus lineamientos para saber acerca de sus métodos y que puede hacer. 3 Presione dos veces sobre FullDuplexSerial en la herramienta propeller localizado en la parte baja izquierda, con esto usted podrá ver el contenido de la librería Propeller 3 Cuando la herramienta Propeller abre el objeto FullDuplexSerial presione el botón de Documentación para ver lo mostrado en la Figura 6-14. Pagina 102 · Kit Educativo de Prácticas Propeller: Fundamentos 6: Práctica de Objetos 3 Verifique la lista de métodos en la sección Interface del objeto “FullDuplexSerial” 3 Baje el cursor y encuentre la documentación para el método start y str y examínelos. Se usaran en el siguiente ejemplo. Figura 6-14: Vistas de Documentación del Objeto FullDuplexSerial El objeto HelloFullDuplexSerial en la Figura 6-13 declara el objeto FullDuplexSerial dándole el apodo Debug. Entonces llama el método start del objeto FullDuplexSerial con el comando Debug.start(31, 30, 0, 57600). De acuerdo a la documentación programa los parámetros de E/S rxpin al pin 31, txpin al 30, mode en 0, y baudrate a 57600. Después de eso un ciclo repeat envía el mismo mensaje de texto a la Terminal Parallax cada segundo. El método Debug.str es el que transfiere la cadena "This is a test message!" a la memoria temporal. Después de eso FullDuplexSerial se encarga de enviar cada carácter sucesivamente en la cadena del chip FT232 el cual lo reenvía a la computadora a través del USB. Veamos más de cerca Debug.str(string("This is a test message!", 13)). Primero Debug.str llama al método str del objeto FullDuplexSerial. La declaración del método para el método str indica que el parámetro esperado deberá ser un puntero de cadena. Al compilar la directiva string("This is a test message!") almacena el valor que corresponde a los caracteres en el mensaje de texto en la memoria de programa del chip Propeller y los anexa con un cero para terminar la cadena. Aun si la documentación del método str no lo incluye (En realidad debería!) espera un cero para terminar la cadena para que pueda obtener y transmitir caracteres hasta encontrar un cero. Mientras está corriendo la directiva string regresa la dirección de inicio de la cadena. Debug.str pasa este parámetro al método str del objeto FullDuplexSerial. Entonces el método str envía caracteres hasta que ve un cero que lo finaliza. Kit Educativo de Practicas Propeller: Fundamentos · Página 103 Práctica de Objetos L Que hace el 13? El 13 en Debug.str(String("This is a test message!", 13)) es un caracter especial que hace que la Terminal Parallax coloque un salto. Es por eso que “This is a text message!” aparece cada vez en su propia línea ya que el mensaje previo fue enviado con un salto. Vea la Figura 6-11 para ver la lista de caracteres de control de la Terminal Serial Parallax. Usted puede ver dónde queda almacenada la cadena en el programa con ayuda de la ventana de Información de la herramienta Propeller. 3 Mientras ve el objeto HelloFullDuplexSerial con la herramienta Propeller presione Run y luego Compile Current y seleccione View Info (F8). Debe aparecer la ventana de información que se muestra en la Figura 6-15. 3 Observe el texto en la columna de la derecha en la línea 4 y 5. El código hexadecimal ASCII ocupa las direcciones de memoria 0038 a 004F con el terminador 0 en la dirección 50. Figura 6-15: Encontrando una Cadena de Texto en Memoria Vista amplia debajo. Desplegando valores Observe nuevamente el objeto FullDuplexSerialen modo de documentación. (Vea la Figura 6-14 en la página 101). Observe que también tiene un método dec para mostrar números decimales. Este método toma un valor y lo convierte al carácter que representa el valor antes de transmitirlos serialmente a la Terminal Parallax. Es usado especialmente para mostrar lecturas de sensores y valores almacenados por variables para depurar programas. 3 Modifique la declaración del mensaje del objeto HelloFullDuplexSerial agregando una declaración local variable: PUB TestMessages | counter 3 Modifique el ciclo repeat del objeto HelloFullDuplexSerial como se muestra: repeat Debug.str(String(13, "counter = ")) Debug.dec(counter++) waitcnt(clkfreq/5 + cnt) 3 Use la herramienta Propeller para cargar la versión modificada de HelloFullDuplexSerial en la EEPROM del chip Propeller (F11). Pagina 104 · Kit Educativo de Prácticas Propeller: Fundamentos 6: Práctica de Objetos 3 Presione en el botón Enable de la Terminal Serial Parallax y verifique que el valor actualizado de counter se muestra varias veces cada segundo. Usted puede presionar y soltar el botón de reinicio para empezar a contar desde 0 nuevamente. Enviando valores de la Terminal Serial Parallax al chip Propeller El objeto FullDuplexSerial no tiene un método equivalente GetDec para complementar dec. Así que no se puede usar FullDuplexSerial para recibir un valor de la Terminal Parallax. Junto con los archivos .spin está incluida una versión modificada de FullDuplexSerial con el nombre de FullDuplexSerialPlus. El objeto FullDuplexSerialPlus tiene los mismos métodos que FullDuplexSerial y otros mas como GetDec, GetBin, y GetHex. Los métodos adicionales pueden utilizarse para recibir la representación de caracteres decimales, hexadecimales y números binarios desde la Terminal Serial Parallax, convertirlos a sus valores numéricos y almacenarlos en variables. Como FullDuplexSerialPlus también tiene los mismos métodos que FullDuplexSerial llamadas como Debug.start, Debug.str, y Debug.dec siguen dando el mismo resultado. L FullDuplexSerialPlus Está incluido en la descarga de Practicas PE (Ver página 17) y una lista completa del código se proporciona en el apéndice A: Lista de Códigos de Objetos en la página 191. Recuerde que un objeto puede declararse siempre y cuando este en la misma carpeta de los objetos a los que se está referenciando o en la misma carpeta que se encuentra la Herramienta Propeller. En este caso el objeto FullDuplexSerialPlus está en la misma carpeta con los objetos de esta práctica. Así, puede ser declarado en el bloque de objetos padres OBJ casi de la misma forma que se declaro FullDuplexSerial. La única diferencia es que el objeto padre usa un nombre diferente. Así que en vez de usar la declaración Debug : FullDuplexSerial se usa Debug : FullDuplexSerialPlus. 3 Abra ambos objetos FullDuplexSerial y FullDuplexSerialPlus en modo de documentación. 3 Use la línea para observar cuales métodos se agregaron – hay 6 y los nombres de métodos están en mayúsculas. 3 Verifique la documentación para los nuevos métodos. Los comentarios para los otros métodos se extendieron también, obsérvelos también. Aplicación de prueba – EnterAndDisplayValues.spin El objeto EnterAndDisplayValues espera para que usted introduzca un valor en la ventana de transmisión de la terminal Parallax. Convierte el carácter a su valor equivalente numérico y lo muestra en formatos decimal, hexadecimal y binario. Figura 6-16: Probando Valores de Entrada La Figura 6-16 muestra un objeto de prueba EnterAndDisplayValues con la Terminal Parallax. El objeto hace que el chip Propeller envíe un cursor que se muestra en la ventana de recepción de la Kit Educativo de Practicas Propeller: Fundamentos · Página 105 Práctica de Objetos Terminal. Después de teclear un valor decimal en la ventana de transmisión y presionar Enter el chip Propeller convierte la cadena de caracteres su valor correspondiente, lo almacena en una variable y luego usa el objeto FullDuplexSerialPlus para enviarlo de regreso en su representación decimal, hexadecimal y binaria. 3 Cargue EnterAndDisplayValues.spin en la EEPROM (F11) e inmediatamente presione el botón Enable de la Terminal Propeller. 3 La aplicación de dará dos segundos para conectar la Terminal Parallax al presionar el botón Enable. Si usted no ve el mensaje “Enter a decimal value:” quizá no presiono a tiempo el botón Enable. Usted puede reiniciar la aplicación presionando el botón de reinicio de la plataforma PE. Usted también puede reiniciar el chip Propeller al seleccionar y deseleccionar la línea DTR. 3 Haga lo que pide el mensaje de la terminal Propeller. Comience con 131071 y verifique que muestra los valores que ve en la Figura 6-16. El Propeller representa números negativos con complementos dos de 32 bits. Las variables long del chip almacenan 32 bits como valores enteros de -2,147,483,648 a 2,147,483,647. 3 Ingrese estos valores: 4, 3, 2, 1, 0, -1, -2, -3, -4, -5, y discierna el patrón de complemento dos. 3 Intente ingresar 2,147,483,645, 2,147,483,646, y 2,147,483,647 examine los valores de sus equivalentes en valores hexadecimales y binarios. 3 También intente con -2,147,483,646, -2,147,483,647, y -2,147,483,648. '' Archivo: EnterAndDisplayValues.spin '' Mensajes de/al chip Propeller con Terminal Serial Parallax. Pide que ingrese un valor y muestra el valor en formatos decimal, binario y hexadecimal. CON _clkmode = xtal1 + pll16x _xinfreq = 5_000_000 OBJ Debug: "FullDuplexSerialPlus" PUB TwoWayCom | value ''Prueba la Terminal Serial Parallax ingresa un numero y muestra. Debug.start(31, 30, 0, 57600) waitcnt(clkfreq*2 + cnt) Debug.tx(16) repeat Debug.Str(String("Enter a decimal value: ")) value := Debug.getDec Debug.Str(String(13, "You Entered", 13, "--------------")) Debug.Str(String(13, "Decimal: ")) Debug.Dec(value) Debug.Str(String(13, "Hexadecimal: ")) Debug.Hex(value, 8) Debug.Str(String(13, "Binary: ")) Debug.Bin(value, 32) repeat 2 Debug.Str(String(13)) Pagina 106 · Kit Educativo de Prácticas Propeller: Fundamentos 6: Práctica de Objetos Debug.dec vs. Debug.getDec El método GetDec del objeto FullDuplexSerialPlus guarda los caracteres que recibe de la Terminal Serial Parallax hasta que presiona la tecla Enter. Convierte el carácter en su correspondiente valor decimal y regresa ese valor. El comando del objeto EnterAndDisplayValues value := Debug.GetDec copia el resultado de la llamada de método GetDec a la variable value. El comando Debug.Dec(value) muestra el valor en formato decimal. El comando Debug.Hex(value, 8) muestra el valor en formato hexadecimal de 8 caracteres y el comando Debug.Bin(value, 32) lo muestra en formato binario de 32 caracteres. Conteo de Caracteres Hex y Bin Si solo va a mostrar palabras positivas o variables de tamaño byte, no hay razón para mostrar todos los 32 bits de valores binarios. Como las palabras variables tienen 16 bits y las variables byte solo tienen 8 bits no tiene sentido mostrar los 32 bits cuando se examinan esas variables más pequeñas. 3 Haga una copia de EnterAndDisplayValues y cambia el comando Debug.Bin(value, 32) a Debug.Bin(value, 16). 3 Remueva la variable local | value de a declaración del método TwoWayCom (recuerde que las variables locales son arreglos de 32 bits, las variables globales pueden ser declaradas como long, Word o byte). 3 Agregue un bloque VAR al objeto y declare value como palabra (Word) variable. 3 Corra el programa ingresando los valores de 0 a 65535. 3 Que sucede si ingresa 65536, 65537 y 65538? Intente repetir esto con el objeto no modificado para ver los bits faltantes. Cada digito hexadecimal toma 4 bits. De esta forma tomara 4 dígitos mostrar todos los valores posibles en una palabra variable (16 bits). 3 Modifique la copia EnterAndDisplayValues para que solo muestre 4 dígitos hexadecimales. Pantalla de Estado de Pin E/S La pantalla de la Terminal Serial Parallax proporciona un medio conveniente para probar sensores y asegurarse que el programa y cableado están correctos. El objeto DisplayPushbuttonsmuestra los valores almacenados en ina[23..21] en formato binario como muestra la Figura 6-17. Un 1 en una ranura especial indica que se presiono un botón; un 0 indica que no se presiono. La Figura 6-17 muestra un ejemplo donde P23 y P21 se presionan. Figura 6-17: Pantalla del estado del Botón en la Terminal Serial El objeto DisplayPushbuttons utiliza el comando Debug.Bin(ina[23..21], 3) para mostrar el estado del botón. Recuerde de la práctica de E/S y tiempo que ina[23..21] regresa el valor almacenado en bits de los registros ina 23 al 21. Este resultado pasa como un parámetro al método bin del objeto Kit Educativo de Practicas Propeller: Fundamentos · Página 107 Práctica de Objetos FullDuplexSerialPlus con el comando Debug.bin(ina[23..21], 3). Note que como solo hay 3 bits para mostrar el parámetro bits del método bin es 3 lo que en su turno hace que el método muestre solo 3 dígitos binarios. El objeto FullDuplexSerialPlus está corriendo en un controlador serial en otro cog y es posible transferir mensajes más rápido de lo que se le permite. El comando waitcnt(clkfreq/100 + cnt) marca el paso al actualizar los valores cada 1/100 de segundo para evitar el sobre flujo. 3 Use la herramienta Propeller para cargar el objeto DisplayPushbuttons.spin en EEPROM (F11) e inmediatamente presione el botón Enable. Nuevamente, si usted no lo presiona en los 2 segundos después de la descarga solo presione el botón de reinicio de la plataforma PE para reiniciar el programa. 3 Presione y suelte varias combinaciones de P23..P21 y verifique que se actualiza el valor en pantalla cuando se presionan. {{ DisplayPushbuttons.spin Muestra el estado del botón en la Terminal Serial Parallax. Botones ────────────────────────────────────────────────────────── 3.3 V 3.3 V 3.3 V │ │ │ ┤ Botón ┤ Botón ┤ Botón │ │ │ P21 ──┫ P22 ──┫ P23 ──┫ │ │ │ 10 kω 10 kω 10 kω │ │ │ GND GND GND ────────────────────────────────────────────────────────── }} CON _clkmode = xtal1 + pll16x _xinfreq = 5_000_000 OBJ Debug: "FullDuplexSerialPlus" PUB TerminalPushbuttonDisplay ''Lee el estado de los botones P23 a P21 y los muestra en la Terminal Serial Parallax. Debug.start(31, 30, 0, 57600) waitcnt(clkfreq*2 + cnt) Debug.tx(Debug#CLS) Debug.str(String("Pushbutton States", Debug#CR)) Debug.str(String("-----------------", Debug#CR)) repeat Debug.tx(Debug#CRSRX) Debug.tx(0) Debug.Bin(ina[23..21], 3) waitcnt(clkfreq/100 + cnt) Pagina 108 · Kit Educativo de Prácticas Propeller: Fundamentos 6: Práctica de Objetos Accesando constantes en objetos con ObjectNickname#OBJECT_CONSTANT Quizá ha notado que la expresión Debug#CR reemplaza el numero 13 para enviar un salto. (Vea el lado izquierdo de la Figura 6-18). Eso es porque los caracteres constantes de control para la Terminal Serial Parallax son declarados en el objeto FullDuplexSerialPlus. Usted puede verlos en la documentación del objeto FullDuplexSerialPlus en la derecha de la Figura 6-18. En vez de usar los números o declararlos por segunda vez en el objeto superior DisplayPushbuttons usa el registro ObjectNickname#OBJECT_CONSTANT para especificar caracteres de control que se envían a la Terminal Serial Parallax. 3 Examine el objeto FullDuplexSerialPlus en ambos modos; documentación y fuente completa. 3 Tome nota de como se declaran las constantes y como son documentadas con comentarios de doble apostrofe. Figura 6-18: DisplayPushbuttons Completa (izq.), DisplayPushbuttons Documentación (der.) Terminal LED Output Control Es importante durante los prototipos probar varios actuadores. El objeto TerminalLedControl demuestra que es conveniente probar varios estados de salidas para probar diferentes circuitos. (Ver Figura 6-19). Mientras este ejemplo usa indicadores LED, los pins de señales de salida pueden así de fácil enviarse a otros pins de entrada de chips, salidas a circuitos que controlan salidas de alta corriente tales como solenoides, relevadores, motores DC, calentadores, lámparas, etc. Figura 6-19: Ingresando patrones binarios que controlan estados de E/S El comando outa[9..4] := Debug.GetBin llama al método GetBin del objeto FullDuplexSerialPlus. EL método regresa el valor correspondiente a los caracteres binarios (unos y ceros) que usted ingreso en la ventana de transmisión de la Terminal Parallax. El valor que el método GetBin regresa se asigna a outa[9..4], lo cual hace encender el LED correspondiente. Kit Educativo de Practicas Propeller: Fundamentos · Página 109 Práctica de Objetos 3 Cargue TerminalLedControl.spin en la EEPROM (F11) e inmediatamente presione el botón Enable de la Terminal Parallax. 3 Intente ingresar los valores mostrados en la Figura 6-19 en la ventana de transmisión y verifique que el LED correspondiente se enciende. {{ TerminalLedControl.spin Ingresa el estado del LED en la Terminal Parallax. El Propeller chip recibe el estado y enciende las luces del LED correspondiente. LED SCHEMATIC ────────────────────── (todos) 100 ω LED P4 ──────────┐ │ P5 ──────────┫ │ P6 ──────────┫ │ P7 ──────────┫ │ P8 ──────────┫ │ P9 ──────────┫ GND ────────────────────── }} CON _clkmode = xtal1 + pll16x _xinfreq = 5_000_000 OBJ Debug : "FullDuplexSerialPlus" PUB TerminalLedControl ''Limpia o Activa el estado del Pin de salida basado en patrones binarios ''ingresados en la Terminal Serial Parallax. Debug.start(31, 30, 0, 57600) waitcnt(clkfreq*2 + cnt) Debug.tx(Debug#CLS) dira[4..9]~~ repeat Debug.Str(String("Enter 6-bit binary pattern: ")) outa[4..9] := Debug.getBin El Bloque DAT y Paso de Direcciones Uno de los usos de bloque DAT es para almacenar secuencias de valores (incluyendo caracteres). Especialmente para mensajes más largos y diseños de menús, manteniendo todos los mensajes en un bloque DAT puede hacer más conveniente que usar string("...")en el código. Pagina 110 · Kit Educativo de Prácticas Propeller: Fundamentos 6: Práctica de Objetos L El Bloque DAT puede usar separa almacenar lenguaje ensamblador que se inicializa en un cog. Por ejemplo observe FullDuplexSerial en vista de modo completo. Debajo del bloque DAT del siguiente ejemplo, TestMessages note como cada línea tiene una etiqueta, un tamaño y una secuencia de valores (caracteres en este caso) DAT MyString MyOtherString byte byte "Este es un mensaje de prueba numero:", 0 ", ", Debug#CR, "y este es otro mensaje de línea de texto.", BlankLine byte Debug#CR, Debug#CR, 0 0 Recuerde que la directiva string regresa la dirección inicial de la cadena así que el método str del objeto FullDuplexSerial puede comenzar a enviar caracteres y luego terminar cuando encuentra un cero que lo termina. Con los bloques DAT el carácter de terminación tiene que ser ingresado manualmente. El nombre de una directiva de bloque DAT hace posible pasar la dirección inicial de la secuencia usando el operador @. Por ejemplo @MyString regresa la dirección del primer carácter en la secuencia MyString. Por lo que Debug.str(@myString) comenzara a obtener y transmitir caracteres a la dirección del primer caracter en MyString, y se detendrá cuando obtenga el 0 que sigue de los caracteres "…number: ". 3 Cargue el objeto TestMessages.spin en la EEPROM (F11), y presione inmediatamente el botón Enable en la Terminal Serial Parallax 3 Verifique que los tres mensajes se muestran cada segundo. '' TestMessages.spin '' Envía mensajes de texto almacenados en el bloque DAT de la Terminal. CON _clkmode = xtal1 + pll16x _xinfreq = 5_000_000 OBJ Debug: "FullDuplexSerialPlus" PUB TestDatMessages | value, counter ''Envía mensajes almacenados en el bloque DAT. Debug.start(31, 30, 0, 57600) waitcnt(clkfreq*2 + cnt) Debug.tx(Debug#CLS) repeat Debug.Str(@MyString) Debug.Dec(counter++) Debug.Str(@MyOtherString) Debug.Str(@BlankLine) waitcnt(clkfreq + cnt) DAT MyString MyOtherString BlankLine byte byte byte "Este es el mensaje de prueba: ", 0 ", ", Debug#CR, "y esta es otra línea de texto.", 0 Debug#CR, Debug#CR, 0 Expandiendo la sección DAT y Accesando sus Elementos Aquí hay una sección DAT modificada. El mensaje de texto tiene diferente contenido y diferentes etiquetas. Además hay un ValueList con elementos long en vez de elementos byte. Kit Educativo de Practicas Propeller: Fundamentos · Página 111 Práctica de Objetos DAT ValTxt ElNumTxt ValueList BlankLine byte byte long byte Debug#CR, "El valor es: ", 0 ", ", Debug#CR, "y su elemento #: ", 0 98, 5282, 299_792_458, 254, 0 Debug#CR, 0 Usted puede accesar elementos individuales en la lista con long, Word, o byte. Por ejemplo, long[@ValueList] regresara el valor 98, el primer long. Hay también una contraparte que puede agregarse en un segundo corchete para accesar elementos sucesivos en la lista. Por ejemplo: value := long[@ValueList][0] value := long[@ValueList][1] value := long[@ValueList][2] ' copia 98 a la variable value ' copia 5282 a la variable value ' copia 299_792_458 a la variable value Las palabras long, Word, y byte tienen diferentes usos en diferentes tipos de bloques. L En bloques VAR, long, Word y byte pueden usarse para declarar tres tamaños diferentes de variables. En bloques DAT, long, Word, y byte pueden usarse para declarar el elemento de tamaño de la lista. En métodos PUB y PRI, long, Word, y byte se usan para recuperar valores de ciertas direcciones. 3 Haga una copia del objeto TestMessages y reemplace la sección DAT con la mostrada arriba. 3 Reemplace la sección PUB con la mostrada abajo. PUB TestDatMessages | value, index Debug.start(31, 30, 0, 57600) waitcnt(clkfreq*2 + cnt) Debug.tx(Debug#CLS) repeat repeat index from 0 to 4 Debug.Str(@ValTxt) value := long[@valueList][index] Debug.Dec(value) Debug.Str(@ElNumTxt) Debug.Dec(index) Debug.Str(@BlankLine) waitcnt(clkfreq + cnt) 3 Pruebe el objeto modificado con el chip Propeller y la Terminal Serial Parallax. Note como una variable index se usa en long[@ValueList][index] para regresar elementos sucesivos en ValueList. Los Objetos Float y FloatString Floating-point es la forma corta para punto decimal flotante y se refiere al valor que puede contener un punto decimal, precedido o seguido por números o dígitos. El formato de precisión (32-bit) punto flotante IEEE754 es soportado por la herramienta Parallax y por los objetos de las librerías Propeller Float y FloatString. Este formato usa un cierto número de bits en una variable de 32-bit para un número significativo, otros bits para almacenar exponente y otro para almacenar el valor del signo. Mientras los cálculos involucran dos valores de punto-flotante precisión-simple los valores no son tan precisos como los que involucran dos variables de 32-bit, es excelente cuando se tienen valores fraccionales a la derecha del punto decimal, incluyendo magnitudes de números grandes y pequeños. Por ejemplo variables long pueden manejar enteros de -2,147,483,648 a 2,147,483,647, los valores de punto-flotante precisión-simple pueden representar valores de entre ±3.403×1038 y ±1.175×10−38. Pagina 112 · Kit Educativo de Prácticas Propeller: Fundamentos 6: Práctica de Objetos Para esta práctica solo es importante conocer que la librería Propeller tiene objetos que pueden usarse para procesar valores de punto flotante. TerminalFloatStringTest demuestra algunas operaciones básicas de punto flotante. Primero a := 1.5 y b := pi usan la habilidad del programa Propeller para reconocer los valores de punto flotante para pre-asignar de 1.5 a la variable a y pi (3.141593) a b. Se usa el objeto FloatMath para agregar los valores de punto flotante almacenados por las variables a y b. Finalmente usa el objeto FloatString para mostrar el resultado que queda almacenado en c. 3 Cargue el objeto FloatStringTest.spin en la EEPROM (F11), e inmediatamente después presione el botón Enable de la Terminal Propeller. 3 Verifique que la ventana de recepción de la Terminal Parallax muestra 1.5 + Pi = 4.641593. ''FloatStringTest.spin ''Resuelve problema matemático de punto flotante y muestra el resultado ''en la Terminal Serial. CON _clkmode = xtal1 + pll16x _xinfreq = 5_000_000 OBJ Debug : "FullDuplexSerialPlus" fMath : "FloatMath" fString : "FloatString" PUB TwoWayCom | a, b, c ''Resuelve problema matemático de punto flotante y muestra el resultado Debug.start(31, 30, 0, 57600) Waitcnt(clkfreq*2 + cnt) Debug.tx(Debug#CLS) a := 1.5 b := pi c := fmath.FAdd(a, b) Debug.str(String("1.5 + Pi = ")) debug.str(fstring.FloatToString(c)) Objetos que usan Direcciones Variables Igual que los elementos en los bloques DAT las variables también tienen direcciones en RAM. Ciertos objetos son diseñados para iniciar con parámetros de direcciones variables. Frecuentemente corren en Cogs separados y actualizan su salida basándose en un valor almacenado en variables del objeto padre, o actualizan la variable del objeto padre basados en mediciones de datos de entrada, o ambos. AddressBlinker es un ejemplo de objeto que toma valores de las variables de su objeto padre. El método Start tiene parámetros para dos valores de direcciones, pinAddress y rateAddress. El objeto padre tiene que pasar al método Start del objeto AddressBlinker la dirección de una variable que almacena el numero de pin de E/S y otro que almacena el tiempo. El método Start transmite estos parámetros al método Blink a través de la llamada de método en el comando cognew. Así cuando el Kit Educativo de Practicas Propeller: Fundamentos · Página 113 Práctica de Objetos método Blink se inicia en un nuevo Cog también recibe copia de sus direcciones. Cada vez que el ciclo repeat del método Blink verifica los valores almacenados en las variables de su objeto padre con pin := long[pinAddress] y rate := long[rateAddress]. Observe que como pinAddress and rateAddress almacena la dirección el operador @ ya no se necesita. L Variables Globales vs. Locales : En este programa las variables pinAddress y rateAddressse pasan al método Start por el objeto padre como parámetros. EL método Start transmite estos valores al método Blink como parámetros también. Ambos métodos Start y Blink terminan con sus propias variables locales pinAddress y rateAddress porque las variables locales solo son accesibles por el método que las declara. Otra práctica común en hacer que el método Start copie parámetros que recibe de variables globales declaradas en el bloque de objeto VAR. Otros métodos en el objeto pueden leer de y escribir a estas variables globales según se necesite. Tenga en cuenta que diferentes Cogs pueden ejecutar código en diferentes métodos. Aun así ambos métodos pueden trabajar con variables globales de objetos. N ejemplo de esta práctica importante se demuestra en la siguiente practica Dentro del Objeto MonitorPWM en la pagina 167. 3 Examine el objeto AddressBlinker.spin y ponga atención a las relaciones que acabamos de discutir. '' Archivo: AddressBlinker.spin '' Ejemplo de administración de Cog que ve variables en su objeto padre VAR long stack[10] byte cog 'Cog stack space 'Cog ID PUB Start(pinAddress, rateAddress) : success ''Inicia un Nuevo proceso en un Cog Nuevo. Regresa True si tiene éxito. ''Parámetros: pinAddress - long dirección de la variable que almacena el pin E/S '' rateAddress - long dirección de la variable que almacena el tiempo Stop success := (cog := cognew(Blink(pinAddress, rateAddress), @stack) + 1) PUB Stop ''Detiene el proceso blinking, si existe. if Cog cogstop(Cog~ - 1) PRI Blink(pinAddress, rateAddress) | pin, rate, pinOld, rateOld pin rate pinOld rateOld := := := := long[pinAddress] long[rateAddress] pin rate repeat pin := long[pinAddress] dira[pin]~~ if pin <> pinOld dira[pinOld]~ !outa[pin] pinOld := pin rate := long[rateAddress] waitcnt(rate/2 + cnt) El objeto AddressBlinkerControl demuestra una forma de declarar variables asignando sus valores y pasando sus direcciones a un objeto que lo estará monitoreando, el objeto AddressBlinker en este Pagina 114 · Kit Educativo de Prácticas Propeller: Fundamentos 6: Práctica de Objetos caso. Después de pasar la dirección de sus variables pin y rateDelay al método Start de AddressBlinker el objeto AddressBlinker verifica estas variables entre cada cambio de estado de LED. Si el valor de pin o rateDelay ha cambiado, AddressBlinker detecta esto y actualiza de acuerdo a esto el pin LED o el tiempo de parpadeo. 3 Cargue el objeto AddressBlinkerControl.spin en la EEPROM (F11), y presione inmediatamente el botón Enable de la Terminal Parallax. 3 Ingreso los números de pins y retrasos de ciclos de reloj mostrados en la Figura 6-20 en la ventana de transmisión de la Terminal y verifique que la aplicación selecciona correctamente el LED y determina la frecuencia de parpadeo. Tan pronto como presione Enter el objeto AddressBlinker se actualizara basado en el nuevo valor almacenado en las variables pin o rateDelay del AddressBlinkerControl. Figura 6-20: Ingresando Pin y Tiempo en la Terminal Serial '' AddressBlinkerControl.spin '' Ingresa el estado del LED en la Terminal Parallax y lo envía al chip '' Propeller a través de la Terminal Serial Parallax CON _clkmode = xtal1 + pll16x _xinfreq = 5_000_000 OBJ Debug: "FullDuplexSerialPlus" AddrBlnk: "AddressBlinker" VAR long pin, rateDelay PUB UpdateVariables '' Actualiza variables que son observadas por el objeto AddressBlinker. Debug.start(31, 30, 0, 57600) waitcnt(clkfreq*2 + cnt) Debug.tx(Debug#CLS) pin := 4 Kit Educativo de Practicas Propeller: Fundamentos · Página 115 Práctica de Objetos rateDelay := 10_000_000 AddrBlnk.start(@pin, @rateDelay) dira[4..9]~~ repeat Debug.Str(String("Enter pin number: ")) pin := Debug.getDec Debug.Str(String("Enter delay clock ticks:")) rateDelay := Debug.getDec Debug.Str(String(Debug#CR)) Mostrando Direcciones En AddressBlinkerControl los valores de pin y rateDelay pueden mostrarse con Debug.Dec(pin) y Debug.Dec(rateDelay). Las direcciones de pin y rateDelay pueden mostrarse con Debug.Dec(@pin) y Debug.Dec(@rateDelay). 3 Inserte comandos que desplieguen las direcciones de las variables pin y rateDelay en la Terminal Parallax justo antes de que comience el ciclo repeat y muestre el valor de esas variables cada vez que se ingresan. Nota: El punto de este ejercicio en reforzar la distinción entre un contenido de variable y su dirección. Pasando Direcciones de Inicio a Objetos que trabajan con Lista de Variables Algunos objetos monitorean o actualizan listas de variables long de otro cog, en este caso, típicamente tienen documentación que explica el orden y tamaño de cada variable que el objeto padre necesita declarar. Este tipo de métodos Start de objetos típicamente solo esperan un valor, la dirección de inicio de la lista de variables en el objeto padre. El objeto hijo toma esa dirección y la usa para accesar el resto de la variables en el objeto padre. AddressBlinkerWithOffsets es un ejemplo de un objeto del que el método start espera la dirección de inicio de una lista de variables. Diferente a AddressBlinker su método Start solo recibe la dirección de la variable del objeto padre que almacena el valor pin. Su documentación requiere que la variable almacene el retraso de la frecuencia de parpadeo para ser declarada, sin variables extra. Como el parámetro baseAddress almacena la dirección de la variable de los objetos padre que almacena el numero de pin, long[baseAddress][0] almacenara este valor. En cambio long[baseAddress][1] accesara la variable que almacena la frecuencia de parpadeo. Así es como el programa obtiene ambos valores de variables con solo un parámetro de dirección. 3 Examine el objeto AddressBlinkerWithOffsets.spin. Note como su método start necesita un baseAddress que lo usa para encontrar variables en sus objetos padre que determinan el pin y el retraso en el parpadeo. 3 Considere como esto puede ser aplicado a listas más grandes de variables usando considerando direcciones. '' '' '' '' '' '' Archivo: AddressBlinkerWithOffsets.spin Ejemplo de cog que observa variables en sus objetos padres Objeto padre para declarar un long que almacena E/S LED y numero de pin seguido por un long que almacena el numero de ciclos de reloj entre cada cambio de estado de LED. Debe pasar la dirección del long que almacena el numero de pin E/S de LED al método Start. Pagina 116 · Kit Educativo de Prácticas Propeller: Fundamentos 6: Práctica de Objetos VAR long stack[10] byte cog 'Cog stack space 'Cog ID PUB Start(baseAddress) : success ''Inicia un nuevo parpadeo en un cog Nuevo; regresa True si tiene éxito. ''baseAddress...la dirección de la variable long que almacena el numero de pin LED. ''baseAddress + 1...la dirección de la variable long que almacena la frecuencia de parpadeo. Stop success := (cog := cognew(Blink(baseAddress), @stack) + 1) PUB Stop ''Detiene el proceso de parpadeo, si existe. if Cog cogstop(Cog~ - 1) PRI Blink(baseAddress) | pin, rate, pinOld, rateOld pin rate pinOld rateOld := := := := long[baseAddress][0] long[baseAddress][1] pin rate repeat pin := long[baseAddress][0] dira[pin]~~ if pin <> pinOld dira[pinOld]~ !outa[pin] pinOld := pin rate := long[baseAddress][1] waitcnt(rate/2 + cnt) Tenga en cuenta que el punto de este ejemplo es demostrar como un objeto padre puede pasar una dirección base a su hijo y la documentación requiere una lista de variables de tamaño especifico que tiene ciertos valores y son declarados en cierto orden. El objeto AddressBlinkerControlWithOffsets trabaja con el objeto AddressBlinkerWithOffsets de esta forma para desarrollar la misma aplicación que en el ejemplo previo, selección de LED y Frecuencia por Terminal. Manteniendo la documentación del objeto AddressBlinkerWithOffsets, AddressBlinkerControlWithOffsets declara una variable long para almacenar pin y la siguiente variable declara rateDelay. Así pasa la dirección de su variable pin al método Start del objeto AddressBlinkerControl. En este objeto la declaración de variables es long pin, rateDelay crucial. Si el orden de estas dos variables se intercambia la aplicación no trabaja bien. Esto es, nuevamente, porque el objeto AddressBlinkerWithOffsets espera recibir la dirección de una variable long que almacena el valor pin, y espera la siguiente variable long consecutiva para almacenar la variable rateDelay. Ahora, está bien declarar variables long antes y después de estas dos. Es solo que pin y rateDelay tienen que ser variables long y tienen que declararse en orden específico por AddressBlinkerWithOffsets. La dirección de inicio de la lista variable también tiene que pasarse al método start del objeto hijo, en este caso con AddrBlnk.start(@pin). Ponga atención en este alcance de los objetos que son diseñados para trabajar con listas de variables long en sus objetos padre. Kit Educativo de Practicas Propeller: Fundamentos · Página 117 Práctica de Objetos 3 Prueba AddressBlinkerControlWithOffsets y verifique que es idénticamente funcional a AddressBlinkerControl. 3 Examine como AddressBlinkerControlWithOffsets se diseña de acuerdo de la documentación del objeto AddressBlinkerWithOffsets. '' '' '' '' '' '' Archivo: AddressBlinkerControlWithOffsets.spin Otro ejemplo de administrador de cog que se basa en un objeto que observa variables en su objeto padre Este método Start solo pasa una dirección variable pero la usa como su ancla para dos variables que se monitorean por ''AddressBlinkerWithOffsets. CON _clkmode = xtal1 + pll16x _xinfreq = 5_000_000 VAR long pin, rateDelay OBJ Debug: "FullDuplexSerialPlus" AddrBlnk: "AddressBlinkerWithOffsets" PUB TwoWayCom ''Envía mensajes de prueba y valores la Terminal Serial Parallax. Debug.start(31, 30, 0, 57600) waitcnt(clkfreq*2 + cnt) Debug.tx(Debug#CLS) pin := 4 rateDelay := 10_000_000 AddrBlnk.start(@pin) dira[4..9]~~ repeat Debug.Str(String("Ingrese el numero de pin: ")) pin := Debug.getDec Debug.Str(String("Ingrese el retraso para 'rate':")) rateDelay := Debug.getDec Debug.tx(Debug#CR) Tiempo de Estudio Preguntas 1) ¿Cuáles son las diferencias entre llamar un método en el mismo objeto y llamar un método en otro objeto? 2) ¿Llamar a un método en otro objeto afecta la forma en que se pasan los parámetros y valores de regreso? 3) ¿Cuáles son los requerimientos de archivos que se tienen que satisfacer antes de que un objeto pueda declarar exitosamente otro objeto? Pagina 118 · Kit Educativo de Prácticas Propeller: Fundamentos 6: Práctica de Objetos 4) 5) 6) 7) 8) 9) 10) 11) 12) 13) 14) 15) 16) 17) 18) 19) 20) 21) 22) 23) 24) 25) 26) 27) ¿Donde se puede ver la cadena de comando en la aplicación? ¿Cómo se incluyen los comentarios en un objeto? ¿Cómo puede ver los comentarios de documentación del objeto mientras filtra el código? Por regla, ¿Que nombres de métodos se usan para iniciar métodos en nuevos cogs y detener los cogs? ¿Qué puede hacer si un objeto administra un proceso en un cog nuevo pero usted quiere iniciar más de una ocurrencia de ese proceso en cogs múltiples? ¿Cuál es el efecto neto de un método Start de objeto llamando su método Stop? ¿Cómo se ingresan caracteres especiales para esquemáticos, medidas, expresiones matemáticas y diagramas de tiempo en los comentarios de objeto? ¿Cuáles son las diferencias entre método público y privado? ¿Cómo se declaran múltiples copias de un objeto? ¿Donde se almacenan los objetos de Librerías Propeller? ¿Cómo se puede ver la información de un objeto? ¿En qué parte de RAM la directiva String hace que se almacene un código de carácter? ¿Por qué un cero de terminación de cadena es importante para el objeto FullDuplexSerial? ¿Que debe explicar el comentario de documentación de un objeto acerca de un método? ¿Cómo se pueden almacenar cadenas de caracteres aparte de la declaración String ¿Cuáles son los tres diferentes usos de las palabras clave long, Word y byte en el lenguaje Spin ¿Qué método usa el objeto Float para sumar dos números de punto flotante? ¿Qué método se usa para mostrar números de punto flotante como cadena de caracteres? ¿Es el comando a := 1.5 procesado por el objeto FloatMath? ¿Cómo se pasa una dirección de variable a un parámetro en un método de otro objeto? ¿Cómo puede pasar una dirección a un método de objeto reducir el número de parámetros? Dada una dirección de variable ¿Cómo un método de objeto accesa valores almacenados en esa variable y variables declaradas posteriormente? Dada una dirección ¿Puede un objeto monitorear un valor variable? Dada una dirección ¿Puede un objeto actualizar la variable en otro objeto usando esa dirección? Ejercicios 1) Dado el archive MyLedObject.spin, escriba una declaración para otro objeto la misma carpeta para que pueda usar sus métodos. Use el apodo led. 2) Escriba un comando que llame un método llamado on en un objeto apodado led. Este método requiere el parámetro pin (use 4). 3) Liste los valores decimales de los caracteres de la fuente Parallax que se requieren para escribir esta expresión en un comentario de documentación f = T. 4) Declare un método privado llamado calcArea que acepte parámetros height y width y regrese área. 5) Declare cinco copias de un objeto llamado FullDuplexSerial (el cual podría ser usado para cinco conexiones de comunicación seriales simultaneas bidireccionales) Use el apodo uart. 6) Llame el tercer método str del objeto FullDuplexSerial y envíe la cadena “Hola!!!”. Asuma el apodo uart. 7) Escriba un bloque DAT e incluya una cadena etiquetada Hi con la terminación de cadena cero “Hola!!!”. 8) Escriba un comando que calcule la circunferencia (c) de un círculo dado el diámetro (d). Asuma que el objeto FloatMath ha sido apodado f. 9) Dada la variable c, la cual almacena un valor de punto flotante pase esto a un método en FloatString que regresa la dirección de la representación de una cadena almacenada de un valor de punto flotante. Almacene esta dirección en la variable address. Asuma el apodo fst. Kit Educativo de Practicas Propeller: Fundamentos · Página 119 Práctica de Objetos Proyectos 1) TestBs2IoLiteObject usa llamadas de método similares a los comandos del lenguaje de programación del micro controlador BASIC Stamp. Este objeto necesita un objeto Bs2IoLite con métodos como high, pause, low, in, y toggle. Escriba un objeto que soporte estas llamadas a métodos usando las descripciones en los comentarios ''Archivo superior: TestBs2IoLiteObject.spin ''Enciende LED en P6 por 1 s, después parpadea LED P5 a 5 Hz cada ''que el botón P21 se mantiene presionado. OBJ stamp : "Bs2IoLite" PUB ButtonBlinkTime | time, index stamp.high(6) stamp.pause(1000) stamp.low(6) stamp.low(5) repeat if stamp.in(21) stamp.toggle(5) else stamp.low(5) stamp.pause(100) ' ' ' ' ' ' ' Programa P6 como salida-alta Retraso 1 s Programa P6 como salida-baja Programa P5 como salida-baja Repite (como DO...LOOP en PBASIC) Si se presiona P21 Cambia el estado de salida P5 ' Retrasa 0.1 s antes de repetir 2) Examine la longitud de de pila en la Librería Propeller, la longitud de pila en la carpeta Demo de la Librería Propeller. Haga una copia de longitud de pila Demo.spin, y modifíquela para probar el espacio de pila requerido para iniciar el método Blink del objeto Blinker (del inicio de ésta práctica) en un cog. Genere la conexión a la Terminal Serial Parallax basado en la documentación de StackLenthDemo para mostrar el resultado. NOTA: Las instrucciones para usar el objeto Stack Lenght están ocultas en los comentarios de TEORIA DE OPERACIÓN, los cuales son visibles en modo de vista. 3) Algunas aplicaciones tendrán un reloj corriendo en un cog para mantener el tiempo. Abajo esta una pantalla que se actualiza cada que el botón P23 de la plataforma PE se presiona y suelta Pagina 120 · Kit Educativo de Prácticas Propeller: Fundamentos 6: Práctica de Objetos La Terminal Parallax se actualice por el objeto de abajo TerminalButtonLogger.spin. Hay dos llamadas al objeto TickTock. La primer llamada es Time.Start(0, 0, 0, 0), que inicia las variables del objeto de TickTock day, hour, minute, y second. La segunda llamada de método es Time.Get(@days, @hours, @minutes, @seconds). Esta llamada de método pasa la dirección del objeto TickTock de las variables days, hours, minutes, y seconds del objeto TerminalButtonLogger. El objeto TickTock actualiza estas variables con el tiempo actual. La tarea en este proyecto es escribir el objeto TickTock que trabaje con el objeto TerminalButtonLogger. Asegúrese de usar la segunda técnica de conteo del método GoodTimeCount de la práctica de E/S y Tiempo. '' TerminalButtonLogger.spin '' Graba las veces que el botón conectado a P23 se presiona/suelta '' en la Terminal Serial Parallax. CON _clkmode = xtal1 + pll16x _xinfreq = 5_000_000 OBJ Debug Button Time : "FullDuplexSerialPlus" : "Button" : "TickTock" VAR long days, hours, minutes, seconds PUB TestDatMessages Debug.start(31, 30, 0, 57600) waitcnt(clkfreq*3 + cnt) Debug.tx(Debug#CLS) 'Inicia objeto FullDuplexSerialPlus. 'Espera tres segundos. Time.Start(0, 0, 0, 0) 'Comienza objeto TickTock e 'inicializa el día, hora, 'minuto y Segundo. 'Muestra instrucciones en 'La Terminal Serial Parallax Debug.Str(@BtnPrompt) repeat if Button.Time(23) ' Si se presiona el botón. ' Pasa variables al objeto ' TickTock para actualizar Time.Get(@days, @hours, @minutes, @seconds) DisplayTime ' Muestra el tiempo actual. PUB DisplayTime Debug.tx(Debug#CR) Debug.Str(String("Day:")) Debug.Dec(days) Debug.Str(String(" Hour:")) Debug.Dec(hours) Debug.Str(String(" Minute:")) Debug.Dec(minutes) Debug.Str(String(" Second:")) Debug.Dec(seconds) Kit Educativo de Practicas Propeller: Fundamentos · Página 121 Práctica de Objetos DAT BtnPrompt byte Debug#CLS, "Press/release P23 pushbutton periodically...", 0 Pagina 122 · Kit Educativo de Prácticas Propeller: Fundamentos 7: Práctica de Módulos Contadores y Aplicaciones de Circuitos 7: Módulos Contadores y Aplicaciones de Circuitos Introducción Cada Cog Propeller tiene dos Módulos Contadores y cada modulo contador puede configurarse para desarrollar tareas repetitivas independientemente. Así que el chip Propeller no solo tiene la habilidad de ejecutar código simultáneamente en cogs separados sino que cada cog puede también orquestar hasta dos procesos adicionales con módulos contadores mientras el cog continúa ejecutando comandos de programa. Los contadores pueden proporcionar una variedad de servicios como: • • • • • • • • Medir Pulsos y Tiempo de Decadencia Contar ciclos de señales y Medir Frecuencia Enviar señales de oscilador numéricamente controladas (NCO). Por ejemplo ondas cuadradas Enviar señales de ciclos de fase cerrada (PLL) las cuales pueden ser útiles para ondas cuadradas de mayor frecuencia Detección de limite de señal Conversiones Análogo Digital (A/D) Conversiones Digital Análogo (D/A) Proporcionar señales internas para generación de video Como cada modulo contador puede configurarse para desarrollar muchas de estas tareas en un tipo de “programe y olvide”, es posible para un Cog ejecutar un programa mientras al mismo tiempo hace cosas como generar tonos de bocina, controlar motores y servos, contar frecuencias de entrada y transmitir y/o medir voltajes análogos. Esta práctica proporciona ejemplos de cómo usar 10 de 32 modos contadores diferentes para desarrollar variaciones de 8 diferentes tareas: • • • • • • • • Medición de tiempo en Decadencia RC para potenciómetros y foto resistores. Conversión Digital Análoga para controlas luminosidad de LED Señales NCO para enviar tonos de bocina Señales NCO para IR modulada para objetos y detección de distancia Contar ciclos de tonos de bocina Detectar una transición de señal Control de Amplitud de Pulso Generar señales de alta frecuencia para detección de metal Un cog no tiene necesariamente que “programar y olvidar” un modulo contador. También puede dedicarse a procesar envolviendo módulos contadores haciendo cosas increíbles, incluyendo un número de aplicaciones de audio y video. Esta práctica incluye un ejemplo que demuestra este tipo de relación cog-contador aplicada a enviar múltiples señales PWM. Prerrequisitos de la Práctica • • • • Configuración y Pruebas E/S y Tiempo Métodos y Cogs Objetos Kit Educativo de Practicas Propeller: Fundamentos · Página 123 Práctica de Módulos Contadores y Aplicaciones de Circuitos Como trabajan los Módulos Contadores Cada cog tiene dos módulos contadores, Contador A y Contador B. Cada cog tiene también tres registros de propósito especial de 32-bit para cada uno de sus módulos contadores. Los registros especiales del contador A son phsa, frqa, ctra, y el B phsb, frqb y ctrb. Note que cada nombre de contador es también una palabra reservada en Spin y Ensamblador Propeller. Si esta práctica esta refiriéndose a un registro generalmente pero no importa si es contador A o B usara nombres genéricos PHS, FRQ, y CTR. Aquí se muestra como cada uno de los tres registros trabaja en un modulo contador: • • • PHS – El registro “Fase” se actualice cada ciclo de reloj. Un modulo contador puede también configurarse haciendo que ciertos bits de registros PHS afecten pines de E/S. FRQ – El registro “Frecuencia” es condicionalmente agregado al registro PHS cada ciclo de reloj. El modo del modulo contador determina que condiciones ocasionan que FRQ se agregue a PHS. Las opciones de Modo incluyen “always”, “never” y opciones condicionales basadas en estados de pin de E/S o transiciones CTR – El registro “Control” configure ambos modos, el modulo contador y Pins de E/S que son monitoreados y/o controlados por el modulo contador. Cada modulo contador tiene 32 modos diferentes, dependiendo del modo puede monitorear y/o controlar hasta dos pin de E/S Midiendo Descarga RC con un Detector de Modo Positivo La descarga Resistor-Capacitor (RC) es útil para una variedad de mediciones de sensores. Algunos ejemplos incluyen: • • • • • • Posición de perilla o joystick con uno o más potenciómetros Niveles de ambientación de luces con Resistencia dependiente o fotodiodo Reflectividad de superficie infrarroja con un LED infrarrojo y fototransistor Presión con platos capacitivos y Presión con placas del capacitor y un dieléctrico compresibles Salinidad de un liquido con puntas de metal Circuito de Descarga RC Las mediciones de descarga RC se desarrollan típicamente cargando un capacitor (C) y después monitoreando el tiempo que tarda el capacitor en descargarse a través de una resistencia (R). En la mayoría de los circuitos de descarga RC uno de los valores es fijo y el otro varía con la variable ambiental. Por ejemplo el circuito en la Figura 7-1 se usa para medir la posición de una perilla. El valor de C es fijo a 0.01 µF, y el valor de R vara con la posición del potenciómetro al ajustar la perilla (la variable ambiental) 3 Construya el circuito mostrado en la Figura 7-1 es la Plataforma PE. Este circuito y otros en esta práctica son adicionales al circuito básico construido en Configuración y Prueba. Figura 7-1: Descarga RC Partes y Circuito Lista de Partes Esquemático ─────────────────────── ─────────────────────────────── (1) Potenciómetro 10 kω P17 ─────┳───────────┐ (1) Capacitor - 0.01 μF │ │ (misc) Cables └ R 0.01 μF GND GND ─────────────────────── ─────────────────────────────── Pagina 124 · Kit Educativo de Prácticas Propeller: Fundamentos 7: Práctica de Módulos Contadores y Aplicaciones de Circuitos Midiendo Descarga RC Antes de tomar la medición de descarga RC, el chip Propeller necesita programar el pin E/S conectado al circuito en Salida Alta. Esto carga el capacitor hasta 3.3 V como se muestra en el lado izquierdo de la Figura 7-2. De esta forma el chip Propeller inicia la medición de descarga al programar el pin E/S a entrada, como se muestra en la derecha de la Figura 7-2. Cuando el pin E/S cambia a Entrada el capacitor se carga y comienza a descargar a través de la resistencia variable. El tiempo que le toma al capacitor para descargarse de 3.3V hasta el punto de cambio del pin 1.65 V es: Δt = 0.693 × C × R Como 0.693 y C son constantes el tiempo Δt que le toma para descargar el circuito es directamente proporcional a R, la resistencia variable. Figura 7-2: RC Carga y Descarga Circuitos y Voltajes Carga Circuito Descarga Circuito (I/O pin = output-high) (I/O pin = input) ───────────────────────────────── ─────────────────────────────────── 3.3 V Vc Vc │i ── │ │ └───────┳─────┴──────┐ I/O Pin ───────┳─────┴──────┐ │ │ │ ── │ │ir ic │ │ i │ └ R C └ R C │ │ │ │ GND GND GND GND ───────────────────────────────── ─────────────────────────────────── 3.3 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - │ │ │ │ 1.65 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - │ │ │ │ │ 0 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Vc (V) t, (s) ─── │─ δt─│ δt = 0.693 × C × R ¿Dónde está la resistencia en serie de limitadores de corriente? L El pin E/S del chip Propeller puede controlar circuitos que no necesitan protegerse de un pico de corriente inicial que resulte cuando el pin E/S está tomando su salida baja o entrada alta. La capacidad de salida del pin E/S y límite de corriente previene de cualquier daño. Si usted trata de usar este circuito con otro micro controlador, probablemente necesitara incluir una resistencia limitadora de corriente entre el pin E/S y el circuito RC. Asegúrese que sea lo suficientemente grande para prevenir daños del pin E/S. Detector Positivo de Modos Hay dos opciones de detectores positivos de Modo, “regular” y “con retroalimentación”. El modo regular el modulo contador del chip Propeller monitorea un pin E/S y agrega FRQ a PHS por cada ciclo de reloj en el cual el pin esta en alto. Para hacer que el registro PHS acumule el numero de ciclos de reloj en el cual el pin esta en alto solo programe el registro del contador de modulo a 1. Para Kit Educativo de Practicas Propeller: Fundamentos · Página 125 Práctica de Módulos Contadores y Aplicaciones de Circuitos medir la descarga RC el modulo contador deberá comenzar a contar (sumando FRQ = 1 para PHS) tan pronto como el pin E/S se cambia de salida alta a entrada. Después que la señal de descarga esta debajo de 1.65V el modulo ya no agrega FRQ a PHS y lo que se almacena en PHS es el tiempo de descarga medida en ciclos de reloj. Una ventaja significativa para usar el modulo contador para medir descarga RC es que el cog no tiene que esperar a que termine la descarga. Como el contador automáticamente incrementa PHS con cada ciclo de reloj en el cual el pin esta en alto el programa está libre para moverse en otra tareas. El programa puede obtener el valor del registro PHS en cualquier momento que sea conveniente. Configurando un Modulo Contador para Detector Positivo de Modo La Figura 7-3 muestra extractos de la Tabla de Modo de Contadores del Objeto CTR de la Librería Propeller. El Objeto CTR tiene información de un modulo contador y un ejemplo de código que genera onda cuadradas. La Tabla de Modo del objeto CTR lista las 32 opciones de modo, siete de las cuales se muestran abajo. El modo que usaremos para la descarga RC es Detector Positivo (sin retroalimentación), mostrado como “POS detector” en los extractos de la tabla. Figura 7-3: Extractos de la Tabla de Modos Contadores en CTR.spin Acumula APIN BPIN CTRMODE Descripción FRQ to PHS output* output* ┌────────┬─────────────────────────────┬────────────┬────────────┬────────────┐ │ %00000 │ Counter disabled (off) │ 0 (never) │ 0 (none) │ 0 (none) │ ├────────┼─────────────────────────────┼────────────┼────────────┼────────────┤ . . ├────────┼─────────────────────────────┼────────────┼────────────┼────────────┤ │ %01000 │ POS detector │ A¹ │ 0 │ 0 │ │ %01001 │ POS detector w/feedback │ A¹ │ 0 │ !A¹ │ │ %01010 │ POSEDGE detector │ A¹ & !A² │ 0 │ 0 │ │ %01011 │ POSEDGE detector w/feedback │ A¹ & !A² │ 0 │ !A¹ │ ├────────┼─────────────────────────────┼────────────┼────────────┼────────────┤ . . │ %11111 │ LOGIC always │ 1 │ 0 │ 0 │ └────────┴─────────────────────────────┴────────────┴────────────┴────────────┘ * Debe programar el correspondiente bit DIR para afectar el PIN A¹ = APIN entrada retrasada por 1 clock A² = APIN entrada retrasada por 2 clocks B¹ = BPIN entrada retrasada por 1 clock Note como cada modo contador en la Figura 7-3 tiene un correspondiente código de 5-bit CTRMODE. Por ejemplo el código para “POS detector” as %01000. Este valor tiene que copiarse a un campo de bit con el registro CTR del modulo contador para hacer su función en modo “POS detector”. La Figura 7-4 muestra el mapa de registro para los registros ctra y ctrb. Note como el mapa de registro nombra los bits 31..26 CTRMODE. Estos son los bits del código 5-bit de CTRMODE en la Figura 7-3 que tienen que copiarse para operar un modulo contador en un modo particular. Pagina 126 · Kit Educativo de Prácticas Propeller: Fundamentos 7: Práctica de Módulos Contadores y Aplicaciones de Circuitos Figura 7-4: Mapa de Registro CTRA/B de CTR.spin ┌────┬─────────┬────────┬────────┬───────┬──────┬──────┐ bits │ 31 │ 30..26 │ 25..23 │ 22..15 │ 14..9 │ 8..6 │ 5..0 │ ├────┼─────────┼────────┼────────┼───────┼──────┼──────┤ Name │ ── │ CTRMODE │ PLLDIV │ ────── │ BPIN │ ──── │ APIN │ └────┴─────────┴────────┴────────┴───────┴──────┴──────┘ Al igual que los registros dira, outa e ina los registros ctra y ctrb son bit-direccionales, así el procedimiento para asignar y limpiar en este registro es el mismo que seria para un grupo de operaciones de pins E/S con dira, outa, o ina. Aquí se muestra un ejemplo para hacer Counter A un “POS detector”: ctra[30..26] := %01000 L La Tabla de Modos Contadores y el Mapa de Registro aparecen en el Objeto CTR de la Librería Propeller y también en el Manual Propeller en la sección CTRA/B localizada en el capítulo de Referencia Spin. APIN y BPIN son pins de E/S que el modulo contador puede controlar, monitorear o no usar dependiendo del modo. Note también en la Figura 7-4 como hay campos de bits para PLLDIV, BPIN, y APIN. PLLDIV es el nombre corto para “ciclo divisor de fase cerrada” y es usado solo para modo contador PLL el cual puede sintetizar ondas cuadradas de alta frecuencia. APIN (y BPIN para modo de dos pins) tienen que almacenar los números de pins E/S que el modulo contador va a monitorear o controlar. En el caso que el contador A coloque a modo POS frqa se suma a phsa basado en el estado del APIN durante el reloj anterior. (Vea referencia A¹ y pie de nota en la Figura 7-3). Así el bit de campo APIN tiene que almacenar el valor 17 ya que P17 va a monitorear el circuito RC. Este es un comando que programa los bits 5..0 del registro ctra a 17: ctra[5..0] := 17 Recuerde que frqa se agrega a phsa con cada ciclo de reloj donde APIN está en alto. Para hacer que el contador identifique cuantos ciclos de reloj el pin esta en alto simplemente programe frqa a 1: frqa := 1 En este punto se le agrega 1 al registro phsa por cada ciclo de reloj en el cual el voltaje que se le aplica a P17 está por encima del disparo lógico 1.65V. La única cosa que tiene que hacer antes de comenzar la medición de la descarga es limpiar el registro phsa. En suma, configurar el modulo contador para que cuente los ciclos de reloj cuando un pin E/S esta en Alto toma 3 pasos: 1) Almacenar %01000 en el campo de bit CTRMODE del registro CTR : ctra[30..26] := %01000 2) Almacenar en el campo APIN del registro CTR el numero de pin E/S que quiere monitorear: ctra[5..0] := 17 3) Almacenar 1 en el registro FRQ para que el registro phsa agregue un 1 por cada ciclo del reloj en el que P17 está en alto: frqa := 1 Kit Educativo de Practicas Propeller: Fundamentos · Página 127 Práctica de Módulos Contadores y Aplicaciones de Circuitos 1 no es el único valor útil para el registro FRQ. Otros valores de registro FRQ pueden usarse para medir el sensor de entrada para cálculos o incluso para activar actuadores. Por ejemplo FRQ puede programarse como clkfreq/1_000_000 para contar la descarga en microsegundos. frqa := clkfreq/1_000_000 Esta expresión trabaja para el sistema de reloj del chip Propeller en frecuencias que normalmente son múltiplos de 1MHz. Por ejemplo trabajará bien con una entrada de cristal de 5 MHz pero no con una de 4.096 MHz ya que los resultados de la frecuencia del reloj no serán múltiplos exactos de 1 MHz. Una desventaja de valores muy grandes de FRQ es que el programa no pude necesariamente compensar el numero de ciclos de reloj entre la limpieza del registro y poner la entrada del pin E/S a 1. Un comando que compensa esta fuente de error se puede agregar después que el ciclo de reloj se termino y puede continuarse con un comando que convierte a una medida conveniente tal como microsegundos. L Midiendo señales de entrada o salida. Este modo contador puede usarse para medir la duración en la cual un pin E/S envía una señal alta y su duración en la que esa señal se aplico a la entrada E/S. La única diferencia es la dirección del pin E/S cuando se toma la medida. “Contando” la Medida de Descarga RC Antes de la medición de descarga RC el capacitor deberá estar cargado. Aquí hay una pieza de código que pone P17 como salida alta luego espera 10µs lo cual es más que suficiente para cargar el capacitor en la red RC de la Figura 7-1. dira[17] := outa[17] := 1 waitcnt(clkfreq/100_000 + cnt) Para empezar la medición de la descarga limpie el registro PHS y luego ponga el pin E/S que está cargando el capacitor como entrada: phsa~ dira[17]~ Después de limpiar phsa y dira, el programa queda libre para desarrollar otras tareas durante la medición. En algún tiempo el programa puede regresar y copiar el contenido del registro phsa a una variable. Por supuesto el programa deberá asegurarse de esperar suficiente tiempo para que se complete la medición. Esto se puede hacer al muestrear el reloj, esperando a que el pin de descarga pase a bajo o desarrollando una tarea conocida que es mayor que el tiempo de descarga. Para completar la medición copie el registro phsa a otra variable y reste 624 de esta para contar el numero de ciclos de reloj entre phsa~ y dira[17]~. El resultado de esta resta puede programarse a un mínimo de 0 con #> 0. Esto tendrá mayor sentido que -624 cuando la resistencia es tan baja que jala la salida del pin E/S de salida alta a baja. time := (phsa – 624) #> 0 De donde viene 624? L El numero de ciclos de reloj entre phsa~ y dira[17]~ se determine reemplazando 0.01 µF capacitor con un capacitor de 100 pF y encontrando el valor más bajo antes de que un cero se regresara. En el programa de prueba time := phsa reemplaza time := (phsa – 624) #> 0, y el valor medible más bajo fue 625. Pagina 128 · Kit Educativo de Prácticas Propeller: Fundamentos 7: Práctica de Módulos Contadores y Aplicaciones de Circuitos Ejemplo de Objeto que mide el Tiempo de Descarga RC El objeto TestRcDecayaplica la técnica que acabamos de discutir para medir la descarga RC en un circuito con Resistencia variable controlada por la posición de una perilla de ajuste de potenciómetro. Como se muestra en la Figura 7-5, el programa muestra un mensaje “working on other tasks” después de iniciar la medición de descarga para demostrar que el modulo contador automáticamente incrementa el registro phsa hasta que el voltaje aplicado a P17 se descarga debajo de 1.65 V. El programa puede entonces verificar después para encontrar el valor almacenado en phsa. Figura 7-5: Tiempos de Descarga RC L La mayoría de los ejemplos en esta práctica son objetos superiores que demuestran detalles de trabajo en los módulos contadores. Si usted planea incorporar estos conceptos en una librería de objetos diseñados para ser usados por otras aplicaciones asegúrese de poner atención en la sección titulada: Prueba y Muestra PWM – Agrega un Objeto, Cog y Par de Contadores que comienza en la pagina 162. 3 Abra el objeto TestRcDecay.spin. Llamara métodos en FullDuplexSerialPlus.spin, asegúrese de que están grabados en la misma carpeta. 3 Abra la Terminal Serial Parallax y programe su Puerto COM para usar el mismo Puerto que la Herramienta Propeller usa para cargar programas en el chip Propeller. 3 Use la herramienta Propeller para cargar TestRcDecay.spin en el chip Propeller. 3 Presione el botón Enable inmediatamente. (No espere a que el programa termine de cargar. De hecho puede presionar el botón inmediatamente después de presionar F10 o F11 en la herramienta Propeller) 3 Pruebe ajustando el potenciómetro a varias posiciones y note los valores del tiempo. Estos deberán variar en proporción a la posición de la perilla. '' TestRcDecay.spin '' Prueba mediciones de descarga Circuito RC CON _clkmode = xtal1 + pll16x _xinfreq = 5_000_000 ' Reloj de Sistema → 80 MHz CR = 13 OBJ Debug: "FullDuplexSerialPlus" ' Use con la terminal Serial ' Parallax para desplegar valores Kit Educativo de Practicas Propeller: Fundamentos · Página 129 Práctica de Módulos Contadores y Aplicaciones de Circuitos PUB Init 'Inicia comunicación serial y espera 2 s para conexión a la Terminal Serial Parallax. Debug.Start(31, 30, 0, 57600) waitcnt(clkfreq * 2 + cnt) ' Configura el Modulo Contador. ctra[30..26] := %01000 ctra[5..0] := 17 frqa := 1 ' Modo a "POS detector" ' Pone APIN a 17 (P17) ' Incrementa phsa 1 por cada ciclo de reloj main ' Llama al método Main PUB Main | time '' Repetidamente toma y despliega las mediciones de descarga de P17 repeat ' Charge RC circuit. dira[17] := outa[17] := 1 waitcnt(clkfreq/100_000 + cnt) ' Pone pin a salida alta ' Espera a cargar circuito ' Inicia medida descarga RC. Automáticamente después esto... phsa~ dira[17]~ ' Opcional ' Limpia el registro phsa ' Pin a entrada detiene carga Hacer otras cosas durante la medición. Debug.str(String(CR, CR, "Working on other tasks", CR)) repeat 22 Debug.tx(".") waitcnt(clkfreq/60 + cnt) ' Medición lista hace tiempo. Ajusta ciclos entre phsa~ y dira[17]~. time := (phsa - 624) #> 0 ' Display Result Debug.Str(String(13, "time = ")) Debug.Dec(time) waitcnt(clkfreq/2 + cnt) Dos mediciones simultaneas de descarga RC Como un modulo contador rastrea el tiempo en alto después de que empieza la descarga y como cada Cog tiene dos módulos contadores es posible tomar mediciones simultaneas de descarga RC en pins diferentes con un solo Cog. La Figura 7-6 muestra un ejemplo de un Segundo circuito conectado a P25 para medir descargas simultáneamente. En vez de un potenciómetro para medir la posición de la perilla este circuito tiene un fototransistor para medir el nivel de luz en interiores. El monto de corriente del fototransistor permite pasar en su terminal colectora (C) y de regreso en su terminal Emisora (E) es controlada por la intensidad de luz brillando en su base (B). Si la luz es más brillante el fototransistor permite pasar más corriente lo que resulta en una descarga más rápida del capacitor. Si la luz es menos brillante el fototransistor permite el paso de menor corriente resultando en tiempo de descargas más lentas. Pagina 130 · Kit Educativo de Prácticas Propeller: Fundamentos 7: Práctica de Módulos Contadores y Aplicaciones de Circuitos 3 Localice el fototransistor en las partes del Kit PE. Hay tres partes con encapsulado transparente que se parecen al fototransistor infrarrojo de la derecha de la Figura 7-6. Las dos partes idénticas son diodos emisores de luz infrarroja. La tercer parte tiene un encapsulado ligeramente más pequeño, ese es el fototransistor infrarrojo. 3 Construya el circuito mostrado en la Figura 7-6. Figura 7-6: Segunda Descarga RC Partes y Circuito Lista de Partes Esquematico ─────────────────────── ────────────────────────────────── 100 ω (1) Resistencia - 100 ω P25 ─────┳───────────┐ (1) Fototransistor │ │ (1) Capacitor - 0.1 μF Foto- 0.1 μF (misc) cables transistor GND GND ─────────────────────── ────────────────────────────────── L B C E La Resistencia en serie de 100 Ω en la Figura 7-6 previene sobrecargas en el capacitor cuando el pin E/S cambia de entrada a salida alta. Tenga en cuenta que el fototransistor conduce más corriente cuando la luz es más brillante. De forma que bajo condiciones de luz brillante, la resistencia en serie reduce la carga del fototransistor de lo contrario se pondría en el pin E/S como se carga en el capacitor. Con un fototransistor en el circuito, la resistencia de 100 Ω no previene al capacitor de cargarse a 3.3 V antes de la medición de descarga. Si el fototransistor fuera reemplazado por un sensor resistivo de luz, menores resistencias podrían terminar en voltajes iniciales menores antes de que la medición de descarga inicie. TestRcDecay.spin puede modificarse para usar el contador B para medir niveles de luz durante un periodo paralelo a la medición de descarga de la perilla del potenciómetro en el contador A. Como un Cog controla ambas mediciones, las inicia secuencialmente- una después de la otra. Sin embargo como ambos contadores pueden rastrear el tiempo de descarga independientemente el código del Cog no tiene que esperar a que termine la primera medición antes de comenzar la segunda. Puede iniciar ambas, una inmediatamente después de la otra, moverse a otras tareas y revisar los resultados en los registros de fase posteriormente. Un enfoque para modificar TestRcDecay.spin par alas dos mediciones podría ser comenzar convirtiendo ka variable time a dos arreglos de elementos así cada medición se almacena en un elemento diferente. PUB Main | time[2] Cada modulo contador puede programarse a detector de modo positivo, con uno monitoreando P17 y el otro monitoreando P25, como esto: ' Configurar módulos contadores. ctra[30..26] := %01000 ctra[5..0] := 17 frqa := 1 reloj ' Modo a "POS detector" ' Activa APIN en 17 (P17) ' Incrementa phsa 1 por cada ciclo de ctrb[30..26] := %01000 ctrb[5..0] := 25 frqb := 1 reloj ' Modo a "POS detector" ' Activa APIN en 25 (P25) ' Incrementa phsb 1 por cada ciclo de Ambos pins E/S pueden activarse a salida alta para cargar ambos capacitores antes de comenzar la medición de descarga. El capacitor en el circuito fototransistor es 10 veces mayor que el del circuito del potenciómetro y hay también una resistencia limitando la corriente de carga del capacitor, así que Kit Educativo de Practicas Propeller: Fundamentos · Página 131 Práctica de Módulos Contadores y Aplicaciones de Circuitos tomara quizá un poco mas de tiempo para cargar. El retraso antes de comenzar la medición puede incrementarse de 10 μs a 100 μs cambiando clkfeq/100_000 a clkfreq/10_000. ' Carga Circuitos RC. dira[17] := outa[17] := 1 dira[25] := outa[25] := 1 waitcnt(clkfreq/10_000 + cnt) ' Activa pin a salida-alta ' Activa pin a salida-alta ' Espera a cargar el circuito Como los módulos contadores están midiendo el tiempo de descarga el Cog puede empezar cada medición en sucesión rápida sin esperar a que termine la primera antes de comenzar la segunda. La medición del potenciómetro empieza al limpiar phsa y dira[17]. Cuando se limpia dira[17] el pin E/S se convierte en entrada. Como entrada no entrega ninguna carga al capacitor y comienza la descarga. Posteriormente la medición del fototransistor comienza limpiando phsb y dira[25]: ' Comienzan mediciones de descarga RC... phsa~ dira[17]~ phsb~ dira[25]~ ' ' ' ' Limpia registro phsa Pin a entrada detiene carga Limpia registro phsb Pin a entrada detiene carga Después de que ha pasado suficiente tiempo el contenido de un registro de fase puede copiarse en la variable time[0] y el otro en la variable time[1]: ' Mediciones listas por largo tiempo. Ajuste ciclos entre phsa~ ' y dira[17]~. Repita para phsb. time[0] := (phsa - 624) #> 0 time[1] := (phsb - 624) #> 0 Al final pero no menos importante despliegue ambos resultados: ' Despliega Resultados debug.Str(String(13, "time[0] = ")) debug.Dec(time[0]) debug.Str(String(13, "time[1] = ")) debug.Dec(time[1]) waitcnt(clkfreq/2 + cnt) 3 Haga una copia de TestRcDecay.spin. 3 Use el enfoque discutido para modificar la copia y medir el circuito de la Figura 7-1 y la Figura 7-6 al mismo tiempo. El código no tiene que esperar por un periodo fijo de tiempo antes de verificar los registros. Puede encontrar si se realizo una medición verificando el estado del pin E/S. Después de que la medición de descarga comenzó si ina[17] almacena un 1 significa que la descarga aun está en proceso por lo que no se debe verificar phsa todavía. Si en cambio almacena un 0 la medición se completó. Igualmente si ina[25] almacena un 1 la medición de la luz aun esta en proceso y no se tiene que verificar phsb todavía. Hay una modificación sencilla que hace que el Cog espere a que terminen ambas mediciones antes de copiar el contenido de los registros a las variables time: ' Espera a que terminen ambas mediciones. Estonces ajusta los ciclos ' entre phsa~ y dira[17]~. Repite para phsb. repeat until ina[17] == 0 and ina[25] == 0 Pagina 132 · Kit Educativo de Prácticas Propeller: Fundamentos 7: Práctica de Módulos Contadores y Aplicaciones de Circuitos time[0] := (phsa - 624) #> 0 time[1] := (phsb - 624) #> 0 Con todos los retrasos en el código no hay una diferencia apreciable. Se hace más evidente cuando se comenta el código que ocasiona los retrasos (excepto el waitcnt que da a los capacitores el tiempo de carga). También ayuda declarar una variable para contar la repeticiones del ciclo repeat y mostrar su valor entre cada medición. Con este arreglo se podrá observar cuantas mediciones se toman por segundo. 3 Inténtelo. Conversión D/A – Controlando luminosidad del LED con Modos DUTY Hay dos opciones de modos DUTY, terminación sencilla y diferencial. Un modulo contador en terminación sencilla permite controlar una señal que puede ser usada por conversión digital a análoga con el registro FRQ. Aun si la señal cambia rápidamente entre alto y bajo el tiempo promedio que esta alto (duty) es determinada por la proporción del registro FRQ a 232. pin high time FRQ duty = ───────────── = ───────────── time 4_294_967_296 Eq. 1 Para conversión D/A vamos a decir que el programa tiene que enviar una señal 0.825 V. Eso es 25% de 3.3 V por lo que se requiere 25% de una señal “duty”. Calcular el valor a almacenar en el registro FRQ es simple. Solo coloque duty = 0.25 y resuelto para FRQ. FRQ 0.25 = ───────────── 4_294_967_296 → FRQ = 1_073_741_824 También puede usar la Eq 1 para calcular que señal de tarea está enviando un objeto. Vamos a decir que el valor 536,870,912 es almacenado en un registro de modulo contador y su registro CTR lo ha configurado a modo DUTY de terminación sencilla. 536_870_912 duty = ───────────── = 0.125 4_294_967_296 En una escala de 3.3 V eso resultaría 0.4125 V. Nuevamente el gran detalle de los contadores es que pueden hacer sus tareas sin atar un cog. Así el cog gestara libre para continuar ejecutando comandos mientras el contador cuida de mantener la señal de tarea de la conversión D/A. Como trabaja el modo DUTY de terminación sencilla Cada vez que FRQ se suma a PHS el sumador de fase del modulo contador (que suma FRQ a PHS con cada ciclo reloj) activa o limpia una bandera de acarreo. Esta operación de acarreo es similar a la operación de acarreo de la suma decimal. Vamos a decir que está permitido 3 posiciones decimales y se intenta agregar dos valores que suman más de 999. Algún valor normalmente no sería acarreado de los cientos a los miles. La versión binaria de la suma con acarreo se aplica cuando el registro FQR se Kit Educativo de Practicas Propeller: Fundamentos · Página 133 Práctica de Módulos Contadores y Aplicaciones de Circuitos suma al registro PHS cuando el resultado es mayor que 232 − 1. Si el resultado excede este valor la bandera de acarreo del sumador PHS se activa. Lo interesante es que la bandera de acarreo es que, el tiempo en el que es 1, es proporcional al valor almacenado en el registro FRQ dividido por 232. En modo DUTY de terminación sencilla el bit de acarreo del sumador de fase del modulo contador controla el estado de salida de un pin de E/S. Como el tiempo en el cual el bit de acarreo del sumador de fase es 1 es proporcional a FRQ/232 es lo mismo para el estado de salida del pin E/S. El pin E/S puede cambiar rápidamente entre alto y bajo pero el promedio en el que el pin esta en alto es determinado por FRQ-to-232 mostrado en la ecuación Eq. 1. Partes y Circuitos Si, de regreso a LEDs por un poco más y después nos moveremos a otros circuitos. Prácticas previas usan LEDs para indicar el estado de pins E/S y tiempo. Esta porción de la práctica usara modo DUTY de terminación sencilla para conversión D/A para controlar el brillo de un LED. Figura 7-6: Circuito LED para control de iluminación con señales Duty Lista de Partes ─────────────────── (4) Resistencia 100 ω (2) LEDs - verde (2) LEDs - amarillo (misc) cables ─────────────────── Esquemático ────────────────────── verde 100 ω LED P4 ────────────┐ verde │ 100 ω LED │ P5 ────────────┫ amarillo │ 100 ω LED │ P6 ────────────┫ amarillo │ 100 ω LED │ P7 ────────────┫ GND ────────────────────── 3 Agregue el circuito mostrado en la Figura 7-6 a la Plataforma PE, deje el circuito de descarga RC en su lugar. Configurando un Contador para modo DUTY La Figura 7-7 muestra más entradas del objeto CTR en la tabla del Modo Contador del Manual Propeller. Como se menciono previamente los dos tipos de modos DUTY son terminación sencilla y diferencial. Con modo DUTY de terminación sencilla el APIN es un espejo del estado del bit de acarreo. Así que si FRQ es programado a un valor de 1,073,741,824 calculado anteriormente el APIN deberá estar alto ¼ del tiempo. Un circuito LED recibiendo esta señal parecerá que brilla a ¼ de su brillo total. Con modo DUTY de terminación sencilla el APIN es un espejo del estado del bit de acarreo del bit de acarreo, mientras BPIN es el valor opuesto. Así que cada que el bit de acarreo del sumador de fase (y APIN) son 1, BPPIN es 0 y viceversa. Si FRQ se programa a 1,073,741,824, APIN debería hacer que un LED brille a ¼ de luminosidad mientras BPIN brilla a ¾ . Pagina 134 · Kit Educativo de Prácticas Propeller: Fundamentos 7: Práctica de Módulos Contadores y Aplicaciones de Circuitos Figura 7-7: Mas extractos de la Tabla de Modo de Contadores CTR.spin Acumulado APIN BPIN CTRMODE Descripción FRQ to PHS salida* salida* ┌────────┬─────────────────────────────┬────────────┬────────────┬────────────┐ │ %00000 │ Contador deshabilitado(off) │ 0 (never) │ 0 (none) │ 0 (none) │ ├────────┼─────────────────────────────┼────────────┼────────────┼────────────┤ . . . ├────────┼─────────────────────────────┼────────────┼────────────┼────────────┤ │ %00110 │ DUTY terminación sencilla │ 1 │ PHS-Carry │ 0 │ │ %00111 │ DUTY diferencial │ 1 │ PHS-Carry │ !PHS-Carry │ ├────────┼─────────────────────────────┼────────────┼────────────┼────────────┤ . . . │ %11111 │ LOGIC siempre │ 1 │ 0 │ 0 │ └────────┴─────────────────────────────┴────────────┴────────────┴────────────┘ * debe programar el bit DIR para afectar el pin A¹ = APIN entrada retrasada por 1 clock A² = APIN entrada retrasada por 2 clocks B¹ = BPIN entrada retrasada por 1 clock La Figura 7-8 es una repetición de la Figura 7-4. De la Figura 7-4 sabemos que el valor almacenado en el campo del bit CTRMODE del registro CTR es %00110 (DUTY terminación sencilla) o %00111 (DUTY diferencial). Entonces el bit APIN (y opcionalmente BPIN) tienen que activarse como pins E/S que transmitirán las señales DUTY. Figura 7-8: CTRA/B Mapa de registro de CTR.spin ┌────┬─────────┬────────┬────────┬───────┬──────┬──────┐ bits │ 31 │ 30..26 │ 25..23 │ 22..15 │ 14..9 │ 8..6 │ 5..0 │ ├────┼─────────┼────────┼────────┼───────┼──────┼──────┤ Nombre│ ── │ CTRMODE │ PLLDIV │ ────── │ BPIN │ ──── │ APIN │ └────┴─────────┴────────┴────────┴───────┴──────┴──────┘ La aplicación de descarga RC activa el registro FRQ a 1 y el resultado fue que se sumo 1 a PHS por cada ciclo de reloj en el cual el pin monitoreado estaba alto. En esta aplicación el registro FRQ está programando valores que controlan el tiempo en alto de una señal DUTY aplicada a un pin E/S. No hay condición para sumar con modo duty; FRQ se suma a PHS cada ciclo de reloj. Activando una señal Duty Aquí tiene unos pasos para activar una señal duty también con un contador: (1) (2) (3) (4) (5) Active el campo de bit CTRMODE del registro CTR para escoger el modo. Active el bit APIN del registro CTR para escoger el pin. Si usted está usando modo DUTY diferencial active el campo BPIN del registro CTR. Active el pin(s) E/S a salida. Active el registro FRQ a un valor que le de el porcentaje de la señal duty que desea Kit Educativo de Practicas Propeller: Fundamentos · Página 135 Práctica de Módulos Contadores y Aplicaciones de Circuitos Ejemplo – Enviar una señal duty de 25% a P4 usando el contador A. (1) Active el campo de bit CTRMODE del registro CTR para escoger el modo. Recuerde que los bits 30..26 del registro CTR (mostrado en la Figura 7-8) tienen que activarse al patrón seleccionado de la lista CTRMODE en la Figura 7-7. Por ejemplo aquí hay un comando que configura el modulo contador para operar en modo DUTY de terminación sencilla ctra[30..26] := %00110 (2) Active el bit APIN del registro CTR para escoger el pin. La Figura 7-8 indica que APIN es los bits 5..0 en el registro CTR. Un ejemplo que activa los bits APIN del registro ctra a 4, el cual controla el LED verde conectado a P4. ctra[5..0] := 4 Nos saltaremos el paso (3) ya que el modulo contador se configure como modo DUTY de terminación sencilla. (4) Active el pin(s) E/S a salida. dira[4]~~ (5) Active el registro FRQ a un valor que le de el porcentaje de la señal duty que desea. Para ¼ de brillo, use duty 25%. Active el registro frqa a 1_073_741_824 (calculado anteriormente). frqa := 1_073_741_824 Claves para activar DUTY con el Registro FRQ Como los registros de propósito especial inicializan a cero, frqa es 0 así que 0 es repetidamente sumado al registro PHS resultando en no cambios de estado del LED. Tan pronto como el programa activa el registro FRQ a alguna fracción de 232 el pin E/S y el LED comenzara a enviar la señal duty, Teniendo 232 diferentes niveles de iluminación no es práctico, pero 256 diferentes niveles trabajaran bien. Un forma simple de llegar a esto es declarando una constante que es 232 ÷ 256. CON scale = 16_777_216 ' 232 ÷ 256 Ahora el programa puede multiplicar la escala constante por un valor entre 0 y 255 para tener 256 niveles de iluminación. Si se quiere ¼ de brillo multiplique la escala por ¼ de 256. frqa := 64 * scale L Variación de Tiempo D/A y Filtro: Cuando se modula el valor de frqa para enviar señales de variaciones de tiempo un circuito RC filtran la señal típicamente. Es mejor usar una fracción más pequeña que la señal de uso, decir 25% a 75% o 12.5% a 18.75%. Manteniendo la señal en este rango el D/A será menos ruidoso y resistencias y capacitores más pequeños se pueden usar para respuestas más rápidas. Esto es importante para señales que varían rápidamente tales como audio, lo cual será visto en otra practica. R Señal duty ────────┳─── voltage C GND Pagina 136 · Kit Educativo de Prácticas Propeller: Fundamentos 7: Práctica de Módulos Contadores y Aplicaciones de Circuitos Código Ejemplo de Modo DUTY de Terminación Sencilla El objeto LedDutySweep.spin demuestra los pasos para configurar un contador DUTY terminado sencillo y transmisión de una señal duty con un pin E/S. También cambia una variable duty de 0 a 255 repetidamente provocando que el LED en P4 incremente gradualmente en brillo y se apague. 3 Cargue el objeto LedDutySweep en el chip Propeller y observe el efecto. ''LedDutySweep.spin ''Ciclo de LED P4 de apagado, brillo parcial, brillo complete. CON scale = 16_777_216 ' 2³²÷ 256 PUB TestDuty | pin, duty, mode 'Configura el modulo contador. ctra[30..26] := %00110 ctra[5..0] := 4 frqa := duty * scale ' Activa ctra a modo DUTY ' Activa APIN de ctra ' Activa registro frqa 'Usa contador para tomar un LED de apagado a brillo completo repitiendo a 2 Hz. dira[4]~~ ' Activa P5 como salida repeat repeat duty from 0 to 255 frqa := duty * scale waitcnt(clkfreq/128 + cnt) ' ' ' ' Repite indefinidamente Cambia duty de 0 a 255 Actualiza registro frqa Retrasa por 1/128 s Modos Duty de Terminación Sencilla vs. Diferencial Diferencial es la segunda opción para modos DUTY, al igual que muchos otros modos contadores. Las señales diferenciales son útiles para obtener señales a través de líneas de transmisión más largas y se usan en Ethernet cableado, RS485 y ciertas señales de audio. Cuando un modulo contador funciona en modo diferencial usa un pin E/S para transmitir la misma señal que transmite la terminación sencilla junto con un segundo pin E/S que transmite la señal de polaridad opuesta. Por ejemplo un modulo contador activado para modo diferencial puede enviar la señal opuesta que P4 transmite en P5 o algún otro pin. Cada que la señal en P4 es alta la de P5 es baja y viceversa. Intente modificar una copia de LedDutySweep.spin para que envíe la señal diferencial en P5. Así en cuanto P4 se empieza a iluminar más P5 ira bajando de intensidad. Aquí están los pasos: 3 Guarde una copia del objeto LedDutySweep que modificara. 3 Para activar el modulo contador a modo DUTY diferencial cambie ctra[30..26] := %00110 a ctra[30..26] := %00111. 3 Active el campo BPIN agregando un comando ctra[14..9] := 5 3 Active P5 a salida para que la señal se transmita por el pin E/S con el comando dira[5]~~. Usando ambos módulos contadores A y B Usando ambos contadores para mostrar la intensidad del LED también es un ejercicio valioso. Para obtener dos módulos contadores enviando señales duty en pins separados intente estos pasos: 3 Guarde otra copia del objeto original, no modificado LedDutySweep objeto. Kit Educativo de Practicas Propeller: Fundamentos · Página 137 Práctica de Módulos Contadores y Aplicaciones de Circuitos 3 3 3 3 Agregue ctrb[30..26] := %00110. Asuma que ctrb controlara P6, agregue ctrb[5..0] := 6. También asumiendo que ctrb controlara P6, agregue dira[6]~~. En el ciclo repeat duty from 0 to 255, haga frqb dos veces el valor de frqa con el comando frqb := 2 * frqa. Esto ocasiona que el LED P6 brille dos veces más rápido que el LED P4. Dentro del Modo DUTY Vamos a observar cómo trabaja examinando la versión 3-bit. Como el denominador de la fracción es 2 de exponente de bits en el registro una versión 3-bit de FRQ seria dividida por 23 = 8: pin high time frq duty = ───────────── = ───── time 8 (3-bit example) Vamos a decir que el bit de acarreo necesita estar en alto 3/8 del tiempo. La versión 3-bit del registro FRQ deberá almacenar 3. El ejemplo de abajo desarrolla ocho sumas de 3-bi-FRQ a 3-bitPHS usando sumas long-hand. El bit de acarreo (que deberá ser acarreado en el bit 4) es marcado con el símbolo ↓ cada que es 1. Note que de las ocho sumas PHS = PHS + FRQ tres resultados acarrean bits. Por lo que el bit de acarreo esta, de hecho, activo 3/8 del tiempo. carry flag set 3-bit frq 011 3-bit phs(previous) +000 ──── 3-bit phs(result) 011 ¹¹ 011 +011 ──── 110 ↓ ¹¹ 011 +110 ──── 001 ¹¹ 011 +001 ──── 100 011 +100 ──── 111 ↓ ¹¹¹ 011 +111 ──── 010 ¹ 011 +010 ──── 101 ↓ ¹¹¹ 011 +101 ──── 000 La Suma binaria trabaja igual que la suma decimal cuando se hace “long hand”. En vez de acarrear un digito de 1 a 9 cuando los dígitos en una columna particular suman un valor mayor a 9 en la suma binaria acarrea un 1 si el resultado en una columna excede 1. Binary Result L 0 + 0 = 0 0 + 1 = 1 1 + 0 = 1 1 + 1 = 10 (0, carry the 1) 1+1+1 = 11 (1, carry the 1) Registros de Propósito Especial Cada cog tiene un arreglo de registro de propósito especial (SPR) del cual los elementos pueden accesar con spr[index]. El valor index lo deja escoger un registro dado de propósito especial. Por ejemplo usted puede activar el valor de ctra asignando un valor a spr[8], o ctrb asignando un valor para spr[9]. Igualmente puede asignar valores a frqa y frqb asignando valores a spr[10] y spr[11], o phsa y phsb asignando valores a spr[12] y spr[13]. Se puede encontrar una lista completa de arreglos de elementos SPR en el Manual Propeller. 3 Observe SPR en la sección de referencia de Lenguaje Spin del Manual Propeller y revise la explicación de SPR y la tabla de arreglo de elementos SPR. Pagina 138 · Kit Educativo de Prácticas Propeller: Fundamentos 7: Práctica de Módulos Contadores y Aplicaciones de Circuitos La ventaja de usar arreglos SPR es que son accesibles por los valores index. También ctrb, frqb, y phsb son elementos todo in uno sobre ctra, frqa, y phsa. Esto hace posible escoger entre registros de contador A y B con tan solo agregar 1 a (o substraer 1 de) el valor del índice usado para accesar un registro SPR dado. Esto en su momento hace posible eliminar la declaración de condiciones para decidir cual modulo contador usar y también hace posible inicializar y actualizar módulos contadores con estructuras cíclicas. Una desventaja de los registros de propósito especial es que no son bit-direccionales. Por ejemplo los comandos ctra[30..26] := %00110 and ctra[5..0] := 4 tienen que codificarse diferente para spr[8], el cual es el elemento del arreglo de propósito especial ctra. El mejor modo de escribir estos dos comandos en lenguaje Spin con el arreglo SPR es como esto: spr[8] := (%00110 << 26) + 4 En el comando de arriba el patrón de bit %00110 se mueve a la izquierda por 26 bits, lo cual tiene el mismo alcance que ctra[30..26] := %00110, y sumando 4 a él sin mover tiene el mismo efecto que ctra[5..0] := 4. Aquí está la suma: %00110 << 26 + 4 ──────────── spr[8] %00011000000000000000000000000000 %00000000000000000000000000000100 ───────────────────────────────── %00011000000000000000000000000100 Vamos a decir que la aplicación enviara señales duty en P4 y P5. Un ciclo que podría activar estos pins de E/S para señales duty se vería así: repeat module from 0 to 1 ' 0 es modulo A, 1 es modulo B. spr[8 + module] := (%00110 << 26) + (4 + module) dira[4 + module]~~ La primera vez en el ciclo module es 0, así el valor 4 se almacena en los bits 5..0 de spr[8] y dira[4 + module]~~ se convierte en dira[4]~~. La segunda vez module es 1, así 5 se almacena en los bits 4..0 de spr[9], y dira[4 + module]~~ se convierte en dira[5]~~. Cuando se usan contadores en objetos los pins probablemente pasaran como parámetros. Si los parámetros sostienen el valor del pin quizá no estarán juntos o ligados por alguna relación matemática. Una manera de mantener una lista de pins no ligados si no está esperando que vengan de otro lado podría ser un comando lookup o lookupz. Dando un valor index ambos lookup y lookupz regresan un elemento en una lista. Por ejemplo el comando value := lookup(index: 7, 11, 13, 1) almacenara 7 en value si index es 1, 11 en value si index is 2, y así. Si index excede la longitud de la tabla el comando lookup almacena0 en value. El mismo comando con lookupz almacenara7 en value si index es 0, o 11 en value si index es 1, y así sucesivamente. Al igual que lookup, lookupz regresa 0 si index excede la longitud de la lista. Abajo hay una versión del ciclo repeat que usa lookupz para almacenar una lista de pins no ligados y los carga en los bits 5..0 de los registros de propósito especial A y B del cog (spr[8] and spr[9]). Note como el comando lookupz almacena 4 y 6. En el primer ciclo module es 0 por lo que se almacena 4 en apin, el cual se almacena en los bits 5..0 de spr[8] y activa el bit 4 en el registro dira. La segunda vez en el ciclo module is 1, así 6 se almacena en apin, el cual a su vez se almacena en los bits 5..0 de spr[9] y el bit 6 de dira queda activado. repeat module from 0 to 1 apin := lookupz (module: 4, 6) spr[8 + module] := (%00110 << 26) + (apin) dira[apin]~~ ' 0 es modulo A, 1 es B. Kit Educativo de Practicas Propeller: Fundamentos · Página 139 Práctica de Módulos Contadores y Aplicaciones de Circuitos El objeto LedSweepWithSpr hace el mismo trabajo que el código LedDutySweep modificado en la sección “Usando ambos Módulos Contadores”. La diferencia es que desarrolla todas las operaciones de modulo usando el arreglo SPR en vez de referirse a los registros CTR, FRQ y PHS de los módulos A y B. 3 Compare la copia de LedDutySweep que mueve ambos contadores contra el código en LedSweepWithSpr.spin. 3 Corra LedSweepWithSpr y use LEDs para verificar que controla dos señales duty separadas. ''LedSweepWithSpr.spin ''Ciclo P4 y P5 LEDs de apagado hasta brillo máximo en diferentes rangos. CON scale = 16_777_216 ' 2³²÷ 256 PUB TestDuty | apin, duty[2], module 'Configura ambos módulos contadores con un ciclo repeat que indexa elementos SPR. repeat module from 0 to 1 apin := lookupz (module: 4, 6) spr[8 + module] := (%00110 << 26) + apin dira[apin]~~ ' 0 es modulo A, 1 es B. 'Repite cambios duty indefinidamente. repeat repeat duty from 0 to 255 duty[1] := duty[0] * 2 repeat module from 0 to 1 spr[10 + module] := duty[module] * scale waitcnt(clkfreq/128 + cnt) ' Cambia duty de 0 a 255 ' duty[1] dos veces más rápido ' Actualiza reg frqa ' Detiene por 1/128 s Modificando LedSweepWithSpr para Señales Diferenciales Intente actualizar el objeto LedSweepWithSprpara que haga dos señales diferenciales, una en P4 y P5 y la otra en P6 y P7. 3 Haga una copia de LedSweepWithSpr.spin. 3 Agregue una variable bpin a la lista de variables locales del método TestDuty. 3 Agregue el comando bpin := lookupz(module: 5, 7) justo debajo del comando que asigna el valor apin con un comando lookup. 3 Cambie spr[8 + module] := (%00110 << 26) + apin a spr[8 + module] := (%00111 << 26) + (bpin << 9) + apin. 3 Agregue dira[bpin]~~ inmediatamente después de dira[apin]~~. 3 Cargue la copia modificada de LedSweepWithSpr.spin en el chip Propeller y verifique que envía dos señales diferenciales duty. Pagina 140 · Kit Educativo de Prácticas Propeller: Fundamentos 7: Práctica de Módulos Contadores y Aplicaciones de Circuitos Generando Tonos en Piezospeaker con Modo NCO NCO significa Oscilador Controlado Numéricamente. Al igual que DUTY hay dos modos NCO, terminación sencilla y diferencial. Si un modulo contador se configura para modo NCO terminación sencilla hará que un pin E/S envíe una onda cuadrada. Asumiendo que clkfreq es constante, la frecuencia de su onda cuadrada es “numéricamente controlada” por un valor almacenado en un registro FRQ del modulo contador en un cog dado. 3 Construya el esquemático mostrado en la Figura 7-9. Figura 7-9: Rango de Audio NCO Lista de Partes y Circuitos Lista de Partes ───────────────────── (2) Piezospeakers (misc) cables ───────────────────── Esquemático ───────────────────────────────────────────── Piezospeakers \+ +/ ((( ─────── P3 P27 ─────── ))) /│ │\ GND GND ───────────────────────────────────────────── Modulo Contador en Modo NCO de Terminación Sencilla Cuando se configura a modo NCO de terminación sencilla el contador hace dos cosas: • El registro FRQ se suma al registro PHS cada ciclo de reloj • El bit 31 del registro PHS controla el estado de un pin E/S. Cuando el bit 31 del registro PHS es 1, el pin E/S que controla envía una señal alta y cuando es 0 una señal baja. Si clkfreq se mantiene igual el hecho de que FRQ se suma a PHS cada ciclo de reloj determina el rango al cual el bit 31 del registro se activara. Esto a su vez determina la frecuencia de onda cuadrada transmitida por el pin controlado por el bit 31 del registro PHS. Dada la frecuencia del reloj del sistema y una frecuencia NCO deseada para transmitir en el Propeller se puede calcular el valor de registro FRQ con esta ecuación: 232 FRQ register = PHS bit 31 frequency × ──────── clkfreq Eq. 2 Ejemplo: Qué valor tiene que almacenar frqa para hacer que el modulo contador transmita a 2093 Hz de onda cuadrada si el sistema de reloj está corriendo a 80MHz? (Si esto fuera una onda senoidal seria Do7 una nota Do en la 7ma Octava) Para la solución empiece sustituyendo 80,000,000 en Eq. 2 para clkfreq y 2093 para frequency. frqa = 2,093 × 232 ÷ 80,000,000 frqa = 2,093 × 53.687 frqa = 112,367 La Tabla 7-1 muestra otras notas en la 6a octava y su valor de registro FRQ a 80 MHz. Las notas agudas están para que se calculen. Tenga en cuenta que estas son las versiones de onda cuadrada. En otra práctica usaremos objetos que digitalmente sintetizan ondas senoidales en tonos. Kit Educativo de Practicas Propeller: Fundamentos · Página 141 Práctica de Módulos Contadores y Aplicaciones de Circuitos Tabla 7-1: Notas, Frecuencias, y Valores de Registro FRQA/B para 80 MHz Nota Frecuencia (Hz) Do 6 1046.5 Do 6# 1107.8 Re 6 1174.7 Re 6# 1244.5 Mi 6 1318.5 Fa 6 1396.9 Fa 6# 1480.0 FRQA/B Registro 56_184 63_066 Nota Frecuencia (Hz) Sol 6 1568.0 Sol 6# 1661.2 FRQA/B Registro 84_181 La 6 1760.0 La 6# 1864.7 94_489 70_786 Si 6 1975.5 105_629 74_995 Do 7 2093.0 112_367 La Eq. 3 puede también reacomodarse para calcular la frecuencia transmitida por un objeto dando un valor que el objeto almacena en su registro FRQ: clkfreq × FRQ register PHS bit 31 frequency = ─────────────────────────── 232 Eq. 3 Ejemplo: Un objeto tiene su contador B del cog operando en modo NCO terminación sencilla y almacena 70,786 en su registro frqb. El sistema de reloj corre a 80 MHz. ¿Cuál es la frecuencia que transmite? Sabemos la respuesta por la Tabla 7-1, pero aquí está con la Eq. 3 80,000,000 × 70,786 PHS bit 31 frequency = ───────────────────── = 1318 Hz 232 Configurando un Modulo Contador para Modo NCO La Figura 7-10 muestra entradas de modo NCO en la tabla de Modo de Contadores del Objeto CTR. Note que se llama modo NCO/PWM en la tabla, usted verá eso ocasionalmente. PWM es una aplicación del modo NCO que será explorado en la sección PWM en la página 158. Como se menciono el modo NCO tiene opciones de terminación sencilla y diferenciales. Modo NCO de Terminación Sencilla hace que iguala el bit 31 del registro PHS sea transmitida por el APIN. Modo diferencial envía la misma señal en APIN junto con la señal invertida en BPIN. Recuerde que con modos DUTY la bandera de acarreo del sumador de fase (bit 32 del registro PHS) determinado por el estado del pin E/S que resultaba en la señal que variaba con el valor almacenado por el registro FRQ. Sin embargo con modo NCO es el bit 31 del registro PHS el que controla el pin E/S lo cual resulta en una onda cuadrada cuya frecuencia es determinada por el valor almacenado en el registro FRQ. Pagina 142 · Kit Educativo de Prácticas Propeller: Fundamentos 7: Práctica de Módulos Contadores y Aplicaciones de Circuitos Figura 7-10: Extractos de la Tabla de Modo de Contadores del Objeto CTR Acumulado APIN BPIN CTRMODE Descripción FRQ to PHS salida* salida* ┌────────┬─────────────────────────────┬────────────┬────────────┬────────────┐ │ %00000 │ Counter desactivado (off) │ 0 (never) │ 0 (none) │ 0 (none) │ ├────────┼─────────────────────────────┼────────────┼────────────┼────────────┤ . . . ├────────┼─────────────────────────────┼────────────┼────────────┼────────────┤ │ %00100 │ NCO/PWM term sencilla │ 1 │ PHS[31] │ 0 │ │ %00101 │ NCO/PWM diferencial │ 1 │ PHS[31] │ !PHS[31] │ ├────────┼─────────────────────────────┼────────────┼────────────┼────────────┤ . . . │ %11111 │ LOGIC siempre │ 1 │ 0 │ 0 │ └────────┴─────────────────────────────┴────────────┴────────────┴────────────┘ • debe activar el correspondiente bit DIR para afectar al pin A¹ = APIN input delayed by 1 clock A² = APIN input delayed by 2 clocks B¹ = BPIN input delayed by 1 clock Los pasos para configurar el modulo contador para modos NCO son similares a los pasos para los modos DUTY. Los campos de bits CTRMODE, APIN (y BPIN para modo diferencial) del registro CTR deben activarse. Luego el registro FRQ da un valor que activa la frecuencia NCO. Como en otros ejemplos de salida los pins E/S usados por el modulo contador tienen que activarse como salida. Aquí están los pasos para configurar el modulo contador a modo NCO: (1) Configure el registro CTRA/B (2) Active el registro FRQA/B (3) Active el pin E/S como salida (1) Configure el registro CTRA/B: Se muestra un ejemplo que active el contador A para modo NCO de terminación sencilla con envío de señal por P27. Para hacer esto active ctra[30..26] a %00100, y ctra[5..0] a 27. ctra[30..26] := %00100 ctra[5..0] := 27 (2) Active el registro FRQA/B Active el Registro FRQA/B: Se muestra un ejemplo para la versión de onda cuadrada de la nota Do 7: frqa := 112_367 (3) Active el pin E/S a salida: Como es P27 el que está enviando la señal conviértalo en salida: dira[27]~~ Después de iniciar el modulo contador corre independientemente. El código en el cog puede olvidarse y hacer otras cosas, o monitorear/controlar/modificar el comportamiento del contador si se necesita. Kit Educativo de Practicas Propeller: Fundamentos · Página 143 Práctica de Módulos Contadores y Aplicaciones de Circuitos Ejemplo de Onda Cuadrada El objeto SquareWaveTest.spin de abajo toca una onda cuadrada de la versión de onda cuadrada de Do en la 7ma octava por un Segundo. • • • • Examine el objeto SquareWaveTest, compárelo con los pasos 1 a 3 que acabamos de discutir. Cargue el objeto SquareWaveTest en el chip Propeller. Córralo y verifique que toca un tono. Cambie frqa := 112_367 a frqa := 224_734. Eso es Do 8, la nota Do en la siguiente octava más alta. Cargue el objeto modificado en el chip Propeller. Esta vez la nota deberá sonar a un tono más agudo. ''SquareWaveTest.spin ''Envía onda cuadrada de 2093 Hz a P27 por 1 s con el modulo contador. CON _clkmode = xtal1 + pll16x _xinfreq = 5_000_000 ' Programa clkfreq = 80 MHz. PUB TestFrequency 'Configura modulo ctra ctra[30..26] := %00100 ctra[5..0] := 27 frqa := 112_367 'Transmite la señal por 1 s dira[27]~~ waitcnt(clkfreq + cnt) ' Activa ctra for "NCO sencillo" ' Activa APIN a P27 ' Activa frqa a 2093 Hz (Do) usando: ' FRQA/B = frecuencia × (2^32 ÷ clkfreq) ' Activa P27 a salida ' Espera por tono para tocar 1 s Deteniendo (y reiniciando) la Señal En el objeto SquareWaveTest el cog se queda sin comandos, así el tono se detiene porque el programa termina. En muchos casos se quiere detener y reiniciar la señal. Los 3 caminos más sencillos de detener (y comenzar) la señal de transmisión son: 1) Cambien la dirección del pin E/S a entrada. En el objeto SquareWaveTest esto podría hacerse con dira[27] := 0 o dira[27]~ cuando el programa está listo para detener la señal. (Para reiniciar la señal use dira[27] := 1 o dira[27]~~.) 2) Detenga el contador limpiando los bits CTR 30..26. En el objeto SquareWaveTest se puede hacer con ctra[30..26] := 0. Otra forma de hacerlo es activando todos los bits en el campo de bits CTRMODE del registro ctra con ctra[30..26]~. En cualquiera de los casos el pin E/S es aun una salida y su estado de salida puede ser alto o bajo. Después examinaremos una forma de asegurarse que la señal termina cuando el pin E/S está transmitiendo una señal baja. (Para reiniciar copie %00100 nuevamente en ctra[30..26]). 3) Detenga la suma a PHS al activar FRQ a 0. En el objeto SquareWaveTest se puede hacer con frqa := 0 o frqa~. El contador podría correr pero como agregara un cero a phsa con cada el bit 31 de phsa no cambiara, así el pin E/S también dejara de cambiar. Igual de detener el contador el pin E/S detendrá el estado de salida que tenía en el momento que se limpio frqa. (Para reiniciar la señal use frqa := 112_367). El objeto Staccato cambia el pin E/S entre salida y entrada para iniciar el tono 2.093 Khz y detener a 15Hz for 1 s. Se usa el método 1 para iniciar y detener la señal. Su trabajo será modificar dos copias del código para hacerlo a través de las opciones 2 y 3. Pagina 144 · Kit Educativo de Prácticas Propeller: Fundamentos 7: Práctica de Módulos Contadores y Aplicaciones de Circuitos 3 3 3 3 Cargue Staccato.spin en el chip Propeller y verifique que suena a 15 Hz por 1 s. Haga dos copias del programa. Modifique una copia para que utilice el método 2 para iniciar y detener la señal. Modifique la otra copia para usar el método 3 para iniciar y detener la señal. ''Staccato.spin ''Envía 2093 Hz sonidos en sucesiones rápidas (15 Hz por 1 s). CON _clkmode = xtal1 + pll16x _xinfreq = 5_000_000 ' Reloj de Sistema → 80 MHz PUB TestFrequency 'Configure ctra module ctra[30..26] := %00100 ctra[5..0] := 27 frqa := 112_367 ' Activa ctra para "NCO terminación sencilla" ' Activa APIN a P27 ' Activa frqa para 2093 Hz (Nota Do): 'Diez timbres encendido/apagado en 1 segundo. repeat 30 !dira[27] ' Activa P27 a Salida waitcnt(clkfreq/30 + cnt) ' Espera por tono para tocar por 1 s 'Termina programa, también detiene el modulo contador. Use F10 y F11 para comprara programas fácilmente: L Es conveniente colocar el original Staccato.spin en EEPROM con F11, luego usar F10 cuando pruebe las modificaciones. Después de correr el programa nuevo puede presionar y soltar el botón de reinicio de la Plataforma PE para tener una comparación de audio inmediata. Tocando una Lista de Notas DoReMi.spin Es un ejemplo del modulo contador donde se toca una serie de notas. Como no se necesita nada más por el momento el pin E/S que envía la onda cuadrada al piezospeaker esta activo como entrada durante el ¼ que detiene entre notas. El bit 31 del registro phsa aun cambia a una frecuencia dada durante el cuarto detenido, pero la pseudo nota no suena. Los valores del registro frqa se almacenan en un bloque DAT con la instrucción: DAT ... notes long 112_367, 126_127, 141_572, 149_948, 168_363, 188_979, 212_123, 224_734 Un ciclo repeat que mueve una variable index de 0 a 7 se usa para obtener y copiar cada una de las notas al registro frqa. El ciclo copia cada valor sucesivo de la secuencia notes al registro frqa con este comando: repeat index from 0 to 7 'Set the frequency. frqa := long[@notes][index] ... 3 Cargue el objeto DoReMi.spin en el chip Propeller y observe el efecto. Kit Educativo de Practicas Propeller: Fundamentos · Página 145 Práctica de Módulos Contadores y Aplicaciones de Circuitos ''DoReMi.spin ''Toca Do6, Re6, Mi6, Fa6, Sol6, La6, Si6, Do7 como cuartos y detiene cuartos en medio. CON _clkmode = xtal1 + pll16x _xinfreq = 5_000_000 ' Reloj de sistema → 80 MHz PUB TestFrequency | index 'Configure ctra module ctra[30..26] := %00100 ctra[5..0] := 27 frqa := 0 ' Activa ctra para "NCO Terminación sencilla" ' Activa APIN a P27 ' No toca notas todavía repeat index from 0 to 7 frqa := long[@notes][index] ' Asigna la frecuencia. 'Transmite la señal por 1/4 s dira[27]~~ waitcnt(clkfreq/4 + cnt) ' Activa P27 a salida ' Espera por tono para tocar por dira[27]~ waitcnt(clkfreq/4 + cnt) ' Detiene 1/4 s s/ DAT 'Valores 80 MHz frqa para onda cuadrada de aproximaciones de la nota musical con el modulo contador 'configurado a NCO: ' Do6 Re6 Mi6 Fa6 Sol6 La6 Si6 Do7 notes long 56_184, 63_066, 70_786, 74_995, 84_181, 94_489, 105_629, 112_528 Ejemplo de Contador Modo NCO con bit 3 en lugar de bit 31 En modo NCO el estado de salida del pin E/S es controlado por bit 31 del registro PHS. Sin embargo la frecuencia encendido/apagado para cualquier bit en una variable o registro puede calcularse usando la Eq. 4 y asumiendo que un valor es sumado repetidamente a un rango dado: frequency = (value × rate) ÷ 2bit + 1 Eq. 4 El siguiente ejemplo se puede hacer en papel y puede ayudar a clarificar como funciona Ejemplo Bit 3: ¿A qué frecuencia cambia el bit 3 en una variable si se le agrega 4 ocho veces cada Segundo? Aquí value es 4, rate es 8 Hz, y bit es 3, así frequency = = = = (value × rate) ÷ 2bit (4 × 8 Hz) ÷ 23 + 1 32 Hz ÷ 16 2 Hz + 1 La Tabla 7-2 muestra cómo trabaja. Cada 1/8 de segundo el valor 4 se suma a una variable. Como resultado el bit 3 de la variable cambia dos veces cada segundo a 2 Hz. Pagina 146 · Kit Educativo de Prácticas Propeller: Fundamentos 7: Práctica de Módulos Contadores y Aplicaciones de Circuitos Tabla 7-2: Ejemplo Bit 3 Tiempo (s) 0.000 Bit 3 en Variable Valor Variable 0 7 6 5 4 3 2 1 0 0 0 0 0 0 0 0 0 4 0 0 0 0 0 1 0 0 0.125 4 0.250 4 8 0 0 0 0 1 0 0 0 0.375 4 12 0 0 0 0 1 1 0 0 0.500 4 16 0 0 0 1 0 0 0 0 0.625 4 20 0 0 0 1 0 1 0 0 0.750 4 24 0 0 0 1 1 0 0 0 0.875 4 28 0 0 0 1 1 1 0 0 1.000 4 32 0 0 1 0 0 0 0 0 1.125 4 36 0 0 1 0 0 1 0 0 1.250 4 40 0 0 1 0 1 0 0 0 1.375 4 44 0 0 1 0 1 1 0 0 1.500 4 48 0 0 1 1 0 0 0 0 1.625 4 52 0 0 1 1 0 1 0 0 1.750 4 56 0 0 1 1 1 0 0 0 1.875 4 60 0 0 1 1 1 1 0 0 Método Calculador NCO FRQ El objeto TerminalFrequencies.spin le permite ingresar frecuencias de onda cuadrada en la Terminal Serial Parallax y calcula y muestra el valor de registro FRQ y también toca el tono en el piezospeaker de P27 (ver Figura 7-11). El método NcoFrqReg del objeto es una adaptación del método fraction del objeto CTR de la Librería Propeller. Dando una frecuencia de onda cuadrada calcula: frqReg = frequency × (232 ÷ clkfreq) Eq. 5 ...y regresa frqReg. Así, por una frecuencia de onda cuadrada simplemente iguala el registro FRQ a result que regresa la llamada a método NcoFrqReg. Ventana de Transmision Ventana de Recepcion Figura 7-11: Calculando frqa dando una frecuencia en HZ Kit Educativo de Practicas Propeller: Fundamentos · Página 147 Práctica de Módulos Contadores y Aplicaciones de Circuitos El método NcoFrqReg usa cálculos binarios para lograr obtener el valor que fue generado por Eq. 5. También sería posible usar la librería FloatMath para desarrollar estos cálculos. Sin embargo el método NcoFrqReg necesita mucho menos espacio de código que la librería FloatMath. También toma menos tiempo completar los cálculos, así que lo hace buen candidato para un objeto contador matemático. 3 Cargue TerminalFrequencies.spin en EEPROM (F11) a inmediatamente después presione el botón Enable de la Terminal Serial Parallax. (Recuerde, no necesita esperar a que termine de cargar el programa) 3 Cuando muestre el cursor ingrese la porción integra de cada valor de frecuencia (no los valores de registro FRQ) de la Tabla 7-1 en la pagina 139 en la ventana de transmisión de la Terminal Serial Parallax mostrada en la Figura 7-11. 3 Verifique que los cálculos del método NcoFrqReg coinciden con los valores de registro FRQ en la Tabla 3 Recuerde presionar el botón Disable de la Terminal Serial Parallax antes de cargar el siguiente programa. ''TerminalFrequencies.spin ''Ingresa frecuencias para tocar en el piezospeaker y mostrar los valores ''de registro frq con la Terminal Serial Parallax CON _clkmode = xtal1 + pll16x _xinfreq = 5_000_000 ' Reloj de sistema → 80 MHz CLS = 16, CR = 13 ' Caracteres de control ' Terminal Serial Parallax OBJ Debug : "FullDuplexSerialPlus" ' Terminal Serial Parallax ' muestra objeto PUB Init 'Configure ctra module. ctra[30..26] := %00100 ctra[5..0] := 27 frqa := 0 dira[27]~~ ' ' ' ' Activa ctra para "NCO terminación sencilla" Activa APIN a P27 No envía tono aun. pin E/S a salida 'Inicia FullDuplexSerialPlus y limpia la Terminal Serial Parallax. Debug.start(31, 30, 0, 57600) waitcnt(clkfreq * 2 + cnt) Debug.tx(CLS) Main PUB Main | frequency, temp repeat Debug.Str(String("Enter a frequency: ")) frequency := Debug.getDec temp := NcoFrqReg(frequency) Debug.Str(String("frqa = ")) Debug.Dec(temp) Debug.tx(CR) Pagina 148 · Kit Educativo de Prácticas Propeller: Fundamentos 7: Práctica de Módulos Contadores y Aplicaciones de Circuitos 'Transmite la señal por 1 s frqa := temp waitcnt(clkfreq + cnt) frqa~ PUB NcoFrqReg(frequency) : frqReg {{ Regresa frqReg = frequency × (2³² ÷ clkfreq) calculado por división long binaria. Esto es más rápido que la librería de punto flotante y toma menos espacio de código. Este método es una adaptación del método fraction del objeto CTR. }} repeat 33 frqReg <<= 1 if frequency => clkfreq frequency -= clkfreq frqReg++ frequency <<= 1 Use Dos Módulos Contadores para Tocar Dos Notas El objeto TwoTones demuestra como ambos contadores pueden usarse para tocar dos ondas cuadradas diferentes en bocinas diferentes. En este ejemplo todo lo que hace el programa es esperar por un cierto tiempo para pasar antes de ajustar los valores de registro frqa y frqb. El programa podría desarrollar otras tareas antes de regresar y esperar por el registro CLK para obtener el siguiente incremento. 3 Cargue el objeto TwoTones.spin en el chip Propeller. 3 Verifique que toca la onda cuadrada de la aproximación de Do6 en la bocina P27 por un segundo, luego detiene por ½ s y toca Mi6 en la bocina de P2 detiene por otro ½ s y toca ambas notas en ambas bocinas al mismo tiempo. ''TwoTones.spin ''Toca notas individuales con cada bocina luego toca las notas con ambas ''al mismo tiempo CON _clkmode = xtal1 + pll16x _xinfreq = 5_000_000 ' Reloj de sistema → 80 MHz OBJ SqrWave : "SquareWave" PUB PlayTones | index, pin, duration 'Inicializa módulos contadores repeat index from 0 to 1 pin := byte[@pins][index] spr[8 + index] := (%00100 << 26) + pin dira[pin]~~ 'Busca tonos y duraciones en la sección DAT y los toca. repeat index from 0 to 4 frqa := SqrWave.NcoFrqReg(word[@Anotes][index]) frqb := SqrWave.NcoFrqReg(word[@Bnotes][index]) duration := clkfreq/(byte[@durations][index]) waitcnt(duration + cnt) Kit Educativo de Practicas Propeller: Fundamentos · Página 149 Práctica de Módulos Contadores y Aplicaciones de Circuitos DAT pins byte 27, 3 'index 0 durations byte 1, anotes word 1047, bnotes word 0, 1 2, 0, 0, 2 1, 0, 1319, 3 2, 0, 0, 4 1 1047 1319 Dentro de TwoTones.spin El objeto TwoTones declara el objeto SquareWave (ver apéndice A) en su bloque OBJ y le da el apodo SqrWave. Este objeto tiene un método con el mismo nombre y función que NcoFrqReg en el objeto TerminalFrequencies, pero el código se basa en métodos adaptados del objeto CTR de la Librería Propeller para desarrollar el cálculo El primer ciclo repeat en el método PlayTones se inicializa el método counter creando los elementos 8 y 9 del arreglo spr, los cuales son los registros ctra y ctrb. La variable index en ese ciclo es usada para ver los números de pin listados en a secuencia Pins del bloque DAT usando pin := byte[@pin][index]. El segundo ciclo repeat ve elementos en las secuencias durations, anotes y bnotes del bloque DAT. Cada secuencia tiene cinco elementos así el ciclo repeat cataloga de 0 a 4 para obtener cada elemento en cada secuencia. Observe el comando frqa := SquareWave.NcoFrqReg(word[@Anotes][index]) en el segundo ciclo repeat del objeto TwoTones. Primero word[@Anotes][index] regresa el valor de index elementos a la derecha de la etiqueta anotes. El primer ciclo index es 0 así que regresa 1047. La segunda, tercera y cuarta vez index es 1, 2 y 3. Regresa 0 cada vez. La quinta vez index es 4 así que regresa 1047 otra vez. Cada uno de estos valores regresados por word[@Anotes][index] es un parámetro en la llamada de método SquareWave.NcoFrqReg. Finalmente el valor regresado por SquareWave.NcoFrqReg se almacena en la variable frqa. ¿El resultado? Un valor de una frecuencia dada en la secuencia anotes se convierte al valor correcto por frqa para hacer que el modulo contador toque una nota. Control de Contador con un Objeto Si examina el objeto SquareWave quizá note que tiene un método Freq que permite escoger el modulo contador 0 o 1 para contador A o Contador B), un pin y una frecuencia. El método Freq considerablemente simplifica el objeto TwoTones. 3 Compare TwoTonesWithSquareWave (abajo) con el objeto TwoTones (arriba). 3 Cargue TwoTonesWithSquareWave en el chip Propeller y verifique que se comporta igual que el objeto TwoTones. ''TwoTonesWithSquareWave.spin ''Toca notas individuales con cada bocina, luego toca notas con ambos al ''mismo tiempo. CON _clkmode = xtal1 + pll16x _xinfreq = 5_000_000 ' Reloj de sistema → 80 MHz OBJ SqrWave : "SquareWave" Pagina 150 · Kit Educativo de Prácticas Propeller: Fundamentos 7: Práctica de Módulos Contadores y Aplicaciones de Circuitos PUB PlayTones | index, pin, duration 'Busca tonos y duraciones en la sección DAT y los toca. repeat index from 0 to 4 SqrWave.Freq(0, 27, word[@Anotes][index]) SqrWave.Freq(1, 3, word[@Bnotes][index]) duration := clkfreq/(byte[@durations][index]) waitcnt(duration + cnt) DAT pins byte 27, 3 'index 0 durations byte 1, anotes word 1047, bnotes word 0, 1 2, 0, 0, 2 1, 0, 1319, 3 2, 0, 0, 4 1 1047 1319 Aplicaciones Objeto IR y Detección de Distancia con modos NCO y DUTY Cuando apunta el control remoto a la TV y presiona un botón el remoto parpadea un LED IR rápidamente para enviar mensajes al receptor en la TV. EL rango al cual parpadea el LED IR coincide con el filtro dentro del recibidor de la TV. Frecuencias comunes son 36.7, 38, 40, y 56.9 kHz. Estas frecuencias y sistemas de filtro se usan para distinguir mensajes remotos Infra Rojos de Infra Rojos tales como luz solar y la señal de 120Hz que se transmite por la luz de su hogar. L La longitud de onda usada de IR por Control Remoto esta típicamente en el rango de 800 a 940 nm. El remoto transmite la información modulando la señal IR. El tiempo que se envía la señal puede contener información tal como iniciar un mensaje, binario 1, binario 2, etc. Transmitiendo secuencias de señales de tiempo encendido/apagado se pueden completar mensajes para varios botones en solo milisegundos. El LED IR y receptor que son usados para enviar mensajes de componentes de sistemas de entretenimiento también pueden usarse para detectar objetos. En este método el LED IR y el receptor son colocados para que la luz rebote en un objeto y regrese al receptor IR. El LED IR tiene que modular su luz para el paso de frecuencia del receptor. Si la luz del LED IR se refleja en un objeto y regresa al Receptor IR, el Receptor envía una señal indicando que está recibiendo una señal IR. Si el IR no refleja el objeto para regresar al Receptor IR envía una señal indicando que no está recibiendo señal IR. L Este método de detección usa partes baratas y cada vez es más popular en robótica. El receptor IR del kit PE mostrado en la derecha de la Figura 7-12 tiene un filtro de 38 kHz. Un modulo contador en el chip Propeller puede usarse para generar la señal de 38kHz para el LED IR y transmitir para detección de objetos o un control de sistema de entretenimiento. Esta sección de la práctica solo prueba la detección de objetos, pero el mismo principio simple aplicara para decodificación remota y control de componentes de sistemas de entretenimiento 3 Construya el circuito mostrado en la Figura 7-12 – Figura 7-14, usando las fotos de las partes como guía. Kit Educativo de Practicas Propeller: Fundamentos · Página 151 Práctica de Módulos Contadores y Aplicaciones de Circuitos Figura 7-12: Detección por IR Partes y Esquemático Lista de Partes Esquemático ───────────────────────────────────────────────────────────────────────── (1) Resistencia 1 kω +5V (1) Resistencia 10 kω (1) LED IR │ ┌┐ (1) Detector IR └──┤│ (1) LED shield P1 ──────────────┐ 10 kω ┌──┤│‣ (1) LED standoff 1 kω IRLED │ P0 ──────┼──┤│ (misc) Cables │ └┘ GND PNA4602 GND o equivalente ────────────────────────────────────────────────────────────────────────── La Figura 7-13 muestra como ensamblar el LED IR para detección de objetos. Primero inserte el LED IR en el soporte del LED. Posteriormente ensamble el protector del LED al soporte. Figura 7-13: Ensamble del IR LED Un arreglo de la placa de prueba que funciona para el LED IR y receptor se ve en la Figura 7-14. Note como la fuente de 5V del receptor es un puente del centro de la tarjeta (K, 3) a la izquierda del contacto de la placa (G, 1). La tierra del receptor IR es un puente del contacto del centro de la placa (K, 4) a la izquierda (G, 2). El cátodo del LED IR se conecta al riel de la izquierda vertical (NEGRO, 4). Una resistencia de 1 kΩ está en serie entre el ánodo del LED IR y P1. Es importante conectar una resistencia más grande de la salida de 5V a la entrada 3.3V del chip Propeller; una resistencia de 10 kΩ se usa entre la salida 5V del receptor IR y el pin E/S P0 del chip Propeller. Una resistencia de 1 a 2 kΩ es útil en serie con el LED IR para reducir el rango de detección. Una resistencia pequeña como 100 Ω puede ocasionar una detección fantasma de objetos lejanos como el techo. Figura 7-14: LED IR y Detector de Orientación Pagina 152 · Kit Educativo de Prácticas Propeller: Fundamentos 7: Práctica de Módulos Contadores y Aplicaciones de Circuitos Detección de Objetos por IR con NCO El objeto IrObjectDetection programa una señal de 38kHz usando modo NCO. Cada que el pin de E/S conectado al LED IR se programa a salida se transmite 38kHz. En un ciclo repeat el programa permite al LED IR transmitir la señal de 38 kHz IR por 1ms, luego guarda ina[0] en una variable llamada state y lo muestra en la Terminal Serial Parallax (Figura 7-15). Figura 7-15: Pantalla Detección de Objeto 3 Cargue IrObjectDetection.spin en la EEPROM (F11) e inmediatamente después presione el botón Enable de la Terminal. 3 El estado debería ser 1 sin obstáculos o 0 cuando coloca su mano frente el Receptor / LED IR '' IrObjectDetection.spin '' Detecta objetos con LED IR y receptor y muestra en la Terminal Serial '' Parallax CON _clkmode = xtal1 + pll16x _xinfreq = 5_000_000 ' Reloj de Sistema → 80 MHz ' Constantes para la Terminal Serial Parallax. HOME = 1, CR = 13, CLS = 16, CRSRX = 14, CLREOL = 11 OBJ Debug SqrWave : "FullDuplexSerialPlus" : "SquareWave" PUB IrDetect | state 'Inicia 38 kHz onda cuadrada SqrWave.Freq(0, 1, 38000) dira[1]~ 'Inicia FullDuplexSerialPlus Debug.start(31, 30, 0, 57600) waitcnt(clkfreq * 2 + cnt) Debug.tx(CLS) ' Señal 38 kHz → P1 ' Activa pin E/S a entrada ' cuando no se necesita señal ' Inicia FullDuplexSerialPlus ' Da tiempo de presionar Enable ' Limpia Pantalla repeat ' Detecta objeto. dira[1]~~ waitcnt(clkfreq/1000 + cnt) ' pin E/S → salida para ' transmitir 38 kHz ' Espera 1 ms Kit Educativo de Practicas Propeller: Fundamentos · Página 153 Práctica de Módulos Contadores y Aplicaciones de Circuitos state := ina[0] dira[1]~ ' Almacena IR salida detector ' Pin E/S → entrada para detener señal ' Muestra detección (0 detectado, 1 no detectado) Debug.str(String(HOME, "State = ")) Debug.Dec(state) Debug.str(String(CR, "Object ")) if state == 1 Debug.str(String("not ")) Debug.str(String("detected.", CLREOL)) waitcnt(clkfreq/10 + cnt) Detección de Distancia con IR usando cambios NCO y DUTY Si el LED IR brilla más hace el detector más intuitivo. Si brilla menos lo hace menos eficiente. Recuerde que el modo DUTY del modulo contador puede usarse para controlar el brillo del LED e incluso para intercambiar el brillo de bajo a brilloso (ver página 130). Este mismo alcance duty puede combinarse con la señal NCO para el ejemplo de detección de objetos con IR para hacer que el LED parpadee a 38kHz cambiando de menor a mayor brillo. Con cada incremento en brillo la salida del detector IR puede ser verificada nuevamente en un ciclo. El número de veces que el detector IR reporte que detecto algo estará relacionado a la distancia del objeto desde el detector LED IR. Aun si el circuito de la Figura 7-12 puede usarse para detección de distancia con una combinación NCO y señales DUTY el circuito en la Figura 7-16 lo hace posible para obtener mejores resultados del receptor IR. En vez de conectar el cátodo del LED IR a tierra se conecta a P2. El programa puede entonces cambiar el voltaje aplicado al cátodo del LED IR de 0 a 3.3 V a través de P2 mientras la señal de P1 transmite la señal NCO de 38kHz a la terminal del ánodo en l circuito. Como un LED es una válvula de 1 sentido la porción baja de la señal de 38kHz no se transmite porque es menor que el voltaje DC que la señal duty producida en P2. Durante las porciones altas de la señal de 38kHz los voltajes incrementados aplicados a P2 reducen el voltaje a través del circuito LED lo cual a su vez reduce el brillo. Así es la misma señal de 38 kHz solo sucesivamente menos brillosa. Figura 7-16: Detección IR Partes y Esquemático Lista de Partes Esquemático ────────────────────────────────────────────────────────────────────────── (1) Resistencia 100 ω IR Detector (1) Resistencia 10 kω (1) LED IR (1) Detector IR (1) LED Protección P1 ──────────── P2 (1) LED Soporte 100ω LED IR (misc) Cables +5V │ ┌┐ └──┤│ 10 kω ┌──┤│‣ P0 ──────┼──┤│ │ └┘ GND PNA4602 o equivalente ────────────────────────────────────────────────────────────────────────── Pagina 154 · Kit Educativo de Prácticas Propeller: Fundamentos 7: Práctica de Módulos Contadores y Aplicaciones de Circuitos El objeto IrDetector.spin de abajo desarrolla la detección de distancia justo como lo platicamos. EL objeto padre tiene que llamar al método init para decirle cuales pins se conectan al ánodo y cátodo del circuito LED IR y las salidas del Receptor IR. Cuando el método distance se llama utiliza el cambio duty que platicamos y los números de pin que pasaron al método init para medir la distancia de los objetos. El método distance del objeto IrDetector utiliza el objeto SquareWave para comenzar a transmitir la señal de 38kHz al ánodo del circuito LED IR usando el contador B. Luego configura el contador A para modo DUTY de terminación sencilla e inicializa frqa y phsa a 0 lo cual resulta en una baja señal inicial al cátodo del circuito LED IR. Después un ciclo repeat cambia muy rápidamente duty de 0/256 a 255/256. Con cada cambio se incrementa el voltaje al circuito LED IR en el cátodo haciendo menos brilloso el LED IR y el Detector IR con menor alcance. Entre cada incremento duty, el ciclo suma la salida del receptor IR al valor de regreso dist. Como la salida del receptor IR esta en alto cuando no ve el reflejo IR dist almacena el número de veces en 256 que no vio un objeto. Cuando el objeto es más cercano este número será menor, cuando es más lejano el numero será mayor. Así después del ciclo el valor de regreso del método dist contiene una representación de la distancia del objeto. Tenga en cuenta que esta medición de distancia puede variar con la superficie que refleja el IR. L Por ejemplo, si la distancia regresa 175, la distancia medida por una hoja Blanca de papel podrá ser cinco veces la distancia de una hoja de vinil negro. La razón es que el papel blanco refleja el infrarrojo por lo que será visible al receptor mucho más lejos. En contraste el vinil negro tiende a absorberlo y solo es vivible en rangos muy cortos. ''IrDetector.spin CON scale = 16_777_216 ' 2³²÷ 256 OBJ SquareWave : "SquareWave" ' Importa objeto SquareWave ' SquareWave VAR long anode, cathode, recPin, dMax, duty PUB init(irLedAnode, irLedCathode, irReceiverPin) anode := irLedAnode cathode := irLedCathode recPin := irReceiverPin PUB distance : dist {{ Realiza una prueba de respuesta en el Receptor/LED IR y regresa dist, Un valor de zona de 0 (mas cercano) a 256 (objeto no detectado). }} 'Inicia señal de 38 kHz. SquareWave.Freq(1, anode, 38000) ' ctrb 38 kHz dira[anode]~~ 'Configura señal Duty. ctra[30..26] := %00110 ctra[5..0] := cathode frqa := phsa := 0 dira[cathode]~~ ' ' ' ' Activa Activa Activa Activa ctra a modo DUTY ctra's APIN registro frqa P5 a salida Kit Educativo de Practicas Propeller: Fundamentos · Página 155 Práctica de Módulos Contadores y Aplicaciones de Circuitos dist := 0 repeat duty from 0 to 255 frqa := duty * scale waitcnt(clkfreq/128000 + cnt) dist += ina[recPin] ' ' ' ' Cambia duty de 0 a 255 Actualiza registro frqa Detiene por 1/128 s Objecto no detectado? ' Agrega 1 a dist. Figura 7-17: Pantalla de Detección de Distancia El objeto TestIrDutyDistanceDetector obtiene medidas de distancia del objeto IrDetector y las muestra en la Terminal erial Parallax (Figura 7-17). Con la resistencia de 100 Ω en serie con el LED IR si el sistema detecta la altura de la mesa al techo o no dependerá de que tan alto y que tan reflectivo sea el techo y que tan sensitivo es el detector en particular. Si el sistema no detecta objetos regresara 256. La luz del día entrando por la ventana podrá generar un poco de ruido en la salida del detector resultando en valores menores que 256 aun cuando no se detecta un objeto. Tan pronto se acerca el objetivo al receptor LED/IR la medición se decrementara, pero no a cero típicamente a menos que el LED IR este apuntando directamente en el fototransistor del receptor IR (La concha negra debajo de los metales cruzados). 3 Asegúrese que IrDetector.spin está grabado en la misma carpeta que TestIrDutyDistanceDetector.spin y FullDuplexSerialPlus.spin. 3 Use la herramienta Propeller para cargar TestIrDutyDistanceDetector.spin en la EEPROM (F11) e inmediatamente presione el botón Enable de la Terminal Serial Parallax. 3 Experimente con una variedad de objetivos y distancias para obtener una idea de para qué puede ser útil el sistema. '' TestIrDutyDistanceDetector.spin '' Prueba distancia de detección con el objeto IrDetector. CON _xinfreq = 5_000_000 _clkmode = xtal1 + pll16x CLS = 16, CRSRX = 14, CLREOL = 11 OBJ ir : "IrDetector" debug : "FullDuplexSerialPlus" PUB TestIr | dist 'Inicia comunicación serial y espera 2 s para la conexión con la 'Terminal Serial Parallax. Pagina 156 · Kit Educativo de Prácticas Propeller: Fundamentos 7: Práctica de Módulos Contadores y Aplicaciones de Circuitos debug.Start(31, 30, 0, 57600) waitcnt(clkfreq * 2 + cnt) debug.tx(CLS) debug.str(string("Distance = ")) 'Configure IR detectors. ir.init(1, 2, 0) repeat 'Obtiene y muestra la distancia. debug.str(string(CRSRX, 11)) dist := ir.Distance debug.dec(dist) debug.str(string("/256", CLREOL)) waitcnt(clkfreq/3 + cnt) Contando Cambios con Modos POSEDGE y NEGEDGE Los módulos contadores también tienen modos detectores de limites (ver Figura 7-18). En modo POSEDGE un modulo contador suma FRQ a PHS cuando detecta un cambio de bajo a alto en un pin de E/S. El modo NEGEDGE hace que se ocurra la suma cuando detecta un cambio de alto a bajo. Cualquiera puede usarse para contar los ciclos de señales que pasan por encima y de regreso debajo del límite lógico de 1.65 V. (Tenga cuidado ya que igual que POS los modos POSEDGE y NEGEDGE tienen opciones “con retroalimentación” aun si no se muestra en nuestro extracto de la Tabla de Modos de Modos Contadores en la Figura 7-18). L Entrada o Salida? Estos modos contadores pueden usarse para contar los cambios de una señal aplicada al pin de E/So a los cambios de la señal de la transmisión de un pin de E/S. Figura 7-18: Extracto de Detector de Limites de la Tabla de Modos Contadores del Objeto CTR Acumulado APIN BPIN CTRMODE Descripción FRQ a PHS output* output* ┌────────┬─────────────────────────────┬────────────┬────────────┬────────────┐ │ %00000 │Contador deshabilitado(off) │ 0 (nunca) │0(ninguno) │ 0(ninguno) │ ├────────┼─────────────────────────────┼────────────┼────────────┼────────────┤ . . . │ %01010 │ detector POSEDGE │ A¹ & !A² │ 0 │ 0 │ . . . │ %01110 │ detector NEGEDGE │ !A¹ & A² │ 0 │ 0 │ . . . │ %11111 │ LOGIC siempre │ 1 │ 0 │ 0 │ └────────┴─────────────────────────────┴────────────┴────────────┴────────────┘ * debe activar el bit DIR correspondiente para afectar el pin A¹ = APIN entrada retrasada por 1 clock A² = APIN entrada retrasada por 2 clocks B¹ = BPIN entrada retrasada por 1 clock Observe en las notas del extracto en la Tabla del Modo de Contadores en la Figura 7-18 que la suma de FRQ a PHS sucede un ciclo después del límite. Esto podría hacer la diferencia en algunos Kit Educativo de Practicas Propeller: Fundamentos · Página 157 Práctica de Módulos Contadores y Aplicaciones de Circuitos lenguajes de programación donde el tiempo es justo, pero no tiene un impacto significativo en la interpretación del programa en lenguaje Spin Los pasos para programar un contador aun contemplan la activación del campo bit de CTRMODE del registro CTR (bits 30..26) y su bit de campo APIN (bits 5..0) junto con la programación del registro FRQ al valor que debería ser sumado al registro PHS cuando se detecta al límite. Antes de la medición pueden activarse a cero. ctrb[30..26] := %01110 ctrb[5..0] := 27 frqb~ phsb~ Un ejemplo del siguiente programa que demuestra una forma de usar el modo detector NEGEDGE para controlar la duración de un tono tocado en una bocina. El modulo contador A se activa para transmitir una onda cuadrada de 2kHz en modo NCO de terminación sencilla en el mismo pin E/S que el registro del contador B va a monitorear con el modo detector NEGEDGE. El registro frqb se activa a 1 para que con cada ciclo de reloj se sume 1 a frqb. Para tocar un tono de 2kHz por 1 segundo toma 2000 ciclos. El comando repeat while phsb < 2000 solo permite al programa continuar y limpiar frqa para detener el sonido después de que se han detectado los 2000 cambios. frqb := 1 frqa := SquareWave.NcoFrqReg(2000) repeat while phsb < 2000 frqa~ L Censando: Este ejemplo censa el registro phsb esperando a que el numero de cambios exceda un cierto valor, pero no necesariamente necesita censar durante los 2000 ciclos. Esto libera el cog para hacer algunas cosas mientras la señal se está transmitiendo y verifica periódicamente para revisar que tan cerca esta phsb de los 2000 cambios. 3 Cargue CountEdgeTest.spin en el chip Propeller y verifique que el contador de limites se puede usar para controlar la duración de un tono. {{ CountEdgeTest.spin Transmite la señal NCO con el contador A Usa el contador B para monitorear los límites negativos de la señal Y detener la señal después de los 2000. }} CON _clkmode = xtal1 + pll16x _xinfreq = 5_000_000 'Reloj de Sistema → 80 MHz OBJ SqrWave : "SquareWave" PUB TestFrequency ' Configura Módulos Contadores. ctra[30..26] := %00100 ctra[5..0] := 27 'ctra modulo a modo NCO ctrb[30..26] := %01110 'ctrb modulo a NEGEDGE detector Pagina 158 · Kit Educativo de Prácticas Propeller: Fundamentos 7: Práctica de Módulos Contadores y Aplicaciones de Circuitos ctrb[5..0] := 27 frqb~ phsb~ 'Transmite la señal por 2000 ciclos. outa[27]~ dira[27]~~ ' P27 → salida-baja frqb := 1 frqa := SqrWave.NcoFrqReg(2000) ' Inicia la señal repeat while phsb < 2000 ' Espera por 2k repeticiones frqa~ ' Detiene la señal Detección de Limites más Rápido El siguiente programa puede parar frecuencias cerca de 43.9kHz en el límite de caída. Para controlar el número de pulsos entregados por señales más rápidas un programa en lenguaje ensamblador será más rápido y puede detectar el límite de caída y detenerlo en un par de ciclos de reloj. BetterCountEdges.spin monitorea una señal de 3kHz transmitida por el Contador A. En vez de monitorear limites negativos activa el contador B para monitorear limites positivos en P27 con ctrb[30..26] := 01010 and ctrb[5..0] := 27. Activa frqb a 1 para que se sume 1 al registro PHS con cada límite positivo. En vez de limpiar el registro PHS y esperar los 3000 limites positivos activa phsb a -3000. Por último activa el bit 27 a 1 en una variable llamada a con el comando a |< 27. 3 Observe la función del operador |< en el Manual Propeller. Cuando el comando frqa := SquareWave.CalcFreqReg(3000) se ejecuta P27 envía una onda cuadrada de 3 kHz. Como phsb es un bit-direccional el comando repeat while phsb[31] se repite mientras el registro phsb es 1. Recuerde que el bit mas alto de un registro o variable será 1 aunque el valor sea negativo. Así phsb[31] será 1 (no cero) mientras phsb sea negativo. El registro phsb se mantendrá negativo hasta que frqb = 1 se suma a phsb 3000 veces. Cuando el ciclo repeat termina, la señal esta en alto porque estaba buscando un límite positivo. La meta es detener la señal después de que baja. El comando waitpeq(0, a, 0) espera hasta que P27 es cero. El comando waitpeq(0, |< 27, 0) también se puede usar pero el programa no responde tan rápido porque tiene que calcular primero |< 27; mientras waitpeq(0, a, 0) ya tiene el valor calculado y almacenado en la variable a. Así el comando waitpeq permite continuar el programa hasta frqa~ para limpiar el registro y detener la señal en salida baja después del ciclo 3000. 3 Vea y lea acerca de waitpeq en el Manual Propeller 3 Cargue BetterCountEdges.spin en el chip Propeller y verifique que toca la señal de 3 kHz por 1 s. 3 Si usted tiene un osciloscopio asigne la señal para 10 ciclos en vez de 3000. Entonces intente incrementar la frecuencia y vea la máxima frecuencia que se entregan 10 ciclos. ''BetterCountEdges.spin CON _clkmode = xtal1 + pll16x _xinfreq = 5_000_000 'Reloj de Sistema → 80 MHz Kit Educativo de Practicas Propeller: Fundamentos · Página 159 Práctica de Módulos Contadores y Aplicaciones de Circuitos OBJ SquareWave : "SquareWave" PUB TestFrequency | a, b, c ' Configura Módulos Contadores. ctra[30..26] := %00100 ctra[5..0] := 27 outa[27]~ dira[27]~~ 'ctra modulo a modo NCO ctrb[30..26] := %01010 'ctrb modulo a detector 'POSEDGE ctrb[5..0] := 27 frqb := 1 phsb := -3000 'Suma 1 por cada ciclo 'Inicia el contador a -3000 a := |< 27 'Activa un pin mascara para 'el comando waitpeq frqa := SquareWave.NcoFrqReg(3000) repeat while phsb[31] 'inicia la onda cuadrada 'Espera por el cambio 3000 'de alto a bajo 'Espera por señal baja 'Detiene la señal waitpeq(0, a, 0) frqa~ 'P27 → salida-baja PWM con Modos NCO PWM significa Modulación de Ancho de Pulso, y puede ser útil para servos y control de motores. Un modulo contador operando en modo NCO puede usarse para generar pulsos de duración precisa y un ciclo repeat con un comando waitcnt puede usarse para mantener el tiempo de ciclo de la señal Vamos a ver como se envía un pulso sencillo con un modulo contador. Este método preciso es tan bueno como el ciclo de Reloj del chip Propeller. Después de activar el contador en modo NCO solo active el registro PHS a la duración que se quiere que dure el pulso cargándolo en un valor negativo. Por ejemplo el comando phsa := -clkfreq en el siguiente ejemplo activa el registro phsa a 80,000,000. Recuerde que el bit 31 de un registro será 1 mientras sea negativo, y también recuerde que el bit 31 del registro PHS en modo NCO controla un estado de salida de un pin de E/S. Así que cuando el registro PHS se activa como valor negativo (y FRQ a 1) el pin de E/S enviara una señal alta por el mismo número de ciclos de reloj que tiene el numero negativo en PHS. 3 El ejemplo de programa en esta sección de PWM enviara señales al circuito LED de la Figura 7-6 en la pagina 131. Si removió el circuito de la Figura 7-6 en la página 131 de su tarjeta reconstrúyalo ahora. Enviando un Pulso Sencillo El objeto SinglePulseWithCounter usa esta técnica para enviar un pulso de 1 segundo al LED en P4. Aun considerando que el programa puede moverse tan pronto como active el registro PHS a clkfreq, no puede ignorar el registro PHS indefinidamente. ¿Por qué? Porque 231 – 1 = 2,147,483,647 ciclos de reloj después el registro PHS cambiara de un numero positivo muy grande a un numero negativo muy grande y volverá a contar. Como el bit 31 del registro PHS cambiara de 0 a 1 en ese punto el pin de E/S cambiara de bajo a alto sin ninguna razón aparente. Pagina 160 · Kit Educativo de Prácticas Propeller: Fundamentos 7: Práctica de Módulos Contadores y Aplicaciones de Circuitos 3 Cargue SinglePulseWithCounter.spin en el chip Propeller y verifique que envía un pulso de 1 segundo. Este pulso durara exactamente 80,000,000 ciclos de reloj. 3 Con el chip Propeller corriendo a 80 MHz el pin cambiara a alto nuevamente después de aproximadamente 26.84 segundos después. Verifique esto con una calculadora y esperando 27 segundos después de que la señal alta de 1 segundo término. 3 Si tiene un osciloscopio intente programar el registro PHS a -1 y vea como puede detector el pulso de 12.5 ns que transmite el chip Propeller. También intente programar phsa a clkfreq/1_000_000 por un pulso de 1 µs. ''SinglePulseWithCounter.spin ''Envía un pulso alto al LED en P4 que dura exactamente 80_000_000 ciclos de reloj CON _clkmode = xtal1 + pll16x _xinfreq = 5_000_000 ' Reloj de Sistema → 80 MHz PUB TestPwm | tc, tHa, tHb, ti, t ctra[30..26] := %00100 ctra[5..0] := 4 frqa := 1 dira[4]~~ ' Configura Contador A a NCO phsa := - clkfreq ' Envía el pulso ' Mantiene corriendo el programa y el pulso tiene tiempo para terminar. repeat Modulación de Ancho de Pulso Para una señal repetitiva PWM el programa tiene que establecer el tiempo de ciclo usando waitcnt. Entonces la duración de pulso se determina cada vez a través del ciclo activando el registro PHS a un valor negativo al principio del ciclo. El objeto 1Hz25PercentDutyCycle.spin parpadea el LED cada Segundo por 0.25 segundos. El ciclo repeat repite una vez cada segundo y el contador envía una señal alta al LED P4 por ¼ s con cada repetición. EL comando tC := clkfreq activa la variable que detiene el tiempo de ciclo a el numero de ciclos de reloj en un segundo. El comando tHa := clkfreq/4 activa el tiempo en alto para el modulo contador A a ¼ s. El comando t := cnt graba el registro cnt a un tiempo inicial. Después un ciclo repeat administra el tren de pulso. Empieza enviando phsa igual a -tHa, lo cual inicia el pulso que durara exactamente clkfreq/4 ciclos. Después suma tC, el tiempo de ciclo de clkfreq, a t, el tiempo meta para el siguiente ciclo. El comando waitcnt(t) espera el numero de ciclos en 1 s antes de repetir el ciclo. 3 Corra el programa y verifique la señal alta de ¼ s cada 1 s en el LED conectado a P4 3 Si tiene un osciloscopio intente una señal que dure 1.5 ms, repetida cada 20 ms. Esto podría ser bueno para hacer que un servo detenga su posición central. ''1Hz25PercentDutyCycle.spin ''Envía una señal de 1 Hz a 25% del ciclo de trabajo al LED en P4. CON _clkmode = xtal1 + pll16x _xinfreq = 5_000_000 ' Reloj de Sistema → 80 MHz Kit Educativo de Practicas Propeller: Fundamentos · Página 161 Práctica de Módulos Contadores y Aplicaciones de Circuitos PUB TestPwm | tc, tHa, t ctra[30..26] := %00100 ctra[5..0] := 4 frqa := 1 dira[4]~~ ' Configura Contador A a NCO tC := clkfreq tHa := clkfreq/4 t := cnt repeat phsa := -tHa t += tC waitcnt(t) ' Activa ciclo y tiempo alto ' ' ' ' ' Marca tiempo de contador Repite señal PWM Activa el Pulso Calcula ciclo repeat Espera el siguiente ciclo Este es otro lugar donde poder examinar las señales diferenciales. Las únicas diferencias entre este ejemplo y el previo son: • • • El modo se active a NCO diferencial usando ctra[30..26] := %00101 (diferencial) en vez de ctra[30..26] := %00100 (terminación sencilla) Un segundo pin de E/S se selecciona para señales diferenciales con ctra[14..9] := 5 P4 y P5 se activan a salidas con dira[4..5]~~ en vez de solo dira[4]~~ 3 Pruebe el programa y verifique que P5 está encendido cada vez que P4 está apagado. ''1Hz25PercentDutyCycleDiffSig.spin ''Versión diferencial de 1Hz25PercentDutyCycle.spin CON _clkmode = xtal1 + pll16x _xinfreq = 5_000_000 ' reloj → 80 MHz PUB TestPwm | tc, tHa, t ctra[30..26] := %00101 ctra[5..0] := 4 ctra[14..9] := 5 frqa := 1 dira[4..5]~~ ' Contador A → NCO (diferencial) ' Selecciona pin E/S ' Suma 1 a phs con cada ciclo ' de reloj ' Activa ambos pins ' diferencial a salida ' El resto es lo mismo que 1Hz25PercentDutyCycle.spin tC := clkfreq tHa := clkfreq/4 t := cnt ' Activa ciclo y tiempos repeat phsa := -tHa t += tC waitcnt(t) ' ' ' ' ' Marca tiempo de contador Repite señal PWM active el Pulso Calcula el siguiente ciclo Espera el siguiente ciclo El objeto TestDualPwm.spin usa ambos contadores para transmitir señales PWM que tienen el mismo tiempo de ciclo pero independientemente de los tiempos altos (1/2 s de tiempo alto con contador A y 1/5 con contador B). Las señales del ciclo DUTY se transmiten en P4 y P6. Pagina 162 · Kit Educativo de Prácticas Propeller: Fundamentos 7: Práctica de Módulos Contadores y Aplicaciones de Circuitos 3 Intente hacer ambas señales diferenciales usando los pins E/S P4..P7. 3 Nuevamente si tiene un osciloscopio intente crear una señal de 1.3 ms y la otra de 1.7 ms. Esto podría hacer un robot con dos controles servos de rotación continua para ir hacia delante o hacia atrás. {{ TestDualPWM.spin Demuestra usando dos módulos contadores el envió de una señal PWM. El tiempo de ciclo es el mismo para ambas señales pero los tiempos altos son independiente uno del otro. }} CON _clkmode = xtal1 + pll16x _xinfreq = 5_000_000 ' Reloj de sistema → 80 MHz PUB TestPwm | tc, tHa, tHb, t ctra[30..26] := ctrb[30..26] := %00100 ' ' ' ' ctra[5..0] := 4 ctrb[5..0] := 6 frqa := frqb := 1 Contadores A y B → NCO terminación sencilla Activa los pins para contadores de control ' Suma 1 a phs con cada ' ciclo de reloj dira[4] := dira[6] := 1 ' Activa pins E/S a salida tC := clkfreq tHa := clkfreq/2 ' Activa tiempo de ciclo ' Activa tiempos altos para ' ambas señales tHb := clkfreq/5 t := cnt ' Marca tiempo actual repeat phsa := -tHa ' Repite señal PWM ' Definen e inicia pulso A phsb := -tHb ' Definen e inicia pulso B t += tC waitcnt(t) ' Calcula siguiente ciclo ' Espera siguiente ciclo Una variable o constante puede usarse para almacenar un incremento de tiempo para pulso y tiempo de ciclo. En el ejemplo la variable tInc almacena clkfreq/1_000_000. Cuando se activa tC a 50_000 * tInc, significa que el tiempo de ciclo será 500,000 µs. Así mismo tHa será 100,000 µs. ''SinglePwmwithTimeIncrements.spin CON _clkmode = xtal1 + pll16x _xinfreq = 5_000_000 ' Reloj de sistema → 80 MHz PUB TestPwm | tc, tHa, t, tInc ctra[30..26] := %00100 ctra[5..0] := 4 frqa := 1 ' ' ' ' ' Configura Contador A a NCO Activa salida de contador a P4 Suma 1 a phsa con cada ciclo de reloj Kit Educativo de Practicas Propeller: Fundamentos · Página 163 Práctica de Módulos Contadores y Aplicaciones de Circuitos dira[4]~~ ' P4 → salida tInc := clkfreq/1_000_000 tC := 500_000 * tInc ' Determina incremento tiempo ' Usa incremento de tiempo ' para activar tiempo de ciclo tHa := 100_000 * tInc ' Usa incremento de tiempo ' para activar tiempo alto ' El resto es lo mismo que 1Hz25PercentDutyCycle.spin t := cnt ' Marca tiempo contador repeat phsa := -tHa t += tC waitcnt(t) ' ' ' ' Repite señal PWM Activa el pulso Calcula siguiente ciclo Espera siguiente ciclo Prueba y Muestra PWM – Agrega un Objeto, Cog y Par de Contadores Como el chip Propeller tiene múltiples procesadores algunos pueden correr aplicaciones mientras otros monitorean y diagnostican códigos. En este ejemplo vamos a incorporar los objetos ya probados en la sección anterior MonitorPWM y FullDuplexSerialPlus (monitoreo/diagnostico) en el objeto TestDualPwm (aplicación). El objeto MonitorPWM es importante porque usa contadores en un Segundo cog para monitorear el tren de pulso transmitido por el cog que está ejecutando el código TestDualPwm (que también está utilizando dos contadores). NOTA: después de demostrar un ejemplo de uso del objeto MonitorPWM del objeto TestDualPwmWithProbes, vamos a examinar a detalle el objeto MonitorPWM. La aplicación TestDualPwmWithProbes es una versión modificada de TestDualPwm que hace posible monitorear el tren de pulsos enviados en P4 y P6 probándolos con P8. La información de prueba se muestra en la Terminal Serial Parallax mostrado en la Figura 7-19. El esquemático en la Figura 7-19 mientras el pin E/S P8 probando P6. En otras palabras hay un puente conectando P6 y P8. Para probar P4 simplemente se desconecte P6 y conecte P4. Las mediciones son mostradas en la Terminal Serial Parallax en términos de 12.5 ns ciclos de reloj. Sin embargo la aplicación puede fácilmente modificarse para mostrarlos en términos de ms µs, duty cycle, etc. Una segunda instrucción de MonitorPWM puede declararse y usarse para monitorear simultáneamente otro canal. Figura 7-19: Use P8 para Medir una Señal PWM de P6 Lista de Partes ─────────────────── (2) Resistencia 100 ω (1) LED - verde (1) LED - amarillo (misc) Cables ─────────────────── Esquemático ────────────────────── LED 100 ω verde P4 ────────────┐ LED │ 100 ω amarillo │ P6 ┳───────────┫ │ │ P8 ┘ GND ────────────────────── Pagina 164 · Kit Educativo de Prácticas Propeller: Fundamentos 7: Práctica de Módulos Contadores y Aplicaciones de Circuitos El código agregado al objeto TestDualPwm monitorea y muestra el tren de pulsos en el objeto TestDualPwmWithProbes. La mayoría del código agregado es para mostrar los valores en la Terminal Serial Parallax todo lo que se necesita incorporar al objeto es: • • • Tres declaraciones variables: tHprobe, tLprobe, y pulseCnt Una declaración de objeto: probe : "MonitorPWM" Una llamada al método start del objeto MonitorPWM que pasa la dirección de tHprobe, tLprobe y pulseCnt, como esta: probe.start(8, @tHprobe, @tLprobe, @pulseCnt). Después de eso el objeto MonitorPWM automáticamente actualiza los valores almacenados por tHprobe, tLprobe, y pulseCnt con cada nuevo ciclo. Estas mediciones son mostradas en la Terminal Serial con debug.dec(tHprobe), debug.dec(tLprobe), y debug.dec(pulseCnt). 3 Asegúrese que el objeto TestDualPwmWithProbes.spin está guardado en la misma carpeta que MonitorPwm.spin y FullDuplexSerialPlus.spin. 3 Cargue TestDualPwmWithProbes.spin en la EEPROM (F11) e inmediatamente presione el botón Enable de la Terminal Serial Parallax. 3 Desconecte la terminal del cable P8 → P6 que está conectado en P6 y conéctelo a P4. La pantalla deberá mostrar la actualización de los diferentes tiempos altos y bajos. {{ TestDualPwmWithProbes.spin Demuestra cómo usar un objeto que usa contadores en otro cog Para medir (probar) actividad de pin E/S Generada por los contadores en este cog. }} CON _clkmode = xtal1 + pll16x _xinfreq = 5_000_000 ' Reloj de sistema → 80 MHz ' Constantes de la Terminal Serial Parallax CLS = 16, CR = 13, CLREOL = 11, CRSRXY = 2 OBJ debug : "FullDuplexSerialPlus" probe : "MonitorPWM" PUB TestPwm | tc, tHa, tHb, t, tHprobe, tLprobe, pulseCnt ' Inicia MonitorServoControlSignal. probe.start(8, @tHprobe, @tLprobe, @pulseCnt) 'Inicia FullDuplexSerialPlus. Debug.start(31, 30, 0, 57600) waitcnt(clkfreq * 2 + cnt) Debug.str(String(CLS, "Cycle Times", CR, "(12.5 ns clock ticks)", CR)) Debug.str(String("tH = ", CR)) Debug.str(String("tL = ", CR)) Debug.str(String("reps = ")) ctra[30..26] := ctrb[30..26] := %00100 ctra[5..0] := 4 ctrb[5..0] := 6 frqa := frqb := 1 ' ' ' ' Contadores A y B → NCO Terminación sencilla Activa pins para controlar contadores ' suma 1 a phs con cada Kit Educativo de Practicas Propeller: Fundamentos · Página 165 Práctica de Módulos Contadores y Aplicaciones de Circuitos ' ciclo de reloj dira[4] := dira[6] := 1 ' Activa pins E/S a Salida tC := clkfreq tHa := clkfreq/2 ' Activa tiempo de ciclo ' Activa tiempos altos para ' ambas señales tHb := clkfreq/5 t := cnt ' Marca tiempo actual. repeat phsa := -tHa ' Repite señal PWM ' Define e inicia el pulso A phsb := -tHb ' Define e inicia el pulso B t += tC ' Calcula siguiente ciclo ' repite ' Muestra información debug.str(String(CLREOL, CRSRXY, 5, 2)) debug.dec(tHprobe) debug.str(String(CLREOL, CRSRXY, 5, 3)) debug.dec(tLprobe) debug.str(String(CLREOL, CRSRXY, 7, 4)) debug.dec(pulseCnt) waitcnt(t) ' Espera por siguiente ciclo Monitoreo PWM – Ejemplo de un Objeto que Usa Contadores en Otro Cog El objeto MonitorPWM puede usarse por otros objetos para medir las características de un tren de pulsos (su tiempo alto y bajo). El código en otros cogs pueden transmitir pulsos y la aplicación puede usar este objeto para medir el tiempo alto y bajo de los pulsos. Hasta este punto todos los objetos han usado los módulos contadores en el cog 0. En contraste el objeto MonitorPWM inicia un cog Nuevo y usa los contadores del Nuevo cog para medir el pulso alto y bajo. Después pone a disposición las mediciones disponibles para otros objetos y acordar las localidades en la memoria principal RAM. Hay tres claves importantes para escribir objetos que inician cogs y usan los módulos contadores de esos cogs. Téngalo en cuenta mientras examina el objeto MonitorPWM: 1) Si el objeto se inicia en un cog Nuevo debe tener métodos start y stop y variables globales llamadas cog y stack. Esta es una regla introducida por Parallax que s usa en la Librería Propeller y el Intercambio de Objetos Propeller. El objeto deberá declarar cualquier variable global requerida por el proceso que se inicia en un cog nuevo. (Esto fue revisado en la práctica de Objetos). 2) El método start deberá copiar cualquier parámetro que recibe de las variables globales antes de iniciar el método que administra el proceso en el cog Nuevo. 3) El método que se inicia en el cog nuevo deberá hacer configuraciones de contadores y asignaciones de pins E/S. De acuerdo a la clave 3: Vamos a decir que el cog 0 llama al método start del objeto y el método start inicia un contador usando métodos en el cog 1 con el comando cognew. Tendrá que poner el código para la configuración del contador y asignación de pins E/S en el método que se inicia por cognew si quiere que el contador en el cog 1 trabaje. Si intenta configurar los contadores o pins E/S en el método start (antes de iniciar el cog) esas configuraciones afectaran al cog 0 en vez del cog 1. Esto podría crear en su caso problemas de programación porque los módulos contadores en el cog 1 no estarán disponibles para accesar los pins E/S. Pagina 166 · Kit Educativo de Prácticas Propeller: Fundamentos 7: Práctica de Módulos Contadores y Aplicaciones de Circuitos {{ MonitorPWM.spin Monitorea características de una señal PWM probada y actualice Direcciones en la RAM principal con el tiempo de pulso alto/ bajo mas reciente medido y contador de pulsos. Como usar este objeto en su aplicación -----------------------------------------1) Declare variables para tiempo alto, bajo y contador de pulso. Ejemplo: VAR long tHprobe, tlprobe, pulseCnt 2) Declare el objeto MonitorPWM. Ejemplo: OBJ probe : MonitorPWM 3) Llame al método start y pase el pin E/S usado para probar y las direcciones de variable del paso 1. Ejemplo: PUB MethodInMyApp '... probe.start(8, @tHprobe, @tLprobe, @pulseCnt) 4) La aplicación puede ahora usar valores de tHprobe, tLprobe, y pulseCnt para monitorear los pulsos medidos en los pins E/S pasados al método start (P8 en este ejemplo). En el ejemplo, este objeto actualizara continuamente tHprobe, tLprobe, y pulseCnt con el tiempo de pulso alto/bajo mas reciente y el contador de pulsos Ver también -------TestDualPwmWithProbes.spin para un ejemplo de aplicación. }} VAR long cog, stack[20] long apin, thaddr, tladdr, pcntaddr ' ' ' ' Clave 1, variables globales para cog y stack. Clave 1, variables globales para el proceso. PUB start(pin, thighAddr, tlowaddr, pulsecntaddr) : okay '' '' '' '' '' '' '' '' '' '' Inicia el objeto y el proceso de monitoreo PWM en un cog Nuevo. Todo el tiempo las mediciones están en términos de ciclos de reloj. pin Numero de pin E/S tHighAddr dirección long que recibe la medición de la señal actual de tiempo alto. tLowAddr - dirección long que recibe la medición de la señal actual de tiempo bajo. pulseCntAddr - dirección long que recibe la medición del conteo actual de pulsos medidos. ' Copia la variables locales del método a variables globales del objeto ' Puede usar longmove(@apin, @pin, 4) en vez de los cuatro comandos: apin := pin thaddr := tHighAddr ' Clave 2, copia parámetros ' a variables globales ' que usara el proceso. Kit Educativo de Practicas Propeller: Fundamentos · Página 167 Práctica de Módulos Contadores y Aplicaciones de Circuitos tladdr := tLowAddr pcntaddr := pulseCntAddr ' Inicia el cog nuevo. okay := cog := cognew(PwmMonitor, @stack) + 1 PUB stop '' Detiene el proceso de monitoreo PWM y libera un cog. if cog cogstop(cog~ - 1) PRI PwmMonitor ' Clave 3, Activa las configuraciones de pin E/S y los módulos (Desde el ' nuevo cog!) ctra[30..26] := %01000 ctra[5..0] := apin frqa := 1 ' Detector POS ' Pin E/S ctrb[30..26] := %01100 ctrb[5..0] := apin frqb := 1 ' Detector NEG ' Pin E/S phsa~ phsb~ ' Limpia contadores ' Activa estados y direcciones de pins E/S. dira[apin]~ ' Hace salida un pin ' Ciclo de monitoreo PWM. repeat waitpeq(|<apin, |<apin, 0) long[tladdr] := phsb phsb~ waitpeq(0, |<apin,0) long[thaddr] := phsa phsa~ long[pcntaddr]++ ' ' ' ' ' ' Ciclo principal Monitorea Cog Espera por apin para ir alto. Guarda tlow, después limpia ' ' ' ' Espera por apin para ir bajo. Guarda thigh luego limpia. ' Incrementa contador ' de pulsos. Dentro del Objeto MonitorPWM Al principio MonitorPWM declara sus variables globales. Las variables cog y stack se presentaron en la práctica de Objetos. La variable cog se usa para rastrear en cual cog el método start del objeto inicio el proceso. Posteriormente si se llama el método stop del objeto sabrá cual cog apagar. Como dos métodos usan esta variable tiene que ser global porque los métodos no pueden ver otras variables locales. La variable stack proporciona espacio de pila para el código que se inicia en el nuevo cog para cálculos, punteros de regreso, etc. VAR long cog, stack[20] long apin, thaddr, tladdr, pcntaddr ' ' ' ' Clave 1, Variables globales para cog y stack. Clave 1, Variables globales para el proceso. Pagina 168 · Kit Educativo de Prácticas Propeller: Fundamentos 7: Práctica de Módulos Contadores y Aplicaciones de Circuitos También se declaran variables globales llamadas apin, thaddr, tladdr, y pcntaddr. Estas variables se usan por dos métodos: start y pwmMonitor. El método start recibe parámetros de un objeto que llama y los copia en estas variables globales para que el método pwmMonitor pueda usarlas. El método PwmMonitor usa la variable apin para configurar pins E/S y usa las otras tres variables como apuntadores de direcciones para almacenar sus medidas en la “localidad acordada mutuamente en la RAM principal” mencionada anteriormente. Cuando otro objeto llama este método start del objeto pasa el numero de pin E/S que estará monitoreando la señal junto y también las direcciones donde la medición de pulsos altos y bajos debería almacenarse y una dirección para almacenar el numero de pulsos que se han contado. Tenga en mente que estos parámetros (pin, thighAddr, tlowaddr, pulsecntaddr) son variables ocales en el método start. Para disponer de esto valores en otros métodos el método start tiene que copiarlos a variables globales. Así antes de iniciar el nuevo cog el método start copia pin a apin, tHighAddr a thaddr, tLowAddr a tlAddr y pulseCntAddr a pcntaddr. Después de eso el comando cognew inicia el método PwmMonitor en un nuevo cog y pasa las direcciones del arreglo stack. El arreglo stack se presento en la práctica de Objetos. PUB start(pin, thighAddr, tlowaddr, pulsecntaddr) : okay '... ' Copia variables locales del método a variables globales del objeto apin := pin ' Clave 2, copia parámetros ' a variables globales thaddr := tHighAddr ' que usara el proceso. tladdr := tLowAddr pcntaddr := pulseCntAddr ' Inicia el nuevo cog. okay := cog := cognew(PwmMonitor, @stack) + 1 Los objetos que inician nuevos cogs que están diseñados para intercambiar información con otros objetos tienen métodos start y stop por regla. También por regla si el objeto no inicia un nuevo cog pero necesita configurarse, se utiliza un método llamado init o config. Observe la última línea en el método start. El comando cognew regresa -1 si no hay cogs disponibles o regresa el numero de cog en el que se inicio el método PwmMonitor, el cual puede ser 0 a 7. Después se suma uno a este valor y el resultado se almacena en la variable cog del objeto y el valor de regreso okay del método start. Así, el método start regresa 0 (falso) si el proceso fallo al inicio o un no-cero si tuvo éxito. El objeto llamando al método start puede usar el valor de regreso del método start en un bloque if para decidir qué hacer. Nuevamente si el valor regresado es 0 (falso) significa que no hay cogs disponibles; mientras que si el valor es no-cero la aplicación sabe que el cog se inicio exitosamente. El método stop también puede determinar si el proceso se inicio apropiadamente porque la variable cog también almacena el resultado regresado cognew mas uno. Si se llama el método stop la primer cosa que hace es usar un enunciado if para asegurarse que realmente se inicio un cog. Por tercera vez, si el valor del cog es cero, no hay un proceso actual bajo el control del objeto que necesite detenerse. En otras palabras si el valor de cog es no-cero cogstop(cog~ − 1) hace 3 cosas: 1) Resta 1 del valor almacenado por cog para obtener el numero de cog que necesita detener. (Recuerde, un comando en el método start sumo 1 a la variable cog). 2) Detiene el cog 3) Limpia el valor de cog para que el objeto sepa que no está a cargo actualmente de un proceso activo (cog) Kit Educativo de Practicas Propeller: Fundamentos · Página 169 Práctica de Módulos Contadores y Aplicaciones de Circuitos PUB stop '' Detiene el proceso de monitoreo PWM y libera un cog. if cog cogstop(cog~ - 1) El método PwmMonitor se inicia en un Nuevo cog por un comando cognew en el método start. Así, hay código corriendo en el método PwmMonitor en un procesador separado dl código que llamo el método start. Lo primero que hace el método PwmMonitor es configurar los módulos contadores y los pins E/S que va a usar. Recuerde su código no puede hacer esto desde otro cog; el código ejecutado por un cog dado tiene que hacer sus propias configuraciones de contadores y asignación de pins E/S. (Vea la Clave 3 discutida previamente) PRI PwmMonitor ' Clave 3, active módulos contadores y configuraciones d pins E/S ' (desde el Nuevo cog) ctra[30..26] := %01000 ctra[5..0] := apin frqa := 1 ' Detector POS ' Pin E/S ctrb[30..26] := %01100 ctrb[5..0] := apin frqb := 1 ' Detector NEG ' Pin E/S phsa~ phsb~ ' Limpia conteos ' Activa direcciones y estados de pins E/S. dira[apin]~ ' Hace apin una ' entrada ' Ciclo monitoreando PWM. El ciclo principal en el método PwmMonitor espera a que la señal este en alto. Luego copia el contenido de phsb, lo cual acumula el tiempo bajo a una dirección en RAM principal. Recuerde que la dirección en memoria principal se paso del parámetro thighaddr del método start. El método start lo copio a la variable global thaddr. Como thaddr es una variable global es accesible en este método también. Similar con tlowaddr → tladdr y pulsecntaddr → pcntaddr. Antes de esperar medir el tiempo bajo de la señal el código limpia el registro phsb para la siguiente medida. Después de que la señal va a bajo, copia phsa a la memoria asignada para medir el tiempo alto. Antes de medir el siguiente ciclo se agrega 1 a la memoria apuntada por la variable pcntaddr, la cual lleva cuenta del número de ciclos. ' Ciclo de monitoreo PWM. repeat waitpeq(|<apin, |<apin, 0) long[tladdr] := phsb phsb~ waitpeq(0, |<apin,0) long[thaddr] := phsa phsa~ long[pcntaddr]++ ' ' ' ' ' Ciclo principal monitoreo del cog Espera por apin para ir alto. Guarda tlow, luego limpia. ' Espera por apin par air ' bajo. ' Guarda thigh, luego limpia. ' Incrementa contador pulso. Pagina 170 · Kit Educativo de Prácticas Propeller: Fundamentos 7: Práctica de Módulos Contadores y Aplicaciones de Circuitos Modos PLL para Aplicaciones de Alta Frecuencia Hasta este punto hemos utilizado modos NCO para generar ondas cuadradas en la frecuencia audible (20 a 20 kHz) y el rango de detector de IR (38kHz). El modo NCO puede usarse para generar señales hasta clkfreq/2. Así con el chip Propeller P8X32A usado en estas prácticas la frecuencia tope para este modo es 40 MHz. Para señales más rápidas de clkfreq/2, se puede usar el modulo contador en modo PLL (ciclo de fase cerrada). En vez de enviar el bit 31 del registro PHS directo a un pin E/S el modo PLL pasa la señal a través de dos subsistemas adicionales antes de transmitirlo. Estos subsistemas no son solo capaces de enviar frecuencias de 500 kHz hasta 128 MHz, también disminuyen las fluctuaciones que hay en las señales NCO. El primer subsistema (contador PLL) toma la frecuencia del bit 31 del registro PHS y la multiplica por 16 usando un circuito oscilador de voltaje controlado (VCO). El Manual Propeller y el objeto CTR llama a esto la frecuencia VCO. El segundo subsistema (divisor) divide el resultado de la frecuencia por una potencia 2 de rangos de 1 a 128. El PLL está diseñado para aceptar frecuencias del bit PHS de 4 a 8 MHz. El subsistema PLL multiplica la entrada de frecuencia por 16, para un rango de frecuencia del contador PLL de 64 a 128 MHz. El subsistema divisor divide esta frecuencia por una potencia dos de 128 a 1 para que la salida final de la señal PLL pueda estar en el rango de 500 kHz a 128 MHz. Configurando el Modulo Contador para Modos PLL La Figura 7-20 es el ahora familiar extracto del objeto CTR de la Librería Propeller, esta vez con la lista de modos PLL. Hay tres modos PLL. El primero PLL interno usado para sincronizar señales de video. Aunque aun no se comentan en esta práctica usted puede verlo aplicado en el objeto TV de la Librería Propeller. Como con los modos DUTY y NCO hay opciones de modo PLL de terminación sencilla y diferencial. Los valores CTRMODE para dirigir las señales PLL a los pins E/S son %00010 para terminación sencilla y %00011 para diferencial. Figura 7-20: Modo PLL Extractos de la Tabla de Modos Contadores del Objeto CTR Acumulado APIN BPIN CTRMODE Descripción FRQ a PHS Salida* Salida* ┌────────┬─────────────────────────────┬────────────┬────────────┬────────────┐ │ %00000 │ Contador Deshabilitado(off) │ 0 (nunca) │0 (ninguno) │0 (ninguno) │ ├────────┼─────────────────────────────┼────────────┼────────────┼────────────┤ . . . ├────────┼─────────────────────────────┼────────────┼────────────┼────────────┤ │ %00001 │ PLL interno (modo video) │1 (siempre) │ 0 │ 0 │ │ %00010 │ PLL terminación sencilla │ 1 │ PLL │ 0 │ │ %00011 │ PLL diferencial │ 1 │ PLL │ !PLL │ ├────────┼─────────────────────────────┼────────────┼────────────┼────────────┤ . . . │ %11111 │ LOGIC siempre │ 1 │ 0 │ 0 │ └────────┴─────────────────────────────┴────────────┴────────────┴────────────┘ * debe activar el bit correspondiente DIR para afectar el pin A¹ = APIN entrada retrasada por 1 clock A² = APIN entrada retrasada por 2 clocks B¹ = BPIN entrada retrasada por 1 clock Kit Educativo de Practicas Propeller: Fundamentos · Página 171 Práctica de Módulos Contadores y Aplicaciones de Circuitos El bit de campo PLLDIV del Registro CTR Para programar frecuencias de pin E/S en modo NCO se hizo directamente a través del registro FRQ. El valor en FRQ se sumaba a PHS cada ciclo de reloj y eso determinaba el rango de cambio del bit 31 de PHS, el cual directamente controlaba una spin E/S. Aun cuando programar frecuencias de pin E/S con modo PLL todavía se usa el bit 31 hay algunos pasos extras. En modo PLL el rango de cambio de bit 31 de PHS aun está determinado por el valor de FRQ, pero antes de que el pin E/S transmita la señal el bit 31 de PHS se multiplica por 16 y luego se divide por potencia dos de su elección (20 = 1, 21 = 2, 22 = 4, … 26 = 64, 27 = 128). La potencia 2 se selecciona por un valor almacenado en el bit de campo PLLDIV del registro CTR (bits 25..23) en la Figura 7-21. Figura 7-21: Mapa de Registro CTRA/B de CTR.spin ┌────┬─────────┬────────┬────────┬───────┬──────┬──────┐ bits │ 31 │ 30..26 │ 25..23 │ 22..15 │ 14..9 │ 8..6 │ 5..0 │ ├────┼─────────┼────────┼────────┼───────┼──────┼──────┤ Name │ ── │ CTRMODE │ PLLDIV │ ────── │ BPIN │ ──── │ APIN │ └────┴─────────┴────────┴────────┴───────┴──────┴──────┘ Calculando la Frecuencia PLL dando FRQ y PLLDIV Vamos a decir que está examinando un código ejemplo que está generando una cierta frecuencia PLL. Usted puede calcular que frecuencia está generando usando los valores de clkfreq, el registro FRQ, y el valor en el bit de campo PLLDIV del registro CTR solo siga estos pasos: (1) Calcule la frecuencia del bit 31 de PHS: clkfreq × registro FRQ Frecuencia bit 31 de PHS = ─────────────────────── 232 (2) Use la frecuencia del bit 31 de PHS para calcular la frecuencia VCO: Frecuencia VCO = 16 × Frecuencia bit 31 PHS (3) Divida el resultado PLLDIV el cual es 27−PLLDIV por la frecuencia VCO: Frecuencia VCO Frecuencia PLL = ─────────────── 27-PLLDIV Ejemplo: Dado una frecuencia de reloj de sistema (clkfreq) de 80 MHz y el código de abajo, calcule la frecuencia PLL transmitida en el Pin E/S P15. 'Configura modulo ctra ctra[30..26] := %00010 frqa := 322_122_547 ctra[25..23] := 2 ctra[5..0] := 15 dira[15]~~ Pagina 172 · Kit Educativo de Prácticas Propeller: Fundamentos 7: Práctica de Módulos Contadores y Aplicaciones de Circuitos (1) Calcule la frecuencia del bit 31 de PHS: 80_000_000 × 322_122_547 Frecuencia bit 31 de PHS = ───────────────────────── 232 = 5_999_999 (2) Use la frecuencia del bit 31 de PHS para calcular la frecuencia VCO: Frecuencia VCO = 16 × 5_999_999 = 95_999_984 (3) Divida el resultado PLLDIV el cual es 27−PLLDIV por la frecuencia VCO: 95_999_984 Frecuencia PLL = ─────────────── 27-2 = 2_999_999 MHz ≈ 3 MHz Calculando FRQ y PLLDIV dando una Frecuencia PLL Calcular la frecuencia PLL dando algunos código pre escritos está bien, pero que pasa si quiere calcular los valores del registro FRQ y bit de campo PLLDIV para generar una frecuencia con código propio?. Aquí hay unos pasos que se pueden usar para calcularlo: (1) Use la tabla de abajo para calcular el valor para colocar en el bit de campo PLLDIV del registro CTR basado en la frecuencia que quiere transmitir. MHz ──────── 0.5 a 1 1 a 2 2 a 4 4 a 8 PLLDIV ────── 0 1 2 3 MHz ───────── 8 a 16 16 a 32 32 a 64 64 a 128 PLLDIV ────── 4 5 6 7 (2) Calcule la frecuencia VCO con la frecuencia PLL que quiere transmitir y el divisor PLL y redondee al siguiente integro más bajo. Frecuencia VCO = Frecuencia PLL × 2(7-PLLDIV) (3) Calcule la frecuencia del bit 31 de PHS que necesitara para la frecuencia VCO. Esto es la frecuencia VCO dividida por 16 Frecuencia del bit 31 PHS = Frecuencia VCO ÷ 16 (4) Use los cálculos de la frecuencia NCO para determinar el valor del registro FRQ para la frecuencia del bit 31 de PHS. Registro FRQ = Frecuencia bit 31 PHS 232 × ─────── clkfreq Ejemplo: clkfreq está corriendo a 80 MHz y quiere generar una señal de 12 MHz con PLL. Calcule el Registro FRQ y el bit de campo PLLDIV. (1) Use la tabla para calcular el valor a colocar en el bit de campo PLLDIV del registro CTR: Kit Educativo de Practicas Propeller: Fundamentos · Página 173 Práctica de Módulos Contadores y Aplicaciones de Circuitos Como 12 MHz esta en el rango de 4 a 16 MHz, PLLDIV es 4.7. Redondeo abajo y se usa 4. (2) Calcule la frecuencia VCO con la frecuencia final PLL y el divisor PLL: Frecuencia VCO = 12 MHz × 2(7-4) = 12 MHz × 8 = 96 MHz (3) Calcule la frecuencia del bit 31 de PHS. Necesitara la frecuencia VCO. Esto es frecuencia VCO dividida por 16: Frecuencia bit 31 de PHS = 96 MHz ÷ 16 = 6 MHz (4) Use la frecuencia NCO para determinar el valor del registro FRQ para la frecuencia del bit 31 de PHS: 232 Registro FRQ = 6 MHz ───────── 80 MHz = 322_122_547 Probando frecuencias PLL El objeto TestPllParameters lo deja controlar la frecuencia de salida PLL del contador A ingresando manualmente los valores de frqa y el bit de campo PLLDIV de ctra en la terminal Parallax (Figura 7-22). El programa trasmite la frecuencia que ingreso por 1 s, contando los ciclos con el contador B programado en modo detector NEGEDGE. Note que hay una pequeña diferencia entre la frecuencia medida y la frecuencia calculada manualmente discutida previamente. Si los cálculos delay := clkfreq + cnt en el objeto TestPllParameters.spin se coloca inmediatamente después de phsb~, el conteo de frecuencia será ligeramente menor a la actual. Si se mueve después de phsb~, la medición será ligeramente mayor que la actual. Se puede obtener una medición exacta con la ayuda de un objeto lenguaje ensamblador. Figura 7-22: Calcular la frecuencia dando FRQA y PLLDIV Aun cuando el PLL puede generar frecuencias de 128 MHz el contador del Propeller solo detecta frecuencias hasta 40MHz con módulos contadores. Esto coincide con el rango de muestreo de Nyquist, el cual debe ser dos veces más rápido que la frecuencia más alta. También si considera que el modo detector NEGEDGE suma FRQ a PHS cuando detecta una señal alta durante un ciclo y una señal baja en el siguiente necesita al menos dos ciclos para detectar un ciclo completo de la señal. Pagina 174 · Kit Educativo de Prácticas Propeller: Fundamentos 7: Práctica de Módulos Contadores y Aplicaciones de Circuitos 3 Calcule el registro FRQ y el bit de campo de PLLDIV para varias frecuencias en el rango de 500 kHz a 40MHz. 3 Cargue TestPllParameters.spin en EEPROM (F11) a inmediatamente después presione el botón Enable de la Terminal Serial Parallax. 3 Ingrese los valores FRQ y PLLDIV en la ventana de transmisión de la Terminal Serial Parallax y verifique que la frecuencia medida es aproximadamente la misma que usted calculo. {{ TestPllParameters.spin Prueba frecuencias PLL hasta 40 MHz. Los valores del registro PHS y el bit de campo PLLDIV se ingresan en la Terminal Serial Parallax. El programa usa estos valores para sintetizar la onda cuadrada con el modo PLL usando el contador A. El contador del modulo B cuenta los ciclos en 1 s y los reporta. }} CON _clkmode = xtal1 + pll16x _xinfreq = 5_000_000 ' Reloj de sistema → 80 MHz ' Constantes para la Terminal Serial Parallax. CLS = 16, CR = 13 OBJ SqrWave : "SquareWave" debug : "FullDuplexSerialPlus" PUB TestFrequency | delay, cycles Debug.Start(31, 30, 0, 57600) waitcnt(clkfreq * 2 + cnt) Debug.tx(CLS) ' Configura módulos contadores. ctra[30..26] := %00010 ' Modulo ctra a PLL modo ' terminación sencilla ctra[5..0] := 15 ctrb[30..26] := %01110 ' Modulo ctrb para modo ' detector NEGEDGE ctrb[5..0] := 15 frqb:= 1 repeat Debug.str(String("Enter frqa: ")) ' frqa y PLLDIV se ingresan ' por el usuario frqa := Debug.GetDec Debug.str(String("Enter PLLDIV: ")) ctra[25..23] := Debug.GetDec dira[15]~~ delay := clkfreq + cnt phsb~ waitcnt(delay) cycles := phsb dira[15]~ Debug.str(String("f = ")) debug.dec(cycles) debug.str(String(" Hz", CR, CR)) ' ' ' ' P15 → salida Pre calcula retraso de ciclos de reloj Espera 1 s. ' Almacena ciclos ' P15 → entrada ' Muestra ciclos como frec. Kit Educativo de Practicas Propeller: Fundamentos · Página 175 Práctica de Módulos Contadores y Aplicaciones de Circuitos Detección de Metal con Modos Detectores PLL, POS y un Circuito LC Los inductores son bobinas que cuando se colocan en un circuito tienen la capacidad de almacenar energía. Se usan en muchas aplicaciones una de las cuales es detección de metal. Hay diferentes instrumentos de detección de metales además de los que quizá ha visto que pasan en las playas en un fin de semana. Otros ejemplos incluyen instrumentos que identifican el tipo de metal verifica fracturas en superficies metálicas y mide precisamente la distancia de una superficie de metal desde un instrumento. Aun pensando que no hay ningún inductor en el kit PE hay muchos cables que pueden enredarse para formar pequeños inductores. Esta parte de la práctica demuestra como un cog puede usar dos contadores, uno PLL de terminación sencilla y el otro en modo POS para enviar señales de alta frecuencia a una entrada de circuito LC (Inductor Capacitor) y deducir la presencia o ausencia de metal examinando la señal de salida. Para el proyecto necesitamos doblar un cable Puente en forma de U para hacer nuestro inductor. La Figure 7-23 muestra una lista de partes y un circuito para el detector de metales del kit PE. Debido a las partes pequeñas y las altas frecuencias este circuito puede ser fastidioso. Para mejores resultados alámbrelo exactamente como muestra la Figura 7-24. El capacitor y resistencia deber estar todos hacia arriba de la placa y los dos cables deben estar en el mismo plano que la placa. Este circuito también requiere ajustes. La Figure 7-23 empieza con R1 a 100 Ω, y R2 (100 Ω) y R3 (470 Ω) están en paralelo. El detalle es que estas prácticas usaran combinaciones de resistencias R2 || R3. El circuito en particular quizá necesite mayor o menor resistencia en paralelo con R1 o R2, pero por ahora comience con R1 = 100 Ω y R2 = 100 Ω || 470 Ω. 3 Construya el circuito de la Figure 7-23 en la Plataforma PE exactamente como se muestra en la Figura 7-24. Para la lista de componentes vea el Apéndice C: Lista de Componentes kit PE en la página 219 Figure 7-23: Detector de Metal Partes y Esquemático Lista de Partes ────────────────────── (1) Capacitor 100 pF (2) cables (2) Resistencias 100 ω (misc) resistencias: 220, 470, 1000, 2000, 10k Esquemático ────────────────────────────────────────── ┌───────────────── P13 │ 100 pF │ R1 ┌─────┐ ┣────┫ ┣─── P15 R2 └────┘ 2.5 inch GND wire loop Pagina 176 · Kit Educativo de Prácticas Propeller: Fundamentos 7: Práctica de Módulos Contadores y Aplicaciones de Circuitos 3 Asegúrese que el cable que usa como inductor tiene forma de U y está en paralelo a la superficie de la tarjeta mientras que las otras partes están perpendiculares. Figura 7-24: Cableado del Detector de Metales Detectando Frecuencia Resonante El circuito LC mostrado en la Figure 7-23 comúnmente se llama rechazo de banda, paro de banda o filtro. El Filtro atenúa ciertas frecuencias de onda senoidal de una señal de entrada, idealmente baja a nada en ciertas frecuencias. La frecuencia que se filtra se llama el centro de la frecuencia o también frecuencia resonante del circuito LC. La Figura 6-1 muestra una grafica de simulación de como el filtro responde a un rango de entrada (P15) d onda de frecuencia senoidal de 30 a 90 MHz. Note que el centro de frecuencia es 50MHz. Así, si la entrada fue una onda senoidal su amplitud se atenuara casi nada; mientras a frecuencias fuera del centro de la frecuencia la salida de amplitud de la onda senoidal estará en el rango de 1.6V. Figura 7-25: Salida simulada P13 Vs. P15 Entrada para Frecuencias de Onda Senoidal Mas acerca de filtros y programas de simulación: L Si cambia R y C || L, tendrá un filtro pasa bandas. La frecuencia de respuesta es la versión invertida de lo que muestra la Figura 7-26. Para más información en Filtros LC vea los términos de circuitos de frecuencia selectiva, filtros, pasa-bajas, pasa-altas, pasa-bandas y rechazo de banda en un libro de electrónica. Las simulaciones en esta sección se desarrollaron con el programa Demo OrCAD el cual está disponible gratuitamente en www.cadence.com Kit Educativo de Practicas Propeller: Fundamentos · Página 177 Práctica de Módulos Contadores y Aplicaciones de Circuitos Sin importar si es filtro rechaza-banda o pasa bandas, la frecuencia del circuito resonante puede calcularse con la ecuación que se muestra abajo. L es la inductancia, medida en Henrios (H), y C es la capacitancia medida en Faradios (F). Por supuesto L y C en la Figure 7-23 a diminutas fracciones de Henrios y Faradios respectivamente. fR = 1 2π LC Eq. 6 Reacomodando los términos es posible calcular la inductancia basada en la respuesta de frecuencia de las pruebas. L = 1 Eq. 7 2 ( 2πfR ) C En esta práctica la entrada del circuito LC será una onda cuadrada de P15. Aun cuando la salida está relacionada a las características de filtrado del circuito, su comportamiento tendrá más sentido si se examina del punto de vista de la respuesta de paso. Una respuesta de paso de circuito es importante en circuitos digitales y la meta típica es hacer que la salida del circuito responda rápido y preciso a la entrada. La respuesta de paso más deseable se llama amortiguación critica porque alcanza su objetivo rápidamente sin rebasarlo. Algunos diseños pueden obtener respuestas rápidas con un circuito su amortiguado pero con alguna penalidad de oscilación sobre y debajo del nuevo objetivo de voltaje antes de que la señal se estabilice. Otros diseños necesitan una respuesta de paso sobre amortiguado, lo cual es más lento para alcanzar su objetivo de voltaje pero asegura que no lo rebasara o resonara. Figura 7-26: Respuesta a la Frecuencia Resonante La respuesta de paso simulada en la Figura 7-26 es un caso drástico de una señal su amortiguada. V(P15Step) en la grafica de arriba es la entrada de señal del circuito LC. V(P13) es la señal de salida, y V(Threshold) es una señal DC de disparo en el chip Propeller de 1.65V. La simulación no es realmente una respuesta típica porque una onda cuadrada de 50 MHz se aplico por 960 ns antes de Pagina 178 · Kit Educativo de Prácticas Propeller: Fundamentos 7: Práctica de Módulos Contadores y Aplicaciones de Circuitos que la llamada de paso (señal alta) se aplicara. El resultado fue que el inductor y el capacitor acumularon alguna energía lo que hace la respuesta de V(P13) un pseudo-paso a la derecha de la marca de 960 ns más pronunciada de lo que seria. Lo importante es notar V(P13) a la derecha de la marca de 960 ns que es una que decrementa gradualmente. Esta onda senoidal ocurre en la frecuencia resonante de 50 MHz en el circuito LC. También observe la línea V(P13) entre 930 y 960 ns con cada cambio de la señal de V(P15Step) 50MHz, V(P13) comienza una reacción de onda senoidal que es inicialmente opuesta a la entrada V(P15Step). Como la señal V(P13) pasa por la mitad de la onda senoidal de 50MHz antes de que la señal V(P15Step) cambie, las porciones de esas respuestas de ondas senoidales nunca pasaran el voltaje de disparo 1.65 V del chip Propeller. Figura 7-27: Circuito LC Respuesta de Salida P13 a Varias Frecuencias 47.62 MHz 49.02 MHz 50.00 MHz 51.02 MHz 52.63 MHz Ahora, compare la respuesta V(P13) a la frecuencia de la onda cuadrada ligeramente arriba y debajo de la frecuencia resonante del circuito, mostrado en la Figura 7-27. A 47.62 MHz la onda senoidal completa ligeramente más de ½ de su ciclo, parte de la cual paso por encima de 1.65V (marcado por la línea con el carácter +). A 49.02 MHz la onda senoidal está repitiendo mas del ciclo completo, pero no tanto, así que la señal tarda más tiempo abajo del voltaje de disparo. A 50 MHz la frecuencia de entrada coincide con la respuesta senoidal y como solo se repite la mitad de la onda senoidal Kit Educativo de Practicas Propeller: Fundamentos · Página 179 Práctica de Módulos Contadores y Aplicaciones de Circuitos entonces no está mucho tiempo por encima del voltaje de disparo. A 51.02 y 52.63 MHz la señal nuevamente pasa tiempo encima del 1.65 V de disparo, esta vez porque la señal de entrada cambia antes de que la onda senoidal ha completado su ciclo. La parte más importante de la Figura 7-27 es que la señal de salida, la cual puede monitorearse por P13, pasara más tiempo sobre él la línea de disparo lógica de 1.65 V cuando la señal de entrada P15 esta mas lejos de la frecuencia resonante del circuito, ya sea arriba o abajo. El Propeller puede usar un contador en modo PLL para generar ondas cuadradas en el rango de las frecuencias mostradas en la Figura 7-27 y puede usar otro contador en modo detector POS para medir que tanto tiempo pasa el circuito arriba del voltaje de disparo 1.65 V del pin E/S P13. Así el chip Propeller puede usar dos módulos contadores y un pequeño código para cambiar la frecuencia PWM en P15 a través de un rango de valores para encontrar la frecuencia resonante del circuito de la Figure 7-23, pero, ¿como hace posible que detecte metal? La respuesta es que un objeto metálico cercano interactúa electromagnéticamente con el cable del circuito de la Figure 7-23 de modo que cambia su inductancia y aumenta un poco su Resistencia. Cuando la inductancia del circuito cambia, su frecuencia resonante también cambia y el chip Propeller puede detectar eso intercambiando las frecuencias PLL de P15 y midiendo el tiempo en alto de P13, lo cual alcanzara un mínimo en de frecuencias resonantes diferentes como resultado de un objeto metálico cercano. Como la Corriente Eddy Afecta el Ciclo de Frecuencia Resonante Cerca de Objetos Metálicos La Figura 7-28 muestra la interacción entre un objeto metálico cerca del alambre de inductancia. Las corrientes alternas a través del ciclo crean efectos electromagnéticos. Estos campos magnéticos hacen viajar grupos de electrones en el metal conductivo en patrones circulares. Estos patrones circulares se llaman Corriente Eddy. Las corrientes alarmas generan un campo magnético opuesto al del cable. Figura 7-28: Corrientes Eddy Causando Campos Magnéticos Opuestos I Las Corrientes Eddy mostradas en la Figura 7-28 nos da un ejemplo de cómo se transmite la potencia en líneas AC. Una espiral conectada a la línea de potencia es acoplada magnéticamente con un espiral de pocas vueltas. La corriente alterna en el primario induce un campo magnético alterno que induce la corriente AC en el espiral secundario. La Figura 7-29 muestra como el espiral secundario y la carga afectan al primario. La inductancia del espiral secundario y cualquier carga resistiva pueden verse en el primario y se puede contarse como L2’ y R’. Pagina 180 · Kit Educativo de Prácticas Propeller: Fundamentos 7: Práctica de Módulos Contadores y Aplicaciones de Circuitos Figura 7-29: Efecto de Corriente Eddy en la Inductancia del Ciclo La Figura 7-29 también representa como la Corriente Eddy, la cual tiene cierta inductancia debido al hecho que son inducidas en un metal, afecta a la inductancia del circuito primario y resistencia. Así es que la corriente Eddy en el metal cercano afecta la inductancia del metal. Como la inductancia del ciclo se mide en L en la ecuación de resonancia, cambiara la frecuencia resonante del circuito LC. También como el chip Propeller puede detectar la frecuencia resonante del circuito al intercambiar frecuencia de onda cuadrada PLL en un pin mientras mide el numero de ciclos de la señal de salida del circuito cuando esta encima del punto de disparo, la aplicación puede detectar presencia o ausencia de metales. Probando una Frecuencia Resonante El objeto Calibrate Metal Detector proporciona una conexión para probar la respuesta del circuito LC con el chip Propeller.. Como se menciono anteriormente los pequeños valores y relativa alta frecuencia usada en este circuito pueden hacerlo fastidioso. Por ejemplo si el capacitor es más que 90º del ciclo, la frecuencia resonante cae, si es menos de 90º la frecuencia resonante se incrementa. También las partes tendrán diversas características así que tomara algo de práctica para dejar el circuito a punto para que la resistencia divisora haga que la señal de salida del circuito LC se mantenga debajo del disparo el pin E/S y se mueva sobre este límite cuando la frecuencia cambie muy por encima o debajo. La Figura 7-30 muestra la salida de CalibrateMetalDetector.spin después de calibrar el circuito. El conteo alto en la izquierda es similar a la respuesta de frecuencia graficada en la Figura 7-25. Los conteos en la derecha muestran que todavía hay una frecuencia resonante pero cambia alrededor de 50.6 MHz. Como el ciclo inductivo también incrementa su resistencia puede evitar atenuar la señal para que las mediciones tarden menos tiempo debajo de cero (o quizá nunca deje de ser cero). Kit Educativo de Practicas Propeller: Fundamentos · Página 181 Práctica de Módulos Contadores y Aplicaciones de Circuitos Figura 7-30: Respuesta de Calibrated Metal Detector – sin metal (izq.) y con metal (der.) Aquí se muestra como calibrar manualmente el circuito detector. La detección automática se deja para la sección de proyectos. 3 Cargue CalibrateMetalDetector.spin en la EEPROM (F11) e inmediatamente después presione el botón Enable de la Terminal Serial Parallax. (Recuerde que ni siquiera tiene que esperar a que el programa termine de cargarse). 3 Cuando el cursor esté listo ingrese la frecuencia comenzando por 48,000,000 3 Ingrese una nueva frecuencia de 200,000 3 Compare su pantalla con la de la izquierda en la Figura 7-30, observando no tanto para que coincidan los números pero viendo que los perfiles sean similares, lo cual muestra una frecuencia resonante centrada cuando el contador es = 0. 3 Si su pantalla muestra una frecuencia resonante clara intente colocar una moneda directamente debajo, pero sin tocar el cable de alambre y presione la tecla R en su teclado para repetir el mismo cambio de frecuencia. 3 Si la pantalla cambia significativamente como el de la derecha en la Figura 7-30 su detector medidor aparentemente no necesita mayor calibración. 3 Si no está viendo frecuencias resonantes claras intente refinar la frecuencia de inicio y la frecuencia de paso para que el cambio claro indique la presencia o ausencia de metal. Pagina 182 · Kit Educativo de Prácticas Propeller: Fundamentos 7: Práctica de Módulos Contadores y Aplicaciones de Circuitos 3 Si aparentemente no hay respuesta del filtro (ya sea todos ceros o valores mayores) intente las sugerencias que se muestran a continuación. Quizá el circuito en vez de necesitar algún ajuste muestre respuestas similares a la Figura 7-30. Si en cambio ve números que están muy altos, ceros o valores muy bajos, el divisor de voltaje quizá necesite ajustarse. Está diseñado para hacer una salida justo debajo del punto de disparo. 3 Si ve puros ceros, el divisor de voltaje necesita estar menos distanciado de la señal. Primero intente sucesivamente resistencias mayores en lugar de R3, Intente 1 kΩ, 2 kΩ, 10 kΩ. 3 Si el divisor de voltaje esta aun tomando mucho de la señal desconecte R3 totalmente y en cambio agregue una R4 en paralelo con R1. Comience con una resistencia grande como 10 kΩ, y trabaje bajando la Resistencia 2 kΩ, 1 kΩ, y así sucesivamente. Repita el cambio de frecuencia entre ajustes hasta que encuentre un divisor de voltaje que trabaje bien para el circuito y el voltaje de disparo del chip Propeller. 3 Si no hay respuesta del filtro, en otras palabras, ningún grupo de valores como en la Figura 7-30 quizá necesite buscar valores de menores o mayores frecuencias después de ajustar el divisor de voltaje. Esto implica comenzar el cambio a valores bajos como 46 MHz en vez de 48 y usar incrementos más pequeños como 100,000 en vez de 200,000 y seleccionar M o Enter cuando se coloque el cursor en pantalla. 3 Una vez que ha tenido frecuencias resonantes buenas, puede usted también diferenciar la distancia del objeto metálico entre 1mm, 5mm y 10mm? '' CalibrateMetalDetector.spin CON _clkmode = xtal1 + pll16x _xinfreq = 5_000_000 ' 80 MHz Reloj Interno CLS = 16, CR = 13 OBJ Debug frq : "FullDuplexSerialPlus" : "SquareWave" PUB Init | count, f, fstart, fstep, c 'Inicia FullDuplexSerialPlus Debug.start(31, 30, 0, 57600) waitcnt(clkfreq*2 + cnt) Debug.tx(CLS) 'Configura modulo ctra para onda cuadrada de 50 MHz ctra[30..26] := %00010 ctra[25..23] := %110 ctra[5..0] := 15 frq.Freq(0, 15, 50_000_000) dira[15]~~ 'Configura modulo ctrb para detección negativa de limite ctrb[30..26] := %01000 ctrb[5..0] := 13 frqb := 1 c := "S" repeat until c == "Q" or c == "q" Kit Educativo de Practicas Propeller: Fundamentos · Página 183 Práctica de Módulos Contadores y Aplicaciones de Circuitos case c "S", "s": Debug.Str(String("Starting Frequency: ")) f := Debug.GetDec Debug.Str(String("Step size: ")) fstep := Debug.GetDec Debug.tx(String(CR)) case c "S", "s", 13, 10, "M", "m": repeat 22 frq.Freq(0, 15, f) count := phsb waitcnt(clkfreq/10000 + cnt) count := phsb - count Debug.Str(String(CR, "Freq = ")) Debug.Dec(f) Debug.Str(String(" count = ")) Debug.Dec(count) waitcnt(clkfreq/20 + cnt) f += fstep Debug.str(String(CR,"Enter->more, Q->Quit, S->Start over, R->repeat: ")) c := Debug.rx Debug.tx(CR) "R", "r": f -= (22 * fstep) c := "m" "Q", "q": quit Debug.str(String(10, 13, "Bye!")) Tiempo de Estudio Preguntas 1) ¿Cuántos módulos contadores tiene un Cog y como son etiquetados? 2) ¿Qué términos usa esta práctica para referirse a los tres registros del modulo contador sin especificar cual modulo se está usando? En otras palabras ¿Qué términos genéricos se usan para referirse a los tres registros del modulo contador? 3) ¿Cuáles son los tres nombres usados para referirse al contador A en código Spin? 4) ¿Cuáles son los tres nombres usados para referirse al contador B en código Spin? 5) ¿Qué registro se suma condicionalmente al registro PHS con cada ciclo de reloj? 6) ¿Qué registro puede usar para activar condiciones por las cuales el registro PHS se actualiza? 7) ¿Cómo afecta el registro PHS los pins E/S con ciertos bits? 8) ¿Como indica la medición de descarga RC el estado de una variable ambiental? 9) Es una resistencia limitadora de corriente necesaria en una red RC conectada al chip Propeller 10) Es posible crear un circuito RC que empieza en 0V y acumula hasta 5 V durante la medición. ¿Cual valor de CTRMODE debería tener para ser usada para medir este tipo de circuito? 11) ¿Cómo es un modo detector positivo del modulo contador usado para medir descarga RC? 12) ¿Donde residen los bits de CTRMODE? 13) ¿Qué seleccionan los bits CTRMODE? 14) Para mediciones de descarga RC, ¿cuales campos se programan en el registro CTR? 15) ¿Qué valor tiene que almacenar el registro FRQ para mediciones de descarga RC? 16) ¿Cuáles son los tres pasos necesarios para configurar un modulo contador para tomar mediciones de descarga RC? Pagina 184 · Kit Educativo de Prácticas Propeller: Fundamentos 7: Práctica de Módulos Contadores y Aplicaciones de Circuitos 17) Asuma que un contador ha sido programado para tomar medición de descarga RC, ¿Que tiene que hacerse para iniciar la medición? 18) ¿Porque pueden tomarse simultáneamente mediciones RC? 19) ¿En que difiere un contador con pin E/S de la descarga RC y aplicaciones de conversión D/A? 20) ¿Cómo controla el registro FRQ una señal D/A en modo DUTY? 21) ¿Qué componente del modulo contador controla el pin E/S? 22) ¿Qué propósito tiene scale = 16_777_216 en LedDutySweep.spin? 23) ¿Cómo se direccionan los registros de propósito especial 8 a 13? 24) ¿Qué registros de propósito especial pueden usarse para controlar el valor de ctrb? 25) ¿Qué registros de propósito especial pueden usarse para activar el valor de frqa? 26) ¿Qué tiene myVariable después de ejecutar el comando myVariable := spr[13]? 27) ¿Cuáles son las dos formas de asignar el valor almacenado en myVar a ctrb? 28) ¿Cómo puede afectar ciertos bits con spr[8] o spr[9], y porque es tan útil? 29) ¿Qué elemento del contador de registro de propósito especial controla un pin E/S en modo NCO? 30) ¿Cuál es la condición para sumar FRQ a PHS en modo NCO? 31) ¿Qué relación necesita la frecuencia deseada NCO para ser multiplicada por un determinado valor de registro FRQ? 32) Si un contador es activado a modo NCO y un programa copia un valor al registro FRQ del contador, ¿Qué relación necesita el registro FRQ para ser multiplicado para determinar la frecuencia? 33) Si in pin E/S está transmitiendo una onda cuadrada NCO, ¿cuales son tres formas de detenerlo? 34) ¿Puede un cog enviar dos ondas cuadradas en dos frecuencias no relacionadas? 35) ¿Qué tiene que hacer un programa para cambiar la frecuencia NCO si un contador está transmitiendo? 36) ¿Puede un modulo contador usarse para medir señal de frecuencia? 37) ¿Son POSEDGE y NEGEDGE incrementados basándose en el límite de una señal? 38) Hay un comando escrito repeat while phsb[31] en BetterCountEdges.spin en la sección de detección rápida de límites en la pagina 157. ¿Sera posible sustituir un registro de propósito especial en lugar de phsb? 39) ¿Qué rango de frecuencia puede transmitir un modo PLL de contador? 40) ¿Qué elementos del modo NCO usa PLL? 41) A diferencia del modo NCO, el modo PLL no usa el bit 31 de su registro PHS para controlar el pin E/S. ¿Qué pasa a esta señal? 42) ¿Cuáles son los pasos para calcular la frecuencia PLL dando los valores almacenados en los registros FRQ, PLLDIV y CLKFREQ? 43) ¿Cuáles son los pasos para calcular FRQ y PLLDIV para sintetizar una frecuencia PLL? Ejercicios 1) Modifique TestRcDecay.spin ara que mida ascensos en vez de tiempo de descarga. 2) Inicie un modo Duty terminación sencilla para conversión D/A a 1V usando contador modulo B y los nombres de registros del modulo contador. 3) Inicie un modo Duty terminación sencilla para conversión D/A a 1V usando contador modulo B y registros de propósito especial. Tenga cuidado al usar elementos del arreglo de registro de propósito especial que afectan DIRA. Para cambiar solo un bit del registro DIRA tome el valor existente almacenado por el registro y hacerlo OR con la máscara del bit 7 puesto a 1. 4) Calcule las celdas vacías en la Tabla 7-1 de la pagina 139. 5) Asuma que el sistema de reloj del chip Propeller corre a 20 MHz, escriba el código para enviar una onda cuadrada aproximada de la nota Do7 en P16 que use el contador B Kit Educativo de Practicas Propeller: Fundamentos · Página 185 Práctica de Módulos Contadores y Aplicaciones de Circuitos 6) Modifique DoReMi.spin para que toque las doce notas de la Tabla 7-1 de la pagina 142. 7) Modifique TwoTonesWithSquareWave.spin para que toque correctamente las notas con un cristal de 2 MHz. 8) Modifique IrDetector.spin para que trabaje en una escala de 0 a 128 en vez de 0 a 256. 9) Modifique CountEdgeTest.spin para que cuente limites positivos en vez de negativos 10) Modifique 1Hz25PercentDutyCycle.spin para que envíe la señal central a un servo. Esto hará que el servo estándar se mantenga en la posición del centro de su rango de movimiento o que un servo de rotación continua se quede sin movimiento. La señal es una serie de pulsos de 1.5ms cada 20ms. 11) Modifique 1Hz25PercentDutyCycle.spin para que haga que la salida del servo cambia de un extreme de su rango de movimiento al otro en 1.5 segundos. Para un servo estándar de 180 grados, la duración del pulso deberá cambiar nominalmente de 0.5 ms a 2.5 ms y de regreso. El pulso deberá entregarse aun a 20ms. En la práctica es bueno asegurarse que el servo no trate de moverse más allá de sus topes mecánicos. Para los servos estándar Parallax un rango seguro esta en el rango de 0.7 a 2.2 ms. 12) Modifique TestDualPwm para que cambia dos servos entre sus extremos opuestos de movimiento en un periodo de 1.5 segundos. Proyectos 1) Escriba un objeto DAC modo DUTY de dos canales modo terminación sencilla que le permita crear y reclamar canales contadores DAC (Contador A y Contador B). Cada canal DAC deberá tener su propia resolución en términos de bits. El DAC deberá soportar el código prueba y documentación mostrada abajo. Si va a altas resoluciones recuerde dejar algo de espacio en los niveles bajos y altos. Vea claves para programar DUTY en la pagina 133. CODIGO PRUEBA ''Test DAC 2 Channel.spin ''DAC 2 canales. OBJ dac : "DAC 2 Channel" PUB TestDuty | level dac.Init(0, 4, 8, 0) dac.Init(1, 5, 7, 64) repeat repeat level from 0 to 256 dac.Update(0, level) dac.Update(1, level + 64) waitcnt(clkfreq/100 + cnt) ' Ch0, P4, 8-bit DAC, inicia a 0 V ' Ch1, P5, 7-bit DAC, inicia a 1.65 V ' DAC salida automáticamente reducida a 128 DOCUMENTACION DE OBJETO Object "DAC 2 Channel" Interface: PUB Init(channel, ioPin, bits, level) PUB Update(channel, level) PUB Remove(channel) Program: Variable: 20 Longs 2 Longs ______________________________________ PUB Init(channel, ioPin, bits, level) Pagina 186 · Kit Educativo de Prácticas Propeller: Fundamentos 7: Práctica de Módulos Contadores y Aplicaciones de Circuitos Inicia un DAC. • channel - 0 o 1 • ioPin - Escoge pin E/S DAC • bits - Resolución (8 bits, 10 bits, etc.) • level - Nivel voltaje inicial = 3.3 V * level ÷ 2 bits ___________________________ PUB Update(channel, level) Actualiza el nivel transmitido por un canal ADC a bits level = 3.3 V * level ÷ 2 ____________________ PUB Remove(channel) Recupera el modulo contador y programa los pins asociados E/S a entrada GUIA: • Defina dos arreglos de variables globales lsb para almacenar el LSB de cada DAC • Las variables lsb son las versiones ajustables de la constante scale en LedSweepWithSpr.spin. • Defina cada elemento del arreglo lsb en el método Init usando lsb[channel] := |< (32 - bits). Por ejemplo si bits es 8, el operador encode asigna 24 del elemento del arreglo bits. ¿Cuál es el valor? 16_777_216. Es el mismo que la constante scale que se declaro para el DAC 8-bit en LedSweepWithSpr.spin. • Para asignar el nivel de voltaje use spr[10 + channel] := level * lsb[channel], donde level es el valor de voltaje deseado. Por ejemplo si bits es 8 (un DAC de 8bits) entonces un level de 128 resultaría en 1.65 V. 2) La solución del ejercicio 12 (mostrado abajo) controla dos servos usando dos módulos contadores. Cada contador en el ciclo repeat entrega un pulso en el rango de 700 a 2200 µs. Entonces el comando waitcnt espera por los 20ms restantes. El máximo tiempo que toma el pulso es 2200 µs (2.2 ms). Como el ciclo repeat se repite cada 20 ms eso deja 17.8 ms para pulsos de otros servos. Modifique el programa para que controle otros dos servos (para un total de cuatro) durante 17.8 ms. Recuerde que los módulos contadores corren independientemente, así que tendrá que insertar retrasos para completar cada par de pulsos antes de moverse al siguiente par. {{ TestDualPWM.spin Demuestra cómo usar dos contadores para enviar una señal doble PWM. El tiempo de ciclo es el mismo para ambas señales, pero los tiempos En alto son independientes del otro. }} CON _clkmode = xtal1 + pll16x _xinfreq = 5_000_000 ' Reloj sistema → 80MHz PUB TestPwm | tc, tHa, tHb, t, us us := clkfreq/1_000_000 ' <- Suma us ' <- Suma ctra[30..26] := ctrb[30..26] := %00100 sencilla ctra[5..0] := 4 ctrb[5..0] := 6 ' Contadores A y B → NCO terminación ' Pins para contadores para control Kit Educativo de Practicas Propeller: Fundamentos · Página 187 Práctica de Módulos Contadores y Aplicaciones de Circuitos frqa := frqb := 1 reloj ' Suma 1 a phs con cada ciclo de dira[4] := dira[6] := 1 ' Activa pisn E/S a salida tC := 20_000 * us tHa := 700 * us tHb := 2200 * us ' <- Cambia Set up tiempo de ciclo ' <- Cambia Set up tiempo alto ' <- Cambia t := cnt ' Marca tiempo actual repeat tHa from (700 * us) to (2200 * us) ' <- Cambia señal PWM phsa := -tHa ' Define e inicia el pulso A phsb := -tHb ' Define e inicia el pulso B t += tC ' Calcula siguiente ciclo repeat waitcnt(t) ' Espera por ciclo 3) Desarrolle un objeto que inicie un cog y permita a otros objetos controlar su modo duty conversión D/A de acuerdo a la documentación mostrada. Pruebe este objeto con un objeto superior que usa un sistema de menú para obtener valores D/A del usuario y los pasa a control de brillo de un LED. ''DualDac.spin ''Proporciona los canales de dos módulos contadores de otro cog para conversión D/A Como usar este objeto en la aplicación -----------------------------------------1) Declare variables los canales D/A. Ejemplo: VAR ch[2] 2) Declare el objeto DualDac. Ejemplo: OBJ dac : DualDac 3) Llame al método start. Ejemplo: PUB MethodInMyApp '... dac.start 4) Active salidas D/A. Ejemplo: ch[0] := 3000 ch[1] := 180 5) Configure los canales DAC. Ejemplo: 'Canal 0, pin 4, 12-bit DAC, ch[0] almacena el valor DAC. dac.Config(0,4,12,@ch[0]) 'Como ch[0] se activo a 3000 en el paso 4, la salida P4 de DAC será ' 3.3V * (3000/4096) 'Canal 1, pin 6, 8-bit DAC, ch[1] almacena el valor de DAC. dac.Config(1,6,8,@ch[1]) 'Como ch[1] se activo a 180 en el paso 4, la salida P6 de DAC será ' 3.3V * (180/256) 6) Métodos y características en este objeto harán posible también: Pagina 188 · Kit Educativo de Prácticas Propeller: Fundamentos 7: Práctica de Módulos Contadores y Aplicaciones de Circuitos - remover un canal DAC - cambiar un canal DAC: o Pin E/S o Resolución o Dirección variable de control o Valor almacenado por la variable control Ver también ----------TestDualDac.spin para un ejemplo de aplicación. Objeto "DualDac" Interface: PUB PUB PUB PUB PUB Start : okay Stop Config(channel, dacPin, resolution, dacAddress) Remove(channel) Update(channel, attribute, value) Program: Variable: 73 Longs 29 Longs _________________ PUB Start : okay Inicia un cog Nuevo D/A. Usa método Config para activar un dac en un pin dado. _________ PUB Stop Detiene el proceso DAC y libera el cog. ____________________________________________________ PUB Config(channel, dacPin, resolution, dacAddress) Configura un el comando. channel dacPin resolution dacAddress DAC. Bloquea la ejecución del programa hasta que otro cog completa - 0 = canal 0, 1 = canal 1 - Numero de pin E/S que desarrolla el D/A - bits de conversión D/A (8 = 8 bits, 12 = 12 bits, etc.) Dirección de la variable que tiene el nivel de conversión D/A, un valor entre 0 y (2^resolucion) - 1. ____________________ PUB Remove(channel) Remueve un canal. Activa canales de pin E/S a entrada y limpia el modulo contador. Bloquea la ejecución del programa hasta que otro cog completa el comando. ______________________________________ PUB Update(channel, attribute, value) Actualiza la configuración de un canal DAC. Bloquea la ejecución del programa hasta que otro cog completa el comando. channel - 0 = canal 1 = canal 1 attribute - el atributo DAC para actualizar 0 -> dacPin 1 -> resolution 2 -> dacAddr 3 -> dacValue value - el valor del atributo para ser actualizado Kit Educativo de Practicas Propeller: Fundamentos · Página 189 Práctica de Módulos Contadores y Aplicaciones de Circuitos Pagina 190 · Kit Educativo de Prácticas Propeller: Fundamentos Apéndice A: Lista de Códigos de Objetos Apéndice A: Lista de Objetos Código FullDuplexSerialPlus.spin '' De Parallax Inc. Kit Educativo Propeller Practica de Objetos {{ ──────────────────────────────────────────────────────────────────────────────────────── Archivo: FullDuplexSerialPlus.spin Versión: 1.1 Derechos Reservados (c) 2008 Parallax, Inc. Ver al final del archive para términos de uso. Este es el objeto FullDuplexSerial v1.1 de la carpeta de la Librería de la Herramienta Propeller con documentación modificada y métodos para convertir cadenas de texto en valores numéricos en diversas bases. ──────────────────────────────────────────────────────────────────────────────────────── }} CON '' ''Caracteres Constantes de Control Terminal Serial Parallax ''──────────────────────────────────────────────────── HOME = 1 ''HOME = CRSRXY = 2 ''CRSRXY = CRSRLF = 3 ''CRSRLF = CRSRRT = 4 ''CRSRRT = CRSRUP = 5 ''CRSRUP = CRSRDN = 6 ''CRSRDN = BELL = 7 ''BELL = BKSP = 8 ''BKSP = TAB = 9 ''TAB = LF = 10 ''LF = CLREOL = 11 ''CLREOL = CLRDN = 12 ''CLRDN = CR = 13 ''CR = CRSRX = 14 ''CRSRX = CRSRY = 15 ''CRSRY = CLS = 16 ''CLS = 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 VAR long cog 'bandera/identificación cog long long long long long long long long long '9 longs próximos rx_head rx_tail tx_head tx_tail rx_pin tx_pin rxtx_mode bit_ticks buffer_ptr byte rx_buffer[16] byte tx_buffer[16] 'transmite y recibe buffers Kit Educativo de Practicas Propeller: Fundamentos · Página 191 Lista de Códigos de Objetos PUB start(rxpin, txpin, mode, baudrate) : okay {{ Inicia controlador serial en un cog nuevo rxpin entrada recibe señales del pin periférico de TX txpin salida envía señales al pin periférico de RX mode - bits en esta variable configuran la señal bit 0 invierte rx bit 1 invierte tx bit 2 abre fuente/drenado tx bit 3 ignora eco tx en rx baudrate - bits por segundo }} okay regresa falso si no hay cog disponible. stop longfill(@rx_head, 0, 4) longmove(@rx_pin, @rxpin, 3) bit_ticks := clkfreq / baudrate buffer_ptr := @rx_buffer okay := cog := cognew(@entry, @rx_head) + 1 PUB stop '' Detiene controlador serial libera un cog if cog cogstop(cog~ - 1) longfill(@rx_head, 0, 9) PUB tx(txbyte) '' Envía byte (puede esperar por espacio en buffer) repeat until (tx_tail <> (tx_head + 1) & $F) tx_buffer[tx_head] := txbyte tx_head := (tx_head + 1) & $F if rxtx_mode & %1000 rx PUB rx : rxbyte '' Recibe byte (puede esperar por byte) '' rxbyte regresa $00..$FF repeat while (rxbyte := rxcheck) < 0 PUB rxflush '' Flush receive buffer repeat while rxcheck => 0 PUB rxcheck : rxbyte '' Verifica si recibió byte (nunca espera) '' rxbyte regresa -1 si no se recibió byte, $00..$FF si hay byte rxbyte-if rx_tail <> rx_head Pagina 192 · Kit Educativo de Prácticas Propeller: Fundamentos Apéndice A: Lista de Códigos de Objetos rxbyte := rx_buffer[rx_tail] rx_tail := (rx_tail + 1) & $F PUB rxtime(ms) : rxbyte | t '' Espera milisegundos ms para recibir byte '' regresa -1 si no se recibió byte, $00..$FF si hay byte t := cnt repeat until (rxbyte := rxcheck) => 0 or (cnt - t) / (clkfreq / 1000) > ms PUB str(stringptr) '' Envía cero terminal de cadena que inicia en la dirección de memoria stringptr repeat strsize(stringptr) tx(byte[stringptr++]) PUB getstr(stringptr) | index '' Obtiene cero terminal de cadena y lo almacena, inicia en la dirección de memoria stringptr index~ repeat until ((byte[stringptr][index++] := rx) == 13) byte[stringptr][--index]~ PUB dec(value) | i '' Imprime un número decimal if value < 0 -value tx("-") i := 1_000_000_000 repeat 10 if value => i tx(value / i + "0") value //= i result~~ elseif result or i == 1 tx("0") i /= 10 PUB GetDec : value | tempstr[11] '' Obtiene la representación de carácter decimal de un numero de la terminal '' Regresa el valor correspondiente GetStr(@tempstr) value := StrToDec(@tempstr) PUB StrToDec(stringptr) : value | char, index, multiply '' Convierte la representación de cero terminal de cadena de un numero decimal a un valor value := index := 0 repeat until ((char := byte[stringptr][index++]) == 0) if char => "0" and char =< "9" value := value * 10 + (char - "0") if byte[stringptr] == "-" value := - value Kit Educativo de Practicas Propeller: Fundamentos · Página 193 Lista de Códigos de Objetos PUB bin(value, digits) '' Envía representación de carácter de un numero binario a la terminal. value <<= 32 - digits repeat digits tx((value <-= 1) & 1 + "0") PUB GetBin : value | tempstr[11] '' Obtiene representación de carácter binario de un numero de la terminal '' Regresa el valor correspondiente GetStr(@tempstr) value := StrToBin(@tempstr) PUB StrToBin(stringptr) : value | char, index '' Convierte representación de cero terminal de cadena de un numero binario a un valor value := index := 0 repeat until ((char := byte[stringptr][index++]) == 0) if char => "0" and char =< "1" value := value * 2 + (char - "0") if byte[stringptr] == "-" value := - value PUB hex(value, digits) '' Imprime un número hexadecimal value <<= (8 - digits) << 2 repeat digits tx(lookupz((value <-= 4) & $F : "0".."9", "A".."F")) PUB GetHex : value | tempstr[11] '' Obtiene representación de carácter hexadecimal de un numero de la terminal '' Regresa el valor correspondiente GetStr(@tempstr) value := StrToHex(@tempstr) PUB StrToHex(stringptr) : value | char, index '' Convierte una representación de cero terminación de cadena de un numero hexadecimal a un valor value := index := 0 repeat until ((char := byte[stringptr][index++]) == 0) if (char => "0" and char =< "9") value := value * 16 + (char - "0") elseif (char => "A" and char =< "F") value := value * 16 + (10 + char - "A") elseif(char => "a" and char =< "f") value := value * 16 + (10 + char - "a") if byte[stringptr] == "-" value := - value DAT '******************************************* '* Controlador serial lenguaje ensamblador * '******************************************* Pagina 194 · Kit Educativo de Prácticas Propeller: Fundamentos Apéndice A: Lista de Códigos de Objetos org ' ' ' Entry ' entry mov add if_z_ne_c if_z ' ' ' Recibe ' receive regresa t1,par t1,#4 << 2 'obtiene dirección estructura 'salta encabezado y finales pasados rdlong t2,t1 mov rxmask,#1 shl rxmask,t2 'obtiene rx_pin add rdlong mov shl 'obtiene tx_pin t1,#4 t2,t1 txmask,#1 txmask,t2 add t1,#4 rdlong rxtxmode,t1 'obtiene rxtx_mode add t1,#4 rdlong bitticks,t1 'obtiene bit_ticks add rdlong mov add t1,#4 rxbuff,t1 txbuff,rxbuff txbuff,#16 'obtiene buffer_ptr test test or or rxtxmode,#%100 wz rxtxmode,#%010 wc outa,txmask dira,txmask 'inicia tx pin de acuerdo a modo mov txcode,#transmit 'inicia ping-pong multitarea jmpret rxcode,txcode 'correo pedazo de código tx, luego test test jmp rxtxmode,#%001 wz rxmask,ina wc #receive 'espera por bit de inicio en pin rx mov mov shr add rxbits,#9 rxcnt,bitticks rxcnt,#1 rxcnt,cnt 'listo para recibir byte :bit add rxcnt,bitticks 'listo siguiente periodo bit :wait regresa jmpret rxcode,txcode 'corre pedazo de codigo tx, luego mov t1,rxcnt 'verifica de completo periodo sub cmps jmp t1,cnt t1,#0 #:wait wc test rcr rxmask,ina rxdata,#1 wc if_z_eq_c recibir bit if_nc 'recibe bit en pin rx Kit Educativo de Practicas Propeller: Fundamentos · Página 195 Lista de Códigos de Objetos if_nz byte ' ' ' Transmite ' transmit regresa if_z :bit if_z_and_c if_z if_nz :wait regresa transmisión de bit if_nc djnz rxbits,#:bit shr and test xor rxdata,#32-9 rxdata,#$FF rxtxmode,#%001 wz rxdata,#$FF 'justifica y corta byte recibido rdlong add wrbyte sub add and wrlong t2,par t2,rxbuff rxdata,t2 t2,rxbuff t2,#1 t2,#$0F t2,par 'guarda byte recibido jmp #receive 'byte completo, recibe siguiente 'si rx invertido, invierte byte jmpret txcode,rxcode 'corre pedazo de código rx, luego mov add rdlong add rdlong cmp jmp t1,par t1,#2 << 2 t2,t1 t1,#1 << 2 t3,t1 t2,t3 #transmit 'verifica encabezado y final add t3,txbuff rdbyte sub add and wrlong txdata,t3 t3,txbuff t3,#1 t3,#$0F t3,t1 or shl or mov mov txdata,#$100 txdata,#2 txdata,#1 txbits,#11 txcnt,cnt 'lectura byte para transmitir test test xor shr muxc muxnc add rxtxmode,#%100 wz rxtxmode,#%010 wc txdata,#1 txdata,#1 wc outa,txmask dira,txmask txcnt,bitticks 'salida bit en pin tx 'de acuerdo a modo wz 'obtiene byte 'listo siguiente cnt jmpret txcode,rxcode 'corre pedazo de código rx, luego mov t1,txcnt 'verifica si termino periodo sub cmps jmp t1,cnt t1,#0 #:wait djnz txbits,#:bit wc Pagina 196 · Kit Educativo de Prácticas Propeller: Fundamentos 'otro bit para transmitir? Apéndice A: Lista de Códigos de Objetos jmp byte. ' ' ' datos no inicializados ' t1 res t2 res t3 res #transmit rxtxmode bitticks res res 1 1 rxmask rxbuff rxdata rxbits rxcnt rxcode res res res res res res 1 1 1 1 1 1 txmask txbuff txdata txbits txcnt txcode res res res res res res 1 1 1 1 1 1 'byte completo, transmite siguiente 1 1 1 {{ ┌────────────────────────────────────────────────────────────────────────┐ │ TERMINOS DE USO: MIT Licencia │ │ │ ├────────────────────────────────────────────────────────────────────────┤ │Se autoriza, de forma gratuita, a cualquier persona que obtenga una │ │copia de este software y archivos de documentación asociados (el │ │"Software"), para trabajar con el Software sin restricción, incluyendo │ │sin limitación los derechos de uso , copiar, modificar, fusionar, │ │publicar, distribuir, sublicenciar, y / o vender copias del Software, y │ │para autorizar a los sujetos a quienes se proporcione el Software para │ │ello, sin perjuicio de las siguientes condiciones: │ │ │ │ │ │El aviso de copyright anterior y esta nota de permiso se incluirá en │ │todas las copias o partes sustanciales del Software. │ │ │ │EL SOFTWARE SE ENTREGA "TAL CUAL", SIN GARANTÍA DE NINGÚN TIPO, EXPRESA │ │O IMPLÍCITA, INCLUYENDO PERO NO LIMITADO A LAS GARANTÍAS DE │ │COMERCIALIZACIÓN, ADECUACIÓN A UN PROPÓSITO PARTICULAR Y NO INFRACCIÓN. │ │ │ │EN NINGÚN CASO LOS AUTORES O TITULARES SERAN RESPONSABLES DE │ │CUALQUIER RECLAMACIÓN, DAÑO U OTRA RESPONSABILIDAD, YA SEA EN UNA ACCIÓN│ │DE CONTRATO, AGRAVIO O DE OTRA DERIVADA DE O EN RELACION CON EL SOFTWARE│ │O EL USO PARA OTROS FINES DEL SOFTWARE │ └────────────────────────────────────────────────────────────────────────┘ }} Kit Educativo de Practicas Propeller: Fundamentos · Página 197 Lista de Códigos de Objetos SquareWave.spin '' De Parallax Inc. Kit Educativo Propeller Practica de Contadores y Circuitos '' SquareWave.spin ''Puede usarse para hacer alguno de los dos módulos contadores del cog ''para transmitir ondas cuadradas PUB Freq(Module, Pin, Frequency) | s, d, ctr '' Determina parámetros CTR para síntesis de 0..128 MHz en pasos de 1 Hz '' '' entrada: Pin = pin para salida de frecuencia '' Freq = actual Hz para sintetizar '' '' salida: ctr y frq tienen valores ctra/ctrb y frqa/frqb '' '' Usa modo NCO %00100 para 0..499_999 Hz '' Usa modo PLL %00010 para 500_000..128_000_000 Hz '' Frequency := Frequency #> 0 <# 128_000_000 'limite de frecuencias if Frequency < 500_000 ctr := constant(%00100 << 26) s := 1 'si 0 a 499_999 Hz, '..activa modo NCO '..shift = 1 else 'si 500_000 a 128_000_000 Hz, ctr := constant(%00010 << 26) '..activa modo PLL d := >|((Frequency - 1) / 1_000_000) 'determina PLLDIV s := 4 - d 'determina shift ctr |= d << 23 'activa PLLDIV spr[10 + module] := fraction(Frequency, CLKFREQ, s) 'calcula frqa/frqb value ctr |= Pin 'activa PINA para 'completar valores ctra/ctrb spr[8 + module] := ctr dira[pin]~~ PUB NcoFrqReg(frequency) : frqReg {{ Regresa frqReg = frequency × (2³² ÷ clkfreq) calculada con división long binaria. Esto es más rápido que la librería de punto flotante y toma menos espacio de código. Este método es una adaptación del método fracción del objeto CTR }} frqReg := fraction(frequency, clkfreq, 1) PRI fraction(a, b, shift) : f if shift > 0 a <<= shift if shift < 0 b <<= -shift 'si shift, pre-shift a o b izq 'para mantener bits significativos 'mientras asegura resultado repeat 32 f <<= 1 if a => b a -= b f++ a <<= 1 'realiza división long de a/b Pagina 198 · Kit Educativo de Prácticas Propeller: Fundamentos Apéndice B: Estudio de Soluciones Apéndice B: Soluciones de Estudios Soluciones de la Practica E/S y Tiempo Soluciones a las preguntas de E/S y Tiempo 1) Ocho 2) 32 KB 3) El chip Propeller proporciona 3.3 V. Cuando el pin E/S es alto el chip Propeller conecta internamente el pin E/S a su voltaje de 3.3V y cuando esta bajo se conecta a Tierra o 0V. 4) El código Spin se almacena en la RAM global del chip Propeller y el cog corriendo un programa interprete obtiene y ejecuta el código. 5) En vez de ejecutar código Spin que obtiene y ejecuta de la RAM global, el código maquina generado por lenguajes ensamblador se almacena en la RAM de 2KB del cog y se ejecuta directamente por el cog. 6) Hay diferentes formas de responder, la más concreta y centrada en Propeller seria que un método en un bloque de código con un mínimo de reglas de accesos declarados y nombre; mientras que un objeto es u n bloque comprimido de todos los códigos en un archivo .spin. Cada objeto contiene uno o más métodos. 7) Es el objeto que proporciona un punto de inicio para una aplicación dada que se carga en la RAM del chip Propeller. Aun si no es requerido, los objetos superiores organizan frecuentemente y orquestaran los objetos de la aplicación. 8) Cada bit en dira active la dirección (Entrada o salida) de un pin E/S para un cog. Cada bit en outa activa el estado de la salida (encendido o apagado) para un cog proporcionando el bit correspondiente en el registro dira que es activado como salida. 9) Hay cuatro formas diferentes de condiciones. El numero d repeticiones se puso a la derecha del comando repeat para especificar cuantas veces se repite el ciclo. La condición while especifica mantener corriendo el ciclo mientras una condición es verdadera. La condición until se uso para mantener el código corriendo hasta que ciertas condiciones ocurren. Finalmente una variable se incremento cada vez que pasaba por el ciclo repeat de cierto valor a cierto valor. 10) clkfreq 11) Necesitan estar abajo a indentados del comando repeat para ser parte del ciclo. El siguiente comando siguiendo el comando repeat que es del mismo o menor nivel de indentacion no es parte del ciclo repeat, ni lo es un comando que lo sigue sin importar su nivel de indentación. 12) El objetivo del valor del comando waitcnt fue típicamente calculado al sumar alguna fracción de clkfreq al registro cnt. Así waitcnt espera hasta que el registro cnt excede el valor waitcnt. 13) _xinfreq almacena la frecuencia de entrada del oscilador, mientras en esta práctica _clkmode se uso para definir la retroalimentación del cristal del chip Propeller y activar el PLL. Para más información revisar los términos en el Manual Propeller. 14) Multiplica la frecuencia por un valor. Las opciones de múltiplos son 1, 2, 4, 8 o 16. 15) La constante clkfreq se ajusta con la frecuencia del reloj del sistema del chip Propeller; mientras un valor constante para retrasos resultara en retrasos que cambian con el reloj del sistema 16) Un cristal externo. 17) Los registros de control de dirección y salida dira y outa respectivamente. Si un pin E/S se activa como entrada el valor del registro ina actualizara al correr cuando un comando ina se entrego regresando 1 o 0 para cada bit dependiendo del voltaje aplicado al pin E/S Kit Educativo de Practicas Propeller: Fundamentos · Página 199 Estudio de Soluciones 18) 19) 20) 21) 22) 23) 24) 25) 26) 27) 28) correspondiente. Los voltajes aplicados a un pin E/S sobre 1.65V generan un 1, los voltajes debajo de 1.65V regresan un 0. Un valor sencillo entre los corchetes a la derecha de dira/outa/ina se refiere a un bit sencillo en el registro. Dos valores separados por dos puntos se refieren a un grupo de bits seguidos. %, El indicador binario de numero. El pin E/S se active como entrada, así que solo monitorea el voltaje aplicado al pin y almacena un 1 en su bit ina si el voltaje esta encima de 1.65V o un 0 si está por debajo de 1.65V. Como entrada este pin no tiene efecto en circuitos externos. Cero. Asigna-Igual :=, Post-Activar ~~, Post-Limpiar ~, Bit inteligente !, Limite Máximo<#=, Limite mínimo #>=, Pre y Post-Incremento ++, Pre y Post-Decremento --, Movimiento a la Derecha >>=, y Movimiento a la izquierda <<=. Es igual ==, No es Igual <>, Es menor que <, Es mayor que >, Es igual o menor que =<, Es igual o mayor que =>. := es el asignador de igual mientras == es la comparación igual a. EL resultado de := asigna el valor del operando en la derecha del operando al operando en la izquierda. EL resultado de == simplemente compara dos valores y regresa -1si son iguales o 0 si no lo son. No, no es necesario aunque se piense útil. En esta práctica el valor que regresa ina para un bit fue 1 o 0 lo cual funciona bien para bloques if porque el código se ejecuta si una condición es no cero o no se ejecuta si la condición es cero (-1 es no cero) Global y Local. Variables globales se declaran en una sección VAR del objeto. Variables locales solo se usan por un método según se ejecuta. Los tres tamaños de una variable son byte (0 a 255), Word (0 a 65535) y long (-2,147,483,648 to 2,147,483,647). Las variables locales son automáticamente tamaño long mientras que las variables globales pueden declararse como byte, Word o long. Un carácter pipa |se usa para declarar variables locales a la derecha de la declaración de método. A la derecha de la pipa, puede declararse más de un nombre de variable separando por comas. Soluciones a Ejercicios de la Practica de E/S y Tiempo 1) Solución: outa[8..12] := dira[8..12] := %1111 2) Solución: dira[9] := outa[9]:= 1 outa[13..15] := %000 dira[13..15] := %111 3) Solución: dira[0..8] :=%111000000 4) Solución: outa[8]~~ outa[9]~ repeat !outa[8..9] waitcnt(clkfreq/100 + cnt) 5) Solución: repeat outa[0..7]!= ina[8..15] Pagina 200 · Kit Educativo de Prácticas Propeller: Fundamentos Apéndice B: Estudio de Soluciones 6) Solución: CON _xinfreq = 5_000_000 _clkmode = xtal1 + pll2x 7) Solución: waitcnt(clkfreq*5 + cnt) 8) Solución: outa[5..11]~~ waitcnt(clkfreq*3 + cnt) outa[5..11] := %1010101 9) Solución: PUB LightsOn | counter dira[4..9] := %111111 repeat counter from 4 to 9 outa[counter] := 1 waitcnt(clkfreq + cnt) repeat 10) Solución: PUB method dira[27] := 1 repeat if ina[0] outa[27]~~ waitcnt(clkfreq*5 + cnt) outa[27] ~ 11) Solución: PUB SecondCountdown dira[9..4]~~ repeat outa[9..4] from 59 to 0 waitcnt(clkfreq + cnt) 12) Solución: PUB SecondCountdown dira[9..4]~~ repeat repeat outa[9..4] from 59 to 0 waitcnt(clkfreq + cnt) 13) Solución: PUB PushTwoStart dira[4]~~ repeat until ina[23..21] == %101 outa[4]~~ 14) Solución: PUB PushTwoCountdown dira[9..4]~~ repeat until ina[23..21] == %101 outa[4]~~ repeat outa[9..4] from 59 to 0 waitcnt(clkfreq + cnt) Kit Educativo de Practicas Propeller: Fundamentos · Página 201 Estudio de Soluciones Soluciones a Proyectos de la Practica E/S y Tiempo 1) Ejemplo de Solución: ''File: NonActuatedStreetlights.spin ''Un prototipo alta velocidad de semáforo controlador N/S E/O. PUB StreetLights dira[9..4]~~ ' Activa pins E/S a salida repeat ' Ciclo principal outa[4..9] := %001100 waitcnt(clkfreq * 8 + cnt) outa[4..9] := %010100 waitcnt(clkfreq * 3 + cnt) outa[4..9] := %100001 waitcnt(clkfreq * 8 + cnt) outa[4..9] := %100010 waitcnt(clkfreq * 3 + cnt) ' ' ' ' ' ' ' ' N/S 8 s N/S 3 s N/S 8 s N/S 3 s verde, E/O rojo amarillo,E/O rojo rojo, E/O Verde rojo,E/O amarillo 2) Ejemplo de Solución: ''File: ActuatedStreetlightsEW.spin ''Un prototipo alta velocidad de semáforo controlador N/S E/O. PUB StreetLightsActuatedEW dira[9..4]~~ ' Activa pins E/S a salida repeat ' Ciclo Principal outa[4..9] := %001100 repeat until ina[21] waitcnt(clkfreq * 3 + cnt) outa[4..9] := %010100 waitcnt(clkfreq * 3 + cnt) outa[4..9] := %100001 waitcnt(clkfreq * 8 + cnt) outa[4..9] := %100010 waitcnt(clkfreq * 3 + cnt) ' ' ' ' ' ' ' ' ' N/S verde, E/O rojo Auto en calle E/O 8 s N/S amarillo,E/O rojo 3 s N/S rojo, E/O verde 8 s N/S rojo,E/O amarillo 3 s 3) Ejemplo de Solución: ''File: LedFrequenciesWithoutCogs.spin ''Experimente la molestia de desarrollar procesos que de otra ''manera podrían funcionar de manera independiente en Cogs ''separados. En este ejemplo, los LED parpadean a 1, 2, 3, 5, 7 y '' 11Hz. CON _xinfreq = 5_000_000 _clkmode = xtal1 + pll16x ' 5 MHz cristal externo ' 5 MHz cristal multiplicado → 80 MHz T_LED_P4 T_LED_P5 T_LED_P6 T_LED_P7 T_LED_P8 T_LED_P9 ' Constantes de incremento de tiempo = = = = = = 2310 1155 770 462 330 210 PUB Blinks | T, dT, count Pagina 202 · Kit Educativo de Prácticas Propeller: Fundamentos Apéndice B: Estudio de Soluciones dira[9..4]~~ ' Activa Pins E/S a Salida dT := clkfreq / 4620 T := cnt ' Activa incremento de tiempo ' Marca tiempo actual repeat ' Ciclo Principal T += dT waitcnt(T) ' Activa sig meta cnt ' Espera por meta if ++count == 2310 count := 0 ' Reinicia cada 2310 ' Actualiza if count // !outa[4] if count // !outa[5] if count // !outa[6] if count // !outa[7] if count // !outa[8] if count // !outa[9] cada estado de LED al conteo correcto. T_LED_P4 == 0 T_LED_P5 == 0 T_LED_P6 == 0 T_LED_P7 == 0 T_LED_P8 == 0 T_LED_P9 == 0 4) Ejemplo de Solución: ''File: MinuteSet.spin ''Imita botones de alarma de reloj. PUB SetTimer | counter, divide dira[9..4]~~ ' Activa pins E/S a salida repeat ' Ciclo principal 'Retrasa por 1 ms. waitcnt(clkfreq/1000 + cnt) ' Retrasa 1 ms {Si se presiona un botón... NOTA: Reiniciar el contador a -1 hace posible presionar y soltar rápidamente el botón y avanzar la pantalla minuto sin ningún retraso aparente.} if ina[21] or ina[23] counter++ else counter := -1 ' ' ' ' si se presiona botón incrementa contador de otra forma deja contador a -1 'Inicia sobre flujo de minuto if outa[9..4] == 63 outa[9..4] := 59 elseif outa[9..4] == 60 ' Si 0 pasa 63 ' reinicia a 59 ' si no 59 incrementos a 60 outa[9..4] := 0 ' activa a 0 'Activa contador duración de tiempo ms if counter > 2000 ' Si contador > 2000 (10 incrementos) divide := 50 ' 50 ms entre incrementos else ' de lo contrario divide := 200 ' 200 ms entre incrementos 'Si uno de los ciclos de ms han pasado if counter // divide == 0 ' si paso un tiempo Kit Educativo de Practicas Propeller: Fundamentos · Página 203 Estudio de Soluciones if ina[21] outa[9..4]++ elseif ina[23] outa[9..4]-- ' ' ' ' si botón P21 se presiona incrementa outa[9..4] si botón P23 se presiona decrementa outa[9..4] 5) Ejemplo de Solución: ''File: SecondCountdownTimer.spin ''Imita botones de alarma de reloj. PUB SetTimerWiCountdown | counter, divide, T dira[9..4]~~ repeat ' Activa pisn E/S a salida ' Ciclo principal repeat until ina[22] 'Retraso de 1 ms. waitcnt(clkfreq/1000 + cnt) ' Quiebra si ' Retraso 1 ms {Si se presiona un botón... NOTA: Reiniciar el contador a -1 hace posible presionar y soltar rápidamente el botón y avanzar la pantalla minuto sin ningún retraso aparente.} if ina[21] or ina[23] ' Si se presiona un botón counter++ ' incrementa contador else ' de otra forma counter := -1 ' active contador a -1 presiona 'Reinicia sobre flujo minutos if outa[9..4] == 63 outa[9..4] := 59 elseif outa[9..4] == 60 outa[9..4] := 0 ' ' ' ' Si 0 pasa sobre 63 reinicia a 59 De otra forma si 59 incrementa a 60 Activa a 0 'Activa duración de tiempo if counter > 2000 divide := 50 else divide := 200 ' ' ' ' Si contador > 2000 (10 incrementos) 50 ms entre incrementos de lo contrario 200 ms entre incrementos 'Si uno de los tiempos ha pasado if counter // divide == 0 if ina[21] outa[9..4]++ elseif ina[23] ' ' ' ' si uno de los tiempos ha pasado si botón P21 se presiona incrementa outa[9..4] de otra forma si botón P23 se outa[9..4]-T := cnt repeat while outa[9..4] T += clkfreq segundos waitcnt(T) outa[9..4]-- Pagina 204 · Kit Educativo de Prácticas Propeller: Fundamentos ' decrementa outa[9..4] ' Marca el tiempo ' repite mientras outa[9..4] no es 0 ' Calcula el siguiente valor de ' Espera por el... ' Decrementa outa[9..4] Apéndice B: Estudio de Soluciones Soluciones al Estudio de la Practica Métodos y Cogs Soluciones a las Preguntas de la Práctica Métodos y Cogs 1) Automáticamente regresa el control del programa y un valor a la llamada de método. 2) Eso depende de cuantos parámetros de variables locales aparezca en la lista de parámetros de las definiciones de método. La llamada a método pasa un valor a cada parámetro. 3) Uno 4) Si no hay valor especificado el método regresa el valor almacenado en su resultado variable, el cual es iniciado a cero cuando el método se llama. Un apodo para la variable resultante se puede declarar a la derecha del parámetro seguida por dos puntos. Por ejemplo un método declarado PUB MyMethod(parameter1, parameter2) : returnAlias regresara el valor almacenado por la variable returnAlias. 5) Una llamada de método y la dirección del arreglo variable que servirá como pila del cog. 6) Cog 0 usa RAM no utilizada para su pila; mientras otros cogs tiene que declarar espacio de pila en el bloque VAR. 7) El comando cognew automáticamente inicia un método en el siguiente cog disponible y regresa el numero de cog, mientras coginit permite especificar cual cog se va a usar para iniciar un método 8) Usar el comando cogstop. 9) Regresa información de dirección, regresa resultado, valor de parámetros y variables locales. 10) Los valores se almacenan en direcciones RAM que siguen de la ultima variable local. Los valores se ponen y mueven de estas localidades para soportar cálculos y operaciones de ciclo. 11) Un Segundo grupo de valores (dirección de regreso, resultado regresado…) se agrega a la pila. Cuando el método regresa el espacio de pila se reclama. 12) Declarar más espacio de pila de la que se piensa se va a usar. 13) El comando cognew regresa el valor del cog donde el método se inicio 14) Si, Se demostró en la sección Indexando Identificaciones de Cog Soluciones a los Ejercicios de Métodos y Cogs 1) Ejemplo: PUB SquareWave(pin, tHigh, tCycle) : success | tC, tH 2) Ejemplo: yesNo := SquareWave(24, clkfreq/2000, clkfreq/100) 3) Ejemplo: VAR swStack[40] 4) Ejemplo: VAR byte swCog 5) En este caso swCog almacenara el resultado de cognew (con o sin éxito). Vea el Manual Propeller para detalles: swCog := cognew(SquareWave(24, clkfreq/2000, clkfreq/100), @swStack) 6) Ejemplo: swCog := coginit(5, SquareWave(24, clkfreq/2000, clkfreq/100), @swStack) 7) Ejemplo: Kit Educativo de Practicas Propeller: Fundamentos · Página 205 Estudio de Soluciones VAR long swStack[120] 8) Ejemplo: VAR byte swCog[3] 9) Ejemplo: swCog[0] := cognew(SquareWave(5, clkfreq/20, clkfreq/10), @swStack) swCog[1] := cognew(SquareWave(6, clkfreq/100, clkfreq/5), @swStack[40]) swCog[2] := cognew(SquareWave(9, clkfreq/2000, clkfreq/500), @swStack[80]) Soluciones a los Proyectos de la Practica Métodos y Cogs 1) Ejemplo de Método: PUB SquareWave(pin, tHigh, tCycle) : success | tH, tC outa[pin]~ dira[pin]~~ tC := cnt repeat outa[pin]~~ tH := tC + tHigh tC += tCycle waitcnt(tH) outa[pin]~ waitcnt(tC) 2) Ejemplo de Solución: ''File: TestSquareWaveMethod.spin CON _xinfreq = 5_000_000 _clkmode = xtal1 + pll16x VAR long swStack[120] byte swCog[3] PUB TestSquareWave swCog[0] := cognew(SquareWave(5, clkfreq/20, clkfreq/10), @swStack) swCog[1] := cognew(SquareWave(6, clkfreq/100, clkfreq/5), @swStack[40]) swCog[2] := cognew(SquareWave(9, clkfreq/2000, clkfreq/500), @swStack[80]) 3) No se da solución, diviértase experimentando! Pagina 206 · Kit Educativo de Prácticas Propeller: Fundamentos Apéndice B: Estudio de Soluciones Soluciones al Estudio de la Practica de Objetos Soluciones a las Preguntas de la Practica de Objetos 1) Una llamada de método en el mismo objeto usa el nombre del método. Una llamada a un método en otro objeto usa un apodo que fue dado objeto en el bloque OBJ, luego un punto y luego el nombre de método. Así la diferencia es en vez de usar el NombreMetodo es ApodoObjeto.NombreMetodo 2) No, los parámetros se pasan y regresa de la misma forma que se haría en un método en el mismo objeto. 3) El objeto que está siendo declarado tiene que estar en la misma carpeta del objeto que lo está declarando o en la misma carpeta del programa de la Herramienta Propeller. 4) En la ventana del objeto, la cual puede verse a la izquierda de la ventana de información (F8) y también en la esquina superior izquierda del panel de la Herramienta Propeller. 5) Dos apostrofes pueden ponerse a la izquierda de un comentario que deberá aparecer en el modo de vista de la Herramienta Propeller. Un bloque de documentación de texto puede definirse con dobles llaves {{Comentarios de documentación}} 6) Presionando el botón de Documentación sobre el código. 7) Nombres de Método Start y Stop. 8) Declare múltiples copias del objeto en la sección OBJ, y llame cada uno de sus métodos Start. 9) Si el proceso que administra el objeto está corriendo en otro cog, la llamada al método Stop lo termina antes de iniciar el proceso en un cog nuevo. 10) Presionando en los caracteres de la Herramienta Propeller 11) Métodos públicos se declaran con PUB, privados con PRI. Métodos públicos pueden llamarse por comandos en otros objetos; métodos privados solo pueden llamarse del mismo objeto. 12) Declare múltiples copias del mismo objeto declarando un arreglo de objeto. Por ejemplo, el comando nickname[3] : ObjectName declara tres copias de ObjectName, nickname[0], nickname[1], and nickname[2]. Note que no hace copias extras del código objeto. Cada instrucción utiliza la misma copia de código Spin que se carga en el chip. 13) Se almacenan en la misma carpeta con el programa Herramienta Propeller archivo .exe 14) Para ver la información de interface del objeto presione el botón de documentación y la herramienta Propeller automáticamente genera esa información y la muestra junto con los comentarios de documentación. 15) En los códigos de programa. 16) Dada una dirección de inicio en RAM el método Str del Objeto FullDuplexSerial obtiene y transmite caracteres hasta que obtiene un cero. 17) Comentarios de documentación deben explicar que hace el método, sus parámetros (si hay) y sus valores de regreso. 18) Cadenas de caracteres y otras listas de valores pueden almacenarse en una sección del objeto DAT 19) Se usan para (1) declarar variables en bloques VAR, (2) Declarar tamaños de lista de elementos en bloques DAT y (3) regresar valores a direcciones dadas en bloques PUB y PRI. 20) El objeto Float usa FAdd para agregar dos números de punto flotante. 21) FloatString. 22) No, la herramienta Propeller empaca 1.5 en el formato de punto flotante al compilar y lo almacena con los códigos byte del programa. El comando a := 1.5 copia el valor en una variable 23) Una dirección de variable se pasa a un parámetro de método de objeto con el operador @. En vez de este formato: ObjectNickname.MethodName(variableName), usa el siguiente formato: ObjectNickname.MethodName(@variableName). Kit Educativo de Practicas Propeller: Fundamentos · Página 207 Estudio de Soluciones 24) Un objeto puede declarar una lista de variables en cierto orden y luego asignarles valores que el objeto usara. Así, las direcciones de la primer variable en la lista pueden pasarse al método del objeto. 25) El objeto usara long, word o byte y las direcciones. Por ejemplo, si la dirección se pasa a un parámetro llamado address, el objeto puede accesar el valor almacenado por la variable con long[address][0] o solo long[address]. Para almacenar la variable declarada inmediatamente a la derecha de la variable en address puede usar long[address][1]. Para la segunda variable a la derecha puede usar long[address][1] y así sucesivamente. 26) Si, Esto puede ser útil algunas veces porque el objeto padre puede simplemente actualizar un valor variable y un objeto corriendo otro proceso se actualizara automáticamente basado en ese valor. 27) Si, Esto se usa cuando un proceso está corriendo en otro cog y el objeto padre necesita uno o más de sus variables para actualizarse automáticamente por otros procesos, Soluciones a los Ejercicios de la Practica de Objetos 1) Solución: led : "MyLedObject" 2) Solución: led.On(4) 3) Con la ayuda del mapa de Caracteres de la Herramienta Propeller: 102, 32, 61, 32, 84, 22. 4) Solución: PRI calcArea(height, width) : area 5) Solución: Uart[5] : "FullDuplexSerial" 6) Solución: uart[2].str(String("Hello!!!")) 7) Solución: DAT Hi byte Hello!!! , 0 8) Solución: c := f.fmul(d, pi) 9) Solución: address := fst(c) Soluciones a los Proyectos de la Practica de Objetos 1) Objeto Ejemplo: {{Bs2IoLite.spin Las características de esta llamada a método similares a los comandos PBASIC para el micro controlador BASIC Stamp 2, tales como high, low, in0 a in15, toggle, y pause. }} PUB high(pin) ''Hace pin salida-alta. Pagina 208 · Kit Educativo de Prácticas Propeller: Fundamentos Apéndice B: Estudio de Soluciones outa[pin]~~ dira[pin]~~ PUB low(pin) ''Hace pin salida-baja outa[pin]~ dira[pin]~~ PUB in(pin) : state {{Regresa el estado del pin. Si el pin es salida el estado refleja la señal de salida. Si el pin es entrada el estado será 1 si el voltaje aplicado al pin esta sobre 1.65V o 0 si esta debajo}} state := ina[pin] PUB toggle(pin) ''Cambia el estado de pin de salida (alto a bajo o bajo a alto). !outa[pin] PUB pause(ms) | time ''Detiene el programa por ms. Esto aplica al cog haciendo la ''llamada. Otros cogs no se afectan. time := ms * (clkfreq/1000) waitcnt(time + cnt) 2) Para modificar la Terminal Serial Parallax, guarde una copia de PropellerCOM con un nuevo nombre como TestPropellerStack.ht. Cambie el Baud Rate de la Terminal Serial Parallax de 57600 a 19200. El objeto modificado StackLenghtDemo tiene varios cambios. EL código debajo del objeto/código probándose para uso de pila se reemplazo con el código del objeto Blinker. La variable de pila de objeto Stack se incremento a 32 longs. Así en el código temporal para probar la sección de uso de pila la llamada a método start se modifico para trabajar con el objeto Blinker. Corra el objeto StackLenghtDemo para probar la pila requerida por el método Blink para iniciar otro cog. Después de que la herramienta Propeller ha completado la descarga tendrá 2 segundos para conectar la Terminal Serial Parallax. El resultado deberá ser 9 Como el resultado es 9 en vez del 10 predicho por el método en la práctica, este proyecto expone un error en la sección titulada “Cuanto espacio de pila se necesita para iniciar un cog?” La variable local time se elimino del método Blink pero no de la discusión de cuanto espacio de pila necesita el método Blink. {{StackLengthDemoModified.spin Esta es una versión modificada del Objeto StackLengthDemo de la carpeta de librería demos del Propeller. Esta versión modificada prueba el método Blink del objeto Blinker de la Práctica de Objetos del Kit Educativo Propeller para requerimientos de espacio de pila. Ver proyecto #2 en la práctica de Objetos para más información.}} Kit Educativo de Practicas Propeller: Fundamentos · Página 209 Estudio de Soluciones {••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••• Código Temporal para uso de Pila •••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••} CON _clkmode _xinfreq = xtal1 + pll16x = 5_000_000 OBJ Stk "Stack Length" 'Incluye Objeto Stack Length : PUB TestStack Stk.Init(@Stack, 32) start(4, clkfreq/10, 20) waitcnt(clkfreq * 3 + cnt) Stk.GetLength(30, 19200) baud 'Usa cristal * 16 para serial rápida 'Cristal Externio5 MHz en XI & XO 'Inicia espacio de pila reservado (reservado abajo) 'Ejercicio código/objeto bajo prueba 'Espera tiempo para uso máx. de pila 'Transmite resultados salida serial P30 a 19,200 {••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••• Probando Código/Objeto para uso de pila •••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••} {{ File: Blinker.spin Ejemplo administración de cog para proceso LED blinking. SCHEMATIC ─────────────────────────────── 100 ω LED pin ──────────┐ GND ─────────────────────────────── }} VAR long stack[32] byte cog 'Cog Espacio de pila 'Cog ID PUB Start(pin, rate, reps) : success {{ Inicia Nuevo proceso blinking en Nuevo cog; Regresa verdadero si tiene éxito. Parámetros: pin la E/S conectada al circuito LED → ver esquemático rate Ciclo encendido/ Apagado definido por ciclos de reloj reps el número de ciclos encendido/apagado }} Stop success := (cog := cognew(Blink(pin, rate, reps), @stack) + 1) PUB Stop ''Detiene proceso Blinking, si hay. if Cog cogstop(Cog~ - 1) PUB Blink(pin, rate, reps) Pagina 210 · Kit Educativo de Prácticas Propeller: Fundamentos Apéndice B: Estudio de Soluciones {{ Parpadea un circuito LED conectado a un pin a una frecuencia dada por rep repeticiones Parámetros: pin la E/S conectada al circuito LED → ver esquemático rate Ciclo encendido/ Apagado definido por ciclos de reloj reps el número de ciclos encendido/apagado }} dira[pin]~~ outa[pin]~ repeat reps * 2 waitcnt(rate/2 + cnt) !outa[pin] 3) Esta solución usa variables globales para days, hours, minutes, y seconds, y el método GoodTimeCount actualiza los cuatro valores. También es posible solo seguir segundos y usar otros métodos para convertir a días, horas, etc. ''File: TickTock.spin VAR long stack[50] byte cog long days, hours, minutes, seconds PUB Start(setDay, setHour, setMinutes, setSeconds) : success {{ Rastera tiempo en otros cogs. Parámetros setDay setHour setMinutes setSeconds }} valores de inicio para: - día - hora - minuto - segundo days := setDay hours := setHour minutes := setMinutes seconds := setSeconds Stop cog := cognew(GoodTimeCount, @stack) success := cog + 1 PUB Stop ''Detiene tiempo continuo. if Cog cogstop(Cog~ - 1) PUB Get(dayAddr, hourAddr, minAddr, secAddr) | time {{ Kit Educativo de Practicas Propeller: Fundamentos · Página 211 Estudio de Soluciones Obtiene el tiempo actual. Los valores se guardan en variables a las direcciones proporcionadas para los parámetros del método Parámetros: dayAddr hourAddr minAddr secAddr }} long[dayAddr] long[hourAddr] long[minAddr] long[secAddr] dirección dirección dirección dirección := := := := variable día variable horas variable minutos segundos days hours minutes seconds PRI GoodTimeCount | dT, T dT := clkfreq T := cnt repeat T += dT waitcnt(T) seconds ++ if seconds == 60 seconds~ minutes++ if minutes == 60 minutes~ hours++ if hours == 24 hours~ days++ Pagina 212 · Kit Educativo de Prácticas Propeller: Fundamentos Apéndice B: Estudio de Soluciones Soluciones al Estudio de Módulos Contadores y Aplicaciones de Circuitos Soluciones a Preguntas de Módulos Contadores y Aplicaciones de Circuitos 1) Cada cog tiene dos módulos contadores, A y B. 2) PHS, FRQ, y CTR. 3) PHSA, FRQA, y CTRA. 4) PHSB, FRQB, y CTRB. 5) El registro FRQ. 6) El registro CTR (control). 7) En modo NCO el bit 31 de un registro phs dado se usa para controlar una E/S en modo terminación sencilla o dos en modo diferencial. En modo PLL la bandera de acarreo controla el estado de pins E/S (a.k.a PHS bit 32). 8) Si una resistencia de sensor o capacitancia varia con una variable ambiental, una medición de descarga RC regresa un tiempo proporcional al valor del sensor. 9) No, Pero lo es con muchos otros micro controladores. 10) Si, con modo NEG, CTRMODE es %01100. 11) Después de que el capacitor se carga completamente, su voltaje tomara un tiempo en descargarse mientras drena a través de una Resistencia. Como resultado el voltaje tarda cierto tiempo arriba del límite lógico 1.65V. Por cada ciclo de reloj que el voltaje está por encima del disparo lógico del pin E/S suma el valor de FRQ a PHS. Después de que se descargo el voltaje FRQ ya no se suma a PHS, así PHS continua almacenando el número de ciclos que la seña estaba en alto. 12) En bits 30..26 de un registro dado CTR. 13) El modo de una operación de modulo contador dado. 14) Los campos MTRMODE y APIN 15) El valor recomendado es 1, pero mientras FRQ almacena un valor no cero no causa sobre flujo en el registro PHS durante la medición, puede usarse para medir la descarga RC. 16) (1) Activa el bit de campo de modo del registro CTR. (2) Activa el bit de campo PIN del registro CTR. (3) Activa el registro PHS a un valor no cero, preferentemente 1. 17) El capacitor en el circuito RC tiene que cargarse. Entonces el valor inicial del registro PHS necesita notarse o puede limpiarse. Inmediatamente después el pin E/S debe activarse como entrada. 18) Porque cada contador cumula independientemente su registro PHS basado en el valor de un pin E/S dado. Así dos contadores pueden acumular sus respectivos registros PHS mientras sus respectivos circuitos RC están descargando pero que están por encima del disparo lógico. Mientras tanto el cog puede ejecutar otros comandos. 19) Con mediciones de descarga RC el modulo contador esta monitoreando el voltaje aplicado a un pin E/S. En conversión D/A el modulo contador está controlando un pin E/S. 20) El rango de FRQ a 232determina el duty. 21) El bit de acarreo de suma de fase, el cual puede pensar como el bit 32 del registro PHS. 22) Lo hace posible para el código para seleccionar de 256 diferentes niveles en vez de 232 diferentes niveles. 23) spr[8] hasta spr[13]. 24) spr[9]. 25) spr[10]. 26) El valor en el registro phsb. 27) (1) ctrb := myVar, y (2) spr[9] := myVar 28) spr[8] es ctra, y SPR[9] es ctrb. Cada uno de estos registros tiene varios bits de campo que afectan el comportamiento del contador. El operador mover a la izquierda << puede usarse Kit Educativo de Practicas Propeller: Fundamentos · Página 213 Estudio de Soluciones 29) 30) 31) 32) 33) 34) 35) 36) 37) 38) 39) 40) 41) 42) 43) para mover un grupo de bits a la izquierda con uno de estas variables. Una serie de operaciones mover a la izquierda pueden combinarse con sumas para determinar cada uno de los bits de campo del registro CTR dado. Bit 31 del registro PHS. La condición de acuerdo a CTR.spin as Siempre, quiere decir que el registro FRQ se suma al registro PHS con cada ciclo de reloj. 232/clkfreq clkfreq/232 (1)Activar pin E/S a entrada, (2) limpiar registro FRQ, o (3) limpiar bits 31..26 en el registro CNT. Si, El contador A puede enviar una señal y el Contador B puede enviar la otra. Actualizar el valor almacenado en el registro FRQ. Si, cualquier detector POSEDGE o NEGEDGE pueden muestrear el número de transiciones en un determinado tiempo para almacenar frecuencia. Detectores positivos y Negativos también se pueden usar para rastrear el tiempo alto y bajo el cual puede usarse para calcular frecuencia de una señal. No, comparan el estado del estado actual lógico del pin E/S con el estado lógico del ciclo previo. Si por ejemplo el estado lógico previo del pin fue 0 y el estado actual es 1, en modo POPSEDGE sumara FRQ a PHS porque ocurrió una transición positiva. No, mientras spr[13] refiere a phsb, no es bit direccional. El comando repeat while esta refiriéndose a un bit en el registro phsb. Sería posible determinar el valor de ese bit usando varias operaciones, tomaría más tiempo que solo verificar phsb[31] . 500 kHz a 128 MHz El circuito PLL del modulo contador necesita recibir una frecuencia de entrada del bit 31 del registro PHS. El valor almacenado en el registro FRQ determina la frecuencia del bit 31 del registro PHS, así como sucede en modo NCO. El circuito PLL del modulo contador multiplica por 16, luego un divisor reduce la frecuencia por una potencia de 2 que cae en el rango de 1 a 128. (a) Calcula la frecuencia del bit 31 de PHS. (b) Usa la frecuencia del bit 31 de PHS para calcular la frecuencia VCO. (c) Divide la frecuencia VCO por 27-PLLDIV. (1) Calcula el PLLDIV, lo cual es la potencia de 2 que la frecuencia VCO tendrá para este cálculo. (2) Multiplica la frecuencia PLL por 2(7-PLLDIV) para calcular la frecuencia VCO. (3) Dada la frecuencia VCO, calcula 1/16 de ese valor el cual es el bit 31 PHS (NCO) que el circuito PLL necesitara. (4) Como el valor almacenado en FRQ determina la frecuencia NCO, usa la frecuencia NCO para calcular el valor de registro FRQ. Soluciones a los Ejercicios de Módulos Contadores y Aplicaciones de Circuitos 1) Solución: ... ' ctra[30..26] := %01000 ctra[30..26] := %01100 ' Set mode to "POS detector" ' Set mode to "NEG detector" ... ' Charge RC circuit. ' Descarga Circuito RC ' dira[17] := outa[17] := 1 dira[17] := 1 outa[17] := 0 ... Pagina 214 · Kit Educativo de Prácticas Propeller: Fundamentos ' Set pin to output-high ' Set pin to output-low Apéndice B: Estudio de Soluciones 2) Solución: 'El duty para esta señal es 1/3.3. Como duty = FRQ/232, podemos resolver 32 1/3.3 = 'FRQ/2 para FRQ. FRQ = 1_301_505_241 ctrb[32..26] := %00110 ' Contador B a modo DUTY ctrb[5..0] := 7 frqb := 1_301_505_241 ' Activar duty para 3.3 V dirb[7] := 1 ' Activar P7 a salida 3) Solución: 'El duty para esta señal es 1/3.3. Como duty = FRQ/232, podemos resolver 32 1/3.3 = 'FRQ/2 para FRQ. FRQ = 1_301_505_241 spr[9] := (%00110<<26) + 7 ' Contador B a modo duty, transmite P7 spr[11] := 1_301_505_241 ' Activa duty para 3.3 V spr[6] |= |< 7 ' Activa P7 a salida 4) Usando registro FRQ = Frecuencia bit 31 PHS × 232 / (clkfreq = 80 MHz) redondeado al entero más cercano: Do6# → 59475, Re6# → 66787, Fa6# → 79457, Sol6# → 89185, La6# → 100111 5) El registro frqa deberá contener la frecuencia del bit 31 contenida en PHS × 232 / (clkfreq = 20 MHz) = 224_734 (redondeado al entero más cercano). ctra[30..26] := %00100 ctra[5..0] := 16 frqb := 224_734 dira[16]~~ ' Contador B a modo duty, transmite P16 ' 20 MHz Do7 ' 20 MHz Do7 6) Solución: ... 'repeat index from 0 to 7 Repite index de 0 to 12 ... DAT 'MODIFICADO.............................................. 'Valores 80 MHz frqa para onda cuadrada de nota musical 'aproximaciones con el modulo contador configurado a NCO: ' Do6 Do6# Re6 Re6# Mi6 Fa6 Fa6# notes long 56_184, 59_475 63_066, 66787, 70_786, 74_995, 79457 ' Sol6 Sol6# La6 La6# Si6 Do7 long 84_181, 89_185, 94_489, 100_111, 105_629, 112_528 7) Como el objeto SquareWave usa clkfreq para calcular los valores de su registro FRQ, el único cambio que necesita hacerse es _xinfreq = 2_000_000 en vez de _xinfreq = 5_000_000. 8) Anexar scale = 16_777_216 con * 2, y luego ajustar el ciclo repeat de 0 a 266 a 0 a 127. 9) Cambiar ctrb[30..26] := %01110 a ctrb[30..26] := %01010. Para obtener ciclos completos. Puede iniciar el outa[27] alto en vez de bajo. Esto asume un piezospeaker, el cual no consume corriente cuando se le aplica voltaje. Algunas bocinas parecen piezospeakers pero tienen inductores dentro lo cual toma mucha corriente cuando un se aplica un voltaje DC. 10) Active tC a clkfreq/50 (es 20 ms). Por el pulso 1.5 ms, 1.5 × 10-3 × clkfreq es aproximadamente equivalente a (1/667) × clkfreq, o clkfreq/667. Así, tHa debe ser Kit Educativo de Practicas Propeller: Fundamentos · Página 215 Estudio de Soluciones clkfreq/667. Otra forma de hacerlo sería sumar un bloque CON con us = clkfreq/1_000_000. Entonces, tHa puede ser 1500 * us. 11) Sume un bloque CON con us = clkfreq/1_000_000. Inicialice tC a 20_000 * us. Inicialice tHa a 700 * us. Sume una variable local llamada count al método TestPwm. Cambie repeat a repeat tHa from (700 * us) to (2200 * us). 12) Solución: {{ TestDualPWM(Exercise 12).spin Usando dos módulos contadores demuestra como enviar una señal PWM. El ciclo de tiempo es el mismo para ambas señales pero los tiempos en alto son independientes uno del otro. }} CON _clkmode = xtal1 + pll16x _xinfreq = 5_000_000 PUB TestPwm | tc, tHa, tHb, t, us us := clkfreq/1_000_000 ctra[30..26] := ctrb[30..26] := %00100 sencilla ctra[5..0] := 4 control ctrb[5..0] := 6 frqa := frqb := 1 reloj ' Reloj sistema → 80 MHz ' <- Suma us ' <- Suma ' Contadores A y B → NCO terminación ' Activa pins para contadores para ' Suma 1 a phs con cada ciclo de dira[4] := dira[6] := 1 ' Activa pins E/S salida tC := 20_000 * us tHa := 700 * us tHb := 2200 * us ' <- Cambia Set up cycle time ' <- Cambia Set up tiempo alto ' <- Cambia t := cnt ' Marca tiempo actual. repeat tHa from (700 * us) to (2200 * us) ' <- Cambia señal Repeat PWM phsa := -tHa ' Define e inicia el pulso A phsb := -tHb ' Define e inicia el pulso B t += tC ' Calcula ciclo repeat waitcnt(t) ' Espera por ciclo Soluciones a Proyectos de Módulos Contadores y Aplicaciones de Circuitos 1) Solución: Versiones comentadas y no comentadas de DAC 2 Channel.spin se muestran abajo. Note en la versión no comentada que realmente no toma mucho código para llevar a cabo la especificación del proyecto. ''DAC 2 Channel.spin Pagina 216 · Kit Educativo de Prácticas Propeller: Fundamentos Apéndice B: Estudio de Soluciones ''Objeto 2 channel DAC. Cada canal se puede configurar para pin E/S y resolución (bits) VAR ' Almacena valores que funcionan como escaleras LSB para los registros FRQ. long lsb[2] PUB Init(channel, ioPin, bits, level) {{ Inicia un DAC. • channel - 0 o 1 • ioPin - Escoge pin E/S DAC • bits - Resolución (8 bits, 10 bits, etc.) bits • level - Nivel de Voltaje Inicial = 3.3 V * level ÷ 2 }} dira[ioPin]~ ' Activa pin E/S a entrada spr[8 + channel] := (%00110 << 26) + ioPin ' Configura CTR para modo duty y pin E/S lsb[channel] := |< (32 - bits) Update(channel, level) dira[ioPin] ~~ ' Define LSB para registro FRQ ' Activa duty inicial ' Activa pin E/S a salida PUB Update(channel, level) '' Actualiza el nivel transmitido por un canal ADC a '' bits '' level = 3.3 V * level ÷ 2 spr[10 + channel] := level * lsb[channel] ' Actualiza salida DAC PUB Remove(channel) ''Reclama el módulo contador y activa los grupos de pin E/S a entrada. dira[spr[8+channel] & %111111]~ ' Activa pin E/S a entrada spr[8+channel]~ ' Limpia canales registro CTR ''DAC 2 Channel.spin (versión no comentada) VAR long lsb[2] PUB Init(channel, ioPin, bits, level) dira[ioPin]~ spr[8 + channel] := (%00110 << 26) + ioPin lsb[channel] := |< (32 - bits) Update(channel, level) dira[ioPin] ~~ PUB Update(channel, level) spr[10 + channel] := level * lsb[channel PUB Remove(channel) dira[spr[8+channel] & %111111]~ spr[8+channel]~ Kit Educativo de Practicas Propeller: Fundamentos · Página 217 Estudio de Soluciones 2) Solución: Líneas sumadas están marcadas abajo. Vamos a asumir que los servos están conectados a P5 y P7. En el ciclo repeat los campos PIN de ctra y ctrb tendrán que activarse a 4 y 6 por el primer par de pulsos, luego cambiar a 5 y 7 por el segundo grupo de pulsos. También un waitcnt tiene que agregarse después de cada par de pulsos para que los pulsos puedan terminar antes de moverse al siguiente par de pulsos A este punto el código todavía tiene 15.6 ms en el ciclo repeat, porque no agregar otros servos y hacer un objeto servo control? Vea forums.parallax.com → Propeller Chip → Propeller Education Kit Labs → PE Kit Servo Control para un ejemplo. {{ TestDualPWM (Project 2).spin Usando dos módulos contadores demuestra como enviar una señal dual PWM. El tiempo de ciclo es el mismo para ambas señales pero los tiempos alto son independientes uno del otro. Modificado para controlar cuatro servos. }} CON _clkmode = xtal1 + pll16x _xinfreq = 5_000_000 PUB TestPwm | tc, tHa, tHb, t, us us := clkfreq/1_000_000 ctra[30..26] := ctrb[30..26] := %00100 sencilla ctra[5..0] := 4 ctrb[5..0] := 6 frqa := frqb := 1 reloj ' Reloj sistema→ 80 MHz ' <- Suma us ' <- Suma ' Contadores A y B → NCO terminación ' Activa pins para control ' Suma 1 a phs con cada ciclo de dira[4] := dira[6] := 1 dira[5] := dira[7] := 1 ' Activa pisn E/S a salida tC := 20_000 * us tHa := 700 * us tHb := 2200 * us ' <- Cambia Set up tiempo de ciclo ' <- Cambia Set up tiempos alto ' <- Cambio t := cnt ' Marca tiempo actual. repeat tHa from (700 * us) to (2200 * us) ' <- Cambia señal PWM Repeat ' Primer par de pulsos ctra[5..0] := 4 contadores ctrb[5..0] := 6 phsa := -tHa phsb := -tHb waitcnt(2200 * us + cnt) ' Segundo par de pulsos ctra[5..0] := 5 contadores ctrb[5..0] := 7 phsa := -tHa phsb := -tHb waitcnt(2200 * us + cnt) Pagina 218 · Kit Educativo de Prácticas Propeller: Fundamentos ' Activa pins para controlar ' Define e inicia el Pulso A ' Define e inicia el pulso B ' Espera por pulsos para terminar ' Activa pins para controlar ' Define e inicia el pulso A ' Define e inicia el pulso B ' Espera por pulsos para terminar Apéndice B: Estudio de Soluciones ' Espera por ciclo 20 ms para completar antes de repetir ciclo t += tC ' Calcula ciclo repeat waitcnt(t) ' Espera ciclo 3) Solución Objeto DAC: (Trabaja pero tenga en cuenta que no es la única solución posible) {{ ''DualDac.spin ''Proporciona dos canales de módulos contadores de otro cog para conversión D/A Como usar este objeto en la aplicación -----------------------------------------1) Declare canales D/A variables. Ejemplo: VAR ch[2] 2) Declare el objeto DualDac. Ejemplo: OBJ dac : DualDac 3) Llame el método start. Ejemplo: PUB MethodInMyApp '... dac.start 4) Active salidas D/A. Ejemplo: ch[0] := 3000 ch[1] := 180 5) Configure canales DAC. Ejemplo: 'Canal 0, pin 4, 12-bit DAC, ch[0] almacena el valor DAC. dac.Config(0,4,12,@ch[0]) 'Como ch[0] se activo a 3000 en paso 4, la salida DAC P4 será '3.3V * (3000/4096) 'Canal 1, pin 6, 8-bit DAC, ch[1] almacena el valor DAC. dac.Config(1,6,8,@ch[1]) 'Como ch[1] se activo a 180 en paso 4, la salida DAC P6 será ' 3.3V * (180/256) 6) Métodos y características en este objeto también hace posible: - remover un canal DAC - cambiar en canal DAC: o pin E/S o Resolución o Dirección de Control variable o Valor almacenado por la variable control ver también -------TestDualDac.spin para un ejemplo de aplicación. }} VAR ' Variables globales long cog, stack[20] ' Para objeto long cmd, ch, pin[2], dacAddr[2], bits[2] ' Para intercambio de info en cogs Kit Educativo de Practicas Propeller: Fundamentos · Página 219 Estudio de Soluciones PUB Start : okay '' Inicia un cog D/A. Usa método Config para activar un dac en un pin. okay := cog := cognew(DacLoop, @stack) + 1 PUB Stop '' Detiene el proceso DAC y libera un cog. if cog cogstop(cog~ - 1) PUB Config(channel, dacPin, resolution, dacAddress) '' Configura un DAC. Bloque ejecución de programa hasta que otro cog completa el comando. '' channel - 0 = canal 0, 1 = canal 1 '' dacPin - número pin E/S que desarrolla el D/A '' resolution - bits de conversión D/A (8 = 8 bits, 12 = 12 bits, etc.) '' dacAddress dirección de la variable que tiene el nivel de conversión D/A, un valor entre 0 y (2^resolucion) - 1. ch pin[channel] bits[channel] dacAddr[channel] cmd repeat while cmd completa cmd. := := := := := channel dacPin |<(32-resolution) dacAddress 4 ' Copia parámetros a variable global. ' Activa el comando para PRI DacLoop. ' Bloquea ejecución hasta que se PUB Remove(channel) '' Remueve un canal. Activa canales pin E/S a entrada y limpia el modulo contador. '' Bloque ejecución de programa hasta que otro cog completa el comando. ch := channel cmd := 5 repeat while cmd cmd. ' Copia parámetro a variable global ' Activa comando para PRI DacLoop. ' Bloque ejecución hasta completar PUB Update(channel, attribute, value) '' Actualiza configuración de canal DAC. '' Bloquea ejecución de programa hasta que cog completa comando. '' channel - 0 = canal 0, 1 = canal 1 '' attribute - El atributo DAC para actualizar '' 0 -> dacPin '' 1 -> resolution '' 2 -> dacAddr '' 3 -> dacValue '' value - El valor del atributo a ser actualizado ch := channel case attribute 0 : cmd := attribute + (value << 16) ' ' ' 1 ' copia parámetro a variable global. ' atributo param decide que hacer. ' 0 = cambia pin DAC. ' pin E/S en upper 16 bits, lower 16 'cmd = 0. Opciones 1 a 3 no requiere un comando para PRI DacLoop -> PRI DacConfig. Solo requiere actualizar ciertas variables globales. : bits[ch] := |<(32-value) ' 1 = Cambia resolución. Pagina 220 · Kit Educativo de Prácticas Propeller: Fundamentos Apéndice B: Estudio de Soluciones 2 : dacAddr[channel] := value control. 3 : long[dacAddr] := value control. repeat while cmd cmd. ' 2 = Cambia dirección variable de PRI DacLoop | i ' ' ' ' ' ' ' 3 = Cambia valor de variable de ' Bloquea ejecución hasta completar Ciclo checa por cmd, Luego actualiza Valores salida DAC. Ciclo principal por con iniciado. Si cmd <> 0 llama DatConfig Actualiza modulo contador FRQA y repeat if cmd DacConfig repeat i from 0 to 1 FRQB. spr[10+ch] := long[dacAddr][ch] * bits[ch] PRI DacConfig | temp ' Actualiza configuración DAC basada ' en cmd. temp := cmd >> 16 ' Si attribute = 0, temp obtiene pin. case cmd & $FF ' Mascara cmd y evalúa caso por caso. 4: ' 4 -> Configura DAC. spr[8+ch] := (%00110 << 26) + pin[ch] ' Almacena mode y pin en registro CTR. dira[pin[ch]]~~ ' Dirección de pin -> salida. 5: ' 5 -> Remueve DAC. spr[8+ch]~ ' Limpia registro CTR. dira[pin[ch]]~ ' Hace pin E/S entrada. 0: ' 0 -> actualice pin. dira[pin[ch]]~ ' Hace pin entrada. pin[ch] := temp ' Obtiene Nuevo pin de variable temp local spr[8+ch] := (%00110 << 26) + pin[ch] ' Actualiza CTR con nuevo pin. dira[pin[ch]]~~ ' Actualiza nueva dirección pin E/S -> salida cmd := 0 otro cog. ' limpia cmd para detener bloqueo en Solución – Menú manejando objeto prueba para DualDac.spin ''TestDualDAC.spin ''Menú de usuario para pruebas DualDac.spin CON _clkmode = xtal1 + pll16x _xinfreq = 5_000_000 ' Sistema reloj→ 80 MHz ' Constantes Terminal Serial Parallax CLS = 16, CR = 13, CLREOL = 11, CRSRXY = 2, BKSPC = 8, CLRDN = 12 OBJ debug : "FullDuplexSerialPlus" dac : "DualDAC" PUB TestPwm | channel, dacPin, resolution, ch[2], menu, choice debug.start(31, 30, 0, 57600) waitcnt(clkfreq * 2 + cnt) debug.str(@_Menu) Kit Educativo de Practicas Propeller: Fundamentos · Página 221 Estudio de Soluciones dac.start repeat debug.tx(">") case menu := debug.rx "C", "c": debug.str(@_Channel) channel := debug.getdec debug.str(@_Pin) dacPin := debug.getdec debug.str(@_Resolution) resolution := debug.getdec dac.Config(channel, dacPin, resolution, @ch[channel]) "S", "s": debug.str(@_Channel) channel := debug.getdec debug.str(@_Value) ch[channel] := debug.getdec "U", "u": debug.str(@_Update) case choice := debug.rx "P", "p": debug.str(@_Channel) channel := debug.getdec debug.str(@_Pin) dacPin := debug.getdec dac.update(channel, 0, dacPin) "B", "b": debug.str(@_Channel) channel := debug.getdec debug.str(@_Resolution) resolution := debug.getdec dac.update(channel, 1, resolution) "R", "r": debug.str(@_Channel) channel := debug.getdec dac.Remove(channel) debug.str(String(CRSRXY, 1,4, BKSPC, CLRDN)) DAT _Menu byte byte _Channel byte _Pin byte _Resolution byte _Value byte _Update byte byte CLS, "C = Configure DAC", CR, "S = Set DAC Output", CR "U = Update DAC Config", CR, "R = Remove DAC", CR, 0 CR, "Channel (0/1) > ", 0 "Pin > ", 0 "Resolution (bits) > ", 0 "Value > ", 0 "Update Choices:", CR, "P = DAC Pin", CR,"B = Bits (resolution)" CR, 0 Pagina 222 · Kit Educativo de Prácticas Propeller: Fundamentos Apéndice C: Lista de Componentes Apéndice C: Lista de Componentes kit PE Partes, cantidades y estilos de están sujetos a cambios sin previo aviso. Tabla C-1: Kit Educativo Propeller – Versión 40-Pin DIP (#32305) # Parte Cant. Descripción 130-32305 1 Propeller DIP Plus Kit, ver Tabla 3-3 en página 25 130-32000 1 Kit de partes Proyecto Propeller, ver Tabla C-2 abajo 700-00077 1 Breadboard Set, ver Tabla 3-1 en página 24 32201 1 Propeller Plug con Cable retráctil USB A a Mini-B, ver Tabla 3-2 en página 24 110-32305 1 Caja de plástico Tabla C-2: Kit de partes Proyecto PE (#130-32000) # Parte Cant. Descripción 150-01011 20 Resistencia 100 Ω, 1/4 watt (café-negro-café) 150-01020 4 Resistencia 1 kΩ, 1/4 watt (café-negro-rojo) 150-01030 8 Resistencia 10 kΩ, 1/4 watt (café-negro-anaranjado) 150-01040 3 Resistencia 100 kΩ, 1/4 watt (café-negro-amarillo) 150-02020 4 Resistencia 2 kΩ, 1/4 watt (rojo-negro-rojo) 150-02210 8 Resistencia 220 Ω, 1/4 watt (rojo-rojo-café) 150-04710 4 Resistencia 470 Ω, 1/4 watt (Amarillo-violeta-café) 150-04720 1 Resistencia 4.7 kΩ, 1/4 watt (Amarillo-violeta-rojo) 152-01031 2 Potenciometro10 kΩ 200-01010 4 Capacitor 100 pF, mono radial (101) 200-01031 4 Capacitor 0.01 µF 50 V, poly (103) 200-01040 4 Capacitor 0.1 µF, mono radial (104) 201-01050 1 Capacitor 1 µF, electrolitico (1µF) 201-01062 2 Capacitor 10 µF, electrolítico (10µF) 350-00001 2 LED Verde 350-00003 2 LED Infrarrojo 350-00006 2 LED Rojo Kit Educativo de Practicas Propeller: Fundamentos · Página 223 Lista de Componentes Tabla C-2: Kit de partes Proyecto PE (#130-32000) # Parte Cant. Descripción 350-00007 2 LED Amarillo 350-00014 2 Receptor Infrarrojo 350-00018 2 Fototransistor Infrarrojo 350-00029 2 Fototransistor 350-90000 2 Protector LED 350-90001 2 Malla LED 400-00002 4 Switch 451-00303 2 Conector 3-pin 602-00015 1 CI Amp-Op Dual IC, 8-pin DIP 800-00016 4 3" cable, bolsa de 10 900-00001 2 Piezospeaker Pagina 224 · Kit Educativo de Prácticas Propeller: Fundamentos Apéndice D: Diagrama de Bloque del Microcontrolador Apéndice D: Diagrama de Bloque del Micro controlador Kit Educativo de Practicas Propeller: Fundamentos · Página 225 Apéndice E: LM2940CT-5.0 Límite de Corriente A pesar de que el regulador de voltaje LM2940CT-5.0 marca una temperatura comercial de 0 °C a 125 °C el diseño del regulador de 5V de la plataforma PE es para uso a temperatura ambiente. Los voltajes pueden reducirse o incrementarse y usted puede usar estas ecuaciones para determinar la máxima salida de corriente a una temperatura dada. Tenga en mente que las placas del kit PE están diseñadas para utilizarse en temperatura ambiente y que el plástico se deformara si se expone a altas temperaturas. Carga de Corriente vs. Temperatura Ambiente De acuerdo a la hoja de datos del LM2940 de National Semiconductor (disponible en national.com), la máxima unión admisible a la resistencia térmica del ambiente (θJA) para el empaque TO220 utilizado en el kit PE es 53 °C/W. Esta cantidad puede describirse en términos del máximo pico permitido (TRMAX) y la potencia disipada (PD) como: θ JA = TR (MAX ) ≥ 53 °C W PD ...donde TR(MAX) es la diferencia entre la máxima unión posible de temperatura (TJ(MAX)) y la máxima temperatura ambiente TA(MAX). La unión máxima de temperatura es 125 °C para el LM2940CT-5.0 TR (MAX ) = TJ ( MAX ) − TA (MAX ) = 125 °C − TA (MAX ) PD también está relacionada a la entrada de voltaje (VIN), salida de voltaje (VOUT), carga de corriente (IL), y corriente estática (IG) por: PD = (VIN − VOUT )I L + (VIN )I G Para el kit PE, VIN = 9 V, VOUT = 5 V, y de la hoja de datos, IG no excederá 20 mA. Resolviendo para la carga de corriente en términos de las otras variables y contantes tenemos: TJ (MAX ) − TA ( MAX ) IL ≤ θ JA − (VIN ) I G VIN − VOUT Substituyendo las constantes proporcionadas por la hoja de datos, la carga de corriente como una función de la temperatura máxima de ambiente para un voltaje de entrada fijo de 9V. 125 °C − TA (MAX ) IL ≤ 53 °C /W − ( 9V ) ( 20 mA ) 9V − 5 V I L ≤ 0. 545 − ( 4. 72 × 10 −3 )T A (MAX ) Pagina 226 · Kit Educativo de Prácticas Propeller: Fundamentos Apéndice D: Diagrama de Bloque del Microcontrolador Para una temperatura ambiente máxima de 80 °F ≈ 26.7 °/C, la máxima carga de corriente IL = 419 mA. Salida ESR de Capacitor La hoja de datos LM2940 tiene requerimientos de estabilidad para la salida capacitancia (mínimo 22 µF) y ESR (Equivalente en Resistencia Serial). Para el kit PE en el rango de 0 to 400 mA la salida ESR del capacitor tiene que estar en el rango de 0.1 Ω a 1.0 Ω para prevenir oscilaciones de salida de voltaje. A este momento la salida del capacitor del kit PE es un capacitor Nichicon VR serie 25 V, 1000 µF. La especificación del catalogo para este capacitor estipula que la perdida de disipación (tan δ) es 0.16 a 120KHz para un capacitor de 1000 µF, 25V. De acuerdo a Nichicon’s General Description of Aluminum Electrolytic Capacitors, la pérdida por disipación en el reciproco de la impedancia, lo cual puede usarse para determinar el ESR (NOTAS TECNICAS CAT.8101E, Pagina 6) tan δ = ESR = 1 XC = 2πfC (ESR ) tan δ 0. 16 = = 0 .212Ω 2πfC 2π 120 (1000 μ ) Las especificaciones de la serie VR también establecen que el rango de la máxima impedancia de (Z-25°C)/(Z+20°C) es 2. Este rango de impedancia junto con el cálculo de la temperatura ambiente indica que la ESR no excederá 0.424 Ω a -25 °C. Así mientras la hoja de datos del LM2940 establece que los valores ESR del capacitor electrolítico pueden incrementarse drásticamente a bajas temperaturas el capacitor de 1000 µF en el kit PE no posee un riesgo de estabilidad a -25º C lo cual está muy por debajo del rango de temperatura del regulador LM2940CT-5.0 Kit Educativo de Practicas Propeller: Fundamentos · Página 227