Sunteți pe pagina 1din 69

Curso de microcontroladores

PIC18F4550 Bootloader CCS y


Proteus

Ing. Braulio Elías Chi Salavarría


Instituto Tecnológico de Lerma
Ing. Braulio Elías Chi Salavarría
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.
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.
Ing. Braulio Elías Chi Salavarría

CAPITULO 1

INTRODUCCION A LOS MICROCONTROLADORES


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


Program Memory Type Flash
Program Memory Size (Kbytes) 32
RAM 2,048
Data EEPROM (bytes) 256
I/O 24
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)

Figura Microcontrolador 18F4550


Ing. Braulio Elías Chi Salavarría

CAPITULO 2

LENGUAJE DE PROGRAMACION C ORIENTADO A SISTEMAS EMBEBIDOS


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
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
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
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
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:
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)
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
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() {

}
Ing. Braulio Elías Chi Salavarría

CAPITULO 3

INSTRUCCIONES PARA LA PROGRAMACIÓN DE MICROCONTROLADOR


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.
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.
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 EquipoPropiedades
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.
Ing. Braulio Elías Chi Salavarría

Para instalar el driver, necesitamos seleccionar Actualizar Controlador

Nos aparecerá una ventana, debemos seleccionar Buscar software manualmente.


Ing. Braulio Elías Chi Salavarría

Seleccionamos Examinar, donde buscaremos la carpeta del curso, dentro de la carpeta


seleccionamos Usb ToolsMCHPUSB Custom Driver
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.
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.
Ing. Braulio Elías Chi Salavarría

CAPITULO 4

PRACTICAS DE LABORATORIO
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
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:
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);
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
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);
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 if(entrada(A0)){


output_b(0x01);
instrucción “output_b(0x01)” en esta delay_ms(1000);
instrucción le decimos al microcontrolador output_b(0x02);
que utilice todo su puerto como salida, y delay_ms(1000);
como en este ejemplo, despliegue un 0x00, y output_b(0x04);
delay_ms(1000);
así sucesivamente.
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);
}
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
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);

}
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
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
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.
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:
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
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 11
RA0/AN0 RC0/T1OSO/T1CKI
3 12
0 4
RA1/AN1
RA2/AN2/VREF-/CVREF
RC1/T1OSI/CCP2/UOE
RC2/CCP1
13
5 15
RA3/AN3/VREF+ RC4/D-/VM
6 16
RA4/T0CKI/C1OUT/RCV RC5/D+/VP
7 17
RA5/AN4/SS/LVDIN/C2OUT RC6/TX/CK
10 18
RA6/OSC2/CLKO RC7/RX/DT/SDO
21
U2 RB0/AN12/INT0/FLT0/SDI/SDA
22
RB1/AN10/INT1/SCK/SCL
10 23
COM RB2/AN8/INT2/VMO
18 1 24 9
1C 1B RB3/AN9/CCP2/VPO OSC1/CLKI
17 2 25
2C 2B RB4/AN11/KBI0/CSSPP
16 3 26 14
3C 3B RB5/KBI1/PGM VUSB
15 4 27
4C 4B RB6/KBI2/PGC
14 5 28 1
5C 5B RB7/KBI3/PGD RE3/MCLR/VPP
13 6
6C 6B
+88.8 12 7 PIC18F2550
7C 7B
11 8
8C 8B
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);
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···········///////
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,
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.
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
2 11
0 3
RA0/AN0
RA1/AN1
RC0/T1OSO/T1CKI
RC1/T1OSI/CCP2/UOE
12
4 13
U2 RA2/AN2/VREF-/CVREF RC2/CCP1
8 16 5 15
RA3/AN3/VREF+ RC4/D-/VM
6 16
RA4/T0CKI/C1OUT/RCV RC5/D+/VP
3 2 7 17
OUT1 VS VSS IN1 RA5/AN4/SS/LVDIN/C2OUT RC6/TX/CK
6 7 10 18
OUT2 IN2 RA6/OSC2/CLKO RC7/RX/DT/SDO
1
EN1
21
RB0/AN12/INT0/FLT0/SDI/SDA
22
RB1/AN10/INT1/SCK/SCL
9 23
EN2 RB2/AN8/INT2/VMO
11 10 24 9
OUT3 IN3 RB3/AN9/CCP2/VPO OSC1/CLKI
14 15 25
OUT4 GND GND IN4 RB4/AN11/KBI0/CSSPP
26 14
RB5/KBI1/PGM VUSB
27
RB6/KBI2/PGC
L293D 28 1
RB7/KBI3/PGD 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);
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.
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?


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:
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···········///////
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;
}
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
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.
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);
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.


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:
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");
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···········///////
}
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.
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);
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.
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
Ing. Braulio Elías Chi Salavarría

Número de clavija Nombre


1 CD: Detector de transmisión
2 RXD: Recibir datos
3 TXD: Transmitir datos
4 DTR: Terminal de datos lista
5 GND: Señal de tierra
6 DSR: Ajuste de datos listo
7 RTS: Permiso para transmitir
8 CTS: Listo para enviar
9 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){
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:%f\r",tempreal);
}
flag_print=0;
}

Asi es que sin importar que carácter le pongamos, no va a responder, solo con el
carácter T.
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 pull-
up. 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.
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:
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.
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
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);
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

S-ar putea să vă placă și