Este documento presenta un curso sobre microcontroladores PIC18F4550 que incluye temas como bootloaders, CCS y Proteus. El curso se enfoca en desarrollar aplicaciones para resolver problemas reales con eficiencia. Incluye capítulos sobre introducción a microcontroladores, lenguaje C y librerías incorporadas.
3. Ing. Braulio Elías Chi Salavarría
INTRODUCCIÓN
En este curso, se enfocara a desarrollar aplicaciones para
resolver problemas reales, con un alto grado de eficiencia y
complejidad, sin dejar de ser fácil de aprender por el alumno,
dando como resultado, prácticas y material realmente
importante para incursionar en el diseño y desarrollo de
aplicaciones avanzadas con tecnología de última generación.
4. Ing. Braulio Elías Chi Salavarría
La tecnología…..
La tecnología avanza día con día, surgiendo nuevas necesidades, cada
vez mas especificas y complejas, esto requiere cierto nivel de
conocimiento mayor que el de hace años, dejando los sistemas de
aprendizaje convencionales obsoletos, para la solución de problemas
que enfrenta la sociedad tecnológica.
Es por esto que nuevas herramientas surgen para tratar de resolver
esas necesidades, mejorando en eficiencia y complejidad. Es por esto,
que los estudiantes necesitan conocer cuáles son estas nuevas
herramientas de desarrollo, llámese, compiladores de lenguaje de alto
nivel, nuevas familias de microcontroladores, con sistemas embebidos
tales como: Ethernet, USB, CAN, PWM, USART, etc. Haciendo de estos
pequeños controladores, poderosas soluciones.
5. Ing. Braulio Elías Chi Salavarría
CAPITULO 1
INTRODUCCION A LOS MICROCONTROLADORES
6. Ing. Braulio Elías Chi Salavarría
Definición de microcontroladores
Un microcontrolador es un circuito integrado o chip que incluye en su interior las tres
unidades funcionales de una computadora: CPU, Memoria y Unidades de E/S, es decir,
se trata de un computador completo en un solo circuito integrado.
Dando una explicación más sencilla, es una microcomputadora con la cual disponemos
de todo, en pequeñas cantidades, para hacer uso en aplicaciones que requieran
automatización, sin la necesidad de tener toda una computadora funcionando.
Aplicaciones
Son diseñados para disminuir el costo económico y el consumo de energía de un
sistema en particular. Por eso el tamaño de la CPU, la cantidad de memoria y los
periféricos incluidos dependerán de la aplicación. El control de un electrodoméstico
sencillo como una batidora, utilizará un procesador muy pequeño (4 u 8 bit) por que
sustituirá a un autómata finito. En cambio un reproductor de música y/o vídeo digital
(mp3 o mp4) requerirá de un procesador de 32 bit o de 64 bit y de uno o más Códec de
señal digital (audio y/o vídeo). El control de un sistema de frenos ABS (Antilock Brake
System) se basa normalmente en un microcontrolador de 16 bit, al igual que el sistema
de control electrónico del motor en un automóvil.
Los microcontroladores representan la inmensa mayoría de los chips de computadoras
vendidos, sobre un 50% son controladores "simples" y el restante corresponde a DSPs
más especializados. Mientras se pueden tener uno o dos microprocesadores de
propósito general en casa, usted tiene distribuidos seguramente entre los
electrodomésticos de su hogar una o dos docenas de microcontroladores. Pueden
encontrarse en casi cualquier dispositivo electrónico como automóviles, lavadoras,
hornos microondas, teléfonos, etc.
Esquema de microcontrolador
Esquema microcontrolador
7. Ing. Braulio Elías Chi Salavarría
Algunas familias de microcontroladores
Clasificación
Actualmente existen más familias de microcontroladores, y más marcas, hasta ahora,
la tendencia es emigrar a 32 bits en la industria, como son los microcontroladores con
arquitectura ARM.
Familia PIC18F4550
Las mejoras que podemos ver en esta familia de microcontroladores de 8 bits de la
compañía Microchip, son los siguientes:
Set de instrucciones extendidas, para optimizar la compilación en lenguaje C
Consumo de corriente mínimo, gracias a su tecnología Nano Watt
Mayores opciones embebidas en esta familia, como pueden ser:
USB
UART
I2C
CAN
Convertidores A/D
PLL integrado
PWM (modulación por ancho de pulso)
Mayor numero de contadores (timer)
8. Ing. Braulio Elías Chi Salavarría
El microcontrolador que vamos a utilizar es el PIC18F4550, en el cual podemos ver sus
principales características:
Ideal para bajo consume (nanoWatt) y conectividad de las aplicaciones que se
benefician de la disponibilidad de tres puertos serie: FS-USB (12 Mbit / s), I ² C ™ y SPI
™ (hasta 10Mbit / s) y uno asincrónico (LIN) de puerto serial (EUSART). Grandes
cantidades de memoria RAM, de memoria FLASH y mejora de la memoria del
programa lo hacen ideal para el control y aplicaciones de monitoreo periódico que
requieren una relación con un ordenador personal a través de datos USB para cargar /
descargar y / o actualizaciones de firmware.
Parameter Name
Program Memory Type
Program Memory Size (Kbytes)
RAM
Data EEPROM (bytes)
I/O
Características
Full Speed USB 2.0 (12Mbit/s) interface
1K byte Dual Port RAM + 1K byte GP RAM
Full Speed Transceiver
16 Endpoints (IN/OUT)
Internal Pull Up resistors (D+/D-)
48 MHz performance (12 MIPS)
Value
Flash
32
2,048
256
24
Figura Microcontrolador 18F4550
9. Ing. Braulio Elías Chi Salavarría
CAPITULO 2
LENGUAJE DE PROGRAMACION C ORIENTADO A SISTEMAS EMBEBIDOS
10. Ing. Braulio Elías Chi Salavarría
Introducción a lenguaje C
Si queremos realizar la programación de los microcontroladores PIC en un lenguaje
como el C, es preciso utilizar un compilador de C.
Dicho compilador nos genera ficheros en formato Intel-hexadecimal, que es el
necesario para programar (utilizando un programador de PIC) un microcontrolador de
6, 8, 18 ó 40 patillas.
El compilador de C que vamos a utilizar es el PCW de la casa CCS Inc. A su vez, el
compilador lo integraremos en un entorno de desarrollo integrado (IDE) que nos va a
permitir desarrollar todas y cada una de las fases que se compone un proyecto, desde
la edición hasta la compilación pasando por la depuración de errores. La última fase, a
excepción de la depuración y retoques hardware finales, será programar el PIC.
Al igual que el compilador de Turbo C, éste "traduce" el código C del archivo fuente (.C)
a lenguaje máquina para los microcontroladores PIC, generando así un archivo en
formato hexadecimal (.HEX). Además de éste, también genera otros seis ficheros.
Operandos
Operadores de asignación
Una expresión de asignación tradicional es de la forma expr1 = expr1 operador expr2,
es decir, i = i + 5. Esta expresión se puede representar por otra forma más corta: expr1
operador= expr2 siguiendo con el mismo ejemplo i += 5.
Es en las expresiones complejas, y no en una tan simple como la del ejemplo, donde se
puede apreciar la conveniencia de usar esta notación. La siguiente tabla resume los
operadores de asignación compuesta y su significado.
Operador Descripción
+= Asignación de suma
-= Asignación de resta
*= Asignación de multiplicación
/= Asignación de división
%= Asignación de resto de división
<<= Asignación de desplazamiento a la izquierda
>>= Asignación de desplazamiento a la derecha
&= Asignación de AND de bits
|= Asignación de OR de bits
^^= Asignación de OR exclusivo de bits
~= Asignación de negación de bits
Operadores aritméticos
11. Ing. Braulio Elías Chi Salavarría
Los operadores aritméticos se usan para realizar operaciones matemáticas. Se listan en
la siguiente tabla:
Operador Descripción Ejemplo
+ Suma (enteros o reales) resul = var1 + var2
- Resta (enteros o reales) resul = var1 - var2
* Multiplicación (enteros o reales) resul = var1 * var2
/ División (enteros o reales) resul = var1 / var2
- Cambio de signo en enteros o reales -var1
% Módulo; resto de una división entera rango = n [A1]% 256
Operadores relacionales
Su misión es comparar dos operandos y dar un resultado entero:
1 (verdadero); 0 (falso).
La siguiente tabla ilustra estos operadores:
Operadores lógicos
Al igual que los operadores relacionales, éstos devuelven 1 (verdadero), 0 (falso) tras la
evaluación de sus operandos. La tabla siguiente ilustra estos operadores.
Operador Descripción
! NO lógico
&& Y lógico
|| O lógico
Operadores de manejo de bits
Estos operadores permiten actuar sobre los operandos a nivel de bits y sólo pueden
ser de tipo entero (incluyendo el tipo char). Son los que siguen:
Operador Descripción
~ Negación de bits (complemento a 1)
& Y de bits (AND)
^^ O exclusivo de bits (EXOR)
| O de bits (OR)
Operador Descripción
< Menor que
> Mayor que
<= Menor o igual que
>= Mayor o igual que
== Igual a
¡= Distinto de
12. Ing. Braulio Elías Chi Salavarría
Librerías Incorporadas
#USE DELAY (CLOCK=frecuencia)
Esta directiva indica al compilador la frecuencia del procesador, en ciclos por segundo,
a la vez que habilita el uso de las funciones DELAY_MS() y DELAY_US().
Opcionalmente podemos usar la función restart_WDT() para que el compilador reinicie
el WDT durante el retardo.
Ejemplos:
#use delay (clock=20000000)
#use delay (clock=32000, RESTART_WDT)
#USE FAST_IO (puerto)
Esta directiva afecta al código que el compilador generará para las instrucciones de
entrada y salida. Este método rápido de hacer I/O ocasiona que el compilador realice
I/O sin programar el registro de dirección. El puerto puede ser A-G.
Ejemplo:
#use fast_io(A)
#USE FIXED_IO (puerto_OUTPUTS=pin_x#, pin_x#...)
Esta directiva afecta al código que el compilador generará para las instrucciones de
entrada y salida. El método fijo de hacer I/O causará que el compilador genere código
para hacer que un pin de I/O sea entrada o salida cada vez que se utiliza. Esto ahorra el
byte de RAM usado en I/O normal.
Ejemplo:
#use fixed_io(a_outputs=PIN_A2 ,PIN_A3)
#USE RS232 (BAUD=baudios, XMIT=pin, RCV=pin...)
Esta directiva le dice al compilador la velocidad en baudios y los pines utilizados para la
I/O serie. Esta directiva tiene efecto hasta que se encuentra otra directiva RS232.
La directiva #USE DELAY debe aparecer antes de utilizar #USE RS232. Esta directiva
habilita el uso de funciones tales como GETCH, PUTCHAR y PRINTF. Si la I/O no es
estándar es preciso poner las directivas FIXED_IO o FAST_IO delante de
#USE RS232
OPCIONES:
RESTART_WDT
Hace que GETC() ponga a cero el WDT mientras espera un carácter.
INVERT
Invierte la polaridad de los pines serie (normalmente no es necesario con el
convertidor de nivel, como el MAX232). No puede usarse con el SCI interno.
PARITY=X Donde X es N, E, u O.
BITS =X Donde X es 5-9 (no puede usarse 5-7 con el SCI).
FLOAT_HIGH Se utiliza para las salidas de colecctor abierto.
ERRORS
Indica al compilador que guarde los errores recibidos en la variable RS232_ERRORS
para restablecerlos cuando se producen.
BRGH1OK
13. Ing. Braulio Elías Chi Salavarría
Permite velocidades de transmisión bajas en chips (uC's, memorias, etc) que tienen
problemas de transmisión.
Cuando utilizamos dispositivos con SCI y se especifican los pines SCI, entonces se usará
el SCI. Si no se puede alcanzar una tasa de baudios dentro del 3% del valor deseado
utilizando la frecuencia de reloj actual, se generará un error.
ENABLE=pin El pin especificado estará a nivel alto durante la transmisión.
FORCE_SW
Usa una UART software en lugar del hardware aun cuando se especifican los pines del
hardware.
La definición de RS232_ERRORS es como sigue:
Sin UART:
El bit 7 es el 9º bit para el modo de datos de 9 bit. El bit 6 a nivel alto indica un fallo en
el modo flotante alto.
Con UART:
Usado sólo para conseguir:
Copia del registro RCSTA, excepto: que el bit 0 se usa para indicar un error de paridad.
Ejemplo:
#use rs232(baud=9600, xmit=PIN_A2,rcv=PIN_A3)
· #USE STANDARD_IO (puerto)
Esta directiva afecta al código que el compilador genera para las instrucciones de
entrada y salida. El método standar de hacer I/O causará que el compilador genere
código para hacer que un pin de I/O sea entrada o salida cada vez que se utiliza. En los
procesadores de la serie 5X esto necesita un byte de RAM para cada puerto
establecido como I/O estandar.
Ejemplo:
#use standard_io(A)
Funciones de I/O discreta
INPUT(pin)
Devuelve el estado '0' o '1' de la patilla indicada en pin. El método de acceso de I/O
depende de la última directiva #USE *_IO utilizada. El valor de retorno es un entero
corto.
Ejemplo:
while ( !input(PIN_B1) );
Nota: El argumento para las funciones de entrada y salida es una dirección de bit. Por
ejemplo, para el bit 3º del port A (byte 5 de los SFR) tendría un valor dirección de
5*8+3=43.
Esto se puede definir como sigue: #define pin3_portA 43.
Los pines o patillas de los dispositivos están definidos como PIN_XX en los archivos de
cabecera *.H. Éstos, se pueden modificar para que los nombres de los pines sean más
significativos para un proyecto determinado.
OUTPUT_BIT(pin, value)
Esta función saca el bit dado en value(0 o 1) por la patilla de I/O especificada en pin. El
modo de establecer la dirección del registro, está determinada por la última directiva
14. Ing. Braulio Elías Chi Salavarría
#USE *_IO.
Ejemplo:
output_bit( PIN_B0, 0); // es lo mismo que output_low(pin_B0);
output_bit( PIN_B0,input( PIN_B1 ) ); // pone B0 igual que B1
output_bit( PIN_B0, shift_left(&data, 1, input(PIN_B1)));
// saca por B0 el MSB de 'data' y al mismo tiempo
// desplaza el nivel en B1 al LSB de data.
OUTPUT_FLOAT(pin)
Esta función pone la patilla especificada como pin en el modo de entrada. Esto
permitirá que la patilla esté flotante para representar un nivel alto en una conexión de
tipo colector abierto.
Ejemplo:
// guardamos la lectura del port A en dato
if( (dato & 0x80)==0 ) // comprobamos si es '1' el MSB
output_low(pin_A0); // si es '1' ponemos a cero el pin A0
else
output_float(pin_A0); // de lo contrario, ponemos el pin A0 a uno
OUTPUT_HIGH(pin)
Pone a 'uno' el pin indicado. El método de acceso de I/O depende de la última directiva
#USE *_IO utilizada.
Ejemplo:
output_high(PIN_A0);
OUTPUT_LOW(pin)
Pone a 'cero' el pin indicado. El método de acceso de I/O depende de la última
directiva
#USE *_IO.
Ejemplo:
output_low(PIN_A0);
PORT_B_PULLUPS(flag)
Esta función activa/desactiva las resistencias pullups en las entradas del puerto B. Flag
puede ser TRUE (activa) o FALSE (desactiva).
Ejemplo:
port_b_pullups(FALSE);
SET_TRIS_A(value)
SET_TRIS_B(value)
SET_TRIS_C(value)
SET_TRIS_D(value)
SET_TRIS_E(value)
Estas funciones permiten escribir directamente los registros tri-estado para la
configuración de los puertos.
Esto debe usarse con FAST_IO() y cuando se accede a los puertos de I/O como si fueran
memoria, igual que cuando se utiliza una directiva #BYTE. Cada bit de value representa
una patilla. Un '1' indica que la patilla es de entrada y un '0' que es de salida.
Ejemplo:
15. Ing. Braulio Elías Chi Salavarría
SET_TRIS_B( 0x0F ); // pone B0, B1, B2 y B3 como entradas; B4, B5, B6 y B7
// como salidas, en un PIC 16c84
Funciones de retardos
DELAY_CYCLES(count)
Esta función realiza retardos según el número de ciclos de instrucción especificado en
count; los valores posibles van desde 1 a 255. Un ciclo de instrucción es igual a cuatro
periodos de reloj.
Ejemplo:
delay_cycles( 3 ); // retardo de 3ciclos instrucción; es igual que un NOP
DELAY_MS(time)
Esta función realiza retardos del valor especificado en time. Dicho valor de tiempo es
en milisegundos y el rango es 0-65535.
Para obtener retardos más largos así como retardos 'variables' es preciso hacer
llamadas a una función separada; véase el ejemplo siguiente.
Es preciso utilizar la directiva #use delay(clock=frecuencia) antes de la llamada a esta
función, para que el compilador sepa la frecuencia de reloj.
Ejemplos:
#use delay (clock=4000000) // reloj de 4MHz
delay_ms( 2 ); // retardo de 2ms
void retardo_segundos(int n) { // retardo de 'n' segundos; 0 <= n => 255
for (; n!=0; n--)
delay_ms( 1000 ); // 1 segundo
}
DELAY_US(time)
Esta función realiza retardos del valor especificado en time. Dicho valor es en
microsegundos y el rango va desde 0 a 65535. Es necesario utilizar la directiva #use
delay antes de la llamada a esta función para que el compilador sepa la frecuencia de
reloj.
Ejemplos:
#use delay(clock=20000000)
delay_us(50);
int espera = 10;
delay_us(espera);
Pasos para hacer un programa en C
Edición de un programa en C
Para crear un programa hay que seguir los pasos siguientes:
1. Especificaciones del programa (qué tiene que hacer)
2. Hacer organigrama
3. Escribir el código fuente (conocer el lenguaje)
16. Ing. Braulio Elías Chi Salavarría
4. Compilar + Enlazar (Link)
5. Depurar errores, si los hay
Análisis de un problema sencillo
Como ejemplo orientativo, se hace a continuación el desarrollo de un programa
sencillo. Se trata de obtener la nota media de un alumno durante un trimestre. El
análisis de esta tarea, que la hemos llamado MEDIA, puede dar el siguiente
procedimiento:
1. leer NOMBRE
2. leer NOTA
3. si no hay mas notas, ir al punto 5
4. ir al punto 2
5. calcular la MEDIA
6. imprimir NOMBRE
7. imprimir MEDIA
2.6.3 Diagrama de flujo del ejemplo “media”
Diagrama de Flujo
17. Ing. Braulio Elías Chi Salavarría
Estructura de un programa en C
De forma generalizada, la estructura de un programa en C tiene el siguiente aspecto:
declaraciones globales
prototipos de funciones
main() {
variables locales;
bloque de sentencias;
llamadas a las funciones;
}
función_1() {
variables locales a 17unción_1;
bloque de sentencias;
llamada a otra/s funciones;
}
función_n() {
…
}
18. Ing. Braulio Elías Chi Salavarría
CAPITULO 3
INSTRUCCIONES PARA LA PROGRAMACIÓN DE MICROCONTROLADOR
19. Ing. Braulio Elías Chi Salavarría
Instrucciones de instalación
Circuito que se montará para la programación del circuito
Fig. Esquema de programación
3.2 Programación de PIC18F4550
Para empezar a programar nuestro microcontrolador daremos los pasos muy sencillos
de cómo hacerlo a continuación
Primer paso
Abrir nuestro plantilla general que se encuentra en la carpeta de programas, con el
nombre de “forma_general” en formato .txt y copiar el texto, abrir nuestro programa
compilador CCS.
20. Ing. Braulio Elías Chi Salavarría
Y seleccionamos NEW-Source File, nos aparecerá la opción de crear nuestro proyecto,
y guardarlo en la carpeta que deseemos, aquí podemos escoger la ubicación que
queramos, como consejo, guardar nuestro archivo en una carpeta exclusiva para
nuestro programa, ya que se crearán muchos archivos al compilar el programa, es solo
cuestión de orden.
Una vez creado el proyecto, pegamos el contenido que copiamos anteriormente (sin
modificar nada) y pegamos en el compilador
Finalmente cerramos nuestra “forma_general” y nos disponemos a modificar el
programa en nuestro compilador.
21. Ing. Braulio Elías Chi Salavarría
Segundo paso
Cuando nuestro programa está bien terminado, y simulado previamente, nos
disponemos a programar físicamente nuestro microcontrolador de una manera muy
sencilla y rápida.
Una vez compilado nuestro programa, se creará un archivo “programa.hex” el cual es
el que necesitamos para poder cargarlo al microcontrolador.
Instalación de Driver para Bootloader USB (Windows vista y 7)
Cuando instalemos el microcontrolador, nos dirá Windows que no reconoce el
dispositivo, y no puede instalar el driver, esto lo haremos manualmente, de la
siguiente forma:
Primero seleccionamos EquipoPropiedades
22. Ing. Braulio Elías Chi Salavarría
Ahora seleccionamos Administrador de dispositivos.
Veremos un dispositivo desconocido conectado al puerto USB, seleccionamos botón
secundario sobre el dispositivo y seleccionamos propiedades.
23. Ing. Braulio Elías Chi Salavarría
Para instalar el driver, necesitamos seleccionar Actualizar Controlador
Nos aparecerá una ventana, debemos seleccionar Buscar software manualmente.
24. Ing. Braulio Elías Chi Salavarría
Seleccionamos Examinar, donde buscaremos la carpeta del curso, dentro de la carpeta
seleccionamos Usb ToolsMCHPUSB Custom Driver
25. Ing. Braulio Elías Chi Salavarría
Programación de microcontrolador con PDFSUSB
Ventana de software para programar microcontrolador
Identificación del software de control.
Conectamos el PIC vía USB, y abrimos el programa “PDFSUSB”, y buscamos la opción
PICDEM FS USB.
26. Ing. Braulio Elías Chi Salavarría
Desde aquí, ya podemos leer el dispositivo, borrarlos, leer el programa compilado
previamente.
Aquí podemos ver, como se leyó, borró y guardó el programa directamente desde USB,
muy fácil y rápido.
Al cargar el programa con la opción Load Hex File, nos saldrá una ventana como esta
Seleccionamos la opción No, para no grabar sobre nuestro programa especial.
Y para grabarlo finalmente, seleccionamos Program Device.
28. Ing. Braulio Elías Chi Salavarría
Guía de Prácticas
Practica #1
Encendido de un led (parpadeo)
Practica #2
Manejo de un puerto como salida, y como entrada
Practica #3
Secuencia de leds con condiciones
Practica #4
Display de 7 segmentos
Practica #5
Motor paso a paso
Practica #6
Motor CD con puente h
Practica #7
ADC
Practica #8
Interrupción timer
Practica #9
PWM (modulación por ancho de pulso)
Practica #10
Manejo de LCD 16x2
Practica #11
LM35 (temperatura)
Practica #12
Puerto Serial RS232
Practica #13
EEPROM externa protocolo I2C
Practica #14
Frecuencímetro
29. Ing. Braulio Elías Chi Salavarría
Ejercicio #1
Encender un led
Objetivo
En esta práctica podremos comenzar a familiarizarnos con los entornos
del compilador, programador, simulación y finalmente programación
física y montaje de nuestro microcontrolador.
Fig. Conexión practica 1 proteus
ESQUEMATICO PRIMERA PRÁCTICA
Hacemos el paso 1 de el capitulo “programación de PIC” y nos disponemos a hacer
nuestro primer programa:
30. Ing. Braulio Elías Chi Salavarría
Este es un programa muy sencillo, en el cual, encenderemos un led durante un
segundo, y se apagará un segundo también, en nuestro programa tenemos el tiempo
de 1 segundo o mejor dicho 1000 milisegundos= 1000*Exp -3; con esta sencilla
conversión podremos darnos cuenta de que si ponemos DELAY_MS(2000) serán 2
segundos y así sucesivamente.
Con la opción “enciende(A0);” ponemos a “1” lógico el pin A0 del puerto A, como
vemos en esta imagen:
enciende(A0);
delay_ms(1000);
apaga(A0);
delay_ms(1000);
31. Ing. Braulio Elías Chi Salavarría
Practica #2
Manejo de un puerto de entrada y salida
Objetivo
Manejar un puerto completo del microcontrolador, así como el manejo
de entrada de datos, por medio de un pulsador, haremos una
introducción a nuevas instrucciones al compilador para poder testear el
puerto A como entrada.
Fig. Esquema practica 2
Esquemático de la práctica
32. Ing. Braulio Elías Chi Salavarría
Código del programa
if(entrada(A0)){
enciende(B7);
}else{
Enapaga(B7);
este programa agregamos una condición if, asi ya podemos tomar decisiones
dependiendo de las condiciones creados por nuestras entradas.
}
Con la condición if(entrada(A0)) preguntamos si el pin A0 se encuentra a 1, si esta
condición es verdadera, entonces enciendo B7, de lo contrario mantenemos apagado
el pin (A0);
33. Ing. Braulio Elías Chi Salavarría
Practica #3
Secuencia de leds (con condiciones)
Objetivo
Dar nuevas condiciones a nuestros programas, para manejar una
secuencia de nuestro puerto B acondicionado por nuestro puerto A
como entrada.
Secuencia de leds (con condiciones)
En esta práctica pondremos a prueba todas las prácticas anteriores
En este programa, vemos una nueva
instrucción “output_b(0x01)” en esta
instrucción le decimos al microcontrolador
que utilice todo su puerto como salida, y
como en este ejemplo, despliegue un 0x00, y
así sucesivamente.
if(entrada(A0)){
output_b(0x01);
delay_ms(1000);
output_b(0x02);
delay_ms(1000);
output_b(0x04);
delay_ms(1000);
output_b(0x08);
delay_ms(1000);
}else{
output_b(0x08);
delay_ms(1000);
output_b(0x04);
delay_ms(1000);
output_b(0x02);
delay_ms(1000);
output_b(0x01);
delay_ms(1000);
}
34. Ing. Braulio Elías Chi Salavarría
Practica #4
Display de 7 segmentos
Objetivo
En esta práctica haremos una secuencia de todo nuestro puerto,
específicamente el puerto B, que se comprende de 8 entradas o salidas,
en este ejemplo lo tomaremos como salidas, formando una palabra de
8 bits (binario). En el cual manejaremos un display de 7 segmentos.
Para nuestro montaje físico, solo utilizaremos 7 bits. Así como también
manejar tiempos de reloj para poder hacer una secuencia de datos
paso a paso.
El visualizador de siete segmentos (llamado también display) es una forma de
representar números en equipos electrónicos. Está compuesto de siete segmentos que
se pueden encender o apagar individualmente. Cada segmento tiene la forma de una
pequeña línea.
Para saber los valores que debemos desplegar en el display de 7 segmentos:
Número a
b
c
d
e
f
g
Valor
hexadecimal
1
X
X
0x60
2
X
X
X
X
X
0xd9
3
X
X
X
X
X
0xf1
4
X
X
X
X
0x63
5
X
X
X
X
X
0xb3
6
X
X
X
X
X
X
0xb7
7
X
X
X
0xe0
8
X
X
X
X
X
X
X
0xf7
9
X
X
X
X
X
0xe3
0
X
X
X
X
X
X
0xf6
35. Ing. Braulio Elías Chi Salavarría
En la tabla de arriba, podemos ver los valores que necesitamos tener en las salidas del
puerto que activará el display de 7 segmentos.
La posición en la cual se conectarán será la siguiente:
PIN D0 = g
PIN D1 = f
PIN D2 = e
PIN D4 = d
PIN D5 = c
PIN D6 = b
PIN D7 = a
Para poder hacer un pequeño contador de 0 a 3 lo realizamos de la siguiente forma:
for(;;){
output_d(0xf6);
delay_ms(500);
output_d(0x60);
delay_ms(500);
output_d(0xd9);
delay_ms(500);
output_d(0xf1);
delay_ms(500);
}
36. Ing. Braulio Elías Chi Salavarría
Practica #5
Motores paso a paso
Objetivo: La siguiente práctica mostrará el conexionado básico para
usar un motor a pasos unipolar.
Agregando a nuestro circuito de prueba un driver ULN2803 al puerto M
y un motor a pasos unipolar a la salida del driver podremos crear un
programa que genere uno de los 3 tipos de movimientos generalizados
para este tipo de motores.
Introducción:
Los motores paso a paso son ideales para la construcción de mecanismos en donde se
requieren movimientos muy precisos.
La característica principal de estos motores es el hecho de poder moverlos un paso a la
vez por cada pulso que se le aplique. Este paso puede variar desde 90° hasta pequeños
movimientos de tan solo 1.8°, es decir, que se necesitarán 4 pasos en el primer caso
(90°) y 200 para el segundo caso (1.8°), para completar un giro completo de 360°.
Estos motores poseen la habilidad de poder quedar enclavados en una posición o bien
totalmente libres. Si una o más de sus bobinas están energizadas, el motor estará
enclavado en la posición correspondiente y por el contrario quedará completamente
libre si no circula corriente por ninguna de sus bobinas.
Secuencias para manejar motores paso a paso Unipolares
Existen tres secuencias posibles para este tipo de motores, las cuales se detallan a
continuación. Todas las secuencias comienzan nuevamente por el paso 1 una vez
alcanzado el paso final (4 u 8). Para revertir el sentido de giro, simplemente se deben
ejecutar las secuencias en modo inverso.
Secuencia Normal: Esta es la secuencia más usada y la que generalmente recomienda
el fabricante. Con esta secuencia el motor avanza un paso por vez y debido a que
siempre hay al menos dos bobinas activadas, se obtiene un alto torque de paso y de
retención.
PASO
Bobina A
Bobina B
Bobina C
Bobina D
1
ON
ON
OFF
OFF
2
OFF
ON
ON
OFF
37. Ing. Braulio Elías Chi Salavarría
3
OFF
OFF
ON
ON
4
ON
OFF
OFF
ON
Fig. Secuencia normal
Secuencia del tipo wave drive: En esta secuencia se activa solo una bobina a la vez. En
algunos motores esto brinda un funcionamiento más suave. La contrapartida es que al
estar solo una bobina activada, el torque de paso y retención es menor.
PASO
Bobina A
Bobina B
Bobina C
Bobina D
1
ON
OFF
OFF
OFF
2
OFF
ON
OFF
OFF
3
OFF
OFF
ON
OFF
4
OFF
OFF
OFF
ON
Fig. secuencia del tipo wave drive
Secuencia del tipo medio paso: En esta secuencia se activan las bobinas de tal forma
de brindar un movimiento igual a la mitad del paso real. Para ello se activan primero 2
bobinas y luego solo 1 y así sucesivamente. Como vemos en la tabla la secuencia
completa consta de 8 movimientos en lugar de 4.
PASO
Bobina A
Bobina B
Bobina C
Bobina D
38. Ing. Braulio Elías Chi Salavarría
1
ON
OFF
OFF
OFF
2
ON
ON
OFF
OFF
3
OFF
ON
OFF
OFF
4
OFF
ON
ON
OFF
5
OFF
OFF
ON
OFF
6
OFF
OFF
ON
ON
7
OFF
OFF
OFF
ON
8
ON
OFF
OFF
ON
Fig. Secuencia del tipo medio paso
Como comentario final, cabe destacar que debido a que los motores paso a paso son
dispositivos mecánicos y como tal deben vencer ciertas inercias, el tiempo de duración
y la frecuencia de los pulsos aplicados es un punto muy importante a tener en cuenta.
39. Ing. Braulio Elías Chi Salavarría
En tal sentido el motor debe alcanzar el paso antes que la próxima secuencia de pulsos
comience. Si la frecuencia de pulsos es muy elevada, el motor puede reaccionar en
alguna de las siguientes formas:
Puede que no realice ningún movimiento en absoluto.
Puede comenzar a vibrar pero sin llegar a girar.
Puede girar erráticamente.
O puede llegar a girar en sentido opuesto.
Para obtener un arranque suave y preciso, es recomendable comenzar con una
frecuencia de pulso baja y gradualmente ir aumentándola hasta la velocidad deseada
sin superar la máxima tolerada. El giro en reversa debería también ser realizado
previamente bajando la velocidad de giro y luego cambiar el sentido de rotación.
Una referencia importante:
Cuando se trabaja con motores P-P usados o bien nuevos, pero de los cuales no
tenemos hojas de datos. Es posible averiguar la distribución de los cables a los
bobinados y el cable común en un motor de paso unipolar de 5 o 6 cables siguiendo las
instrucciones que se detallan a continuación:
Fig. Tipo de motores P.P.
1. Aislando el cable(s) común que va a la fuente de alimentación: Como se aprecia en
las figuras anteriores, en el caso de motores con 6 cables, estos poseen dos cables
comunes, pero generalmente poseen el mismo color, por lo que lo mejor es unirlos
antes de comenzar las pruebas.
Usando un tester para chequear la resistencia entre pares de cables, el cable común
será el único que tenga la mitad del valor de la resistencia entre ella y el resto de los
cables.
Esto es debido a que el cable común tiene una bobina entre ella y cualquier otro cable,
mientras que cada uno de los otros cables tiene dos bobinas entre ellos. De ahí la
mitad de la resistencia medida en el cable común.
2. Identificando los cables de las bobinas (A, B, C y D): aplicar un voltaje al cable
común (generalmente 12 volts, pero puede ser más o menos) y manteniendo uno de
los otros cables a masa (GND) mientras vamos poniendo a masa cada uno de los
demás cables de forma alternada y observando los resultados.
El proceso se puede apreciar en el siguiente cuadro:
40. Ing. Braulio Elías Chi Salavarría
Seleccionar un cable y conectarlo a masa. Ese será
llamado cable A.
Manteniendo el cable A conectado a masa, probar
cuál de los tres cables restantes provoca un paso en
sentido antihorario al ser conectado también a
masa. Ese será el cable B.
Manteniendo el cable A conectado a masa, probar
cuál de los dos cables restantes provoca un paso en
sentido horario al ser conectado a masa. Ese será el
cable D.
El último cable debería ser el cable C. Para
comprobarlo, basta con conectarlo a masa, lo que no
debería generar movimiento alguno debido a que es
la bobina opuesta a la A.
Fig. Funcionamiento de motores P.P.
Nota: La nomenclatura de los cables (A, B, C, D) es totalmente arbitraria.
Identificando los cables en Motores P-P Bipolares:
Para el caso de motores paso a paso bipolares (generalmente de 4 cables de salida), la
identificación es más sencilla. Simplemente tomando un tester en modo ohmetro
(para medir resistencias), podemos hallar los pares de cables que corresponden a cada
bobina, debido a que entre ellos deberá haber continuidad (en realidad una resistencia
muy baja). Luego solo deberemos averiguar la polaridad de la misma, la cual se obtiene
fácilmente probando. Es decir, si conectado de una manera no funciona, simplemente
damos vuelta los cables de una de las bobinas y entonces ya debería funcionar
correctamente. Si el sentido de giro es inverso a lo esperado, simplemente se deben
invertir las conexiones de ambas bobinas y el H-Bridge.
Para recordar
Un motor de paso con 5 cables es casi seguro de 4 fases y unipolar.
Un motor de paso con 6 cables también puede ser de 4 fases y unipolar, pero con 2
cables comunes para alimentación. Pueden ser del mismo color.
Un motor de pasos con solo 4 cables es comúnmente bipolar.
Esquemático
Unipolar: Estos motores suelen tener 6 o 5 cables de salida, dependiendo de su
conexionado interno (ver figura 2). Este tipo se caracteriza por ser más simple
de controlar. En la figura 4 podemos apreciar un ejemplo de conexionado para
controlar un motor paso a paso unipolar mediante el uso de un ULN2803, el
cual es una array de 8 transistores tipo Darlington capaces de manejar cargas
41. Ing. Braulio Elías Chi Salavarría
de hasta 500mA. Las entradas de activación (Activa A, B , C y D) pueden ser
directamente activadas por un microcontrolador.
Conexión ULN2803
0
U1
2
3
4
5
6
7
10
0
U2
+88.8
10
18
17
16
15
14
13
12
11
COM
1C
2C
3C
4C
5C
6C
7C
8C
1B
2B
3B
4B
5B
6B
7B
8B
1
2
3
4
5
6
7
8
21
22
23
24
25
26
27
28
RA0/AN0
RC0/T1OSO/T1CKI
RA1/AN1
RC1/T1OSI/CCP2/UOE
RA2/AN2/VREF-/CVREF
RC2/CCP1
RA3/AN3/VREF+
RC4/D-/VM
RA4/T0CKI/C1OUT/RCV
RC5/D+/VP
RA5/AN4/SS/LVDIN/C2OUT
RC6/TX/CK
RA6/OSC2/CLKO
RC7/RX/DT/SDO
RB0/AN12/INT0/FLT0/SDI/SDA
RB1/AN10/INT1/SCK/SCL
RB2/AN8/INT2/VMO
RB3/AN9/CCP2/VPO
RB4/AN11/KBI0/CSSPP
RB5/KBI1/PGM
RB6/KBI2/PGC
RB7/KBI3/PGD
PIC18F2550
ULN2803
Conexión practica 5
Código
void secuencia(){
output_b(0xFE);
delay_ms(500);
output_b(0xFD);
delay_ms(500);
output_b(0xFB);
delay_ms(500);
output_b(0xF7);
delay_ms(500);
}
void secuencia2(){
output_b(0xF7);
delay_ms(500);
output_b(0xFB);
OSC1/CLKI
VUSB
RE3/MCLR/VPP
11
12
13
15
16
17
18
9
14
1
42. Ing. Braulio Elías Chi Salavarría
delay_ms(500);
output_b(0xFD);
delay_ms(500);
output_b(0xFE);
delay_ms(500);
}
Estas son funciones que vamos a llamar dentro de nuestro menú principal, para que no
tengamos que poner todo, cuando queramos hacer la misma acción.
Programa principal
///////////·······poner programa desde aqui········////////////
if(entrada(A0)){
secuencia();
}
if(entrada(A1)){
secuencia2();
}
//////////··········fin de programa···········///////
43. Ing. Braulio Elías Chi Salavarría
Practica #6
Motor CD con puente H
Objetivo
Conocer el funcionamiento de un Motor CD y dar una explicación de
cómo poner a funcionarlo en ambas direcciones con una lógica de
control avanzada, en la cual será controlada por variables la dirección
de un motor mediante un puente H.
Introducción
Un Puente H o Puente en H es un circuito electrónico que permite a un motor eléctrico
DC girar en ambos sentidos, avance y retroceso. Son ampliamente usados en robótica
y como convertidores de potencia. Los puentes H están disponibles como circuitos
integrados, pero también pueden construirse a partir de componentes discretos.
Funcionamiento puente H
Estructura de un puente H (marcado en rojo)
Puente H
Los 2 estados básicos del circuito.
El término "puente H" proviene de la típica representación gráfica del circuito. Un
puente H se construye con 4 interruptores (mecánicos o mediante transistores).
Cuando los interruptores S1 y S4 (ver primera figura) están cerrados (y S2 y S3
abiertos) se aplica una tensión positiva en el motor, haciéndolo girar en un sentido.
Abriendo los interruptores S1 y S4 (y cerrando S2 y S3), el voltaje se invierte,
permitiendo el giro en sentido inverso del motor.
Con la nomenclatura que estamos usando, los interruptores S1 y S2 nunca podrán
estar cerrados al mismo tiempo, porque esto cortocircuitaría la fuente de tensión. Lo
mismo sucede con S3 y S4.
Como hemos dicho el puente H se usa para invertir el giro de un motor, pero también
puede usarse para frenarlo (de manera brusca), al hacer un corto entre las bornas del
motor, o incluso puede usarse para permitir que el motor frene bajo su propia inercia,
44. Ing. Braulio Elías Chi Salavarría
cuando desconectamos el motor de la fuente que lo alimenta. En el siguiente cuadro
se resumen las diferentes acciones.
S1 S2 S3 S4
Resultado
1 0 0 1 El motor gira en avance
0 1 1 0 El motor gira en retroceso
0 0 0 0 El motor se detiene bajo su inercia
0 1 0 1 El motor frena (fast-stop)
Integrado L293D
Este integrado, es un puente H en el cual, ya no tenemos que hacer todo ese arreglo
de transistores y diodos, esto nos facilita a la hora de armar nuestro circuito, evitando
errores de cableado.
L293D
L293
Diagrama interno de nuestro integrado, en el cual vemos diferentes tipos de
aplicaciones.
45. Ing. Braulio Elías Chi Salavarría
Diagrama a bloques L293
Tabla de verdad de nuestro integrado
Tabla de verdad L293
Esquemático
0
U1
0
8
3
6
11
14
OUT1 VS
OUT2
OUT3
OUT4 GND
U2
16
VSS
GND
IN1
IN2
EN1
EN2
IN3
IN4
2
7
1
9
10
15
L293D
2
3
4
5
6
7
10
21
22
23
24
25
26
27
28
RA0/AN0
RC0/T1OSO/T1CKI
RA1/AN1
RC1/T1OSI/CCP2/UOE
RA2/AN2/VREF-/CVREF
RC2/CCP1
RA3/AN3/VREF+
RC4/D-/VM
RA4/T0CKI/C1OUT/RCV
RC5/D+/VP
RA5/AN4/SS/LVDIN/C2OUT
RC6/TX/CK
RA6/OSC2/CLKO
RC7/RX/DT/SDO
RB0/AN12/INT0/FLT0/SDI/SDA
RB1/AN10/INT1/SCK/SCL
RB2/AN8/INT2/VMO
RB3/AN9/CCP2/VPO
RB4/AN11/KBI0/CSSPP
RB5/KBI1/PGM
RB6/KBI2/PGC
RB7/KBI3/PGD
OSC1/CLKI
VUSB
RE3/MCLR/VPP
PIC18F2550
Código
Declaramos una variable en el lugar donde nos indica que podemos hacerlo
int entradas=0;
Y en nuestro programa principal ponemos esto:
///////////·······poner programa desde aqui········////////////
entradas=PORTA();
if (entradas==0x00){
enciende(B0);
enciende(B5);
enciende(B1);
apaga(B2);
11
12
13
15
16
17
18
9
14
1
46. Ing. Braulio Elías Chi Salavarría
enciende(B6);
apaga(B7);
}
if (entradas==0x01){
enciende(B0);
apaga(B5);
enciende(B1);
apaga(B2);
enciende(B6);
apaga(B7);
}
if (entradas==0x02){
apaga(B0);
enciende(B5);
enciende(B1);
apaga(B2);
enciende(B6);
apaga(B7);
}
if(entradas==0x03){
enciende(B0);
enciende(B5);
enciende(B2);
enciende(B7);
apaga(B1);
apaga(B6);
}
//////////··········fin de programa···········///////
Como podemos ver, en nuestro programa, tenemos que habilitar nuestro driver, y
hacer una combinación de bits de habilitación para poder ir en la dirección que
deseemos ya sea adelante o atrás.
47. Ing. Braulio Elías Chi Salavarría
Practica #7
ADC Convertidor analógico digital
Objetivo
Enseñar el funcionamiento de sensores, los cuales son una parte importante en el
funcionamiento de un sistema automatizado, y como adaptar estas señales a un
microcontrolador.
Introducción
El CNY70 es un sensor óptico reflexivo que tiene una construcción compacta dónde el
emisor de luz y el receptor se colocan en la misma dirección para detectar la presencia
de un objeto utilizando la reflexión del infrarrojo sobre el objeto.
La longitud de onda de trabajo es 950nm. El detector consiste en un fototransistor.
CNY70
¿Cómo configurar nuestro sensor?
48. Ing. Braulio Elías Chi Salavarría
Fig. Conexión CNY70
Valores analógicos y digitales
Los sensores trabajan con señales eléctricas, pero no todos son con señales digitales o
discretas, esto porque su señal es analógica.
Nuestro microcontrolador cuenta con entradas analógicas digitales, esto que quiere
decir, que podemos convertir esas señales analógicas a digitales en forma de un valor
discreto, en esto caso, la hoja de datos nos dice que tenemos hasta 11 canales A/D
repartidos en el puerto A y B con una precisión de 10 bits.
¿10 bits?
Si queremos convertir 10 bits a un valor decimal, solo tendríamos que hacer la
siguiente conversión:
2 = 1024
Tenemos que un voltaje de 5 volts dividido entre 1024 unidades sería que cada
aumento de .00488 volts o 4.88 mili volts, es una cantidad bastante buena y
tendríamos bastante precisión a la hora de medir un sensor.
La fórmula para saber el voltaje adquirido es la siguiente:
∗5
=
1024
Para que nuestro microcontrolador pueda leer valores analógicos cambiamos la
siguiente configuración en nuestra “forma_general”.
setup_adc_ports(AN0_TO_AN1);
setup_adc(ADC_CLOCK_DIV_64);
Seleccionamos una división de 64 debido a que trabajamos a una frecuencia de 48MHz
en el CPU, la tabla del ADC nos dice que:
49. Ing. Braulio Elías Chi Salavarría
Que para una frecuencia de 48MHz seleccionemos una división de 64.
Declaramos una variable
int valor=0x00;
Declaramos una función para leer nuestro valor analógico
void toma_adc(void){
set_adc_channel(0);
delay_ms(1);
valor=read_adc(); }
Y en nuestro programa principal ponemos un valor a partir del cual, pondremos un
valor que cuando llegue, se encenderá nuestro led en el puerto B0.
///////////·······poner programa desde aqui········////////////
toma_adc();
if (valor>100){
enciende(B0);
}else{
apaga(B0);
}
//////////··········fin de programa···········///////
50. Ing. Braulio Elías Chi Salavarría
Practica #8
Interrupción de Timer0
Objetivo
Conocer el funcionamiento de las interrupciones de los temporizadores del microcontrolador,
así como la configuración de las mismas.
Introducción
La interrupción RTCC se produce cada vez que el contador TIMER0 pasa de FFh a 00h.
El timer0 está compuesto por 8 bits, es por esto que solo es de 00h a FFh.
El TIMER0 hace un cómputo completo de 00h a FFh cada 512 µS, sin embargo este
tiempo puede ser cambiado mediante un preescaler o sea un divisor, ajustable. Los
tiempos generados para cada configuración son :
:2 -> 512 µS al mínimo preescaler posible.
:4 -> 1.0 mS
:8 -> 2.0 mS
:16 -> 4.0 mS
:32 -> 8.1 mS
:64 -> 16.3 mS
:128 -> 33.3 mS
:256 -> 66.6 mS al máximo preescaler posible.
El Template que propongo usa un Preescaler de 128 para producir una interrupción
RTCC cada 33.3 mS y así cada 30 veces que se produce cambio de estado la variable
Flag, o sea 33.3 x 30 = 999 mS.
Para declarar una interrupción necesitamos declarar la interrupción de la siguiente
forma
#int_timer0
void int_tiempo0(void){
}
Como se puede observar la directiva #int_timer0 declaramos que es una interrupción
de tipo timer, y debajo de esta directiva tenemos que poner la función que queremos
que haga cuando detecte esta interrupción.
Interrupción timer para nuestro ejemplo
#int_timer0
void int_tiempo0(void){
++contRTCC;
if(contRTCC==30){
contRTCC=0;
if (val==1){
val=0;
}else{
val=1;
}
51. Ing. Braulio Elías Chi Salavarría
}
}
Lo que realizara esta función es cambiar los estados de de las banderas, para que se
apague y prenda A0, asi de esta manera nos evitamos utilizar un retardo y nuestro
programa sigue realizando sus funciones sin tener que parar y quedar en reposo.
En nuestro programa principal tenemos
if(val==1){
output_high(pin_a0);
}else{
output_low(pin_a0);
}
En el esquemático de nuestra práctica únicamente pondremos un led en el puerto A0 y
veremos cómo parpadea, cabe mencionar que hay herramientas fáciles de utilizar para
poder calcular los retardos que deseemos.
Como puede ser RRPic timer calculator
Como podemos observar en la siguiente figura
52. Ing. Braulio Elías Chi Salavarría
Practica #9
PWM (modulación por ancho de pulso)
Objetivo
Aprender la teoría de funcionamiento así como utilizar nuestro PWM
embebido a nuestro microcontrolador y como integrarlo a diferentes
aplicaciones.
Introducción
La modulación por ancho de pulsos (o PWM, de pulse-width modulation en inglés) de
una señal o fuente de energía es una técnica en la que se modifica el ciclo de trabajo
de una señal periódica (por ejemplo sinusoidal o cuadrada) ya sea para transmitir
información a través de un canal de comunicaciones o control de la cantidad de
energía que se envía a una carga.
El ciclo de trabajo de una señal periódica es el ancho relativo de su parte positiva en
relación al período. Matemáticamente:
D es el ciclo de trabajo
τ es el tiempo en que la función es positiva (ancho del pulso)
T es el período de la función
La construcción típica de un circuito PWM se lleva a cabo mediante un comparador
con dos entradas y una salida. Una de las entradas se conecta a un oscilador de onda
triangular, mientras que la otra queda disponible para la señal moduladora. En la salida
la frecuencia es generalmente igual a la de la señal triangular y el ciclo de trabajo esta
en función de la portadora.
La principal desventaja que presentan los circuitos PWM es la posibilidad de que haya
interferencias generadas por radiofrecuencia. Estas pueden minimizarse ubicando el
controlador cerca de la carga y realizando un filtrado de la fuente de alimentación.
53. Ing. Braulio Elías Chi Salavarría
Esquemático a realizar
En esta práctica lo que haremos es configurar nuestro modulo PWM embebido a
nuestro microcontrolador, y variar la anchura de pulso dependiendo de nuestra
entrada de nuestro ADC en el canal A0.
Para empezar debemos de poner en nuestra forma general, los siguientes comandos e
instrucciones
Configuraremos nuestro timer 2, que es el que nos da la frecuencia continua del PWM,
así que pondremos lo siguiente
setup_timer_2(T2_DIV_BY_4, 0xc0, 2);
A continuación configuraremos nuestro modulo CCP como PWM
setup_ccp1(CCP_PWM);
y utilizaremos el ejemplo de la practica #7 para configurar nuestro ADC y tomar los
valores de este.
En nuestro programa principal pondremos
toma_adc();
set_pwm1_duty (valor);
54. Ing. Braulio Elías Chi Salavarría
if (valor>100){
enciende(B0);
}else{
apaga(B0);
}
Y con esto tendremos una lectura parecida a esta en nuestro osciloscopio virtual
El cual variara el ancho de pulso, pero nunca la frecuencia.
55. Ing. Braulio Elías Chi Salavarría
Practica #10
LCD 16x2
Conocer el funcionamiento de un lcd 16x2 y las funciones necesarias
para su aplicación en proyectos.
Introducción
Para que podamos visualizar los resultados obtenidos de nuestros procesos o
monitoreo, una forma muy profesional de visualizarlos es utilizando una pantalla LCD
16x2 que es una excelente opción debido a su bajo consumo y bajo precio en
comparación con otras opciones.
Como podemos observar el
diagrama a bloques de
nuestra practica
En esta práctica lo que
haremos es visualizar el
contenido en nuestro canal
ADC y desplegarlo por la
pantalla.
Para poder llamar a esta
librería, es importante
mencionar que no se
encuentra en las librerías de
CCS, sino que hay que
instalarla en la carpeta de drivers en donde se guardo CCS. Aquí tienen los pasos:
56. Ing. Braulio Elías Chi Salavarría
A continuación configuraremos nuestro canal ADC y nuestro driver para poder
configurar nuestro LCD.
Antes de empezar, es importante decir que debemos quitar los #define para el puerto
B y poner:
#define LCD_DB4 PIN_B3
#define LCD_DB5 PIN_B5
#define LCD_DB6 PIN_B6
#define LCD_DB7 PIN_B7
//
#define LCD_RS PIN_B0
#define LCD_RW PIN_B1
#define LCD_E PIN_B2
Y ponemos al principio la inclusión del archivo
#include <flex_lcd.c>
Para renombrar los pines del puerto B con respecto a nuestra librería flex_lcd.c que se
encuentra en la carpeta.
Inicializamos nuestra función lcd
lcd_init();
lcd_gotoxy(1,1); /////con este comando, le decimos en que fila y que columna
queremos colocar nuestro mensaje
printf(lcd_putc,"PRACTICA 11");///imprimimos mensaje en la pantalla
delay_ms(1500);
lcd_putc('f');///////borramos el mensaje
lcd_gotoxy(1,1);
printf(lcd_putc,"EJEMPLO LCD");
57. Ing. Braulio Elías Chi Salavarría
Código para nuestro menú principal
toma_adc();
lcd_gotoxy(1,1);
printf(lcd_putc,"VALOR ADC:%Lu",valor);
if (valor>1000){ ////esta funcion se utiliza para cuando es mayor a 1000 y se tiene
que borrar
flag_mayor=1; ////el ultimo cero, para que quede igual, y no salga flotando
}
if ((flag_mayor==1)&&(valor<1000)){
lcd_putc('f');
flag_mayor=0;
}
//////////··········fin de programa···········///////
}
58. Ing. Braulio Elías Chi Salavarría
Practica #11
LM35 (sensor de temperatura)
Objetivo
Conocer el funcionamiento de un sensor de temperatura LM35,
características técnicas y programación de lectura de datos.
Introducción
El LM35 es un sensor de temperatura con una precisión calibrada de 1ºC. Puede medir
temperaturas en el rango que abarca desde -55º a + 150ºC. La salida es muy lineal y
cada grado centígrado equivale a 10 mV en la salida.
Sus características más relevantes son:
Precisión de ~1,5ºC (peor caso), 0.5ºC garantizados a 25ºC.
No linealidad de ~0,5ºC (peor caso).
Baja corriente de alimentación (60uA).
Amplio rango de funcionamiento (desde -55º a + 150ºC).
Bajo costo.
Baja impedancia de salida.
Su tensión de salida es proporcional a la temperatura, en la escala Celsius. No necesita
calibración externa y es de bajo costo. Funciona en el rango de alimentación
comprendido entre 4 y 30 voltios.
Como ventaja adicional, el LM35 no requiere de circuitos adicionales para su
calibración externa cuando se desea obtener una precisión del orden de ±0.25 ºC a
temperatura ambiente, y ±0.75 ºC en un rango de temperatura desde 55 a 150 ºC.
La baja impedancia de salida, su salida lineal y su precisa calibración inherente hace
posible una fácil instalación en un circuito de control.
Debido a su baja corriente de alimentación (60uA), se produce un efecto de
autocalentamiento reducido, menos de 0.1 ºC en situación de aire estacionario.
59. Ing. Braulio Elías Chi Salavarría
Para la configuración de nuestro sensor de temperatura utilizaremos el siguiente
esquema:
Ajustamos para que nuestra ganancia para cada grado de aumento sea de .20mv de
voltaje.
Para este ejemplo, no utilizaremos este circuito, aunque se recomienda utilizarlo para
cuando la precisión es muy importante, exponemos el código:
Declaramos variables:
int16 temp=0;
float tempreal=0;
Declaramos nuestra función:
void toma_adc(void){
set_adc_channel(0);
delay_ms(1);
temp=read_adc();
}
Y en nuestro menú principal:
toma_adc();
tempreal=temp/2;
lcd_gotoxy(1,1);
60. Ing. Braulio Elías Chi Salavarría
printf(lcd_putc,"VALOR ADC:%f",tempreal);
Con la pequeña conversión de división, podemos obtener el cálculo correcto de
temperatura.
61. Ing. Braulio Elías Chi Salavarría
Practica #12
Protocolo Serial RS232
Objetivo
Aprender a utilizar el puerto serial y la comunicación con la PC, así
como el uso de interrupción RDA, e interfaz que se necesita para la
conexión.
Introducción
RS-232 (también conocido como Electronic Industries Alliance RS-232C) es una interfaz
que designa una norma para el intercambio serie de datos binarios entre un DTE
(Equipo terminal de datos) y un DCE (Data Communication Equipment, Equipo de
Comunicación de datos), aunque existen otras situaciones en las que también se utiliza
la interfaz RS-232.
Conector RS-232 (DE-9 hembra).
En particular, existen ocasiones en que interesa conectar otro tipo de equipamientos,
como pueden ser computadores. Evidentemente, en el caso de interconexión entre los
mismos, se requerirá la conexión de un DTE (Data Terminal Equipment) con otro DTE.
El RS-232 consiste en un conector tipo DB-25 (de 25 pines), aunque es normal
encontrar la versión de 9 pines (DE-9), más barato e incluso más extendido para cierto
tipo de periféricos (como el ratón serie del PC).
El conector DB9 es
62. Ing. Braulio Elías Chi Salavarría
Número de clavija
1
2
3
4
5
6
7
8
9
Nombre
CD: Detector de transmisión
RXD: Recibir datos
TXD: Transmitir datos
DTR: Terminal de datos lista
GND: Señal de tierra
DSR: Ajuste de datos listo
RTS: Permiso para transmitir
CTS: Listo para enviar
RI: Indicador de llamada
Protección
Diagrama
PROGRAMA
Declaramos la directiva para nuestra interrupción RDA, y nuestra función que hara un
eco a lo que escribamos, y activara una bandera para que cuando detecte el carácter
‘T’ imprima la temperatura.
#int_rda
void serial_isr() {
Keypress=0x00;
if(kbhit()){
Keypress=getc();
if(Keypress!=0x00){
63. Ing. Braulio Elías Chi Salavarría
putchar(keypress);
flag_print=1;
}
}
}
Y en nuestro programa principal tenemos
if (flag_print==1){
if(Keypress=='T'){
printf("VALOR ADC:%fr",tempreal);
}
flag_print=0;
}
Asi es que sin importar que carácter le pongamos, no va a responder, solo con el
carácter T.
64. Ing. Braulio Elías Chi Salavarría
Practica #13
Memoria EEPROM 24C02 (protocolo I2C)
Objetivo
Aprender el protocolo I2C y aplicar las librerías para la memoria
eeprom 24c02
I²C es un bus de comunicaciones en serie. Su nombre viene de Inter-Integrated Circuit
(Circuitos Inter-Integrados). La versión 1.0 data del año 1992 y la versión 2.1 del año
2000, su diseñador es Philips. La velocidad es de 100Kbits por segundo en el modo
estándar, aunque también permite velocidades de 3.4 Mbit/s. Es un bus muy usado en
la industria, principalmente para comunicar microcontroladores y sus periféricos en
sistemas integrados (Embedded Systems) y generalizando más para comunicar
circuitos integrados entre sí que normalmente residen en un mismo circuito impreso.
La principal característica de I²C es que utiliza dos líneas para transmitir la información:
una para los datos y por otra la señal de reloj. También es necesaria una tercera línea,
pero esta sólo es la referencia (masa). Como suelen comunicarse circuitos en una
misma placa que comparten una misma masa esta tercera línea no suele ser necesaria.
Las líneas se llaman:
* SDA: datos
* SCL: reloj
* GND: masa
Las dos primeras líneas son drenador abierto, por lo que necesitan resistencias de pullup. Los dispositivos conectados al bus I²C tienen una dirección única para cada uno.
También pueden ser maestros o esclavos. El dispositivo maestro inicia la transferencia
de datos y además genera la señal de reloj, pero no es necesario que el maestro sea
siempre el mismo dispositivo, esta característica se la pueden ir pasando los
dispositivos que tengan esa capacidad. Esta característica hace que al bus I²C se le
denomine bus multimaestro.
65. Ing. Braulio Elías Chi Salavarría
La siguiente practica nos enseñara como utilizar la memoria EEPROM externa 24C02,
estaremos monitoreando un sensor LM35 y el valor calculado se guardará en la
memoria EEPROM, el tiempo será determinado por la interrupción del timer 0.
La memoria eeprom cuenta con 2Kb de memoria, suficiente para 2000 muestras de 8
bits. Aquí vemos sus características técnicas:
Pueden ponerse más de una memoria en serie, hasta 4 memorias, y estas se controlan
mediante las líneas A0,A1,A2 de la memoria.
Para poder llamar a la librería, necesitamos incluir el archivo 2402.c el cual nos da las
funciones que veremos a continuación:
66. Ing. Braulio Elías Chi Salavarría
///////////·······poner programa desde aqui········////////////
if(flag_timer){
flag_timer=0;
output_toggle(C0);
temp=valor/2;
puntero++;
if(puntero>254)puntero=0;
toma_adc();
write_ext_eeprom(puntero,temp);
}
//////////··········fin de programa···········///////
En donde primero necesitamos llamar a la función init_ext_eeprom(); antes de llamar
a cualquier otra función de la librería. Es importante mencionar que el protocolo I2C
funciona con resistencias pull up. En la simulación podemos ver como se guardan los
datos en la memoria externa.
67. Ing. Braulio Elías Chi Salavarría
Practica #14
Frecuencimetro (Interrupción Externa)
Objetivo:
Conocer el funcionamiento de una interrupción Externa y sus aplicaciones reales en proyectos
avanzados.
Introducción
Las interrupciones externas nos sirven para poder testear un entrada, sin tener que
estarlo haciendo todo el tiempo, solo cuando detecta un cambio lógico en su entrada,
así podemos realizar diversas funciones en nuestro programa, haciendo más eficiente
nuestro código.
Aquí podemos ver el diagrama lógico de todas las interrupciones soportados por
nuestro microcontrolador.
Programa
Nuestro programa capturara una señal desde nuestra interrupción externa, la cual se
incrementará hasta que la interrupción del timer0 llegue a aproximadamente 1
68. Ing. Braulio Elías Chi Salavarría
segundo, debemos saber que no es del todo exacto debido a que la interrupción del
timer0 no llega a 1 segundo exacto para tener un periodo de muestro exacto.
#int_ext
void isr_ext(){
contador++;
}
#int_timer0
void isr_timer0(){
set_timer0(93);
tick++;
if(tick>600){
tick=0;
frecuencia=contador;
contador=0;
}
}
Ahora en nuestro programa for(;;) solo imprimiremos la frecuencia en nuestro LCD:
lcd_gotoxy(1,2);
printf(lcd_putc,"Frec= %Lu",frecuencia);
69. Ing. Braulio Elías Chi Salavarría
REFERENCIAS BIBLIOGRÁFICAS Y VIRTUALES
http://www.elrincondelc.com/cursoc/cursoc7.html
http://www.todorobot.com.ar/informacion/tutorial%20stepper/stepper-tutorial.htm
http://www.terra.es/personal/fremiro/Archivos/CNY70%20web.pdf
http://www.picmania.net