Академический Документы
Профессиональный Документы
Культура Документы
Pgina 1
Pgina 2
Pgina 3
Diseo de la
Placa
Fabricacin de la Placa
Creacin del
Prototipo
Desarrollo
del software
Pruebas del
Prototipo
Con las herramientas de diseo tradicionales, el desarrollo del software y la comprobacin 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.
Diseo esquemtico
del prototipo
Desarrollo
del software
Simulacin del
Circuito
Diseo de
la Placa
Fabricacin
de la Placa
Fabricacin del
Prototipo
Usando Proteus VSM, el desarrollo del software puede comenzar tan pronto como el diseo
esquemtico este acabado y la combinacin del hardware y el software nos permite testear el
prototipo y ver si funciona.
Pgina 4
Comandos de
Fichero e
Impresin
Comandos
de Edicin
Comandos de
Visualizacin
Herramientas
de Diseo
Barra de
Mens
Ventana de Edicin
Comandos de rotacin
y reflexin
Ventana de componentes y
Biblioteca
Ventana de
Trabajo
Modos de Trabajo
Herramientas de
Diseo Electrnico
Comandos de dibujo
Barra de estado
Barra de simulacin
Component.
Pick Devices
Pgina 5
Represente el encapsulado
del Componente en ARES
es decir su encapsulado
Ventana de Edicin
Pgina 6
Cada componente electrnico se puede editar, se selecciona con el botn derecho del ratn
(Se pone en rojo) y con el botn izquierdo se abre.
Se puede cambiar su referencia y valor
Pgina 7
Terminal de entrada
Terminal de Alimentacin
Terminal de masa
Terminal de salida
de la caja de Herramientas de
.
Etiquetado de bus
Pgina 8
Inter-sheet-Terminal (Terminales)
Generator (Generador)
Osciloscopio
Voltmetro (CA)
Pgina 9
Ficheros Fuente
Herramienta de Compilacin
Con la opcin 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
Pgina 10
La opcin Build All compila el programa fuente ejecuta el programa que traduce un lenguaje
de programacin a cdigo 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 cdigo binario que se introduce de forma real al uC PIC.
IES Joan Mir
Pgina 11
Una vez cargado del microcontrolador con el programa fuente Dec_Hex_Bin.COF , se puede
proceder a la simulacin del circuito empleando la Barra de Simulacin.
Marcha
Paso a Paso
Pausa
Stop
Pgina 12
Pgina 13
Barra de Simulacin
Herramientas de Ejecucin de
un programa Paso a Paso
Visualizacin de la memoria de
Programa del uC utilizando las
herramientas de ejecucin paso
a paso.
Visualizacin de la memoria
Pila del uC utilizando las
herramientas de ejecucin
paso a paso.
Visualizacin de la memoria
EPROM del uC utilizando las
herramientas de ejecucin
paso a paso.
Pgina 14
Buscar variables
Pgina 15
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 Ejecucin y visualizamos como
varan las variables y el hardware. Es conveniente
poner puntos de ruptura y ejecutar de golpe el programa hasta dicho punto.
Pgina 16
Habilita o deshabilita
los punto de ruptura.
Componente a buscar
Encapsulado(PCB)
Pgina 17
Antes de realizar la placa comprobar si algn componente tiene pines o patillas ocultas. Los
Circuitos Integrados ocultan los pines de masa GND, VSS y alimentacin VCC , VDD.
Editamos el Componente
Pgina 18
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
botn derecho del ratn (Se pone rojo) y pulsamos el botn izquierdo. Se abre un men
contextual y escribimos GND.
E
Buscamos
una masa
GND y seleccionamos
el cable con el botn
derecho del ratn.
Se abre el men
contextual y
escribimos GND.
Pgina 19
Se abre el men
contextual y
escribimos VCC.
El resultado es el siguiente:
Pgina 20
ARES
Si algn componente no tuviera mscara te pedira que la insertaras, aparece un men
contextual:
Dentro de una Biblioteca de
Seleccionamos el Encapsulado
componentes
Despus de asignar las mscaras a los componentes que no las tenan aparece la Aplicacin
ARES
Pgina 21
Comandos de Visualizacin
File/Print Commands
Display Commands
Ventana de Edicin
Barra de Mens
Comandos de Edicin
Herramientas de Diseo
Editing Commands
Layout Tools
Pad Placement
Herramientas de diseo grfico
2D Graphics
Ventana de
Trabajo
Selector de Objetos
Object Selector
Selector de Caras
Layer Selector
Barra de Estado
Test de errores
2D Graphics box
Herramientas de diseo grfico
2D Graphics
Pgina 22
Borde de placa
Selector de Caras
Board Edge
Layer Selector
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
diseo grfico 2D Graphics seleccionamos el circulo 2D Graphics circle
Cuadrado
2D Graphics circle
Herramientas de diseo grfico
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
Pgina 23
Display Commands
Milmetros/Pulgadas
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 resolucin a la hora de dibujar
(Pistas, Cotas, Tamaos de Placa, etc.), tenemos que
cambiarla, para ello vamos a la Barra de Mens y
seleccionamos VIEW y cambiamos dicha resolucin.
Una vez realizado los ajustes adecuados, procedemos a poner las cotas. Para ello,
buscamos en Herramientas de diseo grfico 2D Graphics y seleccionamos Cotas
Dimension object placement
2D Graphics
Cotas
Con el Selector de Caras Layer Selector seleccionamos borde de placa Board Edge
Borde de placa
Board Edge
Selector de Caras
Layer Selector
Pgina 24
Herramientas de Diseo
Layout Tools
Se abre este men contextual marcamos las reglas de diseo y seleccionamos los
componentes que queremos posicionar de forma automtica.
Reglas de Diseo y Peso
Restaurar valores
Pgina 25
Componentes de diseo
de la placa en ISIS
Selector de Objetos
Object Selector
Situamos los componentes en la placa, para ello posicionamos el ratn sobre la placa y
pulsamos el botn izquierdo del ratn y el componente que este marcado en azul en el
Selector de Objetos Object Selector se insertara en la placa.
Netlis
Pgina 26
Comandos de Edicin
Editing Commands
Pistas de Potencia
Tipo de
prioridad
Optimizar las
esquinas
Tamao de
las Pistas
Tcticas de rutado
Tamao de
las Vas
Tipo de Vas
Normales
Ciegas Superiores
Ciegas Inferiores
Ocultas
Tamao de
las Vas
Tipo cuello
Pistas
Horizontales
y Verticales.
Se trazan
por las
Capas
Superiores
Reglas de diseo
Distancia mnima entre PADs .
Distancia mnima entre PAD y Pista .
Distancia mnima entre Pista .
Distancia mnima a Grficos.
Distancia mnima al Borde de la Placa o
Ranuras.
Pgina 27
Pistas de Seal
Pistas
Horizontales
y Verticales.
Se trazan
por las
Capas
Inferiores
Herramientas de Diseo
Layout Tools
Se abre este men contextual marcamos las reglas de diseo y seleccionamos los
componentes que queremos posicionar de forma automtica.
Opciones de Rutado
Permiso de rutado
Permiso de Ordenamiento
Proteccin manual de las pistas
trazadas manualmente
Pgina 28
Herramientas de Posicionamiento
Pgina 29
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 ratn nos situamos en la Ventana de Trabajo y dibujamos la pista de una patilla a otra
siguiendo las uniones entre componentes Netlis.
Pgina 30
Herramientas de Posicionamiento
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 ratn 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
botn izquierdo del ratn segn estas trazando la pista, sale una VA y las pistas pasan a ser
Top Cooper, seguimos trazando la pista y si pulsas otras dos veces con el botn izquierdo del
ratn sale una VA y las pistas pasan a ser Bottom Cooper.
Otra forma ms fcil es poner VA y trazar las pistas con Bottom Top
Cooper .
Selecciona el Tipo de Vias
Via placement and editing
VIA
Tamao de la VIA
Pista Bottom Cooper
Pgina 31
Herramientas de Posicionamiento
Planos de Masa o Alimentacin
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 ratn nos situamos en la Ventana de Trabajo y dibujamos la Zona que queremos de
cobre. Aparece un men contextual donde decimos tamao de la zona de cobre, Zonas de
clareo, etc.
Clareo
La placa queda:
Pgina 32
Pad Placement
Tipo de PAP
Tamao del PAP
S50-25
S90-50
Pgina 33
Manejo de Bibliotecas
Manage Libraries
Se abre un men contextual, donde podemos crearnos nuestra propia Biblioteca, aadir
encapsulados de otra Biblioteca, borrar encapsulados, etc.
Pgina 34
Mximo 4000
Pgina 35
Biblioteca
Robtica_ARES
Confirmacin
de copia
Top Silk
2D Graphics
Selector de Caras
Layer Selector
Pgina 36
PAD Redondo
Pad Placement
Numeramos el PAP
Editing Commands
Hacer el encapsulado
Make Package
Pgina 37
Nombre del
Encapsulado
Categora
Biblioteca donde se
almacena
Seleccionamos el encapsulado con el botn derecho del ratn (se pone en blanco), pinchamos
sobre el icono de deshacer encapsulados. Decompose de los Comandos de edicin
Comandos de Edicin
Editing Commands
Deshacer el Encapsulado
Decompose
Pgina 38
Cuando pulsamos Create Library tenemos que dar un nombre a la biblioteca Robtica_ISIS
y donde queremos crear la biblioteca C:\Archivos de Programa\Labcenter Electronic\Proteus
6 Professional\Library.
Mximo 4000
Pgina 39
Biblioteca
Robtica_ISIS
Confirmacin
de copia
Pgina 40
Comandos de Dibujo
Tipo de Pin
Patillas de Componentes
Device Pin
Herramientas de Diseo
Que los caracteres no estn excesivamente prximos al pin (El pin no conectar con
el hilo si esto ocurre y habra que descomponer el componente y modificarlo).
Que el tipo de de rejilla sea mayor de Snap 50th (Ver View de la Barra de Mens),
para poder insertar el hilo de forma ms cmoda.
Pgina 41
Make device
Aparece un men contextual y escribimos el nombre del componente MOTOR-TRI_ROBOTICA
y un parmetro de referencia M.
Pgina 42
Aadir Encapsulado
Aadir Encapsulado
Pgina 43
Aparece otro men contextual en el que podemos aadir pines y poner este encapsulado
como principal.
Aadir Pines
Usar Bibliotecas de
ARES
Pgina 44
Se abre otro men contextual donde se puede introducir el modelo de componte simulado
Pgina 45
Introduccin del
Documento
Categora
Biblioteca
Pgina 46
Deshacer el smbolo
Decompose
Pgina 47
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)
Memoria
de Datos
(RAM)
CPU
Buses
Arquitectura Hardvard
PROGRAMA
1. BSF STATUS,RP0
2. CLRF TRISB
3. MOVLW 0XFF
1 Ciclo
2 Ciclo
Bsqueda 1
Ejecuta 1
Bsqueda 2
3 Ciclo
4 Ciclo
5 Ciclo
Ejecuta 2
Bsqueda 3
4. MOVWF TRISA
Ejecuta 3
Bsqueda 4
Ejecuta 4
Pgina 48
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 Adquisicin de datos (5
Entradas Analgicas)
2 mdulos de CCP y PWM. (Comparacin
y captura de datos y generadores de seal
por Modulacin de Anchura de Pulsos).
Un mdulo de comunicacin serie SPI
(Serial Peripheral Interface) I2C (Inter-Integrated Circuit).
Un transmisor-receptor asncrono serie universal USART.
3 Timer (Temporizadores/Contadores).
2 Comparadores de seales analgicas.
Pgina 49
Pgina 50
Pgina 51
del Programa
#fuses XT,NOWDT
#use delay( clock = 4000000 )
#include <math.h>
#include <LUCES-COCHE-FANTASTICO.h>
#include <REPR-NUMEROS-DISPL.h>
// TRISC en 87h.
// PORTC en 07h.
// TRISB en 86h.
// PORTB en 06h.
// TRISA en 85h.
// PORTA en 05h.
Directivas de Preprocesado
Declaracin de Funciones
{
int8 muestra1;
TRISB = 0B00000000;
TRISC= 0B11111111;
TRISD = 0B00000000;
portB = 0B00000000;
portD = 0B00000000;
// Reseteamos el Puerto B.
// Reseteamos el Puerto D.
while (1)
Programa Principal
{
muestra1 = portC;
VariasCosas(muestra1);
// Leemos el Puerto C.
// Ejecuta la funcin VariasCosas definida por la variable muestra1.
}
}
Pgina 52
{
case 0:
LucesFantastico();
break;
case 1:
NumerosDisplay();
break;
Funcin VariasCosas
default:
{
portB = Raiz(muestra2);
delay_ms(50);
}
}
}
//******************************* Funcin Raz ***************************************************************
int8 Raiz (int8 muestra3)
{
int8 resultado;
resultado = SQRT (muestra3);
return(resultado);
Funcin Raz
3.1.3.- Constantes.
Son nmeros, caracteres, etc
Las constantes se pueden especificar en decimal, octal, hexadecimal o en binario, etc
123
Decimal
0123
Octal
0b01011011
Binario
Caracter
Pgina 53
Tamao
Rango
Descripcin
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 dgitos)
Coma flotante
Char
8 bit
0 a 255
Carcter
Signed Int8
8 bit
-128 a 127
Signed Int16
16 bit
-32.768 a 32.767
Signed Int32
32 bit
-231 a +(231-1)
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 funcin o globales que
son validas para todo el programa.
Pgina 54
Ejemplo
a=c
c+=4
c=4
c*=4
c/=4
c%=4
c <<= 4
>>=
c >>= 4
&=
c&=4
|=
c|=4
^=
c^=4
Significado
Asignacin simple. El contenido de c se introduce en a
Incrementa c en 4 unidades.
Decrementa c en 4 unidades.
Modifica c multiplicndolo 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 operacin AND entre los bits de c y los del valor 4.
El resultado se almacena en c.
Se hace la operacin OR entre los bits de c y los del valor 4.
El resultado se almacena en c.
Se hace la operacin XOR entre los bits de c y los del valor 4.
El resultado se almacena en c.
b) Aritmticos.
Sirven para operar con datos numricos.
Operador
+
*
/
%
-++
sizeof
Significado
Suma
Resta
Multiplicacin
Divisin
Mdulo, resto de una divisin entera
Incremento
Decremento
Determina el tamao en byte, de un operando
c) Relacionales.
Sirven para comparar nmeros o caracteres.
Operador
<
>
>=
<=
==
!=
?:
Significado
Menor que
Mayor que
Mayor o igual que
Menor o igual que
Igual
Distinto
Expresin condicional
d) Lgicos.
Permiten crear expresiones lgicas, es decir, basadas en el lgebra de Boole.
Una expresin lgica es aquella que da como resultado cierto o falso.
Pgina 55
Significado
Negacin (No)
Conjuncin (Y)
Disyuncin (O)
e) De Bits.
Realiza operaciones lgicas a nivel de bits independientes, son vlidos con datos de los tipos
char, int, long.
Operador
~
&
^
|
>>
<<
Significado
Negacin de bits (No)
Conjuncin de bits (Y)
Disyuncin de bits (O)
O exclusiva (XOR)
Desplazamiento de bits a la izquierda
Desplazamiento de bits a la derecha
f) Punteros.
Permiten conocer la direccin de memoria en la que est almacenada una variable o una
funcin. Tambin sirven para conocer el valor del dato almacenado en una direccin dada.
Operador
&
*
->
Significado
Direccin
Indireccin
Puntero a estructura
3.1.6.- Funciones.
Pgina 56
#fuses XT,NOWDT
#use delay( clock = 4000000 )
#include <math.h>
#include <LUCES-COCHE-FANTASTICO.h>
#include <REPR-NUMEROS-DISPL.h>
// TRISC en 87h.
// PORTC en 07h.
// TRISB en 86h.
// PORTB en 06h.
// TRISA en 88h.
// PORTA en 08h.
Declaracin de Funciones
Funcin Principal
{
int8 muestra1;
TRISB = 0B00000000;
TRISC = 0B11111111;
TRISD = 0B00000000;
portB = 0B00000000;
portD = 0B00000000;
// Reseteamos el Puerto B.
// Reseteamos el Puerto D.
while (1)
{
muestra1 = portC;
VariasCosas(muestra1);
// Leemos el Puerto C.
// Ejecuta la funcin VariasCosas definida por la variable muestra1.
}
}
Pgina 57
{
case 0:
LucesFantastico();
break;
default:
{
portB = Raiz(muestra2);
delay_ms(50);
{
int8 resultado;
resultado = SQRT (muestra3);
return(resultado);
}
Pgina 58
Instruccin 1
Instruccin 2
Instruccin 3
Instruccin 4
Instruccin 1
Instruccin 1
no
Condicin
Instruccin 3
si
Opcin 1
Instruccin 2
Opcin 2
si
Condicin
no
Estructura Secuencial
Estructura de seleccin
Instruccin 4
Estructura de repeticin
Pgina 59
3.2.1.- If-Else.
La sentencia if-else nos ayuda a tomar decisiones.
Se define de la siguiente manera:
if (expresin)
{
si
Instruccin_1;
no
Condicin
Instruccin_n;
}
Instruccin_1
Instruccin _a
Instruccin _n;
Instruccin _z;
else
{
Instruccin_a;
Incinstruc_z;
}
Pgina 60
Programa_1:
Leer la Patilla RC0 = 1 (RB0=0 y RB1=1),
Diagrama de Flujo:
// Configuracin
TRISB 0B00000000
TRISC 0B11111111
// Reseteamos el Puerto B.
portB 0B00000000
si
no
rc0=1?
rb0 0 // Apagar D9
rb1 1 // Encender D10
rb0 1 // Encender D9
rb1 0 // Apagar D10
Pgina 61
*/
// TRISC en 87h.
// PORTC en 07h.
#fuses XT,NOWDT
#use delay( clock = 4000000 )
portB = 0B00000000;
// Reseteamos el Puerto B.
while (1)
{
if (rc0 == 1 )
// Preguntamos si RC0=1
// Si RC0=1 ejecuta lo que viene a continuacin.
{
rb0 = 0;
rb1 = 1;
}
else
{
// Apagar D9
// Encender D10
// Si RC0=0 ejecuta lo que viene a continuacin.
rb0 = 1;
rb1 = 0;
// Encender D9
// Apagar D10
}
}
}
Pgina 62
switch (expresin)
{
case constante1
Instruccin_1;
Expresin=
constante1?
si
Instruccin_1
Instruccin _n
no
si
break?
Instruccin_n;
break;
no
Instruccin_1
case constante2
Instruccin_1;
Instruccin_n;
Expresin=
Constante2?
si
Instruccin _n
si
no
break?
break;
no
case constanteN
Instruccin_1
Instruccin_1;
Instruccin_n;
break;
Expresin=
ConstanteN?
no
default:
si
Instruccin _n
no
si
break?
Instruccin_1;
Instruccin_n;
}
Instruccin_1
Instruccin _n;
Programa_2:
Leer el Puerto C
Pgina 63
Diagrama de Flujo:
Ejemplo de Switch-Case
// Configuracin
TRISB 0B00000000
TRISC 0B11111111;
// 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
portB0B00000000
Pgina 64
#fuses XT,NOWDT
while (1)
{
Pgina 65
3.2.3.- For.
Se usa para repetir sentencias.
En las expresiones del FOR la inicializacin es una variable a la cual se le asigna un valor inicial.
La condicin de finalizacin sirve para evaluar la variable de control antes de ejecutar la
sentencia. Si es cierta se ejecuta las sentencias que estn entre corchetes.
La expresin de Incremento decremento modifica la variable de control despus de ejecutar
el bucle.
Se define de la siguiente manera:
for (inicializacin; condicin de finalizacin; incremento)
{
Instruccin_1;
Instruccin_n;
}
// Inicializacin de la variable
n1
// Condicin de finalizacin
no
n<=10?
si
Instruccin_1
Instruccin _n;
nn+1
Pgina 66
Nmero
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 Dgito en
Hexadecimal
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
Nmero
Hexadecimal
3F
06
5B
4F
66
6D
7D
07
7F
6F
1 Dgito en
Hexadecimal
2 Dgito en
Hexadecimal
2 Dgito en
Hexadecimal
Pgina 67
Programa_3.c For
Mostrar nmeros 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
// Configuracin
TRISD 0B00000000
// Reseteamos el Puerto D.
portD 0B00000000;
// Inicializacin de la variable
n0
// Condicin de finalizacin
no
n<=Numero_Maximo?
si
portD DISPLAY[n]
Retardo_1Seg
nn+1
Pgina 68
#define Numero_Maximo 9
// TRISD en 88h.
// PORTD en 08h.
int8 n= 0;
#fuses XT,NOWDT
while (1)
{
for (n=0; n<=Numero_Maximo; n++)
{
portD = DISPLAY[n];
delay_ms(1000);
}
}
}
Pgina 69
no
Cumple la
expresin?
while (expresin)
{
Instruccin_1;
si
Instruccin_1
Instruccin_n;
}
Instruccin _n;
Programa_4:
Encender la Lmpara y activar el motor mientras el Puerto C sea igual a cero, si es
distinto de cero apagar la lmpara y parar el motor.
Diagrama de Flujo:
Programa_4.c while
Activar Motor y Lmpara
// Configuracin
TRISE 0B00000000
TRISA 0B00000000
TRISC 0B11111111
portE 0B00000000
portA 0B00000000
// Reseteamos el Puerto E.
// Reseteamos el Puerto A.
no
portC= 0?
lmpara 0
motor 0
// Apagar Lmpara.
// Parar Motor.
si
lmpara 1
motor 1
// Encender Lmpara.
// Activar Motor.
Pgina 70
// TRISE en 89h.
// PORTE en 09h.
// TRISC en 87h.
// PORTC en 07h.
// TRISA en 85h.
// PORTA en 05h.
#fuses XT,NOWDT
portE = 0B00000000;
portA = 0B00000000;
// Reseteamos el Puerto E.
// Reseteamos el Puerto A.
while (true)
{
while (portC==0)
{
lampara = 1;
motor = 1;
// Encender Lmpara.
// Activar Motor.
}
lampara = 0;
motor = 0;
// Apagar Lmpara.
// Parar Motor.
Pgina 71
Instruccin_1
Instruccin _n;
si
Cumple la
expresin?
Instruccin_n;
}
while (expresin);
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
// Configuracin
TRISB 0B00000000
TRISD 0B00000000
TRISC 0B11111111
// Apagar LED
Retardo _1Seg
rc0= 1?
portB 0B00000000;
portD 0B00000000
// Reseteamos el Puerto B.
// Reseteamos el Puerto D.
si
no
portD 0B11111111
// Encender DISPLAY
Retardo _1Seg
portD 0B00000000
// Apagar DISPLAY
Retardo _1Seg
no
si
rc7= 1?
Pgina 72
#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.
}
while (rc0 == 1);
Do
{
}
while (rc7 == 1);
}
}
Pgina 73
Pgina 74
Pgina 75
Pgina 76
Directivas de Preprocesado
Pgina 77
// Leemos el Puerto C.
// Ejecuta la funcin VariasCosas definida por la variable muestra1.
}
}
Programa Principal
default:
{
portB = Raiz(muestra2);
delay_ms(50);
}
}
}
Programa_6.c:
// El Puerto C puede tomar valores comprendidos entre 0 y 255
// Si Puerto C si es 0 realizar la funcin de mostrar por el Display de 7 segmentos los nmeros
// del 0 al 9 con una cadencia de 1 segundo. Despus de este proceso apagar el Display.
// Si Puerto C si es 1 realizar la funcin de simulacin de las luces del coche fantstico.
// despus de este proceso apagar los Led.
// Si Puerto C si es distinto de 0 y 1 realizar una funcin de la raz cuadrada del dato ledo
// y devolverlo en una variable llamada resultado y mostrarlo en el Puerto B
// ******************************** Directivas de Preprocesado*************************************
// (Controlan la conversin del programa a cdigo maquina por parte del compilador)
#include <16F877A.h>
#fuses XT,NOWDT
#use delay( clock = 4000000 )
#include <math.h>
#include <LUCES-COCHE-FANTASTICO.h>
#include <REPR-NUMEROS-DISPL.h>
#BYTE TRISC = 0x87
#BYTE portC = 0x07
Pgina 78
// TRISB en 86h.
// PORTB en 06h.
// TRISD en 88h.
// PORTD en 08h.
muestra1 = portC;
VariasCosas(muestra1);
// Leemos el Puerto C
// Ejecuta la funcin VariasCosas definida por la variable
// muestra1.
}
}
//*************************** Funcin 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 funcin LucesFantastico
break;
case 1:
NumerosDisplay();
break;
default:
{
portB = Raiz(muestra2);
delay_ms(50);
}
}
}
Pgina 79
#include <math.h>
#include <LUCES-COCHE-FANTASTICO.h>
#include <REPR-NUMEROS-DISPL.h>
#BYTE TRISC = 0x87
#BYTE portC = 0x07
// PORTB en 06h.
{
portB = luces;
delay_ms(200);
Pgina 80
}
luces = 0B10000000;
for (i=0;i<7;i++)
{
luces = luces >> 1;
portB = luces;
delay_ms(200);
}
portB = 0B00000000;
// Reseteamos el Puerto B.
LUCES-COCHE-FANTASTICO.H
// Mostrar por el Display de 7 segmentos los nmeros del 0 al 9 con una cadencia de 1 segundo.
// Despus de este proceso apagar el Display.
// *************************** Directivas de Preprocesado ******************************************
#BYTE portD = 0x08
// PORTD en 08h.
// Tabla de 10 datos.
for (i=0;i<10;i++)
{
portD = DISPLAY[i];
delay_ms(500);
}
portD = 0B00000000;
// Reseteamos el Puerto D.
Pgina 81
Pgina 82
5V
E2
24V
IL
5V/115 Ohm
RELE
ID1
D3
1N4007_JOAN
D2
RL
ID2
50
IR
220
D1
R4
IC
R1
220
IB
U1:A
1
R3
Vlvula 5/2
activada electricamente
y retorno com muelle
Q2
BC547BP_JOAN
10k
74LS04
SW1
1
Control
Potencia
Caracterstica de la
Electrovlvula:
(24V/450mA)
Pgina 83
Si dejamos pasar intensidad por el diodo emisor, este emite una luz infrarroja que saturara el
Fototransistor (Se comporta como un Interruptor cerrado)
Pgina 84
Pgina 85
Pgina 86
Vlvula 5/2
activada electricamente
y retorno com muelle
Potencia
Caracterstica de la
Electrovlvula:
(220V/50Hz /450mA)
E1
5V
2
L1
VL
220V
RL
+88.8
500
AC Volts
ID1
ID
R2
I2
IL1
IL2
220
D1
U2
R1
220
360
ID
2
U1:A
I3
R5
IC=0
IR
Zero
Crossing
IG
4
R4
U3
I1
TRIAC
74126
IT
2
100
MOC3031M
SW1
VT
R6
AC Volts
330
I4
+88.8
C1
ALT1
ALTERNADOR_JOAN
312.5V
50Hz
10nF
Pgina 87
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
1
2
3
VSS
VDD
VEE
LCD-16 X 2_JOAN
SEAL
DEFINICIN
PINES
FUNCIN
D7..D0
Data Bus
14..7
Bus de datos
Enable
R/W
Read/Write
RS
Register Select
VEE VLC
VDD
VSS
Ground
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
Tensin para ajustar el
contraste
Tensin de Alimentacin
+5V
Masa.
Pgina 88
nmero
1-9
01-09
1.1-9.9
t ipo
Carcter.
Cadena o Carcter.
Entero sin signo.
Entero con signo.
Entero Largo sin signo.
Entero Largo con signo.
Entero Hexadecimal (minsculas).
Entero Hexadecimal (maysculas).
Entero largo Hexadecimal (minsculas).
Entero largo Hexadecimal(maysculas).
Flotante con truncado.
Flotante con redondeo.
Flotante en formato exponencial.
Entero sin signo con decimales insertados. La 1 cifra indica el
total de nmeros, la 2 cifra indica el nmero de decimales.
Pgina 89
Se limpia el LCD.
El cursor va a la posicin (1,2)
El cursor retrocede una posicin.
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;
Trabaja con el
Puerto D por defecto
Pgina 90
struct lcd_pin_map {
BOOLEAN enable;
BOOLEAN rs;
BOOLEAN rw;
BOOLEAN unused;
int data : 4;
} lcd;
Para entender mejor el manejo del LCD hemos realizado un entrenador con ISIS. Simularemos
diferentes ejemplos.
4.2.1.- LCD_ejemplo1.c
Pgina 91
4.2.2.- LCD_ejemplo2.c
/* ****************** Mostrar nmeros 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
// *********************** Funcin principal o programa principal ***************************
void main()
{
int8 p = 254;
lcd_init();
// Inicializamos el LCD.
lcd_gotoxy(1,1);
printf(lcd_putc,"%3u",p);
lcd_gotoxy(8,1);
printf(lcd_putc,"%03d",p);
lcd_gotoxy(1,2);
printf(lcd_putc,"%4X",p);
lcd_gotoxy(8,2);
printf(lcd_putc,"%3.2w",p);
while (1);
}
Pgina 92
/* ******* Mostrar mensajes y array de nmeros 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.
// Inicializamos el LCD.
lcd_gotoxy(5,1);
printf(lcd_putc, "Decimal");
lcd_gotoxy(5,2);
printf(lcd_putc, "Hexadecimal");
{
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);
}
while (1);
// Fin.
Pgina 93
/* ************ Mostrar mensajes y array de nmeros 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.
// Inicializamos el LCD.
lcd_gotoxy(9,1);
printf(lcd_putc, "int16");
// 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);
}
while (1);
// Fin.
Pgina 94
/* ******** Mostrar mensajes y array de nmeros 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>
// Inicializamos el LCD.
lcd_gotoxy(9,2);
printf(lcd_putc, "S_int32");
// 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);
}
while (1);
// Fin.
Pgina 95
// Inicializamos el LCD.
lcd_gotoxy(3,1);
printf(lcd_putc, "(Caracteres)");
lcd_gotoxy(8,2);
{
printf(lcd_putc,"%1c\b",CARACTER[i]);
delay_ms(1000);
}
while (1);
// Fin.
Pgina 96
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.
// TRISB en 86h.
// PORTB en 06h.
Pgina 97
lcd_init();
// Inicializamos el LCD.
lcd_gotoxy(5,1);
printf(lcd_putc, "Decimal");
lcd_gotoxy(18,1);
printf(lcd_putc, "Hex");
lcd_gotoxy(12,2);
printf(lcd_putc, "Binario");
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);
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.
}
}
Pgina 98
Rango de Entrada.
Simboliza que tensiones puede digitalizar (En los PIC de 0 .. 5V)
Resolucin. (Indica que tensin mnima necesito para aumentar un cdigo digital)
Resolucin = q = 1LSB =
V REF + V REF
1024
5V0V
1024
= 4,8 mV.
Pgina 99
Si trabajamos con tensiones comprendidas entre Vref+ = 5V y Vref- =0V y con 10bits de
salida obtenemos una resolucin de 4,8 mV.
Error de conversin.( Indica para que rango mnimo de tensiones se asigna un valor
digital)
En un uCPIC el Conversor A/D, trabaja con error por redondeo.
Error =
1
2
LSB
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
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
Ve = 512
1022
1023
+ +
1024
0
0
1
1
0
D
N Decimal
5+0
1024
VREF+ = 0V )
= 2,5V
Pgina 100
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+
4.3.1.- Conversin_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/ANALGICO
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
OSCILOSCOPIO
B
Pgina 101
// TRISC en 87h.
// PORTC en 07h.
setup_adc_ports(0);
setup_adc(ADC_CLOCK_INTERNAL);
set_adc_channel(0);
while(1)
{
// Bucle infinito.
delay_us(5);
q = read_adc();
portC = q;
}
}
Se observa que a medida que aumentamos la frecuencia de la seal a digitalizar las muestras
son cada vez, ms visibles.
Segn el criterio de Nyquist-Shannon la frecuencia de muestreo tiene que ser como mnimo 2
veces la frecuencia mxima de la seal.
= 2 = 500 Seg
Pgina 102
V entrada
Vmax = 4V
Frecuencia =60Hz
Seal Sinusoidal
Unipolar
V entrada
V salida
V entrada
Vmax = 4V
Frecuencia =1200Hz
Seal Sinusoidal
Unipolar
V entrada
V salida
Pgina 103
4.3.2.- Conversin_A-D1.c
Pgina 104
// Conversor Analgico 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.
// Inicializamos el LCD.
// Seleccionamos el Puerto A como entradas Analgicas. Mirar
// ADCON1.
// Fuente de reloj RC interno.
set_adc_channel(0);
for (;;)
// Bucle infinito.
{
delay_us(5);
q = read_adc();
p = 5.0 * q / 1024.0;
lcd_gotoxy(1,1);
// Posicionamos el Cursor en la posicin 1, lnea 1.
printf(lcd_putc, "\ADC = %4lu", q);
// Escribimos en el LCD "ADC =" y 4 dgitos de
// "q" en formato largo sin signo.
printf(lcd_putc, "\nVOLTAJE = %01.3fV", p);
// Saltamos de lnea y escribimos en el LCD
// "VOLTAJE =" y 4 dgitos de "P"
// en formato truncado de 4 dgitos con
// 3 decimales y el carcter "V".
}
}
Pgina 105
#FUSES XT,NOWDT
#use delay(clock=4000000)
#include <LCD1.c>
// Incluimos el driver LCD1.c que contiene las funciones de control del LCD.
// Bucle infinito.
// Habilitacin canal 0 "AN0"
// Retardo de 20uS necesaria para respetar el Tiempo
// de Adquisicin Tad.
// Lectura canal 0 "AN0"
// Conversin a tensin del cdigo digital "q".
lcd_gotoxy(1,1);
printf(lcd_putc, "V1=%01.3fv", p);
set_adc_channel(1);
delay_us(5);
q = read_adc();
p = 5.0 * q / 1024.0;
lcd_gotoxy(12,1);
printf(lcd_putc, "V2=%01.3fv", p);
Pgina 106
q = read_adc();
p = 5.0 * q / 1024.0;
lcd_gotoxy(1,2);
printf(lcd_putc, "V3=%01.3fv", p);
set_adc_channel(3);
delay_us(5);
q = read_adc();
p = 5.0 * q / 1024.0;
lcd_gotoxy(12,2);
printf(lcd_putc, "V4=%01.3fv", p);
}
}
4.3.4.- Conversin_A-D3.c
//************* Leer la patilla RA0 si la tensin es superior a 2,5 V activar motor ************************
//*************************** Directivas de Preprocesado******************************************
#include <16F876A.h>
#device adc=10
#FUSES XT,NOWDT
#use delay(clock=4000000)
#include <LCD1.c>
// TRISC en 87h.
// PORTC en 07h.
Pgina 107
setup_adc_ports(0);
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;
lcd_gotoxy(1,1);
printf(lcd_putc, "VOLTAGE = %01.3fV", p);
lcd_gotoxy(1,2);
if(p>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
{
}
}
Pgina 108
V motor
Vmedia= 0% x 5v = 0v
TH
0%
(Motor Parado)
16
32
CT =
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
V motor
5v
TH
T
x 100 =
3,2 mS
16 mS
= 20 %
(mSeg)
TH
50%
16
32
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
CT =
TH
T
x 100 =
12,8 mS
16 mS
= 80 %
(mSeg)
Vmedia= 100% x 5v = 5v
V motor
5v
100%
CT =
TH
T
(Velocidad Mxima)
16
32
TH
T
x 100 =
16 mS
16 mS
(mSeg)
Pgina 109
= 100 %
4.4.1.- PWM1.c
#FUSES XT,NOWDT
#use delay(clock=1000000)
// ***************************** Funcin 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
// Analgicas. Mirar ADCON1.
Pgina 110
// setup_timer(Prescaler,PR2,Postscaler)
// Configuracin 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);
while (true)
// Bucle infinito.
{
delay_us(20);
TH = read_adc();
set_pwm2_duty(TH);
delay_ms(5);
}
}
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 electrnicos idnticos.
Su tabla de la verdad sera:
Entradas
ENA IN1 IN2
0
x
x
1
0
0
1
0
1
1
1
0
1
1
1
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
Pgina 111
Pgina 112
#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;
// *********************** Funcin 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);
Pgina 113
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);
}
}
Pgina 114
Ejemplo:
PORT B 1
TH PORTB
TH TH x 4
set_pwm2_duty(TH);
// TH vale 4
// Se genera una seal PWM cuyo tiempo a nivel alto
// TH es proporcional al cdigo introducido.
PORT B 128
TH PORTB
TH TH x 4
set_pwm2_duty(TH);
// TH vale 512
// Se genera una seal PWM cuyo tiempo a nivel alto
// TH es proporcional al cdigo introducido.
PORT B 255
TH PORTB
TH TH x 4
// TH vale 1020
// Se genera una seal PWM cuyo tiempo a nivel alto
// TH es proporcional al cdigo introducido.
set_pwm2_duty(TH);
Ejemplo:
Pgina 115
// TRISB en 86h.
// PORTB en 06h.
setup_timer_2(T2_DIV_BY_16,249,1);
// setup_timer(Prescaler,PR2,Postscaler)
// Configuracin 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);
delay_ms(5);
}
}
Pgina 116
Pgina 117
4.5.1.- Control_2_Servos_Posicin.c
Pgina 118
*/
Pgina 119
setup_ccp2(CCP_PWM);
TH = THmed;
set_pwm2_duty(TH);
delay_ms(5);
// setup_timer(Prescaler,PR2,Postscaler)
// Configuracin 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 seal.
}
// ******************************** Funcin 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)
// Configuracin 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 seal.
Pgina 120
if(TH<=THmin)
// Si TH THmin
{
TH=THmin+1;
// Cargar TH con valor mnimo
set_pwm2_duty(TH);
// Refrescamos el Tiempo alto TH de la seal.
}
if(TH>=THmax)
// Si TH THmax
{
TH=THmax-1;
// Cargar TH con valor mximo
set_pwm2_duty(TH);
// Refrescamos el Tiempo alto TH de la seal.
}
delay_ms(5);
// Tiene que transcurrir un tiempo mayor que el periodo de la seal T =16000 us,
// para refrescar el nivel alto de la seal.
// Si utilizamos la funcin delay_ms(5)el tiempos de retardo equivale al
// valor puesto multiplicado por 4 (Estamos utilizando un cristal de 1 MHz).
// es decir 20ms.
}
// ********************************** Funcin 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);
// Tiene que transcurrir un tiempo mayor que el periodo de la seal T =16000 us,
// para refrescar el nivel alto de la seal.
// Si utilizamos la funcin delay_ms(5)el tiempos de retardo equivale al
// valor puesto multiplicado por 4 (Estamos utilizando un cristal de 1 MHz).
// es decir 20ms.
Pgina 121
#FUSES XT,NOWDT
#use delay(clock=4000000)
#include <Servo_Futaba_10bit.c>
// While (1);
setup_adc(ADC_CLOCK_INTERNAL);
setup_adc_ports(0);
while (true)
// Bucle infinito.
{
set_adc_channel(0);
delay_us(5);
TH = read_adc();
Futaba_RC1(TH);
set_adc_channel(1);
delay_us(5);
TH = read_adc();
Futaba_RC2(TH);
}
}
Pgina 122
4.6.1.- Introduccin.
Antes de introducirnos en la Transmisin y Recepcin Serie de datos va
radiofrecuencia, explicaremos de forma breve el tipo de transmisin utilizada, como se modula
la seal para poderla transmitir va radio frecuencia y que protocolo se ha seguido para poder
dar seguridad a una transmisin.
4.6.1.1.- Transmisin serie asncrona.
Es transmitir 8 bit de uno en uno siguiendo un protocolo de comunicaciones. Primero
se transmite un bit de START despus 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.
El nmero de bits de datos, bit de Stop es uno de los parmetros configurables, as como
el criterio de paridad par o impar para la deteccin de errores. Normalmente, las
comunicaciones serie tienen los siguientes parmetros: 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 transmisin del dato binario 01011010B. La
lnea en reposo est a nivel alto: (Se transmite primero el bit LSB)
Pgina 123
1bit de START + 8bit de DATOS + 1bit de STOP (Llave que identifica un proceso, se ha
activado un pulsador o se ha variado el Potencimetro del Mando.)
1bit de START + 8bit de DATOS + 1bit de STOP (Informacin del proceso, que pulsador
se ha activado o la tensin digitalizada del Potencimetro del Mando.)
Esta rfaga (Seal que sale de la patilla RC6/TX del microcontrolador PIC16F876A) se
transmite va serie 10 veces a una velocidad de 2400 bit/segundo. El modulador CEBEK C-0503
genera una seal de AM con esta seal moduladora.
El receptor serie CEBEK C-0504 demodula la seal, es decir filtra la portadora de 433,92
MHz obteniendo la seal moduladora (Rfaga de datos)
El microcontrolador del Receptor trabaja en modo interrupcin 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 interrupcin para este proceso.
La rutina de interrupcin realiza el proceso de validar los datos que le llegan. Se validan
los datos si llegan dos rfagas de 20bits consecutivas y tienen la mismas llaves que identifican
el proceso e informacin del proceso.
Pgina 124
Pgina 125
Transmisin_Serie_1a.c
//************************ Mando de Transmisin serie va radiofrecuencia *****************************
// ********************************* Directivas de Preprocesado*************************************
#include <16F876A.h>
#FUSES XT,NOWDT
#use delay(clock=4000000)
#use rs232(baud=2400, xmit=pin_c6, rcv=pin_c7)
Pgina 126
// TRISB en 86h.
// PORTB en 06h.
// 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
// ******************************* Funcin principal o programa principal *****************************
void main()
{
int8 i=1;
int8 q;
TRISB = 0B11111111;
cambio2=0;
TC3 = 0;
rc3 = 1;
while(1)
{
// bucle infinito.
q= portB & 0B00011111;
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;
rc3 = 0;
Pgina 127
{
putc(Clave_Pulsadores);
putc(cambio2);
}
rc3 = 1;
delay_ms(200);
}
}
}
Recepcin_Serie_1a.c
//********************************* Recepcin Serie de Datos Simple ********************************
// ************************************ Directivas de Preprocesado**********************************
#include <16F876A.h>
#FUSES XT,NOWDT
#use delay(clock=4000000)
// Leer Dato.
enable_interrupts(GLOBAL);
Pgina 128
}
}
/* ******************** Atencin a la interrupcin por recepcin 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 funcin "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 funcin "getc()" y se guarda.
Se lee el 3 dato serie recibido con la funcin "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 funcin "getc()" y se compara con
el 2 dato ledo, 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();
switch (Numero_datos1)
{
case 0:
if(Dato_Recibido==Clave_Pulsadores)
{
Numero_datos1=1;
}
break;
case 1:
dato1=Dato_Recibido;
Numero_datos1=2;
break;
Pgina 129
portB=Dato_Recibido;
// El dato vlido se deposita en el Puerto B
Numero_datos1=0;
}
}
Pgina 130
Pgina 131
// 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
Pgina 132
TRISB = 0B11111111;
TC3 = 0;
RC3 = 1;
setup_adc(ADC_CLOCK_INTERNAL);
setup_adc_ports(0);
while(1)
{
set_adc_channel(0);
delay_us(20);
q = read_adc();
if (cambio0!=q)
// Si se ha variado el Potencimetro Derecho transmitir dato.
{
cambio0=q;
RC3 = 0;
// Habilitamos la tarjeta CEBEK C-0503.
for(i=1;i<=Numero_Repeticiones;i++)
// Enviamos el dato va serie, tantas veces
// como diga la variable Nmero_Repeticiones
{
putc(Clave_Pot_Der);
// Enviamos va serie la Clave_Pot_Der.
putc(q);
// Enviamos va serie la variable q.(Tensin
//digitalizada del Potencimetro Derecho)
}
RC3 = 1;
// Inhabilitamos la tarjeta CEBEK C-0503.
}
set_adc_channel(1);
delay_us(20);
q = read_adc();
if (cambio1!=q)
// Si se ha variado el Potencimetro Izquierdo transmitir dato.
{
cambio1=q;
RC3 = 0;
// Habilitamos la tarjeta CEBEK C-0503.
for(i=1;i<=Numero_Repeticiones;i++)
// Enviamos el dato va serie, tantas veces
// como diga la variable Nmero_Repeticiones
{
putc(Clave_Pot_Izq);
// Enviamos va serie la Clave_Pot_Der.
putc(q);
// Enviamos va serie la variable q.(Tensin
// digitalizada del Potencimetro Izquierdo)
Pgina 133
}
q= portB & 0B00011111;
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;
RC3 = 0;
for(i=1;i<=Numero_Repeticiones;i++)
{
putc(Clave_Pulsadores);
putc(cambio2);
}
RC3 = 1;
}
if (rb5!=rb5_1)
{
rb5_1=rb5;
c5=~rb5;
RC3 = 0;
for(i=1;i<=Numero_Repeticiones;i++)
{
putc(Clave_Pulsadores);
putc(cambio2);
}
RC3 = 1;
}
}
}
Pgina 134
Recepcin_Serie_2a.c
//***************************** Recepcin 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 transmisin 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
// Reseteamos el Puerto D.
// Reseteamos el Puerto C.
// Reseteamos el Puerto B.
// Habilitamos la interrupcin serie de datos.
// Habilitamos la Interrupcin General.
Pgina 135
}
}
/* ********************** Atencin a la interrupcin por recepcin 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 funcin "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 funcin "getc()" y se guarda.
Se lee el 3 dato serie recibido con la funcin "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 funcin "getc()" y se compara con
el 2 dato leido, si son iguales se valida el dato con la variable global "Valor".
*/
if (valido_Aut_Pot_Der==1) Automata_Pot_Der();
if (valido_Aut_Pot_Izq==1) Automata_Pot_Izq();
Pgina 136
{
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;
}
}
Pgina 137
{
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;
}
}
Pgina 138
{
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;
}
}
Pgina 139
Pgina 140
#include <LCD1.C>
lcd_init();
// Inicializamos el LCD
TRISA = 0B11111111;
// bucle infinito.
if(ra0==0)
{
valor = ~valor;
delay_ms(200);
cambio =1;
}
Pgina 141
{
putc(clave);
putc(valor);
}
if(valor==1)
{
lcd_gotoxy(1,2);
}
else
{
lcd_gotoxy(1,2);
printf(lcd_putc," Cerrar Puerta ");
}
cambio=0;
}
}
}.
Receptor_Puerta.c
//******************************* Recepcin 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
Pgina 142
// Leer Dato.
lcd_init();
printf(lcd_putc,"Puerta Cerrada");
enable_interrupts(INT_RDA);
enable_interrupts(GLOBAL);
while(1)
{
portC = 0B00101001;
if (valor==1)
{
if (i<8)
{
lcd_gotoxy(1,2);
printf(lcd_putc,"
Espere
");
delay_ms(500);
}
Pgina 143
{
lcd_gotoxy(1,1);
printf(lcd_putc," Puerta Abierta ");
lcd_gotoxy(1,2);
printf(lcd_putc," Puede pasar ");
indicador_apertura = 1;
}
indicador_cierre = 0;
}
else
{
if (i>0)
{
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
{
lcd_gotoxy(1,1);
printf(lcd_putc," Puerta Cerrada ");
lcd_gotoxy(1,2);
printf(lcd_putc,"
indicador_apertura = 0;
indicador_cierre = 1;
");
Pgina 144
Pgina 145
valor=dato_Recibido;
}
}
Pgina 146