Untitled - Biblioteca

Anuncio
PARA LAS ÚNICAS PERSONAS QUE ME INTERESAN EN EL
MUNDO. PUES LO DEMÁS ES VANO.
PARA MIS PADRES….
GRACIAS
“ Y a ti . . . Porque estarás conmigo desde hoy, hasta el fin de los
tiempos. Y he de tomar mi lugar, en las leyendas del pasado ”
A mis padres, Cristóbal Orantes Verdugo y Rosa Osuna. Por ayudarme en lo que
que sea y por sus esfuerzos que no han sido en vano.
A mi asesor, Maestro en ciencias Javier Pérez, Por su apoyo y asesoría.
A los maestros revisores, Mtro. Eduardo romero, Mtro. Othon y Mtro. Solís. Por
su ayuda a la realización de este trabajo y por sus enseñanzas.
A todos los maestros que a través del curso de mi carrera, dedicarón de su
tiempo en mi aprendizaje.
A mi compañero Gabriel Enríque Cázares enriquez, por su amistad y compañía.
Y sobre todo a Isidro Murrieta Dorame, Por patrocinarme con la computadora, y
darme su amistad a través del tiempo que hemos estado juntos y sin estar juntos
también.
i
ÍNDICE
Página
LISTA DE FIGURAS............................................................................................... iv
LISTA DE TABLAS................................................................................................. vii
RESUMEN............................................................................................................... viii
I INTRODUCCIÓN................................................................................................... 1
1.1 Antecedentes.......................................................................................... 1
1.2 Definición del problema........................................................................... 4
1.3 Justificación............................................................................................. 4
1.4 Objetivo.................................................................................................... 4
1.5 Delimitaciones.......................................................................................... 5
1.6 Referencias............................................................................................... 5
II MARCO TEÓRICO................................................................................................ 6
2.1 USB (universal serial bus)........................................................................ 6
2.1.1 Introducción............................................................................... 6
2.1.2 Conexiones................................................................................ 7
2.1.3 Comunicación............................................................................ 8
2.1.4 Paquetes.................................................................................... 10
2.1.5 Transacciones o Transferencias................................................ 11
2.1.6 HUB........................................................................................... 13
2.1.7 Descriptores.............................................................................. 15
2.1.8 Clases (Class) y subclases (Subclass)..................................... 16
2.1.9 Enumeración y Estados del dispositivo.................................... 19
2.1.10 Protocolo, Tramas y Campos de bits....................................... 23
2.1.11 Formato de paquetes............................................................... 24
2.1.12 Formato de transferencia......................................................... 26
2.1.13 Requisiciones........................................................................... 27
2.1.14 Formato de los descriptores..................................................... 29
ii
2.1.15 Descriptor reporte (Report descriptor)...................................... 32
2.1.16 Descriptor físico (physical report)............................................. 44
2.1.17 Dispositivo de interfaz humana (HID)....................................... 46
2.2 Microcontroladores................................................................................... 47
2.2.1 Introducción............................................................................... 47
2.2.2 Puertos de entrada y salida........................................................ 49
2.2.3 Módulo USART........................................................................... 50
2.2.4 Módulo ADC................................................................................ 52
2.2.5 Módulo USB................................................................................ 53
2.3 Freeware.................................................................................................. 57
2.3.1 Introducción................................................................................ 57
2.3.2 Código fuente en ensamblador del freeware.............................. 59
2.3.3 Funciones del código fuente de ensamblador............................ 59
2.3.4 API de Visual Basic (ACTIVEX).................................................. 60
2.3.5 Asiganación del controlador (Driver)........................................... 65
2.4 Referencias.............................................................................................. 66
III DESARROLLO..................................................................................................... 67
3.1 Introducción.............................................................................................. 67
3.2 Conexión de microcontroladores.............................................................. 71
3.3 Modos de funcionamiento........................................................................ 73
3.4 Adecuación del firmware.......................................................................... 75
3.5 Diseño del software para la PC................................................................ 76
3.5.1 Diseño modo de conexión con la PC.......................................... 76
3.5.2 Diseño modo de conexión con el PLC........................................ 82
3.6 Programación de microcontroladores....................................................... 86
3.6.1 Inicialización de microcontroladores (modo conexión PC)......... 86
3.6.2 Inicialización de microcontroladores (modo conexión PLC)....... 87
3.6.3 Generador de señales de activación (modo conexión PC)......... 89
3.6.4 Generador de señales de activación (modo conexión PLC)....... 93
3.6.5 Recepción de datos y claves de conmutación............................ 95
iii
3.6.6 Recepción y apilamiento de datos en RAM................................ 98
3.6.7 Detector de frecuencia válida.................................................... 101
3.6.8 Generador de señal de dato...................................................... 103
3.6.9 Medición de señales de frecuencia........................................... 108
IV PRUEBAS Y RESULTADOS.............................................................................. 113
V CONCLUSIONES Y RECOMENDACIONES....................................................... 120
BIBLIOGRAFÍA....................................................................................................... 122
ANEXOS...................................................................................................................123
Anexo1 Código completo de los programas………………............................ 124
Anexo2 Cuadros de diálogos en el proceso de enumeración....................... 167
Anexo3 Jumpers de configuración................................................................ 172
Anexo4 Fotografias completas de los módulos............................................. 173
Anexo5 Diagramas de los programas en ensamblador................................ 174
iv
LISTA DE FIGURAS
Página
Figura 1.1 Tuberías superficiales........................................................................................................ 1
Figura 1.2 Tubería subterránea........................................................................................................... 1
Figura 1.3 Filtración de humedad........................................................................................................ 1
Figura 1.4 Sistema de riego automatizado (esquema general) …...................................................... 2
Figura 1.5 Sistema de monitoreo........................................................................................................ 3
Figura 2.1 Topología........................................................................................................................... 6
Figura 2.2 Cable.................................................................................................................................. 7
Figura 2.3 (Conector a, Conector b, Receptor a y Receptor b) .......................................................... 7
Figura 2.4 Pines correspondientes (1= Vbus, 2 = d-, 3 = d+, 4 = GND) ........................................... 7
Figura 2.5 Flujo de comunicación (lógica y física) .............................................................................. 8
Figura 2.6 Conexión lógica.................................................................................................................. 9
Figura 2.7 Transacciones (ejemplo) .................................................................................................. 12
Figura 2.8 Ancho de banda................................................................................................................ 12
Figura 2.9 Flujo de información en el hub.......................................................................................... 14
Figura 2.10 El host cuenta con un hub integrado llamado root hub..................................................... 14
Figura 2.11 Descriptores para una y dos interfaces............................................................................. 22
Figura 2.12 Formato de los tokens (IN, OUT y SETUP) ..................................................................... 25
Figura 2.13 Formato del token SOF..................................................................................................... 25
Figura 2.14 Formato del paquete de datos.......................................................................................... 25
Figura 2.15 Token handshake.............................................................................................................. 25
Figura 2.16 Transferencia síncrono y transferencia control................................................................. 26
Figura 2.17 Transferencia bulto (bulk) ................................................................................................. 26
Figura 2.18 Transferencia interrupción................................................................................................. 27
Figura 2.19 Formato para un endpoint específicamente...................................................................... 28
Figura 2.20 Formato para una interfaz específicamente...................................................................... 28
Figura 2.21 ítem Short.......................................................................................................................... 32
Figura 2.22 ítem Long.......................................................................................................................... 32
Figura 2.23 Estructura del descriptor reporte....................................................................................... 43
Figura 2.24 Mapa de memoria del PIC 16C745................................................................................... 48
Figura 2.25 Mapa de memoria del PIC 16F628................................................................................... 49
Figura 2.26 Comunicación serie síncrona............................................................................................ 51
Figura 2.27 Protocolo serie asíncrono.................................................................................................. 51
Figura 2.28 Registro TXSTA................................................................................................................ 51
Figura 2.29 Registro RXSTA................................................................................................................ 51
Figura 2.30 Registro PIR1 del PIC 16C745.......................................................................................... 52
Figura 2.31 Registro PIE1 del pic 16C745........................................................................................... 52
Figura 2.32 Registro ADCON0 del pic 16F873.................................................................................... 52
Figura 2.33 Registro ADCON1 del pic 16F873.................................................................................... 52
Figura 2.34 Registro UIR...................................................................................................................... 53
Figura 2.35 Registro UIE...................................................................................................................... 53
Figura 2.36 Registro UEIR................................................................................................................... 53
Figura 2.37 Registro UEIE.................................................................................................................... 53
Figura 2.38 Registro UCTRL................................................................................................................ 54
Figura 2.39 Registro UADDR............................................................................................................... 54
Figura 2.40 Registro USWSTAT.......................................................................................................... 54
Figura 2.41 Registro UEPn................................................................................................................... 54
Figura 2.42 Tabla de configuración de enpoints.................................................................................. 55
Figura 2.43 Registro BdndAL............................................................................................................... 55
Figura 2.44 Registro BDndBC.............................................................................................................. 56
Figura 2.45 Registro BDndST leído por el MCU.................................................................................. 56
Figura 2.46 Registro BDndBC escrito por el MCU............................................................................... 56
v
Página
Figura 2.47 Registro USTAT................................................................................................................ 56
Figura 2.48 Diagrama para la rutina de servicio de interrupción.......................................................... 57
Figura 2.49 Tipos de tokens que atiende el freeware.......................................................................... 58
Figura 2.50 Cuadro de dialogo en win98.............................................................................................. 65
Figura 3.1 Sistema de riego............................................................................................................... 67
Figura 3.2 Etapas de ambos módulos principales.............................................................................. 67
Figura 3.3 Etapas del módulo maestro............................................................................................... 69
Figura 3.4 Barra de LEDS.................................................................................................................. 69
Figura 3.5 Vista frontal y superior del conector PLC en el módulo maestro...................................... 69
Figura 3.6 Etapas del módulo esclavo............................................................................................... 70
Figura 3.7 Conexion a detalle de los microcontroladores 16f628 y 16c745....................................... 71
Figura 3.8 Conexion a detalle del microcontrolador 16f873............................................................... 72
Figura 3.9 Modo conexión con la PC................................................................................................. 74
Figura 3.10 Modo conexión con el PLC............................................................................................... 74
Figura 3.11 Conector db9 (pines correspondientes) ........................................................................... 74
Figura 3.12 Adecuación al firmware..................................................................................................... 75
Figura 3.13 Proceso de activación en el modo de conexión con la PC............................................... 76
Figura 3.14 Programa en vista de diseño............................................................................................. 77
Figura 3.15 Base de datos para los transductores............................................................................... 78
Figura 3.16 Base de datos para los tiempos de barridos..................................................................... 78
Figura 3.17 Interfaz para el barrido de lecturas manual....................................................................... 79
Figura 3.18 Temporizadores del programa.......................................................................................... 79
Figura 3.19 Funciones del programa.................................................................................................... 80
Figura 3.20 Funcion del timer2............................................................................................................. 81
Figura 3.21 Proceso de activación en el modo de conexión con el PLC............................................. 82
Figura 3.22 Programa en vista de diseño............................................................................................. 83
Figura 3.23 Programa en tiempo de ejecución...................................................................................... 83
Figura 3.24 Función del botón enviar................................................................................................... 85
Figura 3.25 Código para la inicialización del puerto USB y configuraciones de puertos..................... 86
Figura 3.26 Configuración del puerto serie síncrono e inicializaciones................................................ 87
Figura 3.27 Rutina para la configuración del puerto serie síncrono e inicializaciones......................... 88
Figura 3.28 Rutina para inicialización de variables, configuración de puerto y RSI (PIC16F873) …... 88
Figura 3.29 Rutina para el generador de frecuencia o señales de activación...................................... 89
Figura 3.30 Gráfica de la tabla 3.1....................................................................................................... 91
Figura 3.31 Comparación de la ecuación obtenida y los datos de la tabla 3.1.................................... 92
Figura 3.32 Rutina para el generador de señales................................................................................ 93
Figura 3.33 Caracterización del generador de señales de activación.................................................. 94
Figura 3.34 Comparación de la ecuación y los datos de la tabla 3.2................................................... 95
Figura 3.35 Clave1 (arriba línea de dato, abajo línea de reloj) ........................................................... 96
Figura 3.36 Led indicador.................................................................................................................... 96
Figura 3.37 Clave2 (arriba línea de dato, abajo línea de reloj) ........................................................... 97
Figura 3.38 Rutina de interrupción serie síncrona................................................................................ 97
Figura 3.39 Led indicador para cálculo de retardo............................................................................... 98
Figura 3.40 Rutina para la recepción y transmisión de datos.............................................................. 99
Figura 3.41 Rutina para la recepción serie síncrona de datos y su clasificación................................. 99
Figura 3.42 Rutina para el temporizador............................................................................................. 100
Figura 3.43 Ruido presente en estado de reposo (osciloscopio y acercamiento) .............................. 101
Figura 3.44 Rutina para el generador de datos o frecuencia.............................................................. 104
Figura 3.45 Cálculo del número necesario para generar la frecuencia de dato.................................. 105
Figura 3.46 Rutina para determinar el rango de error de la muestra de frecuencia............................ 106
Figura 3.47 Rutina para la adquisición de dato y proceso de cálculo................................................. 107
vi
Página
Figura 3.48 Rutina para el medidor de frecuencia.............................................................................. 108
Figura 3.49 Resultado de la medición de frecuencia.......................................................................... 110
Figura 3.50 Rutina de servicio de interrupción serie síncrona............................................................ 111
Figura 3.51 Recepción de datos de humedad y transmisión por el puerto USB................................. 112
Figura 4.1 Jumpers y push button para pruebas (1.- jumpers. 2.- Push button) ............................. 114
Figura 4.2 Rutina para configurar la frecuencia de activación del módulo esclavo.......................... 114
Figura 4.3 Sincronización del retardo para la adquisición del dato de humedad................................ 115
Figura 4.4 Etapa de adecuación para el PLC (1.- etapa de adecuación. 2.- cable de bus) ............... 115
Figura 4.5 Receptores de cables (1.- módulo de despliegue. 2.- cable de bus) ................................ 116
Figura 4.6 Módulo de despliegue para realizar pruebas..................................................................... 116
Figura 4.7 Conexión de cables para el interfaz con el PLC y módulo de despliegue......................... 117
Figura 4.8 Interpretación de la medición de frecuencia en porcentaje de humedad........................... 119
vii
LISTA DE TABLAS
Página
Tabla 2.1 Tipos de paquetes.............................................................................................................. 10
Tabla 2.2 Resumen de transferencias................................................................................................ 13
Tabla 2.3 Subclases para la clase = 02h............................................................................................ 17
Tabla 2.4 Protocolo para la clase = 02h............................................................................................. 17
Tabla 2.5 Subclases para la clase = 08h............................................................................................ 18
Tabla 2.6 Protocolo para la clase = 08h............................................................................................. 18
Tabla 2.7 Protocolo para la clase = 09h............................................................................................. 19
Tabla 2.8 Requisiciones Standard y sus Códigos.............................................................................. 28
Tabla 2.9 Device descriptor................................................................................................................ 29
Tabla 2.10 String descriptor................................................................................................................. 29
Tabla 2.11 Configuration descriptor..................................................................................................... 30
Tabla 2.12 Interface descriptor............................................................................................................. 30
Tabla 2.13 Hid descriptor..................................................................................................................... 31
Tabla 2.14 Endpoint descriptor............................................................................................................ 31
Tabla 2.15 Prefijo de un byte del short ítem........................................................................................ 33
Tabla 2.16 Mapa de bits...................................................................................................................... 34
Tabla 2.17 Collections......................................................................................................................... 36
Tabla 2.18 ítems globales (nn indica el número de bytes que lo siguen) …........................................ 37
Tabla 2.19 Ejemplo de uso de los ítems Logical maximum y minimum............................................... 38
Tabla 2.20 Valores para el exponente de las unidades....................................................................... 39
Tabla 2.21 Tabla de unidades.............................................................................................................. 39
Tabla 2.22 Local ítems......................................................................................................................... 41
Tabla 2.23 Ejemplo de uso de Usage minimum y maximum............................................................... 42
Tabla 2.24 Descriptor físico cero.......................................................................................................... 44
Tabla 2.25 Descriptor físico.................................................................................................................. 45
Tabla 2.26 Valores de bias................................................................................................................... 45
Tabla 2.27 Descriptor físico agregado.................................................................................................. 45
Tabla 2.28 Valores para los designators.............................................................................................. 45
Tabla 2.29 Valores de qualifier............................................................................................................. 46
Tabla 3.1 Caracterización para el generador de frecuencia................................................................. 90
Tabla 3.2 Caracterización para el generador de frecuencia................................................................. 93
Tabla 3.3 Caracterización del generador de datos.............................................................................. 104
Tabla 3.4 Adecuación ADC................................................................................................................. 105
Tabla 3.5 Caracterización del medidor de frecuencia......................................................................... 109
Tabla 4.1 Resultado final (voltaje de referencia del ADC a 5.2 volts) ................................................ 118
viii
RESUMEN
El presente trabajo muestra el diseño de control para las etapas de radiofrecuencia,
que se encuentran dentro de un sistema de monitoreo de humedad, aplicado en un
sistema de riego por goteo. El control es aplicado por medio de microcontroladores
PIC, para el encendido y apagado de las etapas de todos los dispositivos que
intervienen en la medición de humedad, así como la generación de la banda base
para las transmisiones inalámbricas.
En el capítulo I, se muestra un antecedente de los trabajos anteriores a éste, así
como la descripción de un sistema de monitoreo. Después, se plantea el problema a
resolver, los objetivos a cumplir al terminar el presente trabajo y las ventajas con las
que contará.
En el capítulo II, se encuentran toda la teoria para comprender el funcionamiento del
puerto USB y los módulos que se utilizaron de los PICs.
En el capítulo III, se describen los primeros pasos del diseño, las especificaciones
con las que cuenta las etapas de radiofrecuencia y el sensor de humedad. Para
después definir los bloques que describen el proceso de control que se ejercerá
sobre las demás etapas. Cada uno de estos bloques son descritos a detalle así como
su diseño.
En el capítulo IV, se muestran los resultados obtenidos aplicando dicho control sobre
las etapas. Muestra resultados de las lecturas de humedad asi como los diseños
realizados para llevar a cabo las pruebas.
En el capítulo V, se mencionan las conclusiones sobre el presente trabajo así como
algunas recomendaciones para mejorar este trabajo.
Por último se muestran las referencia de algunos libros de apoyo.
I INTRODUCCIÓN
1.1 Antecedentes
En el valle del yaqui, que es una región de producción agrícola, se tiene el problema
de la falta de agua [1], y es por eso que es importante economizar la poca que queda
en esta área geográfica.
Debido a la necesidad economizar el agua, algunos productores agrícolas han
optado por cambiar a nuevas técnicas de riego, una de ellas es la técnica de riego
por goteo, que riega uniformemente la tierra por medio de tuberías superficiales o
subterráneas (figuras 1.1 y 2.2), ya que sólo humedece el área de absorción de la
planta cultivada, sin necesidad de humedecer áreas donde el agua se filtra o se
evapora (figura 1.3).
Figura 1.1 Tuberías superficiales.
Figura 1.2 Tubería subterránea.
Figura 1.3 Filtración de humedad.
2
En un sistema de riego automatizado como se muestra en la figura 1.4. Las tuberías
se controlan a través de electroválvulas para habilitar el riego o simplemente
detenerlo cuando la tierra alcanza la humedad requerida, esta humedad depende del
tipo de planta que se esté cultivando.
Sistema
De Riego
Central
Cultivo
Figura 1.4 Sistema de riego automatizado (esquema general).
Las electroválvulas son controladas por medio de una central, que tomará las
decisiones de habilitar o no el sistema de riego por goteo, a la central es necesario
informarle las lecturas de humedad (sistema de monitoreo de humedad) y así tomar
la decisión, si al cultivo le falta o no más agua para llegar a la humedad requerida.
En el 2002, el Instituto Tecnológico de Sonora (ITSON) realizó el proyecto de
automatización de un sistema de riego por goteo en un cultivo ubicado en la
manzana 940, lotes 19 y 20, a un costado del CIANO en el Valle del Yaqui, con el
objetivo de aprovechar al máximo la poca agua con la que cuenta el valle [1].
En este proyecto se han implementado varios trabajos de tesis, que van desde
software para el control del sistema de riego, hasta los transductores que miden la
humedad.
El último trabajo de tesis realizado es el de Enrique Cuadras [1], y se acerca mucho
al presente proyecto. El sistema de comunicación con la que cuenta su monitoreo de
humedad es vía RF, y lo componen 2 módulos de acoplamiento y radios comerciales
para establecer esta comunicación, además, fue realizado para un solo transductor y
la medición de humedad es continua.
3
El presente proyecto propone sustituir estos radios, hacer el sistema de monitoreo
para más transductores y que se realice un mínimo de cambios en el hardware al
agregar o quitar transductores en el sistema de riego.
Con los cambios antes mencionados, el sistema de monitoreo de humedad tiene la
siguiente forma: La central lo componen la PC o un PLC y el módulo maestro, este
módulo se enlazará con un módulo esclavo, que a su vez estará conectado a un
sensor de humedad en contacto con la tierra de cultivo.
PC
O
PLC
Módulo Maestro
De transmisión
Y Recepción
Módulo Esclavo
De transmisión
Y Recepción
Sensor
Sistema
De Riego
Figura 1.5 Sistema de monitoreo.
El sistema de monitoreo de humedad, consta de 2 dispositivos principales para llevar
a cabo las lecturas (módulo maestro y módulo esclavo), y ambos dispositivos se
dividen en 2 partes; parte digital y parte analógica.
La parte analógica consiste en un sistema de comunicación de RF, como medio para
realizar el enlace en forma inalámbrica. La parte digital la compone uno o varios
microcontroladores, los cuales servirán para tomar el control de las etapas de la
parte analógica además de otras funciones.
Debido a la complejidad de este proyecto, ambas partes (digital y analógica) se
separan en 2 trabajos de tesis, el presente trabajo se enfocará en la parte digital. La
parte analógica representa otro trabajo en conjunto con este [2].
4
1.2 Definición del problema
Para llevar a acabo la parte digital, se necesita implementar un control al sistema de
comunicación de RF en ambos módulos, esto es, para enviar las señales modulantes
y que la interferencia de una etapa no afecte el desempeño de las otras. También es
necesario crear un interfaz con la PC y PLC.
1.3 Justificación
Debido a que no hay una basta experiencia en el desarrollo de transmisores y
receptores, éstos serán manufacturados en los cubículos de los laboratorios de
electrónica del ITSON [2], contribuyendo al desarrollo de tecnología propia de la
universidad y a la realización de tecnología adaptable a las necesidades. Debido al
control que se aplica al sistema de comunicación de RF, la batería que se encarga
de alimentar a los dispositivos tendrá una duración mayor, ya que sólo alimentará
parte de la circuiteria en estado de reposo y activará a las demás circuiterias a la
hora de activarse las lecturas de humedad ya que las mediciones no serán continuas
como en el proyecto de tesis de Enrique Cuadras [1]. El sistema de comunicación
inalámbrica no sólo se puede aplicar a transductores de humedad sino también a
transductores que manejen un rango de medición de 0 a 5 volts, o que puedan
adecuarse a esa especificación. Este control permitirá trabajar con un PLC o una PC,
abriendo más posibilidades de conexión. Con el software se podrá tener un mejor
control de los transductores del sistema, realizando
baja, altas y cambios de
posiciones de los transductores.
1.4 Objetivo
Diseñar una etapa de control para el sistema de comunicación de RF con
microcontroladores PIC 16C745, 16F628 y 16F873, además crear una aplicación en
Visual Basic para configurar el sistema por medio del puerto USB.
5
1.5 Delimitaciones
-Las pruebas se realizarán con un solo transductor debido a que sólo se dispone de
uno.
-Cuando en la central se disponga de un PLC en vez de una PC, sólo se podrán
ingresar 15 transductores como máximo en el sistema de monitoreo, debido a que se
dispone sólo de 4 pines para indicar el número (binario) del transductor activado,
siendo el cero un valor con el estado en reposo.
-En la comunicación con el PLC la salida de información es a través de un conector
DB9.
-Se utilizarán microcontroladores PIC 16C745, 16F628 y 16F873.
-Se utilizará el software Visual basic empresarial versión 6.0.
1.6 Referencias
[1].- Hugo Enrique Cuadras Aguilar, Desarrollo de un sistema de comunicación para
la transmisión inalámbrica de sensado de humedad. Tesis, México 2003.
[2].- Gabriel Enrique Cázarez Enriquez. Tesis en desarrollo, México 2007.
II MARCO TEÓRICO
2.1 USB (Universal Serial Bus)
2.1.1 Introducción
La información de este capítulo proviene de varios documentos [1],[2],[3],[4]. En esta
parte se presenta la idea principal o resumen de la información original, encontradas
en los documentos fuentes.
Esta tecnología fue desarrollada para incrementar el ancho de banda y el número de
dispositivos que pueden ser conectados, así como una operación de usuario
amigable, comunicación robusta y bajo costo. Los primeros promotores de USB
fueron Intel, Compaq, Microsoft y NEC.
La topología del bus es de tipo estrella, con el HOST en el nivel más alto, los HUBS
en el medio y los diferentes dispositivos al final.
Figura 2.1 Topología.
7
Hoy en día se encuentran dos especificaciones para este estándar, la revisión 1.1 y
la 2.0. En las cuales se hablan de distintas velocidades, en la revisión 1.1 se
manejan las velocidades baja-velocidad (low-speed) y velocidad-completa (fullspeed), las mismas que proporcionan velocidades de 1.5 y 12 mbps y en la
especificación 2.0 alta-velocidad (high-speed) hasta 480 mbps.
2.1.2 Conexiones
El cable que se utiliza para interconectar los dispositivos y hubs hacia el host
contiene 4 hilos por el cuál 2 de ellos (d+ y d-) se transmiten los datos y los 2
restantes proporciona al dispositivo (si éste lo desea) una alimentación de 5 volts.
Figura 2.2 Cable.
En los extremos del cable se encuentran los 2 diferentes tipos de conectores, tipo A y
tipo B. el tipo B es conector trama de subida (up-stream) y en el A es trama de
bajada (down-stream), eso significa que lo dispositivos deberán tener conectores
receptor trama de subida y el host un receptor trama de bajada.
Figura 2.3 (Conector a, Conector b, Receptor a y Receptor b).
Figura 2.4 Pines correspondientes (1= Vbus, 2 = d-, 3 = d+, 4 = GND).
8
2.1.3 Comunicación
La comunicación que se realiza entre el host y el dispositivo se dividen en capas
(como en el modelo OSI), esto es, que cada capa del host se comunica con su
correspondiente capa en lado del dispositivo.
Figura 2.5 Flujo de comunicación (lógica y física).
La capa de funciones en el host, la compone el software cliente del dispositivo, y éste
se encarga de conectarse con una interfaz en el dispositivo por medio de conexiones
virtuales llamadas pipas (PIPES), cuando el software comunica los buffers de
información y obtiene uno o varios puertos virtuales en el dispositivo llamados
endpoints se dice que se ha conectado una pipa.
En la capa lógica del host residen los controladores (drivers) y es aquí donde se
asigna una pipa especial llamada PIPE0, default PIPE o control PIPE que es
conectada a un endpoint especial llamado endpoint0 en el dispositivo. Los
controladores sirven para informar al sistema operativo aspectos físicos del bus USB,
el software cliente será el encargado de comunicarse con el controlador.
Específicamente también se encuentra en esta capa el USB driver (USBD) que
proporciona interfaz entre esta capa y el software cliente.
9
Otro controlador que se encuentra aquí es el
host controler driver (HCD),
proporciona interfaz entre la capa lógica del host y el concentrador que se encuentra
en la capa bus.
En la última capa del host está el concentrador de USB, éste se encarga de enviar
físicamente el dato hacia el dispositivo.
Existen dos modos de operación en las pipas: trama (stream) y mensaje (message).
El modo trama no tiene una imposición de estructura definida, el flujo de paquetes es
de una sola dirección. En el modo mensaje tienen asociadas con ellas las
necesidades de ancho de banda, tipo de transferencia y características de los
puertos virtuales del dispositivo (endpoints) donde además el flujo es bidireccional.
Como se mencionó anteriormente, los endpoints son puertos virtuales que residen en
el dispositivo, poseen un cierto número y son únicos. Estos sirven para transmitir y
recibir datos en una sola dirección, por lo que si se requiere de una comunicación
bidireccional se requiere de dos endpoints. Estos puertos son utilizados para una ruta
de comunicación más avanzada como los son las pipas.
Figura 2.6 Conexión lógica.
10
2.1.4 Paquetes
El host siempre inicializa la transacción, y solamente un dispositivo es seleccionado
por el host para comunicarse sobre el bus. Un dispositivo tiene permiso para hablar
sobre el bus cuando éste recibe un token. Un token es un paquete especial que se
utiliza para el control del bus, indicando el tipo y la dirección de la transacción, siendo
el host el único capaz de generar un token. Así como el token existen otros tipos de
paquetes.
Tabla 2.1 Tipos de paquetes.
Paquetes
Token
Data
Handshake
Especial
Tipos
Out, In, Sof y Setup.
Data0 y Data1.
Ack, Nak y Stall.
Pre.
Tipo SOF.- El inicio de trama (Start of frame) sirve para delimitar la trama y marcar
un punto de inicio, como un mecanismo de sincronización. El host genera estos
paquetes y el dispositivo deberá ser capaz de detectar un SOF cada 1 milisegundo
en el bus, si no ocurre en el siguiente periodo de tiempo, se presenta un error. Este
paquete no recibe respuesta alguna por parte de los dispositivos ni tampoco hay
garantía que éstos los reciban, es responsabilidad de los dispositivos detectar la
pérdida de estos paquetes.
Tipo SETUP.- Se utiliza para que el host envíe información para la pipa de control.
Tipo OUT.- Describen transacciones del host hacia funciones del dispositivo.
Tipo IN.- Describen transacciones de las funciones del dispositivo hacia el host.
11
Los paquetes de datos sirven para lo que su nombre indica, se encargan de enviar
los datos. Se dividen en 2 tipos: data0 y data1, estos tipos son semejantes, sólo que
poseen una pequeña diferencia en el campo PID (los campos se explican en la
sección 2.1.10).
Tipo data0.- Paquete de datos par
Tipo data1.- Paquetes de datos impar
Los paquetes handshake son utilizados para indicar el estado de la transacción,
proporciona al host la satisfactoria o fallo del envío de una transacción, da un control
de flujo y reporta las condiciones de parada (stall). Se encuentran en las
transacciones donde se permita el control de flujo.
Tipo ACK.- Significa que el dato fue recibido sin errores.
Tipo NAK.- Significa que el dispositivo no puede recibir datos del host, y que es una
condición temporal, o lo que es lo mismo, el dato no fué recibido.
Tipo STALL.- Significa que el dispositivo no puede recibir ni transmitir datos hacia el
host, y que el host deberá ayudar al dispositivo a rectificar la situación.
Los paquetes especiales se utilizan como preámbulos, habilita el tráfico de bus trama
de bajada para dispositivos de baja velocidad.
2.1.5 Transacciones o transferencias
Las transacciones sobre el bus son gobernadas por el protocolo. Un protocolo es
simplemente el orden en el cual los paquetes satisfacen la transacción. Cada
transacción consiste en el intercambio de 3 paquetes.
12
Figura 2.7 Transacciones (ejemplo).
En las velocidades velocidad-completa y alta-velocidad soportan 4 tipos de
transferencias: bulto (bulk), interrupción (interrupt), isócrono (isochronous) y control.
Mientras que la velocidad baja-velocidad soporta 2 tipos: interrupción y control.
El tipo isócrono.- Garantiza el tiempo pero no la integridad de la transferencia, no hay
retransmisión ni paquetes de handshaking. En este tipo una porción del ancho de
banda es reservado para la requisición de los dispositivos (si el ancho de banda del
bus lo permite). Este tipo es usado para transmisiones multimedia, donde la pérdida
de unos cuantos paquetes no es crítica, ya que los sentidos humanos no serán
capaz de detectarlo. El tipo de pipa a utilizar en esta transferencia deberá ser de
modo trama.
Figura 2.8 Ancho de banda.
13
El tipo bulto.- Contrario al isócrono garantiza la integridad de la transferencia pero no
el tiempo que le tome hacerlo, garantiza una tasa de transferencia pero se espera
hasta que se presenten las condiciones en el bus. Este tipo se utiliza para
transferencias de datos que no sean críticas. El tipo de pipa deberá ser del modo
trama.
El tipo control.- Es usado para reportar el estado y configuración de los dispositivos,
esto es, que el host lea información, asigne direcciones y configuraciones, así como
otras funciones. Para esto se utiliza el default PIPE y no es necesario crear otra pipa
para el control, si es necesario crear una, se deberá crear una en modo mensaje por
que el flujo de la pipa es bidireccional.
El tipo interrupción.- Es usado para dispositivos que requieran una revisión periódica
para el envío o recepción de pequeñas cantidades de datos. Este tipo no trabaja
como una interrupción de un microcontrolador, sino que el host revisa en un periodo
de tiempo el bus para que de ese modo se vea como una interrupción. El tipo de pipa
de esta transferencia deberá ser del modo trama.
Tabla 2.2 Resumen de transferencias.
Modo de PIPE
Sincronización
Handshake
Control
Mensaje
Ninguna
Si
Isócrono
Trama
Bus, Software
Externo
No Usado
Interrupción
Trama
Ninguna
Si
Bulto
Trama
Ninguna
Si
2.1.6 HUB
El hub es otro dispositivo que proporciona un punto de conexión entre el host y los
diferentes dispositivos finales, cuenta con funciones especiales como conectividad,
proporcionar alimentación a los dispositivos conectados en él y detectar la conexión y
desconexión de dispositivos.
14
Los hubs responden a las requisiciones de los controladores y al software cliente del
host. También hace que el dispositivo hable solamente con el host y no con otros
dispositivos
conectados.
Lo
componen
básicamente
los
receptores
donde
proporciona conectividad, un repetidor que se encarga de re-transmitir la información
y un control que se encargará de las requisiciones, cambiar la conexión del repetidor
y detectar los cambios de estados de si mismo.
Cuando el hub detecta un SOP (start of packet) en un receptor tipo A, los otros
receptores tipo A son cerrados, esto asegura que no cambie nada en el hub hasta
que el paquete se halla enviado (ver figura 2.9).
Figura 2.9 Flujo de información en el hub.
Cuando se detecta un SOP en un receptor tipo B, el hub estabiliza conectividad con
todos los receptores tipo A válidos, mandando los paquetes como una difusión
(broadcast).
Figura 2.10 El host cuenta con un hub integrado llamado root hub.
15
2.1.7 Descriptores (Descriptors)
Los descriptores son una estructura de datos que contiene información como:
tamaño máximo de paquete del endpoint0, número de configuraciones que el
dispositivo soporta, y otras informaciones básicas del dispositivo. Se encuentran
divididos en 2 grupos: estandarizados (Standard) y clases específicas (classespecific). Los estandarizados son los requeridos por todos los dispositivos HID
(human interface device), y lo componen los siguientes descriptores: dispositivo
(Device), configuración (Configuration), interfaz (Interface), Endpoint y cadena
(String). Los descriptores de clase específica son usados para los dispositivos donde
su clase (class) sea HID, este grupo contiene los descriptores HID, reporte (report ) y
descriptores físicos (physical descriptors). Algunos descriptores son opcionales.
Descriptor dispositivo.- Su información es usado en el proceso de enumeración del
dispositivo, en este proceso, se compara la información con los controladores en el
host, y esto ayuda al sistema operativo a seleccionar el controlador.
Descriptor configuración.- Proporciona características de la alimentación que se
proporciona al dispositivo.
Descriptor interfaz.- Indica el tipo de protocolo a usar, en caso de un dispositivo HID.
Descriptor Endpoint.- Indica la dirección y el tamaño máximo del endpoint.
Descriptor cadena.- Contiene una lista de cadenas en las cuales se mencionan
características del dispositivo. La especificación 2.0 menciona que puede tener
indexados de varias cadenas. Éste descriptor es opcional.
Descriptor HID.- Contiene información acerca de la longitud y tipo de todos los
descriptores.
16
Descriptor reporte.- Es usado para indicar información acerca del tipo y formato de
los datos que empiezan a ser enviados por el endpoint.
Descriptor físico.- Proporciona información acerca de partes específicas o partes del
cuerpo humano que están activando uno o varios controles, este descriptor es
opcional.
2.1.8 Clases (class) y Subclases (subclass)
Cuando un grupo de dispositivos comparten funciones similares, entran a un grupo
llamado clases. Por ejemplo, todos los ratones envían el movimiento y los clicks,
todas las impresoras reciben e imprimen el dato y envían el estado de la impresión.
Las clases hacen más fácil escribir un controlador y un firmware, porque trabajan con
atributos definidos.
Cuando un dispositivo tiene funciones adicionales, el device-vendor, puede proveer
un filtro para el controlador, que agrega capacidades al controlador del sistema
operativo y es más fácil que escribir un controlador desde cero.
A continuación se muestran algunos ejemplos de clases y subclases.
Dispositivos de audio.- Para los dispositivos que envían audio. Class = 01h.
Subclass: 01= audio control, 02 = audio streaming, 03 = midi streaming.
Dispositivos chip/smart cart interface.- Tarjetas para transferir pequeñas cantidades
de datos y acceso fácil. Class = 0Bh.
Dispositivos de comunicación.- Modems y tarjetas de red. Este grupo contiene
modems, teléfonos analógicos, terminal de adaptadores ISDN, teléfonos digitales,
ADSL modems, cable modems, 10 base t ethernet adapters y hubs. Class=02h. Para
esta clase se necesita especificar un protocolo.
17
Tabla 2.3 Subclases para la clase = 02h
Código
00h
Subclases
Direct line control
model
02h
Abstract control model
03h
04h
05h
06h
07h
08-0Bh
0Ch
0D-7Fh
80-FEh
Telephone control
model
Miltichannel control
model
CAPI control model
Ethernet networking
Control model
ATM networking
WMC models
Ethernet emulation
model (EEM)
Reservado
Reservado
Aplicación
Teléfono MODEM con el host enviando
cualquier compresión de datos y corrección de
error. El host o el dispositivo deberán de
proveer modulación y demodulación del dato
del MODEM.
Teléfono MODEM con el dispositivo enviando
cualquier compresión de datos, corrección de
error, modulación y demodulación del dato del
MODEM.
Teléfono.
Dispositivos ISDN con múltiple, y canales
multiplexados.
Dispositivos ISDN con soporte de comandos
commond-ISDN-API (CAPI) y mensajes.
Dispositivos que cambian datos ethernet
framed.
Dispositivos ATM.
Comunicaciones inalámbricas móviles.
Futuros usos.
Futuros usos.
Vendor específic.
Tabla 2.4 Protocolo para la clase = 02h
Código
00h
01h
02-06h
07-F0h
FFh
Protocolo
La clase no especifica protocolo.
Comandos AT. (Especificado en ITU v.250).
Comandos AT. (Para dispositivos WMC).
Futuros usos.
Vendor especific.
Dispositivos de control de seguridad.- Muestra el camino para contener nuestro
propio control de acceso hacia los archivos. Puede ser por dos métodos.
Autorización básica o transmisión digital de protección de contenido. Class = 0Dh.
18
Dispositivos con actualización de firmware.- Define un protocolo donde habilita al
host para enviar secciones de código, para el firmware hacia el dispositivo.
Recibiendo una señal conocida como (firmware upgrate), el dispositivo vuelve a
realizar el proceso de enumeración (que será explicado más adelante), usando este
nuevo firmware o sección del firmware. Para indicar un dispositivo de que es de este
tipo se usan los siguientes valores: Class = FEh indica que es una clase muy
específica. Subclass = 01 indica que es del tipo update firmware.
Dispositivos HID.- Se describen en la sección 2.1.17. Class = 03h.
Dispositivos puentes IRDA.- (infrared data association) define el hardware y el
protocolo para el intercambio de datos sobre distancias cortas vía infrarrojo. Class =
FEh indica que es de clase específica. Subclass = 02h índica IRDA brige.
Dispositivos de memoria masiva.- Transfieren archivos (ambas direcciones) a
dispositivos como floppys, discos duros, cd, dvd, flash.
Class = 08h.
Tabla 2.5 Subclases para la clase = 08h.
Código
02h
03h
04h
05h
06h
Subclases
Dispositivos ATAPI/CD/DVD.
Dispositivos QIC-157.
Interfaz USB floppy (UFI).
ATAPI removible media.
Generis SCSI media.
Tabla 2.6 Protocolo para la clase = 08h.
Código
00h
01h
50h
Protocolo
CBI con comandos de transferencias de interrupción
completas.
CBI sin comandos.
Transferencias BULK solamente.
19
Dispositivos impresoras.- Dispositivos para impresión de documentos. Class = 07h.
Tabla 2.7 Protocolo para la clase = 09h.
Código
00h
01h
03h
Protocolo
Unidireccional.
Bidireccional.
IEEE 1284.4 compatible bidireccional.
Dispositivos Still image capture.- (cámaras y scanners). Dispositivos para capturar
imágenes en video y en forma estática. Class = 06h. Subclase = 01h interfaz de
Figura, protocol = 02h función still image capture.
Dispositivos para test y mediciones.- (USBTMC) dispositivos de medición que no
necesitan garantizar el tiempo de medición. Class = FEh indica clase específica,
Subclass = 03h indica test y medición.
Dispositivos de video.- (grabadoras de video, webcams y demás) la documentación
para este tipo de dispositivos está en construcción todavía. Para indicar un
dispositivo de este tipo Class = 0Eh.
2.1.9 Enumeración y Estados del dispositivo
Cuando un dispositivo se conecta por primera vez al host, ocurre el proceso
“enumeración”, y que se describirá a continuación:
1.- El usuario conecta el dispositivo.- El sistema alimenta al dispositivo y éste entra
en el estado de powered (alimentado).
2.- El hub detecta el dispositivo.- El hub monitorea los voltajes en las líneas de señal
de cada puerto USB, El hub tiene resistencias de pull up de 15000 ohms y el
dispositivo de 1500 ohms. Las resistencias del dispositivo cambian la línea en estado
alto permitiendo al hub detectar que fué conectado un dispositivo.
20
3.- El host conoce el nuevo dispositivo.- Cuando el hub detecta un evento éste lo
reporta al host, esto se realiza cuando el host envía la requisición get_report_status.
4.- El hub detecta la velocidad del dispositivo.- En la especificación 1.x dice que se
puede detectar la velocidad después del reset, pero en la especificación 2.0 dice que
los dispositivos de alta velocidad deben detectarse antes del reset. Antes de que el
host mande un reset al dispositivo, el hub detecta la especificación examinando el
voltaje de las líneas de señal. El hub envía una respuesta al host en una requisición
get_report_status. Ahora el dispositivo necesita saber si el host soporta alta
velocidad. Para esto, el dispositivo soporta dos estados especiales llamados chirp J y
k, en el estado J la línea d+ es usado solamente, en el estado K la línea d- es usado
solamente, estos estados son cambios de niveles en la línea. Durante el reset, si el
dispositivo soporta una alta velocidad envía un estado chirp K, el hub detecta el
estado y responde con una serie de varias alteraciones de estados chirps K y J.
Cuando el dispositivo detecta el patrón KJKJKJ, éste quita las resistencias de pull
ups para la velocidad completa y cambia a comunicación de alta velocidad. Si el hub
no responde a los estados K del dispositivo, el dispositivo cambia a comunicación
velocidad completa, por lo que los dispositivos de alta velocidad deberán de
comunicarse también en velocidad completa, que es la velocidad más alta en la
especificación 1.x. Esto es si el host no soporta la especificación 2.0, mínimo deberá
soportar la especificación 1.x.
5.- El host envía un reset al dispositivo.- El host envía un set_port_feature para
resetear al puerto, la condición de reset pone las líneas del dispositivo (en 10
milisegundos) en un estado especial, las líneas d+ y d- están en lógica baja, el hub
envía el reset solo al dispositivo nuevo, los demás dispositivos no detectarán el reset.
6.- El hub estabiliza una ruta de señal entre el dispositivo y el bus.- El host verifica
que el dispositivo se encuentre en estado de reset enviando un get_report_status, un
bit del dato regresado indica que el dispositivo esta ocupado en el estado de reset, si
es necesario el host envía el get_report_status hasta que el dispositivo esté en
21
estado de reset, cuando el hub quita el reset al dispositivo, éste está en estado de
default. Los registros de USB del dispositivo están listos para responder a las
transferencias de control sobre la pipa de control o default PIPE conectado hacia el
endpoint0. Ahora el dispositivo puede comunicarse con el host usando la dirección
default address 00h y el dispositivo puede obtener hasta 100 miliamperes en el bus.
El host solamente asigna un default address a la vez.
7.- Tamaño máximo del default PIPE.- El host envía un get_descriptor para conocer
este dato del dispositivo, el octavo byte del descriptor dispositivo contiene el tamaño
máximo del paquete, soportado por endpoint0.
8.- El host asigna una dirección.- el host asigna una dirección única enviando un
set_address, el dispositivo lo recibe y envía un ACK y cambia a su nueva dirección,
cambiando así, al estado address. Desde aquí, todas las comunicaciones se realizan
con la nueva dirección. La dirección es válida hasta que el dispositivo es
desconectado, esté en estado de reset o se caiga del sistema. En la próxima
enumeración el dispositivo será asignado en una dirección diferente.
9.- El host conoce las habilidades del dispositivo.- El host envía requisiciones como:
get_device_descriptor,
get_configuration_descriptor,
get_report_descriptor
y
get_string_descriptor a la nueva dirección.
El dispositivo enviará la información en el siguiente orden: (dispositivo, configuración,
interfaz, HID, endpoint en caso de de ser un HID).
En caso de 2 interfaces el orden es el siguiente: dispositivo, configuración, interfaz1,
HID1, endpoint1, interfaz2, HID2 y endpoint2.
22
Figura 2.11 Descriptores para una y dos interfaces.
10.- El host asigna y carga el controlador del dispositivo.
11.- El driver selecciona una configuración.- Los controladores requieren una
configuración enviando un set_configuration con el número de configuración (para
múltiples configuraciones), si hay varios, el controlador selecciona uno, si no se
especifica selecciona uno por default. El dispositivo recibe la requisición y cambia al
estado configurated, las interfaces del dispositivo son habilitadas y el dispositivo está
listo para usarse.
El estado attached ocurre si el hub no provee alimentación en el puerto o detecta una
sobre corriente o simplemente que el host quite la alimentación.
El estado suspendido (suspended) significa que el dispositivo no tiene actividad
incluyendo SOFs, en este estado deberán consumir menos potencia y
dispositivos configurados y no configurados deberán soportar este estado.
para
23
Un hub normal se enumera exactamente igual a un dispositivo, y si tiene dispositivos
conectados, los enumera una vez que el hub halla sido enumerado y reporte al host
sobre sus conexiones.
Cuando un dispositivo es desconectado, el hub cambia el reporte del estado, y
cuando el host envía un get_report_status sabrá que se a desconectado cierto
dispositivo. Cambiando así su mapa interno. El sistema operativo da de baja al
dispositivo del administrador de dispositivos (device manager) y libera la dirección
para que pueda ser usado por otro dispositivo.
2.1.10 Protocolo, Tramas y Campos de bits
Los paquetes que se utilizan en las transferencias se dividen en secciones básicas
llamadas campos donde los bits son enviados desde el menos significativo hasta el
más significativo.
Campo SYNC.- todos los paquetes inician con el campo de sincronización, el cuál es
una secuencia codificada que genera la máxima densidad de transición. Éste campo
aparece en el bus como un IDLE seguido por la cadena binaria “KJKJKJKK” esto es
una codificación NRZI. Esto es usado por la circuiteria de entrada de dato y el reloj
local como mecanismo de sincronización.
Campo PID.- Llega después del campo SYNC. Éste le indica al dispositivo que hacer
con el paquete y contiene una longitud de 8 bits, además, el campo PID se divide en
dos subcampos que son tipo y checado. El subcampo tipo tiene la identificación del
paquete, el subcampo checado es el complemento del subcampo tipo y es usado
para comprobar la integridad del paquete, cuando resulta erróneo se ignora el resto
del paquete.
La función de los endpoints son direccionadas utilizando 2 campos: el campo
ADDRESS y el campo ENDPOINT. Una función necesita codificar totalmente ambos
campos.
24
Campo ADDRESS.- Este campo especifica la función y es el origen o destino del
paquete dependiendo del valor que tenga en el campo PID (IN, OUT y SETUP solo
estos tipos). Contiene una longitud de 7 bits por lo que puede tener hasta 127
direcciones válidas.
Campo ENDPOINT.- Este campo permite más flexibilidad de direccionamiento de
funciones en el cual más de un endpoint es requerido. Los números de los endpoint
son funciones específicas y son usados sólo para los tipos IN, OUT y SETUP.
Campo NUMBER FRAME.- Es de 11 bits de longitud. Representa un número que es
incrementado por el host por cada trama (frame), regresa al valor de cero cuando
alcanza el valor de 7FFh y son enviados solamente en los tokens SOF en el inicio de
cada trama.
Campo DATA.- El rango de este campo deberá ser de cero a 1023 bytes.
Campo CRC.- Con una longitud de 5 bits, es usado para proteger la integridad de los
campos que no sean PID en los paquetes tokens y datos. Los bits de este campo
ayudan a un algoritmo a detectar cualquier error. El CRC cubre los campos
ADDRESS y ENDPOINT de los tokens IN, OUT y SETUP.
El generador polynomial es: G(x) = x5 + x2 + 1.
Y en caso de un paquete de dato, el generador es el siguiente:
G(x) = x16 + x15 + x2 + 1.
y cuya longitud del campo CRC es de 16 bits.
2.1.11 Formato de paquetes
El formato de los tokens (IN, OUT y SETUP) consiste en los campos PID –
ADDRESS – ENDPOINT – CRC de 5 bits.
25
Figura 2.12 Formato de los tokens (IN, OUT y SETUP).
El formato para el token SOF lo forman los campos PID – Frame Number – CRC de
5 bits.
Figura 2.13 Formato del token SOF.
El formato del paquete de datos lo forman los campos PID – DATA – CRC de 16 bits.
Figura 2.14 Formato del paquete de datos.
El formato de un paquete handshake lo compone únicamente el campo PID.
Figura 2.15 Token handshake.
26
2.1.12 Formato de las transferencias
Figura 2.16 Transferencia isócrono y transferencia control.
Figura 2.17 Transferencia bulto (bulk).
27
Figura 2.18 Transferencia interrupción.
2.1.13 Requisiciones
Las requisiciones son los datos estructurados que el host envía al hub para conocer
o asignar funciones a los dispositivos conectados al hub, los cuales también se
dividen en secciones básicas llamadas campos.
Campo bmrequestType.- Este campo identifica las características de una requisición
específica, en particular identifica la dirección de la transferencia y es ignorado si el
valor del campo wLength es cero.
Campo bRequest.- Especifica la requisición, los bits del campo bmRequestType
modifica el significado de este campo.
Campo wValue.- El contenido este campo varía de acuerdo a la requisición, esto es
para pasar un parámetro al dispositivo.
Campo wIndex.- El contenido de este campo también varía de acuerdo a la
requisición y pasa un parámetro al dispositivo pero específicamente a un endpoint o
una interfaz.
28
Figura 2.19 Formato para un endpoint específicamente.
Figura 2.20 Formato para una interfaz específicamente.
Campo wLength.- Indica la longitud del dato transferido, en una transferencia de
entrada el dispositivo no deberá de transmitir un dato con una longitud superior al
indicado en este campo, en una transferencia de salida deberá transferir la cantidad
exacta de datos indicado por este campo.
Tabla 2.8 Requisiciones Standard y sus Códigos.
bRequest
Value
bmRequest
type
10000OOOB
10000OO1B
10000 O1OB
wValue
wIndex
wLength
Zero
Zero
Interface
Endpoint
two
00000OOOB
00000OO1B
00000O1OB
Feature
Selector
Zero
Interface
Endpoint
Zero
None
00000OOOB
00000OO1B
00000O1OB
Feature
Selector
Zero
Interface
Endpoint
Zero
None
Device Adress
Descriptor
Type and
Index
Descriptor
Type and
Index
Zero
Zero
Zero or
Language
ID
Zero or
Language
ID
Zero
Zero
Descriptor
Length
None
Configuration
Value
Zero
Zero
Zero
Interface
One
Interface
Zero
Endpoint
Two
Get Status
0
Clear Feature
1
Reserved
2
Set Feature
3
Reserved
Set Adress
4
5
000000OOB
Get Descriptor
6
100000OOB
Set Descriptor
7
000000OOB
Get Configuration
8
100000OOB
Set Configuration
9
000000OOB
Get Interface
10
100000 O1B
Set Interface
11
000000 O1B
Zinc Frame
12
1000001OB
Alternate
Setting
Zero
Data
Device
Interface or
Endpoint
Status
Descriptor
Descriptor
Length
Descriptor
One
Configuration
Value
None
Alternate
Interface
None
Frame
Number
29
2.1.14 Formato de los descriptores (Descriptors)
Tabla 2.9 Device descriptor.
Byte
0
1
Campo
bLength
bDescriptorType
N. Bytes
1
1
Valor
Número
Constante
2
bcdUSB
2
BCD
4
bDeviceClass
1
Class
5
bDeviceSubClass
1
Subclass
6
bDeviceProtocol
1
Protocolo
7
bMaxPacketSize0
1
Número
8
10
idVendor
idProduct
2
2
ID
ID
12
14
bcdDevice
iManufacturer
2
1
BCD
Index
15
iProduct
1
Index
16
iSerialNumber
1
Index
17
bNumConfigurations
1
Número
Byte
0
1
2
Campo
bLength
bDescriptorType
bSTRING ó
wLANGID[n]
Descripción
Tamaño del descriptor en bytes.
Tipo del descriptor (1 = device
descriptor).
Especificación (1.x o 2.0) en BCD.
Si este campo es cero, cada interfaz
contiene una configuración específica
y su propia información class y las
distintas
interfaces
operan
independientemente.
Si contiene un valor entre 1 y FEh
Las
interfaces
no
operan
independientemente.
Si es FFh el class es especificado por
el vendor.
Este campo es afectado por el
anterior. (0-FFh).
Identifica el protocolo. Si está a cero
no utiliza protocolo class específico,
si es FFh el protocolo es especificado
por el vendor.
Tamaño máximo del paquete por el
Endpoint0.
Solamente 8, 16, 32 o 64 son
números válidos.
ID del vendor (asignado por el USB).
ID del producto (asignado por la
manufacturera).
Número del dispositivo. (En BCD)
Index
del
string
descriptor
describiendo la manofacturera.
Index
del
string
descriptor
describiendo el producto.
Index
del
string
descriptor
describiendo el número serial del
producto.
Número de configuraciones posibles
Tabla 2.10 String descriptor.
N. Byte
Descripción
1
Tamaño del descriptor en bytes.
1
Tipo del descriptor 03 = String descriptor.
Número Una cadena en formato unicode.
Número Un arreglo de uno o más códigos de lenguajes.
30
Tabla 2.11 Configuration descriptor.
Byte
0
1
Campo
bLength
bDescriptorType
N. Bytes
1
1
Valor
Número
Constante
2
wTotalLength
2
Número
4
bNumInterfaces
1
Número
5
bConfigurationValue
1
Número
6
iConfiguration
1
Index
7
bmAttributes
1
Bitmap
8
MaxPower
1
mA
Descripción
Tamaño del descriptor en bytes.
Tipo del descriptor (2 = configuration
descriptor).
Longitud total de datos regresados
por esta configuración. Incluyendo los
descriptors interface y endpoint,
además las clases y especificaciones
vendors.
Número de interfaces de esta
configuración.
El valor utilizado como argumento en
la requisición SetConfiguration() para
seleccionar esta configuración.
Index
del
string
descriptor
describiendo esta configuración.
Características de configuración.
D7:
Reservado (puesto a uno).
D6:
Alimentado por si mismo.
D5:
Remote Wake up.
D4-D0: reservado (puesto a cero).
Poder máximo de consumo. Cada
unidad
representa
2
mA
de
alimentación. Por ejemplo 50=
100mA.
Tabla 2.12 Interface descriptor.
Byte
0
1
Campo
bLength
bDescriptorType
N. Bytes
1
1
Valor
Número
Constante
2
3
bInterfaceNumber
bAlternateSetting
1
1
Número
Número
4
bNumEndpoints
1
Número
5
bInterfaceClass
1
Class
6
bInterfaceSubClass
1
SubClass
7
bInterfaceProtocol
1
Protocol
8
iInterface
1
Index
Descripción
Tamaño del descriptor en bytes.
Tipo del descriptor (4 = interface
descriptor).
Número de interfaz.
Valor
usado
para
seleccionar
asignaciones alternadas para la
interfaz identificada en el campo
prioridad.
Número de endpoints usados en esta
interfaz excluyendo el endpoint0, si
este valor es cero, esta interfaz sólo
usa el default PIPE.
Código para clase del dispositivo. Por
ejemplo 03h es un dispositivo HID
(ver sección 2.1.17).
Indica si el dispositivo soporta una
interfaz de buteo (boot interface) (ver
sección 2.1.17).
Indica el protocolo a usar en caso de
usar una interfaz de buteo (ver
sección 2.1.17).
Index
del
string
descriptor
describiendo esta interfaz.
31
Tabla 2.13 Hid descriptor.
Byte
0
1
2
4
Campo
bLength
bDescriptorType
bcdHID
bCountryCode
N. Bytes
1
1
2
1
5
bNumDescriptors
1
6
bDescriptorType
1
7
9
wDescriptorLength
bDescriptorType
2
1
10
wDescriptorLength
2
Descripción
Tamaño del descriptor en bytes.
Tipo del descriptor (21 = HID descriptor) (29 = HUB).
Especificación del HID (revisión).
Número que identifica el país para localizar el
hardware.
Número de class descriptors que son subordinados
a este descriptor.
Tipo de descriptor que está subordinado al HID
class descriptor (report = 22 o físico = 23).
Longitud total del report descriptor.
Tipo de descriptor (opcional). para dispositivos con
mas de un descriptor.
Longitud total del descriptor (opcional). Para
dispositivos con más de un descriptor. Deberá ser
seguido por un adicional wDescriptorType y un
wDescriptorLength.
Tabla 2.14 Endpoint descriptor.
Bytes
0
1
Campo
bLength
bDescriptorType
N. Bytes
1
1
Valor
Número
Constante
2
bEndpointAddress
1
Endpoint
3
bmAttributes
1
Bitmap
4
wMaxPacketSize
2
Número
6
bInterval
1
Número
Descripción
Tamaño del descriptor en bytes.
Tipo del descriptor (5 = endpoint
descriptor).
B3-B0: número de endpoint.
B6-B4: reservado.
B7:
dirección, ignorado por los
endpoints de control.
0 = endpoint de salida.
1 = endpoint de entrada.
Este campo describe los atributos de los
endpoints, cuando esté configurado
usando el campo bConfigurationvalue.
B1-B0: tipo de transferencia.
00 = control
01 = isócrono
10 = bulto
11 = interrupción
Los demás bits son reservados.
Máximo tamaño de paquete de este
endpoint capaz de enviar o recibir cuando
esta configuración es seleccionado.
Para endpoints isócronos este valor es
usado para reservar el tiempo del bus en
la agenda.
Intervalo de poleo de endpoints para
tranferencias de datos. Expresado en
milisegundos.
Este campo es ignorado para los
endpoints bulto y control. Para el endpoint
isócrono este campo deberá ser cero. Y
para el endpoint interrupción el rango
deberá de ser de 1 a 255.
32
2.1.15 Descriptor reporte (Report descriptor)
Es un arreglo de bytes o un complejo ordenamiento de ítems con el cuál se asignan
funciones y unidades. La ventaja de un descriptor complejo es que el dispositivo
puede proveer información acerca del dato enviado y lo que se espera recibir. El
descriptor puede especificar el uso de los valores y que unidades aplicar a los datos
recibidos. La ventaja para la aplicación en el host es que conoce el tipo, tamaño y el
orden de los datos en un reporte, como deberá interpretarlos o ejecutarlos. Por
ejemplo el reporte de un teclado, la aplicación deberá interpretar el caracter si se
encuentra en un procesador de texto.
Un descriptor reporte contiene uno o más controles e ítems de datos, que describen
valores para ser transferidos en uno o más reportes. Un control puede ser un botón,
un switch u otra entidad física que opera o regula un aspecto de un dispositivo. Se
han publicado varios documentos que definen los valores que los reportes deben de
tener, los diferentes dispositivos se han agrupado en: controles generales de
escritorio (general desktop controls), monitoreo (monitor), alimentación (power) y
dispositivos de punto de ventas (point of sale devices).
Este descriptor se transporta en ítems que se pueden ser en 2 formatos: short y long.
El tipo short lo compone un byte de prefijo y dos bytes de dato opcionales (ver figura
2.21). El tipo long lo compone el mismo prefijo, un byte para el tamaño del dato y otro
byte para el tag, seguido de hasta 255 bytes de datos opcionales (ver figura 2.22).
Figura 2.21 ítem Short.
Figura 2.22 ítem Long.
33
El tipo long no está definido en la especificación 1.1 y es reservado para usos
futuros. Utiliza múltiples bytes para almacenar alguna información. El prefijo con un
valor de FEh identifica el ítem como un long.
El prefijo de un byte del short ítem describe: tamaño, tipo y tag.
Tabla 2.15 Prefijo de un byte del short ítem.
Número de
bit
0
1
2
3
4
5
6
7
Contenido
Descripción
Size
Número de bytes en el item.
Type
Alcance del Item : main, global
o local.
Tag
Valor numérico que indica la
Función del item.
=>Donde los valores de size son 00 = 0 bytes, 01= 1 byte, 10 = 2 bytes, 11 = 4 bytes.
=>Donde los valores de Type son 00 = Main, 01= Global, 10 = Local.
Main
define o agrupa campos de datos en el descriptor. Engloba 5 items
principales:
input, output, feature collection y end collection.
Global describe los datos.
Local define características de controles individuales de datos.
=>Donde Tag indica funciones de los ítems.
La parte alta del byte del prefijo indica si es un in, out o feature item. La parte baja
indica si necesita 1 o 2 bytes para transportar el dato. Seguido del prefijo lo siguen 9
bits que describen el dato del ítem (ver tabla 2.16).
34
Tabla 2.16 Mapa de bits.
Prefijo main item
Input
(100000nn, donde nn = al número de
bytes de datos seguido por el prefijo).
Usa 81h para 1 byte de item de dato o
82h para 2 bytes de item de dato.
Output
(100100nn, donde nn = al número de
bytes de datos seguido por el prefijo).
Usa 91h para 1 byte de item de dato o
92h para 2 bytes de item de dato.
Feature
(101100nn, donde nn = al número de
bytes de datos seguido por el prefijo).
Usa B1h para 1 byte de item de dato o
B2h para 2 bytes de item de dato.
N. de bit
0
1
2
3
4
5
6
7
8
9-31
0
1
2
3
4
5
6
7
8
9-31
0
1
2
3
4
5
6
7
8
9-31
Si el bit = 0
Data
Array
Absolute
No wrap
Linear
Preferred state
No null position
Reserved
Bit field
Reserved
Data
Array
Absolute
No wrap
Linear
Preferred state
No null position
Non volatile
Bit field
Reserved
Data
Array
Absolute
No wrap
Linear
Preferred state
No null position
Non volatile
Bit field
Reserved
si el bit = 1
Constant
Variable
Ralative
Wrap
Non – linear
No prefered s.
Null state
Buffered bytes
Constant
Variable
Ralative
Wrap
Non – linear
No prefered s.
Null state
Volatile
Buffered bytes
Constant
Variable
Ralative
Wrap
Non – linear
No prefered s.
Null state
Volatile
Buffered bytes
-Data-Constant. Data significa que el dato es modificable, constant significa que es
sólo de lectura.
-Array-Variable. Especifica si el dato reporta el estado de cada control o solo los
activados. Reportar solo los controles activados compacta más el reporte, para
dispositivos como teclados donde son muchos controles (teclas), pueden ser
activados solo uno o pocos controles a la vez. Si un control (keypad) tiene 8 botones.
Configurar en variable significa que el reporte del control deberá contener un bit para
cada botón, en el tamaño del report deberá ser de 1 bit, el contador del report de 8 y
la cantidad de dato a enviar de 8 bits. Configurar en arreglo (array) significa que cada
35
botón tiene asignado un index, el reporte contiene sólo los indexs de los botones que
son activados, y el tamaño del reporte deberá ser de 3 bits debido a los 8 botones, el
contador del reporte deberá ser igual al número máximo de botones que puedan ser
activadas a la vez, y la cantidad total de datos de 3 bits. Un valor fuera de rango del
array significa que ningún botón está activado.
-Absolute-Relative. Absoluto significa que el valor está basado en un origen fijo,
relativo significa que el dato indica los cambios desde la última lectura.
-No wrap-Wrap. Wrap indica que el valor rota de su valor máximo al mínimo y
viceversa. Un item no wrap deberá reportar un valor fuera de los límites
especificados. Este bit no se aplica para un array de datos.
-Linear-Non linear. Linear indica que el dato medido y el valor reportado tienen una
relación lineal. No linear los datos del reporte forman una gráfica curva. Este bit no se
aplica para un array de datos.
-Preferred state-No preferred state. Preferred state indica que un control va a
regresar a un estado de reposo cuando el usuario no interactúe con él. En un no
preferred state recuerda el último estado en que se encuentra el control. Este bit no
se aplica para un array de datos.
-No null position-Null state. Null state significa que el control soporta un estado
donde el control no esta enviando un dato significativo. Un control indica que está en
estado nulo enviando un valor fuera del rango definido por los ítems logical minimum
y maximum. Un no null position es que cualquier valor del dato puede ser
significativo. Este bit no se aplica para un array de datos.
-Non volatile-volatile. Éste bit solo se aplica para reportes de datos output y feature.
Volatile significa que el dispositivo puede cambiar el valor por si mismo sin la
interacción del host. Non volatile significa que el dispositivo cambia el valor
36
solamente cuando el host requiere un nuevo valor en un reporte. Este bit no se aplica
para un array de datos. Un ejemplo para volatile, es que una función del dispositivo
se ejecute con un botón en el software del host o con un botón en el dispositivo.
-Bit field-Buffered bytes. Bit field significa que cada bit o grupo de bits en un bytes
representan una pieza separada de dato y el byte no representa una simple cantidad.
Buffered bytes significa que el dato consiste en uno o más bytes. El tamaño del
reporte para buffered bytes deberá ser 8, este bit es el 8 si vas a utilizar este bit se
necesitan 2 bytes de datos en el ítem.
Un input ítem son datos que los dispositivos envían hacia el host y un output ítem del
host hacia el dispositivo. Los feature ítems son usados típicamente en la información
que el host envía hacia el dispositivo, esto habilita al host para leer feature ítems del
dispositivo.
Todos los reportes pueden contener los ítems collection y end collection. Que sirven
para agrupar ítems relacionados.
Tabla 2.17 Collections.
Prefijo main ítem
Valor
00h
01h
Collection (A1h)
02h
03-7Fh
80-FFh
End Collection (C0h) Ninguno
Descripción
Physical.
Aplication.
Logical.
Reserved.
Vendor definido.
Cierra una collection.
Aplication contiene ítems que tiene un propósito en común o que juntos tienen una
simple función. Physical contiene ítems que representan datos en un simple punto
geométrico. Para dispositivo que colecciona una variedad de sensores leyendo
desde múltiples direcciones agrupando el dato para cada dirección en una colección
physical, por ejemplo un ratón. Logical forma una estructura de datos que consiste en
ítems de diferentes tipos. Todos los main ítems que se encuentren dentro de los item
collection y end collection forman parte de la misma colección, donde cada colección
37
deberá tener el tag usage, que se describirá más delante de esta lectura. Un
colection superior es un colection que no está jerarquizado con los otros colections.
Un interfaz HID puede tener más de un colection superior, cada colection superior
significaría un diferente HID. A diferencia de los HIDs con interfaces separados,
éstos comparten los endpoints de interrupción. Si el reporte contiene un desconocido
vendor o usage tag el host ignora todos los ítems del collection.
Los Global ítems identifican reportes y describen los datos en ellos incluyendo
características como la función de los datos, valores máximos y mínimos permitidos,
tamaño y número del report item. Un ítem Global se aplica a cada uno de los ítems
que lo siguen hasta encontrar un nuevo ítem global. Los diferentes ítems Global se
muestran en la siguiente tabla.
Tabla 2.18 ítems globales (nn indica el número de bytes que lo siguen).
Global ítem
Usage page
Logical minimum
Valor
000001nn
000101nn
Logical maximum 001001nn
Physical minimum 001101nn
Physical
maximum
Unit exponent
Unit
Report size
Report ID
Report count
Push
010001nn
Pop
101101nn
Reserved
110001nn
to
111101nn
010101nn
011001nn
011101nn
100001nn
100101nn
101001nn
Descripción
Especifica el usage o función del dato.
El valor más pequeño que el ítem va a
reportar.
El valor más grande que el ítem va a reportar.
La lógica mínima expresada en unidades
físicas.
La lógica máxima expresada en unidades
físicas.
Unidades de exponente de base 10.
Valores de unidad.
Tamaño de un campo de bits de un ítem.
Prefijo que identifica un report.
Número de campos de dato para un ítem.
Pone una copia de la tabla de estado del ítem
en el snack.
Remplaza la tabla de estado del ítem con la
última estructura puesta en el stack.
Para usos futuros.
38
-Report ID.- Este valor puede identificar un reporte específico. Un HID puede
soportar múltiples reportes de algunos tipos, teniendo cada reporte su propio report
ID, contenido y formato. No se deberá crear un report ID con el valor de cero.
-Usage page. Es un ítem con un valor de 32 bits que identifica la función que el
dispositivo realiza. Este usage contiene 2 valores: los 16 bits superiores son un
global usage page ítem y los 16 bits inferiores es un local usage ítem. El valor en el
local usage ítem es un usage ID. El término usage puede referirse a cualquier valor
de 32 bits o al valor local de 16 bits. Para evitar la confusión algunas fuentes utilizan
el término extendido usage para referirse a al valor de 32 bits.
-Logical minimum y maximum. Definen los límites para los valores de los reportes.
Son expresados en unidades lógicas. Por ejemplo si un dispositivo reporta lecturas
de hasta 500 miliamperes en unidades de 2 miliamperes, el máximo lógico es 250. Si
el bit más significativo del byte más significativo es 1, el valor es negativo, expresado
como el complemento de 2. Usando el valor de 1 byte, 00h a 7Fh son valores
positivos decimales 0 a 127, y FFh a 80h son los valores negativos decimales -1 a 128. La especificación HID dice que si logical maximum y minimum son positivos, no
hay necesidad de signar el bit. Pero causará un error que se puede solucionar
usando 2 bytes de valores (ver tabla 14). El item logical maximum es 0x26 para
indicar de bytes de datos.
Tabla 2.19 Ejemplo de uso de los ítems Logical maximum y minimum.
0x15 0x00
0x25 0xFF
erroneo.
//Logical minimum. 0x15 0x00
//Logical maximum 0x26 0x00FF
correcto.
//Logical minimum.
//Logical maximum
-Physical minimum y maximum. Definen los límites para un valor, cuando es
expresado en unidades definido por el tag units. Por ejemplo, valores de 0 a 250 en
unidades de 2 miliamperes, el physical minimum es 0 y el physical maximum es 500.
La recepción del dispositivo utiliza los límites de valores de physical y logical para
obtener el valor en las unidades deseadas.
39
-Unit exponent. Especifica el exponente de base 10 que se aplicará al valor
obtenido después de usar los límites logical y physical. El exponente puede ranquear
valores desde -8 hasta +7. Un valor de cero causa que el valor sea el mismo. Por
ejemplo, si el valor obtenido es 1234 y el unit exponent es 0Eh, el valor final es
12.34. A continuación se muestran los valores posibles.
Tabla 2.20 Valores para el exponente de las unidades.
Exp.
0
1
2
3
4
5
6
7
-8
-7
-6
-5
-4
-3
-2
-1
Cod.
00h
01h
02h
03h
04h
05h
06h
07h
08h
09h
0Ah
0Bh
0Ch
0Dh
0Eh
0Fh
-Unit. Especifica que unidades se aplicarán al dato del reporte después de que el
valor es convertido usando los ítems physical y unit exponent.
Tabla 2.21 Tabla de unidades.
Número
de
Nibble
1
2
3
4
5
6
7
Sistema de Medición
Lineal SI
Inglés
Inglés
Rotación Lineal
Rotación
(2)
(3)
(4)
Centímetros Radianes Pulgadas Grados
Gramos
Slugs
Segundos
Kelvin
Fahrenheit
Amperes
Candelas
Calidad de
Medición
Ninguna SI
(0)
(1)
Longitud
Masa
Tiempo
Temperatura
Corriente
Intensidad
Luminosa
Reservado
Ninguna
Ninguna
Ninguna
Ninguna
Ninguna
Ninguna
Ninguna
El valor puede ser de una longitud de 4 bytes, en el cual cada nibble tiene una
función definida. El nibble 0 (el más significativo) especifica el sistema de medición
(SI o Inglés), si la medición es lineal o en unidades angulares. Seguido de cada
nibble representa la calidad de la medición, con el valor del nibble representando el
exponente que se aplicará al valor. Por ejemplo, un nibble con el valor de 2 significa
que el dato está en unidades cuadradas, si es 0Dh representa un -3 por lo que
significa que el dato está en unidades cúbicas negativas. Esto es diferente al ítem
unit exponent.
40
Por ejemplo, para especificar tiempo en segundos hasta un minuto, el descriptor
reporte deberá incluir la siguiente información.
Logical minimum = 0
Logical maximum = 60
Physical minimum = 0
Physical maximum = 60
Unit exponent = 0
Unit = 1003h
Nibble 0 = 3 para seleccionar sistema de medición lineal inglés. Nibble 3 = 1 para
seleccionar el tiempo en segundos. Si se necesita especificar en décimas de
segundos se requiere aumentar los máximos y cambiar el ítem unit exponent. Para
enviar un valor de 600 se requiere de 3 bytes, el cual se deberá especificar en el tag
report size.
Logical minimum = 0
Logical maximum = 600
Physical minimum = 0
Physical maximum = 600
Unit exponent = 0Fh
Unit = 1003h
Para enviar un valor de temperatura de 1 byte, que va desde -20 a 11 grados
Fahrenheit, se requiere lo siguiente.
Logical minimum = -128 o 80h
Logical maximum = 127 o 7Fh
Physical minimum = 0 o
ECh
Physical maximum = 110 o
6Eh
Unit exponent =
0
Unit = 10003h
-Report size. Especifica el tamaño en bits de un campo en un input, output o feature
ítem. Cada campo contiene una pieza de dato.
-Report count. Especifica cuantos campos en los ítems mencionados por report
size. Por ejemplo, si un reporte tiene 2 campos de 8 bits el report size es 8 y el report
count es 2. Si el reporte tiene un campo de 16 bits, el report size es 16 y el report
count es 1. Si se cuenta con múltiples ítems cada uno tiene su propio report size y
report count.
41
-Push. Asigna una copia de la tabla de estado del ítem global en la pila del CPU. La
tabla de estado del global ítem contiene las actuales asignaciones para todos los
global ítems previamente definidos.
-Pop. Es el complemento de push, restaura los estados grabados previamente por el
ítem push.
Los valores de los Local ítems son aplicados a todos los ítems hasta que un nuevo
valor es asignado. Estos no se encuentran sobre los main ítems.
Los local ítems relacionan usages generales, designaciones de body-parts y
cadenas. Un ítem delimitador habilita el grupo que asignará el local ítem. Los local
ítems son mostrados en la siguiente tabla.
Tabla 2.22 Local ítems.
Lócal ítem
Usage
Valor
000010
Usage minimum
000110
Usage maximum
001010
Designator index
001110
Designator minimun
010010
Designator maximum
010110
String index
String minimum
011110
100010
Strim Maximum
100110
Delimiter
101010
Reservado
101011 a 111110
Descripción
Un index que describe el uso para un ítem o
colecction.
El inicio usage asociado con elementos en un
arreglo o mapa de bits.
El final usage asociado con elementos en un
arreglo o mapa de bits.
Un valor designador en un physical descriptor.
Indica que parte del cuerpo aplica el control.
El inicio designador asociado con elementos
en un arreglo o mapa de bits.
El final designador asociado con elementos en
un arreglo o mapa de bits.
Asociaciones a cadenas con un ítem o control.
El primer string index cuando asignan a un
grupo de cadenas subsecuentes para
controles en un arreglo o mapa de bits.
El último string index cuando asignan a un
grupo de cadenas subsecuentes para
controles en un arreglo o mapa de bits.
El inicio (1) o final (0) de una asignación de
local ítems.
Para usos futuros.
42
-Usage. Es el usage ID que trabaja junto con el global usage page para definir la
función de un control, dato, o colección. Al igual que el usage page, la
documentación de tablas usages para HIDs listan usage IDs. Por ejemplo los
botones usage page usan local usage IDs de 1 a FFFFh para identificar cuales
botones se han presionado, el valor de cero significa no botones presionados. Un
reporte deberá asignar un usage a múltiples ítems. Si un report ítem es precedido por
un simple usage, ese usage se aplica a todos los ítems de datos. Si un report ítem
es precedido por más de un usage y el número de controles o ítems de dato es igual
al número de usages, cada usage es aplicado a un control o ítem de dato, con los
usages y los ítems controles/datos emparejados en secuencia. Si el report ítem es
precedido por más de un usage y el número de ítems control/dato es más grande
que el número de usages, cada usage se aplica a un control/dato, hasta que el último
usage se aplica a los controles/datos sobrantes.
-Usage minimum y maximum. Pueden asignar una serie de usage IDs a elementos
en un arreglo o mapa de bits. Por ejemplo, en la siguiente tabla muestra un reporte
que contiene el estado de 3 botones (0 o 1), el usage minimum y maximum
especifican que le primer botón tiene el usage ID de 1, y hasta el tercer botón que
tiene el usage ID de 3.
Tabla 2.23 Ejemplo de uso de Usage minimum y maximum.
Usage page (valor para
botón)
Lógical minimum (0)
Lógical maximum (1)
Usage minimum (1)
Usage maximum
(3)
Report count (3)
Report size (1)
Input (dato,variable,
absoluto)
-Designator index. Para ítems con descriptor físico (physical descriptors), asigna un
valor designado este a su vez especifica que parte del cuerpo usa el control.
-Designator minimum y maximum. Cuando un reporte tiene múltiples designator
indexes éste es aplicado a los elementos en un campo de bits o arreglo, Un
designator minimum y maximum puede asignar un designator index secuencial para
cada ítem de bit o arreglo.
43
-String index. Un ítem o control que puede incluir un string index para asociar una
cadena con el ítem o control.
-String minimum y maximum. Cuando un reporte tiene múltiples string index éstos
se aplican para los elementos de en un mapa de bits o arreglo, un string minimum y
maximum pueden asignar un string index secuencial para cada ítem de bit o arreglo.
-Delimiter. Define el inicio o final de un ítem local (0 o 1). Deberá contener usages
alternados para un control, esto permite que diferentes aplicaciones definan controles
de dispositivos de diferentes maneras. Por ejemplo, un botón deberá tener un uso
genérico (button 1) y un específico uso (send, quit, etc).
En resumen de la sección 2.1.15 se puede organizar los diferentes ítems de la
siguiente forma:
Figura 2.23 Estructura del descriptor reporte.
44
2.1.16 Descriptor físico (Physical descriptor)
Especifica la parte o partes del cuerpo previsto para activar un control. Son
agrupados dentro de asignaciones, cada descriptor set consiste de un corto
encabezado seguido por uno o más descriptores físicos. Los encabezados definen
las bías (si el descriptor set está apuntando a un usuario derecho o zurdo) y la
preferencia de las asignaciones. Para un vendor se pueden definir descriptores
físicos alternados.
El descriptor físico se divide en 3 campos: Designator que identifica el actual parte
del cuerpo que afecta a un ítem por ejemplo la mano. Qualifier a futuro define los
designator por ejemplo mano derecha o izquierda. Effort valor cuantificando el
esfuerzo que el usuario deberá emplear para afectar el ítem. Si múltiples ítem
identifican alguna combinación designator/qualifier el valor de effort puede ser usado
para resolver el asignamiento de la función. Un valor de cero en effort significa que
un dedo está en descanso o cuando una mano está en una posición de descanso.
Sólo una vez uno o más controles tendrán idénticos designator/qualifier/effort
combinaciones porque ellos están físicamente conectados juntos. Por ejemplo
cuando dos teclas son presionadas el descriptor deberá escoger solo una o ejecutar
las dos en caso de que los botones operen como un joystick.
El descriptor set cero, es un descriptor especial que indica el número de descriptor
set adicionales y así el número del descriptor físico en cada asignación.
Tabla 2.24 Descriptor físico cero.
Parte
bNumber
Tamaño
(bytes)
1
bLength
2
Descripción
Expresión numérica que indica el número de
physical descriptor. No incluye el physical descritor
cero.
Expresión numérica que indica la longitud de cada
physical descriptor.
45
Tabla 2.25 Descriptor físico.
Parte
bPhysicalInfo
Tamaño
(bytes)
1
dPhysical
dPhysical
dPhysical
Descripción
Bits especificando información física:
7-5 Bias, 4-0 Preferencia (0 más preferido).
Physical descriptor data, index1.
Physical descriptor data, index2.
Physical descriptor data, index2.
2
2
2
El campo bías indica a cual mano el descriptor set está caracterizando, éste no es
aplicable para algunos dispositivos.
Tabla 2.26 Valores de bias.
Valor
Descripción
0
No aplicable
1
Mano derecha
2
Mano izquierda
Valor
Descripción
3
Ambas manos
4
Cualquier mano
5
Reservado
Valor
Descripción
6
Reservado
7
Reservado
Si se va a indicar preferencia otro descriptor físico como el que sigue será necesario.
Tabla 2.27 Descriptor físico agregado.
Parte
bDesignator
bFlags
Tamaño
(bytes)
1
1
Descripción
Indica que parte del cuerpo afecta al ítem.
Bits especificando banderas: 7-5 qualifier, 4-0
effort.
Tabla 2.28 Valores para los designators.
Valor
00
01
02
03
04
05
06
07
08
09
0A
0B
0C
0D
0E
0F
Descripción
Ninguno
Mano
Globo ocular
Ceja
Párpado
Oreja
Nariz
Boca
Labio superior
Labio inferior
Quijada
Cuello
Brazo superior
Codo
Antebrazo
Muñeca
Valor
10
11
12
13
14
15
16
17
18
19
1A
1B
1C
1D
1E
1F
Descripción
Palma
Pulgar
Dedo índice
Dedo medio
Dedo anillo
Dedo meñique
Cabeza
Hombro
Cadera
Cintura
Muslo
Rodilla
Calf
Tobillo
Pie
Talón
Valor
20
21
22
23
24
25
26
27
28-FF
Descripción
Bola de pie
Dedo gordo
Segundo dedo del pie
Tercer dedo del pie
Cuarto dedo del pie
Dedo chico del pie
Frente
Mejilla
Rservado
46
El campo qualifier indica cual mano (o mitad del cuerpo) el designator está
definiendo. Éste no es aplicable para algunos dispositivos.
Tabla 2.29 Valores de qualifier.
Valor
0
1
2
3
Descripción
No aplicable
Derecha
Izquierda
Ambos
Valor
4
5
6
7
Descripción
Cualquiera
Centro
Reservado
Reservado
2.1.17 Dispositivo de interfaz humana (HID)
Son dispositivos de baja velocidad que tienen contacto directo con personas, estos
dispositivos utilizan reportes para el intercambio de datos. Cuando un dispositivo
tiene un interfaz de selección de inicio (boot), el dispositivo puede ser usado cuando
los controladores de host no son cargados. Esto puede ocurrir cuando la PC inicia
directamente a DOS o cuando estás en modo a prueba de errores en el sistema
operativo. Un teclado o ratón con una interfaz de selección de inicio puede ser
predefinido simplificando el protocolo soportado por el BIOS.
El BIOS carga del ROM u otra memoria no volátil en el Boot up y este es valido en
cualquier modo del sistema operativo. La especificación del HID define el protocolo
de interfaz de selección de inicio para teclado y ratón.
Si el dispositivo tiene una interfaz de selección de inicio, el campo protocolo indica si
soporta una interfaz de teclado (1) o un ratón (2). Los valores de 3 – 255 son
reservados. En el campo subclase, un cero significa que el dispositivo no soporta
interfaz de buteo, los valores de 2 -255 son reservados.
Cuando se llega a cargar el sistema operativo normal, el host envía un Set_protocol
causa que el dispositivo cambie del protocolo de selección de inicio al protocolo del
reporte.
47
2.2 Microcontroladores
2.2.1 Introducción
Un controlador es un dispositivo que se emplea para el gobierno de uno o varios
procesos, a medida que avanzó el tiempo todos los elementos del controlador se han
podido incluir en un chip, este nuevo dispositivo es llamado microcontrolador .
Un microcontrolador es un circuito integrado de alta escala de integración, que
incorpora la mayor parte de sus elementos que configuran un controlador, su menor
tamaño minimiza el número de componentes y el coste.
Los PICs son microcontroladores de la compañía Microchip, donde sus siglas PIC
significan controlador de interrupción programable. Éstos poseen una arquitectura
Harvard, memoria de programa de varios tipos como; flash, OTP (programable una
sola vez) y SQTP (programada desde fábrica con números de serie). También
poseen registros de uso general (RAM), así como múltiples periféricos y módulos de
diferentes propósitos como; ADCs, puertos digitales, comparadores, PWM, etc.
Comunicaciones seriales como; I2C, serial síncrono y asíncrono, interfaz con el
puerto USB y otras.
El lenguaje de programación que utiliza es ensamblador para MPLAB (con 35
instrucciones aproximadamente), MPLAB es un programa para crear código
hexadecimal y así programar el PICs, además es gratuito. Para mayor información
sobre este programa visitar la página www.microchip.com. Y para mayor información
sobre el conjunto de instrucciones ver el PDF de cualquier modelo de PIC.
También es posible utilizar otros programas que manejan lenguaje C y obtener el
código fuente para programar el PIC. Uno de ellos es el PIC C COMPILER.
48
Por mencionar un ejemplo, estos son los registros de configuración (ver figuras 2.24
y 2.25) de los diferentes periféricos y módulos de los microcontroladores 16C745 y
16F628, distribuidas en 4 bancos de memoria.Los de la gama baja solo poseen 2
bancos de memoria.
Figura 2.24 Mapa de memoria del PIC 16C745.
49
Figura 2.25 Mapa de memoria del PIC 16F628.
2.2.2 Puertos de entrada y de salida
Los microcontroladores poseen puertos programables de entrada o de salida, pero
en varios de ellos, algunos pines son multifuncionales, esto es, que asignando
valores a determinados registros (configurar), ese PIN podría ser la entrada de señal
de un comparador, de un ADC, o la salida de un mismo comparador o la salida de un
transmisor serie.
50
Por mencionar algún ejemplo, el PIN RC6/RX/DT del PIC 16C745 puede ser
configurado como un pin de entrada o salida digital, como transmisor de
comunicación serie asíncrona, o transmisor y receptor de datos en la comunicación
serie síncrona. Generalmente sus funciones son separadas con una diagonal. Por
mencionar otro ejemplo el pin RB0/INT que puede ser configurado como un pin de
entrada o salida digital o como entrada para la interrupción de un flanco de subida o
de bajada según sea el caso. En varios casos algunos puertos tienen que ser
configurados y otros están configurados por default. Si es el caso de que un pin, sea
configurado como una entrada o salida digital, ese pin es asociado a un determinado
bit en un registro, para leer o escribir el dato y también se le asocia otro bit en otro
registro, para determinar si ese pin es de entrada o de salida, en el ejemplo del
PIC16C745 son los registros portc y trisc respectivamente para los pines RCn siendo
n el número del pin.
2.2.3 Módulo USART (transmisor-receptor síncrono y asíncrono universal)
Este módulo establece una interfaz de comunicación serie síncrona y asíncrona,
configurando ciertos registros de los bancos de memoria. Si se configura la
comunicación asíncrona, en el PIN TX/CK se usa como línea transmisión y el PIN
RX/DT como de recepción, permitiendo así una comunicación full duplex. Si se
configura como comunicación síncrona los respectivos pines se convierten en una
línea de reloj y una de dato, permitiendo así una comunicación half duplex. En la
comunicación síncrona, se puede configurar al dispositivo como maestro o como
esclavo, esto es, un único maestro genera el reloj de sincronía para la transmisión de
datos. Cada flanco de subida que genera el pin de reloj del maestro, en el pin de dato
se debe de sacar un bit del dato a transmitir (ya sea que el maestro transmita o el
esclavo), cuando el pin de reloj del maestro conmuta a flanco de bajada, éste le
indica al dispositivo receptor (puede ser maestro o esclavo) que debe de leer el nivel
lógico del pin de dato, así que, en cada flanco de subida se saca un bit de dato y en
cada flanco de bajada se debe de leer el dato.
51
Figura 2.26 Comunicación serie síncrona.
En la comunicación asíncrona, posee un protocolo para definir el dato, esto es, un bit
de inicio seguido por los bits de datos y un bit de stop. Además el baudio le indica
como leer los estados lógicos.
Figura 2.27 Protocolo serie asíncrono.
Para configurar este módulo serial es necesario asignar valores a los registros txsta y
rcsta, además, se deben configurar los pines RX/DT y TX/CK como entrada, esto se
logra poniendo sus correspondientes bits, en el registro tris con el valor de uno. Para
transmitir un dato, sólo se necesita cargar al registro txreg el valor, o cuando se
desea leer lo que se a recibido por el puerto serie se lee el registro rcreg, también se
asocian a este módulo banderas que indica si hay un dato válido que leer o si el
puerto serie está listo para transmitir otro dato, esas banderas son RCIF y TXIF
respectivamente, que se leen con un valor de uno si ocurre una recepción o si está
listo para transmitir.
Figura 2.28 Registro TXSTA.
Figura 2.29 Registro RXSTA.
52
Figura 2.30 Registro PIR1 del PIC 16C745.
También se le puede habilitar una interrupción a las banderas, asignando el valor de
uno a los bits RCIE y TXIE.
Figura 2.31 Registro PIE1 del pic 16C745.
2.2.4 Módulo ADC (Convertidor analógico digital)
En el PIC 16F873, el módulo posee 10 bits de resolución, 2 entradas para la
referencia positiva y negativa, si se desea, se puede configurar con una referencia
positiva de la alimentación y el tiempo de adquisición es programable. Todo lo
mencionado se lleva a cabo asignando sus correspondientes valores a los registros
de configuración de este módulo.
Figura 2.32 Registro ADCON0 del pic 16F873.
Figura 2.33 Registro ADCON1 del pic 16F873.
El bit GO/DONE indica si la conversión está en progreso, el bit ADIF se pone a uno
cuando termina la conversión, y también se le puede asociar una interrupción para
cada fin de conversión, habilitando el bit ADIE.
53
2.2.5 Módulo USB
El PIC16C745 proporciona varios registros para llevar a cabo la comunicación con el
puerto USB. El registro UIR es un registro de banderas que proporciona información
sobre los eventos que ocurren el el puerto.
Figura 2.34 Registro UIR.
Asociado a este registro se encuentra el registro UIE que habilita interrupciones si
alguna de las banderas del registro UIR es puesto a uno.
Figura 2.35 Registro UIE.
También proporcina un registro para el control de errores sobre el bus del puerto usb,
de esto se encarga el registro UEIR.
Figura 2.36 Registro UEIR.
A este registro también se le asocia un registro (UEIE), para habilitar interrupciones
en caso de que el microcontrolador detecte un error sobre el bus.
Figura 2.37 Registro UEIE.
54
El registro UCTRL es un registro de control que provee bits para asignar aspectos de
señalización sobre el bus.
Figura 2.38 Registro UCTRL.
El registro UADDR posee la dirección única del dispositivo, éste toma la dirección
cero durante el procesos de enumeración, después, el host le proporciona una
dirección única.
Figura 2.39 Registro UADDR.
Para proporcionar información sobre los estados del dipositivo se encuentra el
registro USWSTAT.
Figura 2.40 Registro USWSTAT.
Cada enpoint del PIC es controlado y configurado por un registro UEPn dónde la n
significa el número de enpoint, el pic16C745 soporta los enpoints 0,1 y 2.
Figura 2.41 Registro UEPn.
55
La figura 2.40 muestra la tabla de configuración para los 3 bit más significativos del
registro UEPn, y que configura los tipos de transacciones que deberá soportar
determinado enpoint, asignar un 06h al registro asegura que el enpoint pueda
realizar transacciónes de tipo control.
Figura 2.42 Tabla de configuración de enpoints.
Para eficientar la comunicación de los enpoints se encuentra un buffer descriptor
table (BDT) en espacio de registros, los buffers son compartidos entre el bus USB y
el MCU (procesador y firmaware del pic) sólo uno de ellos puede actualizar estos
registros a la vez, la bandera UOWN permite saber quien tiene permiso para
modificar el BD (buffer descriptor).
Cada endpoint tiene 4 bytes de BD y apuntan hacia el buffer de dato en los registros
duales usb (dual port registers, banco 3, direcciones 1A0h-1DFh) , para asignar los
BD a estos registros de datos se encuentra el registro BDndAL, dónde la n significa
el número del endpoint y la d la dirección de la transacción. Por ejemplo al enpoint de
control se le asocia los registros BD0OAL (salida), BD0IAL (entrada).
Figura 2.43 Registro BDndAL.
A este registros sólo se le puede asignar valores de B0h – DFh (dirección de los
registros duales USB), los demás registros son reservados para los tokens.
56
Asociado a este registro esta el registro BDndBC (byte count), representa el número
de bytes a transmitir en un token in (modificado por el MCU) o recibidos durante un
token out o setup (modificados por el SIE). En caso de un token de entrada sólo son
válidos los números del 1-8 en este registro.
Figura 2.44 Registro BDndBC.
Otro registro asociado es el registro BDndST, con sus datos reporta el estado de una
transacción y su significado difiere dependiendo si el MCU lee o escribe el registro.
Figura 2.45 Registro BDndST leído por el MCU.
Figura 2.46 Registro BDndST escrito por el MCU.
Cuando el bus a realizado una transacción, el registro USTAT es modificado para
informar el endpoint y la dirección del token, este registro es utilizado por el MCU
para determinar cual DBT fue modificado por la última transacción, las transacciones
se apilan en un STAT FIFO de cuatro bytes, que conforme se limpia el bit TOK_ DNE
del registro UIR los valores se actualizan en este registro.
Figura 2.47 Registro USTAT.
57
Cuando el bus transmite o recibe dato el SIE va a checar que el bit UOWN sea igual
a uno, si es así, el SIE obtiene la dirección del buffer y mueve el dato desde o hacia
el correspondiente buffer, actualizará el BD status y el registro USTAT y al bit UOWN
lo pondrá a cero, cuando el token es completado, el bit TOK_DNE se pone a uno. Al
ponerse este último bit en uno, se crea una interrupción y el MCU dispone de los
registros antes mencionados para servir la transacción y devolver la disponibilidad de
los mismos al SIE.
2.3 Freeware
2.3.1 Introducción
Freeware es un software que se regala sin cargo alguno. Microchip también
proporciona un freeware para no tener que hacer código, que realice lo que a nivel
bajo hace el dispositivo de USB, como atender las interrupciones de USB, realizar
rutinas para checar los estados del dispositivo de USB (mencionado en la sección
2.1.9), así como otras tareas.
Figura 2.48 Diagrama para la rutina de servicio de interrupción.
58
La figura 2.46 muestra un diagrama para visualizar la estructura de la rutina de
servicio de interrupción (RSI), que es donde se lleva acabo la mayoría de las
transacciones del puerto USB. Esta rutina identifica el encendido de bits para
determinar quíen causó la interrupción, una vez determinada, se atiende la
interrupción ya sea saltando o mandar a llamar una rutina, asignar una macro o
atenderla una vez identificada.
La figura 2.49 muestra los tipos de tokens que atiende el freeware. Al terminar de
atender a cualquiera de estos tokens, regresa a la dirección de memoria de
programa donde se vió interrupida.
Figura 2.49 Tipos de tokens que atiende el freeware.
59
2.3.2 Código fuente en ensamblador del Freeware (proporcionado por
Microchip)
El freeware para ensamblador consiste en los siguientes archivos:
• 16C745.lkr – Indica al compilador como ensamblará los archivos con código fuente.
• usb_defs.inc – Define variables de USB y macros que se usarán en los siguientes
archivos.
• usb_main.asm – Aquí se encuentra el programa principal, esto es, lo que el
usuario desea hacer o programar. También se encuentra la rutina de servicio de
interrupción, la configuración inicial del dispositivo hasta que el reset llegue por parte
del hub.
• usb_ch9.asm – Aquí se encuentran las funciones que atienden a los diferentes
estados del dispositivo (explicado en la sección 2.1.9), atiende los tokens y paquetes
según sea la transacción y lectura/escritura por el puerto USB.
• hidclass.asm – Contiene las funciones para un dispositivo HID. Como atender las
requisiciones del host para un HID.
• descript.asm – Contiene los descriptores que describirán nuestro proyecto.
En la versión HI-TEC C, se encuentra los archivos:
• usb.pjt, • usb.h, • usb_defs.h, • usb_main.c, • usb_ch9.c
2.3.3 Funciones del código fuente de ensamblador
InitUSB. Se manda a llamar antes de que el proceso de enumeración empiece
(aproximadamente en 16 microsegundos), habilita los periféricos de USB.
60
ConfiguresdUSB. Polea los bits de estados para ver que el dispositivo ya halla sido
configurado.
DeinitUSBint. Usado para que el dispositivo sea ignorado por el host y así pueda ser
desconectado.
ServiceUSB. Llamado para procesar transacciones como tokens y errores en el
puerto USB.
PutEPn. Envía datos al host vía endpoint n, dándole el número de bytes a enviar
mientras que unos punteros indican el bloque de información a enviar.
GetEPn. Recibe datos del host vía endpoint n, la dirección deseada para los datos
deberá ser indicada con punteros.
Hay en el freeware, más funciones para los demás estados, que sirven para crear un
proyecto más avanzado. Para mayor información visitar la página de microchip.
2.3.4 API de Visual basic (Activex)
Microchip proporciona también un API que nos comunica con el buffer de USB del
host, para extraer los datos al interfaz final para el usuario o programa de aplicación.
Se puede crear un API propio, si se es un experto en Visual Basic y obtienes la
información del kernel, que es allí donde se puede comunicarte con el controlador de
Windows.
Un control Activex es un objeto que coloca un formulario para permitir o mejorar la
interación de un usuario con una aplicación. Los controles Activex tienen eventos y
se pueden incorporar a otros controles. Estos controles tienen una extensión ocx. Un
componente de código Activex es una aplicación servidora que expone funcionalidad
que otras aplicaciones pueden utilizar y reutilizar mediante automatización. Los
componentes Activex permiten a los programadores combinar fragmentos de código
61
reutilizables para crear aplicaciones y servicios. Los componentes de código ofrecen
una completa funcionalidad. Por ejemplo, puede empaquetar una rutina compleja en
un componente simple que puedan utilizar otros programadores. Crear sus propios
componentes Activex o bien adquirirlos a Microsoft o a otros fabricantes para
proporcionar servicios genéricos. Cuando cree aplicaciones, puede combinar
componentes Activex con componentes genéricos para crear robustas soluciones
personalizadas.
Con la versión 5.0 de Visual basic puede crear componentes de código Activex
(antes llamados servidores OLE).
Microchip proporciona un Control ACTIVEX para comunicar la aplicación cliente con
nuestro microcontrolador. Se trata del HIDCOMM, en el cual contiene eventos y
funciones que ayudarán a conocer el estado de nuestro dispositivo, a seleccionar (si
es necesario) el dispositivo que deseamos comunicarnos, realizar operaciones de
lectura/escritura del microcontrolador. Sus propiedades, eventos y funciones son las
siguientes:
PROPIEDADES:
-MatchMethod As Integer. Es un switch de asignación de bits, para especificar cual
será el criterio de búsqueda, que se usara para localizar el dispositivo HID. Por
ejemplo, si se desea comunicarse a un HID, en el cual el ID del producto es 5 y el
vendor ID es 6, el MatchPID y el MatchVID deberán de llenarse con esa información
y poner MatchMethod = CheckPID o CheckVID.
-MatchPID As Long. Es uno de los criterios de búsqueda, se puede especificar y
localizar el dispositivo HID. Si se desea comunicarse a un HID el cual el ID del
producto es 1234, especifica 1234 en esta propiedad.
62
-MatchVID As Long. Es uno de los criterios de búsqueda que se puede especificar
para localizar el dispositivo HID. Si tu quieres comunicarte con un ID vendor 1234,
especifica 1234 en esta propiedad.
-MatchVersion As Long. Es uno de los criterios de búsqueda que puedes
especificar para localizar el dispositivo HID. Si se quiere comunicar a un HID el cual
su versión es 1.00, especifica 256 en esta propiedad, por que el número de la versión
esta expresado en BCD, con los 2 últimos dígitos como parte decimal. La versión
1.10 deberá ser 272.
-MatchManufacturer As String. Es otro de los criterios de búsqueda. Se deberá
colocar una cadena de caracteres para encontrar la manufacturera.
-MatchProduct As String. Es otro de los criterios de búsqueda. Se deberá colocar
una cadena de caracteres para encontrar el producto.
-MatchSerial As String. Es otro de los criterios de búsqueda. Se deberá colocar una
cadena de caracteres para encontrar el serial del producto.
- ReportID As Byte. Determina cual reporte HID esta la PC enviando y recibiendo.
-TimeOut As Long. Indica el intervalo de tiempo en ms. de todas las operaciones de
E/S al dispositivo HID. Si el intervalo del time out a sobrepasado antes de que la E/S
esta completada, la operación habrá fallado, y el evento redfailure/writefailure va a
ser activado.
EVENTOS:
- ConnectSuccess(ByVal Status As Long). Este es activado cuando el control
activex se ha conectado bien al dispositivo.
63
-ConnectFailure(ByVal Status As Long). Este evento se activará cuando no haya
criterio de búsqueda, cuando hay más de un criterio de búsqueda, o si el mismo
método es abierto por otro programa. La razón de fallo está en la variable status.
-Disconnected(ByVal Status As Long). Éste es activado si el dispositivo HID está
desconectado.
- ReadSuccess(ByVal Status As Long, ByVal ByteRead As Long). Éste es
activado si la última lectura asíncrona fue satisfactoria. Los bytes leídos son pasados
a través de byteread.
-ReadFailure(ByVal Status As Long, ByVal ByteRead As Long). Éste es activado
si la última lectura asíncrona ha fallado. La razón del error es pasado a la variable
status y los bytes leídos pasados a byteread.
-WriteSuccess(ByVal Status As Long, ByVal ByteWritten As Long). Éste es
activado si la última escritura asíncrona fue satisfactoria. Los bytes leídos son
pasados a través de byteread.
- WriteFailure(ByVal Status As Long, ByVal ByteWritten As Long). Éste es
activado si la última escritura asíncrona ha fallado. La razón del error es pasado a la
variable status y los bytes leídos pasados a bytewritten.
FUNCIONES:
- Browse() As String. Escanea todos los dispositivos HID actualmente añadidos a la
ruta. El usuario puede escoger un dispositivo desde la lista de todos los dispositivos
añadidos, y la ruta escogida por el dispositivo es regresado. La ruta puede ser usada
en la función ConnectToPath para la conexión directa y escoger el dispositivo HID. Si
el usuario oprime el botón cancel, la ruta va a ser una cadena vacía.
64
- Connect() As Long. El dispositivo HID a comunicar está determinado por la
propiedad matchxxxx y el bit swicheado de MatchMethod. El control activex
HIDcomm deberá ser conectado al dispositivo HID para realizar cualquier operación
de E/S. Si no hay dispositivos encontrados o se encuentran más de un criterio de
búsqueda, la función fallará, un código de estado es regresado para indicar la razón
de la falla o satisfactoria conexión.
- ConnectToPath() As Long. Obtiene esta ruta. El control activex deberá ser
comunicado al dispositivo HID para hacer cualquier operación de E/S. Un código de
estado es regresado para indicar la razón del fallo o satisfactoria conexión.
- GetFeature(ByVal Size As Long)
As Byte(). Obtiene un informe de las
características del dispositivo HID. Size es el número de bytes a leer, los reportes de
características son regresadas como un arreglo de bytes. La variable reportID
determina cual reporte de características se trata.
-ReadFrom(ByRef Size As Long) As Byte(). Lee desde un dispositivo HID. Size es
el tamaño del buffer intermediario de datos. El número de bytes actualmente leídos
se ponen el la variable Size después de la operación de lectura y un arreglo de bytes
es regresado, la variable reportID determina cual reporte de características se trata.
- Sub WriteTo(ByRef Buffer() As Byte, ByRef Size As Long). Escribe a un
dispositivo HID. Buffer tiene el dato a enviar, Size es el no. de bytes a enviar, primero
se indica el tamaño a enviar y después se escribe.
-Function SetFeature(ByRef Buffer() As Byte, ByVal Size As Long) As Boolean.
Pone el reporte de características del HID a especificar valor. Buffer contiene el dato
a enviar, Size es el número de bytes a enviar, si la operación es exitosa, la función
regresa verdadero, de otra forma, falso. La variable reporID determina cual reporte
de características se trata esta transacción.
65
-Sub Uninit(). Esta función descarga archivos DLLs subyacentes usados por el
activex. Esto es necesario para llamar las funciones antes que el programa se
cargue. Llama en tu programa el evento "terminate" o "unload".
2.3.5 Asignación del controlador (Driver)
Microsoft Windows proporciona controladores para dispositivos estándar, en nuestro
caso, proporciona un controlador para los dispositivos catalogados como HID.
Cuando el sistema operativo detecta un dispositivo por primera vez, aparece un
cuadro de diálogo preguntándonos por el controlador para el dispositivo.
Figura 2.50 Cuadro de dialogo en win98.
En caso del sistema operativo XP (si se encuentra actualizado con algún service
pack) la asignación es automática. Un service pack es una actualización del sistema
operativo (parche). Una vez asignado el driver, se puede ver en los registros y en los
administradores de hardware, que nuestro dispositivo forma parte del grupo de
componentes. Para revisar los cuadros de diálogos y registros (en diferentes
versiones de windows) ver las páginas de anexo 2.
66
2.4 Referencias
[1].- Martín Cuenca, J.M. Angulo Usategui, I. Angulo Martinez. Microcontroladores
PIC. Quinta edición. EDITORIAL PARAINFO THOMSON LEARNING.
[2].- Jan Axelson. USB COMPLETE. Second and Third Editions. LAKE VIEW
RESEARCH LLC.
[3].- Steven McDowell, Martin D. Seyer. USB EXPLAINED. EDITORIAL PRENTICE
HALL.
[4].- www.usb.org. Universal serial bus Specification. Rev 1.1, Noviembre de 2005.
III DESARROLLO
3.1 Introducción
El sistema de monitoreo a implementar lo componen dos dispositivos principales a
los cuales se les llamó módulo maestro y módulo esclavo.
Central
Pc o PLC
Módulo maestro
Área de cultivo
Electroválvulas Y
equipo de bombeo
Cultivo y
N Transductores
N Módulos esclavos
Figura 3.1 Sistema de riego.
Como muestra la figura 3.1, el módulo maestro se encuentra en la central y los
módulos esclavos en el área de cultivo, ambos módulos principales se comunican
entre si vía RF y son conectados a diferentes dispositivos; los esclavos se conectan
a varios capacitores que sensan la humedad y el maestro a una PC o a un PLC. En
el sistema de comunicación, el maestro transmite una señal de activación el cual
será recibido por todos los esclavos, pero solo uno estará capacitado para activarse,
una vez activado uno de los esclavos, éste deberá de realizar la lectura de humedad
y transmitirlo al maestro y éste a su vez pueda transmitirlo a la PC o al PLC.
Etapa TX de RF
Etapa RX de RF
Etapa de Control
(microcontroladores)
Figura 3.2 Etapas de ambos módulos principales.
Circuiteria
externa
68
La figura 3.2 muestra las etapas en que se dividen ambos módulos principales como
un primer acercamiento al diseño de los módulos. La etapa de transmisión de RF,
representa la sección por el cuál la etapa de control transmitirá la señal de un módulo
a otro, la etapa de recepción es la encargada de recibir las señales y
proporcionárcelas a la etapa de control, estas etapas de RF se tomarán como una
caja negra, el cuál cuenta con una entrada y una salida para que la etapa de control
transmita y reciba señales, también cuenta con una entrada para que la etapa de
control pueda cambiar el estado de la comunicación de transmisión a recepción y
viceversa. Este cambio de estado no es más que el intercambio de encendido y
apagado entre las etapas de transmisión y recepción, también se intercambia la
conexión de la antena entre las etapas de RF.
La etapa de control es la encargada de encender y apagar varias etapas analógicas,
generar señales para la transmisión, procesar la señal recibida y realizar otras
actividades especiales para cada uno de los módulos principales; para realizar estas
tareas se hará uso de microcontroladores PICs. El encendido y apagado de las
etapas se hizo con el fin de ahorrar energía de la batería, y también, a que algunas
etapas interferían con otras, esto debido a la radiofrecuencia que se está utilizando.
El cálculo para estas tareas y todas las pruebas, se realizarón a prueba y error
observando LEDS que se encendían y apagaban en ambos módulos, o en algunas
ocasiones mirando las frecuencias en el osciloscopio.
La etapa circuiteria externa representa el espacio que ocuparán los circuitos de
excitación para el capacitor que sensa la humedad, esto es en el caso del ser un
módulo esclavo, en un módulo maestro, representa el espacio que ocupará la
circuiteria para la interfaz con la PC y PLC. En la figura 3.2 las flechas representan el
flujo de información de una etapa a otra, las líneas sencillas representan las líneas
de control que ejerce la etapa de control sobre las otras etapas.
Una vez identificadas las necesidades de cada módulo, las etapas finales para cada
uno de ellos son las siguientes:
69
El módulo maestro se divide en varias etapas, como lo muestra la figura 3.3
compuestas por: etapa de control, etapa de modulador FM, etapa de potencia, etapa
receptor FM y adecuador.
Etapa De
Potencia
Modulador
FM
Control
PIC16C745
Receptor
FM
Adecuador
PIC16F628
Barra de
LEDs
y conector
USB
conector
PLC (db9)
Figura 3.3 Etapas del módulo maestro.
El indicador de barras de LEDS (figura 3.4) nos muestra que algunos de los estados
del dispositivo USB (mencionados en la sección 2.1.9 del capítulo 2) se encuentren
correctamente inicializadas, el primer LED (de izquierda a derecha) indica que se han
configurado los registros de USB, el segundo, que el dispositivo ha sido reseteado
por el host, el tercero, que el dispositivo ya tiene una dirección por parte del host, el
cuarto, que el puerto está en modo sleep, el sexto indica actividad en el endpoint.
Figura 3.4 Barra de LEDS.
La figura 3.5 muestra la etapa que servirá de interfaz con el PLC a través de un
conector db9 y una etapa de adecuación de voltaje.
Figura 3.5 Vista frontal y superior del conector PLC en el módulo maestro.
70
El módulo esclavo se divide en las etapas que muestra la figura 3.6, compuestas por:
etapa de control, circuito del transductor, modulador FM, la etapa de potencia, el
receptor FM y el adecuador.
Etapa De
Potencia
Modulador
FM
Circuito del
Transductor
Receptor
FM
Adecuador
Control
PIC16F873
Figura 3.6 Etapas del módulo esclavo.
El circuito del transductor representa la etapa donde se encuentra la circuiteria de
excitación para el capacitor que servirá de cómo sensor de humedad. Este capacitor
estará conectado a esta etapa.
A continuación se mencionan algunas especificaciones para el sistema de monitoreo
ya que algunas de ellas son especificaciones de la etapa de RF.
►Se decidió que el sistema de comunicación sería half duplex, ya que con esto se
utilizaría la misma frecuencia portadora para la activación y la transmisión de datos
de humedad.
► También se decidió que se utilizaría un número mínimo de hardware, es por esa
razón que no se usaron señales digitales para la transmisión de los datos.
► El ancho de banda de la señal moduladora es de 1 a 5 Khz en la etapa de
transmisión de RF.
71
3.2 Conexión de microcontroladores
La figura 3.7 muestra a detalle las conexiones que tiene la etapa de control en el
módulo maestro hacia las demás etapas.
Figura 3.7 Conexion a detalle de los microcontroladores 16f628 y 16c745.
El generador de tonos representa el pin por donde saldrá la señal modulante hacia la
etapa modulador FM. El indicador de estados del puerto USB representa la barra de
leds que nos ayudará visualmente a checar los estados del dispositivo. El puerto
USB representa el conector por el cual se colocará el cable USB y este último hacia
la PC. La conexión entre el pin 17 del PIC16F628 y el pin 4 del PIC16C745,
representa una línea de control entre los 2 pics para realizar una petición de
transmisión de esclavo a maestro, en la comunicación serial síncrona.
72
Las conexiones de los pines 18 y 17 del PIC16C745 hacia los pines 7 y 8 del
PIC16F628 muestran las lineas de dato y reloj de la comunicación serie síncrona. El
medidor de frecuencia representa el pin por donde se recibirá la señal de dato por
parte de la etapa de adecuación. El mute representa parte de la circuitería que se
encuentra en la etapa de adecuación y cuya función es aterrizar la señales de ruido
que entrega el receptor FM hacia el medidor de frecuencia, debido a que perturba en
cierto proceso de comunicación serie síncrona, este mute se activa poniendo en
estado alto el pin 9 del PIC16F628. El pin 11 del mismo PIC, representa el dectector
de nivel del receptor FM, el cual indica en un estado en alto que se ha detectado
portadora y por lo tanto dato de humedad. El pin 12 del PIC16F628, es el encargado
de conmutar el encendido y apagado entre las etapas de potencia y receptor FM,
además también conmuta la conexión de la antena entre dichas etapas; poniendo el
nivel en estado alto se enciende la etapa de potencia y se apaga la etapa receptor
FM además de conectar la antena a la etapa de potencia, en estado bajo hace
exactamente lo contrario a lo mencionado. Los pines 18, del 1 al 3 representan los
pines por los cuales le indicamos al PLC,el transductor activado.
La figura 3.8 muestra a detalle las conexiones que tiene la etapa de control en el
módulo esclavo hacia las demás etapas.
Figura 3.8 Conexion a detalle del microcontrolador 16f873.
73
El generador de tonos representa el pin por donde saldrá la señal modulante hacia la
etapa modulador FM. El pin 4 al igual que el pin 12 del PIC16F628, es el encargado
de conmutar el encendido y apagado entre las etapas de potencia y receptor FM,
además también conmuta la conexión de la antena entre dichas etapas, funciona
exactamente igual que el pin 12 del PIC16F628. El pin 7 es el encargado de
conmutar el encendido y apagado de la etapa circuito del transductor, poniendo en
un estado en alto este pin se enciende la etapa antes mencionada, en estado bajo se
apaga la etapa. Los pines 13 y 14 representan la entrada para los jumpers de
configuración, esto es, modificar la frecuencia de activación, sin colocar los jumper el
microcontrolador lee un estado alto, con los jumper colocados lee un estado en bajo.
El detector de tonos representa el pin por donde se recibirá la frecuencia de
activación por parte de la etapa de adecuación. El pin 15 es el receptor de un push
buton, éste sirve para realizar una activación del módulo esclavo y realice una
transmisión de dato.
3.3 Modos de funcionamiento
Debido a los 2 diferentes destinos del dato de humedad (PC o PLC), el sistema de
monitoreo soporta 2 modos de funcionamiento, uno para la conexión con el PLC y
otro para la PC, estos modos de funcionamiento solo afecta al módulo maestro y se
decidió que solo modificando unos jumpers de sus posiciones, se pueda configurar al
módulo maestro en el modo de funcionamiento deseado (ver anexo 3).
El primer modo se presenta cuando el módulo maestro es conectado hacia la PC,
esta conexión se realiza por medio de un cable USB (figura 3.9), el programa
residente en la PC indica en tiempo real cuando debe de activarse un módulo
esclavo determinado, esto es, transmitiendo los datos necesários para la activación
hacia el módulo maestro por medio del puerto USB. Por este mismo puerto se recibe
los datos de humedad del módulo maestro, que a su vez, fue recibido por el módulo
esclavo activado. El dato es almacenado en el disco duro y el programa activa uno a
la vez cada módulo esclavo que esté dado de alta es su base de datos.
74
PC
Cable USB
Módulo Maestro
Figura 3.9 Modo conexión con la PC.
El segundo modo de funcionamiento es cuando el módulo maestro es conectado
hacia un PLC (figura 3.10), en este modo se requiere que el módulo maestro envíe
los datos a través de 5 pines conectados al PLC, de los cuales 4 de ellos determinan
(en número binario) el módulo esclavo que se ha activado y en el quinto PIN se
entrega la frecuencia o el dato de humedad que generó la activación (figura 3.11), el
PLC deberá ser capaz de leer esta frecuencia o dato de humedad y almacenarlo por
si mismo. En el conector db9 se encuentran los 5 pines de datos y 1 línea por donde
el PLC proporcionará una alimentación de 24 volts, para los transistores que se
encuentran en la etapa que servirá como interfaz con el PLC.
PLC
Módulo Maestro
Figura 3.10 Modo conexión con el PLC.
Donde los pines del 6 al 9 representan en número binario el transductor activado, y
por lo tanto, a quien pertenece el dato de frecuencia que se presenta por el pin
número 5, en el pin 1, el PLC entregará el voltaje de alimentación.
Figura 3.11 Conector db9 (pines correspondientes).
Debido a que la PC ya no estará conectada en este modo de funcionamiento se
dispone de un temporizador, el cual realiza en un determinado tiempo el barrido de
lecturas o activaciones, se tendrá en memoria RAM los datos necesarios para activar
los módulos esclavos así como el tiempo para el temporizador, toda esta información
75
es transmitida por medio de un software especial en la PC hacia el módulo maestro a
través del puerto USB.
Debido a los 2 modos de funcionamiento, se crearon 2 programas para la PC (en
visual basic) y 4 programas para los microcontroladores del módulo maestro (en
ensamblador), el programa para el microcontrolador del módulo esclavo permanece
independiente del modo de funcionamiento (en ensamblador).
3.4 Adecuación del Firmware
La adecuación representa el cambio que se realizó al firmware original para
adecuarlo a la necesidades de nuestro proyecto. Como se muestra acontinuación, se
realizó el cambio en la sección de enpoints en el archivo “descript.asm”.
Original
Endpoint1
retlw
retlw
retlw
retlw
retlw
retlw
retlw
Cambio
Endpoint1
retlw
retlw
retlw
retlw
retlw
retlw
retlw
Endpoint2
retlw
retlw
retlw
retlw
retlw
retlw
retlw
Figura 3.12 Adecuación al firmware.
7
ENDPOINT
0x81 ;endpoint1 de entrada
3
;de interrupción
4
;tamaño de paquete
0
;byte superior
0x0a ;intervalo de poleo
0x07
ENDPOINT
0x81 ;endpoint1 de entrada
0x03 ;de interrupción
0x08 ;tamaño de paquete
0x00 ;byte superior
0x0A ;intervalo de poleo
0x07
ENDPOINT
0x01
0x03
0x08
0x00
0x0A
Con este cambio, podemos enviar 8 paquetes por cada transacción en vez de 4, tal y
como lo indicaba el original, también se agregó un segundo endpoint y aunque no
estriba mucho en el funcionamiento, con esto le indica al host que el dispositivo
contiene un endpoint1 de entrada y otro de salida.
76
3.5 Diseño de software para la PC
El software es el programa hecho en Visual basic. Éste es requerido para dar de alta
los transductores que estarán dentro del sistema de monitoreo; con los 2 modos de
funcionamiento, se crearon 2 programas diferentes.
3.5.1 Diseño modo de conexión con la PC
A continuación se muestra un digrama para explicar el proceso de activación de un
sensor de humedad con el modo de funcionamiento para la PC.
Figura 3.13 Proceso de activación en el modo de conexión con la PC.
77
En este modo, se crea una base de datos para dar de altas los transductores, grabar
las lecturas de humedad y los tiempos en los cuales se realizarán los barridos. La
figura 3.14 se muestra la presentación en tiempo de diseño.
Figura 3.14 Programa en vista de diseño.
En la sección superior izquierda se editan, eliminan y agregan transductores, así
como los tiempos de barridos. En la parte inferior izquierda se encuentra la activación
del barrido de lecturas de forma automática (botón iniciar), esto es, se realizarán los
barridos de lecturas según la base de datos.
En la sección superior derecha se muestra la interfaz para enviar una sola activación
(activación manual), se pueden dar de alta tantos transductores como el ancho de
banda de la señal modulante lo permita, claro que, a mayor número de transductores
el barrido de lectura tardará más tiempo en realizarse. Para dar de alta un
transductor solo hay que oprimir el botón nuevo (figura 3.15), introducir la frecuencia
de activación (se aconseja que las frecuencias de activación para cada transductor
tenga una separación de 50 hertz y así dejar una banda de guarda de 30 hertz) y por
78
último, oprimir el botón guardar. También se pueden utilizar los botones de
desplazamiento para realizar cambios o dar de baja transductores.
Figura 3.15 Base de datos para los transductores.
También es necesario dar de alta el tiempo específico en las que se realizarán los
barridos de lecturas (figura 3.16), en la hora el valor va de 0 a 23 y en minuto 0-59
(como valores válidos). Su operación es idéntica a la sección “alta de transductores”.
Figura 3.16 Base de datos para los tiempos de barridos.
Para arreglos o calibraciones, se creó una interfaz para la activación de
transductores de forma manual (figura 3.17), sólo hay que indicarle la frecuencia del
transductor que se desea activar en la casilla. El botón calcular despliega los datos
necesarios para que el PIC genere la frecuencia indicada en la casilla, y el botón
enviar hace lo que el botón de calcular realiza y envia la información al PIC.
El resultado de la activación es mostrado en la parte inferior, si se desea un barrido
de lecturas de forma automática sólo hay que oprimir el botón iniciar. Esto hará que
el sistema realice los barridos sin tener que realizar los pasos que se explicaron para
la forma manual.
79
Figura 3.17 Interfaz para el barrido de lecturas manual.
El botón calcular se encarga de generar los números que el PIC16C745 necesita
para reproducir la frecuencia de activación, por medio del valor que se introduce en
la casilla de frecuencia y a una ecuación, dicha ecuación se explicará en secciónes
posteriores. El resultado de la ecuación es un número que es repartido en 6 bytes. El
botón enviar se encarga de transmitir 8 bytes a dicho microcontrolador, de los cuales
6 contienen datos para los 6 registros de la función en ensamblador.
Figura 3.18 Temporizadores del programa.
Los temporizadores son funciones que se ejecutan en determinados intervalos de
tiempo. El primer temporizador checa si se encuentran datos en el buffer USB
después de haber activado un transductor, esto se realiza observando el contenido
en una posición determinada del buffer de recepción de datos, si es un valor
diferente de cero, se ha realizado una lectura válida, entonces procede a guardar el
resultado en la base de datos. El segundo temporizador checa si ya puede realizar
un barrido de lecturas de acuerdo con la base de datos, esto es, checa la hora (en
80
tiempo real) de la PC y la compara con la base de datos, si la comparación es
positiva se realiza el barrido de lectura.
Para poder entender el flujo de las funciones, timers y botones, se presentan las
siguientes figuras, que explicarán los lugares y tiempos. El código (en Visual Basic)
se presentará en las páginas de anexo 1.
Timer1
no
Recibir buffer del HID
Hay algún
Dato valido?
si
1
no
Fue activación
manual?
Condiciones para otra
activación manual
1
si
Crear registro nuevo en la base de datos
Salir
Obtener hora y fecha
Botón Enviar
Guardar información en la base de datos
6 registros
al buffer
Deshabilitar timer1
Transmitir buffer al HID
Salir
Botón Calcular
Botón Limpiar
Calcular número
Limpia casillas
Repartirlo en
6 registros
Salir
Figura 3.19 Funciones del programa.
Habilito timer1
Botón Iniciar
Habilitar Timer2
81
Timer2
Deshabilito Timer1
Primer registro de tiempo
Primer registro de transductores
Obtengo el tiempo real
no
si
Tiempo real =
Tiempo de registro?
Obtengo frecuencia del
Registro Transductores
Siguiente registro
De tiempo
Ejecuto botón enviar
Pasó último
Registro
De tiempo?
no
Dato guardado?
si
Salir
si
Siguiente registro
De transductores
Último registro
De transductores?
no
si
Figura 3.20 Funcion del timer2.
no
82
El funcionamiento total del programa consiste en atender las rutinas cuando los timer
lo indiquen, cada segundo (aproximadamente), el timer principal compara el tiempo
real con cada uno de los tiempos de barrido dados de alta, si ya puede realizarse
uno, se hace uso de los botones antes mencionados y se habilita un segundo timer,
que nos indicará si ya se a realizado una lectura válida en el puerto usb, o lo que es
lo mismo, si el dato de una activación ya se encuentra listo para ser dado de alta.
Después de una activación se realizarán tantas como la base de datos indique.
3.5.2 Diseño modo de conexión con el PLC
La siguiente figura muestra un digrama para explicar el proceso de activación de un
sensor de humedad con el modo de funcionamiento para el PLC.
Figura 3.21 Proceso de activación en el modo de conexión con el PLC.
83
En este modo de operación, al igual que la anterior, se deben de dar de alta los
transductores que formarán el sistema de monitoreo y el tiempo entre cada barrido
de lectura. En la figura 3.22 se muestra la presentación en tiempo de diseño.
Figura 3.22 Programa en vista de diseño.
En la sección superior izquierda se editan, eliminan y agregan transductores, su
forma de operar es la misma que la interfaz anterior, sólo que en esta ya se asignan
las frecuencias de los transductores automáticamente. En la parte superior derecha,
se asigna el tiempo que habrá entre cada barrido de lectura. Para explicar el botón
“cambiar a DB”, se muestra el programa en tiempo de ejecución (figura 3.23).
Figura 3.23 Programa en tiempo de ejecución.
84
Esta presentación muestra los transductores que actualmente están dados de alta en
la base de datos, para poder editar, dar de alta y eliminar transductores hay que
cambiar a la presentación que la figura 3.22 nos muestra, esto se logra oprimiendo el
botón “Cambiar a DB” y esa es su función en la interfaz.
Debido a que la PC ya no estará calculando los datos necesarios para llevar a cabo
las activaciones, ni tampoco revisará el tiempo (tiempo real) en que se deban realizar
los barridos de lectura, estos se calcularán una vez que se oprima el botón “guardar”.
Oprimiendo el botón “enviar”, esta función enviará paquetes de 8 bytes con la
información necesaria para las activaciones y los tiempos de barridos, el método es
el siguiente: en el primer paquete, el primer byte indica cuantos paquetes se enviarán
por el puerto USB, el segundo byte representa la suma de dos número, dónde el
primer número es el número de transductores dados de alta en el sistema, el
segundo número es 5, debido a los bytes de información del protocolo, y los
subsecuentes 3 bytes indican el tiempo de barrido, hacen un total de 5 bytes para el
protocolo de envío, los demás bytes los representan los datos calculados para
generar las activaciones, esta trama de información es necesaria, para que la
transferencia de información se pueda llevar correctamente, sin depender del número
de transductores que el usuario pueda dar de alta en el sistema.
Para explicar mejor el funcionamiento del botón enviar se presenta la figura 3.24, ya
que las demas funciones de los botones son similares al interfaz anterior (conexión
con la PC), excepto que la función del botón “guardar”, calcula automáticamente los
datos necesarios para generar la frecuencia asignada, del transductores recién
ingresados en la base de datos.
La figura 3.24 muestra el papel que toman 2 tipos de buffers, uno es el buffer de
datos con toda la información necesária para las activaciones, y el otro, es un buffer
de transmisión el cual tiene una capacidad de 8 bytes (máximo por cada
transacción), se crea un ciclo en el cual se transfiere 8 bytes del buffer de datos al
buffer de transmisión, una vez llenos se transmiten por el puerto USB, y se repite
85
este proceso hasta terminar con el buffer de datos. El código (en Visual Basic) se
presentará en las páginas de anexo 1.
Botón Enviar
Calcula el número de paquetes y lo envía al buffer
Calcula el número de transductores y lo envía al buffer
Calcula el número de segundos del tiempo de barrido y lo envía al buffer
Primer registro de transductores
Dato del registro actual al buffer
Siguiente registro de transductores
no
Último registro?
si
Buffer al buffer de Transmisión
Siguiente index del buffer de transmisión
no
Salir
Son 8 bytes?
si
Transmitir datos al HID
no
Último dato?
Retardo
si
Siguiente index del buffer
Index del buffer de transmisión = 0
Figura 3.24 Función del botón enviar.
86
3.6 Programación de microcontroladores
En esta sección se mostrará el diseño para realizar las funciones de los bloques
faltantes, mostrados en las figuras 3.13 y 3.21. tales funciones serán realizadas por
los microntroladores, programados en lenguaje ensamblador.
3.6.1 Inicialización de microcontroladores (modo conexión pc)
Desde que se alimenta al PIC16C745 con voltaje, se inicia las configuraciones del
puerto USB así como las condiciones iniciales, hasta llegar a un ciclo de espera de
datos que serán enviados por la PC (sección 3.5.1).
Main
banksel TRISA
;selecciona el banco donde se encuentra TRISA
clrf
TRISC
;todo el puerto como salida
bsf
TRISC,0x07
;configura el puerto serie. RC7 como entrada
bsf
TRISC,0x06
;configura el puerto serie. RC6 como entrada
movlw
0x06
movwf
ADCON1
;puerto A como puerto digital
clrf
TRISA
;puerto A como salida
bsf
TRISA,0x02
;pin 4,RA2 como de entrada
clrf
TRISB
;puerto B como salida
banksel PORTA
;selecciona el banco donde se encuentra PORTA
clrf
PORTA
;pone la salida del puerto A puros ceros
clrf
PORTB
;pone la salida del puerto B puros ceros
movlw
.30
;retardo para esperar el reset de USB
movwf
W_save
decfsz
W_save,f
goto
$-1
banksel OPTION_REG
bcf
OPTION_REG,NOT_RBPU ;quita pull ups en el puerto B
pagesel InitUSB
call
InitUSB
;función para inicializar los registros de USB
ConfiguredUSB
;macro para enmascarar las configuraciones de USB
call
inicializar
;inicialización de variables
call
ini_tx
;modo tx=on rx=off del puerto serie síncrono
LoopForData
;bucle para saber si ya se encuentran datos en la RX USB
Pagesel GetEP1
banksel outbuffer
movlw
outbuffer
;dirección de la pila donde la función GetEP1 pondrá los
movwf
FSR
;los datos que mandaron por el Puerto USB.
call
GetEP1
;rutina para obtener los datos del enpoint0
pagesel tonos
btfss
STATUS,C
;por medio del carry la funcion GETEP1
goto
LoopForData
;me indica si hay datos
Figura 3.25 Código para la inicialización del puerto USB y configuraciones de puertos.
87
En el PIC16F628, se inicia la configuración del puerto serie síncrono así como las
condiciones iniciales (figura 3.26), después entra en un ciclo ocioso en la espera de
una clave por parte del PIC16C745.
Inicio
bcf
pie1,TXIE
bcf
estado,RP0
bcf
pir1,RCIF
ciclo
bcf
pir1,TXIF
movlw
0xAA
serial
movwf
clave1
bsf
estado,RP0
movlw
0xBB
movlw
b'00010000'
movwf
clave2
movwf txsta
movlw
0xCC
bcf
estado,RP0
movwf
clave3
movlw
b'10010000'
clrf
porta
movwf
rcsta
movlw
0x07
return
movwf
cmcon
clrf
w
inicial
movlw
0x01
bsf
estado,RP0
movwf
f
movlw
b'00100111'
movwf
cont
movwf
trisb
movlw
0x30
clrf
trisa
movwf
fsr
bsf
trisa,0x05
movlw
0x04
movlw
b'11001000'
movwf
var1
movwf
opcion
clrf
overflow
movlw
b'11000000'
clrf
portb
movwf
intcon
bcf
portb,0x03
bsf
pie1,RCIE
return
Figura 3.26 Configuración del puerto serie síncrono e inicializaciones.
call
call
goto
inicial
serial
ciclo
3.6.2 Inicialización de microcontroladores (modo conexión plc)
La inicialización para el PIC16C745 en este modo conexión es el mismo que el
anterior modo de conexión.
En el PIC16F628, se empieza con la configuración del puerto serie, se preparan las
condiciones iniciales y después entra a un ciclo en espera de datos, que serán
enviados por el puerto serie síncrono (figura 3.27).
A diferencia del anterior modo de conexión, éste presenta cambios en las
configuraciones de los puertos digitales y variables.
88
Inicio
bsf
pie1,RCIE
bcf
pie1,TXIE
bcf
estado,RP0
ciclo
bcf
pir1,RCIF
bcf
pir1,TXIF
clrf
porta
serial
movlw
0x07
bsf
estado,RP0
movwf
cmcon
movlw
b'00010000'
clrf
w
movwf
txsta
movlw
0x01
bcf
estado,RP0
Movwf
f
movlw
b'10010000'
movlw
0x30
movwf rcsta
movwf
fsr
return
movlw
0x1F
movwf
var2
inicial
clrf
overflow1
bsf
estado,RP0
clrf
overflow2
movlw
b'00000110'
clrf
aux1
movwf
trisb
clrf
aux2
clrf
trisa
clrf
aux3
movlw
b'11001000'
clrf
portb
movwf
opcion
bsf
portb,0x03
movlw
b'11000000'
clrf
trans
movwf
intcon
incf
trans,f
return
Figura 3.27 Rutina para la configuración del puerto serie síncrono e inicializaciones.
call
call
goto
inicial
serial
ciclo
En el PIC16F873, se inician las configuraciones de puertos así como las variables,
para luego entrar a un ciclo ocioso (independiende del modo de conexión).
Inicio
bsf
movlw
movwf
movlw
movwf
clrf
clrf
bsf
clrf
bsf
bcf
movlw
movwf
movwf
estado,RP0
b'11001111'
opcion
b'10001110'
adcon1
pie1
trisb
trisb,0x00
trisa
trisa,0x00
estado,RP0
0x01
f
cont
clrf
movlw
movwf
clrf
clrf
clrf
clrf
clrf
clrf
movlw
movwf
movlw
movwf
movlw
movwf
w
b'11010000'
intcon
adcon0
porta
portb
overf
sobra
veces
0xF9
cte
0x14
vuelta
0x05
palta
ciclo
goto
Servicio
btfss
goto
decf
btfss
goto
clrf
bcf
goto
ciclo
intcon,INTF
Tmr0int
cont,f
estado,Z
Puerto
tmr0
intcon,INTF
Atajo
Tmr0int
btfss
retfie
incf
intcon,TOIF
overf,f
Atajo
bcf
intcon,TOIF
bsf
intcon,TOIE
retfie
Figura 3.28 Rutina para inicialización de variables, configuración de puerto y RSI (PIC16F873).
89
Como la interrupción externa se encuentra habilitada, el ruido que entrega la etapa
de adecuación (figura 3.43) interrumpe en cada momento, obligando al programa del
PIC a saltar a la RSI (etiqueta servicio de interrupción), y a su vez entrar a la función
de detección de frecuencia válida (sección 3.6.7).
Hasta esta sección, se puede transmitir los datos desde la PC hacia los
microcontroladores y éstos están configurados para recibirla. Ahora se mostrarán los
diseños de los procesos que dependen de los datos transmitidos por la PC.
3.6.3 Generador de señales de activación (modo conexión pc)
El microcontrolador PIC16C745 se encargará de realizar esta función, haciendo
variar el estado lógico de un PIN a través de una función en lenguaje ensamblador
(figura 3.29), en la cual se le deben de ingresar 6 números en los registros y así crear
el retardo del semiperiodo, esto es, decrementando el valor de los 6 registros tanto
para el tiempo en alto como para el tiempo en bajo.
Tonos
bsf
lo
banksel
movf
movwf
movwf
movf
movwf
movwf
movf
movwf
movwf
movf
movwf
movwf
movf
movwf
movwf
movf
movwf
movwf
banksel
outbuffer
outbuffer,w
over
lower
outbuffer+1,w
over1
lower1
outbuffer+2,w
over2
lower2
outbuffer+3,w
over3
lower3
outbuffer+4,w
over4
lower4
outbuffer+5,w
over5
lower5
PORTA
ok decf
btfss
goto
ok1 decf
btfss
goto
ok2 decf
btfss
goto
ok3 decf
btfss
goto
ok4 decf
btfss
goto
ok5 decf
btfss
goto
PORTA,00h
over,f
STATUS,2
ok
over1,f
STATUS,2
ok1
over2,f
STATUS,2
ok2
over3,f
STATUS,2
ok3
over4,f
STATUS,2
ok4
over5,f
STATUS,2
ok5
bcf
o
o1
o2
o3
o4
o5
btfss
PORTA,00h
decf
lower,f
btfss STATUS,2
goto
o
decf
lower1,f
btfss STATUS,2
goto
o1
decf
lower2,f
btfss STATUS,2
goto
o2
decf
lower3,f
btfss STATUS,2
goto
o3
decf
lower4,f
btfss STATUS,2
goto
o4
decf
lower5,f
btfss STATUS,2
goto
o5
decf
periodos,f
STATUS,2
goto
lo
return
Figura 3.29 Rutina para el generador de frecuencia o señales de activación.
90
Estos registros son rellenados con los datos recibidos por el puerto USB, y que a su
vez fuerón enviados por el programa residente en PC. Poniendo a prueba esta
función se generó la tabla 3.1.
Tabla 3.1 Caracterización para el generador de frecuencia.
registro1 registro2
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
Registros
registro3 registro4 registro5 registro6
1
1
1
125
1
1
1
150
1
1
1
175
1
1
1
200
1
1
1
225
1
1
1
250
1
1
1
255
1
1
25
255
1
1
50
255
1
1
75
255
1
1
100
255
1
1
125
255
1
1
150
255
1
1
175
255
1
1
200
255
1
1
223
255
1
1
225
255
1
1
239
255
1
1
250
255
1
1
255
255
1
2
255
255
1
21
255
255
1
25
255
255
1
40
255
255
1
50
255
255
1
62
255
255
1
75
255
255
1
85
255
255
1
100
255
255
1
110
255
255
1
125
255
255
1
137
255
255
1
150
255
255
1
167
255
255
1
175
255
255
1
199
255
255
1
200
255
255
1
225
255
255
1
234
255
255
Frecuencia
(Khz)
5.6817
4.777
4.1208
3.6231
3.2327
2.9182
2.8625
2.6223
2.4115
2.2321
2.0775
1.9429
1.8248
1.7201
1.6268
1.55
1.5432
1.5
1.4677
1.4534
1.45
1.4
1.3888
1.35
1.3274
1.3
1.2712
1.25
1.2195
1.2
1.1718
1.15
1.1278
1.1
1.0869
1.05
1.0489
1.0535
1
Número
125
150
175
200
225
250
255
280
305
330
355
380
405
430
455
479
480
495
505
510
512
531
535
550
560
572
585
595
610
620
635
647
660
677
685
709
710
735
744
91
En la tabla 3.1, los registros con el número 1 dentro significan un cero en la función
de ensamblador, esto es debido a que los retardos son generados con decrementos
y aunque el número 1 es un valor mínimo, este genera ilapsos de tiempo (tiempo que
no son tomados en cuenta por el programa) en los semiperiodos.
La columna “número” es el resultado de la suma de los 6 registros representando el
retardo del semiperiodo. Y la columna “‘frecuencia” representa la frecuencia que se
generó con dicho retardo. Graficando la columna frecuencia contra la columna
número se obtiene la figura 3.30.
Figura 3.30 Gráfica de la tabla 3.1
Se puede ver claramente que la función no es lineal, debido a que los ilapsos son
diferentes para cada frecuencia a generar, este problema se resuelve con una
ecuación de sexto orden; con esto, es posible obtener un número y se podrá generar
la frecuencia deseada con un mínimo de error. Con la ayuda del programa MATLAB
se consigue la ecuación.
92
Introduciendo los datos y con la función polyfit se obtiene la siguiente ecuación:
Y = 1.01983321076x6 - 21.76684340806x5 + 189.46208279318x4 867.57740836853x3 + 2246.43786488113x2 - 3275.43053009874x +
2474.90135900252
Siendo X la frecuencia generar en Khz y Y el número necesario para generarla.
Graficando esta ecuación, da como resultado la línea que muestra la figura 3.30.
Figura 3.31 Comparación de la ecuación obtenida y los datos de la tabla 3.1.
La figura 3.31 nos muestra, que la ecuación nos ayudará a generar la frecuencia
deseada con un error mínimo. Los asteriscos representan los datos de la tabla 3.1 y
la línea continua representa la ecuación obtenida.
93
3.6.4 Generador de señales de activación (modo conexión plc)
En este modo de funcionamiento, el generador de señales se encuentra en el
PIC16F628. Para generar las frecuencias de activación se utiliza el mismo método
(mencionado en la sección anterior), sólo que este PIC utiliza un cristal de 8 Mhz. y la
rutina para generar la frecuencia se realizó de forma diferente, es por eso, que en
esta rutina (figura 3.32) se utilizó solo un registro para el retardo del semiperiodo, y
en consecuencia, se necesitó caracterizar de nuevo, obteniendo los resultados de la
tabla 3.2 y la figura 3.33, en la tabla 3.2 la variable número representa el valor que
debe de contener el registro para el retardo del semiperiodo en la rutina de la figura
3.32, por lo que dicho número genera su correspondiente frecuencia.
Periodo
call TONO
decf aux3,f
;decrementar no. de veces
; de periodos
btfss estado,Z ;checar si ya acabo en no.
;de periodos
goto Periodo
TONO
bsf
call
bcf
call
return
portb,0x07
RETARDO
portb,0x07
RETARDO
RETARDO
movf
ret,w ;número con el retardo
movwf var1
;del semiperiodo
Bucle2
decf
var1,f
btfss
estado,Z
goto
Bucle2
return
;estado en alto
;retardo del semiperiodo
;estado en bajo
;retardo del semiperiodo
Figura 3.32 Rutina para el generador de señales.
Tabla 3.2 Caracterización para el generador de frecuencia.
Número
Frecuencia
Número
Frecuencia
249
239
229
219
209
199
189
179
169
159
149
145
139
0,994
1,035
1,08
1,128
1,182
1,24
1,305
1,377
1,457
1,548
1,65
1,607
1,767
129
119
109
99
89
79
69
59
49
48
47
46
45
1,901
2,057
2,242
2,463
2,732
3,067
3,496
4,065
4,854
4,95
5,051
5,155
5,263
94
Con los datos de la tabla 3.2 se obtiene la siguiente gráfica:
Figura 3.33 Caracterización del generador de señales de activación.
Al igual que la otra función de ensamblador para generar las señales de activación
(mencionado en la sección anterior), se observa en la figura 3.33 que no es una
función lineal, por lo que se utilizó el mismo método para resolverlo.
En MATLAB se obtiene la siguiente ecuación:
Y = 0.29124078463x6 - 6.32150481492x5 + 56.25953631003x4 - 264.41332239284x3
+703.60080448892x2 - 1051.76677189924x + 809.77563804734
Al graficar los datos de la tabla 3.2 y la ecuación obtenida (figura 3.34), se puede
apreciar el acercamiento del resultado de la ecuación con los datos originales de la
tabla.
95
Figura 3.34 Comparación de la ecuación y los datos de la tabla 3.2.
Donde los puntos nos indica la matriz de datos originales y la línea continua es lo que
la ecuación genera, indicándonos que al generar las señales de activación tendrán
un mínimo de error.
A continuación se explicará el diseño de las rutinas que atenderan la recepción de
datos hasta la generación de señales de activación. Hay que recordar que
explicamos hasta la inicialización de microcontroladores y hay un hueco entre esta
sección y la generación de señales de activación.
3.6.5 Recepción de datos y claves de conmutación (modo conexión pc)
Una vez que llegaron los datos al PIC16C745 por el puerto USB, éste tiene que
informar al PIC16F628 que tiene que encender el transmisor, esto es, para poder
transmitir la frecuencia de activación. Esto se realiza transmitiendo por el puerto serie
96
síncrono una clave que el PIC16F628 lo interpretará como encendido de la etapa del
transmisor (figura 3.35).
Figura 3.35 Clave1 (arriba línea de dato, abajo línea de reloj).
Después de transmitir esa clave, entra en una etapa de retardo (0.5 seg.), este
retardo fue necesario debido a que la velocidad de los PICS es alta y al ejecutar la
siguiente instrucción el transmisor no se encuentra encendido totalmente, esto se
sabe a simple vista ya que la fuente de voltaje con la que se alimenta el módulo,
tiene una aguja que indica la corriente o el consumo del módulo maestro, y esta
aguja no llega a deflexionarse totalmente.
Este retardo se calculó a prueba y error con la ayuda de un LED (figura 3.36) y
viendo la deflexión de la aguja. Se fue aumentando el tiempo de este retardo hasta
cuando se observara lo siguiente: Para cuando se encendía el LED, la aguja ya
debería estar deflexionada totalmente, por lo que el encendido del LED indicaba el fin
del retardo.
Figura 3.36 Led indicador.
97
Después del retardo se genera la señal de activación (explicado en la sección 3.6.3),
al terminar éste, se transmite nuevamente por el puerto serie síncrono otra clave
(figura 3.37) para el PIC16F628, ya que con esto, se logra apagar la etapa del
transmisor. Más tarde, entra a un ciclo dónde checa el estado de un PIN de control,
en el cual el PIC16F628 le indica al PIC16C745 que está listo para enviarle los datos
de humedad por medio del puerto serie síncrono.
Figura 3.37 Clave2 (arriba línea de dato, abajo línea de reloj).
Mientras en el PIC16F628, la clave1 es recibida por medio del puerto serie síncrono,
cuando la recepción de la clave se completa, se produce una interrupción que lo
saca del ciclo ocioso y entra en el RSI (rutina de servicio de interrupción), allí
identifica que interrupción se efectuó, y en el caso de las claves salta a la
interrupción serie (figura 3.38), después verifica el tipo de clave que recibió. Si es la
clave1 el PIC16F628 enciende la etapa del transmisor poniendo en estado alto un
PIN de control.
recep_rx
btfss
retfie
movf
subwf
btfss
goto
bsf
retfie
mm
pir1,RCIF
rcreg,w
clave1,w
estado,2
mm
portb,0x06
movf
subwf
btfss
Retfie
bcf
call
bcf
btfss
goto
bsf
Retfie
rcreg,w
clave2,w
estado,2
portb,0x06
delay
rcsta,CREN
portb,0x05
tt
intcon,INTE
Figura 3.38 Rutina de interrupción serie síncrona.
98
Si es la clave2 apaga la etapa del transmisor poniendo en estado bajo, el PIN de
control antes mencionado, y después entra a un retardo (0.87 seg.). Este retardo fue
necesario debido a que la velocidad del PIC es alta y el transmisor no se encuentra
apagado totalmente cuando entra a la siguiente función, además tiene que esperar a
que el módulo esclavo le envíe los datos de humedad. Este retardo se calculó a
prueba y error con la ayuda de un LED (figura 3.39) y observando el osciloscopio. La
punta del osciloscopio se conecta en el PIN dónde el PIC recibe la señal por parte de
la etapa de adecuación, y se debe de observar que el LED debe de encender cuando
en el osciloscopio se obtiene la señal de dato y se encuentre estable, por lo que el
encendido del LED indica el fin del retardo.
Figura 3.39 Led indicador para cálculo de retardo.
3.6.6 Recepción y apilamiento de datos en ram (modo conexión plc)
Una vez lleguen los datos en el PIC16C745 por parte de la PC (sección 3.5.2), se
verifica si es el primer paquete de 8 bytes enviados (figura 3.40), si es el caso, el
primer byte indica el número de paquetes que se enviarán por el puerto, es por eso
que se pasa a una función llamada “ndatos” para obtener ese byte y después se
pasa el paquete a memoria RAM. Si no es el primer paquete, pasa directamente a
almacenar los datos a la memoria RAM.
Después de esos casos, verifica si ya se recibieron todos los paquetes, si no es el
caso entra al ciclo en espera de datos, si es el caso, se transmiten todos los datos
por el puerto serie síncrono hacia el PIC16F628.
99
bcf
btfss
call
call
decf
btfss
goto
call
goto
STATUS,C
aux6,0x00
ndatos
buffer_ram
aux7,f
STATUS,2
EndLoopForData
ram_serial
EndLoopForData
buffer_ram
ram_serial
clrf
aux1
movlw
0x41
movlw
0x08
movwf
FSR
movwf
aux
movf
INDF,w
dat1
movwf
aux
movlw
outbuffer
decf
FSR,f
movwf
FSR
dat2
movf
aux1,w
movf
INDF,w
addwf
FSR,f
movwf
TXREG
movf
INDF,w
incf
FSR,f
ndatos
movwf
aux2
decf
aux,f
banksel outbuffer
movlw
0x40
btfsc
STATUS,2
movlw
outbuffer
movwf FSR
return
movwf
FSR
movf
aux3,w
Movlw
.100
movf
INDF,w
addwf
FSR,f
movwf
W_save
movwf
aux7
movf
aux2,w
decfsz
W_save,f
movwf
aux5
movwf
INDF
goto
$-1
bsf
aux6,0x00
incf
aux1,f
goto
dat2
return
incf
aux3,f
return
decf
aux,f
btfss
STATUS,2
goto
dat1
return
Figura 3.40 Rutina para la recepción y transmisión de datos.
El PIC16F628 recibe los datos por el puerto serie síncrono, y clasifica esta
información obteniendo el número de transductores del sistema y el tiempo de
barrido para el temporizador, los demás datos son apilados en memoria RAM para
después habilitar la interrupción del TMR0 (figura 3.41).
recep_rx
btfss
retfie
movf
movwf
incf
btfss
goto
movf
movwf
movwf
decf
decf
ok
datos
incf
fsr,f
movlw
0x31
btfss
pir1,RCIF
movwf
fsr
rcreg,w
goto
$-1
movf
INDF,w
INDF
movf
rcreg,w
movwf
frec
fsr,f
movwf INDF
movlw
0x05
pir1,RCIF
decf
var1,f
subwf
frec,f
$-1
btfsc
estado,Z
incf
fsr,f
rcreg,w
goto
algo
movf
INDF,w
INDF
goto ok
movwf
seg
var1
algo
incf
fsr,f
var1,f
call
datos
movf
INDF,w
var1,f
bcf
rcsta,CREN
movwf min
bcf
intcon,TOIF
incf
fsr,f
clrf
tmr0
movf
INDF,w
bsf
intcon,TOIE
movwf
hor
bcf
portb,0x03
return
retfie
Figura 3.41 Rutina para la recepción serie síncrona de datos y su clasificación.
pir1,RCIF
100
Cada vez que se desborde este contador (TMR0), se incrementan variables que
representa el tiempo de un segundo, al llegar a este tiempo, se incrementa el
temporizador y se verifica si es igual al tiempo de barrido (el tiempo de barrido se
encuentra dentro de los datos de información, que se recibieron por el puerto serie
síncrono), si no son iguales, se regresa al ciclo ocioso. Si son iguales, se encuentra
la frecuencia a generar dentro de los datos de información y se enciende el
transmisor, para luego entrar a un retardo (0.097 seg) este retardo fue necesario
para que el transmisor encendiera completamente. Después se genera la señal de
activación (sección 3.6.4) y luego se envía a otro retardo (0.87 seg.). Este retardo se
utiliza para la espera de datos que el módulo esclavo nos enviará vía RF.
Servicio
btfss
goto
btfss
retfie
bcf
incf
btfss
retfie
incf
movf
subwf
btfss
retfie
clrf
incf
btfsc
incf
btfsc
incf
movf
subwf
btfss
retfie
intcon,TOIE
recep_rx
intcon,TOIF
intcon,TOIF
overflow1,f
estado,Z
overflow2,f
var2,w
overflow2,w
estado,Z
overflow2
aux1,f
estado,Z
aux2,f
estado,Z
aux3,f
seg,w
aux1,w
estado,Z
movf
subwf
btfss
retfie
movf
subwf
btfss
retfie
clrf
movlw
movwf
movf
movwf
bsf
cambio
bsf
call
movlw
movwf
incf
movf
movwf
min,w
aux2,w
estado,Z
hor,w
aux3,w
estado,Z
aux1
0x34
fsr
frec,w
cnt
portb,0x04
portb,0x06
delay
0xFF
aux3
fsr,f
INDF,w
ret
nperiodos
call
decf
btfss
goto
bcf
call
bcf
rlf
movwf
incf
call
clrf
decf
btfss
goto
clrf
clrf
bcf
clrf
incf
retfie
TONO
aux3,f
estado,Z
nperiodos
portb,0x06
delay2
estado,C
trans,w
porta
trans,f
delay2
porta
cnt,f
estado,Z
cambio
aux2
aux3
portb,0x04
trans
trans,f
Figura 3.42 Rutina para el temporizador.
Para calcular el número de incrementos que el contador TMR0 debe realizar en un
segundo, se realizó a prueba y error con la ayuda de un LED que se encendía y
apagaba, verificando visualmente que la duración del encendido y el apagado fueran
de un segundo.
101
Con esto se logró que el temporizador se incrementará cada segundo, y en cada
incremento se verificará con el tiempo de barrido que el usuario programó. Todo el
funcionamiento del temporizador es realizado por la rutina que la figura 3. muestra.
Después de este retardo se manda por medio de cuatro pines el número del
transductor que se activo (figura 3.11), el PLC deberá interpretar esto como un
control y que debe de medir la frecuencia.
Hasta esta sección, se a diseñado los procesos de transmisión de datos desde la PC
hasta generar el tono de activación en ambos modos de conexión, a continuación se
presentará el diseño de los procesos realizados por el módulo esclavo (PIC16F873),
y que son independiente del modo de conexión.
3.6.7 Detector de frecuencia válida
Como su nombre lo indica, esta función se encarga de detectar una frecuencia
válida. Es necesaria debido a que en el ambiente se encuentran señales portadoras
que coinciden tener una señal moduladora a la frecuencia de activación (figura 3.43).
Sin esto, haría que el módulo esclavo se active sin ser realmente activado por el
módulo maestro, también es necesario debido, a que todos los módulos esclavos
tanto como el maestro utilizarán una señal portadora de 81 Mhz, lo que significa, que
a todos los módulos le estarán llegando las señales de activación, pero sólo uno se
activará debido a que cada módulo esclavo está programado para activarse con una
señal moduladora diferente.
Figura 3.43 Ruido presente en estado de reposo (osciloscopio y acercamiento).
102
Si la señal de dato de humedad, de un módulo esclavo activado, llegará a generar
una frecuencia exactamente igual a la señal de activación de algún otro módulo
esclavo, para cuando éste último se active, el módulo maestro ya habrá capturado el
dato y no creará conflicto en el sistema.
Para realizar todas estas funciones se midió el tiempo del periodo de la señal, esto
es posible detectando los filos de la frecuencia de la señal a medir, una vez medido
el periodo, se determina si se encuentra dentro de un rango de error, si lo está, se
incrementa un contador, si no, el contador toma el valor de cero.
Con cada incremento del contador verifica si ya llegó a 5 comparaciones positivas, si
es el caso, significa que la frecuencia de activación es válida. Cuando no se cumple
ese número de veces, significa que el ruido coincidió con la frecuencia de activación,
pero no se mantuvo un tiempo requerido para identificarla como señal válida.
Los umbrales de frecuencia, significan el rango de frecuencias a la que el módulo
esclavo se activará o también se le puede llamar rango de error, esto es necesario
debido a que en el ambiente es muy difícil de predecir que la señal moduladora no
sufrirá cambios de frecuencia en el trayecto o transmisión. Los umbrales de
frecuencia se calculan de la siguiente manera:
Por ejemplo: para validar la frecuencia de activación de 1 Khz se calcula los tiempos
para las frecuencias superior e inferior con un rango de error de 10 Hz. arriba y
debajo de la frecuencia que se pretende activar. 990 Hz. y 1010 Hz. dan 0.00101
seg. y 9.900099 seg. respectivamente.
Ahora, es necesario saber hasta qué número tiene que contar el temporizador del
PIC para detectar si la frecuencia medida esta en el rango de error. Este número
depende de la frecuencia del cristal, y el PIC cuenta con uno de 8 Mhz. cada cambio
en la cuenta del temporizador depende de 4 ciclos del cristal y la forma en que se
encuentre configurado un prescalador y en algunos casos un postescalador.
103
Velocidad de cambio en el temporizador =
Tiempo de cambio del temporizador =
1)Umbral Inferior =
8Mhz
= 2Mhz.
4
1
= 500 Nanosegundos
2 Mhz.
.00101
2020
= 2020.2 conteos è
= 7.9235 conteos
5E - 7
255
(7.9235-7)x255 = 235.2
2)Umbral Superior =
9.900099
1980
= 1980.18 conteos è
= 7.7654 conteos
5E - 7
255
(7.7654-7)x255 = 195.18
La medición de frecuencia da como resultado dos números, uno significa los
sobreflujos del temporizador y el otro hasta donde alcanzó el temporizador a contar
antes de generarse el fin del periodo, es obvio que se debe comparar si el sobreflujo
medido es igual a 7 y el otro número, si está entre los números 195 y 235, las cuales
definen el rango de error.
3.6.8 Generador de señal de dato
El objetivo es convertir el voltaje del transductor a su correspondiente frecuencia que
representará el dato de humedad, esto se realiza por medio del ADC interno del
microcontrolador, el voltaje es convertido a un dato de 10 bits, y a su vez, esos 10
bits son convertidos a otro dato, que es necesario para generar la respectiva señal
de dato o frecuencia.
Primero se realizó una función en ensamblador (figura 3.44) para generar el ancho
de banda en la que se transmitirá el dato de humedad. Hay que recordar que el
sistema de RF trabaja de 1 a 5 Khz, de esta función obtuvimos el resultado que
muestra la tabla 3.3.
104
nperiodos
call
decf
btfss
goto
decf
btfss
goto
TONO
bsf
call
bcf
call
return
RETARDO
TONO
vuelta2,f
estado,Z
nperiodos
vuelta,f
estado,Z
Hola
movf
sobra,w
movwf cont
Bucle2
decf
cont,f
btfss
estado,Z
goto
Bucle2
Return
porta,0x01
RETARDO
porta,0x01
RETARDO
Figura 3.44 Rutina para el generador de datos o frecuencia.
Tabla 3.3 Caracterización del generador de datos.
Número
Frecuencia (Khz)
249
246
205
184
165
145
1
1.089
1.204
1.319
1.457
1.607
Número
Frecuencia (Khz)
123
105
85
64
44
1.845
2.164
2.732
3.594
4.854
El ADC interno del PIC tiene una resolución de 10 bits, lo que significa que
tendremos:
210 = 1024 cambios
5
= 0.004882 volts por cada cambio.
1024
Para cero volts necesitamos generar una frecuencia de 1Khz y observamos que en la
tabla 3.4 el número 249 logra generarlo, esto significa que debemos convertir el
número cero que nos entregará el ADC al número 249 para generar esa frecuencia,
pero también, para 5 volts el ADC nos entregará el número 1023, según la tabla 3.4
necesitamos convertir este número al número 44.
Para el caso de cero volts se resuelve restando al número 249 el número que
entrega el ADC, pero para el caso de 5 volts no funcionará, así que, se necesita
105
convertir primero el número 1023 a un número que si le restamos 249 nos pueda dar
como resultado el 44 que deseamos. La operación que nos acerca a este número es
dividir el número que nos entrega el ADC entre 5.
ADC
Cálculo 1
con 0 volts obtenemos el No. 0
=>
con 5 volts obtenemos el No. 1023 =>
0
= 0
5
Cálculo 2
=>
249 – 0 = 249
1023
= 204.6 => 249 – 204.6 = 44.4
5
Figura 3.45 Cálculo del número necesario para generar la frecuencia de dato.
Aplicando estos cálculos se obtiene una pérdida de resolución, debido a que sólo se
toma la parte entera del cálculo y esto ocasiona que genere la misma frecuencia
cada 4 cambios de conversión del ADC, obteniendo como resultado lo siguiente:
Tabla 3.4 Adecuación ADC.
Volts
0
0.053757
1.060479
1.568727
2.037879
2.54124
3.064149
3.513753
4.002453
4.500927
4.999401
ADC
0
11
217
321
417
520
627
719
819
921
1023
ADC/5
0
2.2
43.4
64.2
83.4
104
125.4
143.8
163.8
184.2
102.3
249-(ADC/5)
249
246.8
205.6
184.8
165.6
145
123.6
105.2
85.2
64.8
204.6
Frecuencia (Khz)
1
1.089
1.204
1.319
1.457
1.607
1.845
2.164
2.732
3.594
4.854
Desde que alimenta al PIC16F873, se encuentra rechazando el ruido por medio de la
proceso “detector de frecuencia valida”. En este proceso, detecta los flancos de
subida, y si es el primero se inicia el contador con el TMR0 y regresa al ciclo ocioso,
si es el segundo, se determina si la muestra está dentro del rango de error (figura
3.46), en caso de que no esté, se inicializa a cero el número de muestras y se
106
aplican las condiciones iniciales 1, esto es, colocar valores a las variables que
permitan las subsecuentes muestras, de allí se regresa al ciclo ocioso.
Puerto
Ruido
movf
tmr0,w
;tmr0 a w
clrf
porta
movwf cont
;w a cont
Salir
movlw 0x07
;7 a w
clrf
w
subwf
overf,w
;f-w
overf-7
clrf
overf
btfss
estado,Z ;z=1?
clrf
sobra
goto
Noes
clrf
veces
movlw
0xE4
;228 a w
movlw 0x01
subwf
cont,w
;f-w
cont-228
movwf cont
btfsc
estado,C ;c=0? cont<228
movlw 0xF9
goto
Noes
movwf cte
movlw
0xBC
;188 a w
movlw 0x14
subwf
cont,w
;f-w
cont-188
movwf vuelta
btfss
estado,C ;c=1? cont>188
bcf
intcon,TOIF
goto
Noes
bcf
intcon,TOIE
decf
palta,f
bcf
intcon,INTF
btfss
estado,Z ;z=1?
bsf
intcon,INTE
goto
Ruido
retfie
Noes
movlw 0x05
movwf palta
Figura 3.46 Rutina para determinar el rango de error de la muestra de frecuencia.
Si se encuentra dentro del rango de error, se incrementa el número de muestras y se
verifica que ya se hayan realizado 4 de ellas, en caso negativo, se aplican las
condiciones iniciales 1 antes mencionadas y regresa al ciclo ocioso, en caso positivo,
se prepara el ADC (figura 3.47) e inicia la conversión (ver sección 3.6.8).
La conversión consiste en obtener la muestra de humedad en forma de voltaje, se
logra encendiendo la etapa “circuito del transductor” (ver figura 3.8 en la sección 3.2)
dejando en estado alto un PIN de control.
Después se deja un retardo para que la etapa antes mencionada se encienda
totalmente. El valor de este retardo es desconocido, debido a que este circuito se
encuenta en desarrollo todavía (tesis en desarrollo de Jesús Francisco Camou
Orduño). Después el ADC obtiene la información de voltaje.
107
bsf
bcf
bcf
call
bsf
call
porta,0x05
;enciendo oscilador
intcon,INTE
intcon,TOIE
DELAY
adcon0,ADON
DELAY
bsf
adcon0,GODONE
Per
Chk
movlw
movwf
0xFF
vuelta2
movlw
0x0A
subwf
btfss
goto
incf
goto
pbaja,f
estado,C
Alta
veces,f
Resta
DIV
Resta
btfss pir1,ADIF
goto Chk
Alta
bcf
pir1,ADIF
addwf
pbaja,w
bcf
porta,0x05
addwf
sobra,f
bsf
porta,0x02
movlw
0x01
call
DELAY
subwf
palta,f
movf adresh,w
btfss
estado,C
movwf palta
return
bsf
estado,RP0
movlw
0xFF
movf adresl,w
movwf
pbaja
bcf
estado,RP0
goto
DIV
movwf pbaja
call
DIV
CALC
movf sobra,w
bcf
estado,C
movwf pbaja
rlf
veces,f
clrf
palta
movf
veces,w
call
DIV
subwf
cte,w
call
CALC
return
movwf sobra
Figura 3.47 Rutina para la adquisición de dato y proceso de cálculo.
Una vez se tenga esta información, se apaga la etapa “circuito del transductor” y se
enciende el transmisor, después de eso, la información es enviada a un proceso de
cálculo (figura 3.36), para poder generar la señal de dato. Terminado el cálculo se
genera dicha señal de dato (explicado en la sección 3.6.8), se aplican las
condiciones iniciales 2 y regresa al ciclo ocioso. Las condiciones iniciales 2 son las
condiciones y valores de las variables que permitirán las subsecuentes activaciones.
Hasta esta sección se concluye con el diseño de los procesos realizados por el
módulo esclavo (PIC16F873), también se finalizó el diseño de los procesos para el
módulo maestro, en el caso donde el modo de conexión es con el PLC, debido a que
faltaba diseñar los procesos del módulo esclavo, y a que el PLC se encargará de
adquirir los datos de humedad generados en esta sección. En la sección siguiente
mostraremos los procesos del módulo maestro faltantes, para finalizar con el proseso
general de activación de transductores.
108
3.6.9 Medición de frecuencia
El módulo esclavo devuelve una frecuencia que representa el dato de humedad. es
necesario medir esta frecuencia y sea enviada al software de la PC, para ser
interpretada como una cantidad de humedad. Cabe mencionar que esta rutina (figura
3.48) sólo se presenta en el modo de funcionamiento donde el módulo maestro
estará conectado con la PC. y la realiza el PIC16F628.
Servicio
btfss
goto
decf
btfss
goto
clrf
bcf
bcf
bsf
retfie
Tmr0int
btfss
goto
btfss
retfie
incf
bcf
retfie
muestra
movf
movwf
movlw
subwf
movwf
incf
movf
movwf
incf
clrf
clrf
incf
bcf
bcf
bcf
decf
btfss
retfie
movlw
movwf
intcon,INTF
Tmr0int
cont,f
estado,Z
muestra
tmr0
intcon,INTF
intcon,TOIF
intcon,TOIE
intcon,TOIE
recep_rx
intcon,TOIF
overflow,f
intcon,TOIF
tmr0,w
resta
0x0C
resta,w
INDF
fsr,f
overflow,w
INDF
fsr,f
overflow
cont
cont,f
intcon,TOIF
intcon,TOIE
intcon,INTF
var1,f
estado,Z
0x04
var1
;<checa si la interrupcion es externa>
;<no es ext.>
;dec. contador
;esta la Z=1?
;<termino un periodo>
;borra el TMR0
;bandera de int. ext. a 0
;bandera de overf a 0
;habilita int. de overf TMR0
;esta hab. la int. del TMR0?
;no es int. TMR0
;<checa si la interrupcion es de overf del TMR0>
;no es int. TMR0
;incremento el contador de sobreflujos
;bandera de overf a 0
;resguardo el valor del TMR0
;preparo la resta de los ilapsos
;ocasionados por el número de códigos
;que se ejecutan, desde que se ocasiona
;la interrupción. <guardo sobra en RAM>
;apunto a la siguiente dirección RAM
;<guardo overflow en RAM>
;apunto a la siguiente dirección RAM
;<cond. para otra muestra>
;<cont=1 y overflow=0>
;bandera de overf a 0
;deshabilita int. de overf TMR0
;deshabilita int. de overf TMR0
;bandera de int. ext. a 0
;<¿ya son 4 muestras?>
;<condiciones para otras 4 muestras>
;<var1 = 4>
Figura 3.48 Rutina para el medidor de frecuencia.
109
Esta medición se llevó acabo por medio de una función en ensamblador (figura 3.48),
que mide el periodo de la señal, esto es posible detectando los flancos de subida de
la frecuencia a medir, como la medición de frecuencia no es lineal (ver tabla 3.5), la
relación se realiza con el voltaje.
Tabla 3.5 Caracterización del medidor de frecuencia.
Voltaje
0.1
0.2
0.3
0.4
0.5
0.6
0.7
0.8
0.9
1
1.1
1.2
1.3
1.4
1.5
1.6
1.7
1.8
1.9
2
2.1
2.2
2.3
2.4
2.5
2.6
Frecuencia (Khz)
1.002
1.018
1.035
1.052
1.07
1.089
1.108
1.128
1.149
1.171
1.193
1.24
1.24
1.253
1.278
1.305
1.347
1.362
1.392
1.424
1.457
1.492
1.529
1.587
1.607
1.65
Número
1975
1943
1911
1879
1846
1815
1784
1754
1720
1689
1656
1593
1593
1577
1543
1514
1465
1449
1417
1384
1354
1320
1289
1243
1228
1194
Voltaje
Frecuencia (Khz)
2.7
2.8
2.9
3
3.1
3.2
3.3
3.4
3.5
3.6
3.7
3.8
3.9
4
4.1
4.2
4.3
4.4
4.5
4.6
4.7
4.8
4.9
5
5.1
1.695
1.742
1.792
1.845
1.872
1.901
1.992
2.057
2.127
2.202
2.283
2.369
2.463
2.564
2.674
2.732
2.924
3.067
3.226
3.311
3.496
3.704
3.937
4.202
5
Número
1162
1130
1098
1066
1050
1034
986
954
923
891
858
828
794
764
731
716
669
639
603
589
554
524
493
461
425
Con la tabla 3.5 se obtiene la gráfica de la figura 3.49, la medición es aceptable
debido a la resolución. En el rango donde no es lineal, el error es aceptable ya que
se manejará porcentaje de humedad.
Se optó por graficar contra la variable voltaje, ya que los datos de frecuencia no son
lineales, y es necesario tener una linealidad para relacionarla con la cantidad de
humedad, también es debido a que el transductor (todavía en proceso de diseño),
fue caracterizado en porcentaje de humedad contra voltaje.
110
Figura 3.49 Resultado de la medición de frecuencia.
El PIC16F628 se encuentra en un ciclo oscioso antes de entrar a la función medición
de frecuencia, esto se logra habilitando las interrupciones externas, estas
interrupciones detectan los flancos de subida de la señal de dato, para medir el
tiempo entre flancos se utilizó otro tipo de interrupción esta es la interrupción del
TMR0.
El TMR0 es un registro de 8 bits que cuenta desde el primer flanco hasta el segundo,
como la velocidad de conteo del TMR0 es alta, este registro se desborda varias
veces por lo que es necesario contar las veces que se desborda.
Cuando se detecta el primer flanco de la señal de dato se habilita la interrupción del
TMR0 y se inicializa el conteo, antes que se presente el segundo flanco, el TMR0 se
desbordará y entrará al RSI para identificar la interrupción e incrementar el número
de desbordamientos (este número cambiará dependiendo de la frecuencia del dato),
111
cuando llega el segundo flanco, se revisa que ya se hallan realizado 4 muestras de
frecuencias de dato, sino es el caso se dan las condiciones iniciales para que se
realice otra muestra. Una vez terminadas las muestras, se pone en estado alto un
PIN de control, para avisar al PIC16C745 que le serán enviados por el puerto serie
síncrono los datos de humedad (figura 3.50). Después de enviar los datos por el
puerto serie, se dejan las condiciones iniciales en las variables y entra al ciclo ocioso.
transmitir
bsf
movlw
movwf
movlw
movwf
bsf
bsf
bcf
bsf
otra
incf
movf
movwf
bsf
ansina
portb,0x03
0x08
aux1
0x37
fsr
estado,RP0
txsta,TXEN
estado,RP0
porta,0x00
fsr,f
INDF,w
txreg
estado,RP0
btfss
goto
bcf
decf
btfss
goto
txsta,TRMT
ansina
estado,RP0
aux1,f
estado,Z
otra
bcf
clrf
clrf
bsf
bsf
bcf
bcf
movlw
movwf
bcf
retfie
portb,0x03
portb
porta
rcsta,CREN
estado,RP0
txsta,TXEN
estado,RP0
0x30
fsr
intcon,INTE
salir
Figura 3.50 Rutina de servicio de interrupción serie síncrona.
El PIC16C745 quedó en un ciclo checando el estado lógico del pin de control, por el
cual el PIC16F628 le indicaría el incio de transmisión serie síncrona de los datos del
muetreo de frecuencia, pues bien, si el PIN esta en estado alto, el PIC16C745 entra
a la rutina de recepción serie síncrono, adquiriendo los datos de humedad del
PIC16F628. Una vez adquiridos los datos de humedad en el PIC16C745, se envían
los datos por el puerto USB y regresa al ciclo de espera de datos por el mismo
puerto.
La figura 3.51 muestra la rutina donde el PIC16C745 envía las claves de
conmutación, genera los tonos de activación, checa el estado del PIN de control,
recibe y transmite los datos del muestreo de frecuencia.
112
Banksel
movf
movwf
call
call
banksel
movf
movwf
clave1
clave1,w
TXREG
delay2
tonos
clave2
clave2,w
TXREG
;selecciono el banco donde se encuentra la variable clave1
;valor de la clave1 al acumulador
;envío la clave 1 para encender el transmisor
;tiempo necesario para que el transmisor encienda
;transmito el tono de activación del transductor (tabla 3.1)
btfss
goto
movlw
movwf
movlw
movwf
bsf
call
PORTA,02
andale
0x50
FSR
0x08
aux
PORTA,01h
ini_rx
;por esta línea, el esclavo me avisa que ya muestreó
;4 tonos y está listo para enviarlos
btfss
goto
movf
movwf
incf
decf
btfsc
goto
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
bsf
goto
PIR1,RCIF
recep
RCREG,w
INDF
FSR,f
aux,f
STATUS,2
acabar
;envío la clave 2 para apagar el transmisor
andale
;8 datos serán enviadas a ram
;a partir de la dirección 50 banco 0
;esta variable servirá como contador de las 4 lecturas
;modo RX=on TX=off del puerto serie síncrono
recep
;hay 8 bits recibidos
;registro del byte recibido
;lo guarda en ram
;incremento puntero
;decremento el contador de las lecturas
;ya son 8 datos?
;si... son 8 lecturas, hay que salir
;retardo para que el pic16f628 pueda preparar el envío del
;siguiente byte 541.66 nanosegundos
RCSTA,SREN
recep
;mando otro tren de pulsos de reloj (modo maestro)
;hay que leer otra
acabar
bcf
PORTA,01h
call
ini_tx
; modo RX=off TX=on del puerto serie síncrono
Figura 3.51 Recepción de datos de humedad y transmisión por el puerto USB.
Con esto se finaliza el diseño de los procesos para cada uno de los
microcontroladores es sus 2 modos de conexión, y para hacer un resumen de esos
procesos y mostrar los lugares donde se añadieron los retardos, se presentarán en
las hojas de anexo 5.
IV PRUEBAS Y RESULTADOS
En esta sección, se mostrará el resultado final presentado por el programa residente
en la PC, el módulo de despliegue que muestra el transductor activado en el modo
interfaz con el PLC, además de ajustes y pruebas.
4.1 Pruebas y Ajustes
Todas las pruebas se realizaron por medio de un divisor de voltaje, que simula la
salida de voltaje del transductor de humedad, esto se realizó para poder llevar a cabo
un mayor número de cambios posibles, ya que modificar la humedad a pasos
específicos es difícil.
A la salida de este divisor de voltaje se conectó un multímetro (FLUKE), para
observar el voltaje aplicado al módulo esclavo (microcontrolador), los cambios de
este divisor fueron de cada 100 milivolts empezando desde cero hasta 5 volts, el cual
representa el 100% de humedad.
Para poder comprobar diferentes frecuencias de activación en el módulo esclavo, se
agregaron 2 jumpers y así poder cambiar la frecuencia de activación (figura 4.1), con
esto se puede configurar 4 frecuencias de activación diferentes las cuales son
1000,1050,1100 y 1150 Hz. También se le agregó un push button para realizar
activaciones sin que el módulo maestro intervenga y se pudieran hacer pruebas de
transmisiones. El código adicional es el mostrado por la figura 4.2.
Otra de las pruebas hechas fue ajustar la sincronización del retardo en la adquisición
de dato de humedad (figura 4.3), donde el retardo se ajusta hasta que la señal de
dato esté estabilizada, después se checa el nivel de la línea detector de portadora, si
se encuentra en estado alto se realiza el muestreo. Al terminar éste se pone en alto
el pin de control para dar aviso al PIC16C745 de una transmisión serie (prueba de
caja blanca).
114
También en el modo interfaz con el PLC se realizaron pruebas, en las cuales se
observó que se llevaran a cabo todas las activaciones de los transductores dados de
alta en el sistema, y en los tiempos indicados. Esto se verificó por medio de un
módulo de despliegue y viendo la señal de dato por medio del osciloscopio.
Figura 4.1 Jumpers y push button para pruebas (1.- jumpers. 2.- Push button).
clrf
btfsc
goto
incf
fa
portc,0x02
mk
fa,f
movlw
0x31
;49 a w
movwf
sb1
movlw
0x10
;16 a w
movwf
sb2
mk
goto
ciclo
btfsc portc,0x03
frec3
goto
frec1
movlw
0x01
incf
fa,f
subwf
fa,w
incf
fa,f
btfss
estado,0x02
frec1
goto
frec4
movlw 0x03
movlw
0x07
;7 a w
subwf fa,w
movwf
of1
btfss
estado,0x02
movlw
0x8A
;138 a w
goto
frec2
movwf
sb1
movlw 0x06
;6 a w
movlw
0x65
;101 a w
movwf of1
movwf
sb2
movlw 0xE0
;224 a w
goto
ciclo
movwf sb1
frec4
movlw 0xC2
;194 a w
movlw
0x07
;7 a w
movwf sb2
movwf
of1
goto
ciclo
movlw
0xE4
;228 a w
frec2
movwf
sb1
movlw
0x02
movlw
0xBC
;188 a w
subwf
fa,w
movwf
sb2
btfss
estado,0x02
ciclo
goto
frec3
btfsc
portc,0x04
movlw
0x07
;7 a w
goto
ciclo
movwf
of1
goto
Activar
Figura 4.2 Rutina para configurar la frecuencia de activación del módulo esclavo.
115
Figura 4.3 Sincronización del retardo para la adquisición del dato de humedad.
4.2 Módulo de despliegue y su conexión
En la entrada de la etapa de adecuación para el PLC (ver figura 4.4) se encuentran
los 5 pines de datos conectados al cable de bus, donde 4 provienen del
microcontrolador 16F628 y uno de la etapa de adecuación, todas las señales de
datos varían de 0 a 5 volts. En la salida del módulo se encuentran las mismas
señales de entrada, solo que invertidas y con tensiones de 0 a 24 volts que van hacia
el conector db9, conector por el cual el PLC deberá tomar los datos.
Figura 4.4 Etapa de adecuación para el PLC (1.- etapa de adecuación. 2.- cable de bus).
116
El módulo de adecuación para el PLC, consiste en transistores que son alimentados
por el mismo PLC con 24 volts y su funcionamiento es entrar en estado de corte y
saturación para variar los voltajes a la salida.
El cable de bus es conectado a la entrada número 2 de la figura 4.5, para hacer
contacto con los pines donde el microcontrolador proporcionará los datos. La
entrada número 1 es para un módulo de despliegue (figura 4.6), el cual sirvió para
verificar que efectivamente se estuviera mandando la información al conector db9, y
de éste, hacia el PLC.
Los 4 LEDs indican en número binario, el actual transductor activado, por lo que en
las pruebas se verificaron que se activaran todas las que estuvieran dados de altas
en el sistema y en el osciloscopio la frecuencia correspondiente.
Figura 4.5 Receptores de cables (1.- módulo de despliegue. 2.- cable de bus).
Figura 4.6 Módulo de despliegue para realizar pruebas.
117
La conexión final del módulo de despliegue y del cable de bus para realizar las
prubas en el modo de conexión con el PLC lo muestra la figura 4.7.
Figura 4.7 Conexión de cables para el interfaz con el PLC y módulo de despliegue.
4.3 Resultados
En el modo interfaz con la PC, el resultado final es presentado en porcentaje de
humedad, donde 5 Volts representan el 100% de humedad. Como ya habíamos
mencionado, el resultado es casi lineal (ver tabla 3.5), así que se utilizó otra ecuación
para llegar al resultado final por medio del programa MAT LAB y se obtiene lo
siguiente.
% de humedad = (0.00000002409442n2 - 0.00330379596851n +
6.51707742555624)*20%
Donde n es el número que representa el semiperiodo de la señal de dato y se calcula
a través de las variables OVERFLOWS y SOBRA que se obtienen de la medición de
frecuencia. Cada volt representa el 20% de humedad.
n = (overflows*255) + (sobra)
Los valores de las variables OVERFLOWS y SOBRA, se obtienen de una de las 4
muestras realizadas por la función de medición de frecuencia (ver figura 4.1).
118
Tabla 4.1 Resultado final (voltaje de referencia del ADC a 5.2 volts).
volts
0.1
0.2
0.4
0.5
0.6
0.7
0.8
0.9
1
1.1
1.2
1.4
1.5
1.6
1.7
1.8
1.9
2
2.1
2.2
2.4
2.5
2.6
2.7
2.8
2.9
3
3.1
3.2
3.4
3.5
3.6
3.7
3.8
3.9
4
4.1
4.2
4.4
4.5
4.6
4.7
4.8
4.9
5
frecuencia
(Khz)
1.002
1.018
1.052
1.07
1.089
1.108
1.128
1.149
1.171
1.193
1.24
1.253
1.278
1.305
1.347
1.362
1.392
1.424
1.457
1.492
1.587
1.607
1.65
1.695
1.742
1.792
1.845
1.872
1.901
2.057
2.127
2.202
2.283
2.369
2.463
2.564
2.674
2.732
3.067
3.226
3.311
3.496
3.704
3.937
4.202
sobra
190
158
94
61
30
254
224
190
159
126
63
47
13
239
190
174
142
109
79
45
223
208
174
142
110
78
46
30
14
189
158
126
93
63
29
254
221
206
129
93
79
44
14
238
206
overflows
7
7
7
7
7
6
6
6
6
6
6
6
6
5
5
5
5
5
5
5
4
4
4
4
4
4
4
4
4
3
3
3
3
3
3
2
2
2
2
2
2
2
2
1
1
número
1975
1943
1879
1846
1815
1784
1754
1720
1689
1656
1593
1577
1543
1514
1465
1449
1417
1384
1354
1320
1243
1228
1194
1162
1130
1098
1066
1050
1034
954
923
891
858
828
794
764
731
716
639
603
589
554
524
493
461
porcentaje
1.7212737
3.77528588
7.88627096
10.0075402
12.0012037
13.9957934
15.9269233
18.1165858
20.1140139
22.2413259
26.3054726
27.3382459
29.5337084
31.4071892
34.5745676
35.6093147
37.6795492
39.8155121
41.7582074
43.9609773
48.9537219
49.9269995
52.1338982
54.2119971
56.2910829
58.3711556
60.4522152
61.4931151
62.5342618
67.7436958
69.7640096
71.8504664
74.0031586
75.9610622
78.1810683
80.1408224
82.2975538
83.2782332
88.3158012
90.6729881
91.5900092
93.8833884
95.8500818
97.8832428
99.9829611
119
La tabla 4.1 muestra el resultado de las pruebas realizadas y la relación de cada una
de las variables medidas.
Figura 4.8 Interpretación de la medición de frecuencia en porcentaje de humedad.
V CONCLUSIONES Y RECOMENDACIONES
Con los resultados mostrados se puede decir que se han cumplido con todos los
objetivos y se concluye lo siguiente.
Se ha diseñado un sistema de control para las etapas de radiofrecuencia, con el
objetivo de transmitir activaciones y señales de datos de humedad, aplicado a un
sistema de riego por goteo.
Con este sistema no se requiere una transmisión contínua del porcentaje de
humedad del área de cultivo, y por lo tanto, la duración de la batería de los módulos
esclavos será más larga.
Con la posibilidad de 2 modos de funcionamiento, se tiene la flexibilidad de aplicar
este sistema para un simple control de riego o para otros controles más, como por
ejemplo para un invernadero que controle sus correcciones de abono, fumigación,
etc. por medio de la medición de otros parámetros como PH, calor, etc. o en una
granja acuícola con parametros como oxígeno y nitrógeno.
La interfáz del usuario para dar de alta, editar y manipular el sistema de monitoreo es
amigable, la resolución de la medición de humedad mostrados en los resultados es
aceptable, la designación de las frecuencias son flexibles ya que si se cambia el
ancho de banda o la frecuencia de transmisión, los cambios en los programas serán
mínimos.
Por medio del control que ejerce el microcontrolador sobre las etapas, la interferencia
entre ellas ya no afectan el dato de humedad o la frecuencia de activación como se
presentaba antes de este trabajo de tesis.
Este trabajo presenta una oportunidad para comprender la forma de trabajar del
puerto USB, ya que se puede utilizar como una introducción a este puerto.
121
Aún faltan muchas mejoras de este sistema y se recomienda lo siguiente:
En el modo PLC, se necesita guardar los datos de funcionamiento en la EEPROM
del microcontrolador, ya que esos datos se encuentran en memoria RAM.
En el software, no se tomó en cuenta en caso de que un transductor falle, entonces
el software deberá reportarlo y continuar con el barrido de lectura, esto es, agregar
código de detección de errores y su corrección.
En la base de datos se puede hacer una estadística de las lecturas de humedad y
mostrar gráficas.
Los tiempos de retardos, se pueden reducir aún más, ya que los tiempos actuales
que aparecen en el código fuente, son los necesarios para realizar las pruebas.
En el tiempo de retardo para que se encienda el oscilador (módulo esclavo) y se
estabilice, no es posible reducir su tiempo, debido a que el tiempo de encendido y la
estabilización de su voltaje en la salida son lentos.
122
BIBLIOGRAFÍA
[1].- Martín Cuenca, J.M. Angulo Usategui, I. Angulo Martinez. Microcontroladores
PIC. Quinta edición. EDITORIAL PARAINFO THOMSON LEARNING.
[2].- Jan Axelson. USB COMPLETE. Second and Third Editions. LAKE VIEW
RESEARCH LLC.
[3].- Steven McDowell, Martin D. Seyer. USB EXPLAINED. EDITORIAL PRENTICE
HALL.
[4].- www.usb.org. Universal serial bus Specification. Rev 1.1 Noviembre de 2005.
123
ANEXOS
124
ANEXO 1
Código completo PIC16C745 interfaz con la PC (archivo chicotex.asm)
#include <p16c745.inc>
#include "usb_defs.inc"
aux8
aux9
errorlevel -302
__CONFIG
_H4_OSC & _WDT_OFF &
_PWRTE_OFF & _CP_OFF
unbanked
W_save
bank0 udata
Status_save
PCLATH_save
FSR_save
outbuffer
over
over1
over2
over3
over4
over5
lower
lower1
lower2
lower3
lower4
lower5
periodos
periodos8
multiplo
multiplo2
multiplo3
clave1
clave2
clave3
clave4
clave5
clave6
clave7
clave8
aux
aux1
aux2
aux3
aux4
aux5
aux6
aux7
udata_shr
res
res
res
res
res
res
res
res
res
res
res
res
res
res
res
res
res
res
res
res
res
res
res
res
res
res
res
res
res
res
res
res
res
res
res
res
res
res
1
1
1
8
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
extern
extern
extern
extern
extern
extern
res
res
1
1
InitUSB
PutEP1
GetEP1
ServiceUSBInt
CheckSleep
RemoteWakeup
1
STARTUP
code
pagesel main
goto
main
nop
InterruptServiceVector
movwf W_save
movf STATUS,W
clrf
STATUS
movwf Status_save
movf PCLATH,w
movwf PCLATH_save
movf FSR,w
movwf FSR_save
Process_ISR
btfsc INTCON,INTF
nop
btfsc INTCON,T0IF
nop
btfsc INTCON,RBIF
nop
BANKSEL
PIR1
pagesel ServiceUSBInt
btfsc PIR1,USBIF
call
ServiceUSBInt
btfsc PIR1,ADIF
nop
btfsc PIR1,RCIF
nop
btfsc PIR1,TXIF
nop
btfsc PIR1,CCP1IF
nop
btfsc PIR1,TMR2IF
nop
btfsc PIR1,TMR1IF
nop
btfsc PIR2,CCP2IF
nop
EndISR
clrf
movf
movwf
movf
movwf
movf
movwf
swapf
swapf
retfie
code
STATUS
FSR_save,w
FSR
PCLATH_save,w
PCLATH
Status_save,w
STATUS
W_save,f
W_save,w
main
banksel TRISA
clrf
TRISC
bsf
TRISC,0x07
bsf
TRISC,0x06
movlw 0x06
movwf ADCON1
clrf
TRISA
bsf
TRISA,0x02
clrf
TRISB
banksel PORTA
clrf
PORTA
clrf
PORTB
movlw .30
movwf W_save
decfsz W_save,f
goto
$-1
BANKSEL
OPTION_REG
bcf
OPTION_REG,NOT_RBPU
pagesel InitUSB
call
InitUSB
ConfiguredUSB
call
inicializar
call
ini_tx
LoopForData
pagesel GetEP1
banksel outbuffer
bankisel outbuffer
movlw outbuffer
movwf FSR
call
GetEP1
pagesel tonos
btfss STATUS,C
goto
LoopForData
;===================>PROCESOS
call
hand
call
datos
;********************************
pagesel PutEP1
bankisel outbuffer
banksel outbuffer
movlw outbuffer
movwf FSR
movlw 0x8
call
PutEP1
EndLoopForData
pagesel LoopForData
goto
LoopForData
;====================>FUNCIONES
inicializar
banksel SPBRG
movlw 0x1A
movwf SPBRG
bcf
PIE1,RCIE
bcf
PIE1,TXIE
banksel PIR1
bcf
PIR1,RCIF
bcf
PIR1,TXIF
banksel periodos
movlw 0x64
movwf periodos
movlw 0xAA
movwf clave1
movlw 0xBB
movwf clave2
movlw 0xCC
movwf clave3
return
ini_tx
banksel TXSTA
movlw 0xB0
movwf TXSTA
banksel RCSTA
movlw 0x80
movwf RCSTA
return
ini_rx
banksel TXSTA
movlw 0x90
movwf TXSTA
banksel RCSTA
movlw 0xA0
movwf RCSTA
return
hand
banksel clave1
movf clave1,w
movwf TXREG
call
delay2
call
tonos
banksel clave2
movf clave2,w
movwf TXREG
Andale
btfss
goto
movlw
movwf
movlw
movwf
bsf
call
PORTA,02
andale
0x50
FSR
0x08
aux
PORTA,01h
ini_rx
btfss
goto
movf
movwf
incf
decf
btfsc
goto
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
bsf
goto
PIR1,RCIF
recep
RCREG,w
INDF
FSR,f
aux,f
STATUS,2
acabar
banksel outbuffer
movlw outbuffer
movwf FSR
banksel aux1
movf aux1,w
addwf FSR,f
movf aux2,w
movwf INDF
incf
aux1,f
decf
aux,f
btfss STATUS,2
goto
dat
return
recep
tonos
lo
ok
RCSTA,SREN
recep
acabar
ok1
bcf
PORTA,01h
call
ini_tx
return
ok2
datos
movlw 0x08
movwf aux
clrf
aux1
ok3
dat
movlw
movwf
movf
addwf
movf
movwf
0x50
FSR
aux1,w
FSR,f
INDF,w
aux2
ok4
ok5
banksel outbuffer
movf outbuffer,w
movwf over
movwf lower
movf
outbuffer+1,w
movwf over1
movwf lower1
movf outbuffer+2,w
movwf over2
movwf lower2
movf outbuffer+3,w
movwf over3
movwf lower3
movf outbuffer+4,w
movwf over4
movwf lower4
movf outbuffer+5,w
movwf over5
movwf lower5
banksel PORTA
bsf
PORTA,00h
decf
over,f
btfss STATUS,2
goto
ok
decf
over1,f
btfss STATUS,2
goto
ok1
decf
over2,f
btfss STATUS,2
goto
ok2
decf
over3,f
btfss STATUS,2
goto
ok3
decf
over4,f
btfss STATUS,2
goto
ok4
decf
over5,f
btfss STATUS,2
goto
ok5
o
o1
o2
o3
o4
o5
bcf
decf
btfss
goto
decf
btfss
goto
decf
btfss
goto
decf
btfss
goto
decf
btfss
goto
decf
btfss
goto
decf
btfss
goto
return
PORTA,00h
lower,f
STATUS,2
o
lower1,f
STATUS,2
o1
lower2,f
STATUS,2
o2
lower3,f
STATUS,2
o3
lower4,f
STATUS,2
o4
lower5,f
STATUS,2
o5
periodos,f
STATUS,2
lo
delay2
si2
si1
si
banksel multiplo
movlw 0x0C
movwf multiplo3
clrf
multiplo2
clrf
multiplo
decf
multiplo,f
btfss STATUS,2
goto
si
decf
multiplo2,f
btfss STATUS,2
goto
si1
decf
multiplo3,f
btfss STATUS,2
goto
si2
return
end
PIC16C745 freeware (archivo descript.asm)
#include <p16c745.inc>
#include "usb_defs.inc"
USBBANK
global
global
global
global
global
global
global
global
global
global
global
code
Config_desc_index
Report_desc_index
Descriptions
string_index
DeviceDescriptor
ReportDescriptor
ReportDescriptorLen
String0
String0_end
StringDescriptions
HID_Descriptor
extern EP0_start
extern temp
extern temp2
Config_desc_index
movwf temp
movlw HIGH CDI_start
movwf PCLATH
movlw low CDI_start
addwf temp,w
btfsc
STATUS,C
incf
PCLATH,f
movwf PCL
CDI_start
retlw
retlw
low Config1
high Config1
Report_desc_index
movwf temp
movlw HIGH RDI_start
movwf PCLATH
movlw low RDI_start
addwf temp,w
btfsc STATUS,C
incf
PCLATH,f
movwf PCL
RDI_start
retlw low ReportDescriptorLen
retlw high ReportDescriptorLen
Descriptions
banksel EP0_start
movf EP0_start+1,w
movwf PCLATH
movf EP0_start,w
movwf PCL
DeviceDescriptor
StartDevDescr
retlw 0x12
retlw 0x01
retlw 0x00
retlw 0x01
retlw 0x00
retlw 0x00
retlw 0x00
retlw 0x08
retlw 0x00
retlw 0x00
retlw 0x00
retlw 0x00
retlw 0x00
retlw 0x00
retlw 0x02
retlw 0x01
retlw 0x00
retlw NUM_CONFIGURATIONS
Config1
retlw 0x09
retlw 0x02
retlw EndConfig1 - Config1
retlw 0x00
retlw 0x01
retlw 0x01
retlw 0x04
retlw 0x80
retlw 0x32
Interface1
retlw 0x09
retlw INTERFACE
retlw 0x00
retlw 0x00
retlw 0x02
retlw 0x03
retlw 0x00
retlw 0x00
retlw 0x00
HID_Descriptor
retlw (Endpoint1 - HID_Descriptor)
retlw 0x21
retlw 0x00
retlw 0x01
retlw 0x00
retlw 0x01
retlw 0x22
retlw low (end_ReportDescriptor ReportDescriptor)
retlw high (end_ReportDescriptor ReportDescriptor)
Endpoint1
retlw 0x07
retlw ENDPOINT
retlw 0x81
retlw 0x03
retlw 0x08
retlw 0x00
retlw 0x0A
Endpoint2
retlw 0x07
retlw ENDPOINT
retlw 0x01
retlw 0x03
retlw 0x08
retlw 0x00
retlw 0x0A
EndConfig1
ReportDescriptorLen
retlw low (end_ReportDescriptorReportDescriptor)
ReportDescriptor
dt 006h, 000h, 0ffh
dt 009h, 001h
dt 0a1h, 001h
dt 019h, 001h
dt 029h, 008h
dt 015h, 000h
dt 026h, 0ffh, 000h
dt 075h, 008h
dt 095h, 008h
dt 081h, 002h
dt 019h, 001h
dt 029h, 008h
dt 091h, 002h
dt 0c0h
end_ReportDescriptor
StringDescriptions
banksel EP0_start
movf EP0_start+1,w
movwf PCLATH
movf EP0_start,w
movwf PCL
string_index
movwf temp
bcf
STATUS,C
rlf
temp, f
pagesel langid_index
call
langid_index
movwf temp2
incf
temp, f
pagesel langid_index
call
langid_index
movwf temp
movf
temp, w
movwf PCLATH
movf temp2,w
addwf EP0_start+1,w
btfsc STATUS,C
incf
PCLATH, f
movwf PCL
langid_index
movlw high langids
movwf PCLATH
movlw low langids
addwf temp, w
btfsc STATUS,C
incf
PCLATH,f
movwf PCL
langids
retlw low lang_1
retlw high lang_1
retlw low lang_2
retlw high lang_2
lang_1
retlw low String0
retlw high String0
retlw low String1_l1
retlw high String1_l1
retlw low String2_l1
retlw high String2_l1
retlw low String3_l1
retlw high String3_l1
retlw low String4_l1
retlw high String4_l1
retlw low String5_l1
retlw high String5_l1
lang_2
retlw low String0
retlw high String0
retlw low String1_l2
retlw high String1_l2
retlw low String2_l2
retlw high String2_l2
retlw low String3_l2
retlw high String3_l2
retlw low String4_l2
retlw high String4_l2
retlw
low String5_l2
retlw high String5_l2
String0
retlw low (String1_l1 - String0)
retlw 0x03
retlw 0x09
retlw 0x04
retlw 0x04
retlw 0x08
String0_end
String1_l1
retlw
retlw
retlw
retlw
retlw
retlw
retlw
retlw 0x00
retlw
retlw
retlw
retlw
retlw
retlw
retlw
retlw
retlw
retlw
retlw
retlw
String2_l1
retlw
retlw
retlw
retlw
retlw 'U'
retlw
retlw
retlw
retlw
retlw
retlw
retlw
retlw
retlw
retlw
retlw
retlw
retlw
retlw
retlw
retlw
retlw 0x00
retlw
retlw
retlw
retlw
retlw
retlw
String2_l1-String1_l1
0x03
'C'
0x00
'H'
0x00
'I'
'C'
0x00
'O'
0x00
'T'
0x00
'E'
0x00
'X'
0x00
'.'
0x00
String3_l1-String2_l1
0x03
'J'
0x00
0x00
'A'
0x00
'N'
0x00
''
0x00
'C'
0x00
'A'
0x00
'R'
0x00
'L'
0x00
'O'
'S'
0x00
'.'
0x00
''
0x00
String3_l1
retlw
retlw
retlw
retlw
retlw
retlw
retlw
retlw
retlw
retlw
retlw
retlw
String4_l1
retlw
retlw
retlw
retlw
retlw
retlw
retlw
retlw
retlw
retlw
String5_l1
retlw
retlw
retlw
retlw
retlw
retlw
retlw
retlw
retlw
retlw
retlw
retlw
retlw
retlw
retlw
retlw
String1_l2
retlw
retlw
retlw
retlw
retlw
retlw
retlw
retlw
retlw
retlw
retlw
retlw
retlw
String4_l1-String3_l1
0x03
'V'
0x00
'1'
0x00
'.'
0x00
'0'
0x00
'0'
0x00
String5_l1-String4_l1
0x03
'C'
0x00
'f'
0x00
'g'
0x00
'1'
0x00
String6_l1-String5_l1
0x03
'N'
0x00
'o'
0x00
't'
0x00
'h'
0x00
'i'
0x00
'n'
0x00
'g'
0x00
String2_l2-String1_l2
0x03
'M'
0x00
'i'
0x00
'c'
0x00
'r'
0x00
'o'
0x00
'c'
retlw
retlw
retlw
retlw
retlw
retlw
retlw
String2_l2
retlw
retlw
retlw
retlw 0x00
retlw
retlw
retlw
retlw
retlw
retlw
retlw
retlw
retlw 'C'
retlw
retlw
retlw
retlw
retlw
retlw
retlw 0x00
retlw
retlw
retlw
retlw
retlw
retlw
retlw
retlw
retlw
retlw
retlw
retlw
retlw
retlw
retlw
retlw
retlw
retlw
retlw
retlw
retlw
retlw
retlw
retlw
retlw
retlw
0x00
'h'
0x00
'i'
0x00
'p'
0x00
String3_l2-String2_l2
0x03
'P'
'i'
0x00
'c'
0x00
'1'
0x00
'6'
0x00
0x00
'7'
0x00
'6'
0x00
'5'
''
0x00
'U'
0x00
'S'
0x00
'B'
0x00
''
0x00
'L'
0x00
'C'
0x00
'D'
0x00
''
0x00
'D'
0x00
'E'
0x00
'M'
0x00
'O'
0x00
String3_l2
retlw
retlw
retlw
retlw
retlw
retlw
retlw
retlw
retlw
retlw
retlw
retlw
String4_l2
retlw
retlw
retlw
retlw
retlw
retlw
retlw
retlw
String4_l2-String3_l2
0x03
'V'
0x00
'1'
0x00
'.'
0x00
'0'
0x00
'0'
0x00
String5_l2-String4_l2
0x03
'C'
0x00
'f'
0x00
'g'
0x00
retlw
retlw
String5_l2
retlw
retlw
retlw
retlw
retlw
retlw
retlw
retlw
retlw
retlw
retlw
retlw
retlw
retlw
retlw
retlw
String6_l2
end
'1'
0x00
String6_l2-String5_l2
0x03
'N'
0x00
'o'
0x00
't'
0x00
'h'
0x00
'i'
0x00
'n'
0x00
'g'
0x00
PIC16C745 freeware (archivo hidclass.asm)
#include <p16c745.inc>
#include "usb_defs.inc"
extern
extern
extern
extern
extern
extern
extern
extern
extern
extern
extern
extern
extern
extern
global
ReportDescriptor
ReportDescriptorLen
HID_Descriptor
Descriptions
BufferData
BufferDescriptor
wrongstate
USB_dev_req
EP0_maxLength
EP0_start
EP0_end
copy_descriptor_to_EP0
Send_0Len_pkt
Report_desc_index
ClassSpecificRequest
USBBANK
code
ClassSpecificRequest
Pagesel Dev2HostHIDRequest
movf
BufferData+bmRequestType,w
xorlw
0x21
btfsc
STATUS,Z
goto
Host2DevHIDRequest
pagesel
movf
xorlw
btfsc
goto
pagesel
movf
xorlw
btfsc
goto
pagesel
movf
xorlw
btfsc
goto
pagesel
movf
xorlw
btfsc
goto
pagesel
movf
xorlw
btfsc
goto
pagesel
goto
Host2DevReportRequest
BufferData+bmRequestType,w
0x22
STATUS,Z
Host2DevReportRequest
Host2DevPhysicalRequest
BufferData+bmRequestType,w
0x23
STATUS,Z
Host2DevPhysicalRequest
Dev2HostHIDRequest
BufferData+bmRequestType,w
0xA1
STATUS,Z
Dev2HostHIDRequest
Dev2HostReportRequest
BufferData+bmRequestType,w
0xA2
STATUS,Z
Dev2HostReportRequest
Dev2HostPhysicalRequest
BufferData+bmRequestType,w
0xA3
STATUS,Z
Dev2HostPhysicalRequest
wrongstate
wrongstate
Host2DevHIDRequest
movf BufferData+bRequest,w
xorlw 0x01
pagesel GetHIDReport
btfsc STATUS,Z
goto
GetHIDReport
movf BufferData+bRequest,w
xorlw 0x02
pagesel GetIdle
btfsc STATUS,Z
goto
GetIdle
movf BufferData+bRequest,w
xorlw 0x03
pagesel GetPhysical
btfsc STATUS,Z
goto
GetPhysical
movf BufferData+bRequest,w
xorlw 0x06
pagesel Get_Report_Descriptor
btfsc
STATUS,Z
goto
Get_Report_Descriptor
movf BufferData+bRequest,w
xorlw 0x09
pagesel SetHIDReport
btfsc STATUS,Z
goto
SetHIDReport
movf BufferData+bRequest,w
xorlw 0x0A
pagesel SetIdle
btfsc STATUS,Z
goto
SetIdle
movf BufferData+bRequest,w
xorlw 0x0B
pagesel SetProtocol
btfsc STATUS,Z
goto
SetProtocol
pagesel wrongstate
goto
wrongstate
Get_Report_Descriptor
global Get_Report_Descriptor
banksel EP0_start
movlw GET_DESCRIPTOR
movwf USB_dev_req
movlw 8
movwf EP0_maxLength
movf BufferData+(wValue+1),w
xorlw 0x01
pagesel TryOutputReport
btfsc STATUS,Z
goto
TryOutputReport
bcf
STATUS,C
rlf
BufferData+wIndex,w
pagesel Report_desc_index
call
Report_desc_index
movwf EP0_start
bcf
STATUS,C
rlf
BufferData+wIndex,w
addlw
1
call
Report_desc_index
movwf
EP0_start+1
pagesel Descriptions
call
Descriptions
movwf
EP0_end
incf
EP0_start,f
pagesel CheckReportLength
goto
CheckReportLength
TryOutputReport
movf
BufferData+(wValue+1),w
xorlw
0x02
pagesel TryFeatureReport
btfsc
STATUS,Z
goto
TryFeatureReport
bcf
STATUS,C
rlf
BufferData+wIndex,w
pagesel Report_desc_index
call
Report_desc_index
movwf
EP0_start
bcf
STATUS,C
rlf
BufferData+wIndex,w
addlw
1
call
Report_desc_index
movwf
EP0_start+1
pagesel Descriptions
call
Descriptions
movwf
EP0_end
incf
EP0_start,f
pagesel CheckReportLength
goto
CheckReportLength
TryFeatureReport
movf
BufferData+(wValue+1),w
xorlw
0x03
pagesel wrongstate
btfsc
STATUS,Z
goto
wrongstate
return
CheckReportLength
movf
BufferData+(wLength+1),w
pagesel nolimit_rpt
btfss
STATUS,Z
goto
nolimit_rpt
check_low_bytes
movf
BufferData+wLength,w
subwf
EP0_end,w
movf
BufferData+wLength,w
btfsc
STATUS,C
movwf
EP0_end
nolimit_rpt
incf
EP0_end,f
pagesel copy_descriptor_to_EP0
call
copy_descriptor_to_EP0
return
Get_HID_Descriptor
global Get_HID_Descriptor
movlw GET_DESCRIPTOR
movwf USB_dev_req
movlw 8
movwf EP0_maxLength
movlw low HID_Descriptor
movwf EP0_start
movlw high HID_Descriptor
movwf EP0_start + 1
pagesel Descriptions
call
Descriptions
movwf EP0_end
movf BufferData+(wLength+1),f
pagesel nolimit_hid
btfss STATUS,Z
goto
nolimit_hid
subwf BufferData+wLength,w
movf BufferData+wLength,w
btfss STATUS,C
movwf EP0_end
nolimit_hid
incf
EP0_end,f
pagesel copy_descriptor_to_EP0
call
copy_descriptor_to_EP0
return
Get_Physical_Descriptor
return
Check_Class_Specific_IN
global Check_Class_Specific_IN
pagesel copy_descriptor_to_EP0
movf USB_dev_req,w
xorlw GET_DESCRIPTOR
btfsc STATUS,Z
call
copy_descriptor_to_EP0
return
Host2DevReportRequest
Host2DevPhysicalRequest
Dev2HostHIDRequest
Dev2HostReportRequest
Dev2HostPhysicalRequest
GetHIDReport
GetIdle
GetPhysical
SetProtocol
SetIdle
pagesel wrongstate
goto
wrongstate
SetHIDReport
movlw HID_SET_REPORT
movwf USB_dev_req
banksel BD0OST
return
end
PIC16C745 freeware (archivo usb_ch9.asm)
#include <p16c745.inc>
#include "usb_defs.inc"
errorlevel -302
unbanked
udata_shr
temp
res
1
GPtemp
res
1
global BufferDescriptor
global BufferData
global temp
global temp2
global EP0_maxLength
global EP0_start
global EP0_end
bank2 udata
BufferDescriptor
res
BufferData
res
USBMaskedInterrupts res
USB_Curr_Config
res
USB_status_device
res
USB_dev_req
res
3
8
1
1
1
1
USB_address_pending
USBMaskedErrors
PIDs
EP0_start
EP0_end
EP0_maxLength
temp2
bufindex
USB_Interface
inner
outer
dest_ptr
source_ptr
hid_dest_ptr
hid_source_ptr
counter
bytecounter
RP_save
IS_IDLE
USB_USTAT
res
res
res
res
res
res
res
res
res
res
res
res
res
res
res
res
res
res
res
res
1
1
1
2
1
1
1
1
3
1
1
1
1
1
1
1
1
1
1
1
global USB_Curr_Config
global USB_status_device
global USB_dev_req
global USB_Interface
#ifdef COUNTERRORS
USB_PID_ERR
res
2
USB_CRC5_ERR
res
2
USB_CRC16_ERR
res
2
USB_DFN8_ERR
res
2
USB_BTO_ERR
res
2
USB_WRT_ERR
res
2
USB_OWN_ERR
res
2
USB_BTS_ERR
res
2
#endif
extern Config_desc_index
extern Descriptions
extern string_index
extern String0
extern String0_end
extern ClassSpecificRequest
extern Check_Class_Specific_IN
extern Get_Report_Descriptor
extern Get_HID_Descriptor
extern DeviceDescriptor
extern StringDescriptions
interface
code
GETEP1
GETEP2
PUTEP1
PUTEP2
StallUSBEP
bsf
STATUS,IRP
andlw 0x03
addlw low UEP0
movwf FSR
bsf
INDF,EP_STALL
return
UnstallUSBEP
bsf
STATUS,IRP
andlw 0x03
addlw low UEP0
movwf FSR
bcf
INDF,EP_STALL
return
CheckSleep
global CheckSleep
banksel IS_IDLE
btfss IS_IDLE,0
return
#ifdef SHOW_ENUM_STATUS
banksel PORTB
bsf
PORTB,4
banksel UIR
#endif
#ifdef
bsf
STATUS,RP0
bcf
UIR,ACTIVITY
bsf
UIE,ACTIVITY
bsf
UCTRL,SUSPND
sleep
nop
bcf
UCTRL,SUSPND
bcf
UIR,UIDLE
bsf
UIE,UIDLE
bcf
UIR,ACTIVITY
bcf
UIE,ACTIVITY
SHOW_ENUM_STATUS
banksel PORTB
bcf
PORTB,4
#endif
return
RemoteWakeup
global RemoteWakeup
banksel USB_status_device
btfss USB_status_device, 1
return
bsf
STATUS, RP0
bcf
UCTRL, SUSPND
bsf
UIE,UIDLE
bcf
UIR,UIDLE
bcf
UIE,ACTIVITY
bcf
UIR,ACTIVITY
bsf
UCTRL, 2
bcf
STATUS, RP0
clrf
inner
movlw 0x80
movwf outer
pagesel RemoteLoop
RemoteLoop
decfsz inner, f
goto
RemoteLoop
decfsz outer, f
goto
RemoteLoop
bsf
STATUS, RP0
bcf
UCTRL, 2
return
SoftDetachUSB
global SoftDetachUSB
banksel UCTRL
bcf
UCTRL,DEV_ATT
bcf
STATUS, RP0
clrf
outer
clrf
inner
pagesel SoftDetachLoop
SoftDetachLoop
incfsz
inner,f
goto
SoftDetachLoop
incfsz
outer,f
goto
SoftDetachLoop
pagesel InitUSB
call InitUSB
return
InitUSB
global
InitUSB
banksel
USWSTAT
clrf USWSTAT
movlw
0x01
movwf
UIE
clrf UIR
movlw
0x08
movwf
UCTRL
bcf STATUS, RP0
clrf USB_Curr_Config
movlw
1
movwf
USB_status_device
clrf USB_Interface
clrf USB_Interface+1
clrf USB_Interface+2
movlw
0xFF
movwf
USB_dev_req
#ifdef COUNTERRORS
clrf USB_PID_ERR
clrf USB_PID_ERR+1
clrf USB_CRC5_ERR
clrf USB_CRC5_ERR+1
clrf USB_CRC16_ERR
clrf USB_CRC16_ERR+1
clrf USB_DFN8_ERR
clrf USB_DFN8_ERR+1
clrf USB_BTO_ERR
clrf USB_BTO_ERR+1
clrf USB_WRT_ERR
clrf USB_WRT_ERR+1
clrf USB_OWN_ERR
clrf USB_OWN_ERR+1
clrf USB_BTS_ERR
clrf USB_BTS_ERR+1
#endif
banksel PIR1
bcf PIR1,USBIF
bsf STATUS,RP0
bsf PIE1,USBIE
bsf INTCON, 6
bsf INTCON, 7
#ifdef SHOW_ENUM_STATUS
bcf STATUS,RP0
bsf PORTB,0
#endif
return
DeInitUSB
global
DeInitUSB
banksel
UCTRL
bcf UCTRL,DEV_ATT
bsf UCTRL,SUSPND
clrf USWSTAT
bcf STATUS,RP1
bcf PIE1,USBIE
#ifdef SHOW_ENUM_STATUS
bcf STATUS,RP0
movlw
0x01
movwf
PORTB
bsf STATUS,RP0
#endif
return
core
code
ServiceUSBInt
global ServiceUSBInt
banksel UIR
movf
UIR,w
andwf
UIE,w
bcf
STATUS, RP0
pagesel ExitServiceUSBInt
btfsc
STATUS,Z
goto
ExitServiceUSBInt
movwf USBMaskedInterrupts
pagesel TokenDone
btfsc
USBMaskedInterrupts,ACTIVITY
call
USBActivity
pagesel USBReset
btfsc
USBMaskedInterrupts,USB_RST
call
USBReset
pagesel USBStall
btfsc
USBMaskedInterrupts,TOK_DNE
call
TokenDone
pagesel USBActivity
btfsc
USBMaskedInterrupts,STALL
call
USBStall
pagesel USBError
btfsc
USBMaskedInterrupts,UERR
call
USBError
pagesel USBSleep
btfsc
USBMaskedInterrupts,UIDLE
call
USBSleep
pagesel ServiceUSBInt
goto
ServiceUSBInt
ExitServiceUSBInt
Banksel PIR1
bcf
PIR1,USBIF
return
USBReset
clrf USB_Curr_Config
clrf IS_IDLE
bsf STATUS, RP0
bcf UIR,TOK_DNE
bcf UIR,TOK_DNE
bcf UIR,TOK_DNE
bcf UIR,TOK_DNE
movlw
0x8
movwf
BD0OBC
Movlw USB_Buffer
movwf BD0OAL
movlw 0x88
movwf BD0OST
movlw USB_Buffer+8
movwf BD0IAL
movlw 0x08
movwf BD0IST
clrf
UADDR
clrf
UIR
banksel PIR1
bcf
PIR1,USBIF
banksel UEP0
movlw ENDPT_CONTROL
movwf UEP0
movlw 0x3B
movwf UIE
movlw 0xFF
movwf UEIE
movlw DEFAULT_STATE
movwf USWSTAT
bcf
STATUS,RP0
movlw 0x01
movwf USB_status_device
bcf
STATUS,RP1
#ifdef SHOW_ENUM_STATUS
bsf
PORTB,1
#endif
bsf
STATUS,RP1
return
USBSleep
bsf
STATUS, RP0
bcf
UIE,UIDLE
bcf
UIR,UIDLE
bcf
UIR,ACTIVITY
bsf
UIE,ACTIVITY
bsf
UCTRL, SUSPND
banksel PIR1
bcf
PIR1,USBIF
bsf
STATUS, RP1
bsf
IS_IDLE, 0
return
USBStall
bsf
STATUS, RP0
bcf
UIR, STALL
banksel PIR1
bcf
PIR1,USBIF
bsf
STATUS,RP1
return
USBError
bsf
STATUS, RP0
bcf
UIR,UERR
movf UEIR,w
andwf UEIE,w
clrf
UEIR
banksel
PIR1
bcf
PIR1,USBIF
bsf
STATUS,RP1
movwf
USBMaskedErrors
#ifdef COUNTERRORS
btfss
USBMaskedErrors,PID_ERR
goto
CRC5Error
INCREMENT16 USB_PID_ERR
CRC5Error
btfss
USBMaskedErrors,CRC5
goto
CRC16Error
INCREMENT16 USB_CRC5_ERR
CRC16Error
btfss
USBMaskedErrors,CRC16
goto
DFN8Error
INCREMENT16 USB_CRC16_ERR
DFN8Error
btfss
USBMaskedErrors,DFN8
goto
BTOError
INCREMENT16 USB_DFN8_ERR
BTOError
btfss
USBMaskedErrors,BTO_ERR
goto
WRTError
INCREMENT16 USB_BTO_ERR
WRTError
btfss
USBMaskedErrors,WRT_ERR
goto
OWNError
INCREMENT16 USB_WRT_ERR
OWNError
btfss
USBMaskedErrors,OWN_ERR
goto
BTSError
INCREMENT16 USB_OWN_ERR
BTSError
btfss
USBMaskedErrors,BTS_ERR
goto
EndError
INCREMENT16 USB_BTS_ERR
EndError
#endif
banksel
USBMaskedInterrupts
return
USBActivity
bsf STATUS, RP0
bcf UIE,ACTIVITY
bcf UIR,ACTIVITY
bcf UIR,UIDLE
bsf UIE,UIDLE
bcf UCTRL, SUSPND
banksel
PIR1
bcf PIR1,USBIF
bsf STATUS,RP1
clrf IS_IDLE
return
TokenDone
COPYBUFFERDESCRIPTOR
banksel USTAT
movf
USTAT,w
bcf
UIR,TOK_DNE
banksel PIR1
bcf
PIR1,USBIF
bsf
STATUS,RP1
movwf USB_USTAT
#ifdef SHOW_ENUM_STATUS
bcf
STATUS,RP1
andlw 0x18
pagesel tryEP1activity
btfss
STATUS,Z
goto
tryEP1activity
movlw 0x20
pagesel maskport
goto
maskport
tryEP1activity
xorlw
0x08
btfss
STATUS,Z
movlw 0x80
btfsc
STATUS,Z
movlw 0x40
maskport
xorwf PORTB,f
bsf
STATUS,RP1
#endif
movf
BufferDescriptor,w
andlw 0x3c
movwf PIDs
xorlw
TOKEN_IN
pagesel TokenInPID
btfsc
STATUS,Z
goto
TokenInPID
movf
PIDs,w
xorlw
TOKEN_OUT
pagesel TokenOutPID
btfsc
STATUS,Z
goto
TokenOutPID
movf
PIDs,w
xorlw
TOKEN_SETUP
pagesel TokenSetupPID
btfsc
STATUS,Z
goto
TokenSetupPID
return
TokenOutPID
movf
USB_USTAT,w
pagesel tryEP1
btfss
STATUS,Z
goto
tryEP1
movf
USB_dev_req,w
xorlw
HID_SET_REPORT
pagesel ResetEP0OutBuffer
btfss
STATUS,Z
goto
ResetEP0OutBuffer
HIDSetReport
ResetEP0OutBuffer
bsf
STATUS,RP0
movlw 0x08
movwf BD0OBC
movlw 0x88
movwf BD0OST
pagesel Send_0Len_pkt
bcf
STATUS,RP0
goto
Send_0Len_pkt
return
tryEP1
xorlw
0x08
pagesel tryEP2
btfss
STATUS,Z
goto
tryEP2
return
tryEP2
movf
USB_USTAT,w
xorlw
0x10
btfsc
STATUS,Z
return
return
TokenInPID
EP0_in
movf
USB_USTAT,w
andlw 0x18
pagesel tryEP1in
btfss
STATUS,Z
goto
tryEP1in
movf
USB_dev_req,w
xorlw
GET_DESCRIPTOR
pagesel check_GSD
btfss
STATUS,Z
goto
check_GSD
pagesel copy_descriptor_to_EP0
call
copy_descriptor_to_EP0
goto
exitEP0in
check_GSD
movf
USB_dev_req,w
xorlw GET_STRING_DESCRIPTOR
pagesel check_SA
btfss
STATUS,Z
goto
check_SA
pagesel copy_descriptor_to_EP0
call
copy_descriptor_to_EP0
pagesel exitEP0in
goto
exitEP0in
check_SA
movf
USB_dev_req,w
xorlw
SET_ADDRESS
pagesel check_SF
btfss
STATUS,Z
goto
check_SF
pagesel
finish_set_address
call
finish_set_address
pagesel
exitEP0in
goto
exitEP0in
check_SF
movf
USB_dev_req,w
xorlw
SET_FEATURE
pagesel
check_CF
btfss
STATUS,Z
goto
check_CF
pagesel
exitEP0in
goto
exitEP0in
check_CF
movf
USB_dev_req,w
xorlw
CLEAR_FEATURE
pagesel
Class_Specific
btfss
STATUS,Z
goto
Class_Specific
movf
BufferData+4, w
xorlw
1
pagesel
clear_EP2
btfss
STATUS,Z
goto
clear_EP2
bsf
STATUS, RP0
bsf
UEP1, EP_STALL
bcf
STATUS, RP0
pagesel
exitEP0in
goto
exitEP0in
clear_EP2
movf
BufferData+wIndex, w
xorlw
2
pagesel
exitEP0in
btfss
STATUS,Z
goto
exitEP0in
bsf
STATUS, RP0
bsf
UEP2, EP_STALL
bcf
STATUS, RP0
pagesel
exitEP0in
goto
exitEP0in
Class_Specific
pagesel Check_Class_Specific_IN
goto
Check_Class_Specific_IN
exitEP0in
return
tryEP1in
xorlw
0x08
pagesel tryEP1in
btfss
STATUS,Z
goto
tryEP2in
return
tryEP2in
return
Send_0Len_pkt
global Send_0Len_pkt
banksel
BD0IBC
clrf
BD0IBC
movlw 0xc8
movwf BD0IST
bcf
STATUS,RP0
clrf
USB_dev_req
return
TokenSetupPID
bsf
STATUS,IRP
movf BufferDescriptor+ADDRESS,w
movwf FSR
movf INDF,w
movwf BufferData
incf
FSR,f
movf
INDF,w
movwf BufferData+1
incf
FSR,f
movf
INDF,w
movwf BufferData+2
incf
FSR,f
movf
INDF,w
movwf BufferData+3
incf
FSR,f
movf
INDF,w
movwf BufferData+4
incf
FSR,f
movf
INDF,w
movwf BufferData+5
incf
FSR,f
movf
INDF,w
movwf BufferData+6
incf
FSR,f
movf
INDF,w
movwf BufferData+7
bsf
STATUS, RP0
movlw 0x08
movwf BD0OBC
movwf BD0IST
bcf
STATUS, RP0
movf
BufferData+bmRequestType, w
xorlw
HID_SET_REPORT
movlw
0x88
btfsc
STATUS, Z
movlw
0xC8
bsf
STATUS, RP0
movwf
BD0OST
bcf
UCTRL,PKT_DIS
bcf
STATUS,RP0
clrf
USB_dev_req
movf
BufferData+bmRequestType,w
pagesel HostToDevice
btfsc
STATUS,Z
goto
HostToDevice
movf
BufferData+bmRequestType,w
xorlw
0x01
pagesel HostToInterface
btfsc
STATUS,Z
goto
HostToInterface
movf
BufferData+bmRequestType,w
xorlw
0x02
pagesel HostToEndpoint
btfsc
STATUS,Z
goto
HostToEndpoint
movf
BufferData+bmRequestType,w
xorlw
0x80
pagesel DeviceToHost
btfsc
STATUS,Z
goto
DeviceToHost
movf
BufferData+bmRequestType,w
xorlw
0x81
pagesel InterfaceToHost
btfsc
STATUS,Z
goto
InterfaceToHost
movf
BufferData+bmRequestType,w
xorlw
0x82
pagesel EndpointToHost
btfsc
STATUS,Z
goto
EndpointToHost
movf
BufferData+bmRequestType,w
andlw
0x60
xorlw
0x20
pagesel ClassSpecificRequest
btfsc
STATUS,Z
goto
ClassSpecificRequest
CheckForVendorRequest
movf
BufferData+bmRequestType,w
andlw
0x60
xorlw
0x40
pagesel wrongstate
btfss
STATUS,Z
goto
wrongstate
pagesel CheckVendor
goto
CheckVendor
return
CheckForStandardRequest
HostToDevice
movf
BufferData+bRequest,w
xorlw
CLEAR_FEATURE
pagesel Clear_Device_Feature
btfsc
STATUS,Z
goto
Clear_Device_Feature
movf
BufferData+bRequest,w
xorlw
SET_ADDRESS
pagesel Set_Address
btfsc
STATUS,Z
goto
Set_Address
movf
BufferData+bRequest,w
xorlw
SET_CONFIGURATION
HostToInterface
movf
BufferData+bRequest,w
xorlw
CLEAR_FEATURE
Pagesel
Set_ Configuration
btfsc
STATUS,Z
goto
Set_Configuration
movf
BufferData+bRequest,w
xorlw
SET_FEATURE
pagesel
Set_Device_Feature
btfsc
STATUS,Z
goto
Set_Device_Feature
pagesel
wrongstate
goto
wrongstate
pagesel
Clear_Interface_Feature
btfsc
STATUS,Z
goto
Clear_Interface_Feature
movf
BufferData+bRequest,w
xorlw
SET_INTERFACE
pagesel
Set_Interface
btfsc
STATUS,Z
goto
Set_Interface
movf
BufferData+bRequest,w
xorlw
SET_FEATURE
pagesel
Set_Interface_Feature
btfsc
STATUS,Z
goto
Set_Interface_Feature
pagesel
wrongstate
goto
wrongstate
HostToEndpoint
movf
BufferData+bRequest,w
xorlw
CLEAR_FEATURE
pagesel
Clear_Endpoint_Feature
btfsc
STATUS,Z
goto
Clear_Endpoint_Feature
movf
BufferData+bRequest,w
xorlw
SET_FEATURE
pagesel
Set_Endpoint_Feature
btfsc
STATUS,Z
goto
Set_Endpoint_Feature
DeviceToHost
movf
BufferData+bRequest,w
xorlw
GET_CONFIGURATION
pagesel
Get_Configuration
btfsc
STATUS,Z
goto
Get_Configuration
movf
BufferData+bRequest,w
xorlw
GET_DESCRIPTOR
pagesel
Get_Descriptor
btfsc
STATUS,Z
goto
Get_Descriptor
movf
BufferData+bRequest,w
xorlw
GET_STATUS
pagesel
Get_Device_Status
btfsc
STATUS,Z
goto
Get_Device_Status
InterfaceToHost
movf
BufferData+bRequest,w
xorlw
GET_INTERFACE
pagesel Get_Interface
btfsc
STATUS,Z
goto
Get_Interface
movf
BufferData+bRequest,w
xorlw
GET_STATUS
pagesel Get_Interface_Status
btfsc
STATUS,Z
goto
Get_Interface_Status
movf
BufferData+bRequest,w
xorlw
GET_DESCRIPTOR
pagesel Get_Descriptor
btfsc
STATUS,Z
goto
Get_Descriptor
EndpointToHost
movf
BufferData+bRequest,w
xorlw
GET_STATUS
pagesel Get_Endpoint_Status
btfsc
STATUS,Z
goto
Get_Endpoint_Status
pagesel wrongstate
goto
wrongstate
return
Get_Descriptor
movf
BufferData+(wValue+1),w
xorlw
0x22
pagesel Get_Report_Descriptor
btfsc
STATUS,Z
goto
Get_Report_Descriptor
movf
BufferData+(wValue+1),w
xorlw
0x21
pagesel Get_HID_Descriptor
btfsc
STATUS,Z
goto
Get_HID_Descriptor
GetCh9Descriptor
movlw high StartGDIndex
movwf PCLATH
bcf
STATUS, C
movf BufferData+(wValue+1),w
andlw 0x03
addlw low StartGDIndex
btfsc STATUS,C
incf
PCLATH,f
movwf PCL
StartGDIndex
goto
wrongstate
goto
Get_Device_Descriptor
goto
Get_Config_Descriptor
goto
Get_String_Descriptor
Get_Device_Descriptor
movlw GET_DESCRIPTOR
movwf USB_dev_req
movlw 8
movwf EP0_maxLength
movlw low DeviceDescriptor
movwf EP0_start
movlw high DeviceDescriptor
movwf EP0_start+1
pagesel Descriptions
call
Descriptions
movwf EP0_end
movf
BufferData+(wLength+1),f
pagesel DeviceEndPtr
btfss
STATUS,Z
goto
DeviceEndPtr
subwf BufferData+wLength,w
movf
BufferData+wLength,w
btfss
STATUS,C
movwf EP0_end
DeviceEndPtr
incf
EP0_end,f
pagesel copy_descriptor_to_EP0
call
copy_descriptor_to_EP0
return
Get_Config_Descriptor
movlw GET_DESCRIPTOR
movwf USB_dev_req
bcf
STATUS,C
rlf
BufferData+wValue,w
pagesel Config_desc_index
call
Config_desc_index
movwf EP0_start
bcf
STATUS,C
rlf
BufferData+wValue,w
addlw 1
call
Config_desc_index
movwf EP0_start+1
movlw 2
addwf EP0_start,f
btfsc
STATUS,C
incf
EP0_start+1,f
pagesel Descriptions
call
Descriptions
movwf EP0_end
movlw 2
subwf EP0_start,f
btfss
STATUS,C
decf
EP0_start+1,f
movf
BufferData+(wLength+1),f
pagesel CmpLowerByte
btfsc
STATUS,Z
goto
CmpLowerByte
pagesel ConfigEndPtr
goto
ConfigEndPtr
CmpLowerByte
movf
EP0_end,w
subwf BufferData+wLength,w
pagesel ConfigEndPtr
btfsc
STATUS,C
goto
ConfigEndPtr
LimitSize
movf BufferData+wLength,w
movwf EP0_end
ConfigEndPtr
movlw 8
movwf EP0_maxLength
incf
EP0_end,f
pagesel copy_descriptor_to_EP0
call
copy_descriptor_to_EP0
return
Get_String_Descriptor
movlw
GET_STRING_DESCRIPTOR
movwf USB_dev_req
movf BufferData+wIndex,w
pagesel not_string0
btfss STATUS,Z
goto
not_string0
movf BufferData+(wIndex+1),w
btfss STATUS,Z
goto
not_string0
movlw low String0
movwf EP0_start
movlw high String0
movwf EP0_start+1
pagesel found_string
goto
found_string
not_string0
movlw high (String0+2)
movwf EP0_start+1
movlw low (String0+2)
movwf EP0_start
clrf
inner
check_langid
pagesel StringDescriptions
call
StringDescriptions
incf
EP0_start,f
subwf BufferData+wIndex, w
pagesel wrong_langid
btfss STATUS, Z
goto
wrong_langid
pagesel StringDescriptions
call
StringDescriptions
subwf BufferData+(wIndex+1), w
pagesel right_langid
btfsc
STATUS, Z
goto
right_langid
wrong_langid
incf
EP0_start,f
incf
inner,f
movlw low String0_end
subwf EP0_start,w
pagesel check_langid
btfss STATUS,C
goto
check_langid
clrf
USB_dev_req
pagesel wrongstate
goto
wrongstate
right_langid
movlw 6
subwf BufferData+wValue,w
pagesel right_string
btfss
STATUS,C
goto
right_string
clrf
USB_dev_req
pagesel wrongstate
goto
wrongstate
right_string
rlf
BufferData+wValue,w
movwf EP0_start+1
movf
inner,w
pagesel string_index
call
string_index
movwf EP0_start
incf
EP0_start+1,f
movf
inner,w
call
string_index
movwf EP0_start+1
found_string
pagesel StringDescriptions
call
StringDescriptions
movwf EP0_end
subwf BufferData+wLength,w
movf
BufferData+wLength,w
btfss
STATUS,C
movwf EP0_end
movlw 8
movwf EP0_maxLength
incf
EP0_end,f
pagesel copy_descriptor_to_EP0
call
copy_descriptor_to_EP0
return
wrongstate
global wrongstate
banksel UEP0
bsf
UEP0,EP_STALL
bcf
STATUS,RP0
return
Get_Device_Status
bsf
STATUS,RP0
movf
BD0IAL,w
movwf FSR
bcf
STATUS,RP0
bsf
STATUS,IRP
movf
USB_status_device,w
movwf INDF
incf
FSR,f
clrf
INDF
bsf
STATUS,RP0
movlw 0x02
movwf
BD0IBC
movlw
0xC8
movwf
BD0IST
return
Get_Interface_Status
bsf
STATUS, RP0
movf
USWSTAT,w
xorlw
ADDRESS_STATE
pagesel
Get_Interface_Status2
btfss
STATUS, Z
goto
Get_Interface_Status2
bcf
STATUS, RP0
movf
BufferData+wIndex, w
pagesel
Get_Interface_Status2
btfss
STATUS, Z
goto
Get_Interface_Status2
Get_Interface_Status2
bsf
STATUS, RP0
movf
USWSTAT,w
xorlw
CONFIG_STATE
pagesel
wrongstate
btfss
STATUS, Z
goto
wrongstate
bcf
STATUS, RP0
movf
BufferData+wIndex,w
sublw
(NUM_INTERFACES-1)
pagesel
wrongstate
btfss
STATUS, C
goto
wrongstate
Get_Interface_Status_end
movf
BufferData+wIndex,w
addlw
low USB_Interface
movwf
FSR
bsf
STATUS,IRP
movf
INDF,w
movwf
temp
bsf
STATUS,RP0
movf
BD0IAL,w
movwf
FSR
movf
temp,w
movwf
INDF
movlw
0x02
movwf
BD0IBC
movlw
0xc8
movwf
BD0IST
return
Get_Endpoint_Status
movlw
0x0f
andwf
BufferData+wIndex,w
xorlw
0x01
pagesel get_EP1_status
btfsc
STATUS,Z
goto
get_EP1_status
movlw
0x0f
andwf
BufferData+wIndex,w
xorlw
0x02
pagesel
wrongstate
btfss
STATUS,Z
goto
wrongstate
get_EP2_status
bcf
STATUS,C
bsf
STATUS,RP0
btfsc
UEP2,EP_STALL
bsf
STATUS,C
pagesel
build_status_buffer
goto
build_status_buffer
get_EP1_status
bcf
STATUS,C
bsf
STATUS,RP0
btfsc
UEP1,EP_STALL
bsf
STATUS,C
build_status_buffer
movf
BD0IAL,w
movwf
FSR
clrf
INDF
rlf
INDF,f
incf
FSR,f
clrf
INDF
movlw
0x02
movwf
BD0IBC
movlw
0xC8
movwf
BD0IST
return
Set_Address
movf
BufferData+wValue,w
movwf
USB_address_pending
pagesel
wrongstate
btfsc
USB_address_pending, 7
goto
wrongstate
pagesel
Send_0Len_pkt
call
Send_0Len_pkt
movlw
SET_ADDRESS
movwf
USB_dev_req
return
finish_set_address
clrf
USB_dev_req
clrf
USB_Curr_Config
movf
USB_address_pending,w
bsf
STATUS, RP0
movwf
UADDR
pagesel
endfinishsetaddr
btfsc
STATUS,Z
goto
endfinishsetaddr
movlw
ADDRESS_STATE
movwf
USWSTAT
#ifdef SHOW_ENUM_STATUS
banksel
PORTB
bsf
PORTB,2
banksel
USWSTAT
#endif
endfinishsetaddr
return
Clear_Device_Feature
movf
BufferData+wValue,w
xorlw
0x01
pagesel wrongstate
btfss
STATUS,Z
goto
wrongstate
right_state_clear_feature
bcf
USB_status_device,1
pagesel Send_0Len_pkt
call
Send_0Len_pkt
return
Clear_Endpoint_Feature
movf
BufferData+wValue, w
pagesel wrongstate
btfss
STATUS, Z
goto
wrongstate
movf
BufferData+(wValue+1), w
btfss
STATUS, Z
goto
wrongstate
bsf
STATUS, RP0
movlw 0x03
andwf USWSTAT, w
xorlw
ADDRESS_STATE
pagesel clear_endpoint_feature2
btfss
STATUS, Z
goto
clear_endpoint_feature2
bcf
STATUS, RP0
movlw 0x0F
andwf BufferData+wIndex, w
btfss
STATUS, Z
goto
clear_endpoint_feature2
bsf
STATUS, RP0
bcf
UEP0, 0
pagesel Send_0Len_pkt
call
Send_0Len_pkt
return
clear_endpoint_feature2
bsf
STATUS, RP0
movlw 0x03
andwf USWSTAT, w
xorlw CONFIG_STATE
pagesel wrongstate
btfss
STATUS, Z
goto
wrongstate
bcf
STATUS, RP0
movlw 0x0F
andwf BufferData+wIndex, w
sublw 2
pagesel wrongstate
btfss
STATUS, C
goto
wrongstate
bsf
STATUS, IRP
movlw 0x0F
andwf BufferData+wIndex,w
bsf
STATUS, RP0
addlw UEP0&0xFF
movwf FSR
bcf
INDF, 0
pagesel Send_0Len_pkt
call
Send_0Len_pkt
return
Clear_Interface_Feature
pagesel wrongstate
goto
wrongstate
Set_Device_Feature
movf
BufferData+wValue,w
xorlw
0x01
pagesel wrongstate
btfss
STATUS,Z
goto
wrongstate
bsf
USB_status_device,1
pagesel Send_0Len_pkt
call
Send_0Len_pkt
return
Set_Endpoint_Feature
movf
BufferData+wValue, w
pagesel wrongstate
btfss
STATUS, Z
goto
wrongstate
movf
BufferData+(wValue+1), w
btfss
STATUS, Z
goto
wrongstate
bsf
STATUS, RP0
movlw 0x03
andwf USWSTAT, w
xorlw
ADDRESS_STATE
pagesel set_endpoint_feature2
btfss
STATUS, Z
goto
set_endpoint_feature2
bcf
STATUS, RP0
movlw 0x0F
andwf BufferData+wIndex, w
btfss
STATUS, Z
goto
set_endpoint_feature2
bsf
STATUS, RP0
bsf
UEP0, 0
pagesel Send_0Len_pkt
call
Send_0Len_pkt
return
set_endpoint_feature2
bsf
STATUS, RP0
movlw 0x03
andwf USWSTAT, w
xorlw CONFIG_STATE
pagesel wrongstate
btfss
STATUS, Z
goto
wrongstate
bcf
STATUS, RP0
movlw 0x0F
andwf BufferData+wIndex, w
sublw 2
pagesel wrongstate
btfss
STATUS, C
goto
wrongstate
bsf
STATUS, IRP
movlw 0x0F
andwf BufferData+wIndex,w
bsf
STATUS, RP0
addlw UEP0&0xFF
movwf FSR
bsf
INDF, 0
pagesel Send_0Len_pkt
call
Send_0Len_pkt
return
Set_Interface_Feature
pagesel wrongstate
goto
wrongstate
Get_Configuration
bsf
STATUS, RP0
movf
low BD0IAL,w
movwf FSR
bcf
STATUS, RP0
bsf
STATUS,IRP
movf
USB_Curr_Config,w
movwf INDF
bsf
STATUS, RP0
movlw 0x01
movwf BD0IBC
movlw 0xc8
movwf BD0IST
return
Set_Configuration
movf
BufferData+wValue,w
sublw NUM_CONFIGURATIONS
pagesel wrongstate
btfss
STATUS,C
goto
wrongstate
movf
BufferData+wValue,w
movwf USB_Curr_Config
pagesel AckSetConfigCmd
btfsc
STATUS,Z
goto
AckSetConfigCmd
bsf
STATUS, RP0
movlw CONFIG_STATE
movwf USWSTAT
#ifdef SHOW_ENUM_STATUS
banksel PORTB
bsf
PORTB,3
#endif
AckSetConfigCmd
pagesel Send_0Len_pkt
call
Send_0Len_pkt
banksel BD1OAL
movlw USB_Buffer+0x10
movwf BD1OAL
movlw 8
movwf BD1OBC
movlw 0x88
movwf BD1OST
movlw 8
movwf BD1IBC
movlw USB_Buffer+0x18
movwf BD1IAL
movlw 0x48
movwf BD1IST
movlw USB_Buffer+0x20
movwf BD2OAL
movlw 8
movwf BD2OBC
movlw 0x88
movwf BD2OST
movlw 8
movwf BD2IBC
movlw USB_Buffer+0x20
movwf BD2IAL
movlw 0x48
movwf BD2IST
movlw ENDPT_NON_CONTROL
movwf UEP1
movlw ENDPT_NON_CONTROL
movwf UEP2
return
Get_Interface
bsf
STATUS, RP0
movf
USWSTAT,w
xorlw
CONFIG_STATE
pagesel wrongstate
btfss
STATUS, Z
goto
wrongstate
bcf
STATUS, RP0
movf
BufferData+wIndex,w
sublw (NUM_INTERFACES-1)
pagesel wrongstate
btfss
STATUS, C
goto
wrongstate
movf
BufferData+wIndex,w
addlw low USB_Interface
movwf FSR
bsf
STATUS,IRP
movf
INDF,w
movwf temp
bsf
STATUS,RP0
movf
BD0IAL,w
movwf FSR
movf
temp,w
movwf INDF
movlw 0x01
movwf BD0IBC
movlw 0xc8
movwf BD0IST
return
Set_Interface
bsf
STATUS, RP0
movf
USWSTAT,w
bcf
STATUS,RP0
andlw 0x03
xorlw
CONFIG_STATE
pagesel wrongstate
btfss
STATUS,Z
goto
wrongstate
movf
BufferData+wIndex,w
addlw USB_Interface
movwf FSR
bsf
STATUS,IRP
movf
BufferData+wValue,w
movwf INDF
pagesel Send_0Len_pkt
call
Send_0Len_pkt
return
copy_descriptor_to_EP0
global copy_descriptor_to_EP0
banksel BD0IAL
bankisel BD0IAL
movf BD0IAL,w
movwf FSR
banksel bufindex
clrf
bufindex
gdd_loop
movf bufindex,w
subwf EP0_maxLength,w
pagesel end_gdd_loop
btfsc STATUS,Z
goto
end_gdd_loop
pagesel gdd_copy_loop
decfsz EP0_end, f
goto
gdd_copy_loop
pagesel end_gdd_loop_short_packet
goto
end_gdd_loop_short_packet
gdd_copy_loop
pagesel Descriptions
call
Descriptions
movwf INDF
incf
bufindex,f
incf
FSR,f
pagesel gdd_loop
incfsz EP0_start,f
goto
gdd_loop
incf
EP0_start+1,f
goto
gdd_loop
end_gdd_loop_short_packet
clrf
USB_dev_req
end_gdd_loop
movf bufindex,w
bsf
STATUS,RP0
movwf BD0IBC
movlw (0x01<<DATA01)
xorwf BD0IST,w
andlw (0x01<<DATA01)
iorlw
0x88
movwf BD0IST
pagesel copy_descriptor_to_EP0
return
SetConfiguration
global SetConfiguration
return
CheckVendor
global CheckVendor
return
end
PIC16C745 freeware (archivo usb_defs.inc)
#define NUM_CONFIGURATIONS 1
#define NUM_INTERFACES
1
#define SHOW_ENUM_STATUS
#define POWERED_STATE
0x00
#define DEFAULT_STATE
0x01
#define ADDRESS_STATE
0x02
#define CONFIG_STATE
0x03
#define EP_IDLE_STATE
0x00
#define EP_SETUP_STATE
0x01
#define EP_DISABLED_STATE 0xff
#define ENDPT_DISABLED
0x00
#define ENDPT_IN_ONLY
0x02
#define ENDPT_OUT_ONLY
0x04
#define ENDPT_CONTROL
0x06
#define ENDPT_NON_CONTROL
0x0E
#define INT_STAT_MASK_RESET
0x01
#define INT_STAT_MASK_ERROR
0x02
#define INT_STAT_MASK_TOKEN_DONE 0x04
#define INT_STAT_MASK_SLEEP
0x08
#define INT_STAT_MASK_STALL
0x10
#define TOKEN_OUT
(0x01<<2)
#define TOKEN_ACK
(0x02<<2)
#define TOKEN_IN
(0x09<<2)
#define TOKEN_SETUP (0x0D<<2)
#define USB_Buffer
0xB8
#define BYTECOUNT
0x01
#define ADDRESS
0x02
#define DEVICE
1
#define CONFIGURATION
2
#define STRING
3
#define INTERFACE
4
#define ENDPOINT
5
#define bmRequestType
0x00
#define bRequest
0x01
#define wValue
0x02
#define wValueHigh
0x03
#define wIndex
0x04
#define wIndexHigh
0x05
#define wLength
0x06
#define wLengthHigh
0x07
#define CLEAR_FEATURE
0x01
#define GET_CONFIGURATION
0x08
#define GET_DESCRIPTOR
0x06
#define GET_STRING_DESCRIPTOR 0x66
#define GET_INTERFACE
0x0A
#define GET_STATUS
0x00
#define SET_ADDRESS
0x05
#define SET_CONFIGURATION
0x09
#define SET_FEATURE
0x03
#define SET_INTERFACE
0x0B
#define HID_SET_REPORT
0x21
#define VEND_SET_MEMORY
0x80
#define SVCUSBINT
0x01 << 2
#define SVCTOKENDONE
0x02 << 2
#define SVCRESET
0x03 << 2
#define SVCSLEEP
0x04 << 2
#define SVCSTALL
0x05 << 2
#define SVCERROR
0x06 << 2
#define SVCACTIVITY
0x07 << 2
#define TOKENOUT
0x08 << 2
#define TOKENIN
0x09 << 2
#define TOKENSETUP
0x0A << 2
#define CLEARFEATURE
0x0B << 2
#define GETCONFIG
0x0C << 2
#define GETDESCRIPTOR
0x0D << 2
#define GETINTERFACE
0x0E << 2
#define GETSTATUS
0x0F << 2
#define SETADDRESS
0x10 << 2
#define SETCONFIG
0x11 << 2
#define SETFEATURE
0x12 << 2
#define SETINTERFACE
0x13 << 2
#define FINISHSETADDRESS
0x14 << 2
#define COPYDESC2EP0
0x15 << 2
#define COPYSTRINGDESC2EP0 0x16 << 2
#define ZEROLENPACKET
0x17 << 2
COPYBUFFERDESCRIPTOR macro
bankisel BD0OST
banksel BD0OST
movf
USTAT,w
addlw 0xA0
movwf FSR
bcf
STATUS, RP0
movf
INDF,w
movwf BufferDescriptor
incf
FSR,f
movf
INDF,w
movwf BufferDescriptor+1
incf
FSR,f
movf
INDF,w
movwf BufferDescriptor+2
endm
INCREMENT16macro index
local
endinc16
incfsz index,f
goto
endinc16
incf
index+1,f
endinc16
endm
REQUESTERROR
macro
bsf
STATUS,RP0
movf
USTAT,w
addlw 0xA0
movwf FSR
bsf
INDF,EP_STALL
bcf
STATUS,RP0
endm
ConfiguredUSB macro
local
enumloop
banksel USWSTAT
pagesel enumloop
enumloop
clrwdt
movlw 0x03
andwf USWSTAT,w
xorlw
CONFIG_STATE
btfss
STATUS,Z
goto
enumloop
endm
GETEP1 macro
GetEP1
global GetEP1
local
getEPloop
local
exitgetloop
local
nobuffer
movf
STATUS,w
banksel RP_save
movwf RP_save
movf
FSR,w
movwf dest_ptr
banksel BD1OST
pagesel nobuffer
btfsc
BD1OST,UOWN
goto
nobuffer
movf
BD1OBC,w
banksel counter
movwf counter
movwf bytecounter
pagesel exitgetloop
btfsc
STATUS,Z
goto
exitgetloop
banksel BD1OAL
movf
BD1OAL,w
banksel source_ptr
movwf source_ptr
getEPloop
bsf
STATUS,IRP
movf
source_ptr,w
movwf FSR
movf
INDF,w
movwf GPtemp
movf
dest_ptr,w
movwf FSR
btfss
RP_save,IRP
bcf
STATUS,IRP
movf
GPtemp,w
movwf INDF
incf
dest_ptr,f
incf
source_ptr,f
pagesel getEPloop
decfsz counter,f
goto
getEPloop
exitgetloop
bsf
STATUS,RP0
movf BD1OST,w
andlw 0x40
xorlw 0x40
iorlw
0x88
movwf BD1OST
movlw 0x08
movwf BD1OBC
bcf
STATUS,RP0
movf bytecounter,w
movwf GPtemp
movf RP_save,w
movwf STATUS
movf GPtemp,w
bsf
STATUS,C
return
nobuffer
banksel RP_save
movf RP_save,w
movwf STATUS
bcf
STATUS,C
return
endm
GETEP2
macro
GetEP2
global GetEP2
local
getEPloop2
local
exitgetloop2
local
nobuffer2
movf
STATUS,w
banksel RP_save
movwf RP_save
movf
FSR,w
movwf dest_ptr
banksel BD2OST
pagesel nobuffer2
btfsc
BD2OST,UOWN
goto
nobuffer2
movf
BD2OBC,w
banksel counter
movwf counter
movwf bytecounter
pagesel exitgetloop2
btfsc
STATUS,Z
goto
exitgetloop2
banksel BD2OAL
movf
BD2OAL,w
banksel source_ptr
movwf source_ptr
getEPloop2
bsf
STATUS,IRP
movf source_ptr,w
movwf FSR
movf
INDF,w
movwf GPtemp
movf
dest_ptr,w
movwf FSR
btfss
RP_save,IRP
bcf
STATUS,IRP
movf
GPtemp,w
movwf INDF
incf
dest_ptr,f
incf
source_ptr,f
pagesel getEPloop2
decfsz counter,f
goto
getEPloop2
exitgetloop2
bsf
STATUS,RP0
movf
BD2OST,w
andlw 0x40
xorlw
0x40
iorlw
0x88
movwf BD2OST
movlw 0x08
movwf BD2OBC
bcf
STATUS,RP0
movf
bytecounter,w
movwf GPtemp
movf
RP_save,w
movwf STATUS
movf
GPtemp,w
bsf
STATUS,C
return
nobuffer2
banksel RP_save
movf
RP_save,w
movwf STATUS
bcf
STATUS,C
return
endm
PUTEP1
macro
PutEP1
global PutEP1
local
putEPloop
local
exitputloop
local
nobufferputep
movwf GPtemp
movf
STATUS,w
banksel RP_save
movwf RP_save
movf
GPtemp,w
andlw 0x0F
movwf counter
movf
FSR,w
movwf source_ptr
movf
counter,w
banksel BD1IST
pagesel nobufferputep1
btfsc
BD1IST,UOWN
goto
nobufferputep1
movwf BD1IBC
pagesel exitputloop
btfsc
STATUS,Z
goto
exitputloop
movf
BD1IAL,w
bcf
STATUS,RP0
movwf dest_ptr
putEPloop
bsf
STATUS,IRP
btfss
RP_save,IRP
bcf
STATUS,IRP
movf
source_ptr,w
movwf FSR
movf
INDF,w
movwf GPtemp
bsf
STATUS,IRP
movf
dest_ptr,w
movwf FSR
movf
GPtemp,w
movwf INDF
incf
dest_ptr,f
incf
source_ptr,f
pagesel putEPloop
decfsz counter,f
goto
putEPloop
exitputloop
bsf
STATUS,RP0
movf BD1IST,w
andlw 0x40
xorlw 0x40
iorlw
0x88
movwf BD1IST
banksel RP_save
movf
RP_save,w
movwf STATUS
bsf
STATUS,C
return
nobufferputep1
bcf
STATUS,C
return
endm
PUTEP2
macro
PutEP2
global PutEP2
local
putEPloop2
local
exitputloop2
local
nobufferputep2
movwf GPtemp
movf
STATUS,w
banksel RP_save
movwf RP_save
movf
GPtemp,w
andlw 0x0F
movwf counter
movf
FSR,w
movwf source_ptr
movf
counter,w
banksel BD2IST
pagesel nobufferputep2
btfsc
BD2IST,UOWN
goto
nobufferputep2
movwf BD2IBC
pagesel exitputloop2
btfsc
STATUS,Z
goto
exitputloop2
movf
BD2IAL,w
bcf
STATUS,RP0
movwf dest_ptr
putEPloop2
bsf
STATUS,IRP
btfss
RP_save,IRP
bcf
STATUS,IRP
movf
source_ptr,w
movwf FSR
movf
INDF,w
movwf GPtemp
bsf
STATUS,IRP
movf
dest_ptr,w
movwf FSR
movf
GPtemp,w
movwf INDF
incf
dest_ptr,f
incf
source_ptr,f
pagesel putEPloop2
decfsz counter,f
goto
exitputloop2
bsf
movf
andlw
xorlw
iorlw
movwf
putEPloop2
banksel RP_save
movf RP_save,w
movwf STATUS
bsf
STATUS,C
return
nobufferputep2
bcf
STATUS,C
return
endm
STATUS,RP0
BD2IST,w
0x40
0x40
0x88
BD2IST
Código completo PIC16F628 interfaz con la PC (archivo esclavo2.asm)
LIST p=16F628
RADIX HEX
#include "P16f628.inc"
__config _HS_OSC &
_MCLRE_OFF & _LVP_OFF &
_WDT_OFF & _PWRTE_ON &
_CP_OFF & _BODEN_OFF
;================>registros
;banco 0
estado equ
0x03
tmr0
equ
0x01
portb equ 0x06
porta equ
0x05
pir1
equ
0x0C
rcsta equ
0x18
txreg equ
0x19
rcreg equ
0x1A
intcon equ
0x0B
cmcon equ
0x1F
fsr
equ
0x04
;banco 1
trisb
equ
0x06
trisa
equ
0x05
pcon equ
0x0E
opcion equ
0x01
pie1
equ
0x0C
txsta equ
0x18
spbrg equ
0x19
;bits
RP0
equ 0x05
INTF equ
0x01
INTE equ
0x04
TOIE equ
0x05
TOIF equ
0x02
OSCF equ 0x03
CREN equ
0x04
TXEN equ
0x05
RCIF equ
0x05
TXIF equ
0x04
TRMT equ
0x01
Z
equ
C
equ
SPEN
equ
;variables
f
equ
w
equ
overflow equ
cont
equ
multiplo equ
multiplo2 equ
multiplo3 equ
aux1
equ
aux2
equ
aux3
equ
aux4
equ
aux5
equ
var1
equ
clave1
equ
clave2
equ
clave3
equ
var2
equ
resta
equ
0x02
0x00
0x07
0x20
0x21
0x22
0x23
0x24
0x25
0x26
0x27
0x28
0x29
0x2A
0x2B
0x2C
0x2D
0x2E
0x2F
0x41
0x42
org
goto
org
goto
0x00
Inicio
0x04
Servicio
call
call
goto
inicial
serial
ciclo
Inicio
ciclo
Servicio
btfss
goto
decf
btfss
goto
clrf
intcon,INTF
Tmr0int
cont,f
estado,Z
muestra
tmr0
bcf intcon,INTF
bcf intcon,TOIF
bsf intcon,TOIE
retfie
Tmr0int
btfss intcon,TOIE
goto recep_rx
btfss intcon,TOIF
retfie
incf overflow,f
bcf intcon,TOIF
retfie
recep_rx
btfss pir1,RCIF
retfie
movf rcreg,w
subwf clave1,w
btfss estado,2
goto mm
bsf
portb,0x06
retfie
mm
movf rcreg,w
subwf clave2,w
btfss estado,2
retfie
bcf portb,0x06
call delay
bcf rcsta,CREN
tt
btfss portb,0x05
goto
tt
bsf portb,0x04
bsf intcon,INTE
retfie
muestra
movf tmr0,w
movwf resta
movlw 0x0C
subwf resta,w
movwf INDF
incf
fsr,f
movf
movwf
incf
clrf
clrf
incf
bcf
bcf
bcf
decf
btfss
retfie
movlw
movwf
bcf
transmitir
bsf
movlw
movwf
movlw
movwf
bsf
bsf
bcf
bsf
otra
incf
movf
movwf
bsf
ansina
btfss
goto
bcf
decf
btfss
goto
overflow,w
INDF
fsr,f
overflow
cont
cont,f
intcon,TOIF
intcon,TOIE
intcon,INTF
var1,f
estado,Z
0x08
var1
portb,0x04
portb,0x03
0x08
aux1
0x37
fsr
estado,RP0
txsta,TXEN
estado,RP0
porta,0x00
fsr,f
INDF,w
txreg
estado,RP0
txsta,TRMT
ansina
estado,RP0
aux1,f
estado,Z
otra
salir
bcf
portb,0x03
clrf
portb
clrf
porta
bsf
rcsta,CREN
bsf
estado,RP0
bcf
txsta,TXEN
bcf
estado,RP0
movlw 0x30
movwf fsr
bcf
intcon,INTE
retfie
;===========>FUNCIONES
serial
bsf
estado,RP0
movlw b'00010000'
movwf txsta
bcf
estado,RP0
movlw b'10010000'
movwf rcsta
return
inicial
bsf
estado,RP0
movlw b'00100111'
movwf trisb
clrf
trisa
bsf
trisa,0x05
movlw b'11001000'
movwf opcion
movlw b'11000000'
movwf intcon
bsf
pie1,RCIE
bcf
pie1,TXIE
bcf
estado,RP0
bcf
pir1,RCIF
bcf
pir1,TXIF
movlw 0xAA
movwf clave1
movlw 0xBB
movwf clave2
movlw 0xCC
movwf clave3
clrf
porta
movlw 0x07
movwf cmcon
clrf
w
movlw 0x01
movwf f
movwf cont
movlw 0x30
movwf fsr
movlw 0x04
movwf var1
clrf
overflow
clrf
portb
bcf
portb,0x03
return
delay
banksel multiplo
movlw 0x1B
movwf multiplo3
si2
clrf
multiplo2
si1
clrf
multiplo
si
decf
multiplo,f
btfss STATUS,2
goto
si
decf
multiplo2,f
btfss STATUS,2
goto
si1
decf
multiplo3,f
btfss STATUS,2
goto
si2
return
end
Código completo PIC16C745 interfaz con el PLC (archivo chicotex.asm)
#include <p16c745.inc>
#include "usb_defs.inc"
errorlevel -302
__CONFIG
_H4_OSC & _WDT_OFF &
_PWRTE_OFF & _CP_OFF
unbanked
W_save
bank0
Status_save
PCLATH_save
FSR_save
udata_shr
res
1
udata
res
1
res
1
res
1
outbuffer
periodos
multiplo
multiplo2
multiplo3
clave1
clave2
clave3
aux
aux1
aux2
aux3
res
res
res
res
res
res
res
res
res
res
res
res
8
1
1
1
1
1
1
1
1
1
1
1
aux4
aux5
aux6
aux7
extern
extern
extern
extern
extern
extern
res
res
res
res
1
1
1
1
InitUSB
PutEP1
GetEP1
ServiceUSBInt
CheckSleep
RemoteWakeup
STARTUP
code
pagesel main
goto
main
nop
InterruptServiceVector
movwf W_save
movf STATUS,W
clrf
STATUS
movwf Status_save
movf PCLATH,w
movwf PCLATH_save
movf FSR,w
movwf FSR_save
Process_ISR
btfsc
INTCON,INTF
nop
btfsc
INTCON,T0IF
nop
btfsc
INTCON,RBIF
nop
BANKSEL PIR1
pagesel
ServiceUSBInt
btfsc
PIR1,USBIF
call
ServiceUSBInt
btfsc
PIR1,ADIF
nop
btfsc PIR1,RCIF
nop
btfsc PIR1,TXIF
nop
btfsc PIR1,CCP1IF
nop
btfsc PIR1,TMR2IF
nop
btfsc PIR1,TMR1IF
nop
btfsc PIR2,CCP2IF
nop
EndISR
clrf
STATUS
movf FSR_save,w
movwf FSR
movf PCLATH_save,w
movwf PCLATH
movf
movwf
swapf
swapf
retfie
code
Status_save,w
STATUS
W_save,f
W_save,w
main
banksel
TRISA
clrf
TRISC
bsf
TRISC,0x07
bsf
TRISC,0x06
movlw
0x06
movwf
ADCON1
clrf
TRISA
bsf
TRISA,0x02
clrf
TRISB
banksel
PORTA
clrf
PORTA
clrf
PORTB
movlw
.30
movwf
W_save
decfsz
W_save,f
goto
$-1
BANKSEL OPTION_REG
bcf
OPTION_REG,NOT_RBPU
pagesel
InitUSB
call
InitUSB
ConfiguredUSB
call
inicializar
call
ini_tx
;=====================>PROCESOS
LoopForData
pagesel GetEP1
banksel outbuffer
bankisel outbuffer
movlw outbuffer
movwf FSR
movlw 0x8
call
GetEP1
pagesel ndatos
btfss STATUS,C
goto
LoopForData
bcf
STATUS,C
btfss aux6,0x00
call
ndatos
call
buffer_ram
decf
aux7,f
btfss STATUS,2
goto
EndLoopForData
call
ram_serial
goto
EndLoopForData
EndLoopForData
pagesel LoopForData
goto
LoopForData
;====================>FUNCIONES
inicializar
banksel SPBRG
bcf
PIE1,RCIE
bcf
PIE1,TXIE
banksel PIR1
bcf
PIR1,RCIF
bcf
PIR1,TXIF
banksel aux3
clrf
aux3
clrf
aux6
return
ini_tx
banksel TXSTA
movlw 0xB0
movwf TXSTA
banksel RCSTA
movlw 0x80
movwf RCSTA
return
ini_rx
banksel TXSTA
movlw 0x90
movwf TXSTA
banksel RCSTA
movlw 0xA0
movwf RCSTA
return
ndatos
banksel outbuffer
movlw outbuffer
movwf FSR
movf INDF,w
movwf aux7
movwf aux5
bsf
aux6,0x00
return
incremento
movlw 0x08
movwf aux
movlw outbuffer
movwf FSR
otr
incf
INDF,f
incf
FSR,f
decf
aux,f
btfsc STATUS,2
return
goto
otr
return
buffer_ram
clrf
aux1
movlw 0x08
movwf aux
dat1
movlw outbuffer
movwf FSR
movf aux1,w
addwf FSR,f
movf INDF,w
movwf aux2
movlw 0x40
movwf FSR
movf aux3,w
addwf FSR,f
movf aux2,w
movwf INDF
incf
aux1,f
incf
aux3,f
decf
aux,f
btfss STATUS,2
goto
dat1
return
ram_serial
movlw 0x41
movwf FSR
movf INDF,w
movwf aux
decf
FSR,f
dat2
movf INDF,w
movwf TXREG
incf
FSR,f
decf
aux,f
btfsc STATUS,2
return
movlw .100
movwf W_save
decfsz W_save,fgoto $-1
goto
dat2
return
end
Código completo PIC16F628 interfaz con el PLC (archivo esclavo2.asm)
LIST p=16F628
RADIX HEX
#include "P16f628.inc"
__config _HS_OSC & _MCLRE_OFF &
_LVP_OFF & _WDT_OFF & _PWRTE_ON &
_CP_OFF & _BODEN_OFF
;================>registros
estado equ
0x03
tmr0
equ
0x01
portb equ
0x06
porta equ
0x05
pir1
equ
0x0C
tmr2
equ
0x11
t2con equ
0x12
ccpr1l equ
0x15
ccp1con equ 0x17
rcsta equ
0x18
txreg equ
0x19
rcreg equ
0x1A
intcon equ
0x0B
cmcon equ
0x1F
fsr
equ
0x04
trisb
equ
0x06
trisa
equ
0x05
pcon equ
0x0E
opcion equ
0x01
pie1
equ
0x0C
pr2
equ
0x12
txsta equ
0x18
spbrg equ
0x19
RP0
equ
0x05
INTF equ
0x01
INTE equ
0x04
TOIE equ
0x05
TOIF equ
0x02
CREN equ
0x04
TXEN equ
0x05
RCIF equ
0x05
TXIF equ
0x04
TRMT equ
0x01
Z
equ
0x02
C
equ
0x00
SPEN equ
0x07
f
equ
0x20
w
equ
0x21
var1
equ
0x22
var2
equ
0x23
multiplo
equ
0x24
multiplo2
equ
0x25
multiplo3
equ
0x26
aux1
equ
0x27
aux2
aux3
seg
min
hor
overflow1
overflow2
ret
trans
aux4
frec
cnt
equ
equ
equ
equ
equ
equ
equ
equ
equ
equ
equ
equ
0x28
0x29
0x2A
0x2B
0x2C
0x2D
0x2E
0x2F
0x7B
0x7C
0x7D
0x7E
org
goto
org
goto
0x00
Inicio
0x04
Servicio
call
call
goto
inicial
serial
ciclo
Inicio
ciclo
Servicio
btfss
goto
btfss
retfie
bcf
incf
btfss
retfie
incf
movf
subwf
btfss
retfie
clrf
incf
btfsc
incf
btfsc
incf
movf
subwf
btfss
retfie
movf
subwf
btfss
retfie
intcon,TOIE
recep_rx
intcon,TOIF
intcon,TOIF
overflow1,f
estado,Z
overflow2,f
var2,w
overflow2,w
estado,Z
overflow2
aux1,f
estado,Z
aux2,f
estado,Z
aux3,f
seg,w
aux1,w
estado,Z
min,w
aux2,w
estado,Z
movf
subwf
btfss
retfie
clrf
movlw
movwf
movf
movwf
bsf
hor,w
aux3,w
estado,Z
bsf
call
movlw
movwf
incf
movf
movwf
portb,0x06
delay
0xFF
aux3
fsr,f
INDF,w
ret
call
decf
btfss
goto
bcf
call
bcf
rlf
movwf
incf
call
clrf
decf
btfss
goto
clrf
clrf
bcf
clrf
incf
retfie
recep_rx
btfss
retfie
movf
movwf
incf
btfss
goto
movf
movwf
movwf
decf
decf
ok
incf
TONO
aux3,f
estado,Z
Period
portb,0x06
delay2
estado,C
trans,w
porta
trans,f
delay2
porta
cnt,f
estado,Z
cambio
aux2
aux3
portb,0x04
trans
trans,f
aux1
0x34
fsr
frec,w
cnt
portb,0x04
cambio
Period
pir1,RCIF
rcreg,w
INDF
fsr,f
pir1,RCIF
$-1
rcreg,w
INDF
var1
var1,f
var1,f
fsr,f
btfss
goto
movf
movwf
decf
btfsc
goto
goto
pir1,RCIF
$-1
rcreg,w
INDF
var1,f
estado,Z
algo
ok
algo
call
datos
bcf
rcsta,CREN
bcf
intcon,TOIF
clrf
tmr0
bsf
intcon,TOIE
bcf
portb,0x03
retfie
;====================>FUNCIONES
serial
bsf
estado,RP0
movlw b'00010000'
movwf txsta
bcf
estado,RP0
movlw b'10010000'
movwf rcsta
return
inicial
bsf
estado,RP0
movlw b'00000110'
movwf trisb
clrf
trisa
movlw b'11001000'
movwf opcion
movlw b'11000000'
movwf intcon
bsf
pie1,RCIE
bcf
pie1,TXIE
bcf
estado,RP0
bcf
pir1,RCIF
bcf
pir1,TXIF
clrf
porta
movlw 0x07
movwf cmcon
clrf
w
movlw 0x01
movwf f
movlw 0x30
movwf fsr
movlw 0x1F
movwf var2
clrf
overflow1
clrf
overflow2
clrf
aux1
clrf
aux2
clrf
aux3
clrf
portb
bsf
portb,0x03
clrf
trans
incf
trans,f
return
datos
movlw
movwf
movf
movwf
movlw
subwf
incf
movf
movwf
incf
movf
movwf
incf
movf
movwf
return
TONO bsf
call
bcf
call
return
RETARDO
movf
movwf
Bucle2 decf
btfss
goto
return
0x31
fsr
INDF,w
frec
0x05
frec,f
fsr,f
INDF,w
seg
fsr,f
INDF,w
min
fsr,f
INDF,w
hor
portb,0x07
RETARDO
portb,0x07
RETARDO
ret,w
var1
var1,f
estado,Z
Bucle2
delay
si2
si1
si
banksel multiplo
movlw 0x03
movwf multiplo3
clrf
multiplo2
clrf
multiplo
decf
multiplo,f
btfss STATUS,2
goto
si
decf
multiplo2,f
btfss STATUS,2
goto
si1
decf
multiplo3,f
btfss STATUS,2
goto
si2
return
delay2
zi2
zi1
zi
goto
decf
goto
banksel multiplo
movlw 0x1B
movwf multiplo3
clrf
multiplo2
clrf
multiplo
decf
multiplo,f
btfss STATUS,2
zi
decf
multiplo2,f
btfss STATUS,2
goto
zi1
multiplo3,f
btfss STATUS,2
zi2
return
end
Código completo PIC16F873 (archivo 16f873.asm)
#include <p16f873.inc>
RADIX HEX
errorlevel -302
__CONFIG
_HS_OSC & _WDT_OFF & _PWRTE_OFF & _CP_OFF
tmr0
estado
FSR
porta
portb
portc
intcon
pir1
rcsta
txreg
rcreg
adresh
equ
equ
equ
equ
equ
equ
equ
equ
equ
equ
equ
equ
0x01
0x03
0x04
0x05
0x06
0x07
0x0B
0x0C
0x18
0x19
0x1A
0x1E
adcon0 equ
opcion equ
trisa
equ
trisb
equ
trisc
equ
pie1
equ
txsta equ
spbrg equ
adresl equ
adcon1 equ
RP0
equ
Z
equ
C
equ
INTF
equ
TOIF
equ
INTE
equ
TOIE
equ
ADIF
equ
RCIF
equ
ADON
equ
GODONE equ
overf equ
cont
equ
palta equ
pbaja equ
f
equ
w
equ
sobra equ
veces equ
vuelta equ
cte
equ
vuelta2 equ
resta equ
fa
equ
of1
equ
sb1
equ
sb2
equ
0x1F
0x01
0x05
0x06
0x07
0x0C
0x18
0x19
0x1E
0x1F
0x05
0x02
0x00
0x01
0x02
0x04
0x05
0x06
0x05
0x00
0x02
0x20
0x21
0x22
0x23
0x24
0x25
0x26
0x27
0x28
0x29
0x2A
0x2B
0x2C
0x2D
0x2E
0x30
org
0x00
goto
Inicio
org
0x04
goto
Servicio
Inicio bsf
estado,RP0
movlw b'11001111'
movwf opcion
movlw b'10001110'
movwf adcon1
clrf
pie1
clrf
trisb
bsf
trisb,0x00
clrf
trisa
bsf
trisa,0x00
movlw b'00011100'
movwf trisc
bcf
estado,RP0
movlw 0x01
movwf f
movwf cont
clrf
movlw
movwf
clrf
clrf
clrf
clrf
clrf
clrf
clrf
movlw
movwf
movlw
movwf
movlw
movwf
clrf
btfsc
goto
incf
mk
btfsc
goto
incf
incf
frec1
movlw
subwf
btfss
goto
movlw
movwf
movlw
movwf
movlw
movwf
goto
frec2
movlw
subwf
btfss
goto
movlw
movwf
movlw
movwf
movlw
movwf
goto
frec3
movlw
subwf
btfss
goto
movlw 0x07
w
b'11010000'
intcon
adcon0
porta
portb
portc
overf
sobra
veces
0xF9
cte
0x14
vuelta
0x05
palta
fa
portc,0x02
mk
fa,f
portc,0x03
frec1
fa,f
fa,f
0x03
fa,w
estado,0x02
frec2
0x06
of1
0xE0
sb1
0xC2
sb2
ciclo
0x02
fa,w
estado,0x02
frec3
0x07
of1
0x31
sb1
0x10
sb2
ciclo
0x01
fa,w
estado,0x02
frec4
movwf
movlw
movwf
movlw
movwf
goto
of1
0x8A
sb1
0x65
sb2
ciclo
frec4
movlw
movwf
movlw
movwf
movlw
movwf
ciclo
btfsc
goto
goto
Servicio
btfss
goto
decf
btfss
goto
clrf
bcf
goto
0x07
of1
0xE4
sb1
0xBC
sb2
portc,0x04
ciclo
Activar
intcon,INTF
Tmr0int
cont,f
estado,Z
Puerto
tmr0
intcon,INTF
Atajo
Tmr0int
btfss
retfie
incf
intcon,TOIF
bcf
bsf
retfie
intcon,TOIF
intcon,TOIE
overf,f
Atajo
Puerto
movf tmr0,w
interrupción
movwf cont
movf of1,w
subwf overf,w
btfss estado,Z
goto
Noes
movf sb1,w
subwf cont,w
btfsc estado,C
goto
Noes
movf sb2,w
subwf cont,w
btfss estado,C
goto
Noes
decf
palta,f
btfss estado,Z
goto
Ruido
Activar
bsf
porta,0x05
bcf
intcon,INTE
bcf
call
call
call
call
call
call
call
call
call
bsf
call
Per
bsf
Chk
btfss
goto
bcf
bcf
bsf
call
call
movf
movwf
bsf
movf
bcf
movwf
call
movf
movwf
clrf
call
call
movwf
movlw
movwf
Period call
decf
btfss
goto
decf
btfss
goto
call
movlw
movwf
Noes movlw
movwf
Ruido clrf
Salir
clrf
clrf
clrf
clrf
movlw
movwf
movlw
movwf
intcon,TOIE
DELAY
DELAY
DELAY
DELAY
DELAY
DELAY
DELAY
DELAY
DELAY
adcon0,ADON
DELAY
adcon0,GODONE
pir1,ADIF
Chk
pir1,ADIF
porta,0x05
porta,0x02
DELAY
DELAY
adresh,w
palta
estado,RP0
adresl,w
estado,RP0
pbaja
DIV
sobra,w
pbaja
palta
DIV
CALC
sobra
0xFF
vuelta2
TONO
vuelta2,f
estado,Z
Period
vuelta,f
estado,Z
Period
DELAY
0x02
vuelta
0x05
palta
porta
w
overf
sobra
veces
0x01
cont
0xF9
cte
movlw
movwf
bcf
bcf
bcf
bsf
retfie
DELAY movlw
movwf
movlw
bucle3 movwf
bucle2 movwf
bucle1 decf
btfss
goto
decf
btfss
goto
decf
btfss
goto
return
0x14
vuelta
intcon,TOIF
intcon,TOIE
intcon,INTF
intcon,INTE
0x02
palta
0xFF
overf
cont
cont,f
estado,Z
bucle1
overf,f
estado,Z
bucle2
palta,f
estado,Z
bucle3
DIV
movlw 0x0A
Resta subwf pbaja,f
btfss estado,C
goto
Alta
incf
veces,f
goto
Resta
Alta
addwf
addwf
movlw
subwf
btfss
return
movlw
movwf
goto
pbaja,w
sobra,f
0x01
palta,f
estado,C
CALC bcf
rlf
movf
subwf
return
estado,C
veces,f
veces,w
cte,w
TONO bsf
call
bcf
call
return
porta,0x01
RETARDO
porta,0x01
RETARDO
RETARDO
movf
movwf
decf
btfss
goto
return
Bucle2
0xFF
pbaja
DIV
sobra,w
cont
cont,f
estado,Z
Bucle2
end
Código Visual Basic interfaz con la PC (archivo chicotex.vbp)
Dim buffer() As Byte
Dim buffer2() As Byte
Dim llego, manual, auto As Boolean
Dim askaban As Integer
Private Sub banterior3_Click()
If interfaz.rslectura.EOF Then
Exit Sub
End If
interfaz.rslectura.MovePrevious
Call humedad
If interfaz.rslectura.BOF Then
interfaz.rslectura.MoveFirst
Call humedad
End If
End Sub
Private Sub bcancel2_Click()
txthor.Locked = True
txtmin.Locked = True
interfaz.rstablatiempo.CancelUpdate
End Sub
Private Sub beditar2_Click()
txthor.Locked = False
txtmin.Locked = False
txtfrecuencia.SetFocus
End Sub
Private Sub beliminar2_Click()
interfaz.rstablatiempo.Delete
If interfaz.rstablatiempo.EOF Then
Exit Sub
End If
interfaz.rstablatiempo.MoveNext
If interfaz.rstablatiempo.EOF Then
interfaz.rstablatiempo.MoveLast
End If
End Sub
Private Sub beditar_Click()
txtfrecuencia.Locked = False
txtfrecuencia.SetFocus
End Sub
Private Sub bnuevo2_Click()
interfaz.rstablatiempo.AddNew
txthor.Text = ""
txtmin.Text = ""
txthor.Locked = False
txtmin.Locked = False
txthor.SetFocus
End Sub
Private Sub bguardar_Click()
interfaz.rstablatrans.Update
End Sub
Private Sub bprimero_Click()
Private Sub beliminar_Click()
If interfaz.rstablatrans.EOF Then
Exit Sub
End If
interfaz.rstablatrans.Delete
If interfaz.rstablatrans.EOF Then
Exit Sub
End If
interfaz.rstablatrans.MoveFirst
End Sub
Private Sub banterior_Click()
interfaz.rstablatrans.MoveNext
If interfaz.rstablatrans.EOF Then
interfaz.rstablatrans.MoveLast
End If
If interfaz.rstablatrans.EOF Then
Exit Sub
End If
interfaz.rstablatrans.MovePrevious
End Sub
Private Sub bguardar2_Click()
interfaz.rstablatiempo.Update
End Sub
If interfaz.rstablatrans.BOF Then
interfaz.rstablatrans.MoveFirst
End If
End Sub
Private Sub biniciar_Click()
llego = False
auto = True
tim3.Enabled = True
biniciar.Enabled = False
End Sub
Private Sub bnuevo_Click()
interfaz.rstablatrans.AddNew
txtfrecuencia.Text = ""
txtfrecuencia.Locked = False
txtfrecuencia.SetFocus
End Sub
Private Sub bcancel_Click()
txtfrecuencia.Locked = True
interfaz.rstablatrans.CancelUpdate
End Sub
Private Sub bprimero3_Click()
If interfaz.rslectura.EOF Then
Exit Sub
End If
interfaz.rslectura.MoveFirst
Call humedad
End Sub
Private Sub bsiguiente_Click()
If interfaz.rstablatrans.EOF Then
Exit Sub
End If
interfaz.rstablatrans.MoveNext
If interfaz.rstablatrans.EOF Then
interfaz.rstablatrans.MoveLast
End If
If interfaz.rstablatiempo.EOF Then
Exit Sub
End If
End Sub
interfaz.rstablatiempo.MoveNext
Private Sub bsiguiente3_Click()
If interfaz.rslectura.EOF Then
Exit Sub
End If
If interfaz.rstablatiempo.EOF Then
interfaz.rstablatiempo.MoveLast
End If
End Sub
interfaz.rslectura.MoveNext
Call humedad
Private Sub bultimo2_Click()
If interfaz.rslectura.EOF Then
interfaz.rslectura.MoveLast
Call humedad
End If
If interfaz.rstablatiempo.EOF Then
Exit Sub
End If
interfaz.rstablatiempo.MoveLast
End Sub
End Sub
Private Sub bultimo_Click()
Private Sub benviar_Click()
ReDim buffer(8)
ReDim buffer2(8)
If interfaz.rstablatrans.EOF Then
Exit Sub
End If
buffer2() = HIDComm1.ReadFrom(8)
interfaz.rstablatrans.MoveLast
End Sub
On Error Resume Next
Call blimpiar_Click
Call bcalc_Click
benviar.Enabled = False
Private Sub bprimero2_Click()
If interfaz.rstablatiempo.EOF Then
Exit Sub
End If
interfaz.rstablatiempo.MoveFirst
End Sub
buffer(0) = t.Text
buffer(1) = t1.Text
buffer(2) = t2.Text
buffer(3) = t3.Text
buffer(4) = t4.Text
buffer(5) = t5.Text
HIDComm1.WriteTo buffer(), 8
Private Sub banterior2_Click()
If interfaz.rstablatiempo.EOF Then
Exit Sub
End If
interfaz.rstablatiempo.MovePrevious
If interfaz.rstablatiempo.BOF Then
interfaz.rstablatiempo.MoveFirst
End If
End Sub
Private Sub bsiguiente2_Click()
tim2.Enabled = True
manual = True
End Sub
Private Sub blimpiar_Click()
t.Text = ""
t1.Text = ""
t2.Text = ""
t3.Text = ""
t4.Text = ""
t5.Text = ""
t6.Text = ""
t7.Text = ""
End Sub
Private Sub bultimo3_Click()
If interfaz.rslectura.EOF Then
Exit Sub
End If
interfaz.rslectura.MoveLast
Call humedad
End Sub
Private Sub Form_Load()
askaban = 0
llego = False
manual = False
auto = False
Call bprimero3_Click
HIDComm1.Connect
End Sub
Private Sub Form_Terminate()
HIDComm1.Uninit
End Sub
Private
Sub
HIDComm1_ConnectSuccess(ByVal Status As
Long)
benviar.Enabled = True
f1.Caption = "USB-PIC Conectado"
t4.Text = buffer2(4)
t5.Text = buffer2(5)
t6.Text = buffer2(6)
t7.Text = buffer2(7)
interfaz.rslectura.AddNew
txtid.Text = ""
txtsobra.Text = ""
txtoverflow.Text = ""
txttiempo.Text = ""
txtfecha.Text = ""
If buffer2(5) <> 0 Then
txtsobra.Text = t4.Text
txtoverflow.Text = t5.Text
Else
txtsobra.Text = t6.Text
txtoverflow.Text = t7.Text
End If
If Right(Time, 4) = "p.m." Then
If Left(Time, 2) <> 12 Then
ra = Left(Time, 2) + 12
End If
ra = Left(Time, 2)
Else
ra = Left(Time, 2)
End If
txttiempo.Text = Trim(Str(ra)) & Mid(Time,
3, 3)
txtfecha.Text = Date
End Sub
interfaz.rslectura.Update
Private Sub HIDComm1_Disconnected(ByVal
Status As Long)
tim2.Enabled = False
benviar.Enabled = False
f1.Caption = "USB-PIC DESCONECTADO"
End Sub
Private Sub tim2_Timer()
ReDim buffer2(8)
Dim ra As Integer
buffer2() = HIDComm1.ReadFrom(8)
If manual = True Then
manual = False
End If
llego = True
askaban = 0
benviar.Enabled = True
Else
askaban = askaban + 1
End If
If (buffer2(5) <> 0) Or (buffer2(7) <> 0) Then
t.Text = buffer2(0)
t1.Text = buffer2(1)
t2.Text = buffer2(2)
t3.Text = buffer2(3)
If askaban >= 6 Then
MsgBox "error"
tim2.Enabled = False
If manual = True Then
manual = False
End If
llego = True
benviar.Enabled = True
askaban = 0
End If
End Sub
Private Sub bcalc_Click()
Dim s As Double
Dim r As Double
Dim veces As Integer
Dim sobra As Integer
s = (Val(tnum.Text) / 1000)
r = (1.01983321076 * s * s * s * s * s * s) (21.76684340806 * s * s * s * s * s) +
(189.46208279318 * s * s * s * s) (867.57740836853 * s * s * s) +
(2246.43786488113
*
s
*
s)
(3275.43053009874 * s) + 2474.90135900252
veces = r \ 255
sobra = (r Mod 255)
t.Text = "1"
t1.Text = "1"
t2.Text = "1"
t3.Text = "1"
t4.Text = "1"
t5.Text = "1"
If veces > 1 Then
t3.Text = Trim(Str(sobra))
t4.Text = "255"
t5.Text = "255"
End If
If veces = 1 Then
t4.Text = Trim(Str(sobra))
t5.Text = "255"
End If
If veces < 1 Then
t5.Text = Trim(Str(sobra))
End If
Private Sub humedad()
Dim ll As Double
ll = (Val(Trim(txtoverflow.Text)) * 255) +
Val(Trim(txtsobra.Text))
ll = ((((0.00000002409442 * ll * ll) (0.00330379596851
*
ll))
+
6.51707742555624) * 20)
If (ll <= 101) And (ll > 0) Then
panel.FloodPercent = ll
eti.Caption = "Humedad"
Else
eti.Caption = "Valor Fuera de Rango"
panel.FloodPercent = 0
End If
End Sub
Private Sub tim3_Timer()
Dim j As Integer
Dim lk As Integer
Call bprimero_Click
Call bprimero2_Click
If Right(Time, 4) = "p.m." Then
lk = Left(Time, 2) + 12
Else
lk = Left(Time, 2)
End If
otracomp:
If Trim(txthor.Text) = Trim(Str(lk)) And
Trim(txtmin.Text) = Trim(Str(Mid(Time, 4,
2))) Then
otrotrans:
tnum.Text = txtfrecuencia.Text
Call bcalc_Click
Call benviar_Click
j=0
Do While llego = False
j=j+1
If j = 1000 Then
DoEvents
j=0
End If
Loop
interfaz.rstablatrans.MoveNext
End Sub
If interfaz.rstablatrans.EOF Then
interfaz.rstablatrans.MoveFirst
GoTo condini:
End If
GoTo otrotrans:
interfaz.rstablatiempo.MoveFirst
GoTo condini:
End If
End If
Else
interfaz.rstablatiempo.MoveNext
GoTo otracomp:
condini:
If interfaz.rstablatiempo.EOF Then
End Sub
Código Visual Basic interfaz con el PLC (archivo chicotex.vbp)
Dim buffer() As Byte
Dim trans() As Byte
Dim orale() As Byte
Dim todo() As Byte
Dim registro As Integer
Dim n As Double
Dim edo As Boolean
Private Sub bbase_Click()
If edo = False Then
frame.Visible = True
list.Visible = False
bbase.Caption = "cambiar a lista"
edo = True
Else
frame.Visible = False
list.Visible = True
bbase.Caption = "Cambiar a DB"
edo = False
End If
End Sub
Private Sub benviar_Click()
ReDim buffer(50)
ReDim trans(8)
ReDim orale(8)
Dim i, n, l, o, p As Integer
Dim lop As Long
n = (Val(Trim(thoras.Text)) * 3600)
n = n + (Val(Trim(tminutos.Text)) * 60)
n = n + (Val(Trim(tsegundos.Text)))
i = n \ 255
If i > 255 Then
buffer(4) = n \ 3600
n = n Mod 3600
End If
buffer(3) = n \ 255
i = n Mod 255
buffer(2) = i
i=6
interfaz.rscntb.MoveFirst
buffer(5) = Val(Trim(txtnumero.Text))
otra:
interfaz.rscntb.MoveNext
If interfaz.rscntb.EOF Then
interfaz.rscntb.MoveFirst
GoTo salir
Else
buffer(i) = Val(Trim(txtnumero.Text))
i=i+1
End If
On Error Resume Next
GoTo otra
salir:
p = list.ListCount + 5
n=0
buffer(0) = p \ 8
For i = 0 To (p - 1)
trans(n) = buffer(i)
n=n+1
If n > 7 Then
If (p Mod 8) > 0 Then
buffer(0) = buffer(0) + 1
End If
buffer(1) = p
HIDComm1.WriteTo trans(), 8
For l = 0 To 60000
o=0
o=0+1
Next
n=0
End If
Next
If (p Mod 8) <> 0 Then
For l = 0 To 60000
o=0
o=0+1
Next
HIDComm1.WriteTo trans(), 8
End If
End Sub
Private Sub bguardar_Click()
n = (list.ListCount * 50) + 1000
n = n / 1000
n = (0.29124078463 * n * n * n * n * n * n) (6.32150481492 * n * n * n * n * n) +
(56.25953631003 * n * n * n * n) (264.41332239284 * n * n * n) +
(703.60080448892 * n * n) (1051.76677189924 * n) + 809.77563804734
n = Round(n, 0)
txtnumero.Text = Str(n)
interfaz.rscntb.Update
txttransductor.Locked = True
txtnumero.Locked = True
list.AddItem Trim(txttransductor.Text)
bguardar.Enabled = False
bcancel.Enabled = False
End Sub
Private Sub beditar_Click()
txttransductor.Locked = False
txtnumero.Locked = False
bguardar.Enabled = True
bcancel.Enabled = True
End Sub
Private Sub bcancel_Click()
txttransductor.Locked = True
txtnumero.Locked = True
interfaz.rscntb.CancelUpdate
bguardar.Enabled = False
bcancel.Enabled = False
End Sub
Private Sub bnuevo_Click()
interfaz.rscntb.AddNew
txttransductor.Locked = False
txtnumero.Locked = False
txtid.Text = ""
txttransductor.Text = ""
txtnumero.Text = ""
txttransductor.SetFocus
bguardar.Enabled = True
bcancel.Enabled = True
End Sub
Private Sub beliminar_Click()
Dim n, i As Integer
interfaz.rscntb.Delete
interfaz.rscntb.MoveNext
If interfaz.rscntb.EOF Then
interfaz.rscntb.MoveLast
End If
list.RemoveItem registro
Call bprimero_Click
interfaz.rscntb.MoveNext
If interfaz.rscntb.EOF Then
Call bprimero_Click
Else
registro = registro + 1
End If
otra:
n = (registro * 50) + 1000
n = n / 1000
n = (2.479848712157 * n * n * n * n) (36.548586166465 * n * n * n) +
(200.849383811325 * n * n) (508.543487349061 * n) +
586.17748967466
txtnumero.Text = Str(n)
interfaz.rscntb.Update
interfaz.rscntb.MoveNext
If interfaz.rscntb.EOF Then
Call bprimero_Click
Exit Sub
Else
registro = registro + 1
GoTo otra
End If
End Sub
Private Sub bprimero_Click()
registro = 0
interfaz.rscntb.MoveFirst
End Sub
Private Sub banterior_Click()
registro = (registro - 1)
interfaz.rscntb.MovePrevious
If interfaz.rscntb.BOF Then
interfaz.rscntb.MoveFirst
registro = 0
MsgBox "Estamos en el primer registro"
End If
End Sub
Private Sub bsiguiente_Click()
registro = registro + 1
interfaz.rscntb.MoveNext
If interfaz.rscntb.EOF Then
interfaz.rscntb.MoveLast
registro = (list.ListCount - 1)
MsgBox "Estamos en el último registro"
End If
Private Sub Form_Terminate()
HIDComm1.Uninit
End Sub
Private Sub
HIDComm1_ConnectSuccess(ByVal Status
As Long)
benviar.Enabled = True
f1.Caption = "USB-PIC Conectado"
End Sub
Private Sub
HIDComm1_Disconnected(ByVal Status As
Long)
benviar.Enabled = False
f1.Caption = "USB-PIC DESCONECTADO"
End Sub
Private Sub tim2_Timer()
ReDim todo(50)
Dim l, o As Integer
Dim hojas As Long
End Sub
Private Sub bultimo_Click()
registro = (list.ListCount - 1)
interfaz.rscntb.MoveLast
End Sub
Private Sub Form_Load()
HIDComm1.Connect
interfaz.rscntb.MoveFirst
list.AddItem Trim(txttransductor.Text)
otra:
interfaz.rscntb.MoveNext
If interfaz.rscntb.EOF Then
interfaz.rscntb.MoveFirst
Exit Sub
Else
list.AddItem Trim(txttransductor.Text)
End If
GoTo otra
interfaz.rscntb.MoveFirst
registro = 0
edo = False
End Sub
todo = HIDComm1.ReadFrom(hojas)
MsgBox "hojas= " & hojas
If hojas >= buffer(1) Then
MsgBox "datos= " & buffer(1)
For l = 0 To 8
MsgBox "todo(" & l & ")= " & todo(l)
Next
tim2.Enabled = False
benviar.Enabled = True
End If
End Sub
Private Sub tim1_Timer()
If HIDComm1.Connected = False Then
HIDComm1.Connect
End If
End Sub
Public Function dec_bin(ByRef d As Integer)
As String
Dim cad As String
Dim cad1 As String
Dim i As Integer
Do While d >= 1
If Trim(Str(d Mod 2)) = "1" Then
cad = cad & "1"
Else
cad = cad & "0"
End If
d = Round((d / 2) - 0.4)
Loop
f=f+1
i=i-1
Loop
bin_dec = n
End Function
Public Function elevar(ByRef factor As
Integer) As Integer
Dim r As Integer
Dim l As Integer
l = factor
i = Len(cad)
Do While i > 0
cad1 = cad1 & Mid(cad, i, 1)
i=i-1
Loop
dec_bin = cad1
End Function
Public Function bin_dec(ByRef c As String) As
Integer
Dim i As Integer
Dim f As Integer
Dim n As Integer
f=0
n=0
i = Len(c)
Do While i > 0
If Mid(c, i, 1) = "1" Then
n = n + elevar(f)
End If
If l = 0 Then
elevar = 1
Exit Function
End If
If l = 1 Then
elevar = 2
Exit Function
End If
r=2*2
l=l-2
Do While l > 0
r=r*2
l=l-1
Loop
elevar = r
End Function
167
ANEXO 2
Cuadros de diálogos en el proceso de enumeración (win98)
Cuadros de diálogos en el proceso de enumeración (win2000)
Cuadros de diálogos en el proceso de enumeración (winXP)
172
ANEXO 3
Para configurar el módulo maestro con interfaz hacia la PC, se colocan 2 jumpers en
las posiciones que indica la siguiente figura.
Para configurar el módulo maestro con interfaz hacia la PLC, se quitan los 2 jumpers
mencionados en la figura anterior y sólo se coloca el que indica la siguiente figura.
173
ANEXO 4
Módulo maestro
Módulo esclavo
174
ANEXO 5
Inicio
1
Inicialización de puertos
Retardo en la espera del RESET USB
Inicializar los registros de USB
Espera de la configuración USB
Espera de la señal de control
RSI
Recepción serie de datos de humedad
y asignadas a memoria RAM
Datos en memoria RAM a Buffer de
transmisión USB
Inicializar variables
Configurar comunicación serie
Transmisión de datos
por el puerto USB
Esperar datos de activación
por el puerto USB
Transmitir por el puerto serie CLAVE1
para encender el TX analógico
Retardo para el encendido total
del TX analógico
Generar la señal de
activación
1
Transmitir por el puerto serie CLAVE2
para apagar el TX analógico
Figura 3.51 PIC16C745 modo de conexión PC.
Interrupción Serie
Inicio
Identificar clave
Inicialización de puertos y variables
Configurar puerto serie
Clave1
Encender TX analógico
Clave2
Apagar TX analógico
Ciclo oscioso
1
Retardo
1
RSI
Deshabilito recepción serie y
Habilito interrupción externa
Identificar interrupción
y saltar según sea el caso
1
Interrupción Externa
Interrupción TMR0
Identificar periodo
Incrementar contador de
desbordamientos
Inicio Periodo
Fin Periodo
1
Borrar TMR0
Habilito interrupción
TMR0
1
Muestra a RAM
número de muestras
insusficientes
Determinar número de muestras
Habilito transmisión serie y
transmito las muestras de frecuencia
Condiciones Iniciales 2
Condiciones Iniciales 1
1
Figura 3.52 PIC16F628 modo de conexión PC.
1
Inicio
Inicialización de puertos
Retardo en la espera del reset USB
RSI
Inicializar los registros de USB
Espera de la configuración USB
Inicializar variables
1
Configurar comunicación serie
Esperar datos de configuración para el sistema de
monitoreo, enviados por el puerto USB en paquetes
Identificar primer paquete
Primer paquete
Obtener el número de paquetes
a leer en el puerto USB
Pasar datos del buffer USB
a memoria RAM
Identificar fin de
transmisión de paquetes
1
Transmito memoria RAM
de datos al puerto serie
Fin de transmisión
de paquetes
Figura 3.53 PIC16C745 modo de conexión PLC.
Interrupción serie
Inicio
Inicialización de puertos y variables
Recepción serie de datos
Se obtiene el número de transductores
Y el tiempo para cada barrido
Configuración del puerto serie
1
Ciclo oscioso
Se habilita la interrupción TMR0
RSI
1
Identificar interrupción
Interrupción TMR0
Incrementar el temporizador
1
Condiciones iniciales
no igual
Identificar
temporizador = tiempo de barrido
Fin de barrido
Igual
Identificar fin de barrido
Obtener frecuencia a generar
Número del transductor
activado al PLC
Encender TX analógico
Retardo en espera del
dato de humdad
Apagar TX analógico
Retardo para que se
encienda el TX totalmente
Generar la frecuencia de activación
Figura 3.54 PIC16F628 modo de conexión PLC.
Interrupción TMR0
Inicio
Incrementar contador
de desbordamientos
Inicialización de puertos y variables
1
1
Ciclo oscioso
RSI
Interrupción Externa
Identificar periodo
Inicio de Periodo
Borrar TMR0
Fin de Periodo
Fuera del rango
Identificar rango
Inicializar muestras
Habilito interrupción
TMR0
Dentro del rango
Identificar número
1
Condiciones Iniciales 1
de muestras
1
Activación válida
Preparar ADC e
iniciar conversión
Muestras
insufucientes
Calcular datos para
generar frecuencia
Generar frecuencia
de dato de humedad
Condiciones Iniciales 2
Figura 3.51 PIC16F873.
Descargar