Está en la página 1de 52

TUTORIAL PIC C

CON EL COMPILADOR CCS

Ing. Rafael Omar Mendoza A.


Noviembre 2009
Introducción
• Este tutorial indica la manera de programar en
lenguaje C para microcontroladores PIC utilizando el
compilador CCS. Se utilizarán instrucciones y
ejemplos para facilitar al lector su incorporación en
este lenguaje de programación.

TUTORIAL PIC C Ing. Rafael Omar Mendoza A.


Comentarios
Los comentarios son útiles para facilitar al lector ó al
programador el significado o funcionamiento del cada parte
del programa. Todos los comentarios son ignorados por el
compilador.
Existen 2 maneras de introducir un comentario:
/* esto es un comentario */
Es decir todo lo que esté entre /* y */ es un comentario
La segunda manera es la siguiente:
// esta es otra manera de escribir comentarios
En este caso el comentario comienza en // hasta el final de la
linea

TUTORIAL PIC C Ing. Rafael Omar Mendoza A.


VARIABLES
• En una variable, su contenido es el valor que adopta y la
etiqueta es el nombre de la variable.
TIPOS DE VARIABLES
Tipo Ancho (Bits) Rango
short 1 0o1
short int 1 0o1
int 8 0 a 255
char 8 0 a 255
unsigned 8 0 a 255
unsigned int 8 0 a 255
signed 8 -128 a 127
signed int 8 -128 a 127
long 16 0 a 65536
long int 16 0 a 65536
signed long 16 -32768 a 32767
float 32 3.4E-38 a 3.4E+38
TUTORIAL PIC C Ing. Rafael Omar Mendoza A.
DECLARACION DE VARIABLES
•Deben ser declaradas antes de ser utilizadas en el
programa
•Deben terminar con ;
Forma en que se declara una variable
Tipo nombre_de_la_variable ;
Ejemplo:
Int temperatura;

Esta línea permite al programa emplear la variable de tipo entero


temperatura que será capaz de almacenar cualquier valor comprendido
entre 0 y 255.

TUTORIAL PIC C Ing. Rafael Omar Mendoza A.


Asignar valores a una variable
• Para asignar valores se realiza lo siguiente:
• Nombre_de_la_variable=valor;
Ejemplo:
• Suponga que se quiere asignar el valor 100 a la variable
contador, se haría de la siguiente manera:

contador = 100; //donde 100 es una constante

TUTORIAL PIC C Ing. Rafael Omar Mendoza A.


Declarar Variables y Constantes
Se puede asignar el valor a una variable en el
momento que se declara.
Ejemplos:

1.Int a=0;
2.Signed long a=125, b , c= -10;
3.Char nombre = ‘juan perez’ ;

TUTORIAL PIC C Ing. Rafael Omar Mendoza A.


Variables Globales y Locales
• Si una variable se declara dentro de una función será
“visible” solo dentro de ésta.
Funcion1()
{
Char letra;
.
}
En el ejemplo, la variable tipo char letra solo podrá utilizarse dentro de
la función1, si se intenta utilizar fuera de ella el compilador mostrará
un mensaje de error.

TUTORIAL PIC C Ing. Rafael Omar Mendoza A.


Variables globales
• Si se declara una variable fuera de cualquier función, el alcance de
ésta será global, lo que quiere decir que estará disponible en
cualquier parte del programa Ej:
char letra;
main()
{
.
}
funcion1()
{
.
}

TUTORIAL PIC C Ing. Rafael Omar Mendoza A.


DIRECTIVAS PARA EL COMPILADOR
#ASM, #ENDASM

permite utilizar un bloque de instrucciones en assembler dentro del


código CCS. El siguiente es un ejemplo de uso tomado de la ayuda del
CCS
int find_parity (int data) {
int count;
#ASM
movlw 0x8
movwf count
movlw 0
loop: xorwf data,w
rrf data,f
decfsz count,f
goto loop
movlw 1
awdwf count,f
movwf _return_
#ENDASM
}

TUTORIAL PIC C Ing. Rafael Omar Mendoza A.


¿CUAL PIC UTILIZAR?

ALGUNOS DE LOS
MICROCONTROLADORES MAS
UTILIZADOS

TUTORIAL PIC C Ing. Rafael Omar Mendoza A.


MICROCONTROLADOR GAMA BAJA

TUTORIAL PIC C Ing. Rafael Omar Mendoza A.


Microcontrolador gama baja
PIC12F675 – PIC12F629

TUTORIAL PIC C Ing. Rafael Omar Mendoza A.


IDENTIFICACION DEL PRODUCTO

TUTORIAL PIC C Ing. Rafael Omar Mendoza A.


TUTORIAL PIC C Ing. Rafael Omar Mendoza A.
Características principales de los
PIC

TUTORIAL PIC C Ing. Rafael Omar Mendoza A.


Características principales de los PIC (2)

TUTORIAL PIC C Ing. Rafael Omar Mendoza A.


TUTORIAL PIC C Ing. Rafael Omar Mendoza A.
TUTORIAL PIC C Ing. Rafael Omar Mendoza A.
TUTORIAL PIC C Ing. Rafael Omar Mendoza A.
DIRECTIVAS PARA EL COMPILADOR
#BYTE

Permite crear una nueva variable de un Byte de tamaño, que es


colocada en la memoria del PIC en la posición del byte x. Esta es una
herramienta muy útil para acceder de una manera sencilla a los
registros. Por supuesto, estas variables pueden ser empleadas de la
misma manera que cualquier otra variable tipo int. El formato de
#BYTE es el siguiente:

#BYTE nombre = x
Ejemplos:

#BYTE STATUS = 3
#BYTE PORTB = 6

TUTORIAL PIC C Ing. Rafael Omar Mendoza A.


DIRECTIVAS PARA EL COMPILADOR
#DEFINE
La instrucción #define tiene la siguiente forma:
#DEFINE <label> value

<label> es la etiqueta que se usará en el programa. Y value es el valor


que se está asignando a esta etiqueta. Las instrucciones #DEFINE no
generan código ASM, si no que el preprocesador realiza los
reemplazos que ellas indican en el momento de la compilación. El uso
de #DEFINE permite construir programas mas ordenados y fáciles de
mantener. Ej:

#DEFINE pi 3.14159265359 // cada vez que se escriba pi el compilador asigna


el valor : 3.14159265359

TUTORIAL PIC C Ing. Rafael Omar Mendoza A.


DIRECTIVAS PARA EL COMPILADOR
#DEVICE
Esta directiva informa al compilador que arquitectura de hardware
utilizaremos, para que pueda generar código apropiado para la cantidad de
RAM, ROM y juego de instrucciones disponibles. Para los chips con más de
256 bytes de RAM se puede seleccionar entre emplear punteros de 8 o 16 bits.
Si se desea emplear punteros de 16 bits basta con añadir *=16 a continuación
del nombre microcontrolador seleccionado.
Ej:
#DEVICE PIC16C74 //PIC 16C74, punteros de 8 bits.
#DEVICE PIC16C67 *=16 //PIC 16C67, punteros de 16 bits
#DEVICE PIC16F877 *=16 ADC=10 //PIC 1616F877, punteros de 16 bits y
10 bits en el ADC.

TUTORIAL PIC C Ing. Rafael Omar Mendoza A.


DIRECTIVAS PARA EL COMPILADOR
#FUSE
Permite modificar el valor de los fuses del microcontrolador . Los valores
posibles dependen de cada microcontrolador en particular, y los valores
posibles se cargan al utilizar #INCLUDE seguido del archivo correspondiente.
La forma de #FUSE es la siguiente:
#FUSE opciones donde opciones es una lista de las opciones posibles
separadas mediante comas. recuerde que se puede ver dentro del archivo con
extensión .h correspondiente cuales son los valores posibles para ese
microcontrolador. Están al comienzo del archivo, en forma de comentarios.

Tipo de oscilador: LP, XT, HS, RC


Wach Dog Timer: WDT, NOWDT
Protección de código: PROTECT, NOPROTECT
Power Up Timer: PUT, NOPUT
Brown Out Reset: BROWNOUT, NOBROWNOUT

TUTORIAL PIC C Ing. Rafael Omar Mendoza A.


DIRECTIVAS PARA EL COMPILADOR
#INCLUDE
Permite incluir en el programa uno o mas archivos (conocidos como
header file) que posean extensión .h. Estos archivos contienen
información sobre funciones, argumentos, el nombre de los pines de
un modelo determinado de PIC o cualquier otra cosa que se use
habitualmente en los programas. Esto permite no tener que escribir un
montón de cosas cada vez que se comienza un programa nuevo:
basta con incluir el .h correspondiente.

#INCLUDE <archivo>
#INCLUDE <PIC16F877A.H>
Existe la posibilidad de utilizar #INCLUDE "archivo" en lugar de
#INCLUDE <archivo>. La diferencia es que si se usa "", el archivo se
buscará primero en el directorio actual. Si se emplea <>, el archivo será
buscado primero en la ruta por defecto para los archivos .h.

TUTORIAL PIC C Ing. Rafael Omar Mendoza A.


OPERADORES ARITMÉTICOS
CCS posee cinco operadores aritméticos:
+ (suma)
- (substracción)
* (multiplicación)
/ (división)
% (módulo)
Los primeros cuatro operadores mencionados se pueden utilizar con cualquier
tipo de dato. Estos son algunos ejemplos de como usarlos:
a = b + c;
a = b - c;
a = b * c;
a = b / c;
a = -a; //Cambia el signo de "a“
a = a + 1; //suma 1 al valor de "a".

TUTORIAL PIC C Ing. Rafael Omar Mendoza A.


Retardos (delays)
• delay_ms(tiempo)

• delay_us(tiempo)

• delay_cycles(ciclos) (0-255)
– 1 ciclo= 4 ciclos de reloj

TUTORIAL PIC C Ing. Rafael Omar Mendoza A.


input
• Sintaxis: value = input (pin)
• Retorna:
– 0 (or FALSE) si el pin está en estado bajo,
– 1 (or TRUE) si el pin está en estado alto
• Ejemplo:
Encendido=input(PIN_A4) //retorna el valor del
pin A4 a la variable encendido

TUTORIAL PIC C Ing. Rafael Omar Mendoza A.


Input_x()
• Sintaxis:
value = input_a()
value = input_b()
value = input_c()
– ...
Asigna un byte ( 8 bit) de tipo entero en la
variable de entrada. //lee el puerto (8 bits)
Y lo guarda en value.
TUTORIAL PIC C Ing. Rafael Omar Mendoza A.
Output_x()
• Sintaxis:
output_a (valor)
output_b (valor)
...
Parameters: valor es un entero de 8 bit
Función: Envia un dato de 8 bit al puerto.

TUTORIAL PIC C Ing. Rafael Omar Mendoza A.


Output_bit()
• Syntax: output_bit (pin, value)
• Function: habilita la salida del pin
especificado (0 or 1) en el puerto.
• Ejemplos
– Output_bit (PIN_D1,0)
– Output_bit(PIN_A3,1)

TUTORIAL PIC C Ing. Rafael Omar Mendoza A.


Output_xxxx()
• OUTPUT_HIGH( )
Sintaxis: output_high (pin)
Función: coloca el pin en estado alto.

• OUTPUT_LOW( )
Sintaxis: output_low (pin)
Función: coloca el pin en estado bajo.

TUTORIAL PIC C Ing. Rafael Omar Mendoza A.


Set_tris_x(xxxxx)
• Configura los registros de
direccionamiento de los puertos (TRIS)
• 0 significa salida
• 1 significa entrada
• Ejemplo:
Set_tris_a(0b00001011) // RA0,RA1,RA3 como
//entradas, las demás son salidas

TUTORIAL PIC C Ing. Rafael Omar Mendoza A.


Interrupciones
• Permiten o inhiben las interrupciones.

• Ejemplos:
– enable_interrupts(GLOBAL);
– disable_interrupts(INT_TIMER0);
– enable_interrupts(INT_TIMER1);

TUTORIAL PIC C Ing. Rafael Omar Mendoza A.


Otras funciones
• setup_adc_ports()
• setup_adc()
• set_adc_channel()
• read_adc()

• setup_timer_X()
• set_timer_X()
• get_timer_X()
TUTORIAL PIC C Ing. Rafael Omar Mendoza A.
1 Programa encender 1 led cada 5”
//Notas: Parpadeo de un led cada 0.5s por el pin RB0 del puerto B
/////////////////////// ING RAFAEL MENDOZA ///////////////////////////////////////////////////
//Archivo led84.C
#include <16f84a.h>//pic a utilizar
//#fuses XT,NOWDT,NOPROTECT,PUT //ordenes para el programador
#use delay (clock=4000000) //Fosc=4Mhz
#use fast_io(b)
///PROGRAMA

void main(void)
{
set_tris_b(0xFE); //portb como salida(RB0,las demas desactivadas)
//disable_interrupts(GLOBAL); //todas las interrupciones desactivadas

do{
output_low(PIN_B0); //led off
delay_ms(500);
output_high(PIN_B0); //led on
delay_ms(500);
}
while(TRUE); //bucle infinito
}
TUTORIAL PIC C Ing. Rafael Omar Mendoza A.
2 Programa Encender led de 4 formas diferentes
// Notas: Parpadeo de cuatro leds cada 0.5s de cuatro formas diferentes Ing Rafael O Mendoza A.:
// RB0 -> con la funcion output_high()/output_low()
// RB1 -> definiendo el pin RB1
// RB2 -> con la funcion output_bit()
// RB3 -> con la funcion bit_set()/bit_clear()
//////////////////////////////////////////////////////////////////////////////////
#include <16f84a.h> //pic a utilizar
#fuses XT,NOPROTECT,NOWDT,PUT //ordenes para el programador
#use delay (clock=4000000) //Fosc=4Mhz
#use fixed_io(b_outputs=PIN_B0,PIN_B1,PIN_B2,PIN_B3) //pin de salida portb
#bit RB1=0x106.1 //definicion pin potrb B1
#byte portb=06
///PROGRAMA PRINCIPAL
void main(void)
{
set_tris_b(0x00); //puerto b como salida
disable_interrupts(GLOBAL); //todas interrupciones desactivadas
RB1=0; //valor inicial B1 para que los led"s se iluminen a la vez
do
{
output_high(PIN_B0); //led"s on
RB1=!RB1;
output_bit(PIN_B2,1);
bit_set(portb,3);
delay_ms(500);
output_low(PIN_B0); //led"s off
RB1=!RB1;
output_bit(PIN_B2,0);
bit_clear(portb,3);
delay_ms(500);
}TUTORIAL PIC C Ing. Rafael Omar Mendoza A.
while(TRUE); //bucle infinito
}
3 Programa contador binario
#include <16F84a.h> //pic a utilizar
#use delay (clock=4000000) // Clock=4Mhz
#use standard_io(B) //Puerto B (trabaja con la función output_b)
main()
{
int c=0; // declaro contador como entero( 1 byte) e inicializado en cero
set_tris_b(0x00); //portb como salida
//disable_interrupts(GLOBAL); //todas las interrupciones desactivadas
do{ //Repetir...
output_b(c); //muestra por puerto b digitos 0-9
delay_ms(500);
c++; //incremento contador para visualizar siguiente digito
if(c>9) //¿ya se ha mostrado el digito 9?
{
c=0; //SI -> vuelve a empezar(digito 0)
}
}
while(TRUE); //...infinito
}

TUTORIAL PIC C Ing. Rafael Omar Mendoza A.


Ejercicios Propuestos
• Elabore un proyecto que permita leer 4 entradas
digitales por el puerto A si el valor es superior a 9
emitir un sonido de 1khz, por el PIN_A4, durante un
seg.
• Elabore un proyecto que permita leer 4 entradas
digitales BCD por el puerto A y luego mostrarlas por el
puerto B en un Display BCD 7segmentos. Si la cuenta
es mayor a 6 debe titilar un LED en RA4.
• Realizar un proyecto que genere en un LED
conectado en la línea de salida A4, del PIC, una onda
cuadrada simétrica de un Khz.

TUTORIAL PIC C Ing. Rafael Omar Mendoza A.


PANTALLAS LCD
• En muchos casos, la señalización de estados de los proyectos mediante
diodos LED resulta insuficiente. Una alternativa muy profesional y
económica (y de fácil implementación) es la utilización de displays LCD
alfanuméricos.

TUTORIAL PIC C Ing. Rafael Omar Mendoza A.


Diagrama de Pines de 1 LCD

TUTORIAL PIC C Ing. Rafael Omar Mendoza A.


TUTORIAL PIC C Ing. Rafael Omar Mendoza A.
TUTORIAL PIC C Ing. Rafael Omar Mendoza A.
TUTORIAL PIC C Ing. Rafael Omar Mendoza A.
TUTORIAL PIC C Ing. Rafael Omar Mendoza A.
LIBRERÍA LCD.C
• Para colocarnos las cosas más faciles, dentro de la carpeta "drivers"
de CCS se encuentra un archivo llamado LCD.C, si se incluye en
nuestro proyecto, proveerá de las funciones necesarias. Sin
embargo, LCD.C tiene algunas limitaciones: tal como está, solo
funciona si conectamos el LCD en el puerto D (o B, con una
modificación menor).
• Para incluirlo en el programa, basta con hacer lo siguiente:
• #INCLUDE "lcd.c" en cuanto al hardware,las lineas de datos deben
conectarse de la siguiente manera:
• PORT.D0 -> enable
• PORT.D1 -> rs
• PORT.D2 -> rw
• PORT.D4 -> D4
• PORT.D5 -> D5
• PORT.D6 -> D6
• PORT.D7 -> D7
• como puede verse, se trata de una comunicación con solo 4 bits de
datos.
TUTORIAL PIC C Ing. Rafael Omar Mendoza A.
Lcd_init()
• lcd_init()
Esta función es la encargada de enviar los comandos
de inicializacion necesarios al LCD. Es obligatorio
ejecutar esta función antes de utilizar el display para
escribir sobre él. No recibe ni devuelve valores de
ningun tipo. Su forma de uso es tan simple como:
lcd_init();

TUTORIAL PIC C Ing. Rafael Omar Mendoza A.


Función Lcd_putc
Esta es la función que mas se empleará. Es la que se
encarga de escribir el mensaje en la pantalla. No
devuelve valores, pero si (obviamente) los recibe. La
forma de uso es muy simple. Básta con llamarla,
pansandole como parámetro una variable o constante
tipo char, y la función se encargará de desplegar su
contenido sobre el display.
• Lcd_putc (“ELECTRONICA");
• Lcd_putc(“Ing. Eléctrica”);

TUTORIAL PIC C Ing. Rafael Omar Mendoza A.


Comandos \f , \n, \b
Por supuesto, no se debe olvidar de inicializar previamente el
display. Además, lcd_putc() reconoce los siguientes comandos
que pueden ser enviados en el texto a mostrar:

\f -> Borra la pantalla.


\n -> Salta al comienzo de la segunda línea.
\b -> Retrocede una posición.

Esto quiere decir que si se quiere escribir en las dos lineas el


código queda así:
Lcd_putc (“Electrónica\n LCD en CCS");

TUTORIAL PIC C Ing. Rafael Omar Mendoza A.


EJEMPLO MENSAJE FIJO EN LCD
// ARCHIVO LCD1.c
//este programa muestra el mensaje Hola en el display 2x16

#include <16F84A.h>

#FUSES NOWDT //Watch Dog Timer


#FUSES XT //Crystal osc <= 4mhz
#FUSES PUT //Power Up Timer
#FUSES NOPROTECT //Code not protected from reading
#use delay(clock=4000000) //CRISTAL DE 4MHz
#include <LCD.C> //LIBRERÍA DEL LCD

void main()
{
lcd_init(); //Inicialización del lcd

printf(lcd_putc,"\fHOLA"); //muestra el mensaje “HOLA” en el display

setup_timer_0(RTCC_INTERNAL);setup_wdt(WDT_18MS);

TUTORIAL PIC C Ing. Rafael Omar Mendoza A.


Ejemplo Mensaje intermitente
// ARCHIVO LCD1 intermitente.c
//este programa muestra el mensaje intermitente Hola en el display 2x16
#include <16F84A.h>

#FUSES NOWDT //Watch Dog Timer


#FUSES XT //Crystal osc <= 4mhz
#FUSES PUT //Power Up Timer
#FUSES NOPROTECT //Code not protected from reading
#use delay(clock=4000000)
#include <LCD.C>

void main()
{
lcd_init();

while (true)
{
printf(lcd_putc,"\fHOLA"); //borra la pantalla y muestra el mensaje
delay_ms(500); //retardo de 500 ms

printf(lcd_putc,"\f");
delay_ms(500);

}
setup_timer_0(RTCC_INTERNAL);setup_wdt(WDT_18MS);

} TUTORIAL PIC C Ing. Rafael Omar Mendoza A.


EJEMPLO CONTADOR CON LCD
//conexiones del LCD
// B0 enable
// B1 rs
// B2 rw
// B4 D4
// B5 D5
// B6 D6
// B7 D7
#include <16F84A.h>
#FUSES WDT, XT, PUT, NOPROTECT
#use delay(clock=4000000)
#include <LCD.C>
#BYTE PORTB =0x06

int i;
void main()
{
i=200;
lcd_init();
while (true)
{
lcd_gotoxy(1,1); // mensaje en la primera linea
printf(lcd_putc,"\fCONTADOR %u",i);
delay_ms(100);
lcd_gotoxy(1,2); //mensaje en la segunda linea
printf(lcd_putc,"NUMERO: %u",i);
delay_ms(100);
i=i-1;
}
setup_timer_0(RTCC_INTERNAL);setup_wdt(WDT_18MS);
}

TUTORIAL PIC C Ing. Rafael Omar Mendoza A.

También podría gustarte