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

Anuncio
Curso de Robótica y aplicaciones a el Aula de Tecnología
Curso de Robótica y otras
aplicaciones en el Aula de
Tecnología
Pedro Alonso Sanz
IES Joan Miró
Enero 2009
IES Joan Miró
Página 1
Curso de Robótica y otras aplicaciones en el Aula de Tecnología
1.- MANEJO DEL LABORATORIO ELECTRÓNICO VIRTUAL “PROTEUS”. ............................ 4
1.1.- ISIS (CAPTURA Y SIMULACIÓN DE CIRCUITOS ELECTRÓNICOS). ............................................. 4
1.1.1.- Introducción. ............................................................................................................................. 4
1.1.2.- Captura Electrónica: Entorno Gráfico (ISIS) .............................................................................. 5
1.1.3.- Depuración de programas. ....................................................................................................... 9
1.2.- ARES (DISEÑO DE PLACAS). .............................................................................................. 17
1.2.1.- Diseño de un esquema con ISIS. .............................................................................................. 17
1.2.2.- Generación del listado de conexiones “Netlis to Ares”. .......................................................... 21
1.2.2.1.- Entorno de Trabajo .......................................................................................................................... 22
1.2.3.- Creación del tamaño de la placa de PCB. ............................................................................... 22
1.2.4.- Posicionamiento de los componentes dentro de la placa. ...................................................... 25
1.2.4.1.- Posicionamiento Automático. ......................................................................................................... 25
1.2.4.2.- Posicionamiento Manual. ................................................................................................................ 26
1.2.5.- Rutado de la pistas. ................................................................................................................ 27
1.2.5.1.- Rutado Automático. ........................................................................................................................ 28
1.2.5.2.- Rutado manual. ............................................................................................................................... 29
1.3.- CREACIÓN DE SÍMBOLOS EN ISIS Y ENCAPSULADOS EN ARES. .......................................... 34
1.3.1.- Creación de una biblioteca de encapsulados en ARES. ........................................................... 34
1.3.2.- Creación de un encapsulado en ARES. ................................................................................... 36
1.3.3.- Creación de una biblioteca de símbolos en ISIS. ..................................................................... 39
1.3.4.- Creación de un símbolo en ISIS. ............................................................................................. 41
2.- PRINCIPIOS DE FUNCIONAMIENTO DE UN MICROCONTROLADOR PIC. ...................... 47
2.1.- DIAGRAMA EN BLOQUES. ................................................................................................... 49
2.2.- M APA DE MEMORIA. ........................................................................................................... 50
2.2.1.- Memoria de Programa. .......................................................................................................... 50
2.2.2.- Memoria de Datos. ................................................................................................................. 50
3.- INICIACIÓN A LA PROGRAMACIÓN EN C EN UC PIC. ........................................................ 51
3.1.- COMPILADOR CCS................................................................................................................ 51
3.1.1.- Introducción. ........................................................................................................................... 51
3.1.2.- Estructura de un programa. ................................................................................................... 51
3.1.3.- Constantes. ............................................................................................................................. 53
3.1.4.- Tipo de variables. .................................................................................................................... 54
3.1.5.- Operadores. ............................................................................................................................ 55
a) Asignación. ................................................................................................................................................ 55
b) Aritméticos. ............................................................................................................................................... 55
c) Relacionales. .............................................................................................................................................. 55
d) Lógicos. ...................................................................................................................................................... 55
e) De Bits. ...................................................................................................................................................... 56
f) Punteros. .................................................................................................................................................... 56
3.1.6.- Funciones. ............................................................................................................................... 56
3.2.- M ANEJO DE LAS DECLARACIONES DE CONTROL. ................................................................ 59
3.2.1.- If-Else. .................................................................................................................................. 60
3.2.2.- Switch-Case. ....................................................................................................................... 63
3.2.3.- For. ........................................................................................................................................ 66
3.2.4.- While. .................................................................................................................................... 70
3.2.5.- Do-While. ............................................................................................................................. 72
3.3.- CREACIÓN DE FUNCIONES. ................................................................................................ 74
3.4.- M ANEJO Y CREACIÓN DE DRIVER O LIBRERÍAS..................................................................... 80
IES Joan Miró
Página 2
Curso de Robótica y otras aplicaciones en el Aula de Tecnología
4.- EJEMPLOS PRÁCTICOS. ......................................................................................................... 82
4.1.- INTERFACE OPTOACOPLADA ENTRE DISPOSITIVOS DIGITALES Y ANALÓGICOS ...................... 82
4.1.1.- Control con Relés. ................................................................................................................... 82
4.1.2.- Control con Optotransistores. ................................................................................................. 84
4.1.3.- Control con Optotriac. ............................................................................................................ 86
4.2.- CONTROL DE UNA PANTALLA LCD. .................................................................................... 88
4.2.1.- LCD_ejemplo1.c ...................................................................................................................... 91
4.2.2.- LCD_ejemplo2.c ...................................................................................................................... 92
4.2.3.- LCD_ejemplo3.c ...................................................................................................................... 93
4.2.4.- LCD_ejemplo4.c ...................................................................................................................... 94
4.2.5.- LCD_ejemplo5.c ...................................................................................................................... 95
4.2.6.- LCD_ejemplo6.c ...................................................................................................................... 96
4.2.7.- LCD_ejemplo7.c ...................................................................................................................... 97
4.3.- DIGITALIZACIÓN DE UNA SEÑAL ANALÓGICA CON EL SISTEMA DE ADQUISICIÓN DE DATOS...... 99
4.3.1.- Conversión_A/D_D/A.c ......................................................................................................... 101
4.3.2.- Conversión_A-D1.c................................................................................................................ 104
4.3.3.- Conversión_A-D2.c ............................................................................................................... 106
4.3.4.- Conversión_A-D3.c................................................................................................................ 107
4.4.- CONTROL DE VELOCIDAD Y SENTIDO DE GIRO DE MOTORES DE CORRIENTE CONTINUA. ...... 109
4.4.1.- PWM1.c ................................................................................................................................ 110
4.4.2.- PWM2.c ................................................................................................................................ 111
4.4.3.- PWM3.c ................................................................................................................................ 115
4.5.- CONTROL DE UN SERVO DE POSICIÓN. ............................................................................. 117
4.5.1.- Control_2_Servos_Posición.c ................................................................................................ 118
4.6.- DISEÑO DE MANDOS TRANSMISORES Y RECEPTORES DE RADIO FRECUENCIA. ................... 123
4.6.1.- Introducción. ......................................................................................................................... 123
4.6.1.1.- Transmisión serie asíncrona. ......................................................................................................... 123
4.6.1.2.- Modulación en AM. ....................................................................................................................... 124
4.6.1.3.- Protocolo de Comunicaciones entre el Mando y el Receptor. ...................................................... 124
4.6.2.- Ejemplo 1 (Transmisión Simple). ........................................................................................... 126
4.6.3.- Ejemplo2 (Transmisión Compleja). ....................................................................................... 131
4.6.4.- Apertura de una puerta. ....................................................................................................... 140
4.7.- DISEÑO Y CREACIÓN DE UN ROBOT RASTREADOR Y COCHE TELEDIRIGIDO. ....................... 146
IES Joan Miró
Página 3
Curso de Robótica y otras aplicaciones en el Aula de Tecnología
1.- Manejo del laboratorio electrónico virtual “Proteus”.
1.1.- ISIS (Captura y Simulación de circuitos electrónicos).
1.1.1.- Introducción.
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:
Diseño esquemático
del prototipo
Diseño de la
Placa
Fabricación de la Placa
Creación del
Prototipo
Desarrollo
del software
Pruebas del
Prototipo
En caso de error en el prototipo se
tiene que repetir el 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.
Diseño esquemático
del prototipo
Desarrollo
del software
Simulación del
Circuito
Diseño de
la Placa
Fabricación
de la Placa
Fabricación del
Prototipo
En caso de error se depura hasta
obtener los resultados adecuados
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.
IES Joan Miró
Página 4
Curso de Robótica y otras aplicaciones en el Aula de Tecnología
1.1.2.- Captura Electrónica: Entorno Gráfico (ISIS)
Isis es un programa de diseño electrónico que permite realizar esquemas que pueden
simularse en el entorno VMS y/o pasarlos a un circuito impreso a través del entorno de ARES.
Posee una colección de bibliotecas de componentes. Permite crear nuevos componentes y su
modelización para la simulación.
Sin entrar profundamente en este entorno (Requeriría un libro solo para el entorno de ISIS), se
va a explicar cómo dibujar cualquier circuito electrónico. El programa de ISIS posee un
entorno de trabajo formado por una ventana de trabajo y barras de herramientas.
Comandos de
Fichero e
Impresión
Comandos
de Edición
Comandos de
Visualización
Herramientas
de Diseño
Barra de
Menús
Ventana de Edición
Comandos de rotación
y reflexión
Ventana de componentes y
Biblioteca
Ventana de
Trabajo
Modos de Trabajo
Herramientas de
Diseño Electrónico
Comandos de dibujo
Barra de estado
Barra de simulación
Para dibujar el circuito electrónico se deben primero seleccionar el modo componentes
“Component.” y seleccionar el botón “P” de búsqueda de componentes “Pick Devices” en las
bibliotecas.
Component.
Pick Devices
IES Joan Miró
Página 5
Curso de Robótica y otras aplicaciones en el Aula de Tecnología
Se abre un menú asociado a la búsqueda de componentes. Se busca el componente de dos
maneras diferentes por categorías o poniendo el nombre o palabra clave en la ventana
Keywords (Ejemplo: DAC0808_JOAN)
Permite localiza los
componentes por nombre
Represente el símbolo del
Componente en ISIS y si
está simulado
Permite localiza los
componentes por categoría,
clase y fabricante
Muestra el resultado de la búsqueda de los
componentes a que bibliotecas pertenecen y
una descripción breve de cada uno de ellos
Represente el encapsulado
del Componente en ARES
es decir su encapsulado
Ventana de Edición
Al localizar el componente adecuado se realiza una doble pulsación y
aparecerá en la columna de dispositivos “DEVICE”. Se puede realizar esta
acción tantas veces como componentes se quiera incorporar al esquema. Una
vez finalizado el proceso se cierra la ventana de
Comandos de Edición
búsqueda de componentes.
Antes de situar los componentes en la “Ventana de trabajo” se pude
comprobar la orientación en la “Ventana de Edición” y rotarlos con los
“Comandos de Edición”.
Columna de Dispositivos
DEVICE
Una vez seleccionado el componente en
la “Columna de Dispositivos” se pincha sobre la
“Ventana de Trabajo” y este se posiciona. Si pulsamos más veces sobre dicha ventana se
insertaran componentes con una referencia automática. (Tiene que
estar activa para ello seleccionar TOOLS Real Time Anotation).
Si pasamos el ratón por encima del componente, aparece una
“X” en la patilla del componente, esto nos indica que podemos tirar hilo
hasta la siguiente pata de otro o el mismo componente.
IES Joan Miró
Recorrido del Ratón
Página 6
Curso de Robótica y otras aplicaciones en el Aula de Tecnología
Una vez situado los componentes en la “Ventana de Trabajo” se pueden mover, rotar,
copiar, borrar. Para ello se seleccionan con el botón derecho del ratón (Se ponen en rojo) y se
seleccionan los “Comandos de Edición” en “Herramientas de Grupo” ó “Comandos de
rotación y reflexión “ para un solo elemento.
Rotar un solo componente
Rotar un conjunto de componentes
Cada componente electrónico se puede editar, se selecciona con el botón derecho del ratón
(Se pone en rojo) y con el botón izquierdo se abre.
Se puede cambiar su referencia y valor
Se puede ocultar referencias,
Valores, etc.
Se puede cambiar de encapsulado
Se puede excluir de la simulación
IES Joan Miró
Se puede excluir del diseño de la placa
Página 7
Curso de Robótica y otras aplicaciones en el Aula de Tecnología
Para la unión de diferentes componentes “Sin Cables” se pueden utilizar el Icono “Inter-sheetTerminal”
de la caja de Herramientas de Diseño. Este abrirá una ventana donde
aparecen los diferentes terminales.
Terminal por defecto
Terminal de entrada
Terminal de salida
Terminal Bidireccional
Terminal de Alimentación
Terminal de masa
Terminal bus
Terminal de entrada
Terminal de Alimentación
Terminal de masa
Terminal de salida
Si queremos unir cables en forma de bus se utiliza el Icono
Diseño y etiquetarlos con el icono del Modo de Trabajo
Etiquetado de Cable
IES Joan Miró
de la caja de Herramientas de
.
Etiquetado de bus
Página 8
Curso de Robótica y otras aplicaciones en el Aula de Tecnología
Se pueden introducir Generadores de señal, Voltímetros, Osciloscopios, etc. Utilizando los
iconos de las Herramientas de Diseño.
Inter-sheet-Terminal (Terminales)
Device Pin (Patillas de Componentes)
Simulation Graph (Simulación Gráfica)
Tape Recorder (Grabadora)
Generator (Generador)
Voltaje Probe (Sondas de Tensión)
Current Probe (Sondas de Corriente)
Virtual Instruments (Instrumentos Virtuales)
Osciloscopio
Voltímetro (CA)
Generador de Tensión Sinusoidal
1.1.3.- Depuración de programas.
Una de las características importantes del PROTEUS
VSM es la capacidad de depurar programas fuentes de
distintos lenguajes de programación (Lenguajes
ensamblador, C , Basic, etc). La herramienta que se
utiliza está en la barra de tareas llamada “Source”
IES Joan Miró
Página 9
Curso de Robótica y otras aplicaciones en el Aula de Tecnología
Con la opción añadir o remover ficheros fuentes “Add/Remove Source files” introducimos los
fichero fuentes que queremos añadir a nuestro hardware y elegimos la herramienta de
compilación (Programa que traduce un lenguaje de programación a código Binario)
Ficheros Fuente
Cambiar el Fichero Fuente
Herramienta de Compilación
Nuevos Ficheros Fuente
Quitar Ficheros Fuente
Con la opción “Define Code Generation Tools” podemos introducir nuevos compiladores y
depuradores de programas.
Se introduce el Compilador C de
CCSC para uC PIC dentro del
Proteus
Generador de Ficheros
Se introduce el Depurador de
Programas en el Proteus
IES Joan Miró
Página 10
Curso de Robótica y otras aplicaciones en el Aula de Tecnología
Con la opción “Setup External Text Editor” podemos elegir el Editor de Texto.
Editor de texto del Compilador CCSC
Editor de texto del Proteus
La opción Build All compila el programa fuente ejecuta el programa que traduce un lenguaje
de programación a código Binario.
Si hemos utilizado el editor de texto del Compilador CCSC este nos permite depurar el
programa y ver los errores. Abrimos el Fichero “Dec_Hex_Bin.c” y ejecutamos el Icono
“Compile”
Compila un fichero no un proyecto
Al compilar se genera varios ficheros (ERR, HEX, SYM, LST, COF, PJT, TREE, STA) . El fichero con
“Dec_Hex_Bin.COF”, nos permite depurar el Programa en el Proteus y el fichero
“Dec_Hex_Bin.HEX” es el código binario que se introduce de forma real al uC PIC.
IES Joan Miró
Página 11
Curso de Robótica y otras aplicaciones en el Aula de Tecnología
La forma de introducir el fichero “Dec_Hex_Bin.COF” en un microcontrolador uC PIC
es seleccionar lo con el botón derecho del ratón (El uC PIC se pondrá en color rojo) y pulsar el
botón izquierdo. Se abrirá una ventana contextual e introduciremos el fichero.COF.
Pulsar con el botón derecho del ratón y
después con el botón izquierdo
Pulsar con el botón Izquierdo
del ratón y buscar el
fichero.COF deseado
La frecuencia del reloj se fija
aquí independientemente
del hardware que se utilice
externamente (Cristal de
Cuarzo)
Una vez cargado del microcontrolador con el programa fuente “ Dec_Hex_Bin.COF” , se puede
proceder a la simulación del circuito empleando la Barra de Simulación.
Marcha
IES Joan Miró
Paso a Paso
Pausa
Stop
Página 12
Curso de Robótica y otras aplicaciones en el Aula de Tecnología
Con la opción Marcha la simulación se inicia (el botón se vuelve verde) y funciona en modo
continuo. La simulación no es en tiempo real.
Con la opción Stop la simulación se para.
Con la opción Paso a Paso permite trabajar en tramos de tiempo predefinidos, permitiendo
utilizar herramientas de depuración. Esta opción está asociada a la configuración de
Animación, que está en la Barra de Menús en SYSTEM Set Animation Options.
Número de veces que la pantalla
de ISIS se refresca en 1 Segundo
Tiempo de simulación por cada uno
de los Frames (Suele ser el valor
inverso a Frames per Second)
Se muestra las corrientes y
tensiones de las puntas de
prueba que tengamos en el
circuito
Se muestra en las patillas de
circuitos de Lógica Digital
unos cuadrito de color
rojo “1” o azul “0”
Los cables de los
esquemas toman
diferentes colores
en función de la
intensidad que
pasen por ellos.
Incremento de tiempo que se
desea cada vez que se pulsa la
tecla Paso a Paso
Si los valores en la simulación son inferiores a
estos valores, no se visualizan los efectos de
Animation Options
Se muestran en los cables de los
esquemas el sentido de las Intensidades.
La opción SPICE Options define las características de simulación del
sistema. Son parámetros que podemos manipular para obtener más
precisión en la simulación (No se aconseja tocar si se desconocen)
Si disminuimos los parámetros RELTOL, GMIN y PIVTOL el sistema
converge antes, pero es menos preciso.
Aquí , ya se puede simular (Animar) un sistema con microcontroladores .Lo más
interesante de una simulación es la utilización de las herramientas de depuración que
contiene este sistema de desarrollo.
A estas herramientas se accede pulsando primero Pausa de la Barra de Tareas y
después Debug de la Barra de Menús.
IES Joan Miró
Página 13
Curso de Robótica y otras aplicaciones en el Aula de Tecnología
Barra de Simulación
Ejecución de un programa sin puntos de ruptura.
Ejecución de un programa hasta un tiempo determinado
Herramientas de Ejecución de
un programa Paso a Paso
Visualización de las variables creadas por el usuario y las
propias del microcontrolador, con la simulación en marcha.
Visualización del programa fuente para poder utilizar las
herramientas de ejecución paso a paso.
Visualización de las variables del sistema mientras se están
utilizando las herramientas de ejecución paso a paso.
Visualización de los registros del uC utilizando las
herramientas de ejecución paso a paso.
Visualización de la memoria de datos del uC utilizando las
herramientas de ejecución paso a paso.
Visualización de la memoria de
Programa del uC utilizando las
herramientas de ejecución paso
a paso.
Visualización de la memoria
Pila del uC utilizando las
herramientas de ejecución
paso a paso.
Visualización de la memoria
EPROM del uC utilizando las
herramientas de ejecución
paso a paso.
La ventana Watch Window es la más
versátil se pueden añadir variables propias y
del uC y visualizarlas en plena simulación.
IES Joan Miró
Página 14
Curso de Robótica y otras aplicaciones en el Aula de Tecnología
Si se pincha con el botón derecho del ratón sobre la ventana Watch Window aparece un
menú contextual siguiente:
Permite añadir variables del uC PIC
Permite añadir variables propias
Permite poner puntos de ruptura al programa
en función de determinadas variables
Permite seleccionar todas las variables
Buscar variables
Indica el Tipo de variables (Tiene que estar
seleccionada la variable)
Muestra el formato de la variables
Binario, Decimal, Hexadecimal, etc.
(Tiene que estar seleccionada la
variable)
IES Joan Miró
Página 15
Curso de Robótica y otras aplicaciones en el Aula de Tecnología
Si queremos ejecutar un programa en modo depuración, tenemos que realizar los siguientes
pasos:
1.- Crear una carpeta para contener el hardware y el software “Representación en
Binario, BCD, Hexadecimal”
2.- Crear un Sistema Microprocesado con PIC en la ventana de trabajo de ISIS
3.- Generamos un programa en C “Dec_Hex_Bin.c” desde Source ADD/Remove
Source filesNew.
4.- Compilamos el Programa desde CCSC. (Se genera el fichero. COF
“Dec_Hex_Bin.COF”)
5.- Introducimos el fichero.COF “Dec_Hex_Bin.COF” dentro del uC PIC.
6.- Ejecutamos Paso a Paso ó Pause de la Barra de Simulación.
7.- Pinchamos Debug y abrimos las ventanas siguientes:




Watch Windows
PIC CPU Source Code - U1
PIC CPU Variables - U1
PIC CPU Registers - U1
8.- Ejecutamos paso a paso el programa desde PIC CPU Source Code - U1 utilizando las
Herramientas de Ejecución y visualizamos como
varían las variables y el hardware. Es conveniente
poner puntos de ruptura y ejecutar de golpe el programa hasta dicho punto.
El triangulo indica la instrucción que se va a ejecutar
IES Joan Miró
Página 16
Curso de Robótica y otras aplicaciones en el Aula de Tecnología
Simulación en modo continuo, no
permite ver las ventanas de depuración
a excepción de Watch Window
Permite ejecutar una instrucción. Si es
una subrutina o una función entra
dentro de ella.
Habilita o deshabilita
los punto de ruptura.
Ejecuta una instrucción,
subrutina ó función de
golpe
Trabaja de modo continuo hasta que
encuentra un retorno de cualquier
subrutina o función y sale de ella.
Trabaja de modo continuo
hasta que encuentra un
punto de ruptura.
1.2.- Ares (Diseño de Placas).
En este manual de ARES se mostrará los pasos básicos para realizar el rutado de una
placa PCB, no se pretende enseñar de forma precisa el manejo del programa pero sí las
funciones principales del mismo. Pasos a seguir:
1.2.1.- Diseño de un esquema con ISIS.
Buscar componentes que tengan el encapsulado o huella (PCB)
Componente a buscar
Encapsulado(PCB)
IES Joan Miró
Página 17
Curso de Robótica y otras aplicaciones en el Aula de Tecnología
Dibujamos el esquema.
Antes de realizar la placa comprobar si algún componente tiene pines o patillas ocultas. Los
Circuitos Integrados ocultan los pines de masa “GND, VSS” y alimentación “VCC , VDD”.
Editamos el Componente
Si está la pestaña Hidden Pins
indica que existen patillas
ocultas
IES Joan Miró
Página 18
Curso de Robótica y otras aplicaciones en el Aula de Tecnología
Vemos que patillas están ocultas pinchando
sobre las pestana “Hidden Pin “
Patillas ocultas
Para que estas patillas “GND ó VCC” se conecten en un circuito real, se tienen que
etiquetar los cables donde queremos unir. Seleccionamos de la barra Modos de Trabajo el
icono etiquetado de cable “Wire Label”
Etiquetado de Cable
Wire Label
Modos de Trabajo
Buscamos una Masa ó Tierra “GROUND”. Seleccionamos el cable que está unido a ella con el
botón derecho del ratón (Se pone rojo) y pulsamos el botón izquierdo. Se abre un menú
contextual y escribimos GND.
E
Buscamos
una masa
GND y seleccionamos
el cable con el botón
derecho del ratón.
Se abre el menú
contextual y
escribimos GND.
IES Joan Miró
Página 19
Curso de Robótica y otras aplicaciones en el Aula de Tecnología
Buscamos el positivo de la “Pila de 5V”. Seleccionamos el cable que está unido a ella con el
botón derecho del ratón (Se pone rojo) y pulsamos el botón izquierdo. Se abre un menú
contextual y escribimos VCC.
Buscamos el positivo de la
pila de 5V y seleccionamos el
cable con el botón derecho
del ratón.
Se abre el menú
contextual y
escribimos VCC.
El resultado es el siguiente:
Nota: Cuando etiquetamos
con VCC el cable la simulación
no funciona
Todos los componentes tienen que
tener nombre (Ejemplo: R1, E2, etc ),
si no lo tuvieran no aparecerían en el
diseño de la placa.
IES Joan Miró
Página 20
Curso de Robótica y otras aplicaciones en el Aula de Tecnología
1.2.2.- Generación del listado de conexiones “Netlis to Ares”.
Pulsamos el icono de Herramientas de Diseño “ARES”
Herramientas de Diseño
Herramienta de diseño de placas PCB
ARES
Si algún componente no tuviera máscara te pediría que la insertaras, aparece un menú
contextual:
Dentro de una Biblioteca de
Seleccionamos el Encapsulado
componentes
Componente sin encapsulado
Pulsamos con el botón izquierdo del
ratón y aparecerá aquí
Después de asignar las máscaras a los componentes que no las tenían aparece la Aplicación
ARES
Aparecen todos los componentes
que tienen encapsulado para el
diseño de placas
IES Joan Miró
Página 21
Curso de Robótica y otras aplicaciones en el Aula de Tecnología
1.2.2.1.- Entorno de Trabajo
Comandos de archivos y
de Impresión
Comandos de Visualización
File/Print Commands
Display Commands
Ventana de Edición
Barra de Menús
Comandos de Edición
Herramientas de Diseño
Editing Commands
Layout Tools
Herramientas de Posicionamiento y Rutado
Placing & Routing
Herramientas de emplazamientos de PAD
Pad Placement
Herramientas de diseño gráfico
2D Graphics
Ventana de
Trabajo
Selector de Objetos
Object Selector
Selector de Caras
Herramientas de Rotación y Reflexión
Layer Selector
Rotation & Reflection
Barra de Estado
Test de errores
1.2.3.- Creación del tamaño de la placa de PCB.
Una vez situados los componentes en el Selector de objetos “Object Selector” con las
Herramientas de diseño gráfico “2D Graphics” seleccionamos la cuadrado “2D Graphics box”
Cuadrado
2D Graphics box
Herramientas de diseño gráfico
2D Graphics
IES Joan Miró
Página 22
Curso de Robótica y otras aplicaciones en el Aula de Tecnología
Con el Selector de Caras “Layer Selector” seleccionamos borde de placa “Board Edge”
Borde de placa
Selector de Caras
Board Edge
Layer Selector
Con el ratón nos situamos en la Ventana de Trabajo y dibujamos el tamaño de la placa.
Ponemos las cotas y los agujeros para sujetar la placa a un soporte.
Borde de placa
Board Edge
Cotas
Agujeros para
sujetar la placa
a un soporte
Para poner los agujeros para sujetar la placa a un soporte buscamos en Herramientas de
diseño gráfico “2D Graphics” seleccionamos el circulo “2D Graphics circle”
Cuadrado
2D Graphics circle
Herramientas de diseño gráfico
2D Graphics
Con el Selector de Caras “Layer Selector” seleccionamos borde de placa “Board Edge”
Borde de placa
Board Edge
Selector de Caras
Layer Selector
Con el ratón nos situamos en la Ventana de Trabajo y dibujamos el circulo.
IES Joan Miró
Página 23
Curso de Robótica y otras aplicaciones en el Aula de Tecnología
Para poner las Cotas, elegiremos si queremos trabajar en pulgadas o en milímetros. Si
queremos milímetros vamos a los Comandos de Visualización y pinchamos sobre el icono
“Select Metric/ Imperial Coordinates”
Comandos de Visualización
Display Commands
Milímetros/Pulgadas
Select Metric/ Imperial Coordinates
Se visualiza en la parte baja derecha de la Ventana de trabajo.
Coordenadas X/Y en mm
Estas coordenadas X/Y son con respecto a el punto de origen que está en
el centro de la Ventana de trabajo
Si queremos resolución a la hora de dibujar
(Pistas, Cotas, Tamaños de Placa, etc.), tenemos que
cambiarla, para ello vamos a la Barra de Menús y
seleccionamos VIEW y cambiamos dicha resolución.
Una vez realizado los ajustes adecuados, procedemos a poner las cotas. Para ello,
buscamos en Herramientas de diseño gráfico “2D Graphics” y seleccionamos Cotas
“Dimension object placement”
Herramientas de diseño gráfico
2D Graphics
Cotas
Dinension object placement
Con el Selector de Caras “Layer Selector” seleccionamos borde de placa “Board Edge”
Borde de placa
Board Edge
Selector de Caras
Layer Selector
Con el ratón nos situamos en la Ventana de Trabajo y dibujamos las Cotas.
IES Joan Miró
Página 24
Curso de Robótica y otras aplicaciones en el Aula de Tecnología
1.2.4.- Posicionamiento de los componentes dentro de la placa.
Existen dos posibilidades a la hora de situar los componentes.
1.2.4.1.- Posicionamiento Automático.
Seleccionar en las Herramientas de Diseño “Layout Tools” el icono Posicionamiento
Automático dentro de la Placa “Autoplace the components onto the board”.
Herramientas de Diseño
Layout Tools
Posicionamiento Automático dentro de la Placa
Autoplace the components onto the board
Se abre este menú contextual marcamos las reglas de diseño y seleccionamos los
componentes que queremos posicionar de forma automática.
Reglas de Diseño y Peso
Marcamos que componentes queremos
posicionar de forma automática
Restaurar valores
No obstante se puede posicionar determinados componentes de forma manual y el resto de
forma automática.
IES Joan Miró
Página 25
Curso de Robótica y otras aplicaciones en el Aula de Tecnología
1.2.4.2.- Posicionamiento Manual.
Seleccionamos el icono de Edición y situación de componentes “Component
placement and editing” de Herramientas de Posicionamiento y Rutado “Placing & Routing” y
aparecen los componentes de diseño de la placa en ISIS.
Edición y situación de componentes
Component placement and editing
Herramientas de Posicionamiento y Rutado
Placing & Routing
Componentes de diseño
de la placa en ISIS
Selector de Objetos
Object Selector
Situamos los componentes en la placa, para ello posicionamos el ratón sobre la placa y
pulsamos el botón izquierdo del ratón y el componente que este marcado en azul en el
Selector de Objetos “Object Selector” se insertara en la placa.
Uniones entre componentes
Netlis
IES Joan Miró
Página 26
Curso de Robótica y otras aplicaciones en el Aula de Tecnología
Los componentes puestos en la placa se pueden mover, cortar, copiar, etc con los
Comandos de Edición (Conjunto de componentes) y las Herramientas de Rotación y Reflexión
(Un solo componente). Se seleccionan el ó los componentes con el botón derecho del ratón
(Se ponen en rojo) y después se selecciona la herramienta que queremos utilizar (Rotar,
mover, etc).
Rotación a Derecha de un componente (90º)
Rotación a Izquierda de un componente (-90º)
Herramientas de Rotación y Reflexión
Rotation & Reflection
Reflexión a Derechas de un componente
Reflexión a Izquierda de un componente
Comandos de Edición
Deshacer o rehacer operaciones realizadas
Editing Commands
Copiar un conjunto de componente
Borrar un conjunto de componente
Mover un conjunto de componente
Rotación de un conjunto de componente
1.2.5.- Rutado de la pistas.
Existen dos posibilidades a la hora de realizar el ruteado. Pero antes de rutar, podemos marcar
las estrategias de diseño. Para realizarlo nos vamos a la Barra de Menú y seleccionamos
System Set_Strategies
Marcamos las estrategias para pistas de potencia y para pistas de señal.
Pistas de Potencia
Tipo de
prioridad
Optimizar las
esquinas
Tamaño de
las Pistas
Tácticas de rutado
Tamaño de
las Vías
Tipo de Vías
Normales
Ciegas Superiores
Ciegas Inferiores
Ocultas
Tamaño de
las Vías
Tipo cuello
Pistas
Horizontales
y Verticales.
Se trazan
por las
Capas
Superiores
IES Joan Miró
Reglas de diseño
Distancia mínima entre PADs .
Distancia mínima entre PAD y Pista .
Distancia mínima entre Pista .
Distancia mínima a Gráficos.
Distancia mínima al Borde de la Placa o
Ranuras.
Página 27
Curso de Robótica y otras aplicaciones en el Aula de Tecnología
Pistas de Señal
Pistas
Horizontales
y Verticales.
Se trazan
por las
Capas
Inferiores
1.2.5.1.- Rutado Automático.
Seleccionar en las Herramientas de Diseño “Layout Tools” el icono Diseño automático de
pistas “Autorouter the conections specified by de ratsnest”.
Herramientas de Diseño
Layout Tools
Diseño automático de pistas especificadas por las conexiones
Autorouter the conections specified by de ratsnest
Se abre este menú contextual marcamos las reglas de diseño y seleccionamos los
componentes que queremos posicionar de forma automática.
Son las estrategias de la Barra de
Menú seleccionando System y
Set_Strategies
Opciones de Rutado
Permiso de rutado
Permiso de Ordenamiento
Protección manual de las pistas
trazadas manualmente
IES Joan Miró
Página 28
Curso de Robótica y otras aplicaciones en el Aula de Tecnología
El diseño quedaría:
1.2.5.2.- Rutado manual.
Para el rutado manual tenemos las Herramientas de Posicionamiento y Rutado Placing &
Routing
Edición y situación de componentes
Component placement and editing
(Componentes del Diseño)
Edición y situación de las mascaras
Package placement and editing
(Nos permite editar los encapsulados y
añadir otros tipos de encapsulados
que no son del proyecto).
(Abre el director de Biblioteca de
encapsulados)
Herramientas de Posicionamiento
Placing & Routing
Selecciona el Tipo de Pistas
Track placement and editing
Selecciona el Tipo de Vías
Via placement and editing
Planos de Masa o Alimentación
Zone placement and editing
IES Joan Miró
Página 29
Curso de Robótica y otras aplicaciones en el Aula de Tecnología
Si queremos tirar pistas por la cara de abajo de la placa procedemos de la siguiente manera:
Seleccionamos el Tipo de Pistas “Track placement and editing”
Selecciona el Tipo de Pistas
Track placement and editing
Herramientas de Posicionamiento
Placing & Routing
Con el Selector de Caras “Layer Selector” seleccionamos pistas de tipo Bottom Cooper
Tipo de Pista
Selector de Caras
Botton Cooper
Layer Selector
Con el ratón nos situamos en la Ventana de Trabajo y dibujamos la pista de una patilla a otra
siguiendo las uniones entre componentes “Netlis”.
IES Joan Miró
Página 30
Curso de Robótica y otras aplicaciones en el Aula de Tecnología
Si queremos tirar pistas por la cara de abajo, pasar por una vía y tirar pistas por la capa de
arriba procedemos de la siguiente manera:
Seleccionamos el Tipo de Pistas “Track placement and editing”
Selecciona el Tipo de Pistas
Track placement and editing
Herramientas de Posicionamiento
Placing & Routing
Con el Selector de Caras “Layer Selector” seleccionamos pistas de tipo Bottom Cooper
Tipo de Pista
Bottom
Cooper
Selector de Caras
Layer Selector
Con el ratón nos situamos en la Ventana de Trabajo y dibujamos la pista “Bottom Cooper “ de
una patilla a otra siguiendo las uniones entre componentes “Netlis”, pulsas dos veces con el
botón izquierdo del ratón según estas trazando la pista, sale una “VÍA” y las pistas pasan a ser
“Top Cooper”, seguimos trazando la pista y si pulsas otras dos veces con el botón izquierdo del
ratón sale una “VÍA” y las pistas pasan a ser “Bottom Cooper”.
Otra forma más fácil es poner “VÍA” y trazar las pistas con Bottom ó Top
Cooper .
Selecciona el Tipo de Vias
Via placement and editing
Pista Bottom Cooper
VIA
Tamaño de la VIA
Pista Bottom Cooper
IES Joan Miró
Página 31
Curso de Robótica y otras aplicaciones en el Aula de Tecnología
Si queremos que una determinada zona de una cara sea un plano de masa o alimentación
podemos utilizar Zone placement and editing de las Herramientas de Posicionamiento y
Rutado Placing & Routing
Herramientas de Posicionamiento
Planos de Masa o Alimentación
Placing & Routing
Zone placement and editing
Con el Selector de Caras “Layer Selector” seleccionamos pistas de tipo Bottom Cooper
Tipo de Zona
Top Cooper
Selector de Caras
Layer Selector
Con el ratón nos situamos en la Ventana de Trabajo y dibujamos la Zona que queremos de
cobre. Aparece un menú contextual donde decimos tamaño de la zona de cobre, Zonas de
clareo, etc.
Tamaño de las Zona
de Cobre
Clareo
La placa queda:
IES Joan Miró
Página 32
Curso de Robótica y otras aplicaciones en el Aula de Tecnología
Si queremos cambiar el tamaño o la forma de los PAD de un determinado componente
utilizar herramientas de emplazamientos de PAD “Pad Placement”
PAD Redondo
PAD Cuadrado
PAD tipo DIL
Herramientas de emplazamientos de PAD
Pad Placement
Seleccionamos el tipo de PAD.
Tipo de PAP
Tamaño del PAP
Pinchamos el PAD de un componente de nuestro circuito y este se sustituye.
Tamaño del PAP
Tamaño del PAP
S50-25
S90-50
IES Joan Miró
Página 33
Curso de Robótica y otras aplicaciones en el Aula de Tecnología
Utilizando las herramientas de diseño de placas que nos proporciona ARES tenemos como
resultado el siguiente circuito:
1.3.- Creación de símbolos en ISIS y encapsulados en ARES.
1.3.1.- Creación de una biblioteca de encapsulados en ARES.
Para crear una Biblioteca propia en ARES, se deben primero seleccionar el modo de edición y
situación de componentes “Package placement and editing.” y seleccionar el botón “L”
de manejo de Bibliotecas “Manage Libraries”.
Edición y situación de los Encapsulados
Package placement and editing
Herramientas de Posicionamiento y Rutado
Placing & Routing
Manejo de Bibliotecas
Manage Libraries
Se abre un menú contextual, donde podemos crearnos nuestra propia Biblioteca, añadir
encapsulados de otra Biblioteca, borrar encapsulados, etc.
IES Joan Miró
Página 34
Curso de Robótica y otras aplicaciones en el Aula de Tecnología
Creación de una Biblioteca
Cuando pulsamos “Create Library” tenemos que dar un nombre a la biblioteca
“Robótica_ARES” y donde queremos crear la biblioteca “C:\Archivos de Programa\Labcenter
Electronic\Proteus 6 Professional\Library”.
Nos pedirá un número
máximo de Encapsulados.
Máximo 4000
Pulsamos “OK” y la biblioteca se crea. En la biblioteca nueva “Robótica_ARES”, podemos
copiar componentes “CONN-DIL8” de otras bibliotecas ”CONNECTORS”. Seleccionamos el
encapsulado y damos al icono de copiar “Copy Items”
IES Joan Miró
Página 35
Curso de Robótica y otras aplicaciones en el Aula de Tecnología
Biblioteca
Robótica_ARES
Confirmación
de copia
1.3.2.- Creación de un encapsulado en ARES.
a) Dibujamos el componente sin PAD.
Abrimos el ARES y seleccionamos Herramientas de diseño gráfico “2D Graphics”.
Con el Selector de Caras “Layer Selector” seleccionamos borde de encapsulado “Top Silk” y
dibujamos el encapsulado.
Borde de Encapsulado
Top Silk
Herramientas de diseño gráfico
2D Graphics
Selector de Caras
Layer Selector
IES Joan Miró
Página 36
Curso de Robótica y otras aplicaciones en el Aula de Tecnología
b) Le añadimos los PAD.
Seleccionamos PAD Redondo de las Herramientas de emplazamiento de PAD
“Pad Placement “ los insertamos en el encapsulado dibujado.
PAD Redondo
Herramientas de emplazamientos de PAD
Tamaño del PAP
Pad Placement
c) Editamos el PAD (Poner un número)
Seleccionamos el PAD con el botón derecho del ratón del ratón “El PAD se pone blanco” y
pulsamos el izquierdo. Numeramos el PAP “U” con “1”.
Numeramos el PAP
d) Hacer el encapsulado y almacenarlo.
Seleccionamos el encapsulado con el botón derecho del ratón (se pone en blanco), pinchamos
sobre el icono de realizar un encapsulado “Make Package” de los “Comandos de edición”
Comandos de Edición
Editing Commands
Hacer el encapsulado
Make Package
IES Joan Miró
Página 37
Curso de Robótica y otras aplicaciones en el Aula de Tecnología
Aparece un menú contextual y escribimos el nombre de la huella “MOTOR-TRI_ROBOTICA” su
categoría “Connectors”, tipo de agujero de PAD “agujero pasante” “Through Hole” y la
biblioteca donde se almacena “Robótica_ARES”
Nombre del
Encapsulado
Categoría
Tipo de agujero del
PAD
e) Deshacer el encapsulado y almacenarlo.
Biblioteca donde se
almacena
Seleccionamos el encapsulado con el botón derecho del ratón (se pone en blanco), pinchamos
sobre el icono de deshacer encapsulados. “Decompose” de los “Comandos de edición”
Comandos de Edición
Editing Commands
Deshacer el Encapsulado
Decompose
Variamos el encapsulado, lo seleccionamos con el botón derecho del ratón y volvemos
almacenarlo pulsando Make Package
IES Joan Miró
Página 38
Curso de Robótica y otras aplicaciones en el Aula de Tecnología
1.3.3.- Creación de una biblioteca de símbolos en ISIS.
Para crear una biblioteca propia en ISIS, se deben primero seleccionar el modo
componentes “Component.” y seleccionar el botón “L” de manejo de
bibliotecas “Manage Device Libraries”.
Component.
Manage Device Libraries
Se abre un menú contextual ,
donde podemos crearnos nuestra
propia biblioteca, añadir símbolos
de otra biblioteca, borrar
símbolos, etc.
Creación de una Biblioteca
Cuando pulsamos “Create Library” tenemos que dar un nombre a la biblioteca “Robótica_ISIS”
y donde queremos crear la biblioteca “C:\Archivos de Programa\Labcenter Electronic\Proteus
6 Professional\Library”.
Nos pedirá un número
máximo de simbolos.
Máximo 4000
IES Joan Miró
Página 39
Curso de Robótica y otras aplicaciones en el Aula de Tecnología
Pulsamos “OK” y la biblioteca se crea. En la biblioteca nueva “Robótica_ISIS”, podemos copiar
componentes “2N2907” de otras bibliotecas ”Bipolar”. Seleccionamos el encapsulado y
damos al icono de copiar “Copy Items”
Biblioteca
Robótica_ISIS
Confirmación
de copia
IES Joan Miró
Página 40
Curso de Robótica y otras aplicaciones en el Aula de Tecnología
1.3.4.- Creación de un símbolo en ISIS.
a) Dibujamos el componente sin patillas.
Abrimos el ISIS y seleccionamos “Comandos de Dibujo”
Comandos de Dibujo
b) Le añadimos pines ó patillas.
Seleccionamos Patillas de Componentes “Device Pin“ de las Herramientas de Diseño
Tipo de Pin
Patillas de Componentes
Device Pin
Herramientas de Diseño
Ponemos los pines en el dibujo realizado, teniendo en cuenta lo siguiente:


Que los caracteres no estén excesivamente próximos al pin (El pin no conectará con
el hilo si esto ocurre y habría que descomponer el componente y modificarlo).
Que el tipo de de rejilla sea mayor de Snap 50th (Ver View de la Barra de Menús),
para poder insertar el hilo de forma más cómoda.
c) Editamos el pin (Poner el nombre y número)
Seleccionamos el pin con el botón derecho del ratón del ratón “El pin se pone rojo” y
pulsamos el izquierdo. Nombramos al Pin “U” y lo numeramos “1”.
IES Joan Miró
Página 41
Curso de Robótica y otras aplicaciones en el Aula de Tecnología
Nombre
Número
d) Hacer el símbolo y almacenarlo.
Seleccionamos el símbolo con el botón derecho del ratón (se pone en rojo), pinchamos sobre
el icono de realizar un dispositivo “Make device” de los “Comandos de edición”
Comandos de
Edición
Make device
Aparece un menú contextual y escribimos el nombre del componente “MOTOR-TRI_ROBOTICA”
y un parámetro de referencia “M”.
IES Joan Miró
Página 42
Curso de Robótica y otras aplicaciones en el Aula de Tecnología
Pulsamos “Next” aparece otra ventana donde podemos asignarle el encapsulado físico (Si esta
creado lo asignamos, se puede no asignar y pasar a la siguiente ventana contextual). Pulsamos
añadir encapsulado Add/Edit .
Añadir Encapsulado
Aparece un menú contextual donde pulsamos añadir el encapsulado
Añadir Encapsulado
IES Joan Miró
Página 43
Curso de Robótica y otras aplicaciones en el Aula de Tecnología
Aparece otro menú contextual que abre el ARES y elegimos el encapsulado adecuado.
Elegimos el encapsulado adecuado
MOTOR-TRI_ROBOTICA
Ponemos la palabra
clave MOTOR y aparecen
diferentes motores
Vista del encapsulado
Aparece otro menú contextual en el que podemos añadir pines y poner este encapsulado
como principal.
Encapsulado por defecto
Añadir Pines
Usar Bibliotecas de
ARES
IES Joan Miró
Página 44
Curso de Robótica y otras aplicaciones en el Aula de Tecnología
Si pulsamos asignación de huella “Assign Package(s)” esta queda asignada al símbolo de ISIS
Se abre otro menú contextual donde se puede introducir el modelo de componte simulado
IES Joan Miró
Página 45
Curso de Robótica y otras aplicaciones en el Aula de Tecnología
Se abre otro menú contextual donde se puede introducir un documento donde se especifique
sus características “Data Sheet”
Introducción del
Documento
Se abre otro menú contextual donde se le asigna categoría, Biblioteca.
Categoría
Biblioteca
IES Joan Miró
Página 46
Curso de Robótica y otras aplicaciones en el Aula de Tecnología
e) Deshacer el símbolo y almacenarlo.
Seleccionamos el símbolo con el botón derecho del ratón (se pone en rojo), pinchamos sobre
el icono de deshacer un dispositivo “Decompose” de los “Comandos de edición”
Comandos de
Edición
Deshacer el símbolo
Decompose
Variamos el simbolo, lo seleccionamos con el botón
derecho del ratón y la volvemos almacenarlo pulsando
Make Device
2.- Principios de funcionamiento de un Microcontrolador PIC.
Antes de definir un sistema digital basado en microcontroladores habría que definir un
sistema basado en microprocesadores.
Un microprocesador es básicamente un chip que contiene la CPU (Central Proccesing
Unit) que se encarga de controlar todo un sistema. Un sistema digital basado en un
microcontrolador es un sistema abierto ya que su configuración difiere según a la aplicación a
la que se destine. Se pueden acoplar los módulos necesarios para configurarlo con las
características que se desee. Para ello se saca al exterior las líneas de sus buses de datos,
direcciones y control de modo que permita su conexión con la memoria y los módulos de
entrada/ salida. Finalmente resulta un sistema implementado por varios circuitos integrados
dentro de una misma placa de un circuito impreso.
IES Joan Miró
Página 47
Curso de Robótica y otras aplicaciones en el Aula de Tecnología
Un microcontrolador es un sistema cerrado, lo que quiere decir que en un solo
circuito integrado, se diseña un sistema digital programable completo. Este dispositivo, se
destina a gobernar una sola tarea que no se puede modificar. Disponen de los bloques
esenciales como CPU, memorias de datos y de programa, reloj, periféricos de entrada/salida,
etc.
Existen multitud de fabricantes de microcontroladores Intel, Motorola, Microchip, etc.
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.
Los microcontroladores PIC se caracterizan por lo siguiente:

Tienen una arquitectura Hardvard utiliza dos tipos de memorias (Datos y Programa)
con buses independientes.
CPU
Buses
Memoria
de
Programa y
de Datos
Memoria
de
Programa
Buses
(EEPROM)
Arquitectura Von Neumann

Memoria
de Datos
(RAM)
CPU
Buses
Arquitectura Hardvard
Utilizan un procesamiento segmentado o Pipeline que permiten realizar dos
procesos simultáneamente a la vez (lectura y ejecución de instrucciones).
PROGRAMA
1. BSF STATUS,RP0
2. CLRF TRISB
3. MOVLW 0XFF
1º Ciclo
2º Ciclo
Búsqueda 1
Ejecuta 1
Búsqueda 2
3º Ciclo
4º Ciclo
5º Ciclo
Ejecuta 2
Búsqueda 3
4. MOVWF TRISA
Ejecuta 3
Búsqueda 4
Ejecuta 4

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.

Tiene una estructura Ortogonal es decir que una
instrucción puede utilizar cualquier elemento de la
arquitectura como fuente o destino de datos.
IES Joan Miró
Página 48
Curso de Robótica y otras aplicaciones en el Aula de Tecnología
El microcontrolador PIC 16F876A es un CHIP de 28 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
22 Patillas de entradas/salidas.
Sistema de Adquisición de datos (5
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.
2.1.- Diagrama en bloques.
IES Joan Miró
Página 49
Curso de Robótica y otras aplicaciones en el Aula de Tecnología
2.2.- Mapa de memoria.
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.
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.
IES Joan Miró
Página 50
Curso de Robótica y otras aplicaciones en el Aula de Tecnología
3.- Iniciación a la programación en C en uC PIC.
3.1.- Compilador CCS.
3.1.1.- Introducción.
Un compilador convierte el lenguaje de alto nivel a instrucciones en código máquina. El
compilador CCS C es un compilador cruzado “cross-compiler realizado para un determinado
grupo de microcontroladores PIC (Se desarrolla un lenguaje de alto nivel “C” partiendo de
instrucciones de bajo nivel “Ensamblador” de los microcontroladores PIC).
El Compilador C de CCS ha sido desarrollado específicamente para PIC. Dispone de una
amplia librería de funciones predefinidas, comandos de preprocesado y ejemplos. Además,
suministra los controladores (driver) para diversos dispositivos como LCD, convertidores AD,
relojes de tiempo real, EEPROM serie, etc. Las características generales de este compilador se
pueden encontrar en la dirección www.ccsinfo.com.
Los programas son editados y compilados a instrucciones máquina en el entorno de
trabajo del PC. Estos programas pueden ser depurados con diferentes sistemas de desarrollo
MPLAB , Proteus, etc.
El código máquina puede ser cargado desde el PC al microcontrolador PIC mediante
cualquier programador (ICD2, Bootloader, etc.).
El Lenguaje C de “CCS C” es estándar que incluye las directivas (#include, etc.),
suministra unas directivas especificas para PIC (#DEVICE,ETC.); además incluye funciones
específicas (bit-self(), etc.) . (Mirar el manual de CCS C).
Se suministra con editor que permite controlar la sintaxis del programa.
3.1.2.- Estructura de un programa.
Para escribir un programa en C con el CCS C se deben tener en cuenta los elementos básicos
de su estructura.

Directivas de Preprocesado: Controlan la conversión del programa al código máquina
por parte del compilador.

Declaración de las Funciones: Indicamos que tipo de función es.

Programas o Funciones: Conjunto de Instrucciones. Pueden existir varios. Tiene que
existir uno como principal llamado void main().

Instruciones: Indican cómo debe comportarse el uC PIC.

Comentarios: Permiten describir lo que significa cada línea del programa
IES Joan Miró
Página 51
Curso de Robótica y otras aplicaciones en el Aula de Tecnología
/* El Puerto C puede tomar valores comprendidos entre 0 y 255
Si el Puerto C es 0 realizar la función de mostrar por el Display de 7 segmentos los números del 0 al 9
con una cadencia de 1 segundo. Después de este proceso apagar el Display.
Si el Puerto C es 1 realizar la función de simulación de las luces del coche fantástico.
Nombre
después de este proceso apagar los Led.
Si el Puerto C es distinto de 0 y 1 realizar una función de la raíz cuadrada del dato leído
y devolverlo en una variable llamada resultado y mostrarlo en el Puerto B */
del Programa
/* ***************************** Directivas de Preprocesado************************************************* */
// (Controlan la conversión del programa a código maquina 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
#use delay( clock = 4000000 )
// Define la palabra de configuración del microcontrolador PIC
// Trabaja con un reloj tipo XT y no utiliza perro guardián Wathdog
// Define la frecuencia del reloj de 4 MHz
#include <math.h>
#include <LUCES-COCHE-FANTASTICO.h>
#include <REPR-NUMEROS-DISPL.h>
// Librerías de funciones matemáticas.
// Librerías de simulación Luces del Coche Fantástico.
// Librerías de simulación representación de los números en el Display 7Seg.
#BYTE TRISC = 0x87
#BYTE portC = 0x07
#BYTE TRISB = 0x86
#BYTE portB = 0x06
#BYTE TRISD= 0x85
#BYTE portD = 0x05
// TRISC en 87h.
// PORTC en 07h.
// TRISB en 86h.
// PORTB en 06h.
// TRISA en 85h.
// PORTA en 05h.
#BIT rc0 = 0x07.0
#BIT rc1 = 0x07.1
// RC0 en 0x07 patilla 0.
// RC1 en 0x07 patilla 1.
Directivas de Preprocesado
/* ************************************** Declaración de funciones ****************************************** */
void VariasCosas (int8);
int8 Raiz (int8);
// Generación de la señal cuadrada.
// Realiza la raíz cuadrada.
Declaración de Funciones
// ***************************** Función principal o programa principal *******************************************
void main()
Indica programa principal
{
int8 muestra1;
// Variable muestra1 definida como un entero de 8 bit
TRISB = 0B00000000;
TRISC= 0B11111111;
TRISD = 0B00000000;
// Defines Puerto B como SALIDA de datos.
// Defines Puerto C como ENTRADA de datos.
// Defines Puerto D como SALIDA de datos.
portB = 0B00000000;
portD = 0B00000000;
// Reseteamos el Puerto B.
// Reseteamos el Puerto D.
while (1)
// Ejecuta indefinidamente lo que está entre corchetes.
Programa Principal
{
muestra1 = portC;
VariasCosas(muestra1);
// Leemos el Puerto C.
// Ejecuta la función VariasCosas definida por la variable muestra1.
}
}
IES Joan Miró
Página 52
Curso de Robótica y otras aplicaciones en el Aula de Tecnología
//******************************** Función VariasCosas ******************************************************
void VariasCosas (int8 muestra2)
{
switch (muestra2)
// Preguntamos por la variable muestra2 si es 0 ejecuta el case 0, si es 3 el case 3,
// si es distinto de 0 y 3 ejecuta Raíz
{
case 0:
LucesFantastico();
break;
case 1:
NumerosDisplay();
break;
// Llamamos a la función LucesFantastico
// Llamamos a la función NumerosDisplay
Función VariasCosas
default:
{
portB = Raiz(muestra2);
delay_ms(50);
// Ejecuta la función Raíz definida por la variable muestra2.
// Temporizamos 50 mS.
}
}
}
//******************************* Función Raíz ***************************************************************
int8 Raiz (int8 muestra3)
{
int8 resultado;
resultado = SQRT (muestra3);
return(resultado);
Función Raíz
}
3.1.3.- Constantes.
Son números, caracteres, etc
Las constantes se pueden especificar en decimal, octal, hexadecimal o en binario, etc
IES Joan Miró
123
Decimal
0123
Octal
0b01011011
Binario
‘X’
Caracter
Página 53
Curso de Robótica y otras aplicaciones en el Aula de Tecnología
3.1.4.- Tipo de variables.
Los programas tienen variables y se ubican en la memoria RAM. Se deben declarar
obligatoriamente antes de usarlas. Para ello se debe de indicar el nombre y el tipo de dato que
manejará. Se define de la siguiente forma:
Tipo Nombre de la Variable = Valor Inicial
Tipo de datos:
Tipo
Tamaño
Rango
Descripción
Int1
Short
Int
Int8
Int16
Long
Int32
1 bit
0a1
Entero de 1 bit
8 bit
0 a 255
Entero de 8 bit
16 bit
0 a 65535
Entero de 16 bit
32 bit
0 a 4.294.967.295
Entero de 32 bit
Float
32 bit
±3,4E ±38 (7 dígitos)
Coma flotante
Char
8 bit
0 a 255
Carácter
Signed Int8
8 bit
-128 a 127
Entero con signo
Signed Int16
16 bit
-32.768 a 32.767
Entero largo con signo
Signed Int32
32 bit
-231 a +(231-1)
Entero de 32 bit con signo
Ejemplo:
Int8 dato=34; // Es una variable de tipo entero de 8 bit (Valores comprendidos entre 0y 255)
que se la inicializa con 34.
Las variables pueden ser locales es decir solo son validas dentro de la función o globales que
son validas para todo el programa.
IES Joan Miró
Página 54
Curso de Robótica y otras aplicaciones en el Aula de Tecnología
3.1.5.- Operadores.
a) Asignación.
Transfieren datos de una expresión, una constante o una variable, a una variable.
Operador
=
+=
-=
*=
/=
%=
<<=
Ejemplo
a=c
c+=4
c−=4
c*=4
c/=4
c%=4
c <<= 4
>>=
c >>= 4
&=
c&=4
|=
c|=4
^=
c^=4
Significado
Asignación simple. El contenido de c se introduce en a
Incrementa c en 4 unidades.
Decrementa c en 4 unidades.
Modifica c multiplicándolo por 4.
Ahora c contendrá el cociente de dividir c entre 4.
Ahora c contendrá el resto de dividir c entre 4.
Ahora c contendrá el resultado de desplazar
4 bits a la izquierda a la propia variable c.
Ahora c contendrá el resultado de desplazar
4 bits a la derecha a la propia variable c.
Se hace la operación AND entre los bits de c y los del valor 4.
El resultado se almacena en c.
Se hace la operación OR entre los bits de c y los del valor 4.
El resultado se almacena en c.
Se hace la operación XOR entre los bits de c y los del valor 4.
El resultado se almacena en c.
b) Aritméticos.
Sirven para operar con datos numéricos.
Operador
+
*
/
%
-++
sizeof
Significado
Suma
Resta
Multiplicación
División
Módulo, resto de una división entera
Incremento
Decremento
Determina el tamaño “en byte”, de un operando
c) Relacionales.
Sirven para comparar números o caracteres.
Operador
<
>
>=
<=
==
!=
?:
Significado
Menor que
Mayor que
Mayor o igual que
Menor o igual que
Igual
Distinto
Expresión condicional
d) Lógicos.
Permiten crear expresiones lógicas, es decir, basadas en el álgebra de Boole.
Una expresión lógica es aquella que da como resultado cierto o falso.
IES Joan Miró
Página 55
Curso de Robótica y otras aplicaciones en el Aula de Tecnología
Por ejemplo:
numero < 5 es una expresión lógica, pues puede ser cierto o falso, dependiendo del
valor que tenga la variable numero en el momento de evaluar esa expresión.
Los operadores lógicos sirven para concatenar dos o más expresiones lógicas. El
resultado final de evaluar el conjunto de esas expresiones también será verdadero o
falso; por lo tanto, esas expresiones juntas también formarán una expresión lógica.
Ejemplo:
(numero < 5) && (nivel >= 2) Tenemos dos expresiones lógicas unidas por un operador lógico,
lo que forma otra expresión lógica más compleja. Si cumple la expresión será cierta
Operador
!
&&
||
Significado
Negación (No)
Conjunción (Y)
Disyunción (O)
e) De Bits.
Realiza operaciones lógicas a nivel de bits independientes, son válidos con datos de los tipos
char, int, long.
Operador
~
&
^
|
>>
<<
Significado
Negación de bits (No)
Conjunción de bits (Y)
Disyunción de bits (O)
O exclusiva (XOR)
Desplazamiento de bits a la izquierda
Desplazamiento de bits a la derecha
f) Punteros.
Permiten conocer la dirección de memoria en la que está almacenada una variable o una
función. También sirven para conocer el valor del dato almacenado en una dirección dada.
Operador
&
*
->
Significado
Dirección
Indirección
Puntero a estructura
3.1.6.- Funciones.





Son bloques de sentencias.
Al igual que las variables, las funciones deben definirse y declararse antes de
utilizarlas.
Una función puede ser llamada desde una sentencia de otra función.
Una función puede devolver un valor a la sentencia que la ha llamado.
Una función puede recibir parámetros o argumentos.
IES Joan Miró
Página 56
Curso de Robótica y otras aplicaciones en el Aula de Tecnología
 El Puerto C puede tomar valores comprendidos entre 0 y 255
/*
Si el Puerto C es 0 realizar la función de mostrar por el Display de 7 segmentos los números del 0 al 9
con una cadencia de 1 segundo. Después de este proceso apagar el Display.
Si el Puerto C es 1 realizar la función de simulación de las luces del coche fantástico.
después de este proceso apagar los Led.
Si el Puerto C si es distinto de 0 y 1 realizar una función de la raíz cuadrada del dato leído
y devolverlo en una variable llamada resultado y mostrarlo en el Puerto B */
/* ***************************** Directivas de Preprocesado************************************************* */
// (Controlan la conversión del programa a código maquina 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
#use delay( clock = 4000000 )
// Define la palabra de configuración del microcontrolador PIC
// Trabaja con un reloj tipo XT y no utiliza perro guardián Wathdog
// Define la frecuencia del reloj de 4 MHz
#include <math.h>
#include <LUCES-COCHE-FANTASTICO.h>
#include <REPR-NUMEROS-DISPL.h>
// Librerías de funciones matemáticas.
// Librerías de simulación Luces del Coche Fantástico.
// Librerías de simulación representación de los números en el Display 7Seg.
#BYTE TRISC = 0x87
#BYTE portC = 0x07
#BYTE TRISB = 0x86
#BYTE portB = 0x06
#BYTE TRISD = 0x88
#BYTE portD = 0x08
// TRISC en 87h.
// PORTC en 07h.
// TRISB en 86h.
// PORTB en 06h.
// TRISA en 88h.
// PORTA en 08h.
Definición de la Función “VariasCosas”
Definición de la Función “Raiz”
Devuelve un valor entero de 8 bit “ int8”
Recibe una variable entera de 8 bit “ int8”
#BIT rc0 = 0x07.0
// RC0 en 0x07 patilla 0.
/* ************************************** Declaración de funciones ****************************************** */
void VariasCosas (int8);
int8 Raiz (int8);
// Generación de la señal cuadrada.
// Realiza la raíz cuadrada.
Declaración de Funciones
// ***************************** Función principal o programa principal *******************************************
void main()
Función Principal
{
int8 muestra1;
// Variable muestra1 definida como un entero de 8 bit
TRISB = 0B00000000;
TRISC = 0B11111111;
TRISD = 0B00000000;
// Defines Puerto B como SALIDA de datos.
// Defines Puerto C como ENTRADA de datos.
// Defines Puerto D como SALIDA de datos.
portB = 0B00000000;
portD = 0B00000000;
// Reseteamos el Puerto B.
// Reseteamos el Puerto D.
while (1)
// Ejecuta indefinidamente lo que está entre corchetes.
{
muestra1 = portC;
VariasCosas(muestra1);
// Leemos el Puerto C.
// Ejecuta la función VariasCosas definida por la variable muestra1.
}
}
IES Joan Miró
LLamada de la Función “VariasCosas” lleva implícita la variable “muestra1”
Página 57
Curso de Robótica y otras aplicaciones en el Aula de Tecnología
//******************************** Funcion VariasCosas ******************************************************
Función “VariasCosas” lleva implícita la variable “muestra2”
muestra2 muestra1
void VariasCosas (int8 muestra2)
{
switch (muestra2)
// Preguntamos por la variable muestra2 si es 0 ejecuta el case 0, si es 3 el case 3,
// si es distinto de 0 y 3 ejecuta Raíz
{
case 0:
LucesFantastico();
break;
Llamada a la Función “Luces Fantastico”
// Llamamos a la función LucesFantastico
Llamada a la Función “NumerosDisplay”
case 1:
NumerosDisplay();
break;
// Llamamos a la función NumerosDisplay
implícita la variable “muestra2”
devuelve un valor de 8bit
portB resultado
default:
{
Llamada de una sentencia
a otra función
Llamada a la Función “Raiz” y lleva
portB = Raiz(muestra2);
delay_ms(50);
// Ejecuta la función Raíz definida por la variable muestra.
// Temporizamos 50 mS.
}
}
LLamada de la Función “delay_ms” lleva implícita el parametro “50”
}
//******************************* Funcion Raiz ***************************************************************
int8 Raiz (int8 muestra3)
Función “Raiz” lleva implícita la variable “muestra3”
Muestra3 muestra2
{
int8 resultado;
resultado = SQRT (muestra3);
return(resultado);
}
Llamada de una sentencia
a otra función
IES Joan Miró
Llamada a la Función “SQRT” y lleva implícita la
variable “muestra3”devuelve un valor de 8bit a
resultado
Función “Raiz” devuelve el valor de la variable “resultado”
Página 58
Curso de Robótica y otras aplicaciones en el Aula de Tecnología
3.2.- Manejo de las Declaraciones de Control.
Son sentencias líneas de código usadas para controlar el proceso de ejecución del
programa. Antes de ver las sentencias básicas de un programa vamos a explicar que se
entiende por flujo de programa.
Se entiende por flujo de un programa el modo en que se avanza de una instrucción a
la siguiente dentro de ese programa. También podríamos decir que es la forma en que fluyen
las instrucciones por el microcontrolador. Existen tres estructuras de control del flujo:
Instrucción 1
Instrucción 2
Instrucción 3
Instrucción 4
Instrucción 1
Instrucción 1
no
Condición
Instrucción 3
si
Opción 1
Instrucción 2
Opción 2
si
Condición
no
Estructura Secuencial
Estructura de selección
Instrucción 4
Estructura de repetición

Estructura secuencial: la siguiente instrucción que se ejecuta es la que está justo a
continuación en el listado del código fuente del programa, y que estará en la siguiente
posición de memoria cuando se compile

Estructura de selección: dependiendo del resultado de la evaluación de una
condición, seguidamente se ejecutará una instrucción u otra. De este modo el flujo de
instrucciones se divide en dos o más caminos, aunque si la condición decide avanzar
por un camino se abandonarán los otros (no se puede avanzar por más de un camino a
la vez).

Estructura de iteración o repetición: la siguiente instrucción que se ejecuta se
encuentra antes que la que se acaba de ejecutar, pues ya se ha pasado por ella
anteriormente. Diremos que se ha formado un lazo o bucle en el flujo del programa.
Normalmente hay que evitar los bucles infinitos, dando la posibilidad de que en algún
momento (mediante una condición) se dejen de repetir las mismas instrucciones.
IES Joan Miró
Página 59
Curso de Robótica y otras aplicaciones en el Aula de Tecnología
Para entender mejor las declaraciones de control, los ejemplos se van a desarrollar en un
entrenador realizado en ISIS.
3.2.1.- If-Else.
La sentencia if-else nos ayuda a tomar decisiones.
Se define de la siguiente manera:
if (expresión)
{
si
Instrucción_1;
no
Condición
Instrucción_n;
}
Instrucción_1
Instrucción _a
Instrucción _n;
Instrucción _z;
else
{
Instrucción_a;
Inciónstruc_z;
}
IES Joan Miró
Página 60
Curso de Robótica y otras aplicaciones en el Aula de Tecnología
Programa_1:
Leer la Patilla RC0 = 1  (RB0=0 y RB1=1),
RC0 = 0  (RB0=1 y RB1=0)
Diagrama de Flujo:
RC0 = 1  (RB0=0 y RB1=1)
RC0 = 0  (RB0=1 y RB1=0)
// Configuración
TRISB 0B00000000
TRISC 0B11111111
// Defines Puerto B como SALIDA de datos.
// Defines Puerto C como ENTRADA de datos.
// Reseteamos el Puerto B.
portB  0B00000000
si
no
¿rc0=1?
rb0  0 // Apagar D9
rb1  1 // Encender D10
IES Joan Miró
rb0  1 // Encender D9
rb1 0 // Apagar D10
Página 61
Curso de Robótica y otras aplicaciones en el Aula de Tecnología
Programa_1.c: ( Mirar el punto 1.1.3.- Depuración de programas.)
/*
Leer la Patilla RC0 si es 1 (RB0=0 y RB1=1) y si es 0 (RB0=1 y RB1=0)(Utilizando directamente la RAM)
*/
// ********************************* Directivas de Preprocesado************************************
// (Controlan la conversión del programa a código máquina por parte del compilador)
#include <16F877.h>
#BYTE TRISB = 0x86
#BYTE portB = 0x06
// Incluye el fichero 16F877 al programa tiene que estar en la misma
// carpeta del programa define funciones, patillas y registros.
// Define la palabra de configuración del microcontrolador PIC
// Trabaja con un reloj tipo XT y no utiliza perro guardián Wathdog
// Define la frecuencia del reloj de 4 MHz y el tipo de reloj que vamos a
// utilizar en las funciones de retardo delay
// TRISB en 86h.
// PORTB en 06h.
#BYTE TRISC = 0x87
#BYTE portC = 0x07
// TRISC en 87h.
// PORTC en 07h.
#BIT rb0 = 0x06.0
#BIT rb1 = 0x06.1
#BIT rc0 = 0x07.0
// RB0 en 0x06 patilla 0.
// RB1 en 0x06 patilla 1.
// RC0 en 0x07 patilla 0.
#fuses XT,NOWDT
#use delay( clock = 4000000 )
// **************************** Función principal o programa principal *******************************
// Se define con un void main,
void main()
{
TRISB = 0B00000000;
TRISC = 0B11111111;
// Defines Puerto B como SALIDA de datos.
// Defines Puerto C como ENTRADA de datos.
portB = 0B00000000;
// Reseteamos el Puerto B.
while (1)
// Ejecuta indefinidamente lo que está entre corchetes.
{
if (rc0 == 1 )
// Preguntamos si RC0=1
// Si RC0=1 ejecuta lo que viene a continuación.
{
rb0 = 0;
rb1 = 1;
}
else
{
// Apagar D9
// Encender D10
// Si RC0=0 ejecuta lo que viene a continuación.
rb0 = 1;
rb1 = 0;
// Encender D9
// Apagar D10
}
}
}
IES Joan Miró
Página 62
Curso de Robótica y otras aplicaciones en el Aula de Tecnología
3.2.2.- Switch-Case.
La sentencia switch-case nos ayuda a tomar decisiones múltiples.
Se define de la siguiente manera:
switch (expresión)
{
case constante1
Instrucción_1;
¿Expresión=
constante1?
si
Instrucción_1
Instrucción _n
no
si
¿break?
Instrucción_n;
break;
no
Instrucción_1
case constante2
Instrucción_1;
Instrucción_n;
¿Expresión=
Constante2?
si
Instrucción _n
si
no
¿break?
break;
no
case constanteN
Instrucción_1
Instrucción_1;
Instrucción_n;
break;
¿Expresión=
ConstanteN?
no
default:
si
Instrucción _n
no
si
¿break?
Instrucción_1;
Instrucción_n;
}
Instrucción_1
Instrucción _n;
Programa_2:
Leer el Puerto C

Si PC7..PC2= 0, PC1= 0 y PC0= 0 cargar en el Puerto B= 0b00000011, esperar
1sg, Puerto B= 0b00000000, esperar 1sg.

Si PC7..PC2= 0, PC1= 0 y PC0= 1 cargar en el Puerto B= 0b00001100, esperar
1sg, Puerto B= 0b00000000, esperar 1sg.

Si PC7..PC2= 0, PC1= 1 y PC0= 0 cargar en el Puerto B= 0b00110000, esperar
1sg, Puerto B= 0b00000000, esperar 1sg.
IES Joan Miró
Página 63
Curso de Robótica y otras aplicaciones en el Aula de Tecnología

Si PC7..PC2= 0, PC1= 1 y PC0= 1 cargar en el Puerto B= 0b11000000, esperar
1sg, Puerto B= 0b00000000, esperar 1sg.

Si PC7..PC2 distinto de 0, PC1 = x y PC0 = x cargar en el Puerto B= 0b00000000.
Repetir el proceso cíclicamente.
Programa_2.c
Diagrama de Flujo:
Ejemplo de Switch-Case
// Configuración
TRISB 0B00000000
TRISC 0B11111111;
// Defines Puerto B como SALIDA de datos.
// Defines Puerto C como ENTRADA de datos.
// Reseteamos el Puerto B.
portB  0B00000000
si
¿portC= 0?
portB  0B00000011
no
Retardo_1Seg
Retardo_1Seg
portB  0B00000000
si
portB  0B00001100
¿portC= 1?
no
Retardo_1Seg
Retardo_1Seg
portB  0B00000000
si
portB  0B00110000
¿portC= 2?
no
Retardo_1Seg
Retardo_1Seg
portB  0B00000000
si
¿portC=3?
no
portB  0B00110000
Retardo_1Seg
Retardo_1Seg
portB  0B00000000
portB0B00000000
IES Joan Miró
Página 64
Curso de Robótica y otras aplicaciones en el Aula de Tecnología
Programa_2.c:
// Leer el Puerto C
// Si PC7..PC2= 0, PC1= 0 y PC0= 0 cargar en el Puerto B= 0b00000011, esperar 1sg, Puerto B= 0b00000000, esperar 1sg.
// Si PC7..PC2= 0, PC1= 0 y PC0= 1 cargar en el Puerto B= 0b00001100, esperar 1sg, Puerto B= 0b00000000, esperar 1sg.
// Si PC7..PC2= 0, PC1= 1 y PC0= 0 cargar en el Puerto B= 0b00110000, esperar 1sg, Puerto B= 0b00000000, esperar 1sg.
// Si PC7..PC2= 0, PC1= 1 y PC0= 1 cargar en el Puerto B= 0b11000000, esperar 1sg, Puerto B= 0b00000000, esperar 1sg.
// Si PC7..PC2 distinto de 0, PC1 = x y PC0 = x cargar en el Puerto B= 0b00000000.
// Repetir el proceso cíclicamente.
// ************************************ Directivas de Preprocesado *********************************
// (Controlan la conversión del programa a código máquina por parte del compilador)
#include <16F877.h>
// Incluye el filchero 16F877 al programa tiene que estar en la misma
// carpeta del programa define funciones, patillas y registros.
#fuses XT,NOWDT
// Define la palabra de configuarción del microcontrolador PIC
// Trabaja con un reloj tipo XT y no utiliza perro guardian Wathdog#use
delay( clock = 4000000 )
#BYTE TRISC = 0x87
#BYTE PORTC = 0x07
#BYTE TRISB = 0x86
#BYTE PORTB = 0x06
// Define la frecuencia del reloj de 4 MHz
// TRISC en 87h.
// PORTC en 07h.
// TRISB en 86h.
// PORTB en 06h.
// **************************** Función principal o programa principal *******************************
void main()
{
TRISB = 0B00000000;
TRISC = 0B11111111;
PORTB = 0B00000000;
// Defines Puerto B como SALIDA de datos.
// Defines Puerto C como ENTRADA de datos.
// Reseteamos el Puerto B.
while (1)
{
// Ejecuta indefinidamente lo que está entre corchetes.
switch (PORTC)
{
case 0:
PORTB = 0B00000011;
delay_ms(1000);
PORTB = 0B00000000;
delay_ms(1000);
break;
case 1:
PORTB = 0B00001100;
delay_ms(1000);
PORTB = 0B00000000;
delay_ms(1000);
break;
case 2:
PORTB = 0B00110000;
delay_ms(1000);
PORTB = 0B00000000;
delay_ms(1000);
break;
IES Joan Miró
Página 65
Curso de Robótica y otras aplicaciones en el Aula de Tecnología
case 3:
PORTB = 0B11000000;
delay_ms(1000);
PORTB = 0B00000000;
delay_ms(1000);
break;
default:
PORTB = 0B00000000;
}
}
}
3.2.3.- For.
Se usa para repetir sentencias.
En las expresiones del FOR la inicialización es una variable a la cual se le asigna un valor inicial.
La condición de finalización sirve para evaluar la variable de control antes de ejecutar la
sentencia. Si es cierta se ejecuta las sentencias que estén entre corchetes.
La expresión de Incremento ó decremento modifica la variable de control después de ejecutar
el bucle.
Se define de la siguiente manera:
for (inicialización; condición de finalización; incremento)
{
Instrucción_1;
Instrucción_n;
}
// Inicialización de la variable
n1
// Condición de finalización
no
¿n<=10?
si
Instrucción_1
Instrucción _n;
// Expresión de Incremento ó decremento
nn+1
IES Joan Miró
Página 66
Curso de Robótica y otras aplicaciones en el Aula de Tecnología
Programa_3:
Mostrar los números desde 0 al 9 en un display de 7 Segmentos.
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
Tabla de conversión de Número Decimal a Binario de 7 segmentos
Número
Decimal
0
1
2
3
4
5
6
7
8
9
Puerto D
D7 D6 D5 D4 D3 D2 D1 D0
g f e d c b a
0
0
0
0
0
0
0
0
0
0
0
0
1
1
1
1
1
0
1
1
1
0
0
0
1
1
1
0
1
1
1º Dígito en
Hexadecimal
IES Joan Miró
1
0
1
0
0
0
1
0
1
0
1
0
1
1
0
1
1
0
1
1
1
1
0
1
1
1
1
1
1
1
1
1
1
1
1
0
0
1
1
1
1
0
1
1
0
1
1
1
1
1
Número
Hexadecimal
3F
06
5B
4F
66
6D
7D
07
7F
6F
1º Dígito en
Hexadecimal
2º Dígito en
Hexadecimal
2º Dígito en
Hexadecimal
Página 67
Curso de Robótica y otras aplicaciones en el Aula de Tecnología
Diagrama de Flujo:
Programa_3.c “For”
Mostrar números en un Display
// Directivas de Preprocesado
Numero_Maximo  9
// Numero_Maximo equivale a 9
DISPLAY[10] = {0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F} //Crear una tabla de 10 datos
// Configuración
TRISD 0B00000000
// Defines Puerto D como SALIDA de datos.
// Reseteamos el Puerto D.
portD  0B00000000;
// Inicialización de la variable
n0
// Condición de finalización
no
¿n<=Numero_Maximo?
si
portD DISPLAY[n]
Retardo_1Seg
// Expresión de Incremento ó decremento
nn+1
IES Joan Miró
Página 68
Curso de Robótica y otras aplicaciones en el Aula de Tecnología
Programa_3.c:
// Mostrar los números desde 0 al 9 en un display de 7 Segmentos.
// ***************************** Directivas de Preprocesado****************************************
// (Controlan la conversión del programa a código máquina por parte del compilador)
#include <16F877.h>
#use delay( clock = 4000000 )
// Incluye el fichero 16F877 al programa tiene que estar en la misma carpeta
// del programa define funciones, patillas y registros.
// Define la palabra de configuración del microcontrolador PIC
// Trabaja con un reloj tipo XT y no utiliza perro guardián Wathdog
// Define la frecuencia del reloj de 4 MHz
#define Numero_Maximo 9
// Numero máximo que se representa.
#BYTE TRISD = 0x88
#BYTE portD = 0x08
// TRISD en 88h.
// PORTD en 08h.
int8 n= 0;
// Defines la variable N como entera de 8bit y se carga con valor 0.
// Variable Global afecta a todo el programa.
#fuses XT,NOWDT
byte CONST DISPLAY[10] = {0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F}; // Tabla de 10 datos.
// ****************************** Función principal o programa principal *****************************
void main()
{
TRISD = 0B00000000;
portD = 0B00000000;
// Defines Puerto D como SALIDA de datos.
// Reseteamos el Puerto D.
while (1)
// Ejecuta indefinidamente lo que está entre corchetes.
{
for (n=0; n<=Numero_Maximo; n++)
// Se ejecuta un bucle desde n=0 hasta
// n<=Numero_Maximo en orden
// ascendente de uno en uno
{
portD = DISPLAY[n];
// Mostramos en el Puerto D el valor que tiene
// DISPLAY[n]
delay_ms(1000);
}
}
}
IES Joan Miró
Página 69
Curso de Robótica y otras aplicaciones en el Aula de Tecnología
3.2.4.- While.
La sentencia while se utiliza para repetir procesos. Si cumple la expresión ejecuta las
instrucciones que están entre corchetes.
Se define de la siguiente manera:
no
¿Cumple la
expresión?
while (expresión)
{
Instrucción_1;
si
Instrucción_1
Instrucción_n;
}
Instrucción _n;
Programa_4:
Encender la Lámpara y activar el motor mientras el Puerto C sea igual a cero, si es
distinto de cero apagar la lámpara y parar el motor.
Diagrama de Flujo:
Programa_4.c “while”
Activar Motor y Lámpara
// Configuración
TRISE  0B00000000
TRISA  0B00000000
TRISC 0B11111111
// Defines Puerto E como SALIDA de datos.
// Defines Puerto A como SALIDA de datos.
// Defines Puerto C como ENTRADA de datos.
portE 0B00000000
portA 0B00000000
// Reseteamos el Puerto E.
// Reseteamos el Puerto A.
no
¿portC= 0?
lámpara 0
motor 0
// Apagar Lámpara.
// Parar Motor.
si
lámpara 1
motor 1
IES Joan Miró
// Encender Lámpara.
// Activar Motor.
Página 70
Curso de Robótica y otras aplicaciones en el Aula de Tecnología
Programa_4.c:
/* Encender la Lámpara y activar el motor mientras el Puerto C sea igual a cero,
si es distinto de cero apagar la lámpara y parar el motor. */
// ************************************ Directivas de Preprocesado*********************************
// (Controlan la conversión del programa a código máquina por parte del compilador)
#include <16F877.h>
#use delay( clock = 4000000 )
// Incluye el fichero 16F877 al programa tiene que estar en la misma carpeta
// del programa define funciones, patillas y registros.
// Define la palabra de configuración del microcontrolador PIC
// Trabaja con un reloj tipo XT y no utiliza perro guardián Wathdog
// Define la frecuencia del reloj de 4 MHz
#BYTE TRISE = 0x89
#BYTE portE = 0x09
// TRISE en 89h.
// PORTE en 09h.
#BYTE TRISC = 0x87
#BYTE portC = 0x07
// TRISC en 87h.
// PORTC en 07h.
#BYTE TRISA = 0x85
#BYTE portA = 0x05
// TRISA en 85h.
// PORTA en 05h.
#BIT lampara = 0x09.0
#BIT motor = 0x05.5
// RE0 en 0x09 patilla 0.
// RE0 en 0x09 patilla 0.
#fuses XT,NOWDT
// **************************** Función principal o programa principal *******************************
void main()
{
TRISE = 0B00000000;
TRISA = 0B00000000;
TRISC = 0B11111111;
// Defines Puerto E como SALIDA de datos.
// Defines Puerto A como SALIDA de datos.
// Defines Puerto C como ENTRADA de datos.
portE = 0B00000000;
portA = 0B00000000;
// Reseteamos el Puerto E.
// Reseteamos el Puerto A.
while (true)
{
while (portC==0)
// Ejecuta lo que está entre corchetes mientras cumpla la
// condición.
{
lampara = 1;
motor = 1;
// Encender Lámpara.
// Activar Motor.
}
lampara = 0;
motor = 0;
// Apagar Lámpara.
// Parar Motor.
}
}
IES Joan Miró
Página 71
Curso de Robótica y otras aplicaciones en el Aula de Tecnología
3.2.5.- Do-While.
La sentencia do-while se utiliza para repetir
procesos. Ejecuta primero las instrucciones que están entre
corchetes luego pregunta si se cumple la expresión. Las
instrucciones entre corchetes se ejecutan al menos una
vez.
do
{
Instrucción_1;
Instrucción_1
Instrucción _n;
si
¿Cumple la
expresión?
Instrucción_n;
}
while (expresión);
no
Programa_5:
Si PC0 =1 parpadean los led del puerto B con una cadencia de 1 segundo.
Si PC7 =1 parpadean los led del puerto D con una cadencia de 1 segundo.
1
Diagrama de Flujo:
portB 0B11111111
Programa_5.c “do-while”
Parpadeo Led y Display
// Encender LED
Retardo _1Seg
portB 0B00000000
// Configuración
TRISB  0B00000000
TRISD  0B00000000
TRISC 0B11111111
// Apagar LED
Retardo _1Seg
// Defines Puerto B como SALIDA de datos.
// Defines Puerto D como SALIDA de datos.
// Defines Puerto C como ENTRADA de datos.
¿rc0= 1?
portB 0B00000000;
portD 0B00000000
// Reseteamos el Puerto B.
// Reseteamos el Puerto D.
si
no
portD 0B11111111
// Encender DISPLAY
Retardo _1Seg
1
portD 0B00000000
// Apagar DISPLAY
Retardo _1Seg
no
si
¿rc7= 1?
IES Joan Miró
Página 72
Curso de Robótica y otras aplicaciones en el Aula de Tecnología
Programa_5.c:
// Utilización de la sentencia Do-Wlile
// Si PC0 =1 parpadean los led del puerto B con una cadencia de 1 segundo.
// Si PC7 =1 parpadean los led del puerto D con una cadencia de 1 segundo.
// ******************************** Directivas de Preprocesado *************************************
// (Controlan la conversión del programa a código máquina por parte del compilador)
#include <16F877.h>
// Incluye el fichero 16F877 al programa tiene que estar en la
// misma carpeta del programa define funciones, patillas y registros.
// Define la palabra de configuración del microcontrolador PIC
// Trabaja con un reloj tipo XT y no utiliza perro guardián Wathdog
// Define la frecuencia del reloj de 4 MHz
#fuses XT,NOWDT
#use delay( clock = 4000000 )
#BYTE TRISD = 0x88
#BYTE portD = 0x08
#BYTE TRISC = 0x87
#BYTE portC = 0x07
#BYTE TRISB = 0x86
#BYTE portB = 0x06
#BIT rc0 = 0x07.0
#BIT rc7 = 0x07.7
// TRISD en 88h.
// PORTD en 08h.
// TRISC en 87h.
// PORTC en 07h.
// TRISB en 86h.
// PORTB en 06h.
// RC0 en 0x07 patilla 0.
// RC7 en 0x07 patilla 7.
// *************************** Función principal o programa principal ********************************
void main()
{
TRISB = 0B00000000;
// Defines Puerto B como SALIDA de datos.
TRISC = 0B11111111;
// Defines Puerto C como ENTRADA de datos.
TRISD = 0B00000000;
// Defines Puerto D como SALIDA de datos.
portB = 0B00000000;
// Reseteamos el Puerto B.
portD = 0B00000000;
// Reseteamos el Puerto D.
while (1)
{
// Ejecuta indefinidamente lo que está entre corchetes.
Do
{
// Ejecuta las instrucciones que estan entre corchetes mientras PC0 = 1.
portB = 0B11111111;
delay_ms(1000);
portB = 0B00000000;
delay_ms(1000);
}
while (rc0 == 1);
Do
{
// Ejecuta las instrucciones que estan entre corchetes mientras PC7 = 1.
portD = 0B11111111;
delay_ms(1000);
portD = 0B00000000;
delay_ms(1000);
}
while (rc7 == 1);
}
}
IES Joan Miró
Página 73
Curso de Robótica y otras aplicaciones en el Aula de Tecnología
3.3.- Creación de funciones.
El compilador CCS C suministra una serie de funciones predefinidas para acceder y
utilizar el uC PIC y sus periféricos. Estas funciones facilitan la configuración del PIC sin
necesidad de entrar en un estudio profundo de sus registros de funciones especiales “SFR”. Las
funciones se clasifican por bloques funcionales:
IES Joan Miró
Página 74
Curso de Robótica y otras aplicaciones en el Aula de Tecnología
IES Joan Miró
Página 75
Curso de Robótica y otras aplicaciones en el Aula de Tecnología
IES Joan Miró
Página 76
Curso de Robótica y otras aplicaciones en el Aula de Tecnología
Para mayor información, podemos ver el “Manual compilador C CCS”. Algunas de
estas funciones las utilizaremos en el capítulo de Ejemplos prácticos
La forma de crear nuestras propias funciones es:
a) Declarar las funciones después de las Directivas de Preprocesado y antes del Programa
Principal
#BIT rc0 = 0x07.0
// RC0 en 0x07 patilla 0.
Directivas de Preprocesado
/* ************************************** Declaración de funciones ****************************************** */
void VariasCosas (int8);
int8 Raiz (int8);
// Generación de la señal cuadrada.
// Realiza la raíz cuadrada.
Declaración de las Funciones
// ***************************** Función principal o programa principal *******************************************
void main()
Programa Principal
{
int8 muestra1;
// Variable muestra1 definida como un entero de 8 bit
TRISB = 0B00000000
IES Joan Miró
Página 77
Curso de Robótica y otras aplicaciones en el Aula de Tecnología
b) Crear las funciones después del Programa Principal
while (1)
{
// Ejecuta indefinidamente lo que está entre corchetes.
muestra1 = portC;
VariasCosas(muestra1);
// Leemos el Puerto C.
// Ejecuta la función VariasCosas definida por la variable muestra1.
}
}
Programa Principal
//******************************** Funcion VariasCosas ******************************************************
void VariasCosas (int8 muestra2)
{
switch (muestra2)
// Preguntamos por la variable muestra2 si es 0 ejecuta el case 0, si es 3 el case 3,
// si es distinto de 0 y 3 ejecuta Raíz
{
Función Varias_Cosas
case 0:
LucesFantastico();
// Llamamos a la función LucesFantastico
break;
case 1:
NumerosDisplay();
break;
// Llamamos a la función NumerosDisplay
default:
{
portB = Raiz(muestra2);
delay_ms(50);
// Ejecuta la función Raíz definida por la variable muestra.
// Temporizamos 50 mS.
}
}
}
Programa_6.c:
// El Puerto C puede tomar valores comprendidos entre 0 y 255
// Si Puerto C si es 0 realizar la función de mostrar por el Display de 7 segmentos los números
// del 0 al 9 con una cadencia de 1 segundo. Después de este proceso apagar el Display.
// Si Puerto C si es 1 realizar la función de simulación de las luces del coche fantástico.
// después de este proceso apagar los Led.
// Si Puerto C si es distinto de 0 y 1 realizar una función de la raíz cuadrada del dato leído
// y devolverlo en una variable llamada resultado y mostrarlo en el Puerto B
// ******************************** Directivas de Preprocesado*************************************
// (Controlan la conversión del programa a código maquina por parte del compilador)
#include <16F877A.h>
#fuses XT,NOWDT
#use delay( clock = 4000000 )
// Incluye el fichero 16F877A al programa tiene que estar en la misma
//carpeta del programa define funciones, patillas y registros.
// Define la palabra de configuración del microcontrolador PIC
// Trabaja con un reloj tipo XT y no utiliza perro guardián Wathdog
// Define la frecuencia del reloj de 4 MHz
#include <math.h>
#include <LUCES-COCHE-FANTASTICO.h>
#include <REPR-NUMEROS-DISPL.h>
#BYTE TRISC = 0x87
#BYTE portC = 0x07
IES Joan Miró
// Librería de funciones matemáticas.
// Librería de simulación Luces del Coche Fantástico.
// Librería de simulación representación de los números
// en el Display 7Seg.
// TRISC en 87h.
// PORTC en 07h.
Página 78
Curso de Robótica y otras aplicaciones en el Aula de Tecnología
#BYTE TRISB = 0x86
#BYTE portB = 0x06
#BYTE TRISD = 0x88
#BYTE portD = 0x08
// TRISB en 86h.
// PORTB en 06h.
// TRISD en 88h.
// PORTD en 08h.
#BIT rc0 = 0x07.0
// RC0 en 0x07 patilla 0.
/* **************************** Declaración de funciones **************************************** */
void VariasCosas (int8);
int8 Raiz (int8);
// Generación de la señal cuadrada.
// Realiza la raíz cuadrada.
// ************************ Función principal o programa principal ***********************************
void main()
{
int8 muestra1;
TRISB = 0B00000000;
TRISC = 0B11111111;
TRISD = 0B00000000;
portB = 0B00000000;
portD = 0B00000000;
while (1)
{
// Variable muestra de un entero de 8 bit
// Defines Puerto B como SALIDA de datos.
// Defines Puerto C como ENTRADA de datos.
// Defines Puerto D como SALIDA de datos.
// Reseteamos el Puerto B.
// Reseteamos el Puerto D.
// Ejecuta indefinidamente lo que está entre corchetes.
muestra1 = portC;
VariasCosas(muestra1);
// Leemos el Puerto C
// Ejecuta la función VariasCosas definida por la variable
// muestra1.
}
}
//*************************** Función VariasCosas ************************************************
void VariasCosas (int8 muestra2)
{
switch (muestra2)
// Preguntamos por la variable muestra2 si es 0 ejecuta el case 0, si
// es 3 el case 3, si es distinto de 0 y 3 ejecuta Raiz
{
case 0:
LucesFantastico();
// Llamamos a la función LucesFantastico
break;
case 1:
NumerosDisplay();
break;
// Llamamos a la función NumerosDisplay
default:
{
portB = Raiz(muestra2);
delay_ms(50);
// Ejecuta la función Raíz definida por la variable muestra.
// Temporizamos 50 mS.
}
}
}
//******************************** Función Raíz *************************************************
IES Joan Miró
Página 79
Curso de Robótica y otras aplicaciones en el Aula de Tecnología
int8 Raiz (int8 muestra3)
{
int8 resultado;
resultado = SQRT (muestra3);
return(resultado);
}
3.4.- Manejo y creación de driver o librerías.
Una librería o driver es un programa que realiza una función determinada. Se la puede llamar
desde cualquier otro programa. Debe estar bien documentada.
Si se va a utilizar librerías o driver en un programa se la tiene que incluir en las Directivas de
Preprocesado
// ******************************** Directivas de Preprocesado*************************************
// (Controlan la conversión del programa a código maquina por parte del compilador)
#include <16F877A.h>
#fuses XT,NOWDT
#use delay( clock = 4000000 )
// Incluye el fichero 16F877A al programa tiene que estar en la misma
//carpeta del programa define funciones, patillas y registros.
// Define la palabra de configuración del microcontrolador PIC
// Trabaja con un reloj
tipo XT yono
utiliza perro guardián Wathdog
Librerías
driver
// Define la frecuencia del reloj de 4 MHz
#include <math.h>
#include <LUCES-COCHE-FANTASTICO.h>
#include <REPR-NUMEROS-DISPL.h>
#BYTE TRISC = 0x87
#BYTE portC = 0x07
// Librería de funciones matemáticas.
// Librería de simulación Luces del Coche Fantástico.
// Librería de simulación representación de los números
// en el Display 7Seg.
// TRISC en 87h.
// PORTC en 07h.
Las librerías del Programa_6.c son las siguientes:
LUCES-COCHE-FANTASTICO.H
// Realizar la función de simulación de las Luces del Coche Fantástico.
// Después de este proceso apagar los Led.
//******************************** Directivas de Preprocesado *************************************
#BYTE portB = 0x06
// PORTB en 06h.
//************** Función de Simulación de las Luces del Coche Fantástico. *******************************
void LucesFantastico (void)
{
int8 i,luces;
// Definimos las variable como enteras de 8bit.
luces = 0B00000001;
// Inicializamos la variable luces.
for (i=0;i<8;i++)
// Se ejecuta un bucle desde 0 hasta 8 en orden ascendente de uno
// en uno
{
portB = luces;
delay_ms(200);
IES Joan Miró
// Mostramos en el Puerto B el valor que tiene luces
// Temporizamos 200 mS.
Página 80
Curso de Robótica y otras aplicaciones en el Aula de Tecnología
luces = luces << 1;
// Rotamos el contenido de la variable luces una posición hacia la
// izquierda.
}
luces = 0B10000000;
// Inicializamos la variable luces.
for (i=0;i<7;i++)
// Se ejecuta un bucle desde 0 hasta 7 en orden ascendente de uno
// en uno
{
luces = luces >> 1;
portB = luces;
delay_ms(200);
// Rotamos el contenido de la variable luces una posición hacia la
// Derecha.
// Mostramos en el Puerto B el valor que tiene luces
// Temporizamos 200 mS.
}
portB = 0B00000000;
// Reseteamos el Puerto B.
}
LUCES-COCHE-FANTASTICO.H
// Mostrar por el Display de 7 segmentos los números del 0 al 9 con una cadencia de 1 segundo.
// Después de este proceso apagar el Display.
// *************************** Directivas de Preprocesado ******************************************
#BYTE portD = 0x08
// PORTD en 08h.
byte CONST DISPLAY[10] = {0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};
// Tabla de 10 datos.
//******************** Función de Mostrar los Números en el Display de 7 Segmentos.********************
void NumerosDisplay (void)
{
int8 i;
// Definimos la variable como entera de 8bit.
for (i=0;i<10;i++)
// Se ejecuta un bucle desde 0 hasta 9 en orden ascendente de
// uno en uno
{
portD = DISPLAY[i];
delay_ms(500);
// Mostramos en el Puerto D el valor que tiene DISPLAY[i]
}
portD = 0B00000000;
// Reseteamos el Puerto D.
}
La librería MATCH.H está en la carpeta PICC/DRIVER
IES Joan Miró
Página 81
Curso de Robótica y otras aplicaciones en el Aula de Tecnología
4.- Ejemplos prácticos.
4.1.- Interface optoacoplada entre dispositivos Digitales y Analógicos
Es importante poder controlar dispositivos de potencia con dispositivos electrónicos
(Ordenadores, uC, Dispositivos Lógicos) sin que estos corran peligro.
Existen básicamente dos tipos de dispositivos (Control ON/OFF):
Dispositivos electromecánicos (Reles, Contactores, etc.) y electrónicos (Optotransistores,
Optotriac, etc.)
4.1.1.- Control con Relés.
El relé es un dispositivo electromecánico, que funciona como un interruptor
controlado por un circuito eléctrico en el que, por medio de un electroimán, se acciona un
juego de uno o varios contactos que permiten abrir o cerrar otros circuitos eléctricos
independientes.
IES Joan Miró
Página 82
Curso de Robótica y otras aplicaciones en el Aula de Tecnología
Un ejemplo práctico sería el control de una electroválvula de 24V/0,45A con un
circuito Lógico que funciona a 5v. El Transistor funciona como un interruptor controlado por la
puerta inversora.
Clindro de doble efecto
Control de una electroválvula con una puerta lógica
utilizando un Relé
E1
2
5V
E2
24V
1
1
2
IL
5V/115 Ohm
RELE
A
K
ID1
D3
1N4007_JOAN
K
A
D2
A
RL
ID2
50
IR
220
K
D1
R4
IC
R1
220
IB
U1:A
1
2
R3
Válvula 5/2
activada electricamente
y retorno com muelle
Q2
BC547BP_JOAN
10k
2
74LS04
SW1
1
Control
IES Joan Miró
Potencia
Característica de la
Electroválvula:
(24V/450mA)
Página 83
Curso de Robótica y otras aplicaciones en el Aula de Tecnología
4.1.2.- Control con Optotransistores.
Estos dispositivos digitales son optoacoplados y permiten realizar este proceso con
suma facilidad, tienen la ventaja de que no tiene elementos mecánicos, que con el paso del
tiempo se deterioran. Se comportan como circuitos seguidores de señal o inversores . Aíslan
eléctricamente la parte de potencia de la de control a través de una barrera de luz infrarroja
que aguanta hasta 1200v
Su funcionamiento sería el siguiente:
Si no pasa intensidad por el diodo emisor, no emite luz infrarroja y el Fototransistor está
cortado (Se comporta como un circuito abierto)
Si dejamos pasar intensidad por el diodo emisor, este emite una luz infrarroja que saturara el
Fototransistor (Se comporta como un Interruptor cerrado)
IES Joan Miró
Página 84
Curso de Robótica y otras aplicaciones en el Aula de Tecnología
Un ejemplo práctico sería el control de una electroválvula de 24V/0,45A con un
circuito Lógico que funciona a 5v. Se necesita un montaje Darlington con Transistores, ya que
el optoacoplador no será capaz de absorber la intensidad IC1
IES Joan Miró
Página 85
Curso de Robótica y otras aplicaciones en el Aula de Tecnología
4.1.3.- Control con Optotriac.
Si queremos controlar cargas en corriente alterna con elementos electrónicos el
elemento ideal es el Optotriac.
Un modelo sería el MOC3041 cuyas características más significativas son:




Tensión de aislamiento de 7500V, garantiza un perfecto aislamiento entre la red
eléctrica y los dispositivos lógicos.
Es capaz de proporcionar hasta 100 mA, pudiendo alimentar cargas has 20W.
Su Fototriac interno permite el control de casi todos los grandes Triacs.
Cuenta de un Detector de paso por cero interno, que ahorra poner hardware externo.
Su funcionamiento es el siguiente si hacemos pasar una corriente por Diodo Emisor de
infrarrojos este activa el Fototriac (Interruptor cerrado) dejando pasar la corriente por el.
La red serie del condensador de 10 nF y la resistencia de 100Ω, conectada en paralelo
con el Fotoriac evita que se dispare, por los picos brúscos de la tensión de red, que se pueden
presentar aleatoriamente. Esta red R-C es responsable de que el circuito tenga un cierto
consumo de 0,1W, aunque esté desactivado. El condensador C1 debe ser capaz de soportar al
menos 400V.
IES Joan Miró
Página 86
Curso de Robótica y otras aplicaciones en el Aula de Tecnología
Un ejemplo práctico sería el control de una electroválvula de 220V/0,45A en corriente
alterna con un circuito Lógico que funciona a 5v. Se necesita un Triac adicional para atacar la
electroválvula ya que esta necesita una corriente de 450 mA.
Control de una electroválvula con una puerta lógica
utilizando Optotriac
Control
Clindro de doble efecto
Válvula 5/2
activada electricamente
y retorno com muelle
Potencia
Característica de la
Electroválvula:
(220V/50Hz /450mA)
E1
5V
2
2
1
L1
VL
220V
RL
+88.8
500
1
AC Volts
ID1
ID
R2
I2
IL1
IL2
A
220
K
D1
U2
R1
1
6
1
220
360
ID
2
3
U1:A
I3
R5
IC=0
IR
Zero
Crossing
IG
4
R4
U3
I1
TRIAC
74126
2
IT
2
100
MOC3031M
SW1
VT
R6
AC Volts
1
330
I4
IES Joan Miró
+
+88.8
C1
ALT1
ALTERNADOR_JOAN
312.5V
50Hz
10nF
Página 87
Curso de Robótica y otras aplicaciones en el Aula de Tecnología
4.2.- Control de una Pantalla 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.
 Movimiento del cursor y cambio de su aspecto.
 Permite programas ocho caracteres.
 Puede ser gobernado de dos formas principales:
 Conexión con bus de 4 bits
 Conexión con un bus de 8 bits
El patillaje es el siguiente:
LCD1
D0
D1
D2
D3
D4
D5
D6
D7
7
8
9
10
11
12
13
14
RS
RW
E
4
5
6
Las líneas del bus de datos (D7..D0) son triestado y pasan a
estado de alta impedancia cuando el LCD no se utiliza.
1
2
3
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.
VSS
VDD
VEE
LCD-16 X 2_JOAN
SEÑAL
DEFINICIÓN
PINES
FUNCIÓN
D7..D0
Data Bus
14..7
Bus de datos
E
Enable
6
R/W
Read/Write
5
RS
Register Select
4
VEE ó VLC
Liquid Cristal driving Voltage
3
VDD
Power Supply Voltage
2
VSS
Ground
1
E=0
LCD no habilitado.
E=1
LCD habilitado.
R/W =0 escribe en LCD.
R/W =1 lee del LCD.
RS=0
Modo Comando
RS=1
Modo Caracter
Tensión para ajustar el
contraste
Tensión de Alimentación
+5V
Masa.
IES Joan Miró
Página 88
Curso de Robótica y otras aplicaciones en el Aula de Tecnología
Utilizaremos el driver LCD.c 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
01-09
1.1-9.9
t ipo
(tipo de carácter) puede ser:
c
s
u
d
Lu
Ld
x
X
Lx
LX
f
g
e
w
IES Joan Miró
Cuantos caracteres se escriben.
Indica cuantos ceros existen a la Izquierda.
para coma flotante.
Carácter.
Cadena o Carácter.
Entero sin signo.
Entero con signo.
Entero Largo sin signo.
Entero Largo con signo.
Entero Hexadecimal (minúsculas).
Entero Hexadecimal (mayúsculas).
Entero largo Hexadecimal (minúsculas).
Entero largo Hexadecimal(mayúsculas).
Flotante con truncado.
Flotante con redondeo.
Flotante en formato exponencial.
Entero sin signo con decimales insertados. La 1ª cifra indica el
total de números, la 2ª cifra indica el número de decimales.
Página 89
Curso de Robótica y otras aplicaciones en el Aula de Tecnología
\c puede ser:
\f
\n
\b
Se limpia el LCD.
El cursor va a la posición (1,2)
El cursor retrocede una posición.
El driver utilizado para controlar el LCD creado por CCS es LCD.c está pensado para trabajar
con el Puerto D y B. Por defecto está el Puerto D.
Si queremos trabajar en diferentes puertos tenemos que modificar el driver LCD.c
Driver LCD.c
// As defined in the following structure the pin connection is as follows:
// D0 enable
// D1 rs
// D2 rw
// D4 D4
// D5 D5
// D6 D6
// D7 D7
//
// LCD pins D0-D3 are not used and PIC D3 is not used.
// Un-comment the following define to use port B
// #define use_portb_lcd TRUE
struct lcd_pin_map {
BOOLEAN enable;
BOOLEAN rs;
BOOLEAN rw;
BOOLEAN unused;
int data : 4;
} lcd;
Si queremos trabaja con el
Puerto B habilitamos está
instrucción
// This structure is overlayed
// on to an I/O port to gain
// access to the LCD pins.
// The bits are allocated from
// low order up. ENABLE will
// be pin B0.
#if defined use_portb_lcd
#locate lcd = getenv("sfr:PORTB")
#define set_tris_lcd(x) set_tris_b(x)
#else
#locate lcd = getenv("sfr:PORTD")
#define set_tris_lcd(x) set_tris_d(x)
#endif
IES Joan Miró
Trabaja con el
Puerto D por defecto
// This puts the entire structure over the port
// This puts the entire structure over the port
Página 90
Curso de Robótica y otras aplicaciones en el Aula de Tecnología
Driver LCD2.c
// As defined in the following structure the pin connection is as follows:
// D0 enable
// D1 rs
// D2 rw
// D4 D4
// D5 D5
// D6 D6
// D7 D7
//
// LCD pins D0-D3 are not used and PIC D3 is not used.
// Un-comment the following define to use port B
// #define use_portb_lcd TRUE
struct lcd_pin_map {
BOOLEAN enable;
BOOLEAN rs;
BOOLEAN rw;
BOOLEAN unused;
int data : 4;
} lcd;
// This structure is overlayed
// on to an I/O port to gain
// access to the LCD pins.
// The bits are allocated from
// low order up. ENABLE will
// be pin B0.
#if defined use_portb_lcd
#locate lcd = getenv("sfr:PORTB")
#define set_tris_lcd(x) set_tris_b(x)
#else
#locate lcd = getenv("sfr:PORTD")
#define set_tris_lcd(x) set_tris_d(x)
#endif
Si queremos trabaja con el Puerto C
modificamos estas instrucciones
#locate lcd = getenv("sfr:PORTC")
#define set_tris_lcd(x) set_tris_c(x)
// This puts the entire structure over the port
// This puts the entire structure over the port
Para entender mejor el manejo del LCD hemos realizado un entrenador con ISIS. Simularemos
diferentes ejemplos.
4.2.1.- LCD_ejemplo1.c
IES Joan Miró
Página 91
Curso de Robótica y otras aplicaciones en el Aula de Tecnología
/* ************************* Mostrar mensajes en el LCD ******************************* */
// ************************* Directivas de Preprocesado*********************************
#include <16F876A.h>
#fuses XT,NOWDT
#use delay( clock = 4000000 )
// Reloj de 4 MHz
#include <LCD2.c>
// Incluimos el driver LCD2.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, " f Proyectos");
// Escribimos Proyectos.
while (1);
// Ejecuta está instrucción indefinidamente.
}
4.2.2.- LCD_ejemplo2.c
/* ****************** Mostrar números en diferentes formatos en el LCD ******************** */
// *************************** Directivas de Preprocesado*********************************
#include <16F876A.h>
#fuses XT,NOWDT
#use delay( clock = 4000000 )
// Reloj de 4 MHz
#include <LCD2.c>
// Incluimos el driver LCD2.c
// *********************** Función principal o programa principal ***************************
void main()
{
int8 p = 254;
lcd_init();
// Inicializamos el LCD.
lcd_gotoxy(1,1);
printf(lcd_putc,"%3u",p);
// Posicionamos el Cursor del LCD en la posición 1 línea 1 .
// Escribimos 3 dígitos de la variable "p" en formato entero y sin signo.
lcd_gotoxy(8,1);
printf(lcd_putc,"%03d",p);
// Posicionamos el Cursor del LCD en la posición 8 línea 1 .
// Escribimos 3 dígitos de la variable "p" en formato entero con signo.
lcd_gotoxy(1,2);
printf(lcd_putc,"%4X",p);
// Posicionamos el Cursor del LCD en la posición 1 línea 2 .
// Escribimos 4 dígitos de la variable "p" en formato entero
// hexadecimal mayúsculas.
// Posicionamos el Cursor del LCD en la posición 8 línea 2 .
// Escribimos 3 dígitos de la variables "p" en formato entero
// sin signo con decimales insertados. La 1ª cifra indica el
// total de dígitos y la 2ª el número de decimales.
// Fin.
lcd_gotoxy(8,2);
printf(lcd_putc,"%3.2w",p);
while (1);
}
IES Joan Miró
Página 92
Curso de Robótica y otras aplicaciones en el Aula de Tecnología
4.2.3.- LCD_ejemplo3.c
/* ******* Mostrar mensajes y array de números en formatos Decimal y Hexadecimal en el LCD *********** */
// **************************** Directivas de Preprocesado***************************************
#include <16F876A.h>
#fuses XT,NOWDT
#use delay( clock = 4000000 )
#include <LCD2.c>
// Reloj de 4 MHz
// Incluimos el driver LCD2.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;
lcd_init();
// Inicializamos el LCD.
lcd_gotoxy(5,1);
printf(lcd_putc, "Decimal");
// Posicionamos el Cursor del LCD en la posición 5 línea 1 .
// Escribimos la palabra "Decimal".
lcd_gotoxy(5,2);
printf(lcd_putc, "Hexadecimal");
// Posicionamos el Cursor del LCD en la posición 5 línea 2 .
// 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);
printf(lcd_putc,"%3u",DIGIT_MAP[i]);
lcd_gotoxy(2,2);
printf(lcd_putc,"%2X",DIGIT_MAP[i]);
delay_ms(1000);
// Posicionamos el Cursor del LCD en la posición 1
// línea 1 .
// Escribimos 3 dígitos del dato sacado del array
// DIGITAL_MAP en formato entero y sin signo.
// Posicionamos el Cursor del LCD en la posición 2
// línea 2 .
// Escribimos 2 dígitos del número sacado del array
// DIGITAL_MAP en formato entero hexadecimal
// mayúsculas.
// Retardo de 1 segundo.
}
while (1);
// Fin.
}
IES Joan Miró
Página 93
Curso de Robótica y otras aplicaciones en el Aula de Tecnología
4.2.4.- LCD_ejemplo4.c
/* ************ Mostrar mensajes y array de números en formatos entero 16 bit en el LCD *************** */
// ****************************** Directivas de Preprocesado***************************************
#include <16F876A.h>
#fuses XT,NOWDT
#use delay( clock = 4000000 )
#include <LCD2.c>
// Reloj de 4 MHz
// Incluimos el driver LCD2.c que contiene las funciones de control
// del LCD.
int16 CONST NUMEROS[10]={267,456,856,23984,123,65535,65536,12,7,5};
de 16 bit.
// Array de 10 números tipo entero
// ************************* Función principal o programa principal *********************************
void main()
{
int8 i=0;
lcd_init();
// Inicializamos el LCD.
lcd_gotoxy(9,1);
printf(lcd_putc, "int16");
// Posicionamos el Cursor del LCD en la posición 9 línea 1 .
// Escribimos la palabra "int16".
for(i = 0;i <= 9; ++i)
// Sacamos los diez datos del array uno a uno y los representamos
// en el Display.
{
lcd_gotoxy(1,1);
printf(lcd_putc,"%5Lu",NUMEROS[i]);
delay_ms(1000);
// Posicionamos el Cursor del LCD en la posición 1
// línea 1
// Escribimos 5 dígitos del dato sacado del array
// NUMEROS en formato entero largo sin signo.
// (No representa los ceros a la izquierda)
// Retardo de 1 segundo.
}
while (1);
// Fin.
}
IES Joan Miró
Página 94
Curso de Robótica y otras aplicaciones en el Aula de Tecnología
4.2.5.- LCD_ejemplo5.c
/* ******** Mostrar mensajes y array de números en formatos entero 32 bit con signo en el LCD *********** */
// ****************************** Directivas de Preprocesado***************************************
#include <16F876A.h>
#fuses XT,NOWDT
#use delay( clock = 4000000 )
// Reloj de 4 MHz
#include <LCD2.c>
// Incluimos el driver LCD2.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;
lcd_init();
// Inicializamos el LCD.
lcd_gotoxy(9,2);
printf(lcd_putc, "S_int32");
// Posicionamos el Cursor del LCD en la posición 9 línea 2.
// Escribimos la palabra "S_int32".
for(i = 0;i <= 9; ++i)
// Sacamos los diez datos del array uno a uno y los representamos
// en el Display.
{
lcd_gotoxy(1,2);
printf(lcd_putc,"%7Ld",DATOS[i]);
delay_ms(1000);
// Posicionamos el Cursor del LCD en la posición 1
// línea 2.
// Escribimos 7 dígitos del dato sacado del array
// DATOS en formato entero largo con signo. (No
// representa los ceros a la izquierda)
// Retardo de 1 segundo.
}
while (1);
// Fin.
}
IES Joan Miró
Página 95
Curso de Robótica y otras aplicaciones en el Aula de Tecnología
4.2.6.- LCD_ejemplo6.c
/* ***************** Mostrar mensajes y array de caracteres en el LCD ******************************* */
// **************************** Directivas de Preprocesado****************************************
#include <16F876A.h>
#fuses XT,NOWDT
#use delay( clock = 4000000 )
// Reloj de 4 MHz
#include <LCD2.c>
// Incluimos el driver LCD2.c que contiene las
// funciones de control del LCD.
// Array tipo Char de 16 caracteres.
Char CONST CARACTER[17]={"arthgsupHF12erfj"};
// ******************** Función principal o programa principal ***************************************
void main()
{
int8 i=0;
lcd_init();
// Inicializamos el LCD.
lcd_gotoxy(3,1);
printf(lcd_putc, "(Caracteres)");
// Posicionamos el Cursor del LCD en la posición 3 línea 1.
// 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 <= 15; ++i)
// Sacamos los 15 caracteres del array uno a uno y los
// representamos en el Display.
{
printf(lcd_putc,"%1c\b",CARACTER[i]);
delay_ms(1000);
// Escribimos 1 dígitos tipo caracter sacado del array
// CARACTER. Posicionamos el cursor constantemente
// en la posición 8 línea 2.
// Retardo de 1 segundo.
}
while (1);
// Fin.
}
IES Joan Miró
Página 96
Curso de Robótica y otras aplicaciones en el Aula de Tecnología
4.2.7.- LCD_ejemplo7.c
Realizar un programa que lea el Puerto B y represente en un Display LCD (2x20) el valor en
decimal, hexadecimal y binario. Utilizamos el siguiente circuito:
Programa:
Dec_Hex_Bin.c
/* ***** Leer el Puerto B y mostrar sus valor en el LCD en decimal, hexadecimal y binario ******* */
// ************************* Directivas de Preprocesado**********************************
#include <16F876A.h>
#fuses XT,NOWDT
#use delay( clock = 4000000 )
// Reloj de 4 MHz
#include <LCD1.c>
del LCD.
// Incluimos el driver LCD1.c que contiene las funciones de control
#BYTE TRISB = 0x86
#BYTE PORTB = 0x06
// TRISB en 86h.
// PORTB en 06h.
#BIT RB0 = 0x06.0
#BIT RB1 = 0x06.1
#BIT RB2 = 0x06.2
#BIT RB3 = 0x06.3
#BIT RB4 = 0x06.4
#BIT RB5 = 0x06.5
IES Joan Miró
// RB0 en 0x06 patilla 0.
// RB1 en 0x06 patilla 1.
// RB2 en 0x06 patilla 2.
// RB3 en 0x06 patilla 3.
// RB4 en 0x06 patilla 4.
// RB5 en 0x06 patilla 5.
Página 97
Curso de Robótica y otras aplicaciones en el Aula de Tecnología
#BIT RB6 = 0x06.6
#BIT RB7 = 0x06.7
// RB6 en 0x06 patilla 6.
// RB7 en 0x06 patilla 7.
// ******************* Función principal o programa principal *******************************
void main()
{
int8 dato=0;
TRISB = 0B11111111;
PORTB = 0B00000000;
// Defines Puerto B como ENTRADA de datos.
// Reseteamos el Puerto B.
lcd_init();
// Inicializamos el LCD.
lcd_gotoxy(5,1);
printf(lcd_putc, "Decimal");
// Posicionamos el Cursor del LCD en la posición 5 línea 1.
// Escribimos la palabra "Decimal".
lcd_gotoxy(18,1);
printf(lcd_putc, "Hex");
// Posicionamos el Cursor del LCD en la posición 18 línea 1.
// Escribimos la palabra "Hex".
lcd_gotoxy(12,2);
printf(lcd_putc, "Binario");
// Posicionamos el Cursor del LCD en la posición 12 línea 2.
// Escribimos la palabra "Hexadecimal".
while (1)
{
dato=PORTB;
lcd_gotoxy(1,1);
printf(lcd_putc,"%3u",PORTB);
lcd_gotoxy(15,1);
printf(lcd_putc,"%2X",PORTB);
lcd_gotoxy(3,2);
// Posicionamos el Cursor del LCD en la
// posición 1 línea 1.
// Escribimos 3 dígitos del dato leído del
// Puerto B en formato entero y sin signo.
// Posicionamos el Cursor del LCD en la
// posición 15 línea 1.
// Escribimos 2 dígitos del dato leído del
// Puerto B en formato entero
// hexadecimal mayúsculas.
// Posicionamos el Cursor del LCD en la
// posición 3 línea 2 .
printf(lcd_putc,"%u%u%u%u%u%u%u%u",RB7,RB6,RB5,RB4,RB3,RB2,RB1,RB0);
// Escribimos 8 variables en formato
// entero y sin signo.
delay_ms(100);
// Retardo de 100 mS.
}
}
IES Joan Miró
Página 98
Curso de Robótica y otras aplicaciones en el Aula de Tecnología
4.3.- Digitalización de una señal analógica con el sistema de adquisición
de datos.
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 =
IES Joan Miró
V REF + −V REF −
1024
=
5V−0V
1024
= 4,8 mV.
Página 99
Curso de Robótica y otras aplicaciones en el Aula de Tecnología
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

Error de conversió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 = ±
Error = ± 2,4 mV.
1
2
LSB
La relación existente entre tensiones de entrada Ve y códigos digitales de salida D se refleja en
la siguiente tabla.
Ve
0 < Ve ≤ 2,4 mV
2,4mV < Ve ≤ 7,2 mV
7,2mV < Ve ≤ 12 mV
12mV < Ve ≤ 16,8 mV
16,8mV < Ve ≤ 21,6 mV
16,8mV < Ve ≤ 4,9904mV
4,9904mV < Ve ≤ 4,9952 mV
Código Digital de salida del Conversor Analógico/Digital
D9 D8 D7 D6 D5 D4 D3 D2 D1 D0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
1
0
1
0
1
0
0
1
2
3
4
1 1 1 1 1 1 1 1 1 0
1 1 1 1 1 1 1 1 1 1
Una fórmula válida para trabajar sería: Ve = 𝐷 ∗
Ve = 512 ∗
1022
1023
𝑉𝑅𝐸𝐹 + +𝑉𝑅𝐸𝐹 −
1024
Ejemplo: (Trabajando con tensiones comprendidas entre VREF+ = 5V y
¿Cuánto vale Ve si D=512? :
0
0
1
1
0
D
Nº Decimal
5𝑉+0𝑉
1024
VREF+ = 0V )
= 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
IES Joan Miró
Página 100
Curso de Robótica y otras aplicaciones en el Aula de Tecnología
PCFG(3..0) AN7 AN6 AN5 AN4 AN3
0000
0001
0010
0011
0100
0101
011X
1000
1001
1010
1011
1100
1101
1110
1111
A
A
D
D
D
D
D
A
D
D
D
D
D
D
D
A
A
D
D
D
D
D
A
D
D
D
D
D
D
D
A
A
D
D
D
D
D
A
A
A
A
D
D
D
D
A
A
A
A
D
D
D
A
A
A
A
A
D
D
D
AN2
AN1
AN0
VREF+
VREF-
A
A
A
A
D
D
D
VREFA
A
VREFVREFVREFD
VREF-
A
A
A
A
A
A
D
A
A
A
A
A
A
D
D
A
A
A
A
A
A
D
A
A
A
A
A
A
A
A
VDD
AN3
VDD
D
AN3
VDD
AN3
AN3
VDD
AN3
AN3
AN3
AN3
VDD
AN3
GND
GND
GND
GND
GND
GND
AN2
GND
GND
AN2
AN2
AN2
GND
AN2
A
VREF+
A
VREF+
A
VREF+
D
VREF+
A
VREF+
VREF+
VREF+
VREF+
D
VREF+
Trabajando en C el compilador CCS maneja unas funciones propias para la conversión
analógica-digital. Utilizamos los siguientes ejemplos para entenderlo mejor:
4.3.1.- Conversión_A/D_D/A.c
VDD
C1
15p
X1
CRYSTAL
C2
4MHz
15p
V entrada
+
AM
U1
9
10
1
FM
2
3
4
5
6
7
OSC1/CLKIN
OSC2/CLKOUT
MCLR/Vpp/THV
RB0/INT
RB1
RB2
RB3/PGM
RB4
RB5
RB6/PGC
RB7/PGD
RA0/AN0
RA1/AN1
RA2/AN2/VREFRA3/AN3/VREF+
RA4/T0CKI
RA5/AN4/SS
RC0/T1OSO/T1CKI
RC1/T1OSI/CCP2
RC2/CCP1
RC3/SCK/SCL
RC4/SDI/SDA
RC5/SDO
RC6/TX/CK
RC7/RX/DT
21
22
23
24
25
26
27
28
CONVERSOR DIGITAL/ANALÓGICO
11
12
13
14
15
16
17
18
D0
D1
D2
D3
D4
D5
D6
D7
LE
PIC16F876
V salida
VOUT
VREF+
VREF-
R1
R2
5k
5k
DAC_8
VDD
GENERADOR DE FUNCIONES
VDD
A
OSCILOSCOPIO
B
IES Joan Miró
Página 101
Curso de Robótica y otras aplicaciones en el Aula de Tecnología
//****** Digitalizar la señal Analógica procedente de la patilla AN0 y sacarla por el Puerto C ********
// **************************** 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
#use delay(clock=4000000)
#BYTE TRISC = 0x87
#BYTE portC = 0x07
// TRISC en 87h.
// PORTC en 07h.
// ************************ Función principal o programa principal **************************
void main()
{
int16 q;
TRISC = 0B00000000;
portC = 0;
// Defines Puerto C como SALIDA de datos.
setup_adc_ports(0);
// Seleccionamos el Puerto A como entradas
// Analógicas. Mirar ADCON1.
// Fuente de reloj RC interno.
// Habilitación canal 0 "AN0"
setup_adc(ADC_CLOCK_INTERNAL);
set_adc_channel(0);
while(1)
{
// Bucle infinito.
delay_us(5);
q = read_adc();
// Retardo de 20uS necesaria para respetar el
// tiempo de Adquisición Tad.
// Lectura canal 0 "AN0"
portC = q;
}
}
Se observa que a medida que aumentamos la frecuencia de la señal a digitalizar las muestras
son cada vez, más visibles.
Según el criterio de Nyquist-Shannon la frecuencia de muestreo tiene que ser como mínimo 2
veces la frecuencia máxima de la señal.
Fr muestreo ≥ 2 x Frmáxima de la señal.
Ejemplo:
Frmáxima de la señal.= 1 KHz  Fr muestreo ≥ 2 KHz  Tmuestreo ≤ 𝐹𝑟
1
𝑚𝑢𝑒𝑠𝑡𝑟𝑒𝑜
IES Joan Miró
1
= 2 𝐾ℎ𝑧 = 500 µSeg
Página 102
Curso de Robótica y otras aplicaciones en el Aula de Tecnología
V entrada



Vmax = 4V
Frecuencia =60Hz
Señal Sinusoidal
Unipolar
V entrada
V salida
V entrada



Vmax = 4V
Frecuencia =1200Hz
Señal Sinusoidal
Unipolar
V entrada
V salida
IES Joan Miró
Página 103
Curso de Robótica y otras aplicaciones en el Aula de Tecnología
En los siguientes ejercicios de Conversión Analógica/Digital vamos a digitalizar señales,
presentar su valor en un LCD y actuaremos sobre un motor de Corriente Continua.
4.3.2.- Conversión_A-D1.c
IES Joan Miró
Página 104
Curso de Robótica y otras aplicaciones en el Aula de Tecnología
//*************************Conversión Analógica Digital de la Patilla AN0 *****************************
// ******************************* Directivas de Preprocesado**************************************
#include <16F876A.h>
#device adc=10
de resolucion.
// Conversor Analógico Digital de 10 bit el PIC 16F876A puede trabajar con 8 o 10 bit
#FUSES XT,NOWDT
#use delay(clock=4000000)
#include <LCD1.c>
// Incluimos el driver LCD1.c que contiene las funciones de control del LCD.
// ************************ Función principal o programa principal ***********************************
void main()
{
int16 q;
float p;
lcd_init();
setup_adc_ports(0);
setup_adc(ADC_CLOCK_INTERNAL);
// Inicializamos el LCD.
// Seleccionamos el Puerto A como entradas Analógicas. Mirar
// ADCON1.
// Fuente de reloj RC interno.
set_adc_channel(0);
// Habilitación canal 0 "AN0"
for (;;)
// Bucle infinito.
{
delay_us(5);
q = read_adc();
p = 5.0 * q / 1024.0;
// Retardo de 20uS necesaria para respetar el tiempo de
// Adquisición Tad.
// Lectura canal 0 "AN0"
// Conversión a tensión del código digital "q".
lcd_gotoxy(1,1);
// Posicionamos el Cursor en la posición 1, línea 1.
printf(lcd_putc, "\ADC = %4lu", q);
// Escribimos en el LCD "ADC =" y 4 dígitos de
// "q" en formato largo sin signo.
printf(lcd_putc, "\nVOLTAJE = %01.3fV", p);
// Saltamos de línea y escribimos en el LCD
// "VOLTAJE =" y 4 dígitos de "P"
// en formato truncado de 4 dígitos con
// 3 decimales y el carácter "V".
}
}
IES Joan Miró
Página 105
Curso de Robótica y otras aplicaciones en el Aula de Tecnología
4.3.3.- Conversión_A-D2.c
//************** Conversión Analógica Digital de la Patilla AN0, AN1, AN2 y AN3 *************************
// **************************** Directivas de Preprocesado*****************************************
#include <16F876A.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=4000000)
#include <LCD1.c>
// Incluimos el driver LCD1.c que contiene las funciones de control del LCD.
// *************************** Función principal o programa principal ********************************
void main()
{
int16 q;
float p;
setup_adc(ADC_CLOCK_INTERNAL);
setup_adc_ports(0);
lcd_init();
while (true)
{
set_adc_channel(0);
delay_us(5);
q = read_adc();
p = 5.0 * q / 1024.0;
// Bucle infinito.
// Habilitación canal 0 "AN0"
// Retardo de 20uS necesaria para respetar el Tiempo
// de Adquisición Tad.
// Lectura canal 0 "AN0"
// Conversión a tensión del código digital "q".
lcd_gotoxy(1,1);
printf(lcd_putc, "V1=%01.3fv", p);
// Posicionamos el Cursor en la posición 1, línea 1.
// Escribimos en el LCD "V1 =" y 4 dígitos de "P" en
// formato truncado de 4 dígitos con 3 decimales y el
// carácter "v".
set_adc_channel(1);
delay_us(5);
// Habilitación canal 1 "AN1"
// Retardo de 20uS necesaria para respetar el Tiempo
// de Adquisición Tad.
// Lectura canal 1 "AN1"
// Conversión a tensión del código digital "q".
q = read_adc();
p = 5.0 * q / 1024.0;
lcd_gotoxy(12,1);
printf(lcd_putc, "V2=%01.3fv", p);
IES Joan Miró
// Fuente de reloj RC interno.
// Seleccionamos el Puerto A como entradas
// Analógicas. Mirar ADCON1.
// Inicializamos el LCD.
// Posicionamos el Cursor en la posición 12, línea 1.
// Escribimos en el LCD "V2 =" y 4 dígitos de "P" en
// formato truncado de 4 dígitos con 3 decimales y el
Página 106
Curso de Robótica y otras aplicaciones en el Aula de Tecnología
// carácter "v".
set_adc_channel(2);
delay_us(5);
// Habilitación canal 2 "AN2"
// Retardo de 20uS necesaria para respetar el Tiempo
// de Adquisición Tad.
// Lectura canal 2 "AN2"
// Conversión a tensión del código digital "q".
q = read_adc();
p = 5.0 * q / 1024.0;
lcd_gotoxy(1,2);
printf(lcd_putc, "V3=%01.3fv", p);
// Posicionamos el Cursor en la posición 1, línea 2.
// Escribimos en el LCD "V3 =" y 4 dígitos de "P" en
// formato truncado de 4 dígitos con 3 decimales y el
// carácter "v".
set_adc_channel(3);
delay_us(5);
// Habilitación canal 3 "AN3"
// Retardo de 20uS necesaria para respetar el Tiempo
// de Adquisición Tad.
// Lectura canal 3 "AN3"
// Conversión a tensión del código digital "q".
q = read_adc();
p = 5.0 * q / 1024.0;
lcd_gotoxy(12,2);
printf(lcd_putc, "V4=%01.3fv", p);
// Posicionamos el Cursor en la posición 12, línea 2.
// Escribimos en el LCD "V4 =" y 4 dígitos de "P" en
// formato truncado de 4 dígitos con 3 decimales y el
//carácter "v".
}
}
4.3.4.- Conversión_A-D3.c
//************* Leer la patilla RA0 si la tensión es superior a 2,5 V activar motor ************************
//*************************** 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 resolución.
#FUSES XT,NOWDT
#use delay(clock=4000000)
#include <LCD1.c>
// Incluimos el driver LCD1.c que contiene las funciones de
//control del LCD.
#BYTE TRISC = 0x87
#BYTE portC = 0x07
// TRISC en 87h.
// PORTC en 07h.
#BIT rc0 = 0x07.0
// RC0 en 0x07 patilla 0.
IES Joan Miró
Página 107
Curso de Robótica y otras aplicaciones en el Aula de Tecnología
// ************************** Función principal o programa principal *********************************
void main()
{
int16 q;
float p;
TRISC = 0B00000000;
rc0 = 0;
lcd_init();
// Defines Puerto C como SALIDA de datos.
// Paramos motor.
// Inicializamos el LCD.
setup_adc_ports(0);
// Seleccionamos el Puerto A como entradas Analógicas.
// Mirar ADCON1.
// Fuente de reloj RC interno.
// Habilitación canal 0 "AN0"
setup_adc(ADC_CLOCK_INTERNAL);
set_adc_channel(0);
while(1)
{
// Bucle infinito.
delay_us(20);
q = read_adc();
p = 5.0 * q / 1024.0;
// Retardo de 20uS necesaria para respetar el Tiempo de
// Adquisición Tad.
// Lectura canal 0 "AN0"
// Conversión a tensión del código digital "q".
lcd_gotoxy(1,1);
printf(lcd_putc, "VOLTAGE = %01.3fV", p);
lcd_gotoxy(1,2);
if(p>2.5)
{
// Situamos el Cursor en la posición 1,
// línea 1.
// Escribimos en el LCD "VOLTAJE ="
// y 4 dígitos de "P" en formato truncado de
//4 dígitos con 3 decimales y el carácter "V".
// Posicionamos el Cursor en la posición 1,
// línea 2.
// Preguntamos si p es mayor que 2.5
rc0 = 1;
printf(lcd_putc,"Motor Activado");
// Activamos Motor.
// Escribimos en el LCD "Motor Activado".
rc0 = 0;
printf(lcd_putc," Motor Parado");
// Paramos Motor.
// Escribimos en el LCD "Motor Parado".
}
else
{
}
}
}
IES Joan Miró
Página 108
Curso de Robótica y otras aplicaciones en el Aula de Tecnología
4.4.- Control de velocidad y sentido de giro 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.
V motor
Vmedia= 0% x 5v = 0v
TH
0%
(Motor Parado)
16
32
CT =
t
T
TH
T
x 100 =
0 mS
16 mS
= 0%
(mSeg)
V motor
Vmedia= 20% x 5v = 1v
5v
TH
CT =
20%
3,2
16
32
t
T
V motor
5v
TH
T
x 100 =
3,2 mS
16 mS
= 20 %
(mSeg)
Vmedia= 50% x 5v = 2,5v
TH
50%
8
16
32
t
T
V motor
CT =
TH
T
x 100 =
8 mS
16 mS
= 50 %
(mSeg)
Vmedia= 80% x 5v = 4v
5v
80%
TH
12,8
16
32
t
T
CT =
TH
T
x 100 =
12,8 mS
16 mS
= 80 %
(mSeg)
Vmedia= 100% x 5v = 5v
V motor
5v
100%
CT =
TH
T
IES Joan Miró
(Velocidad Máxima)
16
32
t
TH
T
x 100 =
16 mS
16 mS
(mSeg)
Página 109
= 100 %
Curso de Robótica y otras aplicaciones en el Aula de Tecnología
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.
4.4.1.- PWM1.c
//******************Control de velocidad con PWM a través de un Potenciómetro ***********************
// ********************************* 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 resolución.
#FUSES XT,NOWDT
#use delay(clock=1000000)
// ***************************** Función principal o programa principal ******************************
void main()
{
int16 TH =0;
setup_adc(ADC_CLOCK_INTERNAL);
// Fuente de reloj RC interno.
setup_adc_ports(0);
// Seleccionamos el Puerto A como entradas
// Analógicas. Mirar ADCON1.
IES Joan Miró
Página 110
Curso de Robótica y otras aplicaciones en el Aula de Tecnología
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 4 x 16 x 1
// PR2 =[T/(Tcm x Preescaler x Postscaler)]-1
// PR2 =[16000uS/(4uS x 16 x 1)]-1 = 249
(en C 249)
setup_ccp2(CCP_PWM);
set_adc_channel(0);
// CCP2 en modo PWM (Salida por RC1)
// Habilitación canal 0 "AN0"
while (true)
// Bucle infinito.
{
delay_us(20);
TH = read_adc();
set_pwm2_duty(TH);
delay_ms(5);
// Retardo de 20uS necesaria para respetar el tiempo de
// Adquisición Tad.
// Lectura canal 0 "AN0" set_pwm2_duty(TH);
// Refrescamos el Tiempo alto TH de la señal.
// 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.
}
}
4.4.2.- PWM2.c
En este ejemplo se pretende controlar la velocidad y el sentido de giro de 2 motores
de corriente continua. Se utiliza el C.I. L298N que sirve para invertir el paso de la corriente por
los motores. Tienes dos circuitos electrónicos idénticos.
Su tabla de la verdad sería:
Entradas
ENA IN1 IN2
0
x
x
1
0
0
1
0
1
1
1
0
1
1
1
IES Joan Miró
Salidas
OUT1 OUT2
5v
5v
0v
0v
0v
9v
9v
0v
9v
0v
Efectos sobre un
Motor
Parado
Parado
Giro a Derechas
Giro a Izquierdas
Parado
Página 111
Curso de Robótica y otras aplicaciones en el Aula de Tecnología
IES Joan Miró
Página 112
Curso de Robótica y otras aplicaciones en el Aula de Tecnología
El circuito utilizado para realizar es el de la figura de arriba. Con el Potenciómetro RV1
y el interruptor SW1 controlamos la velocidad y el sentido de giro del Motor MOT1 y con el
Potenciómetro RV2 y el interruptor SW2 controlamos la velocidad y el sentido de giro del
Motor MOT2.
//**********Control de velocidad y sentido de giro de 2 motores de corriente continua ***********
// **************************** 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 resolución.
#FUSES XT,NOWDT
#use delay(clock=1000000)
#BYTE TRISB = 0x86
#BYTE portB = 0x06
#BIT rb0 = 0x06.0
#BIT rb1 = 0x06.1
#BIT rb2 = 0x06.2
#BIT rb3 = 0x06.3
#BIT rb4 = 0x06.4
#BIT rb5 = 0x06.5
// TRISB en 86h.
// PORTB en 06h.
// RB0 en 0x06 patilla 0.
// RB1 en 0x06 patilla 1.
// RB0 en 0x06 patilla 2.
// RB1 en 0x06 patilla 3.
// RB0 en 0x06 patilla 4.
// RB1 en 0x06 patilla 5.
int16 TH =0;
// *********************** Función principal o programa principal ***************************
void main()
{
TRISB = 0B00110000;
// Defines PB7,6,4,3,2,1,0 como SALIDA de datos y
// PB5,4 como entrada de datos.
portB = 0B00000000;
// Reseteamos el Puerto B.
setup_adc(ADC_CLOCK_INTERNAL);
setup_adc_ports(0);
setup_timer_2(T2_DIV_BY_16,249,1);
IES Joan Miró
// Fuente de reloj RC interno.
// Seleccionamos el Puerto A como entradas
// Analógicas. Mirar ADCON1.
// 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 4 x 16 x 1
// PR2 =[T/(Tcm x Preescaler x Postscaler)]-1
// PR2 =[16000uS/(4uS x 16 x 1)]-1 = 249
Página 113
Curso de Robótica y otras aplicaciones en el Aula de Tecnología
setup_ccp2(CCP_PWM);
setup_ccp1(CCP_PWM);
// CCP2 en modo PWM (Salida por RC1)
// CCP1 en modo PWM (Salida por RC2)
while (true)
{
set_adc_channel(0);
delay_us(20);
// Bucle infinito.
TH = read_adc();
set_pwm2_duty(TH);
if(rb4 == 1)
{
rb0 = 1;
rb1 = 0;
}
Else
{
rb0 = 0;
rb1 = 1;
}
set_adc_channel(1);
delay_us(20);
TH = read_adc();
set_pwm1_duty(TH);
if(rb5 == 1)
{
rb2 = 1;
rb3 = 0;
}
Else
{
rb2 = 0;
rb3 = 1;
}
delay_ms(5);
// Habilitación canal 0 "AN0"
// Retardo de 20uS necesaria para respetar el
// tiempo de Adquisición Tad.
// Lectura canal 0 "AN0"
// Refrescamos el Tiempo alto TH de la señal.
// Motor 1. Giro a Derechas
// Motor 1. Giro a Izquierdas
// Habilitación canal 1 "AN1"
// Retardo de 20uS necesaria para respetar el
// tiempo de Adquisición Tad.
// Lectura canal 1 "AN1"
// Refrescamos el Tiempo alto TH de la señal.
// Motor 2. Giro a Derechas
// Motor 2. Giro a Izquierdas
// 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.
}
}
IES Joan Miró
Página 114
Curso de Robótica y otras aplicaciones en el Aula de Tecnología
4.4.3.- PWM3.c
La función set_pwm2_duty(TH) genera una señal de PWM de 10bit, es decir TH está definido
con esta resolución. Tenemos 210 (0…1023) códigos diferentes para controla el nivel alto TH.
Si queremos controlar TH con solo 8 bits 28 (0..255) códigos diferentes el proceso es el
siguiente:



Leemos un dato de 8 bits , lo introducimos en la variable TH de 16 bit 216 (0..65535).
Multiplicamos el contenido de la variable TH por 4.
Introducimos TH en la función set_pwm2_duty(int16);
Ejemplo:


PORT B  1
TH PORTB
// Introducimos en el Puerto B el número 5
// Introducimos en TH el contenido del Puerto B.


TH TH x 4
set_pwm2_duty(TH);
// TH vale 4
// Se genera una señal PWM cuyo tiempo a nivel alto
// TH es proporcional al código introducido.


PORT B  128
TH PORTB
// Introducimos en el Puerto B el número 5
// Introducimos en TH el contenido del Puerto B.


TH TH x 4
set_pwm2_duty(TH);
// TH vale 512
// Se genera una señal PWM cuyo tiempo a nivel alto
// TH es proporcional al código introducido.


PORT B  255
TH PORTB
// Introducimos en el Puerto B el número 5
// Introducimos en TH el contenido del Puerto B.


TH TH x 4
// TH vale 1020
// Se genera una señal PWM cuyo tiempo a nivel alto
// TH es proporcional al código introducido.
set_pwm2_duty(TH);
Ejemplo:
IES Joan Miró
Página 115
Curso de Robótica y otras aplicaciones en el Aula de Tecnología
//****************Control de velocidad de un motor con PWM a través del Puerto B ******************
// ******************************* Directivas de Preprocesado**********************************
#include <16F876A.h>
#FUSES XT,NOWDT
#use delay(clock=1000000)
#BYTE TRISB = 0x86
#BYTE portB = 0x06
// TRISB en 86h.
// PORTB en 06h.
// ************************ Función principal o programa principal *******************************
void main()
{
int16 TH =0;
TRISB = 0B11111111;
// Defines Puerto B como entrada de datos.
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 4 x 16 x 1
// PR2 =[T/(Tcm x Preescaler x Postscaler)]-1
// PR2 =[16000uS/(4uS x 16 x 1)]-1 = 249
(en C 249)
setup_ccp2(CCP_PWM);
while (true)
{
TH = portB;
TH = TH *4;
set_pwm2_duty(TH);
// CCP2 en modo PWM (Salida por RC1)
// Bucle infinito.
delay_ms(5);
// Lectura del Puerto B
// Multiplicar TH por 4
// Refrescamos el Tiempo alto TH de la señal.
// 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.
}
}
IES Joan Miró
Página 116
Curso de Robótica y otras aplicaciones en el Aula de Tecnología
4.5.- Control de un Servo 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:
IES Joan Miró
Página 117
Curso de Robótica y otras aplicaciones en el Aula de Tecnología
En el siguiente ejemplo simulado en Proteus hemos utilizado un driver de control del
servo de posición llamado Servo_Futaba_10bit.c que nos ayudará a realizar el control de
forma muy sencilla.
4.5.1.- Control_2_Servos_Posición.c
IES Joan Miró
Página 118
Curso de Robótica y otras aplicaciones en el Aula de Tecnología
/* *** 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 señal "T1H"
;El Servomotor de Futaba necesita un periodo "T1" entre 10ms y 30 ms.
;Cargando los registros de forma correcta sale T1 =[(249+1)*4*1uS](16)=16 mS (Cristal de cuarzo 1 MHz)
;Tiene un control de Posición de -90 Grados < P (Angular)< +90 Grados controlado con T1H.
;Para -90 Grados corresponde un nivel alto T1H = 0,6 ms
;Para 0 Grados corresponde un nivel alto T1H = 1,2 ms
;Para +90 Grados corresponde un nivel alto T1H = 2,4 ms
*/
// ****************************** Declaración de funciones *****************************************
void Inicializacion_Futaba_RC1();
void Inicializacion_Futaba_RC2();
void Futaba_RC1(int16 TH);
void Futaba_RC2(int16 TH);
// Inicializar PWM por RC1
// Inicializar PWM por RC2
// Generar PWM por RC1
// Generar PWM por RC2
//************************************* Igualdades ***********************************************
#define THmin 37
#define THmax 150
#define THmed 94
IES Joan Miró
// THmin=37 equivale a 600uS a nivel alto a -90º
// THmax=150 equivale a 2400uS a nivel alto a +90º
// THmed=94 equivale a 1500uS a nivel alto a 0º
Página 119
Curso de Robótica y otras aplicaciones en el Aula de Tecnología
// ******************************* Función Inicializacion_Futaba_RC1() *******************************
void Inicializacion_Futaba_RC1()
{
int16 TH;
setup_timer_2(T2_DIV_BY_16,249,1);
setup_ccp2(CCP_PWM);
TH = THmed;
set_pwm2_duty(TH);
delay_ms(5);
// 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)
// CCP2 en modo PWM (Salida por RC1)
// Cargar TH con valor medio
// Refrescamos el Tiempo alto TH de la señal.
}
// ******************************** Función Inicializacion_Futaba_RC2() *******************************
void Inicializacion_Futaba_RC2()
{
int16 TH;
setup_timer_2(T2_DIV_BY_16,249,1);
setup_ccp1(CCP_PWM);
TH = THmed;
set_pwm1_duty(TH);
delay_ms(5);
// 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)
// CCP1 en modo PWM (Salida por RC2)
// Cargar TH con valor medio
// Refrescamos el Tiempo alto TH de la señal.
}
IES Joan Miró
Página 120
Curso de Robótica y otras aplicaciones en el Aula de Tecnología
// ********************************* Función Futaba_RC1(int16 TH) **********************************
void Futaba_RC1(int16 TH)
{
TH = TH+THmin;
if(TH>THmin && TH<THmax) set_pwm2_duty(TH);
// Cargar TH con valor mínimo
// 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_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;
if(TH>THmin && TH<THmax) set_pwm1_duty(TH);
if(TH<=THmin)
{
TH=THmin+1;
set_pwm1_duty(TH);
}
if(TH>=THmax)
{
TH=THmax-1;
set_pwm1_duty(TH);
}
delay_ms(5);
// Cargar TH con valor mínimo
// Si THmin < TH < THmax
// Refrescamos el Tiempo alto TH de la señal.
// Si TH ≤ THmin
// Cargar TH con valor mínimo
// Refrescamos el Tiempo alto TH de la señal.
// Si TH ≥ THmax
// Cargar TH con valor máximo
// Refrescamos el Tiempo alto TH de la señal.
// 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.
}
IES Joan Miró
Página 121
Curso de Robótica y otras aplicaciones en el Aula de Tecnología
//******************************* Control de Posición de 2 Servo Futaba ******************************
// ************************************ 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 resolución.
#FUSES XT,NOWDT
#use delay(clock=4000000)
#include <Servo_Futaba_10bit.c>
// Incluimos el driver que contiene las funciones de control de
// los Servos de Futaba.
// ****************************** Función principal o programa principal ******************************
void main()
{
int16 TH;
Inicializacion_Futaba_RC1();
Inicializacion_Futaba_RC2();
// Inicialización del Servo en RC1
// Inicialización del Servo en RC2
// While (1);
// Vemos posición central.
setup_adc(ADC_CLOCK_INTERNAL);
setup_adc_ports(0);
// Fuente de reloj RC interno.
// Seleccionamos el Puerto A como entradas Analógicas.
// Mirar ADCON1.
while (true)
// Bucle infinito.
{
set_adc_channel(0);
delay_us(5);
TH = read_adc();
// Habilitación canal 0 "AN0"
// Retardo de 20uS necesaria para respetar el tiempo de
// Adquisición Tad.
// Lectura canal 0 "AN0"
Futaba_RC1(TH);
// Posicionar el Servo de la patilla RC1.
set_adc_channel(1);
delay_us(5);
// Habilitación canal 1 "AN1"
// Retardo de 20uS necesaria para respetar el tiempo de
// Adquisición Tad.
// Lectura canal 1 "AN1"
TH = read_adc();
Futaba_RC2(TH);
// Posicionar el Servo de la patilla RC2.
}
}
IES Joan Miró
Página 122
Curso de Robótica y otras aplicaciones en el Aula de Tecnología
4.6.- Diseño de Mandos Transmisores y Receptores de radio frecuencia.
4.6.1.- Introducción.
Antes de introducirnos en la Transmisión y Recepción Serie de datos vía
radiofrecuencia, explicaremos de forma breve el tipo de transmisión utilizada, como se modula
la señal para poderla transmitir vía radio frecuencia y que protocolo se ha seguido para poder
dar seguridad a una transmisión.
4.6.1.1.- Transmisión serie asíncrona.
Es transmitir 8 bit de uno en uno siguiendo un protocolo de comunicaciones. Primero
se transmite un bit de START después 8 bit de DATOS y por ultimo un bit de STOP. El
transmisor y receptor de datos tiene que estar trabajando a la misma velocidad. En nuestro
caso 2400 bit/segundo.

Los datos se comunican en serie de la siguiente manera:
El número de bits de datos, bit de Stop es uno de los parámetros configurables, así como
el criterio de paridad par o impar para la detección de errores. Normalmente, las
comunicaciones serie tienen los siguientes parámetros: 1 bit de Start, 8 bits de Datos, 1 bit de
Stop y sin paridad.
En esta figura se puede ver un ejemplo de la transmisión del dato binario 01011010B. La
línea en reposo está a nivel alto: (Se transmite primero el bit LSB)
IES Joan Miró
Página 123
Curso de Robótica y otras aplicaciones en el Aula de Tecnología
4.6.1.2.- 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.
4.6.1.3.- 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.
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.
IES Joan Miró
Página 124
Curso de Robótica y aplicaciones a el Aula de Tecnología
IES Joan Miró
Página 125
Curso de Robótica y aplicaciones a el Aula de Tecnología
4.6.2.- Ejemplo 1 (Transmisión Simple).
Transmisión_Serie_1a.c
//************************ Mando de Transmisión serie vía radiofrecuencia *****************************
// ********************************* 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.
#BIT TC3 = 0x87.3
#BIT rc3 = 0x07.3
// TC3 en 0x87 patilla 7.
// RC3 en 0x07 patilla 3.
IES Joan Miró
Página 126
Curso de Robótica y otras aplicaciones en el Aula de Tecnología
#BYTE TRISB = 0x86
#BYTE portB = 0x06
// TRISB en 86h.
// PORTB en 06h.
#BIT rb0 = 0x06.0
#BIT rb1 = 0x06.1
#BIT rb2 = 0x06.2
#BIT rb3 = 0x06.3
#BIT rb4 = 0x06.4
// RB0 en 0x06 patilla 0.
// RB1 en 0x06 patilla 1.
// RB2 en 0x06 patilla 2.
// RB3 en 0x06 patilla 3.
// RB4 en 0x06 patilla 4.
#BYTE cambio2 = 0x20
#BIT c0 = 0x20.0
#BIT c1 = 0x20.1
#BIT c2 = 0x20.2
#BIT c3 = 0x20.3
#BIT c4 = 0x20.4
// cambio2 en 0x20h.
// c0 en 0x20.0
// c1 en 0x20.1
// c2 en 0x20.2
// c3 en 0x20.3
// c4 en 0x20.4
#define Clave_Pulsadores 63
#define Numero_Repeticiones 10
// ******************************* Función principal o programa principal *****************************
void main()
{
int8 i=1;
int8 q;
// Definimos la variable "i" como tipo byte.
// Definimos la variable "q" como tipo byte.
TRISB = 0B11111111;
// Defines Puerto B como ENTRADA de datos.
cambio2=0;
TC3 = 0;
rc3 = 1;
// Inicializamos la variable cambio2 con 0.
// Defines la patilla 3 Puerto C como SALIDA de datos.
// Inhabilitamos la tarjeta CEBEK C-0503.
while(1)
{
// bucle infinito.
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;
if (rb1==0) c1=~c1;
if (rb2==0) c2=~c2;
if (rb3==0) c3=~c3;
if (rb4==0) c4=~c4;
rc3 = 0;
IES Joan Miró
// Si se pulsa rb0 cambiar el valor de c0.
// Si se pulsa rb1 cambiar el valor de c1.
// Si se pulsa rb2 cambiar el valor de c2.
// Si se pulsa rb3 cambiar el valor de c3.
// Si se pulsa rb4 cambiar el valor de c4.
// Habilitamos la tarjeta CEBEK C-0503.
Página 127
for (i=0; i<=Numero_Repeticiones;
i++) en//el
Enviamos
via serie, tantas veces
Curso de Robótica
y otras aplicaciones
Aula el
dedato
Tecnología
// como diga la variable Número_Repeticiones
{
putc(Clave_Pulsadores);
putc(cambio2);
// Enviamos vía serie la Clave_Pulsador.
// Enviamos vía serie la variable cambio2.
}
rc3 = 1;
// Inhabilitamos la tarjeta CEBEK C-0503.
delay_ms(200);
// Esperamos 200 mS hasta que dejemos de pulsar.
}
}
}
Recepción_Serie_1a.c
//********************************* Recepción Serie de Datos Simple ********************************
// ************************************ 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.
// TRISB en 86h.
// PORTB en 06h.
#BYTE TRISB = 0x86
#BYTE portB = 0x06
#define Clave_Pulsadores 63
/* ****************************** Declaración de funciones *************************************** */
void leer_dato_serie (void);
// Leer Dato.
// ************************ Función principal o programa principal ************************************
void main()
{
TRISB = 0B00000000;
// Defines Puerto B como SALIDA de datos.
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.
IES Joan Miró
Página 128
Curso de Robótica y otras aplicaciones en el Aula de Tecnología
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 leído, si son iguales se valida el dato con la variable global "Valor".
*/
void leer_dato_serie (void)
{
int8 Dato_Recibido;
int8 Numero_datos1;
int8 dato1;
Dato_Recibido=getc();
// Recibimos el dato serie.
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;
IES Joan Miró
Página 129
Curso de Robótica y otras aplicaciones en el Aula de Tecnología
case 2:
if(Dato_Recibido==Clave_Pulsadores)
{
Numero_datos1=3;
}
else
{
Numero_datos1=0;
}
break;
case 3:
if(Dato_Recibido==dato1)
portB=Dato_Recibido;
// El dato válido se deposita en el Puerto B
Numero_datos1=0;
}
}
IES Joan Miró
Página 130
Curso de Robótica y aplicaciones a el Aula de Tecnología
4.6.3.- Ejemplo2 (Transmisión Compleja).
IES Joan Miró
Página 131
Curso de Robótica y aplicaciones a el Aula de Tecnología
Transmisión_Serie_2.c
//****************** Mando de 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)
#BYTE TRISB = 0x86
#BYTE portB = 0x06
// Definimos la velocidad de transmisión de
// 2400 baudios/segundo
// Elegimos RC6 como patilla transmisora de datos.
// Elegimos RC7 como patilla receptora de datos.
// TRISB en 86h.
// PORTB en 06h.
#BIT TC3 = 0x87.3
#BIT rc3 = 0x07.3
// TC3 en 0x87 patilla 7.
// RC3 en 0x07 patilla 3.
#BIT rb0 = 0x06.0
#BIT rb1 = 0x06.1
#BIT rb2 = 0x06.2
#BIT rb3 = 0x06.3
#BIT rb4 = 0x06.4
#BIT rb5 = 0x06.5
// RB0 en 0x06 patilla 0.
// RB1 en 0x06 patilla 1.
// RB2 en 0x06 patilla 2.
// RB3 en 0x06 patilla 3.
// RB4 en 0x06 patilla 4.
// RB5 en 0x06 patilla 5.
#BYTE cambio2 = 0x20
#BIT c0 = 0x20.0
#BIT c1 = 0x20.1
#BIT c2 = 0x20.2
#BIT c3 = 0x20.3
#BIT c4 = 0x20.4
#BIT c5 = 0x20.5
// cambio2 en 0x20h.
// c0 en 0x20.0
// c1 en 0x20.1
// c2 en 0x20.2
// c3 en 0x20.3
// c4 en 0x20.4
// 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;
IES Joan Miró
// Definimos la variable "i" como tipo byte.
Página 132
Curso de Robótica y otras aplicaciones en el Aula de Tecnología
int8 q;
int1 rb5_1=0;
cambio2=0;
// Definimos la variable "q" como tipo byte.
// Definimos la variable "rb5_1" como tipo bit.
// Reseteamos la variable cambio2.
TRISB = 0B11111111;
TC3 = 0;
RC3 = 1;
// Defines Puerto B como ENTRADA de datos.
// Defines la patilla 3 Puerto C como SALIDA de datos.
// Inhabilitamos la tarjeta CEBEK C-0503.
setup_adc(ADC_CLOCK_INTERNAL);
setup_adc_ports(0);
// Fuente de reloj RC interno.
// Seleccionamos el Puerto A como entradas Analogicas.
// Mirar ADCON1.
// bucle infinito.
while(1)
{
set_adc_channel(0);
delay_us(20);
q = read_adc();
// Habilitación canal 0 "AN0"
// Retardo de 20uS necesaria para respetar el tiempo de
// Adquisición Tad.
// Lectura canal 0 "AN0"
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.
}
set_adc_channel(1);
delay_us(20);
q = read_adc();
// Habilitación canal 1 "AN1"
// Retardo de 20uS necesaria para respetar el tiempo de
// Adquisición Tad.
// 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)
}
IES Joan Miró
Página 133
Curso de Robótica y otras aplicaciones en el Aula de Tecnología
RC3 = 1;
// Inhabilitamos la tarjeta CEBEK C-0503.
}
q= portB & 0B00011111;
// Filtramos los 5 bit menos significativos del Puerto B.
if (q!=0B00011111)
{
if (rb0==0) c0=~c0;
if (rb1==0) c1=~c1;
if (rb2==0) c2=~c2;
if (rb3==0) c3=~c3;
if (rb4==0) c4=~c4;
// Si se activa un pulsador, transmitir datos.
// Si se pulsa rb0 cambiar el valor de c0.
// Si se pulsa rb1 cambiar el valor de c1.
// Si se pulsa rb2 cambiar el valor de c2.
// Si se pulsa rb3 cambiar el valor de c3.
// Si se pulsa rb4 cambiar el valor de c4.
RC3 = 0;
for(i=1;i<=Numero_Repeticiones;i++)
// Habilitamos la tarjeta CEBEK C-0503.
// Enviamos el dato vía serie, tantas veces
// como diga la variable Número_Repeticiones
{
putc(Clave_Pulsadores);
putc(cambio2);
}
RC3 = 1;
// Enviamos vía serie la Clave_Pulsadores.
// Enviamos vía serie la variable cambio2.
// (Pulsador Activado)
// Inhabilitamos la tarjeta CEBEK C-0503.
}
if (rb5!=rb5_1)
// Si se ha cambiado el Interruptor de la patilla rb5
// transmitir dato.
{
rb5_1=rb5;
c5=~rb5;
RC3 = 0;
for(i=1;i<=Numero_Repeticiones;i++)
// Habilitamos la tarjeta CEBEK C-0503.
// Enviamos el dato vía serie, tantas veces
// como diga la variable Número_Repeticiones
{
putc(Clave_Pulsadores);
putc(cambio2);
}
RC3 = 1;
// Enviamos vía serie la Clave_Pulsadores.
// Enviamos vía serie la variable cambio2.
// (Interruptor Activado)
// Inhabilitamos la tarjeta CEBEK C-0503.
}
}
}
IES Joan Miró
Página 134
Curso de Robótica y otras aplicaciones en el Aula de Tecnología
Recepción_Serie_2a.c
//***************************** Recepción Serie de Datos Compleja ***********************************
// ********************************** 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
#define Clave_Pot_Izq 134
#define Clave_Pulsadores 63
// Definimos claves
int8 dato_recibido=0;
int1 valido_Aut_Pul=1;
int1 valido_Aut_Pot_Der=1;
int1 valido_Aut_Pot_Izq=1;
// 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.
// ************************** 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;
portC = 0B00000000;
portB = 0B00000000;
enable_interrupts(INT_RDA);
enable_interrupts(GLOBAL);
IES Joan Miró
// Reseteamos el Puerto D.
// Reseteamos el Puerto C.
// Reseteamos el Puerto B.
// Habilitamos la interrupción serie de datos.
// Habilitamos la Interrupción General.
Página 135
Curso de Robótica y otras aplicaciones en el Aula de Tecnología
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();
if (valido_Aut_Pul==1)
// Recibimos el dato serie.
Automata_Pulsadores();
if (valido_Aut_Pot_Der==1) Automata_Pot_Der();
if (valido_Aut_Pot_Izq==1) Automata_Pot_Izq();
// Ejecutas la función Autómata_Pulsadores
// si la variable Valido_Aut_Pul==1.
// Ejecutas la función Automata_Pot_Der
// si la variable Valido_Aut_Pot_Der==1.
// Ejecutas la función Automata_Pot_Izq
// si la variable Valido_Aut_Pot_Izq==1.
}
IES Joan Miró
Página 136
Curso de Robótica y otras aplicaciones en el Aula de Tecnología
/*************************Función Automata_Pulsadores ***************************************** */
void Automata_Pulsadores(void)
{
int8 numero_datos;
int8 dato;
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;
}
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;
}
}
IES Joan Miró
Página 137
Curso de Robótica y otras aplicaciones en el Aula de Tecnología
/***********************************Función Automata_Pot_Der ********************************** */
void Automata_Pot_Der(void)
{
int8 numero_datos;
int8 dato;
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;
}
}
IES Joan Miró
Página 138
Curso de Robótica y otras aplicaciones en el Aula de Tecnología
/* ******************************Función Automata_Pot_Izq ************************************* */
void Automata_Pot_Izq(void)
{
int8 numero_datos;
int8 dato;
switch (numero_datos)
// Es un autómata modelo Moore, que valida los datos si llegan dos
// tramas iguales consecutives. 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;
}
}
IES Joan Miró
Página 139
Curso de Robótica y otras aplicaciones en el Aula de Tecnología
4.6.4.- Apertura de una puerta.
IES Joan Miró
Página 140
Curso de Robótica y otras aplicaciones en el Aula de Tecnología
Mando_Puerta.c
//******************************** Mando de Apertura de la puerta **********************************
// ************************************ Directivas de Preprocesado**********************************
#include <16F876.h>
#FUSES XT,NOWDT
#use delay(clock=4000000)
#use rs232(baud=9600, xmit=pin_c6, rcv=pin_c7)
#BYTE TRISA = 0x85
#BYTE portA = 0x05
// Definimos la velocidad de transmisión de
// 9600 baudios/segundo
// Elegimos RC6 como patilla transmisora de datos.
// Elegimos RC7 como patilla receptora de datos.
// Incluimos el driver LCD1.c que contiene las funciones
// de control del LCD.
// TRISA en 85h.
// PORTA en 05h.
#BIT ra0 = 0x05.0
// RA0 en 0x05 patilla 0.
#include <LCD1.C>
#define Clave 235
#define Numero_Repeticiones 10
// ****************************** Función principal o programa principal ******************************
void main()
{
int1 valor=0;
int1 cambio=0;
int8 i=1;
// Definimos la variable "valor" como tipo bit.
// Definimos la variable "cambio" como tipo bit.
// Definimos la variable "i" como tipo byte.
lcd_init();
// Inicializamos el LCD
TRISA = 0B11111111;
// Ponemos el puerto A como salida de datos.
printf(lcd_putc," Mando Activo\n");
// Mostramos en el LCD el mensaje Mando Activo y
// saltamos a la línea siguiente.
// Mostramos en el LCD el mensaje Puerta Cerrada.
printf(lcd_putc," Puerta Cerrada");
while(1)
{
// bucle infinito.
if(ra0==0)
{
valor = ~valor;
delay_ms(200);
cambio =1;
}
IES Joan Miró
// Preguntamos si se ha pulsado ra0.
// Complementamos la variable "valor".
// Retardamos 200 mS.
// Activamos la variable "cambio".
Página 141
Curso de Robótica y aplicaciones a el Aula de Tecnología
if (cambio==1)
{
for(i=1;i<=Numero_Repeticiones;i++)
// Si la variable "cambio" está activa actuamos.
// Enviamos el dato vía serie, tantas veces
// como diga la variable Número_Repeticiones
{
putc(clave);
putc(valor);
// Enviamos la clave vía serie.
// Enviamos valor vía serie.
}
if(valor==1)
{
lcd_gotoxy(1,2);
// Si la variable "valor" es 1 abrimos la puerta
printf(lcd_putc," Abrir Puerta ");
// Posicionamos el Cursor del LCD en la
// posición 1 línea 2
// Mostramos en el LCD el mensaje
// Abrir Puerta.
}
else
{
lcd_gotoxy(1,2);
printf(lcd_putc," Cerrar Puerta ");
}
cambio=0;
// Posicionamos el Cursor del LCD en la
// posición 1 línea 2
// Mostramos en el LCD el mensaje
// Cerrar Puerta.
// Desactivamos la variable "cambio".
}
}
}.
Receptor_Puerta.c
//******************************* Recepción Serie de Datos de la puerta ******************************
// ************************************* Directivas de Preprocesado*********************************
#include <16F876.h>
#FUSES XT,NOWDT
#use delay(clock=4000000)
#use rs232(baud=9600, xmit=pin_c6, rcv=pin_c7)
#include <LCD1.C>
#BYTE TRISC = 0x87
#BYTE portC = 0x07
IES Joan Miró
// Definimos la velocidad de transmisión de
// 9600 baudios/segundo
// Elegimos RC6 como patilla transmisora de datos.
// Elegimos RC7 como patilla receptora de datos.
// Incluimos el driver LCD1.c que contiene las funciones
// de control del LCD.
// TRISC en 87h.
// PORTC en 07h.
Página 142
Curso de Robótica y aplicaciones a el Aula de Tecnología
#BIT indicador_cierre = 0x07.5
#BIT indicador_apertura = 0x07.4
int8 valor=0;
// Definimos la variable "valor" como entero de
// 8 bit. Variable global.
#define Clave 235
int8 CONST NUMEROS[9]={9,1,3,2,6,4,12,8,9};
// Array de 9 números tipo entero de 8 bit. Representa
// las posiciones del Motor PAP.
/* ******************************** Declaración de funciones ************************************* */
void leer_dato_serie (void);
// Leer Dato.
// *************************** Función principal o programa principal *********************************
void main()
{
signed int8 i=0;
// Definimos la variable "i" como entera con signo.
TRISC = 0B10000000;
lcd_init();
printf(lcd_putc,"Puerta Cerrada");
// Definimos el puerto C como salida de datos a
// excepción de rc7/rx
// Inicializamos el puerto C con Indicador de cierre
// encendido y activado el Motor PAP.
// Inicializamos el LCD
// Ponemos en el LCD el mensaje "Puerta Cerrada"
enable_interrupts(INT_RDA);
enable_interrupts(GLOBAL);
// Habilitamos la interrupción serie de datos.
// Habilitamos la Interrupción General.
while(1)
{
// Bucle sin fin.
portC = 0B00101001;
if (valor==1)
{
if (i<8)
{
// Si la variable "valor" esta activa abrimos puerta.
// Ejecutamos la secuencia de apertura del Motor PAP.
i++;
portc = NUMEROS[i];
lcd_gotoxy(1,1);
printf(lcd_putc,"Abriendo Puerta ");
lcd_gotoxy(1,2);
printf(lcd_putc,"
Espere
");
// Situamos el cursor del LCD en la
// posición 1, línea 1.
// Ponemos en el LCD el mensaje
// "Abriendo Puerta "
// Situamos el cursor del LCD en la
// posición 1, línea 2.
// Ponemos en el LCD el mensaje "
// Espere "
delay_ms(500);
}
IES Joan Miró
Página 143
Curso de Robótica y aplicaciones a el Aula de Tecnología
else
// Cuando la puerta esté abierta
// mostrar mensajes nuevos.
{
lcd_gotoxy(1,1);
printf(lcd_putc," Puerta Abierta ");
lcd_gotoxy(1,2);
printf(lcd_putc," Puede pasar ");
indicador_apertura = 1;
}
indicador_cierre = 0;
// Situamos el cursor del LCD en la
// posición 1, línea 1.
// Ponemos en el LCD el mensaje
// " Puerta Abierta "
// Situamos el cursor del LCD en la
// posición 1, línea 2.
// Ponemos en el LCD el mensaje
// " Puede pasar "
// Activamos el Indicador de Apertura.
// Desactivamos el Indicador de Cierre.
}
else
// Si la variable "valor" está inactiva
// cerramos puerta.
{
if (i>0)
// Ejecutamos la secuencia de cierre
// del Motor PAP.
{
i--;
portc = NUMEROS[i];
delay_ms(500);
lcd_gotoxy(1,1);
printf(lcd_putc," Cerrando Puerta");
lcd_gotoxy(1,2);
printf(lcd_putc,"
Espere
");
}
else
// Situamos el cursor del LCD en la
//posición 1, línea 1.
// Ponemos en el LCD el mensaje
// " Cerrando Puerta".
// Situamos el cursor del LCD en la
// posición 1, línea 2.
// Ponemos en el LCD el mensaje
// " Espere "
// Cuando la puerta esté cerrada
// mostrar mensajes nuevos.
{
lcd_gotoxy(1,1);
printf(lcd_putc," Puerta Cerrada ");
lcd_gotoxy(1,2);
printf(lcd_putc,"
indicador_apertura = 0;
indicador_cierre = 1;
IES Joan Miró
");
// Situamos el cursor del LCD en la
// posición 1, línea 1.
// Ponemos en el LCD el mensaje
// " Puerta Cerrada "
// Situamos el cursor del LCD en la
// posición 1, línea 2.
// Ponemos en el LCD el mensaje
// "
"
// Desactivamos el Indicador de
// Apertura.
// Activamos el Indicador de Cierre.
Página 144
Curso de Robótica y otras aplicaciones en el Aula de Tecnología
}
}
}
}
/* ********************** 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)
{
int8 numero_datos;
int8 dato_recibido;
int8 dato1;
dato_recibido=getc();
switch (numero_datos)
// Es un autómata modelo Moore, que valida los datos si llegan
{
// dos tramas iguales consecutivas
case 0:
if(dato_recibido==clave)
{
numero_datos=1;
}
break;
case 1:
dato1=dato_recibido;
numero_datos=2;
break;
case 2:
if(dato_Recibido==clave)
{
numero_datos=3;
}
IES Joan Miró
Página 145
Curso de Robótica y otras aplicaciones en el Aula de Tecnología
else
{
numero_datos=0;
}
break;
case 3:
if(dato_Recibido==dato1)
numero_datos=0;
valor=dato_Recibido;
}
}
4.7.- Diseño y creación de un Robot Rastreador y Coche Teledirigido.
El proyecto está en la carpeta Documentación.
IES Joan Miró
Página 146
Descargar