tuto micros
DESCRIPTION
tutorial de micro holaTRANSCRIPT
Taller de Introducción a la Programación y Simulación de Microcontroladores
PROYECTO FINANCIADO POR FONDO CONFIA
Bienvenidos al mundo PIC.
Una de las cosas que más fascinan en la electrónica, es programar un
microcontrolador, independiente de las marcas comerciales, tanto “AVR” como
“Microchip” (entre los más conocidos).
En este tutorial, haremos una introducción básica a la programación de un
microcontrolador de la “Microchip”, dentro de los cuales se usará uno de los más comunes
(PIC16F877a). La programación de estos ejemplos, se realizara con el programa PIC C
COMPILER o también conocido como CCS, el cual trabaja con las bases del lenguaje C.
Además usaremos el Programador PICkit 2, el cual será utilizado en todos los ejemplos
vistos, acompañado del simulador PROTEUS.
Para un buen desarrollo de este tutorial, se recomienda tener conocimientos básicos
en “lenguaje de programación C”, dado que habrá funciones que no corresponderán al
tutorial en si.
Taller de Introducción a la Programación y Simulación de Microcontroladores
PROYECTO FINANCIADO POR FONDO CONFIA
Programador PICkit 2.
El programador PICkit 2 esta compuesto por las siguientes partes.
PICkit 2
1. Leds: Indican el estado del programador.
2. Botón de programación: Utilizado como atajo al momento de programar un
dispositivo. Funciona si la opción “Write on PICkit Button” esta habilitado.
3. Conexión para cordón.
4. Puerto USB para conexión con el computador.
5. Marcador del primer Pin (MCLR).
6. Conector de programación.
La conexión con el microcontrolador se realiza según el siguiente esquema.
Conector PICkit 2
1. Master Clear Reset (MCLR).
2. Vdd. (Voltaje +)
3. Vss. (Tierra)
4. PGD. (Data)
5. PGC. (Clock)
6. Pin Auxiliar.
Una característica importante de este programador es que permite alimentar nuestros
proyectos con un consumo máximo limitado por la capacidad del puerto USB, es decir,
100mA por puerto.
Taller de Introducción a la Programación y Simulación de Microcontroladores
PROYECTO FINANCIADO POR FONDO CONFIA
Características del Software PICkit 2 Programmer
El software utilizado es el PICkit 2 Programmer. La captura de pantalla es mostrada a
continuación.
Pasos para programar un microcontrolador
1. Comprobar que en la Ventana de Estado aparezca el dispositivo encontrado.
Además en la sección Dispositivo debe aparecer el microcontrolador utilizado. En
caso de existir un error, se debe verificar la conexión e ir a Tools>Check
Communications.
2. Ir a File>Import Hex y cargar el programa correspondiente, previamente
compilado.
3. Click en Write y listo!
Para alimentar el circuito desde el programador se debe marcar la casilla “On“.
Taller de Introducción a la Programación y Simulación de Microcontroladores
PROYECTO FINANCIADO POR FONDO CONFIA
Estructura básica de un programa en CCS.
En este tutorial se muestra el modo básico de utilización del compilador CCS. Además se
analizará la estructura básica de los programas en C.
Utilización del PIC Wizard
La herramienta PIC Wizard es utilizada para realizar de forma automatica el código base
de nuestros proyectos. Los pasos siguientes describen la generación básica del código.
1. Ir a Project>PIC Wizard.
2. Guardar el proyecto en una carpeta.
3. A continuación aparecera la pantalla que se muestra en la siguiente fotografia.
4. Elegir las opciones correspondientes al proyecto a realizar. Luego dar click en Ok.
5. Aparecerá el código realizado por PIC Wizard. Se muestra en la siguiente imagen.
Taller de Introducción a la Programación y Simulación de Microcontroladores
PROYECTO FINANCIADO POR FONDO CONFIA
En la primera línea del programa se puede apreciar que se hace referencia a un
archivo externo. De preferencia personal, copio el código contenido en ese archivo para
poder tener a la vista todos los fuses mientras completo el resto del software. Para quedar
de la siguiente forma.
Taller de Introducción a la Programación y Simulación de Microcontroladores
PROYECTO FINANCIADO POR FONDO CONFIA
Finalmente para compilar se da un click en Compile>Compile.
Taller de Introducción a la Programación y Simulación de Microcontroladores
PROYECTO FINANCIADO POR FONDO CONFIA
Programando mi primer PIC.
Como bien sabemos, cada componente electrónico de 3 o más pines, tiene un
pinout, por los cuales se conectan debidamente. Por ende los microcontroladores no son la
excepción. Para trabajarlos debemos saber como conectarlos y para eso debemos buscar el
datasheet, dado que trabajaremos en este tutorial con 2 microcontroladores, anexare el
pinout de ambos a continuación:
Taller de Introducción a la Programación y Simulación de Microcontroladores
PROYECTO FINANCIADO POR FONDO CONFIA
Conexión básica de un microcontrolador.
En esta sección aprenderemos el manejo básico de puertos de los
microcontroladores PIC, utilizando el programador PICkit 2 y el compilador CCS.
Materiales a utilizar:
PIC16F877A.
Cristal 20Mhz.
Leds.
Capacitores 22pF.
Resistores 330Ω.
Resistor 1okΩ.
Programador PicKit 2.
Compilador CCS.
Existen diversas formas de conectar un microcontrolador PIC16F877A para realizar un
proyecto básico. Estas formas son mostradas en la figura que aparece a continuación.
En ambas figuras se utiliza un resistor de 10kΩ en el MCLR (Master Clear Reset). Este
Pin cumple la función de resetear el microcontrolador cuando es llevado a tierra, por ello,
para el normal funcionamiento del programa se debe mantener conectado mediante un
resistor a la alimentación.
La principal diferencia entre las dos conexiones mostradas anteriormente ocurre en la
utilización del Cristal. La figura izquierda muestra el microcontrolador utilizando un cristal
externo de 20Mhz, mientras que el de la derecha utiliza un cristal interno de 4Mhz. En estos
tutoriales utilizaremos la conexión mostrada en la posición derecha.
Taller de Introducción a la Programación y Simulación de Microcontroladores
PROYECTO FINANCIADO POR FONDO CONFIA
Ejemplo 1: Prendiendo Leds
A continuación conoceremos las distintas formas que posee CCS para el manejo de
los puertos del microcontrolador. Lo primero que se debe realizar es seleccionar cada pin
del puerto como entrada o salida. Para esto se utiliza la función set_tris_x. A continuación
algunos ejemplos.
//valor 0 representa pin de salida, valor 1 representa pin de entrada.
set_tris_a(0x00); //Puerto A como salida.
set_tris_b(0b10010000); //Puerto B, pines B4 y B7 como entrada, el resto
como salida
Si el pin es definido como salida, tenemos dos formas de manejar sus estados logicos.
La primera es manejando el puerto completo ó manejando cada pin por separado.
//Opción 1: Manejando todos los pines del puerto
//Se define un byte (fuera del main) con la dirección del puerto (Ver
Datasheet)
#Byte puerto_b = 0x06 //Dirección del puerto B
//Luego se aplican valores
puerto_b = 0b10100100; //Los pines B2,B5 y B7 están en un estado lógico
alto (+5V),
//---------------------------------------------
//Opción 2: Manejando todos los pines del puerto, sin definirlo
output_b(0b10010000); //Los pines B7 y B4 están en un estado lógico alto
(+5V),
//---------------------------------------------
//Opción 3: Manejando los pines uno a uno.
//Utilizando output_high y output_low
output_high(PIN_A1); //Estado lógico alto (+5V) el pin 1 del puerto A.
output_low(PIN_C3); //Estado lógico bajo (0V) el pin 3 del puerto C.
Una de las formas de darle tiempo de función al pin, ya sea para mantenerlo en un
estado logico alto o bajo, se da con la sentencia delay_ms(); delay:us; depende si estas
trabajando en milisegundos o microsegundos respectivamente.
//Un tiempo puede servir para una o más funciones
output_high(pin_b4); //Estado lógico alto (+5V) el pin 4 del puerto B.
delay_ms(400); //Tiempo de trabajo 400 milisegundos.
output_low(pin_b4); //Estado lógico bajo (0V) el pin 4 del puerto B.
output_high(pin_b5): //Estado lógico alto (+5V) el pin 5 del puerto B.
delay_us(2000); //Tiempo de trabajo 2000 microsegundos.
Taller de Introducción a la Programación y Simulación de Microcontroladores
PROYECTO FINANCIADO POR FONDO CONFIA
Con todo lo anterior listo, estamos en condiciones de hacer parpadear distintos leds,
para ellos se utilizará el diagrama de conexión mostrado en la figura siguiente.
Ahora el programa a utilizar hará que cada 500 milisegundos cambie el Led que
prende, pueden modificarlo y comprobar los ejemplos vistos anteriormente.
Taller de Introducción a la Programación y Simulación de Microcontroladores
PROYECTO FINANCIADO POR FONDO CONFIA
Ejemplo 2: Programando pantalla LCD
En el siguiente ejemplo, manejaremos una pantalla LCD de 16x2, la cual será
conectada a el PIC16F877A, por el puerto D, si se desea usar un PIC16F628A, se
recomienda usar el puerto B y modificar la librería.
El pinout de la pantalla LCD, es el siguiente:
1. VSS: Tierra
2. VDD: Voltaje (+3.3 a +5V)
3. VEE: Ajustador de contraste
4. RS: Selector de Registro (Register Select). RS=0: Comando, RS=1: Data
5. RW: Lector/Escritor (Read/Write). R/W=0: Escribe, R/W=1: Lee.
6. E: Habilitador [Clock (Enable)]. Caída de borde Accionado.
7. D0: Bit 0 (No se usa en una operación de 4-bit)
8. D1: Bit 1 (No se usa en una operación de 4-bit)
9. D2: Bit 2 (No se usa en una operación de 4-bit)
10. D3: Bit 3 (No se usa en una operación de 4-bit)
11. D4: Bit 4
12. D5: Bit 5
13. D6: Bit 6
14. D7: Bit 7
15. VDD: Voltaje Backlight (V+)
16. VSS: Voltaje Backlight (V-)
NOTA:
Se recomienda usar un potenciómetro conectado al pin de contraste para variar este
a gusto.
El Backlight no viene incorporado en todas las pantallas LCD, por lo cual algunas
pueden variar entre 14 pines (sin backlight) o 16 pines (con backlight incorporado o espacio
para este).
Taller de Introducción a la Programación y Simulación de Microcontroladores
PROYECTO FINANCIADO POR FONDO CONFIA
Para programar la pantalla LCD, usaremos la librería <lcd.c>, en las cuales
podremos usar nuevas funciones:
//Función OBLIGATORIA para iniciar la pantalla
lcd_init(); Sin esta, la pantalla no funciona
//-----------------------------
//Funciones para escribir la pantalla
lcd_putc(“ “); Entre comillas se escribe lo que quieren mostrar
printf(lcd_putc, “ “);
ejemplo: lcd_putc(“hola mundo!”);
delay_ms(500);
//-----------------------------
//Funciones de posición
//Función que asigna posición
lcd_gotoxy(x,y); donde x: indica posición del primer carácter
y: indica línea de la palabra
ejemplo: lcd_gotoxy (5,1);
lcd_putc(“hola”);
lcd_gotoxy (9,2);
lcd_putc(“mundo”);
Se verá así: 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6
1| h o l a |
2| m u n d o |
//Función que devuelve la posición
lcd_getc(x,y); Te da la posición
//-----------------------------
//Caracteres especiales de control
\f Borra el display
\n Salta a la segunda línea
\b Retrocede una posición
Ejemplo: lcd_putc(“\f”);
Taller de Introducción a la Programación y Simulación de Microcontroladores
PROYECTO FINANCIADO POR FONDO CONFIA
Ahora, con las funciones ya vistas, para lo cual utilizaremos el siguiente diagrama
de conexión micro-pantalla:
Ahora ya podemos hacer que nuestra pantalla haga lo que se requiere, para este
ejemplo haremos que la pantalla muestre “MundoPIC” en movimiento, para lo cual
usaremos el siguiente programa:
Taller de Introducción a la Programación y Simulación de Microcontroladores
PROYECTO FINANCIADO POR FONDO CONFIA
Ejemplo 3: Leyendo entrada ADC (conversor análogo a digital)
Ahora realizaremos un ejemplo para la lectura de un ADC, para esto usaremos
una resistencia variable (un potenciómetro). Con este tipo de lectura, se pueden desarrollar
una cantidad enorme de lectura de sensores, dependiendo de las entradas ADC que posea el
microcontrolador. Estas están denotadas por ANx donde x es un número que parte desde 0.
Ejemplo: El pic16f877a tiene 8 entradas ADC (desde AN0 a AN7).
Para usar este tipo de entradas, no se necesita definir una librería como tal, ya que
estas funciones vienen incluidas dentro de la librería del PIC correspondiente.
Las sentencias a usar en estos casos son:
//Función que determina el número de bits que retorna read_adc();
#device ADC=X, donde X es la cantidad de bits que retornará.
Ej: #include<pic16f877a.h>
#device ADC=8 // me retorna un número de 8 bits.
//Función que sirve para definir los puertos ADC a usar.
setup_adc_ports(); entre paréntesis va el o los ADC.
Ej: 1)setup_adc_ports(AN0); para usar solo el puerto AN0 como análogo
2)setup_adc_ports(AN7, AN6); usas AN7 y AN6 como análogos
3)setup_adc_ports(ALL_ANALOG); usas todos los puertos análogos
//Función para poner el canal de trabajo
set_adc_channel(X); X varia de 0 y varia según ANx.
Ej: set_adc_channel(0); usa el canal 0 para trabajar
//Función para declarar el tiempo de trabajo
setup_adc(ADC_CLOCK_INTERNAL); usa el oscilador interno del ADC.
setup_adc(ADC_CLOCK_DIV_X); donde X=2,4,8,16,32,64,128,256.
Ej: setup_adc(ADC_CLOCK_DIV_8); el timer del micro se divide por 8.
//Función para guardar datos del ADC.
read_adc(); esta sentencia solo lee el dato, el cual debe ser guardado en
un float, int o el que deseen.
Ej: value=read_adc();
delay_ms(10);
Nota: por lo general los datos obtenidos varían entre 0 a 255.
Taller de Introducción a la Programación y Simulación de Microcontroladores
PROYECTO FINANCIADO POR FONDO CONFIA
Con lo antes visto, vamos a seguir con el ejemplo. A continuación vamos a
mostrar la lectura del ADC en una pantalla LCD, para el cual usaremos la siguiente
configuración del PIC.
En el circuito superior, se muestra una conexión del potenciómetro a la entrada
AN0 del microcontrolador, por lo cual el canal a usar será 0. Además como el
potenciómetro en algún momento puede llegar a ser cero (como toda resistencia variable),
le ponemos en serie una resistencia estable, para que así no se provoque un corto circuito.
Luego de esto en el software sería mucho más fácil trabajar con un ADC=8 ya
que retornara un valor entre 0 a 255.
Taller de Introducción a la Programación y Simulación de Microcontroladores
PROYECTO FINANCIADO POR FONDO CONFIA
El programa a utilizar es el siguiente:
Taller de Introducción a la Programación y Simulación de Microcontroladores
PROYECTO FINANCIADO POR FONDO CONFIA
Ejemplo 4: Señal de PWM (Modulación de ancho de pulso)
Uniendo un poco de los ejemplos anteriores, diseñaremos un programa el cual
pueda dar una modulación a un pulso emitido por un pin específico del
microcontrolador(ccp1 o ccp2), el cual hará varias la intensidad lumínica de un LED. Esto
lo haremos tomando la variación de ADC con un potenciómetro.
Las funciones que se añaden a lo antes visto serán las siguientes:
//Función para definir frecuencia de trabajo
setup_timer_2(T2_DIV_BY_X, periodo, T2DIV set to );
Donde X puede ser un divisor exacto de 256.
El periodo es un valor entre 0 y 255.
T2DIV set to es para acomodar la fórmula y tener frecuencias más bajas
o altas.
Ej: setup_timer_2(T2_DIV_BY_1, 49, 1); en este caso se puede trabajar a
20KHz trabajando con un cristal de 4MHz.
//Función para la selección de PIN de PWM a usar
setup_ccpX(CCP_PWM); X es un valor dependiendo del PIN de PWM a usar
Ej: setup_ccp1(CCP_PWM); Habilitamos CCP1 como salida de PWM.
//Función que permite emitir un valor mediante el PIN.
set_pwmX_duty(valor); X debe ser el mismo que el del PIN seleccionado.
El “valor” es un numero que varía entre 0 y 255 (256 bits).
Nota:
La “fórmula” para determinar la frecuencia de trabajo está dada de la siguiente
forma:
F = (4/frecuencia cristal)*T2_DIV*(periodo+1)
Ej: Para la frecuencia de 20KHz.
F = (4/4000000)*1*50 = 50/1000000 = 0.000050 = 50us
Si dividimos 1 en 50us (1/50us) obtenemos los 20KHz de trabajo. Ojo que la frecuencia de
trabajo la obtenemos en ciclos por eso nos da en función del tiempo, y como bien es sabido,
si tenemos un periodo, la inversa es la frecuencia.
Nota2:
La frecuencia de trabajo se determina según lo que se quiere manejar, por
ejemplo, en el caso de un LED o SERVOMOTOR la frecuencia es de 50Hz.
Taller de Introducción a la Programación y Simulación de Microcontroladores
PROYECTO FINANCIADO POR FONDO CONFIA
Una vez entendido el código, procedemos con la conexión del circuito, que sigue
teniendo como base lo antes visto.
El circuito recién presentado, sirve para realizar la variación de intensidad
lumínica de un LED, como se explicaba anteriormente. Además, mostrará la variación de
los valores que a este se le entregan por la lectura del ADC a este.
Una de las grandes diferencias que se no se pueden ver en la conexión, pero si en
el programa, es que usaremos un cristal de 4MHz, ya que el LED trabaja a una frecuencia
de 50Hz, y al aplicar la “fórmula” con un cristal de 20MHz no se alcanza a obtener la
frecuencia requerida.
Este ejemplo se recomienda no simularlo, y desarrollarlo en su totalidad, ya que
en la simulación solo se ve el LED parpadeando a distintas velocidades.
Como se dijo en un ejemplo anteriormente, los valores del potenciómetro y
resistor pueden variarlos para que traten de quedar en el rango de 0 a 255.
Taller de Introducción a la Programación y Simulación de Microcontroladores
PROYECTO FINANCIADO POR FONDO CONFIA
Veamos el código.
Nota: Cambiamos HS (high speed) por XT (external timer) en los fuses, ya que la
frecuencia de trabajo del cristal (4MHz) no alcanza a quedar en el rango de altas
velocidades. Cabe decir que HS y XT se usan para cristales externos dependiendo de su
“velocidad”.
Taller de Introducción a la Programación y Simulación de Microcontroladores
PROYECTO FINANCIADO POR FONDO CONFIA
Ejemplo 5: Comunicación Serial
Ahora que ya sabemos un poco sobre el uso de los microcontroladores, ¿Qué pasaría si con
uno no puedo hacer todo lo que quiero? Hay varias veces que necesito dos circuitos
procesando en paralelo dentro de la misma placa y pasa esto está la comunicación serial.
Para esto lo primero que debemos hacer, después de agregar el clock microcontrolador, es:
//Ya agregadas las librerías
#use delay(clock=20000000)
#use rs232(baud=9600,parity=n,xmit=pin_C6,rcv=pin_C7,bits=8)
Donde BAUD: es la velocidad a la que se quiere transmitir los datos (debe
ser igual en el pic emisor y en el receptor)
Parity: es el bit de paridad (ultimo bit que define si es par o impar)
Xmit: es donde se debe conectar el pin como emisor (C6 en nuestro caso)
Rcv: es donde se debe conectar el pin como receptor (C7)
Bits: es el número de bits por transmisión, puede ser 8 o 9
//Nuevos comandos
Ahora podremos usar las funciones GETC(), PUTCHAR(), PRINTF() Y PUTC()
//Interrupción de lectura
Como podemos estar recibiendo datos en pleno funcionamiento del sistema,
debemos crear una interrupción para que los datos no se pierdan.
Las interrupciones se manejan de la siguiente manera
char caracter; //Variable a guardar dato de entrada
#INT_RDA //Define la interrupcion (función que le sigue)
void int_rda_sr(){ //Define la funcion
if(kbhit()){ //¿Hay señal de entrada? Si, entro.
caracter = getc(); //Guardo mi caracter
if(caracter == 'A'){} //comparo y actuo
if(caracter == 'B'){}
...]]
//Mandar datos
Ya sabemos cómo recibirlos, pero ¿cómo lo enviamos?
Ejemplo:
if(valor==1){
printf("A");}
Y ya se mandó el dato.
Se ve poco más complicado que lo anterior, pero sigue siendo un poco más de lo mismo.
Taller de Introducción a la Programación y Simulación de Microcontroladores
PROYECTO FINANCIADO POR FONDO CONFIA
El circuito a utilizar será el siguiente:
En este ejemplo buscaremos leer la señal ADC y enviar datos de forma serial al otro
controlador el cual tomara la decisión de prender cierto led cada vez que esté dentro de un
rango definido.
Taller de Introducción a la Programación y Simulación de Microcontroladores
PROYECTO FINANCIADO POR FONDO CONFIA
A continuación veremos el código para el emisor:
Taller de Introducción a la Programación y Simulación de Microcontroladores
PROYECTO FINANCIADO POR FONDO CONFIA
Y acá para el receptor: