Upload
doanhanh
View
217
Download
0
Embed Size (px)
Citation preview
PPRROOYYEECCTTOO DDEE IINNGGEENNIIEERRÍÍAA
EELLEECCTTRRÓÓNNIICCAA
Comunicar dos o más microcontroladores es esencial para formar sistemas más complejos tales como las redes de sensores, entre otros. La comunicación puede darse a varios niveles de abstracción. El más básico es, por ejemplo, a nivel caracter que se da usando la comunicación por un enlace físico de radio frecuencia (RF). En este proyecto se implementará la comunicación entre microcontroladores al siguiente nivel de abstracción; es decir, al nivel de enlace de datos. En este nivel se intercambian tramas (paquetes) de información y se contemplan funciones como el control de errores y el control de flujo apropiados para un enlace de RF. La programación se realizará en el lenguaje C o en ensamblador o ambos.
PPRREESSEENNTTAACCIIÓÓNN
Mayo de 2008
UUnniivveerrssiiddaadd AAuuttóónnoommaa MMeettrrooppoolliittaannaaIIzzttaappaallaappaa
AALLUUMMNNOO:: CCAARRLLOOSS EERRNNEESSTTOO MMOORREENNOO EESSCCOOBBAARR 220011221144115599 AASSEESSOORR:: DDRR.. MMIIGGUUEELL ÁÁNNGGEELL RRUUIIZZ SSÁÁNNCCHHEEZZ
[[CCOOMMUUNNIICCAACCIIÓÓNN AA NNIIVVEELL EENNLLAACCEE DDEE DDAATTOOSS EENNTTRREE MMIICCRROOCCOONNTTRROOLLAADDOORREESS CCOONN UUNNIIDDAADDEESS DDEE
RRAADDIIOOFFRREECCUUEENNCCIIAA]]
PPRROOYYEECCTTOO DDEE IINNGGEENNIIEERRÍÍAA EELLEECCTTRRÓÓNNIICCAA
UUNNIIVVEERRSSIIDDAADD AAUUTTÓÓNNOOMMAA MMEETTRROOPPOOLLIITTAANNAA IIZZTTAAPPAALLAAPPAA CCaarrllooss EErrnneessttoo MMoorreennoo EEssccoobbaarr 220011221144115599
CCoonntteenniiddoo
II DDEESSCCRRIIPPCCIIÓÓNN 11
IIII OOBBJJEETTIIVVOOSS 11
11..00 IINNTTRROODDUUCCCCIIÓÓNN 22
22..00 CCRRCC ((CCYYCCLLIICC RREEDDUUNNDDAANNCCYY CCHHEECCKK)) 44
33..00 PPRROOTTOOCCOOLLOO SSTTOOPP AANNDD WWAAIITT 77
44..00 HHAARRDDWWAARREE 1100 44..11 GGEENNEERRAALLIIDDAADDEESS DDEELL UUCCOONNTTRROOLLAADDOORR AAVVRR
AATTMMEEGGAA88553355 1100
44..22 TTRRAANNSSCCEEIIVVEERR CCCC11000000 1122 44..22..11 DDEESSCCRRIIPPCCIIÓÓNN DDEELL CCIIRRCCUUIITTOO 1133 44..22..22 CCIIRRCCUUIITTOO DDEE AAPPLLIICCAACCIIÓÓNN 1133 44..22..33 PPAARRÁÁMMEETTRROOSS CCOONNFFIIGGUURRAABBLLEESS DDEELL CCCC11000000 1144 44..22..44 SSOOFFTTWWAARREE DDEE CCOONNFFIIGGUURRAACCIIÓÓNN PPAARRAA EELL CCCC11000000 1144 44..22..55 CCOONNFFIIGGUURRAACCIIÓÓNN SSEERRIIAALL MMEEDDIIAANNTTEE 33 LLÍÍNNEEAASS 1155 44..22..66 IINNTTEERRFFAAZZ DDEE CCOONNFFIIGGUURRAACCIIÓÓNN 1166 44..22..77 IINNTTEERRFFAAZZ DDEE LLAA SSEEÑÑAALL DDEE DDAATTOOSS 1166 44..22..88 IINNTTEERRFFAAZZ CCOONN EELL UUCCOONNTTRROOLLAADDOORR 1188 44..22..99 SSIINNCCRROONNIIZZAADDOORR DDEE BBIITT YY DDEECCIISSIIÓÓNN DDEE LLOOSS
DDAATTOOSS 1199 44..22..1100 PPRROOGGRRAAMMAACCIIÓÓNN DDEE LLAA FFRREECCUUEENNCCIIAA 2200 44..22..1111 CCOONNFFIIGGUURRAACCIIOONNEESS PPAARRAA LLAASS BBAANNDDAASS IISSMM 2211
PPRROOYYEECCTTOO DDEE IINNGGEENNIIEERRÍÍAA
EELLEECCTTRRÓÓNNIICCAA
[[CCOOMMUUNNIICCAACCIIÓÓNN AA NNIIVVEELL EENNLLAACCEE DDEE DDAATTOOSS EENNTTRREE MMIICCRROOCCOONNTTRROOLLAADDOORREESS CCOONN UUNNIIDDAADDEESS DDEE RRAADDIIOOFFRREECCUUEENNCCIIAA]]
UUNNIIVVEERRSSIIDDAADD AAUUTTÓÓNNOOMMAA MMEETTRROOPPOOLLIITTAANNAA IIZZTTAAPPAALLAAPPAA CCaarrllooss EErrnneessttoo MMoorreennoo EEssccoobbaarr 220011221144115599
44..22..1122 VVCCOO ((OOSSCCIILLAADDOORR CCOONNTTRROOLLAADDOO PPOORR VVOOLLTTAAJJEE)) 2211 44..22..1133 AAUUTTOOCCAALLIIBBRRAACCIIÓÓNN DDEELL VVCCOO YY EELL PPLLLL 2211 44..22..1144 CCOONNTTRROOLL DDEE LLAA PPOOTTEENNCCIIAA 2222 44..22..1155 RREEGGIISSTTRROOSS DDEE CCOONNFFIIGGUURRAACCIIÓÓNN DDEELL CCCC11000000 2222
44..33 MMÓÓDDUULLOO CCCC11000000PPPP886688 2233 44..33..11 DDIIAAGGRRAAMMAA DDEELL CCIIRRCCUUIITTOO 2233 44..33..22 AANNTTEENNAASS 2255
55..00 PPRROOCCEEDDIIMMIIEENNTTOOSS DDEE CCOONNFFIIGGUURRAACCIIÓÓNN 2255
55..11 IINNIICCIIAALLIIZZAACCIIÓÓNN DDEELL CCCC11000000 2266 55..22 RREESSEETT DDEELL CCCC11000000 2277 55..33 CCAALLIIBBRRAACCIIÓÓNN 2277 55..44 PPOOWWEERR DDOOWWNN 2299 55..55 PPOOWWEERR UUPP YY AACCTTIIVVAACCIIÓÓNN DDEE TTXX//RRXX 2299
66..00 IIMMPPLLEEMMEENNTTAACCIIÓÓNN FFÍÍSSIICCAA 3300
66..11 IINNTTEERRFFAACCEE DDEE CCOONNFFIIGGUURRAACCIIÓÓNN CCOONN EELL AAVVRR 3311 66..22 IINNTTEERRFFAACCEE DDEE DDAATTOOSS CCOONN EELL AAVVRR 3311 66..33 CCIIRRCCUUIITTOO GGEENNEERRAALL 3333
77..00 SSOOFFTTWWAARREE PPAARRAA CCOONNFFIIGGUURRAACCIIÓÓNN DDEELL CCCC11000000 3333
77..11 CCOONNSSTTAANNTTEESS GGLLOOBBAALLEESS 3333 77..22 MMAACCRROO:: DDIIRREECC__DDAATTOOSS 3355 77..33 SSPPII PPOORR SSOOFFTTWWAARREE 3388 77..44 FFUUNNCCIIÓÓNN WWRRIITTEETTOOCCCC11000000 3388 77..55 FFUUNNCCIIÓÓNN RREESSEETTCCCC11000000 3399 77..66 FFUUNNCCIIÓÓNN IINNIITTCCCC11000000 3399
[[CCOOMMUUNNIICCAACCIIÓÓNN AA NNIIVVEELL EENNLLAACCEE DDEE DDAATTOOSS EENNTTRREE MMIICCRROOCCOONNTTRROOLLAADDOORREESS CCOONN UUNNIIDDAADDEESS DDEE
RRAADDIIOOFFRREECCUUEENNCCIIAA]]
PPRROOYYEECCTTOO DDEE IINNGGEENNIIEERRÍÍAA EELLEECCTTRRÓÓNNIICCAA
UUNNIIVVEERRSSIIDDAADD AAUUTTÓÓNNOOMMAA MMEETTRROOPPOOLLIITTAANNAA IIZZTTAAPPAALLAAPPAA CCaarrllooss EErrnneessttoo MMoorreennoo EEssccoobbaarr 220011221144115599
77..77 FFUUNNCCIIÓÓNN TTUURRNNOONNTTXX 4411 77..88 FFUUNNCCIIÓÓNN TTUURRNNOOFFFFTTXX 4411 77..99 FFUUNNCCIIÓÓNN TTUURRNNOONNRRXX 4411 77..1100 FFUUNNCCIIÓÓNN TTUURRNNOOFFFFRRXX 4422 77..1111 FFUUNNCCIIÓÓNN AAVVEERR__AAUUTTOO 4433 77..1122 FFUUNNCCIIÓÓNN AAVVEERR__BBLLOOQQ 4433 77..1133 FFUUNNCCIIÓÓNN AAVVEERR__DDEESSBBLLOOQQ 4444 77..1144 FFUUNNCCIIÓÓNN LLEEEERR__CCCC11000000 4444
88..00 SSOOFFTTWWAARREE PPAARRAA LLAA IINNTTEERRFFAACCEE DDEE DDAATTOOSS 4455
88..11 SSUUBBRRUUTTIINNAA DDEE AATTEENNCCIIÓÓNN AA IINNTTEERRRRUUPPCCIIÓÓNN 4455 88..22 FFUUNNCCIIÓÓNN EENNVVIIAA__PPRREEAAMMBBUULLOO 4488 88..33 FFUUNNCCIIÓÓNN EESSPPEERRAA__PPRREEAAMMBBUULLOO 5500 88..44 FFUUNNCCIIÓÓNN EENNVVIIAA__BBYYTTEE 5555 88..55 FFUUNNCCIIÓÓNN RREECCIIBBEE__BBYYTTEE 5577
99..00 CCRRCC--1166 5599
99..11 GGEENNEERRAARR CCHHEECCKKSSUUMM 6600 99..22 VVEERRIIFFIICCAARR CCHHEECCKKSSUUMM 6600
1100..00 SSTTOOPP AANNDD WWAAIITT 6633
1100..11 FFUUNNCCIIÓÓNN SSTTAARRTT__TTIIMMEERR 6644 1100..22 FFUUNNCCIIÓÓNN SSTTOOPP__TTIIMMEERR 6677 1100..33 FFUUNNCCIIÓÓNN EENNVVIIAA__TTRRAAMMAA 6677 1100..44 FFUUNNCCIIÓÓNN RREECCIIBBEE__AACCUUSSEE 6699 1100..55 FFUUNNCCIIÓÓNN RREECCIIBBEE__TTRRAAMMAA 7722 1100..66 FFUUNNCCIIÓÓNN EENNVVIIAA__AACCUUSSEE 7755
1111..00 PPRROOGGRRAAMMAA DDEE EEJJEEMMPPLLOO 7766
PPRROOYYEECCTTOO DDEE IINNGGEENNIIEERRÍÍAA
EELLEECCTTRRÓÓNNIICCAA
[[CCOOMMUUNNIICCAACCIIÓÓNN AA NNIIVVEELL EENNLLAACCEE DDEE DDAATTOOSS EENNTTRREE MMIICCRROOCCOONNTTRROOLLAADDOORREESS CCOONN UUNNIIDDAADDEESS DDEE RRAADDIIOOFFRREECCUUEENNCCIIAA]]
UUNNIIVVEERRSSIIDDAADD AAUUTTÓÓNNOOMMAA MMEETTRROOPPOOLLIITTAANNAA IIZZTTAAPPAALLAAPPAA CCaarrllooss EErrnneessttoo MMoorreennoo EEssccoobbaarr 220011221144115599
1122..00 MMEEDDIICCIIOONNEESS EEXXPPEERRIIMMEENNTTAALLEESS 110099
1133..00 RREESSUULLTTAADDOOSS YY CCOONNCCLLUUSSIIOONNEESS 111111
AAPPÉÉNNDDIICCEE IINNTTEERRFFAACCEE DDEE CCOONNFFIIGGUURRAACCIIÓÓNN PPAARRAA EELL MMIICCRROOCCOONNTTRROOLLAADDOORR PPIICC1166FF664488 111155 BBIIBBLLIIOOGGRRAAFFÍÍAA 112288
[[CCOOMMUUNNIICCAACCIIÓÓNN AA NNIIVVEELL EENNLLAACCEE DDEE DDAATTOOSS EENNTTRREE MMIICCRROOCCOONNTTRROOLLAADDOORREESS CCOONN UUNNIIDDAADDEESS DDEE
RRAADDIIOOFFRREECCUUEENNCCIIAA]]
PPRROOYYEECCTTOO DDEE IINNGGEENNIIEERRÍÍAA EELLEECCTTRRÓÓNNIICCAA
UUNNIIVVEERRSSIIDDAADD AAUUTTÓÓNNOOMMAA MMEETTRROOPPOOLLIITTAANNAA IIZZTTAAPPAALLAAPPAA CCaarrllooss EErrnneessttoo MMoorreennoo EEssccoobbaarr 220011221144115599
‐ 1 ‐
II DDEESSCCRRIIPPCCIIÓÓNN
Este proyecto comienza a partir de la implementación de la comunicación entre el AVR y el Transceiver CC1000PP (Interfaz de configuración). El CC1000 es un Transceiver SRD (Short Range Device) de UHF de baja potencia y bajo voltaje. Trabaja en las bandas de 315, 433, 868 y 915 MHz, pero puede ser programado en las frecuencias de 300 a 1000 MHz. También se incluye el diseño de varias funciones para configuración del CC1000 y un programa de ejemplo para la comunicación mediante RF; una descripción del funcionamiento básico del módulo de RF; la implementación de funciones en lenguaje ensamblador para la configuración del CC1000, así como la interface de datos para la Transmisión y Recepción. El software diseñado para el proyecto puede ser utilizado con cualquier microcontrolador AVR o migrado a otro microcontrolador de 8 bits.
Se ha incluido la implementación del protocolo de comunicaciones Stop and Wait el cual evita la pérdida de la información transmitida. En caso de que la información recibida contenga errores, la verificación por CRC es lo más confiable para la detección de errores. En este caso se implementó el estándar CRC‐16. Los parámetros considerados para este proyecto (frecuencia, baud rate etc.) se listan a continuación:
• Modulación FSK (Realizada por el módulo CC1000PP‐868) • Potencia de salida de 5 dBm (3.16 mWatts) • Frecuencia de operación 868.29 MHz • Baud rate de 38400 bps • Codificación de línea: Manchester síncrono
IIII OOBBJJEETTIIVVOOSS
• Implementar la comunicación entre dos microcontroladores mediante unidades de Radio frecuencia.
• Diseñar la interfaz de datos (Hardware y Software) requerida para que el Transceiver sea capaz transmitir y recibir información.
• El software diseñado para la configuración y comunicación entre el CC1000PP y el microcontrolador debe ser escalable, para que sea usado con cualquier otro microcontrolador y modificado fácilmente.
• Diseñar la interfaz (Hardware y Software) para configurar adecuadamente el Transceiver.
• Los circuitos de transmisión y recepción deben ser capaces de intercambiar información entre ellos, validarla y procesarla. Utilizando el protocolo de comunicaciones Stop and Wait.
• Implementar un CRC‐16 para la verificación de errores.
PPRROOYYEECCTTOO DDEE IINNGGEENNIIEERRÍÍAA
EELLEECCTTRRÓÓNNIICCAA
[[CCOOMMUUNNIICCAACCIIÓÓNN AA NNIIVVEELL EENNLLAACCEE DDEE DDAATTOOSS EENNTTRREE MMIICCRROOCCOONNTTRROOLLAADDOORREESS CCOONN UUNNIIDDAADDEESS DDEE RRAADDIIOOFFRREECCUUEENNCCIIAA]]
UUNNIIVVEERRSSIIDDAADD AAUUTTÓÓNNOOMMAA MMEETTRROOPPOOLLIITTAANNAA IIZZTTAAPPAALLAAPPAA CCaarrllooss EErrnneessttoo MMoorreennoo EEssccoobbaarr 220011221144115599
‐ 2 ‐
11..00 IINNTTRROODDUUCCCCIIÓÓNN
Una nueva clase de redes ha aparecido en los últimos años: las Redes de Sensores Inalámbricas (Wireless Sensor Network). Estas redes están conformadas por nodos individuales que interactúan en el ambiente sensando o controlando parámetros físicos, estos nodos colaboran entre sí para cumplir sus tareas ya que un solo nodo es incapaz de hacerlo, así que se usa la comunicación inalámbrica para que los sensores interactúen entre sí. Para muchas aplicaciones de las redes de sensores, los nodos no pueden ser conectados a una fuente de poder, entonces, el uso de baterías en cada uno de los nodos es indispensable.
Figura 1.0.0 Red de Sensores Inalámbrica
La idea de estas redes es repartir aleatoriamente estos nodos en un territorio grande, en el cual, los nodos “observan” hasta que sus recursos energéticos se agoten. En la actualidad, las redes de sensores es un tema muy activo de investigación en varias universidades, aunque ya empiezan a existir aplicaciones comerciales basadas en este tipo de redes. La red de sensores hasta la fecha más grande consistió de 800 nodos y fue puesta en servicio el 27 agosto 2001 para duración breve en la universidad de Berkeley. Varios tipos de sensores que pueden ser integrados en los nodos de las redes, tales sensores son capaces de medir algunos parámetros físicos del medio. Algunos de los medios más comunes son: temperatura, humedad, acústica, vibraciones, presión, sensores magnéticos, sensado de gases, entre otros. Algunas aplicaciones se muestran a continuación.
• Prevención desastres. Un escenario típico de esta aplicación son los incendios forestales, donde los nodos están equipados con termómetros y los nodos pueden indicar su propia posición. Los nodos pueden ser desplegados en el bosque desde un aeroplano.
• Control del medio ambiente. Las redes de sensores pueden ser utilizadas para control del medio ambiente, por ejemplo, detección de químicos contaminantes.
• Edificios inteligentes. Para el ahorro de energía e incrementar la comodidad de los habitantes del edificio es necesario el monitoreo en tiempo real de variables como temperatura, flujo de aire, humedad y otros parámetros físicos.
[[CCOOMMUUNNIICCAACCIIÓÓNN AA NNIIVVEELL EENNLLAACCEE DDEE DDAATTOOSS EENNTTRREE MMIICCRROOCCOONNTTRROOLLAADDOORREESS CCOONN UUNNIIDDAADDEESS DDEE
RRAADDIIOOFFRREECCUUEENNCCIIAA]]
PPRROOYYEECCTTOO DDEE IINNGGEENNIIEERRÍÍAA EELLEECCTTRRÓÓNNIICCAA
UUNNIIVVEERRSSIIDDAADD AAUUTTÓÓNNOOMMAA MMEETTRROOPPOOLLIITTAANNAA IIZZTTAAPPAALLAAPPAA CCaarrllooss EErrnneessttoo MMoorreennoo EEssccoobbaarr 220011221144115599
‐ 3 ‐
• Instalaciones administrativas. Mediante una red de sensores es posible verificar si una persona tiene permitido el acceso a ciertas áreas. Esta aplicación puede ser extendida para la detección de intrusos, por ejemplo, vehículos circulando en horarios no habituales.
Un nodo de sensores contiene al menos cinco dispositivos principales (Figura 1.0.1):
1. Controlador. El controlador procesa todos los datos relevantes y ejecución de un código.
2. Memoria. Memoria para almacenar programas y datos importantes. 3. Sensores. Interface entre el mundo físico. Dispositivos que pueden observar o
controlar variables físicas del ambiente. 4. Comunicación. Dispositivo capaz de recibir o transmitir información mediante un
canal inalámbrico. 5. Fuente de poder. Usualmente los nodos no pueden conectarse al una fuente de
alimentación, así que es indispensable el uso de baterías.
Figura 1.0.1 Diagrama a Bloques del nodo
PPRROOYYEECCTTOO DDEE IINNGGEENNIIEERRÍÍAA
EELLEECCTTRRÓÓNNIICCAA
[[CCOOMMUUNNIICCAACCIIÓÓNN AA NNIIVVEELL EENNLLAACCEE DDEE DDAATTOOSS EENNTTRREE MMIICCRROOCCOONNTTRROOLLAADDOORREESS CCOONN UUNNIIDDAADDEESS DDEE RRAADDIIOOFFRREECCUUEENNCCIIAA]]
UUNNIIVVEERRSSIIDDAADD AAUUTTÓÓNNOOMMAA MMEETTRROOPPOOLLIITTAANNAA IIZZTTAAPPAALLAAPPAA CCaarrllooss EErrnneessttoo MMoorreennoo EEssccoobbaarr 220011221144115599
‐ 4 ‐
22..00 CCRRCC ((CCYYCCLLIICC RREEDDUUNNDDAANNCCYY CCHHEECCKK))
La finalidad de una técnica de detección de errores es que el receptor identifique que la información recibida, a través de un canal ruidoso, no contenga errores. Para realizar esta operación, el transmisor construye un valor llamado checksum, el cual es una función del mensaje, éste se agrega al mensaje para la transmisión. El receptor utiliza la misma función para calcular el checksum del mensaje recibido y lo compara con el checksum integrado en el mensaje para observar si el mensaje fue correctamente recibido. Ejemplo: Checksum calculado sumando los números de un código.
Código: 04 29 06 Código con checksum: 04 29 06 39
El checksum es simplemente la suma de los números del código. Si el segundo byte se corrompe de 29 a 23, el error será detectado cuando el checksum original sea comparado con el resultante.
Código: 04 29 06 Código con error: 04 23 06 39 ->ERROR!!
Si el primer byte del código se corrompe de 4 a 10 y el segundo byte se corrompe de 29 a 23, el checksum no detectará los errores.
Código: 04 29 06 Código con error: 10 23 06 39 ->CORRECTO!!
El problema con esta técnica es que es muy simple, y no puede detectar errores en distintos bytes en el código. Este ejemplo muestra que la suma de los números de un código no es suficiente para una correcta detección. Ahora, si consideramos el mensaje como un enorme número binario, el cual va a ser dividido por un número binario (polinomio). El checksum será el residuo de esta división. De este modo, el receptor realiza la misma división para comparar el residuo con el checksum recibido. La división utiliza aritmética polinomial en módulo 2, que es similar a la aritmética binaria, excepto que no hay acarreo. Entonces, una suma entre dos números binarios será mediante la operación XOR. Definamos algunas propiedades para la aritmética polinomial.
= número de k bits (código para verificación) = número de (n+1) bits (divisor o polinomio) = número de n bits tal que k>n (residuo o checksum)
donde es el cociente
puede ser descrito como:
2 el cual equivale a agregar n ceros al final del código
[[CCOOMMUUNNIICCAACCIIÓÓNN AA NNIIVVEELL EENNLLAACCEE DDEE DDAATTOOSS EENNTTRREE MMIICCRROOCCOONNTTRROOLLAADDOORREESS CCOONN UUNNIIDDAADDEESS DDEE
RRAADDIIOOFFRREECCUUEENNCCIIAA]]
PPRROOYYEECCTTOO DDEE IINNGGEENNIIEERRÍÍAA EELLEECCTTRRÓÓNNIICCAA
UUNNIIVVEERRSSIIDDAADD AAUUTTÓÓNNOOMMAA MMEETTRROOPPOOLLIITTAANNAA IIZZTTAAPPAALLAAPPAA CCaarrllooss EErrnneessttoo MMoorreennoo EEssccoobbaarr 220011221144115599
‐ 5 ‐
Si es reemplazado en la última ecuación:
2
Es igual a ya que el divisor y el residuo son el mismo número, sumándolo a si mismo con la operación XOR el resultado es cero. Ejemplo de la división CRC. El número 35B, cuyo número binario es 1101011011, es dividido por 13 (10011 binario). El checksum será el residuo de la división de 1101011011 entre 10011. 1100001010 El cociente es ignorado
_______________ 10011 ) 11010110110000 10011,,.,,.... -----,,.,,.... 10011,.,,.... 10011,.,,.... -----,.,,.... 00001.,,.... 00000.,,.... -----.,,.... 00010,,.... 00000,,.... -----,,.... 00101,.... 00000,.... -----,.... 01011.... 00000.... -----.... 10110... 10011... -----... 01010.. 00000.. -----.. 10100. 10011. -----. 01110 00000 ----- 1110 = E Residuo
El checksum es agregado al final del mensaje original. El código resultante será 35BE. Cuando el mensaje es verificado, el mensaje y el checksum son divididos por el divisor. Si el residuo de la división es cero no existen errores en el mensaje. Para cualquier otro caso existen errores en el mensaje. Existen muchos estándares para la detección CRC. Las características del divisor varían entre 8 a 32 bits y la habilidad de detectar errores depende de la longitud del divisor o
PPRROOYYEECCTTOO DDEE IINNGGEENNIIEERRÍÍAA
EELLEECCTTRRÓÓNNIICCAA
[[CCOOMMUUNNIICCAACCIIÓÓNN AA NNIIVVEELL EENNLLAACCEE DDEE DDAATTOOSS EENNTTRREE MMIICCRROOCCOONNTTRROOLLAADDOORREESS CCOONN UUNNIIDDAADDEESS DDEE RRAADDIIOOFFRREECCUUEENNCCIIAA]]
UUNNIIVVEERRSSIIDDAADD AAUUTTÓÓNNOOMMAA MMEETTRROOPPOOLLIITTAANNAA IIZZTTAAPPAALLAAPPAA CCaarrllooss EErrnneessttoo MMoorreennoo EEssccoobbaarr 220011221144115599
‐ 6 ‐
polinomio. Los CRC más comúnmente usados son: CRC-16 =1 1000 0000 0000 0101= 8005 HEX CRC-CCITT =1 0001 0000 0010 0001= 1021 HEX CRC-32 =1 0000 0100 1100 0001 0001 1101 1011 0111=04C11DB7 HEX
[[CCOOMMUUNNIICCAACCIIÓÓNN AA NNIIVVEELL EENNLLAACCEE DDEE DDAATTOOSS EENNTTRREE MMIICCRROOCCOONNTTRROOLLAADDOORREESS CCOONN UUNNIIDDAADDEESS DDEE
RRAADDIIOOFFRREECCUUEENNCCIIAA]]
PPRROOYYEECCTTOO DDEE IINNGGEENNIIEERRÍÍAA EELLEECCTTRRÓÓNNIICCAA
UUNNIIVVEERRSSIIDDAADD AAUUTTÓÓNNOOMMAA MMEETTRROOPPOOLLIITTAANNAA IIZZTTAAPPAALLAAPPAA CCaarrllooss EErrnneessttoo MMoorreennoo EEssccoobbaarr 220011221144115599
‐ 7 ‐
33..00 PPRROOTTOOCCOOLLOO SSTTOOPP AANNDD WWAAIITT
Para la explicación del protocolo Stop and Wait es necesario comenzar desde un modelo ideal, en el cual, el canal de comunicaciones es completamente confiable (sin ruido). Posteriormente, considerando los problemas reales, el protocolo se volverá más complejo. Modelo 1. En un canal de comunicaciones confiable, el transmisor genera el paquete y lo transmite hacia el receptor, donde el paquete es procesado. Considerando este canal ideal, no se introducen errores en el paquete ni hay pérdidas de éste.
Figura 3.0.0 Modelo 1, Protocolo para un canal confiable.
Modelo 2. Un modelo más realista del canal de comunicaciones es aquel en el que el paquete transmitido tuviera errores. En este momento, consideraremos que no hay pérdida de paquetes. En este modelo se usan mensajes de control para indicar si los paquetes se reciben adecuadamente o si éstos contienen errores. Así que al modelo se le agregan dos etapas importantes:
• Detección de error. Es un mecanismo que permite que el receptor identifique si hay errores en el paquete recibido. Un CRC es una buena opción para detectar errores.
• Acuses de recibo (Acknowledgements). Los acuses de recibo positivos (Acknowledgements) y los acuses de recibo negativos (Negative Acknowledgements) son una respuesta del receptor hacia el transmisor para indicarle el estado de los paquetes recibidos. Por ejemplo, si se detectan errores en el paquete se enviará un acuse negativo (NACK). Pero si el paquete es recibido correctamente, se enviará al transmisor un acuse positivo (ACK).
En este protocolo, el transmisor espera los acuses una vez que haya transmitido el paquete. Si se recibe un ACK el transmisor sabe que la información ha llegado correctamente y puede continuar la transmisión. En cambio, si se recibe un NACK, el transmisor retransmite el paquete de datos. Debido a este comportamiento, este tipo de protocolos se denominan “Stop and Wait”. Debemos considerar que los acuses de recibo también pueden sufrir alteraciones, es por eso, que es necesario agregarle redundancia al acuse (CRC) para que el transmisor también verifique si en el acuse existen errores introducidos por el canal. Esta es una buena solución para un canal que solo introduce errores y los paquetes no se pierden. Consideremos que el paquete transmitido se recibe correctamente, pero el acuse no, esto produce que el transmisor reenvíe el paquete lo que puede producir que el paquete se duplique dentro del receptor. Una solución simple a este nuevo problema es agregar a los datos un nuevo campo que indique el número de secuencia que se está transmitiendo (sequence number). De este modo, el receptor identificará la secuencia para determinar si el paquete es el mismo que recibió anteriormente, o si se trata de un nuevo paquete de datos.
PPRROOYYEECCTTOO DDEE IINNGGEENNIIEERRÍÍAA
EELLEECCTTRRÓÓNNIICCAA
[[CCOOMMUUNNIICCAACCIIÓÓNN AA NNIIVVEELL EENNLLAACCEE DDEE DDAATTOOSS EENNTTRREE MMIICCRROOCCOONNTTRROOLLAADDOORREESS CCOONN UUNNIIDDAADDEESS DDEE RRAADDIIOOFFRREECCUUEENNCCIIAA]]
UUNNIIVVEERRSSIIDDAADD AAUUTTÓÓNNOOMMAA MMEETTRROOPPOOLLIITTAANNAA IIZZTTAAPPAALLAAPPAA CCaarrllooss EErrnneessttoo MMoorreennoo EEssccoobbaarr 220011221144115599
‐ 8 ‐
Figura 3.0.1 Modelo 2, Protocolo para un canal que introduce errores.
Modelo 3. Este modelo es la implementación final del protocolo Stop and Wait. Ahora consideremos, además de que el paquete tiene errores, que también hay pérdida completa de paquetes. La problemática es saber: ¿cuándo se perdieron los paquetes? El checksum, los paquetes de acuses y las retransmisiones nos permitirán contestar esta pregunta. El transmisor no sabe en qué momento se ha perdido el paquete, el acuse o simplemente ambos tienen un delay. En todos los casos se debe ejecutar la misma acción: retransmitir. Pero esta vez, implementaremos una retransmisión basada en el tiempo. Un contador (countdown timer) es necesario para generar una interrupción en el transmisor después de cierto tiempo cuando el acuse no es recibido. El transmisor debe ejecutar las siguientes tareas:
1. Inicializar el reloj una vez enviado el paquete. 2. Atender a la interrupción una vez que haya finalizado la cuenta (retransmitir
paquete). 3. Detener el reloj.
[[CCOOMMUUNNIICCAACCIIÓÓNN AA NNIIVVEELL EENNLLAACCEE DDEE DDAATTOOSS EENNTTRREE MMIICCRROOCCOONNTTRROOLLAADDOORREESS CCOONN UUNNIIDDAADDEESS DDEE
RRAADDIIOOFFRREECCUUEENNCCIIAA]]
PPRROOYYEECCTTOO DDEE IINNGGEENNIIEERRÍÍAA EELLEECCTTRRÓÓNNIICCAA
UUNNIIVVEERRSSIIDDAADD AAUUTTÓÓNNOOMMAA MMEETTRROOPPOOLLIITTAANNAA IIZZTTAAPPAALLAAPPAA CCaarrllooss EErrnneessttoo MMoorreennoo EEssccoobbaarr 220011221144115599
‐ 9 ‐
Figura 3.0.2 Modelo 3 (Stop and Wait), Protocolo para un canal que introduce errores y/o
pérdidas de paquetes.
El hecho de que el transmisor reenvíe la información cuando la cuenta del reloj haya finalizado produce duplicados de paquetes. Es por esta razón que en el paquete que contiene el acuse se le introduzca un nuevo campo: número de secuencia, el cual es una copia de la secuencia recibida (generada por el transmisor). De esta manera, el transmisor puede verificar si el paquete fue recibido correctamente. De la figura 3.0.2 se puede observar que la secuencia de paquetes se va alternando entre 0 y 1. A este método se le conoce como protocolo de bit alternante (alternating bit protocol).
PPRROOYYEECCTTOO DDEE IINNGGEENNIIEERRÍÍAA
EELLEECCTTRRÓÓNNIICCAA
[[CCOOMMUUNNIICCAACCIIÓÓNN AA NNIIVVEELL EENNLLAACCEE DDEE DDAATTOOSS EENNTTRREE MMIICCRROOCCOONNTTRROOLLAADDOORREESS CCOONN UUNNIIDDAADDEESS DDEE RRAADDIIOOFFRREECCUUEENNCCIIAA]]
UUNNIIVVEERRSSIIDDAADD AAUUTTÓÓNNOOMMAA MMEETTRROOPPOOLLIITTAANNAA IIZZTTAAPPAALLAAPPAA CCaarrllooss EErrnneessttoo MMoorreennoo EEssccoobbaarr 220011221144115599
‐ 10 ‐
44..00 HHAARRDDWWAARREE
En esta sección se analizará el hardware a utilizar para la elaboración del proyecto. El microcontrolador utilizado es el ATMEGA8535L‐8PI, este microcontrolador tiene la ventaja de trabajar en un rango de voltaje de 2.5‐5.5 Volts lo que permite operarlo dentro del rango de voltajes del Transceiver. También cuenta con tres interrupciones externas activadas por los flancos de subida o de bajada, esto nos permite implementar la interface de datos con el reloj de sincronía generado por el CC1000. Los timers internos ayudan a la implementación del timeout para el protocolo Stop and Wait. La memoria RAM del AVR será utilizada para el almacenamiento y procesamiento de los datos a transmitir/recibir. Es posible utilizar la EEPROM para almacenar permanentemente las configuraciones del Transceiver o datos relevantes. El Transceiver a emplear es el módulo CC1000PP‐868, dicho módulo, está diseñado para trabajarlo con prototipos y además incluye todos los componentes necesarios para su operación. El CC1000PP‐868 trabaja a una frecuencia de 868 MHz a 930 MHz y opera con un voltaje de 2.5‐3.6 Volts. Para el desarrollo de este proyecto se ha considerado trabajar con una de las frecuencias óptimas según el propio diseño del módulo CC1000PP‐868. Esta es: 868.297200 MHz. La segunda frecuencia óptima de trabajo es 914.991600 MHz. Aunque el transceiver opera correctamente a la frecuencia de 914.99 MHz, esta no es utilizada. La frecuencia utilizada durante el desarrollo de este proyecto es la de 868.297200 MHz. Es posible utilizar cualquier otra frecuencia en el rango comprendido entre 868 MHz y 930 MHz, pero se ven afectadas algunas variables como la sensibilidad de transmisión/recepción , el consumo de corriente y en algunos casos la potencia de salida del transmisor. Las principales características del módulo CC1000PP‐868 son:
• Incluye todos los componentes de RF para una correcta operación • Bajo consumo de corriente • Rango de frecuencias: 868 MHz a 930 MHz (Versión CC1000PP‐868). • Sincronizador de bits integrado • Salida de potencia programable ‐20 a 5dBm. • Voltaje de operación 2.1 a 3.6 Volts • Salida RSSI (Received Signal Strength Indicator) • Modulación FSK • Modos de transmisión: UART, NRZ (síncrono), NRZ con codificación Manchester
(síncrono)
44..11..00 GGEENNEERRAALLIIDDAADDEESS DDEELL
µµCCOONNTTRROOLLAADDOORR AAVVRR AATTMMEEGGAA88553355
El ATmega8535 es un microcontrolador CMOS de 8 bits de baja potencia basado en arquitectura RISC; esta arquitectura es diez veces más rápida que los microcontroladores CISC. El AVR combina el set de 130 instrucciones con 32 registros de propósito general conectados directamente a la ALU, permitiendo que dos registros independientes se ejecuten en una instrucción en un ciclo de reloj. Cuenta con un reloj interno configurable con velocidad de 1, 2, 4 y 8 MHz. Tiene 8 Kbytes de memoria flash programable con capacidad de leer mientras escribe, 512 bytes de memoria EEPROM y 512 bytes de SRAM interna, 4 puertos I/O (In/Out), 32 líneas I/O, 3 timer/counter preescalables, un Timer Watchdog, 3 interrupciones externas y 4 interrupciones internas, USART serial programable, ADC de 10 bits con entrada diferencial.
[[CCOOMMUUNNIICCAACCIIÓÓNN AA NNIIVVEELL EENNLLAACCEE DDEE DDAATTOOSS EENNTTRREE MMIICCRROOCCOONNTTRROOLLAADDOORREESS CCOONN UUNNIIDDAADDEESS DDEE
RRAADDIIOOFFRREECCUUEENNCCIIAA]]
PPRROOYYEECCTTOO DDEE IINNGGEENNIIEERRÍÍAA EELLEECCTTRRÓÓNNIICCAA
UUNNIIVVEERRSSIIDDAADD AAUUTTÓÓNNOOMMAA MMEETTRROOPPOOLLIITTAANNAA IIZZTTAAPPAALLAAPPAA CCaarrllooss EErrnneessttoo MMoorreennoo EEssccoobbaarr 220011221144115599
‐ 11 ‐
Figura 4.1.0 Diagrama a Bloques del ATMEGA8535
El ATMEGA85335‐8L trabaja con el voltaje de 2.5V a 5.5 V con una velocidad máxima de 8Mhz (reloj interno o cristal externo).
PPRROOYYEECCTTOO DDEE IINNGGEENNIIEERRÍÍAA
EELLEECCTTRRÓÓNNIICCAA
[[CCOOMMUUNNIICCAACCIIÓÓNN AA NNIIVVEELL EENNLLAACCEE DDEE DDAATTOOSS EENNTTRREE MMIICCRROOCCOONNTTRROOLLAADDOORREESS CCOONN UUNNIIDDAADDEESS DDEE RRAADDIIOOFFRREECCUUEENNCCIIAA]]
UUNNIIVVEERRSSIIDDAADD AAUUTTÓÓNNOOMMAA MMEETTRROOPPOOLLIITTAANNAA IIZZTTAAPPAALLAAPPAA CCaarrllooss EErrnneessttoo MMoorreennoo EEssccoobbaarr 220011221144115599
‐ 12 ‐
44..22..00 CCCC11000000
El CC1000 es un Transceiver SRD (Short Range Device) de UHF de baja potencia y bajo voltaje. Trabaja en las bandas de 315, 433, 868 y 915 MHz, pero puede ser programado en las frecuencias de 300 a 1000 MHz. Los parámetros de configuración del CC1000 pueden ser programados mediante un bus serial de tres líneas. Sus principales características son:
• Bajo consumo de corriente • Rango de frecuencias: 300‐1000 MHz • Sincronizador de bits integrado • Salida de potencia programable ‐20 a 10dBm. • Voltaje de operación 2.1 a 3.6 Volts • Salida RSSI (Received Signal Strength Indicator) • Modulación FSK
Tabla 4.2.0.0 PINOUT del CC1000
[[CCOOMMUUNNIICCAACCIIÓÓNN AA NNIIVVEELL EENNLLAACCEE DDEE DDAATTOOSS EENNTTRREE MMIICCRROOCCOONNTTRROOLLAADDOORREESS CCOONN UUNNIIDDAADDEESS DDEE
RRAADDIIOOFFRREECCUUEENNCCIIAA]]
PPRROOYYEECCTTOO DDEE IINNGGEENNIIEERRÍÍAA EELLEECCTTRRÓÓNNIICCAA
UUNNIIVVEERRSSIIDDAADD AAUUTTÓÓNNOOMMAA MMEETTRROOPPOOLLIITTAANNAA IIZZTTAAPPAALLAAPPAA CCaarrllooss EErrnneessttoo MMoorreennoo EEssccoobbaarr 220011221144115599
‐ 13 ‐
44..22..11 DDEESSCCRRIIPPCCIIÓÓNN DDEELL
CCIIRRCCUUIITTOO
Figura 4.2.0 Diagrama a bloques del CC1000
Un diagrama a bloques simplificado del CC1000 se muestra en la figura 4.2.0. En el modo de recepción, el CC1000 se configura como un receptor superheterodino. La entrada RF es amplificada por el amplificador de bajo ruido (LNA) y convertida a una frecuencia intermedia (IF) por el mezclador (mixer). En la etapa IF (IF Stage) esta señal es amplificada y filtrada antes de que pase al demodulador (Demod). En el modo de transmisión, el VCO (Oscilador controlado por voltaje) saca la señal directamente al amplificador de potencia (PA). Los datos a transmitir (una trama de bits) de la entrada DIO es modulada en FSK.
44..22..22 CCIIRRCCUUIITTOO DDEE AAPPLLIICCAACCIIÓÓNN
Se requieren pocos componentes externos para la operación del CC1000. Un circuito típico de aplicación se muestra en la figura 4.2.1. C31/L32 son para la entrada del receptor. L32 es para acoplamiento de DC. C41, L41 y C42 son utilizados para el acoplamiento de impedancias a 50 ohms. L101 es una bobina requerida por el VCO.
Figura 4.2.1 Circuito de aplicación del CC1000
PPRROOYYEECCTTOO DDEE IINNGGEENNIIEERRÍÍAA
EELLEECCTTRRÓÓNNIICCAA
[[CCOOMMUUNNIICCAACCIIÓÓNN AA NNIIVVEELL EENNLLAACCEE DDEE DDAATTOOSS EENNTTRREE MMIICCRROOCCOONNTTRROOLLAADDOORREESS CCOONN UUNNIIDDAADDEESS DDEE RRAADDIIOOFFRREECCUUEENNCCIIAA]]
UUNNIIVVEERRSSIIDDAADD AAUUTTÓÓNNOOMMAA MMEETTRROOPPOOLLIITTAANNAA IIZZTTAAPPAALLAAPPAA CCaarrllooss EErrnneessttoo MMoorreennoo EEssccoobbaarr 220011221144115599
‐ 14 ‐
44..22..33 PPAARRÁÁMMEETTRROOSS
CCOONNFFIIGGUURRAABBLLEESS DDEELL
CCCC11000000
Mediante los registros internos del CC1000 se pueden modificar los siguientes parámetros:• Modo recepción/transmisión • Potencia de RF • Frecuencia de RF, frecuencia de separación de la modulación FSK • Modo Power Down/Power UP • Tasa de datos y formato de datos (NRZ, Manchester y UART)
44..22..44 SSOOFFTTWWAARREE
DDEE CCOONNFFIIGGUURRAACCIIÓÓNN
PPAARRAA EELL CCCC11000000
Chipcon cuenta con software que nos genera las configuraciones necesarias para el CC1000 basados en selecciones de varios parámetros que realiza el usuario. El programa genera valores hexadecimales que deben ser cargados en los registros de configuración del CC1000. De igual forma, el software nos provee de los valores de los capacitores y bobinas para las diferentes frecuencias programadas. A continuación se muestra la interface de software.
Figura 4.2.2 SmartRF Studio: Ventana de Configuración y Componentes
[[CCOOMMUUNNIICCAACCIIÓÓNN AA NNIIVVEELL EENNLLAACCEE DDEE DDAATTOOSS EENNTTRREE MMIICCRROOCCOONNTTRROOLLAADDOORREESS CCOONN UUNNIIDDAADDEESS DDEE
RRAADDIIOOFFRREECCUUEENNCCIIAA]]
PPRROOYYEECCTTOO DDEE IINNGGEENNIIEERRÍÍAA EELLEECCTTRRÓÓNNIICCAA
UUNNIIVVEERRSSIIDDAADD AAUUTTÓÓNNOOMMAA MMEETTRROOPPOOLLIITTAANNAA IIZZTTAAPPAALLAAPPAA CCaarrllooss EErrnneessttoo MMoorreennoo EEssccoobbaarr 220011221144115599
‐ 15 ‐
Figura 4.2.3 SmartRF Studio: Ventana de Registros
44..22..55 CCOONNFFIIGGUURRAACCIIÓÓNN SSEERRIIAALL MMEEDDIIAANNTTEE 33 LLÍÍNNEEAASS ((33‐‐WWIIRREE))
El CC1000 es configurado mediante una interface de tres líneas (PDATA, PALE, PCLK). Hay 28 registros de configuración de 8 bits, cada registro es direccionado mediante 7 bits. Un bit de lectura y escritura (Read/Write) es utilizado para indicar la operación a ejecutar. La configuración completa del CC1000 requiere que se envíen 22 tramas de 16 bits cada una. En cada ciclo de escritura se envían 16 Bits en la línea PDATA. Los 7 bits más significativos (A6:0) corresponden a la dirección del registro de configuración, A6 es el bit más significativo y es el primer bit que debe ser enviado. El siguiente bit en ser enviado es Read/Write. (Alto para escritura, bajo para lectura). Durante la transmisión de la dirección y el bit R/W la línea PALE (Program Address Match Enable) debe mantenerse en nivel bajo. Después los 8 bits de datos son enviados. Ver figura 4.2.4. Los datos de configuración son almacenados en la RAM interna del CC1000, los datos son retenidos durante el modo “power down” pero no cuando el voltaje de alimentación es desconectado. Los registros de configuración pueden ser leídos por el microcontrolador por la misma interface de configuración. Los siete bits de direcciones son enviados primero, después el bit R/W se pone en estado bajo para iniciar la lectura de los datos. Ver figura 4.2.5.
Figura 4.2.4 Operación de escritura de los registros de configuración.
PPRROOYYEECCTTOO DDEE IINNGGEENNIIEERRÍÍAA
EELLEECCTTRRÓÓNNIICCAA
[[CCOOMMUUNNIICCAACCIIÓÓNN AA NNIIVVEELL EENNLLAACCEE DDEE DDAATTOOSS EENNTTRREE MMIICCRROOCCOONNTTRROOLLAADDOORREESS CCOONN UUNNIIDDAADDEESS DDEE RRAADDIIOOFFRREECCUUEENNCCIIAA]]
UUNNIIVVEERRSSIIDDAADD AAUUTTÓÓNNOOMMAA MMEETTRROOPPOOLLIITTAANNAA IIZZTTAAPPAALLAAPPAA CCaarrllooss EErrnneessttoo MMoorreennoo EEssccoobbaarr 220011221144115599
‐ 16 ‐
Figura 4.2.5 Operación de lectura de los registros de configuración.
44..22..66 IINNTTEERRFFAAZZ DDEE CCOONNFFIIGGUURRAACCIIÓÓNN
Para la interface entre el microcontrolador y el CC1000 es posible utilizar el protocolo de comunicaciones SPI, o algún tipo de UART síncrona (USART). Si se usa el SPI Maestro –donde el microcontrolador es el maestro‐ los pines MISO y MOSI deben estar conectados entre sí. El pin MOSI debe ser configurado como entrada durante la lectura del CC1000. Un pin de propósito general (I/O pin) puede ser usado para controlar el PALE del CC1000.
Figura 4.2.6 Interfaz SPI
La figura 4.2.6 nos muestra la interfaz de configuración utilizando el protocolo SPI. Los pines del microcontrolador conectados a PDATA y PCLK pueden ser utilizados para alguna otra tarea cuando no se está utilizando la configuración con la condición de que PALE se encuentre en estado alto.
44..22..77 IINNTTEERRFFAAZZ DDEE LLAA SSEEÑÑAALL DDEE DDAATTOOSS
La interfaz de señal consiste en DIO y DCLK, y es usado para la transmisión y recepción de los datos. DIO es la línea bidireccional de datos y DCLK produce un reloj síncrono durante la transmisión y recepción de datos hacia el microcontrolador. En este proyecto el modo Manchester será utilizado. El CC1000 se puede configurar para tres formatos de datos distintos:
• Modo síncrono NRZ. En modo de transmisión, el CC1000 produce el reloj de los datos en DCLK, y DIO es usado como entrada de datos. Los datos son modulados en RF sin codificación. En el modo de recepción el CC1000 realiza la sincronización y produce el tiempo de reloj de los datos recibidos en DCLK y los datos en DIO.
• Modo síncrono de codificación Manchester. En modo de transmisión el CC1000 crea el tiempo de reloj de los datos en DCLK y usa DIO como entrada de datos. Los datos se modulan con codificación Manchester en RF. En el modo de recepción el CC1000 crea la sincronización con el tiempo de reloj en DCLK y DIO es utilizado para la recepción de datos.
• Modo asíncrono UART. En modo de transmisión DIO es usado como entrada de datos. Los datos son modulados en RF sin sincronización y sin codificación. En el
[[CCOOMMUUNNIICCAACCIIÓÓNN AA NNIIVVEELL EENNLLAACCEE DDEE DDAATTOOSS EENNTTRREE MMIICCRROOCCOONNTTRROOLLAADDOORREESS CCOONN UUNNIIDDAADDEESS DDEE
RRAADDIIOOFFRREECCUUEENNCCIIAA]]
PPRROOYYEECCTTOO DDEE IINNGGEENNIIEERRÍÍAA EELLEECCTTRRÓÓNNIICCAA
UUNNIIVVEERRSSIIDDAADD AAUUTTÓÓNNOOMMAA MMEETTRROOPPOOLLIITTAANNAA IIZZTTAAPPAALLAAPPAA CCaarrllooss EErrnneessttoo MMoorreennoo EEssccoobbaarr 220011221144115599
‐ 17 ‐
modo de recepción la ráfaga de datos provenientes del demodulador son enviados a la salida. El pin DCLK se usa como salida de datos en este modo.
Figura 4.2.7 Modo NRZ Síncrono
Figura 4.2.8 Modo Manchester
PPRROOYYEECCTTOO DDEE IINNGGEENNIIEERRÍÍAA
EELLEECCTTRRÓÓNNIICCAA
[[CCOOMMUUNNIICCAACCIIÓÓNN AA NNIIVVEELL EENNLLAACCEE DDEE DDAATTOOSS EENNTTRREE MMIICCRROOCCOONNTTRROOLLAADDOORREESS CCOONN UUNNIIDDAADDEESS DDEE RRAADDIIOOFFRREECCUUEENNCCIIAA]]
UUNNIIVVEERRSSIIDDAADD AAUUTTÓÓNNOOMMAA MMEETTRROOPPOOLLIITTAANNAA IIZZTTAAPPAALLAAPPAA CCaarrllooss EErrnneessttoo MMoorreennoo EEssccoobbaarr 220011221144115599
‐ 18 ‐
Figura 4.2.9 Modo UART
44..22..88 IINNTTEERRFFAAZZ CCOONN EELL
MMIICCRROOCCOONNTTRROOLLAADDOORR
En sistemas típicos, el CC1000 utiliza una interfaz con un microcontrolador. Este último usa 3 pines para la interfaz de configuración (PDATA, PCLK, y PALE). El pin del microcontrolador conectado a PDATA debe ser bidireccional para la lectura de datos. Otro pin bidireccional para conectarse a la terminal de los datos (DIO) del CC1000 que serán transmitidos y recibidos. El pin conectado a DCLK produce el reloj que se conecta a la entrada del microprocesador. Los pines del microcontrolador conectados a PDATA y PCLK pueden ser utilizados con otros propósitos cuando la interfaz de la configuración no se usa. Se recomienda utilizar la interfaz SPI del microcontrolador para llevar a cabo la interfaz con el CC1000. Con la SPI en modo maestro, el pin MISO (Master In, Slave Out) y el MOSI (Master Out, Slave In) deben conectarse juntos. El pin MOSI debe configurarse como entrada para lectura desde el CC1000. Un pin I/O de propósito general puede usarse para la interfaz con el pin PALE del CC1000.
Figura 4.2.10 Interfaz con el Microcontrolador
[[CCOOMMUUNNIICCAACCIIÓÓNN AA NNIIVVEELL EENNLLAACCEE DDEE DDAATTOOSS EENNTTRREE MMIICCRROOCCOONNTTRROOLLAADDOORREESS CCOONN UUNNIIDDAADDEESS DDEE
RRAADDIIOOFFRREECCUUEENNCCIIAA]]
PPRROOYYEECCTTOO DDEE IINNGGEENNIIEERRÍÍAA EELLEECCTTRRÓÓNNIICCAA
UUNNIIVVEERRSSIIDDAADD AAUUTTÓÓNNOOMMAA MMEETTRROOPPOOLLIITTAANNAA IIZZTTAAPPAALLAAPPAA CCaarrllooss EErrnneessttoo MMoorreennoo EEssccoobbaarr 220011221144115599
‐ 19 ‐
44..22..99 SSIINNCCRROONNIIZZAADDOORR DDEE BBIITT YY DDEECCIISSIIÓÓNN DDEE
DDAATTOOSS
Un Diagrama a bloques del Demodulador puede observarse en la figura 4.2.11. La señal de IF es muestreada y su frecuencia instantánea es detectada. El resultado es diezmado y filtrado. En el Data Slicer la salida de datos del filtro es comparada con la salida del Filtro Promedio (Average Filter) para generar la salida de datos.
Figura 4.2.11 Diagrama a bloques del Demodulador
El Filtro Promedio es usado para encontrar el valor promedio de los datos entrantes. Mientras el filtro promedio se encuentra “corriendo” y adquiriendo muestras es importante que el número de bits altos sea igual al de bits en nivel bajo (p.e. Un preámbulo balanceado). El preámbulo sugerido es un patrón de “0101010101…”. Todos los modos, incluyendo los modos NRZ Síncronos, necesitan un preámbulo balanceado de DC, para que el data slicer interno, adquiera un nivel correcto de comparación con el filtro promedio. Si el receptor se encuentra en operación continua o es un receptor por encuesta (polled) el filtro promedio puede configurarse en modo automático. Si el receptor se encuentra operando continuamente y buscando por un preámbulo, el filtro promedio debe bloquearse manualmente tan pronto el preámbulo sea detectado. Si se está utilizando codificación Manchester, no hay necesidad de bloquear el filtro (MODEM1.LOCK_AVG_IN=”0”). De igual forma, para este modo de operación se requiere enviar un preámbulo balanceado que consiste en un patrón de “1100110011…”. La longitud del preámbulo depende del tipo de codificación de datos utilizada (NRZ, UART o Manchester), las tablas 4.2.1 y 4.2.2 nos muestra el número mínimo de bits (preámbulo) que debe ser recibido.
Tabla 4.2.1 Número de bits del preámbulo para bloquear el filtro promedio (UART y NRZ)
Tabla 4.2.2 Número de bits del preámbulo para bloquear el filtro promedio (Codificación
Manchester)
PPRROOYYEECCTTOO DDEE IINNGGEENNIIEERRÍÍAA
EELLEECCTTRRÓÓNNIICCAA
[[CCOOMMUUNNIICCAACCIIÓÓNN AA NNIIVVEELL EENNLLAACCEE DDEE DDAATTOOSS EENNTTRREE MMIICCRROOCCOONNTTRROOLLAADDOORREESS CCOONN UUNNIIDDAADDEESS DDEE RRAADDIIOOFFRREECCUUEENNCCIIAA]]
UUNNIIVVEERRSSIIDDAADD AAUUTTÓÓNNOOMMAA MMEETTRROOPPOOLLIITTAANNAA IIZZTTAAPPAALLAAPPAA CCaarrllooss EErrnneessttoo MMoorreennoo EEssccoobbaarr 220011221144115599
‐ 20 ‐
A continuación se muestra el modo de operación del filtro promedio para las configuraciones automática, manual y free‐runing.
• Modo automático. El filtro promedio se bloquea automáticamente después de que un preámbulo es detectado.
Figura 4.2.12 Filtro Promedio Bloqueado Automáticamente
• Modo Manual. El filtro promedio debe ser bloqueado manualmente después de
que el preámbulo es detectado.
Figura 4.2.13 Filtro Promedio Bloqueado Manualmente
• Modo Free‐Running. Este modo es recomendado únicamente cuando se utiliza la
codificación Manchester.
Figura 4.2.14 Filtro Promedio En Modo Free‐Running
44..22..1100 PPRROOGGRRAAMMAACCIIÓÓNN DDEE
LLAA FFRREECCUUEENNCCIIAA
La frecuencia del sintetizador (PLL) es controlada por la palabra de frecuencia en los registros de configuración. Hay dos palabras de frecuencia A y B, las cuales pueden ser programadas en dos frecuencias distintas. Una de las palabras de frecuencia puede ser usada para RX (frecuencia del oscilador local) y la otra palabra para TX (frecuencia de transmisión, f0). Esto hace posible cambiar rápidamente entre los modos Transmisión y Recepción. La palabra utilizada para la programación de frecuencia consta de 24 bits (3 bytes) se encuentran en los registros: FREQ_2A: FREQ_1A: FREQ_0A Y FREQ_2B: FREQ_1B: FREQ_0B. Los valores de estos registros pueden ser generados mediante el software SmartRF Studio.
[[CCOOMMUUNNIICCAACCIIÓÓNN AA NNIIVVEELL EENNLLAACCEE DDEE DDAATTOOSS EENNTTRREE MMIICCRROOCCOONNTTRROOLLAADDOORREESS CCOONN UUNNIIDDAADDEESS DDEE
RRAADDIIOOFFRREECCUUEENNCCIIAA]]
PPRROOYYEECCTTOO DDEE IINNGGEENNIIEERRÍÍAA EELLEECCTTRRÓÓNNIICCAA
UUNNIIVVEERRSSIIDDAADD AAUUTTÓÓNNOOMMAA MMEETTRROOPPOOLLIITTAANNAA IIZZTTAAPPAALLAAPPAA CCaarrllooss EErrnneessttoo MMoorreennoo EEssccoobbaarr 220011221144115599
‐ 21 ‐
44..22..1111 CCOONNFFIIGGUURRAACCIIOONNEESS PPAARRAA LLAASS BBAANNDDAASS IISSMM
El fabricante del dispositivo (Chipcon), nos proporciona una tabla de parámetros para que el CC1000 opere adecuadamente en las bandas ISM (Industrial, Scientific and Medical). Esto nos permite optimizar el funcionamiento del Transceiver para tener una mejor sensibilidad en el modo de recepción. SmartRF Studio puede ser utilizado para lograr optimizar la sensibilidad y corriente. A continuación se muestran las configuraciones recomendadas.
Tabla 4.2.3 Configuraciones recomendadas para las bandas ISM
44..22..1122 VVCCOO
((OOSSCCIILLAADDOORR
CCOONNTTRROOLLAADDOO PPOORR VVOOLLTTAAJJEE))
Se necesita solo un inductor externo (L101) para la operación del VCO el inductor determina la frecuencia de operación del Transceiver. Mediante SmartRF Studio podemos encontrar el valor de este inductor para la operación en la frecuencia que más convenga utilizar.
44..22..1133 AAUUTTOO‐‐CCAALLIIBBRRAACCIIÓÓNN DDEELL
VVCCOO YY EELL PPLLLL
Para compensar variaciones en el voltaje de alimentación, temperatura y algunas otras variaciones en el medio, el VCO y el PLL deben ser calibrados. La calibración se realiza automáticamente. Después de configurar el CC1000 la calibración puede realizarse. La calibración inicia cuando cambiamos a estado alto el bit CAL_START y es válida durante todo el tiempo que el dispositivo esté alimentado. Cada incremento o decremento del voltaje en 0.5 Volts o cada 40 grados requiere una nueva calibración. El proceso de calibración se discutirá en la sección 5.3.0 “Calibración”.
PPRROOYYEECCTTOO DDEE IINNGGEENNIIEERRÍÍAA
EELLEECCTTRRÓÓNNIICCAA
[[CCOOMMUUNNIICCAACCIIÓÓNN AA NNIIVVEELL EENNLLAACCEE DDEE DDAATTOOSS EENNTTRREE MMIICCRROOCCOONNTTRROOLLAADDOORREESS CCOONN UUNNIIDDAADDEESS DDEE RRAADDIIOOFFRREECCUUEENNCCIIAA]]
UUNNIIVVEERRSSIIDDAADD AAUUTTÓÓNNOOMMAA MMEETTRROOPPOOLLIITTAANNAA IIZZTTAAPPAALLAAPPAA CCaarrllooss EErrnneessttoo MMoorreennoo EEssccoobbaarr 220011221144115599
‐ 22 ‐
44..22..1144 CCOONNTTRROOLL DDEE LLAA PPOOTTEENNCCIIAA
El modo Power‐Down es controlado a través del registro MAIN. Tiene bits independientes para controlar la sección de RX y la de TX, el sintetizador de frecuencia y el cristal oscilador. Este control individual puede ser usado para optimizar el consumo de corriente en ciertas aplicaciones.
44..22..1155 RREEGGIISSTTRROOSS DDEE CCOONNFFIIGGUURRAACCIIÓÓNN DDEELL CCCC11000000
La configuración del CC1000 se realiza programando 22 registros de 8 bits. Todos los valores de configuración necesarios que deben ser cargados en cada uno de estos registros pueden ser encontrados fácilmente con SmartRF Studio. Después de un reset (en el registro Main) todos los registros recuperan su valor que tienen por default.
Tabla 4.2.4 Registros de Configuración del CC1000
[[CCOOMMUUNNIICCAACCIIÓÓNN AA NNIIVVEELL EENNLLAACCEE DDEE DDAATTOOSS EENNTTRREE MMIICCRROOCCOONNTTRROOLLAADDOORREESS CCOONN UUNNIIDDAADDEESS DDEE
RRAADDIIOOFFRREECCUUEENNCCIIAA]]
PPRROOYYEECCTTOO DDEE IINNGGEENNIIEERRÍÍAA EELLEECCTTRRÓÓNNIICCAA
UUNNIIVVEERRSSIIDDAADD AAUUTTÓÓNNOOMMAA MMEETTRROOPPOOLLIITTAANNAA IIZZTTAAPPAALLAAPPAA CCaarrllooss EErrnneessttoo MMoorreennoo EEssccoobbaarr 220011221144115599
‐ 23 ‐
44..33..00 MMÓÓDDUULLOO
CCCC11000000PPPP886688
El módulo CC1000PP‐868 (28x20mm) contiene todos los elementos de RF requeridos para su funcionamiento, esto incluye todos los elementos mencionados con anterioridad en el circuito de aplicación del CC1000 (figura 4.2.1), también incluye un cristal de 14.7456 MHz y un filtro LC para eliminar los armónicos emitidos. Este módulo está diseñado para trabajar en la frecuencia de 868 MHz a 930 MHz.
Figura 4.3.0 Módulo CC1000PP‐XXX
44..33..11 DDIIAAGGRRAAMMAA
DDEELL CCIIRRCCUUIITTOO
El CC1000PP viene en dos versiones, CC1000PP‐433 que opera a 433 MHz y el CC1000PP‐868 que opera a 868.3 MHz. Para el proyecto aquí presentado se ha utilizado la versión 868 del módulo. El pinout del módulo se muestra en la siguiente tabla.
Tabla 4.3.0 Pinout del Módulo CC1000PP‐XXX
PPRROOYYEECCTTOO DDEE IINNGGEENNIIEERRÍÍAA
EELLEECCTTRRÓÓNNIICCAA
[[CCOOMMUUNNIICCAACCIIÓÓNN AA NNIIVVEELL EENNLLAACCEE DDEE DDAATTOOSS EENNTTRREE MMIICCRROOCCOONNTTRROOLLAADDOORREESS CCOONN UUNNIIDDAADDEESS DDEE RRAADDIIOOFFRREECCUUEENNCCIIAA]]
UUNNIIVVEERRSSIIDDAADD AAUUTTÓÓNNOOMMAA MMEETTRROOPPOOLLIITTAANNAA IIZZTTAAPPAALLAAPPAA CCaarrllooss EErrnneessttoo MMoorreennoo EEssccoobbaarr 220011221144115599
‐ 24 ‐
Figura 4.3.1 Diagrama eléctrico del módulo CC1000P‐868
[[CCOOMMUUNNIICCAACCIIÓÓNN AA NNIIVVEELL EENNLLAACCEE DDEE DDAATTOOSS EENNTTRREE MMIICCRROOCCOONNTTRROOLLAADDOORREESS CCOONN UUNNIIDDAADDEESS DDEE
RRAADDIIOOFFRREECCUUEENNCCIIAA]]
PPRROOYYEECCTTOO DDEE IINNGGEENNIIEERRÍÍAA EELLEECCTTRRÓÓNNIICCAA
UUNNIIVVEERRSSIIDDAADD AAUUTTÓÓNNOOMMAA MMEETTRROOPPOOLLIITTAANNAA IIZZTTAAPPAALLAAPPAA CCaarrllooss EErrnneessttoo MMoorreennoo EEssccoobbaarr 220011221144115599
‐ 25 ‐
44..33..22 AANNTTEENNAASS
El módulo CC1000PP puede usar conjuntamente cualquier tipo de antena. Si la impedancia de la antena no está cerca de los 50 Ω, se deben usar componentes para aproximar la impedancia a 50 Ω. Un dipolo de λ/4 puede ser usado directamente quitando los pines 1, 2 y 3 de P2 y soldando una pieza de la longitud correcta.
Tabla 4.3.1 1/4 De longitud de onda para las frecuencias comunes
55..00 PPRROOCCEEDDIIMMIIEENNTTOOSS
DDEE CCOONNFFIIGGUURRAACCIIÓÓNN
En este capítulo se mostrarán los procedimientos básicos de configuración e inicialización para comenzar a operar el CC1000. Los procedimientos a analizar son los siguientes:
• Secuencia de Inicialización del CC1000 • Calibración • Modos de operación (Rx y Tx) • Power Down y Power Up
PPRROOYYEECCTTOO DDEE IINNGGEENNIIEERRÍÍAA
EELLEECCTTRRÓÓNNIICCAA
[[CCOOMMUUNNIICCAACCIIÓÓNN AA NNIIVVEELL EENNLLAACCEE DDEE DDAATTOOSS EENNTTRREE MMIICCRROOCCOONNTTRROOLLAADDOORREESS CCOONN UUNNIIDDAADDEESS DDEE RRAADDIIOOFFRREECCUUEENNCCIIAA]]
UUNNIIVVEERRSSIIDDAADD AAUUTTÓÓNNOOMMAA MMEETTRROOPPOOLLIITTAANNAA IIZZTTAAPPAALLAAPPAA CCaarrllooss EErrnneessttoo MMoorreennoo EEssccoobbaarr 220011221144115599
‐ 26 ‐
55..11..00 IINNIICCIIAALLIIZZAACCIIÓÓNN DDEELL CCCC11000000
El procedimiento básico de inicialización del CC1000 se muestra en la figura 5.1.0. Cuando el CC1000 es energizado, se requiere aplicar el reset principal contenido en el registro MAIN. NOTA: El contenido del registro MAIN cambia de valor constantemente durante la configuración y calibración del CC1000. El contenido final del registro (para trabajar como receptor o transmisor) debe cargarse durante la activación de Rx o Tx (Figura 5.50).
Figura 5.1.0 Proceso de inicialización del CC1000
[[CCOOMMUUNNIICCAACCIIÓÓNN AA NNIIVVEELL EENNLLAACCEE DDEE DDAATTOOSS EENNTTRREE MMIICCRROOCCOONNTTRROOLLAADDOORREESS CCOONN UUNNIIDDAADDEESS DDEE
RRAADDIIOOFFRREECCUUEENNCCIIAA]]
PPRROOYYEECCTTOO DDEE IINNGGEENNIIEERRÍÍAA EELLEECCTTRRÓÓNNIICCAA
UUNNIIVVEERRSSIIDDAADD AAUUTTÓÓNNOOMMAA MMEETTRROOPPOOLLIITTAANNAA IIZZTTAAPPAALLAAPPAA CCaarrllooss EErrnneessttoo MMoorreennoo EEssccoobbaarr 220011221144115599
‐ 27 ‐
55..22..00 RREESSEETT DDEELL CCCC11000000
La Figura 5.2.0 nos muestra el procedimiento completo de inicialización del CC1000. El reset se realiza cuando escribimos un cero en el bit RESET_N del registro MAIN y posteriormente escribimos un uno en el mismo bit. El reset debe ejecutarse al encender por primera vez el CC1000 y puede ejecutarse en cualquier momento. Después de un reset, los registros de configuración se cargan con su valor por default.
Figura 5.2.0 Reset del CC1000
55..33..00 CCAALLIIBBRRAACCIIÓÓNN
La calibración debe ejecutarse cuando el CC1000 esté configurado correctamente, es decir, que los registros de configuración estén cargados. Para este caso, los Transceivers serán utilizados para RX y Tx, así que usaremos una calibración dual, donde se calibra tanto la transmisión como la recepción. Es importante dejar claro que el registro de frecuencia FREQA será utilizado para recepción y el registro FREQB será utilizado para transmisión. Los registros deben estar cargados con los valores establecidos. El proceso de calibración dual se muestra a continuación.
PPRROOYYEECCTTOO DDEE IINNGGEENNIIEERRÍÍAA
EELLEECCTTRRÓÓNNIICCAA
[[CCOOMMUUNNIICCAACCIIÓÓNN AA NNIIVVEELL EENNLLAACCEE DDEE DDAATTOOSS EENNTTRREE MMIICCRROOCCOONNTTRROOLLAADDOORREESS CCOONN UUNNIIDDAADDEESS DDEE RRAADDIIOOFFRREECCUUEENNCCIIAA]]
UUNNIIVVEERRSSIIDDAADD AAUUTTÓÓNNOOMMAA MMEETTRROOPPOOLLIITTAANNAA IIZZTTAAPPAALLAAPPAA CCaarrllooss EErrnneessttoo MMoorreennoo EEssccoobbaarr 220011221144115599
‐ 28 ‐
Figura 5.3.0 Calibración Para Transmisor y Receptor
[[CCOOMMUUNNIICCAACCIIÓÓNN AA NNIIVVEELL EENNLLAACCEE DDEE DDAATTOOSS EENNTTRREE MMIICCRROOCCOONNTTRROOLLAADDOORREESS CCOONN UUNNIIDDAADDEESS DDEE
RRAADDIIOOFFRREECCUUEENNCCIIAA]]
PPRROOYYEECCTTOO DDEE IINNGGEENNIIEERRÍÍAA EELLEECCTTRRÓÓNNIICCAA
UUNNIIVVEERRSSIIDDAADD AAUUTTÓÓNNOOMMAA MMEETTRROOPPOOLLIITTAANNAA IIZZTTAAPPAALLAAPPAA CCaarrllooss EErrnneessttoo MMoorreennoo EEssccoobbaarr 220011221144115599
‐ 29 ‐
55..44..00 PPOOWWEERR
DDOOWWNN
El modo Power Down proporciona gran flexibilidad para aplicaciones que requieren poco consumo de corriente. El modo Power Down está controlado por el registro MAIN. La secuencia de Power Down se muestra a continuación.
Figura 5.4.0 Inicialización del Modo Power Down
55..55..00 PPOOWWEERR UUPP
YY AACCTTIIVVAACCIIÓÓNN DDEE TTXX YY RRXX
La siguiente secuencia muestra el procedimiento para habilitar el modo Power Up el CC1000, también muestra el procedimiento para comenzar la transmisión y recepción del Transceiver.
Figura 5.5.0 Secuencia de activación de RX o TX
PPRROOYYEECCTTOO DDEE IINNGGEENNIIEERRÍÍAA
EELLEECCTTRRÓÓNNIICCAA
[[CCOOMMUUNNIICCAACCIIÓÓNN AA NNIIVVEELL EENNLLAACCEE DDEE DDAATTOOSS EENNTTRREE MMIICCRROOCCOONNTTRROOLLAADDOORREESS CCOONN UUNNIIDDAADDEESS DDEE RRAADDIIOOFFRREECCUUEENNCCIIAA]]
UUNNIIVVEERRSSIIDDAADD AAUUTTÓÓNNOOMMAA MMEETTRROOPPOOLLIITTAANNAA IIZZTTAAPPAALLAAPPAA CCaarrllooss EErrnneessttoo MMoorreennoo EEssccoobbaarr 220011221144115599
‐ 30 ‐
66..00 IIMMPPLLEEMMEENNTTAACCIIÓÓNN
FFÍÍSSIICCAA
A continuación se muestran el software y hardware implementado, tanto para la configuración como para la interfaz de datos. Hay que mencionar ciertas características especiales para este diseño en particular. Las características del Microcontrolador utilizado son las siguientes:
• El AVR utilizado es el ATMEGA8535L‐8PI, el cual trabaja en el rango de 2.5 volts a 5.5 con una frecuencia de reloj máxima de 8 MHz.
• El CC1000 es configurado en el modo NRZ Manchester síncrono, por lo que el microcontrolador requiere una interrupción externa activada por flanco de subida para muestrear o transmitir los datos hacia el CC1000.
• El AVR tiene un SPI interno, pero mediante las pruebas realizadas no se pudo establecer una interfaz de configuración adecuada, así que se ha implementado un SPI por software que trabaja de una manera adecuada.
Características del CC1000PP‐868
• El CC1000PP‐868 trabaja únicamente en el rango de 868 MHz a 930Mhz. No es posible utilizar otra frecuencia, ya que los componentes necesarios están ìncluidos en el módulo.
• El CC1000 es configurado en modo NRZ Manchester Síncrono. Los datos a transmitir/recibir entran o salen por el pin DIO. La señal de reloj (generada por el Transceiver) se obtiene en el pin DCLK.
• A continuación se muestran los parámetros del CC1000 para este diseño en particular. Estos parámetros fueron generados mediante el Software SmartRF Studio.
Device: CC1000 System parameters: X-tal frequency: 14.745600 MHz Internal X-tal accuracy: +/- 20 ppm RF frequency A: 868.297200 MHz Inactive Rx RF frequency B: 868.297200 MHz Active Tx RX Mode: Low Current: no, Optimal frequency: yes, Low side LO Frequency separation: 64 kHz Data rate: 76.8 kBaud Data Format: Manchester Accurate RF output power: 5 dBm LOCK indicator: Continuous IF/RSSI: Disabled Operator Mode: Tx Component values, VCO inductor: L101 = 4.7 nH Component values, Match L32 = 120.0 nH L41 = 2.5 nH C31 = 10.0 pF C41 = N.A pF C42 = 4.7 pF
[[CCOOMMUUNNIICCAACCIIÓÓNN AA NNIIVVEELL EENNLLAACCEE DDEE DDAATTOOSS EENNTTRREE MMIICCRROOCCOONNTTRROOLLAADDOORREESS CCOONN UUNNIIDDAADDEESS DDEE
RRAADDIIOOFFRREECCUUEENNCCIIAA]]
PPRROOYYEECCTTOO DDEE IINNGGEENNIIEERRÍÍAA EELLEECCTTRRÓÓNNIICCAA
UUNNIIVVEERRSSIIDDAADD AAUUTTÓÓNNOOMMAA MMEETTRROOPPOOLLIITTAANNAA IIZZTTAAPPAALLAAPPAA CCaarrllooss EErrnneessttoo MMoorreennoo EEssccoobbaarr 220011221144115599
‐ 31 ‐
66..11..00 IINNTTEERRFFAACCEE DDEE CCOONNFFIIGGUURRAACCIIÓÓNN CCOONN EELL AAVVRR
Se ha implementado una interfaz SPI por software en el AVR para que la lectura de los registros de configuración del CC1000 sean leídos correctamente. La interfaz se realiza mediante el protocolo de comunicaciones SPI, donde el AVR es el maestro y el CC1000 es el esclavo. El microcontrolador debe generar el reloj mediante la terminal SCK (PB0), dicho pin se conecta a la terminal PCLK del CC1000 (Este pin funciona como la terminal SCK de un SPI en modo esclavo). En cada flanco de bajada, el microcontrolador debe mostrar los datos seriales en la terminal MOSI (PB2), la cual es conectada a la terminal PDATA (en este caso, PDATA es la terminal MOSI del sistema esclavo). A continuación se muestra un diagrama de las conexiones para la interface de configuración.
Figura 6.1.0 Interfaz de Configuración
En el pin PB0 (SCK) se genera el reloj de la sincronía para el procedimiento de lectura‐escritura. El diagrama de tiempos del procedimiento de Escritura/lectura para esta implementación se puede observar en las figuras 4.2.4 y 4.2.5.
66..22..00 IINNTTEERRFFAACCEE DDEE DDAATTOOSS CCOONN EELL
AAVVRR
Debido a que el CC1000 es configurado en modo Manchester síncrono, requiere el uso de una interrupción externa para la conexión del reloj DCLK generado por el CC1000. Se ha utilizado la interrupción externa INT0 del AVR (pin PD2) que es activada por el flanco de subida del reloj DCLK. El pin PD4 del AVR será la señal entrada/salida de los datos a transmitir, ésta se conecta al pin DIO del CC1000. En modo de transmisión. El pin PD4 debe ser configurado como salida y sacar el bit a transmitir durante el flanco de subida del DCLK. A continuación se muestra la inicialización de la interrupción externa INT0.
//DEFINICION DE LOS PINES .EQU DCLK = PD2 //PD2 PIN .EQU DIO = PD4 //PD4 PIN
. SBI PORTD,DCLK //PD2 COMO ENTRADA
LDI TEMP,(1<<ISC01)|(1<<ISC00) //INTERRUPCION POR FLANCO DE SUBIDA OUT MCUCR,TEMP .
LDI TEMP,1<<INTF0 OUT GIFR,TEMP //LIMPIA INTE. PENDIENTES LDI TEMP,1<<INT0 OUT GICR,TEMP //HABILITA INT. EXTERNA 0 LDI TEMP,1<<OCF1B OUT TIFR,TEMP
PPRROOYYEECCTTOO DDEE IINNGGEENNIIEERRÍÍAA
EELLEECCTTRRÓÓNNIICCAA
[[CCOOMMUUNNIICCAACCIIÓÓNN AA NNIIVVEELL EENNLLAACCEE DDEE DDAATTOOSS EENNTTRREE MMIICCRROOCCOONNTTRROOLLAADDOORREESS CCOONN UUNNIIDDAADDEESS DDEE RRAADDIIOOFFRREECCUUEENNCCIIAA]]
UUNNIIVVEERRSSIIDDAADD AAUUTTÓÓNNOOMMAA MMEETTRROOPPOOLLIITTAANNAA IIZZTTAAPPAALLAAPPAA CCaarrllooss EErrnneessttoo MMoorreennoo EEssccoobbaarr 220011221144115599
‐ 32 ‐
Figura 6.2.0 Interfaz de Datos
Mas adelante podremos observar cómo es que funciona más detalladamente esta interfaz de datos con el CC1000.
[[CCOOMMUUNNIICCAACCIIÓÓNN AA NNIIVVEELL EENNLLAACCEE DDEE DDAATTOOSS EENNTTRREE MMIICCRROOCCOONNTTRROOLLAADDOORREESS CCOONN UUNNIIDDAADDEESS DDEE
RRAADDIIOOFFRREECCUUEENNCCIIAA]]
PPRROOYYEECCTTOO DDEE IINNGGEENNIIEERRÍÍAA EELLEECCTTRRÓÓNNIICCAA
UUNNIIVVEERRSSIIDDAADD AAUUTTÓÓNNOOMMAA MMEETTRROOPPOOLLIITTAANNAA IIZZTTAAPPAALLAAPPAA CCaarrllooss EErrnneessttoo MMoorreennoo EEssccoobbaarr 220011221144115599
‐ 33 ‐
66..33..00 CCIIRRCCUUIITTOO GGEENNEERRAALL
El circuito general de interfaces es mostrado a continuación.
Figura 6.3.0 Conexión completa con el CC1000
Ahora que se tiene implementado el circuito completo –interfaz de configuración y la interfaz de datos‐, podemos continuar con la implementación necesaria del software para configuración.
77..00 SSOOFFTTWWAARREE
PPAARRAA
CCOONNFFIIGGUURRAACCIIÓÓNN DDEELL CCCC11000000
El Software diseñado para esta implementación, requiere el uso de constantes globales para la configuración total del CC1000. El software puede ser utilizado para cualquier modo de operación como Rx y Tx, o incluso, cambiar las frecuencias y la corriente consumida por el Transceiver, el uso de constantes globales nos proporciona esta flexibilidad ya que no hay que modificar el código fuente para cambiar la configuración del CC1000, basta con modificar las constantes globales.
77..11..00 CCOONNSSTTAANNTTEESS GGLLOOBBAALLEESS
Las constantes globales permiten modificar cualquier parámetro del CC1000 sin tener que modificar el código fuente del programa, a continuación se muestran las constantes y su descripción. Cada constante fue obtenida mediante SmartRF Studio, algunas de ellas fueron obtenidas de los diagramas de flujo del datasheet del CC1000.
/***************************************************************** ***** C O N F I G U R A C I O N P A R A E L C C 1 0 0 0 ****** ****************************************************************** // DIRECCIONES DE LOS REGISTROS DE CONFIGURACIÓN // (NO MODIFICAR!) .EQU AMAIN =$00 .EQU AFREQ_2A =$01 .EQU AFREQ_1A =$02 .EQU AFREQ_0A =$03 .EQU AFREQ_2B =$04 .EQU AFREQ_1B =$05 .EQU AFREQ_0B =$06
PPRROOYYEECCTTOO DDEE IINNGGEENNIIEERRÍÍAA
EELLEECCTTRRÓÓNNIICCAA
[[CCOOMMUUNNIICCAACCIIÓÓNN AA NNIIVVEELL EENNLLAACCEE DDEE DDAATTOOSS EENNTTRREE MMIICCRROOCCOONNTTRROOLLAADDOORREESS CCOONN UUNNIIDDAADDEESS DDEE RRAADDIIOOFFRREECCUUEENNCCIIAA]]
UUNNIIVVEERRSSIIDDAADD AAUUTTÓÓNNOOMMAA MMEETTRROOPPOOLLIITTAANNAA IIZZTTAAPPAALLAAPPAA CCaarrllooss EErrnneessttoo MMoorreennoo EEssccoobbaarr 220011221144115599
‐ 34 ‐
.EQU AFSEP1 =$07 .EQU AFSEP0 =$08 .EQU ACURRENT =$09 .EQU AFRONT_END =$0A .EQU APA_POW =$0B .EQU APLL =$0C .EQU ALOCK =$0D .EQU ACAL =$0E .EQU AMODEM2 =$0F .EQU AMODEM1 =$10 .EQU AMODEM0 =$11 .EQU AMATCH =$12 .EQU AFSCTRL =$13 .EQU APREESCALER =$1C .EQU ATEST4 =$42 // CONTENIDO DE LOS REGISTROS (DEFAULT MODO: TX) // (INTRODUCIR AQUÍ EL CONTENIDO DE LOS REGISTROS) .EQU MAIN =$E1 .EQU FREQ_2A =$75 .EQU FREQ_1A =$A0 .EQU FREQ_0A =$00 .EQU FREQ_2B =$58 .EQU FREQ_1B =$33 .EQU FREQ_0B =$13 .EQU FSEP1 =$01 .EQU FSEP0 =$AB .EQU CURRENT =$F3 .EQU FRONT_END =$30 .EQU PA_POW =$FF .EQU PLL =$30 .EQU LOCK =$90 .EQU CAL =$26 .EQU MODEM2 =$C1 .EQU MODEM1 =$6F .EQU MODEM0 =$54 .EQU MATCH =$10 .EQU FSCTRL =$01 .EQU PREESCALER =$00 .EQU TEST4 =$3F // PARA EL MODO DE RX LOS REGISTROS: MAIN, CURRENT // Y PLL CAMBIAN DE VALOR. // INTRODUCIR AQUÍ ESOS VALORES .EQU MAINRX =$11 .EQU CURRENTRX =$8C .EQU PLLRX =$40 .EQU CALRXTX =$26 /*************************************************************** * LAS SIGUIENTES CONSTANTES SON PARA EL RESET, CALIBARCIÓN, * POWER UP Y POWER DOWN DEL CC1000 NO ES NECESARIO MODIFICAR * ESTAS CONSTANTES ***************************************************************/ // CONTSTANTES PARA EL RESET (NO MODIFICAR!!) // (PÁGINA 29 DEL DATASHEET DEL CC1000) .EQU RESET1 =$3A .EQU RESET2 =$3B // CONSTANTES PARA CALIBRACIÓN (NO MODIFICAR!!) // (PÁGINA 26 DEL DATASHEET DEL CC1000)
[[CCOOMMUUNNIICCAACCIIÓÓNN AA NNIIVVEELL EENNLLAACCEE DDEE DDAATTOOSS EENNTTRREE MMIICCRROOCCOONNTTRROOLLAADDOORREESS CCOONN UUNNIIDDAADDEESS DDEE
RRAADDIIOOFFRREECCUUEENNCCIIAA]]
PPRROOYYEECCTTOO DDEE IINNGGEENNIIEERRÍÍAA EELLEECCTTRRÓÓNNIICCAA
UUNNIIVVEERRSSIIDDAADD AAUUTTÓÓNNOOMMAA MMEETTRROOPPOOLLIITTAANNAA IIZZTTAAPPAALLAAPPAA CCaarrllooss EErrnneessttoo MMoorreennoo EEssccoobbaarr 220011221144115599
‐ 35 ‐
.EQU CCAL =$A6 //INICIAR CALIBRACIÓN .EQU CPA_POW =$00 //POWER DOWN MODE .EQU CMAIN =$3F //MAIN EN \u017dMODO POWER DOWN // CONSTANTES PARA HABILITACIÓN DE TX Y RX (NO MODIFICAR!!) // (PÁG 30 DEL DATASHEET DEL CC1000) .EQU TURNONMAIN1 =$3B .EQU TURNONMAIN2 =$39 // CONSTANTE PARA APAGAR MODO TX (NO MODIFICAR!!) .EQU TRN_OFF_TX =$FF // CONSTANTE PARA APAGAR MODO RX (NO MODIFICAR!!) .EQU TRN_OFF_RX =$3F // FILTRO PROMEDIO PARA UART (NO MODIFICAR!!) // (TABLA 4 PÁGINA 20 DEL DATASHEET DEL CC1000) .EQU AUTOMATICO =$67 //MODO AUTÓMATICO .EQU BLOQUEAR =$7F //BLOQUEO MANUAL .EQU DESBLOQUEAR =$6F //DESBLOQUEO MANUAL .EQU RESETAVFILTER =$6E .EQU N=21 //*************** F I N D E L A T A B L A 1 **********************
77..22..00 CCOONNSSTTAANNTTEESS GGLLOOBBAALLEESS MMAACCRROO:: DDIIRREECC__DDAATTOOSS
Las constantes globales mostradas en la sección anterior son almacenadas en la memoria RAM para que mediante una función iterativa sean grabados en el CC1000. Las direcciones son almacenadas de la dirección $60 a $74 y los datos que deben ser cargados en los registros son almacenados de la dirección $75 a $89. El siguiente diagrama muestra el procedimiento de grabación en la RAM.
Figura 7.2.0 Almacenamiento en la RAM del AVR
A continuación se muestra la macro que almacena las direcciones y datos para la configuración del AVR. Nótese que las direcciones y datos son proporcionados por la tabla de constantes globales mostrada anteriormente. La forma de llamar a esta macro es la siguiente: DIREC_DATOS
.MACRO DIREC_DATOS CLR XH LDI XL,$60 //DIRECCIONES DE LOS REGISTROS DE CONFIGURACIÓN LDI TEMP,AFREQ_2A ST X+,TEMP LDI TEMP,AFREQ_1A ST X+,TEMP LDI TEMP,AFREQ_0A ST X+,TEMP
PPRROOYYEECCTTOO DDEE IINNGGEENNIIEERRÍÍAA
EELLEECCTTRRÓÓNNIICCAA
[[CCOOMMUUNNIICCAACCIIÓÓNN AA NNIIVVEELL EENNLLAACCEE DDEE DDAATTOOSS EENNTTRREE MMIICCRROOCCOONNTTRROOLLAADDOORREESS CCOONN UUNNIIDDAADDEESS DDEE RRAADDIIOOFFRREECCUUEENNCCIIAA]]
UUNNIIVVEERRSSIIDDAADD AAUUTTÓÓNNOOMMAA MMEETTRROOPPOOLLIITTAANNAA IIZZTTAAPPAALLAAPPAA CCaarrllooss EErrnneessttoo MMoorreennoo EEssccoobbaarr 220011221144115599
‐ 36 ‐
LDI TEMP,AFREQ_2B ST X+,TEMP LDI TEMP,AFREQ_1B ST X+,TEMP LDI TEMP,AFREQ_0B ST X+,TEMP LDI TEMP,AFSEP1 ST X+,TEMP LDI TEMP,AFSEP0 ST X+,TEMP LDI TEMP,ACURRENT ST X+,TEMP LDI TEMP,AFRONT_END ST X+,TEMP LDI TEMP,APA_POW ST X+,TEMP LDI TEMP,APLL ST X+,TEMP LDI TEMP,ALOCK ST X+,TEMP LDI TEMP,ACAL ST X+,TEMP LDI TEMP,AMODEM2 ST X+,TEMP LDI TEMP,AMODEM1 ST X+,TEMP LDI TEMP,AMODEM0 ST X+,TEMP LDI TEMP,AMATCH ST X+,TEMP LDI TEMP,AFSCTRL ST X+,TEMP LDI TEMP,APREESCALER ST X+,TEMP LDI TEMP,ATEST4 ST X+,TEMP LDI TEMP,FREQ_2A //ALMACENAR LOS DATOS DE CONFIGURACIÓN EN LA RAM ST X+,TEMP LDI TEMP,FREQ_1A ST X+,TEMP LDI TEMP,FREQ_0A ST X+,TEMP LDI TEMP,FREQ_2B ST X+,TEMP LDI TEMP,FREQ_1B ST X+,TEMP LDI TEMP,FREQ_0B ST X+,TEMP LDI TEMP,FSEP1 ST X+,TEMP LDI TEMP,FSEP0 ST X+,TEMP LDI TEMP,CURRENT ST X+,TEMP LDI TEMP,FRONT_END ST X+,TEMP LDI TEMP,PA_POW ST X+,TEMP LDI TEMP,PLL ST X+,TEMP LDI TEMP,LOCK ST X+,TEMP LDI TEMP,CAL
[[CCOOMMUUNNIICCAACCIIÓÓNN AA NNIIVVEELL EENNLLAACCEE DDEE DDAATTOOSS EENNTTRREE MMIICCRROOCCOONNTTRROOLLAADDOORREESS CCOONN UUNNIIDDAADDEESS DDEE
RRAADDIIOOFFRREECCUUEENNCCIIAA]]
PPRROOYYEECCTTOO DDEE IINNGGEENNIIEERRÍÍAA EELLEECCTTRRÓÓNNIICCAA
UUNNIIVVEERRSSIIDDAADD AAUUTTÓÓNNOOMMAA MMEETTRROOPPOOLLIITTAANNAA IIZZTTAAPPAALLAAPPAA CCaarrllooss EErrnneessttoo MMoorreennoo EEssccoobbaarr 220011221144115599
‐ 37 ‐
ST X+,TEMP LDI TEMP,MODEM2 ST X+,TEMP LDI TEMP,MODEM1 ST X+,TEMP LDI TEMP,MODEM0 ST X+,TEMP LDI TEMP,MATCH ST X+,TEMP LDI TEMP,FSCTRL ST X+,TEMP LDI TEMP,PREESCALER ST X+,TEMP LDI TEMP,TEST4 ST X+,TEMP .ENDMACRO
PPRROOYYEECCTTOO DDEE IINNGGEENNIIEERRÍÍAA
EELLEECCTTRRÓÓNNIICCAA
[[CCOOMMUUNNIICCAACCIIÓÓNN AA NNIIVVEELL EENNLLAACCEE DDEE DDAATTOOSS EENNTTRREE MMIICCRROOCCOONNTTRROOLLAADDOORREESS CCOONN UUNNIIDDAADDEESS DDEE RRAADDIIOOFFRREECCUUEENNCCIIAA]]
UUNNIIVVEERRSSIIDDAADD AAUUTTÓÓNNOOMMAA MMEETTRROOPPOOLLIITTAANNAA IIZZTTAAPPAALLAAPPAA CCaarrllooss EErrnneessttoo MMoorreennoo EEssccoobbaarr 220011221144115599
‐ 38 ‐
77..33..00 SSPPII PPOORR SSOOFFTTWWAARREE RRWW__SSPPII
Se ha realizado un programa que implementa el protocolo de comunicación SPI por software. Esta subrutina fue obtenida de la nota de aplicación de ATMEL No. 320. El algoritmo general es:
1. Generar el reloj de sincronización en uno de los pines del AVR (SCK) 2. Cada flanco de bajada del reloj mostrar el dato serial en otro pin de propósito
general del AVR, en este caso se ha utilizado el pin PB2 (MOSI) 3. El programa debe ser capaz de permitir la lectura de mediante el pin MISO (PB3)
Esta subrutina es utilizada para escribir los registros de configuración en el CC1000, y es llamada en la función “WRITETOCC1000”. A continuación se muestra la función implementada para la comunicación SPI.
RW_SPI: LDI TEMP,8 //CONTADOR (8 BITS DE DATOS) SPI_LOOP: LSL SPIDR //DESPLAZA EL REG SPIDR (PARA VER EL BIT A TRANS) BRCC LO_MOSI SBI PORTB,MOSI RJMP MOSI_DONE //ESTE SALTO CREA EL TIEMPO PARA QUE ESTÉ LISTO EL // DATO ANTES DEL FLANCO DE BAJADA LO_MOSI: CBI PORTB,MOSI //TRANSMITE EL CERO SI CarryFlag=0 NOP //TAMBIÉN CREA EL TIEMPO DE "SETUP" DEL MOSI NOP MOSI_DONE: CBI PORTB,SCK //SCK_HI CHANGE BY CARLOS SUBI TEMP, (1 << 5) //(1 * 3) CYCLE DELAY// RANGE IS FROM 1 TO 7! TIME_HI: SUBI TEMP, -(1 << 5) //DURACIÓN DEL TIEMPO EN ESTADO ALTO DE SCK, DESPUES BRCS TIME_HI // C ES LIMPIADA Y TEMP RECUPERA SU VALOR ORIGINAL SBIC PINB,MISO //AFTER DELAY, READ IN SPI BIT & PUT INTO D0 INC SPIDR //WE FORCED D0=0, SO USE INC TO SET D0. DEC TEMP SBI PORTB,SCK //SCK EN ESTADO ALTO SUBI TEMP, (1 << 5) TIME_LO: SUBI TEMP, -(1 << 5) //DURACIÓN DEL TIEMPO EN ESTADO BAJO DE SCK BRCS TIME_LO BRNE SPI_LOOP SBI PORTB,MOSI RET //******** F I N D E L A S S U B R U T I N A S D E L S P I ***********
77..44..00 FFUUNNCCIIÓÓNN WWRRIITTEETTOOCCCC11000000
Esta es la función principal que se utiliza para enviar las configuraciones al CC1000. Esta función necesita como parámetros la dirección del registro (que debe ser cargada previamente en el registro ADDRESS) y el dato a ser cargado en el registro (el cual debe ser cargado previamente en el registro DATA). En esta función es llamada la subrutina RW_SPI, la cual es encargada de transmitir la información hacia el CC1000. Esta función se realizó con la ayuda del diagrama de tiempos para escritura de la figura 4.2.4. La forma de ejecutar esta función es la siguiente: LDI ADDRESS,AMAIN //CARGAR EL REGISTRO ADDRESS CON LA DIRECCIÓN LDI DATA,TRN_OFF_TX //CARGAR EL REGISTRO DATA CON EL DATO
[[CCOOMMUUNNIICCAACCIIÓÓNN AA NNIIVVEELL EENNLLAACCEE DDEE DDAATTOOSS EENNTTRREE MMIICCRROOCCOONNTTRROOLLAADDOORREESS CCOONN UUNNIIDDAADDEESS DDEE
RRAADDIIOOFFRREECCUUEENNCCIIAA]]
PPRROOYYEECCTTOO DDEE IINNGGEENNIIEERRÍÍAA EELLEECCTTRRÓÓNNIICCAA
UUNNIIVVEERRSSIIDDAADD AAUUTTÓÓNNOOMMAA MMEETTRROOPPOOLLIITTAANNAA IIZZTTAAPPAALLAAPPAA CCaarrllooss EErrnneessttoo MMoorreennoo EEssccoobbaarr 220011221144115599
‐ 39 ‐
RCALL WRITETOCC1000 //LLAMAR A LA FUNCIÓN WRITETOCC1000 Los registros ADDRESS y DATA se cargan con los valores constantes definidos en la tabla de constantes globales y con valores definidos por el programador.
WRITETOCC1000: CBI PORTB,PALE //HABILITACIÓN DEL PROGRAM ADDRES LATCH MOV SPIDR,ADDRESS //CARGA LA DIRECCIÓN DEL REGISTRO MAIN SEC ROL SPIDR // BIT DE ESCRITURA (R/W) RCALL RW_SPI //TRANSMITIR LA DIRECCIÓN SBI PORTB,PALE //DESHABILITA EL PROGRAM ADDRES LATCH MOV SPIDR,DATA RCALL RW_SPI //TRANSMITIR DATO RET
77..55..00 FFUUNNCCIIÓÓNN RREESSEETTCCCC11000000
La función RESETCC1000 reinicializa el CC1000 con sus valores por default. Esto se logra limpiando el bit RESET_N del registro MAIN del CC1000 y posteriormente se coloca en estado alto el mismo bit. Después de esto es necesario esperar al menos 2mSeg. Ver la figura 5.2.0. La forma de ejecutar esta función es la siguiente: RCALL RESETCC1000
RESETCC1000: //RESET EL CC1000 LDI ADDRESS,AMAIN LDI DATA,RESET1 //RESET_N=0 RCALL WRITETOCC1000 LDI DATA,RESET2 //RESET_N=1 RCALL WRITETOCC1000 RCALL WAIT2ms RET
77..66..00 FFUUNNCCIIÓÓNN IINNIITTCCCC11000000
Esta función lee de la memoria RAM las direcciones y datos que son cargados en el CC1000 para su configuración. El procedimiento es el siguiente: El apuntador a la pila X es el encargado de leer las direcciones en la RAM y se carga en el registro ADDRESS. El apuntador a la pila Y lee de la RAM los datos de los registros los cuales don almacenados en el registro DATA. Posteriormente se llama a la función WRITETOCC1000 y se graban en el Transceiver. Esta secuencia se ejecuta 21 veces, ya que son 21 registros los que van a ser grabados. Posteriormente se inicia el proceso de calibración, la secuencia es la misma, se carga el registro ADDRESS con la dirección del registro posteriormente el dato es cargado en el registro DATA y se llama a la función WRITETOCC1000. El diagrama de flujo mostrado en la figura 5.1.0 nos muestra el procedimiento de calibración. NOTA: estas funciones utilizan la tabla de constantes globales definidas desde un principio. La forma de ejecutar esta función es la siguiente: RCALL INITCC1000
PPRROOYYEECCTTOO DDEE IINNGGEENNIIEERRÍÍAA
EELLEECCTTRRÓÓNNIICCAA
[[CCOOMMUUNNIICCAACCIIÓÓNN AA NNIIVVEELL EENNLLAACCEE DDEE DDAATTOOSS EENNTTRREE MMIICCRROOCCOONNTTRROOLLAADDOORREESS CCOONN UUNNIIDDAADDEESS DDEE RRAADDIIOOFFRREECCUUEENNCCIIAA]]
UUNNIIVVEERRSSIIDDAADD AAUUTTÓÓNNOOMMAA MMEETTRROOPPOOLLIITTAANNAA IIZZTTAAPPAALLAAPPAA CCaarrllooss EErrnneessttoo MMoorreennoo EEssccoobbaarr 220011221144115599
‐ 40 ‐
INITCC1000: //GRABAR LOS REGISTROS DEL CC1000 (EXCEPTO MAIN) RCALL RESETCC1000 CLR XH LDI XL,$60 //APUNTADOR A LAS DIRECCIONES CLR YH LDI YL,$60+N //APUNTADOR A LOS DATOS TXRX_CONFIG: LD ADDRESS,X+ //CARGA LA DIRECCIÓN DEL REGISTRO DE CONFIGURACIÓN LD DATA,Y+ RCALL WRITETOCC1000 //TRANSMITIR EL DATO CPI YL,$60+(2*N) //FINAL DE LOS DATOS? BRNE TXRX_CONFIG /***************************************************************************** * SECUENCIA DE CALIBRACIÓN DEL CC1000 ******************************************************************************/ LDI ADDRESS,AMAIN //INICIA CALIBRACIÓN LDI DATA,MAINRX // CALIBRAR RX PRIMERO RCALL WRITETOCC1000 LDI ADDRESS,ACURRENT LDI DATA,CURRENTRX RCALL WRITETOCC1000 LDI ADDRESS,APLL LDI DATA,PLLRX RCALL WRITETOCC1000 LDI ADDRESS,ACAL LDI DATA,CCAL RCALL WRITETOCC1000 RCALL WAIT34mS LDI DATA,CAL RCALL WRITETOCC1000 LDI ADDRESS,AMAIN // CALIBRAR TX LDI DATA,MAIN RCALL WRITETOCC1000 LDI ADDRESS,ACURRENT LDI DATA,CURRENT RCALL WRITETOCC1000 LDI ADDRESS,APLL LDI DATA,PLL RCALL WRITETOCC1000 LDI ADDRESS,APA_POW LDI DATA,CPA_POW RCALL WRITETOCC1000 LDI ADDRESS,ACAL LDI DATA,CCAL RCALL WRITETOCC1000 RCALL WAIT34mS LDI DATA,CAL RCALL WRITETOCC1000 //FIN DE LA CALIBRACIÓN LDI ADDRESS,AMAIN //PROGRAMAR MAIN EN MODO POWER DOWN LDI DATA,CMAIN RCALL WRITETOCC1000 LDI ADDRESS,APA_POW //POWER DOWN MODE: PA_POW=00h LDI DATA,CPA_POW RET
[[CCOOMMUUNNIICCAACCIIÓÓNN AA NNIIVVEELL EENNLLAACCEE DDEE DDAATTOOSS EENNTTRREE MMIICCRROOCCOONNTTRROOLLAADDOORREESS CCOONN UUNNIIDDAADDEESS DDEE
RRAADDIIOOFFRREECCUUEENNCCIIAA]]
PPRROOYYEECCTTOO DDEE IINNGGEENNIIEERRÍÍAA EELLEECCTTRRÓÓNNIICCAA
UUNNIIVVEERRSSIIDDAADD AAUUTTÓÓNNOOMMAA MMEETTRROOPPOOLLIITTAANNAA IIZZTTAAPPAALLAAPPAA CCaarrllooss EErrnneessttoo MMoorreennoo EEssccoobbaarr 220011221144115599
‐ 41 ‐
77..77..00 FFUUNNCCIIÓÓNN TTUURRNNOONNTTXX
Esta subrutina se realizó con el diagrama de flujo mostrado en la figura 5.5.0. Primero enciende el CC1000 (Power Up) y posteriormente activa el modo de transmisión. Al igual que las otras funciones, utiliza las constantes globales definidas anteriormente. La forma de ejecutar esta función es la siguiente: RCALL TURNONTX
TURNONTX: LDI ADDRESS,AMAIN LDI DATA,TURNONMAIN1 RCALL WRITETOCC1000 RCALL WAIT2mS LDI DATA,TURNONMAIN2 RCALL WRITETOCC1000 RCALL WAIT250uS LDI ADDRESS,APA_POW LDI DATA,CPA_POW RCALL WRITETOCC1000 LDI ADDRESS,AMAIN LDI DATA,MAIN RCALL WRITETOCC1000 LDI ADDRESS,ACURRENT LDI DATA,CURRENT RCALL WRITETOCC1000 LDI ADDRESS,APLL LDI DATA,PLL RCALL WRITETOCC1000 RCALL WAIT250uS LDI ADDRESS,APA_POW LDI DATA,PA_POW RCALL WRITETOCC1000 RCALL WAIT20uS RET
77..88..00 FFUUNNCCIIÓÓNN TTUURRNNOOFFFFTTXX
Esta función deshabilita el modo de transmisión y cambia el estado del CC1000 a Power Down. Ver figura 5.4.0. La forma de ejecutar esta función es la siguiente: RCALL TURNOFFTX
TURNOFFTX: LDI ADDRESS,AMAIN LDI DATA,TRN_OFF_TX RCALL WRITETOCC1000 LDI ADDRESS,APA_POW LDI DATA,$00 RCALL WRITETOCC1000 RET
77..99..00 FFUUNNCCIIÓÓNN TTUURRNNOONNRRXX
Esta subrutina se realizó con el diagrama de flujo mostrado en la figura 5.5.0. Primero enciende el CC1000 (Power Up) y posteriormente activa el modo de recepción. Al igual que las otras funciones, utiliza las constantes globales definidas anteriormente. La forma de ejecutar esta función es la siguiente: RCALL TURNONRX
TURNONRX:
PPRROOYYEECCTTOO DDEE IINNGGEENNIIEERRÍÍAA
EELLEECCTTRRÓÓNNIICCAA
[[CCOOMMUUNNIICCAACCIIÓÓNN AA NNIIVVEELL EENNLLAACCEE DDEE DDAATTOOSS EENNTTRREE MMIICCRROOCCOONNTTRROOLLAADDOORREESS CCOONN UUNNIIDDAADDEESS DDEE RRAADDIIOOFFRREECCUUEENNCCIIAA]]
UUNNIIVVEERRSSIIDDAADD AAUUTTÓÓNNOOMMAA MMEETTRROOPPOOLLIITTAANNAA IIZZTTAAPPAALLAAPPAA CCaarrllooss EErrnneessttoo MMoorreennoo EEssccoobbaarr 220011221144115599
‐ 42 ‐
LDI ADDRESS,AMAIN LDI DATA,TURNONMAIN1 RCALL WRITETOCC1000 RCALL WAIT2mS LDI DATA,TURNONMAIN2 RCALL WRITETOCC1000 RCALL WAIT250uS LDI ADDRESS,AMAIN LDI DATA,MAINRX RCALL WRITETOCC1000 LDI ADDRESS,ACURRENT LDI DATA,CURRENTRX RCALL WRITETOCC1000 LDI ADDRESS,APLL LDI DATA,PLLRX RCALL WRITETOCC1000 RCALL WAIT250uS RET
77..1100..00 FFUUNNCCIIÓÓNN TTUURRNNOOFFFFRRXX
Esta función deshabilita el modo de recepción y cambia el estado del CC1000 a Power Down. Ver figura 5.4.0. La forma de ejecutar esta función es la siguiente: RCALL TURNOFFRX
TURNOFFRX: LDI ADDRESS,AMAIN LDI DATA,TRN_OFF_RX RCALL WRITETOCC1000 LDI ADDRESS,APA_POW LDI DATA,$00 RCALL WRITETOCC1000 RET
Cabe mencionar que las funciones: TURNONTX, TURNOFFTX, TURNONRX y TURNOFFRX
Fueron obtenidas con ayuda del diagrama de flujo mostrada en la figura 5.5.0. A continuación se muestra ese mismo diagrama de flujo para identificar las funciones mencionadas.
[[CCOOMMUUNNIICCAACCIIÓÓNN AA NNIIVVEELL EENNLLAACCEE DDEE DDAATTOOSS EENNTTRREE MMIICCRROOCCOONNTTRROOLLAADDOORREESS CCOONN UUNNIIDDAADDEESS DDEE
RRAADDIIOOFFRREECCUUEENNCCIIAA]]
PPRROOYYEECCTTOO DDEE IINNGGEENNIIEERRÍÍAA EELLEECCTTRRÓÓNNIICCAA
UUNNIIVVEERRSSIIDDAADD AAUUTTÓÓNNOOMMAA MMEETTRROOPPOOLLIITTAANNAA IIZZTTAAPPAALLAAPPAA CCaarrllooss EErrnneessttoo MMoorreennoo EEssccoobbaarr 220011221144115599
‐ 43 ‐
Figura 7.9.0 Identificación de las Funciones en El diagrama de Flujo
77..1111..00 FFUUNNCCIIÓÓNN AAVVEERR__AAUUTTOO
Esta función configura el filtro promedio del CC1000 para que trabaje en modo automático (ver la sección 4.2.9 “Sincronizador de bit y decisión de datos”). La forma de ejecutar esta función es la siguiente: RCALL AVER_AUTO
AVER_AUTO: LDI ADDRESS,AMODEM1 LDI DATA,AUTOMATICO RCALL WRITETOCC1000 RET
77..1122..00 FFUUNNCCIIÓÓNN AAVVEERR__BBLLOOQQ
Esta función bloquea el filtro promedio. El filtro debe bloquearse manualmente una vez que un preámbulo válido es detectado. (Ver Sección 4.2.9 “Sincronizador de bit y decisión de datos“). La forma de ejecutar esta función es la siguiente: RCALL AVER_BLOQ
PPRROOYYEECCTTOO DDEE IINNGGEENNIIEERRÍÍAA
EELLEECCTTRRÓÓNNIICCAA
[[CCOOMMUUNNIICCAACCIIÓÓNN AA NNIIVVEELL EENNLLAACCEE DDEE DDAATTOOSS EENNTTRREE MMIICCRROOCCOONNTTRROOLLAADDOORREESS CCOONN UUNNIIDDAADDEESS DDEE RRAADDIIOOFFRREECCUUEENNCCIIAA]]
UUNNIIVVEERRSSIIDDAADD AAUUTTÓÓNNOOMMAA MMEETTRROOPPOOLLIITTAANNAA IIZZTTAAPPAALLAAPPAA CCaarrllooss EErrnneessttoo MMoorreennoo EEssccoobbaarr 220011221144115599
‐ 44 ‐
AVER_BLOQ: LDI ADDRESS,AMODEM1 LDI DATA,BLOQUEAR RCALL WRITETOCC1000 RET
77..1133..00 FFUUNNCCIIÓÓNN AAVVEERR__DDEESSBBLLOOQQ
Esta función desbloquea el filtro promedio. Esta función es utilizada si el preámbulo detectado no es el correcto, es decir, si el filtro promedio se bloquea con un preámbulo incorrecto, o el receptor no recibe correctamente los datos, el filtro promedio puede desbloquearse para adquirir nuevamente un preámbulo válido (Ver Sección 4.2.9 “Sincronizador de bit y decisión de datos“). La forma de ejecutar esta función es la siguiente: RCALL AVER_DESBLOQ
AVER_DESBLOQ: LDI ADDRESS,AMODEM1 LDI DATA,DESBLOQUEAR RCALL WRITETOCC1000 RET
77..1144..00 FFUUNNCCIIÓÓNN LLEEEERRCCCC11000000
Esta subrutina lee el contenido de todos los registros de configuración del CC1000, y los almacena en la memoria RAM. El proceso de lectura del CC1000 se puede observar en la figura 4.2.5. La función lee de la memoria RAM las dirección de los registros (cargada previamente con la macro DIREC_DATOS), la transmite hacia el CC1000 (junto con el bit R/W). Inmediatamente después de que el bit de lectura‐escritura es enviado, el CC1000 regresa el contenido del registro que es almacenado en la memoria RAM del AVR para su utilización.
LEERCC1000: CLR XH LDI XL,$60 //APUNTADOR A LAS DIRECCIONES CLR YH LDI YL,$60+N //APUNTADOR A LOS DATOS READTXRX: CBI PORTB,PALE //HABILITACIÓN DEL PROGRAM ADDRES LATCH LD SPIDR,X+ //CARGA LA DIRECCIÓN DEL REGISTRO DE CONFIGURACIÓN CLC ROL SPIDR RCALL RW_SPI //TRANSMITIR LA DIRECCIÓN SBI PORTB,PALE //DESHABILITA EL PROGRAM ADDRES LATCH CBI DDRB,MOSI CLR SPIDR //CARGA EL DATO RCALL RW_SPI //TRANSMITIR EL DATO ST Y+,SPIDR SBI DDRB,MOSI CPI YL,$60+(2*N) //FINAL DE LOS DATOS? BRNE READTXRX SBI DDRB,MOSI RET
[[CCOOMMUUNNIICCAACCIIÓÓNN AA NNIIVVEELL EENNLLAACCEE DDEE DDAATTOOSS EENNTTRREE MMIICCRROOCCOONNTTRROOLLAADDOORREESS CCOONN UUNNIIDDAADDEESS DDEE
RRAADDIIOOFFRREECCUUEENNCCIIAA]]
PPRROOYYEECCTTOO DDEE IINNGGEENNIIEERRÍÍAA EELLEECCTTRRÓÓNNIICCAA
UUNNIIVVEERRSSIIDDAADD AAUUTTÓÓNNOOMMAA MMEETTRROOPPOOLLIITTAANNAA IIZZTTAAPPAALLAAPPAA CCaarrllooss EErrnneessttoo MMoorreennoo EEssccoobbaarr 220011221144115599
‐ 45 ‐
88..00 SSOOFFTTWWAARREE
PPAARRAA LLAA IINNTTEERRFFAACCEE
DDEE DDAATTOOSS
En esta sección analizaremos el software diseñado para implementar la transmisión/recepción de datos. Es necesario remarcar que el Transceiver se ha configurado en un modo síncrono, es decir, el CC1000 genera la señal de reloj requerida para el intercambio de información con el AVR. Para este procedimiento la señal de reloj generada por el CC1000 debe ser conectada a una interrupción externa del AVR, en este caso se ha elegido INT0. Tanto el procedimiento de recepción como el de transmisión requieren la utilización de esta configuración, y por lo tanto, requieren la misma subrutina de atención a interrupción. Para la interface de datos se han diseñado cuatro funciones: ENVIA_PREAMBULO, ESPERA_PREAMBULO, ENVIA_DATO y RECIBE_DATO. Todas ellas tienen el mismo principio de funcionamiento. Una vez comprendido esto, la implementación de las funciones para el intercambio de información serán más comprensibles.
8.0
88..11..00 SSUUBBRRUUTTIINNAA DDEE AATTEENNCCIIÓÓNN AA
IINNTTEERRRRUUPPCCIIÓÓNN
Como se mencionó anteriormente, para el proceso de recepción o transmisión se utiliza la interrupción externa INT0 generada por flanco de subida, por lo que la ISR empleada requiere identificar qué operación va a ejecutar. Para solucionar este problema, se han usado registros auxiliares para la identificación del proceso. Por ejemplo, supongamos que tenemos una subrutina que envía un dato 1 byte. LDI HBYTE,0B11000111 //DATO A TRANSMITIR RCALL ENVIA_DATO //SUBRUTINA DE TRANSMISIÓN DE 1 BYTE La subrutina que envía el dato es la siguiente. ENVIA_DATO: LDI MODO,MODOTXDAT //MODO: TRANSMITIR BYTE LDI CONT,$08 //TRANSMITIR 8 BITS SBI DDRD,DIO //PD4 (DIO) SALIDA /*EN ESTE BUCLE SE ESPERA A QUE SE GENERE EL FLANCO DE SUBIDA DEL RELOJ (DCLK) DEL CC1000*/ ESPERATXDAT: CPI CONT,$00 //CONT='0'? BREQ SALIDA_ED // FIN DE LA SUBRUTINA RJMP ESPERATXDAT //CONTINUA TRANSMITIENDO SALIDA_ED: RET Una vez que el programa entra en el bucle “ESPERATXDAT”, permanece ahí hasta que se genera la interrupción por flanco de subida del reloj del CC1000. Nótese que existe un registro llamado “MODO”, este registro es utilizado para indicarle a la ISR que atienda a la solicitud para enviar un byte hacia el CC1000. Las constantes utilizadas para la identificación son las siguientes: .EQU MODOTXDAT = 1 // MODO DE TRANSMISIÓN .EQU MODORXDAT = 2 // MODO DE RECEPCIÓN .EQU MODOTXPRE = 3 // MODO ENVIA PREAMBULO .EQU MODORXPRE = 4 // MODO RECIBE PREAMBULO Ahora, supongamos que se genera la interrupción y se interrumpe el proceso. La ISR comprueba el contenido del registro “MODO” para ejecutar su tarea, la ISR es de la siguiente forma:
PPRROOYYEECCTTOO DDEE IINNGGEENNIIEERRÍÍAA
EELLEECCTTRRÓÓNNIICCAA
[[CCOOMMUUNNIICCAACCIIÓÓNN AA NNIIVVEELL EENNLLAACCEE DDEE DDAATTOOSS EENNTTRREE MMIICCRROOCCOONNTTRROOLLAADDOORREESS CCOONN UUNNIIDDAADDEESS DDEE RRAADDIIOOFFRREECCUUEENNCCIIAA]]
UUNNIIVVEERRSSIIDDAADD AAUUTTÓÓNNOOMMAA MMEETTRROOPPOOLLIITTAANNAA IIZZTTAAPPAALLAAPPAA CCaarrllooss EErrnneessttoo MMoorreennoo EEssccoobbaarr 220011221144115599
‐ 46 ‐
.ORG INT0addr RJMP RISE_DCLK RISE_DCLK: //IDENTIFICACION DE LA OPERACIÓN CPI MODO,MODOTXDAT BREQ TX_DATO //TRANSMITIR BYTE CPI MODO,MODORXDAT BREQ RX_DATO //RECIBIR BYTE CPI MODO,MODOTXPRE BREQ TX_PREAMBULO //GENERA Y TRANSMITE PREAMBULO CPI MODO,MODORXPRE BREQ RX_PREAMBULO //ESPERA Y VALIDA PREAMBULO TX_PREAMBULO: .
.
. RETI TX_DATO:
.
.
. RETI RX_PREAMBULO:
.
.
. RETI RX_DATO:
.
.
. RETI De esta forma, la ISR identifica la operación a la que va a atender. El diseño definitivo de la ISR se muestra a continuación. NOTA: cada una de las subrutinas mostradas en la ISR (TX_DATO, RX_DATO, TX_PREAMBULO y RX_PREAMBULO) se explicará detalladamente mas adelante.
/*************************************************************************** * CONSTANTES PARA IDENTIFICAR QUE OPERACIÓN SE VA A REALIZAR * DURANTE LA INTERRUPCIÓN POR EL FLANCO DE SUBIDA DEL DCLK ****************************************************************************/ .EQU MODOTXDAT = 1 // MODO DE TRANSMISIÓN .EQU MODORXDAT = 2 // MODO DE RECEPCIÓN .EQU MODOTXPRE = 3 // MODO ENVIA PREAMBULO .EQU MODORXPRE = 4 // MODO RECIBE PREAMBULO RISE_DCLK: //IDENTIFICACION DE LA OPERACIÓN IN S_REG,SREG CPI MODO,MODOTXDAT
[[CCOOMMUUNNIICCAACCIIÓÓNN AA NNIIVVEELL EENNLLAACCEE DDEE DDAATTOOSS EENNTTRREE MMIICCRROOCCOONNTTRROOLLAADDOORREESS CCOONN UUNNIIDDAADDEESS DDEE
RRAADDIIOOFFRREECCUUEENNCCIIAA]]
PPRROOYYEECCTTOO DDEE IINNGGEENNIIEERRÍÍAA EELLEECCTTRRÓÓNNIICCAA
UUNNIIVVEERRSSIIDDAADD AAUUTTÓÓNNOOMMAA MMEETTRROOPPOOLLIITTAANNAA IIZZTTAAPPAALLAAPPAA CCaarrllooss EErrnneessttoo MMoorreennoo EEssccoobbaarr 220011221144115599
‐ 47 ‐
BREQ TX_DATO //TRANSMITIR BYTE CPI MODO,MODORXDAT BREQ RX_DATO //RECIBIR BYTE CPI MODO,MODOTXPRE BREQ TX_PREAMBULO //GENERA Y TRANSMITE PREAMBULO CPI MODO,MODORXPRE BREQ RX_PREAMBULO //ESPERA Y VALIDA PREAMBULO TX_PREAMBULO: // TRANSMITIR PREAMBULO EN FLANCO DE SUBIDA DE DCLK CPI HBYTE,$01 //HBYTE=1 ? BREQ ENVIA1 // SI: GENERAR UN '1' Y TRANSMITIRLO CBI PORTD,DIO // NO: GENERAR UN '0' Y TRANSMITIRLO LDI HBYTE,$01 DEC CONT OUT SREG,S_REG RETI ENVIA1: //SUBRUTINA QUE ENVÍA UN '1' SBI PORTD,DIO //GENERAR UN '1' CLR HBYTE DEC CONT OUT SREG,S_REG RETI TX_DATO: //ENVIAR UN BIT A LA VEZ CADA FLANCO DE SUBIDA DE DCLK ROR HBYTE //ROTAR HBYTE BRCS ENVIA_D1 //CARRY FLAG='0' ? CBI PORTD,DIO // GENERA Y TX UN '1' DEC CONT //OTRO GENERA Y TX UN '0' OUT SREG,S_REG RETI ENVIA_D1: //SUBRUTINA PARA TX UN '1' SBI PORTD,DIO DEC CONT //DECREMENTAR CONTADOR OUT SREG,S_REG RETI RX_PREAMBULO: //ESPERA Y VALIDA EL PREAMBULO CPI TEMP,$00 BREQ ESPERA1 SBIS PIND,DIO //SI PD4='1' CLC // CARRY FLAG='0' SBIC PIND,DIO //SI PD4='0' REGRESA: SEC // CARRY FLAG='1' ROR HBYTE //C->b7....b0->C INC TEMP CPI TEMP,$02 //SI TEMP=2 BREQ VALID_PRE // SATO A VALID_PRE DEC CONT //OTRO DEC CONT OUT SREG,S_REG RETI VALID_PRE: CPI HBYTE,$40 //HBYTE=$40? BREQ PRE_CORRECTO // PREAMBULO CORRECTO LDI CONT,CHIP //REINICIALIZAR CONTADOR CLR TEMP // TEMP CLR HBYTE // HBYTE OUT SREG,S_REG RETI PRE_CORRECTO: DEC CONT //DECREMENTA CONTADOR CLR HBYTE // LIMPIA HBYTE CLR TEMP // LIMPIA TEMP OUT SREG,S_REG
PPRROOYYEECCTTOO DDEE IINNGGEENNIIEERRÍÍAA
EELLEECCTTRRÓÓNNIICCAA
[[CCOOMMUUNNIICCAACCIIÓÓNN AA NNIIVVEELL EENNLLAACCEE DDEE DDAATTOOSS EENNTTRREE MMIICCRROOCCOONNTTRROOLLAADDOORREESS CCOONN UUNNIIDDAADDEESS DDEE RRAADDIIOOFFRREECCUUEENNCCIIAA]]
UUNNIIVVEERRSSIIDDAADD AAUUTTÓÓNNOOMMAA MMEETTRROOPPOOLLIITTAANNAA IIZZTTAAPPAALLAAPPAA CCaarrllooss EErrnneessttoo MMoorreennoo EEssccoobbaarr 220011221144115599
‐ 48 ‐
RETI ESPERA1: SBIC PIND,DIO RJMP REGRESA OUT SREG,S_REG RETI RX_DATO: //RECIBIR UN BIT A LA VEZ CADA FLANCO DE SUBIDA DE DCLK SBIS PIND,DIO //PD4='0' CLC // CARRY FLAG='0' SBIC PIND,DIO //PD='1' SEC // CARRY FLAG='1' ROR HBYTE //C->b7....b0->C DEC CONT OUT SREG,S_REG RETI
88..22..00 FFUUNNCCIIÓÓNN EENNVVIIAA__PPRREEAAMMBBUULLOO
Esta subrutina genera y transmite un preámbulo balanceado requerido para que el receptor lea correctamente los datos recibidos. El procedimiento de generación es el siguiente: Primero se carga el registro MODO con el dato definido en las constantes para que la ISR identifique la operación.
.EQU MODOTXPRE = 3 El pin PD4 es configurado como salida, donde se obtendrán los bits a transmitir cada flanco de subida del DCLK. El preámbulo a transmitir debe ser de 196 bits (para configuración Manchester). La subrutina es llamada de la siguiente forma:
RCALL ENVIA_PREAMBULO //ENVIA EL PREAMBULO El siguiente diagrama de flujo nos muestra la operación de la subrutina.
Figura 8.2.0 Función ENVIA_PREAMBULO
Una vez que el programa entra en el bucle donde se verifica el registro CONT se espera a que se genere la interrupción por el flanco de subida. Una vez realizada la interrupción el programa salta a la ISR.
[[CCOOMMUUNNIICCAACCIIÓÓNN AA NNIIVVEELL EENNLLAACCEE DDEE DDAATTOOSS EENNTTRREE MMIICCRROOCCOONNTTRROOLLAADDOORREESS CCOONN UUNNIIDDAADDEESS DDEE
RRAADDIIOOFFRREECCUUEENNCCIIAA]]
PPRROOYYEECCTTOO DDEE IINNGGEENNIIEERRÍÍAA EELLEECCTTRRÓÓNNIICCAA
UUNNIIVVEERRSSIIDDAADD AAUUTTÓÓNNOOMMAA MMEETTRROOPPOOLLIITTAANNAA IIZZTTAAPPAALLAAPPAA CCaarrllooss EErrnneessttoo MMoorreennoo EEssccoobbaarr 220011221144115599
‐ 49 ‐
Figura 8.2.1 Función ISR de ENVIA_PREAMBULO
En la ISR primero se respalda el Status Register, posteriormente se identifica la operación (MODOTXPRE). El registro HBYTE es utilizado como una bandera que cambia entre los valores de cero y uno, dependiendo del valor del registro bandera, se coloca en nivel alto o bajo el pin PD4 del AVR. Una vez transmitido el bit, se decrementa el contador (CONT) en uno y se regresa de la ISR. Si regresamos a la figura 8.2.0. La condición para salirse del bucle es que CONT sea cero, esto sucede una vez que se ha transmitido todo el preámbulo. A continuación se muestra la ISR y la subrutina ENVIA_PREAMBULO.
RISE_DCLK: CPI MODO,MODOTXPRE BREQ TX_PREAMBULO //GENERA Y TRANSMITE PREAMBULO . . . . /************************************************************************* * GENERA Y TRANSMITE PREAMBULO *************************************************************************/ TX_PREAMBULO: // TRANSMITIR PREAMBULO EN FLANCO DE SUBIDA DE DCLK CPI HBYTE,$01 //HBYTE=1 ? BREQ ENVIA1 // SI: GENERAR UN '1' Y TRANSMITIRLO CBI PORTD,DIO // OTRO: GENERAR UN '0' Y TRANSMITIRLO LDI HBYTE,$01 DEC CONT OUT SREG,S_REG RETI ENVIA1: // SUBRUTINA QUE ENVÍA UN '1' SBI PORTD,DIO CLR HBYTE
PPRROOYYEECCTTOO DDEE IINNGGEENNIIEERRÍÍAA
EELLEECCTTRRÓÓNNIICCAA
[[CCOOMMUUNNIICCAACCIIÓÓNN AA NNIIVVEELL EENNLLAACCEE DDEE DDAATTOOSS EENNTTRREE MMIICCRROOCCOONNTTRROOLLAADDOORREESS CCOONN UUNNIIDDAADDEESS DDEE RRAADDIIOOFFRREECCUUEENNCCIIAA]]
UUNNIIVVEERRSSIIDDAADD AAUUTTÓÓNNOOMMAA MMEETTRROOPPOOLLIITTAANNAA IIZZTTAAPPAALLAAPPAA CCaarrllooss EErrnneessttoo MMoorreennoo EEssccoobbaarr 220011221144115599
‐ 50 ‐
DEC CONT OUT SREG,S_REG RETI /*************************************************************************** * FUNCION: * ENVIA_PREAMBULO ****************************************************************************/ ENVIA_PREAMBULO: LDI MODO,MODOTXPRE //MODO: GENERA Y TRANSMITE PREAMBULO SBI DDRD,DIO //PD4=SALIDA DEL BIT A TRANSMITIR LDI CONT,CHIP //CONT=CHIP LDI HBYTE,$01 LDI TEMP,1<<INTF0 OUT GIFR,TEMP //LIMPIA INTE. PENDIENTES LDI TEMP,1<<INT0 OUT GICR,TEMP //HABILITA INT. EXTERNA 0 ESPERATXPRE: CPI CONT,0 //CONT='0' ? BREQ SALIDA_EP // FIN DE LA SUBRUTINA RJMP ESPERATXPRE //CONTINUA TRANSMITIENDO SALIDA_EP: RET
88..33..00 FFUUNNCCIIÓÓNN EESSPPEERRAA__PPRREEAAMMBBUULLOO
Al igual que la función ENVIA_PREAMBULO, esta subrutina utiliza la interrupción externa INT0, pero en esta ocasión cada flanco de subida del DCLK se recibe un bit. La función ESPERA_PREAMBULO valida el preámbulo recibido. Esto es necesario ya que el CC1000 constantemente recibe datos provenientes del ruido en el medio ambiente. Entonces, se ha realizado una función que descarta las señales de ruido y acepta las señales provenientes de otro CC1000. La subrutina es llamada mediante la instrucción:
RCALL ESPERA_PREAMBULO //ESPERAR PREAMBULO
La función se muestra en el siguiente diagrama de flujo.
[[CCOOMMUUNNIICCAACCIIÓÓNN AA NNIIVVEELL EENNLLAACCEE DDEE DDAATTOOSS EENNTTRREE MMIICCRROOCCOONNTTRROOLLAADDOORREESS CCOONN UUNNIIDDAADDEESS DDEE
RRAADDIIOOFFRREECCUUEENNCCIIAA]]
PPRROOYYEECCTTOO DDEE IINNGGEENNIIEERRÍÍAA EELLEECCTTRRÓÓNNIICCAA
UUNNIIVVEERRSSIIDDAADD AAUUTTÓÓNNOOMMAA MMEETTRROOPPOOLLIITTAANNAA IIZZTTAAPPAALLAAPPAA CCaarrllooss EErrnneessttoo MMoorreennoo EEssccoobbaarr 220011221144115599
‐ 51 ‐
Figura 8.3.0 Función ESPERA_PREAMBULO
Una vez que se haya regresado de esta subrutina el microcontrolador está listo para recibir datos válidos, los cuales deben ser recibidos mediante otra función: RECIBE_BYTE (sección 8.5.0). Puede observarse que tiene un bloque de decisión llamado “TIMEOUT END?”. Este bloque se ha implementado para el diseño del protocolo Stop and Wait. La finalidad de este bloque es identificar si el tiempo de espera (TIMEOUT) ha finalizado y se requiere retransmisión. Este bloque es utilizado únicamente en la función “RECIBE_ACUSE”, donde el timeout es configurado. De cualquier forma, esto se explicara más a detalle en la sección 10.4.0. La ISR correspondiente a la función ESPERA_PREAMBULO es un poco más complicada en su diseño ya que, como se mencionó anteriormente, se requiere diferenciar un preámbulo válido del ruido en el ambiente. La subrutina funciona de la siguiente forma: Primero se establece un contador de bits (TEMP), el cual únicamente cuenta hasta dos para que validen únicamente dos bits del preámbulo “01” en ese estricto orden. Supongamos primero se recibe un preámbulo correcto. Se recomienda ver detalladamente el diagrama de flujo de la figura 8.3.1 para un mejor entendimiento.
1. El primer bit que se recibe es un 1. Entonces si TEMP=$00 y en la entrada (pin PD4) tenemos un 1, esto hace que se encienda la bandera de acarreo y se rote el registro HBYTE a la derecha, entonces HBYTE=$80 (10000000). Ahora se incrementa TEMP (TEMP=$01) indicando que se ha recibido el primer bit. Debido a que TEMP es diferente de $02, la subrutina decrementa en contador CONT (ahora CONT=195) y sale de la ISR. Recordemos que el contador CONT se inicializa en la declaración de la función (ver figura 8.3.0) y es el número de bits de
PPRROOYYEECCTTOO DDEE IINNGGEENNIIEERRÍÍAA
EELLEECCTTRRÓÓNNIICCAA
[[CCOOMMUUNNIICCAACCIIÓÓNN AA NNIIVVEELL EENNLLAACCEE DDEE DDAATTOOSS EENNTTRREE MMIICCRROOCCOONNTTRROOLLAADDOORREESS CCOONN UUNNIIDDAADDEESS DDEE RRAADDIIOOFFRREECCUUEENNCCIIAA]]
UUNNIIVVEERRSSIIDDAADD AAUUTTÓÓNNOOMMAA MMEETTRROOPPOOLLIITTAANNAA IIZZTTAAPPAALLAAPPAA CCaarrllooss EErrnneessttoo MMoorreennoo EEssccoobbaarr 220011221144115599
‐ 52 ‐
preámbulo a recibir (196 bits).2. Ahora, se recibe un 0 en el siguiente flanco de subida del DCLK. TEMP es diferente
de $00 y en la entrada (pin PD4) tenemos un 0, esto provoca que se limpie la bandera de acarreo y se rote el registro HBYTE, ahora HBYTE=$40 (01000000) y TEMP=$02, lo que significa que se ha recibido el segundo bit. Entonces tenemos un segmento del preámbulo: “01”. Debido a que HBYTE es $40 se decrementa CONT (ahora CONT=194), se reinicializa el contador de bits (TEMP) y se limpia HBYTE. Cuando HBYTE=$00, TEMP=$00 se reinicializa la secuencia, y se vuelve al paso 1.
De esta forma CONT se va decrementando hasta recibir los 196 bits de preámbulo esperado. Si observamos la figura 8.3.0 se sale de la subrutina ESPERA_PREAMBULO una vez que el registro CONT es igual a 0. CONT restablece su valor original si la secuencia recibida no es un preámbulo de 196 bits. Consideremos el siguiente caso: Si se recibe un dato diferente, por ejemplo un 11, la ISR se comporta de la siguiente forma:
1. El primer bit que se recibe es un 1. Entonces TEMP=$00, esto hace que se encienda la bandera de acarreo y se rote el registro HBYTE a la derecha, entonces HBYTE=$80 (1000000). Ahora se incrementa TEMP (TEMP=$01) indicando que se ha recibido el primer bit. Debido a que TEMP es diferente de $02, la subrutina decrementa en contador CONT (ahora CONT=195) y sale de la ISR.
2. Ahora el segundo bit a recibir es un 1. TEMP es diferente de cero. Por lo tanto se lee que en la entrada (pin PD4) tenemos un 1, por lo tanto se enciende la bandera de acarreo y se desplaza HBYTE a la derecha. Entonces HBYTE=$C0 (11000000), debido a que HBYTE es diferente de $40 se reinicializa la secuencia (HBYTE=$00 y TEMP=$00), pero en esta ocasión también se reinicializa CONT con el valor CONT=196. De este modo se vuelve al paso 1 para esperar un preámbulo correcto.
[[CCOOMMUUNNIICCAACCIIÓÓNN AA NNIIVVEELL EENNLLAACCEE DDEE DDAATTOOSS EENNTTRREE MMIICCRROOCCOONNTTRROOLLAADDOORREESS CCOONN UUNNIIDDAADDEESS DDEE
RRAADDIIOOFFRREECCUUEENNCCIIAA]]
PPRROOYYEECCTTOO DDEE IINNGGEENNIIEERRÍÍAA EELLEECCTTRRÓÓNNIICCAA
UUNNIIVVEERRSSIIDDAADD AAUUTTÓÓNNOOMMAA MMEETTRROOPPOOLLIITTAANNAA IIZZTTAAPPAALLAAPPAA CCaarrllooss EErrnneessttoo MMoorreennoo EEssccoobbaarr 220011221144115599
‐ 53 ‐
Figura 8.3.1 Función ISR de ESPERA_PREAMBULO
Según el diagrama de flujo, si el primer bit que se recibe es 0 simplemente se regresa de la ISR sin hacer ninguna operación. Esto se ha realizado con la finalidad de que la ISR no pierda tiempo en procesar datos innecesarios. Por último, es importante mencionar que en las pruebas experimentales se han recibido preámbulos inválidos o que, incluso, alteren los datos recibidos. Pero este problema se soluciona fácilmente con la implementación de un CRC y un protocolo de comunicaciones. A continuación se muestran las subrutinas en lenguaje ensamblador.
PPRROOYYEECCTTOO DDEE IINNGGEENNIIEERRÍÍAA
EELLEECCTTRRÓÓNNIICCAA
[[CCOOMMUUNNIICCAACCIIÓÓNN AA NNIIVVEELL EENNLLAACCEE DDEE DDAATTOOSS EENNTTRREE MMIICCRROOCCOONNTTRROOLLAADDOORREESS CCOONN UUNNIIDDAADDEESS DDEE RRAADDIIOOFFRREECCUUEENNCCIIAA]]
UUNNIIVVEERRSSIIDDAADD AAUUTTÓÓNNOOMMAA MMEETTRROOPPOOLLIITTAANNAA IIZZTTAAPPAALLAAPPAA CCaarrllooss EErrnneessttoo MMoorreennoo EEssccoobbaarr 220011221144115599
‐ 54 ‐
RISE_DCLK: CPI MODO,MODORXPRE BREQ RX_PREAMBULO //ESPERA Y VALIDA PREAMBULO. . . /************************************************************************* * RECIBIR PREAMBULO *************************************************************************/ RX_PREAMBULO: CPI TEMP,$00 BREQ ESPERA1 SBIS PIND,DIO //SI PD4='1' CLC // CARRY FLAG='0' SBIC PIND,DIO //SI PD4='0' REGRESA: SEC // CARRY FLAG='1' ROR HBYTE //C->b7....b0->C INC TEMP CPI TEMP,$02 //SI TEMP=2 BREQ VALID_PRE // SATO A VALID_PRE DEC CONT //OTRO DEC CONT OUT SREG,S_REG RETI VALID_PRE: CPI HBYTE,$40 //HBYTE=$40? BREQ PRE_CORRECTO // PREAMBULO CORRECTO LDI CONT,CHIP //REINICIALIZAR CONTADOR CLR TEMP // TEMP CLR HBYTE // HBYTE OUT SREG,S_REG RETI PRE_CORRECTO: DEC CONT //DECREMENTA CONTADOR CLR HBYTE // LIMPIA HBYTE CLR TEMP // LIMPIA TEMP OUT SREG,S_REG RETI ESPERA1: SBIC PIND,DIO RJMP REGRESA OUT SREG,S_REG RETI /*************************************************************************** * FUNCION: * ESPERA_PREAMBULO ****************************************************************************/ ESPERA_PREAMBULO: LDI MODO,MODORXPRE //MODO: RECIBIR PREAMBULO LDI CONT,CHIP CBI DDRD,DIO //PD4 (DIO)COMO ENTRADA SBI PORTD,DIO LDI TEMP,1<<INTF0 OUT GIFR,TEMP //LIMPIA INTE. PENDIENTES LDI TEMP,1<<INT0 OUT GICR,TEMP //HABILITA INT. EXTERNA 0 CLR TEMP ESPERARXPRE: CPI ACUSE,$FF //TIMEOUT AGOTADO? BREQ FORZAR_SALIDA // ENTONCES FORZAR SALIDA PARA RETRANSMITIR CPI CONT,$00 //CONT='0'? BREQ SALIDA_WP // FIN DE LA SUBRUTINA RJMP ESPERARXPRE //CONTINUA TRANSMITIENDO
[[CCOOMMUUNNIICCAACCIIÓÓNN AA NNIIVVEELL EENNLLAACCEE DDEE DDAATTOOSS EENNTTRREE MMIICCRROOCCOONNTTRROOLLAADDOORREESS CCOONN UUNNIIDDAADDEESS DDEE
RRAADDIIOOFFRREECCUUEENNCCIIAA]]
PPRROOYYEECCTTOO DDEE IINNGGEENNIIEERRÍÍAA EELLEECCTTRRÓÓNNIICCAA
UUNNIIVVEERRSSIIDDAADD AAUUTTÓÓNNOOMMAA MMEETTRROOPPOOLLIITTAANNAA IIZZTTAAPPAALLAAPPAA CCaarrllooss EErrnneessttoo MMoorreennoo EEssccoobbaarr 220011221144115599
‐ 55 ‐
SALIDA_WP: SBI PORTA,0 RET FORZAR_SALIDA: RET
88..44..00 FFUUNNCCIIÓÓNN EENNVVIIAA__BBYYTTEE
Una vez que el preámbulo ha sido transmitido es el momento de enviar datos válidos. Esta subrutina envía un byte de información cargado previamente en el registro HBYTE. El principio del funcionamiento de la subrutina es el mismo que en los casos anteriores: primero, se identifica el modo para que la ISR realice la operación, posteriormente se habilita la interrupción externa INT0. Una vez que se encuentra en el bucle, la subrutina espera el flanco de subida de DCLK para transmitir bit a bit el byte.
Figura 8.4.0 Función ENVIA_BYTE
La forma de llamar a esta subrutina es la siguiente: RCALL ENVIA_PREAMBULO //PRIMERO ENVIA UN PREAMBULO LDI HBYTE,$AA //DATO A TRANSMITIR RCALL ENVIA_BYTE //ENVIA EL BYTE HACIA EL CC1000
La ISR de “ENVIA_BYTE” rota el registro HBYTE hacia la derecha, esto provoca que la bandera de acarreo se cargue con el ‘0’ o ‘1’ contenido en el bit menos significativo de HBYTE, dependiendo del valor de la bandera de acarreo se transmite un ‘1’ o un ‘0’. Esta operación se realiza ocho veces ya que únicamente se transmiten ocho bits de datos.
PPRROOYYEECCTTOO DDEE IINNGGEENNIIEERRÍÍAA
EELLEECCTTRRÓÓNNIICCAA
[[CCOOMMUUNNIICCAACCIIÓÓNN AA NNIIVVEELL EENNLLAACCEE DDEE DDAATTOOSS EENNTTRREE MMIICCRROOCCOONNTTRROOLLAADDOORREESS CCOONN UUNNIIDDAADDEESS DDEE RRAADDIIOOFFRREECCUUEENNCCIIAA]]
UUNNIIVVEERRSSIIDDAADD AAUUTTÓÓNNOOMMAA MMEETTRROOPPOOLLIITTAANNAA IIZZTTAAPPAALLAAPPAA CCaarrllooss EErrnneessttoo MMoorreennoo EEssccoobbaarr 220011221144115599
‐ 56 ‐
Figura 8.4.1 Función ISR ENVIA_BYTE
Nótese que primero se envía el bit menos significativo del byte. Una vez que el registro CONT es igual a cero, la subrutina ENVIA_BYTE regresa a la función principal. A continuación se muestran las subrutinas en lenguaje ensamblador.
RISE_DCLK: BREQ TX_DATO //TRANSMITIR BYTE CPI MODO,MODORXDAT . . . /************************************************************************* * TRANSMITIR BYTE *************************************************************************/ TX_DATO: //ENVIAR UN BIT A LA VEZ CADA FLANCO DE SUBIDA DE DCLK ROR HBYTE //ROTAR HBYTE BRCS ENVIA_D1 //CARRY FLAG='0' ? CBI PORTD,DIO // GENERA Y TX UN '1' DEC CONT //OTRO GENERA Y TX UN '0' OUT SREG,S_REG RETI ENVIA_D1: //SUBRUTINA PARA TX UN '1' SBI PORTD,DIO DEC CONT //DECREMENTAR CONTADOR OUT SREG,S_REG RETI /*************************************************************************** * FUNCION: * ENVIA_BYTE ****************************************************************************/
[[CCOOMMUUNNIICCAACCIIÓÓNN AA NNIIVVEELL EENNLLAACCEE DDEE DDAATTOOSS EENNTTRREE MMIICCRROOCCOONNTTRROOLLAADDOORREESS CCOONN UUNNIIDDAADDEESS DDEE
RRAADDIIOOFFRREECCUUEENNCCIIAA]]
PPRROOYYEECCTTOO DDEE IINNGGEENNIIEERRÍÍAA EELLEECCTTRRÓÓNNIICCAA
UUNNIIVVEERRSSIIDDAADD AAUUTTÓÓNNOOMMAA MMEETTRROOPPOOLLIITTAANNAA IIZZTTAAPPAALLAAPPAA CCaarrllooss EErrnneessttoo MMoorreennoo EEssccoobbaarr 220011221144115599
‐ 57 ‐
ENVIA_BYTE: LDI MODO,MODOTXDAT //MODO: TRANSMITIR BYTE LDI CONT,$08 //TRANSMITIR 8 BITS SBI DDRD,DIO //PD4 (DIO) SALIDA LDI TEMP,1<<INTF0 OUT GIFR,TEMP //LIMPIA INTE. PENDIENTES LDI TEMP,1<<INT0 OUT GICR,TEMP //HABILITA INT. EXTERNA 0 ESPERATXDAT: CPI CONT,$00 //CONT='0'? BREQ SALIDA_ED // FIN DE LA SUBRUTINA RJMP ESPERATXDAT //CONTINUA TRANSMITIENDO SALIDA_ED: RET
88..55..00 FFUUNNCCIIÓÓNN RREECCIIBBEE__BBYYTTEE
Una vez que se ha recibido el preámbulo válido, se pueden recibir datos válidos. Recordemos que el programa no se sale de la subrutina ESPERA_PREAMBULO hasta que un preámbulo válido sea recibido. Una vez que se ha salido de la subrutina ESPERA_PREAMBULO es momento de llamar a la subrutina RECIBE_BYTE. La forma de llamar a esta subrutina es la siguiente: RCALL ESPERA_PREAMBULO //ESPERA UN PREAMBULO VALIDO RCALL RECIBE_BYTE //RECIBE UN BYTE DEL CC1000 OUT PORTC,HBYTE //MUESTRA EL BYTE RECIBIDO
El byte recibido es almacenado en el registro HBYTE y está listo para ser procesado. Se puede observar que la figura 8.5.0 es similar a la 8.4.0 (ENVIA_BYTE) con la diferencia de que el pin PD4 del AVR se configura como entrada para recibir los datos.
Figura 8.5.0 Función RECIBE_BYTE
PPRROOYYEECCTTOO DDEE IINNGGEENNIIEERRÍÍAA
EELLEECCTTRRÓÓNNIICCAA
[[CCOOMMUUNNIICCAACCIIÓÓNN AA NNIIVVEELL EENNLLAACCEE DDEE DDAATTOOSS EENNTTRREE MMIICCRROOCCOONNTTRROOLLAADDOORREESS CCOONN UUNNIIDDAADDEESS DDEE RRAADDIIOOFFRREECCUUEENNCCIIAA]]
UUNNIIVVEERRSSIIDDAADD AAUUTTÓÓNNOOMMAA MMEETTRROOPPOOLLIITTAANNAA IIZZTTAAPPAALLAAPPAA CCaarrllooss EErrnneessttoo MMoorreennoo EEssccoobbaarr 220011221144115599
‐ 58 ‐
Figura 8.5.1 Función ISR RECIBE_BYTE
La ISR lee el estado del pin de entrada PD4 del AVR, si se tiene un nivel alto en este pin, se enciende la bandera de acarreo. Pero se tiene un nivel bajo la bandera de acarreo se apaga. Una vez que se ha realizado esto se rota el registro HBYTE para introducir bit a bit el dato recibido. Esto se ejecuta ocho veces ya que se reciben ocho bits de datos. El primer bit recibido entra por el bit HBYTE[7] y se va desplazando a la derecha hasta el bit HBYTE[0], una vez realizado esto en el registro HBYTE tenemos el dato recibido y es entonces cuando se sale de la subrutina RECIBE_BYTE. A continuación se muestran las subrutinas.
RISE_DCLK: //IDENTIFICACION DE LA OPERACIÓN CPI MODO,MODORXDAT BREQ RX_DATO //RECIBIR BYTE . . . /************************************************************************* * RECIBIR BYTE *************************************************************************/ RX_DATO: SBIS PIND,DIO //PD4='0' CLC // CARRY FLAG='0' SBIC PIND,DIO //PD='1' SEC // CARRY FLAG='1' ROR HBYTE //C->b7....b0->C DEC CONT OUT SREG,S_REG
[[CCOOMMUUNNIICCAACCIIÓÓNN AA NNIIVVEELL EENNLLAACCEE DDEE DDAATTOOSS EENNTTRREE MMIICCRROOCCOONNTTRROOLLAADDOORREESS CCOONN UUNNIIDDAADDEESS DDEE
RRAADDIIOOFFRREECCUUEENNCCIIAA]]
PPRROOYYEECCTTOO DDEE IINNGGEENNIIEERRÍÍAA EELLEECCTTRRÓÓNNIICCAA
UUNNIIVVEERRSSIIDDAADD AAUUTTÓÓNNOOMMAA MMEETTRROOPPOOLLIITTAANNAA IIZZTTAAPPAALLAAPPAA CCaarrllooss EErrnneessttoo MMoorreennoo EEssccoobbaarr 220011221144115599
‐ 59 ‐
RETI /*************************************************************************** * FUNCION: * RECIBE_BYTE ****************************************************************************/ RECIBE_BYTE: LDI MODO,MODORXDAT //MODO: RECIBIR BYTE LDI CONT,$08 //RECIBIT 8 BITS ESPERARXDAT: CPI CONT,$00 //CONT='0'? BREQ SALIDA_RD // FIN DE LA SUBRUTINA RJMP ESPERARXDAT //CONTINUA TRANSMITIENDO SALIDA_RD: RET
99..00 CCRRCC‐‐1166
A continuación se muestra la implementación del CRC‐16. La función CRC_GEN genera y verifica el checksum de una serie de datos. Antes de continuar, ¿a cuáles datos le vamos a generar el checksum?, Consideremos una trama de 128 bytes, donde el primer byte es el número de secuencia de la trama y el segundo es un campo de información, estos dos bytes serán utilizados para la implementación del protocolo Stop and Wait. Los 126 bytes restantes son para datos. Los 128 bytes deben ser almacenados en la memoria RAM del AVR. Una vez que se ha calculado el checksum resultante, el cual será de dos bytes. Éstos se almacenarán en la última dirección de la RAM (después de los datos). Entonces la trama que va a ser transmitida será de 130 bytes como se muestra en la siguiente figura.
Figura 9.0.0 Formato de la trama en la memoria RAM
A continuación se muestra el programa principal para la generación y la verificación del checksum, el checksum es almacenado en la RAM al final de los datos. Para la verificación del checksum se debe leer de la RAM el checksum recibido.
PPRROOYYEECCTTOO DDEE IINNGGEENNIIEERRÍÍAA
EELLEECCTTRRÓÓNNIICCAA
[[CCOOMMUUNNIICCAACCIIÓÓNN AA NNIIVVEELL EENNLLAACCEE DDEE DDAATTOOSS EENNTTRREE MMIICCRROOCCOONNTTRROOLLAADDOORREESS CCOONN UUNNIIDDAADDEESS DDEE RRAADDIIOOFFRREECCUUEENNCCIIAA]]
UUNNIIVVEERRSSIIDDAADD AAUUTTÓÓNNOOMMAA MMEETTRROOPPOOLLIITTAANNAA IIZZTTAAPPAALLAAPPAA CCaarrllooss EErrnneessttoo MMoorreennoo EEssccoobbaarr 220011221144115599
‐ 60 ‐
Figura 9.0.1 Diagrama de flujo del programa principal de CRC_GEN
El programa principal llama a la subrutina CRC_GEN con el registro MODO=$00 para generar el checksum. Para la verificación del checksum, el registro MODO es cualquier valor diferente de $00. Es de gran importancia mencionar que todos los bytes recibidos son almacenados temporalmente en un buffer, el buffer comienza de la dirección $60 y finaliza en la $E1. La tarea de este buffer es almacenar los datos en una localidad diferente para que los datos erróneos no sobrescriban los datos correctos.
99..11..00 GGEENNEERRAARR
CCHHEECCKKSSUUMM
Esta operación está basada en rotar bit a bit el contenido de la memoria RAM (de la dirección $60 a la $E0) ver figura 9.0.0. El bit más significativo es desplazado dentro de la bandera de acarreo. Si la bandera de acarreo es 1, a la palabra se le aplica la operación XOR con el polinomio divisor. Al final de los datos se anexan 16 ceros. El checksum es el resultado de la realizar la operación XOR completamente.
99..22..00 VVEERRIIFFIICCAARR CCHHEECCKKSSUUMM
Los mismos principios son utilizados para la verificación pero el checksum recibido es anexado a los datos, remplazando los ceros. Si el resultado del cálculo es cero, entonces los datos no contienen errores, para cualquier otro valor, los datos contienen errores. La misma rutina es utilizada para la verificación del checksum, cuando el registro MODO es cargado con un valor diferente de $00 y la función es llamada, entonces se realizará la verificación del checksum. La figura9.2.0 muestra el diagrama de flujo de la función CRC_GEN.
[[CCOOMMUUNNIICCAACCIIÓÓNN AA NNIIVVEELL EENNLLAACCEE DDEE DDAATTOOSS EENNTTRREE MMIICCRROOCCOONNTTRROOLLAADDOORREESS CCOONN UUNNIIDDAADDEESS DDEE
RRAADDIIOOFFRREECCUUEENNCCIIAA]]
PPRROOYYEECCTTOO DDEE IINNGGEENNIIEERRÍÍAA EELLEECCTTRRÓÓNNIICCAA
UUNNIIVVEERRSSIIDDAADD AAUUTTÓÓNNOOMMAA MMEETTRROOPPOOLLIITTAANNAA IIZZTTAAPPAALLAAPPAA CCaarrllooss EErrnneessttoo MMoorreennoo EEssccoobbaarr 220011221144115599
‐ 61 ‐
Figura 9.2.0 Subrutina CRC_GEN
La figura 9.2.1 muestra la subrutina encargada de rotar las palabras bit a bit.
PPRROOYYEECCTTOO DDEE IINNGGEENNIIEERRÍÍAA
EELLEECCTTRRÓÓNNIICCAA
[[CCOOMMUUNNIICCAACCIIÓÓNN AA NNIIVVEELL EENNLLAACCEE DDEE DDAATTOOSS EENNTTRREE MMIICCRROOCCOONNTTRROOLLAADDOORREESS CCOONN UUNNIIDDAADDEESS DDEE RRAADDIIOOFFRREECCUUEENNCCIIAA]]
UUNNIIVVEERRSSIIDDAADD AAUUTTÓÓNNOOMMAA MMEETTRROOPPOOLLIITTAANNAA IIZZTTAAPPAALLAAPPAA CCaarrllooss EErrnneessttoo MMoorreennoo EEssccoobbaarr 220011221144115599
‐ 62 ‐
Figura 9.2.1 Subrutina ROT_WORD
El código de esta rutina se muestra a continuación
/***************************************************************************** *********** F U N C I O N E S P A R A E L C R C - 1 6 ******************* ******************************************************************************/ .EQU LAST_RAM_ADDR = 0X00DF //DIRECCIÓN DEL ULTIMO DATO (128 BYTES) .EQU FIRST_RAM_ADDR = 0X0060 //INICIO DE LA RAM .EQU POLY = 0X8005 //POLINOMIO DEL CRC .DEF CRC =R0 // CRC CHECKSUM BYTE BAJO .DEF CRCH =R1 // CRC CHECKSUM BYTE ALTO .DEF SIZEL =R16 // TAMAÑO DE LOS DATOS EN RAM BYTE BAJO .DEF SIZEH =R17 // TAMAÑO DE LOS DATOS EN RAM BYTE ALTO .DEF CRDIVH =R18 .DEF CRDIVL =R19 /*************************************************************************** * * FUNCION: * "CRC_GEN" - GENERAR Y VERIFICAR EL CHECKSUM DEL CRC **************************************************************************/ CRC_GEN: LDI XL,LOW(LAST_RAM_ADDR) //APUNTADOR A LA ULTIMA DIRECCION DE LOS DATOS LDI XH,HIGH(LAST_RAM_ADDR) ADIW XL,0X01 //INCREMENTAR APUNTADOR X LD CRC,X+ //CARGAR EL BYTE BAJO DEL CHECKSUM EN REGISTRO LD CRCH,X LDI SIZEL,LOW(LAST_RAM_ADDR) //CARGAR LA ULTIMA DIRECCION DE LOS DATOS LDI SIZEH,HIGH(LAST_RAM_ADDR) LDI XL,LOW(FIRST_RAM_ADDR) //APUNTADORES A INICIO DE LA RAM
[[CCOOMMUUNNIICCAACCIIÓÓNN AA NNIIVVEELL EENNLLAACCEE DDEE DDAATTOOSS EENNTTRREE MMIICCRROOCCOONNTTRROOLLAADDOORREESS CCOONN UUNNIIDDAADDEESS DDEE
RRAADDIIOOFFRREECCUUEENNCCIIAA]]
PPRROOYYEECCTTOO DDEE IINNGGEENNIIEERRÍÍAA EELLEECCTTRRÓÓNNIICCAA
UUNNIIVVEERRSSIIDDAADD AAUUTTÓÓNNOOMMAA MMEETTRROOPPOOLLIITTAANNAA IIZZTTAAPPAALLAAPPAA CCaarrllooss EErrnneessttoo MMoorreennoo EEssccoobbaarr 220011221144115599
‐ 63 ‐
LDI XH,HIGH(FIRST_RAM_ADDR) LDI CRDIVH,HIGH(POLY) //CARGAR EL POLINOMIO LDI CRDIVL,LOW(POLY) LD BYTE_0,X //CARGAR EL PRIMER DATO DE LA RAM MOV BYTE_3,BYTE_0 //MOVERLO AL BYTE MAS ALTO ADIW XL,0X01 //INCREMENTAR APUNTADOR X LD BYTE_0,X //CARGAR EL SEGUNDO DATO DE LA RAM MOV BYTE_2,BYTE_0 NEXT_BYTE: CP XL,SIZEL //COMIENZO DEL CICLO CPC XH,SIZEH //VERIFICAR SI ES LA ULTIMA DIR. BRGE END //SALTA SI ES LA ULTIMA DIRECC. ADIW XL,0X01 LD BYTE_0,X //CARGA EL BYTE MAS ALTO MOV BYTE_1,BYTE_0 //MOVERLO AL BYTE ALTO ADIW XL,0X01 //INCREMENTAR APUNTADOR X LD BYTE_0,X //CARGAR EL DATO CONTENIDO EN RAM RCALL ROT_WORD //LLAMAR A RUTINA ROTAR PALABRA RJMP NEXT_BYTE END: LDI CONT,0X11 CPI MODO,0X00 BRNE CHECK CLR BYTE_0 //CONCATENAR 16 BITS (0X0000) AL CLR BYTE_1 //FINAL DE LOS DATOS PARA LA GENERACION CRC RJMP GEN CHECK: MOV BYTE_0,CRC //CONCATENAR EL CHECKSUM ORIGINAL MOV BYTE_1,CRCH //AL FINAL DE LOS DATOS PARA CHEQUEO DE CRC GEN: RCALL ROT_WORD //LLAMAR A RUTINA ROTAR PALABRA MOV CRC,BYTE_2 MOV CRCH,BYTE_3 LDI XL,LOW(LAST_RAM_ADDR) //APUNTADOR A LA ULTIMA DIRECCION DE LOS DATOS LDI XH,HIGH(LAST_RAM_ADDR) ADIW XL,0X01 //INCREMENTAR APUNTADOR X ST X+,CRC //ALMACENAR EL BYTE BAJO DEL CHECKSUM EN LA RAM ST X,CRCH RET //REGRESO DE SUBRUTINA ROT_WORD: LDI CONT,0X11 ROT_LOOP: DEC CONT //DECREMENTAR CONTADOR BREQ STOP //SALIR SI COUNTADOR = 0 LSL BYTE_0 //DESPLAZAR UN '0' DENTRO DEL BIT MENOR ROL BYTE_1 //DESPLAZAR EN ACARREO EL BYTE PREVIO ROL BYTE_2 //CONTINUA DESPLAZANDO ROL BYTE_3 BRCC ROT_LOOP //LOOP SI MSB = 0 EOR BYTE_2,CRDIVL EOR BYTE_3,CRDIVH //XOR PALABRA ALTA SI MSB = 1 RJMP ROT_LOOP STOP: RET
1100..00 SSTTOOPP AANNDD WWAAIITT
La implementación del protocolo Stop and Wait no es más que una aplicación de todas las funciones anteriores. Por ejemplo, para realizar una función que envíe una trama de datos de 128 bytes es necesario utilizar la función que envíe, en primera estancia, un preámbulo balanceado (ENVIA_PREAMBULO), posteriormente 1 byte para identificación de la secuencia (protocolo de bit alternante), 1 byte de información para indicar si se trata de datos o acuse y finalmente los 126 bytes de datos (ENVIA_BYTE). También a la trama debe
PPRROOYYEECCTTOO DDEE IINNGGEENNIIEERRÍÍAA
EELLEECCTTRRÓÓNNIICCAA
[[CCOOMMUUNNIICCAACCIIÓÓNN AA NNIIVVEELL EENNLLAACCEE DDEE DDAATTOOSS EENNTTRREE MMIICCRROOCCOONNTTRROOLLAADDOORREESS CCOONN UUNNIIDDAADDEESS DDEE RRAADDIIOOFFRREECCUUEENNCCIIAA]]
UUNNIIVVEERRSSIIDDAADD AAUUTTÓÓNNOOMMAA MMEETTRROOPPOOLLIITTAANNAA IIZZTTAAPPAALLAAPPAA CCaarrllooss EErrnneessttoo MMoorreennoo EEssccoobbaarr 220011221144115599
‐ 64 ‐
agregarse el checksum computado por el transmisor (CRC_GEN). A continuación se muestra el formato de la trama que vamos a utilizar para el diseño del protocolo Stop and Wait.
Figura 10.0.0 Formato de la trama para Tx y Rx.
De la figura 10.0.0 se observa que la trama es de 130 bytes más un preámbulo balanceado. El protocolo Stop and Wait requiere de una trama adicional para la transmisión del acuse. El formato es el siguiente: 196 bits de preámbulo, 1 byte de secuencia (el cual es una copia del número de secuencia recibida), 1 byte de información y el CRC del acuse. En total son 4 bytes más el preámbulo. La figura 10.0.1 nos muestra el formato de la trama del acuse.
Figura 10.0.0 Formato de la trama para el acuse.
Cabe mencionar que en esta implementación el acuse negativo (NACK) es simplemente no enviar respuesta, para que el transmisor reenvíe la trama de datos.
1100..11..00 FFUUNNCCIIÓÓNN SSTTAARRTT__TTIIMMEERR
La implementación completa del protocolo Stop and Wait requiere un contador (timeout) para evitar la pérdida de paquetes (ver sección 3.0). Esta función configura el timer counter 1 del AVR. A continuación se muestra una tabla con los tiempos que requiere cada subrutina para calcular el timeout.
Subrutina Ciclos Tiempo @ 8MHz ClockTURNONRX 24996 3.12 mS TURNOFFRX 770 96.25 uS TURNONTX 25394 3.17 mS TURNOFFTX 768 96.00 uS ENVIA_PREAMBULO ‐ 5.10 mS RECIBE_PREAMBULO ‐ 5.10 mS ENVIA_BYTE ‐ 208.33 uS RECIBE_BYTE ‐ 208.33 uS CRC_GEN (generar checksum) 11517 1.43 mS CRC_GEN (verificar checksum) 11519 1.44 mS
NOTA: el tiempo que toma enviar/recibir el preámbulo y enviar/recibir un byte fueron calculados con la velocidad de transmisión a la que está configurado el CC1000. Es fácil encontrarlo mediante una la siguiente fórmula.
Donde: es el número total de bits por transmisión. es la velocidad de transmisión (p.e. 38400bps)
Ejemplo: queremos encontrar el tiempo que requiere la transmisión/recepción del preámbulo (196 bits).
[[CCOOMMUUNNIICCAACCIIÓÓNN AA NNIIVVEELL EENNLLAACCEE DDEE DDAATTOOSS EENNTTRREE MMIICCRROOCCOONNTTRROOLLAADDOORREESS CCOONN UUNNIIDDAADDEESS DDEE
RRAADDIIOOFFRREECCUUEENNCCIIAA]]
PPRROOYYEECCTTOO DDEE IINNGGEENNIIEERRÍÍAA EELLEECCTTRRÓÓNNIICCAA
UUNNIIVVEERRSSIIDDAADD AAUUTTÓÓNNOOMMAA MMEETTRROOPPOOLLIITTAANNAA IIZZTTAAPPAALLAAPPAA CCaarrllooss EErrnneessttoo MMoorreennoo EEssccoobbaarr 220011221144115599
‐ 65 ‐
Recordemos que para este diseño en particular se está trabajando a una velocidad de transmisión de 38400bps. Esta velocidad de transmisión es la velocidad máxima permitida por el CC1000, si ésta es alterada (disminuida), se necesita calcular nuevamente el tiempo de transmisión.
196 38400 5.1
El tiempo de propagación puede ser calculado fácilmente por la siguiente fórmula:
Donde: = distancia máxima entre nodos (m)
= Velocidad de propagación de la onda en el aire (m/s)
es aproximadamente la velocidad de la luz, utilizaremos: 3 10 /
303 10 / 0.1
El timer arranca una vez que el transmisor ha enviado toda la trama. Mediante el siguiente diagrama de tiempos podemos observar el procedimiento de recepción de la trama y de este modo encontrar el timeout requerido.
Figura 10.1.0 Diagrama de tiempos de la recepción.
De la figura 10.1.0 podemos observar que el receptor requiere un tiempo mínimo de 43.25 mS para procesar los datos recibidos y enviar el acuse. Aún así, le podemos dar cierta tolerancia a este tiempo para evitar conteos prematuros. Démosle un 20% de tolerancia al tiempo calculado.
43.25 1.20 51.91 Ya que tenemos definido el tiempo de espera (timeout), podemos configurar el timer counter 1 para la generación del timeout. En primera estancia, el preescalador utilizado será clk/1024, el reloj del AVR es de 8 MHz.
8 101024 7812.5
PPRROOYYEECCTTOO DDEE IINNGGEENNIIEERRÍÍAA
EELLEECCTTRRÓÓNNIICCAA
[[CCOOMMUUNNIICCAACCIIÓÓNN AA NNIIVVEELL EENNLLAACCEE DDEE DDAATTOOSS EENNTTRREE MMIICCRROOCCOONNTTRROOLLAADDOORREESS CCOONN UUNNIIDDAADDEESS DDEE RRAADDIIOOFFRREECCUUEENNCCIIAA]]
UUNNIIVVEERRSSIIDDAADD AAUUTTÓÓNNOOMMAA MMEETTRROOPPOOLLIITTAANNAA IIZZTTAAPPAALLAAPPAA CCaarrllooss EErrnneessttoo MMoorreennoo EEssccoobbaarr 220011221144115599
‐ 66 ‐
1 17812.5 128
El tiempo nos indica que el contador del AVR se va incrementando cada 128 us. Ahora, necesitamos que se genere la interrupción cada 51.91 mseg. Mediante un cálculo sencillo podemos identificar qué valor debe cargarse al registro de comparación del timer counter 1.
1 128 51.91
51.91
128 405.57
El número 405.57 es el valor con el que debe cargarse el registro de comparación del timer counter 1. El número 406 en hexadecimal es $196. El timer counter 1 es de 2 bytes por lo que se debe cargar en el registro alto $01 y en el registro bajo $96. A continuación se muestran las constantes globales utilizadas para cargar el valor de los registros de comparación del timer counter 1.
.EQU OCBL = $96
.EQU OCBH = $01 La forma de llamar a esta función es la siguiente:
RCALL START_TIMER Una vez definido el timeout y el valor de los registros la función para arrancar el timer se configura de la siguiente manera: NOTA: El timer counter se inicia únicamente cuando se espera el acuse de recibo. Para cualquier otra aplicación el timer counter 1 no es utilizado (VER RECIBE_ACUSE EN LA SECCIÓN 10.4 ).
.ORG OC1Baddr RJMP TIMEOUT TIMEOUT: //ISR TIMEOUT IN S_REG,SREG SER ACUSE OUT SREG,S_REG RETI .EQU OCBL = $96 .EQU OCBH = $01 .EQU TIMERPRE = $05 // PREESCALADOR CLK/1024=$05 START_TIMER: LDI TEMP,OCBH OUT OCR1BH,TEMP //CARGAR PALABRA BAJA EN REG. DE COMPARACION LDI TEMP,OCBL OUT OCR1BL,TEMP //CARGAR PALABRA ALTA EN REG. DE COMPARACION LDI TEMP,1<<OCF1B //LIMPIAR BANDERAS PENDIENTES (SOLO POR... OUT TIFR,TEMP // ...PRECAUCION) LDI TEMP,1<<OCIE1B OUT TIMSK,TEMP // Y POR ULTIMO... HABILITAR INTERRUPCION... CLR TEMP
[[CCOOMMUUNNIICCAACCIIÓÓNN AA NNIIVVEELL EENNLLAACCEE DDEE DDAATTOOSS EENNTTRREE MMIICCRROOCCOONNTTRROOLLAADDOORREESS CCOONN UUNNIIDDAADDEESS DDEE
RRAADDIIOOFFRREECCUUEENNCCIIAA]]
PPRROOYYEECCTTOO DDEE IINNGGEENNIIEERRÍÍAA EELLEECCTTRRÓÓNNIICCAA
UUNNIIVVEERRSSIIDDAADD AAUUTTÓÓNNOOMMAA MMEETTRROOPPOOLLIITTAANNAA IIZZTTAAPPAALLAAPPAA CCaarrllooss EErrnneessttoo MMoorreennoo EEssccoobbaarr 220011221144115599
‐ 67 ‐
OUT TCNT1H,TEMP //INICIALIZAR TIMER COUNTER 1 (PALABRA.. OUT TCNT1l,TEMP // ..ALTA Y PALABRA BAJA) LDI TEMP,TIMERPRE //AJUSTAR EL PREESCALADOR DEL TIMER COUNTER OUT TCCR1B,TEMP RET
Una vez que el timer counter llega a su cuenta máxima, se genera la interrupción, la cual únicamente carga el registro ACUSE con el valor $FF, este valor es utilizado en una encuesta para identificar que el timeout se ha agotado. Regresemos a la figura 8.3.0 “ESPERA_PREAMBULO”. El bloque “TIMEOUT END?”, realiza la encuesta para identificar si el timeout se ha agotado. Mediante este bloque forzamos la salida de la subrutina y comienza la retransmisión. (Ver RECIBE_ACUSE en la sección 10.4).
1100..22..00 FFUUNNCCIIÓÓNN SSTTOOPP__TTIIMMEERR
La función STOP_TIMER únicamente detiene el conteo del timer counter 1 y deshabilita la interrupción. Esta función es llamada cuando se ha recibido el acuse correctamente. (Ver RECIBE_ACUSE en la sección 10.4). La subrutina se muestra a continuación.
STOP_TIMER: CLR TEMP //DESHABILITAR EL PREESCALADOR OUT TCCR1B,TEMP LDI TEMP,1<<OCF1B //LIMPIAR BANDERAS PENDIENTES OUT TIFR,TEMP LDI TEMP,0<<OCIE1B //DESHABILITAR INTERRUPCIÓN OUT TIMSK,TEMP RET
1100..33..00 FFUUNNCCIIÓÓNN EENNVVIIAA__TTRRAAMMAA
La función ENVIA_TRAMA envía una trama de 130 bytes. Como se ha mencionado antes, 1 byte para la secuencia, 1 byte para información, 126 bytes de datos y dos bytes de CRC más el preámbulo. Esta rutina emplea todas las funciones diseñadas anteriormente. Antes de llamar a esta rutina, los datos a transmitir deben estar almacenados en la memoria RAM. El campo para los datos comienzan desde la dirección $62 a la $E0. Una vez que los datos son almacenados en la RAM cuando esta subrutina es llamada,
PPRROOYYEECCTTOO DDEE IINNGGEENNIIEERRÍÍAA
EELLEECCTTRRÓÓNNIICCAA
[[CCOOMMUUNNIICCAACCIIÓÓNN AA NNIIVVEELL EENNLLAACCEE DDEE DDAATTOOSS EENNTTRREE MMIICCRROOCCOONNTTRROOLLAADDOORREESS CCOONN UUNNIIDDAADDEESS DDEE RRAADDIIOOFFRREECCUUEENNCCIIAA]]
UUNNIIVVEERRSSIIDDAADD AAUUTTÓÓNNOOMMAA MMEETTRROOPPOOLLIITTAANNAA IIZZTTAAPPAALLAAPPAA CCaarrllooss EErrnneessttoo MMoorreennoo EEssccoobbaarr 220011221144115599
‐ 68 ‐
Figura 10.3.0 Rutina ENVIA_TRAMA
primero se genera el byte de secuencia, el cual se almacena en la localidad $60 de la RAM. Posteriormente, se crea el campo de información que es almacenado en la localidad $61. Una vez que se tienen todos los datos en la RAM, se genera el checksum, el cual es almacenado en las direcciones $E1 y $E2 (después de los datos). Ya que tenemos toda la trama, primero se envía el preámbulo y posteriormente los 130 bytes de datos. Después de que se hayan transmitido todos los bytes, se desactiva la transmisión y se llama a la función “RECIBE_ACUSE”. La cual configura el CC1000 como receptor y espera el acuse de recibo. Si el timeout es agotado, la función RECIBE_ACUSE regresa el registro ACUSE con el valor
[[CCOOMMUUNNIICCAACCIIÓÓNN AA NNIIVVEELL EENNLLAACCEE DDEE DDAATTOOSS EENNTTRREE MMIICCRROOCCOONNTTRROOLLAADDOORREESS CCOONN UUNNIIDDAADDEESS DDEE
RRAADDIIOOFFRREECCUUEENNCCIIAA]]
PPRROOYYEECCTTOO DDEE IINNGGEENNIIEERRÍÍAA EELLEECCTTRRÓÓNNIICCAA
UUNNIIVVEERRSSIIDDAADD AAUUTTÓÓNNOOMMAA MMEETTRROOPPOOLLIITTAANNAA IIZZTTAAPPAALLAAPPAA CCaarrllooss EErrnneessttoo MMoorreennoo EEssccoobbaarr 220011221144115599
‐ 69 ‐
$FF, el cual nos indica que el timeout se ha agotado.El registro ACUSE también es utilizado como una bandera para indicar que el acuse de recibo contiene errores o el número de secuencia es erróneo. Para cualquiera de estos casos se requiere la retransmisión de la trama. La subrutina se llama de la siguiente forma: /*ALMACENAR DATOS EN RAM ANTES DE…*/ RCALL ENVIA_TRAMA
ENVIA_TRAMA: LDI XL,LOW(FIRST_RAM_ADDR) //INICIAR APUNTADORES A RAM (DATOS A LDI XH,HIGH(FIRST_RAM_ADDR) INC SEQ //GENERAR SECUENCIA $FF O $00 SBRS SEQ,0 // UTILIZANDO EL REGISTRO SEQ CLR TEMP //GENERAR SEQ. $00 SBRC SEQ,0 SER TEMP //GENERAR SEQ. $FF ST X+,TEMP //ALMACENAR SECUENCIA EN LA LOCALIDAD $0060 DE LA RAM SER TEMP ST X+,TEMP //INTRODUCIR INFORMACION ($00=DATOS, $FF=ACUSE) //AQUI SOLO SE TRANSMITE EL DATO $00 CLR MODO //LIMPIAR REGISTRO MODO, PREPARAR GENERACION DEL CRC RCALL CRC_GEN //OBTENER CHECKSUM DE LOS DATOS ALMACENADOS EN RAM RETRANSMITIR:
RCALL TURNONTX //ACTIVAR MODO TRANSMISION LDI HBYTE,0B11000111 //ENVIA PREAMBULO
RCALL ENVIA_BYTE RCALL ENVIA_PREAMBULO LDI XL,LOW(FIRST_RAM_ADDR) //INICIAR APUNTADORES A RAM (DATOS A LDI XH,HIGH(FIRST_RAM_ADDR) // TRANSMITIR) TX_TRAMA: //ETAPA DE TRANSMISIÓN LD HBYTE,X+ //CARGAR HBYTE CON EL CONTENIDO DE X RCALL ENVIA_BYTE // Y TRANSMITIR EL DATO CPI XL,LOW(LAST_RAM_ADDR)+3 BRNE TX_TRAMA // DATOS TRANSMITIDOS? LDI TEMP,0<<INT0 // NO, REGRESA OUT GICR,TEMP //DESHABILITA INT. EXTERNA 0 RCALL TURNOFFTX RCALL RECIBE_ACUSE //LLAMADO A FUNCION PARA RECIBIR ACUSE CPI ACUSE,$FF //FINALIZÓ EL TIME OUT Y NO RECIBE ACUSE... //... O EL ACUSE ESTA DAÑADO? BREQ RETRANSMITIR // SI, ENONCES RETRANSMITE RET // OTRO, REGRESA
1100..44..00 FFUUNNCCIIÓÓNN RREECCIIBBEE__AACCUUSSEE
Una vez que se ha transmitido la trama de 130 bytes, se llama a la función“RECIBE_ACUSE”, esta subrutina configura el CC1000 como receptor para esperar el acuse de recibo positivo (ACK). Esta subrutina espera un preámbulo válido y 4 bytes correspondientes al acuse: 1 byte de secuencia (el cual es una copia de la secuencia recibida), 1 byte de información y dos bytes de CRC‐16. Antes de llamar a la función ESPERA_PREAMBULO se inicializa el timer counter 1 mediante el llamado de la función START_TIMER. Si el contador llega a su cuenta máxima y no se ha recibido el acuse, se atiende a la ISR donde el registro ACUSE es cargado con el valor $FF. Cuando el registro ACUSE contiene $FF se regresa de la subrutina RECIBE_ACUSE, si observamos la figura 10.3.0, el registro ACUSE es validado para considerar una
PPRROOYYEECCTTOO DDEE IINNGGEENNIIEERRÍÍAA
EELLEECCTTRRÓÓNNIICCAA
[[CCOOMMUUNNIICCAACCIIÓÓNN AA NNIIVVEELL EENNLLAACCEE DDEE DDAATTOOSS EENNTTRREE MMIICCRROOCCOONNTTRROOLLAADDOORREESS CCOONN UUNNIIDDAADDEESS DDEE RRAADDIIOOFFRREECCUUEENNCCIIAA]]
UUNNIIVVEERRSSIIDDAADD AAUUTTÓÓNNOOMMAA MMEETTRROOPPOOLLIITTAANNAA IIZZTTAAPPAALLAAPPAA CCaarrllooss EErrnneessttoo MMoorreennoo EEssccoobbaarr 220011221144115599
‐ 70 ‐
retransmisión.En esta subrutina también se verifica el estado del acuse de recibo (como el número de secuencia y el CRC). Si existen errores en los datos, entonces también es necesario forzar la retransmisión. Esto se logra cargando manualmente el registro ACUSE con $FF. Ahora, si el acuse es recibido correctamente y en el tiempo estimado, el registro ACUSE permanece con el valor $00. Esto es una bandera para indicar que la trama se ha recibido correctamente. En la figura 10.4.0 podemos observar el diagrama de flujo de la subrutina ESPERA_ACUSE.
Figura 10.4.0 Subrutina RECIBE_ACUSE
NOTA: El CRC del acuse de recibo puede ser precalculado, ya que únicamente tenemos dos combinaciones posibles. Esto nos ahorra memoria programa y tiempo de cálculo. El campo de información del acuse siempre es 11111111 (00000000 para datos y 11111111
[[CCOOMMUUNNIICCAACCIIÓÓNN AA NNIIVVEELL EENNLLAACCEE DDEE DDAATTOOSS EENNTTRREE MMIICCRROOCCOONNTTRROOLLAADDOORREESS CCOONN UUNNIIDDAADDEESS DDEE
RRAADDIIOOFFRREECCUUEENNCCIIAA]]
PPRROOYYEECCTTOO DDEE IINNGGEENNIIEERRÍÍAA EELLEECCTTRRÓÓNNIICCAA
UUNNIIVVEERRSSIIDDAADD AAUUTTÓÓNNOOMMAA MMEETTRROOPPOOLLIITTAANNAA IIZZTTAAPPAALLAAPPAA CCaarrllooss EErrnneessttoo MMoorreennoo EEssccoobbaarr 220011221144115599
‐ 71 ‐
para acuse). El primer CRC cuando se ha recibido la secuencia:
Figura 10.4.1 ACUSE 1 Es 00000010 00000010 ($0202) El segundo CRC cuando se ha recibido la secuencia:
Figura 10.4.2 ACUSE 2
Es 00001101 10000000 ($0D80). Una vez que sabemos cuáles son los CRC asociados a los dos diferentes acuses de recibo. La función RECIBE_ACUSE únicamente necesita comparar el byte alto del CRC con constantes almacenadas en el programa para verificar el estado del acuse.
Figura 10.4.2 Acuses de recibo posibles
Si el CRC es diferente para cualquiera de los dos casos, entonces el acuse contiene errores y se requiere retransmisión. OTRA NOTA: en esta implementación los acuses de recibo negativos (NACK) no existen, si la trama contiene errores el receptor no envía nada y espera retransmisión cuando el timeout finalice.
RECIBE_ACUSE: SBI PORTA,ESPERAACUSE //ENCIENDE BANDERA: "ESPERANDO ACUSE" RCALL TURNONRX //ENCIENDE TRANSMISIÓN RCALL START_TIMER //INICIA TIMEOUT CLR ACUSE //LIMPIA BANDERA DE TIME OUT RCALL ESPERA_PREAMBULO //ESPERA PREAMBULO DEL ACUSE RCALL RECIBE_BYTE // RECIBE SECUENCIA ENVIADA MOV BYTE_0,HBYTE RCALL RECIBE_BYTE // RECIBE TIPO (ACUSE=$FF) MOV BYTE_1,HBYTE RCALL RECIBE_BYTE // RECIBE CRC BYTE BAJO MOV BYTE_2,HBYTE RCALL RECIBE_BYTE // RECIBE CRC BYTE ALTO MOV BYTE_3,HBYTE RCALL STOP_TIMER // ACUSE RECIBIDO, DETENER CONTADOR LDI TEMP,0<<INT0 //DESHABILITAR INT0 OUT GICR,TEMP RCALL TURNOFFRX CPI ACUSE,$FF //TIEMPO AGOTADO? BREQ ACK_ERROR // FORZAR SALIDA PARA RETRANSMITIR // PRIMERO VERIFICAR EL CRC DEL ACUSE // CON EL BYTE ALTO ES SUFICIENTE LDI TEMP,SEQ2CH
PPRROOYYEECCTTOO DDEE IINNGGEENNIIEERRÍÍAA
EELLEECCTTRRÓÓNNIICCAA
[[CCOOMMUUNNIICCAACCIIÓÓNN AA NNIIVVEELL EENNLLAACCEE DDEE DDAATTOOSS EENNTTRREE MMIICCRROOCCOONNTTRROOLLAADDOORREESS CCOONN UUNNIIDDAADDEESS DDEE RRAADDIIOOFFRREECCUUEENNCCIIAA]]
UUNNIIVVEERRSSIIDDAADD AAUUTTÓÓNNOOMMAA MMEETTRROOPPOOLLIITTAANNAA IIZZTTAAPPAALLAAPPAA CCaarrllooss EErrnneessttoo MMoorreennoo EEssccoobbaarr 220011221144115599
‐ 72 ‐
CP TEMP, BYTE_3 //CRC BYTE ALTO DE LA SEC. 2 CORRECTO? BREQ VERIF_SEQ LDI TEMP,SEQ1CH CP TEMP, BYTE_3 //CRC BYTE ALTO DE LA SEC. 1 CORRECTO? BREQ VERIF_SEQ RJMP ACK_ERROR // DESPUES VERIFICAR LA SECUENCIA DEL ACUSE, // DEBE SER IGUAL A LA TRANSMITIDA VERIF_SEQ: LDI XL,LOW(FIRST_RAM_ADDR) //INICIAR APUNTADORES A RAM LDI XH,HIGH(FIRST_RAM_ADDR) //CARGAR BYTE DE SECUENCIA TRANSMITIDA LD TEMP,X // DE LA LOCALIDAD $0060 CP TEMP,BYTE_0 BRNE ACK_ERROR //LISTO! ACUSE VÁLIDO ACK_CRC_OK: CBI PORTA,ESPERAACUSE //APAGAR BANDERA: "ESPERANDO ACUSE" RET //ERROR EN EL ACUSE ACK_ERROR: // ACUSE CON ERRORES O SECUENCIA ILEGAL? SER ACUSE // ACUSE=$FF (FORZAR RETRANSMISIÓN) CBI PORTA,ESPERAACUSE //APAGAR BANDERA: "ESPERANDO ACUSE" RET
1100..55..00 FFUUNNCCIIÓÓNN RREECCIIBBEE__TTRRAAMMAA
La función RECIBE_TRAMA espera un preámbulo más una trama de 130 bytes. Todos los datos recibidos son almacenados temporalmente en el buffer (memoria RAM de $0060 a la $00E1), independientemente si los datos contienen errores o no. Una vez que estos datos están almacenados en el buffer temporal, se verifica el checksum del CRC. Si éste no es correcto, entonces se realiza el salto para comenzar a recibir otra vez la trama. Una vez que el cómputo del CRC sea correcto, entonces es el momento de verificar que es la secuencia de trama esperada (o sea que hay verificar si no se trata de una trama duplicada). Para verificar si se trata de una trama duplicada se utiliza el registro SEQ, en el cual se almacena temporalmente la secuencia de la primera trama recibida. Cuando se recibe la segunda trama, se compara el registro SEQ con el número de secuencia que se acaba de recibir. Si éstas son iguales, entonces tenemos una trama duplicada. Cuando tenemos una trama duplicada, el receptor envía el acuse de recibo de la trama anterior recibida y espera una trama válida. Para alguna aplicación en particular, puede verificarse la bandera T del STATUS REGISTER, si ésta es ’1’, entonces tenemos una trama duplicada, si es ‘0’, entonces la trama es correcta.
[[CCOOMMUUNNIICCAACCIIÓÓNN AA NNIIVVEELL EENNLLAACCEE DDEE DDAATTOOSS EENNTTRREE MMIICCRROOCCOONNTTRROOLLAADDOORREESS CCOONN UUNNIIDDAADDEESS DDEE
RRAADDIIOOFFRREECCUUEENNCCIIAA]]
PPRROOYYEECCTTOO DDEE IINNGGEENNIIEERRÍÍAA EELLEECCTTRRÓÓNNIICCAA
UUNNIIVVEERRSSIIDDAADD AAUUTTÓÓNNOOMMAA MMEETTRROOPPOOLLIITTAANNAA IIZZTTAAPPAALLAAPPAA CCaarrllooss EErrnneessttoo MMoorreennoo EEssccoobbaarr 220011221144115599
‐ 73 ‐
Figura 10.5.0 RECIBE_TRAMA
PPRROOYYEECCTTOO DDEE IINNGGEENNIIEERRÍÍAA
EELLEECCTTRRÓÓNNIICCAA
[[CCOOMMUUNNIICCAACCIIÓÓNN AA NNIIVVEELL EENNLLAACCEE DDEE DDAATTOOSS EENNTTRREE MMIICCRROOCCOONNTTRROOLLAADDOORREESS CCOONN UUNNIIDDAADDEESS DDEE RRAADDIIOOFFRREECCUUEENNCCIIAA]]
UUNNIIVVEERRSSIIDDAADD AAUUTTÓÓNNOOMMAA MMEETTRROOPPOOLLIITTAANNAA IIZZTTAAPPAALLAAPPAA CCaarrllooss EErrnneessttoo MMoorreennoo EEssccoobbaarr 220011221144115599
‐ 74 ‐
Si la trama recibida es correcta (CRC correcto y trama no duplicada), entonces se transmite el acuse y los datos se mueven a una sección de memoria fija para que los datos sean procesados. Dicha localidad de memoria fija es la RAM de la dirección $00E2 a la $0161. El almacenaje en esta localidad nos permite evitar sobrescribir datos correctos.
RECIBE_TRAMA: LDI XL,LOW(FIRST_RAM_ADDR) //INICIAR APUNTADORES AL BUFFER PARA... LDI XH,HIGH(FIRST_RAM_ADDR) //...PARA RECIBIR LOS DATOS RCALL TURNONRX RCALL ESPERA_PREAMBULO // ESPRE PREAMBULO VALIDO RCALL RECIBE_BYTE //PRIMERO RECIBE LA SECUENCIA ST X+,HBYTE //ALMACENAR SECUENCIA RECIBIDA EN $0060 RX_TRAMA: RCALL RECIBE_BYTE // RECIBIR TODA LA TRAMA.. ST X+,HBYTE //...Y ALMACENARLA EN EL BUFFER CPI XL,LOW(LAST_RAM_ADDR)+3 BRNE RX_TRAMA LDI TEMP,0<<INT0 OUT GICR,TEMP //DESHABILITA INT. EXTERNA 0 RCALL TURNOFFRX //DESHABILITA MODO DE RECEPCION SER MODO //MODO=0XFF, PREPARA CHEQUEO DE CRC RCALL CRC_GEN //CHECA CRC CLR TEMP CPSE CRC,TEMP //CHECKSUM RESULTANTE = $00? SBI PORTA,CRCERROR // ENCIENDE BANDERA: "ERROR EN EL CHECKSUM CPSE CRC,TEMP //CHECKSUM RESULTANTE = $00? RJMP RECIBE_TRAMA // SI, ENTONCES ESPERAR TRAMA NUEVAMENTE CBI PORTA,CRCERROR //APAGA BANDERA:"CHECKSUM CORRECTO" LDI XL,LOW(FIRST_RAM_ADDR) //CARGAR SECUENCIA RECIBIDA LDI XH,HIGH(FIRST_RAM_ADDR) LD HBYTE,X //CARGAR SECUENCIA RECIBIDA CP SEQ,HBYTE //TRAMA DUPLICADA? BREQ TRAMA_DUPLICADA // SI: TRAMA DUPLICADA (ENVIAR ACUSE UNICAMENTE) MOV SEQ,HBYTE // NO: ALMACENAR TRAMA EN "SEQ" Y CONTINUAR RCALL ENVIA_ACUSE // ENVIA EL ACUSE CLT //LIMPIAR BANDERA T (TRAMA CORRECTA) CBI PORTA,PACKDUPLI //APAGA BANDERA "TRAMA DUPLICADA" LDI XL,LOW(FIRST_RAM_ADDR)+2 //INICIAR APUNTADORES AL BUFFER PARA... LDI XH,HIGH(FIRST_RAM_ADDR) //...PARA MOVER LOS DATOS LDI YL,$E2 LDI YH,$00 ST_DATA: //MOVER LOS DATOS RECIBIDOS A LA SECCIÓN... LD TEMP,X+ //...FIJA ST Y+,TEMP CPI YL,$60 BREQ COMPYH RJMP ST_DATA COMPYH: CPI YH,$01 BRNE ST_DATA RET TRAMA_DUPLICADA: //TRAMA DUPLICADA: ENVIAR ACUSE ANTERIOR SET //BANDERA T= '1'-> TRAMA DUPLICADA SBI PORTA,PACKDUPLI //ENCIENDE BANDERA: TRAMA DUPLICADA LDI TEMP,0<<INT0 OUT GICR,TEMP //DESHABILITA INT. EXTERNA 0 RCALL TURNOFFRX //DESHABILITA MODO DE RECEPCION RCALL ENVIA_ACUSE //ENVIA EL ACUSE RET
[[CCOOMMUUNNIICCAACCIIÓÓNN AA NNIIVVEELL EENNLLAACCEE DDEE DDAATTOOSS EENNTTRREE MMIICCRROOCCOONNTTRROOLLAADDOORREESS CCOONN UUNNIIDDAADDEESS DDEE
RRAADDIIOOFFRREECCUUEENNCCIIAA]]
PPRROOYYEECCTTOO DDEE IINNGGEENNIIEERRÍÍAA EELLEECCTTRRÓÓNNIICCAA
UUNNIIVVEERRSSIIDDAADD AAUUTTÓÓNNOOMMAA MMEETTRROOPPOOLLIITTAANNAA IIZZTTAAPPAALLAAPPAA CCaarrllooss EErrnneessttoo MMoorreennoo EEssccoobbaarr 220011221144115599
‐ 75 ‐
1100..66..00 FFUUNNCCIIÓÓNN EENNVVIIAA__AACCUUSSEE
Una vez que se haya recibido la trama de datos correctamente, el CC1000 se configura como transmisor y envía el acuse. El acuse consta de 4 bytes: 1 byte de la secuencia recibida, un campo de información y 2 bytes de CRC. Como se mencionó en la sección 10.4, sólo existen dos acuses posibles: cuando la secuencia de la trama recibida es $FF o cuando es $00. Dependiendo del valor de la secuencia recibida se selecciona el CRC que ha de ser transmitido. De este modo, el transmisor verificará únicamente que el byte alto del CRC sea el esperado. Si es cualquier otro valor, entonces lo considerará un acuse inválido y retransmitirá la información.
Figura 10.5.0 ENVIA_ACUSE
A continuación se muestra la subrutina ENVIA_ACUSE.
.EQU SEQ1CL =$02 //BYTE BAJO DEL CRC DE SECUENCIA 1 .EQU SEQ1CH =$02 //BYTE ALTO DEL CRC DE SECUENCIA 1 .EQU SEQ2CL =$0D //BYTE BAJO DEL CRC DE SECUENCIA 2 .EQU SEQ2CH =$80 //BYTE ALTO DEL CRC DE SECUENCIA 2 ENVIA_ACUSE: RCALL TURNONTX RCALL ENVIA_PREAMBULO LDI XL,LOW(FIRST_RAM_ADDR) //INICIAR APUNTADORES A RAM LDI XH,HIGH(FIRST_RAM_ADDR) LD HBYTE,X PUSH HBYTE //ALMACENAR EL BYTE DE SECUENCIA RCALL ENVIA_BYTE //TRANSMITIR SECUENCIA RECIBIDA SER HBYTE RCALL ENVIA_BYTE //TRANSMITIR TIPO (ACUSE=$FF) POP TEMP //RESTAURAR EL BYTE DE SECUENCIA CPI TEMP,$FF //SECUENCIA $FF? BREQ CRCSEQ2 // SI: ENVIA CRC DE LA SEC. 2 CRCSEQ1:
PPRROOYYEECCTTOO DDEE IINNGGEENNIIEERRÍÍAA
EELLEECCTTRRÓÓNNIICCAA
[[CCOOMMUUNNIICCAACCIIÓÓNN AA NNIIVVEELL EENNLLAACCEE DDEE DDAATTOOSS EENNTTRREE MMIICCRROOCCOONNTTRROOLLAADDOORREESS CCOONN UUNNIIDDAADDEESS DDEE RRAADDIIOOFFRREECCUUEENNCCIIAA]]
UUNNIIVVEERRSSIIDDAADD AAUUTTÓÓNNOOMMAA MMEETTRROOPPOOLLIITTAANNAA IIZZTTAAPPAALLAAPPAA CCaarrllooss EErrnneessttoo MMoorreennoo EEssccoobbaarr 220011221144115599
‐ 76 ‐
LDI HBYTE,SEQ1CL // OTRO: ENVIA CRC DE LA SEC. 1 RCALL ENVIA_BYTE LDI HBYTE,SEQ1CH RCALL ENVIA_BYTE RJMP ACUSE_ENVIADO CRCSEQ2: LDI HBYTE,SEQ2CL RCALL ENVIA_BYTE LDI HBYTE,SEQ2CH RCALL ENVIA_BYTE ACUSE_ENVIADO: RCALL TURNOFFTX //DESHABILITA TX LDI TEMP,0<<INT0 OUT GICR,TEMP //DESHABILITA INT. EXTERNA 0 RET
1111..00 PPRROOGGRRAAMMAA DDEE
EEJJEEMMPPLLOO
El programa de ejemplo mostrado a continuación es una aplicación de todas las funciones diseñadas anteriormente. La primera parte del programa de ejemplo corresponde a la programación del AVR como transmisor. Cuando el AVR es configurado como transmisor, transmite una sección de su memoria programa hacia el segundo AVR configurado como receptor. Se ha implementado un push button, el cual, al ser presionado envía una trama de 126 bytes de la memoria programa. El programa está diseñado para transmitir únicamente 4 x 126 bytes de la memoria programa, esto quiere decir que una vez que se hayan transmitido las cuatro tramas, se comenzará a transmitir desde la trama uno. Como se mencionó anteriormente, los datos a transmitir (126 bytes de memoria programa) deben ser almacenados en la memoria RAM a partir de la dirección $0062 a la $00DF. Recordemos que las localidades $0060 y $0061 son utilizadas para los campos de información. Una vez que tenemos en la memoria RAM los 126 bytes que van a ser transmitidos, se llama a la función “ENVIA_TRAMA” para enviar los datos hacia el receptor. Nótese que al llamar a esta función se está implementando el protocolo Stop and Wait. Una vez que el acuse se haya recibido, el transmisor despliega por el puerto C el CRC del acuse. El siguiente diagrama de flujo muestra el programa para la parte del transmisor.
[[CCOOMMUUNNIICCAACCIIÓÓNN AA NNIIVVEELL EENNLLAACCEE DDEE DDAATTOOSS EENNTTRREE MMIICCRROOCCOONNTTRROOLLAADDOORREESS CCOONN UUNNIIDDAADDEESS DDEE
RRAADDIIOOFFRREECCUUEENNCCIIAA]]
PPRROOYYEECCTTOO DDEE IINNGGEENNIIEERRÍÍAA EELLEECCTTRRÓÓNNIICCAA
UUNNIIVVEERRSSIIDDAADD AAUUTTÓÓNNOOMMAA MMEETTRROOPPOOLLIITTAANNAA IIZZTTAAPPAALLAAPPAA CCaarrllooss EErrnneessttoo MMoorreennoo EEssccoobbaarr 220011221144115599
‐ 77 ‐
Figura 11.0.0 Programa de Ejemplo. Transmisor
Nótese que no se usa un contador o algo parecido para determinar si se han transmitido las cuatro tramas, en realidad, se usa un “tope” del apuntador Z. cuando el apuntador es Z=$01F8 ya se han transmitido las cuatro tramas de memoria programa. Ahora, para la parte del receptor, se puede trabajar con dos modos:
1. En el primer modo: los datos recibidos (126 bytes de la memoria programa del transmisor) son desplegados en el puerto C.
PPRROOYYEECCTTOO DDEE IINNGGEENNIIEERRÍÍAA
EELLEECCTTRRÓÓNNIICCAA
[[CCOOMMUUNNIICCAACCIIÓÓNN AA NNIIVVEELL EENNLLAACCEE DDEE DDAATTOOSS EENNTTRREE MMIICCRROOCCOONNTTRROOLLAADDOORREESS CCOONN UUNNIIDDAADDEESS DDEE RRAADDIIOOFFRREECCUUEENNCCIIAA]]
UUNNIIVVEERRSSIIDDAADD AAUUTTÓÓNNOOMMAA MMEETTRROOPPOOLLIITTAANNAA IIZZTTAAPPAALLAAPPAA CCaarrllooss EErrnneessttoo MMoorreennoo EEssccoobbaarr 220011221144115599
‐ 78 ‐
2. En el segundo modo únicamente se muestra el primer byte de cada trama recibida.
Para entrar en el modo 2 del receptor se debe mantener presionado el push button cuando el circuito es energizado o durante un reset.
Figura 11.0.1 Programa de Ejemplo. Receptor
[[CCOOMMUUNNIICCAACCIIÓÓNN AA NNIIVVEELL EENNLLAACCEE DDEE DDAATTOOSS EENNTTRREE MMIICCRROOCCOONNTTRROOLLAADDOORREESS CCOONN UUNNIIDDAADDEESS DDEE
RRAADDIIOOFFRREECCUUEENNCCIIAA]]
PPRROOYYEECCTTOO DDEE IINNGGEENNIIEERRÍÍAA EELLEECCTTRRÓÓNNIICCAA
UUNNIIVVEERRSSIIDDAADD AAUUTTÓÓNNOOMMAA MMEETTRROOPPOOLLIITTAANNAA IIZZTTAAPPAALLAAPPAA CCaarrllooss EErrnneessttoo MMoorreennoo EEssccoobbaarr 220011221144115599
‐ 79 ‐
La primer operación principal del receptor es recibir una trama de 130 bytes mediante la función RECIBE_TRAMA (la cual verifica el estado de los datos recibidos como: CRC o duplicado de tramas). En la sección 10.5.0 se mencionó que se utiliza una bandera para identificar si la trama es un duplicado (Bandera T del STATUS REGISTER). Esta bandera es consultada en el programa de ejemplo, si se recibe una trama duplicada, entonces no se despliega nada por el puerto C. NOTA: Este programa de ejemplo está implementando el protocolo Stop And Wait, así que si existen errores en la trama o pérdidas de ésta, pérdidas de acuse, el sistema se encargará de transmitir/recibir correctamente (ver figura 3.0.2). Diviértete!
A continuación se muestra el diagrama eléctrico del circuito (Tx y Rx)
PPRROOYYEECCTTOO DDEE IINNGGEENNIIEERRÍÍAA
EELLEECCTTRRÓÓNNIICCAA
[[CCOOMMUUNNIICCAACCIIÓÓNN AA NNIIVVEELL EENNLLAACCEE DDEE DDAATTOOSS EENNTTRREE MMIICCRROOCCOONNTTRROOLLAADDOORREESS CCOONN UUNNIIDDAADDEESS DDEE RRAADDIIOOFFRREECCUUEENNCCIIAA]]
UUNNIIVVEERRSSIIDDAADD AAUUTTÓÓNNOOMMAA MMEETTRROOPPOOLLIITTAANNAA IIZZTTAAPPAALLAAPPAA CCaarrllooss EErrnneessttoo MMoorreennoo EEssccoobbaarr 220011221144115599
‐ 80 ‐
Figura 11.0.2 Diagrama eléctrico para el programa de ejemplo.
[[CCOOMMUUNNIICCAACCIIÓÓNN AA NNIIVVEELL EENNLLAACCEE DDEE DDAATTOOSS EENNTTRREE MMIICCRROOCCOONNTTRROOLLAADDOORREESS CCOONN UUNNIIDDAADDEESS DDEE
RRAADDIIOOFFRREECCUUEENNCCIIAA]]
PPRROOYYEECCTTOO DDEE IINNGGEENNIIEERRÍÍAA EELLEECCTTRRÓÓNNIICCAA
UUNNIIVVEERRSSIIDDAADD AAUUTTÓÓNNOOMMAA MMEETTRROOPPOOLLIITTAANNAA IIZZTTAAPPAALLAAPPAA CCaarrllooss EErrnneessttoo MMoorreennoo EEssccoobbaarr 220011221144115599
‐ 81 ‐
A continuación se muestra el código fuente del programa, incluyendo las funciones para configuración e interface de datos y la macro empleada.
/**************************************************************** * _ _ _ _ _ _ _ _ _ _ _ _ * _/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_ * | | * | UNIVERSIDAD AUTONOMA METROPOLITANA IZTAPALAPA | * | PROYECTO DE INGENIERÍA ELECTRÓNICA | * | Comunicacion a nivel de enlace de datos entre | * | microcontroladores mediante unidades de RF | * | | * | CC1000PP-AVRM8535.ASM | * | _ _ _ _ _ _ _ _ _ _ _ _ | * |_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_| * * +_________________________________________________+ * | AUTOR: CARLOS ERNESTO MORENO ESCOBAR | * | E-MAIL: [email protected] | * | MATRICULA: 201214159 | * | ASESOR: Dr. MIGUEL ÁNGEL RUIZ SANCHEZ | * | DISPOSITIVO: ATMEGA8535 (CUALQUIER AVR) | * | RELOJ @ 8 MHZ (OSCILADOR INTERNO) | * | FECHA: VIERNES 9 DE MAYO DE 2008 | * |_________________________________________________| * * * DESCRIPCIÓN: * * 1.- ESTE PROGRAMA IMPLEMENTA TODAS LAS FUNCIONES NECESARIAS * PARA LA CONFIGURACIÓN DEL CC1000PP. SE UTILIZAN CONSTANTES * GLOBALES PARA LA CONFIGURACIÓN.DICHAS CONSTANTES DEBEN * MODIFICARSE SEGÚN LA CONFIGURACIÓN QUE SE DESEE (P.E. MODO UART, * VELOCIDAD DE TX, FRECUENCIA ETC). * LA INTERFACE DE CONFIGURACIÓN CON EL CC1000 SE REALIZA * UTILIZANDO EL PROTOCOLO SPI. * A CONTINUAIÓN SE MUESTRAN TODAS LA FUNCIONES PARA CONFIGURACIÓN: * * RW_SPI. TRANSMITIR-LEER POR EL PUERTO DEL SPI * (MODO TX Y RX) * RESETCC1000. REINICIALIZAR EL CC1000 (MODO TX Y RX) * INITCC1000. GRABAR EL CC1000 CON LOS PARAMETROS * POR DEFAUL EN LAS CONSTANTES GLOBALES * Y CALIBAR EL CC1000. (MODO TX Y RX) * TURNONTX. HABILITAR MODO Tx (MODO TX) * TURNOFFTX. DESHABILITAR MODO Tx (MODO TX) * TURNONRX. HABILITAR MODO Rx (MODO RX) * TURNOFFRX. DESHABILITAR MODO Rx (MODO RX) * WRITETOCC1000. ESCRIBIR DATOS DE CONFIG EN EL CC1000 (MODO TX Y RX) * AVER_AUTO. FILTRO PROMEDIO AUTOMÁTICO (MODO RX) * AVER_BLOQ. BLOQUEAR MANUALMENTE FILTRO PROMEDIO (MODO RX) * AVER_DESBLOQ. DESBLOQUEAR MANUALMENTE FILTRO PROMEDIO (MODO RX) * RESET_AVFILTER. REINICIALIZAR EL FILTRO PROMEDIO (MODO RX) * LEERCC1000. LEER EL CONTENIDO DE TODOS LOS REGISTROS DEL CC1000 * (MODO TX Y RX) * * LAS FUNCIONES MOSTRADAS ARRIBA FUNCIONAN PARA CUALQUIER MODO DE * OPERACIÓN, YA QUE LA INTERFACE DE CONFIGURACIÓN ES INDEPENDIENTE * DE LA INTERFACE DE DATOS. * * 2.- PARA LA REALIZACIÓN DE ESTE PROGRAMA SE HA UTILIZADO LA INTERFACE * DE DATOS SÍNCRONA EN MODO MANCHESTER. SI SE QUIERE IMPLEMENTAR UNA
PPRROOYYEECCTTOO DDEE IINNGGEENNIIEERRÍÍAA
EELLEECCTTRRÓÓNNIICCAA
[[CCOOMMUUNNIICCAACCIIÓÓNN AA NNIIVVEELL EENNLLAACCEE DDEE DDAATTOOSS EENNTTRREE MMIICCRROOCCOONNTTRROOLLAADDOORREESS CCOONN UUNNIIDDAADDEESS DDEE RRAADDIIOOFFRREECCUUEENNCCIIAA]]
UUNNIIVVEERRSSIIDDAADD AAUUTTÓÓNNOOMMAA MMEETTRROOPPOOLLIITTAANNAA IIZZTTAAPPAALLAAPPAA CCaarrllooss EErrnneessttoo MMoorreennoo EEssccoobbaarr 220011221144115599
‐ 82 ‐
* INTERFACE DIFERENTE COMO NRZ SÍNCRONO O UART LAS FUNCIONES SIGUIENTES * DEBEN RE-DISEÑARSE. * * PARA NRZ SINCRONO: * ESPERA_PREAMBULO (HAY QUE BLOQUEAR FILTRO PROMEDIO MANUALMENTE) * * PARA UART: * ENVIA_BYTE * RECIBE_BYTE * ENVIA_PREAMBULO * ESPERA_PREAMBULO * ENVIA_TRAMA * RECIBE_TRAMA * ENVIA_ACUSE * RECIBE_ACUSE * (O SEA QUE HAY QUE MODIFICAR TODO!!) * * 3.- SI SE PIENSA UTILIZAR MANCHESTER (QUE ES LO MAS RECOMENDABLE), ESTE PROGRAMA * FUNCIONA MUY BIEN!!. * * AVR CC1000PP-868 * __________ __________ * | | * (SCK) PB0|_________| PCLK * (MOSI)PB2|____ | * (MISO)PB3|___|_____| PDATA * (PALE)PB4|_________| PALE * | | * (DCLK)PD2|_________| DCLK * (DIO) PD4|_________| DIO * | | * _________| |___________ * * 4.- EL CRC-16 IMPLEMENTADO SE OBTUVO DE LA NOTA DE APLICACIÓN * DE ATMEL No. 136. EL PROGRAMA FUE MODIFICADO PARA CALCULAR * EL CHECKSUM DE LA MEMORIA RAM. * * 5.- EL PROTOCOLO STOP AND WAIT CUENTA CON TODOS LOS ELEMENTOS * REQUERIDOS PARA SU IMPLEMENTACIÓN. * * 6.- EL PROGRAMA DE EJEMPLO ABARCA TANTO EL TRANSMISOR COMO EL * RECEPTOR. EN EL MODO DE TRANSMISIÓN SE TRANSMITE UNA PARTE * DE LA MEMORIA PROGRAMA (4 x 126 BYTES) UTILIZANDO EL * PROTOCOLO STOP AND WAIT. * EN EL MODO DE RECEPCIÓN, SE RECIBE UNA TRAMA Y SE DESPLIEGA * EN EL PUERTO C. * * * PARÁMETROS DEL CC1000 PARA ESTA IMPLEMENTACIÓN: * (GENERADOS CON SMART RF STUDIO) * Device: CC1000 * * System parameters: * X-tal frequency: 14.745600 MHz Internal * X-tal accuracy: +/- 20 ppm * RF frequency A: 868.297200 MHz Inactive Rx * RF frequency B: 868.297200 MHz Active Tx * RX Mode: Low Current: no, Optimal frequency: yes, Low side LO * Frequency separation: 64 kHz * Data rate: 76.8 kBaud * Data Format: Manchester Accurate * RF output power: 5 dBm * LOCK indicator: Continuous
[[CCOOMMUUNNIICCAACCIIÓÓNN AA NNIIVVEELL EENNLLAACCEE DDEE DDAATTOOSS EENNTTRREE MMIICCRROOCCOONNTTRROOLLAADDOORREESS CCOONN UUNNIIDDAADDEESS DDEE
RRAADDIIOOFFRREECCUUEENNCCIIAA]]
PPRROOYYEECCTTOO DDEE IINNGGEENNIIEERRÍÍAA EELLEECCTTRRÓÓNNIICCAA
UUNNIIVVEERRSSIIDDAADD AAUUTTÓÓNNOOMMAA MMEETTRROOPPOOLLIITTAANNAA IIZZTTAAPPAALLAAPPAA CCaarrllooss EErrnneessttoo MMoorreennoo EEssccoobbaarr 220011221144115599
‐ 83 ‐
* IF/RSSI: Disabled * Operator Mode: Tx * * Component values, VCO inductor: * L101 = 4.7 nH * * Component values, Match * L32 = 120.0 nH * L41 = 2.5 nH * C31 = 10.0 pF * C41 = N.A pF * C42 = 4.7 pF * * ******************************************************************/ /************************ COMENZAMOS.....*************************/ .NOLIST .INCLUDE "M8535DEF.INC" .INCLUDE "MACROS.INC" .LIST /***************************************************************** ***** C O N F I G U R A C I O N P A R A E L C C 1 0 0 0 ****** ****************************************************************** *********** C O N S T A N T E S G L O B A L E S ***************** A CONTINUACIÓN SE DEBEN INTRODUCIR LAS DIRECCIONES DE LOS 22 REGISTROS DE CONFIGURACIÓN DEL CC1000, POSTERIORMENTE INTRODUCIR LOS DATOS DE CONFIGURACIÓN QUE DEBEN SER CARGADOS EN CADA UNO DE LOS REGISTROS DEL CC1000. ESTOS DATOS INTRODUCIDOS SON PARA CONFIGURAR EL CC1000 COMO TRANSMISOR OBTENIDOS DE RFSTUDIO. NOTA: NO ES NECESARIO MODIFICAR LAS DIRECCIONES DE LOS REGISTROS SI SE USA EL CC1000. *******************************************************************/ // DIRECCIONES DE LOS REGISTROS DE CONFIGURACIÓN // (NO MODIFICAR!) .EQU AMAIN =$00 .EQU AFREQ_2A =$01 .EQU AFREQ_1A =$02 .EQU AFREQ_0A =$03 .EQU AFREQ_2B =$04 .EQU AFREQ_1B =$05 .EQU AFREQ_0B =$06 .EQU AFSEP1 =$07 .EQU AFSEP0 =$08 .EQU ACURRENT =$09 .EQU AFRONT_END =$0A .EQU APA_POW =$0B .EQU APLL =$0C .EQU ALOCK =$0D .EQU ACAL =$0E .EQU AMODEM2 =$0F .EQU AMODEM1 =$10 .EQU AMODEM0 =$11 .EQU AMATCH =$12 .EQU AFSCTRL =$13 .EQU APREESCALER =$1C .EQU ATEST4 =$42 // CONTENIDO DE LOS REGISTROS (DEFAULT MODO: TX)
PPRROOYYEECCTTOO DDEE IINNGGEENNIIEERRÍÍAA
EELLEECCTTRRÓÓNNIICCAA
[[CCOOMMUUNNIICCAACCIIÓÓNN AA NNIIVVEELL EENNLLAACCEE DDEE DDAATTOOSS EENNTTRREE MMIICCRROOCCOONNTTRROOLLAADDOORREESS CCOONN UUNNIIDDAADDEESS DDEE RRAADDIIOOFFRREECCUUEENNCCIIAA]]
UUNNIIVVEERRSSIIDDAADD AAUUTTÓÓNNOOMMAA MMEETTRROOPPOOLLIITTAANNAA IIZZTTAAPPAALLAAPPAA CCaarrllooss EErrnneessttoo MMoorreennoo EEssccoobbaarr 220011221144115599
‐ 84 ‐
// (INTRODUCIR AQUÍ EL CONTENIDO DE LOS REGISTROS) .EQU MAIN =$E1 .EQU FREQ_2A =$75 .EQU FREQ_1A =$A0 .EQU FREQ_0A =$00 .EQU FREQ_2B =$58 .EQU FREQ_1B =$33 .EQU FREQ_0B =$13 .EQU FSEP1 =$01 .EQU FSEP0 =$AB .EQU CURRENT =$F3 .EQU FRONT_END =$30 .EQU PA_POW =$FF .EQU PLL =$30 .EQU LOCK =$90 .EQU CAL =$26 .EQU MODEM2 =$C1 .EQU MODEM1 =$6F .EQU MODEM0 =$54 .EQU MATCH =$10 .EQU FSCTRL =$01 .EQU PREESCALER =$00 .EQU TEST4 =$3F // PARA EL MODO DE RX LOS REGISTROS: MAIN, CURRENT // Y PLL CAMBIAN DE VALOR. // INTRODUCIR AQUÍ ESOS VALORES .EQU MAINRX =$11 .EQU CURRENTRX =$8C .EQU PLLRX =$40 .EQU CALRXTX =$26 /*************************************************************** * LAS SIGUIENTES CONSTANTES SON PARA EL RESET, CALIBARCIÓN, * POWER UP Y POWER DOWN DEL CC1000 NO ES NECESARIO MODIFICAR * ESTAS CONSTANTES ***************************************************************/ // CONTSTANTES PARA EL RESET (NO MODIFICAR!!) // (PÁGINA 29 DEL DATASHEET DEL CC1000) .EQU RESET1 =$3A .EQU RESET2 =$3B // CONSTANTES PARA CALIBRACIÓN (NO MODIFICAR!!) // (PÁGINA 26 DEL DATASHEET DEL CC1000) .EQU CCAL =$A6 //INICIAR CALIBRACIÓN .EQU CPA_POW =$00 //POWER DOWN MODE .EQU CMAIN =$3F //MAIN EN \u017dMODO POWER DOWN // CONSTANTES PARA HABILITACIÓN DE TX Y RX (NO MODIFICAR!!) // (PÁG 30 DEL DATASHEET DEL CC1000) .EQU TURNONMAIN1 =$3B .EQU TURNONMAIN2 =$39 // CONSTANTE PARA APAGAR MODO TX (NO MODIFICAR!!) .EQU TRN_OFF_TX =$FF // CONSTANTE PARA APAGAR MODO RX (NO MODIFICAR!!) .EQU TRN_OFF_RX =$3F // FILTRO PROMEDIO PARA UART (NO MODIFICAR!!) // (TABLA 4 PÁGINA 20 DEL DATASHEET DEL CC1000) .EQU AUTOMATICO =$67 //MODO AUTÓMATICO
[[CCOOMMUUNNIICCAACCIIÓÓNN AA NNIIVVEELL EENNLLAACCEE DDEE DDAATTOOSS EENNTTRREE MMIICCRROOCCOONNTTRROOLLAADDOORREESS CCOONN UUNNIIDDAADDEESS DDEE
RRAADDIIOOFFRREECCUUEENNCCIIAA]]
PPRROOYYEECCTTOO DDEE IINNGGEENNIIEERRÍÍAA EELLEECCTTRRÓÓNNIICCAA
UUNNIIVVEERRSSIIDDAADD AAUUTTÓÓNNOOMMAA MMEETTRROOPPOOLLIITTAANNAA IIZZTTAAPPAALLAAPPAA CCaarrllooss EErrnneessttoo MMoorreennoo EEssccoobbaarr 220011221144115599
‐ 85 ‐
.EQU BLOQUEAR =$7F //BLOQUEO MANUAL .EQU DESBLOQUEAR =$6F //DESBLOQUEO MANUAL .EQU RESETAVFILTER =$6E .EQU N=21 //*************** F I N D E L A T A B L A 1 ********************** /*************************************************************************** * * DEFINICIONES DE LOS REGISTROS * **************************************************************************/ .DEF SPIDR =R0 // REGISTRO PARA EL SPI .DEF S_REG =R1 // RESPALDO DEL STATUS REGISTER .DEF BYTE_0 =R2 // BYTE BAJO DE LA PALABRA BAJA (CRC-16) .DEF BYTE_1 =R3 // BYTE ALTO DE LA PALABRA BAJA (CRC-16) .DEF BYTE_2 =R4 // BYTE BAJO DE LA PALABRA ALTA (CRC-16) .DEF BYTE_3 =R5 // BYTE ALTO DE LA PALABRA ALTA (CRC-16) .DEF ADDRESS =R16 // DIRECCION DE LOS REG. DEL CC1000 .DEF DATA =R17 // DATO A CARGAR EN LOS REG DEL CC1000 .DEF TEMP =R18 // REGISTRO TEMPORAL .DEF HBYTE =R19 // DATO A TX EN RF .DEF CONT =R21 // CONTADOR AUXILIAR //REGISTROS PROHIBIDOS (CON "REGISTROS PROHIBIDOS" ME REFIERO A QUE NO // SE DEBEN UTILIZAR PARA OTRA COSA, YA QUE AFECTARÁ // ENORMEMENTE EL DESEMPEÑO DEL PROGRAMA") .DEF ACUSE =R22 // TIMEOUT END? .DEF SEQ =R6 // GENERADOR/ VERIFICADOR DE SECUENCIA (STOP N' WAIT) .DEF MODO =R20 // IDENTIFICACIÓN DE OPERACIÓN & GENERAR/VERIFICAR CRC /*************************************************************************** * BANDERAS: * * LAS BANDERAS SON LEDS CONECTADOS AL PUERTO A DEL AVR PARA IDENTIFICACIÓN * DE LAS OPERACIONES QUE SE ESTÁN REALIZANDO. SON UTILIZADAS ÚNICAMENTE * COMO PRUEBA. NO AFECTAN EN NADA EL PROGRAMA Y PUEDEN SER ELIMINADAS DEL * PROGRAMA. * NOTA: SI SE REQUIERE UTILIZAR EL PUERTO A PARA OTRA OPERACIÓN, SE DEBEN * ELIMINAR TODAS LAS INSTRUCCIONES SIGUIENTES: * SBI PORTA,XXXXX * CBI PORTA,XXXXX * EN LA FUNCIÓN "RECIBE_TRAMA" SE DEBEN ELIMINAR LAS INSTRUCCIONES * CPSE CRC,TEMP * SBI PORTA,CRCERROR ***************************************************************************/ .EQU PRERECIBIDO = 0 //PIN 0 DEL PUERTO A: PREAMBULO RECIBIDO .EQU CRCERROR = 1 //PIN 1 DEL PUERTO A: ERROR EN EL CRC .EQU PACKDUPLI = 2 //PIN 2 DEL PUERTO A: TRAMA DUPLICADA .EQU ESPERAACUSE = 3 //PIN 3 DEL PUERTO A: ESPERANDO ACUSE .CSEG .ORG 0x00 RJMP RESET .ORG INT0addr RJMP RISE_DCLK .ORG OC1Baddr RJMP TIMEOUT
PPRROOYYEECCTTOO DDEE IINNGGEENNIIEERRÍÍAA
EELLEECCTTRRÓÓNNIICCAA
[[CCOOMMUUNNIICCAACCIIÓÓNN AA NNIIVVEELL EENNLLAACCEE DDEE DDAATTOOSS EENNTTRREE MMIICCRROOCCOONNTTRROOLLAADDOORREESS CCOONN UUNNIIDDAADDEESS DDEE RRAADDIIOOFFRREECCUUEENNCCIIAA]]
UUNNIIVVEERRSSIIDDAADD AAUUTTÓÓNNOOMMAA MMEETTRROOPPOOLLIITTAANNAA IIZZTTAAPPAALLAAPPAA CCaarrllooss EErrnneessttoo MMoorreennoo EEssccoobbaarr 220011221144115599
‐ 86 ‐
/*************************************************************************** * * VECTORES DE INTERRUPCIÓN * **************************************************************************/ /*************************************************************************** * TIMEOUT * ESTA INTEURRUPCIÓN ES ACTIVADA POR COMPARACIÓN DEL TIMER COUNTER 1. Y * ES UTILIZADA PARA CARGAR LA BANDERA "ACUSE" E IDENTIFICAR QUE SE A * AGOTADO EL TIMEOUT EN EL PROTOCOLO STOP AND WAIT ****************************************************************************/ TIMEOUT: IN S_REG,SREG SER ACUSE OUT SREG,S_REG RETI /*************************************************************************** * RISE_DCLK * * DESCRIPCIÓN: * ESTA ES LA ISR REQUERIDA PARA LA OPERACIÓN DE LAS SIGUIENTES FUNCIONES * -ENVIA_PREAMBULO * -RECIBE_PREAMBULO * -ENVIA_BYTE * -RECIBE_BYTE * CUANDO LA INTERRUPCIÓN INT0 ES ACTIVADA SE GENERA LA INTERRUPCIÓN POR * EL FLANCO DE SUBIDA DEL DCLK DEL CC1000. * EN EL FLANCO DE SUBIDA SE TRANSMITE O RECIBE UN BIT DE DATOS. * SE HA CREADO UN "SELECTOR", EL CUAL IDENTIFICA LA FUNCIÓN EN LA QUE * SE ENCUENTRA (p.e. "RECIBE_PREAMBULO" o "ENVIA_BYTE") CUANDO ES GENERADA * LA INTERRUPCIÓN. ASÍ, CUANDO SE GENERA LA INTERRUPCION SE * IDENTIFICA LA PROCEDENCIA Y SE REALIZA EL SALTO HACIA LA SUBRUTINA * CORRESPONDIENTE * ***************************************************************************/ /*************************************************************************** * CONSTANTES PARA IDENTIFICAR QUE OPERACIÓN SE VA A REALIZAR * DURANTE LA INTERRUPCIÓN POR EL FLANCO DE SUBIDA DEL DCLK ****************************************************************************/ .EQU MODOTXDAT = 1 // MODO DE TRANSMISIÓN .EQU MODORXDAT = 2 // MODO DE RECEPCIÓN .EQU MODOTXPRE = 3 // MODO ENVIA PREAMBULO .EQU MODORXPRE = 4 // MODO RECIBE PREAMBULO RISE_DCLK: //IDENTIFICACION DE LA OPERACIÓN IN S_REG,SREG CPI MODO,MODOTXDAT BREQ TX_DATO //TRANSMITIR BYTE CPI MODO,MODORXDAT BREQ RX_DATO //RECIBIR BYTE CPI MODO,MODOTXPRE BREQ TX_PREAMBULO //GENERA Y TRANSMITE PREAMBULO CPI MODO,MODORXPRE BREQ RX_PREAMBULO //ESPERA Y VALIDA PREAMBULO TX_PREAMBULO: // TRANSMITIR PREAMBULO EN FLANCO DE SUBIDA DE DCLK CPI HBYTE,$01 //HBYTE=1 ? BREQ ENVIA1 // SI: GENERAR UN '1' Y TRANSMITIRLO CBI PORTD,DIO // NO: GENERAR UN '0' Y TRANSMITIRLO LDI HBYTE,$01
[[CCOOMMUUNNIICCAACCIIÓÓNN AA NNIIVVEELL EENNLLAACCEE DDEE DDAATTOOSS EENNTTRREE MMIICCRROOCCOONNTTRROOLLAADDOORREESS CCOONN UUNNIIDDAADDEESS DDEE
RRAADDIIOOFFRREECCUUEENNCCIIAA]]
PPRROOYYEECCTTOO DDEE IINNGGEENNIIEERRÍÍAA EELLEECCTTRRÓÓNNIICCAA
UUNNIIVVEERRSSIIDDAADD AAUUTTÓÓNNOOMMAA MMEETTRROOPPOOLLIITTAANNAA IIZZTTAAPPAALLAAPPAA CCaarrllooss EErrnneessttoo MMoorreennoo EEssccoobbaarr 220011221144115599
‐ 87 ‐
DEC CONT OUT SREG,S_REG RETI ENVIA1: //SUBRUTINA QUE ENVÍA UN '1' SBI PORTD,DIO //GENERAR UN '1' CLR HBYTE DEC CONT OUT SREG,S_REG RETI TX_DATO: //ENVIAR UN BIT A LA VEZ CADA FLANCO DE SUBIDA DE DCLK ROR HBYTE //ROTAR HBYTE BRCS ENVIA_D1 //CARRY FLAG='0' ? CBI PORTD,DIO // GENERA Y TX UN '1' DEC CONT //OTRO GENERA Y TX UN '0' OUT SREG,S_REG RETI ENVIA_D1: //SUBRUTINA PARA TX UN '1' SBI PORTD,DIO DEC CONT //DECREMENTAR CONTADOR OUT SREG,S_REG RETI RX_PREAMBULO: //ESPERA Y VALIDA EL PREAMBULO CPI TEMP,$00 BREQ ESPERA1 SBIS PIND,DIO //SI PD4='1' CLC // CARRY FLAG='0' SBIC PIND,DIO //SI PD4='0' REGRESA: SEC // CARRY FLAG='1' ROR HBYTE //C->b7....b0->C INC TEMP CPI TEMP,$02 //SI TEMP=2 BREQ VALID_PRE // SATO A VALID_PRE DEC CONT //OTRO DEC CONT OUT SREG,S_REG RETI VALID_PRE: CPI HBYTE,$40 //HBYTE=$40? BREQ PRE_CORRECTO // PREAMBULO CORRECTO LDI CONT,CHIP //REINICIALIZAR CONTADOR CLR TEMP // TEMP CLR HBYTE // HBYTE OUT SREG,S_REG RETI PRE_CORRECTO: DEC CONT //DECREMENTA CONTADOR CLR HBYTE // LIMPIA HBYTE CLR TEMP // LIMPIA TEMP OUT SREG,S_REG RETI ESPERA1: SBIC PIND,DIO RJMP REGRESA OUT SREG,S_REG RETI RX_DATO: //RECIBIR UN BIT A LA VEZ CADA FLANCO DE SUBIDA DE DCLK SBIS PIND,DIO //PD4='0' CLC // CARRY FLAG='0' SBIC PIND,DIO //PD='1' SEC // CARRY FLAG='1' ROR HBYTE //C->b7....b0->C
PPRROOYYEECCTTOO DDEE IINNGGEENNIIEERRÍÍAA
EELLEECCTTRRÓÓNNIICCAA
[[CCOOMMUUNNIICCAACCIIÓÓNN AA NNIIVVEELL EENNLLAACCEE DDEE DDAATTOOSS EENNTTRREE MMIICCRROOCCOONNTTRROOLLAADDOORREESS CCOONN UUNNIIDDAADDEESS DDEE RRAADDIIOOFFRREECCUUEENNCCIIAA]]
UUNNIIVVEERRSSIIDDAADD AAUUTTÓÓNNOOMMAA MMEETTRROOPPOOLLIITTAANNAA IIZZTTAAPPAALLAAPPAA CCaarrllooss EErrnneessttoo MMoorreennoo EEssccoobbaarr 220011221144115599
‐ 88 ‐
DEC CONT OUT SREG,S_REG RETI /************************************************************************** ************* F U N C I O N E S P A R A E L S P I ******************* ***************************************************************************/ //DEFINICIONES DEL PUERTO: .EQU SCK = PB0 //PB0 PIN .EQU MOSI = PB2 //PB2 PIN .EQU MISO = PB3 //PB3 PIN .EQU PALE = PB4 //PB4 PIN /*************************************************************************** * * FUNCION * RW_SPI * * DESCRIPCION * * ESCRIBE UN BYTE EN EL SPI MIENTRAS LEE SIMULTÁNEAMENTE OTRO BYTE * PRIMERO SE ENVÍA EL MSB Y LA INFORMACIÓN LEIDA SE ALMACENA DENTRO DEL * MISMO BUFFER EMPLEADO PARA ESCRITURA. SCK Y /SS DEBEN ESTAR INICIALIZADOS * ANTES DE ENTRAR A ESTA SUBRUTINA. * EL TIEMPO DE SCK ALTO ES ((DELAY * 3) + 1) CICLOS DE RELOJ DEL * AVR. * NOTA: ESTA FUNCIÓN SE OBTUVO DE LA NOTA DE APLICACIÓN DE ATMEL No. 320 ***************************************************************************/ RW_SPI: LDI TEMP,8 //CONTADOR (8 BITS DE DATOS) SPI_LOOP: LSL SPIDR //DESPLAZA EL REG SPIDR (PARA VER EL BIT A TRANS) BRCC LO_MOSI SBI PORTB,MOSI RJMP MOSI_DONE //ESTE SALTO CREA EL TIEMPO PARA QUE ESTÉ LISTO EL // DATO ANTES DEL FLANCO DE BAJADA LO_MOSI: CBI PORTB,MOSI //TRANSMITE EL CERO SI CarryFlag=0 NOP //TAMBIÉN CREA EL TIEMPO DE "SETUP" DEL MOSI NOP MOSI_DONE: CBI PORTB,SCK //SCK_HI CHANGE BY CARLOS SUBI TEMP, (1 << 5) //(1 * 3) CYCLE DELAY// RANGE IS FROM 1 TO 7! TIME_HI: SUBI TEMP, -(1 << 5) //DURACIÓN DEL TIEMPO EN ESTADO ALTO DE SCK, DESPUES BRCS TIME_HI // C ES LIMPIADA Y TEMP RECUPERA SU VALOR ORIGINAL SBIC PINB,MISO //AFTER DELAY, READ IN SPI BIT & PUT INTO D0 INC SPIDR //WE FORCED D0=0, SO USE INC TO SET D0. DEC TEMP SBI PORTB,SCK //SCK EN ESTADO ALTO SUBI TEMP, (1 << 5) TIME_LO: SUBI TEMP, -(1 << 5) //DURACIÓN DEL TIEMPO EN ESTADO BAJO DE SCK BRCS TIME_LO BRNE SPI_LOOP SBI PORTB,MOSI RET //******** F I N D E L A S S U B R U T I N A S D E L S P I *********** /*****************************************************************************
[[CCOOMMUUNNIICCAACCIIÓÓNN AA NNIIVVEELL EENNLLAACCEE DDEE DDAATTOOSS EENNTTRREE MMIICCRROOCCOONNTTRROOLLAADDOORREESS CCOONN UUNNIIDDAADDEESS DDEE
RRAADDIIOOFFRREECCUUEENNCCIIAA]]
PPRROOYYEECCTTOO DDEE IINNGGEENNIIEERRÍÍAA EELLEECCTTRRÓÓNNIICCAA
UUNNIIVVEERRSSIIDDAADD AAUUTTÓÓNNOOMMAA MMEETTRROOPPOOLLIITTAANNAA IIZZTTAAPPAALLAAPPAA CCaarrllooss EErrnneessttoo MMoorreennoo EEssccoobbaarr 220011221144115599
‐ 89 ‐
*********** F U N C I O N E S P A R A E L C R C - 1 6 ******************* ******************************************************************************/ .EQU LAST_RAM_ADDR = 0X00DF //DIRECCIÓN DEL ULTIMO DATO (128 BYTES) .EQU FIRST_RAM_ADDR= 0X0060 //INICIO DE LA RAM .EQU POLY = 0X8005 //POLINOMIO DEL CRC-16 .DEF CRC =R0 // CRC CHECKSUM BYTE BAJO .DEF CRCH =R1 // CRC CHECKSUM BYTE ALTO .DEF SIZEL =R16 // TAMAÑO DE LOS DATOS EN RAM BYTE BAJO .DEF SIZEH =R17 // TAMAÑO DE LOS DATOS EN RAM BYTE ALTO .DEF CRDIVH =R18 .DEF CRDIVL =R19 /*************************************************************************** * * FUNCION: * "CRC_GEN" - GENERAR Y VERIFICAR EL CHECKSUM DEL CRC * * DESCRIPCION: * * ESTA SUBRUTINA GENERA EL CHECKSUM DE LOS DATOS CONTENIDOS EN LA * MEMORIA RAM. 32 BITS SE CARGAN EN CUATRO REGISTROS, A LOS 16 BITS * SUPERIORES SE LES APLICA LA OPERACIÓN XOR CON EL VALOR DEL * POLINOMIO CADA VEZ QUE UN 1 ES DESPLAZADO DENTRO DE LA BANDERA DE * ACARREO DEL BIT MAS SIGNIFICATIVO. * SI EL REGISTRO "MODO" ES 0X00, LA RUTINA GENERARÁ EL CHECKSUM: * DESPUES DE CALCULARLO, SE CONCATENAN 16 CEROS AL CODIGO Y EL * CHECKSUM ES CALCULADO. * SI EL REGISTRO "MODO" ES DIFERENTE DE 0X00, LA RUTINA CHECARÁ SI * EL ACTUAL CHECKSUM ES VALIDOS. DESPUES DE CALCULAR EL CÓDIGO ORIGINAL * EL CHECLSUM ES CONCATENADO AL CÓDIGO. EL RESULTADO ES CERO SI NO * EXISTEN ERRORES EN EL CÓDIGO. EL RESULTADO ES ALMACENADO EN LOS * REGISTROS BYTE_2 Y BYTE_3 * * DURACIÓN APROXIMADA DE LA SUBRUTINA PARA 128 BYTES: * GENERAR: 11517 CICLOS, 1439.63 uSEG @ 8MHz * VERIFICAR: 11519 CICLOS, 1439.50 uSEG @ 8MHz * **************************************************************************/ CRC_GEN: LDI XL,LOW(LAST_RAM_ADDR) //APUNTADOR A LA ULTIMA DIRECCION DE LOS DATOS LDI XH,HIGH(LAST_RAM_ADDR) ADIW XL,0X01 //INCREMENTAR APUNTADOR X LD CRC,X+ //CARGAR EL BYTE BAJO DEL CHECKSUM EN REGISTRO LD CRCH,X LDI SIZEL,LOW(LAST_RAM_ADDR) //CARGAR LA ULTIMA DIRECCION DE LOS DATOS LDI SIZEH,HIGH(LAST_RAM_ADDR) LDI XL,LOW(FIRST_RAM_ADDR) //APUNTADORES A INICIO DE LA RAM LDI XH,HIGH(FIRST_RAM_ADDR) LDI CRDIVH,HIGH(POLY) //CARGAR EL POLINOMIO LDI CRDIVL,LOW(POLY) LD BYTE_0,X //CARGAR EL PRIMER DATO DE LA RAM MOV BYTE_3,BYTE_0 //MOVERLO AL BYTE MAS ALTO ADIW XL,0X01 //INCREMENTAR APUNTADOR X LD BYTE_0,X //CARGAR EL SEGUNDO DATO DE LA RAM MOV BYTE_2,BYTE_0 NEXT_BYTE: CP XL,SIZEL //COMIENZO DEL CICLO CPC XH,SIZEH //VERIFICAR SI ES LA ULTIMA DIR. BRGE END //SALTA SI ES LA ULTIMA DIRECC. ADIW XL,0X01 LD BYTE_0,X //CARGA EL BYTE MAS ALTO MOV BYTE_1,BYTE_0 //MOVERLO AL BYTE ALTO
PPRROOYYEECCTTOO DDEE IINNGGEENNIIEERRÍÍAA
EELLEECCTTRRÓÓNNIICCAA
[[CCOOMMUUNNIICCAACCIIÓÓNN AA NNIIVVEELL EENNLLAACCEE DDEE DDAATTOOSS EENNTTRREE MMIICCRROOCCOONNTTRROOLLAADDOORREESS CCOONN UUNNIIDDAADDEESS DDEE RRAADDIIOOFFRREECCUUEENNCCIIAA]]
UUNNIIVVEERRSSIIDDAADD AAUUTTÓÓNNOOMMAA MMEETTRROOPPOOLLIITTAANNAA IIZZTTAAPPAALLAAPPAA CCaarrllooss EErrnneessttoo MMoorreennoo EEssccoobbaarr 220011221144115599
‐ 90 ‐
ADIW XL,0X01 //INCREMENTAR APUNTADOR X LD BYTE_0,X //CARGAR EL DATO CONTENIDO EN RAM RCALL ROT_WORD //LLAMAR A RUTINA ROTAR PALABRA RJMP NEXT_BYTE END: LDI CONT,0X11 CPI MODO,0X00 BRNE CHECK CLR BYTE_0 //CONCATENAR 16 BITS (0X0000) AL CLR BYTE_1 //FINAL DE LOS DATOS PARA LA GENERACION CRC RJMP GEN CHECK: MOV BYTE_0,CRC //CONCATENAR EL CHECKSUM ORIGINAL MOV BYTE_1,CRCH //AL FINAL DE LOS DATOS PARA CHEQUEO DE CRC GEN: RCALL ROT_WORD //LLAMAR A RUTINA ROTAR PALABRA MOV CRC,BYTE_2 MOV CRCH,BYTE_3 LDI XL,LOW(LAST_RAM_ADDR) //APUNTADOR A LA ULTIMA DIRECCION DE LOS DATOS LDI XH,HIGH(LAST_RAM_ADDR) ADIW XL,0X01 //INCREMENTAR APUNTADOR X ST X+,CRC //ALMACENAR EL BYTE BAJO DEL CHECKSUM EN LA RAM ST X,CRCH RET //REGRESO DE SUBRUTINA ROT_WORD: LDI CONT,0X11 ROT_LOOP: DEC CONT //DECREMENTAR CONTADOR BREQ STOP //SALIR SI COUNTADOR = 0 LSL BYTE_0 //DESPLAZAR UN '0' DENTRO DEL BIT MENOR ROL BYTE_1 //DESPLAZAR EN ACARREO EL BYTE PREVIO ROL BYTE_2 //CONTINUA DESPLAZANDO ROL BYTE_3 BRCC ROT_LOOP //LOOP SI MSB = 0 EOR BYTE_2,CRDIVL EOR BYTE_3,CRDIVH //XOR PALABRA ALTA SI MSB = 1 RJMP ROT_LOOP STOP: RET /***************************************************************************** ******** F I N D E L A S F U N C I O N E S P A R A E L C R C ******** ******************************************************************************/ /********************************************************************************* ** F U N C I O N E S P A R A C O N F I G U R A C I O N D E L C C 1 0 0 0 * *********************************************************************************/ /**************************************************************************** * FUNCIÓN: * RESETCC1000 * * DESCRIPCIÓN: * * ESTA SUBRUTINA LEE DE LA MEMORIA RAM LAS DIRECCIONES Y DATOS DE LOS * REGISTROS NECESARIOS PARA REESTABLECER EL CC1000, EL ALGORITMO ES EL * SIGUIENTE: * 1. ESCRIBIR EN MAIN: $FE * 2. ESCRIBIR EN MAIN: $FF * 3. ESPERAR 2msegundos * * PRIMERO SE TRANSMITE LA DIRECCIÓN DE MAIN, POSTERIORMENTE EL DATO QUE * DEBE SER GUARDADO, ESTE PROCEDIMIENTO SE REALIZA DOS VECES. * FIGURA 18 PAGINA 29 (DATASHEET DEL CC1000) *****************************************************************************/
[[CCOOMMUUNNIICCAACCIIÓÓNN AA NNIIVVEELL EENNLLAACCEE DDEE DDAATTOOSS EENNTTRREE MMIICCRROOCCOONNTTRROOLLAADDOORREESS CCOONN UUNNIIDDAADDEESS DDEE
RRAADDIIOOFFRREECCUUEENNCCIIAA]]
PPRROOYYEECCTTOO DDEE IINNGGEENNIIEERRÍÍAA EELLEECCTTRRÓÓNNIICCAA
UUNNIIVVEERRSSIIDDAADD AAUUTTÓÓNNOOMMAA MMEETTRROOPPOOLLIITTAANNAA IIZZTTAAPPAALLAAPPAA CCaarrllooss EErrnneessttoo MMoorreennoo EEssccoobbaarr 220011221144115599
‐ 91 ‐
RESETCC1000: //RESET EL CC1000 LDI ADDRESS,AMAIN LDI DATA,RESET1 //RESET_N=0 RCALL WRITETOCC1000 LDI DATA,RESET2 //RESET_N=1 RCALL WRITETOCC1000 RCALL WAIT2ms RET /***************************************************************************** * FUNCIÓN: * INITCC1000 * * DESCRIPCIÓN: * * ESTA SUBRUTINA LEE DE LA MEMORIA RAM LAS DIRECCIONES Y LOS DATOS QUE VAN * A SER GRABADOS EN LOS REGISTROS DEL CC1000, SE UTILIZAN DOS APUNTADORES * A LA MEMORIA RAM. EL PRIMERO (XL) APUNTA A LAS DIRECCIONES Y EL SEGUNDO * (YL) APUNTA A LOS DATOS. * EN ESTA SUBRUTINA SE PROGRAMAN 21 REGISTROS, YA QUE EL REGISTRO MAIN SE * GRABA AL ÚLTIMO. * EL ALGORITMO ES EL SIGUIENTE: * 1. LEE LA DIRECCIÓN DE LA RAM Y TRANSMÍTELA * 2. LEE EL DATO CORRESPONDIENTE Y TRANSMÍTELO * 3. ÚLTIMO REGISTRO? * SI-> TERMINA * NO-> REGRESA AL PASO 1 * * ESTA SUBRUTINA SE EJECUTA 21 VECES (YA QUE SON 21 REGISTROS) * LAS DIRECCIONES COMIENZAN EN LA DIRECCIÓN DE LA RAM $60 * LOS DATOS COMIENZAN EN $60+N ******************************************************************************/ INITCC1000: //GRABAR LOS REGISTROS DEL CC1000 (EXCEPTO MAIN) RCALL RESETCC1000 CLR XH LDI XL,$60 //APUNTADOR A LAS DIRECCIONES CLR YH LDI YL,$60+N //APUNTADOR A LOS DATOS TXRX_CONFIG: LD ADDRESS,X+ //CARGA LA DIRECCIÓN DEL REGISTRO DE CONFIGURACIÓN LD DATA,Y+ RCALL WRITETOCC1000 //TRANSMITIR EL DATO CPI YL,$60+(2*N) //FINAL DE LOS DATOS? BRNE TXRX_CONFIG /***************************************************************************** * SECUENCIA DE CALIBRACIÓN DEL CC1000 * * * DESCRIPCIÓN: * * ESTA SUBRUTINA ENVÍA LOS DATOS QUE DEBEN SER CARGADOS EN LOS REGISTROS PARA * LA CALIBRACIÓN DEL CC1000. EL ARGORITMO SE ENCUENTRA EN LA PÁGINA 26 DEL * DATASHEET DEL CC1000. * * ALGORITMO: * * 1. MAIN: TX_D=1,RESET_N=1 ;CALIBRAR PRIMERO TX * 2. CURRENT=RX CURRENT * 3. PLL=RX PLL * 4. CAL: CAL_START=1 * 5 ESPERA 34 mS * 6. CAL: CAL_START=0 (ESTADO ORIGINAL) * * 7. MAIN: RXTX=1,FREG=1,RXPD=1,REST_N=1 ;CALIBRAR DESPUÉS RX * 8. CURRENT=TX CURRENT
PPRROOYYEECCTTOO DDEE IINNGGEENNIIEERRÍÍAA
EELLEECCTTRRÓÓNNIICCAA
[[CCOOMMUUNNIICCAACCIIÓÓNN AA NNIIVVEELL EENNLLAACCEE DDEE DDAATTOOSS EENNTTRREE MMIICCRROOCCOONNTTRROOLLAADDOORREESS CCOONN UUNNIIDDAADDEESS DDEE RRAADDIIOOFFRREECCUUEENNCCIIAA]]
UUNNIIVVEERRSSIIDDAADD AAUUTTÓÓNNOOMMAA MMEETTRROOPPOOLLIITTAANNAA IIZZTTAAPPAALLAAPPAA CCaarrllooss EErrnneessttoo MMoorreennoo EEssccoobbaarr 220011221144115599
‐ 92 ‐
* 9. PLL=RX PLL * 10. PA_POW=00h * 11. CAL: CAL_START=1 * 12 ESPERA 34 mS * 13. CAL: CAL_START=0 (ESTADO ORIGINAL) * 14. TERMINA * * FIGURA 16. PÁGINA 26. (DATASHEET DEL CC1000) ******************************************************************************/ LDI ADDRESS,AMAIN //INICIA CALIBRACIÓN LDI DATA,MAINRX // CALIBRAR RX PRIMERO RCALL WRITETOCC1000 LDI ADDRESS,ACURRENT LDI DATA,CURRENTRX RCALL WRITETOCC1000 LDI ADDRESS,APLL LDI DATA,PLLRX RCALL WRITETOCC1000 LDI ADDRESS,ACAL LDI DATA,CCAL RCALL WRITETOCC1000 RCALL WAIT34mS LDI DATA,CAL RCALL WRITETOCC1000 LDI ADDRESS,AMAIN // CALIBRAR TX LDI DATA,MAIN RCALL WRITETOCC1000 LDI ADDRESS,ACURRENT LDI DATA,CURRENT RCALL WRITETOCC1000 LDI ADDRESS,APLL LDI DATA,PLL RCALL WRITETOCC1000 LDI ADDRESS,APA_POW LDI DATA,CPA_POW RCALL WRITETOCC1000 LDI ADDRESS,ACAL LDI DATA,CCAL RCALL WRITETOCC1000 RCALL WAIT34mS LDI DATA,CAL RCALL WRITETOCC1000 //FIN DE LA CALIBRACIÓN LDI ADDRESS,AMAIN //PROGRAMAR MAIN EN MODO POWER DOWN LDI DATA,CMAIN RCALL WRITETOCC1000 LDI ADDRESS,APA_POW //POWER DOWN MODE: PA_POW=00h LDI DATA,CPA_POW RET /***************************************************************************** * FUNCIÓN: TURNONTX * ESTA SUBRUTINA HABILITA EL CC1000 PARA TRANSMISIÓN * * FIGURA 19 PÁGINA 30 (DATASHEET DEL CC1000) ****************************************************************************/ TURNONTX: LDI ADDRESS,AMAIN LDI DATA,TURNONMAIN1 RCALL WRITETOCC1000 RCALL WAIT2mS LDI DATA,TURNONMAIN2 RCALL WRITETOCC1000 RCALL WAIT250uS
[[CCOOMMUUNNIICCAACCIIÓÓNN AA NNIIVVEELL EENNLLAACCEE DDEE DDAATTOOSS EENNTTRREE MMIICCRROOCCOONNTTRROOLLAADDOORREESS CCOONN UUNNIIDDAADDEESS DDEE
RRAADDIIOOFFRREECCUUEENNCCIIAA]]
PPRROOYYEECCTTOO DDEE IINNGGEENNIIEERRÍÍAA EELLEECCTTRRÓÓNNIICCAA
UUNNIIVVEERRSSIIDDAADD AAUUTTÓÓNNOOMMAA MMEETTRROOPPOOLLIITTAANNAA IIZZTTAAPPAALLAAPPAA CCaarrllooss EErrnneessttoo MMoorreennoo EEssccoobbaarr 220011221144115599
‐ 93 ‐
LDI ADDRESS,APA_POW LDI DATA,CPA_POW RCALL WRITETOCC1000 LDI ADDRESS,AMAIN LDI DATA,MAIN RCALL WRITETOCC1000 LDI ADDRESS,ACURRENT LDI DATA,CURRENT RCALL WRITETOCC1000 LDI ADDRESS,APLL LDI DATA,PLL RCALL WRITETOCC1000 RCALL WAIT250uS LDI ADDRESS,APA_POW LDI DATA,PA_POW RCALL WRITETOCC1000 RCALL WAIT20uS RET /***************************************************************************** * FUNCIÓN: TURNOFFTX * ESTA SUBRUTINA DESHABILITA LA TRANSMISIÓN DEL CC1000 * * FIGURA 19 PÁGINA 30 (DATASHEET DEL CC1000) ****************************************************************************/ TURNOFFTX: LDI ADDRESS,AMAIN LDI DATA,TRN_OFF_TX RCALL WRITETOCC1000 LDI ADDRESS,APA_POW LDI DATA,$00 RCALL WRITETOCC1000 RET /***************************************************************************** * FUNCIÓN: TURNONRX * ESTA SUBRUTINA HABILITA EL CC1000 PARA RECEPCIÓN * * FIGURA 19 PÁGINA 30 (DATASHEET DEL CC1000) ****************************************************************************/ TURNONRX: LDI ADDRESS,AMAIN LDI DATA,TURNONMAIN1 RCALL WRITETOCC1000 RCALL WAIT2mS LDI DATA,TURNONMAIN2 RCALL WRITETOCC1000 RCALL WAIT250uS LDI ADDRESS,AMAIN LDI DATA,MAINRX RCALL WRITETOCC1000 LDI ADDRESS,ACURRENT LDI DATA,CURRENTRX RCALL WRITETOCC1000 LDI ADDRESS,APLL LDI DATA,PLLRX RCALL WRITETOCC1000 RCALL WAIT250uS RET /***************************************************************************** * FUNCIÓN: TURNOFFRX * ESTA SUBRUTINA DESHABILITA LA RECEPCIÓN DEL CC1000 * * FIGURA 19 PÁGINA 30 (DATASHEET DEL CC1000) ****************************************************************************/ TURNOFFRX:
PPRROOYYEECCTTOO DDEE IINNGGEENNIIEERRÍÍAA
EELLEECCTTRRÓÓNNIICCAA
[[CCOOMMUUNNIICCAACCIIÓÓNN AA NNIIVVEELL EENNLLAACCEE DDEE DDAATTOOSS EENNTTRREE MMIICCRROOCCOONNTTRROOLLAADDOORREESS CCOONN UUNNIIDDAADDEESS DDEE RRAADDIIOOFFRREECCUUEENNCCIIAA]]
UUNNIIVVEERRSSIIDDAADD AAUUTTÓÓNNOOMMAA MMEETTRROOPPOOLLIITTAANNAA IIZZTTAAPPAALLAAPPAA CCaarrllooss EErrnneessttoo MMoorreennoo EEssccoobbaarr 220011221144115599
‐ 94 ‐
LDI ADDRESS,AMAIN LDI DATA,TRN_OFF_RX RCALL WRITETOCC1000 LDI ADDRESS,APA_POW LDI DATA,$00 RCALL WRITETOCC1000 RET /***************************************************************************** * FUNCIÓN: WRITETOCC1000 * ESTA SUBRUTINA PRIMERO HABILITA EL PALE DEL CC1000, POSTERIORMENTE * TRANSMITE LA DIRECCIÓN HACIA EL CC1000 Y EL DATO A GRABAR EN LOS * REGISTROS DEL CC1000. * * EL ALGORITMO ES EL SIGUIENTE: * 1. PALE=1 * 2. GENERAR BIT DE R/W Y TRANSMITIR DIRECCIÓN AL CC1000. * 3. PALE=0 * 4. TRANSMITIR DATO * 5. REGRESO DE SUBRUTINA * * FIGURA 19 PÁGINA 30 (DATASHEET DEL CC1000) ****************************************************************************/ WRITETOCC1000: CBI PORTB,PALE //HABILITACIÓN DEL PROGRAM ADDRES LATCH MOV SPIDR,ADDRESS //CARGA LA DIRECCIÓN DEL REGISTRO MAIN SEC ROL SPIDR // BIT DE ESCRITURA (R/W) RCALL RW_SPI //TRANSMITIR LA DIRECCIÓN SBI PORTB,PALE //DESHABILITA EL PROGRAM ADDRES LATCH MOV SPIDR,DATA RCALL RW_SPI //TRANSMITIR DATO RET /***************************************************************************** * FUNCIÓN: AVER_AUTO * ESTA SUBRUTINA CONFIGURA EL MODO AUTOMÁTICO PARA DETECTAR EL PREÁMBULO * * TABLA 4 PÁGINA 20 (DATASHEET DEL CC1000) ****************************************************************************/ AVER_AUTO: LDI ADDRESS,AMODEM1 LDI DATA,AUTOMATICO RCALL WRITETOCC1000 RET /***************************************************************************** * FUNCIÓN: AVER_BLOQ * ESTA SUBRUTINA BLOQUEA MANUALMENTE EL FILTRO PROMEDIO * * TABLA 4 PÁGINA 20 (DATASHEET DEL CC1000) *****************************************************************************/ AVER_BLOQ: LDI ADDRESS,AMODEM1 LDI DATA,BLOQUEAR RCALL WRITETOCC1000 RET /***************************************************************************** * FUNCIÓN: AVER_DESBLOQ * ESTA SUBRUTINA DESBLOQUEA MANUALMENTE EL FILTRO PROMEDIO * * TABLA 4 PÁGINA 20 (DATASHEET DEL CC1000) ****************************************************************************/ AVER_DESBLOQ: LDI ADDRESS,AMODEM1 LDI DATA,DESBLOQUEAR
[[CCOOMMUUNNIICCAACCIIÓÓNN AA NNIIVVEELL EENNLLAACCEE DDEE DDAATTOOSS EENNTTRREE MMIICCRROOCCOONNTTRROOLLAADDOORREESS CCOONN UUNNIIDDAADDEESS DDEE
RRAADDIIOOFFRREECCUUEENNCCIIAA]]
PPRROOYYEECCTTOO DDEE IINNGGEENNIIEERRÍÍAA EELLEECCTTRRÓÓNNIICCAA
UUNNIIVVEERRSSIIDDAADD AAUUTTÓÓNNOOMMAA MMEETTRROOPPOOLLIITTAANNAA IIZZTTAAPPAALLAAPPAA CCaarrllooss EErrnneessttoo MMoorreennoo EEssccoobbaarr 220011221144115599
‐ 95 ‐
RCALL WRITETOCC1000 RET /***************************************************************************** * FUNCIÓN: RESET_AVFILTER * ESTA SUBRUTINA RESETEA EL FILTRO PROMEDIO * * PÁGINA 19 (DATASHEET DEL CC1000) ****************************************************************************/ ESET_AVFILTER: LDI ADDRESS,AMODEM1 LDI DATA,RESETAVFILTER RCALL WRITETOCC1000 RCALL AVER_DESBLOQ RET /***************************************************************************** * FUNCIÓN: * LEERCC1000 * * DESCRIPCIÓN: * * ESTA SUBRUTINA LEE DE LA MEMORIA RAM LAS DIRECCIONES DE LOS REGISTROS QUE * VAN A SER LEIDOS. EL CC1000 REGRESA EL CONTENIDO Y LOS ALMACENA EN LA * MEMORIA RAM (EN LA DIRECCIÓN 60+(2*N) * ALGORITMO: * 1. APUNTAR A LAS DIRECCIONES DE LOS REGISTROS * 2. PALE=1 * 3. HABILITAR LECTURA Y TRANSMITIR DIRECCIÓN * 4. PALE=0 * 5. LEER CONTENIDO DE LOS REGISTROS * 6. ALMACENAR DATOS REGRESADOS POR EL CC10000 EN LA RAM ($60+(2*N)) * * ESTA SUBRUTINA SE EJECUTA 21 VECES (YA QUE SON 21 REGISTROS) * LAS DIRECCIONES COMIENZAN EN LA DIRECCIÓN DE LA RAM $60 ******************************************************************************/ LEERCC1000: CLR XH LDI XL,$60 //APUNTADOR A LAS DIRECCIONES CLR YH LDI YL,$60+N //APUNTADOR A LOS DATOS READTXRX: CBI PORTB,PALE //HABILITACIÓN DEL PROGRAM ADDRES LATCH LD SPIDR,X+ //CARGA LA DIRECCIÓN DEL REGISTRO DE CONFIGURACIÓN CLC ROL SPIDR RCALL RW_SPI //TRANSMITIR LA DIRECCIÓN SBI PORTB,PALE //DESHABILITA EL PROGRAM ADDRES LATCH CBI DDRB,MOSI CLR SPIDR //CARGA EL DATO RCALL RW_SPI //TRANSMITIR EL DATO ST Y+,SPIDR SBI DDRB,MOSI CPI YL,$60+(2*N) //FINAL DE LOS DATOS? BRNE READTXRX SBI DDRB,MOSI RET /*************************************************************************** * FUNCIONES: * "WAIT34mS", "WAIT2mS", "WAIT250uS" Y "WAIT20uS" * * DESCRIPCION: * LOS DELAY REQUERIDOS PARA LA CONFIGURACIÓN DEL CC1000 SE REALIZARON * CON LA AYUDA DEL TIMER COUNTER 0. LA UTILIZACIÓN DEL TIMER NOS * PERMITE LIBERAR REGISTROS QUE PUEDEN SER UTILIZADOS POSTERIORMENTE. * EL TIMER COUNTER ES MUCHO MAS PRECISO.
PPRROOYYEECCTTOO DDEE IINNGGEENNIIEERRÍÍAA
EELLEECCTTRRÓÓNNIICCAA
[[CCOOMMUUNNIICCAACCIIÓÓNN AA NNIIVVEELL EENNLLAACCEE DDEE DDAATTOOSS EENNTTRREE MMIICCRROOCCOONNTTRROOLLAADDOORREESS CCOONN UUNNIIDDAADDEESS DDEE RRAADDIIOOFFRREECCUUEENNCCIIAA]]
UUNNIIVVEERRSSIIDDAADD AAUUTTÓÓNNOOMMAA MMEETTRROOPPOOLLIITTAANNAA IIZZTTAAPPAALLAAPPAA CCaarrllooss EErrnneessttoo MMoorreennoo EEssccoobbaarr 220011221144115599
‐ 96 ‐
* PARA LAS FUNCIONES DE 34 mS, 2mS Y 250uS SE UTILIZÓ EL PREESCALADOR * DIVIDIENDO ENTRE 1024 EL RELOJ DEL SISTEMA. PARA EL DELAY DE 20uS * SE UTILIZÓ EL PREESCALADOR CLK/1. LOS DELAYS UTILIZAN OTRAS DOS * FUNCIONES AUXILIARES, LAS CUALES INICIAN/LIMPIAN LA CONFIGURACION * DEL TIMER COUNTER 0. * NOTA: NO SE GENERA NINGUN TIPO DE INTERRUPCIÓN, UNICAMENTE SE * VERIFICA LA BANDERA DE COMPARACIÓN PARA SALIR DE LOS BUCLES. * * 20 uSEGUNDOS * 250 uSEGUNDOS * 2 mSEGUNDOS * 34 mSEGUNDOS ***************************************************************************/ WAIT34mS: LDI TEMP,$85 // CARGAR REGISTRO DE COMPARACION CON $85 OUT OCR0,TEMP RCALL INIT_COUNTER // INICIALIZAR TIMER COUNTER 0 LOOP17mS: // ESPERA 17mS IN TEMP,TIFR // BANDERA DE COMPARACION ENCENDIDA? SBRS TEMP,OCF0 // NO: ESPERA LA BANDERA RJMP LOOP17mS // SI: CONTINUA EJECUCION LDI TEMP,(1<<OCF0) //LIMPIAR BANDERA DE COMPARACION OUT TIFR,TEMP CLR TEMP //BORRAR TIMER COUNTER OUT TCNT0,TEMP LOOP34mS: //ESPERA OTROS 17mS IN TEMP,TIFR //OTRA VEZ COMIENZA EL CICLO SBRS TEMP,OCF0 RJMP LOOP34mS RCALL CLR_COUNTER //LIMPIAR TIMER COUNTER RET WAIT2mS: LDI TEMP,$10 OUT OCR0,TEMP RCALL INIT_COUNTER LOOP2mS: IN TEMP,TIFR SBRS TEMP,OCF0 RJMP LOOP2mS RCALL CLR_COUNTER RET WAIT250uS: LDI TEMP,$02 OUT OCR0,TEMP RCALL INIT_COUNTER LOOP250uS: IN TEMP,TIFR SBRS TEMP,OCF0 RJMP LOOP250uS RCALL CLR_COUNTER RET WAIT20uS: LDI TEMP,$A0 OUT OCR0,TEMP LDI TEMP,(0<<CS02)|(1<<CS00) //SIN PREESCALADOR OUT TCCR0,TEMP CLR TEMP OUT TCNT0,TEMP LDI TEMP,(1<<OCF0) OUT TIFR,TEMP LOOP20uS: IN TEMP,TIFR SBRS TEMP,OCF0
[[CCOOMMUUNNIICCAACCIIÓÓNN AA NNIIVVEELL EENNLLAACCEE DDEE DDAATTOOSS EENNTTRREE MMIICCRROOCCOONNTTRROOLLAADDOORREESS CCOONN UUNNIIDDAADDEESS DDEE
RRAADDIIOOFFRREECCUUEENNCCIIAA]]
PPRROOYYEECCTTOO DDEE IINNGGEENNIIEERRÍÍAA EELLEECCTTRRÓÓNNIICCAA
UUNNIIVVEERRSSIIDDAADD AAUUTTÓÓNNOOMMAA MMEETTRROOPPOOLLIITTAANNAA IIZZTTAAPPAALLAAPPAA CCaarrllooss EErrnneessttoo MMoorreennoo EEssccoobbaarr 220011221144115599
‐ 97 ‐
RJMP LOOP20uS RCALL CLR_COUNTER RET /*************************************************************************** * FUNCIONES: * "INIT_COUNTER" Y "CLR_COUNTER" * * DESCRIPCION: * ESTAS FUNCIONES SON UTILIZADAS PARA CONFIGURAR EL TIMER COUNTER 0 * Y PARA REESTABLECER SU CONFIGURACIÓN INICIAL. SOLO SE UTILIZA EN LOS * DELAYS!!. * ***************************************************************************/ INIT_COUNTER: LDI TEMP,(1<<CS02)|(1<<CS00) //CLK/1024(101) OUT TCCR0,TEMP CLR TEMP OUT TCNT0,TEMP LDI TEMP,(1<<OCF0) OUT TIFR,TEMP RET CLR_COUNTER: CLR TEMP OUT TCCR0,TEMP OUT TCNT0,TEMP LDI TEMP,(1<<OCF0) OUT TIFR,TEMP RET /***************************************************************************** *********** F I N D E F U N C . D E C O N F I G U R A C I Ó N ******** ******************************************************************************/ /***************************************************************************** ************** F U N C I O N E S P A R A T X Y R X ****************** ******************************************************************************/ //DEFINICIONES DEL PUERTO .EQU DCLK = PD2 //PD2 PIN .EQU DIO = PD4 //PD4 PIN .EQU CHIP = 98 //TRANSMITIR/RECIBIR 98 BITS DE PREAMBULO /*************************************************************************** * FUNCION: * ENVIA_PREAMBULO * * DESCRIPCIÓN: * ESTA FUNCIÓN GENERA Y TRANSMITE EL PREÁMBULO REQUERIDO POR EL CC1000. * TRANSMITE 196 BITS (CHIP=196) CON EL PATRÓN: '01010101...'. * CADA FLANCO DE SUBIDA DEL DCLK DEL CC1000 GENERA LA INTERRUPCION * EXTERNA INT0, EN ESE MOMENTO SE TRANSMITE EL BIT POR PD4. ****************************************************************************/ ENVIA_PREAMBULO: LDI HBYTE,0B11000111 RCALL ENVIA_BYTE LDI MODO,MODOTXPRE //MODO: GENERA Y TRANSMITE PREAMBULO SBI DDRD,DIO //PD4=SALIDA DEL BIT A TRANSMITIR LDI CONT,CHIP //CONT=CHIP LDI HBYTE,$01 LDI TEMP,1<<INTF0 OUT GIFR,TEMP //LIMPIA INTE. PENDIENTES LDI TEMP,1<<INT0 OUT GICR,TEMP //HABILITA INT. EXTERNA 0 LDI TEMP,1<<OCF1B OUT TIFR,TEMP ESPERATXPRE: CPI CONT,0 //CONT='0' ?
PPRROOYYEECCTTOO DDEE IINNGGEENNIIEERRÍÍAA
EELLEECCTTRRÓÓNNIICCAA
[[CCOOMMUUNNIICCAACCIIÓÓNN AA NNIIVVEELL EENNLLAACCEE DDEE DDAATTOOSS EENNTTRREE MMIICCRROOCCOONNTTRROOLLAADDOORREESS CCOONN UUNNIIDDAADDEESS DDEE RRAADDIIOOFFRREECCUUEENNCCIIAA]]
UUNNIIVVEERRSSIIDDAADD AAUUTTÓÓNNOOMMAA MMEETTRROOPPOOLLIITTAANNAA IIZZTTAAPPAALLAAPPAA CCaarrllooss EErrnneessttoo MMoorreennoo EEssccoobbaarr 220011221144115599
‐ 98 ‐
BREQ SALIDA_EP // FIN DE LA SUBRUTINA RJMP ESPERATXPRE //CONTINUA TRANSMITIENDO SALIDA_EP: RET /*************************************************************************** * FUNCION: * ESPERA_PREAMBULO * * DESCRIPCION: * ESTA SUBRUTINA VALIDA EL PREAMBULO RECIBIDO. EL PREÁMBULO RECIBIDO * DEBE CONTAR CON 196 BITS CON UN PATRON: '01010101...'. DE OTRO MODO * SERÁ CONSIDERADO COMO UN PREAMBULO INVÁLIDO. LOS DATOS * RECIBIDOS SE INTRODUCEN POR EL PIN PD4 (DIO). UNA VEZ QUE EL * PREAMBULO CORRECTO SE HAYA RECIBIDO, SE SALDRÁ DE ESTA SUBRUTINA. * POR OTRO LADO, SI EL PREAMBULO NO ES EL CORRECTO, EL PROGRAMA * PERMANECERÁ EN ESTA SUBRUTINA HASTA QUE SE RECIBA EL PREAMBULO VALIDO ****************************************************************************/ ESPERA_PREAMBULO: LDI MODO,MODORXPRE //MODO: RECIBIR PREAMBULO LDI CONT,CHIP CBI DDRD,DIO //PD4 (DIO)COMO ENTRADA SBI PORTD,DIO LDI TEMP,1<<INTF0 OUT GIFR,TEMP //LIMPIA INTE. PENDIENTES LDI TEMP,1<<INT0 OUT GICR,TEMP //HABILITA INT. EXTERNA 0 CLR TEMP ESPERARXPRE: CPI ACUSE,$FF //TIMEOUT AGOTADO? BREQ FORZAR_SALIDA // ENTONCES FORZAR SALIDA PARA RETRANSMITIR CPI CONT,$00 //CONT='0'? BREQ SALIDA_WP // FIN DE LA SUBRUTINA RJMP ESPERARXPRE //CONTINUA TRANSMITIENDO SALIDA_WP: SBI PORTA,PRERECIBIDO //ENCIENDE BANDERA:"PREAMBULO VALIDO" RET FORZAR_SALIDA: RET /*************************************************************************** * FUNCION: * ENVIA_BYTE * * DESCRIPCION: * ESTA SUBRUTINA TRANSMITE EL BYTE CONTENIDO EN EL REGISTRO "HBYTE". * EL BIT A TRANSMITIR SE OBSERVA EN EL PIN PD4 CADA FLANCO DE * SUBIDA DEL RELOJ DCLK DEL CC1000 ****************************************************************************/ ENVIA_BYTE: LDI MODO,MODOTXDAT //MODO: TRANSMITIR BYTE LDI CONT,$08 //TRANSMITIR 8 BITS SBI DDRD,DIO //PD4 (DIO) SALIDA LDI TEMP,1<<INTF0 OUT GIFR,TEMP //LIMPIA INTE. PENDIENTES LDI TEMP,1<<INT0 OUT GICR,TEMP //HABILITA INT. EXTERNA 0 ESPERATXDAT: CPI CONT,$00 //CONT='0'? BREQ SALIDA_ED // FIN DE LA SUBRUTINA RJMP ESPERATXDAT //CONTINUA TRANSMITIENDO SALIDA_ED: RET /***************************************************************************
[[CCOOMMUUNNIICCAACCIIÓÓNN AA NNIIVVEELL EENNLLAACCEE DDEE DDAATTOOSS EENNTTRREE MMIICCRROOCCOONNTTRROOLLAADDOORREESS CCOONN UUNNIIDDAADDEESS DDEE
RRAADDIIOOFFRREECCUUEENNCCIIAA]]
PPRROOYYEECCTTOO DDEE IINNGGEENNIIEERRÍÍAA EELLEECCTTRRÓÓNNIICCAA
UUNNIIVVEERRSSIIDDAADD AAUUTTÓÓNNOOMMAA MMEETTRROOPPOOLLIITTAANNAA IIZZTTAAPPAALLAAPPAA CCaarrllooss EErrnneessttoo MMoorreennoo EEssccoobbaarr 220011221144115599
‐ 99 ‐
* FUNCION: * RECIBE_BYTE * * DESCRIPCIÓN: * ESTA SUBRUTINA RECIBE UN BYTE. EL DATO ES MUESTREADO EN EL PIN * PD4 (DIO) CADA FLANCO DE SUBIDA DEL DCLK. ****************************************************************************/ RECIBE_BYTE: LDI MODO,MODORXDAT //MODO: RECIBIR BYTE LDI CONT,$08 //RECIBIR 8 BITS ESPERARXDAT: CPI CONT,$00 //CONT='0'? BREQ SALIDA_RD // FIN DE LA SUBRUTINA RJMP ESPERARXDAT //CONTINUA TRANSMITIENDO SALIDA_RD: RET /***************************************************************************** ******** F I N D E F U N C I O N E S P A R A T X Y R X *********** ******************************************************************************/ /***************************************************************************** ******** F U N C I O N E S P A R A S T O P A N D W A I T *********** ******************************************************************************/ /*************************************************************************** * FUNCION: * "ENVIA_TRAMA" - ENVIAR UNA TRAMA DE DATOS DE 130 BYTES * * DESCRIPCION: * * ESTA SUBRUTINA LEE DE LA MEMORIA RAM LOS DATOS QUE VAN A SER * TRANSMITIDOS. * LOS DATOS VALIDOS A TRANSMITIR COMIENZAN EN LA DIRECCION $0062 * DE LA MEMORIA RAM. EN ESTA SUBRUTINA SE GENERA EL BYTE * IDENTIFICADOR DE SECUENCIA, EL CUAL SE VA LLENANDO CON LOS DATOS * $FF O $00,DEPENDIENDO DE EL CONTENIDO DEL REGISTRO SEQ (EL CUAL * SE INCREMENTA CADA QUE SE LLAMA A ESTA SUBRUTINA). EL IDENTIFICADOR * SE CARGA EN LA LOCALIDAD $0060 DE LA MEMORIA RAM. * * POSTERIORMENTE, SE GENERA Y ALMACENA EN LA LOCALIDAD $0061 DE LA * RAM EL BYTE DE INFORMACIÓN ($FF PARA TRAMA, $00 PARA EL ACUSE) * UNA VEZ REALIZADO ESTE PROCEDIMIENTO SE REALIZA LLAMADO A LA FUNCION * CRC_GEN, ESTA FUNCION GENERA EL CHECKSUM Y POSTERIORMENTE * ÉSTE ES ALMACENADO AL FINAL DE LOS DATOS A SER TRANSMITIDOS * EL CRC DE 16 BITS SE ALMACENAN EN LA LOC. $00E0 $00E1. * EL CHECKSUM TAMBIÉN ES TRANSMITIDO. * UNA VEZ TRANSMITIDOS TODOS LOS DATOS (INCLUYENDO EL CHECKSUM) * LA SUBRUTINA CONFIGURA EL CC1000 COMO TRANSMISOR Y ESPERA EL * ACUSE DE RECIBO, SI ÉSTE NO ES RECIBIDO DESPUÉS DE QUE EL TIMEOUT * DE ESPERA HAYA FINALIZADO, SE REENVIA LA INFORMACION. * LA BANDERA UTILIZADA PARA DETECTAR EL FIN DEL TIMEOUT ES EL * REGISTRO ACUSE. SI ESTE REGISTRO CONTIENE EL DATO $FF SIGNIFICA QUE * FINALIZÓ LA CUENTA Y NO SE RECIBIÓ EL ACUSE Y POR LO TANTO LA * TRAMA ES RETRANSMITIDA. EN OTRO CASO SE REGRESA DE LA SUBRUTINA. * **************************************************************************/ ENVIA_TRAMA: LDI XL,LOW(FIRST_RAM_ADDR) //INICIAR APUNTADORES A RAM (DATOS A LDI XH,HIGH(FIRST_RAM_ADDR) INC SEQ //GENERAR SECUENCIA $FF O $00 SBRS SEQ,0 // UTILIZANDO EL REGISTRO SEQ CLR TEMP //GENERAR SEQ. $00 SBRC SEQ,0 SER TEMP //GENERAR SEQ. $FF ST X+,TEMP //ALMACENAR SECUENCIA EN LA LOCALIDAD $0060 DE LA RAM
PPRROOYYEECCTTOO DDEE IINNGGEENNIIEERRÍÍAA
EELLEECCTTRRÓÓNNIICCAA
[[CCOOMMUUNNIICCAACCIIÓÓNN AA NNIIVVEELL EENNLLAACCEE DDEE DDAATTOOSS EENNTTRREE MMIICCRROOCCOONNTTRROOLLAADDOORREESS CCOONN UUNNIIDDAADDEESS DDEE RRAADDIIOOFFRREECCUUEENNCCIIAA]]
UUNNIIVVEERRSSIIDDAADD AAUUTTÓÓNNOOMMAA MMEETTRROOPPOOLLIITTAANNAA IIZZTTAAPPAALLAAPPAA CCaarrllooss EErrnneessttoo MMoorreennoo EEssccoobbaarr 220011221144115599
‐ 100 ‐
CLR TEMP ST X+,TEMP //INTRODUCIR INFORMACION ($00=DATOS, $FF=ACUSE) //AQUI SOLO SE TRANSMITE EL DATO $00 CLR MODO //LIMPIAR REGISTRO MODO, PREPARAR GENERACION DEL CRC RCALL CRC_GEN //OBTENER CHECKSUM DE LOS DATOS ALMACENADOS EN RAM RETRANSMITIR: RCALL TURNONTX //ACTIVAR MODO TRANSMISION RCALL ENVIA_PREAMBULO LDI XL,LOW(FIRST_RAM_ADDR) //INICIAR APUNTADORES A RAM (DATOS A LDI XH,HIGH(FIRST_RAM_ADDR) // TRANSMITIR) TX_TRAMA: //ETAPA DE TRANSMISIÓN LD HBYTE,X+ //CARGAR HBYTE CON EL CONTENIDO DE X RCALL ENVIA_BYTE // Y TRANSMITIR EL DATO CPI XL,LOW(LAST_RAM_ADDR)+3 BRNE TX_TRAMA // DATOS TRANSMITIDOS? LDI TEMP,0<<INT0 // NO, REGRESA OUT GICR,TEMP //DESHABILITA INT. EXTERNA 0 RCALL TURNOFFTX RCALL RECIBE_ACUSE //LLAMADO A FUNCION PARA RECIBIR ACUSE CPI ACUSE,$FF //FINALIZÓ EL TIME OUT Y NO RECIBE ACUSE... //... O EL ACUSE ESTA DAÑADO? BREQ RETRANSMITIR // SI, ENONCES RETRANSMITE RET // OTRO, REGRESA /*************************************************************************** * * FUNCION: * "RECIBE_TRAMA" - RECIBIR UNA TRAMA DE DATOS DE 130 BYTES * * DESCRIPCION: * * ESTA SUBRUTINA RECIBE UNA TRAMA DE 130 BYTES (2 BYTES DE INFORMACION, * 126 DE DATOS Y 2 DE CRC), * CADA DATO ES ALMACENADO EN UN BUFFER TEMPORAL DE LA MEMORIA RAM * APARTIR DE LA DIRECCIÓN $0060 A LA $00E1. * ESTA SUBRUTINA CONFIGURA EL CC1000 COMO RECEPTOR, POSTERIORMENTE * SE RECIBE EL PREAMBULO Y LOS DATOS VÁLIDOS SON RECIBIDOS. * UNA VEZ QUE LOS DATOS SON ALAMACENADOS, SE LLAMA A LA FUNCION * CRC_GEN DONDE SE REALIZA LA VERIFICACION DEL CHECKSUM. * SI LOS DATOS CONTIENEN ERRORES SE REINICIALIZA LA FUNCION. PARA ESPERAR * LA RETRANSMISIÓN. * POR OTRO LADO, SI LOS DATOS SON CORRECTOS, ESTOS SE COPIAN A OTRA * LOCALIDAD DE MEMORIA FIJA PARA QUE NO SEAN SOBRESCRITOS. EN ESTA SECCION * DE LA MEMORIA UNICAMENTE SE ALMACENAN LOS 126 BYTES DE DATOS. LA * SECCIÓN DE MEMORIA UTILIZADA ES DE LA LOC. $00E2 A LA $0160. * UNA VEZ REALIZADO ESTO, EL CC1000 SE CONFIGURA COMO * TRANSMISOR Y SE ENVIA EL ACUSE. * * NOTA: SI SE DETECTA UNA TRAMA DUPLICADA, SE ENCIENDE LA BANDERA T * DEL STATUS REGISTER (MEDIANTE LA INSTRUCCIÓN "SET"), POR EL * CONTRARIO, SI LA TRAMA ES CORRECTA, SE APAGA DICHA BANDERA. * LA BANDERA ES UTILIZADA PARA VALIDAR DATOS Y NO SOBREESCRIBIR * DATOS VÁLIDOS. VERIFICAR EL PROGRAMA DE EJEMPLO PARA UNA * MEJOR COMPRENSIÓN (RECEPTOR). * **************************************************************************/ RECIBE_TRAMA: LDI XL,LOW(FIRST_RAM_ADDR) //INICIAR APUNTADORES AL BUFFER PARA... LDI XH,HIGH(FIRST_RAM_ADDR) //...PARA RECIBIR LOS DATOS RCALL TURNONRX RCALL ESPERA_PREAMBULO // ESPRE PREAMBULO VALIDO RCALL RECIBE_BYTE //PRIMERO RECIBE LA SECUENCIA ST X+,HBYTE //ALMACENAR SECUENCIA RECIBIDA EN $0060
[[CCOOMMUUNNIICCAACCIIÓÓNN AA NNIIVVEELL EENNLLAACCEE DDEE DDAATTOOSS EENNTTRREE MMIICCRROOCCOONNTTRROOLLAADDOORREESS CCOONN UUNNIIDDAADDEESS DDEE
RRAADDIIOOFFRREECCUUEENNCCIIAA]]
PPRROOYYEECCTTOO DDEE IINNGGEENNIIEERRÍÍAA EELLEECCTTRRÓÓNNIICCAA
UUNNIIVVEERRSSIIDDAADD AAUUTTÓÓNNOOMMAA MMEETTRROOPPOOLLIITTAANNAA IIZZTTAAPPAALLAAPPAA CCaarrllooss EErrnneessttoo MMoorreennoo EEssccoobbaarr 220011221144115599
‐ 101 ‐
RX_TRAMA: RCALL RECIBE_BYTE // RECIBIR TODA LA TRAMA.. ST X+,HBYTE //...Y ALMACENARLA EN EL BUFFER CPI XL,LOW(LAST_RAM_ADDR)+3 BRNE RX_TRAMA LDI TEMP,0<<INT0 OUT GICR,TEMP //DESHABILITA INT. EXTERNA 0 RCALL TURNOFFRX //DESHABILITA MODO DE RECEPCION SER MODO //MODO=0XFF, PREPARA CHEQUEO DE CRC RCALL CRC_GEN //CHECA CRC CLR TEMP CPSE CRC,TEMP //CHECKSUM RESULTANTE = $00? SBI PORTA,CRCERROR // ENCIENDE BANDERA: "ERROR EN EL CHECKSUM" CPSE CRC,TEMP //CHECKSUM RESULTANTE = $00? RJMP RECIBE_TRAMA // SI, ENTONCES ESPERAR TRAMA NUEVAMENTE CBI PORTA,CRCERROR //APAGA BANDERA:"CHECKSUM CORRECTO" LDI XL,LOW(FIRST_RAM_ADDR) //CARGAR SECUENCIA RECIBIDA LDI XH,HIGH(FIRST_RAM_ADDR) LD HBYTE,X //CARGAR SECUENCIA RECIBIDA CP SEQ,HBYTE //TRAMA DUPLICADA? BREQ TRAMA_DUPLICADA // SI: TRAMA DUPLICADA (ENVIAR ACUSE UNICAMENTE) MOV SEQ,HBYTE // NO: ALMACENAR TRAMA EN "SEQ" Y CONTINUAR RCALL ENVIA_ACUSE // ENVIA EL ACUSE CLT //LIMPIAR BANDERA T (TRAMA CORRECTA) CBI PORTA,PACKDUPLI //APAGA BANDERA "TRAMA DUPLICADA" LDI XL,LOW(FIRST_RAM_ADDR)+2 //INICIAR APUNTADORES AL BUFFER PARA... LDI XH,HIGH(FIRST_RAM_ADDR) //...PARA MOVER LOS DATOS LDI YL,$E2 LDI YH,$00 ST_DATA: //MOVER LOS DATOS RECIBIDOS A LA SECCIÓN... LD TEMP,X+ //...FIJA ST Y+,TEMP CPI YL,$60 BREQ COMPYH RJMP ST_DATA COMPYH: CPI YH,$01 BRNE ST_DATA RET TRAMA_DUPLICADA: //TRAMA DUPLICADA: ENVIAR ACUSE ANTERIOR SET //BANDERA T= '1'-> TRAMA DUPLICADA SBI PORTA,PACKDUPLI //ENCIENDE BANDERA: TRAMA DUPLICADA LDI TEMP,0<<INT0 OUT GICR,TEMP //DESHABILITA INT. EXTERNA 0 RCALL TURNOFFRX //DESHABILITA MODO DE RECEPCION RCALL ENVIA_ACUSE //ENVIA EL ACUSE RET /*************************************************************************** * * FUNCION: * "ENVIA_ACUSE" - RENVIAR UN ACUSE DE RECIBO * * DESCRIPCION: * * CONFIGURAR EL CC1000 COMO TRANSMISOR Y ENVIA PREAMBULO. DESPUES DE * ESTO SE LEE LA PRIMERA LOCALIDAD DE LA RAM ($0060) EN LA CUAL SE * ENCUENTRA EL IDENTIFICADOR DE SECUENCIA. * * EL CRC PARA EL ACUSE PUEDE SER PRECALCULADO, YA QUE * SE TRATA ÚNICAMENTE DE DOS SECUENCIAS DIFERENTES. A CONTINUACIÓN
PPRROOYYEECCTTOO DDEE IINNGGEENNIIEERRÍÍAA
EELLEECCTTRRÓÓNNIICCAA
[[CCOOMMUUNNIICCAACCIIÓÓNN AA NNIIVVEELL EENNLLAACCEE DDEE DDAATTOOSS EENNTTRREE MMIICCRROOCCOONNTTRROOLLAADDOORREESS CCOONN UUNNIIDDAADDEESS DDEE RRAADDIIOOFFRREECCUUEENNCCIIAA]]
UUNNIIVVEERRSSIIDDAADD AAUUTTÓÓNNOOMMAA MMEETTRROOPPOOLLIITTAANNAA IIZZTTAAPPAALLAAPPAA CCaarrllooss EErrnneessttoo MMoorreennoo EEssccoobbaarr 220011221144115599
‐ 102 ‐
* SE MUESTRA LAS SECEUNCIAS. * * # SECUENCIA TIPO (ACUSE O DATOS) CRC * RECIBIDA * SEQ 1 -> 00000000 11111111 00000010 00000010 $0202 * SEQ 2 -> 11111111 11111111 00001101 10000000 $0D80 * **************************************************************************/ .EQU SEQ1CL =$02 //BYTE BAJO DEL CRC DE SECUENCIA 1 .EQU SEQ1CH =$02 //BYTE ALTO DEL CRC DE SECUENCIA 1 .EQU SEQ2CL =$0D //BYTE BAJO DEL CRC DE SECUENCIA 2 .EQU SEQ2CH =$80 //BYTE ALTO DEL CRC DE SECUENCIA 2 ENVIA_ACUSE: RCALL TURNONTX RCALL ENVIA_PREAMBULO LDI XL,LOW(FIRST_RAM_ADDR) //INICIAR APUNTADORES A RAM LDI XH,HIGH(FIRST_RAM_ADDR) LD HBYTE,X PUSH HBYTE //ALMACENAR EL BYTE DE SECUENCIA RCALL ENVIA_BYTE //TRANSMITIR SECUENCIA RECIBIDA SER HBYTE RCALL ENVIA_BYTE //TRANSMITIR TIPO (ACUSE=$FF) POP TEMP //RESTAURAR EL BYTE DE SECUENCIA CPI TEMP,$FF //SECUENCIA $FF? BREQ CRCSEQ2 // SI: ENVIA CRC DE LA SEC. 2 CRCSEQ1: LDI HBYTE,SEQ1CL // OTRO: ENVIA CRC DE LA SEC. 1 RCALL ENVIA_BYTE LDI HBYTE,SEQ1CH RCALL ENVIA_BYTE RJMP ACUSE_ENVIADO CRCSEQ2: LDI HBYTE,SEQ2CL RCALL ENVIA_BYTE LDI HBYTE,SEQ2CH RCALL ENVIA_BYTE ACUSE_ENVIADO: RCALL TURNOFFTX //DESHABILITA TX LDI TEMP,0<<INT0 OUT GICR,TEMP //DESHABILITA INT. EXTERNA 0 RET /*************************************************************************** * * FUNCION: * "RECIBE_ACUSE" - ESPERAR UN ACUSE DE RECIBO * * DESCRIPCION: * * CONFIGURAR EL CC1000 COMO RECEPTOR, ESPERAR UN PREAMBULO VALIDO, * Y RECIBIR EL ACUSE DE RECIBO. * **************************************************************************/ // SEQ1CL =$02 //BYTE BAJO DEL CRC DE SECUENCIA 1 // SEQ1CH =$02 //BYTE ALTO DEL CRC DE SECUENCIA 1 // SEQ2CL =$0D //BYTE BAJO DEL CRC DE SECUENCIA 2 // SEQ2CH =$80 //BYTE ALTO DEL CRC DE SECUENCIA 1 RECIBE_ACUSE: SBI PORTA,ESPERAACUSE //ENCIENDE BANDERA: "ESPERANDO ACUSE" RCALL TURNONRX //ENCIENDE TRANSMISIÓN RCALL START_TIMER //INICIA TIMEOUT CLR ACUSE //LIMPIA BANDERA DE TIME OUT
[[CCOOMMUUNNIICCAACCIIÓÓNN AA NNIIVVEELL EENNLLAACCEE DDEE DDAATTOOSS EENNTTRREE MMIICCRROOCCOONNTTRROOLLAADDOORREESS CCOONN UUNNIIDDAADDEESS DDEE
RRAADDIIOOFFRREECCUUEENNCCIIAA]]
PPRROOYYEECCTTOO DDEE IINNGGEENNIIEERRÍÍAA EELLEECCTTRRÓÓNNIICCAA
UUNNIIVVEERRSSIIDDAADD AAUUTTÓÓNNOOMMAA MMEETTRROOPPOOLLIITTAANNAA IIZZTTAAPPAALLAAPPAA CCaarrllooss EErrnneessttoo MMoorreennoo EEssccoobbaarr 220011221144115599
‐ 103 ‐
RCALL ESPERA_PREAMBULO //ESPERA PREAMBULO DEL ACUSE RCALL RECIBE_BYTE // RECIBE SECUENCIA ENVIADA MOV BYTE_0,HBYTE RCALL RECIBE_BYTE // RECIBE TIPO (ACUSE=$FF) MOV BYTE_1,HBYTE RCALL RECIBE_BYTE // RECIBE CRC BYTE BAJO MOV BYTE_2,HBYTE RCALL RECIBE_BYTE // RECIBE CRC BYTE ALTO MOV BYTE_3,HBYTE RCALL STOP_TIMER // ACUSE RECIBIDO, DETENER CONTADOR LDI TEMP,0<<INT0 //DESHABILITAR INT0 OUT GICR,TEMP RCALL TURNOFFRX CPI ACUSE,$FF //TIEMPO AGOTADO? BREQ ACK_ERROR // FORZAR SALIDA PARA RETRANSMITIR // PRIMERO VERIFICAR EL CRC DEL ACUSE // CON EL BYTE ALTO ES SUFICIENTE LDI TEMP,SEQ2CH CP TEMP, BYTE_3 //CRC BYTE ALTO DE LA SEC. 2 CORRECTO? BREQ VERIF_SEQ LDI TEMP,SEQ1CH CP TEMP, BYTE_3 //CRC BYTE ALTO DE LA SEC. 1 CORRECTO? BREQ VERIF_SEQ RJMP ACK_ERROR // DESPUES VERIFICAR LA SECUENCIA DEL ACUSE, // DEBE SER IGUAL A LA TRANSMITIDA VERIF_SEQ: LDI XL,LOW(FIRST_RAM_ADDR) //INICIAR APUNTADORES A RAM LDI XH,HIGH(FIRST_RAM_ADDR) //CARGAR BYTE DE SECUENCIA TRANSMITIDA LD TEMP,X // DE LA LOCALIDAD $0060 CP TEMP,BYTE_0 BRNE ACK_ERROR //LISTO! ACUSE VÁLIDO ACK_CRC_OK: CBI PORTA,ESPERAACUSE //APAGAR BANDERA: "ESPERANDO ACUSE" RET //ERROR EN EL ACUSE ACK_ERROR: // ACUSE CON ERRORES O SECUENCIA ILEGAL? SER ACUSE // ACUSE=$FF (FORZAR RETRANSMISIÓN) CBI PORTA,ESPERAACUSE //APAGAR BANDERA: "ESPERANDO ACUSE" RET /*************************************************************************** * * FUNCION: * "START_TIMER" Y "STOP_TIMER" * * DESCRIPCION: * * INICIALIZAR TIMER COUNTER 1 Y LA INTERRUPCIÓN POR COMPARACIÓN * REGISTROS DE COMPARACIÓN: OCR1BL Y OCR1BH. * * FUNCION: * "STOP_TIMER" * * DESCRIPCION: * * DESHABILITAR EL TIMER COUNTER 1 Y LA INTERRUPCIÓN POR COMPARACIÓN * REGISTROS DE COMPARACIÓN: OCR1BL Y OCR1BH * **************************************************************************/ .EQU OCBL = $96 .EQU OCBH = $01 .EQU TIMERPRE = $05 // PREESCALADOR CLK/1024=$05, CLK/1=$01
PPRROOYYEECCTTOO DDEE IINNGGEENNIIEERRÍÍAA
EELLEECCTTRRÓÓNNIICCAA
[[CCOOMMUUNNIICCAACCIIÓÓNN AA NNIIVVEELL EENNLLAACCEE DDEE DDAATTOOSS EENNTTRREE MMIICCRROOCCOONNTTRROOLLAADDOORREESS CCOONN UUNNIIDDAADDEESS DDEE RRAADDIIOOFFRREECCUUEENNCCIIAA]]
UUNNIIVVEERRSSIIDDAADD AAUUTTÓÓNNOOMMAA MMEETTRROOPPOOLLIITTAANNAA IIZZTTAAPPAALLAAPPAA CCaarrllooss EErrnneessttoo MMoorreennoo EEssccoobbaarr 220011221144115599
‐ 104 ‐
START_TIMER: LDI TEMP,OCBL OUT OCR1BL,TEMP //CARGAR PALABRA ALTA EN REG. DE COMPARACION LDI TEMP,OCBH OUT OCR1BH,TEMP //CARGAR PALABRA BAJA EN REG. DE COMPARACION LDI TEMP,1<<OCF1B //LIMPIAR BANDERAS PENDIENTES (SOLO POR... OUT TIFR,TEMP // ...PRECAUCION) LDI TEMP,1<<OCIE1B OUT TIMSK,TEMP // Y POR ULTIMO... HABILITAR INTERRUPCION... CLR TEMP OUT TCNT1H,TEMP //INICIALIZAR TIMER COUNTER 1 (PALABRA.. OUT TCNT1l,TEMP // ..ALTA Y PALABRA BAJA) LDI TEMP,TIMERPRE //AJUSTAR EL PREESCALADOR DEL TIMER COUNTER OUT TCCR1B,TEMP RET // .. POR COMPARACION STOP_TIMER: CLR TEMP //DESHABILITAR EL PREESCALADOR OUT TCCR1B,TEMP LDI TEMP,1<<OCF1B //LIMPIAR BANDERAS PENDIENTES OUT TIFR,TEMP LDI TEMP,0<<OCIE1B //DESHABILITAR INTERRUPCIÓN OUT TIMSK,TEMP RET /***************************************************************************** ** F I N D E F U N C I O N E S P A R A S T O P A N D W A I T *** ******************************************************************************/ RESET: LDI TEMP,LOW(RAMEND) //INICIALIZA APUNTADORES A LA PILA OUT SPL,TEMP LDI TEMP,HIGH(RAMEND) OUT SPH,TEMP SER TEMP OUT DDRC,TEMP OUT DDRA,TEMP //PUERTO A COMO SALIDA (BANDERAS) SBI DDRB,PALE SBI PORTB,PALE //INICIALIZAR SPI (POR SOFTWARE) SBI PORTB,SCK //ENCIENDE EL SCK (CKPOL=1) SBI DDRB,SCK //ES SALIDA CBI PORTB,MOSI //MOSI=0 SBI DDRB,MOSI //ES SALIDA SBI PORTB,MOSI CBI DDRB,MISO //MISO ES ENTRADA SBI PORTD,DCLK LDI TEMP,(1<<ISC01)|(1<<ISC00) //INTERRUPCION POR FLANCO DE SUBIDA OUT MCUCR,TEMP SEI //HABILITA INTERUPCIONES GLOBALES /****************************************************************/ /****************************************************************/ /****************************************************************/ /*********** P R O G R A M A D E E J E M P L O **************/ /****************************************************************/ /****************************************************************/ /**************************************************************** * * Descripción: * * Transmisor. Se transmiten cuatro tramas * de 126 bytes correspondientes a la memoria programa. * Cada vez que el push button conectado en el PIN 7 del
[[CCOOMMUUNNIICCAACCIIÓÓNN AA NNIIVVEELL EENNLLAACCEE DDEE DDAATTOOSS EENNTTRREE MMIICCRROOCCOONNTTRROOLLAADDOORREESS CCOONN UUNNIIDDAADDEESS DDEE
RRAADDIIOOFFRREECCUUEENNCCIIAA]]
PPRROOYYEECCTTOO DDEE IINNGGEENNIIEERRÍÍAA EELLEECCTTRRÓÓNNIICCAA
UUNNIIVVEERRSSIIDDAADD AAUUTTÓÓNNOOMMAA MMEETTRROOPPOOLLIITTAANNAA IIZZTTAAPPAALLAAPPAA CCaarrllooss EErrnneessttoo MMoorreennoo EEssccoobbaarr 220011221144115599
‐ 105 ‐
* del puerto A es presionado, se transmite una trama. * * Receptor. El receptor recibe la trama y la despliega por * el puerto C. * *****************************************************************/ //PUSHBUTTON DE PRUEBA CBI DDRA,7 SBI PORTA,7 //INICIALIZAR CC1000 DIREC_DATOS //LLAMADO A MACRO RCALL INITCC1000 //GRABA EL CC1000 CON CTES GLOBALES /****************************************************************/ /**************************************************************** * TRANSMISOR. * * Descripción: * * Cada vez que el push button es presionado, se graba en * la memoria RAM (de la dirección $0062 a la $00DF) un * segmento de la memoria programa del AVR. Una vez que se * graban los 126 bytes se transmite la trama mediante la * función ENVIA_TRAMA. Recordemos que dicha función * implementa el protocolo stop and wait. * Una vez que la trama ha sido transmitida satisfactoriamente * (sin errores o pérdidas de tramas y ha recibido * correctamente el acuse), se muestra en el puerto C el * byte mas alto del CRC del acuse y se vuelve al bucle * WAITBUTTON, donde se esperará a que se presione * nuevamente el push button para transmitir la siguiente * trama. * Una vez que se hayan transmitido 4 tramas de memoria * programa, se comenzará a transmitir nuevamente la primera * trama. * * NOTA IMPORTANTE: No utilizar o modificar el registro SEQ * ya que es el GENERADOR del número de secuencia. Cualquier * cambio en este registro afectará la transmisión. * OTRA NOTA: Siempre que inicia el programa es importante * limpiar el registro SEQ Solo una vez. * ****************************************************************/ /* <-QUITAR ESTE COMENTARIO SI QUIERES EL MODO DE TRANSMISIÓN CLR TEMP MOV SEQ,TEMP //INICIALIZAR EL REGISTRO DE SECUENCIA CLR ZL //INICIAR APUNTADOR Z A LA MEMORIA PROGRAMA... CLR ZH //...(ZL=$00 Y ZH=$00) WAITBUTTON: SBIC PINA,7 //ESPERAR QUE EL PUSHBUTTON SEA PRESIONADO RJMP WAITBUTTON WAITBUTTON1: SBIS PINA,7 //ESPERAR QUE EL PUSHBUTTON DEJE DE SER PRESIONADO RJMP WAITBUTTON1 LDI XL,$62 //INICIAR APUNTADORES A LA RAM... LDI XH,$00 //...(DONDE SERÁ ALMACENADO UN SEGMENTO DE... //...LA MEMORIA PROGRAMA) CARGARAM: //LLENAR LA RAM CON 126 BYTES DE LA MEMORIA... //...PROGRAMA LPM //CARGAR EL PRIMER DATO DE LA MEMORIA PROGRAMA... //...EN EL REGISTRO R0 ADIW ZL,1 //INCRMENTAR EL APUNTADOR Z
PPRROOYYEECCTTOO DDEE IINNGGEENNIIEERRÍÍAA
EELLEECCTTRRÓÓNNIICCAA
[[CCOOMMUUNNIICCAACCIIÓÓNN AA NNIIVVEELL EENNLLAACCEE DDEE DDAATTOOSS EENNTTRREE MMIICCRROOCCOONNTTRROOLLAADDOORREESS CCOONN UUNNIIDDAADDEESS DDEE RRAADDIIOOFFRREECCUUEENNCCIIAA]]
UUNNIIVVEERRSSIIDDAADD AAUUTTÓÓNNOOMMAA MMEETTRROOPPOOLLIITTAANNAA IIZZTTAAPPAALLAAPPAA CCaarrllooss EErrnneessttoo MMoorreennoo EEssccoobbaarr 220011221144115599
‐ 106 ‐
ST X+,R0 //ALMACENAR EL DATO EN LA RAM CPI XL,$E0 //SE HAN GRABADO LOS 126 BYTES? BRNE CARGARAM // NO: CONTINUA GRABANDO RCALL ENVIA_TRAMA // SI: TRANSMITE TRAMA OUT PORTC,HBYTE //DESPLEGAR EN EL PUERTO EL CRC DEL ACUSE //...(PUEDES BORRAR ESTO SIN NINGUN RIESGO) CBI PORTA,PRERECIBIDO //APAGAR BANDERA: "PREAMBULO RECIBIDO" CPI ZL,$F8 //SE HAN TRANSMITIDO LAS CUATRO TRAMAS? BREQ VERIFZH RJMP WAITBUTTON // NO: CONTINUA TRANSMITIENDO VERIFZH: CPI ZH,$01 BRNE WAITBUTTON CLR ZL // SI: REINICIALIZA APUNTADOR Z CLR ZH RJMP WAITBUTTON QUITAR ESTE COMENTARIO SI QUIERES EL MODO DE TRANSMISIÓN ->*/ /****************************************************************/ /****************************************************************/ /****************************************************************/ /**************************************************************** * RECEPTOR. * * Descripción: * * En el modo de recepción se puede trabajar de dos modos: * 1.- Cuando se recibe la trama, se despliega en el puerto * C todos los datos recibidos (126 bytes). * 2.- Cuando se recibe la trama, únicamente se despliega el * primer byte recibido de cada trama. * * NOTA: Para activar el modo 2 de la recepción debe mantenerse * presionado el push button cuando el circuito es * energizado o durante un "reset". * * OTRA NOTA: No utilizar o modificar el registro SEQ * ya que es el VERIFICADOR del número de secuencia. Cualquier * cambio en este registro afectará la recepción. * * Y OTRA NOTA MAS!: Siempre que inicia el programa es importante * limpiar el registro SEQ Solo una vez. *****************************************************************/ /* <-QUITAR ESTE COMENTARIO SI QUIERES EL MODO DE RECEPCIÓN PERO COMENTAR EL MODO DE TRANSMISIÓN!!*/ .EQU T=6 //BANDERA T DEL STATUS REGISTER SBIS PINA,7 //SI EL PUSH BUTTON ES PRESIONADO... SER R24 //...HABILITAR EL MODO 2 SBIC PINA,7 CLR R24 CLR TEMP MOV SEQ,TEMP //INICIALIZAR EL REGISTRO DE SECUENCIA RECIBETRAMAS: CBI PORTA,CRCERROR //APAGAR BANDERA: "ERROR EN CRC" RCALL RECIBE_TRAMA //RECIBIR LA TRAMA
[[CCOOMMUUNNIICCAACCIIÓÓNN AA NNIIVVEELL EENNLLAACCEE DDEE DDAATTOOSS EENNTTRREE MMIICCRROOCCOONNTTRROOLLAADDOORREESS CCOONN UUNNIIDDAADDEESS DDEE
RRAADDIIOOFFRREECCUUEENNCCIIAA]]
PPRROOYYEECCTTOO DDEE IINNGGEENNIIEERRÍÍAA EELLEECCTTRRÓÓNNIICCAA
UUNNIIVVEERRSSIIDDAADD AAUUTTÓÓNNOOMMAA MMEETTRROOPPOOLLIITTAANNAA IIZZTTAAPPAALLAAPPAA CCaarrllooss EErrnneessttoo MMoorreennoo EEssccoobbaarr 220011221144115599
‐ 107 ‐
CBI PORTA,PRERECIBIDO //APAGAR BANDERA: "PREAMBULO RECIBIDO" BRBS T,RECIBETRAMAS //VERIFICAR BANDERA T (TRAMA DUPLICADA=1?) // SI:RECIBE NUEVAMENTE LA TRAMA // NO:CONTINUA CBI PORTA,PRERECIBIDO //APAGAR BANDERA: "PREAMBULO RECIBIDO" LDI XL,$E2 //INICIAR APUNTADORES A RAM... LDI XH,$00 //...(DATOS VALIDOS) LD HBYTE,X+ //DESPLIEGA EL PRIMER VALOR DE LOS DATOS... OUT PORTC,HBYTE //...RECIBIDOS CPI R24,$FF //ESTA ACTIVADO EL MODO 2? BREQ RECIBETRAMAS // SI: RECIBE SIGUIENTE TRAMA // NO: DESPLIEGA TODOS LOS DATOS RECIBIDOS LDI XL,$E2 LDI XH,$00 DESPLIEGUE: //COMIENZA DESPLIEGUE DE DATOS EN PUERTO C LD HBYTE,X+ // CARGAR EL DATO OUT PORTC,HBYTE // MOSTRARLO EN EL PUERTO C RCALL DELAY500mS // DELAY CPI xL,$60 //ES EL FINAL DE LOS DATOS? BREQ VERIFXH RJMP DESPLIEGUE // NO: CONTINUA DESPLEGANDO VERIFXH: CPI xH,$01 BRNE DESPLIEGUE rjmp RECIBETRAMAS // SI ESPERA SIGUIENTE TRAMA /*QUITAR ESTE COMENTARIO SI QUIERES EL MODO DE TRANSMISIÓN ->*/ //PERO COMENTAR EL MODO DE TRANSMISIÓN!! /****************************************************************/ /****************************************************************/ // DELAY PARA EL PROGRAMA DE EJEMPLO DELAY500mS: //PARA 0.5 SEGUNDOS LDI TEMP,$0F OUT OCR1AH,TEMP LDI TEMP,$42 OUT OCR1AL,TEMP RJMP STARTDELAY DELAY300mS: //PARA 0.3 SEGUNDOS LDI TEMP,$09 OUT OCR1AH,TEMP LDI TEMP,$27 OUT OCR1AL,TEMP RJMP STARTDELAY DELAY100mS: //PARA 0.1 SEGUNDOS LDI TEMP,$03 OUT OCR1AH,TEMP LDI TEMP,$0D OUT OCR1AL,TEMP RJMP STARTDELAY STARTDELAY: LDI TEMP,1<<OCF1A OUT TIFR,TEMP CLR TEMP OUT TCNT1H,TEMP OUT TCNT1L,TEMP LDI TEMP,(1<<CS12)|(1<<CS10) OUT TCCR1B,TEMP WAITDELAY1: IN TEMP,TIFR // BANDERA DE COMPARACION ENCENDIDA? SBRS TEMP,OCF1A // NO: ESPERA LA BANDERA RJMP WAITDELAY1 // SI: CONTINUA EJECUCION LDI TEMP,(0<<CS12)|(0<<CS10)
PPRROOYYEECCTTOO DDEE IINNGGEENNIIEERRÍÍAA
EELLEECCTTRRÓÓNNIICCAA
[[CCOOMMUUNNIICCAACCIIÓÓNN AA NNIIVVEELL EENNLLAACCEE DDEE DDAATTOOSS EENNTTRREE MMIICCRROOCCOONNTTRROOLLAADDOORREESS CCOONN UUNNIIDDAADDEESS DDEE RRAADDIIOOFFRREECCUUEENNCCIIAA]]
UUNNIIVVEERRSSIIDDAADD AAUUTTÓÓNNOOMMAA MMEETTRROOPPOOLLIITTAANNAA IIZZTTAAPPAALLAAPPAA CCaarrllooss EErrnneessttoo MMoorreennoo EEssccoobbaarr 220011221144115599
‐ 108 ‐
OUT TCCR1B,TEMP RET /*ARCHIVO: MACROS.INC*/ /****************************** M A C R O S ******************************** *************************************************************************** * * MACROS * DIREC_DATOS * * DESCRIPCION * ESTA MACRO ALMACENA EN LA MEMORIA RAM LAS DIRECCIONES DE LOS REGISTROS * DE CONFIGURACIÓN DEL CC1000 Y LOS DATOS QUE DEBEN SER ALMACENADOS EN * DICHOS REGISTROS. * * LOCALIDAD DATOS * * 0x60 - 0x74 DIRECCION DE LOS REGISTROS * 0x75 - 0x89 CONTENIDO DE LOS REGISTROS * 0x8A - 0x8D DATOS PARA RESET DEL CC1000 * 0x8E - 0xA5 DATOS PARA CALIBRACIÓN * **************************************************************************/ .MACRO DIREC_DATOS CLR XH LDI XL,$60 //DIRECCIONES DE LOS REGISTROS DE CONFIGURACIÓN LDI TEMP,AFREQ_2A ST X+,TEMP LDI TEMP,AFREQ_1A ST X+,TEMP LDI TEMP,AFREQ_0A ST X+,TEMP LDI TEMP,AFREQ_2B ST X+,TEMP LDI TEMP,AFREQ_1B ST X+,TEMP LDI TEMP,AFREQ_0B ST X+,TEMP LDI TEMP,AFSEP1 ST X+,TEMP LDI TEMP,AFSEP0 ST X+,TEMP LDI TEMP,ACURRENT ST X+,TEMP LDI TEMP,AFRONT_END ST X+,TEMP LDI TEMP,APA_POW ST X+,TEMP LDI TEMP,APLL ST X+,TEMP LDI TEMP,ALOCK ST X+,TEMP LDI TEMP,ACAL ST X+,TEMP LDI TEMP,AMODEM2 ST X+,TEMP LDI TEMP,AMODEM1 ST X+,TEMP LDI TEMP,AMODEM0 ST X+,TEMP LDI TEMP,AMATCH ST X+,TEMP LDI TEMP,AFSCTRL
[[CCOOMMUUNNIICCAACCIIÓÓNN AA NNIIVVEELL EENNLLAACCEE DDEE DDAATTOOSS EENNTTRREE MMIICCRROOCCOONNTTRROOLLAADDOORREESS CCOONN UUNNIIDDAADDEESS DDEE
RRAADDIIOOFFRREECCUUEENNCCIIAA]]
PPRROOYYEECCTTOO DDEE IINNGGEENNIIEERRÍÍAA EELLEECCTTRRÓÓNNIICCAA
UUNNIIVVEERRSSIIDDAADD AAUUTTÓÓNNOOMMAA MMEETTRROOPPOOLLIITTAANNAA IIZZTTAAPPAALLAAPPAA CCaarrllooss EErrnneessttoo MMoorreennoo EEssccoobbaarr 220011221144115599
‐ 109 ‐
ST X+,TEMP LDI TEMP,APREESCALER ST X+,TEMP LDI TEMP,ATEST4 ST X+,TEMP LDI TEMP,FREQ_2A //ALMACENAR LOS DATOS DE CONFIGURACIÓN EN LA RAM ST X+,TEMP LDI TEMP,FREQ_1A ST X+,TEMP LDI TEMP,FREQ_0A ST X+,TEMP LDI TEMP,FREQ_2B ST X+,TEMP LDI TEMP,FREQ_1B ST X+,TEMP LDI TEMP,FREQ_0B ST X+,TEMP LDI TEMP,FSEP1 ST X+,TEMP LDI TEMP,FSEP0 ST X+,TEMP LDI TEMP,CURRENT ST X+,TEMP LDI TEMP,FRONT_END ST X+,TEMP LDI TEMP,PA_POW ST X+,TEMP LDI TEMP,PLL ST X+,TEMP LDI TEMP,LOCK ST X+,TEMP LDI TEMP,CAL ST X+,TEMP LDI TEMP,MODEM2 ST X+,TEMP LDI TEMP,MODEM1 ST X+,TEMP LDI TEMP,MODEM0 ST X+,TEMP LDI TEMP,MATCH ST X+,TEMP LDI TEMP,FSCTRL ST X+,TEMP LDI TEMP,PREESCALER ST X+,TEMP LDI TEMP,TEST4 ST X+,TEMP .ENDMACRO
1122..00 MMEEDDIICCIIOONNEESS
EEXXPPEERRIIMMEENNTTAALLEESS
La transmisión y recepción se comprobaron mediante la ayuda del analizador de espectros y el osciloscopio. Para estas pruebas, los CC1000 (Configurados como transmisor y receptor) trabajaban a una frecuencia de 868.289 MHz. Los datos enviados fueron tramas de tamaño infinito, es decir, transmisión ininterrumpida de datos. A continuación se muestra el espectro de potencia de la señal transmitida.
PPRROOYYEECCTTOO DDEE IINNGGEENNIIEERRÍÍAA
EELLEECCTTRRÓÓNNIICCAA
[[CCOOMMUUNNIICCAACCIIÓÓNN AA NNIIVVEELL EENNLLAACCEE DDEE DDAATTOOSS EENNTTRREE MMIICCRROOCCOONNTTRROOLLAADDOORREESS CCOONN UUNNIIDDAADDEESS DDEE RRAADDIIOOFFRREECCUUEENNCCIIAA]]
UUNNIIVVEERRSSIIDDAADD AAUUTTÓÓNNOOMMAA MMEETTRROOPPOOLLIITTAANNAA IIZZTTAAPPAALLAAPPAA CCaarrllooss EErrnneessttoo MMoorreennoo EEssccoobbaarr 220011221144115599
‐ 110 ‐
Figura 12.0.0 Espectro de potencia de la señal transmitida por el CC1000 (Espectro
centrado en 868.2895 MHz).
La figura 12.0.1 muestra la señal transmitida y el reloj de sincronía generado por el CC1000 (DCLK).
Figura 12.0.1 Arriba. Señal digital a Transmitida. Abajo. Reloj (DCLK).
De igual forma, la siguiente figura muestra la señal recibida y el reloj de sincronía DCLK.
Figura 12.0.2 Arriba. Señal digital Recibida. Abajo. Reloj (DCLK).
[[CCOOMMUUNNIICCAACCIIÓÓNN AA NNIIVVEELL EENNLLAACCEE DDEE DDAATTOOSS EENNTTRREE MMIICCRROOCCOONNTTRROOLLAADDOORREESS CCOONN UUNNIIDDAADDEESS DDEE
RRAADDIIOOFFRREECCUUEENNCCIIAA]]
PPRROOYYEECCTTOO DDEE IINNGGEENNIIEERRÍÍAA EELLEECCTTRRÓÓNNIICCAA
UUNNIIVVEERRSSIIDDAADD AAUUTTÓÓNNOOMMAA MMEETTRROOPPOOLLIITTAANNAA IIZZTTAAPPAALLAAPPAA CCaarrllooss EErrnneessttoo MMoorreennoo EEssccoobbaarr 220011221144115599
‐ 111 ‐
Como un comparativo, en la figura 12.0.3, se muestra la señal transmitida (arriba) y la señal recibida (abajo). Se puede notar que la amplitud de las señales no varía mucho y los datos recibidos únicamente tienen un delay de (5.6us) generado por todo el proceso que sufre la señal debido a la demodulación y la decodificación (de Manchester a NRZ).
Figura 12.0.3 Arriba. Señal digital Transmitida. Abajo. Señal digital Recibida.
1133..00 RREESSUULLTTAADDOOSS YY CCOONNCCLLUUSSIIOONNEESS
Aunque el proyecto aquí presentado incluye, en su mayoría, los elementos básicos de configuración y funcionamiento del CC1000 y el AVR, es posible escalarlo a un nivel mayor, es decir, implementar más nodos de comunicaciones. Debido a que la cantidad de información que es enviada es considerablemente grande, es posible agregar más campos de información como: número de identificación del nodo o simplemente usar un nodo como “repetidor”, entre otros. El escalamiento del sistema aquí presentado puede realizarse de una forma sencilla, por ejemplo, si queremos agregar en la información a transmitir un campo que indique a qué nodo va dirigida, tendríamos que modificar las funciones ENVIA_TRAMA y RECIBE_TRAMA. La función RECIBE_TRAMA tendría que identificar, primeramente, si la información recibida es para este nodo, de cualquier otra forma desecha la información recibida. Por otro lado, a la función ENVIA_TRAMA se le tiene que agregar el número de nodo al cual está destinada la información. Cabe mencionar que independientemente de la cantidad de nodos que haya, los nodos receptores deben recibir la información del nodo transmisor (independientemente de que la información no sea para éste), para que de este modo verificar el CRC‐16. La verificación del checksum es imprescindible para este sistema de comunicaciones en el que se está trabajando en un medio muy ruidoso. Una vez que se realiza la verificación del checksum, entonces se debe verificar si la información recibida es para el nodo receptor activo. Todas las rutinas para la configuración del CC1000 fueron creadas a partir del datasheet de éste. En estas hojas de especificaciones podemos encontrar diagramas de flujo de operaciones específicas, como por ejemplo, calibración, activación de Tx o Rx, entre otros. Los diagramas de flujo mostrados en este reporte, para la etapa de configuración, son esos mismos diagramas (únicamente están traducidos). Independientemente del tipo de interface de datos que va a ser utilizada como NRZ o UART, las subrutinas creadas son exactamente las mismas, ya que la interface de datos es independiente de la interface de configuración. Esto nos permite utilizar estas mismas funciones para cualquier otro tipo de prueba con otra interface de datos.
PPRROOYYEECCTTOO DDEE IINNGGEENNIIEERRÍÍAA
EELLEECCTTRRÓÓNNIICCAA
[[CCOOMMUUNNIICCAACCIIÓÓNN AA NNIIVVEELL EENNLLAACCEE DDEE DDAATTOOSS EENNTTRREE MMIICCRROOCCOONNTTRROOLLAADDOORREESS CCOONN UUNNIIDDAADDEESS DDEE RRAADDIIOOFFRREECCUUEENNCCIIAA]]
UUNNIIVVEERRSSIIDDAADD AAUUTTÓÓNNOOMMAA MMEETTRROOPPOOLLIITTAANNAA IIZZTTAAPPAALLAAPPAA CCaarrllooss EErrnneessttoo MMoorreennoo EEssccoobbaarr 220011221144115599
‐ 112 ‐
Si se piensa utilizar una interface de datos diferente a la mostrada en este documento, es necesario tener en cuenta las consideraciones que esto implica, como son: el filtro promedio y el número de secuencias del preámbulo a transmitir/recibir. Por ejemplo: si queremos usar el modo NRZ síncrono, se requiere rediseñar todas las subrutinas encargadas de la transmisión/recepción de datos (información y preámbulo), ya que el modo NRZ necesita más números de secuencias de preámbulo y se requiere que el filtro promedio (average filter) se bloquee manualmente. Lo mismo sucede con el modo UART del CC1000, solo que en este caso, trabajamos de manera asíncrona, por lo tanto, la USART del microcontrolador debe ser utilizada. El fabricante del transceiver (Chipcon), nos recomienda ampliamente la utilización del código de línea Manchester, el cual elimina la componente de DC de la señal transmitida ya que se tiene el mismo número de ceros que de unos. La configuración en modo Manchester del CC1000, aparte de las ventajas mencionadas arriba, nos permite observar errores en los datos en un pin del CC1000. Cuando se detecta una violación en el código Manchester se enciende una bandera en dicho pin, la cual puede ser consultada en algún momento mediante el microcontrolador. Aunque esta es una buena forma de detectar una violación en el código, el cual se traduciría como un mal muestreo de los datos recibidos, no es utilizada en esta aplicación, ya que mediante la utilización del CRC‐16 y el protocolo Stop and Wait, cualquier error introducido por el medio o por una violación en el código, éste será detectado y retransmitido correctamente. Ahora bien, mediante mediciones experimentales se pudo encontrar la distancia aproximada máxima de funcionamiento de los transceivers. Las mediciones experimentales se realizaron al aire libre y siempre con línea de vista. Recordemos que el programa cargado en el AVR implementa el protocolo Stop and Wait, esto quiere decir que el transmisor envía los datos y espera un acuse de recibo. El sistema (receptor y transmisor) está cargado con el programa de ejemplo mostrado en la sección 11.0. Las mediciones se realizaron de la siguiente forma: primeramente, se estableció en un lugar fijo el transceiver receptor, posteriormente a una distancia de dos metros se comenzaba la transmisión de los datos y se observaba la respuesta del receptor (el cual muestra en el puerto del AVR el primer byte de cada secuencia recibida), de este modo nos alejamos otros dos metros y así consecutivamente... Continuando con estas pruebas, la distancia a la cual se recibieron los datos y acuses fue de aproximadamente 30 metros. A esta distancia, tanto el receptor como el transmisor presentan alteraciones en la comunicación, por ejemplo, el receptor no recibe la información o el transmisor no recibe el acuse. Gracias a la implementación del Stop and Wait, el transmisor continúa transmitiendo hasta que recibe el acuse. Aún así, a la distancia de 30 metros todavía se continua recibiendo/transmitiendo, pero este proceso toma más tiempo ya que no se deja de transmitir hasta que el receptor reciba correctamente la información y envíe el acuse. Otro factor importante que influye enormemente en el desempeño de la transmisión/recepción son las baterías utilizadas (no me refiero a la marca del fabricante) sino a la corriente y voltaje que son capaces de proporcionar y por cuanto tiempo. Todas las rutinas diseñadas en este proyecto como la interface de datos, de configuración, el CRC‐16 y el protocolo Stop and Wait ocupan aproximadamente el 1.2 kbytes de memoria programa del AVR, lo cual equivale al 17% de la memoria programa (8 kbytes para el ATMEGA8535). Esto significa que nos deja libre un 83% de la memoria programa para incluir alguna otra rutina para la etapa de algún sensor o incluso un protocolo de comunicaciones más complejo. La interfaz de configuración se realiza mediante el protocolo SPI. Aunque el AVR cuenta con
[[CCOOMMUUNNIICCAACCIIÓÓNN AA NNIIVVEELL EENNLLAACCEE DDEE DDAATTOOSS EENNTTRREE MMIICCRROOCCOONNTTRROOLLAADDOORREESS CCOONN UUNNIIDDAADDEESS DDEE
RRAADDIIOOFFRREECCUUEENNCCIIAA]]
PPRROOYYEECCTTOO DDEE IINNGGEENNIIEERRÍÍAA EELLEECCTTRRÓÓNNIICCAA
UUNNIIVVEERRSSIIDDAADD AAUUTTÓÓNNOOMMAA MMEETTRROOPPOOLLIITTAANNAA IIZZTTAAPPAALLAAPPAA CCaarrllooss EErrnneessttoo MMoorreennoo EEssccoobbaarr 220011221144115599
‐ 113 ‐
una SPI interna, no fue posible implementar correctamente la interfaz de configuración ya que la lectura de los registros internos del CC1000 era incorrecta. Según Chipcon, cuando se realiza la lectura del CC1000 las terminales MOSI y MISO del AVR deben estar en conectadas entre sí y posteriormente conectarse en la terminal PDATA del CC1000, como se indica en la figura 4.2.6. La terminal MOSI, que es configurada como salida, debe tener una impedancia alta cuando se inicia la lectura de vuelta del contenido de los registros del Transceiver para que los datos vayan directamente a la terminal MISO, configurada como entrada, y así de este modo leer los registros del CC1000. Cuando se configura la interfaz SPI del AVR, no es posible cambiar la impedancia del la terminal MOSI –es decir, las resistencias pull‐up se desactivan cuando se configura el SPI‐, lo que provoca tener en esta terminal una impedancia baja y por lo tanto, la información que manda el CC1000 se “cae” en esta terminal, provocando que en la entrada MISO no entre la información de configuración. Es por esta circunstancia que se ha empleado una interfaz SPI por software, ya que de este modo podemos controlar las impedancias que hay en los puertos mediante el uso de las resistencias pull‐up internas para la lectura correcta de los registros del CC1000 (ver LEERCC1000). Cabe mencionar que cuando se utiliza la SPI interna del AVR, la configuración del CC1000 se realiza correctamente, pero para la lectura no sucede esto. Debido a que algunas tareas o funciones de configuración, requieren la lectura de los registros de configuración la utilización de la SPI por hardware fue descartada. De alguna manera, el SPI contenido en el hardware del AVR puede ser utilizado a futuro para la implementación de la interfaz de datos síncrona. El software diseñado para la configuración del CC1000 permite la modificación de los parámetros requeridos para el correcto funcionamiento del CC1000PP, como son: frecuencia de RF, velocidad de transmisión de los datos, consumo de corriente de Rx y Tx, frecuencia de separación, etc. Mediante el uso de constantes globales dentro del programa ensamblador, permite que el código fuente no tengan que ser modificadas las funciones. Las constantes globales son almacenadas en la memoria RAM del AVR y éstas incluyen las direcciones de los registros y los parámetros de configuración. Las constantes globales son grabadas en la RAM mediante una macro (DIREC_DATOS) y posteriormente el AVR con la función INITCC1000 las transmite hacia el CC1000 vía SPI. Todas las funciones implementadas para configuración tienen el mismo principio, primero se cargan los registros ADDRESS con la dirección del registro; DATA con el dato que se le va a cargar al registro y posteriormente se llama a la función WRITETOCC1000, esta función prepara los datos, genera el bit de escritura y llama a la función RW_SPI para escribir en el CC1000. Las funciones para la configuración diseñadas pueden ser utilizadas para cualquier modo de operación del CC1000. Las funciones de configuración diseñadas son las siguientes:
1. RESETCC1000. Reinicializar el CC1000. 2. INITCC1000. Calibrar y programar el CC1000 con los valores definidos en las
constantes globales. 3. TURNONTX. Encender modo de transmisión. 4. TURNOFFTX. Apagar modo de transmisión. 5. TURNONRX. Encender recepción. 6. TURNOFFRX. Apagar el modo de recepción.
PPRROOYYEECCTTOO DDEE IINNGGEENNIIEERRÍÍAA
EELLEECCTTRRÓÓNNIICCAA
[[CCOOMMUUNNIICCAACCIIÓÓNN AA NNIIVVEELL EENNLLAACCEE DDEE DDAATTOOSS EENNTTRREE MMIICCRROOCCOONNTTRROOLLAADDOORREESS CCOONN UUNNIIDDAADDEESS DDEE RRAADDIIOOFFRREECCUUEENNCCIIAA]]
UUNNIIVVEERRSSIIDDAADD AAUUTTÓÓNNOOMMAA MMEETTRROOPPOOLLIITTAANNAA IIZZTTAAPPAALLAAPPAA CCaarrllooss EErrnneessttoo MMoorreennoo EEssccoobbaarr 220011221144115599
‐ 114 ‐
7. LEERCC1000. Leer todos los registros de configuración del CC1000.8. AVER_BLOQ. Bloquear manualmente el filtro promedio. 9. AVER_DESBLOQ. Desbloquear el filtro promedio. 10. RESET_AVFILTER. Reinicializar el filtro promedio. 11. WRITETOCC1000. Escribir configuraciones vía SPI
Para una configuración completa del CC1000 se requieren únicamente las once funciones mostradas arriba. El filtro promedio es utilizado para sincronización y detección del ancho de cada bit que va a ser recibido, de este modo, la recepción de los datos es correcta. En las pruebas iniciales de transmisión, se utilizó la interface de datos en modo UART. Por lo tanto el Filtro Promedio se configuró de forma automática. Lo que quiere decir que cada que detecta un preámbulo válido el filtro se bloquea automáticamente. La utilización del filtro promedio automático provocó que se bloqueara solo con cualquier preámbulo contenido en el medio, es decir, el receptor detectaba algún preámbulo en el medio ambiente y se bloquea de manera automática. El preámbulo detectado no siempre era válido, ya que cuando comenzaba la transmisión con el CC1000 –configurado como transmisor‐, el receptor muestra datos inválidos (o muestreados de forma incorrecta). En una segunda prueba, el filtro promedio se configuró manualmente, es decir, el AVR debe monitorear continuamente los datos recibidos por el CC1000, evaluarlos y si es un preámbulo válido, debe bloquear el filtro mediante la función AVER_BLOQ. En el Proyecto de ingeniería Electrónica I se desarrolló todo un análisis de la interface de datos en modo UART. En el cual se diseñaron funciones para trabajar con el filtro promedio en modo manual y evaluar los preámbulos recibidos. Aunque estas pruebas fueron satisfactorias, todavía había un problema: la transmisión/recepción se realiza de forma asíncrona y sin ningún tipo de codificación de línea. Es por esta razón que en el Proyecto de Ingeniería Electrónica II se ha trabajado sobre la codificación Manchester síncrona. La interfaz de datos del CC1000 puede ser configurada en tres modos: NRZ Síncrono, Manchester y UART (Ver sección 4.2.7 “Interfaz de la señal de datos”). El pin DIO es utilizado para generar el reloj de la sincronía para los modos NRZ y Manchester. Durante las primeras pruebas del proyecto, se configuró el CC1000 en modo UART, donde el pin PDATA del CC1000 Funciona como TxD y el pin DIO es utilizado como RxD. Para la transmisión de datos, el AVR envía los datos hacia el CC1000 mediante su UART interna a una velocidad de 38.4 kbauds. En el pin DIO el CC1000 recibe esta información, donde es modulada y transmitida vía RF. Por otra parte, para la recepción de datos, el CC1000 recibe la señal de RF, la demodula y saca la señal digital en el pin PDATA, el cual la transmite hacia el AVR en forma asíncrona. El AVR lo recibe en la UART interna y procesa la información. Cabe mencionar que la interface de datos usada (UART) no es la más conveniente, ya que los datos son únicamente modulados, es decir, no se le agrega ningún tipo de sincronización ni codificación. Además, durante las pruebas de comunicación entre los dos nodos, se detectaron fallas en la comunicación, es decir, no se reciben los datos correctamente. Es por esa razón que se
[[CCOOMMUUNNIICCAACCIIÓÓNN AA NNIIVVEELL EENNLLAACCEE DDEE DDAATTOOSS EENNTTRREE MMIICCRROOCCOONNTTRROOLLAADDOORREESS CCOONN UUNNIIDDAADDEESS DDEE
RRAADDIIOOFFRREECCUUEENNCCIIAA]]
PPRROOYYEECCTTOO DDEE IINNGGEENNIIEERRÍÍAA EELLEECCTTRRÓÓNNIICCAA
UUNNIIVVEERRSSIIDDAADD AAUUTTÓÓNNOOMMAA MMEETTRROOPPOOLLIITTAANNAA IIZZTTAAPPAALLAAPPAA CCaarrllooss EErrnneessttoo MMoorreennoo EEssccoobbaarr 220011221144115599
‐ 115 ‐
empleó la interface de datos síncrona con codificación Manchester. En este modo de transmisión el CC1000 crea el tiempo de reloj de los datos en DCLK y usa DIO como entrada de datos. Los datos se modulan con codificación Manchester en RF. En el modo de recepción el CC1000 crea la sincronización con el tiempo de reloj en DCLK y DIO es utilizado para la recepción de datos.
AAPPÉÉNNDDIICCEE IINNTTEERRFFAACCEE DDEE CCOONNFFIIGGUURRAACCIIÓÓNN
CCOONN EELL µµCC PPIICC1166FF664488AA
Se ha diseñado la interface de configuración para el transceiver CC1000 y el microcontrolador de MICROCHIP PIC16F648A. Cada una de las subrutinas que están en el código fuente son, en esencia, las mismas que se mostraron en el capítulo 7. También se incluye un programa de ejemplo para verificar si los transceivers se han configurado adecuadamente. El programa se divide en dos secciones: TXMODE y RXMODE. En TXMODE el CC1000 es configurado como transmisor y es activada la interrupción externa del PIC. Cada flanco de subida del reloj DCLK del CC1000 comienza a transmitir bit a bit una cadena infinita de la siguiente forma: 101010…… los datos a transmitir se observan en el pin PB1 (DIO) del PIC (configurado como salida). En RXMODE el CC1000 es configurado como receptor. El pin PB1 es configurado como entrada, pero al recibir los datos el controlador no realiza ninguna tarea en particular. Recordemos que la idea principal de este programa es implementar correctamente la interface de configuración del CC1000 y comprobar su funcionamiento. Para comprobar adecuadamente la configuración del CC1000 es una buena idea observar mediante la ayuda del osciloscopio los pines DIO tanto del receptor como el del transmisor. De esta manera puedes observar los datos que están siendo transmitidos y recibidos A continuación se muestra el diagrama de conexiones.
PP
EE
PPRROOYYEECCTTOO DDEEIINNGGEENNIIEERRÍÍAA
EELLEECCTTRRÓÓNNIICCAA
EE AA AA
[[CCOOMMUUNNIICCMMIICCRROOCCOONNRRAADDIIOOFFRREECC
A ContinuCC1000PPCC1000‐PI
CCAACCIIÓÓNN AA NNIIVVEENNTTRROOLLAADDOORREESSCCUUEENNCCIIAA]]
UUNNIIVVEE
ación se muesP. IC.ASM
EELL EENNLLAACCEE DDEE SS CCOONN UUNNIIDDAADD
EERRSSIIDDAADD AAUUTTCCaarrll
stra el código f
DDAATTOOSS EENNTTRREEDDEESS DDEE
ÓÓNNOOMMAA MMEETTooss EErrnneessttoo MM
fuente para la
EE
TTRROOPPOOLLIITTAANNAAMMoorreennoo EEssccoobba
configuración
AA IIZZTTAAPPAALLAAPPAAaarr 220011221144115599
completa del
AA 99
‐ 116 ‐
transceiver
[[CCOOMMUUNNIICCAACCIIÓÓNN AA NNIIVVEELL EENNLLAACCEE DDEE DDAATTOOSS EENNTTRREE MMIICCRROOCCOONNTTRROOLLAADDOORREESS CCOONN UUNNIIDDAADDEESS DDEE
RRAADDIIOOFFRREECCUUEENNCCIIAA]]
PPRROOYYEECCTTOO DDEE IINNGGEENNIIEERRÍÍAA EELLEECCTTRRÓÓNNIICCAA
UUNNIIVVEERRSSIIDDAADD AAUUTTÓÓNNOOMMAA MMEETTRROOPPOOLLIITTAANNAA IIZZTTAAPPAALLAAPPAA CCaarrllooss EErrnneessttoo MMoorreennoo EEssccoobbaarr 220011221144115599
‐ 117 ‐
;**************************************************************** ;* _ _ _ _ _ _ _ _ _ _ _ _ ;* _/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_ ;* | | ;* | UNIVERSIDAD AUTONOMA METROPOLITANA IZTAPALAPA | ;* | PROYECTO DE INGENIERÍA ELECTRÓNICA | ;* | Comunicacion a nivel de enlace de datos entre | ;* | microcontroladores mediante unidades de RF | ;* | | ;* | CC1000PP-P16F648.ASM | ;* | _ _ _ _ _ _ _ _ _ _ _ _ | ;* |_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_| ;* ;* +_________________________________________________+ ;* | AUTOR: CARLOS ERNESTO MORENO ESCOBAR | ;* | E-MAIL: [email protected] | ;* | MATRICULA: 201214159 | ;* | ASESOR: Dr. MIGUEL ÁNGEL RUIZ SANCHEZ | ;* | DISPOSITIVO: PIC16F648A (CUALQUIER PIC) | ;* | RELOJ @ 4 MHZ (OSCILADOR INTERNO) | ;* | FECHA: VIERNES 9 DE MAYO DE 2008 | ;* |_________________________________________________| ;* ;* DESCRIPCIÓN: ;* ;* 1.- ESTE PROGRAMA IMPLEMENTA TODAS LAS FUNCIONES NECESARIAS ;* PARA LA CONFIGURACIÓN DEL CC1000PP. SE UTILIZAN CONSTANTES ;* GLOBALES PARA LA CONFIGURACIÓN.DICHAS CONSTANTES DEBEN ;* MODIFICARSE SEGÚN LA CONFIGURACIÓN QUE SE DESEE (P.E. MODO UART, ;* VELOCIDAD DE TX, FRECUENCIA ETC). ;* LA INTERFACE DE CONFIGURACIÓN CON EL CC1000 SE REALIZA ;* UTILIZANDO EL PROTOCOLO SPI (Implementado por Software). ;* A CONTINUAIÓN SE MUESTRAN TODAS LA FUNCIONES PARA CONFIGURACIÓN: ;* ;* RW_SPI. TRANSMITIR-LEER POR EL PUERTO DEL SPI ;* (MODO TX Y RX). (PARA ESTA VERSION SOLO ESTA ;* DISPONIBLE LA TRANSMISIÓN) ;* RESETCC1000. REINICIALIZAR EL CC1000 (MODO TX Y RX) ;* INITCC1000. GRABAR EL CC1000 CON LOS PARAMETROS ;* POR DEFAULT DE LAS CONSTANTES GLOBALES ;* Y CALIBAR EL CC1000. (MODO TX Y RX) ;* TURNONTX. HABILITAR MODO Tx (MODO TX) ;* TURNOFFTX. DESHABILITAR MODO Tx (MODO TX) ;* TURNONRX. HABILITAR MODO Rx (MODO RX) ;* TURNOFFRX. DESHABILITAR MODO Rx (MODO RX) ;* WRITETOCC1000. ESCRIBIR DATOS DE CONFIG EN EL CC1000 (MODO TX Y RX) ;* AVER_AUTO. FILTRO PROMEDIO AUTOMÁTICO (MODO RX) ;* AVER_BLOQ. BLOQUEAR MANUALMENTE FILTRO PROMEDIO (MODO RX) ;* AVER_DESBLOQ. DESBLOQUEAR MANUALMENTE FILTRO PROMEDIO (MODO RX) ;* RESET_AVFILTER. REINICIALIZAR EL FILTRO PROMEDIO (MODO RX) ;* NOTA: ;* LAS FUNCIONES MOSTRADAS ARRIBA FUNCIONAN PARA CUALQUIER MODO DE ;* OPERACIÓN, YA QUE LA INTERFACE DE CONFIGURACIÓN ES INDEPENDIENTE ;* DE LA INTERFACE DE DATOS. ;* ;* CONEXIÓN ;* PIC16FXX CC1000PP-868 ;* __________ __________ ;* | | ;* (CLK) PB4|-------->| PCLK ;* | | ;* (MOSI)PB5|<--------| PDATA ;* (PALE)PB6|-------->| PALE ;* | | ;* PB0|<--------| DCLK ;* (INT1)PB1|<------->| DIO ;* | | ;* _________| |___________
PPRROOYYEECCTTOO DDEE IINNGGEENNIIEERRÍÍAA
EELLEECCTTRRÓÓNNIICCAA
[[CCOOMMUUNNIICCAACCIIÓÓNN AA NNIIVVEELL EENNLLAACCEE DDEE DDAATTOOSS EENNTTRREE MMIICCRROOCCOONNTTRROOLLAADDOORREESS CCOONN UUNNIIDDAADDEESS DDEE RRAADDIIOOFFRREECCUUEENNCCIIAA]]
UUNNIIVVEERRSSIIDDAADD AAUUTTÓÓNNOOMMAA MMEETTRROOPPOOLLIITTAANNAA IIZZTTAAPPAALLAAPPAA CCaarrllooss EErrnneessttoo MMoorreennoo EEssccoobbaarr 220011221144115599
‐ 118 ‐
;* ;* ;* Una vez que hayas decidido qué interface de datos vas a utilizar ;* (UART, NRZ o Manchester). Puedes cambiar los parámetros mediante ;* SmartRF Studio (http://focus.ti.com/docs/toolsw/folders/print/smartrftm-studio.html). ;* Los parámetros mostrados a continuación son un ejemplo de configuración. ;* ;* PARÁMETROS DEL CC1000 PARA ESTA IMPLEMENTACIÓN: ;* (GENERADOS CON SMART RF STUDIO) ;* Device: CC1000 ;* ;* System parameters: ;* X-tal frequency: 14.745600 MHz Internal ;* X-tal accuracy: +/- 20 ppm ;* RF frequency A: 868.297200 MHz Inactive Rx ;* RF frequency B: 868.297200 MHz Active Tx ;* RX Mode: Low Current: no, Optimal frequency: yes, Low side LO ;* Frequency separation: 64 kHz ;* Data rate: 76.8 kBaud ;* Data Format: Manchester Accurate ;* RF output power: 5 dBm ;* LOCK indicator: Continuous ;* IF/RSSI: Disabled ;* Operator Mode: Tx ;* ;* Component values, VCO inductor: ;* L101 = 4.7 nH ;* ;* Component values, Match ;* L32 = 120.0 nH ;* L41 = 2.5 nH ;* C31 = 10.0 pF ;* C41 = N.A pF ;* C42 = 4.7 pF ;******************************************************************/ ;****************************************************************************** LIST P=16F648A PROCESSOR 16F648A INCLUDE <P16F648A.INC> __CONFIG _BODEN_OFF&_BOREN_OFF&_CP_OFF&_PWRTE_OFF&_WDT_OFF&_LVP_OFF&_MCLRE_ON&_INTOSC_OSC_NOCLKOUT ERRORLEVEL 0, -302, -305 CBLOCK 0x20 TEMP ;Registro temporal SPIDR ;Registro de transmisión para el SPI ADDRESS ;Registro de dirección (dirección del registro del CC1000) DATO ;Registro de dato (dato para un registro del CC1000) CONT ;Contador CONFIG_CONT ;Contador para Tabla AUX ENDC ;/***************************************************************** ;***** C O N F I G U R A C I O N P A R A E L C C 1 0 0 0 ****** ;****************************************************************** ;*********** C O N S T A N T E S G L O B A L E S ***************** ; A CONTINUACIÓN SE DEBEN INTRODUCIR LAS DIRECCIONES DE LOS 22 ; REGISTROS DE CONFIGURACIÓN DEL CC1000, POSTERIORMENTE INTRODUCIR ; LOS DATOS DE CONFIGURACIÓN QUE DEBEN SER CARGADOS EN CADA UNO DE ; LOS REGISTROS DEL CC1000. ESTOS DATOS INTRODUCIDOS SON PARA ; CONFIGURAR EL CC1000 COMO TRANSMISOR OBTENIDOS DE RFSTUDIO. ; NOTA: NO ES NECESARIO MODIFICAR LAS DIRECCIONES DE LOS ; REGISTROS SI SE USA EL CC1000. ;*******************************************************************/
[[CCOOMMUUNNIICCAACCIIÓÓNN AA NNIIVVEELL EENNLLAACCEE DDEE DDAATTOOSS EENNTTRREE MMIICCRROOCCOONNTTRROOLLAADDOORREESS CCOONN UUNNIIDDAADDEESS DDEE
RRAADDIIOOFFRREECCUUEENNCCIIAA]]
PPRROOYYEECCTTOO DDEE IINNGGEENNIIEERRÍÍAA EELLEECCTTRRÓÓNNIICCAA
UUNNIIVVEERRSSIIDDAADD AAUUTTÓÓNNOOMMAA MMEETTRROOPPOOLLIITTAANNAA IIZZTTAAPPAALLAAPPAA CCaarrllooss EErrnneessttoo MMoorreennoo EEssccoobbaarr 220011221144115599
‐ 119 ‐
; DIRECCIONES DE LOS REGISTROS DE CONFIGURACIÓN ; (NO MODIFICAR!) AMAIN EQU 0X00 AFREQ_2A EQU 0X01 AFREQ_1A EQU 0X02 AFREQ_0A EQU 0X03 AFREQ_2B EQU 0X04 AFREQ_1B EQU 0X05 AFREQ_0B EQU 0X06 AFSEP1 EQU 0X07 AFSEP0 EQU 0X08 ACURRENT EQU 0X09 AFRONT_END EQU 0X0A APA_POW EQU 0X0B APLL EQU 0X0C ALOCK EQU 0X0D ACAL EQU 0X0E AMODEM2 EQU 0X0F AMODEM1 EQU 0X10 AMODEM0 EQU 0X11 AMATCH EQU 0X12 AFSCTRL EQU 0X13 APREESCALER EQU 0X1C ATEST4 EQU 0X42 ; CONTENIDO DE LOS REGISTROS (DEFAULT MODO: TX) ; (INTRODUCIR AQUÍ EL CONTENIDO DE LOS REGISTROS ; OBTENIDOS CON SMARTRF STUDIO) MAIN EQU 0XE1 FREQ_2A EQU 0X75 FREQ_1A EQU 0XA0 FREQ_0A EQU 0X00 FREQ_2B EQU 0X58 FREQ_1B EQU 0X33 FREQ_0B EQU 0X13 FSEP1 EQU 0X01 FSEP0 EQU 0XAB CURRENT EQU 0XF3 FRONT_END EQU 0X30 PA_POW EQU 0XFF PLL EQU 0X30 LOCK EQU 0X90 CAL EQU 0X26 MODEM2 EQU 0XC1 MODEM1 EQU 0X6F MODEM0 EQU 0X54 MATCH EQU 0X10 FSCTRL EQU 0X01 PREESCALER EQU 0X00 TEST4 EQU 0X3F ; PARA EL MODO DE RX LOS REGISTROS: MAIN, CURRENT Y PLL CAMBIAN DE VALOR. ; INTRODUCIR AQUÍ ESOS VALORES MAINRX EQU 0X11 CURRENTRX EQU 0X8C PLLRX EQU 0X40 CALRXTX EQU 0X26 ;/*************************************************************** ;* LAS SIGUIENTES CONSTANTES SON PARA EL RESET, CALIBARCIÓN, ;* POWER UP Y POWER DOWN DEL CC1000 NO ES NECESARIO MODIFICAR ;* ESTAS CONSTANTES ;***************************************************************/ ; CONTSTANTES PARA EL RESET (NO MODIFICAR!!) ; (PÁGINA 29 DEL DATASHEET DEL CC1000)
PPRROOYYEECCTTOO DDEE IINNGGEENNIIEERRÍÍAA
EELLEECCTTRRÓÓNNIICCAA
[[CCOOMMUUNNIICCAACCIIÓÓNN AA NNIIVVEELL EENNLLAACCEE DDEE DDAATTOOSS EENNTTRREE MMIICCRROOCCOONNTTRROOLLAADDOORREESS CCOONN UUNNIIDDAADDEESS DDEE RRAADDIIOOFFRREECCUUEENNCCIIAA]]
UUNNIIVVEERRSSIIDDAADD AAUUTTÓÓNNOOMMAA MMEETTRROOPPOOLLIITTAANNAA IIZZTTAAPPAALLAAPPAA CCaarrllooss EErrnneessttoo MMoorreennoo EEssccoobbaarr 220011221144115599
‐ 120 ‐
RESET1 EQU 0X3A RESET2 EQU 0X3B ; CONSTANTES PARA CALIBRACIÓN (NO MODIFICAR!!) ; (PÁGINA 26 DEL DATASHEET DEL CC1000) CCAL EQU 0XA6 ;INICIAR CALIBRACIÓN CPA_POW EQU 0X00 ;POWER DOWN MODE CMAIN EQU 0X3F ;MAIN EN \u017dMODO POWER DOWN ; CONSTANTES PARA HABILITACIÓN DE TX Y RX (NO MODIFICAR!!) ; (PÁG 30 DEL DATASHEET DEL CC1000) TURNONMAIN1 EQU 0X3B TURNONMAIN2 EQU 0X39 ; CONSTANTE PARA APAGAR MODO TX (NO MODIFICAR!!) TRN_OFF_TX EQU 0XFF ; CONSTANTE PARA APAGAR MODO RX (NO MODIFICAR!!) TRN_OFF_RX EQU 0X3F ; FILTRO PROMEDIO PARA UART (NO MODIFICAR!!) ; (TABLA 4 PÁGINA 20 DEL DATASHEET DEL CC1000) AUTOMATICO EQU 0X67 ;MODO AUTÓMATICO BLOQUEAR EQU 0X7F ;BLOQUEO MANUAL DESBLOQUEAR EQU 0X6F ;DESBLOQUEO MANUAL RESETAVFILTER EQU 0X6E ;**************** F I N D E L A T A B L A 1 ********************** ;************************************************************************* ;* DEFINICIONES DE LOS PUERTOS ;************************************************************************* #DEFINE SPI_CLK PORTB,4 ;SALIDA #DEFINE SPI_MOSI PORTB,5 ;SALIDA #DEFINE PALE PORTB,6 ;SALID #DEFINE DCLK PORTB,0 ;ENTRADA #DEFINE DIO PORTB,1 ;SALIDA/ENTRADA ORG 0 GOTO RESET ORG 4 GOTO ISR ;************************************************************************** ;* ISR ;* ESTA ISR ENVÍA EL DATO 101010...., CADA FLANCO DE SUBIDA DEL DCLK ;* DEL CC1000. SE ENVÍA UN SOLO BIT. ;* SE UTILIZA EL REGISTRO "AUX" PARA GENERAR LA TRAMA 10101.... ESTA ;* ISR ES UTILIZADA ÚNICAMENTE PARA EL PROGRAMA DE EJEMPLO EN EL ;* MODO TRANSMISIÓN. ;************************************************************************** ISR INCF AUX ;Incrementar AUX
BTFSS AUX,0 ;El bit 0 de AUX es 0? BCF DIO ; SI: mostrar un 0 en PB1 (transmitir un 0) BTFSC AUX,0 BSF DIO ; NO:mostrar un 1 en PB1 (transmitir un 1) BCF INTCON,INTF ;Limpiar bandera de interrupción RETFIE ;************************************************************************** ;* Configuración del PIC ;************************************************************************** RESET BANKSEL PCON ;Ajustar el Oscilador Interno en 4 Mhz BSF PCON,OSCF ;OSCF=1 ->4 MHz ;OSCF=0 ->48 kHz BANKSEL TRISB CLRF TRISB ;Puerto B como Salida
[[CCOOMMUUNNIICCAACCIIÓÓNN AA NNIIVVEELL EENNLLAACCEE DDEE DDAATTOOSS EENNTTRREE MMIICCRROOCCOONNTTRROOLLAADDOORREESS CCOONN UUNNIIDDAADDEESS DDEE
RRAADDIIOOFFRREECCUUEENNCCIIAA]]
PPRROOYYEECCTTOO DDEE IINNGGEENNIIEERRÍÍAA EELLEECCTTRRÓÓNNIICCAA
UUNNIIVVEERRSSIIDDAADD AAUUTTÓÓNNOOMMAA MMEETTRROOPPOOLLIITTAANNAA IIZZTTAAPPAALLAAPPAA CCaarrllooss EErrnneessttoo MMoorreennoo EEssccoobbaarr 220011221144115599
‐ 121 ‐
BSF TRISB,0 CLRF OPTION_REG BSF OPTION_REG,INTEDG ;Configurar interrupción por flanco de subida BSF OPTION_REG,NOT_RBPU BANKSEL PORTB BSF SPI_CLK ;Enciende CLK BSF PALE ;PALE=1 BCF SPI_MOSI ;MOSI = 0 ;************************************************************************** ;* PROGRAMA DE EJEMPLO ;* TRANSMISOR: SE CONFIGURA EL CC1000 COMO ;* TRANSMISOR Y SE ACTIVA LA INTERRUPCION POR FLANCO DE SUBIDA. ;* CADA FLANCO DE SUBIDA (GENERADO POR DCLK DEL CC1000) SE TRANSMITE ;* UNA TRAMA INFINITA DE 10101... ;* ;* RECEPTOR: SE CONFIGURA EL CC1000 COMO RECEPTOR. ;* NOTA: EN ESTA ETAPA SE RECIBEN LOS DATOS POR EL PIN PB1 PERO EL ;* CONTROLADOR NO HACE ABSOLUTAMENTE NADA (RECUERDA QUE UNICAMENTE ;* ES UN PROGRAMA DE MUESTRA). ;************************************************************************** TXMODE CALL INITCC1000 ;INICIALIZAR EL CC1000 CALL TURNONTX ;ENCENDER TRANSMISIÓN BANKSEL INTCON MOVLW B'10010000' MOVWF INTCON ;HABILITAR INTERRUPCIÓN EXTERNA FOREVER GOTO FOREVER ;ESPERAR EL FLANCO DE SUBIDA PARA TRANSMITIR ;************************************************** ;* SI QUIERES EL MODO DE RECEPCIÓN COMENTA LAS ;* INSTRUCCIONES MOSTRADAS ARRIBA (TXMODE) ;************************************************** RXMODE BANKSEL TRISB BSF TRISB,1 ;PIN DIO COMO ENTRADA BANKSEL PORTB CALL INITCC1000 ;INICIALIZAR EL CC1000 CALL TURNONRX ;ENCERDER RECEPCION FOREVER1 GOTO FOREVER1 ;NO HACER NADA ;*************************** FIN PROGRAMA DE EJEMPLO ********************** ;************************************************************************** ;************ F U N C I O N E S P A R A E L S P I ******************* ;**************************************************************************/ ;* ;* FUNCION ;* RW_SPI ; ;* DESCRIPCION ;* ;* Esta función implementa el protocolo SPI, por el pin RB4 podemos observar ;* el reloj del sistema y por el pin RB5 observamos el bit que será ;* transmitido hacia el CC1000. ESTA FUNCIÓN ÚNICAMENTE TRANSMITE. NO LEE. ;* Esta función se ha obtenido de: ;* http://www.maxim-ic.com/appnotes.cfm/an_pk/2361 pero ha sido modificada. ;***************************************************************************/ RW_SPI movlw 08h ;Send 8 bits movwf CONT SPI_w_loop: btfsc SPIDR, 7 bsf SPI_MOSI ; if data out=1, set bit bcf SPI_CLK bcf SPI_MOSI ; assume data out is low
PPRROOYYEECCTTOO DDEE IINNGGEENNIIEERRÍÍAA
EELLEECCTTRRÓÓNNIICCAA
[[CCOOMMUUNNIICCAACCIIÓÓNN AA NNIIVVEELL EENNLLAACCEE DDEE DDAATTOOSS EENNTTRREE MMIICCRROOCCOONNTTRROOLLAADDOORREESS CCOONN UUNNIIDDAADDEESS DDEE RRAADDIIOOFFRREECCUUEENNCCIIAA]]
UUNNIIVVEERRSSIIDDAADD AAUUTTÓÓNNOOMMAA MMEETTRROOPPOOLLIITTAANNAA IIZZTTAAPPAALLAAPPAA CCaarrllooss EErrnneessttoo MMoorreennoo EEssccoobbaarr 220011221144115599
‐ 122 ‐
SPI_w_cont: rlf SPIDR, 1 bsf SPI_CLK ; clock it in decfsz CONT, 1 goto SPI_w_loop BCF SPI_MOSI ;MOSI = 0 return ;/**************************************************************************** ;* FUNCIÓN: ;* RESETCC1000 ;* ;* DESCRIPCIÓN: ;* ;* ESTA SUBRUTINA LEE DE LA MEMORIA RAM LAS DIRECCIONES Y DATOS DE LOS ;* REGISTROS NECESARIOS PARA REESTABLECER EL CC1000, EL ALGORITMO ES EL ;* SIGUIENTE: ;* 1. ESCRIBIR EN MAIN: $FE ;* 2. ESCRIBIR EN MAIN: $FF ;* 3. ESPERAR 2msegundos ;* ;* PRIMERO SE TRANSMITE LA DIRECCIÓN DE MAIN, POSTERIORMENTE EL DATO QUE ;* DEBE SER GUARDADO, ESTE PROCEDIMIENTO SE REALIZA DOS VECES. ;* FIGURA 18 PAGINA 29 (DATASHEET DEL CC1000) ;*******************************************************************************/ RESETCC1000 ;RESET EL CC1000 MOVLW AMAIN MOVWF ADDRESS MOVLW RESET1 ;RESET_N=0 MOVWF DATO CALL WRITETOCC1000 MOVLW RESET2 ;RESET_N=1 MOVWF DATO CALL WRITETOCC1000 CALL Retardo_2ms RETURN ;/***************************************************************************** ;* FUNCIÓN: WRITETOCC1000 ;* ESTA SUBRUTINA PRIMERO HABILITA EL PALE DEL CC1000, POSTERIORMENTE ;* TRANSMITE LA DIRECCIÓN HACIA EL CC1000 Y EL DATO A GRABAR EN LOS ;* REGISTROS DEL CC1000. ;* ;* EL ALGORITMO ES EL SIGUIENTE: ;* 1. PALE=1 ;* 2. GENERAR BIT DE R/W Y TRANSMITIR DIRECCIÓN AL CC1000. ;* 3. PALE=0 ;* 4. TRANSMITIR DATO ;* 5. REGRESO DE SUBRUTINA ;* ;* FIGURA 19 PÁGINA 30 (DATASHEET DEL CC1000) ;****************************************************************************/ WRITETOCC1000 BCF PALE ;HABILITACIÓN DEL PROGRAM ADDRES LATCH MOVFW ADDRESS ;CARGA LA DIRECCIÓN DEL REGISTRO MAIN MOVWF SPIDR BSF STATUS,C ; BIT DE ESCRITURA (R/W) RLF SPIDR,F CALL RW_SPI ;TRANSMITIR LA DIRECCIÓN BSF PALE ;DESHABILITA EL PROGRAM ADDRES LATCH MOVFW DATO MOVWF SPIDR CALL RW_SPI ;TRANSMITIR DATO RETURN ;/***************************************************************************** ;* FUNCIÓN: ;* INITCC1000
[[CCOOMMUUNNIICCAACCIIÓÓNN AA NNIIVVEELL EENNLLAACCEE DDEE DDAATTOOSS EENNTTRREE MMIICCRROOCCOONNTTRROOLLAADDOORREESS CCOONN UUNNIIDDAADDEESS DDEE
RRAADDIIOOFFRREECCUUEENNCCIIAA]]
PPRROOYYEECCTTOO DDEE IINNGGEENNIIEERRÍÍAA EELLEECCTTRRÓÓNNIICCAA
UUNNIIVVEERRSSIIDDAADD AAUUTTÓÓNNOOMMAA MMEETTRROOPPOOLLIITTAANNAA IIZZTTAAPPAALLAAPPAA CCaarrllooss EErrnneessttoo MMoorreennoo EEssccoobbaarr 220011221144115599
‐ 123 ‐
;* ;* DESCRIPCIÓN: ;* ;* ESTA SUBRUTINA LEE DE LAS TABLAS "DIRECCIONES" Y "DATOS" LOS DATOS ;* A SER GRABADOS EN LOS REGISTROS DEL CC1000, ;* LA FUNCION "LEEDIRECCIONES" REGRESA LA DIRECCIÓN DEL REGISTRO DEL CC1000 Y ;* ÉSTE ES ALMACENADO EN EL REGISTRO ADDRESS. LA FUNCIÓN "LEEDATOS" REGRESA EL ;* CONTENIDO DEL REGISTRO A SER GRABADO. ;* ;* ESTA SUBRUTINA SE EJECUTA 21 VECES (YA QUE SON 21 REGISTROS) ;******************************************************************************/ INITCC1000 ;GRABAR LOS REGISTROS DEL CC1000 (EXCEPTO MAIN) CALL RESETCC1000 MOVLW .21 MOVWF CONFIG_CONT TXRX_CONFIG CALL LEEDIRECCIONES ;Obten dirección del registro MOVWF ADDRESS ;Almacénalo en ADDRESS CALL LEEDATOS ;Obten dato a ser grabado MOVWF DATO ;Almacénalo en DATO CALL WRITETOCC1000 ;Escribe en el CC1000 DECFSZ CONFIG_CONT ; Se ha transmitido el último dato? GOTO TXRX_CONFIG ; NO: Continua transmitiedo ;/***************************************************************************** ;* SECUENCIA DE CALIBRACIÓN DEL CC1000 ;* ;* ;* DESCRIPCIÓN: ;* ;* ESTA SUBRUTINA ENVÍA LOS DATOS QUE DEBEN SER CARGADOS EN LOS REGISTROS PARA ;* LA CALIBRACIÓN DEL CC1000. EL ARGORITMO SE ENCUENTRA EN LA PÁGINA 26 DEL ;* DATASHEET DEL CC1000. ;* ;* ALGORITMO: ;* ;* 1. MAIN: TX_D=1,RESET_N=1 ;CALIBRAR PRIMERO TX ;* 2. CURRENT=RX CURRENT ;* 3. PLL=RX PLL ;* 4. CAL: CAL_START=1 ;* 5 ESPERA 34 mS ;* 6. CAL: CAL_START=0 (ESTADO ORIGINAL) ;* ;* 7. MAIN: RXTX=1,FREG=1,RXPD=1,REST_N=1 ;CALIBRAR DESPUÉS RX ;* 8. CURRENT=TX CURRENT ;* 9. PLL=RX PLL ;* 10. PA_POW=00h ;* 11. CAL: CAL_START=1 ;* 12 ESPERA 34 mS ;* 13. CAL: CAL_START=0 (ESTADO ORIGINAL) ;* 14. TERMINA ;* ;* FIGURA 16. PÁGINA 26. (DATASHEET DEL CC1000) ;******************************************************************************/ MOVLW AMAIN ;INICIA CALIBRACIÓN MOVWF ADDRESS ; CALIBRAR RX PRIMERO MOVLW MAINRX MOVWF DATO CALL WRITETOCC1000 MOVLW ACURRENT MOVWF ADDRESS MOVLW CURRENTRX MOVWF DATO CALL WRITETOCC1000 MOVLW APLL MOVWF ADDRESS MOVLW PLLRX MOVWF DATO CALL WRITETOCC1000
PPRROOYYEECCTTOO DDEE IINNGGEENNIIEERRÍÍAA
EELLEECCTTRRÓÓNNIICCAA
[[CCOOMMUUNNIICCAACCIIÓÓNN AA NNIIVVEELL EENNLLAACCEE DDEE DDAATTOOSS EENNTTRREE MMIICCRROOCCOONNTTRROOLLAADDOORREESS CCOONN UUNNIIDDAADDEESS DDEE RRAADDIIOOFFRREECCUUEENNCCIIAA]]
UUNNIIVVEERRSSIIDDAADD AAUUTTÓÓNNOOMMAA MMEETTRROOPPOOLLIITTAANNAA IIZZTTAAPPAALLAAPPAA CCaarrllooss EErrnneessttoo MMoorreennoo EEssccoobbaarr 220011221144115599
‐ 124 ‐
MOVLW ACAL MOVWF ADDRESS MOVLW CCAL MOVWF DATO CALL WRITETOCC1000 CALL Retardo_34ms MOVLW CAL MOVWF DATO CALL WRITETOCC1000 MOVLW AMAIN ; CALIBRAR TX MOVWF ADDRESS MOVLW MAIN MOVWF DATO CALL WRITETOCC1000 MOVLW ACURRENT MOVWF ADDRESS MOVLW CURRENT MOVWF DATO CALL WRITETOCC1000 MOVLW APLL MOVWF ADDRESS MOVLW PLL MOVWF DATO CALL WRITETOCC1000 MOVLW APA_POW MOVWF ADDRESS MOVLW CPA_POW MOVWF DATO CALL WRITETOCC1000 MOVLW ACAL MOVWF ADDRESS MOVLW CCAL MOVWF DATO CALL WRITETOCC1000 CALL Retardo_34ms MOVLW CAL MOVWF DATO CALL WRITETOCC1000 ;FIN DE LA CALIBRACIÓN MOVLW AMAIN ;PROGRAMAR MAIN EN MODO POWER DOWN MOVWF ADDRESS MOVLW CMAIN MOVWF DATO CALL WRITETOCC1000 MOVLW APA_POW ;POWER DOWN MODE: PA_POW=00h MOVWF ADDRESS MOVLW CPA_POW MOVWF DATO CALL WRITETOCC1000 RETURN ;/***************************************************************************** ;* FUNCIÓN: TURNONTX ;* ESTA SUBRUTINA HABILITA EL CC1000 PARA TRANSMISIÓN ;* ;* FIGURA 19 PÁGINA 30 (DATASHEET DEL CC1000) ;****************************************************************************/ TURNONTX MOVLW AMAIN ;POWER DOWN MODE: PA_POW=00h MOVWF ADDRESS MOVLW TURNONMAIN1 MOVWF DATO CALL WRITETOCC1000 CALL Retardo_2ms MOVLW TURNONMAIN2 MOVWF DATO CALL WRITETOCC1000 CALL Retardo_200micros CALL Retardo_50micros
[[CCOOMMUUNNIICCAACCIIÓÓNN AA NNIIVVEELL EENNLLAACCEE DDEE DDAATTOOSS EENNTTRREE MMIICCRROOCCOONNTTRROOLLAADDOORREESS CCOONN UUNNIIDDAADDEESS DDEE
RRAADDIIOOFFRREECCUUEENNCCIIAA]]
PPRROOYYEECCTTOO DDEE IINNGGEENNIIEERRÍÍAA EELLEECCTTRRÓÓNNIICCAA
UUNNIIVVEERRSSIIDDAADD AAUUTTÓÓNNOOMMAA MMEETTRROOPPOOLLIITTAANNAA IIZZTTAAPPAALLAAPPAA CCaarrllooss EErrnneessttoo MMoorreennoo EEssccoobbaarr 220011221144115599
‐ 125 ‐
MOVLW APA_POW ;POWER DOWN MODE: PA_POW=00h MOVWF ADDRESS MOVLW CPA_POW MOVWF DATO CALL WRITETOCC1000 MOVLW AMAIN MOVWF ADDRESS MOVLW MAIN MOVWF DATO CALL WRITETOCC1000 MOVLW ACURRENT MOVWF ADDRESS MOVLW CURRENT MOVWF DATO CALL WRITETOCC1000 MOVLW APLL MOVWF ADDRESS MOVLW PLL MOVWF DATO CALL WRITETOCC1000 CALL Retardo_200micros CALL Retardo_50micros MOVLW APA_POW MOVWF ADDRESS MOVLW PA_POW MOVWF DATO CALL WRITETOCC1000 CALL Retardo_200micros CALL Retardo_50micros RETURN ;/***************************************************************************** ;* FUNCIÓN: TURNOFFTX ;* ESTA SUBRUTINA DESHABILITA LA TRANSMISIÓN DEL CC1000 ;* ;* FIGURA 19 PÁGINA 30 (DATASHEET DEL CC1000) ;****************************************************************************/ TURNOFFTX MOVLW AMAIN MOVWF ADDRESS MOVLW TRN_OFF_TX MOVWF DATO CALL WRITETOCC1000 MOVLW APA_POW MOVWF ADDRESS MOVLW 0X00 MOVWF DATO CALL WRITETOCC1000 RETURN ;/***************************************************************************** ;* FUNCIÓN: TURNONRX ;* ESTA SUBRUTINA HABILITA EL CC1000 PARA RECEPCIÓN ;* ;* FIGURA 19 PÁGINA 30 (DATASHEET DEL CC1000) ;****************************************************************************/ TURNONRX MOVLW AMAIN MOVWF ADDRESS MOVLW TURNONMAIN1 MOVWF DATO CALL WRITETOCC1000 CALL Retardo_2ms MOVLW TURNONMAIN2 MOVWF DATO CALL WRITETOCC1000 CALL Retardo_200micros CALL Retardo_50micros CALL WRITETOCC1000 MOVLW AMAIN
PPRROOYYEECCTTOO DDEE IINNGGEENNIIEERRÍÍAA
EELLEECCTTRRÓÓNNIICCAA
[[CCOOMMUUNNIICCAACCIIÓÓNN AA NNIIVVEELL EENNLLAACCEE DDEE DDAATTOOSS EENNTTRREE MMIICCRROOCCOONNTTRROOLLAADDOORREESS CCOONN UUNNIIDDAADDEESS DDEE RRAADDIIOOFFRREECCUUEENNCCIIAA]]
UUNNIIVVEERRSSIIDDAADD AAUUTTÓÓNNOOMMAA MMEETTRROOPPOOLLIITTAANNAA IIZZTTAAPPAALLAAPPAA CCaarrllooss EErrnneessttoo MMoorreennoo EEssccoobbaarr 220011221144115599
‐ 126 ‐
MOVWF ADDRESS MOVLW MAINRX MOVWF DATO CALL WRITETOCC1000 MOVLW ACURRENT MOVWF ADDRESS MOVLW CURRENTRX MOVWF DATO CALL WRITETOCC1000 MOVLW APLL MOVWF ADDRESS MOVLW PLLRX MOVWF DATO CALL WRITETOCC1000 CALL Retardo_200micros CALL Retardo_50micros RETURN ;/***************************************************************************** ;* FUNCIÓN: TURNOFFRX ;* ESTA SUBRUTINA DESHABILITA LA RECEPCIÓN DEL CC1000 ;* ;* FIGURA 19 PÁGINA 30 (DATASHEET DEL CC1000) ;****************************************************************************/ TURNOFFRX MOVLW AMAIN MOVWF ADDRESS MOVLW TRN_OFF_RX MOVWF DATO CALL WRITETOCC1000 MOVLW APA_POW MOVWF ADDRESS MOVLW 0X00 MOVWF DATO CALL WRITETOCC1000 RETURN ;/***************************************************************************** ;* FUNCIÓN: AVER_AUTO ;* ESTA SUBRUTINA CONFIGURA EL MODO AUTOMÁTICO PARA DETECTAR EL PREÁMBULO ;* ;* TABLA 4 PÁGINA 20 (DATASHEET DEL CC1000) ;****************************************************************************/ AVER_AUTO MOVLW AMODEM1 MOVWF ADDRESS MOVLW AUTOMATICO MOVWF DATO CALL WRITETOCC1000 RETURN ;/***************************************************************************** ;* FUNCIÓN: AVER_BLOQ ;* ESTA SUBRUTINA BLOQUEA MANUALMENTE EL FILTRO PROMEDIO ;* ;* TABLA 4 PÁGINA 20 (DATASHEET DEL CC1000) ;****************************************************************************/ AVER_BLOQ MOVLW AMODEM1 MOVWF ADDRESS MOVLW BLOQUEAR MOVWF DATO CALL WRITETOCC1000 RETURN ;/***************************************************************************** ;* FUNCIÓN: AVER_DESBLOQ ;* ESTA SUBRUTINA DESBLOQUEA MANUALMENTE EL FILTRO PROMEDIO ;* ;* TABLA 4 PÁGINA 20 (DATASHEET DEL CC1000) ;****************************************************************************/
[[CCOOMMUUNNIICCAACCIIÓÓNN AA NNIIVVEELL EENNLLAACCEE DDEE DDAATTOOSS EENNTTRREE MMIICCRROOCCOONNTTRROOLLAADDOORREESS CCOONN UUNNIIDDAADDEESS DDEE
RRAADDIIOOFFRREECCUUEENNCCIIAA]]
PPRROOYYEECCTTOO DDEE IINNGGEENNIIEERRÍÍAA EELLEECCTTRRÓÓNNIICCAA
UUNNIIVVEERRSSIIDDAADD AAUUTTÓÓNNOOMMAA MMEETTRROOPPOOLLIITTAANNAA IIZZTTAAPPAALLAAPPAA CCaarrllooss EErrnneessttoo MMoorreennoo EEssccoobbaarr 220011221144115599
‐ 127 ‐
AVER_DESBLOQ MOVLW AMODEM1 MOVWF ADDRESS MOVLW DESBLOQUEAR MOVWF DATO CALL WRITETOCC1000 RETURN ;/***************************************************************************** ;* FUNCIÓN: RESET_AVFILTER ;* ESTA SUBRUTINA RESETEA EL FILTRO PROMEDIO ;* ;* PÁGINA 19 (DATASHEET DEL CC1000) ;****************************************************************************/ RESET_AVFILTER MOVLW AMODEM1 MOVWF ADDRESS MOVLW RESETAVFILTER MOVWF DATO CALL WRITETOCC1000 CALL AVER_DESBLOQ RETURN ORG 0X110 ;/***************************************************************************** ;* FUNCIÓN: LEEDIRECCIONES y LEEDATOS ;* Esta subrutina carga en el program counter la dirección del dato que ;* es requerido para la configuración. Utiliza como "offset" el registro ;* CONFIG_CONT, el cual, se decrementa en la función INITCC1000. ;* ;****************************************************************************/ LEEDIRECCIONES MOVLW HIGH DIRECCIONES MOVWF PCLATH MOVLW LOW DIRECCIONES ADDWF CONFIG_CONT,W MOVWF PCL LEEDATOS MOVLW HIGH DATOS MOVWF PCLATH MOVLW LOW DATOS ADDWF CONFIG_CONT,W MOVWF PCL ;******************************************************** ;* TABLAS: ;* Las tablas mostradas a continuación son para la ;* configuración del CC1000. Las constantes mostradas ;* pueden modificarse al inicio de este ASM (según la ;* configuración deseada) ;******************************************************** DIRECCIONES NOP RETLW AFREQ_2A RETLW AFREQ_1A RETLW AFREQ_0A RETLW AFREQ_2B RETLW AFREQ_1B RETLW AFREQ_0B RETLW AFSEP1 RETLW AFSEP0 RETLW ACURRENT RETLW AFRONT_END RETLW APA_POW RETLW APLL RETLW ALOCK RETLW ACAL RETLW AMODEM2 RETLW AMODEM1 RETLW AMODEM0
PPRROOYYEECCTTOO DDEE IINNGGEENNIIEERRÍÍAA
EELLEECCTTRRÓÓNNIICCAA
[[CCOOMMUUNNIICCAACCIIÓÓNN AA NNIIVVEELL EENNLLAACCEE DDEE DDAATTOOSS EENNTTRREE MMIICCRROOCCOONNTTRROOLLAADDOORREESS CCOONN UUNNIIDDAADDEESS DDEE RRAADDIIOOFFRREECCUUEENNCCIIAA]]
UUNNIIVVEERRSSIIDDAADD AAUUTTÓÓNNOOMMAA MMEETTRROOPPOOLLIITTAANNAA IIZZTTAAPPAALLAAPPAA CCaarrllooss EErrnneessttoo MMoorreennoo EEssccoobbaarr 220011221144115599
‐ 128 ‐
RETLW AMATCH RETLW AFSCTRL RETLW APREESCALER RETLW ATEST4 DATOS NOP RETLW FREQ_2A RETLW FREQ_1A RETLW FREQ_0A RETLW FREQ_2B RETLW FREQ_1B RETLW FREQ_0B RETLW FSEP1 RETLW FSEP0 RETLW CURRENT RETLW FRONT_END RETLW PA_POW RETLW PLL RETLW LOCK RETLW CAL RETLW MODEM2 RETLW MODEM1 RETLW MODEM0 RETLW MATCH RETLW FSCTRL RETLW PREESCALER RETLW TEST4 INCLUDE <RETARDOS.INC> END
BBIIBBLLIIOOGGRRAAFFÍÍAA
Notas de AplicaciónATMEL
• ATMEL ATMEGA8535L‐8PI Datasheet • ATMEL Application Note 151: “Setup ad use SPI” • ATMEL Application Note 236 : “CRC check of program memory” • ATMEL Application Note 320 : “Software SPI Master”
CHIPCON • CHIPCON CC1000 Datasheet • CHIPCON CC1000PP User Manual • CHIPCON Application Note 003: “SDR Antennas” • CHIPCON Application Note 009: “CC1000/CC1050 Microcontroller
Interfacing” • CHIPCON Application Note 015: “RF Modem Reference Design”
Internet
• A Painless Guide to Error Detection Algorithms. Ross N. Williams. ftp://ftp.rocksoft.com/papers/crc_v3.txt
• Computer Networking: A Top‐Down Approach Featuring the internet. James F.
Kurose y Keith W. Ross. Editorial Addison Wesley. 1999 • Computer Networks. Andrew S. Tanenbaun. Editorial: Prentice Hall PTR. 2003. • Data Communication, Computer Networks and Open Systems. Editorial: Addison‐
Wesley Publishers 1992. • Protocols And Architecture for Wireless Sensor Networks. Holger Karl, Andreas
Willing. Editorial: John Wiley & Sons,2006 • Sistemas Digitales: Principios y Aplicaciones. Tocci, Ronald J. Editorial Prentice
[[CCOOMMUUNNIICCAACCIIÓÓNN AA NNIIVVEELL EENNLLAACCEE DDEE DDAATTOOSS EENNTTRREE MMIICCRROOCCOONNTTRROOLLAADDOORREESS CCOONN UUNNIIDDAADDEESS DDEE
RRAADDIIOOFFRREECCUUEENNCCIIAA]]
PPRROOYYEECCTTOO DDEE IINNGGEENNIIEERRÍÍAA EELLEECCTTRRÓÓNNIICCAA
UUNNIIVVEERRSSIIDDAADD AAUUTTÓÓNNOOMMAA MMEETTRROOPPOOLLIITTAANNAA IIZZTTAAPPAALLAAPPAA CCaarrllooss EErrnneessttoo MMoorreennoo EEssccoobbaarr 220011221144115599
‐ 129 ‐
Hall Hispanoamericana. 1993• Transmisión de información Modulación y Ruido. Schwartz, Mischa. Editorial
McGraw Hill. 1983. • Wireless Sensor Networks: An Information Processing Approach. Feng Zhao,
Leonidas Guibas. Editorial: Morgan Kaufmann Publishers. 2004