Professional Documents
Culture Documents
Microcontroladores
Pgina 1
Pgina
Microcontroladores
Pgina 2
Microcontroladores
Pgina 3
Microcontroladores
Pgina 4
Aprendizaje de la Electrnica a travs de la Robtica - ARCE 5.3.8.1.2.- Conversor A-D_D-A_PCF8591. .............................................................................................................................................. 141
5.3.8.1.2.1.- PCF8591_ADC. .............................................................................................................................................................. 141
5.3.8.1.2.1.1.- I2C_CAD_1.c ......................................................................................................................................................... 142
5.3.8.1.2.1.2.- I2C_CAD_2.c ......................................................................................................................................................... 143
5.3.8.1.2.2.- PCF8591_DAC. .............................................................................................................................................................. 144
5.3.8.1.2.2.1.- I2C_CDA_1.c ......................................................................................................................................................... 145
Microcontroladores
Pgina 5
Microcontroladores
Pgina 6
2.2.- Memorias.
Son circuitos integrados que almacenan informacin.
2.2.1.- ROM.
ROM (Read Only Memory) significa memoria de solo lectura. Se almacenan la
informacin en el proceso de fabricacin. No volatil
Proceso de Lectura:
Microcontroladores
Pgina 7
22+1= 8 palabras.
El Bus de Datos nos indica el nmero de bit que tiene cada palabra.
Bit = n+1, donde n=7 por el bus de datos D7,
7+1= 8 Bit
2.2.2.- RAM.
RAM (Random Access Memory) significa memoria de acceso aleatorio. Se puede leer
(R) y escribir (W). Memoria Volatil.
Proceso de Escritura:
Microcontroladores
Pgina 8
2.3.- Interfaces.
Son circuitos electrnicos que comunican el exterior con el uP.
Microcontroladores
Pgina 9
Aprendizaje de la Electrnica a travs de la Robtica - ARCE El proceso de lectura y escritura es igual que las memorias. Se tiene que configurar
cuando queremos leer o escribir datos del exterior.
A travs Tx y GND transmitimos los datos del uP al exterior.
A travs de Rx y GND el uP recibe los datos del exterior.
El protocolo de comunicaciones tiene que estar predefinido. Existen diferentes tipos:
Asncrona.
Es tambin conocida como Start/stop. Requiere de una seal que identifique el
inicio del carcter y a la misma se la denomina bit de arranque. Tambin se requiere de
otra seal denominada seal de parada que indica la finalizacin del carcter o bloque.
Sncrona.
Sncrono significa "con reloj" y exactamente eso es lo que necesitamos, un reloj
(o dicho en ingls un Clock). La transmisin sncrona necesita de dos lneas, una de
datos sobre la que se van a representar los distintos estados de los bits a transmitir y
una de reloj donde vamos indicando cuando est disponible cada bit en la lnea de
datos. Esta lnea de reloj es la de "sincronizacin" entre ambos dispositivos, el emisor
y el receptor de la transmisin
Microcontroladores
Pgina 10
Simplex.
En este caso el transmisor y el receptor estn perfectamente definidos y la
comunicacin es unidireccional. Este tipo de comunicaciones se emplean usualmente
en redes de radiodifusin, donde los receptores no necesitan enviar ningn tipo de dato
al transmisor.
Full Duplex.
Existen diferentes interfaces serie: UART, USART, PS2, USB, FireWire, etc.
Microcontroladores
Pgina 11
Microcontroladores
Pgina 12
La trama jaspeada
representa la palabra
que se direcciona
dentro del dispositivo.
Ejemplo: Direccin 3
A2 A1 A0 = 011
Palabra 3
La trama jaspeada
representa la palabra
que se direcciona
dentro del dispositivo.
Ejemplo: Direccin 15
A2 A1 A0 = 111
Palabra 7
La trama jaspeada
representa la palabra
que se direcciona
dentro del dispositivo.
Ejemplo: Direccin 21
A2 A1 A0 = 101
Palabra 5
La trama jaspeada
representa la palabra
que se direcciona
dentro del dispositivo.
Ejemplo: Direccin 28
A2 A1 A0 = 100
Palabra 4
Microcontroladores
Pgina 13
CPU
Buses
Memoria de
Memoria de
CPU
Programa y
Programa
de Datos
(EEPROM)
Datos
Buses
(RAM)
Arquitectura Hardvard
PROGRAMA
1 Ciclo
2 Ciclo
Bsqueda 1
Ejecuta 1
3 Ciclo
4 Ciclo
5 Ciclo
1. BSF STATUS,RP0
2. CLRF TRISB
3. MOVLW 0XFF
Bsqueda 2
Ejecuta 2
Bsqueda 3
Ejecuta 3
Bsqueda 4
4. MOVWF TRISA
Ejecuta 4
Microcontroladores
Pgina 14
Tiene 35 Instrucciones
Tiene una Memoria de Programa de 8192 palabras FLASH
368 byte de Memoria de Datos RAM
256 byte de EEPROM
33 Patillas de entradas/salidas.
Sistema de Adquisicin de datos (8 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 (InterIntegrated Circuit).
Un transmisor-receptor asncrono serie universal USART.
3 Timer (Temporizadores/Contadores).
2 Comparadores de seales analgicas.
Microcontroladores
Pgina 15
Microcontroladores
Pgina 16
compuesta por:
Microcontroladores
Pgina 17
3.2.3.- Ensamblador.
3.2.3.1.- Lenguaje Mquina.
Es un lenguaje binario Unos y Ceros que es el nico que entienden los
microcontroladores. El lenguaje ensamblador se compila Traduce a lenguaje mquina.
Se trabaja con formato Hexadecimal.
Ejemplo:
Instruccin en lenguaje
Ensamblador
Cdigo Binario
Compilador
BTFSS PORTA, 4
0001 1110
Cdigo Hexadecimal
Microcontroladores
0000
0101
Pgina 18
W58+W
Fichero Fuente
Ejemplo1.asm
Programa Ensamblador
MPASM.EXE
Fichero Ejecutable
Fichero Errores
Fichero Listable
Ejemplo1.hex
Ejemplo1.err
Ejemplo1.lst
Microcontroladores
Otros ficheros
Pgina 19
Microcontroladores
Pgina 20
4.2.- Simuladores.
Una vez que el programa se ha escrito y ensamblado o compilado se est en
binario *.hex que es el que se graba en el microcontrolador. Es casi indispensable probar
este programa, hacindolo funcionar en condiciones tan prximas como sea posible a las de
utilizacin real. Para hacer esto hay varias soluciones, las ms utilizadas son dos: utilizar un
econmico simulador software o un potente emulador.
Como su propio nombre indica, un simulador por software "simula" la ejecucin de las
instrucciones de un programa desarrollado para un modelo de microcontroladores especfico.
Representa el comportamiento interno del microcontrolador y el estado de sus lneas de
entrada/salida. Al ejecutar el simulador se pueden visualizar fcilmente las instrucciones
donde se producen funcionamientos no deseados. Como el microcontrolador se simula por
software el comportamiento no es idntico a la real sin embargo, proporciona una aproximacin
aceptable, especialmente cuando no es esencial el trabajo en tiempo real. Su gran ventaja es
el bajo precio.
El simulador realiza la ejecucin del programa mucho ms lento que lo hara el mismo
programa directamente sobre el microcontrolador, por eso determinadas operaciones en las
que son necesarios tiempos muy precisos o crticos no se puede probar mediante la
simulacin. No obstante, bien utilizado permite desarrollar aplicaciones interesantes con una
mnima inversin.
El simulador gratuito ms utilizado para los PIC es el MPLAB SIM, que trabaja dentro
del entorno MPLAB . En los ltimos est teniendo una gran aceptacin PROTEUS VSM
(www.labcenter.co.uk).
Microcontroladores
Pgina 21
Un editor de texto.
Un ensamblador llamado MPASM.
Un simulador llamado MPLAB SIM.
Un organizador de proyectos.
Este programa es gratuito. Se puede bajar en la direccin Internet del fabricante www.microchip.com.
Su instalacin es muy sencilla y similar a cualquier otro programa para el sistema operativo Windows.
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.
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.
Microcontroladores
Pgina 22
El emulador ICE 2000 dispone de una "cabeza" con idntico patillaje que el del
microcontrolador que emula. Esta cabeza se inserta en el zcalo donde ir el
microcontrolador con el programa que trata de comprobar. El emulador hace funcionar el
sistema como si hubiese un microcontrolador real y adems con la ventaja de que visualiza
en el monitor del ordenador toda la informacin necesaria para comprobar el funcionamiento
de los programas, permitiendo realizar todo tipo de pruebas. Los resultados obtenidos
son idnticos a los del producto final, puesto que a diferencia de los simuladores
la ejecucin se realiza en tiempo real.
El emulador es el mtodo de depuracin ms sofisticado que se puede emplear, pero
su alto precio no lo hace especialmente accesible y mucho menos para uso domstico. Para
muchas aplicaciones es suficiente con el simulador software.
Pgina 23
Aprendizaje de la Electrnica a travs de la Robtica - ARCE directamente desde el PC sin necesidad de utilizar ningn tipo de grabador, es decir en
la propia aplicacin. La descarga se hace a travs del puerto serie, USB.
E1
2
VDD
5V
VSS
VCC
U2
21
22
23
24
25
26
27
28
C6
J6
5
9
4
8
3
7
2
6
1
CONN-D9M
TXPC
14
13
7
8
RXPC
C9
VDD
2
6
1uF
1uF
1uF
C1-
C1+
T1OUT
R1IN
T2OUT
R2IN
T1IN
R1OUT
T2IN
R2OUT
11
12
13
14
15
16
17
18
U5
11
12
10
9
OSC1/CLKIN
OSC2/CLKOUT
MCLR/Vpp/THV
RA0/AN0
RA1/AN1
RA2/AN2/VREFRA3/AN3/VREF+
RA4/T0CKI
RC0/T1OSO/T1CKI
RA5/AN4/SS
RC1/T1OSI/CCP2
RC2/CCP1
RC3/SCK/SCL
RC4/SDI/SDA
RC5/SDO
RC6/TX/CK
RC7/RX/DT
9
10
1
2
3
4
5
6
7
PIC16F876_JOAN
VDD
VS+
VSC2-
C8
RB0/INT
RB1
RB2
RB3/PGM
RB4
RB5
RB6/PGC
RB7/PGD
C2+
C7
+
GND
1uF
MAX232
GND=GND
VCC=VCC
C10
100nF
Compilador C. (CCS)
Microcontroladores
Pgina 24
Visualizacin de Informacin.
Entradas Digitales.
Timer 0.
Timer 1.
Timer 2.
Interrupciones Externas.
Simulador_Perifricos.
Simulador_Perifricos_Potencia.
Simulador_Potencia.
Entradas Analgicas.
Led.
Display de 7 Segmentos.
LCD.
Cable.
Radiofrecuencia.
Radiofrecuencia_Multitarea.
Mdulo MSSP.
I2C.
SPI.
Expansor_Bus_PCF8574.
Conversor A-D_D-A_PCF8591.
Sensores de Distancia.
Sensores de Temperatura.
PT100.
Sensor de Temperatura TC74.
Sensor Trmico D-TPA81.
L298-L293B.
Puente en H con TRT.
Microcontroladores
Pgina 25
Aprendizaje de la Electrnica a travs de la Robtica - ARCE Los esquemas bsicos de simulacin del Monibot son:
Simulador Potencia.
Simulador Perifricos.
Microcontroladores
Pgina 26
5.3.1.1.1.- Led_1.c
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Programa.....: Led_1.c
//
// Plataforma hw: Placa Monibot 16F877A
//
// Fecha........: Mayo-2011
//
// Programador..: Pedro Alonso
//
// Descripcin..: Encender y apagar led RB7 con una cadencia de 1 segundo.
//
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// *********************************** Directivas de procesado*****************************************
// (Controlan la conversin del programa a cdigo mquina por parte del compilador)
#include <16F877A.h>
#fuses XT,NOWDT,NOPROTECT,NOLVP
#use delay( clock = 1000000 )
#DEFINE ENCENDIDO 1
#DEFINE APAGADO 0
// Reloj de 1 MHz
Microcontroladores
Pgina 27
while (1)
{
rb7 = ENCENDIDO;
delay_ms(1000);
rb7 = APAGADO;
delay_ms(1000);
}
}
5.3.1.1.2.- Led_2.c
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Programa.....: Led_2.c
//
// Plataforma hw: Placa Monibot 16F877A
//
// Fecha........: Mayo-2011
//
// Programador..: Pedro Alonso
//
// Descripcin..: Encender y apagar todos los Led con una cadencia de 2 segundos y 1
//
//
segundo respectivamente
//
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// ************************************ Directivas de procesado****************************************
// (Controlan la conversin del programa a cdigo mquina por parte del compilador)
#include <16F877A.h>
#fuses XT,NOWDT,NOPROTECT,NOLVP
#use delay( clock = 1000000 )
// Reloj de 1 MHz
while (1)
{
portB =0b11111111;
delay_ms(2000);
portB =0b00000000;
delay_ms(1000);
}
}
Microcontroladores
Pgina 28
int8 n=0;
// Reloj de 1 MHz
while (1)
{
for (n=0;n<=9;n++)
{
portB=n;
delay_ms(1000);
}
}
}
5.3.1.1.4.- Led_4.c
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Programa.....: Led_4.c
//
// Plataforma hw: Placa Monibot 16F877A
//
// Fecha........: Mayo-2011
//
// Programador..: Pedro Alonso
//
// Descripcin..: Simular Coche Fantstico
//
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// ********************************** Directivas de procesado******************************************
// (Controlan la conversin del programa a cdigo mquina por parte del compilador)
#include <16F877A.h>
#fuses XT,NOWDT,NOPROTECT,NOLVP
#use delay( clock = 1000000 )
int8 n=0 ;
Microcontroladores
// Reloj de 1 MHz
Pgina 29
Aprendizaje de la Electrnica a travs de la Robtica - ARCE // **************************** Funcin principal o programa principal ******************************
// Se define con un void main,
void main()
{
TRISB = 0B00000000;
portB = 0b00000001;
delay_ms(500);
// Activamos PB0.
// Esperamos 0,5 segundo.
while (1)
{
for (n=0;n<=6;n++)
{
portB<<=1;
delay_ms(500);
}
for(n=7;n>0;n--)
{
portB>>=1;
delay_ms(500);
}
}
}
5.3.1.2.- Display_7Segmentos.
Los entrenadores utilizados son Simulador Perifricos y Dispay_7Seg dentro de la
carpeta de Display_7Segmentos.
Un display de 7 segmentos son diodos LED encapsulados con una determinada
configuracin. Si queremos que aparezcan los nmeros decimales sobre el display es
necesario realizar una conversin de nmero decimal a 7 segmentos. Dicha conversin
depender de la conexin del display al microcontrolador.
Microcontroladores
Pgina 30
Aprendizaje de la Electrnica a travs de la Robtica - ARCE Tabla de conversin de Nmero Decimal a Binario de 7 segmentos
Nmero
Decimal
0
1
2
3
4
5
6
7
8
9
Puerto B
B7 B6 B5 B4 B3 B2 B1 B0
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
0
1
0
0
0
1
0
1
0
1 Dgito en
Hexadecimal
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
Nmero
Hexadecimal
1
0
1
1
0
1
1
1
1
1
3F
06
5B
4F
66
6D
7D
07
7F
6F
2 Dgito en
Hexadecimal
5.3.1.2.1.- Display_7Seg_1.c
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Programa.....: Display_7Seg_1.c
//
// Plataforma hw: Placa Monibot 16F877A
//
// Fecha........: Mayo-2011
//
// Programador..: Pedro Alonso
//
// Descripcin..: Mostrar los nmeros desde 0 al 9 en un display de 7 Segmentos.
//
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#define Numeros_Tabla 10
// Nmeros de la Tabla.
int8 n=0 ;
// Tabla de conversin de
// BCD a 7 Seg.
while (1)
Microcontroladores
Pgina 31
{
portB = DISPLAY[n];
delay_ms(1000);
}
}
}
5.3.1.2.2.- Display_7Seg_2.c
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Programa.....: Display_7Seg_2.c
//
// Plataforma hw: Placa Monibot 16F877A
//
// Fecha........: Mayo-2011
//
// Programador..: Pedro Alonso
//
// Descripcin..: Mostrar los nmeros desde 9 al 0 en un display de 7 Segmentos.
//
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Reloj de 1 MHz
#define Numeros_Tabla 10
// Nmeros de la Tabla.
// Tabla de conversin de
// BCD a 7 Seg.
while (1)
{
for (n=Numeros_Tabla-1; n>=0; n--)
{
portB = DISPLAY[n];
delay_ms(1000);
}
}
}
Microcontroladores
Pgina 32
// Reloj de 1 MHz
#define Numeros_Tabla 5
// Nmeros de la Tabla.
int8 n=0;
// Tabla de 5 datos.
while (1)
{
for (n=0;n<Numeros_Tabla;n++)
{
portB = DISPLAY[n];
delay_ms(1000);
}
}
}
Microcontroladores
Pgina 33
La pantalla de cristal lquido o display LCD (Liquid Crystal Display) se utiliza para
mostrar mensajes. Puede mostrar cualquier carcter alfanumrico.
La pantalla consta de una matriz de de caracteres (Normalmente de 5x7 punto por
carcter), distribuidos en una, dos, tres, cuatro lneas (Hasta 40 caracteres por lnea). El
proceso de visualizacin es gobernado por un microcontrolador incorporado en la propia
pantalla. El modelo ms utilizados es el Hitachi HD44780.
Uno de los modelos utilizados es el LM16L cuyas caractersticas son:
Microcontroladores
Pgina 34
SEAL
DEFINICIN
PINES
D7..D0
E
Data Bus
Enable
14..7
6
R/W
Read/Write
RS
Register Select
VEE VLC
VDD
VSS
Ground
D0
D1
D2
D3
D4
D5
D6
D7
7
8
9
10
11
12
13
14
4
5
6
1
2
3
VSS
VDD
VEE
RS
RW
E
El patillaje es el siguiente:
FUNCIN
Bus de datos
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.
Utilizaremos el driver flex_lcd.c que es una variacin del creado por CCS, con las
siguientes funciones:
Lcd_init(); Inicializa el LCD.
Lcd_gotoxy (byte x, byte y); Indica la posicin y lnea donde se posiciona el cursor.
byte x es posicin del cursor y byte y el lnea.
Utilizamos funciones del compilador de C de CCS para escribir en el LCD.
PRINTF(function, string, values)
La funcin de impresin formateada PRINTF saca una cadena de caracteres al
estndar serie RS-232 o a una funcin especificada. El formato est relacionado con el
argumento que ponemos dentro de la cadena (string).
function es una funcin. 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, nmero, tipo ,\c.
mensaje
nmero
1-9
Microcontroladores
Pgina 35
c
s
u
d
Lu
Ld
x
X
Lx
LX
f
g
e
w
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.
\c puede ser:
\f
\n
\b
Se limpia el LCD.
El cursor va a la posicin (1,2)
El cursor retrocede una posicin.
5.3.1.3.1.- LCD_1.c
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Programa.....: LCD_1.c
//
// Plataforma hw: Placa Monibot 16F877A
//
// Fecha........: Mayo-2011
//
// Programador..: Pedro Alonso
//
// Descripcin..: Mostrar mensajes en el LCD
//
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#include <flex_lcd.c>
// Reloj de 1 MHz
// Incluimos el driver flex_lcd.c que contiene las funciones de control del LCD.
// Inicializamos el LCD.
// Escribimos "I.E.S. Joan Miro" y
// saltamos a la siguiente lnea.
// Escribimos " Ciclo GM de EC".
while (1);
Microcontroladores
Pgina 36
#include <flex_lcd.c> // Incluimos el driver flex_lcd.c que contiene las funciones de control del LCD.
int8 numero_1 = 254;
signed int8 numero_2 = -128;
int8 numero_3 = 142;
float numero_4 = -2.35;
// Inicializamos el LCD.
lcd_gotoxy(1,1);
printf(lcd_putc,"%3u",numero_1);
lcd_gotoxy(8,1);
printf(lcd_putc,"%4d",numero_2);
lcd_gotoxy(1,2);
printf(lcd_putc,"%2X",numero_3);
lcd_gotoxy(8,2);
printf(lcd_putc,"%5.2f",numero_4);
while (1);
}
5.3.1.3.3.- LCD_3.c
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Programa.....: LCD_3.c
//
// Plataforma hw: Placa monibot 16F877A
//
// Fecha........: Mayo-2011
//
// Programador..: Pedro Alonso
//
// Descripcin..: Mostrar mensajes y array de nmeros en formatos Decimal
//
//
y Hexadecimal en el LCD
//
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Microcontroladores
Pgina 37
// Reloj de 1 MHz
#include <flex_lcd.c>
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.
5.3.1.3.4.- LCD_4.c
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Programa.....: LCD_4.c
//
// Plataforma hw: Placa Monibot 16F877A
//
// Fecha........: Mayo-2011
//
// Programador..: Pedro Alonso
//
// Descripcin..: Mostrar mensajes y array de nmeros en formatos entero 16 bit en el LCD //
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#include <flex_lcd.c>
// Reloj de 1 MHz
// Incluimos el driver flex_lcd.c que contiene las funciones de control del LCD.
Microcontroladores
Pgina 38
Aprendizaje de la Electrnica a travs de la Robtica - ARCE // ************************** Funcin principal o programa principal ********************************
void main()
{
int8 i=0;
lcd_init();
// Inicializamos el LCD.
lcd_gotoxy(9,1);
printf(lcd_putc, "int16");
// Sacamos los diez nmeros del array uno a uno y los representamos
// en el Display.
{
lcd_gotoxy(1,1);
printf(lcd_putc,"%5Lu",NUMEROS[i]);
delay_ms(1000);
// Retardo de 1 segundo.
}
while (1);
// Fin.
5.3.1.3.5.- LCD_5.c
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Programa.....: LCD_5.c
//
// Plataforma hw: Placa Monibot 16F877A
//
// Fecha........: Mayo-2010
//
// Programador..: Pedro Alonso
//
// Descripcin..: Mostrar mensajes y array de nmeros en formatos entero 32
//
//
bit con signo en el LCD
//
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Reloj de 1 MHz
#include <flex_lcd.c>
lcd_init();
// Inicializamos el LCD.
lcd_gotoxy(9,2);
printf(lcd_putc, "S_int32");
Microcontroladores
Pgina 39
{
lcd_gotoxy(1,2);
printf(lcd_putc,"%7Ld",DATOS[i]);
delay_ms(1000);
// Retardo de 1 segundo.
}
while (1);
// Fin.
5.3.1.3.6.- LCD_6.c
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Programa.....: LCD_6.c
//
// Plataforma hw: Placa Monibot 16F877A
//
// Fecha........: Mayo-2011
//
// Programador..: Pedro Alonso
//
// Descripcin..: Mostrar mensajes y array de caracteres en el LCD
//
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#include <flex_lcd.c>
// Reloj de 1 MHz
lcd_init();
// 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);
// Retardo de 1 segundo.
}
while (1);
// Fin.
Microcontroladores
Pgina 40
// Reloj de 1 MHz
#include <flex_lcd.c>
","Dibujo
","Fisica
lcd_init();
// Inicializamos el LCD.
lcd_gotoxy(1,1);
printf(lcd_putc,"Jose Luengo");
while(1)
{
for(i = 0;i <= 3; i++)
{
lcd_gotoxy(13,2);
printf(lcd_putc,"%2u",NOTAS[i]);
lcd_gotoxy(1,2);
// Retardo de 1 segundo.
}
}
}
Microcontroladores
Pgina 41
5.3.2.1.1.- Interruptores_Led_1.c
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Programa.....: Interruptores_Led_1.c
//
// Plataforma hw: Placa Monibot 16F877A
//
// Fecha........: Mayo-2011
//
// Programador..: Pedro Alonso
//
// Descripcin..: Leer la posicin de los interruptores y llevar dicha informacin a los LED
//
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// *********************************** Directivas de procesado ****************************************
// (Controlan la conversin del programa a cdigo mquina por parte del compilador)
#include <16F877A.h>
#fuses XT, NOWDT, NOPROTECT, NOLVP
#use delay( clock = 1000000 )
Microcontroladores
Pgina 42
while (1)
{
portB = portA;
}
}
5.3.2.1.2.- Interruptores_Led_2.c
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Programa.....: Interruptores_Led_2.c
//
// Plataforma hw: Placa Monibot 16F877A
//
// Entrenador: Simulador Perifricos.DSN
//
// Fecha........: Mayo-2011
//
// Programador..: Pedro Alonso
//
// Descripcin..: Leer puerto A si es menor o igual que 7 activar el Led RBO
//
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// ********************************* Directivas de procesado*******************************************
// (Controlan la conversin del programa a cdigo mquina por parte del compilador)
#include <16F877A.h>
// Eleccin del uC 16F877A
#fuses XT, NOWDT, NOPROTECT, NOLVP
#use delay( clock = 1000000 )
// Reloj de 1 MHz
#BYTE TRISB = 0x86
#BYTE TRISA = 0x85
while (1)
{
}
}
Microcontroladores
Pgina 43
// Reloj de 1 MHz
// Tabla de conversin de
// BCD a 7 Seg.
while (1)
{
if(portA<=9)
{
portB=DISPLAY[portA];
portB = 0B11111001;
// Poner la letra E
}
else
{
}
}
}
Microcontroladores
Pgina 44
// Reloj de 1 MHz
while (1)
{
switch (portA)
{
case 0:
break;
case 1:
break;
case 2:
Microcontroladores
Pgina 45
// DISPLAY[2].
// Retardo de 0,25 Segundos.
// Apagar Display.
// Retardo de 0,25 Segundos.
break;
case 3:
break;
default:
// Apagar Display.
}
}
}
5.3.2.1.5.- Pulsadores_DISPL_7S_1.c
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Programa.....: Pulsadores_DISPL_7S_1.c
//
// Plataforma hw: Placa Monibot 16F877A
//
// Fecha........: Mayo-2011
//
// Programador..: Pedro Alonso
//
// Descripcin..: Leer los pulsadores RCO(incremento) y T0CKI(Decremento) y mostrar la
//
//
informacin en un Display de 7 Segmentos.
//
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
portB = DISPLAY[0];
Microcontroladores
Pgina 46
{
WHILE(rc0==1)
{
n++;
// Incrementar la variable n.
if (n>9)
{
portB = DISPLAY[9];
n=9;
portB=DISPLAY[n];
}
else
{
delay_ms(1000);
}
}
WHILE(t0cki==0)
{
n--;
// Decrementar la variable n.
if (n<0)
{
portB = DISPLAY[0];
n=0;
portB=DISPLAY[n];
}
else
{
delay_ms(1000);
}
}
}
}
Microcontroladores
Pgina 47
// Reloj de 1 MHz
#include <flex_lcd.c>
#define ON 1
// ON equivale a 1.
int8 contador=0;
int1 cambio=0;
// Inicializamos el LCD.
TA0 = 1;
while(1)
{
lcd_gotoxy(1,1);
if(RA0==ON)
{
if (cambio==0)
{
printf(lcd_putc, "Encendido");
contador++;
lcd_gotoxy(11,1);
printf(lcd_putc,"%3u",contador);
cambio=1;
}
delay_ms(50);
}
else
{
printf(lcd_putc, "Apagado ");
cambio=0;
delay_ms(50);
}
}
}
Microcontroladores
Pgina 48
// Incluimos el driver flex_lcd.c que contiene las funciones de control del LCD.
#define ON 1
int8 contador=0;
int1 cambio=0;
// Inicializamos el LCD.
// Configuramos la patilla RA0 com entrada de datos
TRISB = 0B00000000;
portB = DISPLAY[0];
while(1)
{
lcd_gotoxy(1,1);
if(RC0==ON)
// Si RA0=ON haz lo que viene a continuacin.
{
if (cambio==0)
// Haz una sola vez elte proceso si RA0=ON
{
printf(lcd_putc, "Encendido");
// Escribimos la palabra "Encendido".
contador++;
// Incremento la variable contador.
lcd_gotoxy(11,1);
printf(lcd_putc,"%3u",contador);
portB = DISPLAY[contador];
cambio=1;
}
delay_ms(50);
// Cambiamos la variable.
// Espereramos 50 mS.
}
else
{
}
}
}
Microcontroladores
Pgina 49
5.3.2.3.1.- Pulsadores_LCD_1.c
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Programa.....: Pulsadores_LCD_1.c
//
// Plataforma hw: Placa Monibot 16F877A
//
// Fecha........: Mayo-2011
//
// Programador..: Pedro Alonso
//
// Descripcin..: Si RC0= 1 mostrar en el LCD Apagado. Si RC0= 0 mostrar en el LCD Encendido. //
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// *********************************** Directivas de Preprocesado ************************************
#include <16F877A.h>
#fuses XT,NOWDT,NOPROTECT,NOLVP
#use delay( clock = 1000000 )
// Reloj de 1 MHz
#include <flex_lcd.c>
// Incluimos el driver flex_lcd.c que contiene las funciones de control del LCD.
#BYTE TRISC = 0X87
#BIT pulsador = 0X07.0
#define ON 1
// Inicializamos el LCD.
// Ponemos el Puerto C como ENTRADA de
// datos a excepcin de RC7.
while(1)
{
lcd_gotoxy(1,1);
if(pulsador==ON)
{
printf(lcd_putc, "Encendido");
}
else
{
printf(lcd_putc, "Apagado ");
}
}
}
Microcontroladores
Pgina 50
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 =
= 4,8 mV.
q= Intervalo de cuantificacin.
LSB= Bit menos significativo
Si trabajamos con tensiones comprendidas entre Vref+ = 5V y Vref- =0V y con 10bits de salida
obtenemos una resolucin de 4,8 mV.
Microcontroladores
Pgina 51
Error de Cuantificacin.( 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 = 2,4 mV.
Error = 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
4,9736mV < Ve 4,9904mV
4,9904mV < Ve 4,9952 mV
1
1
1
1
1 1
1 1
1
1
1
1
1
1
1
1
1
1
D
N Decimal
0
1
2
3
4
0
1
1022
1023
AN7
AN6
AN5
AN4
AN3
AN2
AN1
AN0
VREF+
VREF-
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
A
VREF+
A
VREF+
A
VREF+
D
VREF+
A
VREF+
VREF+
VREF+
VREF+
D
VREF+
A
A
A
A
D
D
D
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
AN3D
VDD
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
VREFA
A
VREFVREFVREFD
VREF-
Microcontroladores
Pgina 52
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
V ENTRADA
V SALIDA
Microcontroladores
Pgina 53
#FUSES XT,NOWDT
#use delay(clock=4000000)
//#use delay(clock=20000000)
// TRISC en 87h.
// PORTC en 07h.
setup_adc_ports(0);
setup_adc(ADC_CLOCK_INTERNAL);
// setup_adc(ADC_CLOCK_DIV_2);
set_adc_channel(0);
while(1)
{
// Bucle infinito.
delay_us(5);
// delay_us(1);
q = read_adc();
portC = q;
}
}
Microcontroladores
Pgina 54
5.3.3.2.1.- Conversin_A-D1.c
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Programa.....: Conversin_A-D1.c
//
// Plataforma hw: Placa Monibot 16F877A
//
// Fecha........: Septiembre-2011
//
// Programador..: Pedro Alonso
//
// Descripcin..: Conversin Analgica Digital de la Patilla AN0
//
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// ************************************ Directivas de Preprocesado************************************
#include <16F877A.h>
#device adc=10
de resolucion.
// Conversor Analogico Digital de 10 bit el PIC 16F876A puede trabajar con 8 o 10 bit
#FUSES XT,NOWDT
#use delay(clock=1000000)
#include <flex_lcd.c>
// Incluimos el driver flex_lcd.c que contiene las funciones de control del LCD.
// Inicializamos el LCD.
setup_adc_ports(2);
Mirar ADCON1.
setup_adc(ADC_CLOCK_INTERNAL);
set_adc_channel(0);
for (;;)
// Bucle infinito.
{
delay_us(20);
q = read_adc();
Microcontroladores
Pgina 55
}
}
5.3.3.2.2.- Conversin_A-D2.c
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Programa.....: Conversin_A-D2.c
//
// Plataforma hw: Placa Monibot 16F877A
//
// Fecha........: Septiembre-2011
//
// Programador..: Pedro Alonso
//
// Descripcin..: Conversin Analgica Digital de la Patilla AN0 y AN3
//
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// *********************************** Directivas de Preprocesado ************************************
#include <16F877A.h>
#device adc=10
#FUSES XT,NOWDT
#use delay(clock=1000000)
#include <flex_lcd.c>
// Incluimos el driver flex_lcd.c que contiene las funciones de control del LCD.
setup_adc_ports(2);
lcd_init();
while (true)
{
set_adc_channel(0);
delay_us(20);
q = read_adc();
p = 5.0 * q / 1024.0;
// 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=%04.3fv", p);
set_adc_channel(3);
delay_us(20);
q = read_adc();
p = 5.0 * q / 1024.0;
lcd_gotoxy(1,2);
printf(lcd_putc, "V2=%04.3fv", p);
}
}
Microcontroladores
Pgina 56
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Programa.....: Conversin_A-D2a.c
//
// Plataforma hw: Placa Monibot 16F877A
//
// Fecha........: Septiembre-2011
//
// Programador..: Pedro Alonso
//
// Descripcin..: Si RA2=1 digitalizamos la seal ANO y presentamos
//
//
la Informacin en el LCD
//
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// ******************************** Directivas de Preprocesado ***************************************
#include <16F877A.h>
#device adc=10
#FUSES XT,NOWDT
#use delay(clock=1000000)
#include <flex_lcd.c>
// Incluimos el driver LCD1.c que contiene las funciones de control del LCD.
setup_adc_ports(4);
lcd_init();
// Inicializamos el LCD.
TA2=1;
Microcontroladores
Pgina 57
// Bucle infinito.
{
if(RA2 == 1)
{
set_adc_channel(0);
delay_us(20);
q = read_adc();
p = 5.0 * q / 1024.0;
lcd_gotoxy(1,1);
printf(lcd_putc, "V1=%04.3fv", p);
set_adc_channel(3);
delay_us(20);
}
else
{
q = read_adc();
p = 5.0 * q / 1024.0;
lcd_gotoxy(1,1);
printf(lcd_putc, "V2=%04.3fv", p);
}
}
}
Microcontroladores
Pgina 58
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)
Microcontroladores
Pgina 59
= 100 %
5.3.4.1.1.- Prueba_Motor_Derecho.c
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Programa.....: Prueba_Motor_Derecho.c
//
// Plataforma hw: Placa monibot 16F877A
//
// Fecha........: Septiembre_2011
//
// Programador..: Pedro Alonso
//
// Descripcin..: Prueba de Motor Derecho sin control de velocidad
//
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// ********************************* Directiva de Preprocesado ****************************************
// (Controlan la conversin del programa a cdigo mquina por parte del compilador)
#include <16F877A.h>
#fuses XT,NOWDT
Microcontroladores
Pgina 60
Aprendizaje de la Electrnica a travs de la Robtica - ARCE // *************************** Funcin principal o programa principal *******************************
void main()
{
// *********************** Configuracin de los Puertos del PIC y reseteos del Rastreador ********************
TRISC = 0B10000001;
TRISB = 0B00000000;
delay_ms(2000);
// Retardo de 2 segundo.
en2 = 0;
delay_ms(2000);
// Retardo de 2 segundo.
en2 = 1;
giro_d=1;
delay_ms(2000);
// Retardo de 2 segundo.
en2 = 0;
delay_ms(2000);
// Retardo de 2 segundo.
}
}
5.3.4.1.2.- Prueba_Control_Velocidad_Motor_Derecho.c
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Programa.....: Prueba_Control_Velocidad_Motor_Derecho.c
//
// Plataforma hw: Placa monibot 16F877A
//
// Fecha........: Septiembre_2011
//
// Programador..: Pedro Alonso
//
// Descripcin..: Control de velocidad y sentido de giro de un motor de corriente
//
//
continua. MOT2
//
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// ************************************ Directiva de Preprocesado *************************************
// (Controlan la conversin del programa a cdigo mquina por parte del compilador)
#include <16F877A.h>
#fuses XT,NOWDT
Microcontroladores
Pgina 61
Aprendizaje de la Electrnica a travs de la Robtica - ARCE // ***************************** Funcin principal o programa principal ****************************
void main()
{
int16 i=0;
/ / ************************ Configuracin de los Puertos del PIC y reseteos el dispositivo *********************
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 1 x 16
// PR2 =[T/(Tcm x Preescaler x Postscaler)]-1
// PR2 =[16000uS/(4uS x 16 x 1)]-1 = 249
(en C 249)
setup_ccp1(CCP_PWM);
TRISC = 0B10010001;
set_pwm1_duty(i);
TRISB = 0B00000000;
for(i=0;i<=1000;i=i+100)
{
set_pwm1_duty(i);
delay_ms(1000);
}
giro_d=1;
for(i=0;i<=1000;i=i+100)
{
set_pwm1_duty(i);
delay_ms(1000);
}
}
}
5.3.4.1.3.- Prueba_Control_Velocidad_Motor_Derecho_f.c
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Programa.....: Prueba_Control_Velocidad_Motor_Derecho_f.c
//
// Plataforma hw: Placa monibot 16F877A
//
// Fecha........: Septiembre_2011
//
// Programador..: Pedro Alonso
//
// Descripcin..: Control de velocidad y sentido de giro de un motor de
//
// corriente continua. MOT2
//
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Microcontroladores
Pgina 62
#fuses XT,NOWDT
// Inico seal PW
// Refresco seal PWM.
giro_d=1;
Refresco_PWM();
}
}
// **************************************************** Funcion Inicio_PWM *******************************************************
void Inicio_PWM(void)
{
int16 i=0;
setup_timer_2(T2_DIV_BY_16,249,1);
// setup_timer(Prescaler,PR2,Postscaler)
// 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 1 x 16
// PR2 =[T/(Tcm x Preescaler x Postscaler)]-1
// PR2 =[16000uS/(4uS x 16 x 1)]-1 = 249
(en C 249)
setup_ccp1(CCP_PWM);
TRISC = 0B10010001;
set_pwm1_duty(i);
Microcontroladores
Pgina 63
// Refresca el nivel alto de la seal PWM. Salida por RC2. (Motor Derecho)
// Retarodo de 1 segundo.
5.3.4.1.4.- Prueba_Control_Velocidad_Motor_Izquierdo_Derecho_f.c
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Programa.....: Prueba_Control_Velocidad_Motor_Izquierdo_Derecho_f.c
//
// Plataforma hw: Placa monibot 16F877A
//
// Fecha........: Septiembre_2011
//
// Programador..: Pedro Alonso
//
// Descripcin..: Control de velocidad y sentido de giro de los motores de corriente
//
//
continua. MOT1 y 2
//
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// *********************************** Directiva de Preprocesado **************************************
// (Controlan la conversin del programa a cdigo mquina por parte del compilador)
#include <16F876A.h>
#fuses XT,NOWDT
// Inico seal PW
// Refresco seal PWM.
Microcontroladores
Pgina 64
}
}
// ************************************************ Funcion Inicio_PWM ***********************************************************
void Inicio_PWM(void)
{
int16 i=0;
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 1 x 16
// PR2 =[T/(Tcm x Preescaler x Postscaler)]-1
// PR2 =[16000uS/(4uS x 16 x 1)]-1 = 249
setup_ccp1(CCP_PWM);
setup_ccp2(CCP_PWM);
(en C 249)
TRISC = 0B10010001;
set_pwm1_duty(i);
set_pwm2_duty(i);
}
}
}
Microcontroladores
Pgina 65
Microcontroladores
Pgina 66
5.3.4.2.1.- Control_2_Servo_Posicin.c
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Programa.....: Control_2_Servo_Posicin.c
//
// Plataforma hw: Placa monibot 16F877A
//
// Fecha........: Octubre-2010
//
// Programador..: Pedro Alonso
//
// Descripcin..: Control de 2 Servos de Posicin
//
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// *********************************** Directivas de Preprocesado ************************************
#include <16F877A.h>
#device adc=8
#FUSES XT,NOWDT
#use delay(clock=1000000)
#include <Servo_Futaba_10bit.c>
// While (1);
setup_adc(ADC_CLOCK_INTERNAL);
setup_adc_ports(0);
Microcontroladores
Pgina 67
// Bucle infinito.
TH = read_adc();
Futaba_RC1(TH);
set_adc_channel(3);
delay_us(5);
TH = read_adc();
Futaba_RC2(TH);
}
}
;El microcontrolador PIC 16f876a tiene un hardware integrado que puede generar 2 seales PWM
;por las patillas RC2 y RC1.
;El periodo para ambas seales se fija con la siguiente frmula
;T =[(PR2+1)*4*Tosc]*(TMR2_Valor_preescalar)
;El nivel alto T1H se controla con 10 bit ( Los 8 bit ms significativo con el registro CCPR1L y
;los dos bit menos significativos con CCP1X y CCP1Y que estn en el registro CCP1CON)
;Esta seal sale por la patilla RC2.
;El nivel alto T2H se controla con 10 bit ( Los 8 bit ms significativo con el registro CCPR2L y
;los dos bit menos significativos con CCP2X y CCP2Y que estn en el registro CCP2CON)
;Esta seal 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 seal cuadrada de periodo "T1".
;La posicin del Servomotor lo determina el nivel alto de la senal "T1H"
;El Servomotor de Futaba necesita un periodo "T1" entre 10ms y 30 ms.
;Cargando los registros de forma correcta sale T1 =[(249+1)*4*1uS](16)=16 mS (Cristal de cuarzo 1 MHz)
;Tiene un control de Posicin 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
*/
// ****************************************************** Declaracin de funciones ***********************************************
void Inicializacion_Futaba_RC1();
void Inicializacion_Futaba_RC2();
void Futaba_RC1(int16 TH);
void Futaba_RC2(int16 TH);
Microcontroladores
Pgina 68
// 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
setup_ccp2(CCP_PWM);
TH = THmed;
set_pwm2_duty(TH);
delay_ms(5);
(en C 249)
}
// ************************************************* Funcin Inicializacion_Futaba_RC2() **************************************
void Inicializacion_Futaba_RC2()
{
int16 TH;
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
// 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
setup_ccp1(CCP_PWM);
TH = THmed;
set_pwm1_duty(TH);
delay_ms(5);
(en C 249)
}
// *********************************************** Funcin Futaba_RC1(int16 TH) ************************************************
void Futaba_RC1(int16 TH)
{
TH = TH+THmin;
if(TH<=THmin)
{
TH=THmin+1;
Microcontroladores
Pgina 69
}
if(TH>=THmax)
{
TH=THmax-1;
set_pwm2_duty(TH);
}
delay_ms(5);
// Si TH >= THmax
// Cargar TH con valor mximo
// Refrescamos el Tiempo alto TH de la seal.
// 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=THmin+1;
set_pwm1_duty(TH);
}
if(TH>=THmax)
{
TH=THmax-1;
set_pwm1_duty(TH);
}
delay_ms(5);
// Si TH >= THmax
// Cargar TH con valor mximo
// Refrescamos el Tiempo alto TH de la seal.
// 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.
Microcontroladores
Pgina 70
5.3.5.1.1.- Interrupcin_INT_RB0.c
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Programa.....: Interrupcin_INT_RB0.c
//
// Plataforma hw: Placa Monibot 16F877A
//
// Fecha........: Septiembre_2011
//
// Programador..: Pedro Alonso
//
// Descripcin..: Manejo de Interrupcin externa INT
//
//
Un programa principal, simula las luces del Coche Fantstico.
//
//
Cuando pulso la patilla RB0 interrumpimos el programa principal y
//
//
ejecutamos un programa (rutina de interrupcin)
//
//
La rutina de interrupcin, activa un buzzer tres veces con una cadencia
//
//
de de 0,5 segundos
//
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// *********************************** Directivas de Preprocesado ************************************
#include <16F877A.h>
#fuses XT,NOWDT,PUT,NOWRT
#use delay(clock= 1000000)
// TRISB en 86h.
// PORTB en 06h.
Microcontroladores
Pgina 71
// Coche fantstico.
// Pitido.
portB=luces;
delay_ms(100);
// retraso.
port_b_pullups(TRUE);
enable_interrupts(int_ext);
ext_int_edge(L_TO_H);
enable_interrupts(GLOBAL);
while (1)
{
Coche_Fantastico();
}
}
/* ********************************** Atencin a la interrupcin por cambio en RB0 **************************************** */
#INT_EXT
void Pitido()
{
int8 i;
for(i=0; i<3; i++)
{
buzzer=1;
delay_ms(500);
buzzer=0;
delay_ms(500);
}
}
/* ************************************************ Coche_Fantastico ************************************************************ */
void Coche_Fantastico (Void)
{
static int8 luces=0B00001000;
int8 n;
for(n=0;n<4;n++)
{
luces<<=1;
portB=luces;
delay_ms(500);
}
for(n=4;n>0;n--)
{
luces>>=1;
portB=luces;
delay_ms(500);
}
Microcontroladores
Pgina 72
// TRISB en 86h.
// PORTB en 06h.
int8 luces=0B00001000;
/* ******************************************* Declaracin de funciones ******************************************************** */
void Coche_Fantastico (void);
void Tono (void);
// Coche fantstico.
// pitidos.
portB = luces;
delay_ms(100);
// inicializamos el puerto B.
// Retraso.
port_b_pullups(TRUE);
enable_interrupts(int_ext);
ext_int_edge(L_TO_H);
enable_interrupts(GLOBAL);
while (1)
{
}
}
/* ***************************** Atencin a la interrupcin por cambio en RB0 ********************************************* */
#INT_EXT
void Tono()
{
int16 i;
// for(i=0;i<5000;i++)
for(i=0;i<500;i++)
{
altavoz=1;
delay_us(100);
altavoz=0;
delay_us(100);
}
Microcontroladores
// Real
// Simulado
Pgina 73
// Real
// Simulado
}
/* ************************************************ Coche_Fantastico ************************************************************ */
void Coche_Fantastico (void)
{
static int8 luces=0B00001000;
int8 n=0;
for (n=0;n<4;n++)
{
luces<<=1;
portB=luces;
delay_ms(100);
}
for (n=4;n>0;n--)
{
luces>>=1;
portB=luces;
delay_ms(100);
}
5.3.5.1.3.- Interrupcin_INT_RB0b.c
Microcontroladores
Pgina 74
// Incluimos el driver flex_lcd.c que contiene las funciones de control del LCD.
#define Numeros_Tabla 3
// Nmeros de la Tabla.
// TRISB en 86h.
// PORTB en 06h.
// Funcin Mensaje.
// Funcin Display_7s.
lcd_init();
// Inicializamos el LCD.
port_b_pullups(TRUE);
enable_interrupts(int_ext);
ext_int_edge(L_TO_H);
enable_interrupts(GLOBAL);
while (1)
{
}
}
/* ********************************* Atencin a la interrupcin por cambio en RB0 ***************************************** */
#INT_EXT
void Display_7s()
{
int8 n=0 ;
{
portB = DISPLAY[n];
delay_ms(500);
}
portB = 0B00000000;
Microcontroladores
Pgina 75
");
5.3.5.2.1.- Interrupcin_INT_RB4567.c
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Programa.....: Interrupcin_INT_RB4567.c
//
// Plataforma hw: Placa monibot 16F877A
//
// Fecha........: Septiembre_2011
//
// Programador..: Pedro Alonso
//
// Descripcin..: Manejo de las Interrupciones de INT y por cambio de nivel
//
//
de RB4, RB5, RB6, RB7.
//
//
Un programa principal, ejecuta un programa que mueve un Motor PAP.
//
//
Cuando plso la patilla RB0 interrumpimos el programa principal y
//
//
activamos un Motor de CC y si volvemos a pulsar lo desactivamos.
//
//
Cuando abrimos o cerramos la patilla RB4,RB5,RB6 RB7,
//
//
interrumpimos el programa principal y activamos desactivamos un LED
//
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Microcontroladores
Pgina 76
// TRISC en 87h.
// PORTC en 07h.
// TRISB en 86h.
// PORTB en 06h.
// Activa el Motor.
// Encender Led.
// Motor_PAP.
TRISB = 0B11111111;
TRISC = 0B00000000;
portC = 0B00000000;
// Reseteamos el Puerto C.
port_b_pullups(TRUE);
n = portB;
RBIF = 0;
enable_interrupts(int_rb);
enable_interrupts(int_ext);
ext_int_edge(L_TO_H);
enable_interrupts(GLOBAL);
while (1)
{
}
}
/* ********************************* Atencin a la interrupcin por cambio en RB0 ***************************************** */
#INT_EXT
void Activar_Motor()
{
rc5 = ~rc5;
}
Microcontroladores
Pgina 77
Aprendizaje de la Electrnica a travs de la Robtica - ARCE /* ********************** Atencin a la interrupcin por cambio en RB4,RB5,RB6 y RB7. ******************************** */
#INT_RB
void Led()
{
int n;
rc4 = ~rc4;
n = portB;
}
/* *********************************************** Motor Paso a Paso ************************************************************ */
void Motor_PAP (Void)
{
rc3 = 0;
rc2 = 0;
rc1 = 0;
rc0 = 1;
delay_ms(500);
// Retardo de 500 ms
rc3 = 0;
rc2 = 0;
rc1 = 1;
rc0 = 1;
delay_ms(500);
// Retardo de 500 ms
rc3 = 0;
rc2 = 0;
rc1 = 1;
rc0 = 0;
delay_ms(500);
// Retardo de 500 ms
rc3 = 0;
rc2 = 1;
rc1 = 1;
rc0 = 0;
delay_ms(500);
// Retardo de 500 ms
rc3 = 0;
rc2 = 1;
rc1 = 0;
rc0 = 0;
delay_ms(500);
// Retardo de 500 ms
rc3 = 1;
rc2 = 1;
rc1 = 0;
rc0 = 0;
delay_ms(500);
// Retardo de 500 ms
rc3 = 1;
rc2 = 0;
rc1 = 0;
rc0 = 0;
delay_ms(500);
// Retardo de 500 ms
rc3 = 1;
rc2 = 0;
rc1 = 0;
rc0 = 1;
delay_ms(500);
// Retardo de 500 ms
Microcontroladores
Pgina 78
// TRISC en 87h.
// PORTC en 07h.
// TRISB en 86h.
// PORTB en 06h.
// Activa el Motor.
// Encender Led.
// Motor_PAP.
TRISB = 0B11111111;
TRISC = 0B00000000;
portC = 0B00000000;
// Reseteamos el Puerto C.
port_b_pullups(TRUE);
n = portB;
RBIF = 0;
enable_interrupts(int_rb);
enable_interrupts(int_ext);
ext_int_edge(L_TO_H);
enable_interrupts(GLOBAL);
Microcontroladores
Pgina 79
{
Motor_PAP();
}
}
/* ******************************* Atencin a la interrupcin por cambio en RB0 ******************************************* */
#INT_EXT
void Activar_Motor(void)
{
int i;
for(i=0;i<10;i++)
{
rc5 = ~rc5;
delay_ms(1000);
}
}
/* ******************** Atencin a la interrupcin por cambio en RB4, RB5, RB6 y RB7. ******************************** */
#INT_RB
void Led(void)
{
int i;
for(i=0;i<5;i++)
{
rc4 = ~rc4;
delay_ms(500);
}
i = portB;
}
/* ********************************************** Motor Paso a Paso ************************************************************* */
void Motor_PAP (Void)
{
rc3 = 0;
rc2 = 0;
rc1 = 0;
rc0 = 1;
delay_ms(500);
// Retardo de 500 ms
rc3 = 0;
rc2 = 0;
rc1 = 1;
rc0 = 1;
delay_ms(500);
// Retardo de 500 ms
rc3 = 0;
rc2 = 0;
rc1 = 1;
rc0 = 0;
delay_ms(500);
// Retardo de 500 ms
rc3 = 0;
rc2 = 1;
rc1 = 1;
rc0 = 0;
delay_ms(500);
// Retardo de 500 ms
rc3 = 0;
rc2 = 1;
rc1 = 0;
Microcontroladores
Pgina 80
// Retardo de 500 ms
rc3 = 1;
rc2 = 1;
rc1 = 0;
rc0 = 0;
delay_ms(500);
// Retardo de 500 ms
rc3 = 1;
rc2 = 0;
rc1 = 0;
rc0 = 0;
delay_ms(500);
// Retardo de 500 ms
rc3 = 1;
rc2 = 0;
rc1 = 0;
rc0 = 1;
delay_ms(500);
// Retardo de 500 ms
5.3.6.1.- Timer 0.
Se trata de un
temporizador/contador de 8 bits.
La fuente de eventos puede ser
interna (Temporizador) o externa
(Contador de pulsos, patilla RA4)
TMR0)
Microcontroladores
Pgina 81
Aprendizaje de la Electrnica a travs de la Robtica - ARCE El tiempo o pulsos contados estn en funcin de esta frmula:
5.3.6.1.1.- Timer0_Contador.c
Microcontroladores
Pgina 82
// Incluimos el driver flex_lcd.c que contiene las funciones de control del LCD.
// TRISB en 86h.
// PORTB en 06h.
#define numero 5
// Inicializamos el LCD.
lcd_gotoxy(1,1);
printf(lcd_putc,"%3u",contador);
setup_timer_0(RTCC_DIV_4|RTCC_EXT_L_TO_H);
set_timer0(0);
while (TRUE)
{
do
{
contador = get_timer0();
// Leemos el Contador.
if(contador!=contador_anterior)
// Escribir en el el LCD si contador ha variado.
{
contador_anterior=contador;
// Preguntamos si ha llegado el final de
// la cuenta.
lcd_gotoxy(1,1);
printf(lcd_putc,"%3u",contador);
}
}
while(contador<=numero);
set_timer0(0);
}
}
Microcontroladores
Pgina 83
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Programa.....: Timer0_temporizador_multitarea_1.c
//
// Plataforma hw: Placa Monibot 16F877A
//
// Fecha........: Septiembre-2011
//
// Programador..: Pedro Alonso
//
// Descripcin..: Un programa principal activa un servo en 2 posiciones y cada 0.20ms
//
//
se interrumpe el programa principal y generamos una seal cuadrada
//
//
de 0,2 mS por la patilla RB0
//
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// *********************************** Directivas de Preprocesado ************************************
#include <16F877A.h>
#fuses XT,NOWDT,PUT,NOWRT
#use delay(clock= 1000000)
#include <Servo_Futaba_10bit.c>
int8 INICIO_CUENTA=61;
Microcontroladores
Pgina 84
Inicializacion_Futaba_RC1();
//while(1);
setup_timer_0(RTCC_DIV_128|RTCC_INTERNAL);
set_timer0(INICIO_CUENTA);
enable_interrupts(INT_TIMER0);
enable_interrupts(global);
while (1)
{
TH = 56;
Futaba_RC1(TH);
delay_ms(500);
}
}
/* ******************* Atencin a la interrupcin por desbordamiento del TIMER 0 ************************************** */
#INT_TIMER0
void Senal_Cuadrada (Void)
{
RB0 = ~RB0;
set_timer0(INICIO_CUENTA);
5.3.6.1.3.- Timer0_temporizador_multitarea_2.c
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Programa.....: Timer0_temporizador_multitarea_2.c
//
// Plataforma hw: Placa Monibot 16F877A
//
// Fecha........: Septiembre-2011
//
// Programador..: Pedro Alonso
//
// Descripcin..: Un programa principal activa un servo en 2 posiciones y cada 0.25ms
//
//
se interrumpe el programa principal y simula las luces del coche fantstico. //
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Microcontroladores
Pgina 85
#include <Servo_Futaba_10bit.c>
int8 INICIO_CUENTA=12;
Inicializacion_Futaba_RC1();
//while(1);
setup_timer_0(RTCC_DIV_256|RTCC_INTERNAL);
set_timer0(INICIO_CUENTA);
enable_interrupts(INT_TIMER0);
enable_interrupts(global);
while (1)
{
TH = 56;
Futaba_RC1(TH);
delay_ms(500);
}
}
Microcontroladores
Pgina 86
Aprendizaje de la Electrnica a travs de la Robtica - ARCE /* **************** Atencin a la interrupcin por desbordamiento del TIMER 0 ***************************************** */
#INT_TIMER0
void coche_fantastico (Void)
{
#DEFINE DERECHA 0
#DEFINE IZQUIERDA 1
static int8 ir=derecha;
switch (ir)
{
case 0:
portB<<=1;
if(portB==128) ir=IZQUIERDA;
break;
case 1:
portB>>=1;
if(portB==1) ir=DERECHA;
break;
}
set_timer0(INICIO_CUENTA);
5.3.6.2.- Timer 1.
Microcontroladores
Pgina 87
Aprendizaje de la Electrnica a travs de la Robtica - ARCE Se puede trabajar en modo POLLING (Preguntando si TMR1IF =1 constantemente por un valor del
o interrupcin si TMR1IF =1(Para ello es necesario que estas estn activadasTMR1IE=1 y
registro TMR1)
GIE=1).
5.3.6.2.1.- Timer1_Contador.c
Microcontroladores
Pgina 88
// Incluimos el driver flex_lcd.c que contiene las funciones de control del LCD.
// inicializamos LCD
//setup_timer_1(T1_EXTERNAL|T1_DIV_BY_1);
setup_timer_1(T1_EXTERNAL|T1_DIV_BY_2);
while (TRUE)
{
set_timer1(0);
Do
{
contador = get_timer1();
//delay_ms(200);
// Leemos el Contador.
lcd_gotoxy(1,1);
printf(lcd_putc,"%2lu",contador);
}
While (contador<= pulsos);
}
}
5.3.6.2.2.- Timer1_temporizador_multitarea.c
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Programa.....: Timer1_temporizador_multitarea.c
//
// Plataforma hw: Placa Monibot 16F877A
//
// Fecha........: Septiembre-2011
//
// Programador..: Pedro Alonso
//
// Descripcin..: Un programa principal realiza la simulacin del coche fantstico y se
//
//
interrumpe cada 100 mS realizando una conversin analgica/digital
//
//
por AN0 y muestra su valor en tensin en el LCD.
//
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// *********************************** Directivas de Preprocesado ************************************
#include <16F877A.h>
#device adc=10
#fuses XT,NOWDT,PUT,NOWRT
#use delay(clock= 1000000)
#include <flex_lcd.c>
Microcontroladores
// Incluimos el driver LCD1.c que contiene las funciones de control del LCD.
Pgina 89
setup_adc_ports(4);
// Inicializamos el LCD.
enable_interrupts(INT_TIMER1);
enable_interrupts(global);
}
}
Microcontroladores
Pgina 90
Aprendizaje de la Electrnica a travs de la Robtica - ARCE /* **************************** Atencin a la interrupcin por desbordamiento del TIMER 1 ***************************** */
#INT_TIMER1
void Voltimetro (Void)
{
int16 q;
float p;
set_adc_channel(0);
delay_us(5);
q = read_adc();
p = 5.0 * q / 1024.0;
lcd_gotoxy(1,1);
printf(lcd_putc, "V1=%01.3fv", p);
set_timer1(inicio_cuenta);
5.3.6.3.- Timer 2.
Se trata de un temporizador de 8
bits con pre-escala y post-escala.
Cuenta ciclos de instruccin
(Fosc=4). Se activa con
T2CON.TMR2ON = 1
Pre-escala seleccionable entre 1:1,
1:4 1:16 mediante
T2CON.T2CKPS1:T2CKPS0.
Dispone de un registro periodo PR2
El registro TMR2
se incrementa partiendo de cero hasta
alcanzar PR2.
(Configurable de 0 a 255).
La salida del temporizador TMR2 pasa por una post-escala programable: 1:1 ...1:16
(T2CON.TOUTPS3:TOUTPS0) antes de generar una interrupcin.
Genera interrupciones si:
Cuando el campo PIR1.TMR2IF = 1, indica que se alcanz el periodo. Hay que borrarlo
despus. (Cuando TMR2 se iguala con PR2, teniendo en cuenta el Prescaler y Postscaler)
El tiempo o pulsos contados estn en funcin de esta frmula:
Microcontroladores
Pgina 91
5.3.6.3.1.- Timer2_Seal_Cuadrada.c
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Programa.....: Timer2_Seal_Cuadrada.c
//
// Plataforma hw: Placa Monibot 16F877A
//
// Fecha........: Septiembre-2011
//
// Programador..: Pedro Alonso
//
// Descripcin..: Generar una seal cuadrada de 1 KHz
//
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// ********************************* Directivas de Preprocesado **************************************
#INCLUDE <16F877A.h>
#use delay(clock=20000000)
#fuses XT,NOWDT
#BYTE TRISB = 0x86
#BYTE portB = 0x06
// TRISB en 86h.
// PORTB en 06h.
Microcontroladores
Pgina 92
portB = 0B00000000;
// Reseteamos el Puerto B.
setup_timer_2(T2_DIV_BY_4,124,5);
// setup_timer(Prescaler,PR2,Postscaler)
// Configuracin timer2. Si el Periodo = 1mS ----> T = 500uS
// T = Tcm[Prescaler x(PR2+1)x Postscaler]
// PR2 puede valer de 0 a 255.
// Tcm es el tiempo de Ciclo Maquina.
// Tcm = 4/Fosc = 4/20.000.000 hz = 0,2uS.
// Prescaler puede valer 1,4,16
// Postscaler puede valer 1,2,3,...,15,16.
// 500uS = 0,2uS[1.(PR2+1)1]
// PR2 =[T/(Tcm x Preescaler x Postscaler)]-1
// PR2 =[500uS/(0,2uS x 4 x 5)]-1 = 124
enable_interrupts(INT_TIMER2);
enable_interrupts(global);
while (1);
// bucle infinito
}
/* ************************** Atencin a la interrupcin por desbordamiento del TIMER 2 ****************************** */
#int_TIMER2
void Timer2 (void)
{
rb0 = ~rb0;
}
5.3.6.3.2.- Timer2_Servos_Posicion.c
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Programa.....: Timer2_Servos_Posicion.c
//
// Plataforma hw: Placa Monibot 16F877A
//
// Fecha........: Septiembre-2011
//
// Programador..: Pedro Alonso
//
// Descripcin..: Control de 4 Servomotores de Posicin va software
//
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// ********************************** Directivas de Preprocesado *************************************
#INCLUDE <16F877A.h>
#device adc=8
#use delay(clock=20000000)
#fuses XT,NOWDT
// TRISD en 88h.
// PORTD en 08h.
Microcontroladores
Pgina 93
portD = 0B00000000;
// Reseteamos el Puerto D.
setup_timer_2(T2_DIV_BY_1,199,1);
// setup_timer(Prescaler,PR2,Postscaler)
// Configuracin timer2. T = 40uS
// T = Tcm[Prescaler x(PR2+1)x Postscaler]
// PR2 puede valer de 0 a 255.
// Tcm es el tiempo de Ciclo Maquina.
// Tcm = 4/Fosc = 4/20.000.000 hz = 0,2uS.
// Prescaler puede valer 1,4,16
// Postscaler puede valer 1,2,3,...,15,16.
// 40uS = 0,2uS[1.(PR2+1)1]
// PR2 =[T/(Tcm x Preescaler x Postscaler)]-1
// PR2 =[40uS/(0,2uS x 1 x 1)]-1 = 199
setup_adc(ADC_CLOCK_INTERNAL);
setup_adc_ports(0);
enable_interrupts(INT_TIMER2);
enable_interrupts(global);
while (1)
{
// bucle infinito
set_adc_channel(0);
delay_us(5);
h1 = read_adc();
h1=(h1/5)+15;
if(h1>60) h1=60;
l1=400-h1;
set_adc_channel(1);
delay_us(5);
h2 = read_adc();
h2=(h2/5)+15;
if(h2>60) h2=60;
l2=400-h2;
set_adc_channel(2);
delay_us(5);
h3 = read_adc();
h3=(h3/5)+15;
if(h3>60) h3=60;
l3=400-h3;
set_adc_channel(3);
delay_us(5);
h4 = read_adc();
h4=(h4/5)+15;
if(h4>60) h4=60;
l4=400-h4;
Timer2 (h1,l1,h2,l2,h3,l3,h4,l4);
}
}
Microcontroladores
Pgina 94
Aprendizaje de la Electrnica a travs de la Robtica - ARCE /* ******************************* Atencin a la interrupcin por desbordamiento del TIMER 2 ************************** */
int_TIMER2
void Timer2 (int16 h1,int16 l1,int16 h2,int16 l2,int16 h3,int16 l3,int16 h4,int16 l4)
{
int16 th1,tl1,th2,tl2,th3,tl3,th4,tl4;
// ************************************* Control del Servomotor 1 ********************************
if(th1<h1)
{
rd0 = 1;
th1++;
}
else
{
if(tl1<l1)
{
rd0 = 0;
tl1++;
}
else
{
th1=0;
tl1=0;
}
}
// ************************************* Control del Servomotor 2 ********************************
if(th2<h2)
{
rd1 = 1;
th2++;
}
else
{
if(tl2<l2)
{
rd1 = 0;
tl2++;
}
else
{
th2=0;
tl2=0;
}
}
// ************************************* Control del Servomotor 3 ********************************
if(th3<h3)
{
rd2 = 1;
th3++;
}
else
{
if(tl3<l3)
{
rd2 = 0;
tl3++;
}
else
{
th3=0;
tl3=0;
}
}
Microcontroladores
Pgina 95
Aprendizaje de la Electrnica a travs de la Robtica - ARCE // ************************************* Control del Servomotor 4 ********************************
if(th4<h4)
{
rd3 = 1;
th4++;
}
else
{
if(tl4<l4)
{
rd3 = 0;
tl4++;
}
else
{
th4=0;
tl4=0;
}
}
}
El dato a transmitir se
deposita en TXREG.
Cuando se termina de
transmitir el dato anterior se
traslada automticamente
al registro de desplazamiento
TSR y se indica con
PIR1.TXIF (TXREG vaco). Si
PIE1.TXIE = 1 se produce
una interrupcin para
recargarlo.
Microcontroladores
Pgina 96
Si se recibe un tercer dato sin haber ledo los anteriores se producir un error de
desbordamiento (RCSTA.OERR = 1) y se inhibirn futuras recepciones hasta que
se borre.
5.3.7.1.- Cable.
Utilizaremos el entrenador Simulacin del TRANSMISOR-RECEPTOR_Cable.DSN
contenido en la carpeta de Transmisin Serie Asncrona\ Cable.
Microcontroladores
Pgina 97
while(1)
{
// bucle infinito.
ra0= portA & 0B00000001;
if (ra0!=ra0_anterior)
{
ra0_anterior=ra0;
if(ra0==0)
{
dato=0B00000001;
// dato=1
dato=0B00001101;
// dato=13
}
else
{
}
putc(dato);
delay_ms(100);
}
}
}
5.3.7.1.2.- Recepcin_Serie_Polling.c
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Programa.....: Recepcin_Serie_Polling.c
//
// Plataforma hw: Placa Monibot
//
// Fecha........: Septiembre-2011
//
// Programador..: Pedro Alonso Sanz
//
// Descripcin..: Cuando el dato recibido va serie es "1" escribimos "Si" en el LCD
//
//
Cuando el dato recibido va serie es "13" escribimos "No" en el LCD
//
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Microcontroladores
Pgina 98
#include <flex_lcd.c>
int8 dato=0;
// Inicializamos el LCD.
while(1)
{
dato=getc();
if(dato==1)
{
lcd_gotoxy(1,1);
printf(lcd_putc,"Si");
}
if(dato==13)
{
lcd_gotoxy(1,1);
printf(lcd_putc,"No");
}
}
}
5.3.7.1.3.- Recepcin_Serie_Interrupcin.c
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Programa.....: Recepcin_Serie_Interrupcin.c
//
// Plataforma hw: Placa Monibot
//
// Fecha........: Septiembre-2011
//
// Programador..: Pedro Alonso Sanz
//
// Descripcin..: Un programa principal simula las luces del coche fantstico
//
//
Cuando se recibe va serie un "1" en el LCD aparecera "Si"
//
//
Cuando se recibe va serie un "13" en el LCD aparecera "No"
//
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// ********************************** Directivas de Preprocesado *************************************
#include <16F877A.h>
#FUSES XT,NOWDT
#use delay(clock=1000000)
#use rs232(baud=4800,xmit=pin_c6, rcv=pin_c7)
#include <flex_lcd.c>
// TRISB en 86h.
// PORTB en 06h.
Microcontroladores
Pgina 99
portB = luces;
delay_ms(100);
// inicializamos el puerto B.
// Retraso.
lcd_init();
// Inicializamos el LCD.
// Escribimos mensaje.
enable_interrupts(INT_RDA);
enable_interrupts(GLOBAL);
while(1)
{
}
}
/************************************************** Coche_Fantastico *************************************************************/
void Coche_Fantastico (void)
{
int8 n=0;
for (n=0;n<7;n++)
{
luces<<=1;
portB=luces;
delay_ms(100);
}
for (n=7;n>0;n--)
{
luces>>=1;
portB=luces;
delay_ms(100);
}
}
/* ***************************** Atencin a la interrupcin por recepcin serie de datos ********************************* */
#int_RDA
void Leer_dato_serie (void)
{
static int8 dato_recibido=0;
dato_recibido=getc();
if(dato_recibido==1)
{
lcd_gotoxy(1,2);
printf(lcd_putc,"Si");
}
if(dato_recibido==13)
{
lcd_gotoxy(1,2);
printf(lcd_putc,"No");
}
Microcontroladores
Pgina 100
// TRISB en 86h.
// TRISB en 86h.
#define CLAVE_RA0 63
#define CLAVE_RA1 135
int8 ra0=0;
int8 ra0_anterior=0;
int8 ra1=0;
int8 ra1_anterior=0;
int8 dato=0;
while(1)
{
// bucle infinito.
ra0= portA & 0B00000001;
if (ra0!=ra0_anterior)
{
ra0_anterior=ra0;
if(ra0==0)
{
dato=0B00000001;
// dato=1
dato=0B00001101;
// dato=13
}
else
{
}
putc(CLAVE_RA0);
delay_ms(5);
putc(dato);
delay_ms(50);
}
ra1= portA & 0B00000010;
if (ra1!=ra1_anterior)
{
ra1_anterior=ra1;
Microcontroladores
Pgina 101
// dato=0
dato=56;
// dato=56
}
else
{
}
putc(CLAVE_RA1);
delay_ms(5);
putc(dato);
delay_ms(5);
}
}
}
5.3.7.1.5.- Recepcin_Serie_Interrupcin_Multitarea.c
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Programa.....: Recepcin_Serie_Interrupcin_Multitarea.c
//
// Plataforma hw: Placa Monibot
//
// Fecha........: Septiembre-2011
//
// Programador..: Pedro Alonso Sanz
//
// Descripcin..: Un programa principal simula las luces del coche fantstico
//
//
Cuando se recibe va serie la clave "63" y el dato "1" en el LCD aparecer "Si"
//
//
Cuando se recibe va serie la clave "63" y el dato "13" en el LCD aparecer "No" //
//
Cuando se recibe va serie la clave "135" y el dato "0" el Servomotor de
//
//
Posicin se posicionara en -90.
//
//
Cuando se recibe va serie la clave "135" y el dato "56" el Servomotor de
//
//
Posicin se posicionara en 0.
//
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// ********************************** Directivas de Preprocesado *************************************
#include <16F877A.h>
#FUSES XT,NOWDT
#use delay(clock=1000000)
#include <flex_lcd.c>
#include <Servo_Futaba_10bit.c>
de los Servos de Futaba.
#BYTE TRISB = 0x86
#BYTE portB = 0x06
// TRISB en 86h.
// PORTB en 06h.
#define CLAVE_RA0 63
#define CLAVE_RA1 135
int8 luces=0B00000001;
/* ********************************************** Declaracin de funciones ***************************************************** */
void Coche_Fantastico (void);
void Leer_dato_serie (void);
void Mensaje_LCD (int8);
void Posicion_Servo (int8);
Microcontroladores
Pgina 102
Aprendizaje de la Electrnica a travs de la Robtica - ARCE // **************************** Funcin principal o programa principal ******************************
void main()
{
TRISB = 0B00000000;
portB = luces;
delay_ms(100);
// inicializamos el puerto B.
// Retraso.
lcd_init();
// Inicializamos el LCD.
// Escribimos mensaje.
Inicializacion_Futaba_RC1();
enable_interrupts(INT_RDA);
enable_interrupts(GLOBAL);
while(1)
{
}
}
/************************************************** Coche_Fantastico *************************************************************/
void Coche_Fantastico (void)
{
int8 n=0;
for(n=0;n<7;n++)
{
luces<<=1;
portB=luces;
delay_ms(100);
}
for(n=7;n>0;n--)
{
luces>>=1;
portB=luces;
delay_ms(100);
}
}
/* ******************************** Atencin a la interrupcin por recepcin serie de datos ****************************** */
#int_RDA
void Leer_dato_serie (void)
{
#DEFINE ES_CLAVE_RA0 0
#DEFINE ES_CLAVE_RA1 1
#DEFINE IR_LCD 2
#DEFINE IR_SERVO 3
static int8 caso=ES_CLAVE_RA0;
static int8 dato_recibido=0;
dato_recibido=getc();
switch (caso)
// Preguntamos por la variable "ir" si es 0 ejecuta el case 0, si es 1 el case 1,
{
case ES_CLAVE_RA0:
if(dato_recibido==CLAVE_RA0)
{
caso=IR_LCD;
}
case ES_CLAVE_RA1:
if(dato_recibido==CLAVE_RA1)
Microcontroladores
Pgina 103
caso=ES_CLAVE_RA0;
break;
case IR_SERVO:
Posicion_Servo (dato_recibido);
// Posicionar el Sevomotor.
caso=ES_CLAVE_RA0;
break;
default:
caso=ES_CLAVE_RA0;
}
}
/* ************************************************ Funcin Mensaje_LCD ****************************************************** */
void Mensaje_LCD (int8 dato)
{
if(dato==1)
{
lcd_gotoxy(1,2);
printf(lcd_putc,"Si");
}
if(dato==13)
{
lcd_gotoxy(1,2);
printf(lcd_putc,"No");
}
}
/* ******************************************* Funcin Posicion_Servo ********************************************************* */
void Posicion_Servo (int8 TH)
{
Futaba_RC1(TH);
}
// Posicionar el Sevomotor.
// Posicionar el Servo de la patilla RC1.
5.3.7.1.6.- Transmisin_Serie_Multitarea_1.c
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Programa.....: Transmisin_Serie_Multitarea_1.c
//
// Plataforma hw: Placa Monibot
//
// Fecha........: Septiembre-2011
//
// Programador..: Pedro Alonso Sanz
//
// Descripcin..: Si RA0=0 transmito via serie el 1
//
//
Si RA0=1 transmito via serie un 13
//
//
Si RA1=0 transmito via serie un 30
//
//
Si RA1=1 transmito via serie un 90
//
//
Si RA2=0 transmito via serie un 20
//
//
Si RA2=1 transmito via serie un 80
//
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// ********************************** Directivas de Preprocesado *************************************
#include <16F877A.h>
Microcontroladores
Pgina 104
// TRISB en 86h.
// TRISB en 86h.
while(1)
{
// bucle infinito.
// ****************************** Transmisin de RA0 ***************************************************
if (ra0!=ra0_anterior)
{
ra0_anterior=ra0;
if(ra0==0)
{
informacion_LCD=0B00000001;
// informacion_LCD=1
informacion_LCD=0B00001101;
// informacion_LCD=13
}
else
{
}
putc(CLAVE_LCD);
delay_ms(1);
putc(informacion_LCD);
delay_ms(1);
}
if(ra1==0)
{
informacion_SERVO1=30;
// informacion_SERVO=30
informacion_SERVO1=90;
// informacion_SERVO=90
}
else
{
}
putc(CLAVE_SERVO1);
delay_ms(1);
Microcontroladores
Pgina 105
delay_ms(1);
}
if(ra2==0)
{
informacion_SERVO2=20;
// informacion_SERVO2=20
informacion_SERVO2=80;
// informacion_SERVO2=80
}
else
{
}
putc(CLAVE_SERVO2);
delay_ms(1);
putc(informacion_SERVO2);
delay_ms(1);
}
}
}
5.3.7.1.7.- Recepcin_Serie_Interrupcin_Multitarea_1.c
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Programa.....: Recepcin_Serie_Interrupcin_Multitarea.c
//
// Plataforma hw: Placa Monibot
//
// Fecha........: Septiembre-2011
//
// Programador..: Pedro Alonso Sanz
//
// Descripcin..: Un programa principal simula las luces del coche fantstico
//
//
Cuando se recibe va serie la clave "63" y el dato "1" en el LCD aparecer "Si"
//
//
Cuando se recibe va serie la clave "63" y el dato "13" en el LCD aparecer "No"
//
//
Cuando se recibe va serie la clave "135" y el dato "30" el Servomotor 1 de
//
//
Posicin se posicionar en 42
//
//
Cuando se recibe va serie la clave "135" y el dato "90" el Servomotor 1 de
//
//
Posicin se posicionar en 53
//
//
Cuando se recibe va serie la clave "135" y el dato "20" el Servomotor 2 de
//
//
Posicin se posicionar en 37
//
//
Cuando se recibe va serie la clave "135" y el dato "80" el Servomotor 2 de
//
//
Posicin se posicionar en 58
//
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// *********************************** Directivas de Preprocesado ************************************
#include <16F877A.h>
#FUSES XT,NOWDT
#use delay(clock=1000000)
#include <flex_lcd.c>
#include <Servo_Futaba_10bit.c>
Microcontroladores
Pgina 106
// TRISB en 86h.
// PORTB en 06h.
#define CLAVE_LCD 63
#define CLAVE_SERVO1 135
#define CLAVE_SERVO2 211
int8 luces=0B00000001;
/* ********************************************** Declaracin de funciones ***************************************************** */
void Coche_Fantastico (void);
void Leer_dato_serie (void);
void Mensaje_LCD (int8);
void Posicion_Servo1 (int8);
void Posicion_Servo2 (int8);
portB = luces;
delay_ms(100);
// inicializamos el puerto B.
// Retraso.
lcd_init();
// Inicializamos el LCD.
// Escribimos mensaje.
Inicializacion_Futaba_RC1();
Inicializacion_Futaba_RC2();
enable_interrupts(INT_RDA);
enable_interrupts(GLOBAL);
while(1)
{
Coche_Fantastico ();
}
}
/************************************************** Coche_Fantastico *************************************************************/
void Coche_Fantastico (void)
{
int8 n=0;
for(n=0;n<7;n++)
{
luces<<=1;
portB=luces;
delay_ms(100);
}
for(n=7;n>0;n--)
{
luces>>=1;
portB=luces;
delay_ms(100);
}
}
/* ******************************** Atencin a la interrupcin por recepcin serie de datos ****************************** */
#int_RDA
void Leer_dato_serie (void)
{
#DEFINE ES_PROCESO_LCD 0
#DEFINE ES_PROCESO_SERVO1 1
#DEFINE ES_PROCESO_SERVO2 2
#DEFINE IR_LCD 3
Microcontroladores
Pgina 107
switch (caso)
// Preguntamos por la variable "ir" si es 0 ejecuta el case 0, si es 1 el case 1,
{
case ES_PROCESO_LCD:
if(dato_recibido==CLAVE_LCD)
{
caso=IR_LCD;
}
case ES_PROCESO_SERVO1:
if(dato_recibido==CLAVE_SERVO1)
{
caso=IR_SERVO1;
}
case ES_PROCESO_SERVO2:
if(dato_recibido==CLAVE_SERVO2)
{
caso=IR_SERVO2;
}
break;
case IR_LCD:
Mensaje_LCD (dato_recibido);
caso=ES_PROCESO_LCD;
break;
case IR_SERVO1:
Posicion_Servo1 (dato_recibido);
caso=ES_PROCESO_LCD;
break;
// Posicionar el Sevomotor 1.
case IR_SERVO2:
Posicion_Servo2 (dato_recibido);
caso=ES_PROCESO_LCD;
break;
// Posicionar el Sevomotor 2.
default:
caso=ES_PROCESO_LCD;
}
}
/* ******************************************* Funcin Mensaje_LCD ****************************************************** */
void Mensaje_LCD (int8 dato)
{
if(dato==1)
{
lcd_gotoxy(1,2);
printf(lcd_putc,"Si");
}
if(dato==13)
{
lcd_gotoxy(1,2);
printf(lcd_putc,"No");
}
Microcontroladores
Pgina 108
// Posicionar el Servomotor 1.
// Posicionar el Servo de la patilla RC1.
// Posicionar el Servomotor 2.
// Posicionar el Servo de la patilla RC2.
5.3.7.2.- Radiofrecuencia.
5.3.7.2.0.- Modulacin en AM.
Es introducir una seal moduladora (En nuestro caso una seal cuadrada
procedente de la transmisin serie de datos) en la Amplitud de la portadora.
La Tarjeta Transmisora de Datos CEBEK C-0503 es un circuito hbrido encargado de
transmitir va radiofrecuencia, los datos digitales SERIE procedentes de la patilla RC6/TX del
microcontrolador PIC 16f876a del mando. La seal digital tiene que tener una frecuencia entre
20 Hz < fo < 4 KHz. Y se modular con una portadora de 433,92 MHz.
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 C0503 genera una seal de AM con esta seal moduladora.
Microcontroladores
Pgina 109
Microcontroladores
Pgina 110
Aprendizaje de la Electrnica a travs de la Robtica - ARCE 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.
Microcontroladores
Pgina 111
// TRISA en 85h.
// PORTA en 05h.
#define Clave_Pulsadores 63
// ****************************************** Funcin principal o programa principal *******************************************
void main()
{
int8 i=1;
int8 q;
TRISA = 0B11111111;
while(1)
{
// bucle infinito.
q= portA & 0B00111111;
q=q | 0B11000000;
q=~q;
if (q!=0B00000000)
{
putc(Clave_Pulsadores);
putc(q);
}
}
}
// TRISA en 85h.
// PORTA en 05h.
// cambio1 en 0x20h.
#BIT c0 = 0x20.0
#BIT c1 = 0x20.1
#BIT c2 = 0x20.2
#BIT c3 = 0x20.3
// c0 en 0x20.0
// c1 en 0x20.1
// c2 en 0x20.2
// c3 en 0x20.3
Microcontroladores
Pgina 112
// c4 en 0x20.4
// c5 en 0x20.5
#define Clave_Pulsadores 63
#define Numero_Repeticiones 10
TRISA = 0B11111111;
cambio=0;
while(1)
{
// bucle infinito.
q= portA & 0B00111111;
q=q | 0B11000000;
q=~q;
if (q!=0B00000000)
{
if (ra0==0) c0=~c0;
if (ra1==0) c1=~c1;
if (ra2==0) c2=~c2;
if (ra3==0) c3=~c3;
if (ra4==0) c4=~c4;
if (ra5==0) c5=~c5;
for(i=1;i<=Numero_Repeticiones;i++)
{
putc(Clave_Pulsadores);
putc(cambio);
}
delay_ms(500);
// Enviamos va serie la
// Clave_Pulsador.
// Enviamos va serie la variable
// cambio.
}
}
}
5.3.7.2.3.- Recepcin_Serie_Radiofrecuencia_1.c
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Programa.....: Recepcin_Serie_Radiofrecuencia_1.c
//
// Plataforma hw: MONIBOT
//
// Fecha........: Septiembre-2011
//
// Programador..: Pedro Alonso Sanz
//
// Descripcin..: Recepcin de un dato va serie con tarjeta de radiofrecuencia
//
//
Un programa principal representa en el LCD el pulsador activado del
//
//
mando de radiofrecuencia.
//
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// ********************************* Directivas de Preprocesado **************************************
#include <16F877A.h>
#FUSES XT,NOWDT
#use delay(clock=4000000)
#use rs232(baud=9600,xmit=pin_c6, rcv=pin_c7)
#include <flex_lcd.c>
Microcontroladores
Pgina 113
// dato en 0x20h.
#BIT d0 = 0x22.0
#BIT d1 = 0x22.1
#BIT d2 = 0x22.2
#BIT d3 = 0x22.3
#BIT d4 = 0x22.4
#BIT d5 = 0x22.5
// 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_Pulsadores 63
int8 dato_recibido;
int8 dato_anterior=0;
/* ********************************************** Declaracin de funciones ***************************************************** */
void Leer_dato_serie (void);
// Leer Dato.
// Inicializamos el LCD.
// Escribimos mensaje.
lcd_gotoxy(1,2);
while(1)
{
printf(lcd_putc,"%1u%1u%1u%1u%1u%1u",d5,d4,d3,d2,d1,d0);
// Escribimos 5
// variables
// "Pulsadores del
// mando"
}
}
}
/* ******************************* 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)
{
static int8 numero_datos1=0;
static int8 dato1=0;
dato_recibido=getc();
Microcontroladores
Pgina 114
{
case 0:
if(dato_recibido==Clave_Pulsadores)
{
numero_datos1=1;
}
break;
case 1:
dato1=dato_recibido;
numero_datos1=2;
break;
case 2:
if(dato_recibido==Clave_Pulsadores)
{
numero_datos1=3;
}
else
{
numero_datos1=0;
}
break;
case 3:
if(dato_recibido==dato1)
{
dato_valido=dato_recibido;
}
numero_datos1=0;
}
}
Microcontroladores
Pgina 115
// TRISB en 86h.
// PORTB en 06h.
int8 i=1;
int8 q;
TRISB = 0B11111111;
TC3 = 0;
RC3 = 1;
setup_adc(ADC_CLOCK_INTERNAL);
setup_adc_ports(0);
while(1)
{
if (rb5==1)
// Si se Cierra el Interruptor de rb5 no transmitir ms datos.
{
//**************** Transmisin de datos "Potencimetro Derecho" ************************
set_adc_channel(0);
delay_us(20);
q = read_adc();
if (cambio0!=q)
{
cambio0=q;
RC3 = 0;
Microcontroladores
Pgina 116
{
putc(Clave_Pot_Der);
putc(q);
}
RC3 = 1;
// Enviamos va serie la
// Clave_Pot_Der.
// Enviamos va serie la variable q.
// (Tensin digitalizada del
// Potencimetro Derecho)
}
//**************** Transmisin de datos "Potencimetro Izquierdo" ***********************
set_adc_channel(1);
delay_us(20);
q = read_adc();
if (cambio1!=q)
{
cambio1=q;
RC3 = 0;
for(i=1;i<=Numero_Repeticiones;i++)
{
putc(Clave_Pot_Izq);
putc(q);
}
RC3 = 1;
// Enviamos va serie la
// Clave_Pot_Der.
// Enviamos va serie la variable q.
// (Tensin digitalizada del
// Potencimetro Izquierdo)
}
//********************* Transmisin de datos "Pulsadores" ***********************************
q= portB & 0B00111111;
if (q!=0B00111111)
{
RC3 = 0;
for(i=1;i<=Numero_Repeticiones;i++)
{
putc(Clave_Pulsadores);
putc(~q);
}
RC3 = 1;
// Enviamos va serie la
// Clave_Pulsadores.
// Enviamos va serie la variable q
// invertida.(Pulsador Activado)
}
}
}
}
5.3.7.3.2.- Transmisin_Serie_RF_Multitarea_2.c
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Programa.....: Transmisin_Serie_RF_Multitarea_2.c
//
// Plataforma hw: MONIBOT
//
// Fecha........: Septiembre-2011
//
// Programador..: Pedro Alonso Sanz
//
// Descripcin..: Transmisin serie va radiofrecuencia (Pulsadores y Potencimetros)
//
//
se conserva los datos de las pulsaciones anteriores.
//
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Microcontroladores
Pgina 117
// 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
// c5 en 0x20.5
int8 i=1;
int8 q;
int1 rb5_1=0;
cambio2=0;
TRISB = 0B11111111;
TC3 = 0;
RC3 = 1;
setup_adc(ADC_CLOCK_INTERNAL);
setup_adc_ports(0);
while(1)
{
Microcontroladores
Pgina 118
{
cambio0=q;
RC3 = 0;
for(i=1;i<=Numero_Repeticiones;i++)
{
putc(Clave_Pot_Der);
putc(q);
}
RC3 = 1;
}
//******************* Transmisin de datos "Potencimetro Izquierdo" ********************************
set_adc_channel(1);
delay_us(20);
q = read_adc();
if (cambio1!=q)
{
cambio1=q;
RC3 = 0;
for(i=1;i<=Numero_Repeticiones;i++)
{
putc(Clave_Pot_Izq);
putc(q);
}
RC3 = 1;
}
//*********************** Transmisin de datos "Pulsadores" ********************************************
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;
// Enviamos va serie la
// Clave_Pulsadores.
// Enviamos va serie la variable
// cambio2. (Pulsador Activado)
}
//**************************** Transmisin de datos "Interruptor" ****************************************
if (rb5!=rb5_1)
{
rb5_1=rb5;
c5=~rb5;
Microcontroladores
Pgina 119
for(i=1;i<=Numero_Repeticiones;i++)
{
putc(Clave_Pulsadores);
putc(cambio2);
}
RC3 = 1;
// Enviamos va serie la
// Clave_Pulsadores.
// Enviamos va serie la variable
// cambio2. (Interruptor Activado)
}
}
}
5.3.7.3.3.- Recepcin_Serie_RF_Multitarea.c
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Programa.....: Recepcin_Serie_RF_Multitarea.c
//
// Plataforma hw: MONIBOT
//
// Fecha........: Septiembre-2011
//
// Programador..: Pedro Alonso Sanz
//
// Descripcin..: Recepcin de datos va serie con tarjeta de radiofrecuencia (Multitarea)
//
//
Un programa principal est en modo sueo
//
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// ********************************* Directivas de Preprocesado **************************************
#include <16F877A.h>
#FUSES XT,NOWDT
#use delay(clock=4000000)
#use rs232(baud=2400,xmit=pin_c6, rcv=pin_c7)
// TRISD en 88h.
// PORTD en 08h.
// TRISC en 87h.
// PORTC en 07h.
// TRISB en 86h.
// PORTB en 06h.
// Definimos claves.
// Inicializamos variables
Microcontroladores
// Leer Dato.
// Valida los datos serie procedentes de los Pulsadores.
// Valida los datos serie procedentes del Potencimetro Derecho.
// Valida los datos serie procedentes del Potencimetro Izquierdo.
Pgina 120
portD = 0B00000000;
portC = 0B00000000;
portB = 0B00000000;
// Reseteamos el Puerto D.
// Reseteamos el Puerto C.
// Reseteamos el Puerto B.
enable_interrupts(INT_RDA);
enable_interrupts(GLOBAL);
while(1)
{
}
}
/* ************************* 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();
}
/*********************************************Funcin Automata_Pulsadores ************************************************* */
void Automata_Pulsadores(void)
{
static int8 numero_datos=0;
static int8 dato=0;
switch (numero_datos)
{
case 0:
if(dato_recibido==Clave_Pulsadores)
{
numero_datos=1;
valido_Aut_Pot_Der=0;
valido_Aut_Pot_Izq=0;
}
Microcontroladores
Pgina 121
{
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;
}
}
Microcontroladores
Pgina 122
{
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)
numero_datos=0;
valido_Aut_Pul=1;
valido_Aut_Pot_Der=1;
portB=dato_recibido;
}
}
Modo I2C (Inter-Integrated Circuit). Las patillas asociadas a este modo sern
RC3/SCL y RC4/SDA.
5.3.8.1.- I2C.
Microcontroladores
Pgina 123
Modos de operacin:
Funcionamiento:
El compilador C de CCS nos proporciona unas funciones para trabajar con I2C. Para
entender mejor lo explicado utilizaremos unos ejemplos.
Microcontroladores
Pgina 124
5.3.8.1.1.1.- PCF8574_1.
Utilizaremos el entrenador PCF8574_1.DSN contenido en la carpeta de I2C\
Expansor_Bus_PCF8574\ PCF8574_1.
Microcontroladores
Pgina 125
// Configuracin de I2C
// Definimos el PIC como maestro
// Forzamos a trabajar con su hardware
// interno.(Asociado a I2C)
// Trabajamos a velocidad baja 100 Kbps
// Elegimos sda=PIN_C4 como patilla de datos.
// Elegimos scl=PIN_C3 como patilla de reloj.
void Escritura(int8);
Escritura(~dato_recibido);
delay_ms(1);
}
}
/* ******************************** Funcin de int8 Lectura_Interruptores() ************************************************* */
int8 Lectura_Interruptores()
{
int8 data;
i2c_start();
i2c_write(0B01000001);
// Inicializa la recepcin.
// Seleccionar esclavo U4 en modo lectura. ( 0100,A2,A1,A0,1 )
// (0100) identifica al C.I. PCF8476.
// (A2,A1,A0)=(000) por hardware.
// El ultimo bit a 1 para poner el C.I. PCF8476 en modo lectura.
data=i2c_read(0);
i2c_stop();
return(data);
}
/* ****************************** Funcin de Escritura(int8 dato_recibido) ************************************************** */
void Escritura(int8 dato_recibido)
{
i2c_start();
i2c_write(0x48);
Microcontroladores
// Inicializa la transmisin
// Seleccionar esclavo U3 en modo escritura. ( 0100,A2,A1,A0,0 )
// (0100) identifica al C.I. PCF8476.
Pgina 126
// Dato a escribir
// Finalizacin de la transmisin.
// Configuracin de I2C
// Definimos el PIC como maestro
// Forzamos a trabajar con su hardware
interno.(Asociado a I2C)
// Trabajamos a velocidad baja 100 Kbps
// Elegimos sda=PIN_C4 como patilla de datos.
// Elegimos scl=PIN_C3 como patilla de reloj.
#BYTE TRISA = 0x85
#BYTE portA = 0x05
// TRISA en 85h.
// PORTA en 05h.
portA = 0B00101000;
// Reseteamos el Puerto A.
port_b_pullups(TRUE);
enable_interrupts(int_ext);
ext_int_edge(H_TO_L);
INTF = 1;
// Forzamos la Interrupcin.
enable_interrupts(GLOBAL);
while (1)
Microcontroladores
Pgina 127
Escritura(~dato_recibido);
}
/* ******************************************** Motor Paso a Paso *************************************************************** */
void Motor_PAP (void)
{
ra3 = 0;
ra2 = 0;
ra1 = 0;
ra5 = 1;
delay_ms(500);
// Retardo de 500 ms
ra3 = 0;
ra2 = 0;
ra1 = 1;
ra5 = 1;
delay_ms(500);
// Retardo de 500 ms
ra3 = 0;
ra2 = 0;
ra1 = 1;
ra5 = 0;
delay_ms(500);
// Retardo de 500 ms
ra3 = 0;
ra2 = 1;
ra1 = 1;
ra5 = 0;
delay_ms(500);
// Retardo de 500 ms
ra3 = 0;
ra2 = 1;
ra1 = 0;
ra5 = 0;
delay_ms(500);
// Retardo de 500 ms
ra3 = 1;
ra2 = 1;
ra1 = 0;
ra5 = 0;
delay_ms(500);
// Retardo de 500 ms
ra3 = 1;
ra2 = 0;
ra1 = 0;
ra5 = 0;
delay_ms(500);
// Retardo de 500 ms
ra3 = 1;
ra2 = 0;
ra1 = 0;
Microcontroladores
Pgina 128
// Retardo de 500 ms
}
/* *************************************** Funcin de int8 Lectura_Interruptores() ****************************************** */
int8 Lectura_Interruptores()
{
int8 data;
i2c_start();
i2c_write(0x41);
// Inicializa la recepcin.
// Seleccionar esclavo U4 en modo lectura. ( 0100,A2,A1,A0,1 )
// (0100) identifica al C.I. PCF8476.
// (A2,A1,A0)=(000) por hardware.
// El ultimo bit a 1 para poner el C.I. PCF8476 en modo lectura.
data=i2c_read(0);
i2c_stop();
return(data);
}
/* ************************************* Funcin de Escritura(int8 dato_recibido) ******************************************* */
void Escritura(int8 dato_recibido)
{
i2c_start();
i2c_write(0x48);
i2c_write(dato_recibido);
i2c_stop();
// Inicializa la transmisin
// Seleccionar esclavo U3 en modo escritura. ( 0100,A2,A1,A0,0 )
// (0100) identifica al C.I. PCF8476.
// (A2,A1,A0)=(100) por hardware.
// El ultimo bit a 0 para poner el C.I. PCF8476 en modo escritura.
// Dato a escribir
// Finalizacin de la transmisin.
5.3.8.1.1.2.- PCF8574_2.
Utilizaremos el entrenador PCF8574_2.DSN contenido en la carpeta de I2C\
Expansor_Bus_PCF8574\ PCF8574_2.
Microcontroladores
Pgina 129
// Configuracin de I2C
// Definimos el PIC como maestro
// Forzamos a trabajar con su hardware
// interno.(Asociado a I2C)
// Trabajamos a velocidad baja 100 Kbps
// Elegimos sda=PIN_C4 como patilla de datos.
// Elegimos scl=PIN_C3 como patilla de reloj.
delay_ms(50);
Escritura_Led_1(dato_recibido);
delay_ms(50);
dato_recibido = Lectura_Interruptores_2();
delay_ms(50);
Escritura_Led_2(dato_recibido);
delay_ms(50);
}
}
/* ********************************* Funcin de int8 Lectura_Interruptores_1() ********************************************* */
int8 Lectura_Interruptores_1()
{
int8 data;
i2c_start();
i2c_write(0B01000001);
data=i2c_read(0);
Microcontroladores
// Inicializa la recepcin.
// Seleccionar esclavo U3 en modo lectura. ( 0100,A2,A1,A0,1 )
// (0100) identifica al C.I. PCF8476.
// (A2,A1,A0)=(000) por hardware.
// El ultimo bit a 1 para poner el C.I. PCF8476 en modo lectura.
// Lectura del dato
Pgina 130
// Finalizacin de la transmisin.
return(data);
}
/* ********************************* Funcin de Escritura_1(int8 dato_recibido) ******************************************** */
void Escritura_Led_1(int8 dato_recibido)
{
i2c_start();
i2c_write(0x48);
i2c_write(dato_recibido);
i2c_stop();
// Inicializa la transmisin
// Seleccionar esclavo U4 en modo escritura. ( 0100,A2,A1,A0,0 )
// (0100) identifica al C.I. PCF8476.
// (A2,A1,A0)=(100) por hardware.
// El ultimo bit a 0 para poner el C.I. PCF8476 en modo escritura.
// Dato a escribir
// Finalizacin de la transmisin.
}
/* ********************************* Funcin de int8 Lectura_Interruptores_2() ********************************************* */
int8 Lectura_Interruptores_2()
{
int8 data;
i2c_start();
i2c_write(0B01001011);
data=i2c_read(0);
i2c_stop();
// Inicializa la recepcin.
// Seleccionar esclavo U5 en modo lectura. ( 0100,A2,A1,A0,1 )
// (0100) identifica al C.I. PCF8476.
// (A2,A1,A0)=(101) por hardware.
// El ultimo bit a 1 para poner el C.I. PCF8476 en modo lectura.
// Lectura del dato
// Finalizacin de la transmisin.
return(data);
}
/* ********************************* Funcin de Escritura_2(int8 dato_recibido) ******************************************** */
void Escritura_Led_2(int8 dato_recibido)
{
i2c_start();
i2c_write(0x4E);
i2c_write(dato_recibido);
i2c_stop();
// Inicializa la transmisin
// Seleccionar esclavo U6 en modo escritura. ( 0100,A2,A1,A0,0 )
// (0100) identifica al C.I. PCF8476.
// (A2,A1,A0)=(111) por hardware.
// El ultimo bit a 0 para poner el C.I. PCF8476 en modo escritura.
// Dato a escribir
// Finalizacin de la transmisin.
Microcontroladores
// Configuracin de I2C
// Definimos el PIC como maestro
// Forzamos a trabajar con su hardware
Pgina 131
// TRISA en 85h.
// PORTA en 05h.
// TRISB en 86h.
// PORTB en 06h.
portA = 0B00101000;
// Reseteamos el Puerto A.
port_b_pullups(TRUE);
enable_interrupts(int_rb);
enable_interrupts(GLOBAL);
RBIF = 1;
// Forzamos la Interrupcin.
while (1)
{
}
}
/* ************************************************ Motor Paso a Paso *********************************************************** */
void Motor_PAP (void)
{
ra3 = 0;
ra2 = 0;
ra1 = 0;
ra5 = 1;
delay_ms(500);
// Retardo de 500 ms
ra3 = 0;
ra2 = 0;
ra1 = 1;
ra5 = 1;
Microcontroladores
Pgina 132
// Retardo de 500 ms
ra3 = 0;
ra2 = 0;
ra1 = 1;
ra5 = 0;
delay_ms(500);
// Retardo de 500 ms
ra3 = 0;
ra2 = 1;
ra1 = 1;
ra5 = 0;
delay_ms(500);
// Retardo de 500 ms
ra3 = 0;
ra2 = 1;
ra1 = 0;
ra5 = 0;
delay_ms(500);
// Retardo de 500 ms
ra3 = 1;
ra2 = 1;
ra1 = 0;
ra5 = 0;
delay_ms(500);
// Retardo de 500 ms
ra3 = 1;
ra2 = 0;
ra1 = 0;
ra5 = 0;
delay_ms(500);
// Retardo de 500 ms
ra3 = 1;
ra2 = 0;
ra1 = 0;
ra5 = 1;
delay_ms(500);
// Retardo de 500 ms
}
/* ******************************* Atencin a la interrupcin por cambio en RB0 ******************************************* */
#INT_RB
void Lectura_Escritura_PCF8476(void)
{
int n;
int8 dato_recibido;
if(rb4==0)
// Preguntamos si ha interrumpido (U3)
{
dato_recibido = Lectura_Interruptores_1();
// Leemos el dato a travs del bus I2c del
// esclavo U3.
Escritura_Led_1(dato_recibido);
// Escribimos el dato a travs del bus I2c en el
// esclavo U4.
}
if(rb5==0)
// Preguntamos si ha interrumpido (U4)
{
dato_recibido = Lectura_Interruptores_2();
// Leemos el dato a travs del bus I2c del
// esclavo U5.
Escritura_Led_2(dato_recibido);
// Escribimos el dato a travs del bus I2c en el
// esclavo U6.
}
n = portB;
Microcontroladores
Pgina 133
// Inicializa la recepcin.
// Seleccionar esclavo U3 en modo lectura. ( 0100,A2,A1,A0,1 )
// (0100) identifica al C.I. PCF8476.
// (A2,A1,A0)=(000) por hardware.
// El ultimo bit a 1 para poner el C.I. PCF8476 en modo lectura.
data=i2c_read(0);
i2c_stop();
return(data);
}
/* ***************************** Funcin de Escritura_1(int8 dato_recibido) ************************************************ */
void Escritura_Led_1(int8 dato_recibido)
{
i2c_start();
i2c_write(0x48);
i2c_write(dato_recibido);
i2c_stop();
// Inicializa la transmisin
// Seleccionar esclavo U4 en modo escritura. ( 0100,A2,A1,A0,0 )
// (0100) identifica al C.I. PCF8476.
// (A2,A1,A0)=(100) por hardware.
// El ultimo bit a 0 para poner el C.I. PCF8476 en modo escritura.
// Dato a escribir
// Finalizacin de la transmisin.
// Inicializa la recepcin.
// Seleccionar esclavo U5 en modo lectura. ( 0100,A2,A1,A0,1 )
// (0100) identifica al C.I. PCF8476.
// (A2,A1,A0)=(101) por hardware.
// El ultimo bit a 1 para poner el C.I. PCF8476 en modo lectura.
data=i2c_read(0);
i2c_stop();
return(data);
}
/* ****************************** Funcin de Escritura_2(int8 dato_recibido) *********************************************** */
void Escritura_Led_2(int8 dato_recibido)
{
i2c_start();
i2c_write(0x4E);
i2c_write(dato_recibido);
i2c_stop();
// Inicializa la transmisin
// Seleccionar esclavo U6 en modo escritura. ( 0100,A2,A1,A0,0 )
// (0100) identifica al C.I. PCF8476.
// (A2,A1,A0)=(111) por hardware.
// El ultimo bit a 0 para poner el C.I. PCF8476 en modo escritura.
// Dato a escribir
// Finalizacin de la transmisin.
Microcontroladores
Pgina 134
5.3.8.1.1.3.1.- CAD_PCF8547.c
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Programa.....: CAD_PCF8547.c
//
// Plataforma hw: Placa Monibot
//
// Fecha........: Septiembre-2011
//
// Programador..: Pedro Alonso
//
// Descripcin..: Un programa principal controla un motor PAP.
//
//
El Conversor A/D interrumpe el programa principal digitalizando la patilla RA0
//
//
y llevar su resultado a el expansor de Bus paralelo PCF8574 (U7).
//
//
El cristal de cuarzo tiene que ser de 20 MHz
//
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// ********************************* Directivas de Preprocesado **************************************
#include <16F876A.h>
#device adc=8
#fuses XT,NOWDT,PUT,NOWRT
#use delay(clock= 20000000)
// Configuracin de I2C
// Definimos el PIC como maestro
// Forzamos a trabajar con su hardware
// interno.(Asociado a I2C)
// Trabajamos a velocidad baja 100 Kbps
// Elegimos sda=PIN_C4 como patilla de datos.
// Elegimos scl=PIN_C3 como patilla de reloj.
// TRISA en 85h.
Microcontroladores
Pgina 135
// PORTA en 05h.
setup_adc(ADC_CLOCK_INTERNAL);
set_adc_channel(0);
ta1 = 0;
ta2 = 0;
ta3 = 0;
ta4 = 0;
ta5 = 0;
ra1 = 0;
// Activamos el Motor PAP y encendemos LED.
ra2 = 0;
ra3 = 1;
ra4 = 0;
ra5 = 1
enable_interrupts(int_ad);
// Habilitamos la interrupcin por Conversin A/D.
enable_interrupts(GLOBAL);
// Habilitamos la Interrupcion General.
read_adc(adc_start_only);
while (1)
{
}
}
/* ********************************* Atencin a la interrupcin por Conversin A/D **************************************** */
#INT_AD
void Lectura_Escritura_PCF8476(void)
{
int8 dato_recibido;
delay_ms(10);
dato_recibido = read_adc(adc_read_only);
Escritura(dato_recibido);
read_adc(adc_start_only);
Microcontroladores
Pgina 136
delay_ms(100);
// Retardo de 100 ms
ra3 = 0;
ra2 = 0;
ra1 = 1;
ra5 = 1;
delay_ms(100);
// Retardo de 100 ms
ra3 = 0;
ra2 = 0;
ra1 = 1;
ra5 = 0;
delay_ms(100);
// Retardo de 100 ms
ra3 = 0;
ra2 = 1;
ra1 = 1;
ra5 = 0;
delay_ms(100);
// Retardo de 100 ms
ra3 = 0;
ra2 = 1;
ra1 = 0;
ra5 = 0;
delay_ms(100);
// Retardo de 100 ms
ra3 = 1;
ra2 = 1;
ra1 = 0;
ra5 = 0;
delay_ms(100);
// Retardo de 100 ms
ra3 = 1;
ra2 = 0;
ra1 = 0;
ra5 = 0;
delay_ms(100);
// Retardo de 100 ms
ra3 = 1;
ra2 = 0;
ra1 = 0;
ra5 = 1;
delay_ms(100);
// Retardo de 100 ms
i2c_write(dato_recibido);
i2c_stop();
// Inicializa la transmisin
// Seleccionar esclavo U3 en modo escritura. ( 0100,A2,A1,A0,0 )
// (0100) identifica al C.I. PCF8476.
// (A2,A1,A0)=(110) por hardware.
// El ultimo bit a 0 para poner el C.I. PCF8476 en modo escritura.
// Dato a escribir
// Finalizacin de la transmisin.
Microcontroladores
Pgina 137
#fuses XT,NOWDT,PUT,NOWRT
#use delay(clock= 20000000)
// TRISA en 85h.
// PORTA en 05h.
// Configuracin de I2C
// Definimos el PIC como maestro
// Forzamos a trabajar con su hardware
// interno.(Asociado a I2C)
// Trabajamos a velocidad baja 100 Kbps
// Elegimos sda=PIN_C4 como patilla de datos.
// Elegimos scl=PIN_C3 como patilla de reloj.
#define U3 0x48
#define U7 0x4C
/* ************************************** Declaracin de funciones ************************************************************* */
void Escritura(int8, int8);
tipo entero de 8 bit)
int8 Lectura_Interruptores();
Microcontroladores
Pgina 138
ta1 = 0;
ta2 = 0;
ta3 = 0;
ta4 = 0;
ta5 = 0;
ra1 = 0;
ra2 = 0;
ra3 = 1;
ra4 = 0;
ra5 = 1;
port_b_pullups(TRUE);
enable_interrupts(int_ext);
ext_int_edge(H_TO_L);
INTF = 1;
// Forzamos la Interrupcin.
enable_interrupts(int_ad);
enable_interrupts(GLOBAL);
read_adc(adc_start_only);
while (1)
{
Motor_PAP();
}
}
/* **************************** Atencin a la interrupcin por Conversin A/D ********************************************* */
#INT_AD
void Lectura_Escritura_AD_PCF8476(void)
{
int8 dato_recibido;
delay_ms(10);
dato_recibido = read_adc(adc_read_only);
Escritura(dato_recibido,U7);
read_adc(adc_start_only);
}
/* *************************************** Atencin a la interrupcin por cambio en RB0 *********************************** */
#INT_EXT
void Lectura_Escritura_INT_PCF8476(void)
{
int8 dato_recibido;
dato_recibido = Lectura_Interruptores();
Escritura(~dato_recibido,U3);
}
/* ************************** Funcin de Escritura(int8 dato_recibido, int8 esclavo) ************************************** */
void Escritura(int8 dato_recibido, int8 esclavo)
{
i2c_start();
i2c_write(esclavo);
Microcontroladores
// Inicializa la transmisin
// Seleccionar esclavo U3 en modo escritura.
// ( 0100,A2,A1,A0,0 )
// (0100) identifica al C.I. PCF8476.
// (A2,A1,A0)=(100) por hardware.
Pgina 139
}
/* *************************************** Funcin de int8 Lectura_Interruptores() ****************************************** */
int8 Lectura_Interruptores()
{
int8 data;
i2c_start();
i2c_write(0x41);
// Inicializa la recepcin.
// Seleccionar esclavo U4 en modo lectura. ( 0100,A2,A1,A0,1 )
// (0100) identifica al C.I. PCF8476.
// (A2,A1,A0)=(000) por hardware.
// El ultimo bit a 1 para poner el C.I. PCF8476 en modo lectura.
data=i2c_read(0);
i2c_stop();
return(data);
}
/* ********************************************* Motor Paso a Paso ************************************************************** */
void Motor_PAP (void)
{
ra3 = 0;
ra2 = 0;
ra1 = 0;
ra5 = 1;
delay_ms(100);
// Retardo de 100 ms
ra3 = 0;
ra2 = 0;
ra1 = 1;
ra5 = 1;
delay_ms(100);
// Retardo de 100 ms
ra3 = 0;
ra2 = 0;
ra1 = 1;
ra5 = 0;
delay_ms(100);
// Retardo de 100 ms
ra3 = 0;
ra2 = 1;
ra1 = 1;
ra5 = 0;
delay_ms(100);
// Retardo de 100 ms
ra3 = 0;
ra2 = 1;
ra1 = 0;
ra5 = 0;
delay_ms(100);
// Retardo de 100 ms
ra3 = 1;
ra2 = 1;
ra1 = 0;
ra5 = 0;
delay_ms(100);
// Retardo de 100 ms
ra3 = 1;
ra2 = 0;
ra1 = 0;
ra5 = 0;
Microcontroladores
Pgina 140
// Retardo de 100 ms
ra3 = 1;
ra2 = 0;
ra1 = 0;
ra5 = 1;
delay_ms(100);
// Retardo de 100 ms
5.3.8.1.2.1.- PCF8591_ADC.
Utilizaremos el entrenador PCF8591_AD.DSN contenido en la carpeta de I2C\
Conversor A-D_D-A_PCF8591\ PCF8591_ADC
Microcontroladores
Pgina 141
#include <flex_lcd.c>
#define PCF8591
#define CANAL
0b10011001
// 0x 9
9
0B00000000
// Configuracin de I2C
// Definimos el PIC como maestro
// Forzamos a trabajar con su hardware
// interno.(Asociado a I2C)
// Trabajamos a velocidad baja 100 Kbps
// Elegimos sda=PIN_C4 como patilla de datos.
// Elegimos scl=PIN_C3 como patilla de reloj.
// Incluimos el driver flex_lcd.c que contiene las
// funciones de control del LCD.
// Inicializamos el LCD.
i2c_start();
i2c_write(PCF8591&0B11111110);
i2c_write(CANAL);
while (1)
{
i2c_write(PCF8591);
q=i2c_read(0);
i2c_stop();
// Secuencia de stop
v1 = 5.0 * q / 256.0;
lcd_gotoxy(1,1);
printf(lcd_putc,"V1=%3.1gv",v1);
lcd_gotoxy(1,2);
printf(lcd_putc,"q=%3u",q);
}
}
Microcontroladores
Pgina 142
#include <flex_lcd.c>
#define AIN0 0
#define AIN1 1
#define AIN2 2
#define AIN3 3
// Configuracin de I2C
// Definimos el PIC como maestro
// Forzamos a trabajar con su hardware
// interno.(Asociado a I2C)
// Trabajamos a velocidad baja 100 Kbps
// Elegimos sda=PIN_C4 como patilla de datos.
// Elegimos scl=PIN_C3 como patilla de reloj.
// Incluimos el driver flex_lcd.c que contiene las
// funciones de control del LCD.
// Inicializamos el LCD.
// Bucle infinito de espera
entrada_analogica=AIN0;
lcd_gotoxy(1,1);
printf(lcd_putc,"V1=%3.1gv",Leer_PCF8591(entrada_analogica));
entrada_analogica=AIN1;
lcd_gotoxy(9,1);
printf(lcd_putc,"V2=%3.1gv",Leer_PCF8591(entrada_analogica));
entrada_analogica=AIN2;
lcd_gotoxy(1,2);
printf(lcd_putc,"V3=%3.1gv",Leer_PCF8591(entrada_analogica));
entrada_analogica=AIN3;
lcd_gotoxy(9,2);
printf(lcd_putc,"V4=%3.1gv",Leer_PCF8591(entrada_analogica));
}
}
Microcontroladores
Pgina 143
0b10011001
// 0x 9
9
{
int8 q;
float v;
i2c_start();
i2c_write(PCF8591&0B11111110);
i2c_write(canal);
i2c_write(PCF8591);
q=i2c_read(0);
i2c_stop();
// Secuencia de stop
i2c_write(PCF8591);
q=i2c_read(0);
i2c_stop();
// Secuencia de stop
return(v);
}
5.3.8.1.2.2.- PCF8591_DAC.
Utilizaremos el entrenador PCF8591_DA.DSN contenido en la carpeta de I2C\
Conversor A-D_D-A_PCF8591\ PCF8591_DAC
Microcontroladores
Pgina 144
#include <flex_lcd.c>
// Configuracin de I2C
// Definimos el PIC como maestro
// Forzamos a trabajar con su hardware
// interno.(Asociado a I2C)
// Trabajamos a velocidad baja 100 Kbps
// Elegimos sda=PIN_C4 como patilla de datos.
// Elegimos scl=PIN_C3 como patilla de reloj.
// Incluimos el driver flex_lcd.c que contiene las
// funciones de control del LCD.
#define AIN0 0
#define AIN1 1
#define AIN2 2
#define AIN3 3
// Inicializamos el LCD.
while (1)
{
v = 5.0 * q1 / 256.0;
lcd_gotoxy(1,1);
printf(lcd_putc,"V1=%3.1gv",v);
Escribir_U1_PCF8591(q1);
}
}
// ***************************************** Funcin int8 Leer_U2_PCF8159(int8) ***********************************************
int8 Leer_U2_PCF8591(int8 canal)
#define PCF8591_U2
0b10011001
// 0x 9
9
{
int8 q;
Microcontroladores
Pgina 145
i2c_start();
i2c_write(PCF8591_U2&0B11111110);
i2c_write(canal);
i2c_write(PCF8591_U2);
q=i2c_read(0);
i2c_stop();
// Secuencia de stop
i2c_write(PCF8591_U2);
q=i2c_read(0);
i2c_stop();
/ /Secuencia de stop
return(q);
}
// ***************************************** Funcin Escribir_U1_PCF8159(int8) ************************************************
void Escribir_U1_PCF8591(int8 dato)
#define PCF8591_U1
0B10010011
// 0x 9 3
{
i2c_start();
i2c_write(PCF8591_U1&0B11111110);
i2c_write(0B01000000);
i2c_write(dato);
i2c_write(dato);
i2c_stop();
}
Microcontroladores
Pgina 146
CNY70
R1= 220
I1
R2= 47K
I3
74HC14
I2
CNY70
E1= 5V
Diodo
Emisor
de Luz
Optotransistor
Cortado
V1= 5V
Luz Infrarroja
V2= 0V
I3
R1= 220
I1
R2= 47K
Ic
I2
I4
74HC14
CNY70
E1= 5V
Diodo
Emisor
de Luz
Luz Infrarroja
Optotransistor
Saturado
V1= 0V
V2= 5V
Microcontroladores
Pgina 147
5.3.9.1.1.- Prueba_Sensores_CNY70.c
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Programa.....: Prueba_Sensores_CNY70.c
//
// Plataforma hw: Placa monibot 16F877A
//
// Fecha........: Mayo-2010
//
// Programador..: Pedro Alonso
//
// Descripcin..: Leer los sensores CNY70 y visualizarlo en el LCD.
//
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// *********************************** Directivas de Preprocesado ************************************
#include <16F877A.h>
#fuses XT,NOWDT,NOPROTECT,NOLVP
#use delay( clock = 1000000 )
// Reloj de 1 MHz
#include <flex_lcd.c>
// TRISA en 85h.
// PORTA en 05h.
// TRISD en 88h.
// PORTD en 08h.
Microcontroladores
// Inicializamos el LCD.
Pgina 148
while (1)
{
lcd_gotoxy(6,1);
printf(lcd_putc,"%2u%2u",~rd3,~rd2);
lcd_gotoxy(3,2);
printf(lcd_putc,"%2u%2u%4u%2u",~ra5,~ra4,~rd1,~rd0);
}
}
Microcontroladores
Pgina 149
Microcontroladores
Pgina 150
5.3.9.2.1.1.- Lectura_S1_GP2D12.c
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Programa.....: Lectura_S1_GP2D12.c
//
// Plataforma hw: Placa Monibot 16F877A
//
// Fecha........: Octubre-2010
//
// Programador..: Pedro Alonso
//
// Descripcin..: Prueba de un sensor GP2D12
//
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// *********************************** Directivas de Preprocesado ************************************
#include <16F877A.h>
#device adc=10
#FUSES XT,NOWDT
#use delay(clock=1000000)
#include <flex_lcd.c>
#include <driver2_GP2D12.c>
// #include <driver1_GP2D12.c>
Microcontroladores
Pgina 151
q = read_adc();
v = (5.0 * q) / 1024.0;
d=Gp2d12_v_d(v);
lcd_gotoxy(1,1);
printf(lcd_putc, "Voltios = %2.1fV", v);
lcd_gotoxy(1,2);
printf(lcd_putc, "S1 = %5.1fcm",d );
}
}
5.3.9.2.1.2.- Lectura_S1_GP2D12.c
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Programa.....: Lectura_S1_S2_GP2D12.c
//
// Plataforma hw: Placa Monibot 16F877A
//
// Fecha........: Octubre-2010
//
// Programador..: Pedro Alonso
//
// Descripcin..: Prueba de dos sensor GP2D12
//
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// ******************************* Directivas de Preprocesado ****************************************
#include <16F877A.h>
#device adc=10
#FUSES XT,NOWDT
#use delay(clock=4000000)
#include <flex_lcd.c>
#include <driver2_GP2D12.c>
// #include <driver1_GP2D12.c>
set_adc_channel(0);
delay_us(20);
q = read_adc();
v = (5.0 * q) / 1024.0;
d=Gp2d12_v_d(v);
lcd_gotoxy(1,1);
printf(lcd_putc, "S1 = %4.1fcm",d );
set_adc_channel(1);
delay_us(20);
q = read_adc();
v = (5.0 * q) / 1024.0;
Microcontroladores
Pgina 152
}
}
5.3.9.2.1.3.- driver1_GP2D12.c
//*********** Driver de Control del Sensor de Infrarrojos Gp2d12, para una distancia
//*********** entre 8 cm y 55 cm.*
// Se obtiene una distancia "d" (Formato float) en funcin de la tensin "v" (Formato float).
// Se realiza aproximaciones a la curva con rectas.
// Ecuacin de la recta con dos puntos:
// d=d1+[(v-v1)/(v2-v1)](d2-d1)
// Mirar archivo Ecuacin de la Recta.
//******************************** DECLARACIN DE FUNCIONES***************************************************************
float Gp2d12_v_d(float);
//***********************************************FUNCIN Gp2d12_v_d************************************************************
float Gp2d12_v_d(float v)
{
float l;
l=0;
if(v>2.6)
else if(v<2.6&&v>=1.9)
else if(v<1.9&&v>=1.65)
else if(v<1.65&&v>=1.38)
else if(v<1.38&&v>=1.15)
else if(v<1.15&&v>=0.95)
else if(v<0.95&&v>=0.75)
else if(v<0.75&&v>=0.68)
else if(v<0.68&&v>=0.58)
else if(v<0.58)
return(l);
l = 8;
l = 13.5 + ((8-13.5)* (v - 1.9) /(2.6-1.9));
l = 16 + ((13.5-16)* (v- 1.65) / (1.9-1.65));
l = 20 + ((16-20)* (v- 1.38) / (1.65-1.38));
l = 25 + ((20-25)* (v- 1.15) / (1.38-1.15));
l = 30 + ((25-30)* (v- 0.95) / (1.15-0.95));
l = 40 + ((30-40)* (v- 0.75) / (0.95-0.75));
l = 45 + ((40-45)* (v- 0.68) / (0.75-0.68));
l = 55 + ((45-55)* (v- 0.58) / (0.68-0.58));
l=55;
5.3.9.2.1.4.- driver2_GP2D12.c
//********* Driver de Control del Sensor de Infrarrojos Gp2d12, para una distancia entre
//********* 8 cm y 55 cm.
// Se obtiene una distancia "d" (Formato float)en funcin de la tensin "v"(Formato float).
// Se utiliza una ecuacin de 4 grado.
//****************************** DECLARACIN DE FUNCIONES ****************************************************************
float Gp2d12_v_d(float);
//****************************************FUNCIN Gp2d12_v_d ******************************************************************
float Gp2d12_v_d(float v)
{
float i; //variable auxiliar de cuenta
float r;
float s;
float d;
r=v*v;
s=v*v*v;
i=v*v*v*v;
d=((16.75*i)-119.26*s)+(311.7*r)-(365.71*v)+183.03;
return(d);
}
Microcontroladores
Pgina 153
Se comunica va I2C.
Un diodo led en la parte posterior del mdulo genera un cdigo de intermitencias que
expresa la direccin del I2C actual del mdulo as com el inicio de una nueva medida.
La direccin del mdulo es por defecto 0XE0, aunque existe la posibilidad de cambiarla
por otras 15 (0XE2, 0XE4, 0XE6, 0XE8, 0XEA, 0XEC, 0XEE, 0XF0, 0XF2, 0XF4, 0XF6,
0XF8, 0XFA, 0XFC o 0XFE. Esto permite controlar hasta 16 mdulo SRF08 con el bus
I2C.
Adems de las direcciones anteriores, todos los sonares conectados al bus I2C
respondern a la direccin 0x00 de llamada general. Esto significa que escribir un
comando de medicin de la distancia para la direccin 0x00 de I2C,iniciar las
mediciones en todos los sensores al mismo tiempo. Esto es til en el modo ANN (Red
Neuronal Artificial). Los resultados deben leerse de manera individual de cada uno de
las direcciones reales de los sensores.
Microcontroladores
Pgina 154
5.3.9.2.2.1.- Lectura_S1_SRF08_Real.
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Programa.....: Lectura_S1_SRF08_Real.c
//
// Plataforma hw: Placa Monibot 16F877A
//
// Fecha........: Mayo-2011
//
// Programador..: Pedro Alonso
//
// Descripcin..: Lectura de un Sensor SRF08
//
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// ************************************* Directivas de Preprocesado **********************************
#include <16F877A.h>
#fuses XT,NOWDT,PUT,NOWRT
#use delay(clock= 1000000)
#use i2c(Master, force_hw, slow, sda=PIN_C4, scl=PIN_C3)
// Configuracin de I2C
// Definimos el PIC como maestro
// Forzamos a trabajar con su hardware
interno.(Asociado a I2C)
// Trabajamos a velocidad baja 100 Kbps
// Elegimos sda=PIN_C4 como patilla de datos.
// Elegimos scl=PIN_C3 como patilla de reloj.
#include <flex_lcd.c>
#define SRF08
0xE2
Microcontroladores
Pgina 155
// Inicializamos el LCD.
while (1)
{
}
}
/* ************************************* Funcin de int16 Lectura_SRF08() *************************************************** */
int16 Lectura_SRF08()
#define SRF08_cm 0x51
{
int16 resultado=0;
int8 byte_alto=0;
int8 byte_bajo=0;
// Medida en cm
i2c_start();
i2c_write(SRF08);
i2c_write(0x00);
i2c_write(SRF08_cm);
i2c_stop();
delay_ms(70);
// Secuencia de inicio
// Direccin I2C del SRF08 modo escritura
// Direccin interna 0x00 (registro de comandos)
// Enviar comando a ejecutar, lectura en cm
// Secuencia de stop
// Temporizacin de 70mS necesaria para realizar la ejecucin
i2c_start();
i2c_write(SRF08);
i2c_write(0x02);
i2c_stop();
// Secuencia de inicio
// Direccin I2C del dispositivo modo escritura
// Enva direccin interna del dispositivo, nos posicionamos en el
// registro del 1 eco
// Enva secuencia de stop
i2c_start();
i2c_write(SRF08|0b00000001);
byte_alto=i2c_read();
byte_bajo=i2c_read(0);
i2c_stop();
//Secuencia de stop
resultado=make16(byte_alto, byte_bajo);
return (resultado);
}
5.3.9.2.2.2.- Lectura_S1_S2_SRF08_Real.c
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Programa.....: Lectura_S1_S2_SRF08_Real.c
//
// Plataforma hw: Placa Monibot 16F877A
//
// Fecha........: Mayo-2011
//
// Programador..: Pedro Alonso
//
// Descripcin..: Lectura de dos Sensor SRF08
//
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// ************************************** Directivas de Preprocesado *********************************
#include <16F876A.h>
Microcontroladores
Pgina 156
#include <LCD1.c>
// Configuracin de I2C
// Definimos el PIC como maestro
// Forzamos a trabajar con su hardware
// interno.(Asociado a I2C)
// Trabajamos a velocidad baja 100 Kbps
// Elegimos sda=PIN_C4 como patilla de datos.
// Elegimos scl=PIN_C3 como patilla de reloj.
// Incluimos el driver LCD1.c que contiene las
// funciones de control del LCD.
#define SENSOR_1
#define SENSOR_2
0xE4
0xE2
// Inicializamos el LCD.
while (1)
{
sensor=SENSOR_1;
dato_recibido = Lectura_SRF08(sensor);
lcd_gotoxy(9,1);
printf(lcd_putc,"S1=%03lu",dato_recibido);
}
}
/* *************************************** Funcin de int8 Lectura_SRF08() ************************************************** */
int16 Lectura_SRF08(int8 SRF08)
#define SRF08_cm 0x51
{
int16 resultado=0;
int8 byte_alto=0;
int8 byte_bajo=0;
// Medida en cm
i2c_start();
i2c_write(SRF08);
i2c_write(0x00);
i2c_write(SRF08_cm);
i2c_stop();
delay_ms(20);
// Secuencia de inicio
// Direccin I2C del SRF08 modo escritura
// Direccin interna 0x00 (registro de comandos)
// Enviar comando a ejecutar, lectura en cm
// Secuencia de stop
// Temporizacin de 80mS necesaria para realizar la ejecucin
i2c_start();
i2c_write(SRF08);
i2c_write(0x02);
// Secuencia de inicio
// Direccin I2C del dispositivo modo escritura
// Enva direccin interna del dispositivo, nos posicionamos en el
// registro del 1 eco
// Enva secuencia de stop
i2c_stop();
Microcontroladores
Pgina 157
byte_alto=i2c_read();
byte_bajo=i2c_read(0);
i2c_stop();
resultado=make16(byte_alto, byte_bajo);
return(resultado);
}
5.3.9.2.2.3.- Lectura_S1_S2_SRF08_Real_Simulado.c
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Programa.....: Lectura_S1_S2_SRF08_Real_Simulado.c
//
// Plataforma hw: Placa Monibot 16F877A
//
// Fecha........: Mayo-2011
//
// Programador..: Pedro Alonso
//
// Descripcin..: Lectura de dos Sensor SRF08 real y simulado
//
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// ************************************* Directivas de Preprocesado***********************************
#include <16F877A.h>
#fuses XT,NOWDT,PUT,NOWRT
#use delay(clock= 1000000)
#use i2c(Master, force_hw, slow, sda=PIN_C4, scl=PIN_C3)
#include <driver_SRF08.c>
// #include <driver_PCF8591.c>
// #include <driver_Luz_Distancia_SRF08.c>
#include <flex_lcd.c>
#define SENSOR_1
#define SENSOR_2
// Configuracin de I2C
// Definimos el PIC como maestro
// Forzamos a trabajar con su hardware
// interno.(Asociado a I2C)
// Trabajamos a velocidad baja 100 Kbps
// Elegimos sda=PIN_C4 como patilla de datos.
// Elegimos scl=PIN_C3 como patilla de reloj.
// Real
// Simulado
// Simulado
// Incluimos el driver LCD1.c que contiene las
// funciones de control del LCD.
0xE4
0xE2
// Inicializamos el LCD.
while (1)
{
}
}
Microcontroladores
Pgina 158
// Configuracin de I2C
// Definimos el PIC como maestro
// Forzamos a trabajar con su hardware
// interno.(Asociado a I2C)
// Trabajamos a velocidad baja 100 Kbps
// Elegimos sda=PIN_C4 como patilla de datos.
// Elegimos scl=PIN_C3 como patilla de reloj.
// #include <driver_SRF08.c>
// #include <driver_PCF8591.c>
#include <driver_Luz_Distancia_SRF08.c>
// Real
// Simulado
// Simulado
#include <flex_lcd.c>
#define SENSOR_1
0xE2
// Inicializamos el LCD.
while (1)
{
}
}
// Medida en cm
Microcontroladores
Pgina 159
// Secuencia de inicio
// Direccin I2C del SRF08 modo escritura
//**** Seleccionamos el registro de Comandos e indicamos que vamos a realizar una lectura en cm ****
i2c_write(0x00);
i2c_write(SRF08_cm);
i2c_stop();
// Secuencia de inicio
// Direccin I2C del dispositivo modo escritura
//********************** Leemos los datos obtenidos del sensor (Byte Alto y Byte Bajo) **********************
i2c_start();
i2c_write(SRF08|0b00000001);
byte_alto=i2c_read();
byte_bajo=i2c_read(0);
i2c_stop();
// Secuencia de stop
resultado=make16(byte_alto,byte_bajo);
return(resultado);
}
5.3.9.2.2.6.- driver_Luz_Distancia_SRF08.c
/* ********************************* driver_Luz_Distancia_SRF08.c ******************************** */
#define SRF08_cm 0x51
#define SRF08_Lumenes 0x01
// Medida en cm
// Medida en Lumenes
Microcontroladores
Pgina 160
// Secuencia de inicio
// Direccin I2C del SRF08 modo escritura
//**** Seleccionamos el registro de Comandos e indicamos que vamos a realizar una lectura en cm ****
i2c_write(0x00);
i2c_write(SRF08_cm);
i2c_stop();
// Secuencia de inicio
// Direccin I2C del dispositivo modo escritura
//*********************Leemos los datos obtenidos del sensor (Byte Alto y Byte Bajo) ************************
i2c_start();
i2c_write(SRF08|0b00000001);
byte_alto=i2c_read();
byte_bajo=i2c_read(0);
i2c_stop();
// Secuencia de stop
resultado=make16(byte_alto,byte_bajo);
return(resultado);
}
/* ******************************** Funcin de int8 Lectura_Lumenes_SRF08(int8 SRF08) ******************************* */
int8 Lectura_Lumenes_SRF08(int8 SRF08)
{
int8 lumenes=0;
//************************************ Seleccionamos el dispositivo SRF08 *****************************************
i2c_start();
i2c_write(SRF08);
// Secuencia de inicio
// Direccin I2C del SRF08 modo escritura
//* Seleccionamos el registro de Comandos e indicamos que vamos a realizar una lectura en Lumenes
i2c_write(SRF08_Lumenes);
i2c_stop();
// Secuencia de inicio
i2c_write(SRF08|0b00000001);
lumenes=i2c_read(0);
i2c_stop();
// Secuencia de stop
return(lumenes);
}
Microcontroladores
Pgina 161
//
0x99 = 0B10011001
// Seleccionar esclavo U1 en modo lectura. ( 1001,A2,A1,A0,1 )
// (0100) identifica al C.I. PCF8591.
// (A2,A1,A0)=(100) por hardware.
// El ultimo bit a 1 para poner el C.I. PCF8591 en modo lectura.
if(SRF08==0xE2) PCF8591=0x95;
//
0x95 = 0B10010101
// Seleccionar esclavo U3 en modo lectura. ( 1001,A2,A1,A0,1 )
// (0100) identifica al C.I. PCF8591.
// (A2,A1,A0)=(010) por hardware.
// El ultimo bit a 1 para poner el C.I. PCF8591 en modo lectura.
i2c_start();
i2c_write(PCF8591);
resultado=i2c_read(0);
i2c_stop();
// Secuencia de stop
return(resultado);
}
5.3.9.2.2.8.- Cambio_Direccin.c
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Programa.....: Cambio_Direccin.c
//
// Plataforma hw: Placa Monibot 16F877A
//
// Fecha........: Mayo-2011
//
// Programador..: Pedro Alonso
//
// Descripcin..: Cambiar las direcciones de los sensores de ultrasonidos SRF08
//
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// ********************************* Directivas de Preprocesado **************************************
#include <16F877A.h>
#fuses XT,NOWDT,PUT,NOWRT
#use delay(clock= 1000000)
#use i2c(Master, force_hw, slow, sda=PIN_C4, scl=PIN_C3)
// Configuracin de I2C
// Definimos el PIC como maestro
// Forzamos a trabajar con su hardware
// interno.(Asociado a I2C)
// Trabajamos a velocidad baja 100 Kbps
// Elegimos sda=PIN_C4 como patilla de datos.
// Elegimos scl=PIN_C3 como patilla de reloj.
Microcontroladores
// Secuencia de inicio
// Direccin I2C del SRF08 modo escritura
Pgina 162
i2c_start();
i2c_write(SRF08_inicial);
i2c_write(0x00);
i2c_write(0xAA);
i2c_stop();
// Secuencia de inicio
// Direccin I2C del SRF08 modo escritura
// Direccin interna 0x00 (registro de comandos)
// 2 secuencia para el cambio de direccin
// Secuencia de stop
i2c_start();
i2c_write(SRF08_inicial);
i2c_write(0x00);
i2c_write(0xA5);
i2c_stop();
// Secuencia de inicio
// Direccin I2C del SRF08 modo escritura
// Direccin interna 0x00 (registro de comandos)
// 3 secuencia para el cambio de direccin
// Secuencia de stop
i2c_start();
i2c_write(SRF08_inicial);
i2c_write(0x00);
i2c_write(SRF08_final);
i2c_stop();
// Secuencia de inicio
// Direccin I2C del SRF08 modo escritura
// Direccin interna 0x00 (registro de comandos)
// Nueva direccin I2C
// Secuencia de stop
while(1);
}
// Configuracin de I2C
// Definimos el PIC como maestro
// Forzamos a trabajar con su hardware
interno.(Asociado a I2C)
// Trabajamos a velocidad baja 100 Kbps
// Elegimos sda=PIN_C4 como patilla de datos.
// Elegimos scl=PIN_C3 como patilla de reloj.
#include <driver_SRF08.c>
// #include <driver_PCF8591.c>
// #include <driver_Luz_Distancia_SRF08.c>
// Real
// Simulado
// Simulado
#include <flex_lcd.c>
0xE2
ON 1
OFF 0
ADELANTE 0
ATRAS 1
Microcontroladores
Pgina 163
// Inicializamos el LCD.
while (1)
{
lcd_gotoxy(1,1);
printf(lcd_putc,"S1=%03lu",distancia);
if(distancia<20)
{
rc1_EN1= ON;
rb2_MI= ATRAS;
rc2_EN2= ON;
rb3_MD= ATRAS;
}
else
{
if(distancia>=20 && distancia<40)
{
rc1_EN1= ON;
rb2_MI= ADELANTE;
rc2_EN2= ON;
rb3_MD= ADELANTE;
}
else
{
rc1_EN1= OFF;
rc2_EN2= OFF;
}
}
}
}
El incremento de la resistencia no es
lineal pero si creciente y caracterstico del platino
de tal forma que mediante tablas es posible
encontrar la temperatura exacta a la que
corresponde.
Un Pt100 es un tipo particular de RTD
(Dispositivo Termo Resistivo)
Normalmente las Pt100 industriales se
consiguen encapsuladas en la misma forma que
Microcontroladores
Pgina 164
RPT100= R0 (1 + a1 x t + a2 x t )
o
(Coeficiente de temperatura)
(Coeficiente de temperatura)
1 + a1 x t + a2 x t = A
Una vez introducidos los valores queda:
Microcontroladores
Pgina 165
a2 x t + a1 x t + (1-A) = 0
t = (-b
) / 2a =
t = (- a1+
)/ 2 a2
Factor de Correccin
5.3.9.3.1.1.- Lectura_S1_PT100.c
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Programa.....: Lectura_S1_PT100.c
//
// Plataforma hw: Placa monibot 16F877A
//
// Fecha........: Octubre-2010
//
// Programador..: Pedro Alonso
//
// Descripcin..: Prueba de un sensor PT100
//
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// ************************************ Directivas de Preprocesado ***********************************
#include <16F877A.h>
#device adc=10
#FUSES XT,NOWDT
#use delay(clock=1000000)
#include <MATH.H>
#include <flex_lcd.c>
#define a1 0.0039083
#define a2 -0.0000005775
//******************************************************** Declaracin de Funciones *********************************************
float Con_V_T(float);
//********************************************************* Programa Principal *****************************************************
void main()
{
int16 q;
float tension;
float temperatura;
lcd_init();
setup_adc_ports(2);
setup_adc(ADC_CLOCK_INTERNAL);
set_adc_channel(0);
for (;;)
{
// Inicializamos el LCD.
// Seleccionamos el Puerto A como entradas Analgicas.
// Mirar ADCON1.
// Fuente de reloj RC interno.
// Habilitacin canal 0 "AN0"
// Bucle infinito.
delay_us(5);
Microcontroladores
Pgina 166
temperatura = Con_V_T(tension);
lcd_gotoxy(1,1);
printf(lcd_putc, "V1= %04.3f v", tension);
lcd_gotoxy(1,2);
printf(lcd_putc, "T1= %3.0g C", temperatura);
}
}
//*************************************************** Funcin Con_V_T ************************************************************
float Con_V_T(float p)
{
float t;
float a;
float b;
float raiz;
a = (p*70.5)/(117.5 - p*1.5);
b = (a1*a1)-4*a2*(1-a);
raiz = sqrt(b);
t =-2+(-a1 + raiz)/(2*a2) ;
if(t<0) t=t-0.5;
return(t);
}
Microcontroladores
Pgina 167
Microcontroladores
// Configuracin de I2C
// Definimos el PIC como maestro
// Forzamos a trabajar con su hardware
Pgina 168
#define TC74_1
#define TC74_2
0x90
0x92
// Inicializamos el LCD.
lcd_gotoxy(1,1);
printf(lcd_putc,"S1=");
lcd_gotoxy(1,2);
printf(lcd_putc,"S2=");
while (1)
{
delay_ms(40);
}
}
/* *********************************** Funcin de int8 Lectura_SRF08() ****************************************************** */
signed int8 Lectura_TC74(int8 sensor)
{
signed int8 temperatura=0;
i2c_start();
i2c_write(sensor);
i2c_write(0x00);
// Secuencia de inicio
// Direccin I2C del dispositivo modo escritura
// Enva direccin interna del dispositivo, nos posicionamos en
// el registro.
i2c_start();
i2c_write(sensor|0b00000001);
temperatura=i2c_read(0);
i2c_stop();
return (temperatura);
}
Microcontroladores
Pgina 169
Campo de visin:
El campo de visin del sensor TPA81 es de 41 x 6, con
lo que a cada uno de los pixels o termopilas que forman la matriz
lneas le corresponde un campo de 5,12 x 6. Esta matriz esta
orientada segn se muestra en la figura. El pxel n 1 es el que
est ms prximo a la pestaa de referencia del propio sensor.
Microcontroladores
Pgina 170
Lectura
Escritura
0
1
Registro de comandos
Rango del servo (versin 6 del firmware o superior)
2
3
4
5
6
7
8
9
No disponible
No disponible
No disponible
No disponible
No disponible
No disponible
No disponible
No disponible
Microcontroladores
Pgina 171
Microcontroladores
Pgina 172
// Configuracin de I2C
// Definimos el PIC como maestro
// Forzamos a trabajar con su hardware
// interno.(Asociado a I2C)
// Trabajamos a velocidad baja 100 Kbps
// Elegimos sda=PIN_C4 como patilla de datos.
// Elegimos scl=PIN_C3 como patilla de reloj.
#include <flex_lcd.c>
funciones de control del LCD.
#define DTPA81
int8 sensor=1;
0xD0
// Inicializamos el LCD.
while (1)
{
sensor=2;
dato_recibido = Lectura_DTPA81(sensor);
lcd_gotoxy(5,1);
printf(lcd_putc,"%1u C",dato_recibido);
delay_ms(40);
}
}
/* ***************************** Funcin int8 Lectura_DTPA81(int8 sensor) ************************************************ */
int8 Lectura_DTPA81(int8 sensor)
{
int8 temperatura=0;
Microcontroladores
Pgina 173
// Secuencia de inicio
// Direccin I2C del dispositivo modo escritura
// Envia direccin interna del dispositivo, nos posicinamos
// en el registro.
// Enva secuencia de stop
i2c_start();
i2c_write(DTPA81|0b00000001);
temperatura=i2c_read(0);
i2c_stop();
return(temperatura);
}
5.3.9.3.3.2.- Test2_D-TPA81.c
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Programa.....: Test2_D-TPA81.c
//
// Plataforma hw: Placa Monibot 16F877A
//
// Fecha........: Octubre-2010
//
// Programador..: Pedro Alonso
//
// Descripcin..: Prueba de un sensor D-TPA81
//
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// ****************************** Directivas de Preprocesado *****************************************
#include <16F877A.h>
#fuses XT,NOWDT,PUT,NOWRT
#use delay(clock= 1000000)
#use i2c(Master, force_hw, slow, sda=PIN_C4, scl=PIN_C3)
#include <flex_lcd.c>
#define DTPA81
int8 sensor;
// Configuracin de I2C
// Definimos el PIC como maestro
// Forzamos a trabajar con su hardware
// interno.(Asociado a I2C)
// Trabajamos a velocidad baja 100 Kbps
// Elegimos sda=PIN_C4 como patilla de datos.
// Elegimos scl=PIN_C3 como patilla de reloj.
// Incluimos el driver flex_lcd.c que contiene las
// funciones de control del LCD.
// Direccin I2C del D-TPA81
// N de sensor
0xD0
// Inicializamos el LCD.
// Bucle infinito de espera
sensor=1;
dato_recibido = Lectura_DTPA81(sensor);
lcd_gotoxy(1,1);
printf(lcd_putc,"%1u",dato_recibido);
sensor=2;
dato_recibido = Lectura_DTPA81(sensor);
lcd_gotoxy(4,1);
Microcontroladores
Pgina 174
sensor=3;
dato_recibido = Lectura_DTPA81(sensor);
lcd_gotoxy(7,1);
printf(lcd_putc,"%1u",dato_recibido);
sensor=4;
dato_recibido = Lectura_DTPA81(sensor);
lcd_gotoxy(10,1);
printf(lcd_putc,"%1u",dato_recibido);
sensor=5;
dato_recibido = Lectura_DTPA81(sensor);
lcd_gotoxy(13,1);
printf(lcd_putc,"%1u",dato_recibido);
sensor=6;
dato_recibido = Lectura_DTPA81(sensor);
lcd_gotoxy(4,2);
printf(lcd_putc,"%1u",dato_recibido);
sensor=7;
dato_recibido = Lectura_DTPA81(sensor);
lcd_gotoxy(7,2);
printf(lcd_putc,"%1u",dato_recibido);
sensor=8;
dato_recibido = Lectura_DTPA81(sensor);
lcd_gotoxy(10,2);
printf(lcd_putc,"%1u",dato_recibido);
sensor=9;
dato_recibido = Lectura_DTPA81(sensor);
lcd_gotoxy(13,2);
printf(lcd_putc,"%1u",dato_recibido);
delay_ms(100);
}
}
/* *************************************** Funcin de int8 Lectura_SRF08() ************************************************** */
int8 Lectura_DTPA81(int8 sensor)
{
int8 temperatura=0;
i2c_start();
i2c_write(DTPA81);
i2c_write(sensor);
i2c_stop();
Microcontroladores
// Secuencia de inicio
// Direccin I2C del dispositivo modo escritura
// Envia direccin interna del dispositivo, nos posicinamos
// en el registro.
// Enva secuencia de stop
Pgina 175
return(temperatura);
}
// Configuracin de I2C
// Definimos el PIC como maestro
// Forzamos a trabajar con su hardware
// interno.(Asociado a I2C)
// Trabajamos a velocidad baja 100 Kbps
// Elegimos sda=PIN_C4 como patilla de datos.
// Elegimos scl=PIN_C3 como patilla de reloj.
#include <flex_lcd.c>
#define Numero_Maximo 8
// Nmero pixel-1
// Tabla de 9 datos.
// Inicializamos el LCD.
lcd_gotoxy(1,1);
printf(lcd_putc,"Sensor= ");
lcd_gotoxy(1,2);
printf(lcd_putc,"Tmax=
C ");
while (1)
{
sensor = Direccion_Pixel[0];
Microcontroladores
Pgina 176
sensor = Direccion_Pixel[1];
temperatura_mayor= Lectura_TC74(sensor);
sensor_mayor=1;
for (n=2; n<=Numero_Maximo; n++)
{
sensor = Direccion_Pixel[n];
temperatura= Lectura_TC74(sensor);
if(temperatura>temperatura_mayor)
{
temperatura_mayor=temperatura;
sensor_mayor=n;
}
}
temperatura_real = temperatura_mayor-temperatura_ambiente;
lcd_gotoxy(9,1);
printf(lcd_putc,"%1u",sensor_mayor);
lcd_gotoxy(6,2);
printf(lcd_putc,"%3u",temperatura_mayor);
// Obtenemos la temperatura
// real del punto caliente
// Posicionamos el Cursor del LCD en la
// posicin 9 lnea 1.
// Visualiza sobre la pantalla LCD la
// variables sensor_mayor.
// Posicionamos el Cursor del LCD en la
// posicin 6 lnea 2.
// Visualiza sobre la pantalla LCD la
// variables temperatura_mayor.
delay_ms(40);
}
}
/* *********************************** Funcin de int8 Lectura_SRF08() ****************************************************** */
int8 Lectura_TC74(int8 sensor)
{
int8 temperatura=0;
i2c_start();
i2c_write(sensor);
i2c_write(0x00);
i2c_start();
i2c_write(sensor|0b00000001);
temperatura=i2c_read(0);
i2c_stop();
// Secuencia de inicio
// Direccin I2C del dispositivo modo escritura
// Envia direccin interna del dispositivo, nos posicinamos
// en el registro.
// Enva secuencia de inicio
// Enva direccin I2C del dispositivo en modo lectura
// Si, lee ltimo byte, enva NACK y almacena en el buffer
// Secuencia de stop
return(temperatura);
}
Microcontroladores
Pgina 177
#include <flex_lcd.c>
// Configuracin de I2C
// Definimos el PIC como maestro
// Forzamos a trabajar con su hardware
// interno.(Asociado a I2C)
// Trabajamos a velocidad baja 100 Kbps
// Elegimos sda=PIN_C4 como patilla de datos.
// Elegimos scl=PIN_C3 como patilla de reloj.
// Incluimos el driver flex_lcd.c que contiene las
// funciones de control del LCD.
// Incluimos el driver TC74_9_sensores.c que
// contiene las funciones de control del TC74.
// Incluimos el driver D-TPA81.c que contiene las
// funciones de control del D-TPA81.
// Nmero pixel.
// #include <driver_TC74_9_sensores.c>
#include <driver_D-TPA81.c>
#define Numero_Maximo 8
// Inicializamos el LCD.
// Posicionamos el Cursor del LCD en la posicin 1 lnea 1.
// Visualiza sobre la pantalla LCD el mensaje "Sensor= ".
// Posicionamos el Cursor del LCD en la posicin 1 lnea 2.
// Visualiza sobre la pantalla LCD el mensaje "Tmax= C ".
while (1)
{
{
temperatura= Lectura_DTPA81(n);
if(temperatura>temperatura_mayor)
{
temperatura_mayor=temperatura;
sensor_mayor=n;
}
}
temperatura_real = temperatura_mayor-temperatura_ambiente;
lcd_gotoxy(9,1);
printf(lcd_putc,"%1u",sensor_mayor);
lcd_gotoxy(6,2);
printf(lcd_putc,"%3u",temperatura_mayor);
// Obtenemos la temperatura
// real del punto caliente
// Posicionamos el Cursor del LCD en la
// posicin 9 lnea 1.
// Visualiza sobre la pantalla LCD la
// variables sensor_mayor.
// Posicionamos el Cursor del LCD en
// la posicin 6 lnea 2.
// Visualiza sobre la pantalla LCD la
// variables temperatura_mayor.
delay_ms(100);
}
}
Microcontroladores
Pgina 178
0xD0
// Secuencia de inicio
// Direccin I2C del dispositivo modo escritura
// Envia direccin interna del dispositivo, nos posicinamos en
// el registro.
// Enva secuencia de inicio
// Enva direccin I2C del dispositivo en modo lectura
// Si, lee ltimo byte, enva NACK y almacena en el buffer
// Secuencia de stop
return(temperatura);
}
5.3.9.3.3.6.- driver_TC74_9_sensores.c
// ****************************** Driver de Control de 9 sensor TC74 ********************************
// Debemos abrir el menu contestual de cada sensor y asignarle una direccin en el apartado {DEVADDR=$92},
// asignamos la direccin 92.
// Cuando copiamos el hardware en otra carpeta debemos asegurarnos que tiene la direccin asignada.
byte CONST Direccion_Pixel[9] = {0x90,0x92,0x94,0x96,0xA2,0x9A,0x9C,0x9E,0xA0};
//
{Ta, Pixel1, Pixel2,Pixel3,Pixel4,Pixel5,Pixel6,Pixel7,Pixel8}
// Tabla de 9 datos.
return(temperatura);
}
Microcontroladores
Pgina 179
// Configuracin de I2C
// Definimos el PIC como maestro
// Forzamos a trabajar con su hardware
// interno.(Asociado a I2C)
// Trabajamos a velocidad baja 100 Kbps
// Elegimos sda=PIN_C4 como patilla de datos.
// Elegimos scl=PIN_C3 como patilla de reloj.
#include <Servo_Futaba_10bit.c>
#include <flex_lcd.c>
// #include <driver_TC74_9_sensores.c>
#include <driver_D-TPA81.c>
// Nmero pixel.
// Inicializamos el LCD.
Inicializacion_Futaba_RC2();
TR0=0;
TR1=0;
TR5=0;
lcd_gotoxy(1,1);
printf(lcd_putc,"Sensor= ");
lcd_gotoxy(1,2);
printf(lcd_putc,"Tmax=
Microcontroladores
C ");
Pgina 180
while (1)
{
sensor = 1;
temperatura_mayor= Lectura_DTPA81(sensor);
sensor_mayor=1;
for (n=2; n<=Numero_Maximo; n++)
// Seleccionamos el sensor 0
// (TAMBIENTE).
// Leemos la temperatura ambiente a
// travs del bus I2c del esclavo
// TAMBIENTE.
// Seleccionamos el sensor PIXEL1.
// Leemos la temperatura del sensor
// PIXEL1 a travs del bus I2c.
// Asignamos a sensor_mayor=1;
// Se ejecuta un bucle desde n=2 hasta
// n<=Numero_Maximo en orden
// ASCENDENTE de uno en uno
{
temperatura= Lectura_DTPA81(n);
if(temperatura>temperatura_mayor)
{
temperatura_mayor=temperatura;
sensor_mayor=n;
}
}
temperatura_real = temperatura_mayor-temperatura_ambiente;
lcd_gotoxy(9,1);
// Obtenemos la temperatura
// real del punto caliente
printf(lcd_putc,"%1u",sensor_mayor);
if(temperatura_mayor>45)
{
if(sensor_mayor>4)
{
posicion++;
if(posicion>68) posicion=68;
}
if(sensor_mayor<4)
{
posicion--;
if(posicion<47) posicion=47;
}
Futaba_RC2(posicion);
}
lcd_gotoxy(6,2);
printf(lcd_putc,"%3u",temperatura_mayor);
delay_ms(50);
}
}
Microcontroladores
Pgina 181
Microcontroladores
Pgina 182
// Incluimos el driver flex_lcd.c que contiene las funciones de control del LCD.
// Inicializamos el LCD.
while(true)
{
dato=portA;
// Bucle infinito.
if(dato!=dato_anterior)
{
dato_anterior=dato;
cs=0;
spi_write(0x0);
cs=1;
cs=0;
spi_write(0x11);
spi_write(portD);
delay_us(120);
cs=1;
// 0x11
ganancia=((dato*10)/256)+1;
lcd_gotoxy(1,1);
printf(lcd_putc,"PORTA=%3u",portA);
Microcontroladores
Pgina 183
}
}
}
5.3.9.5.1.- Control_SD20.c
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Programa.....: Control_SD20.c
//
// Plataforma hw: Placa monibot 16F877A
//
// Fecha........: Octubre-2010
//
// Programador..: Pedro Alonso
//
// Descripcin..: Control del Servo 1 con SD20
//
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// ********************************** Directivas de Preprocesado *************************************
#include <16F877A.h>
#fuses XT,NOWDT,PUT,NOWRT
#use delay(clock= 1000000)
#use i2c(Master, force_hw, slow, sda=PIN_C4, scl=PIN_C3)
Microcontroladores
// Configuracin de I2C
// Definimos el PIC como maestro
Pgina 184
// Inicializa la transmisin
// Seleccionamos el SD20
// Registro de configuracin extandar o control modo expandido.
i2c_start();
i2c_write(0xC2);
i2c_write(22);
i2c_write(0x1);
i2c_stop();
// Inicializa la transmisin
// Seleccionamos el SD20
// Direccin 22H del SD20 Modo expansor de offset (Parte Alta)
// 460D -->01CCH (Se introduce la parte alta 01H)
// Finalizacin de la transmisin.
i2c_start();
i2c_write(0xC2);
i2c_write(23);
i2c_write(0xCC);
i2c_stop();
// Inicializa la transmisin
// Seleccionamos el SD20
// Direccin 23H del SD20 Modo expansor de offset (Parte Baja)
// 460D -->01CCH (Se introduce la parte baja CCH)
// Finalizacin de la transmisin.
while (1)
{
// Bucle infinito
// Finalizacin de la transmisin.
i2c_start();
i2c_write(0xC2);
i2c_write(1);
i2c_write(240);
i2c_stop();
// Inicializa la transmisin
// Seleccionamos el SD20
// Seleccionamos el Servo1
// Posicionamos el Servo en el extremo A
// Finalizacin de la transmisin.
delay_ms(1000);
// Retardamos 1 segundos
i2c_start();
i2c_write(0xC2);
i2c_write(1);
i2c_write(10);
i2c_stop();
// Inicializa la transmisin
// Seleccionamos el SD20
// Seleccionamos el Servo1
// Posicionamos el Servo en el extremo B
// Finalizacin de la transmisin.
delay_ms(1000);
// Retardamos 1 segundos
}
}
5.3.9.5.2.- Control_Servos_Funciones_SD20.c
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Programa.....: Control_Servos_Funciones_SD20.c
//
// Plataforma hw: Placa Monibot 16F877A
//
// Fecha........: Octubre-2010
//
// Programador..: Pedro Alonso
//
// Descripcin..: Control de los servos del SD20 con funciones.
//
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/* ************************************* Control del SD20 ********************************************* */
#include <16F877A.h>
#fuses XT,NOWDT,PUT,NOWRT
#use delay(clock= 4000000)
#use i2c(Master, force_hw, slow, sda=PIN_C4, scl=PIN_C3)
Microcontroladores
// Configuracin de I2C
// Definimos el PIC como maestro
Pgina 185
}
}
/* *********************************************** Funcin Sd20_ini ************************************************************** */
void Sd20_ini (void)
{
// Fijamos el rango de trabajo de los servor desde THmin= 0,480 mS hasta THmax= 2,520 mS.
// THmin = Reg22,Reg23 + 20uS
// THmax =(256x255)/Reg21 +(Reg22,Reg23+20)=
// THmin = Reg22,Reg23 +20 uS = 460uS + 20uS = 480 uS ( 460d --> 1CCH )
// THmax =(256x255)/32 +(460+20)= 2520 uS
i2c_start();
i2c_write(0xC2);
i2c_write(21);
i2c_write(32);
i2c_stop();
// Inicializa la transmisin
// Seleccionamos el SD20
// Registro de configuracin extandar o control modo expandido.
i2c_start();
i2c_write(0xC2);
i2c_write(22);
i2c_write(0x1);
i2c_stop();
// Inicializa la transmisin
// Seleccionamos el SD20
// Direccin 22H del SD20 Modo expansor de offset(Parte Alta)
// 460D -->01CCH (Se introduce la parte alta 01H)
// Finalizacin de la transmisin.
i2c_start();
i2c_write(0xC2);
i2c_write(23);
i2c_write(0xCC);
i2c_stop();
// Inicializa la transmisin
// Seleccionamos el SD20
// Direccin 23H del SD20 Modo expansor de offset(Parte Baja)
// 460D -->01CCH (Se introduce la parte baja CCH)
// Finalizacin de la transmisin.
// Finalizacin de la transmisin.
}
/* ********************************************** Funcin Sd20(int8,int8) ******************************************************* */
void Sd20(int8 servo, int8 posicion)
{
i2c_start();
i2c_write(0xC2);
i2c_write(servo);
i2c_write(posicion);
i2c_stop();
}
Microcontroladores
// Inicializa la transmisin
// Seleccionamos el SD20
// Seleccionamos el Servo1
// Posicionamos el Servo en el extremo A
// Finalizacin de la transmisin.
Pgina 186
#fuses XT,NOWDT,PUT,NOWRT
#use delay(clock= 4000000)
#use i2c(Master, force_hw, slow, sda=PIN_C4, scl=PIN_C3)
// Configuracin de I2C
// Definimos el PIC como maestro
// Forzamos a trabajar con su hardware
// interno.(Asociado a I2C)
// Trabajamos a velocidad baja 100 Kbps
// Elegimos sda=PIN_C4 como patilla de datos.
// Elegimos scl=PIN_C3 como patilla de reloj.
setup_adc_ports(0);
setup_adc(ADC_CLOCK_INTERNAL);
set_adc_channel(3);
While(1)
{
q = read_adc();
Sd20(1,q);
delay_ms(5);
}
}
/* *************************************************** Funcin Sd20_ini ********************************************************** */
void Sd20_ini (void)
{
// Fijamos el rango de trabajo de los servor desde THmin= 0,480 mS hasta THmax= 2,520 mS.
// THmin = Reg22,Reg23 + 20uS
// THmax =(256x255)/Reg21 +(Reg22,Reg23+20)=
// THmin = Reg22,Reg23 +20 uS = 460uS + 20uS = 480 uS ( 460d --> 1CCH )
// THmax =(256x255)/32 +(460+20)= 2520 uS
i2c_start();
i2c_write(0xC2);
i2c_write(21);
i2c_write(32);
i2c_stop();
Microcontroladores
// Inicializa la transmisin
// Seleccionamos el SD20
// Registro de configuracin extandar o control modo expandido.
// Finalizacin de la transmisin.
Pgina 187
// Inicializa la transmisin
// Seleccionamos el SD20
// Direccin 22H del SD20 Modo expansor de offset(Parte Alta)
// 460D -->01CCH (Se introduce la parte alta 01H)
// Finalizacin de la transmisin.
i2c_start();
i2c_write(0xC2);
i2c_write(23);
i2c_write(0xCC);
i2c_stop();
// Inicializa la transmisin
// Seleccionamos el SD20
// Direccin 23H del SD20 Modo expansor de offset(Parte Baja)
// 460D -->01CCH (Se introduce la parte baja CCH)
// Finalizacin de la transmisin.
}
/* ************************************************** Funcin Sd20(int8,int8) *************************************************** */
void Sd20(int8 servo, int8 posicion)
{
i2c_start();
i2c_write(0xC2);
i2c_write(servo);
i2c_write(posicion);
i2c_stop();
}
// Inicializa la transmisin
// Seleccionamos el SD20
// Seleccionamos el Servo1
// Posicionamos el Servo en el extremo A
// Finalizacin de la transmisin.
5.3.9.6.- Puentes en H.
Un Puente H o Puente en H es un circuito electrnico que permite a un motor elctrico
DC girar en ambos sentidos, avance y retroceso. Son ampliamente usados en robtica y como
convertidores de potencia. Los puentes H estn disponibles como circuitos integrados, pero
tambin pueden construirse a partir de componentes discretos.
Microcontroladores
S1 S2 S3 S4
Resultado
Pgina 188
Imax=4A.
V max (Salida) = 46V
Control digital. (TTL)
Alta inmunidad al ruido.
Separacin entre
alimentaciones de control y
de potencia.
Proteccin a temperaturas
altas.
Microcontroladores
Pgina 189
Microcontroladores
Salidas
OUT1 OUT2
5v
5v
0v
0v
0v
9v
9v
0v
9v
0v
Pgina 190
Microcontroladores
Pgina 191
Microcontroladores
Pgina 192