aprendizaje de la electrónica a través de la robótica - … · aprendizaje de la electrónica a...

192
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: 2009-2011 Proyecto: Aprendizaje de la Electrónica a través de la Robótica

Upload: docong

Post on 29-Sep-2018

224 views

Category:

Documents


1 download

TRANSCRIPT

Page 1: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Aprendizaje de la Electrónica a través de la Robótica - ARCE -

Microcontroladores IES Joan Miró Página 1

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: 2009-2011

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

Page 2: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Aprendizaje de la Electrónica a través de la Robótica - ARCE -

Microcontroladores IES Joan Miró Página 2

Índice Página

1.- Sistemas Microcontrolados. ................................................................................................. 6

2.- Diagrama en Bloques de un sistema Microprocesado. Estructura Von Neumann. ........ 6

2.1.- Microprocesador (uP). .................................................................................................................... 6

2.2.- Buses. .............................................................................................................................................. 7

2.2.1.- Bus de Direcciones. .................................................................................................................................. 7

2.2.2.- Bus de Datos. ............................................................................................................................................ 7

2.2.3.- Bus de Control. ......................................................................................................................................... 7

2.2.- Memorias. ........................................................................................................................................ 7

2.2.1.- ROM. .......................................................................................................................................................... 7

2.2.2.- RAM............................................................................................................................................................ 8

2.3.- Interfaces. ........................................................................................................................................ 9

2.3.1.- Interface Serie. .......................................................................................................................................... 9

2.3.2.- Interface Paralelo. ................................................................................................................................... 11

2.4.- Decodificador de Direcciones. .................................................................................................... 12

2.4.1.- Mapa de Memoria. ................................................................................................................................... 13

3.- Microcontroladores. ............................................................................................................. 14

3.1.- Microcontroladores PIC. .............................................................................................................. 14

3.1.1.- Diagrama en bloques “ Estructura Hardvard” ....................................................................................... 14

3.1.2.- Proceso Segmentado “Pipeline”. ........................................................................................................... 14

3.1.3.- Instrucciones RISC. ................................................................................................................................ 14

3.1.4.- Estructura Ortogonal. ............................................................................................................................. 14

3.2.- Microcontrolador PIC 16F877A. ................................................................................................... 15

3.2.1.- Diagrama en Bloques. ............................................................................................................................. 16

3.2.2.- Mapa de Memoria. ................................................................................................................................... 17

3.2.2.1.- Memoria de Programa. ................................................................................................................................................. 17

3.2.2.2.- Memoria de Datos. ........................................................................................................................................................ 18

3.2.3.- Ensamblador. .......................................................................................................................................... 18

3.2.3.1.- Lenguaje Máquina. ....................................................................................................................................................... 18

3.2.3.2- Lenguaje Ensamblador. ................................................................................................................................................ 19

3.2.3.3.- Programa Ensamblador. .............................................................................................................................................. 19

3.2.4.- Set de Instrucciones. .............................................................................................................................. 20

4.- Herramientas de Desarrollo. ............................................................................................... 21

4.1.- Ensambladores y Compiladores. ................................................................................................ 21

4.2.- Simuladores. ................................................................................................................................. 21

4.2.1.- MPLAB. .................................................................................................................................................... 22

4.2.2.- PROTEUS VSM. ....................................................................................................................................... 22

4.3.- Emuladores. .................................................................................................................................. 23

4.4.- Grabadores o programadores. .................................................................................................... 23

5.- Sistema de Desarrollo << Monibot >>. ............................................................................. 24

5.1.- Fabricación del Monibot. .............................................................................................................. 24

5.1.1.- Placas y Esquemas. ................................................................................................................................ 24

5.1.2.- Listado de Componentes. ....................................................................................................................... 24

5.1.3.- Estructura. ............................................................................................................................................... 24

5.2.- Herramientas de desarrollo utilizadas. ....................................................................................... 24

Page 3: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Aprendizaje de la Electrónica a través de la Robótica - ARCE -

Microcontroladores IES Joan Miró Página 3

5.3.- Recursos bibliográficos. .............................................................................................................. 24

5.3.- Simulador Monibot. ...................................................................................................................... 25

5.3.1.- Visualización de Información. ................................................................................................................ 27

5.3.1.1.- Led. ................................................................................................................................................................................. 27

5.3.1.1.1.- Led_1.c .................................................................................................................................................................................... 27 5.3.1.1.2.- Led_2.c .................................................................................................................................................................................... 28 5.3.1.1.3.- Led_3.c .................................................................................................................................................................................... 29 5.3.1.1.4.- Led_4.c .................................................................................................................................................................................... 29

5.3.1.2.- Display_7Segmentos. ................................................................................................................................................. 30

5.3.1.2.1.- Display_7Seg_1.c .................................................................................................................................................................... 31 5.3.1.2.2.- Display_7Seg_2.c .................................................................................................................................................................... 32 5.3.1.2.3.- Display_7Seg_3.c .................................................................................................................................................................... 33

5.3.1.3.- LCD. ................................................................................................................................................................................ 34

5.3.1.3.1.- LCD_1.c ................................................................................................................................................................................... 36 5.3.1.3.2.- LCD_2.c ................................................................................................................................................................................... 37 5.3.1.3.3.- LCD_3.c ................................................................................................................................................................................... 37 5.3.1.3.4.- LCD_4.c ................................................................................................................................................................................... 38 5.3.1.3.5.- LCD_5.c ................................................................................................................................................................................... 39 5.3.1.3.6.- LCD_6.c ................................................................................................................................................................................... 40 5.3.1.3.7.- LCD_7.c ................................................................................................................................................................................... 41

5.3.2.- Entradas Digitales. .................................................................................................................................. 42

5.3.2.1.- Simulador de Periféricos. ............................................................................................................................................ 42

5.3.2.1.1.- Interruptores_Led_1.c ............................................................................................................................................................ 42 5.3.2.1.2.- Interruptores_Led_2.c ............................................................................................................................................................ 43 5.3.2.1.3.- Interruptores_DISPL_7S_1.c ................................................................................................................................................... 44 5.3.2.1.4.- Interruptores_DISPL_7S_2.c. .................................................................................................................................................. 45 5.3.2.1.5.- Pulsadores_DISPL_7S_1.c ....................................................................................................................................................... 46

5.3.2.2.- Simulador de Periféricos y Potencia. ......................................................................................................................... 47

5.3.2.2.1.- Interruptores_LCD_1.c ............................................................................................................................................................ 48 5.3.2.2.2.- Interruptores_LCD_2.c ............................................................................................................................................................ 49

5.3.2.3.- Simulador de Potencia. ................................................................................................................................................ 50

5.3.2.3.1.- Pulsadores_LCD_1.c ................................................................................................................................................................ 50

5.3.3.- Entradas Analógicas. .............................................................................................................................. 51

5.3.3.1.- Conversión A-D_D-A .................................................................................................................................................... 53

5.3.3.1.1.- Conversión_A-D_A-D.c .......................................................................................................................................................... 54

5.3.3.2.- Conversión Analógica Digital. .................................................................................................................................... 55

5.3.3.2.1.- Conversión_A-D1.c ................................................................................................................................................................. 55 5.3.3.2.2.- Conversión_A-D2.c ................................................................................................................................................................. 56 5.3.3.2.3.- Conversión_A-D2a.c ............................................................................................................................................................... 57

5.3.4.- Modulación por Anchura de Pulso (PWM). ............................................................................................ 58

5.3.4.1.- Control de Motores de Corriente Continua. .............................................................................................................. 58

5.3.4.1.1.- Prueba_Motor_Derecho.c ...................................................................................................................................................... 60 5.3.4.1.2.- Prueba_Control_Velocidad_Motor_Derecho.c ...................................................................................................................... 61 5.3.4.1.3.- Prueba_Control_Velocidad_Motor_Derecho_f.c ................................................................................................................... 62 5.3.4.1.4.- Prueba_Control_Velocidad_Motor_Izquierdo_Derecho_f.c .................................................................................................. 64

5.3.4.2.- Servomotores de Posición. ......................................................................................................................................... 66

5.3.4.2.1.- Control_2_Servo_Posición.c ................................................................................................................................................... 67 5.3.4.2.2.- Servo_ Futaba_10bit.c ............................................................................................................................................................ 68

Page 4: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Aprendizaje de la Electrónica a través de la Robótica - ARCE -

Microcontroladores IES Joan Miró Página 4

5.3.5.- Interrupciones Externas. ........................................................................................................................ 70

5.3.5.1.- Interrupción por RB0/INT. ............................................................................................................................................ 71

5.3.5.1.1.- Interrupción_INT_RB0.c ......................................................................................................................................................... 71 5.3.5.1.2.- Interrupción_INT_RB0a.c ....................................................................................................................................................... 73 5.3.5.1.3.- Interrupción_INT_RB0b.c ....................................................................................................................................................... 74

5.3.5.2.- Interrupción por cambio de nivel de RB4_5_6_7. ..................................................................................................... 76

5.3.5.2.1.- Interrupción_INT_RB4567.c ................................................................................................................................................... 76 5.3.5.2.1.- Interrupción_INT_RB4567a.c .................................................................................................................................................. 79

5.3.6.- Temporizadores y Contadores. (Timer 0,1 y 2). .................................................................................... 81

5.3.6.1.- Timer 0. .......................................................................................................................................................................... 81

5.3.6.1.1.- Timer0_Contador.c ................................................................................................................................................................. 82 5.3.6.1.2.- Timer0_temporizador_multitarea_1.c ................................................................................................................................... 84 5.3.6.1.3.- Timer0_temporizador_multitarea_2.c ................................................................................................................................... 85

5.3.6.2.- Timer 1. .......................................................................................................................................................................... 87

5.3.6.2.1.- Timer1_Contador.c ................................................................................................................................................................. 88 5.3.6.2.2.- Timer1_temporizador_multitarea.c ....................................................................................................................................... 89

5.3.6.3.- Timer 2. .......................................................................................................................................................................... 91

5.3.6.3.1.- Timer2_Señal_Cuadrada.c ...................................................................................................................................................... 92 5.3.6.3.2.- Timer2_Servos_Posicion.c ...................................................................................................................................................... 93

5.3.7.- Transmisión Serie de Datos. USART ..................................................................................................... 96

5.3.7.1.- Cable. ............................................................................................................................................................................. 97

5.3.7.1.1.- Transmisión_Serie_1.c ............................................................................................................................................................ 98 5.3.7.1.2.- Recepción_Serie_Polling.c ...................................................................................................................................................... 98 5.3.7.1.3.- Recepción_Serie_Interrupción.c ............................................................................................................................................. 99 5.3.7.1.4.- Transmisión_Serie_Multitarea.c .......................................................................................................................................... 101 5.3.7.1.5.- Recepción_Serie_Interrupción_Multitarea.c ....................................................................................................................... 102 5.3.7.1.6.- Transmisión_Serie_Multitarea_1.c ...................................................................................................................................... 104 5.3.7.1.7.- Recepción_Serie_Interrupción_Multitarea_1.c............................................................................................................. 106

5.3.7.2.- Radiofrecuencia. ......................................................................................................................................................... 109

5.3.7.2.0.- Modulación en AM. .............................................................................................................................................................. 109 5.3.7.2.1.- Transmisión_Serie_ Radiofrecuencia_1.c...................................................................................................................... 111 5.3.7.2.2.- Transmisión_Serie_ Radiofrecuencia_2.c...................................................................................................................... 112 5.3.7.2.3.- Recepción_Serie_Radiofrecuencia_1.c ........................................................................................................................... 113

5.3.7.3.- Radiofrecuencia Multitarea........................................................................................................................................ 115

5.3.7.3.1.- Transmisión_Serie_RF_Multitarea_1.c ........................................................................................................................... 116 5.3.7.3.2.- Transmisión_Serie_RF_Multitarea_2.c ........................................................................................................................... 117 5.3.7.3.3.- Recepción_Serie_RF_Multitarea.c ................................................................................................................................... 120

5.3.8.- Módulo MSSP. ....................................................................................................................................... 123

5.3.8.1.- I2C. ............................................................................................................................................................................... 123

5.3.8.1.1.- Expansor_Bus_PCF8574. ....................................................................................................................................................... 125 5.3.8.1.1.1.- PCF8574_1. ................................................................................................................................................................... 125

5.3.8.1.1.1.1.- Lectura y escritura en PCF8574 modo polling.c .................................................................................................... 126 5.3.8.1.1.1.2.- Lectura y escritura en PCF8574 en modo Interrupción.c ...................................................................................... 127

5.3.8.1.1.2.- PCF8574_2. ................................................................................................................................................................... 129 5.3.8.1.1.2.1.- Lectura y escritura de multiples PCF8574 modo polling.c ..................................................................................... 130 5.3.8.1.1.2.2.- Lectura y escritura de multiples PCF8574 modo Interrupción.c............................................................................ 131

5.3.8.1.1.3.- PCF8574_3. ................................................................................................................................................................... 135 5.3.8.1.1.3.1.- CAD_PCF8547.c .................................................................................................................................................... 135 5.3.8.1.1.3.2.- CAD_PCF8547_MULTIPLES.c ................................................................................................................................ 138

Page 5: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Aprendizaje de la Electrónica a través de la Robótica - ARCE -

Microcontroladores IES Joan Miró Página 5

5.3.8.1.2.- Conversor A-D_D-A_PCF8591. .............................................................................................................................................. 141 5.3.8.1.2.1.- PCF8591_ADC. .............................................................................................................................................................. 141

5.3.8.1.2.1.1.- I2C_CAD_1.c ......................................................................................................................................................... 142 5.3.8.1.2.1.2.- I2C_CAD_2.c ......................................................................................................................................................... 143

5.3.8.1.2.2.- PCF8591_DAC. .............................................................................................................................................................. 144 5.3.8.1.2.2.1.- I2C_CDA_1.c ......................................................................................................................................................... 145

5.3.9.- Sensores y Hardware. ........................................................................................................................... 147

5.3.9.1.- Sensores de Infrarrojos CNY70. ............................................................................................................................... 147

5.3.9.1.1.- Prueba_Sensores_CNY70.c ................................................................................................................................................... 148

5.3.9.2.- Sensores de Distancia. .............................................................................................................................................. 149

5.3.9.2.1.- Sensor de Infrarrojos GP2D12. ............................................................................................................................................. 149 5.3.9.2.1.1.- Lectura_S1_GP2D12.c .................................................................................................................................................. 151 5.3.9.2.1.2.- Lectura_S1_GP2D12.c .................................................................................................................................................. 152 5.3.9.2.1.3.- driver1_GP2D12.c ........................................................................................................................................................ 153 5.3.9.2.1.4.- driver2_GP2D12.c ........................................................................................................................................................ 153

5.3.9.2.2.- Sensor de Ultrasonidos SRF08. ............................................................................................................................................. 154 5.3.9.2.2.1.- Lectura_S1_SRF08_Real. .............................................................................................................................................. 155 5.3.9.2.2.2.- Lectura_S1_S2_SRF08_Real.c ....................................................................................................................................... 156 5.3.9.2.2.3.- Lectura_S1_S2_SRF08_Real_Simulado.c ...................................................................................................................... 158 5.3.9.2.2.4.- Lectura_S1_SRF08_Distancia_Lumenes.c .................................................................................................................... 159 5.3.9.2.2.5.- driver SRF08.c ............................................................................................................................................................... 159 5.3.9.2.2.6.- driver_Luz_Distancia_SRF08.c...................................................................................................................................... 160 5.3.9.2.2.7.- driver PCF8591.c ........................................................................................................................................................... 162 5.3.9.2.2.8.- Cambio_Dirección.c ...................................................................................................................................................... 162 5.3.9.2.2.9.- Ejercicio 1.c ................................................................................................................................................................... 163

5.3.9.3.- Sensores de Temperatura. ........................................................................................................................................ 164

5.3.9.3.1.- PT100. ................................................................................................................................................................................... 164 5.3.9.3.1.1.- Lectura_S1_PT100.c ..................................................................................................................................................... 166

5.3.9.3.2.- Sensor de Temperatura TC74. .............................................................................................................................................. 167 5.3.9.3.2.1.- Test _TC74.c ................................................................................................................................................................. 168

5.3.9.3.3.- Sensor Térmico D-TPA81. ..................................................................................................................................................... 170 5.3.9.3.3.1.- Test1_D-TPA81.c .......................................................................................................................................................... 173 5.3.9.3.3.2.- Test2_D-TPA81.c .......................................................................................................................................................... 174 5.3.9.3.3.3.- Temperatura Mayor.c .................................................................................................................................................. 176 5.3.9.3.3.4.- Temperatura Mayor_con driver.c ................................................................................................................................ 177 5.3.9.3.3.5.- driver_D-TPA81.c ......................................................................................................................................................... 179 5.3.9.3.3.6.- driver_TC74_9_sensores.c ............................................................................................................................................ 179 5.3.9.3.3.7.- Seguimiento de un punto caliente.c ............................................................................................................................. 180

5.3.9.4.- Potenciómetro Digital MCP41010. ............................................................................................................................ 182

5.3.9.4.1.- CG_Ampl_No_Inversor.c ...................................................................................................................................................... 183

5.3.9.5.- Control de múltiples servomotores de posición SD20. ......................................................................................... 184

5.3.9.5.1.- Control_SD20.c ..................................................................................................................................................................... 184 5.3.9.5.2.- Control_Servos_Funciones_SD20.c ...................................................................................................................................... 185 5.3.9.5.3.- A-D_SD20.c ........................................................................................................................................................................... 187

5.3.9.6.- Puentes en H. .............................................................................................................................................................. 188

5.3.9.6.1.- L293B y L298. ........................................................................................................................................................................ 189 5.3.9.6.2.- Puente en H con TRT............................................................................................................................................................. 192

Page 6: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Aprendizaje de la Electrónica a través de la Robótica - ARCE -

Microcontroladores IES Joan Miró Página 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.

2.1.- 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.

Page 7: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Aprendizaje de la Electrónica a través de la Robótica - ARCE -

Microcontroladores IES Joan Miró Página 7

2.2.- Buses.

Es un conjunto de hilos, pistas o cables que tienes la misión de transportar información

digital.

2.2.1.- Bus de Direcciones.

Es un bus que el uP utiliza para selecciona o direcciona los dispositivos externos.

2.2.2.- Bus de Datos.

Es un bus que el uP utiliza para enviar o recibir información de los dispositivos externos.

2.2.3.- 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.

2.2.- Memorias.

Son circuitos integrados que almacenan información.

2.2.1.- ROM.

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.

Page 8: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Aprendizaje de la Electrónica a través de la Robótica - ARCE -

Microcontroladores IES Joan Miró Página 8

Estructura interna de la memoria:

El Bus de Direcciones nos indica el número de palabras que tiene la memoria.

Palabras = 2n+1

, donde “n=2 por la dirección A2”, 22+1

= 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

2.2.2.- 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.

Page 9: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Aprendizaje de la Electrónica a través de la Robótica - ARCE -

Microcontroladores IES Joan Miró Página 9

Estructura interna de la memoria:

2.3.- Interfaces.

Son circuitos electrónicos que comunican el exterior con el uP.

2.3.1.- 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.

Page 10: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Aprendizaje de la Electrónica a través de la Robótica - ARCE -

Microcontroladores IES Joan Miró Página 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

Page 11: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Aprendizaje de la Electrónica a través de la Robótica - ARCE -

Microcontroladores IES Joan Miró Página 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.

2.3.2.- Interface Paralelo.

Las conexiones paralelas consisten en transmisiones simultáneas de N cantidad de bits, del uP al Exterior o viceversa.

Page 12: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Aprendizaje de la Electrónica a través de la Robótica - ARCE -

Microcontroladores IES Joan Miró Página 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.

Page 13: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Aprendizaje de la Electrónica a través de la Robótica - ARCE -

Microcontroladores IES Joan Miró Página 13

2.4.1.- 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

Page 14: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Aprendizaje de la Electrónica a través de la Robótica - ARCE -

Microcontroladores IES Joan Miró Página 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.

3.1.- 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.

3.1.1.- Diagrama en bloques “ Estructura Hardvard”

Se caracteriza por utilizar dos tipos de memorias (Datos y Programa) con buses independientes.

3.1.2.- Proceso Segmentado “Pipeline”.

Permite realizar dos procesos simultáneamente a la vez (lectura y ejecución de

instrucciones).

3.1.3.- 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.

3.1.4.- Estructura Ortogonal.

Una instrucción puede utilizar cualquier elemento de la arquitectura como fuente o destino de datos.

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 4

CPU

Memoria de

Datos

(RAM)

Memoria de

Programa

(EEPROM)

Arquitectura Hardvard

CPU

Memoria de

Programa y

de Datos

Arquitectura Von Neumann

Buses Buses

Page 15: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Aprendizaje de la Electrónica a través de la Robótica - ARCE -

Microcontroladores IES Joan Miró Página 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.

Page 16: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Aprendizaje de la Electrónica a través de la Robótica - ARCE -

Microcontroladores IES Joan Miró Página 16

3.2.1.- Diagrama en Bloques.

Page 17: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Aprendizaje de la Electrónica a través de la Robótica - ARCE -

Microcontroladores IES Joan Miró Página 17

3.2.2.- Mapa de Memoria.

3.2.2.1.- 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.

Page 18: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Aprendizaje de la Electrónica a través de la Robótica - ARCE -

Microcontroladores IES Joan Miró Página 18

3.2.2.2.- 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.

3.2.3.- Ensamblador.

3.2.3.1.- 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 BTFSS PORTA, 4 0001 1110 0000 0101

Código Hexadecimal 1 E 0 5

Compilador

Page 19: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Aprendizaje de la Electrónica a través de la Robótica - ARCE -

Microcontroladores IES Joan Miró Página 19

3.2.3.2- 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

3.2.3.3.- 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”.

Programa Ensamblador

“MPASM.EXE”

Fichero Fuente

“Ejemplo1.asm”

Fichero Ejecutable

“Ejemplo1.hex”

Fichero Errores

“Ejemplo1.err”

Fichero Listable

Ejemplo1.lst”

Otros ficheros

Page 20: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Aprendizaje de la Electrónica a través de la Robótica - ARCE -

Microcontroladores IES Joan Miró Página 20

3.2.4.- Set de Instrucciones.

Page 21: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Aprendizaje de la Electrónica a través de la Robótica - ARCE -

Microcontroladores IES Joan Miró Página 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

4.1.- Ensambladores y Compiladores.

El programa ensamblador traduce las instrucciones que se han escrito, usando los

nemónicos del lenguaje ensamblador , a código binar io 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 MPASMTM

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 (www.htsoft.com) y el PCW de la empresa CCS (www.ccsinfo.com).

Un compilador para Basic es el PICBasic Pro propiedad de MicroEngineering Labs

(www.melabs.com).

4.2.- 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

(www.labcenter.co.uk).

Page 22: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Aprendizaje de la Electrónica a través de la Robótica - ARCE -

Microcontroladores IES Joan Miró Página 22

4.2.1.- 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 www.microchip.com. Su instalación es muy sencilla y similar a cualquier otro programa para el sistema operativo Windows.

4.2.2.- 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.

Page 23: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Aprendizaje de la Electrónica a través de la Robótica - ARCE -

Microcontroladores IES Joan Miró Página 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 2000.

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.

4.4.- 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

Page 24: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Aprendizaje de la Electrónica a través de la Robótica - ARCE -

Microcontroladores IES Joan Miró Página 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.

5.- 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.

5.1.- Fabricación del Monibot.

5.1.1.- Placas y Esquemas.

5.1.2.- Listado de Componentes.

5.1.3.- Estructura.

5.2.- 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)

5.3.- Recursos bibliográficos.

Curso de Robótica y otras aplicaciones en el Aula de Tecnología.

Data book PIC16F87xA.

Curso de Microcontroladores PIC Avanzados.

TXPC

RXPC

GND

VSS

RA0/AN02

RA1/AN13

RA2/AN2/VREF-4

RA4/T0CKI6

RA5/AN4/SS7

OSC1/CLKIN9

OSC2/CLKOUT10

RC1/T1OSI/CCP212

RC2/CCP113

RC3/SCK/SCL14

RB7/PGD28

RB6/PGC27

RB526

RB425

RB3/PGM24

RB223

RB122

RB0/INT21

RC7/RX/DT18

RC6/TX/CK17

RC5/SDO16

RC4/SDI/SDA15

RA3/AN3/VREF+5

RC0/T1OSO/T1CKI11

MCLR/Vpp/THV1

U2

PIC16F876_JOAN

T1IN11

R1OUT12

T2IN10

R2OUT9

T1OUT14

R1IN13

T2OUT7

R2IN8

C2+

4

C2-

5

C1+

1

C1-

3

VS+2

VS-6

U5

MAX232

GND=GND

VCC=VCC

C6

1uF

C7

1uF

C81uF

C9

1uF

VDDVDD

C10100nF

1

6

2

7

3

8

4

9

5

J6

CONN-D9M

Adaptador de señales PC-uC

12

E1

5V

VDD

VCC

+

+

+

+Este condensador debe estar proximo a la

alimentación del MAX 232

Al Puerto Serie del PC

Page 25: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Aprendizaje de la Electrónica a través de la Robótica - ARCE -

Microcontroladores IES Joan Miró Página 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 MCP41010.

Control de múltiples servomotores de posición SD20.

Puentes en H.

L298-L293B. Puente en H con TRT.

Page 26: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Aprendizaje de la Electrónica a través de la Robótica - ARCE -

Microcontroladores IES Joan Miró Página 26

Los esquemas básicos de simulación del Monibot son:

Simulador Potencia y Periféricos.

Simulador Potencia.

Simulador Periféricos.

Page 27: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Aprendizaje de la Electrónica a través de la Robótica - ARCE -

Microcontroladores IES Joan Miró Página 27

5.3.1.- Visualización de Información.

5.3.1.1.- Led. El entrenador utilizado es Simulador Periféricos dentro de la carpeta de Led.

5.3.1.1.1.- 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> // Elección del uC 16F877A #fuses XT,NOWDT,NOPROTECT,NOLVP #use delay( clock = 1000000 ) // Reloj de 1 MHz #BYTE TRISB = 0x86 // Asignamos a la etiqueta TRISB la dirección 86h de memoria RAM. #BYTE portB = 0x06 // Asignamos a la etiqueta portB la dirección 06h de memoria RAM. #BIT rb7 = 0X06.7 // Asignamos a la etiqueta rb7 el bit 7 de la dirección 06h

// de la memoria RAM. #DEFINE ENCENDIDO 1 // ENCENDIDO equivale a 1. #DEFINE APAGADO 0 // APAGADO equivale a 0.

// ***************************** Función principal o programa principal ***************************** // Se define con un void main, void main()

Page 28: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Aprendizaje de la Electrónica a través de la Robótica - ARCE -

Microcontroladores IES Joan Miró Página 28

TRISB = 0B00000000; // Defines Puerto B como SALIDA de datos.

portB = 0B00000000; // Resteamos el puerto B Led apagados. while (1) // Ejecuta indefinidamente lo que está entre corchetes.

rb7 = ENCENDIDO; // Enciende el Led que esta en la patilla rb7. delay_ms(1000); // Espero 1 segundo. rb7 = APAGADO; // Apago el Led que esta en la patilla rb7. delay_ms(1000); // Espero 1 segundo.

5.3.1.1.2.- 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> // Elección del uC 16F877A #fuses XT,NOWDT,NOPROTECT,NOLVP #use delay( clock = 1000000 ) // Reloj de 1 MHz #BYTE TRISB = 0x86 // Asignamos a la etiqueta TRISB la dirección 86h de memoria RAM.

#BYTE portB = 0x06 // 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 = 0B00000000; // Defines Puerto B como SALIDA de datos. portB = 0B00000000; // Resteamos el puerto B Led apagados. while (1) // Ejecuta indefinidamente lo que está entre corchetes. portB =0b11111111; // Enciende todos los Led delay_ms(2000); // Espero 2 segundo portB =0b00000000; // Apago todos los led delay_ms(1000); // Espero 1 segundo

Page 29: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Aprendizaje de la Electrónica a través de la Robótica - ARCE -

Microcontroladores IES Joan Miró Página 29

5.3.1.1.3.- 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> // Elección del uC 16F877A #fuses XT,NOWDT,NOPROTECT,NOLVP #use delay( clock = 1000000 ) // Reloj de 1 MHz #BYTE TRISB = 0x86 // Asignamos a la etiqueta TRISB la dirección 86h de memoria RAM. #BYTE portB = 0x06 // 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 = 0B00000000; // Defines Puerto B como SALIDA de datos. portB = 0B00000000; // Resteamos el puerto B Led apagados. while (1) // Ejecuta indefinidamente lo que está entre corchetes. for (n=0;n<=9;n++) // Ejecuta el contenido que está entre corchetes 10 veces //de 0 a 9 portB=n; // Asignamos la variable n al puertoB. delay_ms(1000); // Espero 1 segundo.

5.3.1.1.4.- 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> // Elección del uC 16F877A #fuses XT,NOWDT,NOPROTECT,NOLVP #use delay( clock = 1000000 ) // Reloj de 1 MHz #BYTE TRISB = 0x86 // Asignamos a la etiqueta TRISB la dirección 86h de memoria RAM. #BYTE portB = 0x06 // 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.

Page 30: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Aprendizaje de la Electrónica a través de la Robótica - ARCE -

Microcontroladores IES Joan Miró Página 30

// **************************** Función principal o programa principal ****************************** // Se define con un void main, void main()

TRISB = 0B00000000; // Defines Puerto B como SALIDA de datos. portB = 0b00000001; // Activamos PB0. delay_ms(500); // 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; // Movemos un bit a la izquierda delay_ms(500); // 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; // Movemos un bit a la derecha. delay_ms(500); // Esperamos 0,5 segundo.

5.3.1.2.- 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.

Page 31: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Aprendizaje de la Electrónica a través de la Robótica - ARCE -

Microcontroladores IES Joan Miró Página 31

Tabla de conversión de Número Decimal a Binario de 7 segmentos

5.3.1.2.1.- 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 = 1000000 ) // Reloj de 1 MHz #define Numeros_Tabla 10 // Números de la Tabla. #BYTE TRISB = 0x86 // Asignamos a la etiqueta TRISB la dirección 86h de memoria RAM. #BYTE portB = 0x06 // 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 = 0B00000000; // Defines Puerto B como SALIDA de datos. portB = 0B00000000; // Reseteamos el Puerto B. while (1) // Ejecuta indefinidamente lo que está entre corchetes.

Número Decimal

Puerto B

B7 B6 B5 B4 B3 B2 B1 B0 g f e d c b a

Número Hexadecimal

0 1 2 3 4 5 6 7 8 9

0 0 1 1 1 1 1 1 0 0 0 0 0 1 1 0 0 1 0 1 1 0 1 1 0 1 0 0 1 1 1 1 0 1 1 0 0 1 1 0 0 1 1 0 1 1 0 1 0 1 1 1 1 1 0 1 0 0 0 0 0 1 1 1 0 1 1 1 1 1 1 1 0 1 1 0 1 1 1 1

3F 06 5B 4F 66 6D 7D 07 7F 6F

1º Dígito en Hexadecimal

2º Dígito en Hexadecimal

Page 32: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Aprendizaje de la Electrónica a través de la Robótica - ARCE -

Microcontroladores IES Joan Miró Página 32

for (n=0; n<Numeros_Tabla; n++) // Se ejecuta un bucle desde n=0 hasta // n<=Numeros_Tabla en orden // ASCENDENTE de uno en uno portB = DISPLAY[n]; // Mostramos en el Puerto B el valor que

// tiene la tabla DISPLAY[n] delay_ms(1000); // Retardo de 1 Segundo.

5.3.1.2.2.- 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 = 1000000 ) // Reloj de 1 MHz #define Numeros_Tabla 10 // Números de la Tabla. #BYTE TRISB = 0x86 // Asignamos a la etiqueta TRISB la dirección 86h de memoria RAM. #BYTE portB = 0x06 // 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 = 0B00000000; // Defines Puerto B como SALIDA de datos. portB = 0B00000000; // 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]; // Mostramos en el Puerto B el valor que tiene DISPLAY[n] delay_ms(1000); // Retardo de 1 Segundo.

Page 33: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Aprendizaje de la Electrónica a través de la Robótica - ARCE -

Microcontroladores IES Joan Miró Página 33

5.3.1.2.3.- 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 = 1000000 ) // Reloj de 1 MHz #define Numeros_Tabla 5 // Números de la Tabla. #BYTE TRISB = 0x86 // Asignamos a la etiqueta TRISB la dirección 86h de memoria RAM. #BYTE portB = 0x06 // 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; // Tabla de 5 datos. // P E d r O

// ***************************** Función principal o programa principal **************************** // Se define con un void main, void main()

TRISB = 0B00000000; // 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++) // Se ejecuta un bucle desde n=0 hasta // n<Numeros_Tabla en orden ASCENDENTE

// de uno en uno portB = DISPLAY[n]; // Mostramos en el Puerto B el valor que tiene DISPLAY[n] delay_ms(1000); // Retardo de 1 Segundo.

Page 34: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Aprendizaje de la Electrónica a través de la Robótica - ARCE -

Microcontroladores IES Joan Miró Página 34

5.3.1.3.- 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 HD44780.

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.

Page 35: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Aprendizaje de la Electrónica a través de la Robótica - ARCE -

Microcontroladores IES Joan Miró Página 35

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:

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 14..7 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 Texto a escribir en el LCD

número (número de caracteres) es opcional 1-9 Cuantos caracteres se escriben.

D7

14

D6

13

D5

12

D4

11

D3

10

D2

9D

18

D0

7

E6

RW

5R

S4

VS

S1

VD

D2

VE

E3

LCD1LCD-16 X 2_JOAN

Page 36: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Aprendizaje de la Electrónica a través de la Robótica - ARCE -

Microcontroladores IES Joan Miró Página 36

01-09 Indica cuantos ceros existen a la Izquierda. 1.1-9.9 para coma flotante. t ipo (tipo de carácter) puede ser: c Carácter. s Cadena o Carácter. u Entero sin signo. d Entero con signo. Lu Entero Largo sin signo. Ld Entero Largo con signo. x Entero Hexadecimal (minúsculas). X Entero Hexadecimal (mayúsculas). Lx Entero largo Hexadecimal (minúsculas). LX Entero largo Hexadecimal(mayúsculas). f Flotante con truncado. g Flotante con redondeo. e Flotante en formato exponencial. w Entero sin signo con decimales insertados. La 1ª cifra indica el

total de números, la 2ª cifra indica el número de decimales. \c puede ser: \f Se limpia el LCD. \n El cursor va a la posición (1,2) \b El cursor retrocede una posición.

5.3.1.3.1.- 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 = 1000000 ) // 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(); // Inicializamos el LCD. printf(lcd_putc, "I.E.S. Joan Miro\n"); // Escribimos "I.E.S. Joan Miro" y

// saltamos a la siguiente línea. printf(lcd_putc, " Ciclo GM de EC"); // Escribimos " Ciclo GM de EC". while (1); // Ejecuta está instrucción indefinidamente.

Page 37: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Aprendizaje de la Electrónica a través de la Robótica - ARCE -

Microcontroladores IES Joan Miró Página 37

5.3.1.3.2.- 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 = 1000000 ) // 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.

5.3.1.3.3.- 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

Page 38: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Aprendizaje de la Electrónica a través de la Robótica - ARCE -

Microcontroladores IES Joan Miró Página 38

#use delay( clock = 1000000 ) // 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) // Sacamos los diez números del array uno a uno y los // representamos en el Display en diferentes formatos. lcd_gotoxy(1,1); // Posicionamos el Cursor del LCD en la posición // 1 línea 1 . printf(lcd_putc,"%3u",DIGIT_MAP[i]); // Escribimos 3 dígitos del dato sacado del array // DIGITAL_MAP en formato entero y sin signo. lcd_gotoxy(2,2); // Posicionamos el Cursor del LCD en la posición // 2 línea 2 . printf(lcd_putc,"%2X",DIGIT_MAP[i]); // Escribimos 2 dígitos del número sacado del

// array DIGITAL_MAP en formato entero // hexadecimal mayúsculas.

delay_ms(1000); // Retardo de 1 segundo. while (1); // Fin.

5.3.1.3.4.- 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 = 1000000 ) // 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.

Page 39: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Aprendizaje de la Electrónica a través de la Robótica - ARCE -

Microcontroladores IES Joan Miró Página 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) // Sacamos los diez números del array uno a uno y los representamos // en el Display. lcd_gotoxy(1,1); // Posicionamos el Cursor del LCD en la

// posición 1 línea 1 . printf(lcd_putc,"%5Lu",NUMEROS[i]); // 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.

5.3.1.3.5.- 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 = 1000000 ) // 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,-456232,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".

Page 40: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Aprendizaje de la Electrónica a través de la Robótica - ARCE -

Microcontroladores IES Joan Miró Página 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.

5.3.1.3.6.- 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 = 1000000 ) // 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) // Sacamos los diez números del array uno a uno y los // representamos en el Display en diferentes formatos. printf(lcd_putc,"%1c\b",CARACTER[i]); // 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.

Page 41: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Aprendizaje de la Electrónica a través de la Robótica - ARCE -

Microcontroladores IES Joan Miró Página 41

5.3.1.3.7.- 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 = 1000000 ) // Reloj de 1 MHz #include <flex_lcd.c> // 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.

Page 42: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Aprendizaje de la Electrónica a través de la Robótica - ARCE -

Microcontroladores IES Joan Miró Página 42

5.3.2.- Entradas Digitales.

Utilizaremos diferentes entrenadores, contenidos en la carpeta de Entradas Digitales.

5.3.2.1.- Simulador de Periféricos.

5.3.2.1.1.- 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> // Elección del uC 16F877A #fuses XT, NOWDT, NOPROTECT, NOLVP #use delay( clock = 1000000 ) // Reloj de 1 MHz #BYTE TRISB = 0x86 // Asignamos a la etiqueta TRISB la dirección 86h de memoria RAM. #BYTE TRISA = 0x85 // Asignamos a la etiqueta TRISA la dirección 85h de memoria RAM. #BYTE portB = 0x06 // Asignamos a la etiqueta portB la dirección 06h de memoria RAM. #BYTE portA = 0x05 // 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 = 0B00000000; // Defines Puerto B como SALIDA de datos.

Page 43: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Aprendizaje de la Electrónica a través de la Robótica - ARCE -

Microcontroladores IES Joan Miró Página 43

TRISA = 0B11111111; // 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.

5.3.2.1.2.- 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 = 1000000 ) // Reloj de 1 MHz #BYTE TRISB = 0x86 // Asignamos a la etiqueta TRISB la dirección 86h de memoria RAM. #BYTE TRISA = 0x85 // Asignamos a la etiqueta TRISA la dirección 85h de memoria RAM. #BYTE portB = 0x06 // Asignamos a la etiqueta portB la dirección 06h de memoria RAM. #BYTE portA = 0x05 // Asignamos a la etiqueta portA la dirección 05h de memoria RAM. #BIT RB0 = 0x06.0 // 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 = 0B00000000; // Defines Puerto B como SALIDA de datos. RISA = 0B11111111; // Defines Puerta A como ENTRADA de datos. portB = 0; // Reseteas el puerto B.

while (1) // Ejecuta indefinidamente lo que está entre corchetes. if(portA<=7) // Si portA es menor o igual que 7 realiza lo que está entre corchetes. RB0 = 1; // Encender el Led de RBO. else // Si portA es mayor que 7 realiza lo que está entre corchetes. RB0 = 0; // Apagar el Led de RBO.

Page 44: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Aprendizaje de la Electrónica a través de la Robótica - ARCE -

Microcontroladores IES Joan Miró Página 44

5.3.2.1.3.- 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 = 1000000 ) // Reloj de 1 MHz #BYTE TRISB = 0x86 // Asignamos a la etiqueta TRISB la dirección 86h de memoria RAM. #BYTE TRISA = 0x85 // Asignamos a la etiqueta TRISA la dirección 85h de memoria RAM. #BYTE portB = 0x06 // Asignamos a la etiqueta portB la dirección 06h de memoria RAM. #BYTE portA = 0x05 // 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 = 0B11111111; // Defines Puerto A como ENTRADA de datos. TRISB = 0B00000000; // Defines Puerto B como SALIDA de datos. portB = 0B00000000; // Reseteamos el Puerto B. while (1) // Ejecuta indefinidamente lo que está entre corchetes. if(portA<=9) // 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 = 0B11111001; // Poner la letra E

Page 45: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Aprendizaje de la Electrónica a través de la Robótica - ARCE -

Microcontroladores IES Joan Miró Página 45

5.3.2.1.4.- 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=0B00000000 aparecera en el Display 7Seg "0" parapadenado con una cadencia de 1 Seg. // // Si portA=0B00000001 aparecera en el Display 7Seg "1" parapadenado con una cadencia de 0,5 Seg. // // Si portA=0B00000010 aparecera en el Display 7Seg "2" parapadenado con una cadencia de 0,25 Seg. // // Si portA=0B00000011 aparecera en el Display 7Seg "3" parapadenado con una cadencia de 0,1 Seg. // // Si portA>0B00000011 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> // Elección del uC 16F877A #fuses XT,NOWDT,NOPROTECT,NOLVP #use delay( clock = 1000000 ) // Reloj de 1 MHz #BYTE TRISB = 0x86 // Asignamos a la etiqueta TRISB la dirección 86h de memoria RAM. #BYTE TRISA = 0x85 // Asignamos a la etiqueta TRISA la dirección 85h de memoria RAM. #BYTE portB = 0x06 // Asignamos a la etiqueta portB la dirección 06h de memoria RAM. #BYTE portA = 0x05 // 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 = 0B00000000; // Defines Puerto B como SALIDA de datos. TRISA = 0B11111111; // Defines Puerta A como ENTRADA de datos. portB = 0; // reseteas el puerto B. while (1) // Ejecuta indefinidamente lo que está entre corchetes.

switch (portA) // Preguntamos por portA case 0: // Si portA=0 realiza lo que viene a continuación. portB = DISPLAY [0]; // Mostramos en el Puerto B el valor que tiene

// DISPLAY[0]. delay_ms(1000); // Retardo de 1 Segundo. portB = 0; // Apagar Display. delay_ms(1000); // Retardo de 1 Segundo. break; // No realiza los siguientes casos.

case 1: // Si portA=1 realiza lo que viene a continuación portB = DISPLAY[1]; // Mostramos en el Puerto B el valor que tiene // DISPLAY[1]. delay_ms(500); // Retardo de 0,5 Segundos. portB = 0; // Apagar Display. delay_ms(500); // Retardo de 0,5 Segundos. break; // 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

Page 46: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Aprendizaje de la Electrónica a través de la Robótica - ARCE -

Microcontroladores IES Joan Miró Página 46

// DISPLAY[2]. delay_ms(250); // Retardo de 0,25 Segundos. portB = 0; // Apagar Display. delay_ms(250); // Retardo de 0,25 Segundos. break; // No realiza los siguientes casos. case 3: // Si portA=3 realiza lo que viene a continuación portB = DISPLAY [3]; // Mostramos en el Puerto B el valor que tiene // DISPLAY[3]. delay_ms(100); // Retardo de 0,1 Segundos. portB = 0; // Apagar Display. delay_ms(100); // Retardo de 0,1 Segundos. break; // No realiza los siguientes casos. default: // Si portA>3 realiza lo que viene a continuación portB = 0; // Apagar Display.

5.3.2.1.5.- 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 = 1000000 ) // Reloj de 1 MHz #BYTE TRISC = 0x87 // Asignamos a la etiqueta TRISC la dirección 87h de memoria RAM. #BYTE portC = 0x07 // Asignamos a la etiqueta portC la dirección 07h de memoria RAM. #BYTE TRISB = 0x86 // Asignamos a la etiqueta TRISB la dirección 86h de memoria RAM. #BYTE portB = 0x06 // Asignamos a la etiqueta portB la dirección 06h de memoria RAM. #BYTE TRISA = 0x85 // Asignamos a la etiqueta TRISA la dirección 85h de memoria RAM. #BYTE portA = 0x05 // Asignamos a la etiqueta portA la dirección 05h de memoria RAM. #BIT rc0 = 0X07.0 // Asignamos a la etiqueta rc0 el bit 0 de la dirección 07h de la memoria RAM. #BIT t0cki = 0X05.4 // 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 = 0B10000001; // Defines Puerto C como SALIDA de datos a excepción de

// RC7 y RC0. TRISA = 0B11111111; // Defines Puerto A como ENTRADA de datos. TRISB = 0B00000000; // Defines Puerto B como SALIDA de datos. portB = DISPLAY[0]; // Ponemos en el Display de 7Seg. "0".

Page 47: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Aprendizaje de la Electrónica a través de la Robótica - ARCE -

Microcontroladores IES Joan Miró Página 47

while (1) // Ejecuta indefinidamente lo que está entre corchetes.

WHILE(rc0==1) // 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]; // Mostramos en el Puerto D el valor que tiene // DISPLAY[n]. delay_ms(1000); // 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]; // Mostramos en el Puerto D el valor que tiene // DISPLAY[n]. delay_ms(1000); // Retardo de 1 Segundo.

5.3.2.2.- Simulador de Periféricos y Potencia.

Page 48: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Aprendizaje de la Electrónica a través de la Robótica - ARCE -

Microcontroladores IES Joan Miró Página 48

5.3.2.2.1.- 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 = 1000000 ) // Reloj de 1 MHz #include <flex_lcd.c> // Incluimos el driver flex_lcd.c que contiene las funciones de control

// del LCD. #BIT TA0 = 0X85.0 // Asignamos TA0 el bit 0 de la dirección asociada a TRISA. #BIT RA0 = 0X05.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;

// **************************** Función principal o programa principal ****************************** void main()

lcd_init(); // Inicializamos el LCD. TA0 = 1; // Configuramos la patilla RA0 com entrada de datos while(1) lcd_gotoxy(1,1); // Posicionamos el Cursor del LCD en la posición 1 línea 1 . if(RA0==ON) if (cambio==0) printf(lcd_putc, "Encendido"); // Escribimos la palabra "Encendido". contador++; lcd_gotoxy(11,1); printf(lcd_putc,"%3u",contador); cambio=1; delay_ms(50); else printf(lcd_putc, "Apagado "); // Escribimos la palabra "Apagado ". cambio=0; delay_ms(50);

Page 49: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Aprendizaje de la Electrónica a través de la Robótica - ARCE -

Microcontroladores IES Joan Miró Página 49

5.3.2.2.2.- 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 = 1000000 ) // Reloj de 1 MHz #include <flex_lcd.c> // Incluimos el driver flex_lcd.c que contiene las funciones de control del LCD. #BYTE TRISB = 0x86 // Asignamos a la etiqueta TRISB la dirección 86h de memoria RAM. #BYTE portB = 0x06 // 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(); // Inicializamos el LCD. TC0 = 1; // Configuramos la patilla RA0 com entrada de datos TRISB = 0B00000000; // Defines Puerto B como SALIDA de datos. portB = DISPLAY[0]; 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); // Posicionamos el Cursor del LCD en la // posición 11 línea 1 . printf(lcd_putc,"%3u",contador); // Escribimos 3 dígitos de la variable

// "contador" en formato entero y sin // signo.

portB = DISPLAY[contador]; // Mostramos en el Puerto B el valor

// que tiene la tabla DISPLAY[n] cambio=1; // Cambiamos la variable. delay_ms(50); // Espereramos 50 mS. else printf(lcd_putc, "Apagado "); // Escribimos la palabra "Apagado ". cambio=0; // Cambiamos la variable. delay_ms(50); // Espereramos 50 mS.

Page 50: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Aprendizaje de la Electrónica a través de la Robótica - ARCE -

Microcontroladores IES Joan Miró Página 50

5.3.2.3.- Simulador de Potencia.

5.3.2.3.1.- 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 = 1000000 ) // 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(); // Inicializamos el LCD. TRISC=0B10000001; // Ponemos el Puerto C como ENTRADA de

// datos a excepción de RC7. while(1) lcd_gotoxy(1,1); // Posicionamos el Cursor del LCD en la posición 1 línea 1 . if(pulsador==ON) printf(lcd_putc, "Encendido"); // Escribimos la palabra "Encendido". else printf(lcd_putc, "Apagado "); // Escribimos la palabra "Apagado ".

Page 51: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Aprendizaje de la Electrónica a través de la Robótica - ARCE -

Microcontroladores IES Joan Miró Página 51

5.3.3.- 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

Page 52: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Aprendizaje de la Electrónica a través de la Robótica - ARCE -

Microcontroladores IES Joan Miró Página 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 = ±

LSB

Error = ± 2,4 mV.

La relación existente entre tensiones de entrada Ve y códigos digitales de salida D se refleja en la siguiente tabla.

Una fórmula válida para trabajar sería: Ve =

Ejemplo: (Trabajando con tensiones comprendidas entre VREF+ = 5V y VREF+ = 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

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).

Ve Código Digital de salida del Conversor

Analógico/Digital D9 D8 D7 D6 D5 D4 D3 D2 D1 D0

D Nº Decimal

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

0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 1 0 0

1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1

0 1 2 3 4

1022 1023

PCFG(3..0) AN7 AN6 AN5 AN4 AN3 AN2 AN1 AN0 VREF+ VREF-

0000 A A A A A A A A VDD GND

0001 A A A A VREF+ A A A AN3D GND

0010 D D D A A A A A VDD GND

0011 D D D A VREF+ A A A AN3 GND

0100 D D D D A D A A VDD GND

0101 D D D D VREF+ D A A AN3 GND

011X D D D D D D D D - -

1000 A A A A VREF+ VREF- A A AN3 AN2

1001 D D A A A A A A VDD GND

1010 D D A A VREF+ A A A AN3 GND

1011 D D A A VREF+ VREF- A A AN3 AN2

1100 D D D A VREF+ VREF- A A AN3 AN2

1101 D D D D VREF+ VREF- A A AN3 AN2

1110 D D D D D D D A VDD GND

1111 D D D D VREF+ VREF- D A AN3 AN2

Page 53: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Aprendizaje de la Electrónica a través de la Robótica - ARCE -

Microcontroladores IES Joan Miró Página 53

5.3.3.1.- Conversión A-D_D-A

RA0/AN02

RA1/AN13

RA2/AN2/VREF-4

RA4/T0CKI6

RA5/AN4/SS7

OSC1/CLKIN9

OSC2/CLKOUT10

RC1/T1OSI/CCP212

RC2/CCP113

RC3/SCK/SCL14

RB7/PGD28

RB6/PGC27

RB526

RB425

RB3/PGM24

RB223

RB122

RB0/INT21

RC7/RX/DT18

RC6/TX/CK17

RC5/SDO16

RC4/SDI/SDA15

RA3/AN3/VREF+5

RC0/T1OSO/T1CKI11

MCLR/Vpp/THV1

U1

PIC16F876

C1

15p

C2

15p

X1CRYSTAL

4MHz

VDD

A

B

OSCILOSCOPIO

AM FM

+

-

GENERADOR DE FUNCIONES

V entrada

VOUT

VREF+

VREF-

LE

D0

D1

D2

D3

D4

D5

D6

D7

CONVERSOR DIGITAL/ANALÓGICO

DAC_8

R25k

R15k

VDD

VDD

V salida

V ENTRADA

V SALIDA

Page 54: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Aprendizaje de la Electrónica a través de la Robótica - ARCE -

Microcontroladores IES Joan Miró Página 54

5.3.3.1.1.- 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=4000000) //#use delay(clock=20000000) // 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 = 0B00000000; // Defines Puerto C como SALIDA de datos. portC = 0; setup_adc_ports(0); // Seleccionamos el Puerto A como entradas Analógicas. // Mirar ADCON1. setup_adc(ADC_CLOCK_INTERNAL); // 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) // Bucle infinito. delay_us(5); // Retardo de 20uS necesaria para respetar el tiempo de

// Adquisicion Tad. // delay_us(1); q = read_adc(); // Lectura canal 0 "AN0" portC = q;

Page 55: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Aprendizaje de la Electrónica a través de la Robótica - ARCE -

Microcontroladores IES Joan Miró Página 55

5.3.3.2.- 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.

5.3.3.2.1.- 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 // Conversor Analogico Digital de 10 bit el PIC 16F876A puede trabajar con 8 o 10 bit de resolucion.

#FUSES XT,NOWDT #use delay(clock=1000000)

#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(); // Inicializamos el LCD. setup_adc_ports(2); // Seleccionamos el Puerto A como entradas Analógicas.

Mirar ADCON1. setup_adc(ADC_CLOCK_INTERNAL); // Fuente de reloj RC interno. set_adc_channel(0); // Habilitación canal 0 "AN0" for (;;) // Bucle infinito.

delay_us(20); // Retardo de 20uS necesaria para respetar el tiempo de // Adquisición Tad.

q = read_adc(); // Lectura canal 0 "AN0"

Page 56: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Aprendizaje de la Electrónica a través de la Robótica - ARCE -

Microcontroladores IES Joan Miró Página 56

v = 5.0 * q / 1024.0; // Conversión a tensión del código digital "q". printf(lcd_putc, "ADC = %4lu", 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".

5.3.3.2.2.- 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=1000000) #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); // Fuente de reloj RC interno. setup_adc_ports(2); // Seleccionamos el Puerto A como entradas Analógicas.

// Mirar ADCON1. lcd_init(); // Inicializamos el LCD. while (true) // Bucle infinito. set_adc_channel(0); // Habilitación canal 0 "AN0" delay_us(20); // Retardo de 20uS necesaria para respetar el

// Tiempo de Adquisición Tad. q = read_adc(); // Lectura canal 0 "AN0" p = 5.0 * q / 1024.0; // 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); // Habilitación canal 3 "AN3" delay_us(20); // Retardo de 20uS necesaria para respetar el

// Tiempo de Adquisición Tad. q = read_adc(); // Lectura canal 1 "AN1" p = 5.0 * q / 1024.0; // 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".

Page 57: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Aprendizaje de la Electrónica a través de la Robótica - ARCE -

Microcontroladores IES Joan Miró Página 57

5.3.3.2.3.- 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 // Conversor Analogico Digital de 10 bit el PIC 16F877A puede trabajar

// con 8 o 10 bit de resolucion. #FUSES XT,NOWDT #use delay(clock=1000000) #include <flex_lcd.c> // 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); // Fuente de reloj RC interno. setup_adc_ports(4); // Seleccionamos el Puerto A como entradas Analógicas.

// Mirar ADCON1. lcd_init(); // Inicializamos el LCD. TA2=1;

Page 58: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Aprendizaje de la Electrónica a través de la Robótica - ARCE -

Microcontroladores IES Joan Miró Página 58

while (true) // Bucle infinito. if(RA2 == 1) // si RA2=1 se pone en funcionamiento pot R17A set_adc_channel(0); // Habilitación canal 0 "AN0" delay_us(20); // Retardo de 5uS necesaria para respetar el // Tiempo de Adquisición Tad. q = read_adc(); // Lectura canal 0 "AN0" p = 5.0 * q / 1024.0; // 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".

else set_adc_channel(3); // Habilitación canal 3 "AN3" delay_us(20); // Retardo de 5uS necesaria para respetar el

// Tiempo de Adquisición Tad. q = read_adc(); // Lectura canal 1 "AN1" p = 5.0 * q / 1024.0; // 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".

5.3.4.- Modulación por Anchura de Pulso (PWM).

5.3.4.1.- 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 TH de la señal, es

decir variando su ciclo de trabajo CT= TH/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.

Page 59: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Aprendizaje de la Electrónica a través de la Robótica - ARCE -

Microcontroladores IES Joan Miró Página 59

Utilizaremos el entrenador Simulador Potencia.DSN, contenidos en la carpeta de PWM\Control de Motores de CC\Motores de CC.

V motor

t (mSeg)

V motor

t (mSeg)

V motor

t (mSeg)

V motor

t (mSeg)

V motor

t (mSeg)

0%

80%

20%

50%

100%

(Motor Parado)

(Velocidad Máxima)

T

TH

TH

T

T

T

TH

TH

T

TH

CT =TH

T=

16 32

16 32

16 32

16 32

16 32

3,2

8

x 100

12,8

0 mS

16 mS= 0 %

CT =TH

T=x 100

3,2 mS

16 mS= 20 %

CT =TH

T=x 100

8 mS

16 mS= 50 %

CT =TH

T=x 100

12,8 mS

16 mS= 80 %

CT =TH

T=x 100

16 mS

16 mS= 100 %

5v

5v

5v

5v

Vmedia= 0% x 5v = 0v

Vmedia= 20% x 5v = 1v

Vmedia= 50% x 5v = 2,5v

Vmedia= 80% x 5v = 4v

Vmedia= 100% x 5v = 5v

Page 60: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Aprendizaje de la Electrónica a través de la Robótica - ARCE -

Microcontroladores IES Joan Miró Página 60

5.3.4.1.1.- 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> // Incluye el fichero 16F877A al programa tiene que estar en la misma carpeta // del programa define funciones, patillas y registros. #fuses XT,NOWDT // Define la palabra de configuración del microcontrolador PIC // Trabaja con un reloj tipo XT y no utiliza perro guardián Wathdog #use delay( clock = 1000000 ) // Define la frecuencia del reloj de 1 MHz #BYTE TRISC = 0x87 // Asignamos TRISC a la dirección 87h

// (Registro de configuración del Puerto C). #BYTE portC = 0x07 // Asignamos portC a la dirección 07h (Puerto de entrada y salida). #BYTE TRISB = 0x86 // Asignamos TRISB a la dirección 86h

// (Registro de configuración del Puerto A). #BYTE portB = 0x06 // Asignamos portB a la dirección 06h (Puerto de entrada y salida). #BIT giro_d = 0x06.3 // Asignamos "giro_d" a la patilla 3 del Puerto B del

// Microcontrolador PIC 16f876a. #BIT en2 = 0x07.2 // Asignamos "en2" a la patilla 2 del Puerto C del Microcontrolador PIC 16f876a.

Page 61: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Aprendizaje de la Electrónica a través de la Robótica - ARCE -

Microcontroladores IES Joan Miró Página 61

// *************************** Función principal o programa principal ******************************* void main()

// *********************** Configuración de los Puertos del PIC y reseteos del Rastreador ******************** TRISC = 0B10000001; // Defines Puerto C como SALIDA de datos a excepción de RC7/Rx y RC0 TRISB = 0B00000000; // Defines Puerto B como SALIDA de datos. / / ************************************************* Inicio ***************************************************************** while (1) // Ejecuta indefinidamente lo que está entre corchetes. en2 = 1; // Activamos Motor Derecho.MOT2 giro_d=0; // 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; // Activamos Motor Derecho. giro_d=1; // 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.

5.3.4.1.2.- 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> // Incluye el fichero 16F877A al programa tiene que estar en la misma

// carpeta del programa define funciones, patillas y registros. #fuses XT,NOWDT // Define la palabra de configuración del microcontrolador PIC // Trabaja con un reloj tipo XT y no utiliza perro guardián Wathdog #use delay( clock = 1000000 ) // Define la frecuencia del reloj de 4 MHz #BYTE TRISB = 0x86 // Asignamos TRISB a la dirección 86h

// (Registro de configuración del Puerto A). #BYTE portB = 0x06 // Asignamos portB a la dirección 06h (Puerto de entrada y salida). #BYTE TRISC = 0x87 // Asignamos TRISC a la dirección 87h

// (Registro de configuración del Puerto C). #BYTE portC = 0x07 // Asignamos portC a la dirección 07h (Puerto de entrada y salida). #BIT giro_d = 0x06.3 // Asignamos "giro_d" a la patilla RB3 del Microcontrolador PIC 16f876a.

Page 62: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Aprendizaje de la Electrónica a través de la Robótica - ARCE -

Microcontroladores IES Joan Miró Página 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/1.000.000 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); // CCP2 en modo PWM (Salida por RC2)(Motor Derecho)MOT2 TRISC = 0B10010001; // Defines Puerto C como SALIDA de datos a excepción de

// RC7, RC4 Y RCO. set_pwm1_duty(i); // Refresca el nivel alto de la señal PWM.

// Salida por RC2. (Motor Derecho) TRISB = 0B00000000; // Defines Puerto B como SALIDA de datos. // ************************************************** Inicio **************************************************************** while (1) // Ejecuta indefinidamente lo que está entre corchetes. giro_d=0; // Motor Derecho hacia adelante. for(i=0;i<=1000;i=i+100) set_pwm1_duty(i); // Refresca el nivel alto de la señal PWM. Salida por RC2.

// (Motor Derecho) delay_ms(1000); // 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); // Refresca el nivel alto de la señal PWM. Salida por RC2. // (Motor Derecho) delay_ms(1000); // Retardo de 1 segundo. Este tiempo tiene que ser superior

// al periodo de la señal "T= 16 ms".

5.3.4.1.3.- 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 // /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

Page 63: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Aprendizaje de la Electrónica a través de la Robótica - ARCE -

Microcontroladores IES Joan Miró Página 63

// *********************************** Directiva de Preprocesado ************************************** // (Controlan la conversión del programa a código máquina por parte del compilador) #include <16F877A.h> // Incluye el fichero 16F877A al programa tiene que estar en la misma

// carpeta del programa define funciones, patillas y registros. #fuses XT,NOWDT // Define la palabra de configuración del microcontrolador PIC // Trabaja con un reloj tipo XT y no utiliza perro guardián Wathdog #use delay( clock = 1000000 ) // Define la frecuencia del reloj de 4 MHz #BYTE TRISB = 0x86 // Asignamos TRISB a la dirección 86h

// (Registro de configuración del Puerto A). #BYTE portB = 0x06 // Asignamos portB a la dirección 06h (Puerto de entrada y salida). #BYTE TRISC = 0x87 // Asignamos TRISC a la dirección 87h

// (Registro de configuración del Puerto C). #BYTE portC = 0x07 // Asignamos portC a la dirección 07h (Puerto de entrada y salida). #BIT giro_d = 0x06.3 // Asignamos "giro_d" a la patilla RB3 del Microcontrolador PIC 16f876a. // ************************************************** Declaración de funciones *************************************************** void Inicio_PWM(void); // Inico señal PW void Refresco_PWM(void); // 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 = 0B00000000; // Defines Puerto B como SALIDA de datos. // ****************************************************** Inicio ************************************************************ while (1) // Ejecuta indefinidamente lo que está entre corchetes. giro_d=0; // Motor Derecho hacia adelante. Refresco_PWM(); giro_d=1; // Motor Derecho hacia atrás. Refresco_PWM(); // **************************************************** 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/1.000.000 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); // CCP2 en modo PWM (Salida por RC2)

//(Motor Derecho)MOT2 TRISC = 0B10010001; // Defines Puerto C como SALIDA de datos a excepción

// de RC7, RC4 Y RCO. set_pwm1_duty(i); // Refresca el nivel alto de la señal PWM. Salida por RC2. // (Motor Derecho)

Page 64: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Aprendizaje de la Electrónica a través de la Robótica - ARCE -

Microcontroladores IES Joan Miró Página 64

//************************************************** Funcion Refresco_PWM ****************************************************** void Refresco_PWM(void) int16 i=0; for(i=0;i<=1000;i=i+100) set_pwm1_duty(i); // Refresca el nivel alto de la señal PWM. Salida por RC2. (Motor Derecho) delay_ms(1000); // Retarodo de 1 segundo.

5.3.4.1.4.- 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> // Incluye el fichero 16F876A al programa tiene que estar en la misma

// carpeta del programa define funciones, patillas y registros. #fuses XT,NOWDT // Define la palabra de configuración del microcontrolador PIC // Trabaja con un reloj tipo XT y no utiliza perro guardián Wathdog #use delay( clock = 1000000 ) // Define la frecuencia del reloj de 4 MHz #BYTE TRISC = 0x87 // Asignamos TRISC a la dirección 87h

// (Registro de configuración del Puerto C). #BYTE portC = 0x07 // Asignamos portC a la dirección 07h (Puerto de entrada y salida). #BYTE TRISB = 0x86 // Asignamos TRISB a la dirección 86h

// (Registro de configuración del Puerto A). #BYTE portB = 0x06 // Asignamos portB a la dirección 06h (Puerto de entrada y salida). #BIT giro_d = 0x06.3 // Asignamos "giro_d" a la patilla 3 del Puerto B del

// Microcontrolador PIC 16f876a. #BIT giro_i = 0x06.2 // Asignamos "giro_i" a la patilla 2 del Puerto B del

// Microcontrolador PIC 16f876a. // ******************************************** Declaración de funciones ********************************************************* void Inicio_PWM(void); // Inico señal PW void Refresco_PWM(void); // 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 = 0B00000000; // Defines Puerto B como SALIDA de datos. // ****************************************************** Inicio ************************************************************ while (1) // Ejecuta indefinidamente lo que está entre corchetes. giro_d=0; // Motor Derecho hacia adelante. giro_i=0; // Motor Izquierdo hacia adelante. Refresco_PWM();

Page 65: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Aprendizaje de la Electrónica a través de la Robótica - ARCE -

Microcontroladores IES Joan Miró Página 65

giro_d=1; // Motor Derecho hacia atrás. giro_i=1; // Motor Izquierdo hacia atrás. Refresco_PWM(); // ************************************************ 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/1.000.000 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); // CCP2 en modo PWM (Salida por RC2)

// (Motor Derecho)MOT2 setup_ccp2(CCP_PWM); // CCP2 en modo PWM (Salida por RC1)

// (Motor Derecho)MOT1 TRISC = 0B10010001; // Defines Puerto C como SALIDA de datos a

// excepción de RC7, RC4 Y RCO. set_pwm1_duty(i); // Refresca el nivel alto de la señal PWM. Salida por RC2. // (Motor Derecho) set_pwm2_duty(i); // 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); // Refresca el nivel alto de la señal PWM.Salida por RC1. (Motor Izquierdo) set_pwm1_duty(i); // Refresca el nivel alto de la señal PWM.Salida por RC2. (Motor Derecho) delay_ms(1000); // Retardo de 1 segundo.

Page 66: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Aprendizaje de la Electrónica a través de la Robótica - ARCE -

Microcontroladores IES Joan Miró Página 66

5.3.4.2.- 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.

Page 67: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Aprendizaje de la Electrónica a través de la Robótica - ARCE -

Microcontroladores IES Joan Miró Página 67

5.3.4.2.1.- 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=1000000) #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(); // Inicialización del Servo en RC1 Inicializacion_Futaba_RC2(); // Inicialización del Servo en RC2 // While (1); // Vemos posición central. setup_adc(ADC_CLOCK_INTERNAL); // Fuente de reloj RC interno. setup_adc_ports(0); // Seleccionamos el Puerto A como entradas Analógicas.

// Mirar ADCON1.

Page 68: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Aprendizaje de la Electrónica a través de la Robótica - ARCE -

Microcontroladores IES Joan Miró Página 68

while (true) // Bucle infinito.

set_adc_channel(0); // Habilitación canal 0 "AN0" delay_us(5); // Retardo de 20uS necesaria para respetar el tiempo de // Adquisición Tad. TH = read_adc(); // Lectura canal 0 "AN0" Futaba_RC1(TH); // Posicionar el Servo de la patilla RC1. set_adc_channel(3); // Habilitación canal 3 "AN3" delay_us(5); // Retardo de 20uS necesaria para respetar el tiempo de

// Adquisición Tad. TH = read_adc(); // Lectura canal 1 "AN3" Futaba_RC2(TH); // Posicionar el Servo de la patilla RC2.

5.3.4.2.2.- 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(); // Inicializar PWM por RC1 void Inicializacion_Futaba_RC2(); // Inicializar PWM por RC2 void Futaba_RC1(int16 TH); // Generar PWM por RC1 void Futaba_RC2(int16 TH); // 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º

Page 69: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Aprendizaje de la Electrónica a través de la Robótica - ARCE -

Microcontroladores IES Joan Miró Página 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/1.000.000 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); // CCP2 en modo PWM (Salida por RC1) TH = THmed; // Cargar TH con valor medio set_pwm2_duty(TH); // Refrescamos el Tiempo alto TH de la señal. delay_ms(5); // ************************************************* 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/1.000.000 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); // CCP1 en modo PWM (Salida por RC2) TH = THmed; // Cargar TH con valor medio set_pwm1_duty(TH); // Refrescamos el Tiempo alto TH de la señal. delay_ms(5); // *********************************************** Función Futaba_RC1(int16 TH) ************************************************ void Futaba_RC1(int16 TH)

TH = TH+THmin; // Cargar TH con valor mínimo if(TH>THmin && TH<THmax) set_pwm2_duty(TH); // Si THmin < TH < THmax // Refrescamos el Tiempo alto TH de la señal. if(TH<=THmin) // Si TH <= THmin TH=THmin+1; // Cargar TH con valor mínimo

Page 70: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Aprendizaje de la Electrónica a través de la Robótica - ARCE -

Microcontroladores IES Joan Miró Página 70

set_pwm2_duty(TH); // Refrescamos el Tiempo alto TH de la señal. if(TH>=THmax) // Si TH >= THmax TH=THmax-1; // Cargar TH con valor máximo set_pwm2_duty(TH); // 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; // Cargar TH con valor mínimo if(TH>THmin && TH<THmax) set_pwm1_duty(TH); // Si THmin < TH < THmax // Refrescamos el Tiempo alto TH de la señal. if(TH<=THmin) // Si TH <= THmin TH=THmin+1; // Cargar TH con valor mínimo set_pwm1_duty(TH); // Refrescamos el Tiempo alto TH de la señal. if(TH>=THmax) // Si TH >= THmax TH=THmax-1; // Cargar TH con valor máximo set_pwm1_duty(TH); // 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.

5.3.5.- 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.

Page 71: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Aprendizaje de la Electrónica a través de la Robótica - ARCE -

Microcontroladores IES Joan Miró Página 71

5.3.5.1.- 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_RB0.

5.3.5.1.1.- 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= 1000000) #BYTE TRISB = 0x86 // TRISB en 86h. #BYTE portB = 0x06 // PORTB en 06h. #BIT buzzer =0x06.2 // Patilla RB2 buzzer. int8 luces= 0B00001000;

Page 72: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Aprendizaje de la Electrónica a través de la Robótica - ARCE -

Microcontroladores IES Joan Miró Página 72

/* ******************************************** Declaración de funciones ******************************************************* */ void Coche_Fantastico (void); // Coche fantástico. void Pitido (void); // Pitido.

/* ****************************** Función principal o programa principal ************************* */ void main()

TRISB = 0B00000001; // Defines Puerto B como SALIDA de datos a excepción de RB0. portB=luces; delay_ms(100); // retraso. port_b_pullups(TRUE); // Habilitamos resistencias pullup. enable_interrupts(int_ext); // Habilitamos la interrupción INT de la patilla RB0. ext_int_edge(L_TO_H); // Que la interrupción de INT sea por flanco de subida. enable_interrupts(GLOBAL); // 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=0B00001000; int8 n; for(n=0;n<4;n++) luces<<=1; // Movemos un bit a la izquierda portB=luces; delay_ms(500); // retraso.

for(n=4;n>0;n--) luces>>=1; //Movemos un bit a la derecha. portB=luces; delay_ms(500); //Retraso.

Page 73: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Aprendizaje de la Electrónica a través de la Robótica - ARCE -

Microcontroladores IES Joan Miró Página 73

5.3.5.1.2.- 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= 1000000) #BYTE TRISB = 0x86 // TRISB en 86h. #BYTE portB = 0x06 // PORTB en 06h. #BIT altavoz =0x06.1 // Patilla RB1 altavoz. int8 luces=0B00001000; /* ******************************************* Declaración de funciones ******************************************************** */ void Coche_Fantastico (void); // Coche fantástico. void Tono (void); // pitidos. /* ********************************** Función principal o programa principal ************************************************ */ void main()

TRISB = 0B00000001; // 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); // Habilitamos resistencias pullup. enable_interrupts(int_ext); // Habilitamos la interrupción INT de la patilla RB0. ext_int_edge(L_TO_H); // Que la interrupción de INT sea por flanco de subida. enable_interrupts(GLOBAL); // 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 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);

Page 74: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Aprendizaje de la Electrónica a través de la Robótica - ARCE -

Microcontroladores IES Joan Miró Página 74

//for(i=0;i<1000;i++) // Real for(i=0;i<100;i++) // Simulado altavoz=1; delay_us(500); altavoz=0; delay_us(500); /* ************************************************ Coche_Fantastico ************************************************************ */ void Coche_Fantastico (void)

static int8 luces=0B00001000; int8 n=0; for (n=0;n<4;n++) luces<<=1; // Movemos un bit a la izquierda portB=luces; delay_ms(100); // Retraso. for (n=4;n>0;n--) luces>>=1; // Movemos un bit a la derecha. portB=luces; delay_ms(100); // Retraso.

5.3.5.1.3.- Interrupción_INT_RB0b.c

Page 75: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Aprendizaje de la Electrónica a través de la Robótica - ARCE -

Microcontroladores IES Joan Miró Página 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= 1000000) #include <flex_lcd.c> // Incluimos el driver flex_lcd.c que contiene las funciones de control del LCD. #define Numeros_Tabla 3 // 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); // Función Mensaje. void Display_7s (void); // Función Display_7s.

/* *************************** Función principal o programa principal **************************** */ void main()

TRISB = 0B00000001; // Defines Puerto B como SALIDA de datos a excepción de RB0. lcd_init(); // Inicializamos el LCD. port_b_pullups(TRUE); // Habilitamos resistencias pullup. enable_interrupts(int_ext); // Habilitamos la interrupción INT de la patilla RB0. ext_int_edge(L_TO_H); // Que la interrupción de INT sea por flanco de subida. enable_interrupts(GLOBAL); // Habilitamos la Interrupción General. while (1) // Bucle infinito de espera Mensajes(); /* ********************************* 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++) // Se ejecuta un bucle desde n=0 hasta n<Numeros_Tabla en orden //ASCENDENTE de uno en uno portB = DISPLAY[n]; // Mostramos en el Puerto B el valor que tiene la tabla DISPLAY[n] delay_ms(500); // Retardo de 0,5 Segundo. portB = 0B00000000; // Apagar DISPLAY_7SEG.

Page 76: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Aprendizaje de la Electrónica a través de la Robótica - ARCE -

Microcontroladores IES Joan Miró Página 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);

5.3.5.2.- Interrupción por cambio de nivel de RB4_5_6_7.

5.3.5.2.1.- 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 // /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

Page 77: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Aprendizaje de la Electrónica a través de la Robótica - ARCE -

Microcontroladores IES Joan Miró Página 77

// *********************************** Directivas de Preprocesado ************************************ #include <16F876A.h> #fuses XT,NOWDT,PUT,NOWRT #use delay(clock= 4000000) #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); // Activa el Motor. void Led (void); // Encender Led. void Motor_PAP (Void); // Motor_PAP.

/* ************************* Función principal o programa principal ****************************** */ void main()

int n; // Necesario para borrar el flag en el Proteus TRISB = 0B11111111; // Defines Puerto B como ENTRADA de datos. TRISC = 0B00000000; // Defines Puerto C como SALIDA de datos. portC = 0B00000000; // Reseteamos el Puerto C. port_b_pullups(TRUE); // Habilitamos resistencias pullup. n = portB; // Necesario para borrar el flag en el Proteus RBIF = 0; // Necesario para borrar el flag en el Proteus enable_interrupts(int_rb); // Habilitamos la interrupción por cambio de nivel de RB4, RB5, RB6, RB7. enable_interrupts(int_ext); // Habilitamos la interrupción INT de la patilla RB0. ext_int_edge(L_TO_H); // Que la interrupción de INT sea por flanco de subida. enable_interrupts(GLOBAL); // Habilitamos la Interrupción General. while (1) // Bucle infinito de espera Motor_PAP(); /* ********************************* 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.

Page 78: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Aprendizaje de la Electrónica a través de la Robótica - ARCE -

Microcontroladores IES Joan Miró Página 78

/* ********************** Atención a la interrupción por cambio en RB4,RB5,RB6 y RB7. ******************************** */ #INT_RB void Led()

int n; // Necesario en el Proteus, para poder borrar el flag RBIF.

rc4 = ~rc4; // Lee rc4 lo complementa a 1 y lo carga en rc4. n = portB; // Necesario en el Proteus, para poder borrar el flag RBIF. /* *********************************************** Motor Paso a Paso ************************************************************ */ void Motor_PAP (Void)

rc3 = 0; // Posicionamos el Motor PAP en la 1ª Posición. rc2 = 0; rc1 = 0; rc0 = 1; delay_ms(500); // Retardo de 500 ms rc3 = 0; // Posicionamos el Motor PAP en la 2ª Posición. rc2 = 0; rc1 = 1; rc0 = 1; delay_ms(500); // Retardo de 500 ms rc3 = 0; // Posicionamos el Motor PAP en la 3ª Posición. rc2 = 0; rc1 = 1; rc0 = 0; delay_ms(500); // Retardo de 500 ms rc3 = 0; // Posicionamos el Motor PAP en la 4ª Posición. rc2 = 1; rc1 = 1; rc0 = 0; delay_ms(500); // Retardo de 500 ms rc3 = 0; // Posicionamos el Motor PAP en la 5ª Posición. rc2 = 1; rc1 = 0; rc0 = 0; delay_ms(500); // Retardo de 500 ms rc3 = 1; // Posicionamos el Motor PAP en la 6ª Posición. rc2 = 1; rc1 = 0; rc0 = 0; delay_ms(500); // Retardo de 500 ms rc3 = 1; // Posicionamos el Motor PAP en la 7ª Posición. rc2 = 0; rc1 = 0; rc0 = 0; delay_ms(500); // Retardo de 500 ms rc3 = 1; // Posicionamos el Motor PAP en la 8ª Posición. rc2 = 0; rc1 = 0; rc0 = 1; delay_ms(500); // Retardo de 500 ms

Page 79: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Aprendizaje de la Electrónica a través de la Robótica - ARCE -

Microcontroladores IES Joan Miró Página 79

5.3.5.2.1.- 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= 4000000) #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); // Activa el Motor. void Led (void); // Encender Led. void Motor_PAP (Void); // Motor_PAP.

/* ********************** Función principal o programa principal ********************************* */ void main()

int n; // Necesario para borrar el flag en el Proteus TRISB = 0B11111111; // Defines Puerto B como ENTRADA de datos. TRISC = 0B00000000; // Defines Puerto C como SALIDA de datos. portC = 0B00000000; // Reseteamos el Puerto C. port_b_pullups(TRUE); // Habilitamos resistencias pullup. n = portB; // Necesario para borrar el flag en el Proteus RBIF = 0; // Necesario para borrar el flag en el Proteus enable_interrupts(int_rb); // Habilitamos la interrupción por cambio de nivel

// de RB4, RB5, RB6, RB7. enable_interrupts(int_ext); // Habilitamos la interrupción INT de la patilla RB0. ext_int_edge(L_TO_H); // Que la interrupción de INT sea por flanco de subida. enable_interrupts(GLOBAL); // Habilitamos la Interrupción General.

Page 80: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Aprendizaje de la Electrónica a través de la Robótica - ARCE -

Microcontroladores IES Joan Miró Página 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; // Lee rc5 lo complementa a 1 y lo carga en rc5. delay_ms(1000);

/* ******************** Atención a la interrupción por cambio en RB4, RB5, RB6 y RB7. ******************************** */ #INT_RB void Led(void)

int i; // Necesario en el Proteus, para poder borrar el flag RBIF. for(i=0;i<5;i++) rc4 = ~rc4; // Lee rc4 lo complementa a 1 y lo carga en rc4. delay_ms(500); i = portB; // Necesario en el Proteus, para poder borrar el flag RBIF. /* ********************************************** Motor Paso a Paso ************************************************************* */ void Motor_PAP (Void) rc3 = 0; // Posicionamos el Motor PAP en la 1ª Posición. rc2 = 0; rc1 = 0; rc0 = 1; delay_ms(500); // Retardo de 500 ms rc3 = 0; // Posicionamos el Motor PAP en la 2ª Posición. rc2 = 0; rc1 = 1; rc0 = 1; delay_ms(500); // Retardo de 500 ms rc3 = 0; // Posicionamos el Motor PAP en la 3ª Posición. rc2 = 0; rc1 = 1; rc0 = 0; delay_ms(500); // Retardo de 500 ms rc3 = 0; // Posicionamos el Motor PAP en la 4ª Posición. rc2 = 1; rc1 = 1; rc0 = 0; delay_ms(500); // Retardo de 500 ms rc3 = 0; // Posicionamos el Motor PAP en la 5ª Posición. rc2 = 1; rc1 = 0;

Page 81: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Aprendizaje de la Electrónica a través de la Robótica - ARCE -

Microcontroladores IES Joan Miró Página 81

rc0 = 0; delay_ms(500); // Retardo de 500 ms rc3 = 1; // Posicionamos el Motor PAP en la 6ª Posición. rc2 = 1; rc1 = 0; rc0 = 0; delay_ms(500); // Retardo de 500 ms rc3 = 1; // Posicionamos el Motor PAP en la 7ª Posición. rc2 = 0; rc1 = 0; rc0 = 0; delay_ms(500); // Retardo de 500 ms rc3 = 1; // Posicionamos el Motor PAP en la 8ª Posición. rc2 = 0; rc1 = 0; rc0 = 1; delay_ms(500); // Retardo de 500 ms

5.3.6.- 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.

5.3.6.1.- 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.

Page 82: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Aprendizaje de la Electrónica a través de la Robótica - ARCE -

Microcontroladores IES Joan Miró Página 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)

Utilizaremos los entrenadores Simulación Proteus.DSN y Simulación_Periféricos_y_Servos.DSN, contenidos en la carpeta de Timer\ Timer 0.

5.3.6.1.1.- Timer0_Contador.c

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)= 65536 µS.

Page 83: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Aprendizaje de la Electrónica a través de la Robótica - ARCE -

Microcontroladores IES Joan Miró Página 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= 1000000) #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); // Programamos el Timer 0 en modo contador de // pulsos con prescaler de 4 set_timer0(0); // Inicializamos el contador timer 0 con inicio de // cuenta. while (TRUE) // Bucle infinito de espera do contador = get_timer0(); // Leemos el Contador. if(contador!=contador_anterior) // Escribir en el el LCD si contador ha variado. contador_anterior=contador; // Preguntamos si ha llegado el final de

// la cuenta. 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. while(contador<=numero); set_timer0(0); // Inicializamos el contador timer 0 con // inicio de cuenta.

Page 84: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Aprendizaje de la Electrónica a través de la Robótica - ARCE -

Microcontroladores IES Joan Miró Página 84

5.3.6.1.2.- 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= 1000000) #include <Servo_Futaba_10bit.c> // Incluimos el driver que contiene las funciones de control de los Servos

// de Futaba. #BIT TB0 = 0x86.0 // TB0 en la direccón 86.Oh. #BIT RB0 = 0x06.0 // RB0 en la dirección 06.0h. int8 INICIO_CUENTA=61; // Si el periodo de la señal T=200000 uS Cargamos inicio de cuenta con // T/2=100000 uS // T = 100000 uS. // T = Tcm x Preescaler x (256 - INICIO_CUENTA) // Despejando INICIO_CUENTA = 256 - [T/(Tcm x Prescaler)] // Tcm es el tiempo de Ciclo Maquina. Tcm = 4/Fosc = 4/1.000.000 hz = 4uS. // INICIO_CUENTA = 256 - [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

Page 85: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Aprendizaje de la Electrónica a través de la Robótica - ARCE -

Microcontroladores IES Joan Miró Página 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; // Defines RB0 como SALIDA de datos. RB0 = 0; // Apagamos el Led de RB0. Inicializacion_Futaba_RC1(); // 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) // Bucle infinito de espera TH = 0; Futaba_RC1(TH); // Posicionar el Servo de la patilla RC1. delay_ms(500); // Retardo de 0.5 seg. TH = 56; Futaba_RC1(TH); // Posicionar el Servo de la patilla RC1. delay_ms(500); // Retardo de 0.5 seg. /* ******************* Atención a la interrupción por desbordamiento del TIMER 0 ************************************** */ #INT_TIMER0 void Senal_Cuadrada (Void)

RB0 = ~RB0; // Lee RB0 lo complementa a 1 y lo carga en RB0. // Pulsar AltGr 4 y barra espaciadora para el símbolo "~" set_timer0(INICIO_CUENTA); // Inicializamos el Timer 0 para temporizar 0,25 segundos.

5.3.6.1.3.- 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. // /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

Page 86: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Aprendizaje de la Electrónica a través de la Robótica - ARCE -

Microcontroladores IES Joan Miró Página 86

// *********************************** Directivas de Preprocesado ************************************ #include <16F877A.h> #fuses XT,NOWDT,PUT,NOWRT #use delay(clock= 1000000) #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 = 250000 uS. // T = Tcm x Preescaler x (256 - INICIO_CUENTA) // Despejando INICIO_CUENTA = 256 - [T/(Tcm x Prescaler)] // Tcm es el tiempo de Ciclo Maquina.

// Tcm = 4/Fosc = 4/1.000.000 hz = 4uS. // INICIO_CUENTA = 256 - [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 = 0B00000000; // Defines Puerto B como SALIDA de datos. portB = 0b00000001; // 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) // Bucle infinito de espera TH = 0; Futaba_RC1(TH); // Posicionar el Servo de la patilla RC1. delay_ms(500); // Retardo de 0.5 seg. TH = 56; Futaba_RC1(TH); // Posicionar el Servo de la patilla RC1. delay_ms(500); // Retardo de 0.5 seg.

Page 87: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Aprendizaje de la Electrónica a través de la Robótica - ARCE -

Microcontroladores IES Joan Miró Página 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; // Rotamos el portB hacia la izquierda if(portB==128) ir=IZQUIERDA; break; case 1: portB>>=1; // Rotamos el portB hacia la derecha if(portB==1) ir=DERECHA; break; set_timer0(INICIO_CUENTA); // Inicializamos el Timer 0 para temporizar 0,25 segundos.

5.3.6.2.- Timer 1.

Se trata de un temporizador/contador de 16 bits.

La fuente de eventos puede ser interna (Temporizador) o externa (Contador de pulsos, patilla

RC0)

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 65535 el Timer se ha desbordado y el flag TMR1IF se

pone a 1

Page 88: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Aprendizaje de la Electrónica a través de la Robótica - ARCE -

Microcontroladores IES Joan Miró Página 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 (65536 - 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)

Utilizaremos los entrenadores Simulación Proteus.DSN y Simulación_Potencia.DSN, contenidos en la carpeta de Timer\ Timer 1.

5.3.6.2.1.- Timer1_Contador.c

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 (65535 - INICIO_CUENTA) = 1µS. x 8 x (65535-0)= 524280 µS.

Page 89: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Aprendizaje de la Electrónica a través de la Robótica - ARCE -

Microcontroladores IES Joan Miró Página 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= 1000000) #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(); // inicializamos LCD //setup_timer_1(T1_EXTERNAL|T1_DIV_BY_1); // Programamos el Timer 1 en modo contador de

// pulsos; ESTA ES REAL setup_timer_1(T1_EXTERNAL|T1_DIV_BY_2); //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(); // Leemos el Contador. //delay_ms(200); lcd_gotoxy(1,1); // Posicionamos el Cursor del LCD en la posición

// 1 línea 1 . printf(lcd_putc,"%2lu",contador); // Mostramos contador en el LCD. While (contador<= pulsos); // Preguntamos si ha llegado el final de la cuenta.

5.3.6.2.2.- 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 // Conversor Analogico Digital de 10 bit el PIC 16F877A puede trabajar con

// 8 o 10 bit de resolucion. #fuses XT,NOWDT,PUT,NOWRT #use delay(clock= 1000000) #include <flex_lcd.c> // Incluimos el driver LCD1.c que contiene las funciones de control del LCD.

Page 90: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Aprendizaje de la Electrónica a través de la Robótica - ARCE -

Microcontroladores IES Joan Miró Página 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 = 100.000 uS. // El semiperiodo viene definido por

// T = Tcm x Prescaler x (65536 - INICIO_CUENTA) // Despejando INICIO_CUENTA = 65536 - [T/(Tcm x Prescaler)] // Tcm es el tiempo de Ciclo Maquina. Tcm = 4/Fosc = 4/1.000.000 hz = 4uS. // INICIO_CUENTA = 65536 - [100000uS/(4uS x 1)] = 40536 // 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 = 40536 /* ************************************************* 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 = 0B00000000; // Defines Puerto B como SALIDA de datos. portB = 0b00000001; // inicializamos el puerto B. delay_ms(50); // Retraso. //******************************* Inicializar la conversión analógica/digital ***************************************** setup_adc(ADC_CLOCK_INTERNAL); // Fuente de reloj RC interno. setup_adc_ports(4); // 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); // Programamos el Timer 1 en modo temporizador // Con prescaler de 1 set_timer1(INICIO_CUENTA); // 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); // Retraso. for(n=7;n>0;n--) portB>>=1; // Movemos un bit a la derecha. delay_ms(200); // Retraso.

Page 91: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Aprendizaje de la Electrónica a través de la Robótica - ARCE -

Microcontroladores IES Joan Miró Página 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); // Habilitación canal 0 "AN0" delay_us(5); // Retardo de 20uS necesaria para respetar el Tiempo de

// Adquisición Tad. q = read_adc(); // Lectura canal 0 "AN0" p = 5.0 * q / 1024.0; // 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.

5.3.6.3.- 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)

Page 92: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Aprendizaje de la Electrónica a través de la Robótica - ARCE -

Microcontroladores IES Joan Miró Página 92

Postscaler puede valer (1,2, …,16)

Utilizaremos el entrenador Timer2.DSN contenido en la carpeta de Timer\ Timer 2.

5.3.6.3.1.- 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=20000000) #fuses XT,NOWDT #BYTE TRISB = 0x86 // TRISB en 86h. #BYTE portB = 0x06 // PORTB en 06h. #BIT rb0 = 0x06.0 // RB0 en 0x06 patilla 0.

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] = 65536 µS.

Page 93: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Aprendizaje de la Electrónica a través de la Robótica - ARCE -

Microcontroladores IES Joan Miró Página 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 = 0B00000000; // Defines Puerto B como SALIDA de datos. portB = 0B00000000; // 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/20.000.000 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); // Habilita interrupción timer2 enable_interrupts(global); // Habilita interrupción general while (1); // bucle infinito /* ************************** Atención a la interrupción por desbordamiento del TIMER 2 ****************************** */ #int_TIMER2 void Timer2 (void)

rb0 = ~rb0;

5.3.6.3.2.- 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=20000000) #fuses XT,NOWDT #BYTE TRISD = 0x88 // TRISD en 88h. #BYTE portD = 0x08 // PORTD en 08h. #BIT rd0 = 0x08.0 // RD0 en 0x08 patilla 0.

Page 94: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Aprendizaje de la Electrónica a través de la Robótica - ARCE -

Microcontroladores IES Joan Miró Página 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 = 0B00000000; // Defines Puerto D como SALIDA de datos. portD = 0B00000000; // Reseteamos el Puerto D. setup_timer_2(T2_DIV_BY_1,199,1); // 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/20.000.000 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 setup_adc(ADC_CLOCK_INTERNAL); // Fuente de reloj RC interno. setup_adc_ports(0); // Seleccionamos el Puerto A como entradas Analógicas.

// Mirar ADCON1. enable_interrupts(INT_TIMER2); // Habilita interrupción timer2 enable_interrupts(global); // Habilita interrupción general

while (1) // bucle infinito set_adc_channel(0); // Habilitación canal 0 "AN0" delay_us(5); // Retardo de 5uS necesaria para respetar el tiempo de

// Adquisición Tad. h1 = read_adc(); // Lectura canal 0 "AN0" 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); // Habilitación canal 1 "AN1" delay_us(5); // Retardo de 5uS necesaria para respetar el tiempo de // Adquisición Tad. h2 = read_adc(); // Lectura canal 1 "AN1" h2=(h2/5)+15; if(h2>60) h2=60; l2=400-h2; set_adc_channel(2); // Habilitación canal 2 "AN2" delay_us(5); // Retardo de 5uS necesaria para respetar el tiempo de

// Adquisición Tad. h3 = read_adc(); // Lectura canal 2 "AN0" h3=(h3/5)+15; if(h3>60) h3=60; l3=400-h3; set_adc_channel(3); // Habilitación canal 3 "AN3" delay_us(5); // Retardo de 5uS necesaria para respetar el tiempo de

// Adquisición Tad. h4 = read_adc(); // Lectura canal 3 "AN0" h4=(h4/5)+15; if(h4>60) h4=60; l4=400-h4;

Timer2 (h1,l1,h2,l2,h3,l3,h4,l4);

Page 95: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Aprendizaje de la Electrónica a través de la Robótica - ARCE -

Microcontroladores IES Joan Miró Página 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) rd0 = 0; tl1++; else th1=0; tl1=0; // ************************************* Control del Servomotor 2 ******************************** if(th2<h2) rd1 = 1; th2++; else if(tl2<l2) rd1 = 0; tl2++; else th2=0; tl2=0; // ************************************* Control del Servomotor 3 ******************************** if(th3<h3) rd2 = 1; th3++; else if(tl3<l3) rd2 = 0; tl3++; else th3=0; tl3=0;

Page 96: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Aprendizaje de la Electrónica a través de la Robótica - ARCE -

Microcontroladores IES Joan Miró Página 96

// ************************************* Control del Servomotor 4 ******************************** if(th4<h4) rd3 = 1; th4++; else if(tl4<l4) rd3 = 0; tl4++; else th4=0; tl4=0;

5.3.7.- 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.

Page 97: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Aprendizaje de la Electrónica a través de la Robótica - ARCE -

Microcontroladores IES Joan Miró Página 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.

5.3.7.1.- Cable. Utilizaremos el entrenador Simulación del TRANSMISOR-RECEPTOR_Cable.DSN

contenido en la carpeta de Transmisión Serie Asíncrona\ Cable.

Page 98: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Aprendizaje de la Electrónica a través de la Robótica - ARCE -

Microcontroladores IES Joan Miró Página 98

5.3.7.1.1.- 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=1000000) #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 = 0B11111111; // Defines Puerto A como ENTRADA de datos. while(1) // bucle infinito. ra0= portA & 0B00000001; // Filtramos los RA0 if (ra0!=ra0_anterior) // Si varia ra0, transmitimos el dato. ra0_anterior=ra0; // Guardamos el contenido de ra0; if(ra0==0) dato=0B00000001; // dato=1 else dato=0B00001101; // dato=13 putc(dato); // Enviamos vía serie la variable dato. delay_ms(100); // Esperamos 100 mS.

5.3.7.1.2.- 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 // /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

Page 99: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Aprendizaje de la Electrónica a través de la Robótica - ARCE -

Microcontroladores IES Joan Miró Página 99

// ********************************* Directivas de Preprocesado ************************************** #include <16F877A.h> #FUSES XT,NOWDT #use delay(clock=1000000) #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. #include <flex_lcd.c> // 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".

5.3.7.1.3.- 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=1000000) #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. #include <flex_lcd.c> // Incluimos el driver flex_lcd.c que contiene las funciones

// del LCD. #BYTE TRISB = 0x86 // TRISB en 86h. #BYTE portB = 0x06 // PORTB en 06h.

Page 100: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Aprendizaje de la Electrónica a través de la Robótica - ARCE -

Microcontroladores IES Joan Miró Página 100

int8 luces=0B00000001; /* ********************************************** Declaración de funciones ***************************************************** */ void Coche_Fantastico (void); // Simulación Coche fantastico. void Leer_dato_serie (void); // Leer datos via serie

// ************************** Función principal o programa principal ******************************** void main()

TRISB = 0B00000000; // Defines Puerto B como SALIDA de datos. portB = luces; // inicializamos el puerto B. delay_ms(100); // Retraso. lcd_init(); // Inicializamos el LCD. printf(lcd_putc,"IES Joan Miro"); // Escribimos mensaje. enable_interrupts(INT_RDA); // Habilitamos la interrupción serie de datos. enable_interrupts(GLOBAL); // Habilitamos la Interrupción General. while(1) // Bucle sin fin. Coche_Fantastico (); /************************************************** Coche_Fantastico *************************************************************/ void Coche_Fantastico (void)

int8 n=0; for (n=0;n<7;n++) luces<<=1; // Movemos un bit a la izquierda portB=luces; delay_ms(100); // Retraso. for (n=7;n>0;n--) luces>>=1; // Movemos un bit a la derecha. portB=luces; delay_ms(100); // 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".

Page 101: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Aprendizaje de la Electrónica a través de la Robótica - ARCE -

Microcontroladores IES Joan Miró Página 101

5.3.7.1.4.- 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=1000000) #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 = 0B11111111; // Defines Puerto A como ENTRADA de datos. while(1) // bucle infinito. ra0= portA & 0B00000001; // Filtramos los RA0 if (ra0!=ra0_anterior) // Si varia ra0, transmitimos el dato. ra0_anterior=ra0; // Guardamos el contenido de ra0; if(ra0==0) dato=0B00000001; // dato=1 else dato=0B00001101; // dato=13 putc(CLAVE_RA0); // Enviamos vía serie la CLAVE_RA0. delay_ms(5); // Esperamos 5 mS. putc(dato); // Enviamos vía serie la variable dato. delay_ms(50); // Esperamos 5 mS. ra1= portA & 0B00000010; // Filtramos los RA1 if (ra1!=ra1_anterior) // Si varia ra1, transmitimos el dato. ra1_anterior=ra1; // Guardamos el contenido de ra1;

Page 102: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Aprendizaje de la Electrónica a través de la Robótica - ARCE -

Microcontroladores IES Joan Miró Página 102

if(ra1==0) dato=0; // dato=0 else dato=56; // dato=56 putc(CLAVE_RA1); // Enviamos vía serie la CLAVE_RA1. delay_ms(5); // Esperamos 5 mS. putc(dato); // Enviamos vía serie la variable dato. delay_ms(5); // Esperamos 5 mS.

5.3.7.1.5.- 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=1000000) #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. #include <flex_lcd.c> // Incluimos el driver flex_lcd.c que contiene las funciones // del LCD. #include <Servo_Futaba_10bit.c> // Incluimos el driver que contiene las funciones de control de los Servos de Futaba. #BYTE TRISB = 0x86 // TRISB en 86h. #BYTE portB = 0x06 // PORTB en 06h. #define CLAVE_RA0 63 #define CLAVE_RA1 135 int8 luces=0B00000001; /* ********************************************** Declaración de funciones ***************************************************** */ void Coche_Fantastico (void); // Simulación Coche fantastico. void Leer_dato_serie (void); // Leer datos via serie void Mensaje_LCD (int8); // Escribir un mensaje en el LCD void Posicion_Servo (int8); // Posicionar el Sevomotor.

Page 103: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Aprendizaje de la Electrónica a través de la Robótica - ARCE -

Microcontroladores IES Joan Miró Página 103

// **************************** Función principal o programa principal ****************************** void main()

TRISB = 0B00000000; // Defines Puerto B como SALIDA de datos. portB = luces; // inicializamos el puerto B. delay_ms(100); // Retraso. lcd_init(); // Inicializamos el LCD. printf(lcd_putc,"IES Joan Miro"); // Escribimos mensaje. Inicializacion_Futaba_RC1(); // Inicialización del Servo en RC1 enable_interrupts(INT_RDA); // Habilitamos la interrupción serie de datos. enable_interrupts(GLOBAL); // Habilitamos la Interrupción General. while(1) // Bucle sin fin. Coche_Fantastico (); /************************************************** Coche_Fantastico *************************************************************/ void Coche_Fantastico (void)

int8 n=0; for(n=0;n<7;n++) luces<<=1; // Movemos un bit a la izquierda portB=luces; delay_ms(100); // Retraso. for(n=7;n>0;n--) luces>>=1; // Movemos un bit a la derecha. portB=luces; delay_ms(100); // 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)

Page 104: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Aprendizaje de la Electrónica a través de la Robótica - ARCE -

Microcontroladores IES Joan Miró Página 104

caso=IR_SERVO; break; case IR_LCD: Mensaje_LCD (dato_recibido); // Escribir un mensaje en el LCD caso=ES_CLAVE_RA0; break; case IR_SERVO: 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) // Posicionar el Sevomotor.

Futaba_RC1(TH); // Posicionar el Servo de la patilla RC1.

5.3.7.1.6.- 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>

Page 105: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Aprendizaje de la Electrónica a través de la Robótica - ARCE -

Microcontroladores IES Joan Miró Página 105

#FUSES XT,NOWDT #use delay(clock=1000000) #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 = 0B11111111; // Defines Puerto A como ENTRADA de datos. while(1) // bucle infinito. // ****************************** Transmisión de RA0 *************************************************** if (ra0!=ra0_anterior) // Si varia ra0, transmitimos el dato. ra0_anterior=ra0; // Guardamos el contenido de ra0; if(ra0==0) informacion_LCD=0B00000001; // informacion_LCD=1 else informacion_LCD=0B00001101; // informacion_LCD=13 putc(CLAVE_LCD); // Enviamos vía serie la CLAVE_LCD. delay_ms(1); // Esperamos 1 mS. putc(informacion_LCD); // Enviamos vía serie la variable // informacion_LCD. delay_ms(1); // Esperamos 1 mS. // ****************************** Transmisión de RA1 *************************************************** if (ra1!=ra1_anterior) // Si varia ra1, transmitimos el dato. ra1_anterior=ra1; // Guardamos el contenido de ra1; if(ra1==0) informacion_SERVO1=30; // informacion_SERVO=30 else informacion_SERVO1=90; // informacion_SERVO=90 putc(CLAVE_SERVO1); // Enviamos vía serie la CLAVE_SERVO1. delay_ms(1); // Esperamos 1 mS.

Page 106: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Aprendizaje de la Electrónica a través de la Robótica - ARCE -

Microcontroladores IES Joan Miró Página 106

putc(informacion_SERVO1); // Enviamos vía serie la variable //informacion_SERVO1. delay_ms(1); // Esperamos 1 mS. // ****************************** Transmisión de RA2 *************************************************** if (ra2!=ra2_anterior) // Si varia ra2, transmitimos el dato. ra2_anterior=ra2; // Guardamos el contenido de ra2; if(ra2==0) informacion_SERVO2=20; // informacion_SERVO2=20 else informacion_SERVO2=80; // informacion_SERVO2=80 putc(CLAVE_SERVO2); // Enviamos vía serie la CLAVE_SERVO2. delay_ms(1); // Esperamos 1 mS. putc(informacion_SERVO2); // Enviamos vía serie la variable // informacion_SERVO2. delay_ms(1); // Esperamos 1 mS.

5.3.7.1.7.- 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=1000000) #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. #include <flex_lcd.c> // Incluimos el driver flex_lcd.c que contiene las funciones

// del LCD. #include <Servo_Futaba_10bit.c> // Incluimos el driver que contiene las funciones de control

// de los Servos de Futaba.

Page 107: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Aprendizaje de la Electrónica a través de la Robótica - ARCE -

Microcontroladores IES Joan Miró Página 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=0B00000001; /* ********************************************** 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 = 0B00000000; // Defines Puerto B como SALIDA de datos. portB = luces; // inicializamos el puerto B. delay_ms(100); // Retraso. lcd_init(); // Inicializamos el LCD. printf(lcd_putc,"IES Joan Miro"); // Escribimos mensaje. Inicializacion_Futaba_RC1(); // Inicialización del Servo en RC1 Inicializacion_Futaba_RC2(); // Inicialización del Servo en RC2 enable_interrupts(INT_RDA); // Habilitamos la interrupción serie de datos. enable_interrupts(GLOBAL); // Habilitamos la Interrupción General. while(1) // Bucle sin fin. Coche_Fantastico (); /************************************************** Coche_Fantastico *************************************************************/ void Coche_Fantastico (void)

int8 n=0; for(n=0;n<7;n++) luces<<=1; // Movemos un bit a la izquierda portB=luces; delay_ms(100); // Retraso. for(n=7;n>0;n--) luces>>=1; // Movemos un bit a la derecha. portB=luces; delay_ms(100); // 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

Page 108: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Aprendizaje de la Electrónica a través de la Robótica - ARCE -

Microcontroladores IES Joan Miró Página 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: if(dato_recibido==CLAVE_SERVO2) caso=IR_SERVO2; break; case IR_LCD: Mensaje_LCD (dato_recibido); // Escribir un mensaje en el LCD caso=ES_PROCESO_LCD; break; case IR_SERVO1: Posicion_Servo1 (dato_recibido); // Posicionar el Sevomotor 1. caso=ES_PROCESO_LCD; break; case IR_SERVO2: Posicion_Servo2 (dato_recibido); // Posicionar el Sevomotor 2. caso=ES_PROCESO_LCD; break; default: 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".

Page 109: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Aprendizaje de la Electrónica a través de la Robótica - ARCE -

Microcontroladores IES Joan Miró Página 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 RC2.

5.3.7.2.- Radiofrecuencia.

5.3.7.2.0.- 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-0503 genera una señal de AM con esta señal moduladora.

Page 110: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Aprendizaje de la Electrónica a través de la Robótica - ARCE -

Microcontroladores IES Joan Miró Página 110

Page 111: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Aprendizaje de la Electrónica a través de la Robótica - ARCE -

Microcontroladores IES Joan Miró Página 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.

5.3.7.2.1.- 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=4000000)

Page 112: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Curso de Robótica y otras aplicaciones en el Aula de Tecnología

Microcontroladores IES Joan Miró Página 112

#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; // Definimos la variable "i" como tipo byte. int8 q; // Definimos la variable "q" como tipo byte. TRISA = 0B11111111; // Defines Puerto A como ENTRADA de datos.

while(1) // bucle infinito. q= portA & 0B00111111; // Filtramos los 6 bit menos significativos del Puerto A. q=q | 0B11000000; // Le añadimos dos 1 al bit 6 y 7. q=~q; // Invertimos para obtener el resultado en lógica positiva. if (q!=0B00000000) // Si se activa un pulsador, transmitir datos. putc(Clave_Pulsadores); // Enviamos vía serie la Clave_Pulsador. putc(q); // Enviamos vía serie la variable cambio.

5.3.7.2.2.- 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=4000000) #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

Page 113: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Curso de Robótica y otras aplicaciones en el Aula de Tecnología

Microcontroladores IES Joan Miró Página 113

#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; // Definimos la variable "i" como tipo byte. int8 q; // Definimos la variable "q" como tipo byte. TRISA = 0B11111111; // Defines Puerto A como ENTRADA de datos. cambio=0; // Inicializamos la variable cambio con 0. while(1) // bucle infinito. q= portA & 0B00111111; // Filtramos los 5 bit menos significativos del Puerto A. q=q | 0B11000000; // Le añadimos dos 1 al bit 6 y 7. q=~q; // Invertimos para obtener el resultado en lógica positiva. if (q!=0B00000000) // 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++) // Enviamos el dato vía serie, tantas

// veces como diga la variable // Número_Repeticiones

putc(Clave_Pulsadores); // Enviamos vía serie la

// Clave_Pulsador. putc(cambio); // Enviamos vía serie la variable

// cambio. delay_ms(500); // Esperamos un tiempo suficiente hasta dejar de pulsar.

5.3.7.2.3.- 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=4000000) #use rs232(baud=9600,xmit=pin_c6, rcv=pin_c7) // Definimos la velocidad de transmisión de

// 9600 baudios/segundo // Elegimos RC6 como patilla transmisora de datos. // Elegimos RC7 como patilla receptora de datos. #include <flex_lcd.c> // Incluimos el driver flex_lcd.c que contiene las funciones // del LCD.

Page 114: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Curso de Robótica y otras aplicaciones en el Aula de Tecnología

Microcontroladores IES Joan Miró Página 114

#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(); // Inicializamos el LCD. printf(lcd_putc,"IES Joan Miro"); // 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); // Habilitamos la interrupción serie de datos. enable_interrupts(GLOBAL); // Habilitamos la Interrupción General. while(1) // Bucle sin fin. if(dato_valido!=dato_anterior) // Si es el mismo dato no escribir en el LCD. dato_anterior=dato_valido; // Guardamos el dato anterior 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 // "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; // La variable solo valdra 0 la primera vez. static int8 dato1=0; dato_recibido=getc(); // Recibimos el dato serie.

Page 115: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Curso de Robótica y otras aplicaciones en el Aula de Tecnología

Microcontroladores IES Joan Miró Página 115

switch (numero_datos1) // Es un autómata modelo Moore, que valida los datos // si llegan dos tramas iguales consecutivas

case 0: if(dato_recibido==Clave_Pulsadores) numero_datos1=1; break; 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;

5.3.7.3.- Radiofrecuencia Multitarea. Utilizaremos el entrenador TRANSMISOR-RECEPTOR_RF_Multitarea.DSN contenido

en la carpeta de Transmisión Serie Asíncrona\ Radiofrecuencia_Multitarea.

Page 116: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Curso de Robótica y otras aplicaciones en el Aula de Tecnología

Microcontroladores IES Joan Miró Página 116

5.3.7.3.1.- 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=4000000) #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; // Definimos la variable "cambio0" como tipo bit. int8 cambio1=0; // Definimos la variable "cambio1" como tipo bit. int8 i=1; // Definimos la variable "i" como tipo byte. int8 q; // Definimos la variable "q" como tipo byte. TRISB = 0B11111111; // Defines Puerto B como ENTRADA de datos. TC3 = 0; // Defines la patilla 3 Puerto C como SALIDA de datos. RC3 = 1; // Inhabilitamos la tarjeta CEBEK C-0503. 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); // Habilitación canal 0 "AN0" delay_us(20); // Retardo de 20uS necesaria para respetar el tiempo

// de Adquisición Tad. q = read_adc(); // Lectura canal 0 "AN0" if (cambio0!=q) // Si se ha variado el Potenciómetro Derecho transmitir

// dato. cambio0=q; RC3 = 0; // Habilitamos la tarjeta CEBEK C-0503.

Page 117: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Curso de Robótica y otras aplicaciones en el Aula de Tecnología

Microcontroladores IES Joan Miró Página 117

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-0503. //**************** Transmisión de datos "Potenciómetro Izquierdo" *********************** set_adc_channel(1); // Habilitación canal 1 "AN1" delay_us(20); // Retardo de 20uS necesaria para respetar el

// tiempo de Adquisición Tad. q = read_adc(); // Lectura canal 1 "AN1" if (cambio1!=q) // Si se ha variado el Potenciómetro Izquierdo

// transmitir dato. cambio1=q; RC3 = 0; // Habilitamos la tarjeta CEBEK C-0503. 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-0503. //********************* Transmisión de datos "Pulsadores" *********************************** q= portB & 0B00111111; // Filtramos los 5 bit menos significativos del // Puerto B. if (q!=0B00111111) // Si se activa un pulsador, transmitir datos. RC3 = 0; // Habilitamos la tarjeta CEBEK C-0503. for(i=1;i<=Numero_Repeticiones;i++) // Enviamos el dato vía serie, tantas // veces como diga la variable

// Número_Repeticiones putc(Clave_Pulsadores); // Enviamos vía serie la

// Clave_Pulsadores. putc(~q); // Enviamos vía serie la variable q // invertida.(Pulsador Activado) RC3 = 1; // Inhabilitamos la tarjeta CEBEK C-0503.

5.3.7.3.2.- 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. // /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

Page 118: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Curso de Robótica y otras aplicaciones en el Aula de Tecnología

Microcontroladores IES Joan Miró Página 118

// *********************************** Directivas de Preprocesado ************************************ #include <16F876A.h> #device adc=8 #FUSES XT,NOWDT #use delay(clock=4000000) #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; // Definimos la variable "cambio0" como tipo bit. int8 cambio1=0; // Definimos la variable "cambio1" como tipo bit. int8 i=1; // Definimos la variable "i" como tipo byte. int8 q; // Definimos la variable "q" como tipo byte. int1 rb5_1=0; // Definimos la variable "rb5_1" como tipo bit. cambio2=0; // Reseteamos la variable cambio2. TRISB = 0B11111111; // Defines Puerto B como ENTRADA de datos. TC3 = 0; // Defines la patilla 3 Puerto C como SALIDA de datos. RC3 = 1; // Inhabilitamos la tarjeta CEBEK C-0503. 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. //*********************** Transmisión de datos "Potenciómetro Derecho" ***************************** set_adc_channel(0); // Habilitación canal 0 "AN0" delay_us(20); // Retardo de 20uS necesaria para respetar el tiempo de // Adquisición Tad. q = read_adc(); // Lectura canal 0 "AN0"

Page 119: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Curso de Robótica y otras aplicaciones en el Aula de Tecnología

Microcontroladores IES Joan Miró Página 119

if (cambio0!=q) // Si se ha variado el Potenciómetro Derecho transmitir // dato.

cambio0=q; RC3 = 0; // Habilitamos la tarjeta CEBEK C-0503. 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-0503. //******************* Transmisión de datos "Potenciómetro Izquierdo" ******************************** set_adc_channel(1); // Habilitación canal 1 "AN1" delay_us(20); // Retardo de 20uS necesaria para respetar el tiempo de

// Adquisición Tad. q = read_adc(); // Lectura canal 1 "AN1" if (cambio1!=q) // Si se ha variado el Potenciómetro Izquierdo

// transmitir dato. cambio1=q; RC3 = 0; // Habilitamos la tarjeta CEBEK C-0503. 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-0503. //*********************** Transmisión de datos "Pulsadores" ******************************************** q= portB & 0B00011111; // Filtramos los 5 bit menos significativos del Puerto B. if (q!=0B00011111) // 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-0503. for(i=1;i<=Numero_Repeticiones;i++) // Enviamos el dato vía serie, tantas

// veces como diga la variable // Número_Repeticiones

putc(Clave_Pulsadores); // Enviamos vía serie la

// Clave_Pulsadores. putc(cambio2); // Enviamos vía serie la variable

// cambio2. (Pulsador Activado) RC3 = 1; // Inhabilitamos la tarjeta CEBEK C-0503. //**************************** Transmisión de datos "Interruptor" **************************************** if (rb5!=rb5_1) // Si se ha cambiado el Interruptor de la patilla rb5

// transmitir dato. rb5_1=rb5; c5=~rb5;

Page 120: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Curso de Robótica y otras aplicaciones en el Aula de Tecnología

Microcontroladores IES Joan Miró Página 120

RC3 = 0; // Habilitamos la tarjeta CEBEK C-0503. for(i=1;i<=Numero_Repeticiones;i++) // Enviamos el dato vía serie, tantas

// veces como diga a variable // Número_Repeticiones

putc(Clave_Pulsadores); // Enviamos vía serie la // Clave_Pulsadores. putc(cambio2); // Enviamos vía serie la variable

// cambio2. (Interruptor Activado) RC3 = 1; // Inhabilitamos la tarjeta CEBEK C-0503.

5.3.7.3.3.- 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=4000000) #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); // Leer Dato. void Automata_Pulsadores (void); // Valida los datos serie procedentes de los Pulsadores. void Automata_Pot_Der (void); // Valida los datos serie procedentes del Potenciómetro Derecho. void Automata_Pot_Izq (void); // Valida los datos serie procedentes del Potenciómetro Izquierdo.

Page 121: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Curso de Robótica y otras aplicaciones en el Aula de Tecnología

Microcontroladores IES Joan Miró Página 121

// ****************************** Función principal o programa principal **************************** void main()

TRISD = 0B00000000; // Defines Puerto D como SALIDA de datos. TRISC = 0B10000000; // Defines Puerto C como SALIDA de datos // a excepción de RC7/Rx que es entrada de datos. TRISB = 0B00000000; // Defines Puerto B como SALIDA de datos. portD = 0B00000000; // Reseteamos el Puerto D. portC = 0B00000000; // Reseteamos el Puerto C. portB = 0B00000000; // Reseteamos el Puerto B. enable_interrupts(INT_RDA); // Habilitamos la interrupción serie de datos. enable_interrupts(GLOBAL); // Habilitamos la Interrupción General. while(1) // Bucle sin fin. sleep(); // 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) // 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.

case 0: if(dato_recibido==Clave_Pulsadores) numero_datos=1; valido_Aut_Pot_Der=0; valido_Aut_Pot_Izq=0;

Page 122: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Curso de Robótica y otras aplicaciones en el Aula de Tecnología

Microcontroladores IES Joan Miró Página 122

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) // Es un autómata modelo Moore, que valida los datos si llegan dos

// tramas iguales consecutivas. Variaciones del Potenciómetro // Derecho del Transmisor.

case 0: if(dato_recibido==Clave_Pot_Der) numero_datos=1; valido_Aut_Pul=0; valido_Aut_Pot_Izq=0; break; 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;

Page 123: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Curso de Robótica y otras aplicaciones en el Aula de Tecnología

Microcontroladores IES Joan Miró Página 123

/* *********************************************Función Automata_Pot_Izq **************************************************** */ void Automata_Pot_Izq(void)

static int8 numero_datos=0; static int8 dato=0; switch (numero_datos) // Es un autómata modelo Moore, que valida los datos si llegan dos

// tramas iguales consecutivas. Variaciones del Potenciómetro // Izquierdo del Transmisor.

case 0: if(dato_recibido==Clave_Pot_Izq) numero_datos=1; valido_Aut_Pul=0; valido_Aut_Pot_Der=0; break; case 1: dato=dato_recibido; numero_datos=2; break; case 2: 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) portB=dato_recibido; numero_datos=0; valido_Aut_Pul=1; valido_Aut_Pot_Der=1;

5.3.8.- Módulo MSSP.

El módulo MSSP (Master Synchronous Serial Port) es un interfaz de comunicaciones serie. Puede trabajar en dos modos:

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.

5.3.8.1.- I2C.

Funciona en modo maestro ó esclavo. Permite el direccionamiento de 7 bits o de 10 bits. Atiende a la llamada general (dir = 00000000b). 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.

Page 124: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Curso de Robótica y otras aplicaciones en el Aula de Tecnología

Microcontroladores IES Joan Miró Página 124

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, Fi2c = 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.

Page 125: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Curso de Robótica y otras aplicaciones en el Aula de Tecnología

Microcontroladores IES Joan Miró Página 125

5.3.8.1.1.- Expansor_Bus_PCF8574.

El dispositivo es un expansor remoto de 8bits I/O para bus I2C, consiste en un puerto

cuasi bidireccional de 8 bit y una interfaz I2C-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

2C-bus. Esto quiere decir que el

PCF8574 puede seguir siendo un simple dispositivo esclavo.

5.3.8.1.1.1.- PCF8574_1.

Utilizaremos el entrenador PCF8574_1.DSN contenido en la carpeta de I2C\ Expansor_Bus_PCF8574\ PCF8574_1.

Page 126: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Curso de Robótica y otras aplicaciones en el Aula de Tecnología

Microcontroladores IES Joan Miró Página 126

5.3.8.1.1.1.1.- 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= 1000000) #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); // Declaramos la función Lectura_Interruptores

// (Nos devuelve una variable tipo entero de 8 bit) void Escritura(int8); // 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) // Bucle infinito de espera dato_recibido = Lectura_Interruptores(); // Leemos el dato a través del bus I2c del delay_ms(1); // esclavo U4 Escritura(~dato_recibido); // Escribimos el dato a través del bus I2c en el delay_ms(1); // esclavo U3

/* ******************************** Función de int8 Lectura_Interruptores() ************************************************* */ int8 Lectura_Interruptores()

int8 data; i2c_start(); // Inicializa la recepción. i2c_write(0B01000001); // 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); // Lectura del dato i2c_stop(); // 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.

Page 127: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Curso de Robótica y otras aplicaciones en el Aula de Tecnología

Microcontroladores IES Joan Miró Página 127

// (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.

5.3.8.1.1.1.2.- 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= 1000000) #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 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(); // Declaramos la función Lectura_Interruptores (Nos devuelve una

// variable tipo entero de 8 bit) void Escritura(int8); // Declaramos la función Escritura (LLeva una variable asociada de // tipo entero de 8 bit) void Motor_PAP (void); void Lectura_Escritura_PCF8476(void);

/* *************************** Función principal o programa principal **************************** */ void main()

TRISA = 0B00000000; // Defines Puerto A como SALIDA de datos. portA = 0B00101000; // Reseteamos el Puerto A. port_b_pullups(TRUE); // Habilitamos resistencias pullup. enable_interrupts(int_ext); // Habilitamos la interrupción INT de la patilla RB0. ext_int_edge(H_TO_L); // Que la interrupción de INT sea por flanco de BAJADA. INTF = 1; // Forzamos la Interrupción. enable_interrupts(GLOBAL); // Habilitamos la Interrupción General. while (1) // Bucle infinito de espera

Page 128: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Curso de Robótica y otras aplicaciones en el Aula de Tecnología

Microcontroladores IES Joan Miró Página 128

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(); // Leemos el dato a través del bus I2c del esclavo U4 Escritura(~dato_recibido); // Escribimos el dato a través del bus I2c en el esclavo U3 /* ******************************************** Motor Paso a Paso *************************************************************** */ void Motor_PAP (void)

ra3 = 0; // Posicionamos el Motor PAP en la 1ª Posición. ra2 = 0; ra1 = 0; ra5 = 1; delay_ms(500); // Retardo de 500 ms ra3 = 0; // Posicionamos el Motor PAP en la 2ª Posición. ra2 = 0; ra1 = 1; ra5 = 1; delay_ms(500); // Retardo de 500 ms ra3 = 0; // Posicionamos el Motor PAP en la 3ª Posición. ra2 = 0; ra1 = 1; ra5 = 0; delay_ms(500); // Retardo de 500 ms ra3 = 0; // Posicionamos el Motor PAP en la 4ª Posición. ra2 = 1; ra1 = 1; ra5 = 0; delay_ms(500); // Retardo de 500 ms ra3 = 0; // Posicionamos el Motor PAP en la 5ª Posición. ra2 = 1; ra1 = 0; ra5 = 0; delay_ms(500); // Retardo de 500 ms ra3 = 1; // Posicionamos el Motor PAP en la 6ª Posición. ra2 = 1; ra1 = 0; ra5 = 0; delay_ms(500); // Retardo de 500 ms ra3 = 1; // Posicionamos el Motor PAP en la 7ª Posición. ra2 = 0; ra1 = 0; ra5 = 0; delay_ms(500); // Retardo de 500 ms ra3 = 1; // Posicionamos el Motor PAP en la 8ª Posición. ra2 = 0; ra1 = 0;

Page 129: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Curso de Robótica y otras aplicaciones en el Aula de Tecnología

Microcontroladores IES Joan Miró Página 129

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); // Lectura del dato i2c_stop(); // 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); // Dato a escribir i2c_stop(); // Finalización de la transmisión.

5.3.8.1.1.2.- PCF8574_2.

Utilizaremos el entrenador PCF8574_2.DSN contenido en la carpeta de I2C\ Expansor_Bus_PCF8574\ PCF8574_2.

Page 130: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Curso de Robótica y otras aplicaciones en el Aula de Tecnología

Microcontroladores IES Joan Miró Página 130

5.3.8.1.1.2.1.- 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= 1000000) #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) // Bucle infinito de espera dato_recibido = Lectura_Interruptores_1(); // Leemos el dato a través del bus I2c del

// esclavo U3 delay_ms(50); Escritura_Led_1(dato_recibido); // Escribimos el dato a través del bus I2c en el // esclavo U4 delay_ms(50); dato_recibido = Lectura_Interruptores_2(); // Leemos el dato a través del bus I2c del

// esclavo U5 delay_ms(50); Escritura_Led_2(dato_recibido); // Escribimos el dato a través del bus I2c en el

// esclavo U6 delay_ms(50); /* ********************************* Función de int8 Lectura_Interruptores_1() ********************************************* */ int8 Lectura_Interruptores_1()

int8 data; i2c_start(); // Inicializa la recepción. i2c_write(0B01000001); // 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

Page 131: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Curso de Robótica y otras aplicaciones en el Aula de Tecnología

Microcontroladores IES Joan Miró Página 131

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(0B01001011); // 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); // Dato a escribir i2c_stop(); // Finalización de la transmisión.

5.3.8.1.1.2.2.- 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= 1000000) #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

Page 132: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Curso de Robótica y otras aplicaciones en el Aula de Tecnología

Microcontroladores IES Joan Miró Página 132

// 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. #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. #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 = 0B00000000; // Defines Puerto A como SALIDA de datos. TRISB = 0B11111111; // Defines Puerto B como ENTRADA de datos. portA = 0B00101000; // Reseteamos el Puerto A. port_b_pullups(TRUE); // Habilitamos resistencias pullup. enable_interrupts(int_rb); // Habilitamos la interrupción INT de la patilla RB0. enable_interrupts(GLOBAL); // Habilitamos la Interrupcion General. RBIF = 1; // Forzamos la Interrupción. while (1) // Bucle infinito de espera Motor_PAP(); /* ************************************************ Motor Paso a Paso *********************************************************** */ void Motor_PAP (void)

ra3 = 0; // Posicionamos el Motor PAP en la 1ª Posición. ra2 = 0; ra1 = 0; ra5 = 1; delay_ms(500); // Retardo de 500 ms ra3 = 0; // Posicionamos el Motor PAP en la 2ª Posición. ra2 = 0; ra1 = 1; ra5 = 1;

Page 133: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Curso de Robótica y otras aplicaciones en el Aula de Tecnología

Microcontroladores IES Joan Miró Página 133

delay_ms(500); // Retardo de 500 ms ra3 = 0; // Posicionamos el Motor PAP en la 3ª Posición. ra2 = 0; ra1 = 1; ra5 = 0; delay_ms(500); // Retardo de 500 ms ra3 = 0; // Posicionamos el Motor PAP en la 4ª Posición. ra2 = 1; ra1 = 1; ra5 = 0; delay_ms(500); // Retardo de 500 ms ra3 = 0; // Posicionamos el Motor PAP en la 5ª Posición. ra2 = 1; ra1 = 0; ra5 = 0; delay_ms(500); // Retardo de 500 ms ra3 = 1; // Posicionamos el Motor PAP en la 6ª Posición. ra2 = 1; ra1 = 0; ra5 = 0; delay_ms(500); // Retardo de 500 ms ra3 = 1; // Posicionamos el Motor PAP en la 7ª Posición. ra2 = 0; ra1 = 0; ra5 = 0; delay_ms(500); // Retardo de 500 ms ra3 = 1; // Posicionamos el Motor PAP en la 8ª Posición. ra2 = 0; ra1 = 0; ra5 = 1; delay_ms(500); // 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.

Page 134: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Curso de Robótica y otras aplicaciones en el Aula de Tecnología

Microcontroladores IES Joan Miró Página 134

/* **************************** Función de int8 Lectura_Interruptores_1() ************************************************** */ int8 Lectura_Interruptores_1()

int8 data; i2c_start(); // Inicializa la recepción. i2c_write(0B01000001); // 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 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(0B01001011); // 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); // Dato a escribir i2c_stop(); // Finalización de la transmisión.

Page 135: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Curso de Robótica y otras aplicaciones en el Aula de Tecnología

Microcontroladores IES Joan Miró Página 135

5.3.8.1.1.3.- PCF8574_3.

Utilizaremos el entrenador PCF8574_3.DSN contenido en la carpeta de I2C\ Expansor_Bus_PCF8574\ PCF8574_3.

5.3.8.1.1.3.1.- 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 // Conversor Analogico Digital de 8 bit el PIC 16F876A puede trabajar

// con 8 o 10 bit de resolucion. #fuses XT,NOWDT,PUT,NOWRT #use delay(clock= 20000000) // 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.

Page 136: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Curso de Robótica y otras aplicaciones en el Aula de Tecnología

Microcontroladores IES Joan Miró Página 136

#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); // Declaramos la función Escritura

// (LLeva una variable asociada de tipo entero de 8 bit) void Motor_PAP (void); void Lectura_Escritura_PCF8476(void); /* ************************************* Función principal o programa principal ********************************************* */ void main() setup_adc_ports(14); // Seleccionamos el PA0 como entrada Analógica y // PA1..PA5 digitales. Mirar ADCON1. setup_adc(ADC_CLOCK_INTERNAL); // Fuente de reloj RC interno. set_adc_channel(0); // Habilitación canal 0 "AN0" ta1 = 0; // Defines PA1 como SALIDA de datos. ta2 = 0; // Defines PA2 como SALIDA de datos. ta3 = 0; // Defines PA3 como SALIDA de datos. ta4 = 0; // Defines PA4 como SALIDA de datos. ta5 = 0; // 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) // Bucle infinito de espera. Motor_PAP(); // 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); // Retardo de 10 mS. (No es necesario, solo se hace para

// dar tiempo al motor PAP a posicionarse) dato_recibido = read_adc(adc_read_only); // Lectura canal 0 "AN0". (Solo leemos el dato digitalizado) Escritura(dato_recibido); // Escribimos el dato a través del bus I2c en el esclavo U3 read_adc(adc_start_only); // Lanzamos el Conversor A/D.

Page 137: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Curso de Robótica y otras aplicaciones en el Aula de Tecnología

Microcontroladores IES Joan Miró Página 137

/* ******************************************************* Motor Paso a Paso **************************************************** */ void Motor_PAP (void)

ra3 = 0; // Posicionamos el Motor PAP en la 1ª Posición. ra2 = 0; ra1 = 0; ra5 = 1; delay_ms(100); // Retardo de 100 ms ra3 = 0; // Posicionamos el Motor PAP en la 2ª Posición. ra2 = 0; ra1 = 1; ra5 = 1; delay_ms(100); // Retardo de 100 ms ra3 = 0; // Posicionamos el Motor PAP en la 3ª Posición. ra2 = 0; ra1 = 1; ra5 = 0; delay_ms(100); // Retardo de 100 ms ra3 = 0; // Posicionamos el Motor PAP en la 4ª Posición. ra2 = 1; ra1 = 1; ra5 = 0; delay_ms(100); // Retardo de 100 ms ra3 = 0; // Posicionamos el Motor PAP en la 5ª Posición. ra2 = 1; ra1 = 0; ra5 = 0; delay_ms(100); // Retardo de 100 ms ra3 = 1; // Posicionamos el Motor PAP en la 6ª Posición. ra2 = 1; ra1 = 0; ra5 = 0; delay_ms(100); // Retardo de 100 ms ra3 = 1; // Posicionamos el Motor PAP en la 7ª Posición. ra2 = 0; ra1 = 0; ra5 = 0; delay_ms(100); // Retardo de 100 ms ra3 = 1; // Posicionamos el Motor PAP en la 8ª Posición. ra2 = 0; ra1 = 0; ra5 = 1; 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); // Dato a escribir i2c_stop(); // Finalización de la transmisión.

Page 138: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Curso de Robótica y otras aplicaciones en el Aula de Tecnología

Microcontroladores IES Joan Miró Página 138

5.3.8.1.1.3.2.- 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= 20000000) // 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); // Declaramos la función Escritura (LLeva dos variable asociada de tipo entero de 8 bit) int8 Lectura_Interruptores(); // Declaramos la función Lectura_Interruptores // (Nos devuelve una variable tipo entero de 8 bit) void Motor_PAP (void); void Lectura_Escritura_AD_PCF8476(void); void Lectura_Escritura_INT_PCF8476(void);

/* *************************** Función principal o programa principal **************************** */ void main() setup_adc_ports(14); // Seleccionamos el PA0 como entrada Analógica y // PA1..PA5 digitales. Mirar ADCON1. setup_adc(ADC_CLOCK_INTERNAL); // Fuente de reloj RC interno.

Page 139: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Curso de Robótica y otras aplicaciones en el Aula de Tecnología

Microcontroladores IES Joan Miró Página 139

set_adc_channel(0); // Habilitación canal 0 "AN0" ta1 = 0; // Defines PA1 como SALIDA de datos. ta2 = 0; // Defines PA2 como SALIDA de datos. ta3 = 0; // Defines PA3 como SALIDA de datos. ta4 = 0; // Defines PA4 como SALIDA de datos. ta5 = 0; // Defines PA5 como SALIDA de datos. ra1 = 0; // Activamos el Motor PAP y encendemos LED. ra2 = 0; ra3 = 1; ra4 = 0; ra5 = 1; port_b_pullups(TRUE); // Habilitamos resistencias pullup. enable_interrupts(int_ext); // Habilitamos la interrupción INT de la patilla RB0. ext_int_edge(H_TO_L); // Que la interrupción de INT sea por flanco de BAJADA. INTF = 1; // Forzamos la Interrupción. enable_interrupts(int_ad); // Habilitamos la interrupción por Conversión A/D. enable_interrupts(GLOBAL); // Habilitamos la Interrupción General. read_adc(adc_start_only); // Lanzamos el Conversor A/D. while (1) // 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); // Retardo de 10 mS. (No es necesario, solo se hace para // dar tiempo al motor PAP a posicionarse) dato_recibido = read_adc(adc_read_only); // Lectura canal 0 "AN0". (Solo leemos el dato digitalizado) Escritura(dato_recibido,U7); // Escribimos el dato a través del bus I2c en el esclavo U3 read_adc(adc_start_only); // 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(); // Leemos el dato a través del bus I2c del esclavo U4 Escritura(~dato_recibido,U3); // 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(); // Inicializa la transmisión i2c_write(esclavo); // Seleccionar esclavo U3 en modo escritura. // ( 0100,A2,A1,A0,0 ) // (0100) identifica al C.I. PCF8476. // (A2,A1,A0)=(100) por hardware.

Page 140: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Curso de Robótica y otras aplicaciones en el Aula de Tecnología

Microcontroladores IES Joan Miró Página 140

// 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() ****************************************** */ 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); // Lectura del dato i2c_stop(); // Finalización de la transmisión. return(data); /* ********************************************* Motor Paso a Paso ************************************************************** */ void Motor_PAP (void) ra3 = 0; // Posicionamos el Motor PAP en la 1ª Posición. ra2 = 0; ra1 = 0; ra5 = 1; delay_ms(100); // Retardo de 100 ms ra3 = 0; // Posicionamos el Motor PAP en la 2ª Posición. ra2 = 0; ra1 = 1; ra5 = 1; delay_ms(100); // Retardo de 100 ms ra3 = 0; // Posicionamos el Motor PAP en la 3ª Posición. ra2 = 0; ra1 = 1; ra5 = 0; delay_ms(100); // Retardo de 100 ms ra3 = 0; // Posicionamos el Motor PAP en la 4ª Posición. ra2 = 1; ra1 = 1; ra5 = 0; delay_ms(100); // Retardo de 100 ms ra3 = 0; // Posicionamos el Motor PAP en la 5ª Posición. ra2 = 1; ra1 = 0; ra5 = 0; delay_ms(100); // Retardo de 100 ms ra3 = 1; // Posicionamos el Motor PAP en la 6ª Posición. ra2 = 1; ra1 = 0; ra5 = 0; delay_ms(100); // Retardo de 100 ms ra3 = 1; // Posicionamos el Motor PAP en la 7ª Posición. ra2 = 0; ra1 = 0; ra5 = 0;

Page 141: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Curso de Robótica y otras aplicaciones en el Aula de Tecnología

Microcontroladores IES Joan Miró Página 141

delay_ms(100); // Retardo de 100 ms ra3 = 1; // Posicionamos el Motor PAP en la 8ª Posición. ra2 = 0; ra1 = 0; ra5 = 1; delay_ms(100); // Retardo de 100 ms

5.3.8.1.2.- 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.

5.3.8.1.2.1.- PCF8591_ADC.

Utilizaremos el entrenador PCF8591_AD.DSN contenido en la carpeta de I2C\ Conversor A-D_D-A_PCF8591\ PCF8591_ADC

Page 142: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Curso de Robótica y otras aplicaciones en el Aula de Tecnología

Microcontroladores IES Joan Miró Página 142

5.3.8.1.2.1.1.- 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= 1000000) #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 PCF8591 0b10011001 // 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 0B00000000 // 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(); // Inicializamos el LCD. i2c_start(); // Envía secuencia de inicio i2c_write(PCF8591&0B11111110); // Envía dirección I2C del dispositivo en modo escritura i2c_write(CANAL); // Seleccionamos el canal y modo conversión A/D. while (1) // Bucle infinito de espera i2c_start(); // Envía secuencia de inicio i2c_write(PCF8591); // Envía dirección I2C del dispositivo en modo lectura q=i2c_read(0); // Lee último byte, envía NACK y almacena en el buffer i2c_stop(); // Secuencia de stop v1 = 5.0 * q / 256.0; // 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"

Page 143: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Curso de Robótica y otras aplicaciones en el Aula de Tecnología

Microcontroladores IES Joan Miró Página 143

5.3.8.1.2.1.2.- 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= 1000000) #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 AIN0 0 // Elección del Canal 0 y modo conversión A/D. #define AIN1 1 // Elección del Canal 1 y modo conversión A/D. #define AIN2 2 // Elección del Canal 2 y modo conversión A/D. #define AIN3 3 // 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) // Bucle infinito de espera entrada_analogica=AIN0; 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)); // Visualiza sobre la pantalla // LCD la lectura del canal 0 // AIN0 entrada_analogica=AIN1; 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)); // Visualiza sobre la pantalla // LCD la lectura del canal 1 // AIN1 entrada_analogica=AIN2; 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)); // Visualiza sobre la pantalla // LCD la lectura del canal 2 // AIN2 entrada_analogica=AIN3; 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

Page 144: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Curso de Robótica y otras aplicaciones en el Aula de Tecnología

Microcontroladores IES Joan Miró Página 144

// ***************************************** Función floatint8 Leer_PCF8159(int8) ********************************************** float Leer_PCF8591(int8 canal) #define PCF8591 0b10011001 // 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(); // Envía secuencia de inicio i2c_write(PCF8591&0B11111110); // Envía dirección I2C del dispositivo en modo escritura i2c_write(canal); // Seleccionamos el canal y modo conversión A/D. //********************************************* Leer Canal ************************************************************ i2c_start(); // Envía secuencia de inicio i2c_write(PCF8591); // Envía dirección I2C del dispositivo en modo lectura q=i2c_read(0); // Lee último byte, envía NACK y almacena en el buffer i2c_stop(); // Secuencia de stop //********************************************* Leer Canal ************************************************************ i2c_start(); // Envía secuencia de inicio i2c_write(PCF8591); // Envía dirección I2C del dispositivo en modo lectura q=i2c_read(0); // Lee último byte, envía NACK y almacena en el buffer i2c_stop(); // 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);

5.3.8.1.2.2.- PCF8591_DAC.

Utilizaremos el entrenador PCF8591_DA.DSN contenido en la carpeta de I2C\ Conversor A-D_D-A_PCF8591\ PCF8591_DAC

Page 145: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Curso de Robótica y otras aplicaciones en el Aula de Tecnología

Microcontroladores IES Joan Miró Página 145

5.3.8.1.2.2.1.- 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= 1000000) #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 AIN0 0 // Elección del Canal 0 y modo conversión A/D. #define AIN1 1 // Elección del Canal 1 y modo conversión A/D. #define AIN2 2 // Elección del Canal 2 y modo conversión A/D. #define AIN3 3 // 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(); // Inicializamos el LCD. while (1) // Bucle infinito de espera entrada_analogica=AIN1; q1=Leer_U2_PCF8591(entrada_analogica); // 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 0b10011001 // 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;

Page 146: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Curso de Robótica y otras aplicaciones en el Aula de Tecnología

Microcontroladores IES Joan Miró Página 146

i2c_start(); // Envía secuencia de inicio i2c_write(PCF8591_U2&0B11111110); // Envía dirección I2C del dispositivo en modo escritura i2c_write(canal); // Seleccionamos el canal y modo conversión A/D. //********************************************* Leer Canal ************************************************************ i2c_start(); // Envía secuencia de inicio i2c_write(PCF8591_U2); // Envía dirección I2C del dispositivo en modo lectura q=i2c_read(0); // Lee último byte, envía NACK y almacena en el buffer i2c_stop(); // Secuencia de stop //********************************************* Leer Canal ************************************************************ i2c_start(); // Envía secuencia de inicio i2c_write(PCF8591_U2); // Envía dirección I2C del dispositivo en modo lectura q=i2c_read(0); // Lee último byte, envía NACK y almacena en el buffer i2c_stop(); / /Secuencia de stop return(q); // ***************************************** Función Escribir_U1_PCF8159(int8) ************************************************ void Escribir_U1_PCF8591(int8 dato) #define PCF8591_U1 0B10010011 // 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&0B11111110); // Envía dirección I2C del dispositivo en modo escritura i2c_write(0B01000000); // Seleccionamos el modo conversión D/A. i2c_write(dato); // Envía el contenido de la variable dato y se convierte en // señal analógica. i2c_write(dato); // Envía el contenido de la variable dato y se convierte en // señal analógica. i2c_stop(); // Secuencia de stop

Page 147: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Curso de Robótica y otras aplicaciones en el Aula de Tecnología

Microcontroladores IES Joan Miró Página 147

5.3.9.- Sensores y Hardware.

5.3.9.1.- 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.

Vista externa y circuitos internos del sensor CNY70

Funcionamiento:

Utilizaremos el entrenador Robot Rastreador_Monibot.DSN contenido en la carpeta de Sensores y Hardware\ CNY70.

CNY70

E1= 5V

I1

R1= 220 R2= 47K

I2

I3 74HC14

Luz InfrarrojaLínea negra absorbe la luz

V1= 5V V2= 0V

Optotransistor

Cortado

Diodo

de LuzEmisor

0

CNY70

E1= 5V

I1

R1= 220 R2= 47K

I2

I3

74HC14

Luz InfrarrojaLínea blanca refleja la luz

V1= 0V V2= 5V

Optotransistor

Saturado

Diodo

de LuzEmisor

1I4Ic

CNY70A

3

C

1

K

4

E

2

Page 148: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Curso de Robótica y otras aplicaciones en el Aula de Tecnología

Microcontroladores IES Joan Miró Página 148

5.3.9.1.1.- 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 = 1000000 ) // Reloj de 1 MHz #include <flex_lcd.c> // 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.

Page 149: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Curso de Robótica y otras aplicaciones en el Aula de Tecnología

Microcontroladores IES Joan Miró Página 149

TRISA = 0B11111111; // Defines Puerto A como ENTRADA de datos. TRISD = 0B00001111; // Configurar el Puerto D como ENTRADAS (RD3..0) y // SALIDAS (RD7..4) de datos. while (1) lcd_gotoxy(6,1); // Posicionamos el Cursor del LCD en la posición // 6 línea 1 . printf(lcd_putc,"%2u%2u",~rd3,~rd2); // 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.

5.3.9.2.- Sensores de Distancia.

5.3.9.2.1.- 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

Page 150: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Curso de Robótica y otras aplicaciones en el Aula de Tecnología

Microcontroladores IES Joan Miró Página 150

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):

Utilizaremos el entrenador Monibot_GP2D12.DSN contenido en la carpeta de

Sensores y Hardware\ GP2D12.

d= 16,75 v4 – 119,26 v3 + 311,7 v2 - 365,71 v + 183,03

Page 151: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Curso de Robótica y otras aplicaciones en el Aula de Tecnología

Microcontroladores IES Joan Miró Página 151

5.3.9.2.1.1.- 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 // 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=1000000) #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); // Seleccionamos el Puerto A como entradas Analógicas. // Mirar ADCON1. setup_adc(ADC_CLOCK_INTERNAL); // Fuente de reloj RC interno. lcd_init(); // Inicializamos el LCD. for (;;) // Bucle infinito.

Page 152: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Curso de Robótica y otras aplicaciones en el Aula de Tecnología

Microcontroladores IES Joan Miró Página 152

set_adc_channel(0); // Habilitación canal 0 "AN0" delay_us(20); // Retardo de 20uS necesaria para respetar el tiempo de // adquisición Tad. q = read_adc(); // Lectura canal 0 "AN0" v = (5.0 * q) / 1024.0; // 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".

5.3.9.2.1.2.- 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 // Conversor Analógico Digital de 10 bit el PIC 16F876A puede // trabajar con 8 o 10 bit de resolución. #FUSES XT,NOWDT #use delay(clock=4000000) #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); // Seleccionamos el Puerto A como entradas analógicas. // Mirar ADCON1. setup_adc(ADC_CLOCK_INTERNAL); // Fuente de reloj RC interno. lcd_init(); // Inicializamos el LCD. for (;;) // Bucle infinito. set_adc_channel(0); // Habilitación canal 0 "AN0" delay_us(20); // Retardo de 20uS necesaria para respetar el tiempo de // Adquisición Tad. q = read_adc(); // Lectura canal 0 "AN0" v = (5.0 * q) / 1024.0; // 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, "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); // Habilitación canal 0 "AN1" delay_us(20); // Retardo de 20uS necesaria para respetar el tiempo de // Adquisición Tad. q = read_adc(); // Lectura canal 0 "AN0" v = (5.0 * q) / 1024.0; // Conversión a tensión del código digital "q".

Page 153: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Curso de Robótica y otras aplicaciones en el Aula de Tecnología

Microcontroladores IES Joan Miró Página 153

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".

5.3.9.2.1.3.- 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 = 13.5 + ((8-13.5)* (v - 1.9) /(2.6-1.9)); else if(v<1.9&&v>=1.65) l = 16 + ((13.5-16)* (v- 1.65) / (1.9-1.65)); else if(v<1.65&&v>=1.38) l = 20 + ((16-20)* (v- 1.38) / (1.65-1.38)); else if(v<1.38&&v>=1.15) l = 25 + ((20-25)* (v- 1.15) / (1.38-1.15)); else if(v<1.15&&v>=0.95) l = 30 + ((25-30)* (v- 0.95) / (1.15-0.95)); else if(v<0.95&&v>=0.75) l = 40 + ((30-40)* (v- 0.75) / (0.95-0.75)); else if(v<0.75&&v>=0.68) l = 45 + ((40-45)* (v- 0.68) / (0.75-0.68)); else if(v<0.68&&v>=0.58) l = 55 + ((45-55)* (v- 0.58) / (0.68-0.58)); else if(v<0.58) l=55; return(l);

5.3.9.2.1.4.- 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)-119.26*s)+(311.7*r)-(365.71*v)+183.03; return(d);

Page 154: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Curso de Robótica y otras aplicaciones en el Aula de Tecnología

Microcontroladores IES Joan Miró Página 154

5.3.9.2.2.- 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)

Page 155: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Curso de Robótica y otras aplicaciones en el Aula de Tecnología

Microcontroladores IES Joan Miró Página 155

5.3.9.2.2.1.- 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= 1000000) #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 SRF08 0xE2 // Dirección I2C del SRF08 /* ************************************************* Declaración de funciones ************************************************** */ int16 Lectura_SRF08(void); // Declaramos la función Lectura_Interruptores (Nos devuelve una variable tipo entero de 8 bit)

Page 156: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Curso de Robótica y otras aplicaciones en el Aula de Tecnología

Microcontroladores IES Joan Miró Página 156

/* *************************** Función principal o programa principal **************************** */ void main() int16 dato_recibido; lcd_init(); // Inicializamos el LCD. while (1) // Bucle infinito de espera dato_recibido = Lectura_SRF08(); // Leemos el dato a través del bus I2c del // esclavo U4 lcd_gotoxy(1,1); // Posicionamos el Cursor del LCD en la // posición 1 línea 1 . printf(lcd_putc,"%03lu cm",dato_recibido); // 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 // Medida en cm int16 resultado=0; int8 byte_alto=0; int8 byte_bajo=0; i2c_start(); // Secuencia de inicio i2c_write(SRF08); // Dirección I2C del SRF08 modo escritura i2c_write(0x00); // Dirección interna 0x00 (registro de comandos) i2c_write(SRF08_cm); // Enviar comando a ejecutar, lectura en cm i2c_stop(); // Secuencia de stop delay_ms(70); // Temporización de 70mS necesaria para realizar la ejecución i2c_start(); // Secuencia de inicio i2c_write(SRF08); // Dirección I2C del dispositivo modo escritura i2c_write(0x02); // Envía dirección interna del dispositivo, nos posicionamos en el // registro del 1º eco i2c_stop(); // Envía secuencia de stop i2c_start(); // Envía secuencia de inicio i2c_write(SRF08|0b00000001); // Envía dirección I2C del dispositivo en modo lectura byte_alto=i2c_read(); // No, leer el byte, enviar ACK y almacenar en el buffer byte_bajo=i2c_read(0); // Si, lee último byte, envía NACK y almacena en el buffer i2c_stop(); //Secuencia de stop resultado=make16(byte_alto, byte_bajo); // Convierte parta alta y baja en un entero de 16 bit return (resultado);

5.3.9.2.2.2.- 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>

Page 157: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Curso de Robótica y otras aplicaciones en el Aula de Tecnología

Microcontroladores IES Joan Miró Página 157

#fuses XT,NOWDT,PUT,NOWRT #use delay(clock= 1000000) #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 <LCD1.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 /* *********************************************** 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); // Leemos el dato a través del bus I2c del // Sensor 2 lcd_gotoxy(1,1); // Posicionamos el Cursor del LCD en la // posición 1 línea 1 . printf(lcd_putc,"S2=%03lu",dato_recibido); // Visualiza sobre la pantalla LCD la lectura del // Sensor 2 sensor=SENSOR_1; dato_recibido = Lectura_SRF08(sensor); // Leemos el dato a través del bus I2c del // Sensor 1 lcd_gotoxy(9,1); // Posicionamos el Cursor del LCD en la // posición 9 línea 1 . printf(lcd_putc,"S1=%03lu",dato_recibido); // 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 // Medida en cm int16 resultado=0; int8 byte_alto=0; int8 byte_bajo=0; i2c_start(); // Secuencia de inicio i2c_write(SRF08); // Dirección I2C del SRF08 modo escritura i2c_write(0x00); // Dirección interna 0x00 (registro de comandos) i2c_write(SRF08_cm); // Enviar comando a ejecutar, lectura en cm i2c_stop(); // Secuencia de stop delay_ms(20); // Temporización de 80mS necesaria para realizar la ejecución i2c_start(); // Secuencia de inicio i2c_write(SRF08); // Dirección I2C del dispositivo modo escritura i2c_write(0x02); // Envía dirección interna del dispositivo, nos posicionamos en el // registro del 1º eco i2c_stop(); // Envía secuencia de stop

Page 158: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Curso de Robótica y otras aplicaciones en el Aula de Tecnología

Microcontroladores IES Joan Miró Página 158

i2c_start(); // Envía secuencia de inicio i2c_write(SRF08|0b00000001); // Envía dirección I2C del dispositivo en modo lectura byte_alto=i2c_read(); // No, leer el byte, enviar ACK y almacenar en el buffer byte_bajo=i2c_read(0); // Si, lee último byte, envía NACK y almacena en el buffer i2c_stop(); // Secuencia de stop resultado=make16(byte_alto, byte_bajo); // Convierte parta alta y baja en un entero de 16 bit return(resultado);

5.3.9.2.2.3.- 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= 1000000) #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 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(); // Inicializamos el LCD. while (1) // Bucle infinito de espera sensor=SENSOR_1; dato_recibido = Lectura_SRF08(sensor); // Leemos el dato a través del bus I2c del // Sensor 1 lcd_gotoxy(1,1); // Posicionamos el Cursor del LCD en la // posición 1 línea 1 . printf(lcd_putc,"S1=%03lu",dato_recibido); // Visualiza sobre la pantalla LCD la lectura del // Sensor 1 sensor=SENSOR_2; dato_recibido = Lectura_SRF08(sensor); // Leemos el dato a través del bus I2c del // Sensor 2 lcd_gotoxy(9,1); // Posicionamos el Cursor del LCD en la // posición 9 línea 1 . printf(lcd_putc,"S2=%03lu",dato_recibido); // Visualiza sobre la pantalla LCD la lectura del // Sensor 2

Page 159: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Curso de Robótica y otras aplicaciones en el Aula de Tecnología

Microcontroladores IES Joan Miró Página 159

5.3.9.2.2.4.- 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= 1000000) #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(); // Inicializamos el LCD. while (1) // Bucle infinito de espera sensor=SENSOR_1; distancia = Lectura_SRF08(sensor); // Leemos el dato a través del bus I2c del // Sensor 1 lcd_gotoxy(1,1); // Posicionamos el Cursor del LCD en la // posición 1 línea 1 . printf(lcd_putc,"S1=%03lu cm",distancia); // Visualiza sobre la pantalla LCD la lectura del // Sensor 1 luz = Lectura_Lumenes_SRF08(sensor); // Leemos el dato a través del bus I2c del // Sensor 1 lcd_gotoxy(1,2); // Posicionamos el Cursor del LCD en la // posición 1 línea 2 . printf(lcd_putc,"S1=%03u lumenes",luz); // Visualiza sobre la pantalla LCD la lectura del // Sensor 1

5.3.9.2.2.5.- 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)

Page 160: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Curso de Robótica y otras aplicaciones en el Aula de Tecnología

Microcontroladores IES Joan Miró Página 160

/* *************************************** 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(); // Secuencia de inicio i2c_write(SRF08); // 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); // Dirección interna 0x00 (registro de comandos) i2c_write(SRF08_cm); // Enviar comando a ejecutar, lectura en cm i2c_stop(); // 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(); // Secuencia de inicio i2c_write(SRF08); // Dirección I2C del dispositivo modo escritura //*************************************** Nos posicionamos en el 1º Eco ********************************************* i2c_write(0x02); // Envía dirección interna del dispositivo, nos posicionamos en el // registro del 1º eco i2c_stop(); // Envía secuencia de stop //********************** Leemos los datos obtenidos del sensor (Byte Alto y Byte Bajo) ********************** i2c_start(); // Envía secuencia de inicio i2c_write(SRF08|0b00000001); // Envía dirección I2C del dispositivo en modo lectura byte_alto=i2c_read(); // No, leer el byte, envíar ACK y almacenar en el buffer byte_bajo=i2c_read(0); // Si, lee último byte, envía NACK y almacena en el buffer i2c_stop(); // Secuencia de stop resultado=make16(byte_alto,byte_bajo); // Convierte parta alta y baja en un entero de 16 bit return(resultado);

5.3.9.2.2.6.- driver_Luz_Distancia_SRF08.c

/* ********************************* driver_Luz_Distancia_SRF08.c ******************************** */ #define SRF08_cm 0x51 // Medida en cm #define SRF08_Lumenes 0x01 // Medida en Lumenes /* ************************************************ Declaración de funciones *************************************************** */ int16 Lectura_SRF08(int8); // Declaramos la función Lectura_SRF08 // (Nos devuelve una variable tipo entero de 8 bit) int8 Lectura_Lumenes_SRF08(int8); // 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 *****************************************

Page 161: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Curso de Robótica y otras aplicaciones en el Aula de Tecnología

Microcontroladores IES Joan Miró Página 161

i2c_start(); // Secuencia de inicio i2c_write(SRF08); // 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); // Dirección interna 0x00 (registro de comandos) i2c_write(SRF08_cm); // Enviar comando a ejecutar, lectura en cm i2c_stop(); // 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(); // Secuencia de inicio i2c_write(SRF08); // Dirección I2C del dispositivo modo escritura //*************************************** Nos posicionamos en el 1º Eco ********************************************* i2c_write(0x02); // Envía dirección interna del dispositivo, nos posicionamos // en el registro del 1º eco i2c_stop(); // Envía secuencia de stop //*********************Leemos los datos obtenidos del sensor (Byte Alto y Byte Bajo) ************************ i2c_start(); // Envía secuencia de inicio i2c_write(SRF08|0b00000001); // Envía dirección I2C del dispositivo en modo lectura byte_alto=i2c_read(); // No, leer el byte, envíar ACK y almacenar en el buffer byte_bajo=i2c_read(0); // Si, lee último byte, envía NACK y almacena en el buffer i2c_stop(); // 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(); // Secuencia de inicio i2c_write(SRF08); // 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); // Enviar comando a ejecutar, lectura i2c_stop(); // Secuencia de stop //************************************ Leemos el dispositivo SRF08 ************************************************** i2c_start(); // Secuencia de inicio i2c_write(SRF08|0b00000001); // Envía dirección I2C del dispositivo en modo lectura lumenes=i2c_read(0); // Si, lee último byte, envía NACK y almacena en el buffer i2c_stop(); // Secuencia de stop return(lumenes);

Page 162: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Curso de Robótica y otras aplicaciones en el Aula de Tecnología

Microcontroladores IES Joan Miró Página 162

5.3.9.2.2.7.- 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 = 0B10011001 // 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 = 0B10010101 // 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(); // Envía secuencia de inicio i2c_write(PCF8591); // Envía dirección I2C del dispositivo en modo lectura resultado=i2c_read(0); // Si, lee último byte, envía NACK y almacena en el buffer i2c_stop(); // Secuencia de stop return(resultado);

5.3.9.2.2.8.- 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= 1000000) #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(); // Secuencia de inicio i2c_write(SRF08_inicial); // Dirección I2C del SRF08 modo escritura

Page 163: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Curso de Robótica y otras aplicaciones en el Aula de Tecnología

Microcontroladores IES Joan Miró Página 163

i2c_write(0x00); // Dirección interna 0x00 (registro de comandos) i2c_write(0xA0); //1ª secuencia para el cambio de dirección i2c_stop(); // Secuencia de stop i2c_start(); // Secuencia de inicio i2c_write(SRF08_inicial); // Dirección I2C del SRF08 modo escritura i2c_write(0x00); // Dirección interna 0x00 (registro de comandos) i2c_write(0xAA); // 2ª secuencia para el cambio de dirección i2c_stop(); // Secuencia de stop i2c_start(); // Secuencia de inicio i2c_write(SRF08_inicial); // Dirección I2C del SRF08 modo escritura i2c_write(0x00); // Dirección interna 0x00 (registro de comandos) i2c_write(0xA5); // 3ª secuencia para el cambio de dirección i2c_stop(); // Secuencia de stop i2c_start(); // Secuencia de inicio i2c_write(SRF08_inicial); // Dirección I2C del SRF08 modo escritura i2c_write(0x00); // Dirección interna 0x00 (registro de comandos) i2c_write(SRF08_final); // Nueva dirección I2C i2c_stop(); // Secuencia de stop while(1);

5.3.9.2.2.9.- 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= 1000000) #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. #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

Page 164: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Curso de Robótica y otras aplicaciones en el Aula de Tecnología

Microcontroladores IES Joan Miró Página 164

/* *************************** 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(); // Inicializamos el LCD. while (1) // Bucle infinito de espera sensor=SENSOR_1; distancia = Lectura_SRF08(sensor); // Leemos el dato a través del bus I2c del // Sensor 1 lcd_gotoxy(1,1); // Posicionamos el Cursor del LCD en la // posición 1 línea 1 . printf(lcd_putc,"S1=%03lu",distancia); // Visualiza sobre la pantalla LCD la lectura del // Sensor 1 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;

5.3.9.3.- Sensores de Temperatura.

5.3.9.3.1.- 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

Page 165: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Curso de Robótica y otras aplicaciones en el Aula de Tecnología

Microcontroladores IES Joan Miró Página 165

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: RPT100= R0 (1 + a1 x t + a2 x t

2)

Donde R0 es 100Ω a (100

oC)

a1 = 0.0039083 (Coeficiente de temperatura) a2 = -0.0000005775 (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:

Ve= [ E1 / (R1+RPT100)] x RPT100

VS= [(R4 +R5)/R5] x Ve

El resultado es:

RPT100 = [(VS x R5 x R1) / ((R4 +R5) x E1 - VS x R5))] R0 (1 + a1 x t + a2 x t

2) = [(VS x R5 x R1) / ((R4 +R5) x E1 - VS x R5))]

1 + a1 x t + a2 x t

2 = [(VS x R5 x R1) / ((R4 +R5) x E1 - VS x R5)) x R0]

1 + a1 x t + a2 x t

2 = A

Una vez introducidos los valores queda:

Page 166: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Curso de Robótica y otras aplicaciones en el Aula de Tecnología

Microcontroladores IES Joan Miró Página 166

A = (VS x 70.5) / (117.5 - VS x 1.5); a2 x t

2 + a1 x t + (1-A) = 0

t = (-b ± ) / 2a =

t = (- a1+ )/ 2 a2

5.3.9.3.1.1.- 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 // Conversor Analógico Digital de 10 bit el PIC 16F876A puede // trabajar con 8 o 10 bit de resolución. #FUSES XT,NOWDT #use delay(clock=1000000) #include <MATH.H> #include <flex_lcd.c> // Incluimos el driver flex_lcd.c que contiene las funciones de control // del LCD. #define a1 0.0039083 #define a2 -0.0000005775 //******************************************************** Declaración de Funciones ********************************************* float Con_V_T(float); //********************************************************* Programa Principal ***************************************************** void main() int16 q; float tension; float temperatura; lcd_init(); // Inicializamos el LCD. setup_adc_ports(2); // Seleccionamos el Puerto A como entradas Analógicas. // Mirar ADCON1. setup_adc(ADC_CLOCK_INTERNAL); // Fuente de reloj RC interno. set_adc_channel(0); // Habilitación canal 0 "AN0" for (;;) // Bucle infinito. delay_us(5); // Retardo de 20uS necesaria para respetar el tiempo de // Adquisición Tad.

t = - 2 + (-a1 + raiz) / (2*a2) if (t<0) t = t - 0.5

Factor de Corrección

Page 167: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Curso de Robótica y otras aplicaciones en el Aula de Tecnología

Microcontroladores IES Joan Miró Página 167

q = read_adc(); // Lectura canal 0 "AN0" tension = 5.0 * q / 1024.0; // 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)/(117.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);

5.3.9.3.2.- 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: 1-0-0-1-1-0-1 (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.

Page 168: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Curso de Robótica y otras aplicaciones en el Aula de Tecnología

Microcontroladores IES Joan Miró Página 168

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 TC74.

5.3.9.3.2.1.- 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= 1000000) #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

Page 169: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Curso de Robótica y otras aplicaciones en el Aula de Tecnología

Microcontroladores IES Joan Miró Página 169

//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); // Leemos el dato a través del bus I2c del // esclavo TC74_2 lcd_gotoxy(4,2); // Posicionamos el Cursor del LCD en la // posición 4 línea 2 . printf(lcd_putc,"%3d C",dato_recibido); // 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(); // Secuencia de inicio i2c_write(sensor); // Dirección I2C del dispositivo modo escritura i2c_write(0x00); // Envía dirección interna del dispositivo, nos posicionamos en // el registro. i2c_start(); // Envía secuencia de inicio i2c_write(sensor|0b00000001); // Envía dirección I2C del dispositivo en modo lectura temperatura=i2c_read(0); // Si, lee último byte, envía NACK y almacena en el buffer i2c_stop(); // Secuencia de stop return (temperatura);

Page 170: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Curso de Robótica y otras aplicaciones en el Aula de Tecnología

Microcontroladores IES Joan Miró Página 170

5.3.9.3.3.- 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.

Page 171: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Curso de Robótica y otras aplicaciones en el Aula de Tecnología

Microcontroladores IES Joan Miró Página 171

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):

11 10 11 12 12 29 15 13

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 pull-up 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

Page 172: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Curso de Robótica y otras aplicaciones en el Aula de Tecnología

Microcontroladores IES Joan Miró Página 172

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) + 540

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.

Page 173: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Curso de Robótica y otras aplicaciones en el Aula de Tecnología

Microcontroladores IES Joan Miró Página 173

5.3.9.3.3.1.- 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= 1000000) #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=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) // Bucle infinito de espera sensor=1; dato_recibido = Lectura_DTPA81(sensor); // Leemos el dato a través del bus I2c del sensor1 // DTPA81. lcd_gotoxy(1,1); // Posicionamos el Cursor del LCD en la posición // 1 línea 1 . printf(lcd_putc,"%1u C",dato_recibido); // Visualiza sobre la pantalla LCD la temperatura // del sensor1. sensor=2; dato_recibido = Lectura_DTPA81(sensor); // Leemos el dato a través del bus I2c del sensor2 // DTPA81. lcd_gotoxy(5,1); // Posicionamos el Cursor del LCD en la // posición 5 línea 1 . printf(lcd_putc,"%1u C",dato_recibido); // 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;

Page 174: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Curso de Robótica y otras aplicaciones en el Aula de Tecnología

Microcontroladores IES Joan Miró Página 174

i2c_start(); // Secuencia de inicio i2c_write(DTPA81); // Dirección I2C del dispositivo modo escritura i2c_write(sensor); // Envia dirección interna del dispositivo, nos posicinamos // en el registro. i2c_stop(); // Envía secuencia de stop i2c_start(); // Envía secuencia de inicio i2c_write(DTPA81|0b00000001); // Envía dirección I2C del dispositivo en modo lectura temperatura=i2c_read(0); // Si, lee último byte, envía NACK y almacena en el buffer i2c_stop(); // Secuencia de stop return(temperatura);

5.3.9.3.3.2.- 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= 1000000) #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); // Leemos el dato a través del bus I2c del //sensor 1 DTPA81. lcd_gotoxy(1,1); // Posicionamos el Cursor del LCD en la // posición 1 línea 1 . printf(lcd_putc,"%1u",dato_recibido); // Visualiza sobre la pantalla LCD la temperatura. sensor=2; dato_recibido = Lectura_DTPA81(sensor); // Leemos el dato a través del bus I2c del // sensor 2 DTPA81. lcd_gotoxy(4,1); // Posicionamos el Cursor del LCD en la // posición 4 línea 1 .

Page 175: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Curso de Robótica y otras aplicaciones en el Aula de Tecnología

Microcontroladores IES Joan Miró Página 175

printf(lcd_putc,"%1u",dato_recibido); // Visualiza sobre la pantalla LCD la temperatura. sensor=3; dato_recibido = Lectura_DTPA81(sensor); // Leemos el dato a través del bus I2c del // sensor 3 DTPA81. lcd_gotoxy(7,1); // Posicionamos el Cursor del LCD en la // posición 7 línea 1 . printf(lcd_putc,"%1u",dato_recibido); // Visualiza sobre la pantalla LCD la temperatura. sensor=4; dato_recibido = Lectura_DTPA81(sensor); // Leemos el dato a través del bus I2c del // sensor 4 DTPA81. lcd_gotoxy(10,1); // Posicionamos el Cursor del LCD en la posición // 10 línea 1. printf(lcd_putc,"%1u",dato_recibido); // Visualiza sobre la pantalla LCD la temperatura. sensor=5; dato_recibido = Lectura_DTPA81(sensor); // Leemos el dato a través del bus I2c del // sensor 5 DTPA81. lcd_gotoxy(13,1); // Posicionamos el Cursor del LCD en la // posición 13 línea 1. printf(lcd_putc,"%1u",dato_recibido); // Visualiza sobre la pantalla LCD la temperatura. sensor=6; dato_recibido = Lectura_DTPA81(sensor); // Leemos el dato a través del bus I2c del //sensor 6 DTPA81. lcd_gotoxy(4,2); // Posicionamos el Cursor del LCD en la // posición 4 línea 2 . printf(lcd_putc,"%1u",dato_recibido); // Visualiza sobre la pantalla LCD la temperatura. sensor=7; dato_recibido = Lectura_DTPA81(sensor); // Leemos el dato a través del bus I2c del // sensor 7 DTPA81. lcd_gotoxy(7,2); // Posicionamos el Cursor del LCD en la // posición 7 línea 2 . printf(lcd_putc,"%1u",dato_recibido); // Visualiza sobre la pantalla LCD la temperatura. sensor=8; dato_recibido = Lectura_DTPA81(sensor); // Leemos el dato a través del bus I2c del // sensor 8 DTPA81. lcd_gotoxy(10,2); // Posicionamos el Cursor del LCD en la // posición 10 línea 2 . printf(lcd_putc,"%1u",dato_recibido); // Visualiza sobre la pantalla LCD la temperatura. sensor=9; dato_recibido = Lectura_DTPA81(sensor); // Leemos el dato a través del bus I2c del //sensor 9 DTPA81. lcd_gotoxy(13,2); // Posicionamos el Cursor del LCD en la // posición 13 línea 2 . printf(lcd_putc,"%1u",dato_recibido); // 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(); // Secuencia de inicio i2c_write(DTPA81); // Dirección I2C del dispositivo modo escritura i2c_write(sensor); // Envia dirección interna del dispositivo, nos posicinamos // en el registro. i2c_stop(); // Envía secuencia de stop

Page 176: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Curso de Robótica y otras aplicaciones en el Aula de Tecnología

Microcontroladores IES Joan Miró Página 176

i2c_start(); // Envía secuencia de inicio i2c_write(DTPA81|0b00000001); // Envía dirección I2C del dispositivo en modo lectura temperatura=i2c_read(0); // Si, lee último byte, envía NACK y almacena en el buffer i2c_stop(); //Secuencia de stop return(temperatura);

5.3.9.3.3.3.- 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= 1000000) #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 Numero_Maximo 8 // Número pixel-1 byte CONST Direccion_Pixel[9] = 0x90,0x92,0x94,0x96,0x98,0x9A,0x9C,0x9E,0xA0; // Tabla de 9 datos. // Ta, Pixel1,Pixel2,Pixel3,Pixel4,Pixel5,Pixel6,Pixel7,Pixel8 /* ******************************************** 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]

Page 177: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Curso de Robótica y otras aplicaciones en el Aula de Tecnología

Microcontroladores IES Joan Miró Página 177

temperatura_ambiente= Lectura_TC74(sensor); // Leemos la temperatura ambiente a // través del bus I2c del esclavo // TªAMBIENTE. sensor = Direccion_Pixel[1]; // Sacamos la dirección del sensor // PIXEL1 de la tabla Direccion_Pixel[1] temperatura_mayor= Lectura_TC74(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++) // Se ejecuta un bucle desde n=2 hasta // n<=Numero_Maximo en orden // ASCENDENTE de uno en uno sensor = Direccion_Pixel[n]; // Sacamos la dirección del sensor de la // tabla Direccion_Pixel[n] temperatura= Lectura_TC74(sensor); // Leemos la temperatura del sensor a // través del bus I2c. if(temperatura>temperatura_mayor) // Detectamos la temperatura mayor. temperatura_mayor=temperatura; // Guardamos la temperatura mayor. sensor_mayor=n; // 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(); // Secuencia de inicio i2c_write(sensor); // Dirección I2C del dispositivo modo escritura i2c_write(0x00); // Envia dirección interna del dispositivo, nos posicinamos // en el registro. i2c_start(); // Envía secuencia de inicio i2c_write(sensor|0b00000001); // Envía dirección I2C del dispositivo en modo lectura temperatura=i2c_read(0); // Si, lee último byte, envía NACK y almacena en el buffer i2c_stop(); // Secuencia de stop return(temperatura);

5.3.9.3.3.4.- 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>

Page 178: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Curso de Robótica y otras aplicaciones en el Aula de Tecnología

Microcontroladores IES Joan Miró Página 178

#fuses XT,NOWDT,PUT,NOWRT #use delay(clock= 1000000) #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++) // Se ejecuta un bucle desde n=2 hasta // n<=Numero_Maximo en orden // ASCENDENTE de uno en uno temperatura= Lectura_DTPA81(n); // Leemos la temperatura del sensor a // través del bus I2c. if(temperatura>temperatura_mayor) // Detectamos la temperatura mayor. temperatura_mayor=temperatura; // Guardamos la temperatura mayor. sensor_mayor=n; // 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);

Page 179: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Curso de Robótica y otras aplicaciones en el Aula de Tecnología

Microcontroladores IES Joan Miró Página 179

5.3.9.3.3.5.- 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(); // Secuencia de inicio i2c_write(DTPA81); // Dirección I2C del dispositivo modo escritura i2c_write(sensor+1); // Envia dirección interna del dispositivo, nos posicinamos en // el registro. i2c_start(); // Envía secuencia de inicio i2c_write(DTPA81|0b00000001); // Envía dirección I2C del dispositivo en modo lectura temperatura=i2c_read(0); // Si, lee último byte, envía NACK y almacena en el buffer i2c_stop(); // Secuencia de stop return(temperatura);

5.3.9.3.3.6.- 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; // Tabla de 9 datos. // Ta, Pixel1, Pixel2,Pixel3,Pixel4,Pixel5,Pixel6,Pixel7,Pixel8 /* ********************************************** 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]; // Sacamos la dirección del sensor de la table // Direccion_Pixel[n] i2c_start(); // Secuencia de inicio i2c_write(sensor); // Dirección I2C del dispositivo modo escritura i2c_write(0x00); // Envia dirección interna del dispositivo, nos posicinamos // en el registro. i2c_start(); // Envía secuencia de inicio i2c_write(sensor|0b00000001); // Envía dirección I2C del dispositivo en modo lectura temperatura=i2c_read(0); // Si, lee último byte, envía NACK y almacena en el buffer i2c_stop(); // Secuencia de stop return(temperatura);

Page 180: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Curso de Robótica y otras aplicaciones en el Aula de Tecnología

Microcontroladores IES Joan Miró Página 180

5.3.9.3.3.7.- 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= 1000000) #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 <Servo_Futaba_10bit.c> // Incluimos el driver que contiene las funciones // de control de los Servos de Futaba. #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. #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(); // Inicializamos el LCD. Inicializacion_Futaba_RC2(); // 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 ".

Page 181: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Curso de Robótica y otras aplicaciones en el Aula de Tecnología

Microcontroladores IES Joan Miró Página 181

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++) // Se ejecuta un bucle desde n=2 hasta // n<=Numero_Maximo en orden // ASCENDENTE de uno en uno temperatura= Lectura_DTPA81(n); // Leemos la temperatura del sensor a // través del bus I2c. if(temperatura>temperatura_mayor) // Detectamos la temperatura mayor. temperatura_mayor=temperatura; // Guardamos la temperatura mayor. sensor_mayor=n; // 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. 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); // 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(50);

Page 182: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Curso de Robótica y otras aplicaciones en el Aula de Tecnología

Microcontroladores IES Joan Miró Página 182

5.3.9.4.- Potenciómetro Digital MCP41010.

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\ MCP41010.

Page 183: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Curso de Robótica y otras aplicaciones en el Aula de Tecnología

Microcontroladores IES Joan Miró Página 183

5.3.9.4.1.- 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=1000000) #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=0B00000000; lcd_init(); // Inicializamos el LCD. while(true) // Bucle infinito. dato=portA; if(dato!=dato_anterior) dato_anterior=dato; cs=0; spi_write(0x0); cs=1; cs=0; spi_write(0x11); // 0x11 spi_write(portD); delay_us(120); cs=1; ganancia=((dato*10)/256)+1; lcd_gotoxy(1,1); // Posicionamos el Cursor del LCD en la //posición 1 línea 1 . printf(lcd_putc,"PORTA=%3u",portA); // Escribimos 3 dígitos de la variable // "PORTA" en formato entero y sin // signo.

Page 184: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Curso de Robótica y otras aplicaciones en el Aula de Tecnología

Microcontroladores IES Joan Miró Página 184

lcd_gotoxy(1,2); // Posicionamos el Cursor del LCD en la // posición 1 línea 2 . printf(lcd_putc,"Ganancia=%5.2f",ganancia); // Escribimos 5 dígitos de la variable // "ganancia" en formato float, con // 2 decimales.

5.3.9.5.- 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.

5.3.9.5.1.- 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= 1000000) #use i2c(Master, force_hw, slow, sda=PIN_C4, scl=PIN_C3) // Configuración de I2C // Definimos el PIC como maestro

Page 185: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Curso de Robótica y otras aplicaciones en el Aula de Tecnología

Microcontroladores IES Joan Miró Página 185

// 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,Reg23 + 20uS // THmax =(256x255)/Reg21 +(Reg22,Reg23+20)= // THmin = Reg22,Reg23 +20 uS = 460uS + 20uS = 480 uS ( 460d --> 1CCH ) // THmax =(256x255)/32 +(460+20)= 2520 uS i2c_start(); // Inicializa la transmisión i2c_write(0xC2); // Seleccionamos el SD20 i2c_write(21); // Registro de configuración extandar o control modo expandido. i2c_write(32); i2c_stop(); // 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(); // Inicializa la transmisión i2c_write(0xC2); // Seleccionamos el SD20 i2c_write(23); // Dirección 23H del SD20 Modo expansor de offset (Parte Baja) i2c_write(0xCC); // 460D -->01CCH (Se introduce la parte baja CCH) i2c_stop(); // Finalización de la transmisión. while (1) // Bucle infinito i2c_start(); // Inicializa la transmisión i2c_write(0xC2); // Seleccionamos el SD20 i2c_write(1); // Seleccionamos el Servo1 i2c_write(240); // Posicionamos el Servo en el extremo A i2c_stop(); // Finalización de la transmisión. delay_ms(1000); // Retardamos 1 segundos i2c_start(); // Inicializa la transmisión i2c_write(0xC2); // Seleccionamos el SD20 i2c_write(1); // Seleccionamos el Servo1 i2c_write(10); // Posicionamos el Servo en el extremo B i2c_stop(); // Finalización de la transmisión. delay_ms(1000); // Retardamos 1 segundos

5.3.9.5.2.- 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= 4000000) #use i2c(Master, force_hw, slow, sda=PIN_C4, scl=PIN_C3) // Configuración de I2C // Definimos el PIC como maestro

Page 186: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Curso de Robótica y otras aplicaciones en el Aula de Tecnología

Microcontroladores IES Joan Miró Página 186

// 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,Reg23 + 20uS // THmax =(256x255)/Reg21 +(Reg22,Reg23+20)= // THmin = Reg22,Reg23 +20 uS = 460uS + 20uS = 480 uS ( 460d --> 1CCH ) // THmax =(256x255)/32 +(460+20)= 2520 uS

i2c_start(); // Inicializa la transmisión i2c_write(0xC2); // Seleccionamos el SD20 i2c_write(21); // Registro de configuración extandar o control modo expandido. i2c_write(32); i2c_stop(); // 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(); // Inicializa la transmisión i2c_write(0xC2); // Seleccionamos el SD20 i2c_write(23); // Dirección 23H del SD20 Modo expansor de offset(Parte Baja) i2c_write(0xCC); // 460D -->01CCH (Se introduce la parte baja CCH) i2c_stop(); // Finalización de la transmisión.

/* ********************************************** Función Sd20(int8,int8) ******************************************************* */ void Sd20(int8 servo, int8 posicion)

i2c_start(); // Inicializa la transmisión i2c_write(0xC2); // Seleccionamos el SD20 i2c_write(servo); // Seleccionamos el Servo1 i2c_write(posicion); // Posicionamos el Servo en el extremo A i2c_stop(); // Finalización de la transmisión.

Page 187: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Curso de Robótica y otras aplicaciones en el Aula de Tecnología

Microcontroladores IES Joan Miró Página 187

5.3.9.5.3.- 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 // Conversor Analógico Digital de 10 bit el PIC 16F876A // puede trabajar con 8 o 10 bit de resolucion #fuses XT,NOWDT,PUT,NOWRT #use delay(clock= 4000000) #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(); // Fijamos los niveles máximos y minimos de TH setup_adc_ports(0); // Seleccionamos el Puerto A como entradas Analógicas.

// Mirar ADCON1 setup_adc(ADC_CLOCK_INTERNAL); // Fuente de reloj RC interno. set_adc_channel(3); // 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,Reg23 + 20uS // THmax =(256x255)/Reg21 +(Reg22,Reg23+20)= // THmin = Reg22,Reg23 +20 uS = 460uS + 20uS = 480 uS ( 460d --> 1CCH ) // THmax =(256x255)/32 +(460+20)= 2520 uS

i2c_start(); // Inicializa la transmisión i2c_write(0xC2); // Seleccionamos el SD20 i2c_write(21); // Registro de configuración extandar o control modo expandido. i2c_write(32); i2c_stop(); // Finalización de la transmisión.

Page 188: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Curso de Robótica y otras aplicaciones en el Aula de Tecnología

Microcontroladores IES Joan Miró Página 188

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(); // Inicializa la transmisión i2c_write(0xC2); // Seleccionamos el SD20 i2c_write(23); // Dirección 23H del SD20 Modo expansor de offset(Parte Baja) i2c_write(0xCC); // 460D -->01CCH (Se introduce la parte baja CCH) i2c_stop(); // Finalización de la transmisión.

/* ************************************************** Función Sd20(int8,int8) *************************************************** */ void Sd20(int8 servo, int8 posicion)

i2c_start(); // Inicializa la transmisión i2c_write(0xC2); // Seleccionamos el SD20 i2c_write(servo); // Seleccionamos el Servo1 i2c_write(posicion); // Posicionamos el Servo en el extremo A i2c_stop(); // Finalización de la transmisión.

5.3.9.6.- 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

1 0 0 1 El motor gira en avance

0 1 1 0 El motor gira en retroceso

0 0 0 0 El motor se detiene bajo su inercia

1 0 1 0 El motor frena (fast-stop)

Page 189: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Curso de Robótica y otras aplicaciones en el Aula de Tecnología

Microcontroladores IES Joan Miró Página 189

Montaje

Lo más habitual en este tipo de circuitos es emplear interruptores de estado sólido (como Transistores), puesto que sus tiempos de vida y frecuencias de conmutación son mucho más altas. En convertidores de potencia es impensable usar interruptores mecánicos, dado su bajo número de conmutaciones de vida útil y las altas frecuencias que se suelen emplear.

Además los interruptores se acompañan de diodos (conectados a ellos en paralelo) que permitan a las corrientes circular en sentido inverso al previsto cada vez que se conmute la tensión, puesto que el motor está compuesto por bobinados que durante breves períodos de tiempo se opondrán a que la corriente varíe.

5.3.9.6.1.- L293B y L298.

Dos integrados clásicos utilizados son L293B y el L298, capaces de proporcionar una corriente elevada “I” en su salida. Se controlan con lógica digital, además podemos controlar la cantidad y el sentido de la corriente. Caracteristicas del L293B:

Imax=1A por canal

Ipico max (no repetitiva)= 2A por canal.

V max (Salida) = 36V

Control digital. (TTL)

Alta inmunidad al ruido.

Separación entre alimentaciones de control y de potencia.

Protección a temperaturas altas. Caracteristicas del L298:

Imax=4A.

V max (Salida) = 46V

Control digital. (TTL)

Alta inmunidad al ruido.

Separación entre alimentaciones de control y de potencia.

Protección a temperaturas altas.

Page 190: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Curso de Robótica y otras aplicaciones en el Aula de Tecnología

Microcontroladores IES Joan Miró Página 190

Para ver el funcionamiento de estos integrados, utilizaremos el entrenador Simulación del L298-L293B.DSN contenido en la carpeta de Sensores y Hardware \ Puentes en H \ L298-L293B.

Tabla de la Verdad:

Entradas ENA IN1 IN2

Salidas OUT1 OUT2

Efectos sobre un Motor

0 x x 1 0 0 1 0 1 1 1 0 1 1 1

5v 5v 0v 0v 0v 9v 9v 0v 9v 0v

Parado Parado

Giro a Izquierdas Giro a Derechas

Parado

Page 191: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Curso de Robótica y otras aplicaciones en el Aula de Tecnología

Microcontroladores IES Joan Miró Página 191

Si queremo realizar un control de velocidad sobre un motor, tendremos que generar una señal pulsante (Modulación por Anchura de Pulso, PWM) sobre la patilla EN. Ver el circuito L293B_PWM.DSN contenido en la carpeta de Sensores y Hardware \ Puentes en H \ L298-L293B.

Page 192: Aprendizaje de la Electrónica a través de la Robótica - … · Aprendizaje de la Electrónica a través de la Robótica - ARCE - Microcontroladores IES Joan Miró Página 2 Índice

Curso de Robótica y otras aplicaciones en el Aula de Tecnología

Microcontroladores IES Joan Miró Página 192

5.3.9.6.2.- Puente en H con TRT.

Si necesitamos corrientes y tensiones superiores, se pueden utilizar transistores.