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
1 usaremos
2 #INCLUDE <16f886.inc>
3
4
ORG 0x00
5
6
bsf STATUS,RP0
7
movlw b'0001111'
8
movwf TRISA
9
clrf TRISB
10
bcf STATUS,RP0
11
12
13inicio
movf PORTA,W
14
movwf PORTB
15
goto inicio
16

END

;seleccionamos que microcontrolador


;carga librera del microcontrolador
;origen de programa
;acceso al banco 1 de la memoria
;configura el puertoA como entrada
;configura el puertoB como salida
;RP0 a 0 para acceder al banco 0
;mueve el contenido del PuertoA a W
;mueve el dato de W al puertoB
;salta a inicio y entra en un bucle
;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.

8.
9.

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.

Gestin de los puertos de Entrada y Salida:


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
memoria
1#BYTE PORTA
2memoria
3#BYTE TRISB
4memoria
#BYTE PORTB
memoria

= 0x85

//direccin del registro TRISA en el banco de

= 0x05

//direccin del registro PORTA en el banco de

= 0x86

//direccin del registro TRISb en el banco de

= 0x06

//direccin del registro PORTB en el banco de

12. Una vez definidas estas variables se pueden configurar y controlar los puertos.
13. ?
1TRISA = 0xFF;
2TRISB = 0x00;
3TRISC = 0x0F;

// todos los pines de entrada


// todos los pines de salida
// 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);
(0-255).
input_X();
1correspondiente.
2set_tris_X(valor);
3
255)
4
5port_b_pullups(true);
PORTB .
get_trisX();
A,B,C,D)

//Por el puerto correspondiente saca el valor


//Se obtiene el valor en el puerto
//Carga el registro TRISx con el valor (0//Habilita

las

resistencias pul-up en el

//Devuelve el valor del registro TRISx (x es

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>
1 usaremos
2 #fuses nowdt
3 #use delay(clock=20M)
4 void main()
5 {
6
while(true)
7
{
8
output_high(pin_b0);
9
delay_ms(200);
10
output_low(pin_b0);
11
delay_ms(200);
12
}
13

//definimos que microncontrolador


//no usar el WDT (watchdog timer)
//definimos un cristal de 20Mhz.
//declaramos la funcin principal
//bucle infinito
//Pin B0 en alto
//retardo de 200ms
//Pin B0 en bajo
//retardo de 200ms

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()
2
3

Must be called before any other function.

4
5
6
7
8
9
1
0
1
1
1
2
1
3
1
4
1
5
1
6
1
7
1
8
1
9
2
0
2
1
2
2
2
3
2
4
2
5
2
6
2
7
2
8

lcd_putc(c)

Will display c on the next position of the LCD.


\a Set cursor position to upper

left
\f

Clear display, set cursor to upper

\n

Go to start of second

left
line
\b Move back one
position
lcd_gotoxy(x,y) Set write position on LCD (upper left is 1,1)
lcd_getc(x,y)
Returns character at position x,y on
LCD
CONFIGURACION
Nos dice que podemos controlarla de 2 maneras utilizando
a.) acceso por puerto
con este codigo le decimos que utilizaremos un completo.
ejemplo:
#define LCD_DATA_PORT getenv("SFR:PORTC")
b.) acceso por pines
aqu podemos usar los pines de la manera que queramos.
ejemplo:
#define
LCD_ENABLE_PIN PIN_C0
#define
LCD_RS_PIN
PIN_C1
#define
LCD_RW_PIN
PIN_C2
#define
LCD_DATA4
PIN_C4
#define
LCD_DATA5
PIN_C5
#define
LCD_DATA6
PIN_C6
#define
LCD_DATA7
PIN_C7

58.
El codigo queda como sigue:
59. ?
1 #include &lt16F886.h&gt
//No Watch Dog Timer
2 #FUSES NOWDT
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
void main()
10
11{
lcd_init();
//inilicializar LCD
12
13
while(TRUE)
14
15
{

lcd_gotoxy(1,1);
printf(lcd_putc,"LCD 16x2");
delay_ms(50);
lcd_gotoxy(1,2);
printf(lcd_putc,"hacermirobot");
delay_ms(50);

16
17
18
19
20

//ir a la
//mensaje
//retardo
//ir a la
//mensaje
//retardo

linea 1 posicion 1
en linea1
de 50ms
linea 2 posicion 1
linea 2
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
digitales.
1
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
#fuses nowdt
#use delay(clock=20000000)
#define LCD_DATA_PORT getenv("SFR:PORTC")
puerto C.
#include <lcd.c>

//10bits

1
2
3
//lcd conectado al
4
5
6
7 void main()
8
{
9
int16 q;
10
float p;
11
setup_adc_ports(sAN0);
//AN0 en otros
12
13microcontroladores.
setup_adc(adc_clock_internal);
//reloj interno.
14
15
lcd_init();
//inicializar el lcd.
16
17
while(true)
18
{
19
set_adc_channel(0);
//canal 0.
20
delay_us(20);
21
lcd_gotoxy(1,1);
22
q=read_adc();
23
p=(5.0*q)/1024.0;
24
printf(lcd_putc," ADC = %ld",q);
25
26
printf(lcd_putc,"\nVoltaje=%1.2fv",p);

}
}