Proyecto: Aprendizaje de la Electrónica a través de la Robótica

Tamaño: px
Comenzar la demostración a partir de la página:

Download "Proyecto: Aprendizaje de la Electrónica a través de la Robótica"

Transcripción

1 Proyecto: Aprendizaje de la Electrónica a través de la Robótica CICLO FORMATIVO DE GRADO SUPERIOR DE DESARROLLO DE PRODUCTOS ELECTRÓNICOS Módulos: Lógica Digital y Microprogramable. Técnicas de Programación. Electrónica Analógica. Electrónica de Sistemas. Desarrollo y Construcción de Prototipos Electrónicos. Mantenimiento de Equipos Electrónicos. Desarrollo de Proyectos de Productos Electrónicos CICLO FORMATIVO DE GRADO MEDIO DE ELECTRÓNICA DE CONSUMO Módulo: Electrónica Digital y Microprogramable. Profesores: Pedro Alonso Sanz. Juan DonGil García Félix Jiménez Jiménez. Juan Carlos Vázquez Moliní Miguel Ángel García Marcos. Alfonso García Gallego. Instituto: IES Joan Miró Localidad: San Sebastian de los Reyes Periodo: Microcontroladores IES Joan Miró Página 1

2 Índice Página 1.- Sistemas Microcontrolados Diagrama en Bloques de un sistema Microprocesado. Estructura Von Neumann Microprocesador (up) Buses Bus de Direcciones Bus de Datos Bus de Control Memorias ROM RAM Interfaces Interface Serie Interface Paralelo Decodificador de Direcciones Mapa de Memoria Microcontroladores Microcontroladores PIC Diagrama en bloques Estructura Hardvard Proceso Segmentado Pipeline Instrucciones RISC Estructura Ortogonal Microcontrolador PIC 16F877A Diagrama en Bloques Mapa de Memoria Memoria de Programa Memoria de Datos Ensamblador Lenguaje Máquina Lenguaje Ensamblador Programa Ensamblador Set de Instrucciones Herramientas de Desarrollo Ensambladores y Compiladores Simuladores MPLAB PROTEUS VSM Emuladores Grabadores o programadores Sistema de Desarrollo << Monibot >> Fabricación del Monibot Placas y Esquemas Listado de Componentes Estructura Herramientas de desarrollo utilizadas Microcontroladores IES Joan Miró Página 2

3 5.3.- Recursos bibliográficos Simulador Monibot Visualización de Información Led Led_1.c Led_2.c Led_3.c Led_4.c Display_7Segmentos Display_7Seg_1.c Display_7Seg_2.c Display_7Seg_3.c LCD LCD_1.c LCD_2.c LCD_3.c LCD_4.c LCD_5.c LCD_6.c LCD_7.c Entradas Digitales Simulador de Periféricos Interruptores_Led_1.c Interruptores_Led_2.c Interruptores_DISPL_7S_1.c Interruptores_DISPL_7S_2.c Pulsadores_DISPL_7S_1.c Simulador de Periféricos y Potencia Interruptores_LCD_1.c Interruptores_LCD_2.c Simulador de Potencia Pulsadores_LCD_1.c Entradas Analógicas Conversión A-D_D-A Conversión_A-D_A-D.c Conversión Analógica Digital Conversión_A-D1.c Conversión_A-D2.c Conversión_A-D2a.c Modulación por Anchura de Pulso (PWM) Control de Motores de Corriente Continua Prueba_Motor_Derecho.c Prueba_Control_Velocidad_Motor_Derecho.c Prueba_Control_Velocidad_Motor_Derecho_f.c Prueba_Control_Velocidad_Motor_Izquierdo_Derecho_f.c Servomotores de Posición Control_2_Servo_Posición.c Servo_ Futaba_10bit.c Microcontroladores IES Joan Miró Página 3

4 Interrupciones Externas Interrupción por RB0/INT Interrupción_INT_RB0.c Interrupción_INT_RB0a.c Interrupción_INT_RB0b.c Interrupción por cambio de nivel de RB4_5_6_ Interrupción_INT_RB4567.c Interrupción_INT_RB4567a.c Temporizadores y Contadores. (Timer 0,1 y 2) Timer Timer0_Contador.c Timer0_temporizador_multitarea_1.c Timer0_temporizador_multitarea_2.c Timer Timer1_Contador.c Timer1_temporizador_multitarea.c Timer Timer2_Señal_Cuadrada.c Timer2_Servos_Posicion.c Transmisión Serie de Datos. USART Cable Transmisión_Serie_1.c Recepción_Serie_Polling.c Recepción_Serie_Interrupción.c Transmisión_Serie_Multitarea.c Recepción_Serie_Interrupción_Multitarea.c Transmisión_Serie_Multitarea_1.c Recepción_Serie_Interrupción_Multitarea_1.c Radiofrecuencia Modulación en AM Transmisión_Serie_ Radiofrecuencia_1.c Transmisión_Serie_ Radiofrecuencia_2.c Recepción_Serie_Radiofrecuencia_1.c Radiofrecuencia Multitarea Transmisión_Serie_RF_Multitarea_1.c Transmisión_Serie_RF_Multitarea_2.c Recepción_Serie_RF_Multitarea.c Módulo MSSP I2C Expansor_Bus_PCF PCF8574_ Lectura y escritura en PCF8574 modo polling.c Lectura y escritura en PCF8574 en modo Interrupción.c PCF8574_ Lectura y escritura de multiples PCF8574 modo polling.c Lectura y escritura de multiples PCF8574 modo Interrupción.c PCF8574_ CAD_PCF8547.c CAD_PCF8547_MULTIPLES.c Microcontroladores IES Joan Miró Página 4

5 Conversor A-D_D-A_PCF PCF8591_ADC I2C_CAD_1.c I2C_CAD_2.c PCF8591_DAC I2C_CDA_1.c Sensores y Hardware Sensores de Infrarrojos CNY Prueba_Sensores_CNY70.c Sensores de Distancia Sensor de Infrarrojos GP2D Lectura_S1_GP2D12.c Lectura_S1_GP2D12.c driver1_gp2d12.c driver2_gp2d12.c Sensor de Ultrasonidos SRF Lectura_S1_SRF08_Real Lectura_S1_S2_SRF08_Real.c Lectura_S1_S2_SRF08_Real_Simulado.c Lectura_S1_SRF08_Distancia_Lumenes.c driver SRF08.c driver_luz_distancia_srf08.c driver PCF8591.c Cambio_Dirección.c Ejercicio 1.c Sensores de Temperatura PT Lectura_S1_PT100.c Sensor de Temperatura TC Test _TC74.c Sensor Térmico D-TPA Test1_D-TPA81.c Test2_D-TPA81.c Temperatura Mayor.c Temperatura Mayor_con driver.c driver_d-tpa81.c driver_tc74_9_sensores.c Seguimiento de un punto caliente.c Potenciómetro Digital MCP CG_Ampl_No_Inversor.c Control de múltiples servomotores de posición SD Control_SD20.c Control_Servos_Funciones_SD20.c A-D_SD20.c Puentes en H L293B y L Puente en H con TRT Microcontroladores IES Joan Miró Página 5

6 1.- Sistemas Microcontrolados. Un sistema microcontrolado es un equipo electrónico basado en microcontroladores que puede interactuar sobre dispositivos analógicos, digitales. Es programable. 2.- Diagrama en Bloques de un sistema Microprocesado. Estructura Von Neumann Microprocesador (up). Es un circuito integrado que se puede programar. Está compuesto por tres bloques básicos y se comunica con el exterior a través de cables Buses. Unidad de Control: Es el cerebro del up y tiene la misión de decodificar las instrucciones y generar las microordenes que activan los circuitos del microprocesador que realizan las funciones de las instrucciones. Unidad Aritmético Lógica (ALU): Es un circuito electrónico que realiza operaciones aritméticas (Sumas, Restas, etc.) y Lógicas (AND, OR, etc). Registros: Son unidades de memoria de N bit que almacenan información procedente del interior y exterior del up. Microcontroladores IES Joan Miró Página 6

7 2.2.- Buses. digital. Es un conjunto de hilos, pistas o cables que tienes la misión de transportar información Bus de Direcciones. Es un bus que el up utiliza para selecciona o direcciona los dispositivos externos Bus de Datos. Es un bus que el up utiliza para enviar o recibir información de los dispositivos externos Bus de Control. Es un bus que el up utiliza para escribir o leer los dispositivos externos. También sirve para resetear o deshabilitar al up Memorias ROM. Son circuitos integrados que almacenan información. ROM (Read Only Memory) significa memoria de solo lectura. Se almacenan la información en el proceso de fabricación. No volatil Proceso de Lectura: El up a través del Decodificador de Direcciones selecciona la ROM [CS2] El up a través del Bus de Direcciones [A2..A0] selecciona la palabra de la memoria. El up a través del Bus de Control [R] da la orden de lectura a la memoria ROM. La memoria ROM pone la información en el Bus de Datos [D7..D0] y el up la almacena en sus Registros. Microcontroladores IES Joan Miró Página 7

8 Estructura interna de la memoria: El Bus de Direcciones nos indica el número de palabras que tiene la memoria. Palabras = 2 n+1, donde n=2 por la dirección A2, = 8 palabras. El Bus de Datos nos indica el número de bit que tiene cada palabra. Bit = n+1, donde n=7 por el bus de datos D7, 7+1= 8 Bit RAM. RAM (Random Access Memory) significa memoria de acceso aleatorio. Se puede leer (R) y escribir (W). Memoria Volatil. Proceso de Escritura: El up a través del Decodificador de Direcciones selecciona la RAM [CS2] El up a través del Bus de Direcciones [A2..A0] selecciona la palabra de la memoria. El up pone la información en el Bus de Datos [D7..D0]. El up a través del Bus de Control [W] da la orden de escritura en la memoria RAM. Microcontroladores IES Joan Miró Página 8

9 Estructura interna de la memoria: Interfaces. Son circuitos electrónicos que comunican el exterior con el up Interface Serie. Comunican el exterior con el up con un bus serie de tres hilos. Los datos se mandan o se reciben del exterior de uno en uno. Microcontroladores IES Joan Miró Página 9

10 El proceso de lectura y escritura es igual que las memorias. Se tiene que configurar cuando queremos leer o escribir datos del exterior. A través Tx y GND transmitimos los datos del up al exterior. A través de Rx y GND el up recibe los datos del exterior. El protocolo de comunicaciones tiene que estar predefinido. Existen diferentes tipos: Asíncrona. Es también conocida como Start/stop. Requiere de una señal que identifique el inicio del carácter y a la misma se la denomina bit de arranque. También se requiere de otra señal denominada señal de parada que indica la finalización del carácter o bloque. Síncrona. Síncrono significa "con reloj" y exactamente eso es lo que necesitamos, un reloj (o dicho en inglés un Clock). La transmisión síncrona necesita de dos líneas, una de datos sobre la que se van a representar los distintos estados de los bits a transmitir y una de reloj donde vamos indicando cuando está disponible cada bit en la línea de datos. Esta línea de reloj es la de "sincronización" entre ambos dispositivos, el emisor y el receptor de la transmisión Microcontroladores IES Joan Miró Página 10

11 Tipo de Comunicaciones: Simplex. En este caso el transmisor y el receptor están perfectamente definidos y la comunicación es unidireccional. Este tipo de comunicaciones se emplean usualmente en redes de radiodifusión, donde los receptores no necesitan enviar ningún tipo de dato al transmisor. Duplex ó Semi Duplex. En este caso ambos extremos del sistema de comunicación cumplen funciones de transmisor y receptor y los datos se desplazan en ambos sentidos pero no simultáneamente. Este tipo de comunicación se utiliza habitualmente en la interacción entre terminales y un computador central. Full Duplex. El sistema es similar al duplex, pero los datos se desplazan en ambos sentidos simultáneamente. Para ello ambos transmisores poseen diferentes frecuencias de transmisión o dos caminos de comunicación separados, mientras que la comunicación semi-duplex necesita normalmente uno solo. Existen diferentes interfaces serie: UART, USART, PS2, USB, FireWire, etc Interface Paralelo. Las conexiones paralelas consisten en transmisiones simultáneas de N cantidad de bits, del up al Exterior o viceversa. Microcontroladores IES Joan Miró Página 11

12 2.4.- Decodificador de Direcciones. Es un conjunto de circuitos electrónicos que seleccionan los diferentes dispositivos conectados a los buses (Memorias, Interfaces, etc). El up controla el Decodificador. El diseño de los decodificadores está supeditado al conjunto de dispositivos que se conecten a los buses. Un mapa de memoria ayuda a realizar este proceso. Microcontroladores IES Joan Miró Página 12

13 Mapa de Memoria. La trama jaspeada representa la palabra que se direcciona dentro del dispositivo. Ejemplo: Dirección 3 A2 A1 A0 = 011 Palabra 3 La trama jaspeada representa la palabra que se direcciona dentro del dispositivo. Ejemplo: Dirección 15 A2 A1 A0 = 111 Palabra 7 La trama jaspeada representa la palabra que se direcciona dentro del dispositivo. Ejemplo: Dirección 21 A2 A1 A0 = 101 Palabra 5 La trama jaspeada representa la palabra que se direcciona dentro del dispositivo. Ejemplo: Dirección 28 A2 A1 A0 = 100 Palabra 4 Microcontroladores IES Joan Miró Página 13

14 3.- Microcontroladores. Un microcontrolador es un circuito integrado que contiene dentro un sistema microprocesado (up, Memorias, Interfaces, etc) y hardware de control de dispositivos electrónicos (Sistema de Adquisición de Datos Conversión Analógica/ Digital, Modulación de anchura de pulso Control de Velocidad de Motores, etc. Es programable Microcontroladores PIC. Los microcontroladores PIC de la casa Microchip se caracterizan por ser baratos, por proporcionar un entorno de desarrollo integrado gratuito MPLAB. Este entorno permite editar un el archivo fuente del proyecto, ensamblarlo, simularlo en un Ordenador Personal y comprobar la evolución de las variables en la memoria RAM, registros, etc Diagrama en bloques Estructura Hardvard Se caracteriza por utilizar dos tipos de memorias (Datos y Programa) con buses independientes. CPU Memoria de Programa y Memoria de Programa CPU Memoria de Datos Buses de Datos (EEPROM) Buses (RAM) Arquitectura Von Neumann Arquitectura Hardvard Proceso Segmentado Pipeline. Permite realizar dos procesos simultáneamente a la vez (lectura y ejecución de instrucciones). PROGRAMA 1. BSF STATUS,RP0 2. CLRF TRISB 3. MOVLW 0XFF 4. MOVWF TRISA 1º Ciclo 2º Ciclo 3º Ciclo 4º Ciclo 5º Ciclo Búsqueda 1 Ejecuta 1 Búsqueda 2 Ejecuta 2 Búsqueda 3 Ejecuta 3 Búsqueda 4 Ejecuta Instrucciones RISC. Tiene un reducido grupo de instrucciones (RISC Reduced Instruction Set Computer). Son instrucciones simples que se ejecutan en un solo ciclo máquina (4 ciclos de reloj). El microcontrolador PIC16F876A tiene 35 instrucciones Estructura Ortogonal. Una instrucción puede utilizar cualquier elemento de la arquitectura como fuente o destino de datos. Microcontroladores IES Joan Miró Página 14

15 3.2.- Microcontrolador PIC 16F877A. El microcontrolador PIC 16F877A es un CHIP de 40 patillas, que se caracteriza por lo siguiente: Tiene 35 Instrucciones Tiene una Memoria de Programa de 8192 palabras FLASH 368 byte de Memoria de Datos RAM 256 byte de EEPROM 33 Patillas de entradas/salidas. Sistema de Adquisición de datos (8 Entradas Analógicas) 2 módulos de CCP y PWM. (Comparación y captura de datos y generadores de señal por Modulación de Anchura de Pulsos). Un módulo de comunicación serie SPI (Serial Peripheral Interface) I2C (Inter- Integrated Circuit). Un transmisor-receptor asíncrono serie universal USART. 3 Timer (Temporizadores/Contadores). 2 Comparadores de señales analógicas. Microcontroladores IES Joan Miró Página 15

16 Diagrama en Bloques. Microcontroladores IES Joan Miró Página 16

17 Mapa de Memoria Memoria de Programa. Es una memoria tipo FLASH, los programas son almacenados en este tipo de memoria, cuando se desconecta la alimentación la información almacenada no se pierde.(la memoria flash es una forma desarrollada de la memoria EEPROM que permite que múltiples posiciones de memoria sean escritas o borradas en una misma operación de programación mediante impulsos eléctricos, frente a las anteriores que sólo permite escribir o borrar una única celda cada vez. Por ello, flash permite funcionar a velocidades muy superiores cuando los sistemas emplean lectura y escritura en diferentes puntos de esta memoria al mismo tiempo.), está compuesta por: 8192 palabras de 14bit. (Cada instrucción ocupa solo una palabra). Una pila de 8 niveles. Un solo vector de Interrupción. Vector de Reset (Dirección 0000h) 4 zonas de memoria. Microcontroladores IES Joan Miró Página 17

18 Memoria de Datos. Es una memoria de tipo RAM (Memoria de Acceso Aleatorio), se pierde la información cuando se desconecta la alimentación. Está compuesta por 4 bancos de trabajo. Contiene registros (Tipo Byte) de 2 tipos: Registros de funciones especiales SFR que sirven para comunicarnos con el hardware interno del PIC. Registro de Propósito General que nos sirven para almacenar nuestras variables de nuestro programas Ensamblador Lenguaje Máquina. Es un lenguaje binario Unos y Ceros que es el único que entienden los microcontroladores. El lenguaje ensamblador se compila Traduce a lenguaje máquina. Se trabaja con formato Hexadecimal. Ejemplo: Instrucción en lenguaje Ensamblador Código Binario Compilador BTFSS PORTA, Código Hexadecimal 1 E 0 5 Microcontroladores IES Joan Miró Página 18

19 Lenguaje Ensamblador. El lenguaje ensamblador utiliza un lenguaje nemónico que son grupos de caracteres alfanuméricos que simbolizan ordenes o tareas a realizar con cada instrucción. Los nemónicos se corresponden con las iniciales de cada nombre de las instrucciones en ingles. Ejemplo: Suma 58 al registro de trabajo W y guarda el resultado en este mismo registro W. addlw d 58 ; W58+W Programa Ensamblador. Es un software encargado de traducir el lenguaje ensamblador a lenguaje máquina. Al lenguaje ensamblador se le llama Fichero Fuente y al traducido Fichero Ejecutable El programa fuente tiene la extensión asm y el ejecutable hex. Fichero Fuente Ejemplo1.asm Programa Ensamblador MPASM.EXE Fichero Ejecutable Ejemplo1.hex Fichero Errores Ejemplo1.err Fichero Listable Ejemplo1.lst Otros ficheros Microcontroladores IES Joan Miró Página 19

20 Set de Instrucciones. Microcontroladores IES Joan Miró Página 20

21 4.- Herramientas de Desarrollo. Cuando se diseñan sistemas con circuitos programables se precisan herramientas para la puesta a punto del hardware y del software. Las más importantes son: editores de dores, compiladores, simuladores, grabadores, emuladores y sistemas de desarrollo Ensambladores y Compiladores. El programa ensamblador traduce las instrucciones que se han escrito, usando los nemónicos del lenguaje ensamblador, a código binario ejecutable por el microcontrolador. El proceso de ensamblado produce un fichero *.hex que se grabará en la memoria del programa del PIC mediante el grabador o programador. La secuencia de nemónicos se llama código fuente del programa. El ensamblador más utilizado para los PIC es el MPASM TM que trabaja dentro del entorno software MPLAB. El programa compilador traduce las instrucciones que se han escrito en lenguaje de alto nivel (por ejemplo en lenguaje C), a código binario ejecutable por el microcontrolador. Los compiladores para lenguaje C más populares son el PICC por Hi-Tech Software ( y el PCW de la empresa CCS ( Un compilador para Basic es el PICBasic Pro propiedad de MicroEngineering Labs ( Simuladores. Una vez que el programa se ha escrito y ensamblado o compilado se está en binario *.hex que es el que se graba en el microcontrolador. Es casi indispensable probar este programa, haciéndolo funcionar en condiciones tan próximas como sea posible a las de utilización real. Para hacer esto hay varias soluciones, las más utilizadas son dos: utilizar un económico simulador software o un potente emulador. Como su propio nombre indica, un simulador por software "simula" la ejecución de las instrucciones de un programa desarrollado para un modelo de microcontroladores específico. Representa el comportamiento interno del microcontrolador y el estado de sus líneas de entrada/salida. Al ejecutar el simulador se pueden visualizar fácilmente las instrucciones donde se producen funcionamientos no deseados. Como el microcontrolador se simula por software el comportamiento no es idéntico a la real sin embargo, proporciona una aproximación aceptable, especialmente cuando no es esencial el trabajo en tiempo real. Su gran ventaja es el bajo precio. El simulador realiza la ejecución del programa mucho más lento que lo haría el mismo programa directamente sobre el microcontrolador, por eso determinadas operaciones en las que son necesarios tiempos muy precisos o críticos no se puede probar mediante la simulación. No obstante, bien utilizado permite desarrollar aplicaciones interesantes con una mínima inversión. El simulador gratuito más utilizado para los PIC es el MPLAB SIM, que trabaja dentro del entorno MPLAB. En los últimos está teniendo una gran aceptación PROTEUS VSM ( Microcontroladores IES Joan Miró Página 21

22 MPLAB. MPLAB IDE es un software de "Entorno de Desarrollo Integrado" (Integrated Development Environment, IDE) que se ejecuta bajo Windows. Con este entorno se puede desarrollar aplicaciones para los microcontroladores PIC. El MPLAB incluye todas las utilidades necesarias para la realización de proyectos con mivrocontroladores PIC, permite editar el archivo fuente del proyecto, además de ensamblarlo y simularlo en pantalla para comprobar como evolucionan tanto la memoria de datos RAM, como la de programa ROM, los registros del SFR, etc, según progresa la ejecución del programa. El MPLAB incluye: Un editor de texto. Un ensamblador llamado MPASM. Un simulador llamado MPLAB SIM. Un organizador de proyectos. Este programa es gratuito. Se puede bajar en la dirección Internet del fabricante Su instalación es muy sencilla y similar a cualquier otro programa para el sistema operativo Windows PROTEUS VSM. El laboratorio virtual electrónico PROTEUS VSM de LABCENTER ELECTRONICS, nos permite simular circuitos electrónicos analógicos/ digitales y microprocesados. Es capaz de realizar simultáneamente una simulación hardware y software (Lenguaje de bajo y alto nivel Ensamblador y C respectivamente) en un mismo entorno gráfico. También enlaza con una herramienta que nos permite desarrollar las placas para realizar los prototipos. Para ello suministra tres potentes herramientas: ISIS (Diseño Gráfico) VSM(Virtual System Modelling) Simulación de Componentes. ARES (Diseño de Placas). Las herramientas tradicionales de diseño seguían el siguiente proceso: Con las herramientas de diseño tradicionales, el desarrollo del software y la comprobación del prototipo, no puede realizarse hasta que este no se desarrolla. Esto puede suponer semanas de retraso. Si se localiza un error hardware, la totalidad del proceso se debe repetir. Usando Proteus VSM, el desarrollo del software puede comenzar tan pronto como el diseño esquemático este acabado y la combinación del hardware y el software nos permite testear el prototipo y ver si funciona. Microcontroladores IES Joan Miró Página 22

23 4.3.- Emuladores. El emulador es una potente herramienta que consiste en un complejo equipo físico controlado por un software desde un ordenador y que se comporta exactamente como el microcontrolador al que reemplaza. El fabricante Microchip ofrece algunos de ellos en su página WEB, tal como el MPLAB-ICE El emulador ICE 2000 dispone de una "cabeza" con idéntico patillaje que el del microcontrolador que emula. Esta cabeza se inserta en el zócalo donde irá el microcontrolador con el programa que trata de comprobar. El emulador hace funcionar el sistema como si hubiese un microcontrolador real y además con la ventaja de que visualiza en el monitor del ordenador toda la información necesaria para comprobar el funcionamiento de los programas, permitiendo realizar todo tipo de pruebas. Los resultados obtenidos son idénticos a los del producto final, puesto que a diferencia de los simuladores la ejecución se realiza en tiempo real. El emulador es el método de depuración más sofisticado que se puede emplear, pero su alto precio no lo hace especialmente accesible y mucho menos para uso doméstico. Para muchas aplicaciones es suficiente con el simulador software Grabadores o programadores. Una vez realizado el programa y comprobado en el simulador o emulador, se debe proceder a grabarlo en la memoria de programa del microcontrolador mediante un grabador o programador. El grabador PICSTART PLUS ofrecido por Microchip es uno de los más utilizados. En internet se ofrecen numerosos esquemas para la construcción de económicos programadores de PIC. Uno de los más populares es el JDM en sus diferentes versiones, que se utiliza junto con el programa IC-Prog. Otra forma de grabar los microcontroladores es utilizar el firmware boootloader (El firmware es un bloque de instrucciones de programa para propósitos específicos, grabado en una memoria de tipo no volátil (ROM, EEPROM, flash, etc), que establece la lógica de más bajo nivel que controla los circuitos electrónicos de un dispositivo de cualquier tipo) Un bootloader es un firmware para permitir la rápida descarga de programas en los microcontroladores. En el caso de los PIC, el bootloader permite descargar programas Microcontroladores IES Joan Miró Página 23

24 directamente desde el PC sin necesidad de utilizar ningún tipo de grabador, es decir en la propia aplicación. La descarga se hace a través del puerto serie, USB. E1 2 1 VDD VSS 5V VCC Al Puerto Serie del PC J CONN-D9M Adaptador de señales PC-uC C6 TXPC RXPC C9 VDD 1uF + 3 1uF C1-14 T1OUT 13 R1IN 7 T2OUT 8 R2IN 2 VS+ 6 VS- + 1 U5 C1+ 11 T1IN 12 R1OUT 10 T2IN 9 R2OUT VDD U2 RB0/INT RB1 RB2 RB3/PGM RB4 RB5 RB6/PGC RB7/PGD RC0/T1OSO/T1CKI RC1/T1OSI/CCP2 RC2/CCP1 RC3/SCK/SCL RC4/SDI/SDA RC5/SDO RC6/TX/CK RC7/RX/DT PIC16F876_JOAN OSC1/CLKIN OSC2/CLKOUT MCLR/Vpp/THV RA0/AN0 RA1/AN1 RA2/AN2/VREF- RA3/AN3/VREF+ RA4/T0CKI RA5/AN4/SS C8 1uF GND C2-5 C7 1uF + C2+ 4 MAX232 GND=GND VCC=VCC C10 100nF Este condensador debe estar proximo a la alimentación del MAX Sistema de Desarrollo << Monibot >>. Un sistema de desarrollo está formado por un conjunto de herramientas hardware y software que permitan fabricar y simular prototipos, emular, depurar y grabar programas de forma eficiente e intuitiva Fabricación del Monibot Placas y Esquemas Listado de Componentes Estructura Herramientas de desarrollo utilizadas. Fabricación de Placas. Proteus (ARES) Simulación hardware y software de los prototipos. Proteus (ISIS) Compilador C. (CCS) Grabador de programas en el Microcontrolador. (Bootloader) Recursos bibliográficos. Curso de Robótica y otras aplicaciones en el Aula de Tecnología. Data book PIC16F87xA. Curso de Microcontroladores PIC Avanzados. Microcontroladores IES Joan Miró Página 24

25 5.3.- Simulador Monibot. El Monibot se va a programar en Lenguaje C, el método utilizado será enseñar las estructuras básicas de C utilizando unos esquemas básicos de simulación del robot. Para ello se ha estructurado en diferentes aplicaciones prácticas: Visualización de Información. Led. Display de 7 Segmentos. LCD. Entradas Digitales. Simulador_Periféricos. Simulador_Periféricos_Potencia. Simulador_Potencia. Entradas Analógicas. Conversión A/D y D/A. Conversión Analógica/Digital. Modulación por Anchura de Pulso. PWM Control de Motores de Corriente Continua. Servomotores de Posición. Interrupciones Externas. Interrupción por RB0/INT. Interrupción por cambio de nivel de RB4_5_6_7. Temporizadores y Contadores. (Timer 0,1 y 2). Timer 0. Timer 1. Timer 2. Transmisión Serie de Datos. USART Cable. Radiofrecuencia. Radiofrecuencia_Multitarea. Módulo MSSP. I2C. Expansor_Bus_PCF8574. Conversor A-D_D-A_PCF8591. SPI. Sensores de Infrarrojos CNY70. Sensores de Distancia. Sensor de Infrarrojos GP2D12. Sensor de Ultrasonidos SRF08. Sensores de Temperatura. PT100. Sensor de Temperatura TC74. Sensor Térmico D-TPA81. Potenciómetro Digital MCP Control de múltiples servomotores de posición SD20. Puentes en H. L298-L293B. Puente en H con TRT. Microcontroladores IES Joan Miró Página 25

26 Los esquemas básicos de simulación del Monibot son: Simulador Potencia y Periféricos. Simulador Potencia. Simulador Periféricos. Microcontroladores IES Joan Miró Página 26

27 Visualización de Información Led. El entrenador utilizado es Simulador Periféricos dentro de la carpeta de Led Led_1.c // Programa...: Led_1.c // // Plataforma hw: Placa Monibot 16F877A // // Fecha...: Mayo-2011 // // Programador..: Pedro Alonso // // Descripción..: Encender y apagar led RB7 con una cadencia de 1 segundo. // //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // *********************************** Directivas de procesado***************************************** // (Controlan la conversión del programa a código máquina por parte del compilador) #include <16F877A.h> #fuses XT,NOWDT,NOPROTECT,NOLVP #use delay( clock = ) // Elección del uc 16F877A // Reloj de 1 MHz #BYTE TRISB = 0x86 #BYTE portb = 0x06 #BIT rb7 = 0X06.7 #DEFINE ENCENDIDO 1 // ENCENDIDO equivale a 1. #DEFINE APAGADO 0 // APAGADO equivale a 0. // Asignamos a la etiqueta TRISB la dirección 86h de memoria RAM. // Asignamos a la etiqueta portb la dirección 06h de memoria RAM. // Asignamos a la etiqueta rb7 el bit 7 de la dirección 06h // de la memoria RAM. // ***************************** Función principal o programa principal ***************************** // Se define con un void main, void main() Microcontroladores IES Joan Miró Página 27

28 TRISB = 0B ; portb = 0B ; // Defines Puerto B como SALIDA de datos. // Resteamos el puerto B Led apagados. while (1) // Ejecuta indefinidamente lo que está entre corchetes. rb7 = ENCENDIDO; delay_ms(1000); // Enciende el Led que esta en la patilla rb7. // Espero 1 segundo. rb7 = APAGADO; delay_ms(1000); // Apago el Led que esta en la patilla rb7. // Espero 1 segundo Led_2.c // Programa...: Led_2.c // // Plataforma hw: Placa Monibot 16F877A // // Fecha...: Mayo-2011 // // Programador..: Pedro Alonso // // Descripción..: Encender y apagar todos los Led con una cadencia de 2 segundos y 1 // // segundo respectivamente // // ************************************ Directivas de procesado**************************************** // (Controlan la conversión del programa a código máquina por parte del compilador) #include <16F877A.h> #fuses XT,NOWDT,NOPROTECT,NOLVP #use delay( clock = ) #BYTE TRISB = 0x86 #BYTE portb = 0x06 // Elección del uc 16F877A // Reloj de 1 MHz // Asignamos a la etiqueta TRISB la dirección 86h de memoria RAM. // Asignamos a la etiqueta portb la dirección 06h de memoria RAM. // ***************************** Función principal o programa principal ***************************** // Se define con un void main, void main() TRISB = 0B ; portb = 0B ; while (1) // Defines Puerto B como SALIDA de datos. // Resteamos el puerto B Led apagados. // Ejecuta indefinidamente lo que está entre corchetes. portb =0b ; delay_ms(2000); // Enciende todos los Led // Espero 2 segundo portb =0b ; delay_ms(1000); // Apago todos los led // Espero 1 segundo Microcontroladores IES Joan Miró Página 28

29 Led_3.c // Programa...: Led_3.c // // Plataforma hw: Placa Monibot 16F877A // // Fecha...: Mayo-2011 // // Programador..: Pedro Alonso // // Descripción..: Contador en binario de 0 a 9 // // ************************************ Directivas de procesado**************************************** // (Controlan la conversión del programa a código máquina por parte del compilador) #include <16F877A.h> #fuses XT,NOWDT,NOPROTECT,NOLVP #use delay( clock = ) #BYTE TRISB = 0x86 #BYTE portb = 0x06 // Elección del uc 16F877A // Reloj de 1 MHz // Asignamos a la etiqueta TRISB la dirección 86h de memoria RAM. // Asignamos a la etiqueta portb la dirección 06h de memoria RAM. int8 n=0; // Declaramos la variable n con 8 bit y la inicializamos con 0. // ****************************** Función principal o programa principal **************************** // Se define con un void main, void main() TRISB = 0B ; portb = 0B ; while (1) // Defines Puerto B como SALIDA de datos. // Resteamos el puerto B Led apagados. // Ejecuta indefinidamente lo que está entre corchetes. for (n=0;n<=9;n++) portb=n; delay_ms(1000); // Ejecuta el contenido que está entre corchetes 10 veces //de 0 a 9 // Asignamos la variable n al puertob. // Espero 1 segundo Led_4.c //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Programa...: Led_4.c // // Plataforma hw: Placa Monibot 16F877A // // Fecha...: Mayo-2011 // // Programador..: Pedro Alonso // // Descripción..: Simular Coche Fantástico // // ********************************** Directivas de procesado****************************************** // (Controlan la conversión del programa a código máquina por parte del compilador) #include <16F877A.h> #fuses XT,NOWDT,NOPROTECT,NOLVP #use delay( clock = ) #BYTE TRISB = 0x86 #BYTE portb = 0x06 // Elección del uc 16F877A // Reloj de 1 MHz // Asignamos a la etiqueta TRISB la dirección 86h de memoria RAM. // Asignamos a la etiqueta portb la dirección 06h de memoria RAM. int8 n=0 ; // Declaramos la variable n con 8 bit y la inicializamos con 0. Microcontroladores IES Joan Miró Página 29

30 // **************************** Función principal o programa principal ****************************** // Se define con un void main, void main() TRISB = 0B ; portb = 0b ; delay_ms(500); // Defines Puerto B como SALIDA de datos. // Activamos PB0. // Esperamos 0,5 segundo. while (1) // Ejecuta indefinidamente lo que está entre corchetes. for (n=0;n<=6;n++) // Ejecuta el contenido que está entre corchetes 7 veces de 0 a 6 portb<<=1; delay_ms(500); // Movemos un bit a la izquierda // Esperamos 0,5 segundo. for(n=7;n>0;n--) // Ejecuta el contenido que está entre corchetes 7 veces de 7 a 1 portb>>=1; delay_ms(500); // Movemos un bit a la derecha. // Esperamos 0,5 segundo Display_7Segmentos. Los entrenadores utilizados son Simulador Periféricos y Dispay_7Seg dentro de la carpeta de Display_7Segmentos. Un display de 7 segmentos son diodos LED encapsulados con una determinada configuración. Si queremos que aparezcan los números decimales sobre el display es necesario realizar una conversión de número decimal a 7 segmentos. Dicha conversión dependerá de la conexión del display al microcontrolador. Microcontroladores IES Joan Miró Página 30

31 Tabla de conversión de Número Decimal a Binario de 7 segmentos Número Decimal Puerto B B7 B6 B5 B4 B3 B2 B1 B0 g f e d c b a Número Hexadecimal 3F 06 5B 4F 66 6D 7D 07 7F 6F 1º Dígito en Hexadecimal 2º Dígito en Hexadecimal Display_7Seg_1.c // Programa...: Display_7Seg_1.c // // Plataforma hw: Placa Monibot 16F877A // // Fecha...: Mayo-2011 // // Programador..: Pedro Alonso // // Descripción..: Mostrar los números desde 0 al 9 en un display de 7 Segmentos. // /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // ******************************* Directivas de procesado********************************************* // (Controlan la conversión del programa a código máquina por parte del compilador) #include <16F877A.h> #fuses XT,NOWDT,NOPROTECT,NOLVP #use delay( clock = ) // Reloj de 1 MHz #define Numeros_Tabla 10 #BYTE TRISB = 0x86 #BYTE portb = 0x06 // Números de la Tabla. // Asignamos a la etiqueta TRISB la dirección 86h de memoria RAM. // Asignamos a la etiqueta portb la dirección 06h de memoria RAM. int8 n=0 ; // Declaramos la variable n con 8 bit y la inicializamos con 0. byte CONST DISPLAY[10] = 0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F; // Tabla de conversión de // BCD a 7 Seg. // ************************ Función principal o programa principal ********************************** // Se define con un void main, void main() TRISB = 0B ; // Defines Puerto B como SALIDA de datos. portb = 0B ; // Reseteamos el Puerto B. while (1) // Ejecuta indefinidamente lo que está entre corchetes. Microcontroladores IES Joan Miró Página 31

32 for (n=0; n<numeros_tabla; n++) portb = DISPLAY[n]; delay_ms(1000); // Se ejecuta un bucle desde n=0 hasta // n<=numeros_tabla en orden // ASCENDENTE de uno en uno // Mostramos en el Puerto B el valor que // tiene la tabla DISPLAY[n] // Retardo de 1 Segundo Display_7Seg_2.c // Programa...: Display_7Seg_2.c // // Plataforma hw: Placa Monibot 16F877A // // Fecha...: Mayo-2011 // // Programador..: Pedro Alonso // // Descripción..: Mostrar los números desde 9 al 0 en un display de 7 Segmentos. // //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // *********************************** Directivas de procesado***************************************** // (Controlan la conversión del programa a código máquina por parte del compilador) #include <16F877A.h> #fuses XT,NOWDT,NOPROTECT,NOLVP #use delay( clock = ) // Reloj de 1 MHz #define Numeros_Tabla 10 #BYTE TRISB = 0x86 #BYTE portb = 0x06 // Números de la Tabla. // Asignamos a la etiqueta TRISB la dirección 86h de memoria RAM. // Asignamos a la etiqueta portb la dirección 06h de memoria RAM. signed int8 n=0 ; // Declaramos la variable n con 8 bit y signo, la inicializamos con 0. byte CONST DISPLAY[10] = 0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F; // Tabla de conversión de // BCD a 7 Seg. // ****************************** Función principal o programa principal **************************** // Se define con un void main, void main() TRISB = 0B ; // Defines Puerto B como SALIDA de datos. portb = 0B ; // Reseteamos el Puerto B. while (1) // Ejecuta indefinidamente lo que está entre corchetes. for (n=numeros_tabla-1; n>=0; n--) // Se ejecuta un bucle desde n=numero_tabla-1 hasta // n>=0 en orden DESCENDENTE de uno en uno portb = DISPLAY[n]; delay_ms(1000); // Mostramos en el Puerto B el valor que tiene DISPLAY[n] // Retardo de 1 Segundo. Microcontroladores IES Joan Miró Página 32

33 Display_7Seg_3.c // Programa...: Display_7Seg_1b.c // // Plataforma hw: Placa Monibot 16F877A // // Fecha...: Mayo-2011 // // Programador..: Pedro Alonso // // Descripción..: Mostrar mi nombre. // // ********************************** Directivas de procesado****************************************** // (Controlan la conversión del programa a código máquina por parte del compilador) #include <16F877A.h> #fuses XT,NOWDT,NOPROTECT,NOLVP #use delay( clock = ) // Reloj de 1 MHz #define Numeros_Tabla 5 #BYTE TRISB = 0x86 #BYTE portb = 0x06 // Números de la Tabla. // Asignamos a la etiqueta TRISB la dirección 86h de memoria RAM. // Asignamos a la etiqueta portb la dirección 06h de memoria RAM. int8 n=0; // Declaramos la variable n con 8 bit y la inicializamos con 0. byte CONST DISPLAY[5] = 0x73,0x79,0x5E,0x50,0x3F; // P E d r O // Tabla de 5 datos. // ***************************** Función principal o programa principal **************************** // Se define con un void main, void main() TRISB = 0B ; // Defines Puerto B como SALIDA de datos. portb = 0; // Reseteamos el Puerto B. while (1) // Ejecuta indefinidamente lo que está entre corchetes. for (n=0;n<numeros_tabla;n++) portb = DISPLAY[n]; delay_ms(1000); // Se ejecuta un bucle desde n=0 hasta // n<numeros_tabla en orden ASCENDENTE // de uno en uno // Mostramos en el Puerto B el valor que tiene DISPLAY[n] // Retardo de 1 Segundo. Microcontroladores IES Joan Miró Página 33

34 LCD. Los entrenador utilizados son Simulador Potencia y LCD dentro de la carpeta de LCD. La pantalla de cristal líquido o display LCD (Liquid Crystal Display) se utiliza para mostrar mensajes. Puede mostrar cualquier carácter alfanumérico. La pantalla consta de una matriz de de caracteres (Normalmente de 5x7 punto por carácter), distribuidos en una, dos, tres, cuatro líneas (Hasta 40 caracteres por línea). El proceso de visualización es gobernado por un microcontrolador incorporado en la propia pantalla. El modelo más utilizados es el Hitachi HD Uno de los modelos utilizados es el LM16L cuyas características son: Consumo reducido, del orden de 7,5 mw. Pantalla de caracteres ASCII, caracteres griegos, símbolos matemáticos, etc. Desplaza los caracteres hacia la izquierda o a la derecha. Memoria de 40 caracteres por línea de pantalla, visualización de 16 caracteres por línea. Microcontroladores IES Joan Miró Página 34

35 VSS VDD VEE RS RW E D0 D1 D2 D3 D4 D5 D6 D7 Aprendizaje de la Electrónica a través de la Robótica - ARCE - Movimiento del cursor y cambio de su aspecto. Permite programas ocho caracteres. Puede ser gobernado de dos formas principales: Conexión con bus de 4 bits Conexión con un bus de 8 bits El patillaje es el siguiente: LCD1 LCD-16 X 2_JOAN La alimentación es de 5V. La regulación de contraste se realiza por la patilla VEE con un potenciómetro de 10K. Si ponemos VEE a masa tiene el máximo contraste. Las líneas del bus de datos (D7..D0) son triestado y pasan a estado de alta impedancia cuando el LCD no se utiliza. SEÑAL DEFINICIÓN PINES FUNCIÓN D7..D0 Data Bus Bus de datos E Enable 6 E=0 LCD no habilitado. E=1 LCD habilitado. R/W Read/Write 5 R/W =0 escribe en LCD. R/W =1 lee del LCD. RS Register Select 4 RS=0 Modo Comando RS=1 Modo Caracter VEE ó VLC Liquid Cristal driving Voltage 3 Tensión para ajustar el contraste VDD Power Supply Voltage 2 Tensión de Alimentación +5V VSS Ground 1 Masa. Utilizaremos el driver flex_lcd.c que es una variación del creado por CCS, con las siguientes funciones: Lcd_init(); Inicializa el LCD. Borra el LCD y lo configura en el formato de 4 bits, con dos líneas de caracteres (5x7 puntos), en modo encendido, cursor apagado y sin parpadeo. Lcd_gotoxy (byte x, byte y); Indica la posición y línea donde se posiciona el cursor. byte x es posición del cursor y byte y el línea. Utilizamos funciones del compilador de C de CCS para escribir en el LCD. PRINTF(function, string, values) La función de impresión formateada PRINTF saca una cadena de caracteres al estándar serie RS-232 o a una función especificada. El formato está relacionado con el argumento que ponemos dentro de la cadena (string). function es una función. Ejemplo ( Lcd_putc) values es una lista de variables separadas por comas. Ejemplo V1,I1,DATO string es una cadena de caracteres, donde se indica, mensaje, número, tipo,\c. mensaje número Texto a escribir en el LCD (número de caracteres) es opcional 1-9 Cuantos caracteres se escriben. Microcontroladores IES Joan Miró Página 35

36 01-09 Indica cuantos ceros existen a la Izquierda para coma flotante. t ipo c s u d Lu Ld x X Lx LX f g e w \c puede ser: (tipo de carácter) puede ser: Carácter. Cadena o Carácter. Entero sin signo. Entero con signo. Entero Largo sin signo. Entero Largo con signo. Entero Hexadecimal (minúsculas). Entero Hexadecimal (mayúsculas). Entero largo Hexadecimal (minúsculas). Entero largo Hexadecimal(mayúsculas). Flotante con truncado. Flotante con redondeo. Flotante en formato exponencial. Entero sin signo con decimales insertados. La 1ª cifra indica el total de números, la 2ª cifra indica el número de decimales. \f Se limpia el LCD. \n El cursor va a la posición (1,2) \b El cursor retrocede una posición LCD_1.c // Programa...: LCD_1.c // // Plataforma hw: Placa Monibot 16F877A // // Fecha...: Mayo-2011 // // Programador..: Pedro Alonso // // Descripción..: Mostrar mensajes en el LCD // //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // ******************************** Directivas de Preprocesado**************************************** #include <16F877A.h> #fuses XT,NOWDT,NOPROTECT,NOLVP #use delay( clock = ) // Reloj de 1 MHz #include <flex_lcd.c> // Incluimos el driver flex_lcd.c que contiene las funciones de control del LCD. // *********************** Función principal o programa principal *********************************** void main() lcd_init(); printf(lcd_putc, "I.E.S. Joan Miro\n"); printf(lcd_putc, " Ciclo GM de EC"); // Inicializamos el LCD. // Escribimos "I.E.S. Joan Miro" y // saltamos a la siguiente línea. // Escribimos " Ciclo GM de EC". while (1); // Ejecuta está instrucción indefinidamente. Microcontroladores IES Joan Miró Página 36

37 LCD_2.c // Programa...: LCD_2.c // // Plataforma hw: Placa Monibot 16F877A // // Fecha...: Mayo-2011 // // Programador..: Pedro Alonso // // Descripción..: Mostrar números en diferentes formatos en el LCD // //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // ******************************* Directivas de Preprocesado**************************************** #include <16F877A.h> #fuses XT,NOWDT,NOPROTECT,NOLVP #use delay( clock = ) // Reloj de 1 MHz #include <flex_lcd.c> // Incluimos el driver flex_lcd.c que contiene las funciones de control del LCD. int8 numero_1 = 254; // Números comprendidos de 0 a 255 signed int8 numero_2 = -128; // Números comprendidos de -128 hasta 127 int8 numero_3 = 142; // Números comprendidos de 0 a 255 (8E en Hexadecimal) float numero_4 = -2.35; // Números con decimales // *********************** Función principal o programa principal *********************************** void main() lcd_init(); // Inicializamos el LCD. lcd_gotoxy(1,1); // Posicionamos el Cursor del LCD en la posición 1 línea 1. printf(lcd_putc,"%3u",numero_1); // Escribimos 3 dígitos de la variable "numero_1" en formato entero y // sin signo. lcd_gotoxy(8,1); // Posicionamos el Cursor del LCD en la posición 8 línea 1. printf(lcd_putc,"%4d",numero_2); // Escribimos 4 dígitos de la variable "numero_2" en formato entero // con signo. lcd_gotoxy(1,2); // Posicionamos el Cursor del LCD en la posición 1 línea 2. printf(lcd_putc,"%2x",numero_3); // Escribimos 2 dígitos de la variable "numero_3" en formato entero // hexadecimal mayúsculas. lcd_gotoxy(8,2); // Posicionamos el Cursor del LCD en la posición 8 línea 2. printf(lcd_putc,"%5.2f",numero_4); // Escribimos 5 dígitos de la variable "numero_4" en formato flotante. // La 1ª cifra indica el total de dígitos y la 2ª el número de decimales. while (1); // Fin LCD_3.c // Programa...: LCD_3.c // // Plataforma hw: Placa monibot 16F877A // // Fecha...: Mayo-2011 // // Programador..: Pedro Alonso // // Descripción..: Mostrar mensajes y array de números en formatos Decimal // // y Hexadecimal en el LCD // // ******************************** Directivas de Preprocesado**************************************** #include <16F877A.h> #fuses XT,NOWDT,NOPROTECT,NOLVP Microcontroladores IES Joan Miró Página 37

38 #use delay( clock = ) // Reloj de 1 MHz #include <flex_lcd.c> // Incluimos el driver flex_lcd.c que contiene las funciones // de control del LCD. byte CONST DIGIT_MAP[10]=162,5,64,100,245,11,255,16,217,5; // Array de 10 números tipo byte // ************************ Función principal o programa principal ********************************** void main() int8 i=0; // Declaramos la variable i en formato de 8 bit y la inicializamos con 0. lcd_init(); // Inicializamos el LCD. lcd_gotoxy(5,1); // Posicionamos el Cursor del LCD en la posición 5 línea 1. printf(lcd_putc, "Decimal"); // Escribimos la palabra "Decimal". lcd_gotoxy(5,2); // Posicionamos el Cursor del LCD en la posición 5 línea 2. printf(lcd_putc, "Hexadecimal"); // Escribimos la palabra "Hexadecimal". for(i=0; i <= 9; ++i) lcd_gotoxy(1,1); printf(lcd_putc,"%3u",digit_map[i]); lcd_gotoxy(2,2); printf(lcd_putc,"%2x",digit_map[i]); delay_ms(1000); // Sacamos los diez números del array uno a uno y los // representamos en el Display en diferentes formatos. // Posicionamos el Cursor del LCD en la posición // 1 línea 1. // Escribimos 3 dígitos del dato sacado del array // DIGITAL_MAP en formato entero y sin signo. // Posicionamos el Cursor del LCD en la posición // 2 línea 2. // Escribimos 2 dígitos del número sacado del // array DIGITAL_MAP en formato entero // hexadecimal mayúsculas. // Retardo de 1 segundo. while (1); // Fin LCD_4.c // Programa...: LCD_4.c // // Plataforma hw: Placa Monibot 16F877A // // Fecha...: Mayo-2011 // // Programador..: Pedro Alonso // // Descripción..: Mostrar mensajes y array de números en formatos entero 16 bit en el LCD // // *********************************** Directivas de Preprocesado************************************* #include <16F877A.h> #fuses XT,NOWDT,NOPROTECT,NOLVP #use delay( clock = ) // Reloj de 1 MHz #include <flex_lcd.c> // Incluimos el driver flex_lcd.c que contiene las funciones de control del LCD. int16 CONST NUMEROS[10]=267,456,856,23984,123,65535,65536,12,7,5; // Array de 10 números tipo // entero de 16 bit. Microcontroladores IES Joan Miró Página 38

39 // ************************** Función principal o programa principal ******************************** void main() int8 i=0; // Declaramos la variable i en formato de 8 bit y la inicializamos con 0. lcd_init(); // Inicializamos el LCD. lcd_gotoxy(9,1); // Posicionamos el Cursor del LCD en la posición 9 línea 1. printf(lcd_putc, "int16"); // Escribimos la palabra "int16". for(i = 0;i <= 9; ++i) lcd_gotoxy(1,1); printf(lcd_putc,"%5lu",numeros[i]); // Sacamos los diez números del array uno a uno y los representamos // en el Display. // Posicionamos el Cursor del LCD en la // posición 1 línea 1. // Escribimos 5 dígitos del dato sacado del array // NUMEROS en formato entero largo sin signo. // (No representa los ceros a la izquierda) delay_ms(1000); // Retardo de 1 segundo. while (1); // Fin LCD_5.c // Programa...: LCD_5.c // // Plataforma hw: Placa Monibot 16F877A // // Fecha...: Mayo-2010 // // Programador..: Pedro Alonso // // Descripción..: Mostrar mensajes y array de números en formatos entero 32 // // bit con signo en el LCD // // ************************************** Directivas de Preprocesado ********************************* #include <16F877A.h> #fuses XT,NOWDT,NOPROTECT,NOLVP #use delay( clock = ) // Reloj de 1 MHz #include <flex_lcd.c> // Incluimos el driver flex_lcd.c que contiene las funciones de control // del LCD. Signed Int32 CONST DATOS[10]=-26745, ,856323,234,123,235336,233,-12,-778,895; // Array de 10 // números tipo // entero de 32 bit // con signo. // *************************** Función principal o programa principal ****************************** void main() int8 i=0; // Declaramos la variable i en formato de 8 bit y la inicializamos con 0. lcd_init(); // Inicializamos el LCD. lcd_gotoxy(9,2); // Posicionamos el Cursor del LCD en la posición 9 línea 2. printf(lcd_putc, "S_int32"); // Escribimos la palabra "S_int32". Microcontroladores IES Joan Miró Página 39

40 for (i = 0;i <= 9; ++i) // Sacamos los diez números del array uno a uno y los // representamos en el Display. lcd_gotoxy(1,2); // Posicionamos el Cursor del LCD en la posición 1 línea 2. printf(lcd_putc,"%7ld",datos[i]); // Escribimos 7 dígitos del dato sacado del array // DATOS en formato entero largo con signo. (No // representa los ceros a la izquierda) delay_ms(1000); // Retardo de 1 segundo. while (1); // Fin LCD_6.c // Programa...: LCD_6.c // // Plataforma hw: Placa Monibot 16F877A // // Fecha...: Mayo-2011 // // Programador..: Pedro Alonso // // Descripción..: Mostrar mensajes y array de caracteres en el LCD // /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // ************************************ Directivas de Preprocesado*********************************** #include <16F877A.h> #fuses XT,NOWDT,NOPROTECT,NOLVP #use delay( clock = ) // Reloj de 1 MHz #include <flex_lcd.c> // Incluimos el driver flex_lcd.c que contiene las funciones de // control del LCD. Char CONST CARACTER[17]="arthgsupHF12erfj"; // Array tipo Char de 16 caracteres. // números tipo entero de 32 bit con signo. // *************************** Función principal o programa principal ******************************* void main() int8 i=0; // Declaramos la variable i en formato de 8 bit y la inicializamos con 0. lcd_init(); // Inicializamos el LCD. lcd_gotoxy(3,1); // Posicionamos el Cursor del LCD en la posición 3 línea 1. printf(lcd_putc, "(Caracteres)"); // Escribimos la palabra "(Caracteres)". lcd_gotoxy(8,2); // Posicionamos el Cursor del LCD en la posición 8 línea 2. for (i = 0;i <= 9; ++i) printf(lcd_putc,"%1c\b",caracter[i]); // Sacamos los diez números del array uno a uno y los // representamos en el Display en diferentes formatos. // Escribimos 1 dígitos tipo carácter sacado del // array CARACTER. Posicionamos el cursor // constantemente en la posición 8 línea 2. delay_ms(1000); // Retardo de 1 segundo. while (1); // Fin. Microcontroladores IES Joan Miró Página 40

41 LCD_7.c // Programa...: LCD_7.c // // Plataforma hw: Placa Monibot 16F877A // // Fecha...: Mayo-2011 // // Programador..: Pedro Alonso // // Descripción..: Queremos que aparezcan en la pantalla de un LCD las notas de un // // alumno de CM EC, en la primera línea el nombre y en la segunda // // Línea la nota y la signatura con una cadencia de un segundo // // ************************************* Directivas de Preprocesado ********************************** #include <16F877A.h> #fuses XT,NOWDT,NOPROTECT,NOLVP #use delay( clock = ) #include <flex_lcd.c> // Reloj de 1 MHz // Incluimos el driver flex_lcd.c que contiene las funciones de // control del LCD. byte CONST NOTAS[4]=10,8,2,6; // Array de 4 números tipo byte char CONST ASIGNATURAS[4][12]="Matematicas","Ingles ","Dibujo ","Fisica "; // Array de 4 filas 12 columnas // ***************************** Función principal o programa principal ***************************** void main() int8 i=0; // Declaramos la variable i en formato de 8 bit y la inicializamos con 0. lcd_init(); // Inicializamos el LCD. lcd_gotoxy(1,1); // Posicionamos el Cursor del LCD en la posición 1 línea 1. printf(lcd_putc,"jose Luengo"); // Escribimos las palabra "Jose Luengo". while(1) for(i = 0;i <= 3; i++) // Sacamos los 4 notas y asignaturas de los // arrays. lcd_gotoxy(13,2); // Posicionamos el Cursor en la posición 13 // línea 2. printf(lcd_putc,"%2u",notas[i]); // Escribimos 2 dígitos del dato sacado del // array NOTAS en formato entero y sin signo. lcd_gotoxy(1,2); // Posicionamos el Cursor en la posición 1 // línea 2. printf(lcd_putc,"%s",asignaturas[i]); // Escribimos los caracteres del array // ASIGNATURAS delay_ms(1000); // Retardo de 1 segundo. Microcontroladores IES Joan Miró Página 41

42 Entradas Digitales. Utilizaremos diferentes entrenadores, contenidos en la carpeta de Entradas Digitales Simulador de Periféricos Interruptores_Led_1.c // Programa...: Interruptores_Led_1.c // // Plataforma hw: Placa Monibot 16F877A // // Fecha...: Mayo-2011 // // Programador..: Pedro Alonso // // Descripción..: Leer la posición de los interruptores y llevar dicha información a los LED // //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // *********************************** Directivas de procesado **************************************** // (Controlan la conversión del programa a código máquina por parte del compilador) #include <16F877A.h> #fuses XT, NOWDT, NOPROTECT, NOLVP #use delay( clock = ) // Elección del uc 16F877A // Reloj de 1 MHz #BYTE TRISB = 0x86 #BYTE TRISA = 0x85 #BYTE portb = 0x06 #BYTE porta = 0x05 // Asignamos a la etiqueta TRISB la dirección 86h de memoria RAM. // Asignamos a la etiqueta TRISA la dirección 85h de memoria RAM. // Asignamos a la etiqueta portb la dirección 06h de memoria RAM. // Asignamos a la etiqueta porta la dirección 05h de memoria RAM. // *************************** Función principal o programa principal ******************************* // Se define con un void main, void main() TRISB = 0B ; // Defines Puerto B como SALIDA de datos. Microcontroladores IES Joan Miró Página 42

43 TRISA = 0B ; // Defines Puerta A como ENTRADA de datos. portb = 0; // Reseteas el puerto B. while (1) // Ejecuta indefinidamente lo que está entre corchetes. portb = porta; // Introducimos el contenido del puerto A en el puerto B Interruptores_Led_2.c /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Programa...: Interruptores_Led_2.c // // Plataforma hw: Placa Monibot 16F877A // // Entrenador: Simulador Periféricos.DSN // // Fecha...: Mayo-2011 // // Programador..: Pedro Alonso // // Descripción..: Leer puerto A si es menor o igual que 7 activar el Led RBO // /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // ********************************* Directivas de procesado******************************************* // (Controlan la conversión del programa a código máquina por parte del compilador) #include <16F877A.h> // Elección del uc 16F877A #fuses XT, NOWDT, NOPROTECT, NOLVP #use delay( clock = ) // Reloj de 1 MHz #BYTE TRISB = 0x86 #BYTE TRISA = 0x85 #BYTE portb = 0x06 #BYTE porta = 0x05 #BIT RB0 = 0x06.0 // Asignamos a la etiqueta TRISB la dirección 86h de memoria RAM. // Asignamos a la etiqueta TRISA la dirección 85h de memoria RAM. // Asignamos a la etiqueta portb la dirección 06h de memoria RAM. // Asignamos a la etiqueta porta la dirección 05h de memoria RAM. // Asignamos a la etiqueta RB0 la dirección 06.0h de memoria RAM. // ************************** Función principal o programa principal ******************************* // Se define con un void main, void main() TRISB = 0B ; // Defines Puerto B como SALIDA de datos. RISA = 0B ; // Defines Puerta A como ENTRADA de datos. portb = 0; // Reseteas el puerto B. while (1) if(porta<=7) RB0 = 1; else RB0 = 0; // Ejecuta indefinidamente lo que está entre corchetes. // Si porta es menor o igual que 7 realiza lo que está entre corchetes. // Encender el Led de RBO. // Si porta es mayor que 7 realiza lo que está entre corchetes. // Apagar el Led de RBO. Microcontroladores IES Joan Miró Página 43

44 Interruptores_DISPL_7S_1.c // Programa...: Interruptores_DISPL_7S_1.c // // Plataforma hw: Placa Monibot 16F877A // // Fecha...: Mayo-2011 // // Programador..: Pedro Alonso // // Descripción..: Leer el Puerto A y mostrar la información en un display de 7 Segmentos. // // Si el número es mayor de 9 poner la letra E. // // ************************************* Directivas de procesado*************************************** // (Controlan la conversión del programa a código máquina por parte del compilador) #include <16F877A.h> #fuses XT,NOWDT,NOPROTECT,NOLVP #use delay( clock = ) #BYTE TRISB = 0x86 #BYTE TRISA = 0x85 #BYTE portb = 0x06 #BYTE porta = 0x05 // Reloj de 1 MHz // Asignamos a la etiqueta TRISB la dirección 86h de memoria RAM. // Asignamos a la etiqueta TRISA la dirección 85h de memoria RAM. // Asignamos a la etiqueta portb la dirección 06h de memoria RAM. // Asignamos a la etiqueta porta la dirección 05h de memoria RAM. byte CONST DISPLAY[10] = 0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F; // Tabla de conversión de // BCD a 7 Seg. // *************************** Función principal o programa principal ******************************* // Se define con un void main, void main() TRISA = 0B ; // Defines Puerto A como ENTRADA de datos. TRISB = 0B ; // Defines Puerto B como SALIDA de datos. portb = 0B ; // Reseteamos el Puerto B. while (1) if(porta<=9) // Ejecuta indefinidamente lo que está entre corchetes. // Si porta <=9 mostrar en el Display 7Seg el valor en BCD. portb=display[porta]; // Mostramos en el Puerto B el valor que tiene // DISPLAY[portA]. else portb = 0B ; // Poner la letra E Microcontroladores IES Joan Miró Página 44

45 Interruptores_DISPL_7S_2.c. // Programa...: Interruptores_DISPL_7S_2.c // // Plataforma hw: Placa Monibot 16F877A // // Fecha...: Mayo-2010 // // Programador..: Pedro Alonso // // Descripción..: Leer el Puerto A y mostrar la información en un display de 7 Segmentos. // // Siguiendo el siguiente patrón: // // Si porta=0b aparecera en el Display 7Seg "0" parapadenado con una cadencia de 1 Seg. // // Si porta=0b aparecera en el Display 7Seg "1" parapadenado con una cadencia de 0,5 Seg. // // Si porta=0b aparecera en el Display 7Seg "2" parapadenado con una cadencia de 0,25 Seg. // // Si porta=0b aparecera en el Display 7Seg "3" parapadenado con una cadencia de 0,1 Seg. // // Si porta>0b aparecera en el Display 7Seg " " // //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // ************************************* Directivas de procesado*************************************** // (Controlan la conversión del programa a código máquina por parte del compilador) #include <16F877A.h> #fuses XT,NOWDT,NOPROTECT,NOLVP #use delay( clock = ) #BYTE TRISB = 0x86 #BYTE TRISA = 0x85 #BYTE portb = 0x06 #BYTE porta = 0x05 // Elección del uc 16F877A // Reloj de 1 MHz // Asignamos a la etiqueta TRISB la dirección 86h de memoria RAM. // Asignamos a la etiqueta TRISA la dirección 85h de memoria RAM. // Asignamos a la etiqueta portb la dirección 06h de memoria RAM. // Asignamos a la etiqueta porta la dirección 05h de memoria RAM. byte CONST DISPLAY [4]=0x3F,0x06,0x5B,0x4F; // Tabla de conversión de BCD a 7 Seg. // **************************** Función principal o programa principal ****************************** // Se define con un void main, void main() TRISB = 0B ; // Defines Puerto B como SALIDA de datos. TRISA = 0B ; // Defines Puerta A como ENTRADA de datos. portb = 0; // reseteas el puerto B. while (1) switch (porta) case 0: // Ejecuta indefinidamente lo que está entre corchetes. // Preguntamos por porta // Si porta=0 realiza lo que viene a continuación. portb = DISPLAY [0]; delay_ms(1000); portb = 0; delay_ms(1000); break; // Mostramos en el Puerto B el valor que tiene // DISPLAY[0]. // Retardo de 1 Segundo. // Apagar Display. // Retardo de 1 Segundo. // No realiza los siguientes casos. case 1: // Si porta=1 realiza lo que viene a continuación portb = DISPLAY[1]; delay_ms(500); portb = 0; delay_ms(500); break; // Mostramos en el Puerto B el valor que tiene // DISPLAY[1]. // Retardo de 0,5 Segundos. // Apagar Display. // Retardo de 0,5 Segundos. // No realiza los siguientes casos. case 2: // Si porta=2 realiza lo que viene a continuación portb = DISPLAY [2]; // Mostramos en el Puerto B el valor que tiene Microcontroladores IES Joan Miró Página 45

46 delay_ms(250); portb = 0; delay_ms(250); break; // DISPLAY[2]. // Retardo de 0,25 Segundos. // Apagar Display. // Retardo de 0,25 Segundos. // No realiza los siguientes casos. case 3: // Si porta=3 realiza lo que viene a continuación portb = DISPLAY [3]; delay_ms(100); portb = 0; delay_ms(100); break; // Mostramos en el Puerto B el valor que tiene // DISPLAY[3]. // Retardo de 0,1 Segundos. // Apagar Display. // Retardo de 0,1 Segundos. // No realiza los siguientes casos. default: // Si porta>3 realiza lo que viene a continuación portb = 0; // Apagar Display Pulsadores_DISPL_7S_1.c // Programa...: Pulsadores_DISPL_7S_1.c // // Plataforma hw: Placa Monibot 16F877A // // Fecha...: Mayo-2011 // // Programador..: Pedro Alonso // // Descripción..: Leer los pulsadores RCO(incremento) y T0CKI(Decremento) y mostrar la // // información en un Display de 7 Segmentos. // // ********************************* Directivas de procesado******************************************* // (Controlan la conversión del programa a código máquina por parte del compilador) #include <16F877A.h> #fuses XT,NOWDT,NOPROTECT,NOLVP #use delay( clock = ) // Reloj de 1 MHz #BYTE TRISC = 0x87 #BYTE portc = 0x07 #BYTE TRISB = 0x86 #BYTE portb = 0x06 #BYTE TRISA = 0x85 #BYTE porta = 0x05 #BIT rc0 = 0X07.0 #BIT t0cki = 0X05.4 // Asignamos a la etiqueta TRISC la dirección 87h de memoria RAM. // Asignamos a la etiqueta portc la dirección 07h de memoria RAM. // Asignamos a la etiqueta TRISB la dirección 86h de memoria RAM. // Asignamos a la etiqueta portb la dirección 06h de memoria RAM. // Asignamos a la etiqueta TRISA la dirección 85h de memoria RAM. // Asignamos a la etiqueta porta la dirección 05h de memoria RAM. // Asignamos a la etiqueta rc0 el bit 0 de la dirección 07h de la memoria RAM. // Asignamos a la etiqueta t0cki el bit 4 de la dirección 05h de la memoria RAM. byte CONST DISPLAY[10] = 0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F; // Tabla de conversión de BCD a 7 Seg. // ************************* Función principal o programa principal ********************************* // Se define con un void main, void main() signed int8 n=0; TRISC = 0B ; TRISA = 0B ; TRISB = 0B ; // Defines Puerto C como SALIDA de datos a excepción de // RC7 y RC0. // Defines Puerto A como ENTRADA de datos. // Defines Puerto B como SALIDA de datos. portb = DISPLAY[0]; // Ponemos en el Display de 7Seg. "0". Microcontroladores IES Joan Miró Página 46

47 while (1) WHILE(rc0==1) // Ejecuta indefinidamente lo que está entre corchetes. // Mientras rc0=1 haz lo que existe entre corchetes. n++; // Incrementar la variable n. if (n>9) // Si n>9 el Display de 7 Segmentos representa 9. portb = DISPLAY[9]; // Ponemos en el Display de 7Seg. "0". n=9; // Inicializar n=9. else portb=display[n]; delay_ms(1000); // Mostramos en el Puerto D el valor que tiene // DISPLAY[n]. // Retardo de 1 Segundo. WHILE(t0cki==0) // Mientras t0cki=0 haz lo que existe entre corchetes. n--; // Decrementar la variable n. if (n<0) // Si n<0 el Display de 7 Segmentos representa 0. portb = DISPLAY[0]; // Ponemos en el Display de 7Seg. "0". n=0; // Inicializar n=0. else portb=display[n]; delay_ms(1000); // Mostramos en el Puerto D el valor que tiene // DISPLAY[n]. // Retardo de 1 Segundo Simulador de Periféricos y Potencia. Microcontroladores IES Joan Miró Página 47

48 Interruptores_LCD_1.c // Programa...: Interruptores_LCD_1.c // // Plataforma hw: Placa Monibot 16F877A // // Entrenador: Simulador Potencia y Periféricos.DSN // // Fecha...: Mayo-2011 // // Programador..: Pedro Alonso // // Descripción..: Si RA0= 1 mostrar en el LCD Apagado. Si RA0= 0 mostrar en el LCD // // Encendido. // // Aparecera en LCD las veces que RA0=0 // // *********************************** Directivas de Preprocesado************************************* #include <16F877A.h> #fuses XT,NOWDT,NOPROTECT,NOLVP #use delay( clock = ) #include <flex_lcd.c> #BIT TA0 = 0X85.0 #BIT RA0 = 0X05.0 // Reloj de 1 MHz // Incluimos el driver flex_lcd.c que contiene las funciones de control // del LCD. // Asignamos TA0 el bit 0 de la dirección asociada a TRISA. // Asignamos a la etiqueta pulsador el bit 0 de la dirección 05h de la // memoria RAM. #define ON 1 // ON equivale a 1. int8 contador=0; int1 cambio=0; // **************************** Función principal o programa principal ****************************** void main() lcd_init(); TA0 = 1; while(1) // Inicializamos el LCD. // Configuramos la patilla RA0 com entrada de datos lcd_gotoxy(1,1); // Posicionamos el Cursor del LCD en la posición 1 línea 1. if(ra0==on) if (cambio==0) else delay_ms(50); printf(lcd_putc, "Encendido"); contador++; lcd_gotoxy(11,1); printf(lcd_putc,"%3u",contador); cambio=1; // Escribimos la palabra "Encendido". printf(lcd_putc, "Apagado "); // Escribimos la palabra "Apagado ". cambio=0; delay_ms(50); Microcontroladores IES Joan Miró Página 48

49 Interruptores_LCD_2.c ////////////////////////////////////// // Programa...: Pulsadores_LCD_2.c // // Plataforma hw: Placa Monibot 16F877A // // Entrenador: Simulador Potencia.DSN // // Fecha...: Mayo-2011 // // Programador..: Pedro Alonso // // Descripción..: Si RC0= 0 mostrar en el LCD Apagado. Si RC0= 1 mostrar en el LCD Encendido. // // aparecera en LCD y en el DISPLAY_7s las veces que RC0=1 // ////////////////////////////////////// // ************************************* Directivas de Preprocesado*********************************** #include <16F877A.h> #fuses XT, NOWDT, NOPROTECT, NOLVP #use delay( clock = ) // Reloj de 1 MHz #include <flex_lcd.c> #BYTE TRISB = 0x86 #BYTE portb = 0x06 // Incluimos el driver flex_lcd.c que contiene las funciones de control del LCD. // Asignamos a la etiqueta TRISB la dirección 86h de memoria RAM. // Asignamos a la etiqueta portb la dirección 06h de memoria RAM. #BIT TC0 = 0X87.0 // Asignamos TA0 el bit 0 de la dirección asociada a TRISA. #BIT RC0 = 0X07.0 // Asignamos a la etiqueta pulsador el bit 0 de la dirección 05h de la memoria // RAM. #define ON 1 // ON equivale a 1. int8 contador=0; int1 cambio=0; byte CONST DISPLAY[10] = 0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F; // Tabla de conversión de BCD a 7 Seg. // *********************** Función principal o programa principal *********************************** void main() lcd_init(); TC0 = 1; TRISB = 0B ; portb = DISPLAY[0]; // Inicializamos el LCD. // Configuramos la patilla RA0 com entrada de datos // Defines Puerto B como SALIDA de datos. while(1) lcd_gotoxy(1,1); // Posicionamos el Cursor del LCD en la posición 1 línea 1. if(rc0==on) // Si RA0=ON haz lo que viene a continuación. if (cambio==0) // Haz una sola vez elte proceso si RA0=ON printf(lcd_putc, "Encendido"); // Escribimos la palabra "Encendido". contador++; // Incremento la variable contador. lcd_gotoxy(11,1); printf(lcd_putc,"%3u",contador); portb = DISPLAY[contador]; // Posicionamos el Cursor del LCD en la // posición 11 línea 1. // Escribimos 3 dígitos de la variable // "contador" en formato entero y sin // signo. // Mostramos en el Puerto B el valor // que tiene la tabla DISPLAY[n] else cambio=1; delay_ms(50); // Cambiamos la variable. // Espereramos 50 ms. printf(lcd_putc, "Apagado "); // Escribimos la palabra "Apagado ". cambio=0; // Cambiamos la variable. delay_ms(50); // Espereramos 50 ms. Microcontroladores IES Joan Miró Página 49

50 Simulador de Potencia Pulsadores_LCD_1.c // Programa...: Pulsadores_LCD_1.c // // Plataforma hw: Placa Monibot 16F877A // // Fecha...: Mayo-2011 // // Programador..: Pedro Alonso // // Descripción..: Si RC0= 1 mostrar en el LCD Apagado. Si RC0= 0 mostrar en el LCD Encendido. // //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // *********************************** Directivas de Preprocesado ************************************ #include <16F877A.h> #fuses XT,NOWDT,NOPROTECT,NOLVP #use delay( clock = ) // Reloj de 1 MHz #include <flex_lcd.c> // Incluimos el driver flex_lcd.c que contiene las funciones de control del LCD. #BYTE TRISC = 0X87 // Asignamos a la etiqueta TRISC la dirección 87h de memoria RAM. #BIT pulsador = 0X07.0 // Asignamos a la etiqueta pulsador el bit 0 de la dirección 07h // de la memoria RAM. #define ON 1 // ON equivale a 1. // **************************** Función principal o programa principal ****************************** void main() lcd_init(); TRISC=0B ; while(1) // Inicializamos el LCD. // Ponemos el Puerto C como ENTRADA de // datos a excepción de RC7. lcd_gotoxy(1,1); // Posicionamos el Cursor del LCD en la posición 1 línea 1. if(pulsador==on) else printf(lcd_putc, "Encendido"); // Escribimos la palabra "Encendido". printf(lcd_putc, "Apagado "); // Escribimos la palabra "Apagado ". Microcontroladores IES Joan Miró Página 50

51 Entradas Analógicas. Los microcontroladores PIC llevan un sistema de adquisición de datos. Está compuesto por : Multiplexor Analógico (Selecciona la patilla a digitalizar). Circuito de muestreo y retención (Sample & Hold) (Retiene la señal analógica un instante para poderla muestrear). Conversor Analógico/Digital de aproximaciones sucesivas (Convierte las señales analógicas en códigos digitales). Las características principales son: Rango de Entrada. Simboliza que tensiones puede digitalizar (En los PIC de 0.. 5V) Número de bits de salida del Conversor A/D. En los PIC de gama media es de 10 bits. Resolución. (Indica que tensión mínima necesito para aumentar un código digital) Resolución = q = 1LSB = = = 4,8 mv. q= Intervalo de cuantificación. LSB= Bit menos significativo Si trabajamos con tensiones comprendidas entre Vref+ = 5V y Vref- =0V y con 10bits de salida obtenemos una resolución de 4,8 mv. Tempo de conversión (Tiempo que tarda el sistema de adquisición de datos en obtener una muestra digital proporcional a la tensión analógica) En un ucpic trabajando con un oscilador interno (RC) tarda entorno a 20uS Microcontroladores IES Joan Miró Página 51

52 Error de Cuantificación.( Indica para que rango mínimo de tensiones se asigna un valor digital) En un ucpic el Conversor A/D, trabaja con error por redondeo. Error = ± 2,4 mv. Error = ± LSB La relación existente entre tensiones de entrada Ve y códigos digitales de salida D se refleja en la siguiente tabla. Ve 0 < Ve 2,4 mv 2,4mV < Ve 7,2 mv 7,2mV < Ve 12 mv 12mV < Ve 16,8 mv 16,8mV < Ve 21,6 mv 4,9736mV < Ve 4,9904mV 4,9904mV < Ve 4,9952 mv Código Digital de salida del Conversor Analógico/Digital D 9 D 8 D 7 D 6 D 5 D 4 D 3 D 2 D 1 D D Nº Decimal Una fórmula válida para trabajar sería: Ve = Ejemplo: (Trabajando con tensiones comprendidas entre V REF+ = 5V y V REF+ = 0V ) Cuánto vale Ve si D=512? : Ve = = 2,5V El sistema de adquisición de datos te permite elegir el canal a digitalizar actuando sobre el Multiplexor Analógico (CHS2..CHS0) Te permite configurar las patillas actuando sobre un registro llamado (ADCON1) Indicando si son analógicas o digitales o si vas a utilizar Vref externas PCFG(3..0) AN7 AN6 AN5 AN4 AN3 AN2 AN1 AN0 V REF+ V REF A A A A A A A A VDD GND 0001 A A A A V REF+ A A A AN3D GND 0010 D D D A A A A A VDD GND 0011 D D D A V REF+ A A A AN3 GND 0100 D D D D A D A A VDD GND 0101 D D D D V REF+ D A A AN3 GND 011X D D D D D D D D A A A A V REF+ V REF- A A AN3 AN D D A A A A A A VDD GND 1010 D D A A V REF+ A A A AN3 GND 1011 D D A A V REF+ V REF- A A AN3 AN D D D A V REF+ V REF- A A AN3 AN D D D D V REF+ V REF- A A AN3 AN D D D D D D D A VDD GND 1111 D D D D V REF+ V REF- D A AN3 AN2 Trabajando en C el compilador CCS maneja unas funciones propias para la conversión analógica-digital. Para más información ver Conversión Analógica (3 bit). Microcontroladores IES Joan Miró Página 52

53 Conversión A-D_D-A AM FM C1 15p C2 15p + - VDD X1 CRYSTAL 4MHz V entrada U1 OSC1/CLKIN RB0/INT OSC2/CLKOUT RB1 MCLR/Vpp/THV RB2 RB3/PGM RA0/AN0 RB4 RA1/AN1 RB5 RA2/AN2/VREF- RB6/PGC RA3/AN3/VREF+ RB7/PGD RA4/T0CKI RA5/AN4/SS RC0/T1OSO/T1CKI RC1/T1OSI/CCP2 RC2/CCP1 RC3/SCK/SCL RC4/SDI/SDA RC5/SDO RC6/TX/CK RC7/RX/DT PIC16F CONVERSOR DIGITAL/ANALÓGICO D0 D1 D2 D3 D4 D5 D6 D7 LE DAC_8 VOUT VREF+ VREF- R1 5k R2 5k V salida VDD GENERADOR DE FUNCIONES VDD A OSCILOSCOPIO B V ENTRADA V SALIDA Microcontroladores IES Joan Miró Página 53

54 Conversión_A-D_A-D.c // Programa...: Conversión_A-D_A-D.c // // Plataforma hw: Placa Monibot 16F877A // // Fecha...: Septiembre-2011 // // Programador..: Pedro Alonso // // Descripción..: Digitalizar la señal Analógica procedente de la patilla AN0 y sacarla por el // // Puerto C // // Comprobar el Teorema de Nyquist fm>=2*fmax(señal) // // ********************************** Directivas de Preprocesado ************************************* #include <16F876A.h> #device adc=10 // Conversor Analógico Digital de 10 bit el PIC 16F876A puede trabajar // con 8 o 10 bit de resolucion. #FUSES XT,NOWDT #use delay(clock= ) //#use delay(clock= ) // Ojo Cambiar la frecuencia de reloj en el uc. #BYTE TRISC = 0x87 // TRISC en 87h. #BYTE portc = 0x07 // PORTC en 07h. // ************************** Función principal o programa principal ******************************* void main() int16 q; TRISC = 0B ; portc = 0; setup_adc_ports(0); setup_adc(adc_clock_internal); // Defines Puerto C como SALIDA de datos. // Seleccionamos el Puerto A como entradas Analógicas. // Mirar ADCON1. // Fuente de reloj RC interno. // setup_adc(adc_clock_div_2); // Fuente de reloj RC la marca el Cristal y un divisor de // frecuencia interno. set_adc_channel(0); // Habilitación canal 0 "AN0" while(1) delay_us(5); // delay_us(1); q = read_adc(); // Bucle infinito. // Retardo de 20uS necesaria para respetar el tiempo de // Adquisicion Tad. // Lectura canal 0 "AN0" portc = q; Microcontroladores IES Joan Miró Página 54

55 Conversión Analógica Digital. Utilizaremos los entrenadores Simulación Proteus.DSN y Conversión A-D.DSN, contenidos en la carpeta de Conversión Analógica Digital Conversión_A-D1.c // Programa...: Conversión_A-D1.c // // Plataforma hw: Placa Monibot 16F877A // // Fecha...: Septiembre-2011 // // Programador..: Pedro Alonso // // Descripción..: Conversión Analógica Digital de la Patilla AN0 // // ************************************ Directivas de Preprocesado************************************ #include <16F877A.h> #device adc=10 de resolucion. // Conversor Analogico Digital de 10 bit el PIC 16F876A puede trabajar con 8 o 10 bit #FUSES XT,NOWDT #use delay(clock= ) #include <flex_lcd.c> // Incluimos el driver flex_lcd.c que contiene las funciones de control del LCD. // *********************** Función principal o programa principal *********************************** void main() int16 q; float v; lcd_init(); setup_adc_ports(2); Mirar ADCON1. setup_adc(adc_clock_internal); set_adc_channel(0); for (;;) // Inicializamos el LCD. // Seleccionamos el Puerto A como entradas Analógicas. // Fuente de reloj RC interno. // Habilitación canal 0 "AN0" // Bucle infinito. delay_us(20); q = read_adc(); // Retardo de 20uS necesaria para respetar el tiempo de // Adquisición Tad. // Lectura canal 0 "AN0" Microcontroladores IES Joan Miró Página 55

56 v = 5.0 * q / ; printf(lcd_putc, "ADC = %4lu", q); // Conversión a tensión del código digital "q". // Escribimos en el LCD "ADC =" y 4 dígitos de "q" en // formato largo sin signo. printf(lcd_putc, "\nvoltage = %04.3fV", v); // Saltamos de línea y escribimos en el LCD // "VOLTAJE =" y 4 dígitos de "v" // en formato float de 4 dígitos con 3 decimales y // el carácter "V" Conversión_A-D2.c // Programa...: Conversión_A-D2.c // // Plataforma hw: Placa Monibot 16F877A // // Fecha...: Septiembre-2011 // // Programador..: Pedro Alonso // // Descripción..: Conversión Analógica Digital de la Patilla AN0 y AN3 // //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // *********************************** Directivas de Preprocesado ************************************ #include <16F877A.h> #device adc=10 // Conversor Analogico Digital de 10 bit el PIC 16F876A puede trabajar // con 8 o 10 bit de resolucion. #FUSES XT,NOWDT #use delay(clock= ) #include <flex_lcd.c> // Incluimos el driver flex_lcd.c que contiene las funciones de control del LCD. // **************************** Función principal o programa principal ***************************** void main() int16 q; float p; setup_adc(adc_clock_internal); setup_adc_ports(2); lcd_init(); while (true) set_adc_channel(0); delay_us(20); q = read_adc(); p = 5.0 * q / ; // Fuente de reloj RC interno. // Seleccionamos el Puerto A como entradas Analógicas. // Mirar ADCON1. // Inicializamos el LCD. // Bucle infinito. // Habilitación canal 0 "AN0" // Retardo de 20uS necesaria para respetar el // Tiempo de Adquisición Tad. // Lectura canal 0 "AN0" // Conversión a tensión del código digital "q". lcd_gotoxy(1,1); // Situamos el Cursor en la posición 1, línea 1. printf(lcd_putc, "V1=%04.3fv", p); // Escribimos en el LCD "V1=" y 4 dígitos de "P" // en formato float de 4 dígitos con 3 decimales // y el caracter "V". set_adc_channel(3); delay_us(20); q = read_adc(); p = 5.0 * q / ; // Habilitación canal 3 "AN3" // Retardo de 20uS necesaria para respetar el // Tiempo de Adquisición Tad. // Lectura canal 1 "AN1" // Conversión a tensión del código digital "q". lcd_gotoxy(1,2); // Situamos el Cursor en la posición 1, línea 2. printf(lcd_putc, "V2=%04.3fv", p); // Escribimos en el LCD "V2=" y 4 dígitos de "P" // en formato float de 4 dígitos con 3 decimales // y el caracter "V". Microcontroladores IES Joan Miró Página 56

57 Conversión_A-D2a.c // Programa...: Conversión_A-D2a.c // // Plataforma hw: Placa Monibot 16F877A // // Fecha...: Septiembre-2011 // // Programador..: Pedro Alonso // // Descripción..: Si RA2=1 digitalizamos la señal ANO y presentamos // // la Información en el LCD // // ******************************** Directivas de Preprocesado *************************************** #include <16F877A.h> #device adc=10 #FUSES XT,NOWDT #use delay(clock= ) #include <flex_lcd.c> // Conversor Analogico Digital de 10 bit el PIC 16F877A puede trabajar // con 8 o 10 bit de resolucion. // Incluimos el driver LCD1.c que contiene las funciones de control del LCD. #BIT RA2 = 0x05.2 #BIT TA2 = 0x85.2 // ********************* Función principal o programa principal ************************************ void main() int16 q; float p; setup_adc(adc_clock_internal); setup_adc_ports(4); lcd_init(); // Fuente de reloj RC interno. // Seleccionamos el Puerto A como entradas Analógicas. // Mirar ADCON1. // Inicializamos el LCD. TA2=1; Microcontroladores IES Joan Miró Página 57

58 while (true) // Bucle infinito. if(ra2 == 1) set_adc_channel(0); delay_us(20); q = read_adc(); p = 5.0 * q / ; // si RA2=1 se pone en funcionamiento pot R17A // Habilitación canal 0 "AN0" // Retardo de 5uS necesaria para respetar el // Tiempo de Adquisición Tad. // Lectura canal 0 "AN0" // Conversión a tensión del código digital "q". else lcd_gotoxy(1,1); // Situamos el Cursor en la posición 1, línea 1. printf(lcd_putc, "V1=%04.3fv", p); // Escribimos en el LCD "V1=" y 4 dígitos de "P" // en formato float de 4 dígitos con 3 decimales y // el caracter "V". set_adc_channel(3); delay_us(20); q = read_adc(); p = 5.0 * q / ; // Habilitación canal 3 "AN3" // Retardo de 5uS necesaria para respetar el // Tiempo de Adquisición Tad. // Lectura canal 1 "AN1" // Conversión a tensión del código digital "q". lcd_gotoxy(1,1); // Situamos el Cursor en la posición 1, línea 1. printf(lcd_putc, "V2=%04.3fv", p); // Escribimos en el LCD "V2=" y 4 dígitos de "P" // en formato float de 4 dígitos con 3 decimales y // el caracter "V" Modulación por Anchura de Pulso (PWM) Control de Motores de Corriente Continua. La velocidad de un Motor de Corriente Continua depende del valor medio de la tensión aplicada en sus extremos. El sistema más utilizado para controlar la velocidad de un motor DC de pequeña potencia es mediante la modulación por ancho de pulso PWM (Pulse Width Modulation) de una señal cuadrada TTL. El motor gira a una velocidad proporcional a la media del nivel de tensión de la señal cuadrada aplicada. La tensión media aplicada al motor se controla aplicando una señal cuadrada de frecuencia constante (Periodo constante T) y variando el tiempo a nivel alto T H de la señal, es decir variando su ciclo de trabajo CT= T H /T. Si el CT es del 50% la tensión media aplicada al motor será del 50%. A mayor tensión mayor velocidad. El microcontrolador PIC16F876A tiene incorporado dos circuito electrónicos que generan señal es PWM. Cada señal PWM sale por diferentes patillas RC1 y RC2. La frecuencia para ambas señales es la misma, ya que utilizan el mismo temporizador para generar dicha frecuencia (TIMER2). El compilador C de CCS nos proporciona unas funciones para trabajar con PWM. Para entender mejor lo explicado utilizaremos unos ejemplos. Microcontroladores IES Joan Miró Página 58

59 V motor Vmedia= 0% x 5v = 0v T H (Motor Parado) 0% CT = T H T x 100 = 0 ms 16 ms = 0 % T t (mseg) V motor 5v T H Vmedia= 20% x 5v = 1v 20% CT = T H T x 100 = 3,2 ms 16 ms = 20 % 3,2 T t (mseg) V motor Vmedia= 50% x 5v = 2,5v 5v T H 50% CT = T H T x 100 = 8 ms 16 ms = 50 % 8 T t (mseg) V motor Vmedia= 80% x 5v = 4v 5v T H 80% CT = T H T x ,8 ms = = 80 % 16 ms T 12, t (mseg) V motor Vmedia= 100% x 5v = 5v 5v T H (Velocidad Máxima) 100% CT = T H T x 100 = 16 ms 16 ms = 100 % T t (mseg) Utilizaremos el entrenador Simulador Potencia.DSN, contenidos en la carpeta de PWM\Control de Motores de CC\Motores de CC. Microcontroladores IES Joan Miró Página 59

60 Prueba_Motor_Derecho.c // Programa...: Prueba_Motor_Derecho.c // // Plataforma hw: Placa monibot 16F877A // // Fecha...: Septiembre_2011 // // Programador..: Pedro Alonso // // Descripción..: Prueba de Motor Derecho sin control de velocidad // //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // ********************************* Directiva de Preprocesado **************************************** // (Controlan la conversión del programa a código máquina por parte del compilador) #include <16F877A.h> #fuses XT,NOWDT #use delay( clock = ) #BYTE TRISC = 0x87 #BYTE portc = 0x07 #BYTE TRISB = 0x86 #BYTE portb = 0x06 #BIT giro_d = 0x06.3 #BIT en2 = 0x07.2 // Incluye el fichero 16F877A al programa tiene que estar en la misma carpeta // del programa define funciones, patillas y registros. // Define la palabra de configuración del microcontrolador PIC // Trabaja con un reloj tipo XT y no utiliza perro guardián Wathdog // Define la frecuencia del reloj de 1 MHz // Asignamos TRISC a la dirección 87h // (Registro de configuración del Puerto C). // Asignamos portc a la dirección 07h (Puerto de entrada y salida). // Asignamos TRISB a la dirección 86h // (Registro de configuración del Puerto A). // Asignamos portb a la dirección 06h (Puerto de entrada y salida). // Asignamos "giro_d" a la patilla 3 del Puerto B del // Microcontrolador PIC 16f876a. // Asignamos "en2" a la patilla 2 del Puerto C del Microcontrolador PIC 16f876a. Microcontroladores IES Joan Miró Página 60

61 // *************************** Función principal o programa principal ******************************* void main() // *********************** Configuración de los Puertos del PIC y reseteos del Rastreador ******************** TRISC = 0B ; TRISB = 0B ; // Defines Puerto C como SALIDA de datos a excepción de RC7/Rx y RC0 // Defines Puerto B como SALIDA de datos. / / ************************************************* Inicio ***************************************************************** while (1) en2 = 1; giro_d=0; // Ejecuta indefinidamente lo que está entre corchetes. // Activamos Motor Derecho.MOT2 // Motor Derecho hacia adelante. delay_ms(2000); // Retardo de 2 segundo. en2 = 0; // Paramos el Motor Derecho. delay_ms(2000); // Retardo de 2 segundo. en2 = 1; giro_d=1; // Activamos Motor Derecho. // Motor Derecho hacia atras.mot2 delay_ms(2000); // Retardo de 2 segundo. en2 = 0; // Paramos el Motor Derecho. delay_ms(2000); // Retardo de 2 segundo Prueba_Control_Velocidad_Motor_Derecho.c // Programa...: Prueba_Control_Velocidad_Motor_Derecho.c // // Plataforma hw: Placa monibot 16F877A // // Fecha...: Septiembre_2011 // // Programador..: Pedro Alonso // // Descripción..: Control de velocidad y sentido de giro de un motor de corriente // // continua. MOT2 // // ************************************ Directiva de Preprocesado ************************************* // (Controlan la conversión del programa a código máquina por parte del compilador) #include <16F877A.h> #fuses XT,NOWDT #use delay( clock = ) #BYTE TRISB = 0x86 #BYTE portb = 0x06 #BYTE TRISC = 0x87 #BYTE portc = 0x07 #BIT giro_d = 0x06.3 // Incluye el fichero 16F877A al programa tiene que estar en la misma // carpeta del programa define funciones, patillas y registros. // Define la palabra de configuración del microcontrolador PIC // Trabaja con un reloj tipo XT y no utiliza perro guardián Wathdog // Define la frecuencia del reloj de 4 MHz // Asignamos TRISB a la dirección 86h // (Registro de configuración del Puerto A). // Asignamos portb a la dirección 06h (Puerto de entrada y salida). // Asignamos TRISC a la dirección 87h // (Registro de configuración del Puerto C). // Asignamos portc a la dirección 07h (Puerto de entrada y salida). // Asignamos "giro_d" a la patilla RB3 del Microcontrolador PIC 16f876a. Microcontroladores IES Joan Miró Página 61

62 // ***************************** Función principal o programa principal **************************** void main() int16 i=0; / / ************************ Configuración de los Puertos del PIC y reseteos el dispositivo ********************* setup_timer_2(t2_div_by_16,249,1); // setup_timer(prescaler,pr2,postscaler) // Configuración timer2. Si el Periodo = 16mS ----> // T = 16000uS // T = [PR2+1] x Tcm x Postscaler x Prescaler // PR2 puede valer de 0 a 255. // Tcm es el tiempo de Ciclo Maquina. // Tcm = 4/Fosc = 4/ hz = 4uS. // Prescaler puede valer 1,4,16 // Postscaler puede valer 1. // 16000uS = [PR2+1] x 1 x 16 // PR2 =[T/(Tcm x Preescaler x Postscaler)]-1 // PR2 =[16000uS/(4uS x 16 x 1)]-1 = 249 (en C 249) setup_ccp1(ccp_pwm); TRISC = 0B ; set_pwm1_duty(i); TRISB = 0B ; // CCP2 en modo PWM (Salida por RC2)(Motor Derecho)MOT2 // Defines Puerto C como SALIDA de datos a excepción de // RC7, RC4 Y RCO. // Refresca el nivel alto de la señal PWM. // Salida por RC2. (Motor Derecho) // Defines Puerto B como SALIDA de datos. // ************************************************** Inicio **************************************************************** while (1) giro_d=0; // Ejecuta indefinidamente lo que está entre corchetes. // Motor Derecho hacia adelante. for(i=0;i<=1000;i=i+100) set_pwm1_duty(i); delay_ms(1000); // Refresca el nivel alto de la señal PWM. Salida por RC2. // (Motor Derecho) // Retardo de 1 segundo. Este tiempo tiene que ser superior // al periodo de de la señal "T= 16 ms". giro_d=1; // Motor Derecho hacia atrás. for(i=0;i<=1000;i=i+100) set_pwm1_duty(i); delay_ms(1000); // Refresca el nivel alto de la señal PWM. Salida por RC2. // (Motor Derecho) // Retardo de 1 segundo. Este tiempo tiene que ser superior // al periodo de la señal "T= 16 ms" Prueba_Control_Velocidad_Motor_Derecho_f.c // Programa...: Prueba_Control_Velocidad_Motor_Derecho_f.c // // Plataforma hw: Placa monibot 16F877A // // Fecha...: Septiembre_2011 // // Programador..: Pedro Alonso // // Descripción..: Control de velocidad y sentido de giro de un motor de // // corriente continua. MOT2 // Microcontroladores IES Joan Miró Página 62

63 // *********************************** Directiva de Preprocesado ************************************** // (Controlan la conversión del programa a código máquina por parte del compilador) #include <16F877A.h> #fuses XT,NOWDT #use delay( clock = ) #BYTE TRISB = 0x86 #BYTE portb = 0x06 #BYTE TRISC = 0x87 #BYTE portc = 0x07 #BIT giro_d = 0x06.3 // Incluye el fichero 16F877A al programa tiene que estar en la misma // carpeta del programa define funciones, patillas y registros. // Define la palabra de configuración del microcontrolador PIC // Trabaja con un reloj tipo XT y no utiliza perro guardián Wathdog // Define la frecuencia del reloj de 4 MHz // Asignamos TRISB a la dirección 86h // (Registro de configuración del Puerto A). // Asignamos portb a la dirección 06h (Puerto de entrada y salida). // Asignamos TRISC a la dirección 87h // (Registro de configuración del Puerto C). // Asignamos portc a la dirección 07h (Puerto de entrada y salida). // Asignamos "giro_d" a la patilla RB3 del Microcontrolador PIC 16f876a. // ************************************************** Declaración de funciones *************************************************** void Inicio_PWM(void); void Refresco_PWM(void); // Inico señal PW // Refresco señal PWM. // ************************ Función principal o programa principal ********************************** void main() // ************************** Configuración de los Puertos del PIC y reseteos el dispositivo ******************* Inicio_PWM(); TRISB = 0B ; // Defines Puerto B como SALIDA de datos. // ****************************************************** Inicio ************************************************************ while (1) giro_d=0; Refresco_PWM(); // Ejecuta indefinidamente lo que está entre corchetes. // Motor Derecho hacia adelante. giro_d=1; Refresco_PWM(); // Motor Derecho hacia atrás. // **************************************************** Funcion Inicio_PWM ******************************************************* void Inicio_PWM(void) int16 i=0; setup_timer_2(t2_div_by_16,249,1); // setup_timer(prescaler,pr2,postscaler) // Configuración timer2. Si el Periodo = 16mS ----> // T = 16000uS // T = [PR2+1] x Tcm x Postscaler x Prescaler // PR2 puede valer de 0 a 255. // Tcm es el tiempo de Ciclo Maquina. // Tcm = 4/Fosc = 4/ hz = 4uS. // Prescaler puede valer 1,4,16 // Postscaler puede valer 1. // 16000uS = [PR2+1] x 1 x 16 // PR2 =[T/(Tcm x Preescaler x Postscaler)]-1 // PR2 =[16000uS/(4uS x 16 x 1)]-1 = 249 (en C 249) setup_ccp1(ccp_pwm); TRISC = 0B ; set_pwm1_duty(i); // CCP2 en modo PWM (Salida por RC2) //(Motor Derecho)MOT2 // Defines Puerto C como SALIDA de datos a excepción // de RC7, RC4 Y RCO. // Refresca el nivel alto de la señal PWM. Salida por RC2. // (Motor Derecho) Microcontroladores IES Joan Miró Página 63

64 //************************************************** Funcion Refresco_PWM ****************************************************** void Refresco_PWM(void) int16 i=0; for(i=0;i<=1000;i=i+100) set_pwm1_duty(i); delay_ms(1000); // Refresca el nivel alto de la señal PWM. Salida por RC2. (Motor Derecho) // Retarodo de 1 segundo Prueba_Control_Velocidad_Motor_Izquierdo_Derecho_f.c // Programa...: Prueba_Control_Velocidad_Motor_Izquierdo_Derecho_f.c // // Plataforma hw: Placa monibot 16F877A // // Fecha...: Septiembre_2011 // // Programador..: Pedro Alonso // // Descripción..: Control de velocidad y sentido de giro de los motores de corriente // // continua. MOT1 y 2 // //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // *********************************** Directiva de Preprocesado ************************************** // (Controlan la conversión del programa a código máquina por parte del compilador) #include <16F876A.h> #fuses XT,NOWDT #use delay( clock = ) #BYTE TRISC = 0x87 #BYTE portc = 0x07 #BYTE TRISB = 0x86 #BYTE portb = 0x06 #BIT giro_d = 0x06.3 #BIT giro_i = 0x06.2 // Incluye el fichero 16F876A al programa tiene que estar en la misma // carpeta del programa define funciones, patillas y registros. // Define la palabra de configuración del microcontrolador PIC // Trabaja con un reloj tipo XT y no utiliza perro guardián Wathdog // Define la frecuencia del reloj de 4 MHz // Asignamos TRISC a la dirección 87h // (Registro de configuración del Puerto C). // Asignamos portc a la dirección 07h (Puerto de entrada y salida). // Asignamos TRISB a la dirección 86h // (Registro de configuración del Puerto A). // Asignamos portb a la dirección 06h (Puerto de entrada y salida). // Asignamos "giro_d" a la patilla 3 del Puerto B del // Microcontrolador PIC 16f876a. // Asignamos "giro_i" a la patilla 2 del Puerto B del // Microcontrolador PIC 16f876a. // ******************************************** Declaración de funciones ********************************************************* void Inicio_PWM(void); void Refresco_PWM(void); // Inico señal PW // Refresco señal PWM. // *************************** Función principal o programa principal ****************************** void main() // ********************** Configuración de los Puertos del PIC y reseteos el dispositivo *********************** Inicio_PWM(); TRISB = 0B ; // Defines Puerto B como SALIDA de datos. // ****************************************************** Inicio ************************************************************ while (1) giro_d=0; giro_i=0; Refresco_PWM(); // Ejecuta indefinidamente lo que está entre corchetes. // Motor Derecho hacia adelante. // Motor Izquierdo hacia adelante. Microcontroladores IES Joan Miró Página 64

65 giro_d=1; giro_i=1; Refresco_PWM(); // Motor Derecho hacia atrás. // Motor Izquierdo hacia atrás. // ************************************************ Funcion Inicio_PWM *********************************************************** void Inicio_PWM(void) int16 i=0; setup_timer_2(t2_div_by_16,249,1); // setup_timer(prescaler,pr2,postscaler) // Configuración timer2. Si el Periodo = 16mS ----> // T = 16000uS // T = [PR2+1] x Tcm x Postscaler x Prescaler // PR2 puede valer de 0 a 255. // Tcm es el tiempo de Ciclo Maquina. // Tcm = 4/Fosc = 4/ hz = 4uS. // Prescaler puede valer 1,4,16 // Postscaler puede valer 1. // 16000uS = [PR2+1] x 1 x 16 // PR2 =[T/(Tcm x Preescaler x Postscaler)]-1 // PR2 =[16000uS/(4uS x 16 x 1)]-1 = 249 (en C 249) setup_ccp1(ccp_pwm); setup_ccp2(ccp_pwm); TRISC = 0B ; set_pwm1_duty(i); set_pwm2_duty(i); // CCP2 en modo PWM (Salida por RC2) // (Motor Derecho)MOT2 // CCP2 en modo PWM (Salida por RC1) // (Motor Derecho)MOT1 // Defines Puerto C como SALIDA de datos a // excepción de RC7, RC4 Y RCO. // Refresca el nivel alto de la señal PWM. Salida por RC2. // (Motor Derecho) // Refresca el nivel alto de la señal PWM. Salida por RC1. // (Motor Izquierdo) // ************************************************* Funcion Refresco_PWM ****************************************************** void Refresco_PWM(void) int16 i=0; for(i=0;i<=1000;i=i+100) set_pwm2_duty(i); set_pwm1_duty(i); // Refresca el nivel alto de la señal PWM.Salida por RC1. (Motor Izquierdo) // Refresca el nivel alto de la señal PWM.Salida por RC2. (Motor Derecho) delay_ms(1000); // Retardo de 1 segundo. Microcontroladores IES Joan Miró Página 65

66 Servomotores de Posición. Un Servomotor de posición, da una posición angular proporcional a una variable eléctrica. Si se intenta variar la posición angular (Quitando o poniendo Inercia en su eje) este debe mantener su posición angular. Los servos de posición más utilizados en microcrobótica son los controlados por PWM. (Hitec HS-300, Futaba S3003, etc.) Están constituidos por un pequeño motor de corriente continua, unas ruedas dentadas que trabajan como reductoras, (dando una potencia considerable) y una pequeña tarjeta de control. Debido a la reductora mecánica formada por las ruedas mecánicas se pueden conseguir pares de fuerzas de 3 Kg/cm o superiores. La señal de PWM que ataca a los servos está comprendida entre 4 y 8V. El consumo puede ser considerable hasta que el servo alcanza su posición (hasta 500 ma). Funcionamiento: Utilizaremos el entrenador Simulación_Servomotores_Posición.DSN, contenido en la carpeta de PWM\ Control de un Servo de Posición. Microcontroladores IES Joan Miró Página 66

67 Control_2_Servo_Posición.c // Programa...: Control_2_Servo_Posición.c // // Plataforma hw: Placa monibot 16F877A // // Fecha...: Octubre-2010 // // Programador..: Pedro Alonso // // Descripción..: Control de 2 Servos de Posición // // *********************************** Directivas de Preprocesado ************************************ #include <16F877A.h> #device adc=8 // Conversor Analógico Digital de 10 bit el PIC 16F876A puede trabajar con // 8 o 10 bit de resolucion. #FUSES XT,NOWDT #use delay(clock= ) #include <Servo_Futaba_10bit.c> // Incluimos el driver que contiene las funciones de control de los // Servos de Futaba. // ******************************** Función principal o programa principal ************************** void main() int16 TH; Inicializacion_Futaba_RC1(); Inicializacion_Futaba_RC2(); // Inicialización del Servo en RC1 // Inicialización del Servo en RC2 // While (1); // Vemos posición central. setup_adc(adc_clock_internal); setup_adc_ports(0); // Fuente de reloj RC interno. // Seleccionamos el Puerto A como entradas Analógicas. // Mirar ADCON1. Microcontroladores IES Joan Miró Página 67

68 while (true) set_adc_channel(0); delay_us(5); TH = read_adc(); Futaba_RC1(TH); set_adc_channel(3); delay_us(5); TH = read_adc(); // Bucle infinito. // Habilitación canal 0 "AN0" // Retardo de 20uS necesaria para respetar el tiempo de // Adquisición Tad. // Lectura canal 0 "AN0" // Posicionar el Servo de la patilla RC1. // Habilitación canal 3 "AN3" // Retardo de 20uS necesaria para respetar el tiempo de // Adquisición Tad. // Lectura canal 1 "AN3" Futaba_RC2(TH); // Posicionar el Servo de la patilla RC Servo_ Futaba_10bit.c /* *********** Driver de control de un Servomotor de Posición de Futaba con PWM ********** /* ************************************ utilizando 10 bit de resolución ******************************** ; Con TH=0 corresponde a -90 grados de Posición del servo ; Con TH=57 corresponde a 0 grados de Posición del servo ; Con TH=113 corresponde a 90 grados de Posición del servo ;El microcontrolador PIC 16f876a tiene un hardware integrado que puede generar 2 señales PWM ;por las patillas RC2 y RC1. ;El periodo para ambas señales se fija con la siguiente fórmula ;T =[(PR2+1)*4*Tosc]*(TMR2_Valor_preescalar) ;El nivel alto T1H se controla con 10 bit ( Los 8 bit más significativo con el registro CCPR1L y ;los dos bit menos significativos con CCP1X y CCP1Y que están en el registro CCP1CON) ;Esta señal sale por la patilla RC2. ;El nivel alto T2H se controla con 10 bit ( Los 8 bit más significativo con el registro CCPR2L y ;los dos bit menos significativos con CCP2X y CCP2Y que están en el registro CCP2CON) ;Esta señal sale por la patilla RC1. ;Para refrescar el nivel alto T1H que haber transcurrido un tiempo superior a un periodo "T". ;El Servomotor de Futaba se controla con una señal cuadrada de periodo "T1". ;La posición del Servomotor lo determina el nivel alto de la senal "T1H" ;El Servomotor de Futaba necesita un periodo "T1" entre 10ms y 30 ms. ;Cargando los registros de forma correcta sale T1 =[(249+1)*4*1uS](16)=16 ms (Cristal de cuarzo 1 MHz) ;Tiene un control de Posición de -90 Grados < P (Angular)< +90 Grados controlado con T1H. ;Para -90 Grados corresponde un nivel alto T1H = 0,6 ms ;Para 0 Grados corresponde un nivel alto T1H = 1,2 ms ;Para +90 Grados corresponde un nivel alto T1H = 2,4 ms */ // ****************************************************** Declaración de funciones *********************************************** void Inicializacion_Futaba_RC1(); void Inicializacion_Futaba_RC2(); void Futaba_RC1(int16 TH); void Futaba_RC2(int16 TH); // Inicializar PWM por RC1 // Inicializar PWM por RC2 // Generar PWM por RC1 // Generar PWM por RC2 //*************************************************** Igualdades ****************************************************************** #define THmin 37 // THmin=37 equivale a 600uS a nivel alto a -90º #define THmax 150 // THmax=150 equivale a 2400uS a nivel alto a +90º Microcontroladores IES Joan Miró Página 68

69 #define THmed 94 // THmed=94 equivale a 1500uS a nivel alto a 0º // ************************************************** Función Inicializacion_Futaba_RC1() ************************************** void Inicializacion_Futaba_RC1() int16 TH; setup_timer_2(t2_div_by_16,249,1); // setup_timer(prescaler,pr2,postscaler) // Configuración timer2. Si el Periodo = 16mS ----> // T = 16000uS // T = [PR2+1] x Tcm x Postscaler // PR2 puede valer de 0 a 255. // Tcm es el tiempo de Ciclo Maquina. // Tcm = 4/Fosc = 4/ hz = 4uS. // Prescaler puede valer 1,4,16 // Postscaler puede valer 1. // 16000uS = [PR2+1] x 1 x 16 // PR2 =[T/(Tcm x Preescaler x Postscaler)]-1 // PR2 =[16000uS/(4uS x 16 x 1)]-1 = 249 (en C 249) setup_ccp2(ccp_pwm); TH = THmed; set_pwm2_duty(th); delay_ms(5); // CCP2 en modo PWM (Salida por RC1) // Cargar TH con valor medio // Refrescamos el Tiempo alto TH de la señal. // ************************************************* Función Inicializacion_Futaba_RC2() ************************************** void Inicializacion_Futaba_RC2() int16 TH; setup_timer_2(t2_div_by_16,249,1); // setup_timer(prescaler,pr2,postscaler) // Configuración timer2. Si el Periodo = 16mS ----> // T = 16000uS // T = [PR2+1] x Tcm x Postscaler // PR2 puede valer de 0 a 255. // Tcm es el tiempo de Ciclo Maquina. // Tcm = 4/Fosc = 4/ hz = 4uS. // Prescaler puede valer 1,4,16 // Postscaler puede valer 1. // 16000uS = [PR2+1] x 1 x 16 // PR2 =[T/(Tcm x Preescaler x Postscaler)]-1 // PR2 =[16000uS/(4uS x 16 x 1)]-1 = 249 (en C 249) setup_ccp1(ccp_pwm); TH = THmed; set_pwm1_duty(th); delay_ms(5); // CCP1 en modo PWM (Salida por RC2) // Cargar TH con valor medio // Refrescamos el Tiempo alto TH de la señal. // *********************************************** Función Futaba_RC1(int16 TH) ************************************************ void Futaba_RC1(int16 TH) TH = TH+THmin; if(th>thmin && TH<THmax) set_pwm2_duty(th); if(th<=thmin) TH=THmin+1; // Cargar TH con valor mínimo // Si THmin < TH < THmax // Refrescamos el Tiempo alto TH de la señal. // Si TH <= THmin // Cargar TH con valor mínimo Microcontroladores IES Joan Miró Página 69

70 set_pwm2_duty(th); // Refrescamos el Tiempo alto TH de la señal. if(th>=thmax) TH=THmax-1; set_pwm2_duty(th); // Si TH >= THmax // Cargar TH con valor máximo // Refrescamos el Tiempo alto TH de la señal. delay_ms(5); // Tiene que transcurrir un tiempo mayor que el periodo de la señal T =16000 us, // para refrescar el nivel alto de la señal. // Si utilizamos la función delay_ms(5)el tiempos de retardo equivale al // valor puesto multiplicado por 4 (Estamos utilizando un cristal de 1 MHz). // es decir 20ms. // ************************************************ Función Futaba_RC2(int16 TH) *********************************************** void Futaba_RC2(int16 TH) TH = TH+THmin; if(th>thmin && TH<THmax) set_pwm1_duty(th); if(th<=thmin) TH=THmin+1; set_pwm1_duty(th); if(th>=thmax) TH=THmax-1; set_pwm1_duty(th); // Cargar TH con valor mínimo // Si THmin < TH < THmax // Refrescamos el Tiempo alto TH de la señal. // Si TH <= THmin // Cargar TH con valor mínimo // Refrescamos el Tiempo alto TH de la señal. // Si TH >= THmax // Cargar TH con valor máximo // Refrescamos el Tiempo alto TH de la señal. delay_ms(5); // Tiene que transcurrir un tiempo mayor que el periodo de la señal T =16000 us, // para refrescar el nivel alto de la señal. // Si utilizamos la función delay_ms(5)el tiempos de retardo equivale al // valor puesto multiplicado por 4 (Estamos utilizando un cristal de 1 MHz). // es decir 20ms Interrupciones Externas. Las Interrupciones tienen la misión de poder detener un programa principal y ejecutar otro programa (Rutina de Interrupción) y volver al programa principal. Los µc tienen hardware especifico que se puede habilitar en modo interrupción. El PIC 16F877a tiene 14 modos diferentes de interrupción: En CCS existen diferentes funciones que permiten trabajar de forma sencilla las interrupciones. Las interrupciones externas como su nombre indica son patillas que permiten interrumpir programas principales. Microcontroladores IES Joan Miró Página 70

71 Interrupción por RB0/INT. Utilizaremos los entrenadores Simulación_Periféricos.DSN y Simulador Potencia y Periféricos.DSN, contenidos en la carpeta de Interrupciones Externas\ Interrupción_RB Interrupción_INT_RB0.c // Programa...: Interrupción_INT_RB0.c // // Plataforma hw: Placa Monibot 16F877A // // Fecha...: Septiembre_2011 // // Programador..: Pedro Alonso // // Descripción..: Manejo de Interrupción externa INT // // Un programa principal, simula las luces del Coche Fantástico. // // Cuando pulso la patilla RB0 interrumpimos el programa principal y // // ejecutamos un programa (rutina de interrupción) // // La rutina de interrupción, activa un buzzer tres veces con una cadencia // // de de 0,5 segundos // // *********************************** Directivas de Preprocesado ************************************ #include <16F877A.h> #fuses XT,NOWDT,PUT,NOWRT #use delay(clock= ) #BYTE TRISB = 0x86 // TRISB en 86h. #BYTE portb = 0x06 // PORTB en 06h. #BIT buzzer =0x06.2 // Patilla RB2 buzzer. int8 luces= 0B ; Microcontroladores IES Joan Miró Página 71

72 /* ******************************************** Declaración de funciones ******************************************************* */ void Coche_Fantastico (void); void Pitido (void); // Coche fantástico. // Pitido. /* ****************************** Función principal o programa principal ************************* */ void main() TRISB = 0B ; portb=luces; delay_ms(100); port_b_pullups(true); enable_interrupts(int_ext); ext_int_edge(l_to_h); enable_interrupts(global); // Defines Puerto B como SALIDA de datos a excepción de RB0. // retraso. // Habilitamos resistencias pullup. // Habilitamos la interrupción INT de la patilla RB0. // Que la interrupción de INT sea por flanco de subida. // Habilitamos la Interrupción General. while (1) // Bucle infinito de espera Coche_Fantastico(); /* ********************************** Atención a la interrupción por cambio en RB0 **************************************** */ #INT_EXT void Pitido() int8 i; for(i=0; i<3; i++) buzzer=1; delay_ms(500); buzzer=0; delay_ms(500); /* ************************************************ Coche_Fantastico ************************************************************ */ void Coche_Fantastico (Void) static int8 luces=0b ; int8 n; for(n=0;n<4;n++) luces<<=1; portb=luces; delay_ms(500); for(n=4;n>0;n--) luces>>=1; portb=luces; delay_ms(500); // Movemos un bit a la izquierda // retraso. //Movemos un bit a la derecha. //Retraso. Microcontroladores IES Joan Miró Página 72

73 Interrupción_INT_RB0a.c // Programa...: Interrupciones_RB0a.c // // Plataforma hw: Placa Monibot 16F877A // // Fecha...: Septiembre_2011 // // Programador..: Pedro Alonso // // Descripción..: Manejo de Interrupción externa INT // // Un programa principal, simula las luces del Coche Fantástico. // // Cuando pulso la patilla RB0 interrumpimos el programa principal // // y ejecutamos un programa (rutina de interrupción) // // La rutina de interrupción, genera un sonido bitonal en un altavoz tres veces // // con una cadencia de de 0,5 segundos. // // *********************************** Directivas de Preprocesado ************************************ #include <16F877A.h> #fuses XT,NOWDT,PUT,NOWRT #use delay(clock= ) #BYTE TRISB = 0x86 // TRISB en 86h. #BYTE portb = 0x06 // PORTB en 06h. #BIT altavoz =0x06.1 // Patilla RB1 altavoz. int8 luces=0b ; /* ******************************************* Declaración de funciones ******************************************************** */ void Coche_Fantastico (void); void Tono (void); // Coche fantástico. // pitidos. /* ********************************** Función principal o programa principal ************************************************ */ void main() TRISB = 0B ; // Defines Puerto B como SALIDA de datos a excepción de RB0. portb = luces; // inicializamos el puerto B. delay_ms(100); // Retraso. port_b_pullups(true); enable_interrupts(int_ext); ext_int_edge(l_to_h); enable_interrupts(global); while (1) Coche_fantastico(); // Habilitamos resistencias pullup. // Habilitamos la interrupción INT de la patilla RB0. // Que la interrupción de INT sea por flanco de subida. // Habilitamos la Interrupción General. // Bucle infinito de espera /* ***************************** Atención a la interrupción por cambio en RB0 ********************************************* */ #INT_EXT void Tono() int16 i; // for(i=0;i<5000;i++) // Real for(i=0;i<500;i++) // Simulado altavoz=1; delay_us(100); altavoz=0; delay_us(100); Microcontroladores IES Joan Miró Página 73

74 //for(i=0;i<1000;i++) for(i=0;i<100;i++) altavoz=1; delay_us(500); altavoz=0; delay_us(500); // Real // Simulado /* ************************************************ Coche_Fantastico ************************************************************ */ void Coche_Fantastico (void) static int8 luces=0b ; int8 n=0; for (n=0;n<4;n++) luces<<=1; portb=luces; delay_ms(100); for (n=4;n>0;n--) luces>>=1; portb=luces; delay_ms(100); // Movemos un bit a la izquierda // Retraso. // Movemos un bit a la derecha. // Retraso Interrupción_INT_RB0b.c Microcontroladores IES Joan Miró Página 74

75 // Programa...: Interrupción_INT_RB0b.c // // Plataforma hw: Placa monibot 16F877A // // Fecha...: Septiembre_2011 // // Programador..: Pedro Alonso // // Descripción..: Manejo de Interrupción externa INT // // Un programa principal, pone dos mensajes en el LCD con una // // cadencia de 1 Segundo. Cuando pulso la patilla RB0, interrumpimos el // // programa principal y ejecutamos un programa (rutina de interrupción) // // La rutina de interrupción, generar números "0,1,2,3" en el DISPLAY_7SEG // // con una cadencia de 0,5 segundos // // *********************************** Directivas de Preprocesado ************************************ #include <16F877A.h> #fuses XT,NOWDT,PUT,NOWRT #use delay(clock= ) #include <flex_lcd.c> #define Numeros_Tabla 3 // Incluimos el driver flex_lcd.c que contiene las funciones de control del LCD. // Números de la Tabla. #BYTE TRISB = 0x86 // TRISB en 86h. #BYTE portb = 0x06 // PORTB en 06h. byte CONST DISPLAY[10] = 0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F; // Tabla de conversión de BCD a 7 Seg. /* *********************************************** Declaración de funciones **************************************************** */ void Mensajes (void); void Display_7s (void); // Función Mensaje. // Función Display_7s. /* *************************** Función principal o programa principal **************************** */ void main() TRISB = 0B ; lcd_init(); port_b_pullups(true); enable_interrupts(int_ext); ext_int_edge(l_to_h); enable_interrupts(global); // Defines Puerto B como SALIDA de datos a excepción de RB0. // Inicializamos el LCD. // Habilitamos resistencias pullup. // Habilitamos la interrupción INT de la patilla RB0. // Que la interrupción de INT sea por flanco de subida. // Habilitamos la Interrupción General. while (1) Mensajes(); // Bucle infinito de espera /* ********************************* Atención a la interrupción por cambio en RB0 ***************************************** */ #INT_EXT void Display_7s() int8 n=0 ; // Declaramos la variable n con 8 bit y la inicializamos con 0. for (n=0; n<=numeros_tabla; n++) portb = DISPLAY[n]; delay_ms(500); portb = 0B ; // Se ejecuta un bucle desde n=0 hasta n<numeros_tabla en orden //ASCENDENTE de uno en uno // Mostramos en el Puerto B el valor que tiene la tabla DISPLAY[n] // Retardo de 0,5 Segundo. // Apagar DISPLAY_7SEG. Microcontroladores IES Joan Miró Página 75

76 /* ************************************************ Coche_Fantastico ************************************************************ */ void Mensajes (Void) lcd_gotoxy(1,1); // Posicionamos el Cursor del LCD en la posición 1 línea 1. printf(lcd_putc,"ies Joan Miro"); // Escribimos el mensaje "IES Joan Miro". delay_ms(1000); lcd_gotoxy(1,1); // Posicionamos el Cursor del LCD en la posición 1 línea 1. printf(lcd_putc,"cfgs DPE "); // Escribimos el mensaje "CFGS DPE ". delay_ms(1000); Interrupción por cambio de nivel de RB4_5_6_ Interrupción_INT_RB4567.c // Programa...: Interrupción_INT_RB4567.c // // Plataforma hw: Placa monibot 16F877A // // Fecha...: Septiembre_2011 // // Programador..: Pedro Alonso // // Descripción..: Manejo de las Interrupciones de INT y por cambio de nivel // // de RB4, RB5, RB6, RB7. // // Un programa principal, ejecuta un programa que mueve un Motor PAP. // // Cuando púlso la patilla RB0 interrumpimos el programa principal y // // activamos un Motor de CC y si volvemos a pulsar lo desactivamos. // // Cuando abrimos o cerramos la patilla RB4,RB5,RB6 ó RB7, // // interrumpimos el programa principal y activamos ó desactivamos un LED // Microcontroladores IES Joan Miró Página 76

77 // *********************************** Directivas de Preprocesado ************************************ #include <16F876A.h> #fuses XT,NOWDT,PUT,NOWRT #use delay(clock= ) #BYTE TRISC = 0x87 // TRISC en 87h. #BYTE portc = 0x07 // PORTC en 07h. #BYTE TRISB = 0x86 // TRISB en 86h. #BYTE portb = 0x06 // PORTB en 06h. #BIT rc0 = 0x07.0 // RC0 en 0x07 patilla 0. #BIT rc1 = 0x07.1 // RC1 en 0x07 patilla 1. #BIT rc2 = 0x07.2 // RC2 en 0x07 patilla 2. #BIT rc3 = 0x07.3 // RC3 en 0x07 patilla 3. #BIT rc4 = 0x07.4 // RC4 en 0x07 patilla 4. #BIT rc5 = 0x07.5 // RC5 en 0x07 patilla 5. #BIT RBIF = 0x0B.0 // RBIF en 0x0B patilla 0. /* *************************************** Declaración de funciones ************************************************************ */ void Activar_Motor (void); void Led (void); void Motor_PAP (Void); // Activa el Motor. // Encender Led. // Motor_PAP. /* ************************* Función principal o programa principal ****************************** */ void main() int n; TRISB = 0B ; TRISC = 0B ; // Necesario para borrar el flag en el Proteus // Defines Puerto B como ENTRADA de datos. // Defines Puerto C como SALIDA de datos. portc = 0B ; // Reseteamos el Puerto C. port_b_pullups(true); n = portb; RBIF = 0; enable_interrupts(int_rb); enable_interrupts(int_ext); ext_int_edge(l_to_h); enable_interrupts(global); // Habilitamos resistencias pullup. // Necesario para borrar el flag en el Proteus // Necesario para borrar el flag en el Proteus // Habilitamos la interrupción por cambio de nivel de RB4, RB5, RB6, RB7. // Habilitamos la interrupción INT de la patilla RB0. // Que la interrupción de INT sea por flanco de subida. // Habilitamos la Interrupción General. while (1) Motor_PAP(); // Bucle infinito de espera /* ********************************* Atención a la interrupción por cambio en RB0 ***************************************** */ #INT_EXT void Activar_Motor() rc5 = ~rc5; // Lee rc5 lo complementa a 1 y lo carga en rc5. Microcontroladores IES Joan Miró Página 77

78 /* ********************** Atención a la interrupción por cambio en RB4,RB5,RB6 y RB7. ******************************** */ #INT_RB void Led() int n; rc4 = ~rc4; n = portb; // Necesario en el Proteus, para poder borrar el flag RBIF. // Lee rc4 lo complementa a 1 y lo carga en rc4. // Necesario en el Proteus, para poder borrar el flag RBIF. /* *********************************************** Motor Paso a Paso ************************************************************ */ void Motor_PAP (Void) rc3 = 0; rc2 = 0; rc1 = 0; rc0 = 1; delay_ms(500); rc3 = 0; rc2 = 0; rc1 = 1; rc0 = 1; delay_ms(500); rc3 = 0; rc2 = 0; rc1 = 1; rc0 = 0; delay_ms(500); rc3 = 0; rc2 = 1; rc1 = 1; rc0 = 0; delay_ms(500); rc3 = 0; rc2 = 1; rc1 = 0; rc0 = 0; delay_ms(500); rc3 = 1; rc2 = 1; rc1 = 0; rc0 = 0; delay_ms(500); rc3 = 1; rc2 = 0; rc1 = 0; rc0 = 0; delay_ms(500); rc3 = 1; rc2 = 0; rc1 = 0; rc0 = 1; delay_ms(500); // Posicionamos el Motor PAP en la 1ª Posición. // Retardo de 500 ms // Posicionamos el Motor PAP en la 2ª Posición. // Retardo de 500 ms // Posicionamos el Motor PAP en la 3ª Posición. // Retardo de 500 ms // Posicionamos el Motor PAP en la 4ª Posición. // Retardo de 500 ms // Posicionamos el Motor PAP en la 5ª Posición. // Retardo de 500 ms // Posicionamos el Motor PAP en la 6ª Posición. // Retardo de 500 ms // Posicionamos el Motor PAP en la 7ª Posición. // Retardo de 500 ms // Posicionamos el Motor PAP en la 8ª Posición. // Retardo de 500 ms Microcontroladores IES Joan Miró Página 78

79 Interrupción_INT_RB4567a.c // Programa...: Interrupción_INT_RB4567a.c // // Plataforma hw: Placa monibot 16F877A // // Fecha...: Septiembre_2011 // // Programador..: Pedro Alonso // // Descripción..: Manejo de las Interrupciones de INT y por cambio de // // nivel de RB4, RB5, RB6, RB7. // // Un programa principal, ejecuta un programa que mueve un Motor PAP. // // Cuando pulso la patilla RB0 interrumpimos el programa principal // // y activamos y desactivamos un Motor de CC, 10 veces con una // // cadencia de 1 Segundo. // // Cuando abrimos o cerramos la patilla RB4, RB5, RB6 ó RB7, // // interrumpimos el programa principal // // y activamos ó desactivamos un LED, 5 veces con una cadencia de // // 0,5 Segundo. // // *********************************** Directivas de Preprocesado ************************************ #include <16F876A.h> #fuses XT,NOWDT,PUT,NOWRT #use delay(clock= ) #BYTE TRISC = 0x87 // TRISC en 87h. #BYTE portc = 0x07 // PORTC en 07h. #BYTE TRISB = 0x86 // TRISB en 86h. #BYTE portb = 0x06 // PORTB en 06h. #BIT rc0 = 0x07.0 // RC0 en 0x07 patilla 0. #BIT rc1 = 0x07.1 // RC1 en 0x07 patilla 1. #BIT rc2 = 0x07.2 // RC2 en 0x07 patilla 2. #BIT rc3 = 0x07.3 // RC3 en 0x07 patilla 3. #BIT rc4 = 0x07.4 // RC4 en 0x07 patilla 4. #BIT rc5 = 0x07.5 // RC5 en 0x07 patilla 5. #BIT RBIF = 0x0B.0 // RBIF en 0x0B patilla 0. Necesario para Proteus /* ************************************* Declaración de funciones ************************************************************** */ void Activar_Motor (void); void Led (void); void Motor_PAP (Void); // Activa el Motor. // Encender Led. // Motor_PAP. /* ********************** Función principal o programa principal ********************************* */ void main() int n; TRISB = 0B ; TRISC = 0B ; // Necesario para borrar el flag en el Proteus // Defines Puerto B como ENTRADA de datos. // Defines Puerto C como SALIDA de datos. portc = 0B ; // Reseteamos el Puerto C. port_b_pullups(true); n = portb; RBIF = 0; enable_interrupts(int_rb); enable_interrupts(int_ext); ext_int_edge(l_to_h); enable_interrupts(global); // Habilitamos resistencias pullup. // Necesario para borrar el flag en el Proteus // Necesario para borrar el flag en el Proteus // Habilitamos la interrupción por cambio de nivel // de RB4, RB5, RB6, RB7. // Habilitamos la interrupción INT de la patilla RB0. // Que la interrupción de INT sea por flanco de subida. // Habilitamos la Interrupción General. Microcontroladores IES Joan Miró Página 79

80 while (TRUE) // Bucle infinito de espera Motor_PAP(); /* ******************************* Atención a la interrupción por cambio en RB0 ******************************************* */ #INT_EXT void Activar_Motor(void) int i; for(i=0;i<10;i++) rc5 = ~rc5; delay_ms(1000); // Lee rc5 lo complementa a 1 y lo carga en rc5. /* ******************** Atención a la interrupción por cambio en RB4, RB5, RB6 y RB7. ******************************** */ #INT_RB void Led(void) int i; for(i=0;i<5;i++) rc4 = ~rc4; delay_ms(500); // Necesario en el Proteus, para poder borrar el flag RBIF. // Lee rc4 lo complementa a 1 y lo carga en rc4. i = portb; // Necesario en el Proteus, para poder borrar el flag RBIF. /* ********************************************** Motor Paso a Paso ************************************************************* */ void Motor_PAP (Void) rc3 = 0; rc2 = 0; rc1 = 0; rc0 = 1; delay_ms(500); rc3 = 0; rc2 = 0; rc1 = 1; rc0 = 1; delay_ms(500); rc3 = 0; rc2 = 0; rc1 = 1; rc0 = 0; delay_ms(500); rc3 = 0; rc2 = 1; rc1 = 1; rc0 = 0; delay_ms(500); rc3 = 0; rc2 = 1; rc1 = 0; // Posicionamos el Motor PAP en la 1ª Posición. // Retardo de 500 ms // Posicionamos el Motor PAP en la 2ª Posición. // Retardo de 500 ms // Posicionamos el Motor PAP en la 3ª Posición. // Retardo de 500 ms // Posicionamos el Motor PAP en la 4ª Posición. // Retardo de 500 ms // Posicionamos el Motor PAP en la 5ª Posición. Microcontroladores IES Joan Miró Página 80

81 rc0 = 0; delay_ms(500); rc3 = 1; rc2 = 1; rc1 = 0; rc0 = 0; delay_ms(500); rc3 = 1; rc2 = 0; rc1 = 0; rc0 = 0; delay_ms(500); rc3 = 1; rc2 = 0; rc1 = 0; rc0 = 1; delay_ms(500); // Retardo de 500 ms // Posicionamos el Motor PAP en la 6ª Posición. // Retardo de 500 ms // Posicionamos el Motor PAP en la 7ª Posición. // Retardo de 500 ms // Posicionamos el Motor PAP en la 8ª Posición. // Retardo de 500 ms Temporizadores y Contadores. (Timer 0,1 y 2). Los timer o temporizadores es un hardware específico contenido en los microcontroladores que tienen la misión de contar pulsos del exterior o temporizar (Si trabajamos con los timer en modo interrupción podemos crear sistemas multitarea). El µc PIC16F877A tiene 3 timer. Utilizaremos las funciones del compilador CCS para programarlos Timer 0. Se trata de un temporizador/contador de 8 bits. La fuente de eventos puede ser interna (Temporizador) o externa (Contador de pulsos, patilla RA4) Si trabaja como contador de pulsos del exterior, se pude seleccionar que la cuenta sea por la detección de un flanco se subida (T0SE=0) o de bajada (T0SE=1) en RA4. Dispone de una pre-escala programable de 8 bits que se selecciona vía software Cuando TMR0 supera el valor de 255 el Timer se ha desbordado y el flag T0IF se pone a 1 Se puede trabajar en modo POLLING (Preguntando si T0IF=1 constantemente ó por un valor del registro TMR0) o interrupción si T0IF=1(Para ello es necesario que estas estén activadast0ie=1 y GIE=1). Está asociado al temporizador Watchdog si PSA=1. Microcontroladores IES Joan Miró Página 81

82 El tiempo o pulsos contados están en función de esta fórmula: T = Tcm x Prescaler x (256 - INICIO_CUENTA) Donde Tcm = 4/Fosc donde Fosc es el reloj que pongamos al µc. Prescaler puede valer (1,2,4,8,16,32,64,128,256) INICIO_CUENTA es el valor de carga inicial en el registro TMR0 (0 a 255) El valor máximo de T es cuando Prescaler= 256 e INICIO_CUENTA= 0 Ejemplo: Si el reloj es de Fosc=4Mhz Tcm = 4/Fosc= 4/4Mhz= 1µS. Tmax= Tcm x Preescaler x (256 - INICIO_CUENTA) = 1µS. x 256 x (256-0)= µs. Utilizaremos los entrenadores Simulación Proteus.DSN y Simulación_Periféricos_y_Servos.DSN, contenidos en la carpeta de Timer\ Timer Timer0_Contador.c Microcontroladores IES Joan Miró Página 82

83 // Programa...: Timer0_Contador.c // // Plataforma hw: Placa Monibot 16F877A // // Fecha...: Septiembre_2011 // // Programador..: Pedro Alonso // // Descripción..: Manejo del Timer 0 como contador de pulsos del exterior // // Cada 4 pulso producidos en la patilla RA4/TOCKI incrementamos una // // variable y la representamos en el LCD. Cuando la variable supere 5 se // // pondrá a 0 // // *********************************** Directivas de Preprocesado ************************************ #include <16F877A.h> #fuses XT,NOWDT,PUT,NOWRT #use delay(clock= ) #include <flex_lcd.c> // Incluimos el driver flex_lcd.c que contiene las funciones de control del LCD. #BYTE TRISB = 0x87 // TRISB en 86h. #BYTE portb = 0x07 // PORTB en 06h. #define numero 5 /* ***************************** Función principal o programa principal ************************** */ void main() int8 contador=0; int8 contador_anterior=0; lcd_init(); // Inicializamos el LCD. lcd_gotoxy(1,1); // Posicionamos el Cursor del LCD en la posición 1 línea 1. printf(lcd_putc,"%3u",contador); // Escribimos 3 dígitos de la variable "contador" en formato // entero y sin signo. setup_timer_0(rtcc_div_4 RTCC_EXT_L_TO_H); set_timer0(0); // Programamos el Timer 0 en modo contador de // pulsos con prescaler de 4 // Inicializamos el contador timer 0 con inicio de // cuenta. while (TRUE) do contador = get_timer0(); if(contador!=contador_anterior) contador_anterior=contador; // Bucle infinito de espera // Leemos el Contador. // Escribir en el el LCD si contador ha variado. // Preguntamos si ha llegado el final de // la cuenta. while(contador<=numero); lcd_gotoxy(1,1); printf(lcd_putc,"%3u",contador); // Posicionamos el Cursor del LCD en la // posición 1 línea 1. // Escribimos 3 dígitos de la variable // "contador" en formato entero y sin // signo. set_timer0(0); // Inicializamos el contador timer 0 con // inicio de cuenta. Microcontroladores IES Joan Miró Página 83

84 Timer0_temporizador_multitarea_1.c // Programa...: Timer0_temporizador_multitarea_1.c // // Plataforma hw: Placa Monibot 16F877A // // Fecha...: Septiembre-2011 // // Programador..: Pedro Alonso // // Descripción..: Un programa principal activa un servo en 2 posiciones y cada 0.20ms // // se interrumpe el programa principal y generamos una señal cuadrada // // de 0,2 ms por la patilla RB0 // // *********************************** Directivas de Preprocesado ************************************ #include <16F877A.h> #fuses XT,NOWDT,PUT,NOWRT #use delay(clock= ) #include <Servo_Futaba_10bit.c> #BIT TB0 = 0x86.0 #BIT RB0 = 0x06.0 // Incluimos el driver que contiene las funciones de control de los Servos // de Futaba. // TB0 en la direccón 86.Oh. // RB0 en la dirección 06.0h. int8 INICIO_CUENTA=61; // Si el periodo de la señal T= us Cargamos inicio de cuenta con // T/2= us // T = us. // T = Tcm x Preescaler x (256 - INICIO_CUENTA) // Despejando INICIO_CUENTA = [T/(Tcm x Prescaler)] // Tcm es el tiempo de Ciclo Maquina. Tcm = 4/Fosc = 4/ hz = 4uS. // INICIO_CUENTA = [100000uS/(4uS x 128)] = 61 // Esto es cierto si se trabaja en ensamblador. El tiempo de ejecución en C es // mayor. // Utilizando herramientas de proteus o MPLAB sacamos que T = 61 Microcontroladores IES Joan Miró Página 84

85 /* *************************************** Declaración de funciones ************************************************************ */ void Senal_Cuadrada (Void); // Generar una señal cuadrada por RBO. /* **************************** Función principal o programa principal *************************** */ void main() int16 TH; TB0 = 0; RB0 = 0; Inicializacion_Futaba_RC1(); // Defines RB0 como SALIDA de datos. // Apagamos el Led de RB0. // Inicialización del Servo en RC1 //while(1); setup_timer_0(rtcc_div_128 RTCC_INTERNAL); // Programamos el Timer 0 en modo contador de // pulsos con prescaler de 256 set_timer0(inicio_cuenta); // Inicializamos el contador timer 0 con inicio de cuenta. enable_interrupts(int_timer0); // Habilitamos la interrupción por Timer 0. enable_interrupts(global); // Habilitamos la interrupción global. while (1) TH = 0; Futaba_RC1(TH); delay_ms(500); TH = 56; Futaba_RC1(TH); delay_ms(500); // Bucle infinito de espera // Posicionar el Servo de la patilla RC1. // Retardo de 0.5 seg. // Posicionar el Servo de la patilla RC1. // Retardo de 0.5 seg. /* ******************* Atención a la interrupción por desbordamiento del TIMER 0 ************************************** */ #INT_TIMER0 void Senal_Cuadrada (Void) RB0 = ~RB0; set_timer0(inicio_cuenta); // Lee RB0 lo complementa a 1 y lo carga en RB0. // Pulsar AltGr 4 y barra espaciadora para el símbolo "~" // Inicializamos el Timer 0 para temporizar 0,25 segundos Timer0_temporizador_multitarea_2.c // Programa...: Timer0_temporizador_multitarea_2.c // // Plataforma hw: Placa Monibot 16F877A // // Fecha...: Septiembre-2011 // // Programador..: Pedro Alonso // // Descripción..: Un programa principal activa un servo en 2 posiciones y cada 0.25ms // // se interrumpe el programa principal y simula las luces del coche fantástico. // Microcontroladores IES Joan Miró Página 85

86 // *********************************** Directivas de Preprocesado ************************************ #include <16F877A.h> #fuses XT,NOWDT,PUT,NOWRT #use delay(clock= ) #include <Servo_Futaba_10bit.c> // Incluimos el driver que contiene las funciones de control de los // Servos de Futaba. #BYTE TRISB = 0x86 // TRISB en la direccón 86h. #BYTE portb = 0x06 // PORTB en la dirección 06h. int8 INICIO_CUENTA=12; // Cargamos inicio de cuenta // T = us. // T = Tcm x Preescaler x (256 - INICIO_CUENTA) // Despejando INICIO_CUENTA = [T/(Tcm x Prescaler)] // Tcm es el tiempo de Ciclo Maquina. // Tcm = 4/Fosc = 4/ hz = 4uS. // INICIO_CUENTA = [250000uS/(4uS x 256)] = 11 // Esto es cierto si se trabaja en ensamblador. El tiempo de ejecución // en C es mayor. // Utilizando herramientas de proteus o MPLAB sacamos que T = 12 /* ********************************************* Declaración de funciones ****************************************************** */ void coche_fantastico (Void); // Simulación del coche fantastico. /* *************************** Función principal o programa principal **************************** */ void main() int16 TH; TRISB = 0B ; // Defines Puerto B como SALIDA de datos. portb = 0b ; // inicializamos el puerto B. delay_ms(245); // Retraso. Inicializacion_Futaba_RC1(); // Inicialización del Servo en RC1 //while(1); setup_timer_0(rtcc_div_256 RTCC_INTERNAL); // Programamos el Timer 0 en modo contador de // pulsos con prescaler de 256 set_timer0(inicio_cuenta); // Inicializamos el contador timer 0 con inicio de cuenta. enable_interrupts(int_timer0); // Habilitamos la interrupción por Timer 0. enable_interrupts(global); // Habilitamos la interrupción global. while (1) TH = 0; // Bucle infinito de espera Futaba_RC1(TH); delay_ms(500); // Posicionar el Servo de la patilla RC1. // Retardo de 0.5 seg. TH = 56; Futaba_RC1(TH); delay_ms(500); // Posicionar el Servo de la patilla RC1. // Retardo de 0.5 seg. Microcontroladores IES Joan Miró Página 86

87 /* **************** Atención a la interrupción por desbordamiento del TIMER 0 ***************************************** */ #INT_TIMER0 void coche_fantastico (Void) #DEFINE DERECHA 0 #DEFINE IZQUIERDA 1 static int8 ir=derecha; switch (ir) // Preguntamos por la variable "ir" si es 0 ejecuta el case 0, //si es 1 el case 1, case 0: portb<<=1; if(portb==128) ir=izquierda; break; // Rotamos el portb hacia la izquierda case 1: portb>>=1; if(portb==1) ir=derecha; break; set_timer0(inicio_cuenta); // Rotamos el portb hacia la derecha // Inicializamos el Timer 0 para temporizar 0,25 segundos Timer 1. Se trata de un temporizador/contador de 16 bits. RC0) La fuente de eventos puede ser interna (Temporizador) o externa (Contador de pulsos, patilla Puede seleccionar una fuente de reloj interna (T1CON.TMR1CS = 0) o externa (T1CON.TMR1CS = 1) Dispone de una preescaler programable de (1,2,4,8) que se selecciona vía software Cuando TMR1 supera el valor de el Timer se ha desbordado y el flag TMR1IF se pone a 1 Microcontroladores IES Joan Miró Página 87

88 Se puede trabajar en modo POLLING (Preguntando si TMR1IF =1 constantemente ó por un valor del registro TMR1) o interrupción si TMR1IF =1(Para ello es necesario que estas estén activadastmr1ie=1 y GIE=1). El tiempo o pulsos contados están en función de esta fórmula: T = Tcm x Prescaler x ( INICIO_CUENTA) Donde Tcm = 4/Fosc donde Fosc es el reloj que pongamos al µc. Prescaler puede valer (1,2,4,8) INICIO_CUENTA es el valor de carga inicial en el registro TMR1 (0 a 65535) El valor máximo de T es cuando Prescaler= 8 e INICIO_CUENTA= 0 Ejemplo: Si el reloj es de Fosc=4Mhz Tcm = 4/Fosc= 4/4Mhz= 1µS. Tmax= Tcm x Preescaler x ( INICIO_CUENTA) = 1µS. x 8 x ( )= µs. Utilizaremos los entrenadores Simulación Proteus.DSN y Simulación_Potencia.DSN, contenidos en la carpeta de Timer\ Timer Timer1_Contador.c Microcontroladores IES Joan Miró Página 88

89 // Programa...: Timer1_Contador.c // // Plataforma hw: Placa Monibot 16F877A // // Fecha...: Septiembre-2011 // // Programador..: Pedro Alonso // // Descripción..: Contar pulsos de exterior (T1CK) y Mostrar en el LCD // // *********************************** Directivas de Preprocesado ************************************ #include <16F877A.h> #fuses XT,NOWDT,PUT,NOWRT #use delay(clock= ) #include <flex_lcd.c> // Incluimos el driver flex_lcd.c que contiene las funciones de control del LCD. /* **************************** Función principal o programa principal *************************** */ void main() int16 contador; int16 pulsos=20; LCD_init(); //setup_timer_1(t1_external T1_DIV_BY_1); setup_timer_1(t1_external T1_DIV_BY_2); // inicializamos LCD // Programamos el Timer 1 en modo contador de // pulsos; ESTA ES REAL //setup_timer_1(t1_external T1_DIV_BY_2); // ESTA ES SIMULADA while (TRUE) // Bucle infinito de espera set_timer1(0); // Inicializamos el contador timer 1 con 0. Do contador = get_timer1(); //delay_ms(200); // Leemos el Contador. lcd_gotoxy(1,1); printf(lcd_putc,"%2lu",contador); While (contador<= pulsos); // Posicionamos el Cursor del LCD en la posición // 1 línea 1. // Mostramos contador en el LCD. // Preguntamos si ha llegado el final de la cuenta Timer1_temporizador_multitarea.c // Programa...: Timer1_temporizador_multitarea.c // // Plataforma hw: Placa Monibot 16F877A // // Fecha...: Septiembre-2011 // // Programador..: Pedro Alonso // // Descripción..: Un programa principal realiza la simulación del coche fantástico y se // // interrumpe cada 100 ms realizando una conversión analógica/digital // // por AN0 y muestra su valor en tensión en el LCD. // // *********************************** Directivas de Preprocesado ************************************ #include <16F877A.h> #device adc=10 #fuses XT,NOWDT,PUT,NOWRT #use delay(clock= ) #include <flex_lcd.c> // Conversor Analogico Digital de 10 bit el PIC 16F877A puede trabajar con // 8 o 10 bit de resolucion. // Incluimos el driver LCD1.c que contiene las funciones de control del LCD. Microcontroladores IES Joan Miró Página 89

90 #BYTE TRISB = 0x86 // TRISB en la direccón 86h. #BYTE portb = 0x06 // PORTB en la dirección 06h. int16 INICIO_CUENTA = 40536; // Cargamos inicio de cuenta // T = us. // El semiperiodo viene definido por // T = Tcm x Prescaler x ( INICIO_CUENTA) // Despejando INICIO_CUENTA = [T/(Tcm x Prescaler)] // Tcm es el tiempo de Ciclo Maquina. Tcm = 4/Fosc = 4/ hz = 4uS. // INICIO_CUENTA = [100000uS/(4uS x 1)] = // Esto es cierto si se trabaja en ensamblador. // El tiempo de ejcucion en C es mayor. // Utilizando herramientas de proteus o MPLAB sacamos que T = /* ************************************************* Declaración de funciones ************************************************** */ void Voltimetro (Void); // Simulación de un voltimetro de 0 a 5v. /* **************************** Función principal o programa principal *************************** */ void main() int8 n=0 ; // Entero que usaremos como contador y salida de datos //******************************** Inicializar los led ********************************************************************* TRISB = 0B ; // Defines Puerto B como SALIDA de datos. portb = 0b ; // inicializamos el puerto B. delay_ms(50); // Retraso. //******************************* Inicializar la conversión analógica/digital ***************************************** setup_adc(adc_clock_internal); setup_adc_ports(4); // Fuente de reloj RC interno. // Seleccionamos el Puerto A como entradas Analógicas. // Mirar ADCON1. //******************************** Inicializar el LCD ********************************************************************* lcd_init(); // Inicializamos el LCD. //*************************** Inicializamos el timer1 en modo interrupción *************************************** setup_timer_1(t1_internal T1_DIV_BY_1); set_timer1(inicio_cuenta); // Programamos el Timer 1 en modo temporizador // Con prescaler de 1 // Inicializamos el contador timer 1 con inicio de cuenta. enable_interrupts(int_timer1); // Habilitamos la interrupción del Timer 1 enable_interrupts(global); // Habilitamos la Interrupción General. //************************************ Coche fantástico ***************************************************************** while (1) // Bucle infinito de espera for(n=0;n<7;n++) portb<<=1; // Movemos un bit a la izquierda delay_ms(200); for(n=7;n>0;n--) portb>>=1; delay_ms(200); // Retraso. // Movemos un bit a la derecha. // Retraso. Microcontroladores IES Joan Miró Página 90

91 /* **************************** Atención a la interrupción por desbordamiento del TIMER 1 ***************************** */ #INT_TIMER1 void Voltimetro (Void) int16 q; float p; set_adc_channel(0); delay_us(5); q = read_adc(); p = 5.0 * q / ; // Habilitación canal 0 "AN0" // Retardo de 20uS necesaria para respetar el Tiempo de // Adquisición Tad. // Lectura canal 0 "AN0" // Conversión a tensión del código digital "q". lcd_gotoxy(1,1); // Situamos el Cursor en la posición 1, línea 1. printf(lcd_putc, "V1=%01.3fv", p); // Escribimos en el LCD "V1=" y 4 dígitos de "P" // en formato truncado de 4 dígitos con 3 decimales y el // caracter "V". set_timer1(inicio_cuenta); // Inicializamos el contador timer 1 con inicio de cuenta Timer 2. Se trata de un temporizador de 8 bits con pre-escala y post-escala. Cuenta ciclos de instrucción (Fosc=4). Se activa con T2CON.TMR2ON = 1 Pre-escala seleccionable entre 1:1, 1:4 ó 1:16 mediante T2CON.T2CKPS1:T2CKPS0. Dispone de un registro periodo PR2 (Configurable de 0 a 255). El registro TMR2 se incrementa partiendo de cero hasta alcanzar PR2. La salida del temporizador TMR2 pasa por una post-escala programable: 1:1...1:16 (T2CON.TOUTPS3:TOUTPS0) antes de generar una interrupción. Genera interrupciones si: INTCON.GIE = 1, habilitación global. INTCON.PEIE=1 y PIE1.TMR2IE = 1, habilitación local. Cuando el campo PIR1.TMR2IF = 1, indica que se alcanzó el periodo. Hay que borrarlo después. (Cuando TMR2 se iguala con PR2, teniendo en cuenta el Prescaler y Postscaler) El tiempo o pulsos contados están en función de esta fórmula: T = Tcm x [Prescaler x (PR2+1) x Postscaler] Donde Tcm = 4/Fosc donde Fosc es el reloj que pongamos al µc. Prescaler puede valer (1,4,16) Microcontroladores IES Joan Miró Página 91

92 Postscaler puede valer (1,2,,16) El valor máximo de T es cuando Prescaler= 16 y Postscaler= 16 y PR2= 255 Ejemplo: Si el reloj es de Fosc=4Mhz Tcm = 4/Fosc= 4/4Mhz= 1µS. Tmax= Tcm x [Prescaler x (PR2+1) x Postscaler] = 1µS. x [16 x (255+1) x 16] = µs. Utilizaremos el entrenador Timer2.DSN contenido en la carpeta de Timer\ Timer Timer2_Señal_Cuadrada.c // Programa...: Timer2_Señal_Cuadrada.c // // Plataforma hw: Placa Monibot 16F877A // // Fecha...: Septiembre-2011 // // Programador..: Pedro Alonso // // Descripción..: Generar una señal cuadrada de 1 KHz // // ********************************* Directivas de Preprocesado ************************************** #INCLUDE <16F877A.h> #use delay(clock= ) #fuses XT,NOWDT #BYTE TRISB = 0x86 // TRISB en 86h. #BYTE portb = 0x06 // PORTB en 06h. #BIT rb0 = 0x06.0 // RB0 en 0x06 patilla 0. Microcontroladores IES Joan Miró Página 92

93 /* *************************************** Declaración de funciones ************************************************************ */ void Timer2 (void); // Declaración de la función del Timer 2. /* *********************** Función principal o programa principal ******************************** */ void main() TRISB = 0B ; // Defines Puerto B como SALIDA de datos. portb = 0B ; // Reseteamos el Puerto B. setup_timer_2(t2_div_by_4,124,5); // setup_timer(prescaler,pr2,postscaler) // Configuración timer2. Si el Periodo = 1mS ----> T = 500uS // T = Tcm[Prescaler x(pr2+1)x Postscaler] // PR2 puede valer de 0 a 255. // Tcm es el tiempo de Ciclo Maquina. // Tcm = 4/Fosc = 4/ hz = 0,2uS. // Prescaler puede valer 1,4,16 // Postscaler puede valer 1,2,3,...,15,16. // 500uS = 0,2uS[1.(PR2+1)1] // PR2 =[T/(Tcm x Preescaler x Postscaler)]-1 // PR2 =[500uS/(0,2uS x 4 x 5)]-1 = 124 enable_interrupts(int_timer2); enable_interrupts(global); while (1); // Habilita interrupción timer2 // Habilita interrupción general // bucle infinito /* ************************** Atención a la interrupción por desbordamiento del TIMER 2 ****************************** */ #int_timer2 void Timer2 (void) rb0 = ~rb0; Timer2_Servos_Posicion.c // Programa...: Timer2_Servos_Posicion.c // // Plataforma hw: Placa Monibot 16F877A // // Fecha...: Septiembre-2011 // // Programador..: Pedro Alonso // // Descripción..: Control de 4 Servomotores de Posición vía software // // ********************************** Directivas de Preprocesado ************************************* #INCLUDE <16F877A.h> #device adc=8 // Conversor Analógico Digital de 10 bit el PIC 16F876A puede // trabajar con 8 o 10 bit de resolución. #use delay(clock= ) #fuses XT,NOWDT #BYTE TRISD = 0x88 // TRISD en 88h. #BYTE portd = 0x08 // PORTD en 08h. #BIT rd0 = 0x08.0 // RD0 en 0x08 patilla 0. Microcontroladores IES Joan Miró Página 93

94 #BIT rd1 = 0x08.1 // RD1 en 0x08 patilla 1. #BIT rd2 = 0x08.2 // RD2 en 0x08 patilla 2. #BIT rd3 = 0x08.3 // RD2 en 0x08 patilla 2. /* ***************************** Declaración de funciones ****************************************** */ void Timer2 (int16,int16,int16,int16,int16,int16,int16,int16); // Declaración de la función del Timer 2. /* *********************** Función principal o programa principal ******************************** */ void main() int16 h1,l1,h2,l2,h3,l3,h4,l4; TRISD = 0B ; // Defines Puerto D como SALIDA de datos. portd = 0B ; // Reseteamos el Puerto D. setup_timer_2(t2_div_by_1,199,1); setup_adc(adc_clock_internal); setup_adc_ports(0); enable_interrupts(int_timer2); enable_interrupts(global); // setup_timer(prescaler,pr2,postscaler) // Configuración timer2. T = 40uS // T = Tcm[Prescaler x(pr2+1)x Postscaler] // PR2 puede valer de 0 a 255. // Tcm es el tiempo de Ciclo Maquina. // Tcm = 4/Fosc = 4/ hz = 0,2uS. // Prescaler puede valer 1,4,16 // Postscaler puede valer 1,2,3,...,15,16. // 40uS = 0,2uS[1.(PR2+1)1] // PR2 =[T/(Tcm x Preescaler x Postscaler)]-1 // PR2 =[40uS/(0,2uS x 1 x 1)]-1 = 199 // Fuente de reloj RC interno. // Seleccionamos el Puerto A como entradas Analógicas. // Mirar ADCON1. // Habilita interrupción timer2 // Habilita interrupción general while (1) set_adc_channel(0); delay_us(5); // bucle infinito // Habilitación canal 0 "AN0" // Retardo de 5uS necesaria para respetar el tiempo de // Adquisición Tad. // Lectura canal 0 "AN0" h1 = read_adc(); h1=(h1/5)+15; // THmín (h1=0) --> h1=(0/5)+15=15 --> // THmín(uS)= 15*40uS= 600uS. if(h1>60) h1=60; // Limita el tiempo THmax --> // THmax(uS)=60*40uS= 2400uS. l1=400-h1; // Periodo(h1=0)--> T(uS)= 400*40uS= 16000uS= 16mS. set_adc_channel(1); delay_us(5); h2 = read_adc(); h2=(h2/5)+15; if(h2>60) h2=60; l2=400-h2; set_adc_channel(2); delay_us(5); h3 = read_adc(); h3=(h3/5)+15; if(h3>60) h3=60; l3=400-h3; set_adc_channel(3); delay_us(5); h4 = read_adc(); h4=(h4/5)+15; if(h4>60) h4=60; l4=400-h4; // Habilitación canal 1 "AN1" // Retardo de 5uS necesaria para respetar el tiempo de // Adquisición Tad. // Lectura canal 1 "AN1" // Habilitación canal 2 "AN2" // Retardo de 5uS necesaria para respetar el tiempo de // Adquisición Tad. // Lectura canal 2 "AN0" // Habilitación canal 3 "AN3" // Retardo de 5uS necesaria para respetar el tiempo de // Adquisición Tad. // Lectura canal 3 "AN0" Timer2 (h1,l1,h2,l2,h3,l3,h4,l4); Microcontroladores IES Joan Miró Página 94

95 /* ******************************* Atención a la interrupción por desbordamiento del TIMER 2 ************************** */ int_timer2 void Timer2 (int16 h1,int16 l1,int16 h2,int16 l2,int16 h3,int16 l3,int16 h4,int16 l4) int16 th1,tl1,th2,tl2,th3,tl3,th4,tl4; // ************************************* Control del Servomotor 1 ******************************** if(th1<h1) rd0 = 1; th1++; else if(tl1<l1) else rd0 = 0; tl1++; th1=0; tl1=0; // ************************************* Control del Servomotor 2 ******************************** if(th2<h2) rd1 = 1; th2++; else if(tl2<l2) else rd1 = 0; tl2++; th2=0; tl2=0; // ************************************* Control del Servomotor 3 ******************************** if(th3<h3) rd2 = 1; th3++; else if(tl3<l3) else rd2 = 0; tl3++; th3=0; tl3=0; Microcontroladores IES Joan Miró Página 95

96 // ************************************* Control del Servomotor 4 ******************************** if(th4<h4) rd3 = 1; th4++; else if(tl4<l4) else rd3 = 0; tl4++; th4=0; tl4=0; Transmisión Serie de Datos. USART El módulo USART (Universal Synchronous Asynchronous Receiver Transmitter) es un interfaz de comunicaciones serie, también conocido como SCI (Serial Communication Interface). Puede ser configurado como: Modo asíncrono (full duplex). Modo síncrono maestro (half duplex). Modo síncrono esclavo (half duplex). Independientemente del modo debemos, habilitarlo con RCSTA.SPEN = 1. Y dependiendo del modo (TX salida, RX entrada), configurar TRISC.6 = 0 (pin RC6/TX/CK como salida) y TRISC.7 = 1 (pin RC7/RX/DT como entrada). Modo asíncrono: transmisión Funcionamiento El dato a transmitir se deposita en TXREG. Cuando se termina de transmitir el dato anterior se traslada automáticamente al registro de desplazamiento TSR y se indica con PIR1.TXIF (TXREG vacío). Si PIE1.TXIE = 1 se produce una interrupción para recargarlo. Se extraen de TSR los bits (LSBit...MSBit) al ritmo indicado por el generador de baudios a través de RC6/TX. El dato se precede de un bit de inicio (0) y al final se añade un bit de parada (1). El bit TXSTA.TRMT indica cuando se ha terminado de transmitir el contenido de TSR. Microcontroladores IES Joan Miró Página 96

97 Modo asíncrono: recepción Funcionamiento Los bits recibidos en RC7/RX/DT se muestrean (a un ritmo de SPBRG x 16) y son introducidos en el registro de desplazamiento RSR al ritmo indicado por SPBRG. Después de recibir el bit de stop el dato es copiado en RCREG si está vacío y se indica (PIR1.RCIF = 1). Si están activadas (PIE1.RCIE = 1, INTCON.PEIE = 1 y INTCON.GIE = 1) se producirá una interrupción. PIR1.RCIF se pondrá a cero cuando se lea el dato de RCREG. RCREG es un registro doble que funciona como un pila FIFO (First In, First Out: primero en entrar, primero en salir). Si se recibe un tercer dato sin haber leído los anteriores se producirá un error de desbordamiento (RCSTA.OERR = 1) y se inhibirán futuras recepciones hasta que se borre. Si el dato es de 9 bits, se debe leer primero RCSTA.RX9D y después RCREG para no perder información. Si el dato se recibe incompleto (bit de stop incompleto) se indica con RCSTA.FERR Cable. Utilizaremos el entrenador Simulación del TRANSMISOR-RECEPTOR_Cable.DSN contenido en la carpeta de Transmisión Serie Asíncrona\ Cable. Microcontroladores IES Joan Miró Página 97

98 Transmisión_Serie_1.c // Programa...: Transmisión_Serie_1.c // // Plataforma hw: Placa Monibot // // Fecha...: Septiembre-2011 // // Programador..: Pedro Alonso Sanz // // Descripción..: Si RA0=0 transmito vía serie el 1 // // Si RA0=1 transmito vía serie un 13 // // ********************************** Directivas de Preprocesado ************************************* #include <16F877A.h> #FUSES XT,NOWDT #use delay(clock= ) #use rs232(baud=4800, xmit=pin_c6, rcv=pin_c7) // Definimos la velocidad de transmisión de // 4800 baudios/segundo // Elegimos RC6 como patilla transmisora de datos. // Elegimos RC7 como patilla receptora de datos. #BYTE TRISA = 0x85 // TRISB en 86h. #BYTE porta = 0x05 // TRISB en 86h. int8 ra0=0; int8 ra0_anterior=0; int8 dato=0; // ****************************** Función principal o programa principal **************************** void main() TRISA = 0B ; // Defines Puerto A como ENTRADA de datos. while(1) ra0= porta & 0B ; if (ra0!=ra0_anterior) ra0_anterior=ra0; if(ra0==0) else dato=0b ; dato=0b ; // bucle infinito. // Filtramos los RA0 // Si varia ra0, transmitimos el dato. // Guardamos el contenido de ra0; // dato=1 // dato=13 putc(dato); delay_ms(100); // Enviamos vía serie la variable dato. // Esperamos 100 ms Recepción_Serie_Polling.c // Programa...: Recepción_Serie_Polling.c // // Plataforma hw: Placa Monibot // // Fecha...: Septiembre-2011 // // Programador..: Pedro Alonso Sanz // // Descripción..: Cuando el dato recibido vía serie es "1" escribimos "Si" en el LCD // // Cuando el dato recibido vía serie es "13" escribimos "No" en el LCD // Microcontroladores IES Joan Miró Página 98

99 // ********************************* Directivas de Preprocesado ************************************** #include <16F877A.h> #FUSES XT,NOWDT #use delay(clock= ) #use rs232(baud=4800,xmit=pin_c6, rcv=pin_c7) #include <flex_lcd.c> // Definimos la velocidad de transmisión de //4800 baudios/segundo // Elegimos RC6 como patilla transmisora de datos. // Elegimos RC7 como patilla receptora de datos. // Incluimos el driver flex_lcd.c que contiene las funciones // de control del LCD. int8 dato=0; // *************************** Función principal o programa principal ******************************* void main() lcd_init(); // Inicializamos el LCD. while(1) dato=getc(); // Leo el dato recibido vía serie. if(dato==1) // Si dato=1 realizo lo que está entre corchetes. lcd_gotoxy(1,1); // Posicionamos el Cursor del LCD en la posición 1 línea 1. printf(lcd_putc,"si"); // Escribimos el mensaje "Si". if(dato==13) // Si dato=13 realizo lo que está entre corchetes. lcd_gotoxy(1,1); // Posicionamos el Cursor del LCD en la posición 1 línea 1. printf(lcd_putc,"no"); // Escribimos el mensaje "No" Recepción_Serie_Interrupción.c // Programa...: Recepción_Serie_Interrupción.c // // Plataforma hw: Placa Monibot // // Fecha...: Septiembre-2011 // // Programador..: Pedro Alonso Sanz // // Descripción..: Un programa principal simula las luces del coche fantástico // // Cuando se recibe vía serie un "1" en el LCD aparecera "Si" // // Cuando se recibe vía serie un "13" en el LCD aparecera "No" // // ********************************** Directivas de Preprocesado ************************************* #include <16F877A.h> #FUSES XT,NOWDT #use delay(clock= ) #use rs232(baud=4800,xmit=pin_c6, rcv=pin_c7) #include <flex_lcd.c> // Definimos la velocidad de transmisión de // 4800 baudios/segundo // Elegimos RC6 como patilla transmisora de datos. // Elegimos RC7 como patilla receptora de datos. // Incluimos el driver flex_lcd.c que contiene las funciones // del LCD. #BYTE TRISB = 0x86 // TRISB en 86h. #BYTE portb = 0x06 // PORTB en 06h. Microcontroladores IES Joan Miró Página 99

100 int8 luces=0b ; /* ********************************************** Declaración de funciones ***************************************************** */ void Coche_Fantastico (void); void Leer_dato_serie (void); // Simulación Coche fantastico. // Leer datos via serie // ************************** Función principal o programa principal ******************************** void main() TRISB = 0B ; // Defines Puerto B como SALIDA de datos. portb = luces; // inicializamos el puerto B. delay_ms(100); // Retraso. lcd_init(); printf(lcd_putc,"ies Joan Miro"); enable_interrupts(int_rda); enable_interrupts(global); // Inicializamos el LCD. // Escribimos mensaje. // Habilitamos la interrupción serie de datos. // Habilitamos la Interrupción General. while(1) Coche_Fantastico (); // Bucle sin fin. /************************************************** Coche_Fantastico *************************************************************/ void Coche_Fantastico (void) int8 n=0; for (n=0;n<7;n++) luces<<=1; portb=luces; delay_ms(100); for (n=7;n>0;n--) luces>>=1; portb=luces; delay_ms(100); // Movemos un bit a la izquierda // Retraso. // Movemos un bit a la derecha. // Retraso. /* ***************************** Atención a la interrupción por recepción serie de datos ********************************* */ #int_rda void Leer_dato_serie (void) static int8 dato_recibido=0; dato_recibido=getc(); // Recibimos el dato serie. if(dato_recibido==1) // Si dato=1 realizo lo que está entre corchetes. lcd_gotoxy(1,2); // Posicionamos el Cursor del LCD en la posición 1 línea 2. printf(lcd_putc,"si"); // Escribimos el mensaje "Si". if(dato_recibido==13) // Si dato=13 realizo lo que está entre corchetes. lcd_gotoxy(1,2); // Posicionamos el Cursor del LCD en la posición 1 línea 2. printf(lcd_putc,"no"); // Escribimos el mensaje "No". Microcontroladores IES Joan Miró Página 100

101 Transmisión_Serie_Multitarea.c // Programa...: Transmisión_Serie_Multitarea.c // // Plataforma hw: Placa Monibot // // Fecha...: Septiembre-2011 // // Programador..: Pedro Alonso Sanz // // Descripción..: Si RA0=0 transmito vía serie el 1 // // Si RA0=1 transmito vía serie un 13 // // ******************************* Directivas de Preprocesado **************************************** #include <16F877A.h> #FUSES XT,NOWDT #use delay(clock= ) #use rs232(baud=4800, xmit=pin_c6, rcv=pin_c7) // Definimos la velocidad de transmisión de // 4800 baudios/segundo // Elegimos RC6 como patilla transmisora de datos. // Elegimos RC7 como patilla receptora de datos. #BYTE TRISA = 0x85 // TRISB en 86h. #BYTE porta = 0x05 // TRISB en 86h. #define CLAVE_RA0 63 #define CLAVE_RA1 135 int8 ra0=0; int8 ra0_anterior=0; int8 ra1=0; int8 ra1_anterior=0; int8 dato=0; // **************************** Función principal o programa principal ****************************** void main() TRISA = 0B ; // Defines Puerto A como ENTRADA de datos. while(1) ra0= porta & 0B ; if (ra0!=ra0_anterior) ra0_anterior=ra0; if(ra0==0) else dato=0b ; dato=0b ; // bucle infinito. // Filtramos los RA0 // Si varia ra0, transmitimos el dato. // Guardamos el contenido de ra0; // dato=1 // dato=13 putc(clave_ra0); delay_ms(5); putc(dato); delay_ms(50); // Enviamos vía serie la CLAVE_RA0. // Esperamos 5 ms. // Enviamos vía serie la variable dato. // Esperamos 5 ms. ra1= porta & 0B ; if (ra1!=ra1_anterior) ra1_anterior=ra1; // Filtramos los RA1 // Si varia ra1, transmitimos el dato. // Guardamos el contenido de ra1; Microcontroladores IES Joan Miró Página 101

102 if(ra1==0) else dato=0; dato=56; // dato=0 // dato=56 putc(clave_ra1); delay_ms(5); putc(dato); delay_ms(5); // Enviamos vía serie la CLAVE_RA1. // Esperamos 5 ms. // Enviamos vía serie la variable dato. // Esperamos 5 ms Recepción_Serie_Interrupción_Multitarea.c // Programa...: Recepción_Serie_Interrupción_Multitarea.c // // Plataforma hw: Placa Monibot // // Fecha...: Septiembre-2011 // // Programador..: Pedro Alonso Sanz // // Descripción..: Un programa principal simula las luces del coche fantástico // // Cuando se recibe vía serie la clave "63" y el dato "1" en el LCD aparecerá "Si" // // Cuando se recibe vía serie la clave "63" y el dato "13" en el LCD aparecerá "No" // // Cuando se recibe vía serie la clave "135" y el dato "0" el Servomotor de // // Posición se posicionara en -90º. // // Cuando se recibe vía serie la clave "135" y el dato "56" el Servomotor de // // Posición se posicionara en 0º. // // ********************************** Directivas de Preprocesado ************************************* #include <16F877A.h> #FUSES XT,NOWDT #use delay(clock= ) #use rs232(baud=4800,xmit=pin_c6, rcv=pin_c7) #include <flex_lcd.c> #include <Servo_Futaba_10bit.c> de los Servos de Futaba. // Definimos la velocidad de transmisión de // 4800 baudios/segundo // Elegimos RC6 como patilla transmisora de datos. // Elegimos RC7 como patilla receptora de datos. // Incluimos el driver flex_lcd.c que contiene las funciones // del LCD. // Incluimos el driver que contiene las funciones de control #BYTE TRISB = 0x86 // TRISB en 86h. #BYTE portb = 0x06 // PORTB en 06h. #define CLAVE_RA0 63 #define CLAVE_RA1 135 int8 luces=0b ; /* ********************************************** Declaración de funciones ***************************************************** */ void Coche_Fantastico (void); void Leer_dato_serie (void); void Mensaje_LCD (int8); void Posicion_Servo (int8); // Simulación Coche fantastico. // Leer datos via serie // Escribir un mensaje en el LCD // Posicionar el Sevomotor. Microcontroladores IES Joan Miró Página 102

103 // **************************** Función principal o programa principal ****************************** void main() TRISB = 0B ; // Defines Puerto B como SALIDA de datos. portb = luces; // inicializamos el puerto B. delay_ms(100); // Retraso. lcd_init(); printf(lcd_putc,"ies Joan Miro"); Inicializacion_Futaba_RC1(); enable_interrupts(int_rda); enable_interrupts(global); // Inicializamos el LCD. // Escribimos mensaje. // Inicialización del Servo en RC1 // Habilitamos la interrupción serie de datos. // Habilitamos la Interrupción General. while(1) Coche_Fantastico (); // Bucle sin fin. /************************************************** Coche_Fantastico *************************************************************/ void Coche_Fantastico (void) int8 n=0; for(n=0;n<7;n++) luces<<=1; portb=luces; delay_ms(100); for(n=7;n>0;n--) luces>>=1; portb=luces; delay_ms(100); // Movemos un bit a la izquierda // Retraso. // Movemos un bit a la derecha. // Retraso. /* ******************************** Atención a la interrupción por recepción serie de datos ****************************** */ #int_rda void Leer_dato_serie (void) #DEFINE ES_CLAVE_RA0 0 #DEFINE ES_CLAVE_RA1 1 #DEFINE IR_LCD 2 #DEFINE IR_SERVO 3 static int8 caso=es_clave_ra0; static int8 dato_recibido=0; dato_recibido=getc(); // Recibimos el dato serie. switch (caso) // Preguntamos por la variable "ir" si es 0 ejecuta el case 0, si es 1 el case 1, case ES_CLAVE_RA0: if(dato_recibido==clave_ra0) caso=ir_lcd; case ES_CLAVE_RA1: if(dato_recibido==clave_ra1) Microcontroladores IES Joan Miró Página 103

104 break; caso=ir_servo; case IR_LCD: Mensaje_LCD (dato_recibido); // Escribir un mensaje en el LCD case IR_SERVO: caso=es_clave_ra0; break; Posicion_Servo (dato_recibido); // Posicionar el Sevomotor. caso=es_clave_ra0; break; default: caso=es_clave_ra0; /* ************************************************ Función Mensaje_LCD ****************************************************** */ void Mensaje_LCD (int8 dato) // Escribir un mensaje en el LCD if(dato==1) // Si dato=1 realizo lo que está entre corchetes. lcd_gotoxy(1,2); // Posicionamos el Cursor del LCD en la posición 1 línea 2. printf(lcd_putc,"si"); // Escribimos el mensaje "Si". if(dato==13) // Si dato=13 realizo lo que está entre corchetes. lcd_gotoxy(1,2); // Posicionamos el Cursor del LCD en la posición 1 línea 2. printf(lcd_putc,"no"); // Escribimos el mensaje "No". /* ******************************************* Función Posicion_Servo ********************************************************* */ void Posicion_Servo (int8 TH) Futaba_RC1(TH); // Posicionar el Sevomotor. // Posicionar el Servo de la patilla RC Transmisión_Serie_Multitarea_1.c // Programa...: Transmisión_Serie_Multitarea_1.c // // Plataforma hw: Placa Monibot // // Fecha...: Septiembre-2011 // // Programador..: Pedro Alonso Sanz // // Descripción..: Si RA0=0 transmito via serie el 1 // // Si RA0=1 transmito via serie un 13 // // Si RA1=0 transmito via serie un 30 // // Si RA1=1 transmito via serie un 90 // // Si RA2=0 transmito via serie un 20 // // Si RA2=1 transmito via serie un 80 // // ********************************** Directivas de Preprocesado ************************************* #include <16F877A.h> Microcontroladores IES Joan Miró Página 104

105 #FUSES XT,NOWDT #use delay(clock= ) #use rs232(baud=4800, xmit=pin_c6, rcv=pin_c7) // Definimos la velocidad de transmisión de // 4800 baudios/segundo // Elegimos RC6 como patilla transmisora de datos. // Elegimos RC7 como patilla receptora de datos. #BYTE TRISA = 0x85 // TRISB en 86h. #BYTE porta = 0x05 // TRISB en 86h. #BIT ra0 = 0X05.0 #BIT ra1 = 0X05.1 #BIT ra2 = 0X05.2 #define CLAVE_LCD 63 #define CLAVE_SERVO1 135 #define CLAVE_SERVO2 211 int1 ra0_anterior=0; int1 ra1_anterior=0; int1 ra2_anterior=0; int8 informacion_lcd=0; int8 informacion_servo1=0; int8 informacion_servo2=0; // **************************** Función principal o programa principal ****************************** void main() TRISA = 0B ; // Defines Puerto A como ENTRADA de datos. while(1) // bucle infinito. // ****************************** Transmisión de RA0 *************************************************** if (ra0!=ra0_anterior) ra0_anterior=ra0; // Si varia ra0, transmitimos el dato. // Guardamos el contenido de ra0; if(ra0==0) else informacion_lcd=0b ; informacion_lcd=0b ; // informacion_lcd=1 // informacion_lcd=13 putc(clave_lcd); delay_ms(1); putc(informacion_lcd); delay_ms(1); // Enviamos vía serie la CLAVE_LCD. // Esperamos 1 ms. // Enviamos vía serie la variable // informacion_lcd. // Esperamos 1 ms. // ****************************** Transmisión de RA1 *************************************************** if (ra1!=ra1_anterior) ra1_anterior=ra1; if(ra1==0) else informacion_servo1=30; informacion_servo1=90; putc(clave_servo1); delay_ms(1); // Si varia ra1, transmitimos el dato. // Guardamos el contenido de ra1; // informacion_servo=30 // informacion_servo=90 // Enviamos vía serie la CLAVE_SERVO1. // Esperamos 1 ms. Microcontroladores IES Joan Miró Página 105

106 putc(informacion_servo1); delay_ms(1); // Enviamos vía serie la variable //informacion_servo1. // Esperamos 1 ms. // ****************************** Transmisión de RA2 *************************************************** if (ra2!=ra2_anterior) ra2_anterior=ra2; if(ra2==0) else informacion_servo2=20; informacion_servo2=80; putc(clave_servo2); delay_ms(1); // Si varia ra2, transmitimos el dato. // Guardamos el contenido de ra2; // informacion_servo2=20 // informacion_servo2=80 // Enviamos vía serie la CLAVE_SERVO2. // Esperamos 1 ms. putc(informacion_servo2); delay_ms(1); // Enviamos vía serie la variable // informacion_servo2. // Esperamos 1 ms Recepción_Serie_Interrupción_Multitarea_1.c // Programa...: Recepción_Serie_Interrupción_Multitarea.c // // Plataforma hw: Placa Monibot // // Fecha...: Septiembre-2011 // // Programador..: Pedro Alonso Sanz // // Descripción..: Un programa principal simula las luces del coche fantástico // // Cuando se recibe vía serie la clave "63" y el dato "1" en el LCD aparecerá "Si" // // Cuando se recibe vía serie la clave "63" y el dato "13" en el LCD aparecerá "No" // // Cuando se recibe vía serie la clave "135" y el dato "30" el Servomotor 1 de // // Posición se posicionará en 42º // // Cuando se recibe vía serie la clave "135" y el dato "90" el Servomotor 1 de // // Posición se posicionará en 53º // // Cuando se recibe vía serie la clave "135" y el dato "20" el Servomotor 2 de // // Posición se posicionará en 37º // // Cuando se recibe vía serie la clave "135" y el dato "80" el Servomotor 2 de // // Posición se posicionará en 58º // // *********************************** Directivas de Preprocesado ************************************ #include <16F877A.h> #FUSES XT,NOWDT #use delay(clock= ) #use rs232(baud=4800,xmit=pin_c6, rcv=pin_c7) #include <flex_lcd.c> #include <Servo_Futaba_10bit.c> // Definimos la velocidad de transmisión de // 4800 baudios/segundo // Elegimos RC6 como patilla transmisora de datos. // Elegimos RC7 como patilla receptora de datos. // Incluimos el driver flex_lcd.c que contiene las funciones // del LCD. // Incluimos el driver que contiene las funciones de control // de los Servos de Futaba. Microcontroladores IES Joan Miró Página 106

107 #BYTE TRISB = 0x86 // TRISB en 86h. #BYTE portb = 0x06 // PORTB en 06h. #define CLAVE_LCD 63 #define CLAVE_SERVO1 135 #define CLAVE_SERVO2 211 int8 luces=0b ; /* ********************************************** Declaración de funciones ***************************************************** */ void Coche_Fantastico (void); // Simulación Coche fantástico. void Leer_dato_serie (void); // Leer datos vía serie void Mensaje_LCD (int8); // Escribir un mensaje en el LCD void Posicion_Servo1 (int8); // Posicionar el Sevomotor 1. void Posicion_Servo2 (int8); // Posicionar el Sevomotor 2. // **************************** Función principal o programa principal ****************************** void main() TRISB = 0B ; // Defines Puerto B como SALIDA de datos. portb = luces; // inicializamos el puerto B. delay_ms(100); // Retraso. lcd_init(); printf(lcd_putc,"ies Joan Miro"); Inicializacion_Futaba_RC1(); Inicializacion_Futaba_RC2(); enable_interrupts(int_rda); enable_interrupts(global); while(1) // Inicializamos el LCD. // Escribimos mensaje. // Inicialización del Servo en RC1 // Inicialización del Servo en RC2 // Habilitamos la interrupción serie de datos. // Habilitamos la Interrupción General. // Bucle sin fin. Coche_Fantastico (); /************************************************** Coche_Fantastico *************************************************************/ void Coche_Fantastico (void) int8 n=0; for(n=0;n<7;n++) luces<<=1; portb=luces; delay_ms(100); for(n=7;n>0;n--) luces>>=1; portb=luces; delay_ms(100); // Movemos un bit a la izquierda // Retraso. // Movemos un bit a la derecha. // Retraso. /* ******************************** Atención a la interrupción por recepción serie de datos ****************************** */ #int_rda void Leer_dato_serie (void) #DEFINE ES_PROCESO_LCD 0 #DEFINE ES_PROCESO_SERVO1 1 #DEFINE ES_PROCESO_SERVO2 2 #DEFINE IR_LCD 3 Microcontroladores IES Joan Miró Página 107

108 #DEFINE IR_SERVO1 4 #DEFINE IR_SERVO2 5 static int8 caso=es_proceso_lcd; static int8 dato_recibido=0; dato_recibido=getc(); // Recibimos el dato serie. switch (caso) // Preguntamos por la variable "ir" si es 0 ejecuta el case 0, si es 1 el case 1, case ES_PROCESO_LCD: if(dato_recibido==clave_lcd) caso=ir_lcd; case ES_PROCESO_SERVO1: if(dato_recibido==clave_servo1) caso=ir_servo1; case ES_PROCESO_SERVO2: case IR_LCD: if(dato_recibido==clave_servo2) caso=ir_servo2; break; Mensaje_LCD (dato_recibido); caso=es_proceso_lcd; break; // Escribir un mensaje en el LCD case IR_SERVO1: case IR_SERVO2: default: Posicion_Servo1 (dato_recibido); // Posicionar el Sevomotor 1. caso=es_proceso_lcd; break; Posicion_Servo2 (dato_recibido); // Posicionar el Sevomotor 2. caso=es_proceso_lcd; break; caso=es_proceso_lcd; /* ******************************************* Función Mensaje_LCD ****************************************************** */ void Mensaje_LCD (int8 dato) // Escribir un mensaje en el LCD if(dato==1) // Si dato=1 realizo lo que está entre corchetes. lcd_gotoxy(1,2); // Posicionamos el Cursor del LCD en la posición 1 línea 2. printf(lcd_putc,"si"); // Escribimos el mensaje "Si". if(dato==13) // Si dato=13 realizo lo que está entre corchetes. lcd_gotoxy(1,2); // Posicionamos el Cursor del LCD en la posición 1 línea 2. printf(lcd_putc,"no"); // Escribimos el mensaje "No". Microcontroladores IES Joan Miró Página 108

109 /* ******************************************* Función Posicion_Servo1 **************************************************** */ void Posicion_Servo1 (int8 TH) // Posicionar el Servomotor 1. Futaba_RC1(TH); // Posicionar el Servo de la patilla RC1. /* ******************************************* Función Posicion_Servo2 **************************************************** */ void Posicion_Servo2 (int8 TH) // Posicionar el Servomotor 2. Futaba_RC2(TH); // Posicionar el Servo de la patilla RC Radiofrecuencia Modulación en AM. Es introducir una señal moduladora (En nuestro caso una señal cuadrada procedente de la transmisión serie de datos) en la Amplitud de la portadora. La Tarjeta Transmisora de Datos CEBEK C-0503 es un circuito híbrido encargado de transmitir vía radiofrecuencia, los datos digitales SERIE procedentes de la patilla RC6/TX del microcontrolador PIC 16f876a del mando. La señal digital tiene que tener una frecuencia entre 20 Hz < fo < 4 KHz. Y se modulará con una portadora de 433,92 MHz. Protocolo de Comunicaciones entre el Mando y el Receptor. Se ha utilizado una transmisión serie asíncrona de datos. Se transmite una ráfaga de datos de la siguiente manera: 1bit de START + 8bit de DATOS + 1bit de STOP (Llave que identifica un proceso, se ha activado un pulsador o se ha variado el Potenciómetro del Mando.) 1bit de START + 8bit de DATOS + 1bit de STOP (Información del proceso, que pulsador se ha activado o la tensión digitalizada del Potenciómetro del Mando.) Esta ráfaga (Señal que sale de la patilla RC6/TX del microcontrolador PIC16F876A) se transmite vía serie 10 veces a una velocidad de 2400 bit/segundo. El modulador CEBEK C genera una señal de AM con esta señal moduladora. Microcontroladores IES Joan Miró Página 109

110 Microcontroladores IES Joan Miró Página 110

111 El receptor serie CEBEK C-0504 demodula la señal, es decir filtra la portadora de 433,92 MHz obteniendo la señal moduladora (Ráfaga de datos) El microcontrolador del Receptor trabaja en modo interrupción Serie de Datos. Es decir cada vez que le llega un dato con el protocolo asincrono serie ( 1bit de START 8 bit de DATOS, 1 bit de STOP y a una frecuencia de 2400 bit/segundo.) interrumpirá un programa principal y ejecutará una rutina de interrupción para este proceso. La rutina de interrupción realiza el proceso de validar los datos que le llegan. Se validan los datos si llegan dos ráfagas de 20bits consecutivas y tienen la mismas llaves que identifican el proceso e información del proceso. Utilizaremos el entrenador TRANSMISOR-RECEPTOR_Radiofrecuencia.DSN contenido en la carpeta de Transmisión Serie Asíncrona\ Radiofrecuencia Transmisión_Serie_ Radiofrecuencia_1.c // Programa...: Transmisión_Serie_Radiofrecuencia_1.c // // Plataforma hw: MONIBOT // // Fecha...: Septiembre-2011 // // Programador..: Pedro Alonso Sanz // // Descripción..: Cada vez que pulso una patilla del puerto A se transmite este vía serie // // ******************************* Directivas de Preprocesado **************************************** #include <16F876A.h> #FUSES XT,NOWDT #use delay(clock= ) Microcontroladores IES Joan Miró Página 111

112 Curso de Robótica y otras aplicaciones en el Aula de Tecnología #use rs232(baud=2400, xmit=pin_c6, rcv=pin_c7) // Definimos la velocidad de transmisión de //2400 baudios/segundo // Elegimos RC6 como patilla transmisora de datos. // Elegimos RC7 como patilla receptora de datos. #BYTE TRISA = 0x85 // TRISA en 85h. #BYTE porta = 0x05 // PORTA en 05h. #define Clave_Pulsadores 63 // ****************************************** Función principal o programa principal ******************************************* void main() int8 i=1; int8 q; TRISA = 0B ; // Definimos la variable "i" como tipo byte. // Definimos la variable "q" como tipo byte. // Defines Puerto A como ENTRADA de datos. while(1) // bucle infinito. q= porta & 0B ; // Filtramos los 6 bit menos significativos del Puerto A. q=q 0B ; // Le añadimos dos 1 al bit 6 y 7. q=~q; // Invertimos para obtener el resultado en lógica positiva. if (q!=0b ) putc(clave_pulsadores); putc(q); // Si se activa un pulsador, transmitir datos. // Enviamos vía serie la Clave_Pulsador. // Enviamos vía serie la variable cambio Transmisión_Serie_ Radiofrecuencia_2.c // Programa...: Transmisión_Serie_Radiofrecuencia_2.c // // Plataforma hw: MONIBOT // // Fecha...: Septiembre-2011 // // Programador..: Pedro Alonso Sanz // // Descripción..: Cada vez que pulso una patilla del puerto A se transmite esta patilla // // vía serie se conserva los datos de las pulsaciones anteriores. // // ****************************** Directivas de Preprocesado ***************************************** #include <16F876A.h> #FUSES XT,NOWDT #use delay(clock= ) #use rs232(baud=2400, xmit=pin_c6, rcv=pin_c7) // Definimos la velocidad de transmisión de // 2400 baudios/segundo // Elegimos RC6 como patilla transmisora de datos. // Elegimos RC7 como patilla receptora de datos. #BYTE TRISA = 0x85 // TRISA en 85h. #BYTE porta = 0x05 // PORTA en 05h. #BIT ra0 = 0x05.0 // RA0 en 0x05 patilla 0. #BIT ra1 = 0x05.1 // RA1 en 0x05 patilla 1. #BIT ra2 = 0x05.2 // RA2 en 0x05 patilla 2. #BIT ra3 = 0x05.3 // RA3 en 0x05 patilla 3. #BIT ra4 = 0x05.4 // RA4 en 0x05 patilla 4. #BIT ra5 = 0x05.5 // RA5 en 0x05 patilla 5. #BYTE cambio = 0x20 // cambio1 en 0x20h. #BIT c0 = 0x20.0 // c0 en 0x20.0 #BIT c1 = 0x20.1 // c1 en 0x20.1 #BIT c2 = 0x20.2 // c2 en 0x20.2 #BIT c3 = 0x20.3 // c3 en 0x20.3 Microcontroladores IES Joan Miró Página 112

113 Curso de Robótica y otras aplicaciones en el Aula de Tecnología #BIT c4 = 0x20.4 // c4 en 0x20.4 #BIT c5 = 0x20.5 // c5 en 0x20.5 #define Clave_Pulsadores 63 #define Numero_Repeticiones 10 // ***************************** Función principal o programa principal ***************************** void main() int8 i=1; int8 q; TRISA = 0B ; // Definimos la variable "i" como tipo byte. // Definimos la variable "q" como tipo byte. // Defines Puerto A como ENTRADA de datos. cambio=0; // Inicializamos la variable cambio con 0. while(1) // bucle infinito. q= porta & 0B ; // Filtramos los 5 bit menos significativos del Puerto A. q=q 0B ; // Le añadimos dos 1 al bit 6 y 7. q=~q; // Invertimos para obtener el resultado en lógica positiva. if (q!=0b ) // Si se activa un pulsador, transmitir datos. if (ra0==0) c0=~c0; // Si se pulsa rb0 cambiar el valor de c0. if (ra1==0) c1=~c1; // Si se pulsa rb1 cambiar el valor de c1. if (ra2==0) c2=~c2; // Si se pulsa rb2 cambiar el valor de c2. if (ra3==0) c3=~c3; // Si se pulsa rb3 cambiar el valor de c3. if (ra4==0) c4=~c4; // Si se pulsa rb4 cambiar el valor de c4. if (ra5==0) c5=~c5; // Si se pulsa rb4 cambiar el valor de c5. for(i=1;i<=numero_repeticiones;i++) delay_ms(500); putc(clave_pulsadores); putc(cambio); // Enviamos el dato vía serie, tantas // veces como diga la variable // Número_Repeticiones // Enviamos vía serie la // Clave_Pulsador. // Enviamos vía serie la variable // cambio. // Esperamos un tiempo suficiente hasta dejar de pulsar Recepción_Serie_Radiofrecuencia_1.c // Programa...: Recepción_Serie_Radiofrecuencia_1.c // // Plataforma hw: MONIBOT // // Fecha...: Septiembre-2011 // // Programador..: Pedro Alonso Sanz // // Descripción..: Recepción de un dato vía serie con tarjeta de radiofrecuencia // // Un programa principal representa en el LCD el pulsador activado del // // mando de radiofrecuencia. // // ********************************* Directivas de Preprocesado ************************************** #include <16F877A.h> #FUSES XT,NOWDT #use delay(clock= ) #use rs232(baud=9600,xmit=pin_c6, rcv=pin_c7) #include <flex_lcd.c> // Definimos la velocidad de transmisión de // 9600 baudios/segundo // Elegimos RC6 como patilla transmisora de datos. // Elegimos RC7 como patilla receptora de datos. // Incluimos el driver flex_lcd.c que contiene las funciones // del LCD. Microcontroladores IES Joan Miró Página 113

114 Curso de Robótica y otras aplicaciones en el Aula de Tecnología #BYTE dato_valido = 0x22 // dato en 0x20h. #BIT d0 = 0x22.0 // c0 en 0x20.0 #BIT d1 = 0x22.1 // c1 en 0x20.1 #BIT d2 = 0x22.2 // c2 en 0x20.2 #BIT d3 = 0x22.3 // c3 en 0x20.3 #BIT d4 = 0x22.4 // c4 en 0x20.4 #BIT d5 = 0x22.5 // c5 en 0x20.5 #define Clave_Pulsadores 63 int8 dato_recibido; int8 dato_anterior=0; /* ********************************************** Declaración de funciones ***************************************************** */ void Leer_dato_serie (void); // Leer Dato. // *************************** Función principal o programa principal ******************************* void main() dato_valido=0; lcd_init(); printf(lcd_putc,"ies Joan Miro"); // Inicializamos el LCD. // Escribimos mensaje. lcd_gotoxy(1,2); // Posicionamos el Cursor del LCD // en la posición 1 línea 2. printf(lcd_putc,"%1u%1u%1u%1u%1u%1u",d5,d4,d3,d2,d1,d0); // Escribimos 5 variables enable_interrupts(int_rda); enable_interrupts(global); // Habilitamos la interrupción serie de datos. // Habilitamos la Interrupción General. while(1) if(dato_valido!=dato_anterior) dato_anterior=dato_valido; lcd_gotoxy(1,2); // Bucle sin fin. // Si es el mismo dato no escribir en el LCD. // Guardamos el dato anterior // Posicionamos el Cursor del LCD en la posición // 1 línea 2. printf(lcd_putc,"%1u%1u%1u%1u%1u%1u",d5,d4,d3,d2,d1,d0); // Escribimos 5 // variables // "Pulsadores del // mando" /* ******************************* Atención a la interrupción por recepción serie de datos ******************************* */ #int_rda /* Validamos el dato serie si cumple las siguiente condiciones. Si dos palabras consecutivas de 2 byte son iguales se valida el dato. clave,dato,clave,dato,...,clave,dato Se lee el 1º dato serie recibido con la función "getc()" y se compara con la "clave" del transmisor que tiene que ser la misma que la del receptor, si son iguales se lee el 2º dato serie recibido con la función "getc()" y se guarda. Se lee el 3º dato serie recibido con la función "getc()" y se compara con la "clave" del transmisor que tiene que ser la misma que la del receptor, si son iguales se lee el 4º dato serie recibido con la función "getc()" y se compara con el 2º dato leído, si son iguales se valida el dato con la variable global "Valor". */ void leer_dato_serie (void) static int8 numero_datos1=0; static int8 dato1=0; dato_recibido=getc(); // La variable solo valdra 0 la primera vez. // Recibimos el dato serie. Microcontroladores IES Joan Miró Página 114

115 Curso de Robótica y otras aplicaciones en el Aula de Tecnología switch (numero_datos1) case 0: if(dato_recibido==clave_pulsadores) numero_datos1=1; break; // Es un autómata modelo Moore, que valida los datos // si llegan dos tramas iguales consecutivas case 1: dato1=dato_recibido; numero_datos1=2; break; case 2: if(dato_recibido==clave_pulsadores) numero_datos1=3; else numero_datos1=0; break; case 3: if(dato_recibido==dato1) dato_valido=dato_recibido; numero_datos1=0; Radiofrecuencia Multitarea. Utilizaremos el entrenador TRANSMISOR-RECEPTOR_RF_Multitarea.DSN contenido en la carpeta de Transmisión Serie Asíncrona\ Radiofrecuencia_Multitarea. Microcontroladores IES Joan Miró Página 115

116 Curso de Robótica y otras aplicaciones en el Aula de Tecnología Transmisión_Serie_RF_Multitarea_1.c // Programa...: Transmisión_Serie_RF_Multitarea_1.c // // Plataforma hw: MONIBOT // // Fecha...: Septiembre-2011 // // Programador..: Pedro Alonso Sanz // // Descripción..: Transmisión serie vía radiofrecuencia (Pulsadores y Potenciómetros) // // ********************************** Directivas de Preprocesado ************************************* #include <16F876A.h> #device adc=8 #FUSES XT,NOWDT #use delay(clock= ) #use rs232(baud=2400, xmit=pin_c6, rcv=pin_c7) // Definimos la velocidad de transmisión de // 2400 baudios/segundo // Elegimos RC6 como patilla transmisora de datos. // Elegimos RC7 como patilla receptora de datos. #BYTE TRISB = 0x86 // TRISB en 86h. #BYTE portb = 0x06 // PORTB en 06h. #BIT TC3 = 0x87.3 // TC3 en 0x87 patilla 7. #BIT rc3 = 0x07.3 // RC3 en 0x07 patilla 3. #BIT rb5 = 0x06.5 // RB5 en 0x06 patilla 5. #define Clave_Pot_Der 235 #define Clave_Pot_Izq 134 #define Clave_Pulsadores 63 #define Numero_Repeticiones 10 // **************************** Función principal o programa principal ****************************** void main() int8 cambio0=0; int8 cambio1=0; int8 i=1; int8 q; TRISB = 0B ; TC3 = 0; RC3 = 1; // Definimos la variable "cambio0" como tipo bit. // Definimos la variable "cambio1" como tipo bit. // Definimos la variable "i" como tipo byte. // Definimos la variable "q" como tipo byte. // Defines Puerto B como ENTRADA de datos. // Defines la patilla 3 Puerto C como SALIDA de datos. // Inhabilitamos la tarjeta CEBEK C setup_adc(adc_clock_internal); // Fuente de reloj RC interno. setup_adc_ports(0); // Seleccionamos el Puerto A como entradas // Analógicas. Mirar ADCON1. while(1) // bucle infinito. if (rb5==1) // Si se Cierra el Interruptor de rb5 no transmitir más datos. //**************** Transmisión de datos "Potenciómetro Derecho" ************************ set_adc_channel(0); delay_us(20); q = read_adc(); if (cambio0!=q) cambio0=q; RC3 = 0; // Habilitación canal 0 "AN0" // Retardo de 20uS necesaria para respetar el tiempo // de Adquisición Tad. // Lectura canal 0 "AN0" // Si se ha variado el Potenciómetro Derecho transmitir // dato. // Habilitamos la tarjeta CEBEK C Microcontroladores IES Joan Miró Página 116

117 Curso de Robótica y otras aplicaciones en el Aula de Tecnología for(i=1;i<=numero_repeticiones;i++) RC3 = 1; putc(clave_pot_der); // Enviamos el dato vía serie, tantas // veces como diga la variable // Número_Repeticiones // Enviamos vía serie la // Clave_Pot_Der. putc(q); // Enviamos vía serie la variable q. // (Tensión digitalizada del // Potenciómetro Derecho) // Inhabilitamos la tarjeta CEBEK C //**************** Transmisión de datos "Potenciómetro Izquierdo" *********************** set_adc_channel(1); delay_us(20); q = read_adc(); if (cambio1!=q) cambio1=q; RC3 = 0; // Habilitación canal 1 "AN1" // Retardo de 20uS necesaria para respetar el // tiempo de Adquisición Tad. // Lectura canal 1 "AN1" // Si se ha variado el Potenciómetro Izquierdo // transmitir dato. // Habilitamos la tarjeta CEBEK C for(i=1;i<=numero_repeticiones;i++) RC3 = 1; putc(clave_pot_izq); // Enviamos el dato vía serie, tantas // veces como diga la variable // Número_Repeticiones // Enviamos vía serie la // Clave_Pot_Der. putc(q); // Enviamos vía serie la variable q. // (Tensión digitalizada del // Potenciómetro Izquierdo) // Inhabilitamos la tarjeta CEBEK C //********************* Transmisión de datos "Pulsadores" *********************************** q= portb & 0B ; // Filtramos los 5 bit menos significativos del // Puerto B. if (q!=0b ) RC3 = 0; // Si se activa un pulsador, transmitir datos. // Habilitamos la tarjeta CEBEK C for(i=1;i<=numero_repeticiones;i++) RC3 = 1; putc(clave_pulsadores); putc(~q); // Enviamos el dato vía serie, tantas // veces como diga la variable // Número_Repeticiones // Enviamos vía serie la // Clave_Pulsadores. // Enviamos vía serie la variable q // invertida.(pulsador Activado) // Inhabilitamos la tarjeta CEBEK C Transmisión_Serie_RF_Multitarea_2.c // Programa...: Transmisión_Serie_RF_Multitarea_2.c // // Plataforma hw: MONIBOT // // Fecha...: Septiembre-2011 // // Programador..: Pedro Alonso Sanz // // Descripción..: Transmisión serie vía radiofrecuencia (Pulsadores y Potenciómetros) // // se conserva los datos de las pulsaciones anteriores. // Microcontroladores IES Joan Miró Página 117

118 Curso de Robótica y otras aplicaciones en el Aula de Tecnología // *********************************** Directivas de Preprocesado ************************************ #include <16F876A.h> #device adc=8 #FUSES XT,NOWDT #use delay(clock= ) #use rs232(baud=2400, xmit=pin_c6, rcv=pin_c7) // Definimos la velocidad de transmisión de // 2400 baudios/segundo // Elegimos RC6 como patilla transmisora de datos. // Elegimos RC7 como patilla receptora de datos. #BYTE TRISB = 0x86 // TRISB en 86h. #BYTE portb = 0x06 // PORTB en 06h. #BIT TC3 = 0x87.3 // TC3 en 0x87 patilla 7. #BIT rc3 = 0x07.3 // RC3 en 0x07 patilla 3. #BIT rb0 = 0x06.0 // RB0 en 0x06 patilla 0. #BIT rb1 = 0x06.1 // RB1 en 0x06 patilla 1. #BIT rb2 = 0x06.2 // RB2 en 0x06 patilla 2. #BIT rb3 = 0x06.3 // RB3 en 0x06 patilla 3. #BIT rb4 = 0x06.4 // RB4 en 0x06 patilla 4. #BIT rb5 = 0x06.5 // RB5 en 0x06 patilla 5. #BYTE cambio2 = 0x20 // cambio2 en 0x20h. #BIT c0 = 0x20.0 // c0 en 0x20.0 #BIT c1 = 0x20.1 // c1 en 0x20.1 #BIT c2 = 0x20.2 // c2 en 0x20.2 #BIT c3 = 0x20.3 // c3 en 0x20.3 #BIT c4 = 0x20.4 // c4 en 0x20.4 #BIT c5 = 0x20.5 // c5 en 0x20.5 #define Clave_Pot_Der 235 #define Clave_Pot_Izq 134 #define Clave_Pulsadores 63 #define Numero_Repeticiones 10 // **************************** Función principal o programa principal ****************************** void main() int8 cambio0=0; int8 cambio1=0; int8 i=1; int8 q; int1 rb5_1=0; cambio2=0; TRISB = 0B ; TC3 = 0; RC3 = 1; setup_adc(adc_clock_internal); setup_adc_ports(0); // Definimos la variable "cambio0" como tipo bit. // Definimos la variable "cambio1" como tipo bit. // Definimos la variable "i" como tipo byte. // Definimos la variable "q" como tipo byte. // Definimos la variable "rb5_1" como tipo bit. // Reseteamos la variable cambio2. // Defines Puerto B como ENTRADA de datos. // Defines la patilla 3 Puerto C como SALIDA de datos. // Inhabilitamos la tarjeta CEBEK C // Fuente de reloj RC interno. // Seleccionamos el Puerto A como entradas // Analógicas. Mirar ADCON1. while(1) // bucle infinito. //*********************** Transmisión de datos "Potenciómetro Derecho" ***************************** set_adc_channel(0); delay_us(20); q = read_adc(); // Habilitación canal 0 "AN0" // Retardo de 20uS necesaria para respetar el tiempo de // Adquisición Tad. // Lectura canal 0 "AN0" Microcontroladores IES Joan Miró Página 118

119 Curso de Robótica y otras aplicaciones en el Aula de Tecnología if (cambio0!=q) cambio0=q; RC3 = 0; // Si se ha variado el Potenciómetro Derecho transmitir // dato. // Habilitamos la tarjeta CEBEK C for(i=1;i<=numero_repeticiones;i++) // Enviamos el dato vía serie, tantas // veces como diga la variable // Número_Repeticiones putc(clave_pot_der); // Enviamos vía serie la Clave_Pot_Der. putc(q); // Enviamos vía serie la variable q. // (Tensión digitalizada del // Potenciómetro Derecho) RC3 = 1; // Inhabilitamos la tarjeta CEBEK C //******************* Transmisión de datos "Potenciómetro Izquierdo" ******************************** set_adc_channel(1); delay_us(20); q = read_adc(); if (cambio1!=q) cambio1=q; RC3 = 0; // Habilitación canal 1 "AN1" // Retardo de 20uS necesaria para respetar el tiempo de // Adquisición Tad. // Lectura canal 1 "AN1" // Si se ha variado el Potenciómetro Izquierdo // transmitir dato. // Habilitamos la tarjeta CEBEK C for(i=1;i<=numero_repeticiones;i++) // Enviamos el dato vía serie, tantas // veces como diga la variable // Número_Repeticiones putc(clave_pot_izq); // Enviamos vía serie la Clave_Pot_Der. putc(q); // Enviamos vía serie la variable q. // (Tensión digitalizada del // Potenciómetro Izquierdo) RC3 = 1; // Inhabilitamos la tarjeta CEBEK C //*********************** Transmisión de datos "Pulsadores" ******************************************** q= portb & 0B ; // Filtramos los 5 bit menos significativos del Puerto B. if (q!=0b ) // Si se activa un pulsador, transmitir datos. if (rb0==0) c0=~c0; // Si se pulsa rb0 cambiar el valor de c0. if (rb1==0) c1=~c1; // Si se pulsa rb1 cambiar el valor de c1. if (rb2==0) c2=~c2; // Si se pulsa rb2 cambiar el valor de c2. if (rb3==0) c3=~c3; // Si se pulsa rb3 cambiar el valor de c3. if (rb4==0) c4=~c4; // Si se pulsa rb4 cambiar el valor de c4. RC3 = 0; // Habilitamos la tarjeta CEBEK C for(i=1;i<=numero_repeticiones;i++) RC3 = 1; putc(clave_pulsadores); putc(cambio2); // Enviamos el dato vía serie, tantas // veces como diga la variable // Número_Repeticiones // Enviamos vía serie la // Clave_Pulsadores. // Enviamos vía serie la variable // cambio2. (Pulsador Activado) // Inhabilitamos la tarjeta CEBEK C //**************************** Transmisión de datos "Interruptor" **************************************** if (rb5!=rb5_1) rb5_1=rb5; c5=~rb5; // Si se ha cambiado el Interruptor de la patilla rb5 // transmitir dato. Microcontroladores IES Joan Miró Página 119

120 Curso de Robótica y otras aplicaciones en el Aula de Tecnología RC3 = 0; // Habilitamos la tarjeta CEBEK C for(i=1;i<=numero_repeticiones;i++) RC3 = 1; putc(clave_pulsadores); putc(cambio2); // Enviamos el dato vía serie, tantas // veces como diga a variable // Número_Repeticiones // Enviamos vía serie la // Clave_Pulsadores. // Enviamos vía serie la variable // cambio2. (Interruptor Activado) // Inhabilitamos la tarjeta CEBEK C Recepción_Serie_RF_Multitarea.c // Programa...: Recepción_Serie_RF_Multitarea.c // // Plataforma hw: MONIBOT // // Fecha...: Septiembre-2011 // // Programador..: Pedro Alonso Sanz // // Descripción..: Recepción de datos vía serie con tarjeta de radiofrecuencia (Multitarea) // // Un programa principal está en modo sueño // // ********************************* Directivas de Preprocesado ************************************** #include <16F877A.h> #FUSES XT,NOWDT #use delay(clock= ) #use rs232(baud=2400,xmit=pin_c6, rcv=pin_c7) // Definimos la velocidad de transmisión de // 2400 baudios/segundo // Elegimos RC6 como patilla transmisora de datos. // Elegimos RC7 como patilla receptora de datos. #BYTE TRISD = 0x88 // TRISD en 88h. #BYTE portd = 0x08 // PORTD en 08h. #BYTE TRISC = 0x87 // TRISC en 87h. #BYTE portc = 0x07 // PORTC en 07h. #BYTE TRISB = 0x86 // TRISB en 86h. #BYTE portb = 0x06 // PORTB en 06h. #define Clave_Pot_Der 235 // Definimos claves. #define Clave_Pot_Izq 134 #define Clave_Pulsadores 63 int1 valido_aut_pul=1; int1 valido_aut_pot_der=1; int1 valido_aut_pot_izq=1; int8 dato_recibido=0; // Inicializamos variables /* ************************************** Declaración de funciones ************************************************************* */ void Leer_dato_serie (void); void Automata_Pulsadores (void); void Automata_Pot_Der (void); void Automata_Pot_Izq (void); // Leer Dato. // Valida los datos serie procedentes de los Pulsadores. // Valida los datos serie procedentes del Potenciómetro Derecho. // Valida los datos serie procedentes del Potenciómetro Izquierdo. Microcontroladores IES Joan Miró Página 120

121 Curso de Robótica y otras aplicaciones en el Aula de Tecnología // ****************************** Función principal o programa principal **************************** void main() TRISD = 0B ; TRISC = 0B ; TRISB = 0B ; // Defines Puerto D como SALIDA de datos. // Defines Puerto C como SALIDA de datos // a excepción de RC7/Rx que es entrada de datos. // Defines Puerto B como SALIDA de datos. portd = 0B ; // Reseteamos el Puerto D. portc = 0B ; // Reseteamos el Puerto C. portb = 0B ; // Reseteamos el Puerto B. enable_interrupts(int_rda); enable_interrupts(global); // Habilitamos la interrupción serie de datos. // Habilitamos la Interrupción General. while(1) sleep(); // Bucle sin fin. // Se pone el uc en bajo consumo. Cuando le llega una // transmisión serie de datos se activa el uc. Atiende la interrupción // y vuelve a bajo consumo. /* ************************* Atención a la interrupción por recepción serie de datos ************************************* */ #int_rda /* Validamos el dato serie si cumple las siguiente condiciones. Si dos palabras consecutivas de 2 byte son iguales se valida el dato. clave,dato,clave,dato,...,clave,dato Se lee el 1º dato serie recibido con la función "getc()" y se compara con la "clave" del transmisor que tiene que ser la misma que la del receptor, si son iguales se lee el 2º dato serie recibido con la función "getc()" y se guarda. Se lee el 3º dato serie recibido con la función "getc()" y se compara con la "clave" del transmisor que tiene que ser la misma que la del receptor, si son iguales se lee el 4º dato serie recibido con la función "getc()" y se compara con el 2º dato leido, si son iguales se valida el dato con la variable global "Valor". */ void Leer_dato_serie (void) dato_recibido=getc(); // Recibimos el dato serie. if (valido_aut_pul==1) Automata_Pulsadores(); // Ejecutas la función Autómata_Pulsadores si la // variable Valido_Aut_Pul==1. if (valido_aut_pot_der==1) Automata_Pot_Der(); // Ejecutas la función Automata_Pot_Der si la // variable Valido_Aut_Pot_Der==1. if (valido_aut_pot_izq==1) Automata_Pot_Izq(); // Ejecutas la función Automata_Pot_Izq si la // variable Valido_Aut_Pot_Izq==1. /*********************************************Función Automata_Pulsadores ************************************************* */ void Automata_Pulsadores(void) static int8 numero_datos=0; static int8 dato=0; switch (numero_datos) case 0: if(dato_recibido==clave_pulsadores) numero_datos=1; valido_aut_pot_der=0; valido_aut_pot_izq=0; // Es un autómata modelo Moore, que valida los datos si llegan dos // tramas iguales consecutivas. Variación de los Pulsadores e // Interruptor del Transmisor. Microcontroladores IES Joan Miró Página 121

122 Curso de Robótica y otras aplicaciones en el Aula de Tecnología break; case 1: dato=dato_recibido; numero_datos=2; break; case 2: if(dato_recibido==clave_pulsadores) numero_datos=3; else numero_datos=0; valido_aut_pot_der=1; valido_aut_pot_izq=1; break; case 3: if(dato_recibido==dato) portc=dato_recibido; numero_datos=0; valido_aut_pot_der=1; valido_aut_pot_izq=1; /************************************************Función Automata_Pot_Der ************************************************** */ void Automata_Pot_Der(void) static int8 numero_datos=0; static int8 dato=0; switch (numero_datos) case 0: if(dato_recibido==clave_pot_der) numero_datos=1; valido_aut_pul=0; valido_aut_pot_izq=0; break; // Es un autómata modelo Moore, que valida los datos si llegan dos // tramas iguales consecutivas. Variaciones del Potenciómetro // Derecho del Transmisor. case 1: dato=dato_recibido; numero_datos=2; break; case 2: if(dato_recibido==clave_pot_der) numero_datos=3; else numero_datos=0; valido_aut_pul=1; valido_aut_pot_izq=1; break; case 3: if(dato_recibido==dato) portd =dato_recibido; numero_datos=0; valido_aut_pul=1; valido_aut_pot_izq=1; Microcontroladores IES Joan Miró Página 122

123 Curso de Robótica y otras aplicaciones en el Aula de Tecnología /* *********************************************Función Automata_Pot_Izq **************************************************** */ void Automata_Pot_Izq(void) static int8 numero_datos=0; static int8 dato=0; switch (numero_datos) case 0: if(dato_recibido==clave_pot_izq) numero_datos=1; valido_aut_pul=0; valido_aut_pot_der=0; break; // Es un autómata modelo Moore, que valida los datos si llegan dos // tramas iguales consecutivas. Variaciones del Potenciómetro // Izquierdo del Transmisor. case 1: case 2: dato=dato_recibido; numero_datos=2; break; if(dato_recibido==clave_pot_izq) numero_datos=3; else numero_datos=0; valido_aut_pul=1; valido_aut_pot_der=1; break; case 3: if(dato_recibido==dato) numero_datos=0; valido_aut_pul=1; valido_aut_pot_der=1; portb=dato_recibido; Módulo MSSP. El módulo MSSP (Master Synchronous Serial Port) es un interfaz de comunicaciones serie. Puede trabajar en dos modos: I2C. Modo I2C (Inter-Integrated Circuit). Las patillas asociadas a este modo serán RC3/SCL y RC4/SDA. Modo SPI (Serial Peripheral Interface). Las patillas asociadas serán RC3/SCK, RC4/SDI, RC5/SDO y RA5/SS. Funciona en modo maestro ó esclavo. Permite el direccionamiento de 7 bits o de 10 bits. Atiende a la llamada general (dir = b). Funciona a 100 khz, a 400 khz y a 1 MHz. La patilla RC3/SCL es el reloj (bidireccional). La patilla RC4/SDA son los datos (bidireccional). Se activa el modulo con SSPCON.SSPEN = 1. TRISC debe configurar RC3/SCL y RC4/SDA como entradas. Microcontroladores IES Joan Miró Página 123

124 Curso de Robótica y otras aplicaciones en el Aula de Tecnología Se controla con 5 registros: SSPCON, registro de control del módulo MSSP. SSPCON2, registro de control número 2 del módulo MSSP. SSPSTAT, registro de estado del módulo MSSP. SSPBUF, búfer de recepción/envío. SSPADD, registro de dirección. Modos de operación: I2C esclavo (dirección de 7 bits). I2C esclavo (dirección de 10 bits). I2C maestro, F i2c = Fosc=(4(SSPADD+1)). Funcionamiento: SSPSTAT.CKE = 0, configurará niveles compatibles I2C. SSPSTAT.CKE = 1, configurará niveles eléctricos compatibles SMBus (Intel 1995). SSPSTAT.S indicará la condición de start. SSPSTAT.P indicará la condición de stop. SSPSTAT.D_A indicará si se recibió dato o dirección. SSPSTAT.UA indicará si el dato es la extensión a 10 bits de la dirección. Modo I2C maestro: Funcionamiento: SSPCON.WCOL indica que ha habido una colisión en una escritura. Secuencia de transmisión: Se genera la condición de start con SSPCON2.SEN = 1. PIR1.SSPIF estará a 1. Se espera la inicialización del módulo. Se escribe la dirección del dispositivo en SSPBUF. La dirección es transmitida. El módulo MSSP lee el bit ACK y lo copia en SSPCON2.ACKSTAT. Se activa PIR1.SSPIF y se produce una interrupción, si está habilitada. Se escribe el dato en SSPBUF. El dato es transmitido. El módulo MSSP lee el bit ACK y lo copia en SSPCON2.ACKSTAT. Se genera la condición de stop con SSPCON2.PEN. Se genera una interrupción si están habilitadas. El compilador C de CCS nos proporciona unas funciones para trabajar con I2C. Para entender mejor lo explicado utilizaremos unos ejemplos. Microcontroladores IES Joan Miró Página 124

125 Curso de Robótica y otras aplicaciones en el Aula de Tecnología Expansor_Bus_PCF8574. El dispositivo es un expansor remoto de 8bits I/O para bus I 2 C, consiste en un puerto cuasi bidireccional de 8 bit y una interfaz I 2 C-bus. El PCF8574 tiene una baja corriente consumo e incluye salidas tipo latch con alta capacidad de corriente para activar directamente LEDs. Este, también posee una línea de interrupción (INT), que puede ser conectada a la lógica interrupt del microcontrolador. Mediante el envío de una señal interrupt sobre esta línea, la E/S remota puede informar al microcontrolador si hay datos entrantes en sus puertos sin necesidad de comunicarse a través del I 2 C-bus. Esto quiere decir que el PCF8574 puede seguir siendo un simple dispositivo esclavo PCF8574_1. Utilizaremos el entrenador PCF8574_1.DSN contenido en la carpeta de I2C\ Expansor_Bus_PCF8574\ PCF8574_1. Microcontroladores IES Joan Miró Página 125

126 Curso de Robótica y otras aplicaciones en el Aula de Tecnología Lectura y escritura en PCF8574 modo polling.c // Programa...: Lectura y escritura en PCF8574 modo polling.c // // Plataforma hw: Placa Monibot // // Fecha...: Septiembre-2011 // // Programador..: Pedro Alonso // // Descripción..: Control con I2C de dos expansores de Bus paralelo PCF8574 // // en modo polling // // ********************************* Directivas de Preprocesado ************************************** #include <16F877A.h> #fuses XT,NOWDT,PUT,NOWRT #use delay(clock= ) #use i2c(master, force_hw, slow, sda=pin_c4, scl=pin_c3) // Configuración de I2C // Definimos el PIC como maestro // Forzamos a trabajar con su hardware // interno.(asociado a I2C) // Trabajamos a velocidad baja 100 Kbps // Elegimos sda=pin_c4 como patilla de datos. // Elegimos scl=pin_c3 como patilla de reloj. /* ***************************************** Declaración de funciones ********************************************************** */ int8 Lectura_Interruptores(void); void Escritura(int8); // Declaramos la función Lectura_Interruptores // (Nos devuelve una variable tipo entero de 8 bit) // Declaramos la función Escritura (Lleva una variable // asociada de tipo entero de 8 bit) /* *************************** Función principal o programa principal **************************** */ void main() int8 dato_recibido; while (1) dato_recibido = Lectura_Interruptores(); delay_ms(1); // Bucle infinito de espera // Leemos el dato a través del bus I2c del // esclavo U4 Escritura(~dato_recibido); delay_ms(1); // Escribimos el dato a través del bus I2c en el // esclavo U3 /* ******************************** Función de int8 Lectura_Interruptores() ************************************************* */ int8 Lectura_Interruptores() int8 data; i2c_start(); // Inicializa la recepción. i2c_write(0b ); // Seleccionar esclavo U4 en modo lectura. ( 0100,A2,A1,A0,1 ) // (0100) identifica al C.I. PCF8476. // (A2,A1,A0)=(000) por hardware. // El ultimo bit a 1 para poner el C.I. PCF8476 en modo lectura. data=i2c_read(0); i2c_stop(); // Lectura del dato // Finalización de la transmisión. return(data); /* ****************************** Función de Escritura(int8 dato_recibido) ************************************************** */ void Escritura(int8 dato_recibido) i2c_start(); // Inicializa la transmisión i2c_write(0x48); // Seleccionar esclavo U3 en modo escritura. ( 0100,A2,A1,A0,0 ) // (0100) identifica al C.I. PCF8476. Microcontroladores IES Joan Miró Página 126

127 Curso de Robótica y otras aplicaciones en el Aula de Tecnología // (A2,A1,A0)=(100) por hardware. // El ultimo bit a 0 para poner el C.I. PCF8476 en modo escritura. i2c_write(dato_recibido); i2c_stop(); // Dato a escribir // Finalización de la transmisión Lectura y escritura en PCF8574 en modo Interrupción.c // Programa...: Lectura y escritura en PCF8574 en modo Interrupción.c // // Plataforma hw: Placa Monibot // // Fecha...: Septiembre-2011 // // Programador..: Pedro Alonso // // Descripción..: Control con I2C de un expansor de Bus paralelo PCF8574 (U4) en modo // // interrupción. // // ********************************* Directivas de Preprocesado ************************************** #include <16F877A.h> #fuses XT,NOWDT,PUT,NOWRT #use delay(clock= ) #use i2c(master, force_hw, slow, sda=pin_c4, scl=pin_c3) interno.(asociado a I2C) // Configuración de I2C // Definimos el PIC como maestro // Forzamos a trabajar con su hardware // Trabajamos a velocidad baja 100 Kbps // Elegimos sda=pin_c4 como patilla de datos. // Elegimos scl=pin_c3 como patilla de reloj. #BYTE TRISA = 0x85 // TRISA en 85h. #BYTE porta = 0x05 // PORTA en 05h. #BIT INTF = 0x0B.1 // INTF en 0x0B patilla 1. #BIT ra1 = 0x05.1 // RA1 en 0x05 patilla 1. #BIT ra2 = 0x05.2 // RA2 en 0x05 patilla 2. #BIT ra3 = 0x05.3 // RA3 en 0x05 patilla 3. #BIT ra4 = 0x05.4 // RA4 en 0x05 patilla 4. #BIT ra5 = 0x05.5 // RA5 en 0x05 patilla 5. /* *************************************** Declaración de funciones ************************************************************ */ int8 Lectura_Interruptores(); void Escritura(int8); void Motor_PAP (void); void Lectura_Escritura_PCF8476(void); // Declaramos la función Lectura_Interruptores (Nos devuelve una // variable tipo entero de 8 bit) // Declaramos la función Escritura (LLeva una variable asociada de // tipo entero de 8 bit) /* *************************** Función principal o programa principal **************************** */ void main() TRISA = 0B ; // Defines Puerto A como SALIDA de datos. porta = 0B ; // Reseteamos el Puerto A. port_b_pullups(true); enable_interrupts(int_ext); ext_int_edge(h_to_l); INTF = 1; enable_interrupts(global); while (1) // Habilitamos resistencias pullup. // Habilitamos la interrupción INT de la patilla RB0. // Que la interrupción de INT sea por flanco de BAJADA. // Forzamos la Interrupción. // Habilitamos la Interrupción General. // Bucle infinito de espera Microcontroladores IES Joan Miró Página 127

128 Curso de Robótica y otras aplicaciones en el Aula de Tecnología Motor_PAP(); /* ************************************* Atención a la interrupción por cambio en RB0 ************************************* */ #INT_EXT void Lectura_Escritura_PCF8476(void) int8 dato_recibido; dato_recibido = Lectura_Interruptores(); Escritura(~dato_recibido); // Leemos el dato a través del bus I2c del esclavo U4 // Escribimos el dato a través del bus I2c en el esclavo U3 /* ******************************************** Motor Paso a Paso *************************************************************** */ void Motor_PAP (void) ra3 = 0; ra2 = 0; ra1 = 0; ra5 = 1; delay_ms(500); ra3 = 0; ra2 = 0; ra1 = 1; ra5 = 1; delay_ms(500); ra3 = 0; ra2 = 0; ra1 = 1; ra5 = 0; delay_ms(500); ra3 = 0; ra2 = 1; ra1 = 1; ra5 = 0; delay_ms(500); ra3 = 0; ra2 = 1; ra1 = 0; ra5 = 0; delay_ms(500); ra3 = 1; ra2 = 1; ra1 = 0; ra5 = 0; delay_ms(500); ra3 = 1; ra2 = 0; ra1 = 0; ra5 = 0; delay_ms(500); ra3 = 1; ra2 = 0; ra1 = 0; // Posicionamos el Motor PAP en la 1ª Posición. // Retardo de 500 ms // Posicionamos el Motor PAP en la 2ª Posición. // Retardo de 500 ms // Posicionamos el Motor PAP en la 3ª Posición. // Retardo de 500 ms // Posicionamos el Motor PAP en la 4ª Posición. // Retardo de 500 ms // Posicionamos el Motor PAP en la 5ª Posición. // Retardo de 500 ms // Posicionamos el Motor PAP en la 6ª Posición. // Retardo de 500 ms // Posicionamos el Motor PAP en la 7ª Posición. // Retardo de 500 ms // Posicionamos el Motor PAP en la 8ª Posición. Microcontroladores IES Joan Miró Página 128

129 Curso de Robótica y otras aplicaciones en el Aula de Tecnología ra5 = 1; delay_ms(500); // Retardo de 500 ms /* *************************************** Función de int8 Lectura_Interruptores() ****************************************** */ int8 Lectura_Interruptores() int8 data; i2c_start(); // Inicializa la recepción. i2c_write(0x41); // Seleccionar esclavo U4 en modo lectura. ( 0100,A2,A1,A0,1 ) // (0100) identifica al C.I. PCF8476. // (A2,A1,A0)=(000) por hardware. // El ultimo bit a 1 para poner el C.I. PCF8476 en modo lectura. data=i2c_read(0); i2c_stop(); // Lectura del dato // Finalización de la transmisión. return(data); /* ************************************* Función de Escritura(int8 dato_recibido) ******************************************* */ void Escritura(int8 dato_recibido) i2c_start(); // Inicializa la transmisión i2c_write(0x48); // Seleccionar esclavo U3 en modo escritura. ( 0100,A2,A1,A0,0 ) // (0100) identifica al C.I. PCF8476. // (A2,A1,A0)=(100) por hardware. // El ultimo bit a 0 para poner el C.I. PCF8476 en modo escritura. i2c_write(dato_recibido); i2c_stop(); // Dato a escribir // Finalización de la transmisión PCF8574_2. Utilizaremos el entrenador PCF8574_2.DSN contenido en la carpeta de I2C\ Expansor_Bus_PCF8574\ PCF8574_2. Microcontroladores IES Joan Miró Página 129

130 Curso de Robótica y otras aplicaciones en el Aula de Tecnología Lectura y escritura de multiples PCF8574 modo polling.c // Programa...: Lectura y escritura de multiples PCF8574 modo polling.c // // Plataforma hw: Placa Monibot // // Fecha...: Septiembre-2011 // // Programador..: Pedro Alonso // // Descripción..: Control con I2C de cuatro expansores de Bus paralelo PCF8574 // // en modo polling. // // ********************************* Directivas de Preprocesado ************************************** #include <16F877A.h> #fuses XT,NOWDT,PUT,NOWRT #use delay(clock= ) #use i2c(master, force_hw, slow, sda=pin_c4, scl=pin_c3) // Configuración de I2C // Definimos el PIC como maestro // Forzamos a trabajar con su hardware // interno.(asociado a I2C) // Trabajamos a velocidad baja 100 Kbps // Elegimos sda=pin_c4 como patilla de datos. // Elegimos scl=pin_c3 como patilla de reloj. /* ********************************************* Declaración de funciones ****************************************************** */ int8 Lectura_Interruptores_1(void); // Declaramos la función Lectura_Interruptores_1 // (Nos devuelve una variable tipo entero de 8 bit) void Escritura_Led_1(int8); // Declaramos la función Escritura_Led_1 // (LLeva una variable asociada de tipo entero de 8 bit) int8 Lectura_Interruptores_2(void); // Declaramos la función Lectura_Interruptores_2 // (Nos devuelve una variable tipo entero de 8 bit) void Escritura_Led_2(int8); // Declaramos la función Escritura_Led_2 // (LLeva una variable asociada de tipo entero de 8 bit) /* *************************** Función principal o programa principal **************************** */ void main() int8 dato_recibido; while (1) dato_recibido = Lectura_Interruptores_1(); delay_ms(50); // Bucle infinito de espera // Leemos el dato a través del bus I2c del // esclavo U3 Escritura_Led_1(dato_recibido); delay_ms(50); // Escribimos el dato a través del bus I2c en el // esclavo U4 dato_recibido = Lectura_Interruptores_2(); delay_ms(50); // Leemos el dato a través del bus I2c del // esclavo U5 Escritura_Led_2(dato_recibido); delay_ms(50); // Escribimos el dato a través del bus I2c en el // esclavo U6 /* ********************************* Función de int8 Lectura_Interruptores_1() ********************************************* */ int8 Lectura_Interruptores_1() int8 data; i2c_start(); // Inicializa la recepción. i2c_write(0b ); // Seleccionar esclavo U3 en modo lectura. ( 0100,A2,A1,A0,1 ) // (0100) identifica al C.I. PCF8476. // (A2,A1,A0)=(000) por hardware. // El ultimo bit a 1 para poner el C.I. PCF8476 en modo lectura. data=i2c_read(0); // Lectura del dato Microcontroladores IES Joan Miró Página 130

131 Curso de Robótica y otras aplicaciones en el Aula de Tecnología i2c_stop(); // Finalización de la transmisión. return(data); /* ********************************* Función de Escritura_1(int8 dato_recibido) ******************************************** */ void Escritura_Led_1(int8 dato_recibido) i2c_start(); // Inicializa la transmisión i2c_write(0x48); // Seleccionar esclavo U4 en modo escritura. ( 0100,A2,A1,A0,0 ) // (0100) identifica al C.I. PCF8476. // (A2,A1,A0)=(100) por hardware. // El ultimo bit a 0 para poner el C.I. PCF8476 en modo escritura. i2c_write(dato_recibido); // Dato a escribir i2c_stop(); // Finalización de la transmisión. /* ********************************* Función de int8 Lectura_Interruptores_2() ********************************************* */ int8 Lectura_Interruptores_2() int8 data; i2c_start(); // Inicializa la recepción. i2c_write(0b ); // Seleccionar esclavo U5 en modo lectura. ( 0100,A2,A1,A0,1 ) // (0100) identifica al C.I. PCF8476. // (A2,A1,A0)=(101) por hardware. // El ultimo bit a 1 para poner el C.I. PCF8476 en modo lectura. data=i2c_read(0); // Lectura del dato i2c_stop(); // Finalización de la transmisión. return(data); /* ********************************* Función de Escritura_2(int8 dato_recibido) ******************************************** */ void Escritura_Led_2(int8 dato_recibido) i2c_start(); // Inicializa la transmisión i2c_write(0x4e); // Seleccionar esclavo U6 en modo escritura. ( 0100,A2,A1,A0,0 ) // (0100) identifica al C.I. PCF8476. // (A2,A1,A0)=(111) por hardware. // El ultimo bit a 0 para poner el C.I. PCF8476 en modo escritura. i2c_write(dato_recibido); i2c_stop(); // Dato a escribir // Finalización de la transmisión Lectura y escritura de multiples PCF8574 modo Interrupción.c // Programa...: Lectura y escritura de multiples PCF8574 modo Interrupción.c // // Plataforma hw: Placa Monibot // // Fecha...: Septiembre-2011 // // Programador..: Pedro Alonso // // Descripción..: Control con I2C de cuatro expansores de Bus paralelo PCF8574 // // en modo Interrupción. // // ********************************* Directivas de Preprocesado ************************************** #include <16F877A.h> #fuses XT,NOWDT,PUT,NOWRT #use delay(clock= ) #use i2c(master, force_hw, slow, sda=pin_c4, scl=pin_c3) // Configuración de I2C // Definimos el PIC como maestro // Forzamos a trabajar con su hardware Microcontroladores IES Joan Miró Página 131

132 Curso de Robótica y otras aplicaciones en el Aula de Tecnología #BYTE TRISA = 0x85 // TRISA en 85h. #BYTE porta = 0x05 // PORTA en 05h. #BYTE TRISB = 0x86 // TRISB en 86h. #BYTE portb = 0x06 // PORTB en 06h. #BIT rb4 = 0x06.4 // RA4 en 0x05 patilla 4. #BIT rb5 = 0x06.5 // RA5 en 0x05 patilla 5. // interno.(asociado a I2C) // Trabajamos a velocidad baja 100 Kbps // Elegimos sda=pin_c4 como patilla de datos. // Elegimos scl=pin_c3 como patilla de reloj. #BIT ra1 = 0x05.1 // RA1 en 0x05 patilla 1. #BIT ra2 = 0x05.2 // RA2 en 0x05 patilla 2. #BIT ra3 = 0x05.3 // RA3 en 0x05 patilla 3. #BIT ra4 = 0x05.4 // RA4 en 0x05 patilla 4. #BIT ra5 = 0x05.5 // RA5 en 0x05 patilla 5. #BIT RBIF = 0x0B.0 // RBIF en 0x0B patilla 0. Necesario para Proteus /* ********************************************* Declaración de funciones ****************************************************** */ void Motor_PAP (void); void Lectura_Escritura_PCF8476(void); int8 Lectura_Interruptores_1(void); // Declaramos la función Lectura_Interruptores_1 // (Nos devuelve una variable tipo entero de 8 bit) void Escritura_Led_1(int8); // Declaramos la función Escritura_Led_1 // (LLeva una variable asociada de tipo entero de 8 bit) int8 Lectura_Interruptores_2(void); // Declaramos la función Lectura_Interruptores_2 //(Nos devuelve una variable tipo entero de 8 bit) void Escritura_Led_2(int8); // Declaramos la función Escritura_Led_2 //(LLeva una variable asociada de tipo entero de 8 bit) /* ****************************************** Función principal o programa principal **************************************** */ void main() TRISA = 0B ; TRISB = 0B ; // Defines Puerto A como SALIDA de datos. // Defines Puerto B como ENTRADA de datos. porta = 0B ; // Reseteamos el Puerto A. port_b_pullups(true); enable_interrupts(int_rb); enable_interrupts(global); RBIF = 1; // Habilitamos resistencias pullup. // Habilitamos la interrupción INT de la patilla RB0. // Habilitamos la Interrupcion General. // Forzamos la Interrupción. while (1) Motor_PAP(); // Bucle infinito de espera /* ************************************************ Motor Paso a Paso *********************************************************** */ void Motor_PAP (void) ra3 = 0; ra2 = 0; ra1 = 0; ra5 = 1; delay_ms(500); ra3 = 0; ra2 = 0; ra1 = 1; ra5 = 1; // Posicionamos el Motor PAP en la 1ª Posición. // Retardo de 500 ms // Posicionamos el Motor PAP en la 2ª Posición. Microcontroladores IES Joan Miró Página 132

133 Curso de Robótica y otras aplicaciones en el Aula de Tecnología delay_ms(500); ra3 = 0; ra2 = 0; ra1 = 1; ra5 = 0; delay_ms(500); ra3 = 0; ra2 = 1; ra1 = 1; ra5 = 0; delay_ms(500); ra3 = 0; ra2 = 1; ra1 = 0; ra5 = 0; delay_ms(500); ra3 = 1; ra2 = 1; ra1 = 0; ra5 = 0; delay_ms(500); ra3 = 1; ra2 = 0; ra1 = 0; ra5 = 0; delay_ms(500); ra3 = 1; ra2 = 0; ra1 = 0; ra5 = 1; delay_ms(500); // Retardo de 500 ms // Posicionamos el Motor PAP en la 3ª Posición. // Retardo de 500 ms // Posicionamos el Motor PAP en la 4ª Posición. // Retardo de 500 ms // Posicionamos el Motor PAP en la 5ª Posición. // Retardo de 500 ms // Posicionamos el Motor PAP en la 6ª Posición. // Retardo de 500 ms // Posicionamos el Motor PAP en la 7ª Posición. // Retardo de 500 ms // Posicionamos el Motor PAP en la 8ª Posición. // Retardo de 500 ms /* ******************************* Atención a la interrupción por cambio en RB0 ******************************************* */ #INT_RB void Lectura_Escritura_PCF8476(void) int n; // Necesario en el Proteus, para poder borrar el flag RBIF. int8 dato_recibido; if(rb4==0) // Preguntamos si ha interrumpido (U3) dato_recibido = Lectura_Interruptores_1(); // Leemos el dato a través del bus I2c del // esclavo U3. Escritura_Led_1(dato_recibido); // Escribimos el dato a través del bus I2c en el // esclavo U4. if(rb5==0) // Preguntamos si ha interrumpido (U4) dato_recibido = Lectura_Interruptores_2(); // Leemos el dato a través del bus I2c del // esclavo U5. Escritura_Led_2(dato_recibido); // Escribimos el dato a través del bus I2c en el // esclavo U6. n = portb; // Necesario en el Proteus, para poder borrar el flag RBIF. Microcontroladores IES Joan Miró Página 133

134 Curso de Robótica y otras aplicaciones en el Aula de Tecnología /* **************************** Función de int8 Lectura_Interruptores_1() ************************************************** */ int8 Lectura_Interruptores_1() int8 data; i2c_start(); // Inicializa la recepción. i2c_write(0b ); // Seleccionar esclavo U3 en modo lectura. ( 0100,A2,A1,A0,1 ) // (0100) identifica al C.I. PCF8476. // (A2,A1,A0)=(000) por hardware. // El ultimo bit a 1 para poner el C.I. PCF8476 en modo lectura. data=i2c_read(0); i2c_stop(); // Lectura del dato // Finalización de la transmisión. return(data); /* ***************************** Función de Escritura_1(int8 dato_recibido) ************************************************ */ void Escritura_Led_1(int8 dato_recibido) i2c_start(); // Inicializa la transmisión i2c_write(0x48); // Seleccionar esclavo U4 en modo escritura. ( 0100,A2,A1,A0,0 ) // (0100) identifica al C.I. PCF8476. // (A2,A1,A0)=(100) por hardware. // El ultimo bit a 0 para poner el C.I. PCF8476 en modo escritura. i2c_write(dato_recibido); i2c_stop(); // Dato a escribir // Finalización de la transmisión. /* ********************************* Función de int8 Lectura_Interruptores_2() ********************************************* */ int8 Lectura_Interruptores_2() int8 data; i2c_start(); // Inicializa la recepción. i2c_write(0b ); // Seleccionar esclavo U5 en modo lectura. ( 0100,A2,A1,A0,1 ) // (0100) identifica al C.I. PCF8476. // (A2,A1,A0)=(101) por hardware. // El ultimo bit a 1 para poner el C.I. PCF8476 en modo lectura. data=i2c_read(0); i2c_stop(); // Lectura del dato // Finalización de la transmisión. return(data); /* ****************************** Función de Escritura_2(int8 dato_recibido) *********************************************** */ void Escritura_Led_2(int8 dato_recibido) i2c_start(); // Inicializa la transmisión i2c_write(0x4e); // Seleccionar esclavo U6 en modo escritura. ( 0100,A2,A1,A0,0 ) // (0100) identifica al C.I. PCF8476. // (A2,A1,A0)=(111) por hardware. // El ultimo bit a 0 para poner el C.I. PCF8476 en modo escritura. i2c_write(dato_recibido); i2c_stop(); // Dato a escribir // Finalización de la transmisión. Microcontroladores IES Joan Miró Página 134

135 Curso de Robótica y otras aplicaciones en el Aula de Tecnología PCF8574_3. Utilizaremos el entrenador PCF8574_3.DSN contenido en la carpeta de I2C\ Expansor_Bus_PCF8574\ PCF8574_ CAD_PCF8547.c // Programa...: CAD_PCF8547.c // // Plataforma hw: Placa Monibot // // Fecha...: Septiembre-2011 // // Programador..: Pedro Alonso // // Descripción..: Un programa principal controla un motor PAP. // // El Conversor A/D interrumpe el programa principal digitalizando la patilla RA0 // // y llevar su resultado a el expansor de Bus paralelo PCF8574 (U7). // // El cristal de cuarzo tiene que ser de 20 MHz // // ********************************* Directivas de Preprocesado ************************************** #include <16F876A.h> #device adc=8 #fuses XT,NOWDT,PUT,NOWRT #use delay(clock= ) // Conversor Analogico Digital de 8 bit el PIC 16F876A puede trabajar // con 8 o 10 bit de resolucion. // Cambiar el reloj a 20 MHz #use i2c(master, force_hw, slow, sda=pin_c4, scl=pin_c3) // Configuración de I2C // Definimos el PIC como maestro // Forzamos a trabajar con su hardware // interno.(asociado a I2C) // Trabajamos a velocidad baja 100 Kbps // Elegimos sda=pin_c4 como patilla de datos. // Elegimos scl=pin_c3 como patilla de reloj. #BYTE TRISA = 0x85 // TRISA en 85h. Microcontroladores IES Joan Miró Página 135

136 Curso de Robótica y otras aplicaciones en el Aula de Tecnología #BYTE porta = 0x05 // PORTA en 05h. #BIT ra1 = 0x05.1 // RA1 en 0x05 patilla 1. #BIT ra2 = 0x05.2 // RA2 en 0x05 patilla 2. #BIT ra3 = 0x05.3 // RA3 en 0x05 patilla 3. #BIT ra4 = 0x05.4 // RA4 en 0x05 patilla 4. #BIT ra5 = 0x05.5 // RA5 en 0x05 patilla 5. #BIT ta1 = 0x85.1 // TA1 en 0x85 patilla 1. #BIT ta2 = 0x85.2 // TA2 en 0x85 patilla 2. #BIT ta3 = 0x85.3 // TA3 en 0x85 patilla 3. #BIT ta4 = 0x85.4 // TA4 en 0x85 patilla 4. #BIT ta5 = 0x85.5 // TA5 en 0x85 patilla 5. /* ******************************************* Declaración de funciones ******************************************************** */ void Escritura(int8); void Motor_PAP (void); void Lectura_Escritura_PCF8476(void); // Declaramos la función Escritura // (LLeva una variable asociada de tipo entero de 8 bit) /* ************************************* Función principal o programa principal ********************************************* */ void main() setup_adc_ports(14); setup_adc(adc_clock_internal); set_adc_channel(0); // Seleccionamos el PA0 como entrada Analógica y // PA1..PA5 digitales. Mirar ADCON1. // Fuente de reloj RC interno. // Habilitación canal 0 "AN0" ta1 = 0; ta2 = 0; ta3 = 0; ta4 = 0; ta5 = 0; // Defines PA1 como SALIDA de datos. // Defines PA2 como SALIDA de datos. // Defines PA3 como SALIDA de datos. // Defines PA4 como SALIDA de datos. // Defines PA5 como SALIDA de datos. ra1 = 0; // Activamos el Motor PAP y encendemos LED. ra2 = 0; ra3 = 1; ra4 = 0; ra5 = 1 enable_interrupts(int_ad); // Habilitamos la interrupción por Conversión A/D. enable_interrupts(global); // Habilitamos la Interrupcion General. read_adc(adc_start_only); // Lanzamos el Conversor A/D. while (1) Motor_PAP(); // Bucle infinito de espera. // Ejecuta la funcion Motor PAP. /* ********************************* Atención a la interrupción por Conversión A/D **************************************** */ #INT_AD void Lectura_Escritura_PCF8476(void) int8 dato_recibido; delay_ms(10); dato_recibido = read_adc(adc_read_only); Escritura(dato_recibido); read_adc(adc_start_only); // Retardo de 10 ms. (No es necesario, solo se hace para // dar tiempo al motor PAP a posicionarse) // Lectura canal 0 "AN0". (Solo leemos el dato digitalizado) // Escribimos el dato a través del bus I2c en el esclavo U3 // Lanzamos el Conversor A/D. Microcontroladores IES Joan Miró Página 136

137 Curso de Robótica y otras aplicaciones en el Aula de Tecnología /* ******************************************************* Motor Paso a Paso **************************************************** */ void Motor_PAP (void) ra3 = 0; ra2 = 0; ra1 = 0; ra5 = 1; delay_ms(100); ra3 = 0; ra2 = 0; ra1 = 1; ra5 = 1; delay_ms(100); ra3 = 0; ra2 = 0; ra1 = 1; ra5 = 0; delay_ms(100); ra3 = 0; ra2 = 1; ra1 = 1; ra5 = 0; delay_ms(100); ra3 = 0; ra2 = 1; ra1 = 0; ra5 = 0; delay_ms(100); ra3 = 1; ra2 = 1; ra1 = 0; ra5 = 0; delay_ms(100); ra3 = 1; ra2 = 0; ra1 = 0; ra5 = 0; delay_ms(100); ra3 = 1; ra2 = 0; ra1 = 0; ra5 = 1; // Posicionamos el Motor PAP en la 1ª Posición. // Retardo de 100 ms // Posicionamos el Motor PAP en la 2ª Posición. // Retardo de 100 ms // Posicionamos el Motor PAP en la 3ª Posición. // Retardo de 100 ms // Posicionamos el Motor PAP en la 4ª Posición. // Retardo de 100 ms // Posicionamos el Motor PAP en la 5ª Posición. // Retardo de 100 ms // Posicionamos el Motor PAP en la 6ª Posición. // Retardo de 100 ms // Posicionamos el Motor PAP en la 7ª Posición. // Retardo de 100 ms // Posicionamos el Motor PAP en la 8ª Posición. delay_ms(100); // Retardo de 100 ms /* **************************** Función de Escritura(int8 dato_recibido) **************************************************** */ void Escritura(int8 dato_recibido) i2c_start(); // Inicializa la transmisión i2c_write(0x4c); // Seleccionar esclavo U3 en modo escritura. ( 0100,A2,A1,A0,0 ) // (0100) identifica al C.I. PCF8476. // (A2,A1,A0)=(110) por hardware. // El ultimo bit a 0 para poner el C.I. PCF8476 en modo escritura. i2c_write(dato_recibido); i2c_stop(); // Dato a escribir // Finalización de la transmisión. Microcontroladores IES Joan Miró Página 137

138 Curso de Robótica y otras aplicaciones en el Aula de Tecnología CAD_PCF8547_MULTIPLES.c // Programa...: CAD_PCF8547_MULTIPLES.c // // Plataforma hw: Placa Monibot // // Fecha...: Septiembre-2011 // // Programador..: Pedro Alonso // // Descripción..: Un programa principal controla un motor PAP. // // El Conversor A/D interrumpe el programa principal digitalizando la patilla RA0 // // y llevar su resultado a el expansor de Bus paralelo PCF8574 (U7). // // El expansor de Bus paralelo PCF8574 (U4) también interrumpe el programa // // principal y sus datos son al expansor de Bus paralelo PCF8574 (U3) // // El cristal de cuarzo tiene que ser de 20 MHz // // ********************************* Directivas de Preprocesado ************************************** #include <16F876A.h> #device adc=8 // Conversor Analógico Digital de 8 bit el PIC 16F876A puede // trabajar con 8 o 10 bit de resolución. #fuses XT,NOWDT,PUT,NOWRT #use delay(clock= ) // Cambiar el reloj a 20 MHz #use i2c(master, force_hw, slow, sda=pin_c4, scl=pin_c3) // Configuración de I2C // Definimos el PIC como maestro // Forzamos a trabajar con su hardware // interno.(asociado a I2C) // Trabajamos a velocidad baja 100 Kbps // Elegimos sda=pin_c4 como patilla de datos. // Elegimos scl=pin_c3 como patilla de reloj. #BYTE TRISA = 0x85 // TRISA en 85h. #BYTE porta = 0x05 // PORTA en 05h. #BIT ra1 = 0x05.1 // RA1 en 0x05 patilla 1. #BIT ra2 = 0x05.2 // RA2 en 0x05 patilla 2. #BIT ra3 = 0x05.3 // RA3 en 0x05 patilla 3. #BIT ra4 = 0x05.4 // RA4 en 0x05 patilla 4. #BIT ra5 = 0x05.5 // RA5 en 0x05 patilla 5. #BIT ta1 = 0x85.1 // TA1 en 0x85 patilla 1. #BIT ta2 = 0x85.2 // TA2 en 0x85 patilla 2. #BIT ta3 = 0x85.3 // TA3 en 0x85 patilla 3. #BIT ta4 = 0x85.4 // TA4 en 0x85 patilla 4. #BIT ta5 = 0x85.5 // TA5 en 0x85 patilla 5. #BIT INTF = 0x0B.1 // INTF en 0x0B patilla 1. #define U3 0x48 #define U7 0x4C /* ************************************** Declaración de funciones ************************************************************* */ void Escritura(int8, int8); tipo entero de 8 bit) int8 Lectura_Interruptores(); void Motor_PAP (void); void Lectura_Escritura_AD_PCF8476(void); void Lectura_Escritura_INT_PCF8476(void); // Declaramos la función Escritura (LLeva dos variable asociada de // Declaramos la función Lectura_Interruptores // (Nos devuelve una variable tipo entero de 8 bit) /* *************************** Función principal o programa principal **************************** */ void main() setup_adc_ports(14); setup_adc(adc_clock_internal); // Seleccionamos el PA0 como entrada Analógica y // PA1..PA5 digitales. Mirar ADCON1. // Fuente de reloj RC interno. Microcontroladores IES Joan Miró Página 138

139 Curso de Robótica y otras aplicaciones en el Aula de Tecnología set_adc_channel(0); ta1 = 0; ta2 = 0; ta3 = 0; ta4 = 0; ta5 = 0; ra1 = 0; ra2 = 0; ra3 = 1; ra4 = 0; ra5 = 1; port_b_pullups(true); enable_interrupts(int_ext); ext_int_edge(h_to_l); INTF = 1; enable_interrupts(int_ad); enable_interrupts(global); read_adc(adc_start_only); while (1) // Habilitación canal 0 "AN0" // Defines PA1 como SALIDA de datos. // Defines PA2 como SALIDA de datos. // Defines PA3 como SALIDA de datos. // Defines PA4 como SALIDA de datos. // Defines PA5 como SALIDA de datos. // Activamos el Motor PAP y encendemos LED. // Habilitamos resistencias pullup. // Habilitamos la interrupción INT de la patilla RB0. // Que la interrupción de INT sea por flanco de BAJADA. // Forzamos la Interrupción. // Habilitamos la interrupción por Conversión A/D. // Habilitamos la Interrupción General. // Lanzamos el Conversor A/D. // Bucle infinito de espera. Motor_PAP(); // Ejecuta la función Motor PAP. /* **************************** Atención a la interrupción por Conversión A/D ********************************************* */ #INT_AD void Lectura_Escritura_AD_PCF8476(void) int8 dato_recibido; delay_ms(10); dato_recibido = read_adc(adc_read_only); Escritura(dato_recibido,U7); read_adc(adc_start_only); // Retardo de 10 ms. (No es necesario, solo se hace para // dar tiempo al motor PAP a posicionarse) // Lectura canal 0 "AN0". (Solo leemos el dato digitalizado) // Escribimos el dato a través del bus I2c en el esclavo U3 // Lanzamos el Conversor A/D. /* *************************************** Atención a la interrupción por cambio en RB0 *********************************** */ #INT_EXT void Lectura_Escritura_INT_PCF8476(void) int8 dato_recibido; dato_recibido = Lectura_Interruptores(); Escritura(~dato_recibido,U3); // Leemos el dato a través del bus I2c del esclavo U4 // Escribimos el dato a través del bus I2c en el esclavo U3 /* ************************** Función de Escritura(int8 dato_recibido, int8 esclavo) ************************************** */ void Escritura(int8 dato_recibido, int8 esclavo) i2c_start(); i2c_write(esclavo); // Inicializa la transmisión // Seleccionar esclavo U3 en modo escritura. // ( 0100,A2,A1,A0,0 ) // (0100) identifica al C.I. PCF8476. // (A2,A1,A0)=(100) por hardware. Microcontroladores IES Joan Miró Página 139

140 Curso de Robótica y otras aplicaciones en el Aula de Tecnología i2c_write(dato_recibido); i2c_stop(); // El ultimo bit a 0 para poner el C.I. PCF8476 en modo escritura. // Dato a escribir // Finalización de la transmisión. /* *************************************** Función de int8 Lectura_Interruptores() ****************************************** */ int8 Lectura_Interruptores() int8 data; i2c_start(); // Inicializa la recepción. i2c_write(0x41); // Seleccionar esclavo U4 en modo lectura. ( 0100,A2,A1,A0,1 ) // (0100) identifica al C.I. PCF8476. // (A2,A1,A0)=(000) por hardware. // El ultimo bit a 1 para poner el C.I. PCF8476 en modo lectura. data=i2c_read(0); i2c_stop(); // Lectura del dato // Finalización de la transmisión. return(data); /* ********************************************* Motor Paso a Paso ************************************************************** */ void Motor_PAP (void) ra3 = 0; ra2 = 0; ra1 = 0; ra5 = 1; delay_ms(100); ra3 = 0; ra2 = 0; ra1 = 1; ra5 = 1; delay_ms(100); ra3 = 0; ra2 = 0; ra1 = 1; ra5 = 0; delay_ms(100); ra3 = 0; ra2 = 1; ra1 = 1; ra5 = 0; delay_ms(100); ra3 = 0; ra2 = 1; ra1 = 0; ra5 = 0; delay_ms(100); ra3 = 1; ra2 = 1; ra1 = 0; ra5 = 0; delay_ms(100); ra3 = 1; ra2 = 0; ra1 = 0; ra5 = 0; // Posicionamos el Motor PAP en la 1ª Posición. // Retardo de 100 ms // Posicionamos el Motor PAP en la 2ª Posición. // Retardo de 100 ms // Posicionamos el Motor PAP en la 3ª Posición. // Retardo de 100 ms // Posicionamos el Motor PAP en la 4ª Posición. // Retardo de 100 ms // Posicionamos el Motor PAP en la 5ª Posición. // Retardo de 100 ms // Posicionamos el Motor PAP en la 6ª Posición. // Retardo de 100 ms // Posicionamos el Motor PAP en la 7ª Posición. Microcontroladores IES Joan Miró Página 140

141 Curso de Robótica y otras aplicaciones en el Aula de Tecnología delay_ms(100); ra3 = 1; ra2 = 0; ra1 = 0; ra5 = 1; delay_ms(100); // Retardo de 100 ms // Posicionamos el Motor PAP en la 8ª Posición. // Retardo de 100 ms Conversor A-D_D-A_PCF8591. El PCF8591 es un conversor analógico/digital y digital/analógico con salida I2C, está compuesto por un sistema de adquisición de datos con cuatro entradas analógicas y un conversor digital/analógico. Tres pines de dirección A0, A1 y A2 se utilizan para la programación de la dirección de hardware, permitiendo el uso de ocho dispositivos conectados al bus I2C. La resolución es de 8 bit PCF8591_ADC. Utilizaremos el entrenador PCF8591_AD.DSN contenido en la carpeta de I2C\ Conversor A-D_D-A_PCF8591\ PCF8591_ADC Microcontroladores IES Joan Miró Página 141

142 Curso de Robótica y otras aplicaciones en el Aula de Tecnología I2C_CAD_1.c // Programa...: I2C_CAD_1.c // // Plataforma hw: Placa Monibot // // Fecha...: Septiembre-2011 // // Programador..: Pedro Alonso // // Descripción..: Conversión Analógica/Digital en formato I2C // // ********************************* Directivas de Preprocesado ************************************** #include <16F877A.h> #fuses XT,NOWDT,PUT,NOWRT #use delay(clock= ) #use i2c(master, force_hw, slow, sda=pin_c4, scl=pin_c3) #include <flex_lcd.c> // Configuración de I2C // Definimos el PIC como maestro // Forzamos a trabajar con su hardware // interno.(asociado a I2C) // Trabajamos a velocidad baja 100 Kbps // Elegimos sda=pin_c4 como patilla de datos. // Elegimos scl=pin_c3 como patilla de reloj. // Incluimos el driver flex_lcd.c que contiene las // funciones de control del LCD. #define PCF8591 0b // Dirección I2C del PCF8591 (1001) identifica al C.I. PCF8591. // 0x 9 9 // Seleccionar esclavo U1 en modo lectura. ( 1001,A2,A1,A0,1 ) // (A2,A1,A0)=(100) por hardware. // El ultimo bit a 1 para poner el C.I. PCF8591 en modo lectura. #define CANAL 0B // Seleccionamos el PCF8591 como C A/D y el Canal AIN0 /* ************************ Función principal o programa principal ******************************* */ void main() int8 q; float v1; lcd_init(); i2c_start(); i2c_write(pcf8591&0b ); i2c_write(canal); // Inicializamos el LCD. // Envía secuencia de inicio // Envía dirección I2C del dispositivo en modo escritura // Seleccionamos el canal y modo conversión A/D. while (1) i2c_start(); // Bucle infinito de espera // Envía secuencia de inicio i2c_write(pcf8591); // Envía dirección I2C del dispositivo en modo lectura q=i2c_read(0); i2c_stop(); v1 = 5.0 * q / 256.0; // Lee último byte, envía NACK y almacena en el buffer // Secuencia de stop // Conversión a tensión del código digital "q". lcd_gotoxy(1,1); // Posicionamos el Cursor del LCD en la posición 1 línea 1. printf(lcd_putc,"v1=%3.1gv",v1); // Visualiza sobre la pantalla LCD la lectura de V1 lcd_gotoxy(1,2); // Posicionamos el Cursor del LCD en la posición 1 línea 2. printf(lcd_putc,"q=%3u",q); // Visualiza sobre la pantalla LCD la lectura de q "Código // digital proporcional a la tensión" Microcontroladores IES Joan Miró Página 142

143 Curso de Robótica y otras aplicaciones en el Aula de Tecnología I2C_CAD_2.c // Programa...: I2C_CAD_2.c // // Plataforma hw: Placa Monibot // // Fecha...: Septiembre-2011 // // Programador..: Pedro Alonso // // Descripción..: Conversión Analógica/Digital en formato I2C de los 4 canales AIN0..3 // // ********************************* Directivas de Preprocesado ************************************** #include <16F877A.h> #fuses XT,NOWDT,PUT,NOWRT #use delay(clock= ) #use i2c(master, force_hw, slow, sda=pin_c4, scl=pin_c3) #include <flex_lcd.c> // Configuración de I2C // Definimos el PIC como maestro // Forzamos a trabajar con su hardware // interno.(asociado a I2C) // Trabajamos a velocidad baja 100 Kbps // Elegimos sda=pin_c4 como patilla de datos. // Elegimos scl=pin_c3 como patilla de reloj. // Incluimos el driver flex_lcd.c que contiene las // funciones de control del LCD. #define AIN0 0 #define AIN1 1 #define AIN2 2 #define AIN3 3 // Elección del Canal 0 y modo conversión A/D. // Elección del Canal 1 y modo conversión A/D. // Elección del Canal 2 y modo conversión A/D. // Elección del Canal 3 y modo conversión A/D. // ************************************************** Declaración de Funciones *************************************************** float Leer_PCF8591(int8); /* **************************** Función principal o programa principal *************************** */ void main() int8 entrada_analogica; lcd_init(); // Inicializamos el LCD. while (1) entrada_analogica=ain0; // Bucle infinito de espera lcd_gotoxy(1,1); // Posicionamos el Cursor del LCD en la posición 1 línea 1. printf(lcd_putc,"v1=%3.1gv",leer_pcf8591(entrada_analogica)); entrada_analogica=ain1; // Visualiza sobre la pantalla // LCD la lectura del canal 0 // AIN0 lcd_gotoxy(9,1); // Posicionamos el Cursor del LCD en la posición 9 línea 1. printf(lcd_putc,"v2=%3.1gv",leer_pcf8591(entrada_analogica)); entrada_analogica=ain2; // Visualiza sobre la pantalla // LCD la lectura del canal 1 // AIN1 lcd_gotoxy(1,2); // Posicionamos el Cursor del LCD en la posición 1 línea 2. printf(lcd_putc,"v3=%3.1gv",leer_pcf8591(entrada_analogica)); entrada_analogica=ain3; // Visualiza sobre la pantalla // LCD la lectura del canal 2 // AIN2 lcd_gotoxy(9,2); // Posicionamos el Cursor del LCD en la posición 9 línea 2. printf(lcd_putc,"v4=%3.1gv",leer_pcf8591(entrada_analogica)); // Visualiza sobre la pantalla // LCD la lectura del canal 3 // AIN3 Microcontroladores IES Joan Miró Página 143

144 Curso de Robótica y otras aplicaciones en el Aula de Tecnología // ***************************************** Función floatint8 Leer_PCF8159(int8) ********************************************** float Leer_PCF8591(int8 canal) #define PCF8591 0b // Dirección I2C del PCF8591 (1001) identifica al C.I. PCF8591. // 0x 9 9 // Seleccionar esclavo U1 en modo lectura. ( 1001,A2,A1,A0,1 ) // (A2,A1,A0)=(100) por hardware. // El ultimo bit a 1 para poner el C.I. PCF8591 en modo lectura. int8 q; float v; i2c_start(); i2c_write(pcf8591&0b ); i2c_write(canal); // Envía secuencia de inicio // Envía dirección I2C del dispositivo en modo escritura // Seleccionamos el canal y modo conversión A/D. //********************************************* Leer Canal ************************************************************ i2c_start(); i2c_write(pcf8591); q=i2c_read(0); i2c_stop(); // Envía secuencia de inicio // Envía dirección I2C del dispositivo en modo lectura // Lee último byte, envía NACK y almacena en el buffer // Secuencia de stop //********************************************* Leer Canal ************************************************************ i2c_start(); i2c_write(pcf8591); // Envía secuencia de inicio // Envía dirección I2C del dispositivo en modo lectura q=i2c_read(0); i2c_stop(); // Lee último byte, envía NACK y almacena en el buffer // Secuencia de stop //********************************* Convertir el código digital en tensión ******************************************* v = 5.0 * q / 256.0; // Conversión a tensión del código digital "q". return(v); PCF8591_DAC. Utilizaremos el entrenador PCF8591_DA.DSN contenido en la carpeta de I2C\ Conversor A-D_D-A_PCF8591\ PCF8591_DAC Microcontroladores IES Joan Miró Página 144

145 Curso de Robótica y otras aplicaciones en el Aula de Tecnología I2C_CDA_1.c // Programa...: I2C_CDA_1.c // // Plataforma hw: Placa Monibot // // Fecha...: Septiembre-2011 // // Programador..: Pedro Alonso // // Descripción..: Conversión Analógica/Digital y Digital/Analógica en formato I2C // // ********************************* Directivas de Preprocesado ************************************** #include <16F877A.h> #fuses XT,NOWDT,PUT,NOWRT #use delay(clock= ) #use i2c(master, force_hw, slow, sda=pin_c4, scl=pin_c3) #include <flex_lcd.c> // Configuración de I2C // Definimos el PIC como maestro // Forzamos a trabajar con su hardware // interno.(asociado a I2C) // Trabajamos a velocidad baja 100 Kbps // Elegimos sda=pin_c4 como patilla de datos. // Elegimos scl=pin_c3 como patilla de reloj. // Incluimos el driver flex_lcd.c que contiene las // funciones de control del LCD. #define AIN0 0 #define AIN1 1 #define AIN2 2 #define AIN3 3 // Elección del Canal 0 y modo conversión A/D. // Elección del Canal 1 y modo conversión A/D. // Elección del Canal 2 y modo conversión A/D. // Elección del Canal 3 y modo conversión A/D. // ********************************************** Declaración de Funciones ******************************************************* int8 Leer_U2_PCF8591(int8); void Escribir_U1_PCF8591(int8); /* **************************** Función principal o programa principal *************************** */ void main() int8 entrada_analogica,q1; float v; lcd_init(); while (1) entrada_analogica=ain1; q1=leer_u2_pcf8591(entrada_analogica); // Inicializamos el LCD. // Bucle infinito de espera // Leemos el Código digital proporcional a la señal // analógica de la patilla AIN1 v = 5.0 * q1 / 256.0; // Conversión a tensión del código digital "q1". lcd_gotoxy(1,1); // Posicionamos el Cursor del LCD en la posición // 1 línea 1. printf(lcd_putc,"v1=%3.1gv",v); // Visualiza sobre la pantalla LCD la lectura de v. Escribir_U1_PCF8591(q1); // Obtenemos una señal analógica proporcional al // código digital q1. // ***************************************** Función int8 Leer_U2_PCF8159(int8) *********************************************** int8 Leer_U2_PCF8591(int8 canal) #define PCF8591_U2 0b // Dirección I2C del PCF8591_U2 (1001) identifica al C.I. U2 PCF8591. // 0x 9 9 // Seleccionar esclavo U1 en modo lectura. ( 1001,A2,A1,A0,1 ) // (A2,A1,A0)=(100) por hardware. // El ultimo bit a 1 para poner el C.I. PCF8591 en modo lectura. int8 q; Microcontroladores IES Joan Miró Página 145

146 Curso de Robótica y otras aplicaciones en el Aula de Tecnología i2c_start(); i2c_write(pcf8591_u2&0b ); i2c_write(canal); // Envía secuencia de inicio // Envía dirección I2C del dispositivo en modo escritura // Seleccionamos el canal y modo conversión A/D. //********************************************* Leer Canal ************************************************************ i2c_start(); i2c_write(pcf8591_u2); q=i2c_read(0); i2c_stop(); // Envía secuencia de inicio // Envía dirección I2C del dispositivo en modo lectura // Lee último byte, envía NACK y almacena en el buffer // Secuencia de stop //********************************************* Leer Canal ************************************************************ i2c_start(); i2c_write(pcf8591_u2); q=i2c_read(0); i2c_stop(); // Envía secuencia de inicio // Envía dirección I2C del dispositivo en modo lectura // Lee último byte, envía NACK y almacena en el buffer / /Secuencia de stop return(q); // ***************************************** Función Escribir_U1_PCF8159(int8) ************************************************ void Escribir_U1_PCF8591(int8 dato) #define PCF8591_U1 0B // Dirección I2C del PCF8591_U1 (1001) identifica al C.I. U1 PCF8591. // 0x 9 3 // Seleccionar esclavo U1 en modo lectura. ( 1001,A2,A1,A0,1 ) // (A2,A1,A0)=(001) por hardware. // El ultimo bit a 1 para poner el C.I. PCF8591 en modo lectura. i2c_start(); // Envía secuencia de inicio i2c_write(pcf8591_u1&0b ); i2c_write(0b ); i2c_write(dato); i2c_write(dato); i2c_stop(); // Envía dirección I2C del dispositivo en modo escritura // Seleccionamos el modo conversión D/A. // Envía el contenido de la variable dato y se convierte en // señal analógica. // Envía el contenido de la variable dato y se convierte en // señal analógica. // Secuencia de stop Microcontroladores IES Joan Miró Página 146

147 Curso de Robótica y otras aplicaciones en el Aula de Tecnología Sensores y Hardware Sensores de Infrarrojos CNY70. El CNY70 es un sensor de infrarrojos de corto alcance basado en un emisor de luz y un receptor, ambos apuntando en la misma dirección, y cuyo funcionamiento se basa en la capacidad de reflexión del objeto, y la detección del rayo reflectado por el receptor. 3 1 A CNY70 C K E 4 2 Funcionamiento: Vista externa y circuitos internos del sensor CNY70 I1 E1= 5V I2 Diodo Emisor de Luz R1= 220 R2= 47K CNY70 I3 Optotransistor Cortado 74HC14 0 V1= 5V V2= 0V Luz Infrarroja Línea negra absorbe la luz I1 E1= 5V I2 Diodo Emisor de Luz R1= 220 R2= 47K Ic CNY70 I3 Optotransistor Saturado I4 74HC14 1 V1= 0V V2= 5V Luz Infrarroja Línea blanca refleja la luz Utilizaremos el entrenador Robot Rastreador_Monibot.DSN contenido en la carpeta de Sensores y Hardware\ CNY70. Microcontroladores IES Joan Miró Página 147

148 Curso de Robótica y otras aplicaciones en el Aula de Tecnología Prueba_Sensores_CNY70.c // Programa...: Prueba_Sensores_CNY70.c // // Plataforma hw: Placa monibot 16F877A // // Fecha...: Mayo-2010 // // Programador..: Pedro Alonso // // Descripción..: Leer los sensores CNY70 y visualizarlo en el LCD. // // *********************************** Directivas de Preprocesado ************************************ #include <16F877A.h> #fuses XT,NOWDT,NOPROTECT,NOLVP #use delay( clock = ) #include <flex_lcd.c> // Reloj de 1 MHz // Incluimos el driver flex_lcd.c que contiene las funciones // de control del LCD. #BYTE TRISA = 0x85 // TRISA en 85h. #BYTE PORTA = 0x05 // PORTA en 05h. #BYTE TRISD = 0x88 // TRISD en 88h. #BYTE PORTD = 0x08 // PORTD en 08h. #BIT rd0 = 0x08.0 // RD0 en 0x08 patilla 0. #BIT rd1 = 0x08.1 // RD1 en 0x08 patilla 1. #BIT rd2 = 0x08.2 // RD2 en 0x08 patilla 2. #BIT rd3 = 0x08.3 // RD3 en 0x08 patilla 3. #BIT ra4 = 0x05.4 // RA4 en 0x05 patilla 4. #BIT ra5 = 0x05.5 // RA5 en 0x05 patilla 5. // ****************************** Función principal o programa principal **************************** // Se define con un void main, void main() lcd_init(); // Inicializamos el LCD. Microcontroladores IES Joan Miró Página 148

149 Curso de Robótica y otras aplicaciones en el Aula de Tecnología TRISA = 0B ; TRISD = 0B ; while (1) lcd_gotoxy(6,1); printf(lcd_putc,"%2u%2u",~rd3,~rd2); // Defines Puerto A como ENTRADA de datos. // Configurar el Puerto D como ENTRADAS (RD3..0) y // SALIDAS (RD7..4) de datos. // Posicionamos el Cursor del LCD en la posición // 6 línea 1. // Escribimos 1 dígitos de la variables "rd3 y rd2" // invertidas en formato entero y sin signo. lcd_gotoxy(3,2); // Posicionamos el Cursor del LCD en la // posición 3 línea 2. printf(lcd_putc,"%2u%2u%4u%2u",~ra5,~ra4,~rd1,~rd0); // Escribimos 1 dígitos de la variables // "ra5, ra4, rd1 y rd0" invertidas en // formato entero y sin signo Sensores de Distancia Sensor de Infrarrojos GP2D12. Los IR Sharp GP2DXX son una familia de sensores de infrarrojos para la detección y medida de distancia a los objetos. Proporciona una tensión en función de la distancia (0-3V) Rango de medida de 10 a 80 cm con una respuesta en 39 ms. Estos dispositivos emplean el método de triangulación utilizando un pequeño Sensor Detector de Posición (PSD) lineal para determinar la distancia o la presencia de los objetos dentro de su campo de visión. Básicamente su modo de funcionamiento consiste en la emisión de un pulso de luz infrarroja, que se transmite a través de su campo de visón que se refleja contra un objeto o que por el contrario no lo hace. Si no encuentra ningún obstáculo, el haz de luz no refleja y en la lectura que se hace indica que no hay ningún obstáculo. En el caso de encontrar un obstáculo el haz de luz infrarroja se reflecta y crea un triangulo formado por el emisor, el punto de reflexión (obstáculo) y el detector. La información de la distancia se extrae midiendo el ángulo recibido. Si el ángulo es grande, entonces el objeto está cerca, por que el triangulo es ancho. Si el ángulo es pequeño, entonces el Microcontroladores IES Joan Miró Página 149

150 Curso de Robótica y otras aplicaciones en el Aula de Tecnología objeto está lejos, por que el triangulo formado es estrecho. Por lo tanto, si el ángulo es pequeño, quiere decir que el objeto está lejos, porque el triangulo es largo y delgado. El LED infrarrojo emite el has de luz a través de una pequeña lente convergente que hace que el haz emisor llegue de forma paralela al objeto. Cuando la luz choca con un obstáculo, una cierta cantidad de luz se refleja, si el obstáculo fuera un espejo perfecto, todos los rayos del haz de luz pasarían, y sería imposible medir la distancia. Sin embargo, casi todas las sustancias tienen un grado bastante grande de rugosidad de la superficie que produce una dispersión hemisférica de la luz ( la llamada reflexión no teórica). Alguno de estos haces de esta luz rebota hacia el sensor que es recibido por la lente. La lente receptora también es una lente convexa, pero ahora sirve para un propósito Diferente. Actúa para convertir el ángulo de posición. Si un objeto se pone en el plano focal de una lente convexa y los otros rayos de luz paralelos en otro lado, el rayo que pasa por el centro de la lente atraviesa inalterado o marca el lugar focal. Los rayos restantes también enfocan a este punto. Puesto en el plano focal es un Sensor Detector de Posición (PSD). Éste dispositivo semiconductor entrega una salida cuya intensidad es proporcional a la posición respecto al centro (centro eficaz) de la luz que incide en él. En el caso del GP2D12, los rendimientos de PSD la salida es proporcional a la posición del punto focal. Esta señal analógica tratada es la que se obtiene a la salida del sensor. Consideraciones Prácticas Las lentes del dispositivo deben de estar siempre limpias, no utilizar para su limpieza agua o aceite. Cuando la superficie del detector recibe la luz directa del sol o de una lámpara de tungsteno, puede darse el caso de que no se pueda medir la distancia. Tener esto en cuenta para que el detector no reciba la luz directa de una fuente de luz potente. Para estabilizar la tensión de alimentación del dispositivo, se recomienda conectar un condensador de 10 mf o más entre VCC y GND cerca del GP2D12. La ecuación que relaciona la distancia d con la tensión v es una ecuación de 4º grado para una distancia desde (10 cm hasta 80 cm): d= 16,75 v 4 119,26 v ,7 v 2-365,71 v + 183,03 Utilizaremos el entrenador Monibot_GP2D12.DSN contenido en la carpeta de Sensores y Hardware\ GP2D12. Microcontroladores IES Joan Miró Página 150

151 Curso de Robótica y otras aplicaciones en el Aula de Tecnología Lectura_S1_GP2D12.c // Programa...: Lectura_S1_GP2D12.c // // Plataforma hw: Placa Monibot 16F877A // // Fecha...: Octubre-2010 // // Programador..: Pedro Alonso // // Descripción..: Prueba de un sensor GP2D12 // // *********************************** Directivas de Preprocesado ************************************ #include <16F877A.h> #device adc=10 #FUSES XT,NOWDT #use delay(clock= ) // Conversor Analógico Digital de 10 bit el PIC 16F876A puede // trabajar con 8 o 10 bit de resolucion. #include <flex_lcd.c> // Incluimos el driver "flex_lcd.c" que contiene las funciones de // control del LCD. #include <driver2_gp2d12.c> // Incluimos el driver "driver2_gp2d12.c" que contiene la función de // control del GP2D12. Curva matemática // #include <driver1_gp2d12.c> // Incluimos el driver "driver1_gp2d12.c" que contiene la función de // control del GP2D12. Aproximación por rectas. /* *************************** Función principal o programa principal **************************** */ void main() int16 q; float d,v; setup_adc_ports(2); setup_adc(adc_clock_internal); lcd_init(); for (;;) // Seleccionamos el Puerto A como entradas Analógicas. // Mirar ADCON1. // Fuente de reloj RC interno. // Inicializamos el LCD. // Bucle infinito. Microcontroladores IES Joan Miró Página 151

152 Curso de Robótica y otras aplicaciones en el Aula de Tecnología set_adc_channel(0); delay_us(20); q = read_adc(); v = (5.0 * q) / ; // Habilitación canal 0 "AN0" // Retardo de 20uS necesaria para respetar el tiempo de // adquisición Tad. // Lectura canal 0 "AN0" // Conversión a tensión del código digital "q". d=gp2d12_v_d(v); lcd_gotoxy(1,1); // Posicionamos el Cursor en la posición 1, línea 1. printf(lcd_putc, "Voltios = %2.1fV", v); // Escribimos en el LCD "Voltios =" y 3 dígitos de "v" // en formato truncado con 1 decimales y el carácter "V". lcd_gotoxy(1,2); // Posicionamos el Cursor en la posición 1, línea 2. printf(lcd_putc, "S1 = %5.1fcm",d ); // Saltamos de línea y escribimos en el LCD "d =" y 6 // dígitos de "d" en formato truncado de 6 dígitos con // 1 decimal y los caracteres "cm" Lectura_S1_GP2D12.c // Programa...: Lectura_S1_S2_GP2D12.c // // Plataforma hw: Placa Monibot 16F877A // // Fecha...: Octubre-2010 // // Programador..: Pedro Alonso // // Descripción..: Prueba de dos sensor GP2D12 // // ******************************* Directivas de Preprocesado **************************************** #include <16F877A.h> #device adc=10 #FUSES XT,NOWDT #use delay(clock= ) // Conversor Analógico Digital de 10 bit el PIC 16F876A puede // trabajar con 8 o 10 bit de resolución. #include <flex_lcd.c> // Incluimos el driver "flex_lcd.c" que contiene las funciones de control // del LCD. #include <driver2_gp2d12.c> // Incluimos el driver "driver2_gp2d12.c" que contiene la función de // control del GP2D12. Curva matemática // #include <driver1_gp2d12.c> // Incluimos el driver "driver1_gp2d12.c" que contiene la función de // control del GP2D12. Aproximación por rectas //******************************* PROGRAMA PRINCIPAL ********************************************* void main() int16 q; float d, v; setup_adc_ports(2); setup_adc(adc_clock_internal); lcd_init(); // Seleccionamos el Puerto A como entradas analógicas. // Mirar ADCON1. // Fuente de reloj RC interno. // Inicializamos el LCD. for (;;) set_adc_channel(0); delay_us(20); q = read_adc(); v = (5.0 * q) / ; d=gp2d12_v_d(v); // Bucle infinito. // Habilitación canal 0 "AN0" // Retardo de 20uS necesaria para respetar el tiempo de // Adquisición Tad. // Lectura canal 0 "AN0" // Conversión a tensión del código digital "q". lcd_gotoxy(1,1); // Posicionamos el Cursor en la posición 1, línea 1. printf(lcd_putc, "S1 = %4.1fcm",d ); // Escribimos en el LCD "S1 =" y 4 dígitos de "d" // en formato truncado con 1 decimal y los caracteres "cm". set_adc_channel(1); delay_us(20); q = read_adc(); v = (5.0 * q) / ; // Habilitación canal 0 "AN1" // Retardo de 20uS necesaria para respetar el tiempo de // Adquisición Tad. // Lectura canal 0 "AN0" // Conversión a tensión del código digital "q". Microcontroladores IES Joan Miró Página 152

153 Curso de Robótica y otras aplicaciones en el Aula de Tecnología d=gp2d12_v_d(v); lcd_gotoxy(1,2); // Posicionamos el Cursor en la posición 1, línea 2. printf(lcd_putc, "S2 = %4.1fcm",d ); // Escribimos en el LCD "S2 =" y 4 dígitos de "d" // en formato truncado con 1 decimal y los caracteres "cm" driver1_gp2d12.c //*********** Driver de Control del Sensor de Infrarrojos Gp2d12, para una distancia //*********** entre 8 cm y 55 cm.* // Se obtiene una distancia "d" (Formato float) en función de la tensión "v" (Formato float). // Se realiza aproximaciones a la curva con rectas. // Ecuación de la recta con dos puntos: // d=d1+[(v-v1)/(v2-v1)](d2-d1) // Mirar archivo Ecuación de la Recta. //******************************** DECLARACIÓN DE FUNCIONES*************************************************************** float Gp2d12_v_d(float); //***********************************************FUNCIÓN Gp2d12_v_d************************************************************ float Gp2d12_v_d(float v) float l; l=0; if(v>2.6) l = 8; else if(v<2.6&&v>=1.9) l = ((8-13.5)* (v - 1.9) /( )); else if(v<1.9&&v>=1.65) l = 16 + (( )* (v- 1.65) / ( )); else if(v<1.65&&v>=1.38) l = 20 + ((16-20)* (v- 1.38) / ( )); else if(v<1.38&&v>=1.15) l = 25 + ((20-25)* (v- 1.15) / ( )); else if(v<1.15&&v>=0.95) l = 30 + ((25-30)* (v- 0.95) / ( )); else if(v<0.95&&v>=0.75) l = 40 + ((30-40)* (v- 0.75) / ( )); else if(v<0.75&&v>=0.68) l = 45 + ((40-45)* (v- 0.68) / ( )); else if(v<0.68&&v>=0.58) l = 55 + ((45-55)* (v- 0.58) / ( )); else if(v<0.58) l=55; return(l); driver2_gp2d12.c //********* Driver de Control del Sensor de Infrarrojos Gp2d12, para una distancia entre //********* 8 cm y 55 cm. // Se obtiene una distancia "d" (Formato float)en función de la tensión "v"(formato float). // Se utiliza una ecuación de 4 grado. //****************************** DECLARACIÓN DE FUNCIONES **************************************************************** float Gp2d12_v_d(float); //****************************************FUNCIÓN Gp2d12_v_d ****************************************************************** float Gp2d12_v_d(float v) float i; //variable auxiliar de cuenta float r; float s; float d; r=v*v; s=v*v*v; i=v*v*v*v; d=((16.75*i) *s)+(311.7*r)-(365.71*v) ; return(d); Microcontroladores IES Joan Miró Página 153

154 Curso de Robótica y otras aplicaciones en el Aula de Tecnología Sensor de Ultrasonidos SRF08. El módulo SRF08 consiste en un medidor ultrasónico de distancia de bajo costo desarrollado por la firma DEVANTECH Ltd. y es una versión mejorada del módulo SRF04. Emplea un microcntrolador PIC16F872 que realiza todas las funciones de control e interface, dos capsulas ultrasónicas de 40 KHz y una célula LDR capaz de proporcionar una medida de luz ambiente. Se comunica vía I2C. Reducido consumo (3 ma en Standby 15 ma en funcionamiento). Es capaza de medir diferentes ecos recibidos por la señal ultrasónica. La ganancia de los amplificadores internos son ajustables al igual que el rango de medidas. Ofrece una lectura directa (centímetros, pulgadas o microsegundos) Un diodo led en la parte posterior del módulo genera un código de intermitencias que expresa la dirección del I2C actual del módulo así com el inicio de una nueva medida. La dirección del módulo es por defecto 0XE0, aunque existe la posibilidad de cambiarla por otras 15 (0XE2, 0XE4, 0XE6, 0XE8, 0XEA, 0XEC, 0XEE, 0XF0, 0XF2, 0XF4, 0XF6, 0XF8, 0XFA, 0XFC o 0XFE. Esto permite controlar hasta 16 módulo SRF08 con el bus I2C. Además de las direcciones anteriores, todos los sonares conectados al bus I2C responderán a la dirección 0x00 de llamada general. Esto significa que escribir un comando de medición de la distancia para la dirección 0x00 de I2C,iniciará las mediciones en todos los sensores al mismo tiempo. Esto es útil en el modo ANN (Red Neuronal Artificial). Los resultados deben leerse de manera individual de cada uno de las direcciones reales de los sensores. Utilizaremos el entrenador Monibot_SRF08.DSN contenido en la carpeta de Sensores y Hardware\ SRF08. Nota: El sensor SFR08 no está simulado utilizaremos dos driver que tienen las mismas funciones. driver_pcf8591.c (Válido para la simulación) driver_srf08.c (Real) Microcontroladores IES Joan Miró Página 154

155 Curso de Robótica y otras aplicaciones en el Aula de Tecnología Lectura_S1_SRF08_Real. // Programa...: Lectura_S1_SRF08_Real.c // // Plataforma hw: Placa Monibot 16F877A // // Fecha...: Mayo-2011 // // Programador..: Pedro Alonso // // Descripción..: Lectura de un Sensor SRF08 // // ************************************* Directivas de Preprocesado ********************************** #include <16F877A.h> #fuses XT,NOWDT,PUT,NOWRT #use delay(clock= ) #use i2c(master, force_hw, slow, sda=pin_c4, scl=pin_c3) interno.(asociado a I2C) #include <flex_lcd.c> // Configuración de I2C // Definimos el PIC como maestro // Forzamos a trabajar con su hardware // Trabajamos a velocidad baja 100 Kbps // Elegimos sda=pin_c4 como patilla de datos. // Elegimos scl=pin_c3 como patilla de reloj. // Incluimos el driver flex_lcd.c que contiene las // funciones de control del LCD. #define SRF08 0xE2 // Dirección I2C del SRF08 /* ************************************************* Declaración de funciones ************************************************** */ int16 Lectura_SRF08(void); variable tipo entero de 8 bit) // Declaramos la función Lectura_Interruptores (Nos devuelve una Microcontroladores IES Joan Miró Página 155

156 Curso de Robótica y otras aplicaciones en el Aula de Tecnología /* *************************** Función principal o programa principal **************************** */ void main() int16 dato_recibido; lcd_init(); // Inicializamos el LCD. while (1) dato_recibido = Lectura_SRF08(); lcd_gotoxy(1,1); printf(lcd_putc,"%03lu cm",dato_recibido); // Bucle infinito de espera // Leemos el dato a través del bus I2c del // esclavo U4 // Posicionamos el Cursor del LCD en la // posición 1 línea 1. // Visualiza sobre la pantalla LCD la lectura del // sensor (3 dígitos) /* ************************************* Función de int16 Lectura_SRF08() *************************************************** */ int16 Lectura_SRF08() #define SRF08_cm 0x51 int16 resultado=0; int8 byte_alto=0; int8 byte_bajo=0; i2c_start(); i2c_write(srf08); i2c_write(0x00); i2c_write(srf08_cm); i2c_stop(); delay_ms(70); i2c_start(); i2c_write(srf08); i2c_write(0x02); i2c_stop(); // Medida en cm // Secuencia de inicio // Dirección I2C del SRF08 modo escritura // Dirección interna 0x00 (registro de comandos) // Enviar comando a ejecutar, lectura en cm // Secuencia de stop // Temporización de 70mS necesaria para realizar la ejecución // Secuencia de inicio // Dirección I2C del dispositivo modo escritura // Envía dirección interna del dispositivo, nos posicionamos en el // registro del 1º eco // Envía secuencia de stop i2c_start(); i2c_write(srf08 0b ); byte_alto=i2c_read(); byte_bajo=i2c_read(0); i2c_stop(); // Envía secuencia de inicio // Envía dirección I2C del dispositivo en modo lectura // No, leer el byte, enviar ACK y almacenar en el buffer // Si, lee último byte, envía NACK y almacena en el buffer //Secuencia de stop resultado=make16(byte_alto, byte_bajo); // Convierte parta alta y baja en un entero de 16 bit return (resultado); Lectura_S1_S2_SRF08_Real.c // Programa...: Lectura_S1_S2_SRF08_Real.c // // Plataforma hw: Placa Monibot 16F877A // // Fecha...: Mayo-2011 // // Programador..: Pedro Alonso // // Descripción..: Lectura de dos Sensor SRF08 // // ************************************** Directivas de Preprocesado ********************************* #include <16F876A.h> Microcontroladores IES Joan Miró Página 156

157 Curso de Robótica y otras aplicaciones en el Aula de Tecnología #fuses XT,NOWDT,PUT,NOWRT #use delay(clock= ) #use i2c(master, force_hw, slow, sda=pin_c4, scl=pin_c3) #include <LCD1.c> // Configuración de I2C // Definimos el PIC como maestro // Forzamos a trabajar con su hardware // interno.(asociado a I2C) // Trabajamos a velocidad baja 100 Kbps // Elegimos sda=pin_c4 como patilla de datos. // Elegimos scl=pin_c3 como patilla de reloj. // Incluimos el driver LCD1.c que contiene las // funciones de control del LCD. #define SENSOR_1 0xE4 // Dirección I2C del Sensor 1 SRF08 #define SENSOR_2 0xE2 // Dirección I2C del Sensor 2 SRF08 /* *********************************************** Declaración de funciones **************************************************** */ int16 Lectura_SRF08(int8); // Declaramos la función Lectura_Interruptores // (Nos devuelve una variable tipo entero de 8 bit) /* *************************** Función principal o programa principal **************************** */ void main() int16 dato_recibido; int8 sensor; lcd_init(); // Inicializamos el LCD. while (1) // Bucle infinito de espera sensor=sensor_2; dato_recibido = Lectura_SRF08(sensor); lcd_gotoxy(1,1); printf(lcd_putc,"s2=%03lu",dato_recibido); // Leemos el dato a través del bus I2c del // Sensor 2 // Posicionamos el Cursor del LCD en la // posición 1 línea 1. // Visualiza sobre la pantalla LCD la lectura del // Sensor 2 sensor=sensor_1; dato_recibido = Lectura_SRF08(sensor); lcd_gotoxy(9,1); printf(lcd_putc,"s1=%03lu",dato_recibido); // Leemos el dato a través del bus I2c del // Sensor 1 // Posicionamos el Cursor del LCD en la // posición 9 línea 1. // Visualiza sobre la pantalla LCD la lectura del // Sensor 1 /* *************************************** Función de int8 Lectura_SRF08() ************************************************** */ int16 Lectura_SRF08(int8 SRF08) #define SRF08_cm 0x51 int16 resultado=0; int8 byte_alto=0; int8 byte_bajo=0; i2c_start(); i2c_write(srf08); i2c_write(0x00); i2c_write(srf08_cm); i2c_stop(); delay_ms(20); i2c_start(); i2c_write(srf08); i2c_write(0x02); i2c_stop(); // Medida en cm // Secuencia de inicio // Dirección I2C del SRF08 modo escritura // Dirección interna 0x00 (registro de comandos) // Enviar comando a ejecutar, lectura en cm // Secuencia de stop // Temporización de 80mS necesaria para realizar la ejecución // Secuencia de inicio // Dirección I2C del dispositivo modo escritura // Envía dirección interna del dispositivo, nos posicionamos en el // registro del 1º eco // Envía secuencia de stop Microcontroladores IES Joan Miró Página 157

158 Curso de Robótica y otras aplicaciones en el Aula de Tecnología i2c_start(); i2c_write(srf08 0b ); byte_alto=i2c_read(); byte_bajo=i2c_read(0); i2c_stop(); // Envía secuencia de inicio // Envía dirección I2C del dispositivo en modo lectura // No, leer el byte, enviar ACK y almacenar en el buffer // Si, lee último byte, envía NACK y almacena en el buffer // Secuencia de stop resultado=make16(byte_alto, byte_bajo); // Convierte parta alta y baja en un entero de 16 bit return(resultado); Lectura_S1_S2_SRF08_Real_Simulado.c // Programa...: Lectura_S1_S2_SRF08_Real_Simulado.c // // Plataforma hw: Placa Monibot 16F877A // // Fecha...: Mayo-2011 // // Programador..: Pedro Alonso // // Descripción..: Lectura de dos Sensor SRF08 real y simulado // // ************************************* Directivas de Preprocesado*********************************** #include <16F877A.h> #fuses XT,NOWDT,PUT,NOWRT #use delay(clock= ) #use i2c(master, force_hw, slow, sda=pin_c4, scl=pin_c3) #include <driver_srf08.c> // Real // #include <driver_pcf8591.c> // Simulado // #include <driver_luz_distancia_srf08.c> // Simulado // Configuración de I2C // Definimos el PIC como maestro // Forzamos a trabajar con su hardware // interno.(asociado a I2C) // Trabajamos a velocidad baja 100 Kbps // Elegimos sda=pin_c4 como patilla de datos. // Elegimos scl=pin_c3 como patilla de reloj. #include <flex_lcd.c> // Incluimos el driver LCD1.c que contiene las // funciones de control del LCD. #define SENSOR_1 0xE4 // Dirección I2C del Sensor 1 SRF08 #define SENSOR_2 0xE2 // Dirección I2C del Sensor 2 SRF08 /* *************************** Función principal o programa principal **************************** */ void main() int16 dato_recibido; int8 sensor; lcd_init(); while (1) sensor=sensor_1; dato_recibido = Lectura_SRF08(sensor); lcd_gotoxy(1,1); printf(lcd_putc,"s1=%03lu",dato_recibido); sensor=sensor_2; dato_recibido = Lectura_SRF08(sensor); lcd_gotoxy(9,1); printf(lcd_putc,"s2=%03lu",dato_recibido); // Inicializamos el LCD. // Bucle infinito de espera // Leemos el dato a través del bus I2c del // Sensor 1 // Posicionamos el Cursor del LCD en la // posición 1 línea 1. // Visualiza sobre la pantalla LCD la lectura del // Sensor 1 // Leemos el dato a través del bus I2c del // Sensor 2 // Posicionamos el Cursor del LCD en la // posición 9 línea 1. // Visualiza sobre la pantalla LCD la lectura del // Sensor 2 Microcontroladores IES Joan Miró Página 158

159 Curso de Robótica y otras aplicaciones en el Aula de Tecnología Lectura_S1_SRF08_Distancia_Lumenes.c //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Programa...: Lectura_S1_SRF08_Distancia_Lumenes.c // // Plataforma hw: Placa Monibot 16F877A // // Fecha...: Mayo-2011 // // Programador..: Pedro Alonso // // Descripción..: Lectura de dos Sensor SRF08 real y simulado // // ************************************* Directivas de Preprocesado ********************************** #include <16F877A.h> #fuses XT,NOWDT,PUT,NOWRT #use delay(clock= ) #use i2c(master, force_hw, slow, sda=pin_c4, scl=pin_c3) // Configuración de I2C // Definimos el PIC como maestro // Forzamos a trabajar con su hardware // interno.(asociado a I2C) // Trabajamos a velocidad baja 100 Kbps // Elegimos sda=pin_c4 como patilla de datos. // Elegimos scl=pin_c3 como patilla de reloj. // #include <driver_srf08.c> // Real // #include <driver_pcf8591.c> // Simulado #include <driver_luz_distancia_srf08.c> // Simulado #include <flex_lcd.c> // Incluimos el driver LCD1.c que contiene las // funciones de control del LCD. #define SENSOR_1 0xE2 // Dirección I2C del Sensor 1 SRF08 /* **************************** Función principal o programa principal *************************** */ void main() int16 distancia; int8 luz; int8 sensor; lcd_init(); while (1) sensor=sensor_1; distancia = Lectura_SRF08(sensor); lcd_gotoxy(1,1); printf(lcd_putc,"s1=%03lu cm",distancia); luz = Lectura_Lumenes_SRF08(sensor); lcd_gotoxy(1,2); printf(lcd_putc,"s1=%03u lumenes",luz); // Inicializamos el LCD. // Bucle infinito de espera // Leemos el dato a través del bus I2c del // Sensor 1 // Posicionamos el Cursor del LCD en la // posición 1 línea 1. // Visualiza sobre la pantalla LCD la lectura del // Sensor 1 // Leemos el dato a través del bus I2c del // Sensor 1 // Posicionamos el Cursor del LCD en la // posición 1 línea 2. // Visualiza sobre la pantalla LCD la lectura del // Sensor driver SRF08.c /* **************************************** driver SRF08.c ******************************************** */ #define SRF08_cm 0x51 // Medida en cm /* ************************************************ Declaración de funciones *************************************************** */ int16 Lectura_SRF08(int8); // Declaramos la función Lectura_SRF08 // (Nos devuelve una variable tipo entero de 8 bit) Microcontroladores IES Joan Miró Página 159

160 Curso de Robótica y otras aplicaciones en el Aula de Tecnología /* *************************************** Función de int8 Lectura_SRF08() ************************************************** */ int16 Lectura_SRF08(int8 SRF08) int16 resultado=0; int8 byte_alto=0; int8 byte_bajo=0; //************************************ Seleccionamos el dispositivo SRF08 ***************************************** i2c_start(); i2c_write(srf08); // Secuencia de inicio // Dirección I2C del SRF08 modo escritura //**** Seleccionamos el registro de Comandos e indicamos que vamos a realizar una lectura en cm **** i2c_write(0x00); i2c_write(srf08_cm); i2c_stop(); // Dirección interna 0x00 (registro de comandos) // Enviar comando a ejecutar, lectura en cm // Secuencia de stop //******************************* Esperamos un tiempo mínimo de 70 ms ****************************************** delay_ms(70); // Temporización de 70mS necesaria para realizar la ejecución //************************************ Seleccionamos el dispositivo SRF08 ***************************************** i2c_start(); i2c_write(srf08); // Secuencia de inicio // Dirección I2C del dispositivo modo escritura //*************************************** Nos posicionamos en el 1º Eco ********************************************* i2c_write(0x02); i2c_stop(); // Envía dirección interna del dispositivo, nos posicionamos en el // registro del 1º eco // Envía secuencia de stop //********************** Leemos los datos obtenidos del sensor (Byte Alto y Byte Bajo) ********************** i2c_start(); i2c_write(srf08 0b ); byte_alto=i2c_read(); byte_bajo=i2c_read(0); i2c_stop(); // Envía secuencia de inicio // Envía dirección I2C del dispositivo en modo lectura // No, leer el byte, envíar ACK y almacenar en el buffer // Si, lee último byte, envía NACK y almacena en el buffer // Secuencia de stop resultado=make16(byte_alto,byte_bajo); // Convierte parta alta y baja en un entero de 16 bit return(resultado); driver_luz_distancia_srf08.c /* ********************************* driver_luz_distancia_srf08.c ******************************** */ #define SRF08_cm 0x51 #define SRF08_Lumenes 0x01 // Medida en cm // Medida en Lumenes /* ************************************************ Declaración de funciones *************************************************** */ int16 Lectura_SRF08(int8); int8 Lectura_Lumenes_SRF08(int8); // Declaramos la función Lectura_SRF08 // (Nos devuelve una variable tipo entero de 8 bit) // Declaramos la función Lectura_ Lumenes_SRF08 // (Nos devuelve una variable tipo entero de 8 bit) /* *************************************** Función de int8 Lectura_SRF08() ************************************************** */ int16 Lectura_SRF08(int8 SRF08) int16 resultado=0; int8 byte_alto=0; int8 byte_bajo=0; //************************************ Seleccionamos el dispositivo SRF08 ***************************************** Microcontroladores IES Joan Miró Página 160

161 Curso de Robótica y otras aplicaciones en el Aula de Tecnología i2c_start(); i2c_write(srf08); // Secuencia de inicio // Dirección I2C del SRF08 modo escritura //**** Seleccionamos el registro de Comandos e indicamos que vamos a realizar una lectura en cm **** i2c_write(0x00); i2c_write(srf08_cm); i2c_stop(); // Dirección interna 0x00 (registro de comandos) // Enviar comando a ejecutar, lectura en cm // Secuencia de stop //******************************* Esperamos un tiempo mínimo de 70 ms ***************************************** delay_ms(70); // Temporización de 65mS necesaria para realizar la ejecución //************************************ Seleccionamos el dispositivo SRF08 ***************************************** i2c_start(); i2c_write(srf08); // Secuencia de inicio // Dirección I2C del dispositivo modo escritura //*************************************** Nos posicionamos en el 1º Eco ********************************************* i2c_write(0x02); i2c_stop(); // Envía dirección interna del dispositivo, nos posicionamos // en el registro del 1º eco // Envía secuencia de stop //*********************Leemos los datos obtenidos del sensor (Byte Alto y Byte Bajo) ************************ i2c_start(); i2c_write(srf08 0b ); byte_alto=i2c_read(); byte_bajo=i2c_read(0); i2c_stop(); // Envía secuencia de inicio // Envía dirección I2C del dispositivo en modo lectura // No, leer el byte, envíar ACK y almacenar en el buffer // Si, lee último byte, envía NACK y almacena en el buffer // Secuencia de stop resultado=make16(byte_alto,byte_bajo); // Convierte parta alta y baja en un entero de 16 bit return(resultado); /* ******************************** Función de int8 Lectura_Lumenes_SRF08(int8 SRF08) ******************************* */ int8 Lectura_Lumenes_SRF08(int8 SRF08) int8 lumenes=0; //************************************ Seleccionamos el dispositivo SRF08 ***************************************** i2c_start(); i2c_write(srf08); // Secuencia de inicio // Dirección I2C del SRF08 modo escritura //* Seleccionamos el registro de Comandos e indicamos que vamos a realizar una lectura en Lumenes i2c_write(srf08_lumenes); i2c_stop(); // Enviar comando a ejecutar, lectura // Secuencia de stop //************************************ Leemos el dispositivo SRF08 ************************************************** i2c_start(); i2c_write(srf08 0b ); lumenes=i2c_read(0); i2c_stop(); // Secuencia de inicio // Envía dirección I2C del dispositivo en modo lectura // Si, lee último byte, envía NACK y almacena en el buffer // Secuencia de stop return(lumenes); Microcontroladores IES Joan Miró Página 161

162 Curso de Robótica y otras aplicaciones en el Aula de Tecnología driver PCF8591.c /* *************************************** driver PCF8591.c ******************************************* */ /* ********************************************* Declaración de funciones ****************************************************** */ int16 Lectura_SRF08(int8); // Declaramos la función Lectura_SRF08 // (Nos devuelve una variable tipo entero de 8 bit) /* ************************************** Función de int8 Lectura_PCF8591() ************************************************ */ int16 Lectura_SRF08(int8 SRF08) int16 resultado=0; int8 PCF8591=0; if(srf08==0xe4) PCF8591=0x99; // 0x99 = 0B // Seleccionar esclavo U1 en modo lectura. ( 1001,A2,A1,A0,1 ) // (0100) identifica al C.I. PCF8591. // (A2,A1,A0)=(100) por hardware. // El ultimo bit a 1 para poner el C.I. PCF8591 en modo lectura. if(srf08==0xe2) PCF8591=0x95; // 0x95 = 0B // Seleccionar esclavo U3 en modo lectura. ( 1001,A2,A1,A0,1 ) // (0100) identifica al C.I. PCF8591. // (A2,A1,A0)=(010) por hardware. // El ultimo bit a 1 para poner el C.I. PCF8591 en modo lectura. i2c_start(); i2c_write(pcf8591); resultado=i2c_read(0); i2c_stop(); // Envía secuencia de inicio // Envía dirección I2C del dispositivo en modo lectura // Si, lee último byte, envía NACK y almacena en el buffer // Secuencia de stop return(resultado); Cambio_Dirección.c // Programa...: Cambio_Dirección.c // // Plataforma hw: Placa Monibot 16F877A // // Fecha...: Mayo-2011 // // Programador..: Pedro Alonso // // Descripción..: Cambiar las direcciones de los sensores de ultrasonidos SRF08 // // ********************************* Directivas de Preprocesado ************************************** #include <16F877A.h> #fuses XT,NOWDT,PUT,NOWRT #use delay(clock= ) #use i2c(master, force_hw, slow, sda=pin_c4, scl=pin_c3) // Configuración de I2C // Definimos el PIC como maestro // Forzamos a trabajar con su hardware // interno.(asociado a I2C) // Trabajamos a velocidad baja 100 Kbps // Elegimos sda=pin_c4 como patilla de datos. // Elegimos scl=pin_c3 como patilla de reloj. #define SRF08_inicial 0xE0 // Dirección I2C del SRF08 inicial #define SRF08_final 0xEE // Dirección I2C del SRF08 final // ***************************** Función principal o programa principal ***************************************************** void main() i2c_start(); i2c_write(srf08_inicial); // Secuencia de inicio // Dirección I2C del SRF08 modo escritura Microcontroladores IES Joan Miró Página 162

163 Curso de Robótica y otras aplicaciones en el Aula de Tecnología i2c_write(0x00); i2c_write(0xa0); i2c_stop(); i2c_start(); i2c_write(srf08_inicial); i2c_write(0x00); i2c_write(0xaa); i2c_stop(); i2c_start(); i2c_write(srf08_inicial); i2c_write(0x00); i2c_write(0xa5); i2c_stop(); i2c_start(); i2c_write(srf08_inicial); i2c_write(0x00); i2c_write(srf08_final); i2c_stop(); // Dirección interna 0x00 (registro de comandos) //1ª secuencia para el cambio de dirección // Secuencia de stop // Secuencia de inicio // Dirección I2C del SRF08 modo escritura // Dirección interna 0x00 (registro de comandos) // 2ª secuencia para el cambio de dirección // Secuencia de stop // Secuencia de inicio // Dirección I2C del SRF08 modo escritura // Dirección interna 0x00 (registro de comandos) // 3ª secuencia para el cambio de dirección // Secuencia de stop // Secuencia de inicio // Dirección I2C del SRF08 modo escritura // Dirección interna 0x00 (registro de comandos) // Nueva dirección I2C // Secuencia de stop while(1); Ejercicio 1.c // Programa...: Ejercicio 1.c // // Plataforma hw: Placa Monibot 16F877A // // Fecha...: Mayo-2011 // // Programador..: Pedro Alonso // // Descripción..: Guiado de un robot en función de la distancia // // ********************************* Directivas de Preprocesado ************************************* #include <16F877A.h> #fuses XT,NOWDT,PUT,NOWRT #use delay(clock= ) #use i2c(master, force_hw, slow, sda=pin_c4, scl=pin_c3) interno.(asociado a I2C) // Configuración de I2C // Definimos el PIC como maestro // Forzamos a trabajar con su hardware // Trabajamos a velocidad baja 100 Kbps // Elegimos sda=pin_c4 como patilla de datos. // Elegimos scl=pin_c3 como patilla de reloj. #include <driver_srf08.c> // Real // #include <driver_pcf8591.c> // Simulado // #include <driver_luz_distancia_srf08.c> // Simulado #include <flex_lcd.c> // Incluimos el driver LCD1.c que contiene las // funciones de control del LCD. #BIT tc1_en1= 0X87.1 #BIT tc2_en2= 0X87.2 #BIT tb2_mi= 0X86.2 #BIT tb3_md= 0X86.3 #BIT rc1_en1= 0X07.1 #BIT rc2_en2= 0X07.2 #BIT rb2_mi= 0X06.2 #BIT rb3_md= 0X06.3 #define SENSOR_1 0xE2 // Dirección I2C del Sensor 1 SRF08 #define ON 1 #define OFF 0 #define ADELANTE 0 #define ATRAS 1 Microcontroladores IES Joan Miró Página 163

164 Curso de Robótica y otras aplicaciones en el Aula de Tecnología /* *************************** Función principal o programa principal **************************** */ void main() int16 distancia; int8 sensor; tc1_en1= 0; tc2_en2= 0; tb2_mi= 0; tb3_md= 0; lcd_init(); while (1) sensor=sensor_1; distancia = Lectura_SRF08(sensor); lcd_gotoxy(1,1); printf(lcd_putc,"s1=%03lu",distancia); if(distancia<20) rc1_en1= ON; rb2_mi= ATRAS; rc2_en2= ON; rb3_md= ATRAS; else if(distancia>=20 && distancia<40) rc1_en1= ON; rb2_mi= ADELANTE; rc2_en2= ON; rb3_md= ADELANTE; else rc1_en1= OFF; rc2_en2= OFF; // Inicializamos el LCD. // Bucle infinito de espera // Leemos el dato a través del bus I2c del // Sensor 1 // Posicionamos el Cursor del LCD en la // posición 1 línea 1. // Visualiza sobre la pantalla LCD la lectura del // Sensor Sensores de Temperatura PT100. Un Pt100 es un sensor de temperatura. Consiste en un alambre de platino que a 0 C tiene 100 ohms y que al aumentar la temperatura aumenta su resistencia eléctrica. (Coeficiente positivo de temperatura) El incremento de la resistencia no es lineal pero si creciente y característico del platino de tal forma que mediante tablas es posible encontrar la temperatura exacta a la que corresponde. Un Pt100 es un tipo particular de RTD (Dispositivo Termo Resistivo) Normalmente las Pt100 industriales se consiguen encapsuladas en la misma forma que Microcontroladores IES Joan Miró Página 164

165 Curso de Robótica y otras aplicaciones en el Aula de Tecnología los termopares, es decir dentro de un tubo de acero inoxidable u otro material (vaina), en un extremo está el elemento sensible (alambre de platino) y en el otro está el terminal eléctrico de los cables protegido dentro de una caja redonda de aluminio ( cabezal ). La fórmula matemática es: R PT100 = R 0 (1 + a 1 x t + a 2 x t 2 ) Donde R 0 es 100Ω a (100 o C) a 1 = a 2 = (Coeficiente de temperatura) (Coeficiente de temperatura) Utilizaremos el entrenador PT100.DSN contenido en la carpeta de Sensores y Hardware\ PT100. Las formulas que determinan la conversión de tensión a temperatura son: V e = [ E 1 / (R 1 +R PT100 )] x R PT100 V S = [(R 4 +R 5 )/R 5 ] x V e El resultado es: R PT100 = [(V S x R 5 x R 1 ) / ((R 4 +R 5 ) x E 1 - V S x R 5 ))] R 0 (1 + a 1 x t + a 2 x t 2 ) = [(V S x R 5 x R 1 ) / ((R 4 +R 5 ) x E 1 - V S x R 5 ))] 1 + a 1 x t + a 2 x t 2 = [(V S x R 5 x R 1 ) / ((R 4 +R 5 ) x E 1 - V S x R 5 )) x R 0 ] 1 + a 1 x t + a 2 x t 2 = A Una vez introducidos los valores queda: Microcontroladores IES Joan Miró Página 165

166 Curso de Robótica y otras aplicaciones en el Aula de Tecnología A = (V S x 70.5) / ( V S x 1.5); a 2 x t 2 + a 1 x t + (1-A) = 0 t = (-b ± ) / 2a = t = (- a 1 + )/ 2 a 2 Factor de Corrección t = (-a1 + raiz) / (2*a 2 ) if (t<0) t = t Lectura_S1_PT100.c // Programa...: Lectura_S1_PT100.c // // Plataforma hw: Placa monibot 16F877A // // Fecha...: Octubre-2010 // // Programador..: Pedro Alonso // // Descripción..: Prueba de un sensor PT100 // // ************************************ Directivas de Preprocesado *********************************** #include <16F877A.h> #device adc=10 #FUSES XT,NOWDT #use delay(clock= ) // Conversor Analógico Digital de 10 bit el PIC 16F876A puede // trabajar con 8 o 10 bit de resolución. #include <MATH.H> #include <flex_lcd.c> // Incluimos el driver flex_lcd.c que contiene las funciones de control // del LCD. #define a #define a //******************************************************** Declaración de Funciones ********************************************* float Con_V_T(float); //********************************************************* Programa Principal ***************************************************** void main() int16 q; float tension; float temperatura; lcd_init(); setup_adc_ports(2); setup_adc(adc_clock_internal); set_adc_channel(0); // Inicializamos el LCD. // Seleccionamos el Puerto A como entradas Analógicas. // Mirar ADCON1. // Fuente de reloj RC interno. // Habilitación canal 0 "AN0" for (;;) delay_us(5); // Bucle infinito. // Retardo de 20uS necesaria para respetar el tiempo de // Adquisición Tad. Microcontroladores IES Joan Miró Página 166

167 Curso de Robótica y otras aplicaciones en el Aula de Tecnología q = read_adc(); tension = 5.0 * q / ; // Lectura canal 0 "AN0" // Conversión a tensión del código digital "q". temperatura = Con_V_T(tension); lcd_gotoxy(1,1); // Posicionamos el Cursor en la posición 1, // línea 1. printf(lcd_putc, "V1= %04.3f v", tension); // Salta línea y escribe en el LCD "V1=" y // 4 dígitos de "tensión" en formato truncado de // con 3 decimales y el carácter "V". lcd_gotoxy(1,2); // Posicionamos el Cursor en la posición 1, // línea 2. printf(lcd_putc, "T1= %3.0g C", temperatura); // Escribe en el LCD "t=" y 3 dígitos de // "temperatura" en formato truncado con // 0 decimales. //*************************************************** Función Con_V_T ************************************************************ float Con_V_T(float p) float t; float a; float b; float raiz; a = (p*70.5)/( p*1.5); b = (a1*a1)-4*a2*(1-a); raiz = sqrt(b); t =-2+(-a1 + raiz)/(2*a2) ; if(t<0) t=t-0.5; return(t); Sensor de Temperatura TC74. El sensor es un combinación de sensor de Tª, conversor A/D de 8 bits e interface I2C en un solo C.I. Siempre será dispositivo esclavo y estará recibiendo o emitiendo datos cuando se lo solicite el Maestro del bus Dirección asignada en I2C como esclavo: (Hay otras 7 direcciones distintas que se podrían asignar bajo pedido a Microchip) Medida de temperatura: de -65ºC a 127ºC Precisión de ±2ºC de +25ºC a 85ºC y ±3ºC de 0ºC a 125ºC Resolución de 8 bits: 1ºC Proporciona valor en binario y valores negativos en complemento a 2 Tensión de alimentación: 2,7V a 5,5V Consumo en operación de 200 μa y en standby de 5 μa Funcionamiento: MEDIDA DE LA TEMPERATURA El integrado realiza la adquisición y conversión de temperaturas mediante un sensor de estado sólido con una resolución de ±1ºC En modo de operación normal, se toman y convierten 8 muestras por segundo y el resultado de la conversión se almacena en un registro interno al que se puede acceder en cualquier momento vía serie mediante el bus I2C. Microcontroladores IES Joan Miró Página 167

168 Curso de Robótica y otras aplicaciones en el Aula de Tecnología El C.I. se puede situar en modo de bajo consumo (Stand-by) en el que se suspende la adquisición de temperatura y queda retenido en el registro interno el resultado de la última conversión. Internamente existe un registro de configuración (CONFIG) donde hay un bit (SHDN) que establece el modo de trabajo: normal (SHDN a 0) o de bajo consumo (SHDN a 1) El registro de configuración interno se puede escribir y se puede leer, mientras que el registro de temperatura sólo puede ser leído. Las lecturas y escrituras siguen las tramas típicas en un bus I2C Utilizaremos el entrenador TC74.DSN contenido en la carpeta de Sensores y Hardware\ Sensor de Temperatura TC Test _TC74.c // Programa...: Test1_TC74.c // // Plataforma hw: Placa monibot 16F877A // // Fecha...: Octubre-2011 // // Programador..: Pedro Alonso // // Descripción..: Prueba de un sensor TC74 // // ****************************** Directivas de Preprocesado ***************************************** #include <16F877A.h> #fuses XT,NOWDT,PUT,NOWRT #use delay(clock= ) #use i2c(master, force_hw, slow, sda=pin_c4, scl=pin_c3) // Configuración de I2C // Definimos el PIC como maestro // Forzamos a trabajar con su hardware Microcontroladores IES Joan Miró Página 168

169 Curso de Robótica y otras aplicaciones en el Aula de Tecnología //interno.(asociado a I2C) // Trabajamos a velocidad baja 100 Kbps // Elegimos sda=pin_c4 como patilla de datos. // Elegimos scl=pin_c3 como patilla de reloj. #include <flex_lcd.c> // Incluimos el driver flex_lcd.c que contiene las // funciones de control del LCD. #define TC74_1 0x90 //Dirección I2C del TC74_1 #define TC74_2 0x92 //Dirección I2C del TC74_2 /* ******************************************** Declaración de funciones ******************************************************* */ signed int8 Lectura_TC74(int8); // Declaramos la función Lectura_TC74 // (Nos devuelve una variable tipo entero de 8 bit con signo) /* *************************** Función principal o programa principal **************************** */ void main() signed int8 dato_recibido; int8 sensor; lcd_init(); // Inicializamos el LCD. lcd_gotoxy(1,1); // Posicionamos el Cursor del LCD en la posición 1 línea 1. printf(lcd_putc,"s1="); // Visualiza sobre la pantalla LCD el mensaje "S1=". lcd_gotoxy(1,2); // Posicionamos el Cursor del LCD en la posición 1 línea 2. printf(lcd_putc,"s2="); // Visualiza sobre la pantalla LCD el mensaje "S2=". while (1) // Bucle infinito de espera sensor = TC74_1; dato_recibido = Lectura_TC74(sensor); // Leemos el dato a través del bus I2c del // esclavo TC74_1 lcd_gotoxy(4,1); // Posicionamos el Cursor del LCD en la // posición 4 línea 1. printf(lcd_putc,"%3d C",dato_recibido); // Visualiza sobre la pantalla LCD la temperatura. sensor = TC74_2; dato_recibido = Lectura_TC74(sensor); lcd_gotoxy(4,2); printf(lcd_putc,"%3d C",dato_recibido); // Leemos el dato a través del bus I2c del // esclavo TC74_2 // Posicionamos el Cursor del LCD en la // posición 4 línea 2. // Visualiza sobre la pantalla LCD la temperatura. delay_ms(40); /* *********************************** Función de int8 Lectura_SRF08() ****************************************************** */ signed int8 Lectura_TC74(int8 sensor) signed int8 temperatura=0; i2c_start(); i2c_write(sensor); i2c_write(0x00); i2c_start(); i2c_write(sensor 0b ); temperatura=i2c_read(0); i2c_stop(); // Secuencia de inicio // Dirección I2C del dispositivo modo escritura // Envía dirección interna del dispositivo, nos posicionamos en // el registro. // Envía secuencia de inicio // Envía dirección I2C del dispositivo en modo lectura // Si, lee último byte, envía NACK y almacena en el buffer // Secuencia de stop return (temperatura); Microcontroladores IES Joan Miró Página 169

170 Curso de Robótica y otras aplicaciones en el Aula de Tecnología Sensor Térmico D-TPA81. TPA81 es un sensor térmico de 8 píxeles capaz de medir la temperatura de un objeto a distancia. Desarrollado por la firma Devantech Ltd., el sensor térmico TPA81 consiste en una matriz lineal de células sensibles a la temperatura y que reciben el nombre de termopilas (TPA). Estas detectan luz infra roja con una longitud de onda en el rango de 2μm a 22μm y que corresponde a la luz que desprenden los objetos calientes. Otro tipo de sensores son los piroeléctricos (PIR). Se usan normalmente para detectar presencia en sistemas de alarmas, control de alumbrados, etc. y trabajan en la misma longitud de onda que las termopilas (TPA). Los sensores PIR únicamente pueden detectar cambios de temperatura producidas por el movimiento. Por su parte las termopilas (TPA) pueden medir la temperatura en cuestión, sin contacto físico con el objeto y como si de un termómetro a distancia se tratara. Su campo o ángulo de detección se muy amplio, en torno a los 100º, pero se puede reducir mediante el empleo de carcasas y lentes de silicona. El sensor TPA81 consta de un total de 8 termopilas o pixels agrupadas en una única hilera o matriz lineal, pudiendo por tanto tomar temperaturas de 8 puntos adyacentes y de forma simultánea. Cada termopila es capaz de detectar la llama de una vela a una distancia de 2m sin que se vea afectado por la luz ambiente. El sensor también dispone del control y las conexiones necesarias para gobernar un servo opcional al que puede estar fijado el propio sensor. Mediante el software de control apropiado se puede hacer que dicho servo vaya rotando de un sentido al otro, a modo de barrido, al tiempo que se van tomando muestras de las distintas temperaturas que suministran las 8 TPA s integradas. Se puede así obtener mapas térmicos de diferentes zonas u objetos. Caracteristicas: Las características más importantes se resumen a continuación: Tensión única de alimentación + 5Vcc Consumo reducido de tan sólo 5mA. Se excluye el posible servo que pudiera estar conectado. Rango de temperaturas de 4ºC hasta 100ºC Resolución en pleno campo de visión de +/- 3ºC en el rango de 4ºC a 10ºC y de +/- 2ºC o el +/- 2% en el rango de 10ºC a 100ºC Campo de visión 41º x 6º lo que hace que cada píxel o TPA tenga un campo de 5º x 6º Información de salida que indica la temperatura ambiente y la que capta cada uno de los pixels o TPA s. Comunicación con el microcontrolador principal a través del interfaz I2C. Posibilidad de controlar un servo opcional con 32 pasos de unos 5,6º para conseguir una rotación de 180º en cualquiera de los sentidos. Tamaño reducido de 31 mm x 18 mm. Se controla con bus I2c. Campo de visión: El campo de visión del sensor TPA81 es de 41º x 6º, con lo que a cada uno de los pixels o termopilas que forman la matriz líneas le corresponde un campo de 5,12º x 6º. Esta matriz esta orientada según se muestra en la figura. El píxel nº 1 es el que está más próximo a la pestaña de referencia del propio sensor. Microcontroladores IES Joan Miró Página 170

171 Curso de Robótica y otras aplicaciones en el Aula de Tecnología Sensibilidad: Aquí se muestran los resultados de alguna de las pruebas realizadas por el fabricante Devatech Ltd. Se emplea una vela a una distancia de 1m del sensor en una habitación a 12º de temperatura ambiente. Los valores leídos en cada uno de los 8 pixels o termopilas son los siguientes (en grados centígrados): La vela se encuentra frente al píxel cuya lectura indica una lectura de 29ºC. Si se aumenta la distancia de la vela a 2m esa temperatura se reduce a 20ºC, unos 8ºC por encima de la temperatura ambiente (12ºC) por lo que todavía la fuente de calor es fácilmente detectable. A una distancia de 0.6m la temperatura sube hasta unos 64ªC y a 0.3m a más de 100ºC. En la misma habitación pero con una temperatura ambiente de 18º, esa vela a una distancia de 2 m nos proporciona una temperatura de 27ºC aproximadamente. Esto se debe a que la vela ocupa una pequeña parte del campo de visión del sensor y su temperatura se suma a la temperatura ambiente, no se superpone por completo. El cuerpo humano aparecerá con una temperatura de 29ºC a 20º de temperatura ambiente. Conexiones: La comunicación entre el sensor TPA81 con el microcontrolador principal se realiza según el protocolo I2C, mediante un conector de 4 líneas. Tal y como se muestra en la figura. Las líneas SCL y SDA son las señales de reloj y datos respectivamente. Se deben conectar con unas resistencias pullup a +5Vcc. Estas resistencias normalmente ya forman parte del bus y las suele proporcionar el Master del mismo. El TPA81 actúa siempre como un slave, pero si hicieran falta se recomienda emplear unos valores en torno a 1.8K. También dispone de un conector para la conexión directa con un servo motor estándar alimentado a +5V. El sensor TPA81 dispone de los comandos necesarios para expresar la posición del servo. El TPA81 se encarga de generar la señal de control con el ancho de pulso necesario. Registros internos: Un total de 10 registros a los que se puede acceder vía I2C, son los que dispone el sensor TPA81 para su total control. Únicamente los registros 0 y 1 se pueden escribir. El registro 0 es el registro de comandos y se emplea para ajustar la nueva posición del servo y para cambiar la dirección base I2C del TPA81. En caso de leer este registro se obtiene la versión del firmware interno del sensor. Escribiendo sobre el registro 1 se establece el rango de movimiento del servo. Cuando se lee se obtiene la medida de la temperatura ambiente. Nº de Reg. Lectura Escritura 0 Revisión del firmware interno Registro de comandos 1 Temperatura ambiente en ºC Rango del servo (versión 6 del firmware o superior) 2 Temperatura del píxel 1 en ºC No disponible 3 Temperatura del píxel 2 en ºC No disponible 4 Temperatura del píxel 3 en ºC No disponible 5 Temperatura del píxel 4 en ºC No disponible 6 Temperatura del píxel 5 en ºC No disponible 7 Temperatura del píxel 6 en ºC No disponible 8 Temperatura del píxel 7 en ºC No disponible 9 Temperatura del píxel 8 en ºC No disponible Microcontroladores IES Joan Miró Página 171

172 Curso de Robótica y otras aplicaciones en el Aula de Tecnología Dispone de 9 registros para la lectura de las temperaturas expresadas en ºC. El registro 1 devuelve el valor de la temperatura ambiente. Los registros del 2 al 9 ofrecen las temperaturas de cada uno de los pixels. La adquisición de las temperaturas es constante y son válidas aproximadamente 40mS después de que el sensor apunte a una nueva posición. Posición del servo: En el registro 0 se escriben los diferentes comandos admitidos. Los comandos numerados del 0 al 31 (0x00 a 0x1F) permiten ajustar la anchura del pulso que se aplica al servo, llevándole así a una nueva posición. Dicha anchura se calcula: Anchura = (nº comando x 60) Se consigue un pulso cuya anchura varía de 540μS (0.54mS) a 2400μS (2,4mS) en pasos de 60μS. Esta anchura es aceptada por la mayor parte de servos. Cambiando la dirección I2C: La dirección por defecto que tiene el sensor TPA81 es la 0xD0. Esta dirección es posible cambiarla con objeto de que en el mismo bus I2C puedan convivir más de dos sensores idénticos o cualquier otro dispositivo pero sin que se repita la dirección. Según el protocolo I2C NO es posible que dos o más dispositivos tengan la misma dirección. Para ello existen tres comandos que, escritos en el orden apropiado sobre el registro de comandos (registro nº 0), permite cambiar la dirección base del sensor TPA81: 160 (0xA0), 165 (0xA5) y 170 (0xAA). Por ejemplo, para cambiar la actual dirección 0xD0 por la nueva 0xD2 basta con escribir la siguiente secuencia sobre el registro 0: 0xA0, 0xAA, 0xA5, 0xD2. Las direcciones que puede admitir el TPA81 son: 0xD0 (defecto), 0xD2, 0xD4, 0xD6, 0xD8, 0xDA, 0xDC o 0xDE. Utilizaremos el entrenador Simulacion_9_Sensores.DSN contenido en la carpeta de Sensores y Hardware\ Sensor Térmico D-TPA81. Microcontroladores IES Joan Miró Página 172

173 Curso de Robótica y otras aplicaciones en el Aula de Tecnología Test1_D-TPA81.c // Programa...: Test1_D-TPA81.c // // Plataforma hw: Placa Monibot 16F877A // // Fecha...: Octubre-2010 // // Programador..: Pedro Alonso // // Descripción..: Prueba de un sensor D-TPA81 // // ****************************** Directivas de Preprocesado ***************************************** #include <16F877A.h> #fuses XT,NOWDT,PUT,NOWRT #use delay(clock= ) #use i2c(master, force_hw, slow, sda=pin_c4, scl=pin_c3) #include <flex_lcd.c> funciones de control del LCD. // Configuración de I2C // Definimos el PIC como maestro // Forzamos a trabajar con su hardware // interno.(asociado a I2C) // Trabajamos a velocidad baja 100 Kbps // Elegimos sda=pin_c4 como patilla de datos. // Elegimos scl=pin_c3 como patilla de reloj. // Incluimos el driver flex_lcd.c que contiene las #define DTPA81 0xD0 // Dirección I2C del D-TPA81 int8 sensor=1; // Nº de sensor /* ********************************************* Declaración de funciones ****************************************************** */ int8 Lectura_DTPA81(int8); // Declaramos la función Lectura_DTPA81. // (Introducimos una variable tipo entero de 8 bit y // nos devuelve una variable tipo entero de 8 bit) /* *************************** Función principal o programa principal **************************** */ void main() int8 dato_recibido; lcd_init(); // Inicializamos el LCD. while (1) sensor=1; dato_recibido = Lectura_DTPA81(sensor); lcd_gotoxy(1,1); printf(lcd_putc,"%1u C",dato_recibido); sensor=2; dato_recibido = Lectura_DTPA81(sensor); lcd_gotoxy(5,1); printf(lcd_putc,"%1u C",dato_recibido); // Bucle infinito de espera // Leemos el dato a través del bus I2c del sensor1 // DTPA81. // Posicionamos el Cursor del LCD en la posición // 1 línea 1. // Visualiza sobre la pantalla LCD la temperatura // del sensor1. // Leemos el dato a través del bus I2c del sensor2 // DTPA81. // Posicionamos el Cursor del LCD en la // posición 5 línea 1. // Visualiza sobre la pantalla LCD la temperatura // del sensor2. delay_ms(40); /* ***************************** Función int8 Lectura_DTPA81(int8 sensor) ************************************************ */ int8 Lectura_DTPA81(int8 sensor) int8 temperatura=0; Microcontroladores IES Joan Miró Página 173

174 Curso de Robótica y otras aplicaciones en el Aula de Tecnología i2c_start(); i2c_write(dtpa81); i2c_write(sensor); i2c_stop(); // Secuencia de inicio // Dirección I2C del dispositivo modo escritura // Envia dirección interna del dispositivo, nos posicinamos // en el registro. // Envía secuencia de stop i2c_start(); i2c_write(dtpa81 0b ); temperatura=i2c_read(0); i2c_stop(); // Envía secuencia de inicio // Envía dirección I2C del dispositivo en modo lectura // Si, lee último byte, envía NACK y almacena en el buffer // Secuencia de stop return(temperatura); Test2_D-TPA81.c // Programa...: Test2_D-TPA81.c // // Plataforma hw: Placa Monibot 16F877A // // Fecha...: Octubre-2010 // // Programador..: Pedro Alonso // // Descripción..: Prueba de un sensor D-TPA81 // // ****************************** Directivas de Preprocesado ***************************************** #include <16F877A.h> #fuses XT,NOWDT,PUT,NOWRT #use delay(clock= ) #use i2c(master, force_hw, slow, sda=pin_c4, scl=pin_c3) // Configuración de I2C // Definimos el PIC como maestro // Forzamos a trabajar con su hardware // interno.(asociado a I2C) // Trabajamos a velocidad baja 100 Kbps // Elegimos sda=pin_c4 como patilla de datos. // Elegimos scl=pin_c3 como patilla de reloj. #include <flex_lcd.c> // Incluimos el driver flex_lcd.c que contiene las // funciones de control del LCD. #define DTPA81 0xD0 // Dirección I2C del D-TPA81 int8 sensor; // Nº de sensor /* ****************************************** Declaración de funciones ********************************************************* */ int8 Lectura_DTPA81(int8); // Declaramos la función Lectura_DTPA81 // (Introducimos una variable tipo entero de 8 bit y nos devuelve // una variable tipo entero de 8 bit) /* ************************* Función principal o programa principal ****************************** */ void main() int8 dato_recibido; lcd_init(); // Inicializamos el LCD. while (1) // Bucle infinito de espera sensor=1; dato_recibido = Lectura_DTPA81(sensor); lcd_gotoxy(1,1); printf(lcd_putc,"%1u",dato_recibido); // Leemos el dato a través del bus I2c del //sensor 1 DTPA81. // Posicionamos el Cursor del LCD en la // posición 1 línea 1. // Visualiza sobre la pantalla LCD la temperatura. sensor=2; dato_recibido = Lectura_DTPA81(sensor); lcd_gotoxy(4,1); // Leemos el dato a través del bus I2c del // sensor 2 DTPA81. // Posicionamos el Cursor del LCD en la // posición 4 línea 1. Microcontroladores IES Joan Miró Página 174

175 Curso de Robótica y otras aplicaciones en el Aula de Tecnología printf(lcd_putc,"%1u",dato_recibido); // Visualiza sobre la pantalla LCD la temperatura. sensor=3; dato_recibido = Lectura_DTPA81(sensor); lcd_gotoxy(7,1); printf(lcd_putc,"%1u",dato_recibido); // Leemos el dato a través del bus I2c del // sensor 3 DTPA81. // Posicionamos el Cursor del LCD en la // posición 7 línea 1. // Visualiza sobre la pantalla LCD la temperatura. sensor=4; dato_recibido = Lectura_DTPA81(sensor); lcd_gotoxy(10,1); printf(lcd_putc,"%1u",dato_recibido); // Leemos el dato a través del bus I2c del // sensor 4 DTPA81. // Posicionamos el Cursor del LCD en la posición // 10 línea 1. // Visualiza sobre la pantalla LCD la temperatura. sensor=5; dato_recibido = Lectura_DTPA81(sensor); lcd_gotoxy(13,1); printf(lcd_putc,"%1u",dato_recibido); // Leemos el dato a través del bus I2c del // sensor 5 DTPA81. // Posicionamos el Cursor del LCD en la // posición 13 línea 1. // Visualiza sobre la pantalla LCD la temperatura. sensor=6; dato_recibido = Lectura_DTPA81(sensor); lcd_gotoxy(4,2); printf(lcd_putc,"%1u",dato_recibido); // Leemos el dato a través del bus I2c del //sensor 6 DTPA81. // Posicionamos el Cursor del LCD en la // posición 4 línea 2. // Visualiza sobre la pantalla LCD la temperatura. sensor=7; dato_recibido = Lectura_DTPA81(sensor); lcd_gotoxy(7,2); printf(lcd_putc,"%1u",dato_recibido); // Leemos el dato a través del bus I2c del // sensor 7 DTPA81. // Posicionamos el Cursor del LCD en la // posición 7 línea 2. // Visualiza sobre la pantalla LCD la temperatura. sensor=8; dato_recibido = Lectura_DTPA81(sensor); lcd_gotoxy(10,2); printf(lcd_putc,"%1u",dato_recibido); // Leemos el dato a través del bus I2c del // sensor 8 DTPA81. // Posicionamos el Cursor del LCD en la // posición 10 línea 2. // Visualiza sobre la pantalla LCD la temperatura. sensor=9; dato_recibido = Lectura_DTPA81(sensor); lcd_gotoxy(13,2); printf(lcd_putc,"%1u",dato_recibido); // Leemos el dato a través del bus I2c del //sensor 9 DTPA81. // Posicionamos el Cursor del LCD en la // posición 13 línea 2. // Visualiza sobre la pantalla LCD la temperatura. delay_ms(100); /* *************************************** Función de int8 Lectura_SRF08() ************************************************** */ int8 Lectura_DTPA81(int8 sensor) int8 temperatura=0; i2c_start(); i2c_write(dtpa81); i2c_write(sensor); i2c_stop(); // Secuencia de inicio // Dirección I2C del dispositivo modo escritura // Envia dirección interna del dispositivo, nos posicinamos // en el registro. // Envía secuencia de stop Microcontroladores IES Joan Miró Página 175

176 Curso de Robótica y otras aplicaciones en el Aula de Tecnología i2c_start(); i2c_write(dtpa81 0b ); temperatura=i2c_read(0); i2c_stop(); // Envía secuencia de inicio // Envía dirección I2C del dispositivo en modo lectura // Si, lee último byte, envía NACK y almacena en el buffer //Secuencia de stop return(temperatura); Temperatura Mayor.c // Programa...: Temperatura Mayor.c // // Plataforma hw: Placa Monibot 16F877A // // Fecha...: Octubre-2010 // // Programador..: Pedro Alonso // // Descripción..: Detectar la temperatura mayor del sensor D-TPA81 // // ****************************** Directivas de Preprocesado ***************************************** #include <16F877A.h> #fuses XT,NOWDT,PUT,NOWRT #use delay(clock= ) #use i2c(master, force_hw, slow, sda=pin_c4, scl=pin_c3) #include <flex_lcd.c> #define Numero_Maximo 8 // Configuración de I2C // Definimos el PIC como maestro // Forzamos a trabajar con su hardware // interno.(asociado a I2C) // Trabajamos a velocidad baja 100 Kbps // Elegimos sda=pin_c4 como patilla de datos. // Elegimos scl=pin_c3 como patilla de reloj. // Incluimos el driver flex_lcd.c que contiene las // funciones de control del LCD. // Número pixel-1 byte CONST Direccion_Pixel[9] = 0x90,0x92,0x94,0x96,0x98,0x9A,0x9C,0x9E,0xA0; // Ta, Pixel1,Pixel2,Pixel3,Pixel4,Pixel5,Pixel6,Pixel7,Pixel8 // Tabla de 9 datos. /* ******************************************** Declaración de funciones ******************************************************* */ int8 Lectura_DTPA81(int8); // Declaramos la función Lectura_DTPA81 // (Introducimos una variable tipo entero de 8 bit y // nos devuelve una variable tipo entero de 8 bit) /* ************************* Función principal o programa principal ****************************** */ void main() int8 sensor; int8 n; int8 temperatura_ambiente=0; int8 temperatura_mayor=0; int8 temperatura_real=0; int8 temperatura; int8 sensor_mayor; lcd_init(); // Inicializamos el LCD. lcd_gotoxy(1,1); // Posicionamos el Cursor del LCD en la posición 1 línea 1. printf(lcd_putc,"sensor= "); // Visualiza sobre la pantalla LCD el mensaje "Sensor= ". lcd_gotoxy(1,2); // Posicionamos el Cursor del LCD en la posición 1 línea 2. printf(lcd_putc,"tmax= C "); // Visualiza sobre la pantalla LCD el mensaje "Tmax= C ". while (1) // Bucle infinito de espera sensor = Direccion_Pixel[0]; // Sacamos la dirección del sensor TªAMBIENTE de la tabla // Direccion_Pixel[0] Microcontroladores IES Joan Miró Página 176

177 Curso de Robótica y otras aplicaciones en el Aula de Tecnología temperatura_ambiente= Lectura_TC74(sensor); sensor = Direccion_Pixel[1]; temperatura_mayor= Lectura_TC74(sensor); sensor_mayor=1; for (n=2; n<=numero_maximo; n++) sensor = Direccion_Pixel[n]; temperatura= Lectura_TC74(sensor); if(temperatura>temperatura_mayor) temperatura_mayor=temperatura; sensor_mayor=n; // Leemos la temperatura ambiente a // través del bus I2c del esclavo // TªAMBIENTE. // Sacamos la dirección del sensor // PIXEL1 de la tabla Direccion_Pixel[1] // Leemos la temperatura del sensor // PIXEL1 a través del bus I2c. // Asignamos a sensor_mayor=1; // Se ejecuta un bucle desde n=2 hasta // n<=numero_maximo en orden // ASCENDENTE de uno en uno // Sacamos la dirección del sensor de la // tabla Direccion_Pixel[n] // Leemos la temperatura del sensor a // través del bus I2c. // Detectamos la temperatura mayor. // Guardamos la temperatura mayor. // Guardamos el sensor que tiene la // temperatura mayor. temperatura_real = temperatura_mayor-temperatura_ambiente; // Obtenemos la temperatura // real del punto caliente lcd_gotoxy(9,1); // Posicionamos el Cursor del LCD en la // posición 9 línea 1. printf(lcd_putc,"%1u",sensor_mayor); // Visualiza sobre la pantalla LCD la // variables sensor_mayor. lcd_gotoxy(6,2); // Posicionamos el Cursor del LCD en la // posición 6 línea 2. printf(lcd_putc,"%3u",temperatura_mayor); // Visualiza sobre la pantalla LCD la // variables temperatura_mayor. delay_ms(40); /* *********************************** Función de int8 Lectura_SRF08() ****************************************************** */ int8 Lectura_TC74(int8 sensor) int8 temperatura=0; i2c_start(); i2c_write(sensor); i2c_write(0x00); i2c_start(); i2c_write(sensor 0b ); temperatura=i2c_read(0); i2c_stop(); // Secuencia de inicio // Dirección I2C del dispositivo modo escritura // Envia dirección interna del dispositivo, nos posicinamos // en el registro. // Envía secuencia de inicio // Envía dirección I2C del dispositivo en modo lectura // Si, lee último byte, envía NACK y almacena en el buffer // Secuencia de stop return(temperatura); Temperatura Mayor_con driver.c // Programa...: Temperatura Mayor_con driver.c // // Plataforma hw: Placa Monibot 16F877A // // Fecha...: Octubre-2010 // // Programador..: Pedro Alonso // // Descripción..: Detectar la temperatura mayor del sensor D-TPA81 // // ****************************** Directivas de Preprocesado ***************************************** #include <16F877A.h> Microcontroladores IES Joan Miró Página 177

178 Curso de Robótica y otras aplicaciones en el Aula de Tecnología #fuses XT,NOWDT,PUT,NOWRT #use delay(clock= ) #use i2c(master, force_hw, slow, sda=pin_c4, scl=pin_c3) // Configuración de I2C // Definimos el PIC como maestro // Forzamos a trabajar con su hardware // interno.(asociado a I2C) // Trabajamos a velocidad baja 100 Kbps // Elegimos sda=pin_c4 como patilla de datos. // Elegimos scl=pin_c3 como patilla de reloj. #include <flex_lcd.c> // Incluimos el driver flex_lcd.c que contiene las // funciones de control del LCD. // #include <driver_tc74_9_sensores.c> // Incluimos el driver TC74_9_sensores.c que // contiene las funciones de control del TC74. #include <driver_d-tpa81.c> // Incluimos el driver D-TPA81.c que contiene las // funciones de control del D-TPA81. #define Numero_Maximo 8 // Número pixel. /* ************************** Función principal o programa principal ***************************** */ void main() int8 sensor; int8 n; int8 temperatura_ambiente=0; int8 temperatura_mayor=0; int8 temperatura_real=0; int8 temperatura; int8 sensor_mayor; lcd_init(); // Inicializamos el LCD. lcd_gotoxy(1,1); // Posicionamos el Cursor del LCD en la posición 1 línea 1. printf(lcd_putc,"sensor= "); // Visualiza sobre la pantalla LCD el mensaje "Sensor= ". lcd_gotoxy(1,2); // Posicionamos el Cursor del LCD en la posición 1 línea 2. printf(lcd_putc,"tmax= C "); // Visualiza sobre la pantalla LCD el mensaje "Tmax= C ". while (1) // Bucle infinito de espera sensor = 0; // Seleccionamos el sensor 0 (TªAMBIENTE). temperatura_ambiente= Lectura_DTPA81(sensor); // Leemos la temperatura ambiente a // través del bus I2c del esclavo // TªAMBIENTE. sensor = 1; // Seleccionamos el sensor PIXEL1. temperatura_mayor= Lectura_DTPA81(sensor); // Leemos la temperatura del sensor // PIXEL1 a través del bus I2c. sensor_mayor=1; // Asignamos a sensor_mayor=1; for (n=2; n<=numero_maximo; n++) temperatura= Lectura_DTPA81(n); if(temperatura>temperatura_mayor) temperatura_mayor=temperatura; sensor_mayor=n; // Se ejecuta un bucle desde n=2 hasta // n<=numero_maximo en orden // ASCENDENTE de uno en uno // Leemos la temperatura del sensor a // través del bus I2c. // Detectamos la temperatura mayor. // Guardamos la temperatura mayor. // Guardamos el sensor que tiene la // temperatura mayor. temperatura_real = temperatura_mayor-temperatura_ambiente; // Obtenemos la temperatura // real del punto caliente lcd_gotoxy(9,1); // Posicionamos el Cursor del LCD en la // posición 9 línea 1. printf(lcd_putc,"%1u",sensor_mayor); // Visualiza sobre la pantalla LCD la // variables sensor_mayor. lcd_gotoxy(6,2); // Posicionamos el Cursor del LCD en // la posición 6 línea 2. printf(lcd_putc,"%3u",temperatura_mayor); // Visualiza sobre la pantalla LCD la // variables temperatura_mayor. delay_ms(100); Microcontroladores IES Joan Miró Página 178

179 Curso de Robótica y otras aplicaciones en el Aula de Tecnología driver_d-tpa81.c // ***************************** Driver de Control del sensor DTPA81 ******************************* #define DTPA81 0xD0 //Dirección I2C del D-TPA81 /* *********************************************** Declaración de funciones **************************************************** */ int8 Lectura_DTPA81(int8); // Declaramos la función Lectura_DTPA81 // (Introducimos una variable tipo entero de 8 bit y nos devuelve // una variable tipo entero de 8 bit) /* *************************************** Función de int8 Lectura_SRF08() ************************************************** */ int8 Lectura_DTPA81(int8 sensor) int8 temperatura=0; i2c_start(); i2c_write(dtpa81); i2c_write(sensor+1); i2c_start(); i2c_write(dtpa81 0b ); temperatura=i2c_read(0); i2c_stop(); // Secuencia de inicio // Dirección I2C del dispositivo modo escritura // Envia dirección interna del dispositivo, nos posicinamos en // el registro. // Envía secuencia de inicio // Envía dirección I2C del dispositivo en modo lectura // Si, lee último byte, envía NACK y almacena en el buffer // Secuencia de stop return(temperatura); driver_tc74_9_sensores.c // ****************************** Driver de Control de 9 sensor TC74 ******************************** // Debemos abrir el menu contestual de cada sensor y asignarle una dirección en el apartado DEVADDR=$92, // asignamos la dirección 92. // Cuando copiamos el hardware en otra carpeta debemos asegurarnos que tiene la dirección asignada. byte CONST Direccion_Pixel[9] = 0x90,0x92,0x94,0x96,0xA2,0x9A,0x9C,0x9E,0xA0; // Ta, Pixel1, Pixel2,Pixel3,Pixel4,Pixel5,Pixel6,Pixel7,Pixel8 // Tabla de 9 datos. /* ********************************************** Declaración de funciones ***************************************************** */ int8 Lectura_DTPA81(int8); // Declaramos la función Lectura_DTPA81 // (Introducimos una variable tipo entero de 8 bit y nos devuelve una variable // tipo entero de 8 bit) /* *************************************** Función de int8 Lectura_SRF08() ************************************************** */ int8 Lectura_DTPA81(int8 sensor) int8 temperatura=0; sensor = Direccion_Pixel[sensor]; i2c_start(); i2c_write(sensor); i2c_write(0x00); i2c_start(); i2c_write(sensor 0b ); temperatura=i2c_read(0); i2c_stop(); // Sacamos la dirección del sensor de la table // Direccion_Pixel[n] // Secuencia de inicio // Dirección I2C del dispositivo modo escritura // Envia dirección interna del dispositivo, nos posicinamos // en el registro. // Envía secuencia de inicio // Envía dirección I2C del dispositivo en modo lectura // Si, lee último byte, envía NACK y almacena en el buffer // Secuencia de stop return(temperatura); Microcontroladores IES Joan Miró Página 179

180 Curso de Robótica y otras aplicaciones en el Aula de Tecnología Seguimiento de un punto caliente.c // Programa...: Seguimiento de un punto caliente.c // // Plataforma hw: Placa Monibot 16F877A // // Fecha...: Octubre-2010 // // Programador..: Pedro Alonso // // Descripción..: El sensor D-TPA81 está montado sobre un servo de posición // // y sigue a un punto caliente. // // ****************************** Directivas de Preprocesado ***************************************** #include <16F877A.h> #fuses XT,NOWDT,PUT,NOWRT #use delay(clock= ) #use i2c(master, force_hw, slow, sda=pin_c4, scl=pin_c3) #include <Servo_Futaba_10bit.c> #include <flex_lcd.c> // Configuración de I2C // Definimos el PIC como maestro // Forzamos a trabajar con su hardware // interno.(asociado a I2C) // Trabajamos a velocidad baja 100 Kbps // Elegimos sda=pin_c4 como patilla de datos. // Elegimos scl=pin_c3 como patilla de reloj. // Incluimos el driver que contiene las funciones // de control de los Servos de Futaba. // Incluimos el driver flex_lcd.c que contiene las //funciones de control del LCD. // #include <driver_tc74_9_sensores.c> // Incluimos el driver TC74_9_sensores.c que // contiene las funciones de control del TC74. #include <driver_d-tpa81.c> // Incluimos el driver D-TPA81.c que contiene las // funciones de control del D-TPA81. #BIT TR0 = 0x87.0 #BIT TR1 = 0x87.1 #BIT TR5 = 0x87.5 #define Numero_Maximo 8 // Número pixel. /* **************************** Función principal o programa principal *************************** */ void main() int8 sensor; int8 n; int8 temperatura_ambiente=0; int8 temperatura_mayor=0; int8 temperatura_real=0; int8 temperatura; int8 sensor_mayor; int8 posicion=56; lcd_init(); Inicializacion_Futaba_RC2(); // Inicializamos el LCD. // Inicialización del Servo en MANGUERA1. TR0=0; TR1=0; TR5=0; lcd_gotoxy(1,1); // Posicionamos el Cursor del LCD en la posición 1 línea 1. printf(lcd_putc,"sensor= "); // Visualiza sobre la pantalla LCD el mensaje "Sensor= ". lcd_gotoxy(1,2); // Posicionamos el Cursor del LCD en la posición 1 línea 2. printf(lcd_putc,"tmax= C "); // Visualiza sobre la pantalla LCD el mensaje "Tmax= C ". Microcontroladores IES Joan Miró Página 180

181 Curso de Robótica y otras aplicaciones en el Aula de Tecnología while (1) // Bucle infinito de espera sensor = 0; // Seleccionamos el sensor 0 // (TªAMBIENTE). temperatura_ambiente= Lectura_DTPA81(sensor); // Leemos la temperatura ambiente a // través del bus I2c del esclavo // TªAMBIENTE. sensor = 1; temperatura_mayor= Lectura_DTPA81(sensor); sensor_mayor=1; for (n=2; n<=numero_maximo; n++) temperatura= Lectura_DTPA81(n); if(temperatura>temperatura_mayor) temperatura_mayor=temperatura; sensor_mayor=n; // Seleccionamos el sensor PIXEL1. // Leemos la temperatura del sensor // PIXEL1 a través del bus I2c. // Asignamos a sensor_mayor=1; // Se ejecuta un bucle desde n=2 hasta // n<=numero_maximo en orden // ASCENDENTE de uno en uno // Leemos la temperatura del sensor a // través del bus I2c. // Detectamos la temperatura mayor. // Guardamos la temperatura mayor. // Guardamos el sensor que tiene la // temperatura mayor. temperatura_real = temperatura_mayor-temperatura_ambiente; // Obtenemos la temperatura // real del punto caliente lcd_gotoxy(9,1); printf(lcd_putc,"%1u",sensor_mayor); // Posicionamos el Cursor del LCD en la // posición 9 línea 1. // Visualiza sobre la pantalla LCD la // variables sensor_mayor. if(temperatura_mayor>45) if(sensor_mayor>4) posicion++; if(posicion>68) posicion=68; if(sensor_mayor<4) posicion--; if(posicion<47) posicion=47; Futaba_RC2(posicion); lcd_gotoxy(6,2); printf(lcd_putc,"%3u",temperatura_mayor); // Posicionamos el Cursor del LCD en la // posición 6 línea 2. // Visualiza sobre la pantalla LCD la // variables temperatura_mayor. delay_ms(50); Microcontroladores IES Joan Miró Página 181

182 Curso de Robótica y otras aplicaciones en el Aula de Tecnología Potenciómetro Digital MCP Es un circuito electrónico que toma diferentes valores de resistencia en función de un código digital. Características: 256 valores diferentes. Los valores del potenciómetro de 10 KΩ, 50 KΩ y 10 KΩ. SPI interfaz en serie (modo 0,0 y 1,1) Trabaja con tensiones de 2,7 a 5,5V. Utilizaremos el entrenador Simulación del MCP41010.DSN contenido en la carpeta de Sensores y Hardware\ MCP Microcontroladores IES Joan Miró Página 182

183 Curso de Robótica y otras aplicaciones en el Aula de Tecnología CG_Ampl_No_Inversor.c // Programa...: CG_Ampl_No_Inversor.c // // Plataforma hw: Placa Monibot 16F877A // // Fecha...: Mayo-2011 // // Programador..: Pedro Alonso // // Descripción..: Potenciometro Digital MCP41010 con protocolo SPI // // Control de ganancia de un amplificador no inversor // // ********************************** Directivas de Preprocesado ************************************* #include <16F877A.h> #FUSES XT,NOWDT #use delay(clock= ) #include <flex_lcd.c> // Incluimos el driver flex_lcd.c que contiene las funciones de control del LCD. #BYTE TRISA = 0x85 #BYTE porta = 0x05 #BIT TC6 = 0x87.6 #BIT TC5 = 0x87.5 #BIT TC3 = 0x87.3 #BIT cs = 0x07.6 //**************************************** Programa Principal *************************************** void main() float dato=0; float dato_anterior=0; float ganancia=0; setup_spi( spi_master spi_l_to_h spi_clk_div_16 ); TC6 =0; TC5 =0; TC3 =0; TRISA=0B ; lcd_init(); while(true) dato=porta; // Inicializamos el LCD. // Bucle infinito. if(dato!=dato_anterior) dato_anterior=dato; cs=0; spi_write(0x0); cs=1; cs=0; spi_write(0x11); spi_write(portd); delay_us(120); cs=1; ganancia=((dato*10)/256)+1; lcd_gotoxy(1,1); printf(lcd_putc,"porta=%3u",porta); // 0x11 // Posicionamos el Cursor del LCD en la //posición 1 línea 1. // Escribimos 3 dígitos de la variable // "PORTA" en formato entero y sin // signo. Microcontroladores IES Joan Miró Página 183

184 Curso de Robótica y otras aplicaciones en el Aula de Tecnología lcd_gotoxy(1,2); printf(lcd_putc,"ganancia=%5.2f",ganancia); // Posicionamos el Cursor del LCD en la // posición 1 línea 2. // Escribimos 5 dígitos de la variable // "ganancia" en formato float, con // 2 decimales Control de múltiples servomotores de posición SD20. El SD20 es un microcontrolador PIC16F872 corriendo a 8 Mhz, capaz de controlar y mover hasta 20 servo motores. Las ordenes de control entre el procesador principal y el sd20 se realiza mediante un bus I2C, consiguiendose una comunicación de alta velocidad que permite controlar los servos de una forma muy precisa. Todos los canales permanecen inicialmente inactivos, hasta que se envía la primera orden de posicionamiento. Puede funcionar en modo estándar con pulsos de 1 a 2 ms, o bien en modo expandido ampliando la anchura de los impulsos de control fuera de estos limites. Todas las ordenes, así como las posición de los servos se almacenan en registros que pueden leerse o escribirse fácilmente desde cualquier microcontrolador. El circuito resulta muy útil como coprocesador en robots con una gran numero de servos, pues libera al procesador principal de gran parte del trabajo, pudiendose dedicar a otras tareas Control_SD20.c // Programa...: Control_SD20.c // // Plataforma hw: Placa monibot 16F877A // // Fecha...: Octubre-2010 // // Programador..: Pedro Alonso // // Descripción..: Control del Servo 1 con SD20 // // ********************************** Directivas de Preprocesado ************************************* #include <16F877A.h> #fuses XT,NOWDT,PUT,NOWRT #use delay(clock= ) #use i2c(master, force_hw, slow, sda=pin_c4, scl=pin_c3) // Configuración de I2C // Definimos el PIC como maestro Microcontroladores IES Joan Miró Página 184

185 Curso de Robótica y otras aplicaciones en el Aula de Tecnología // Forzamos a trabajar con su hardware // interno.(asociado a I2C) // Trabajamos a velocidad baja 100 Kbps // Elegimos sda=pin_c4 como patilla de datos. // Elegimos scl=pin_c3 como patilla de reloj. /* ****************************** Función principal o programa principal ************************* */ void main() // Fijamos el rango de trabajo de los servor desde THmin= 0,480 ms hasta THmax= 2,520 ms. // THmin = Reg22,Reg uS // THmax =(256x255)/Reg21 +(Reg22,Reg23+20)= // THmin = Reg22,Reg us = 460uS + 20uS = 480 us ( 460d --> 1CCH ) // THmax =(256x255)/32 +(460+20)= 2520 us i2c_start(); i2c_write(0xc2); i2c_write(21); i2c_write(32); i2c_stop(); // Inicializa la transmisión // Seleccionamos el SD20 // Registro de configuración extandar o control modo expandido. // Finalización de la transmisión. i2c_start(); // Inicializa la transmisión i2c_write(0xc2); // Seleccionamos el SD20 i2c_write(22); // Dirección 22H del SD20 Modo expansor de offset (Parte Alta) i2c_write(0x1); // 460D -->01CCH (Se introduce la parte alta 01H) i2c_stop(); // Finalización de la transmisión. i2c_start(); i2c_write(0xc2); i2c_write(23); i2c_write(0xcc); i2c_stop(); // Inicializa la transmisión // Seleccionamos el SD20 // Dirección 23H del SD20 Modo expansor de offset (Parte Baja) // 460D -->01CCH (Se introduce la parte baja CCH) // Finalización de la transmisión. while (1) i2c_start(); i2c_write(0xc2); i2c_write(1); i2c_write(240); i2c_stop(); // Bucle infinito // Inicializa la transmisión // Seleccionamos el SD20 // Seleccionamos el Servo1 // Posicionamos el Servo en el extremo A // Finalización de la transmisión. delay_ms(1000); // Retardamos 1 segundos i2c_start(); i2c_write(0xc2); i2c_write(1); i2c_write(10); i2c_stop(); // Inicializa la transmisión // Seleccionamos el SD20 // Seleccionamos el Servo1 // Posicionamos el Servo en el extremo B // Finalización de la transmisión. delay_ms(1000); // Retardamos 1 segundos Control_Servos_Funciones_SD20.c // Programa...: Control_Servos_Funciones_SD20.c // // Plataforma hw: Placa Monibot 16F877A // // Fecha...: Octubre-2010 // // Programador..: Pedro Alonso // // Descripción..: Control de los servos del SD20 con funciones. // /* ************************************* Control del SD20 ********************************************* */ #include <16F877A.h> #fuses XT,NOWDT,PUT,NOWRT #use delay(clock= ) #use i2c(master, force_hw, slow, sda=pin_c4, scl=pin_c3) // Configuración de I2C // Definimos el PIC como maestro Microcontroladores IES Joan Miró Página 185

186 Curso de Robótica y otras aplicaciones en el Aula de Tecnología // Forzamos a trabajar con su hardware // interno.(asociado a I2C) // Trabajamos a velocidad baja 100 Kbps // Elegimos sda=pin_c4 como patilla de datos. // Elegimos scl=pin_c3 como patilla de reloj. /* ************************************************ Declaración de funcionesa ***************************************************/ void Sd20_ini (void); void Sd20(int8,int8); /* *************************** Función principal o programa principal **************************** */ void main() Sd20_ini(); While(1) Sd20(1,100); // Posicionamos el Servo1 del SD20 en 100. delay_ms(100); Sd20(1,50); // Posicionamos el Servo1 del SD20 en 50. delay_ms(100); Sd20(2,100); // Posicionamos el Servo2 del SD20 en 100. delay_ms(100); Sd20(2,50); / / Posicionamos el Servo2 del SD20 en 50. delay_ms(100); /* *********************************************** Función Sd20_ini ************************************************************** */ void Sd20_ini (void) // Fijamos el rango de trabajo de los servor desde THmin= 0,480 ms hasta THmax= 2,520 ms. // THmin = Reg22,Reg uS // THmax =(256x255)/Reg21 +(Reg22,Reg23+20)= // THmin = Reg22,Reg us = 460uS + 20uS = 480 us ( 460d --> 1CCH ) // THmax =(256x255)/32 +(460+20)= 2520 us i2c_start(); i2c_write(0xc2); i2c_write(21); i2c_write(32); i2c_stop(); // Inicializa la transmisión // Seleccionamos el SD20 // Registro de configuración extandar o control modo expandido. // Finalización de la transmisión. i2c_start(); // Inicializa la transmisión i2c_write(0xc2); // Seleccionamos el SD20 i2c_write(22); // Dirección 22H del SD20 Modo expansor de offset(parte Alta) i2c_write(0x1); // 460D -->01CCH (Se introduce la parte alta 01H) i2c_stop(); // Finalización de la transmisión. i2c_start(); i2c_write(0xc2); i2c_write(23); i2c_write(0xcc); i2c_stop(); // Inicializa la transmisión // Seleccionamos el SD20 // Dirección 23H del SD20 Modo expansor de offset(parte Baja) // 460D -->01CCH (Se introduce la parte baja CCH) // Finalización de la transmisión. /* ********************************************** Función Sd20(int8,int8) ******************************************************* */ void Sd20(int8 servo, int8 posicion) i2c_start(); i2c_write(0xc2); i2c_write(servo); i2c_write(posicion); i2c_stop(); // Inicializa la transmisión // Seleccionamos el SD20 // Seleccionamos el Servo1 // Posicionamos el Servo en el extremo A // Finalización de la transmisión. Microcontroladores IES Joan Miró Página 186

187 Curso de Robótica y otras aplicaciones en el Aula de Tecnología A-D_SD20.c // Programa...: A-D_SD20.c // // Plataforma hw: Placa monibot 16F877A // // Fecha...: Octubre-2010 // // Programador..: Pedro Alonso // // Descripción..: Control de un servo del SD20 con un potenciómetro // // ********************************** Directivas de Preprocesado ************************************* #include <16F876A.h> #device adc=8 #fuses XT,NOWDT,PUT,NOWRT #use delay(clock= ) // Conversor Analógico Digital de 10 bit el PIC 16F876A // puede trabajar con 8 o 10 bit de resolucion #use i2c(master, force_hw, slow, sda=pin_c4, scl=pin_c3) // Configuración de I2C // Definimos el PIC como maestro // Forzamos a trabajar con su hardware // interno.(asociado a I2C) // Trabajamos a velocidad baja 100 Kbps // Elegimos sda=pin_c4 como patilla de datos. // Elegimos scl=pin_c3 como patilla de reloj. /* ******************************************* Declaración de funciones *********************************************************/ void Sd20_ini (void); void Sd20(int8,int8); /* **************************** Función principal o programa principal *************************** */ void main() int8 q=0; Sd20_ini(); setup_adc_ports(0); setup_adc(adc_clock_internal); set_adc_channel(3); // Fijamos los niveles máximos y minimos de TH // Seleccionamos el Puerto A como entradas Analógicas. // Mirar ADCON1 // Fuente de reloj RC interno. // Habilitación canal 3 "AN3" While(1) q = read_adc(); // Lectura canal 0 "AN3" Sd20(1,q); // Posicionamos el Servo3 del SD20 en función de q. delay_ms(5); // Retardo de 5 ms. /* *************************************************** Función Sd20_ini ********************************************************** */ void Sd20_ini (void) // Fijamos el rango de trabajo de los servor desde THmin= 0,480 ms hasta THmax= 2,520 ms. // THmin = Reg22,Reg uS // THmax =(256x255)/Reg21 +(Reg22,Reg23+20)= // THmin = Reg22,Reg us = 460uS + 20uS = 480 us ( 460d --> 1CCH ) // THmax =(256x255)/32 +(460+20)= 2520 us i2c_start(); i2c_write(0xc2); i2c_write(21); i2c_write(32); i2c_stop(); // Inicializa la transmisión // Seleccionamos el SD20 // Registro de configuración extandar o control modo expandido. // Finalización de la transmisión. Microcontroladores IES Joan Miró Página 187

188 Curso de Robótica y otras aplicaciones en el Aula de Tecnología i2c_start(); // Inicializa la transmisión i2c_write(0xc2); // Seleccionamos el SD20 i2c_write(22); // Dirección 22H del SD20 Modo expansor de offset(parte Alta) i2c_write(0x1); // 460D -->01CCH (Se introduce la parte alta 01H) i2c_stop(); // Finalización de la transmisión. i2c_start(); i2c_write(0xc2); i2c_write(23); i2c_write(0xcc); i2c_stop(); // Inicializa la transmisión // Seleccionamos el SD20 // Dirección 23H del SD20 Modo expansor de offset(parte Baja) // 460D -->01CCH (Se introduce la parte baja CCH) // Finalización de la transmisión. /* ************************************************** Función Sd20(int8,int8) *************************************************** */ void Sd20(int8 servo, int8 posicion) i2c_start(); i2c_write(0xc2); i2c_write(servo); i2c_write(posicion); i2c_stop(); // Inicializa la transmisión // Seleccionamos el SD20 // Seleccionamos el Servo1 // Posicionamos el Servo en el extremo A // Finalización de la transmisión Puentes en H. Un Puente H o Puente en H es un circuito electrónico que permite a un motor eléctrico DC girar en ambos sentidos, avance y retroceso. Son ampliamente usados en robótica y como convertidores de potencia. Los puentes H están disponibles como circuitos integrados, pero también pueden construirse a partir de componentes discretos. Estructura de un puente H (marcado en rojo). Los 2 estados básicos del circuito. El término "puente H" proviene de la típica representación gráfica del circuito. Un puente H se construye con 4 interruptores (mecánicos o mediante transistores). Cuando los interruptores S1 y S4 (ver primera figura) están cerrados (y S2 y S3 abiertos) se aplica una tensión positiva en el motor, haciéndolo girar en un sentido. Abriendo los interruptores S1 y S4 (y cerrando S2 y S3), el voltaje se invierte, permitiendo el giro en sentido inverso del motor. Con la nomenclatura que estamos usando, los interruptores S1 y S2 nunca podrán estar cerrados al mismo tiempo, porque esto cortocircuitaría la fuente de tensión. Lo mismo Aplicaciones: Como hemos dicho el puente H se usa para invertir el giro de un motor, pero también puede usarse para frenarlo (de manera brusca), al hacer un corto entre las bornas del motor, o incluso puede usarse para permitir que el motor frene bajo su propia inercia, cuando desconectamos el motor de la fuente que lo alimenta. En el siguiente cuadro se resumen las diferentes acciones. S1 S2 S3 S4 Resultado El motor gira en avance El motor gira en retroceso El motor se detiene bajo su inercia El motor frena (fast-stop) Microcontroladores IES Joan Miró Página 188

Programación y diseño de dispositivos mediante microcontroladores PIC

Programación y diseño de dispositivos mediante microcontroladores PIC Metodología de Programación, Programación en C, Aplicaciones electrónicas 1 / 7 Programación y diseño de dispositivos mediante microcontroladores PIC Hemos elegido el microcontrolador PIC16F84 por las

Más detalles

Usando los Codificadores Cuadráticos

Usando los Codificadores Cuadráticos Usando los Codificadores Cuadráticos Autor: Ing. Carlos Narváez Universidad de Oriente email: cnarvaez@udo.edu.ve Introducción El presente trabajo es una introducción a los denominados codificadores cuadráticos,

Más detalles

Memoria La memoria es la parte del ordenador en la que se guardan o almacenan los programas (las instrucciones y los datos).

Memoria La memoria es la parte del ordenador en la que se guardan o almacenan los programas (las instrucciones y los datos). Memoria La memoria es la parte del ordenador en la que se guardan o almacenan los programas (las instrucciones y los datos). Memoria Típica. Los datos almacenados en memoria tienen que pasar, en un momento

Más detalles

PROCESO DE SIMULACIÓN EN PROTEUS

PROCESO DE SIMULACIÓN EN PROTEUS USB PROCESO DE SIMULACIÓN EN PROTEUS Departamento de Electrónica Fundación San Valero Microchip PIC18F4550 1 Microchip Firmware PIC18F4550 La velocidad de transferencia a ido aumentando rápidamente a lo

Más detalles

I NTRODUCCIÓN 1. ORDENADOR E INFORMÁTICA

I NTRODUCCIÓN 1. ORDENADOR E INFORMÁTICA I. INTRODUCCIÓN 1. ORDENADOR E INFORMÁTICA 1.1. Informática Informática (Información Automática) es la ciencia y la técnica del tratamiento automatizado de la información mediante el uso de ordenadores.

Más detalles

Se encarga de realizar las funciones básicas de manejo y configuración del ordenador. La BIOS tiene más tareas fundamentales: Chequearse a sí misma.

Se encarga de realizar las funciones básicas de manejo y configuración del ordenador. La BIOS tiene más tareas fundamentales: Chequearse a sí misma. La BIOS, siglas de su nombre en inglés Basic Input-Output System, también conocida como Sistema Básico de Entrada / Salida, es básicamente un código de software que permite iniciar el sistema operativo

Más detalles

El módulo LCD Ejemplos de funcionamiento

El módulo LCD Ejemplos de funcionamiento SISTEMAS ELECTRÓNICOS Y AUTOMÁTICOS PRACTICAS DE MICROCONTROLADORES PIC PRÁCTICA 7: El módulo LCD El módulo LCD Ejemplos de funcionamiento - 1 - 1. Objetivos: - Conocer el funcionamiento y programación

Más detalles

... partes internas del computador!...

... partes internas del computador!... ... partes internas del computador!... LOS DISPOSITIVOS INTERNOS UNA PC EN SI, PUEDE "DAR SEÑALES DE VIDA" SIN EL TECLADO, SIN EL MONITOR, SIN EL RATÓN Y TODOS LOS DISPOSITIVOS EXTERNOS, AUNQUE NO TENDRÍA

Más detalles

Aprendiendo a programar Microcontroladores PIC en Lenguaje C con CCS

Aprendiendo a programar Microcontroladores PIC en Lenguaje C con CCS Aprendiendo a programar Microcontroladores PIC en Lenguaje C con CCS Por Andrés Raúl Bruno Saravia Entrega Nº 5. Cómo declaramos una variable en Lenguaje C? En C siempre se deben declarar las variables.

Más detalles

INSTRUMENTACIÓN AVANZADA Departamento de Ingeniería Eléctrica y Electromecánica Facultad de Ingeniería Universidad Nacional de Mar del Plata

INSTRUMENTACIÓN AVANZADA Departamento de Ingeniería Eléctrica y Electromecánica Facultad de Ingeniería Universidad Nacional de Mar del Plata Problema a resolver Ejercicio 2.1 Tomando el ejercicio 1.4 realizar los ajustes necesarios para que además de encenderse un LED en pantalla se encienda un LED físicamente sobre la placa PIC suministrada

Más detalles

BUS I2C. IES Los Viveros Sevilla Dpto. Electrónica. 1

BUS I2C. IES Los Viveros Sevilla Dpto. Electrónica. 1 BUS I2C Se trata de un protocolo serie desarrollado por Philips Semiconductors usado por muchos integrados para comunicarse entre ellos, para su funcionamiento requiere sólo dos líneas, una de reloj (SCL)

Más detalles

Ensamblador. Interrupciones. Dentro de una computadora existen dos clases de interrupciones:

Ensamblador. Interrupciones. Dentro de una computadora existen dos clases de interrupciones: Ensamblador Interrupciones Definición: Una interrupción es el rompimiento en la secuencia de un programa para ejecutar un programa especial llamando una rutina de servicio cuya característica principal

Más detalles

JUEGO DE CARRERA DE AUTOS EN LCD

JUEGO DE CARRERA DE AUTOS EN LCD JUEGO DE CARRERA DE AUTOS EN LCD Andrés Bastidas; Nathali Gordón; Verónica Grefa; Mónica Mejía; Juan Carlos Obregón Control con Microprocesadores, Nelson Sotomayor, MSc. 1 INTRODUCCIÓN El objetivo del

Más detalles

podemos enfocar al funcionamiento del robot, es decir la parte de electrónica. Para que el

podemos enfocar al funcionamiento del robot, es decir la parte de electrónica. Para que el CAPÍTULO 4 Funcionamiento del Robot Después de analizar paso a paso el diseño y funcionamiento de la interfase, nos podemos enfocar al funcionamiento del robot, es decir la parte de electrónica. Para que

Más detalles

GUIA GENERAL PARA LA PROGRAMACIÓN DEL SISTEMA PICCITO 16F88 INDICE

GUIA GENERAL PARA LA PROGRAMACIÓN DEL SISTEMA PICCITO 16F88 INDICE 1 GUIA GENERAL PARA LA PROGRAMACIÓN DEL SISTEMA PICCITO 16F88 INDICE 1. Información general sobre el programa Bootloader para el sistema PICCITO 16F88. Auto-programador (Self programming) a través del

Más detalles

ACTIVIDADES TEMA 1. EL LENGUAJE DE LOS ORDENADORES. 4º E.S.O- SOLUCIONES.

ACTIVIDADES TEMA 1. EL LENGUAJE DE LOS ORDENADORES. 4º E.S.O- SOLUCIONES. 1.- a) Explica qué es un bit de información. Qué es el lenguaje binario? Bit es la abreviatura de Binary digit. (Dígito binario). Un bit es un dígito del lenguaje binario que es el lenguaje universal usado

Más detalles

Arquitectura basica de un computador

Arquitectura basica de un computador Arquitectura basica de un computador Componentes o División básica de un computador Perifericos: Son todos los dispositivos de entrada (Input) y salida (Output): Monitor, Teclado, Ratón, Unidades de almacenamiento

Más detalles

Práctica 1. Introducción al SIEMENS 80C167

Práctica 1. Introducción al SIEMENS 80C167 Práctica 1 Introducción al SIEMENS 80C167 1 Objetivos Toma de contacto con los recursos de la tarjeta PHY80C167 basada en el microcontrolador SIEMENS 80C167 Familiarizarse con la herramienta de desarrollo

Más detalles

GUIA GENERAL PARA LA PROGRAMACIÓN DEL SISTEMA EB88 BOOTLOADER: TINY INDICE

GUIA GENERAL PARA LA PROGRAMACIÓN DEL SISTEMA EB88 BOOTLOADER: TINY INDICE 1 GUIA GENERAL PARA LA PROGRAMACIÓN DEL SISTEMA EB88 BOOTLOADER: TINY INDICE 1. Información general sobre el programa Bootloader para el sistema EB88. Auto-programador (Self programming) a través del puerto

Más detalles

BUS I2C: IMPLEMENTACIÓN PRÁCTICA CON MICROCONTROLADORES PIC MEMORIAS EEPROM SERIE

BUS I2C: IMPLEMENTACIÓN PRÁCTICA CON MICROCONTROLADORES PIC MEMORIAS EEPROM SERIE BUS I2C: IMPLEMENTACIÓN PRÁCTICA CON MICROCONTROLADORES PIC MEMORIAS EEPROM SERIE Fernando Nuño García 1 Ventajas del BUS I2C Definido inicialmente a mediados de los 80 para trabajar a 100kbit/s y en 1995

Más detalles

Tema 1 Introducción. Arquitectura básica y Sistemas Operativos. Fundamentos de Informática

Tema 1 Introducción. Arquitectura básica y Sistemas Operativos. Fundamentos de Informática Tema 1 Introducción. Arquitectura básica y Sistemas Operativos Fundamentos de Informática Índice Descripción de un ordenador Concepto básico de Sistema Operativo Codificación de la información 2 1 Descripción

Más detalles

PROTEUS Depuración de programas para microprocesadores

PROTEUS Depuración de programas para microprocesadores PROTEUS Depuración de programas para microprocesadores Introducción Como ya se ha indicado en temas anteriores, la aplicación PROTEUS, tiene entre sus utilidades la simulación de los esquemas realizados

Más detalles

HARDWARE DE SISTEMA AUTOMÁTICO DE RASTREO DE VEHÍCULOS MEDIANTE TECNOLOGÍAS GPRS Y GPS

HARDWARE DE SISTEMA AUTOMÁTICO DE RASTREO DE VEHÍCULOS MEDIANTE TECNOLOGÍAS GPRS Y GPS HARDWARE DE SISTEMA AUTOMÁTICO DE RASTREO DE VEHÍCULOS MEDIANTE TECNOLOGÍAS GPRS Y GPS Ing. Javier A. Garabello Facultad Regional Villa María UTN Av. Universidad 450 Tel: 0353-4537500 javiergarabello@hotmail.com

Más detalles

TRABAJO FINAL TECNICAS DIGITALES II

TRABAJO FINAL TECNICAS DIGITALES II Universidad Tecnológica Nacional Facultad Regional Córdoba TRABAJO FINAL TECNICAS DIGITALES II SISTEMA DE ADQUISICIÓN DE MUESTRAS DE TEMPERATURA AUTORES: TOUZ, FEDERICO ANDRES LEG: 43310 MONDINO,MAURO

Más detalles

COMUNICACIÓN I2C (INTER-INTEGRATED CIRCUIT)

COMUNICACIÓN I2C (INTER-INTEGRATED CIRCUIT) COMUNICACIÓN I2C (INTER-INTEGRATED CIRCUIT) Centro CFP/ES COMUNICACIÓN I2C 1 VENTAJAS DE LA COMUNICACIÓN I2C COMPARATIVA ESTANDAR DE TRANSMISIÓN 2 DISPOSITIVOS I2C DISPOSITIVOS I2C MAX518 3 DISPOSITIVOS

Más detalles

Especificaciones técnicas. Power, Inputs and Outputs. Operating Voltage Input Voltage (recommended) Input Voltage (limits) Analog Input Pins

Especificaciones técnicas. Power, Inputs and Outputs. Operating Voltage Input Voltage (recommended) Input Voltage (limits) Analog Input Pins Especificaciones técnicas Microcontroller Operating Voltage Input Voltage (recommended) Input Voltage (limits) Digital I/O Pins Analog Input Pins DC Current for I/O Pin DC Current for 3.3V Pin Flash Memory

Más detalles

UNIVERSIDAD DON BOSCO

UNIVERSIDAD DON BOSCO CICLO 02 2013 UNIVERSIDAD DON BOSCO FACULTAD DE ESTUDIOS TECNOLÓGICOS COORDINACIÓN DE ELECTRÓNICA GUÍA DE LABORATORIO Nº 03 ASIGNATURA: Control Digital NOMBRE DE LA PRACTICA: Configuración de los Puertos

Más detalles

LCD. Las pantallas de cristal líquido o módulos LCD, como. Módulo. con interface serial

LCD. Las pantallas de cristal líquido o módulos LCD, como. Módulo. con interface serial Módulo Módulo LCD con interface serial LCD con interface serial EDISON DUQUE C. Este módulo permite mostrar, en una pantalla de cristal líquido, los mensajes que son enviados desde una computadora o un

Más detalles

TEMA 20.0. EL BUS I 2 C (Inter Integrated Circuit Bus) I2C EN C

TEMA 20.0. EL BUS I 2 C (Inter Integrated Circuit Bus) I2C EN C TEMA 20.0 EL BUS I 2 C (Inter Integrated Circuit Bus) I2C EN C La comunicación n serie en los PIC 16F87X Los microcontroladores PIC de la familia 16F78x, tienen la posibilidad de comunicación serie, las

Más detalles

Tema 2 HARDWARE II. TICs 1º Bachillerato

Tema 2 HARDWARE II. TICs 1º Bachillerato Tema 2 HARDWARE II TICs 1º Bachillerato Hardware Es la parte 5sica del ordenador. Se refiere al conjunto de disposi=vos 5sicos que lo integran: CPU, monitor, teclado, ratón SoMware Es la parte lógica del

Más detalles

Manual Time One Software control de horarios

Manual Time One Software control de horarios Manual Time One Software control de horarios C/ Salva 63, 3º, 1ª 08004 Barcelona ( España ) Telf.: 93 329 34 35 Mail: info@bioclave.com Web: www.bioclave.com Índice 1 - Instalación.....3 2 - Guía inicio

Más detalles

Nombre del estudiante: Grimaldo velazquez Rafael. Herrera Díaz Jefree. Campus: san Rafael

Nombre del estudiante: Grimaldo velazquez Rafael. Herrera Díaz Jefree. Campus: san Rafael Nombre del estudiante: Grimaldo velazquez Rafael Herrera Díaz Jefree Campus: san Rafael Carrera /Prepa: ingeniería en sistemas computacionales Introducción. Como en mecánica la conmutación electrónica

Más detalles

PIC 16F87X. Juan González. Escuela Politécnica Superior Universidad Autónoma de Madrid. Flir Networked Systems. Flir Networked Systems

PIC 16F87X. Juan González. Escuela Politécnica Superior Universidad Autónoma de Madrid. Flir Networked Systems. Flir Networked Systems PIC 16F87X Juan González Andrés Prieto-Moreno Ricardo Gómez Escuela Politécnica Superior Universidad Autónoma de Madrid Flir Networked Systems Flir Networked Systems Curso de microcontroladores PIC. Semana

Más detalles

SOFTWARE CSU-485. Para conectar el dispositivo CSU-485 lo podemos hacer de dos maneras:

SOFTWARE CSU-485. Para conectar el dispositivo CSU-485 lo podemos hacer de dos maneras: SOFTWARE CSU-485 El Software CSU-485, es un software utilizado para configurar el dispositivo CSU-485, como la configuración del rango de la entrada analógica o el registro de datos. También es posible

Más detalles

Circuitos Digitales CON José Manuel Ruiz Gutiérrez

Circuitos Digitales CON José Manuel Ruiz Gutiérrez Circuitos Digitales CON José Manuel Ruiz Gutiérrez j.m.r.gutierrez@gmail.com PRÁCTICAS DE CIRCUITOS DIGITALES Circuitos digitales básicos 1. Simulación de operadores lógicos básicos. Realizar la simulación

Más detalles

HARDWARE DE UN ORDENADOR. Elementos básicos

HARDWARE DE UN ORDENADOR. Elementos básicos HARDWARE DE UN ORDENADOR Elementos básicos Componentes de un ordenador Hardware: todos los componentes físicos, tanto internos como externos: monitor, teclado, disco duro, memoria, etc. Software: todos

Más detalles

502 A I.S.C. JOSE BARDO MORENO MACHADO ENRIQUE EDUARDO MORAN PRADO EDILBERTO RASCON HERNANDEZ

502 A I.S.C. JOSE BARDO MORENO MACHADO ENRIQUE EDUARDO MORAN PRADO EDILBERTO RASCON HERNANDEZ 502 A I.S.C. JOSE BARDO MORENO MACHADO ENRIQUE EDUARDO MORAN PRADO EDILBERTO RASCON HERNANDEZ Dispositivo basado en circuitos que posibilitan el almacenamiento limitado de información y su posterior recuperación.

Más detalles

MANEJO DE DISPLAY LCD (Versión 1.1)

MANEJO DE DISPLAY LCD (Versión 1.1) MANEJO DE DISPLAY LCD (Versión 1.1) Prof: Bolaños D. Si bien mucas aplicaciones donde debemos mostrar información podemos resolverlas con display de 7 segmentos, estos presentas algunas limitaciones importantes,

Más detalles

GUIA GENERAL PARA LA PROGRAMACIÓN DEL SISTEMA EVOLUPIC Bootloader 16F88 BOOTLOADER: AN1310 DE MICROCHIP INDICE

GUIA GENERAL PARA LA PROGRAMACIÓN DEL SISTEMA EVOLUPIC Bootloader 16F88 BOOTLOADER: AN1310 DE MICROCHIP INDICE 1 GUIA GENERAL PARA LA PROGRAMACIÓN DEL SISTEMA EVOLUPIC Bootloader 16F88 BOOTLOADER: AN1310 DE MICROCHIP INDICE 1. Información general sobre el programa Bootloader para el sistema EVOLUPIC-16F88. Auto-programador

Más detalles

Detección de Presencia Serie para la Identificación de Módulos de Memoria

Detección de Presencia Serie para la Identificación de Módulos de Memoria Detección de Presencia Serie para la Identificación de Módulos de Memoria MSc. Guillermo Alvarez Bestard Tec. Miguel A. Machirán Simón Instituto de Cibernética Matemática y Física, AENTA Ministerio de

Más detalles

Quark Pro 2 Cargador de Microcontroladores PIC y Memorias EEPROM 24CXX

Quark Pro 2 Cargador de Microcontroladores PIC y Memorias EEPROM 24CXX Art Tapa - QuarkPro 2 19/2/04 2:09 PM Page 3 ARTÍCULO DE TAPA Quark Pro 2 Cargador de Microcontroladores PIC y Memorias EEPROM 24CXX Hemos desarrollado un prototipo económico, pero de alto desempeño para

Más detalles

Práctica 0. Emulador XENON de la computadora CESIUS

Práctica 0. Emulador XENON de la computadora CESIUS Práctica 0. Emulador XENON de la computadora CESIUS 1. Introducción El objeto de la presente práctica es permitir al alumno ensayar y familiarizarse con los conceptos de programación de computadoras digitales

Más detalles

Clase 20: Arquitectura Von Neuman

Clase 20: Arquitectura Von Neuman http://computacion.cs.cinvestav.mx/~efranco @efranco_escom efranco.docencia@gmail.com Estructuras de datos (Prof. Edgardo A. Franco) 1 Contenido Arquitectura de una computadora Elementos básicos de una

Más detalles

Componentes de la placa base

Componentes de la placa base 28/9/2015 Componentes de la placa base Inharú Quesada y Tatiana Rosales 2ºBach A 1. Componentes externos de la placa base Puerto Paralelo Un puerto es una interfaz que se halla integrada a la placa madre

Más detalles

CONTEXTO DE LA MEMORIA EN UN SISTEMA DE CÓMPUTO M E M O R I A S

CONTEXTO DE LA MEMORIA EN UN SISTEMA DE CÓMPUTO M E M O R I A S 152 CONTEXTO DE LA MEMORIA EN UN SISTEMA DE CÓMPUTO M E M O R I A S La manipulación la información binaria en la mayoría de los procesos lógicos en electrónica digital y en general en los sistemas de cómputo,

Más detalles

Conceptos iniciales. Sistema informático. La informática. Componentes del ordenador

Conceptos iniciales. Sistema informático. La informática. Componentes del ordenador Sistema informático Conceptos iniciales El sistema encargado de recoger y procesar los datos y de transmitir la información recibe el nombre de sistema informático. La informática La informática es el

Más detalles

TRABAJO PRÁCTICO Nº 6: PUERTO SERIE

TRABAJO PRÁCTICO Nº 6: PUERTO SERIE TRABAJO PRÁCTICO Nº 6: PUERTO SERIE Introducción a las comunicaciones serie Las comunicaciones serie se utilizan para enviar datos a través de largas distancias, ya que las comunicaciones en paralelo exigen

Más detalles

Introducción a Arduino

Introducción a Arduino 9 de Noviembre de 2012 Indice-I Plataforma Estándar Electrónica IDE Conceptos básicos electrónica Ley de Ohm y efecto Joule Ruido, puntos sin conexión y efecto rebote Semiconductores Conceptos básicos

Más detalles

Capítulo 1 Introducción a la Computación

Capítulo 1 Introducción a la Computación Capítulo 1 Introducción a la Computación 1 MEMORIA PRINCIPAL (RAM) DISPOSITIVOS DE ENTRADA (Teclado, Ratón, etc) C P U DISPOSITIVOS DE SALIDA (Monitor, Impresora, etc.) ALMACENAMIENTO (Memoria Secundaria:

Más detalles

Guía para construir un programador y una mini placa de desarrollo para el microcontrolador PIC

Guía para construir un programador y una mini placa de desarrollo para el microcontrolador PIC Guía para construir un programador y una mini placa de desarrollo para el microcontrolador PIC Rafael Fernández Andrés Aguirre Introducción: Esto de ninguna manera pretende ser una guía completa de como

Más detalles

El mundo de los PIC. Un PICmicro es un circuito integrado programable. Microchip, su fabricante dice: Programable Integrated Circuit.

El mundo de los PIC. Un PICmicro es un circuito integrado programable. Microchip, su fabricante dice: Programable Integrated Circuit. El mundo de los PIC Un PICmicro es un circuito integrado programable. Microchip, su fabricante dice: Programable Integrated Circuit. Programable quiere decir que se puede planificar la manera como va a

Más detalles

MANUAL CÁMARA DE MOWAY

MANUAL CÁMARA DE MOWAY MANUAL CÁMARA DE MOWAY Página 2 de 12 Copyright (c) 2011 Bizintek Innova, S.L. Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License,

Más detalles

INTRODUCCIÓN. Definiciones ORDENADOR (RAE 1992): En esta asignatura computador y ordenador tiene el mismo significado

INTRODUCCIÓN. Definiciones ORDENADOR (RAE 1992): En esta asignatura computador y ordenador tiene el mismo significado INTRODUCCIÓN UPCO ICAI Departamento de Electrónica y Automática 1 Definiciones ORDENADOR (RAE 1992): Máquina electrónica dotada de una memoria de gran capacidad y de métodos de tratamiento de la información,

Más detalles

MÓDULO 1: Sistemas de Cómputo

MÓDULO 1: Sistemas de Cómputo Asignatura: PROGRAMACIÓN Código: TE243 Prerrequisitos: Algebra Lineal (S)* Intensidad horaria: 80 H.P.S. MÓDULO 1: Sistemas de Cómputo Introducción: un sistema de cómputo es un conjunto de elementos electrónicos

Más detalles

Práctica 2 - Motores

Práctica 2 - Motores Práctica 2 - Motores INTRODUCCIÓN - Motores DC vs Servo motores Un motor de corriente directa cuenta con dos conexiones. La corriente eléctrica es proporcionada a través de estas conexiones, y por dentro

Más detalles

AD2100 10 a 24Vcc 100mA (1) SI SI SI 100 mw 1Km (2) 256 bytes AD2500 10 a 24Vcc 500mA (1) SI SI SI 500 mw 3km (2) 256 bytes

AD2100 10 a 24Vcc 100mA (1) SI SI SI 100 mw 1Km (2) 256 bytes AD2500 10 a 24Vcc 500mA (1) SI SI SI 500 mw 3km (2) 256 bytes AD2100 y AD2500 Transceptor Industrial de RF Interfaz RS232, RS485 y USB Manual de usuario e instalación Rev. 2 1. Introducción Los equipos de comunicación AD2100 y AD2500 son radio módems, los cuales

Más detalles

PARTES DE UN COMPUTADOR

PARTES DE UN COMPUTADOR PARTES DE UN COMPUTADOR FACULTAD DE CIENCIAS ECONOMICAS Y ADMINISTRATIVAS TECNICA PROFESIONAL EN CONTADURIA Convenio con la Alcaldía de Bucaramanga Docente: Fernando Gavieles Mira Materia: Informática

Más detalles

PROBLEMAS DE FUNDAMENTOS DE TECNOLOGÍA DE COMPUTADORES T5. MEMORIAS

PROBLEMAS DE FUNDAMENTOS DE TECNOLOGÍA DE COMPUTADORES T5. MEMORIAS PROBLEMAS DE FUNDAMENTOS DE TECNOLOGÍA DE COMPUTADORES T5. MEMORIAS Tema 5 Memorias Hoja: 2 / 14 Base teórica La memoria es el lugar en el que se almacenan las instrucciones y los datos para que se puedan

Más detalles

Anexo B. Comunicaciones entre mc y PC

Anexo B. Comunicaciones entre mc y PC Anexo B Comunicaciones entre mc y PC En este apartado se hará hincapié en los comandos para el manejo del módulo de comunicaciones desde el PC. Conociendo estos comando se podrá realizar una aplicación

Más detalles

Diseño e Implementación de un Sistema de Monitoreo Inalámbrico para Sistemas Embebidos

Diseño e Implementación de un Sistema de Monitoreo Inalámbrico para Sistemas Embebidos I CONGRESO VIRTUAL DE MICROCONTROLADORES Y SUS APLICACIONES 1 Diseño e Implementación de un Sistema de Monitoreo Inalámbrico para Sistemas Embebidos Juan Felipe Medina L., John Edward Salazar D., Nicolás

Más detalles

Curso sobre Microcontroladores Familia HC9S08 de Freescale

Curso sobre Microcontroladores Familia HC9S08 de Freescale Curso sobre Microcontroladores Familia HC9S08 de Freescale Por Ing. Daniel Di Lella EduDevices www.edudevices.com.ar e-mail: info@edudevices.com.ar Capítulo 8.- Inter Integrated Circuit Interface I2C MMIIC

Más detalles

AUTOMATIZACIÓN INDUSTRIAL

AUTOMATIZACIÓN INDUSTRIAL 2º I.T.I. Electrónica Industrial AUTOMATIZACIÓN INDUSTRIAL PRÁCTICAS PRÁCTICA 1 El objetivo que se pretende con esta práctica es la familiarización con el autómata Simatic S7-200 así como con el programa

Más detalles

SERIE DE EJERCICIOS 3

SERIE DE EJERCICIOS 3 1 SERIE DE EJERCICIOS 3 PARTE I: MANEJO DE VARIABLES Y ARREGLOS. PARA EL MICROCONTROLADOR 18F2550. VERIFIQUE SUS RESPUESTAS USANDO EL SIMULADOR DE MPLAB IDE. 1) Diga que valores hexadecimales se almacenan

Más detalles

Herramientas hardware y software para el desarrollo de aplicaciones con Microcontroladores PIC bajo plataformas GNU/Linux

Herramientas hardware y software para el desarrollo de aplicaciones con Microcontroladores PIC bajo plataformas GNU/Linux Herramientas hardware y software para el desarrollo de aplicaciones con Microcontroladores PIC bajo plataformas GNU/Linux Juan González Gómez Escuela Politécnica Superior Universidad Autónoma de Madrid

Más detalles

Temporizadores y contadores en tiempo real: El módulo Timer0 y el prescaler del PIC

Temporizadores y contadores en tiempo real: El módulo Timer0 y el prescaler del PIC Temporizadores y contadores en tiempo real: El módulo Timer0 y el aler del PIC 1. Introducción...1 2. Estructura del Timer0...1 3. Funcionamiento del Timer0...2 3.1. Entrada de reloj del modulo Timer0...

Más detalles

Control de un módulo LCD a través del bus I2C

Control de un módulo LCD a través del bus I2C Control de un módulo LCD a través del bus I2C Requerimientos hardware Placa basada en microcontrolador pic 16F877x (Plataforma Monibot) Módulo lcd por I2C modelo LCD03 Cable de comunicación de 4 hilos

Más detalles

Fundamentos básicos sobre computación

Fundamentos básicos sobre computación Universidad del Cauca Fundamentos básicos sobre computación División de Sistemas - División de Recursos Humanos 2007 1 Contenido 1. Introducción-Conceptos básicos... 3 1.1. Qué es un computador?... 3 1.2.

Más detalles

El Computador. Software

El Computador. Software El Computador Es una máquina electrónica que recibe y procesa datos para convertirlos en información útil. Una computadora es una colección de circuitos integrados y otros componentes relacionados que

Más detalles

ANEXO D X-CTU CONFIGURATION & TEST UTILITY SOFTWARE. Technical Support: Online support: http://www.digi.com/support/eservice/login.

ANEXO D X-CTU CONFIGURATION & TEST UTILITY SOFTWARE. Technical Support: Online support: http://www.digi.com/support/eservice/login. ANEXO D X-CTU CONFIGURATION & TEST UTILITY SOFTWARE Technical Support: Online support: http://www.digi.com/support/eservice/login.jsp TABLA DE CONTENIDO 1. INTRODUCCION... 2 2. PC SETTINGS... 3 2.1 COM

Más detalles

Organización de Computadoras. Turno Recursantes Clase 8

Organización de Computadoras. Turno Recursantes Clase 8 Organización de Computadoras Turno Recursantes Clase 8 Temas de Clase Subsistema de Memoria Organización de Memoria Principal Notas de clase 8 2 Memoria Velocidad del procesador: se duplica cada 18 meses

Más detalles

Introduccion al Lenguaje C. Omar Andrés Zapata Mesa Grupo de Fenomenología de Interacciones Fundamentales, (Gfif) Universidad de Antioquia

Introduccion al Lenguaje C. Omar Andrés Zapata Mesa Grupo de Fenomenología de Interacciones Fundamentales, (Gfif) Universidad de Antioquia Introduccion al Lenguaje C Omar Andrés Zapata Mesa Grupo de Fenomenología de Interacciones Fundamentales, (Gfif) Universidad de Antioquia Introducción C es un lenguaje de programación creado en 1972 por

Más detalles

Reproductor de MP3 Trek

Reproductor de MP3 Trek www.master-g.com Reproductor de MP3 Trek Lea cuidadosamente el manual de uso antes de conectar o poner en marcha el equipo. 1 - Introducción Felicitaciones por adquirir este reproductor de MP3. La alta

Más detalles

Practica de Control y Programación de Robots ROBOT HERMES. Curso 2007-2008

Practica de Control y Programación de Robots ROBOT HERMES. Curso 2007-2008 Practica de Control y Programación de Robots ROBOT HERMES Curso 2007-2008 CAMPUS TECNOLÓGICO DE LA UNIVERSIDAD DE NAVARRA NAFARROAKO UNIBERTSITATEKO CAMPUS TEKNOLOGIKOA Paseo de Manuel Lardizábal 13. 20018

Más detalles

DISPLAYS DE CRISTAL LIQUIDO

DISPLAYS DE CRISTAL LIQUIDO DISPLAYS DE CRISTAL LIQUIDO INDICE MANUAL DE REFERENCIA DEL LCD 1.- INTRODUCCION 2.- CARACTERISTICAS DEL DISPLAY 2.1.- Aspecto físico 2.2.- Alimentación 2.3.- Los caracteres del LCD 2.4.- La memoria del

Más detalles

DEPARTAMENTO ELECTRÓNICA PIC - TEMA 2 INTRODUCCIÓN A LOS MICROCONTROLADORES PIC

DEPARTAMENTO ELECTRÓNICA PIC - TEMA 2 INTRODUCCIÓN A LOS MICROCONTROLADORES PIC DEPARTAMENTO ELECTRÓNICA PIC - TEMA 2 INTRODUCCIÓN A LOS MICROCONTROLADORES PIC 1 Los 'PIC' son una familia de microcontroladores tipo RISC fabricados por Microchip Technology Inc. y derivados del PIC1650,

Más detalles

Capítulo 4 Procesos con estructuras de repetición

Capítulo 4 Procesos con estructuras de repetición Estructura de contador Capítulo 4 Procesos con estructuras de repetición Esta es una operación que incrementa en una unidad el valor almacenado en la variable c, cada vez que el flujo del diagrama pasa

Más detalles

Proyecto Rastreador + Coche Teledirigido

Proyecto Rastreador + Coche Teledirigido Proyecto Rastreador + Coche Teledirigido Profesor: Pedro Alonso Sanz Instituto: I.E.S. Joan Miró Localidad: San Sebastián de los Reyes Curso: Enero_009 Índice de contenido.- Explicación breve del Proyecto....-

Más detalles

Servicio de Informática Vicerrectorado de Tecnologías de la Información y la Comunicación

Servicio de Informática Vicerrectorado de Tecnologías de la Información y la Comunicación Vicerrectorado de Tecnologías de la Información y la Comunicación Conexión mediante Escritorio Remoto de Windows Última Actualización 22 de enero de 2015 Histórico de cambios Fecha Descripción Autor 16/09/13

Más detalles

Memoria 24LC256 I. I NTRODUCCIÓN

Memoria 24LC256 I. I NTRODUCCIÓN 1 Memoria 24LC256 I. I NTRODUCCIÓN I2C es un bus de comunicación serial sincrónica desarrollado por Phillips Semiconductors a principios de los años 80 s, con la principal intención de interconectar una

Más detalles

5. Despliegue en la PC

5. Despliegue en la PC 5 DESPLIEGUE EN LA PC 62 5.1 Conexión a la PC por medio de la tarjeta de audio La adquisición de señales analógicas es un trabajo que cada vez se hace más necesario en todos los campos relacionados con

Más detalles

Programación de dispositivos Arduino Asignatura Sistemas Digitales!

Programación de dispositivos Arduino Asignatura Sistemas Digitales! Programación de dispositivos Arduino Asignatura Sistemas Digitales! Gabriel Astudillo Muñoz Escuela de Ingeniería Civil en Informática Universidad de Valparaíso, Chile http://informatica.uv.cl Descripción

Más detalles

PROYECTO DE ELECTRÓNICA

PROYECTO DE ELECTRÓNICA PROYECTO DE ELECTRÓNICA Sistema de Alarma Raúl Lapaz de Juan Francisco Javier López Alcarria 1 ÍNDICE - Objetivo:... 3 - Justificación:... 3 - Plan de trabajo:... 3 A) Montaje del circuito en protoboards:...

Más detalles

UNIDADES FUNCIONALES DEL ORDENADOR TEMA 3

UNIDADES FUNCIONALES DEL ORDENADOR TEMA 3 UNIDADES FUNCIONALES DEL ORDENADOR TEMA 3 INTRODUCCIÓN El elemento hardware de un sistema básico de proceso de datos se puede estructurar en tres partes claramente diferenciadas en cuanto a sus funciones:

Más detalles

Tema 7: Esquema del Funcionamiento de una Computadora. Escuela Politécnica Superior Ingeniería Informática Universidad Autónoma de Madrid

Tema 7: Esquema del Funcionamiento de una Computadora. Escuela Politécnica Superior Ingeniería Informática Universidad Autónoma de Madrid Tema 7: Esquema del Funcionamiento de una Computadora Ingeniería Informática Universidad Autónoma de Madrid Esquema del Funcionamiento de una Computadora O B J E T I V O S Adquirir los conceptos básicos

Más detalles

EL MODELO DE ESTRATIFICACIÓN POR CAPAS DE TCP/IP DE INTERNET

EL MODELO DE ESTRATIFICACIÓN POR CAPAS DE TCP/IP DE INTERNET 1 EL MODELO DE ESTRATIFICACIÓN POR CAPAS DE TCP/IP DE INTERNET Cada capa de la pila añade a los datos a enviar a la capa inferior, información de control para que el envío sea correcto. Esta información

Más detalles

Desde el punto de vista físico en un ordenador se pueden distinguir los siguientes elementos:

Desde el punto de vista físico en un ordenador se pueden distinguir los siguientes elementos: Desde el punto de vista físico en un ordenador se pueden distinguir los siguientes elementos: Unidad Central de proceso (CPU/UCP): Unidad que se encarga del control del ordenador, procesando para ello

Más detalles

Organizacion del Computador

Organizacion del Computador Universidad Nacional de Ingeniería Facultad de Ciencias Introducción a la Ciencia de la Computación Organizacion del Computador Prof: J. Solano 2011-I Objetivos Despues de estudiar este cap. el estudiante

Más detalles

Tema 1 Fundamentos de Computación

Tema 1 Fundamentos de Computación Tema 1 Fundamentos de Computación Clase 2 Prof. María Alejandra Quintero Asignatura: Informática Escuela de Ingeniería Forestal Puntos a tratar Continuación hardware Memoria principal Dispositivos de almacenamiento

Más detalles

-PRODUCTO DESCATALOGADO- Relojes controlados por satélite Arbiter Systems, Inc.

-PRODUCTO DESCATALOGADO- Relojes controlados por satélite Arbiter Systems, Inc. -PRODUCTO DESCATALOGADO- Relojes controlados por satélite Arbiter Systems, Inc. Opción 32: Servidor interno de protocolo de tiempo de red 1.0 Descripción General. Opción 32: El servidor interno de protocolo

Más detalles

En el presente capítulo se describe la programación del instrumento virtual y cómo

En el presente capítulo se describe la programación del instrumento virtual y cómo Capítulo 6. Instrumentación virtual En el presente capítulo se describe la programación del instrumento virtual y cómo éste controla el circuito de captura de señales, la llamada telefónica y escribe los

Más detalles

PROCEDIMIENTO DE ENLACE TCPIP

PROCEDIMIENTO DE ENLACE TCPIP DISPOSITIVOS TCP/IP. Los dispositivos TCP/IP son equipos autónomos que funcionan de forma independiente a la PC y que tiene incorporado el procesamiento de identificación por medio de la huella digital,

Más detalles

I2C. Ing. Pablo Martín Gomez pgomez@fi.uba.ar

I2C. Ing. Pablo Martín Gomez pgomez@fi.uba.ar I2C Ing. Pablo Martín Gomez pgomez@fi.uba.ar 1 Comunicaciones en un bus serie 2 Comunicaciones en un bus serie 3 I²C Velocidad 4 UART Universal Asynchronous Receiver Transmitter Estándar de comunicación

Más detalles

Programación de Microcontroladores

Programación de Microcontroladores Programación de Microcontroladores Simulación en Crocodile Technology Práctica Nº 1 Encender un led cuando arranque el microcontrolador. Práctica Nº 2 Encender un led tres veces consecutivas. 1 Práctica

Más detalles

Informática I para Bachillerato

Informática I para Bachillerato CIMAT Introducción a la programación en C/C++ CIMAT Sesión 2 Cual es el lenguaje máquina? El lenguaje utilizado por el procesador se denomina lenguaje máquina. Se trata de datos tal como llegan al procesador,

Más detalles

UN SIMULADOR DE UNA MAQUINA COMPUTADORA COMO HERRAMIENTA PARA LA ENSEÑANZA DE LA ARQUITECTURA DE COMPUTADORAS

UN SIMULADOR DE UNA MAQUINA COMPUTADORA COMO HERRAMIENTA PARA LA ENSEÑANZA DE LA ARQUITECTURA DE COMPUTADORAS UN SIMULADOR DE UNA MAQUINA COMPUTADORA COMO HERRAMIENTA PARA LA ENSEÑANZA DE LA ARQUITECTURA DE COMPUTADORAS Autores GROSSI, María Delia (mdgrossi@mara.fi.uba.ar) JIMÉNEZ REY, M. Elizabeth (ejimenez@mara.fi.uba.ar)

Más detalles

INSTRUMENTACIÓN AVANZADA Departamento de Ingeniería Eléctrica y Electromecánica Facultad de Ingeniería Universidad Nacional de Mar del Plata

INSTRUMENTACIÓN AVANZADA Departamento de Ingeniería Eléctrica y Electromecánica Facultad de Ingeniería Universidad Nacional de Mar del Plata Características del datalogger autónomo EJERCICIO: El datalogger o registrador debe sensar la temperatura ambiente cada 1s y guardarla junto a la fecha y hora de adquisición en un archivo.txt alojado en

Más detalles

MEMORIAS DE SEMICONDUCTORES

MEMORIAS DE SEMICONDUCTORES MEMORIAS DE SEMICONDUCTORES Se ha visto anteriormente que un registro (latch o flip-flop) puede almacenar un bit. Para almacenar una gran cantidad de bits, se recurre al uso de memorias. Una memoria, en

Más detalles

GUIA RAPIDA DE LECTORA BIOMETRICA IN01-A ID PARA CONTROL DE ASISTENCIA Y ACCESO.

GUIA RAPIDA DE LECTORA BIOMETRICA IN01-A ID PARA CONTROL DE ASISTENCIA Y ACCESO. GUIA RAPIDA DE LECTORA BIOMETRICA IN01-A ID PARA CONTROL DE ASISTENCIA Y ACCESO. Principales Características: Pantalla a color TFT de 3" (pulgadas). Soporta 3,000 huellas. Soporta 100,000 registros de

Más detalles

Sensor de Temperatura utilizando el Starter Kit Javelin Stamp. Realizado por: Bertha Palomeque A. Rodrigo Barzola J.

Sensor de Temperatura utilizando el Starter Kit Javelin Stamp. Realizado por: Bertha Palomeque A. Rodrigo Barzola J. Sensor de Temperatura utilizando el Starter Kit Javelin Stamp Realizado por: Bertha Palomeque A. Rodrigo Barzola J. INTRODUCCION DIFERENCIAS EJEMPLOS JAVA Orientado a Objetos Multiplataforma Programar

Más detalles

Guía de uso de Moodle para participantes

Guía de uso de Moodle para participantes Guía de uso de Moodle para participantes ÍNDICE 1 ACCESO... 4 1.1 PORTAL... 4 1.2 INGRESAR A PLATAFORMA... 6 1.3 ESTRUCTURA DEL CURSO... 7 1.3.1 BLOQUES... 8 2 RECURSOS Y MÓDULOS... 10 LOS RECURSOS SE

Más detalles