Kit Educativo Propeller - Fundamentos

Anuncio
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
Descargar