Está en la página 1de 13

Que lenguaje usar para programar Microcontroladores PIC

Es la primera pregunta que debemos contestarnos al querer programar un microcontrolador,


frente a esta pregunta eres tu el que debe decidir el lenguaje de programacin, en esta entrada
expongo el porque he elegido hacerlo en CCS.
ASSEMBLER
En mi opinin este es el mejor lenguaje para comenzar a programar, esto si queremos saber
exactamente que estamos haciendo con el microcontrolador.
Mi recomendacin es comenzar con lenguaje ensamblador aprender a utilizar los puertos a
configurar registros etc, todo lo bsico. Y luego pasarse a un lenguaje de alto nivel como CCS
o C18. Esto es opcional si quieres comenzar directamente con CCS puedes hacerlo.

Ventajas

- Precisin: Controla totalmente la operacin del microcontrolador y permite al programador


precisin en las operaciones.
- Herramienta educacional: permite conocer a detalle la arquitectura interna del
microcontrolador, el set de instrucciones, los registros y su funcionamiento interno.
- Tamao: los compiladores generan ms cdigo mquina del necesario; por ello, el programa
ejecutable crece. Por lo tanto cuando es importante reducir el tamao del ejecutable,
optimizando el uso de la memoria y teniendo tambin beneficios en velocidad, puede convenir
usar el lenguaje Ensamblador.

Al ser un lenguaje ms primitivo, el Ensamblador tiene ciertas desventajas:

- Cdigos mas complejos desde el punto de vista del programador: en assembler


debemos declarar correctamente todo lo que usaremos a diferencia de los lenguajes basados
en C, esto hace que veamos nuestro cdigo mas extenso y complejo.
- Tiempo programando: Para aplicaciones complejas no recomendara asembler ya que se
debe invertir una cantidad de tiempo muchsimo mayor que con otros lenguajes.
- Falta de potabilidad: debido a que depende de la estructura interna del microcontrolador, el
cdigo de un microcontrolador no puede correr en otro de diferente arquitectura.

Ejemplo de cdigo assembler


?

PROCESSOR 16f886 ;seleccionamos que microcontrolador


1 usaremos
2 #INCLUDE <16f886.inc> ;carga librera del microcontrolador
3
4 ORG 0x00 ;origen de programa
5
6 bsf STATUS,RP0 ;acceso al banco 1 de la memoria
7 movlw b'0001111'
8 movwf TRISA ;configura el puertoA como entrada
9
clrf TRISB ;configura el puertoB como salida
10
11 bcf STATUS,RP0 ;RP0 a 0 para acceder al banco 0
12
13inicio
14 movf PORTA,W ;mueve el contenido del PuertoA a W
15 movwf PORTB ;mueve el dato de W al puertoB
16 goto inicio ;salta a inicio y entra en un bucle
END ;fin del cdigo

EL LENGUAJE C
Ventajas:

- Facilidad de uso: Los programas en C son ms fciles de mantener (revisar, modificar,


ampliar).
Existen muchsimas libreras libremente disponibles para el uso de cualquier programador, lo
cual facilita el desarrollo de una aplicacin.
- Potabilidad: Generalmente un programa escrito para un tipo de microcontrolador puede
correr con mnimas modificaciones en otro microcontrolador de diferente arquitectura.

- Eficiencia: Es ms rpido y eficiente que otros lenguajes de alto nivel usados tambin para
programar microcontroladores y su uso est altamente difundido en aplicaciones
profesionales. Con compiladores modernos puede llegar a ser tan rpido como el ensamblador
dependiendo de la habilidad y los recursos del programador.

Desventajas:
- El cdigo escrito en C ocupa ms memoria que el escrito en ensamblador.
Los programas al compilarlos pueden resultar un poco extensos y pesados por ello debe
tenerse en cuenta la capacidad de memoria de programa del PIC a utilizar.
- Control:Con este lenguaje no se puede controlar del todo los tiempos y los registros bit a bit.

Compilador CCS PCW HD


Este es un compilador de punto flotante que puede integrarse al ambiente MPLAB IDE de
Microchip.

Un dato importante de este compilador, es que abstrae del hardware, y con ello sacas muy
rpido tus proyectos, no tienes que conocer tan finamente al microcontrolador que programas
y sus "modulos", ademas trae una cantidad de libreras y programas de ejemplos,esto acorta
increblemente los tiempos de aprendizaje y desarrollo de los proyectos.

A continuacin veremos algunas caractersticas que presenta el compilador PCW CCS y


que hacen de l una buena opcin para elegirlo como compilador de C para programar
Microcontroladores PIC

1. Al compilar genera un cdigo mquina muy compacto y eficiente.


2. Se integra perfectamente con MPLAB y otros simuladores/emuladores como
PROTEUS para el proceso de depuracin.
3. Incluye una biblioteca muy completa de funciones precompiladas para el acceso al
hardware de los dispositivos (entrada/salida, temporizaciones, conversor A/D,
transmisin RS-232,bus I2C.,etc.
4. Tiene numerosas libreras ya integradas al compilador para dispositivos externos, tales
como pantallas LCD, teclados numricos, memorias EEPROM, conversores A/D,
relojes en tiempo real, etc.
5. Permite insertar partes de cdigo directamente en Ensamblador, manteniendo otras
partes del programa en C.

6. Primeros Pasos con CCS encender un LED


7. En la "entrada anterior" aprendimos a descargar e instalar el Compilador CCS,
ademas crear nuestro primer cdigo fuente (vaco), en esta entrada aprenderemos un
poco mas sobre como empezar a programar, para esto vamos a hacer el hola mundo
de la electrnica, encender y apagar un LED. Pero primero vamos a conocer un poco
mas sobre este lenguaje de programacin.
8. Gestin de los puertos de Entrada y Salida:
9.
Los puertos son el punto de comunicacin entre el microncontrolador y el mundo
exterior , a travs de ellos se pueden recibir y enviar seales al exterior para efectuar
procesos de control electrnico sobre otros dispositivos.
En el lenguaje CCS se pueden gestionar los puertos de 2 formas:

1.- Declarando los registros TRISX y PORTX.

Se definen los registros PORTx y TRISx como bytes y se sitan en la posicin


correspondiente de la memoria RAM. La directiva utilizada de C es #BYTE
10. #BYTE variable=constante;
11. ?

#BYTE TRISA = 0x85 //direccin del registro TRISA en el banco de


memoria
1#BYTE PORTA = 0x05 //direccin del registro PORTA en el banco de
2memoria
3#BYTE TRISB = 0x86 //direccin del registro TRISb en el banco de
4memoria
#BYTE PORTB = 0x06 //direccin del registro PORTB en el banco de
memoria

12. Una vez definidas estas variables se pueden configurar y controlar los puertos.
13. ?

1TRISA = 0xFF; // todos los pines de entrada


2TRISB = 0x00; // todos los pines de salida
3TRISC = 0x0F; // 4 terminales de salida, 4 terminales de entrada

14. Tambin podemos trabajar bit a bit con los registros o variables definidas previamente.
15. ?

1bit_clear(PIN_B0) ; //Pone a 0 el bit especifico de la variable


2bit_set(PIN_B0); //Pone a 1 el bit especifico de la variable
3bit_test(PIN_B0); //Muestra el bit especifico de la variable

16. o podemos definir todos los bits del puerto de una vez con:
17. ?

1PORTC = 0xFF; //define todo el puertoA a 1

18.
2.- Utilizando las directivas especificas del compilador.

El Lenguaje C admite unas directivas de compilacin que le dicen al compilador cmo


debe tratar los TRIS del puerto, esta es la manera mas simple de hacerlo y es la que
usaremos.

Estas directivas son: USE FAST_IO, USE FIXED_IO, USE_STANDARD_IO

Si declaramos un puerto cmo #USE FAST_IO(PUERTO)


Es el usuario quien debe asegurarse de que el sentido del pin es el correcto y para ello
debe colocar antes de leer o escribir en el puerto correspondiente el
SET_TRIS_X(0b00000000) para indicar el uso de entrada o salida de cada bit del
puerto.
Si declaramos un puerto cmo #USE FIXED_IO(PUERTO_OUTPUTS=1,3,5,7)
El compilador genera e inserta en tu cdigo los SET_TRIS_X(0b10101010)
correspondientes a dicha declaracin independiente del uso que tus instrucciones
hagan despus de dichos pines. Si has declarado con FIXED_IO de salida el pin 1 del
puerto X y despus lo lees el compilador no har nada y estars leyendo un puerto de
salida.

Si por ltimo declaramos el puerto cmo #USE STANDARD_IO(PUERTO)


El compilador generar automticamente e insertar antes de cualquier operacin de
entrada o salida de cualquier pin del puerto X los SET_TRIS_X() correspondientes a la
instruccin que le sigue. Esto hace que los TRIS siempre estn de acuerdo con la
instruccin a ejecutar. Si colocamos en nuestro cdigo un OUTPUT_HIGH(PIN_B0) y
el puerto B est declarado como #USE STANDARD_IO(B) justo antes del output habr
un TRIS declarando el PIN_B0 como salida, si a continuacin ponemos un
INPUT_(PIN_B0) el compilador pondr ahora un TRIS para declarar PIN_B0 como
entrada.

Este #USE STANDARD_IO(X) es el modo POR DEFECTO de todos los puertos en


CCS si no se declara lo contrario.

Gestin de los puertos a travs de Directivas:


19. ?

output_X(valor); //Por el puerto correspondiente saca el valor


(0-255).
input_X(); //Se obtiene el valor en el puerto
1correspondiente.
2set_tris_X(valor); //Carga el registro TRISx con el valor (0-
3
255)
4
5port_b_pullups(true); //Habilita las resistencias pul-up en el
PORTB .
get_trisX(); //Devuelve el valor del registro TRISx (x es
A,B,C,D)

20.
Las funciones para trabajar bit a bit son:
21. ?

1output_low(pin*) //Pin a 0.
2output_high(pin*) //Pin a 1
3output_bit(pin*,valor) //Pin al valor especificado
4input(pin*); //Lee el valor del pin.

22.
23. Estructuras de Control Repetitivas
24.
25. Las estructuras de control repetitivas o iterativas, tambin conocidas como bucles se
pueden usar cuando se quiere repetir cierta parte del cdigo n veces, otras permiten
repetir un segmento de cdigo cuando se cumplen ciertas condiciones.

Bucle WHILE
Este bucle ejecuta una instruccin o un conjunto de instrucciones mientras la
condicin se cumpla, generalmente a la condicin se le coloca el valor true, para que
siempre se repita.
26. ?
1while(condicin)
2 {
3 segmento de cdigo a repetir
4 }

27. Bucle FOR


Este bucle permite ejecutar una instruccin o un bloque de instrucciones una cantidad
determinada de veces. se suele reemplazar por el ciclo while cuando se conoce o se
desea un cierto numero de iteraciones.
28. ?

1for(int i=0;i<10;i++)
2 {
3 bloque;
4 }

29.
30. Configuracin de los FUSES
31.
La directiva FUSES establece los distintos bits de configuracin del micro, los mismos
que puedes seleccionar en tu software de grabacin.
Cada micro tiene los suyos, y los podrs encontrar en el apartado "Configuration Word"
del correspondiente datasheet, En CCS puedes encontrar los fuses correspondientes al
microcontrolador que estamos usando en el men VIEW > CONFIG BITS.

32.
33.
Nos aparecer una lista con todos los fuses de microcontrolador que seleccionamos.
34.
35.
36. De esta lista los mas importantes son:
37.
WDT (Watchdog Timer):
38. ?

1#fuses WDT
2#fuses NOWDT

39. El famoso "perro guardian" del pic. Esta es una capacidad del pic de autoresetearse.
Es muy til, por ejemplo si un Pic, por un descuido de programacin, se queda en un
bucle infinito, esta "utilidad" lo sacar de l. Su funcionamiento es sumamente sencillo.
Simplemente es un registro que debemos borrar cada cierto tiempo. Si transcurrido un
cierto tiempo el registro no ha sido borrado el pic se resetea.

OSC (Oscilador):
40. ?

1#fuses HS
2#fuses XT

41. Es el modo de oscilacin que va a usar el Pic, los mas usados son:
XT: viene de XTAL (cristal). Este modo de funcionamiento implica que tendremos que
disponer de un cristal de cuarzo externo al Pic y dos condensadores.
HS: Para cuando necesitemos aplicaciones de "alta velocidad", mas de 8Mhz. Se basa
tambin en un cristal de cuarzo, como el XT.

PUT (Power Up Timer Reset):


42. ?
1#fuses PUT
2#fuses NOPUT

43. Si activamos este FUSE, lo que conseguimos es que se genere un retardo en la


inicializacin del Pic. Esto se usa para que la tensin se estabilice, por lo que se
recomienda su uso.

Ahora ya tenemos los conocimientos bsicos necesarios para realizar nuestro primero
proyecto el hola mundo de la electrnica encender y apagar un LED, vamos all.

PROYECTO: Encender y apagar un LED,


ademas agregar un retardo para que el
encendido y apagado del led pueda ser
visualizado correctamente.
Cdigo:
44. ?

#include <16f886.h> //definimos que microncontrolador


1 usaremos
2 #fuses nowdt //no usar el WDT (watchdog timer)
3 #use delay(clock=20M) //definimos un cristal de 20Mhz.
4 void main() //declaramos la funcin principal
5 {
6 while(true) //bucle infinito
7
{
8
9 output_high(pin_b0); //Pin B0 en alto
10 delay_ms(200); //retardo de 200ms
11 output_low(pin_b0); //Pin B0 en bajo
12 delay_ms(200); //retardo de 200ms
13 }
}

45. Esquema Proteus:

46.
47. Como Incorporar una Pantalla LCD
48. En esta entrada aprenderemos a utilizar una pantalla LCD la mas comn es la 2x16
49.
50.
51. Esta es la manera de conectar la LCD generalmente usaremos 4 lineas para los datos
(D4-D7) los bits RS,RW , GND VDD y VEE pin al cual ira un potencimetro para regular
el contraste, ademas de los pines bk+ y bk- para el blackligth en las pantallas que traen
iluminacin LED de fondo.

52.
53.
54.
PROYECTO: Enviar un mensaje a una pantalla LCD conectada al puertoC de
microcontrolador.

CCS dispone de una librera para trabajar con pantallas LCD llamada lcd.h la cual
llamamos con la
instruccin: #include <lcd.c>

55.
56.
La abrimos como muestra la imagen y dentro encontramos los comandos necesarios
para controlarla:
57. ?

1 lcd_init() Must be called before any other function.


2
3
4 lcd_putc(c) Will display c on the next position of the LCD.
5 \a Set cursor position to upper
6 left
7 \f Clear display, set cursor to upper
8 left
9
\n Go to start of second
1
0 line
1 \b Move back one
1 position
1 lcd_gotoxy(x,y) Set write position on LCD (upper left is 1,1)
2 lcd_getc(x,y) Returns character at position x,y on
1 LCD
3
1 CONFIGURACION
4 Nos dice que podemos controlarla de 2 maneras utilizando
1
5
1
a.) acceso por puerto
6 con este codigo le decimos que utilizaremos un completo.
1 ejemplo:
7 #define LCD_DATA_PORT getenv("SFR:PORTC")
1
8
1 b.) acceso por pines
9 aqu podemos usar los pines de la manera que queramos.
2 ejemplo:
0 #define
2
LCD_ENABLE_PIN PIN_C0
1
2 #define
2 LCD_RS_PIN PIN_C1
2 #define
3 LCD_RW_PIN PIN_C2
2 #define
4 LCD_DATA4 PIN_C4
2 #define
5 LCD_DATA5 PIN_C5
2 #define
6
LCD_DATA6 PIN_C6
2
7
#define
2 LCD_DATA7 PIN_C7
8

58.
El codigo queda como sigue:
59. ?

1 #include &lt16F886.h&gt
2 #FUSES NOWDT //No Watch Dog Timer
3 #use delay(crystal=20000000) //reloj de 20Mhz
4 #define LCD_DATA_PORT getenv("SFR:PORTC") //indicamos lcd
5 conectada a PuertoC
6 #include &ltlcd.c&gt //librera LCD viene con
7
el compilador
8
9
10
void main()
11{
12 lcd_init(); //inilicializar LCD
13
14 while(TRUE)
15 {
16 lcd_gotoxy(1,1); //ir a la linea 1 posicion 1
17 printf(lcd_putc,"LCD 16x2"); //mensaje en linea1
18 delay_ms(50); //retardo de 50ms
19 lcd_gotoxy(1,2); //ir a la linea 2 posicion 1
20 printf(lcd_putc,"hacermirobot"); //mensaje linea 2
delay_ms(50); //retardo de 50ms
}
}

60.
Montaje en PROTEUS

61.
62.
63.
64. El conversor Anlogo Digital ADC
65. Un poco de teora:

El conversor anlogo digital se utiliza para convertir seales anlogas provenientes de


sensores conectados a la entrada del microcontrolador en seales digitales para ser
mostradas en indicadores tal como una pantalla lcd.

66.
67.
El microcontrolador PIC19F886 como la mayora de los microcontroladores de la gama
media cuenta un modulo conversor anlogo digital de 8 a 10 bits selecionables por el
programador.

La tensin de entrada puede variar entre 0 a 5volts si utilizamos el adc en el modo de


10bits significa que tenemos 10 bits para representar digitalmente la seal analgica de
entrada, como 2^10=1024, tendremos los valores de entre 0 a 1024 para representar
las tensiones de 0 a 5v.
para calcular la resolucin usamos la siguiente formula:

68.
69.

70. Si consideramos una tensin de entrada Vin de 5v y 10bits tendremos:

71.
72. de este modo si la el valor ledo es 511 511*0.0048 nos da un voltaje de 2.49v.
73.
74.
75. Configuracin del ADC
76.
EN CCS para controlar el conversor ADC se debe hacer mediante las siguientes
instrucciones:

#device ADC= 10:


Selecciona la cantidad de bits que usara el conversor (8 o 10).

SETUP_ADC(mode):
Esta funcin configura el reloj del conversor, los parmetros que acepta son:
77. ?

1ADC_CLOCK_DIV_2
2ADC_CLOCK_DIV_8
3ADC_CLOCK_DIV_32
4ADC_CLOCK_INTERNAL

78.
SETUP_ADC_PORTS(value):
Esta funcin configura cuales pines del ADC sern analgicos y cuales digitales o
alguna
combinacin de ambos. Las constantes usadas son diferentes para cada chip. se debe
revisar el archivo .h, ejemplo.
79. ?

AN0_AN1_AN3 pines RA0, RA1 y RA3 analgicos y los restantes


1 digitales.
2ALL_ANALOG y NO_ANALOGS, estas constantes son vlidas para todos los
chips.

80.
SET_ADC_CHANNEL(channel:
Especifica el canal a utilizar por la funcin READ_ADC(). El nmero de canal empieza
en 0. Es preciso esperar un corto espacio de tiempo despus de cambiar el canal de
adquisicin, antes de que se puedan obtener lecturas de datos vlidos.Ejemplo:
81. ?

1set_adc_channel(2);
82.

PROYECTO: Probar el funcionamiento del conversor anlogo


digital utilizando un potencimetro que simula un sensor a la
entrada del pin AN0 del PIC y visualizar la salida digital en un LCD.
Montaje en Proteus:

83.
84.
Codigo CCS:
85. ?

#include <16F886.h>
#device adc=10 //10bits
1#fuses nowdt
2#use delay(clock=20000000)
3#define LCD_DATA_PORT getenv("SFR:PORTC") //lcd conectado al
4puerto C.
5#include <lcd.c>
6
7 void main()
8
{
9
10 int16 q;
11 float p;
12 setup_adc_ports(sAN0); //AN0 en otros
13microcontroladores.
14 setup_adc(adc_clock_internal); //reloj interno.
15 lcd_init(); //inicializar el lcd.
16
17 while(true)
18 {
19
set_adc_channel(0); //canal 0.
20
21
delay_us(20);
22 lcd_gotoxy(1,1);
23 q=read_adc();
24 p=(5.0*q)/1024.0;
25 printf(lcd_putc," ADC = %ld",q);
26 printf(lcd_putc,"\nVoltaje=%1.2fv",p);
}
}