Compilador C para PIC CCS C
Compilador C para PIC CCS PIC COMPILER • Un compilador convierte convierte un lenguaje de alto alto nivel a instrucciones instrucciones en código código máquina. • Un “cross-compiler” es es un compilador que funciona en un procesador (normalmente
en PC) diferente al procesador objeto. Varios compiladores C tiene como procesador objetos los PICmicro tal es el caso de HiTECH, MicroChip y CCS.
• Los programas son editados y compilados a instrucciones máquina en el PC. • El código máquina es cargado del PC al sistema PIC mediante el ICD2. • El código es ejecutado en el PIC y puede ser depurado (puntos de ruptura, paso a
paso, etc) desde el PC.
Nota: Ver documentos anexos sobre CCS
Compilador C para PIC CCS PIC COMPILER • Un compilador convierte convierte un lenguaje de alto alto nivel a instrucciones instrucciones en código código máquina. • Un “cross-compiler” es es un compilador que funciona en un procesador (normalmente
en PC) diferente al procesador objeto. Varios compiladores C tiene como procesador objetos los PICmicro tal es el caso de HiTECH, MicroChip y CCS.
• Los programas son editados y compilados a instrucciones máquina en el PC. • El código máquina es cargado del PC al sistema PIC mediante el ICD2. • El código es ejecutado en el PIC y puede ser depurado (puntos de ruptura, paso a
paso, etc) desde el PC.
Nota: Ver documentos anexos sobre CCS
Compilador C para PIC CCS PIC COMPILER • Los elementos básicos de un programa en C
– Directivas de preprocesado
• Indican al compilador cómo debe generar el
código máquina. – Programas • •
Bloques de programa. Siempre debe incluirse una llamada main().
– Sentencias
Instrucciones que definen lo que hace el programa progr ama y la secuencia de ejecución del mismo. •
– Comentarios
Imprescindibles código fuente. •
como
documentación
del
Compilador C para PIC VARIABLES •Una variable es un nombre asignado a una o varias posiciones de memoria RAM. •En C es necesario declarar todas las variables antes de poder utilizarlas, indicando el
nombre asignado y el tipo de datos que en ella se van a almacenar (opcionalmente también el valor inicial asignado).
tipo nombre_variable [=valor];
p.e.:int i;
•Los tipos de datos aceptados en C estándar son cinco:
char (carácter) float (coma flotante en 32 bits) void (sin valor)
int (entero) double (coma flotante en 64 bits)
•Las variables pueden ser locales o globales. Las variables locales sólo pueden ser
usadas en la función en que se declaran, mientras que las variables globales son compartidas por todas las funciones del programa (deben declararse fuera de cualquier función y antes de ser utilizadas).
Compilador C para PIC VARIABLES • El compilador de CCS acepta los siguiente tipos de variable.
Especificación char int float double void int1 int8 int16 int32 short long
Significado carácter entero coma flotante float doble precisión sin valor entero de 1 bit entero de 8 bits entero de 16 bits entero de 32 bits entero de 1 bit entero de 16 bits
Tamaño 8 bits 8 bits 32 bits no soportado nulo 1 bit 8 bits 16 bits 32 bits 1 bit 16 bits
Rango 0 a 255 (sin signo) 0 a 255 (sin signo) 6 bits de precisión No para PCM ninguno 0a1 0 a 255 (sin signo) 0 a 65535 (sin signo) 0 a (232-1) 0a1 0 a 65535 (sin signo)
•Los tipos de variable short y long pueden tener detrás la palabra int sin efecto alguno.
Compilador C para PIC VARIABLES •Todos los tipos de datos son por defecto sin signo (unsigned) salvo los de tipo float. •Para almacenar datos con signo, hay que introducir el modificador signed delante del
tipo. El efecto que se consigue es el recogido en la siguiente tabla. Especificación signed char signed int16 signed long
Significado carácter con signo entero con signo coma flotante
Tamaño 8 bits 16 bits 16 bits
Rango -128 a 127 -16384 a 16383 -32768 a 32767
•Los números negativos se codifican en complemento a 2. •Cuando se opera con distintos grupos de datos en una misma expresión, se aplican una serie de reglas para resolver las diferencias. En general se produce una “promoción”
hacia los tipos de datos de mayor longitud presentes en la expresión.
Compilador C para PIC FUNCIONES •Las funciones son los bloques constructivos fundamentales en C. Todas las sentencias
deben encontrarse dentro de funciones. •Las funciones deben ser definidas antes de ser utilizadas. •Formato general de definición de una función: tipo_dato_return
nombre_func (tipo param1 , tipo param2 , … )
{ cuerpo de la función (sentencias); } •Las funciones pueden devolver un valor a la sentencia que las llama. El tipo de dato
devuelto se indica mediante tipo_dato (char, int16, long). Si no se indica nada, se entiende que devuelve un entero. Si no devuelve nada, debe incluirse una especificación tipo void. •
Compilador C para PIC FUNCIONES •La manera que tiene una función para devolver un valor es mediante la sentencia
return.
return (expresión);
return expresión;
•La expresión debe proporcionar el mismo tipo de dato que el especificado en la
función. Si no debe devolver nada, se finaliza con return;
•Cuando una función se encuentra con una sentencia return se vuelve a la rutina de
llamada inmediatamente y las sentencias posteriores a return no se ejecutan.
• Además de con las sentencia return, las funciones terminan su ejecución y vuelven al
lugar desde donde se les llamó cuando alcanzan la llave de cierre de función } tras ejecutar la última sentencia de la misma.
Compilador C para PIC FUNCIONES • Además de devolver valores, una función también puede recibir parámetros
(denominados argumentos) según se indicó en su definición. int suma (int a , int b) { return (a+b); } main() { int c; c = suma (10 , 23); }
Parámetros formales
Argumentos de llamada
•Los argumentos se pueden pasar a las funciones por valor o por referencia . • La llamada por valor copia el argumento de llamada en el parámetro formal de la
función (No modifica su valor en la función de partida). • La llamada por referencia usa la dirección de la variable que se pasa a la función (se consigue usando punteros o arrays).
Compilador C para PIC OPERADORES •El lenguaje C define numerosos operadores mediante los cuales se construyen las
expresiones (combinación de operadores y operandos). •De asignación
• Aritméticos
Compilador C para PIC OPERADORES •Relacionales
•Lógicos
•De bits
Compilador C para PIC OPERADORES •In/decremento
•Desplazamiento bit
•Dirección/indirección
En lenguaje C “profesional” es muy frecuente usar abreviaturas. Así, por ejemplo, es más habitual ver a += b; que a = a + b;
Compilador C para PIC OPERADORES
Compilador C para PIC DECLARACIONES
Compilador C para PIC Sentencias de control de programa –
Sentencia if •
Se ejecuta una sentencia o bloque de código si la expresión que acompaña al if tiene un valor distinto a cero (verdadero). Si es cero (falso) continúa sin ejecutar la sentencia o bloque de sentencias. if (expresión) sentencia; sentencia 1; sentencia 2; ... }
–
{
Sentencia if-else •
Se evalúa una expresión y, si es cierta, se ejecuta el primer bloque de código (o sentencia 1). Si es falsa, se ejecuta el segundo.
if (expresión) sentencia 1; else sentencia 2;
(expresión) ? (sentencia 1) : (sentencia 2);
Compilador C para PIC Sentencias de control de programa –
Sentencia if-if/else If (P1 !=0) c=20; else c=0; If (a>b) { If (a>d) c = 15; else c=0; }
If (a>b) { If (a>d) c = 15; } else c=0;
Compilador C para PIC Sentencias de control de programa –
Sentencia switch •
Substituye a if-else cuando se realiza una selección múltiple que compara una expresión con una lista de constantes enteras o caracteres. Cuando se da una coincidencia, el cuerpo de sentencias asociadas a esa constante se ejecuta hasta que aparezca break . switch (expresión) { case constante 1: grupo 1 de sentencias; break; case constante 2: grupo 2 de sentencias; break; ... default: grupo n de sentencias; }
break es opcional. Si no aparece se sigue con el case siguiente.
No puede haber constantes iguales en dos case de la misma sentencia switch.
default es opcional y el bloque asociado se ejecuta sólo si no hay ninguna coincidencia con las constantes especificadas.
Compilador C para PIC Sentencias de control de programa –
Sentencia switch Switch (k) { case 0: x=1; break; case 2: c=6; b=15; break; case 3: x=12; break; default: break; }
Compilador C para PIC Sentencias de control de programa –
Sentencia de bucle for • Se emplea para repetir una sentencia o bloque de sentencias.
for (inicialización ; condición ; incremento) { sentencia(s); } •
En la inicialización se le asigna un valor inicial a una variable que se emplea para el control de la repetición del bucle.
•
La condición se evalúa antes de ejecutar la sentencia. Si es cierta, se ejecuta el bucle. Si no, se sale del mismo.
•
El incremento establece cómo cambia la variable de control cada vez que se repite el bucle.
•
Es posible anidar bucles for para modificar dos o más variables de control.
Compilador C para PIC Sentencias de control de programa –
Sentencia de bucle for
For (i=1;i<=100;i++) { delay_ms(33); px=?px; }
For (y=1;i<=99;y=y+3) { delay_ms(33); px=y; }
Compilador C para PIC Sentencias de control de programa –
Sentencia de bucle while
La repetición se lleva a cabo mientras sea cierta una expresión. while(mientras) (expresión) { sentencia(s); } • La expresión se evalúa antes de cualquier iteración. Si es falsa, ya no se ejecuta la sentencia o bloque de sentencias. •
–
Sentencia de bucle do-while.
do { sentencia(s); } while (expresión) • Las sentencias se ejecutan antes de que se evalúe la expresión, por lo que el bucle se ejecuta siempre al menos una vez.
Compilador C para PIC Sentencias de control de programa –
Sentencia de bucle while-do/while while (x>0 && y++<5) { a=1; b=45; x=p1; }
do { a=1; b=45; x=p1; } while (x>0 && y++>5);
Compilador C para PIC Comentarios Los comentarios se incluyen en el código fuente para explicar el sentido y la intención del código al que acompañan. Son ignorados por el compilador y no afectan a la longitud ni rapidez de ejecución del código final. – Un comentario se puede colocan en cualquier lugar del programa y pueden tener la longitud y el número de líneas que se quiera. – Hay dos formatos posibles para los comentarios. Formato 1. Empiezan por // y finalizan con el final de la línea. –
// Esto es un comentario. Formato 2. Empiezan por /* y finalizan por */. No es posible anidar comentarios con este formato. /* Esto también es un comentario */ /* Pero esto que /* parece un comentario válido*/ no lo es */
Compilador C para PIC C específico para los PIC –
Las principales diferencias entre compiladores residen en las directivas ( preprocessor commands) y en las funciones integradas (built-in functions).
– Al final de esta sección se incluyen sendas listas con las directivas y las
funciones integradas correspondientes al compilador de CCS.
Directivas de preprocesado más habituales: #ASM Las líneas entre estas dos directivas deben ser instrucciones #ENDASM ensamblador que se insertan tal y como aparecen. #BIT id=x.y
Se crea una variable tipo bit correspondiente al bit y del byte x en memoria.
#BYTE id=x
Se crea una variable y se sitúa en el byte x en memoria. Si ya existía esa variable, se coloca físicamente en la posición especificada.
Compilador C para PIC C específico para los PIC #DEFINE id texto
El identificador se sustituye por el texto adjunto.
#DEVICE chip
Define el micro para el que se escribe el código.
#FUSES options
Define la palabra de configuración para la grabación del microcontrolador.
#INCLUDE #INCLUDE “fichero”
Se incluye el texto del fichero especificado en el directorio o fuera de él.
#INLINE
La función que sigue a esta directiva se copia en memoria de programa cada vez que se le llame. Puede servir para mejorar la velocidad.
#SEPARATE
La función que sigue a esta directiva se implementa de manera separada (no INLINE). De esta manera se ahorra ROM
Compilador C para PIC C específico para los PIC #ORG start
Sitúa el código a partir de una determinada posición de la memoria de programa
#INT_xxxx
Indica que la función que sigue es un programa de tratamiento de la interrupción xxxx. Indica que la función que sigue es un programa genérico de tratamiento de interrupción. No se incluye código de salvaguarda de registros ni de recuperación como cuando se usa #INT_xxxx.
#INT_GLOBAL
#PRIORITY ints
Establece un orden de prioridad en las interrupciones.
#USE DELAY (clock = frecuencia en Hz) Define la frecuencia del oscilador que se va a utilizar, que se emplea para realizar los cálculos para funciones integradas de retardo.
Compilador C para PIC pre-processor commands
Compilador C para PIC built-in functions
Compilador C para PIC built-in functions
Compilador C para PIC PIC C COMPILER INICIO > PIC-C > PIC C COMPILER
–
Se puede Crear o abrir un fichero (FILE > NEW / OPEN) o crear un proyecto (conjunto de ficheros y opciones de compilación que se utilizan en un programa). Los proyectos tienen la extensión PJT.
–
Para crear un nuevo proyecto PROJECT > NEW > PIC WIZARD / MANUAL CREATE
Compilador C para PIC PIC C COMPILER
PCB (12bit) PCM (14bit) PCH (PIC18)
COMPILAR (F9) MONTARLO
Compilador C para PIC GESTION DE PUERTOS •
Existen dos opciones para configurar y manejar los puertos E/S –
Definiendo los registros como variables localizadas en RAM . Se definen los puertos y los registros de dirección como variables de C y se colocan en las posiciones reales de estos registros en la memoria RAM de datos. Constituye la manera más directa de trabajar con los puertos E/S.
–
Usando las funciones integradas específicas del compilador. Se definen la dirección de datos si es necesario y se gestionan las entradas y las salidas mediante funciones relativas al manejo de todo el puerto o de bits particulares del mismo. •
Cuando se usan las funciones integradas del compilador de CCS, el código que introduce el compilador puede variar en cuanto a tamaño y tiempo de ejecución. Dependerá de la activación de ciertas directivas de preprocesado:
#USE FAST_IO - #USE FIXED_IO - #USE STANDARD_IO
Compilador C para PIC GESTION DE PUERTOS: POR RAM OPCIÓN 1. Definiendo los registros en la RAM. Se definen los registros PORTx y TRISx como bytes y se sitúan en la posición correspondiente de la memoria RAM. La directiva C utilizada es #BYTE: #BYTE variable=constante; #BYTE TRISA = 0x85 //Variable TRISA en 85h. #BYTE PORTA = 0x05 //Variable PORTA en 05h. #BYTE TRISB = 0x86 //Variable TRISB en 86h. #BYTE PORTB = 0x06 //Variable PORTB en 06h. – Una vez definidas estas variables se pueden configurar y controlar los puertos mediante comandos de asignación.A partir de este punto, estas variables permiten controlar los puertos y se pueden utilizar en sentencias de asignación. TRISA = 0xFF; // 8 terminales de entrada TRISB = 0x00; // 8 terminales de salida TRISC = 0x0F; // 4 pin de mayor peso OUT,4 pin de menor peso IN
Compilador C para PIC GESTION DE PUERTOS: POR RAM Escritura en los puertos: PORTC = 0x0A; // salida del datos 00001010 por el puerto C – Lectura de puertos: valor = PORTA; // Asigna el dato del puerto A a la variable valor. – Manejo de sentencias: TRISD=0x0F; if (PORTD & 0x0F) PORTD |= 0xA0; //comprueba los 4 terminales de // menor peso del puerto D y si son // 1111 saca por los 4 terminales de // mayor peso el dato 1010. –
Compilador C para PIC GESTION DE PUERTOS: POR RAM –
El compilador de CCS incorpora una serie de funciones integradas que permite manejar los bits de una variable previamente definida. bit_clear (var,bit); bit_set (var , bit); bit_test (var , bit); swap (var);
//Pone a 0 el bit específico (0 a 7) de la variable. //Pone a 1 el bit específico (0 a 7) de la variable. //Muestra el bit específico (0 a 7) de la variable. //Intercambia los 4 bits de mayor peso por los 4 //de menor peso de la variable.
//”saca” un 1 por el terminal RC4 bit_set (PORTC , 4); if (bit_test(PORTB,0)==1) bit_clear(PORTB,1); //si RB0 es 1 borra RB1 –
También se puede declarar un bit de un registro con una variable mediante la directiva #BIT y trabajar directamente con la variable.
#BIT nombre = posición.bit
#BIT RA4 = 0x05.4 ...... RA4 = 0;
Compilador C para PIC GESTION DE PUERTOS: POR RAM Ejemplo: LED CONTROLADO POR BOTON RB0/INT RB1 RB2 RB3/PGM RB4 RB5 RB6/PGC RB7/PGD RC0/T1OSO/T1CKI RC1/T1OSI/CCP2 RC2/CCP1 RC3/SCK/SCL RC4/SDI/SDA RC5/SDO RC6/TX/CK RC7/RX/DT
21 22 23 24 25 26 27
SW1 D1 LED-BLUE
28 11 12 13 14 15 16 17 18
COMPILAR (F9) MONTARLO
R1 180
SW-SPST-MOM
Compilador C para PIC GESTION DE PUERTOS: POR DIRECTIVAS •
OPCIÓN 2. Usando funciones integradas del compilador. –
El compilador de CCS incorpora una serie de funciones integradas orientadas a trabajar con los puertos E/S. output_X (valor); input_X(); set_tris_X(valor); port_b_pullups (valor);
//Por el puerto correspondiente se saca // el valor (0-255). //Se obtiene el valor en el puerto correspondiente. //Carga el registro TRISx con el valor (0-255). //Mediante valor=TRUE o valor=FALSE habilita o //deshabilita las resistencias de pull-up en PORTB.
Compilador C para PIC GESTION DE PUERTOS: POR DIRECTIVAS –
Hay una serie de funciones asociadas a un terminal o pin*. El parámetro pin* se define en un fichero include (por ejemplo, 16F876.h) con un formato del tipo PIN_Xn, donde X es el puerto y n es el número de pin. #define PIN_A0 40 #define PIN_A1 41 output_low (pin*); output_high (pin*); output_bit (pin* , valor); output_toggle(pin*); output_float (pin*); input_state(pin*); input(pin*);
//Pin a 0. //Pin a 1. //Pin al valor especificado. //Complementa el valor del pin. //Pin de entrada, quedando a tensión flotante //lee el valor del pin sin cambiar su sentido // lee el valor del pin.
Compilador C para PIC GESTION DE PUERTOS: POR DIRECTIVAS –
La generación de código para las funciones output_x( ) e input_x( ) depende de la última directiva del tipo #USE *_IO que esté activa.
#USE FAST_IO (PUERTO) [PUERTO: A…] – Cada vez que se emplea una función output...() se saca el valor directamente al puerto, y cada vez que se emplea una función input...() se lee el puerto, pero no se modifican previamente el registro TRIS correspondiente. – El usuario debe asegurarse de que los registros TRIS están cargados adecuadamente antes de llamar a las funciones. Ej. #USE FAST_IO (B) #USE STANDARD_IO (PUERTO) [PUERTO: A…] – Cada vez que se emplea una función output...() se inserta código previo para forzar a que el bit particular o el puerto completo sean de salida (mediante la carga del TRIS correspondiente). Si se trata de una función input...() se carga código para definir bit o puerto completo como de entrada. – Ésta es la opción activa por defecto. Ej. #USE STANDARD_IO (C)
Compilador C para PIC GESTION DE PUERTOS: POR DIRECTIVAS #USE FIXED_IO (PUERTO_OUTPUTS=pin* , ...) [PUERTO: A…] – Se genera código relativo a la dirección de los datos de manera previa cada vez que aparece una función integrada del tipo input…( ) ó output…( ), pero los pines se configuran de acuerdo con la información que acompaña a la directiva (sólo se indican los pines de salida) y no dependiendo de que la operación sea de entrada o de salida como sucede con #USE STANDARD_IO(PUERTO) Ej. USE FIXED_IO (B_OUTPUTS = PIN_B2 , PIN_B3) –
El efecto de colocar una u otra directiva se puede observar en los ficheros *.lst que se generan como resultado de la compilación. En general se puede decir que resulta más cómodo gestionar los pines de E/S de modo STANDARD, pero haciéndolo de modo FAST se adquiere más control de lo que se le está mandando al PIC y se optimiza código.
Compilador C para PIC GESTION DE PUERTOS: POR DIRECTIVAS
Compilador C para PIC GESTION DE PUERTOS: POR PUNTEROS •
La memoria se puede acceder en C usando punteros. Los punteros deben ser del tipo INT. #define portb (int *) 0x06 –
portb es un puntero INT cuyo valor es la dirección del bus del dispositivo. El puerto es accesible mediante el uso del operado *. int p p = *portb
–
En este ejemplo el valor del dato en el puerto direccionado en la posición de memoria 0x06 (puerto B) es asignado a la variable p. Antes de que el puerto sea leido es necesario establecer si es de entrada o salida #define trisb (int *) 0x86 *trisb = 0xFF
Compilador C para PIC GESTION DE PUERTOS: POR PUNTEROS – Los pines pueden escritos o leidos mediante operadores lógicos.
*portb |= 0b00000100;
pone el pin 2 del portB a 1
*portb &= 0b11111011;
pone el pin 2 del portB a 0.
Para lee el valor del pin 7 del portB: If (*portb & 0b10000000) {…..
Compilador C para PIC GESTION DE PUERTOS: POR PUNTEROS
Compilador C para PIC Ejemplo: DISPLA DISPLAYY LCD con driver HD44780 1.- Vss (Masa) 2.- Vcc (Alimentación de 2.7V a 5.5V) 3.- Ajuste de contraste (de 0 a 5.5V) 4.- RS (selección de registro) 5.- R/W (lectura/escritura) 6.- E (enable) 7.- D0 (dato LSB) 8.- D1 9.- D2 10.- D3 11.- D4 12.- D5 13.- D6 14.- D7 (dato MSB)
Compilador C para PIC Ejemplo: DISPLA DISPLAYY
Compilador C para PIC Ejemplo: DISPLAY •
LCD en el compilador C de CCS El compilador C de CCS incluye un driver para manejar LCD, el fichero que define las funciones indicadas a continuación. lcd_init (); – Debe llamarse antes que ninguna otra función del fichero LCD.C. – Tal y como aparece en el fichero, además de borrar el display, configura el LCD para trabajar como sigue: a) En formato de 4 bits, con dos líneas y con caracteres de 5×8 puntos. b) Con display encendido, cursor apagado y sin parpadeo. c) Con autoincremento del puntero de direcciones y sin desplazamiento del display real. lcd_gotoxy (x , y); – Establece la posición del LCD a la que se – debe acceder. – Recuérdese que la primera posición de la primera línea tiene coordenadas (1 , 1), y que la primera posición de la segunda línea es la (1 , 2). –
Compilador C para PIC Ejemplo: DISPLA DISPLAYY lcd_putc (dato); – Escribe dato en la posición a la que apunta el puntero de direcciones. – La variable dato es de tipo char, y se definen algunos caracteres especiales: \f Borra el display \n Se posiciona en el inicio de la segunda línea \b Retrocede una posición –
Por defecto, este driver usa siete bits del puerto B para establecer la comunicación entre el LCD y el microcontrolador (aunque también se puede utilizar el puerto D). B0 Enable B4 Bit de datos D4 B1 RS B5 Bit de datos D5 B2 R/W B6 Bit de datos D6 B3 B7 Bit de datos D7
Compilador C para PIC Ejemplo: DISPLA DISPLAYY
También es posible escribir en el LCD usando la siguiente función.
–
printf(lcd_putc,cadena,vars); cadena: Cadena de caracteres que puede formarse usando el contenido de cadena: una o más variables. • vars vars:: Variables incluidas en la cadena (separadas por comas). •
–
Para indicar la posición y el tipo de las variables a incluir en la cadena, se usa el formato %nt %nt,, donde n es opcional. n: (opcional)
1-9 Indica el número de caracteres a mostrar 01-09 Indica el número de ceros a la izquierda 1.1-9.9 Indica cuántos decimales se han de mostrar
t:
Carácter e Flotante (formato exp) Cadena o carácter f Flotante truncando Entero sin signo lu Entero largo sin signo Entero hexadecimal lx ó lX Entero largo hexadecimal Entero con signo ld Entero largo con signo Flotante rendondeado Entero sin signo. La 1ª cifra indica el total, la 2ª el nº de decimales
c s u xóX d g w
Compilador C para PIC Ejemplo: DISPLA DISPLAYY – Algunos ejemplos.
printf(lcd_putc , ”Hola”); printf(lcd_putc , ”Tecla %c pulsada %u veces” , , key , cont );
– Ejemplos de formato.
Especificador %03u %u %2u %5 %d %x %X %4X %3.1w
Valor=0x12 018 18 18 18 18 12 12 0012 1.8
Valor=0xfe 254 254 ??? 254 -2 fe FE 00FE 25.4
Ejemplo: DISPLAY C para PIC Compilador –
El driver LCD.C está pensado para trabajar con el PORTB o el PORTD.
–
Si se quiere trabajar con otro puerto, como por ejemplo el PORTC, se deben cambiar los datos en el fichero
#define use_portb_lcd TRUE permite seleccionar el PORT
Compilador C para PIC Ejemplo: DISPLAY LCD2 LM016L
S D E S D E V V V 1 2 3
S W R R E 4 5 6
0 1 2 3 4 5 6 7 D D D D D D D D 7 8 9 0 1 2 3 4 1 1 1 1 1
U1 9 10 1 2 3 4 5 6 7
OSC1/CLKIN OSC2/CLKOUT MCLR/Vpp/THV
RB0/INT RB1 RB2 RB3/PGM
RA0/AN0 RA1/AN1 RA2/AN2/VREFRA3/AN3/VREF+
RB4 RB5 RB6/PGC RB7/PGD
RA4/T0CKI RA5/AN4/SS
RC0/T1OSO/T1CKI RC1/T1OSI/CCP2 RC2/CCP1 RC3/SCK/SCL RC4/SDI/SDA RC5/SDO RC6/TX/CK RC7/RX/DT
21 22 23 24 25 26 27 28 11 12 13 14 15 16 17 18
PIC16F876
COMPILAR (F9) MONTARLO
Compilador C para PIC Ejemplo: DISPLAY/MENU LCD1 LM016L
S D E S D E V V V 1 2 3
S W R R E 4 5 6
0 1 2 3 4 5 6 7 D D D D D D D D 7 8 9 0 1 2 3 4 1 1 1 1 1
U1 9 10 1 2 3 4 5 6
R1
7
OSC1/CLKIN OSC2/CLKOUT MCLR/Vpp/THV
RB0/INT RB1 RB2 RB3/PGM
RA0/AN0 RA1/AN1 RA2/AN2/VREFRA3/AN3/VREF+
RB4 RB5 RB6/PGC RB7/PGD
RA4/T0CKI RA5/AN4/SS
10k
RC0/T1OSO/T1CKI RC1/T1OSI/CCP2 RC2/CCP1 RC3/SCK/SCL RC4/SDI/SDA RC5/SDO RC6/TX/CK RC7/RX/DT
21 22 23 24 25 26 27 28 11 12 13 14 15 16 17 18
PIC16F876
COMPILAR (F9) MONTARLO
Compilador C para PIC Ejemplo: TECLADO/DISPLAY •
KEYPAD (3x4) en el compilador C de CCS –
El compilador C de CCS incluye un driver KBD.C para manejar el teclado (3x4).
kbd_get(); • Devuelve el valor de la tecla pulsada en función de la tabla que tiene programada.
Vista desde atrás
Compilador C para PIC Ejemplo: TECLADO/DISPLAY –
El driver KBD.C está pensado para trabajar con el PORTB o el PORTD.
#define use_portb_lcd TRUE permite seleccionar el PORT
Compilador C para PIC Ejemplo: TECLADO/DISPLAY –
Las conexiones vienen dadas en el fichero pero se pueden modificar: col
pin(port)
C0 R0
C1 C2 1
2
3
A
1
2
3
B
4
5
6
C
7
8
9
0
#
R1 RB0/INT RB1 RB2 RB3/PGM RB4 RB5 RB6/PGC RB7/PGD
21 22
R2
23 24 25 26 27 28
R3
D
Compilador C para PIC Ejemplo: TECLADO/DISPLAY LCD2 LM016L
1
2
3
A
1
2
3
B
4
5
6
C
7
8
9
0
#
U1 9 10 1 2 3 4 5 6 7
OSC1/CLKIN OSC2/CLKOUT
RB0/INT RB1
MCLR/Vpp/THV
RB2
RA0/AN0
RB3/PGM RB4
RA1/AN1 RA2/AN2/VREF-
RB5 RB6/PGC
RA3/AN3/VREF+
RB7/PGD
RA4/T0CKI RA5/AN4/SS
RC0/T1OSO/T1CKI RC1/T1OSI/CCP2 RC2/CCP1 RC3/SCK/SCL RC4/SDI/SDA RC5/SDO RC6/TX/CK RC7/RX/DT
PIC16F876
21 22 23 24 25 26 27 28 11 12 13 14 15 16 17 18
D
S D E S D E V V V 1 2 3
S W R R E 4 5 6
0 1 2 3 4 5 6 7 D D D D D D D D 7 8 9 0 1 2 3 4 1 1 1 1 1
Compilador C para PIC Ejemplo: TECLADO/DISPLAY LCD2 LM016L
1
2
3
A
1
2
3
B
4
5
6
C
7
8
9
0
#
U1 9 10 1 2 3 4 5 6 7
OSC1/CLKIN OSC2/CLKOUT MCLR/Vpp/THV
RB0/INT RB1 RB2
RA0/AN0
RB3/PGM RB4
RA1/AN1 RA2/AN2/VREF-
RB5 RB6/PGC
RA3/AN3/VREF+
RB7/PGD
RA4/T0CKI RA5/AN4/SS
RC0/T1OSO/T1CKI RC1/T1OSI/CCP2 RC2/CCP1 RC3/SCK/SCL RC4/SDI/SDA RC5/SDO RC6/TX/CK RC7/RX/DT
PIC16F876
21 22 23 24 25 26 27 28 11 12 13 14 15 16 17 18
D
S D E S D E V V V 1 2 3
S W R R E 4 5 6
0 1 2 3 4 5 6 7 D D D D D D D D 7 8 9 0 1 2 3 4 1 1 1 1 1
Compilador C para PIC Ejemplo: TECLADO/DISPLAY
COMPILAR (F9) MONTARLO
Compilador C para PIC Ejemplo: TECLADO/DISPLAY
Compilador C para PIC Ejemplo: INTERRUPCIONES
Las directivas #INT_xxxx. Indican que la función que aparece a continuación corresponde al tratamiento de una interrupción (no tiene ni necesita parámetros). – En el caso de los PIC 16F87x hay 14 posibles directivas. –
#INT_RTCC #INT_RB #INT_EXT #INT_AD #INT_TBE #INT_RDA #INT_TIMER1 #INT_TIMER2 #INT_CCP1 #INT_CCP2 #INT_SSP #INT_BUSCOL #INT_EEPROM
Desbordamiento de TMR0. Cambio en los pines RB<4:7>. Flanco en pin RB0. Fin de conversión A/D. Buffer de transmisión USART vacío. Dato recibido en USART. Desbordamiento de TMR1. Desbordamiento de TMR2. Captura / Comparación en módulo CCP1. Captura / Comparación en módulo CCP2. Envío / Recepción de dato serie síncrono. Colisión de bus I2C. Escritura completa en EEPROM de datos.
(T0IF) (RBIF) (INTF) (ADIF) (TXIF) (RCIF) (TMR1IF) (TMR2IF) (CCP1IF) (CCP2IF) (SSPIF) (BCLIF) (EEIF)
Compilador C para PIC Ejemplo: INTERRUPCIONES –
La directiva #INT_DEFAULT. Indica que la función que viene a continuación será llamada si se dispara una interrupción y ninguno de los flags está activo.
–
La directiva #INT_GLOBAL. Indica que la función que va a continuación sustituye todas las acciones que inserta el compilador al aceptarse una interrupción. Sólo se ejecuta lo que vaya en dicha función.
– Ventajas de usar las directivas de interrupciones •
El compilador genera el código necesario para saltar a la función que va tras esta directiva en el momento de la interrupción.
•
También genera código para salvar al principio y restituir al final el contexto, y borrará el flag que se activó con la interrupción.
•
El programador debe seguir encargándose de habilitar las interrupciones.
Compilador C para PIC Ejemplo: INTERRUPCIONES
Funciones para gestión de interrupciones. El compilador C de CCS incluye algunas funciones integradas destinadas a manejar interrupciones.
– •
enable_interrupts (nivel); nivel es una constante definida en 16F876.h y genera el código necesario para
activar las máscaras necesarias. Etiquetas de nivel definidas para el 16F876: GLOBAL INT_RTCC INT_RB INT_EXT INT_AD INT_TBE INT_RDA INT_TIMER1 INT_TIMER2 INT_CCP1 INT_CCP2 INT_SSP INT_PSP INT_BUSCOL INT_EEPROM La máscara global (la que hace GIE=1) debe activarse de manera independiente. Las otras sólo activan la máscara particular y el PEIE si es necesario. •
disable_interrupts (nivel);
Hace la acción contraria a la función anterior, poniendo a 0 las máscaras relacionadas con la interrupción indicada.
Compilador C para PIC Ejemplo: INTERRUPCIONES
Existe también una función adicional destinada a configurar el flanco activo que genera la interrupción externa (en RB0).
– •
•
ext_int_edge (H_TO_L);
Selecciona flanco de bajada para activar el flag INTF. ext_int_edge (L_TO_H);
Selecciona flanco de subida para activar el flag INTF.
#INT_EXT ext_isr() { ......} enable_interrupts (INT_EXT); ext_int_edge (H_TO_L); enable_interrupts (GLOBAL);
// Activa máscara INTE // Flag INTF si flanco de bajada. // Habilita máscara global de int.
/* Si entra una interrupción por flanco de bajada en RB0, se irá a la función que aparece tras la directiva #INT_EXT */ disable_interrupts (INT_EXT); disable_interrupts (GLOBAL);
// Desactiva interrupciones en RB0. // Desactiva todas las interrupciones.
Compilador C para PIC Ejemplo: INTERRUPCIONES_RB0 U1 9 10 1 2 3 4 5 6 7
OSC1/CLKIN OSC2/CLKOUT MCLR/Vpp/THV RA0/AN0 RA1/AN1 RA2/AN2/VREFRA3/AN3/VREF+ RA4/T0CKI RA5/AN4/SS
RB0/INT RB1 RB2 RB3/PGM RB4 RB5 RB6/PGC RB7/PGD RC0/T1OSO/T1CKI RC1/T1OSI/CCP2 RC2/CCP1 RC3/SCK/SCL RC4/SDI/SDA RC5/SDO RC6/TX/CK RC7/RX/DT
21 22 23
SW1
24 25
SW-SPDT-MOM
26 27 28 11 12 13 14
D1 LED-GREEN
15 16 17 18
R1
PIC16F876
180
COMPILAR (F9) MONTARLO
Compilador C para PIC Ejemplo: TIMER0 –
TMR0 / WDT en el compilador C de CCS • Configuración del módulo TMR0. setup_timer_0 (modo); modo: RTCC_INTERNAL (OPTION_REG ← 00h)
RTCC_EXT_L_TO_H (OPTION_REG ← 20h) RTCC_EXT_H_TO_L (OPTION_REG ← 30h) RTCC_DIV_2 (OPTION_REG ← 00h) RTCC_DIV_4 (OPTION_REG ← 01h) RTCC_DIV_8 (OPTION_REG ← 02h) RTCC_DIV_16 (OPTION_REG ← 03h) RTCC_DIV_32 (OPTION_REG ← 04h) RTCC_DIV_64 (OPTION_REG ← 05h) RTCC_DIV_128 (OPTION_REG ← 06h) RTCC_DIV_256 (OPTION_REG ← 07h) Se pueden agrupar constantes de distintos grupos con |.
Compilador C para PIC Ejemplo: TIMER0 –
Configuración del módulo WDT. setup_wdt (modo); modo:
•
WDT_18MS WDT_36MS WDT_72MS WDT_144MS WDT_288MS WDT_576MS WDT_1152MS WDT_2304MS
(OPTION_REG ← 08h) (OPTION_REG ← 09h) (OPTION_REG ← 0Ah) (OPTION_REG ← 0Bh) (OPTION_REG ← 0Ch) (OPTION_REG ← 0Dh) (OPTION_REG ← 0Eh) (OPTION_REG ← 0Fh)
Para que el temporizador WATCHDOG pueda llevar a cabo su misión es necesario indicarlo así con la directiva #fuses. WDT activado #fuses [opciones], WDT [opciones] #fuses [opciones], NOWDT [opciones] WDTdesactivado
Compilador C para PIC Ejemplo: TIMER0 –
Configuración de los módulos TMR0 y WDT (obsoleto).
•
Funciones implementadas en el compilador por compatibilidad con versiones anteriores. No se recomienda su uso. setup_counters (rtcc , prescaler); rtcc: RTCC_INTERNAL (OPTION_REG ← 00h) RTCC_EXT_L_TO_H (OPTION_REG ← 20h) RTCC_EXT_H_TO_L (OPTION_REG ← 30h) prescaler: RTCC_DIV_2 (OPTION_REG ← 00h) ... ... RTCC_DIV_256 (OPTION_REG ← 07h) WDT_18MS (OPTION_REG ← 08h) WDT_36MS (OPTION_REG ← 09h) WDT_72MS (OPTION_REG ← 0Ah) WDT_144MS (OPTION_REG ← 0Bh) WDT_288MS (OPTION_REG ← 0Ch) WDT_576MS (OPTION_REG ← 0Dh) WDT_1152MS (OPTION_REG ← 0Eh) WDT_2304MS (OPTION_REG ← 0Fh)
Compilador C para PIC Ejemplo: TIMER0 –
–
–
Escritura en el módulo TMR0. set_timer0 (valor); valor: Entero de 8 bits. Lectura del módulo TMR0. valor = get_timer0 (); valor: Entero de 8 bits.
(TMR0 ← valor)
(valor ← TMR0)
Puesta a cero del Watchdog.
restart_wdt (); No precisa ningún parámetro.
(equivale a CLRWDT)
Compilador C para PIC Ejemplo: TIMER0
Generar una señal cuadrada de 1KHz utilizando la interrupción del Timer0. Con un semiperiodo de 500us
#INCLUDE <16F876.h> #use delay(clock=4000000) #fuses XT,NOWDT #use standard_io(B) int1 var0=0;
//variable de cambio
#int_TIMER0 void TIMER0_isr(void) { var0++; if (var0==1) output_bit(PIN_B0,1); else output_bit(PIN_B0,0); set_timer0 (0x06); }
500us=4/Fosc(256-x) X = 6 Con Fosc=4MHz y preescaler 1:2
//se complementa la variable //para semiperiodo alto //para semiperiodo bajo //se recarga el timer0
void main() { setup_timer_0(RTCC_INTERNAL|RTCC_DIV_2); set_timer0 (0x06); enable_interrupts(INT_TIMER0); enable_interrupts(global); while (1); }
//configuración timer0 //carga del timer0 //habilita interrupcion timer0 //habilita interrupción general //bucle infinito
Compilador C para PIC Ejemplo: TIMER0
Para ajustar el tiempo se carga el timer0 con 29 (0x1D). Esto es debido a la generación de código ensamblador por parte del compilador.
Compilador C para PIC Ejemplo: TIMER1 –
Registro T1CON (10h)
bits 5-4 T1CKPS1:T1CKPS0: Selección del prescaler 00: Prescaler1:1. 10: Prescaler1:4. 01: Prescaler1:2. 11: Prescaler1:8. bit 3 T1OSCEN: Habilitación del oscilador de TMR1 0: Apagado 1: Habilitado bit 1 TMR1CS: Reloj de TMR1 0: Reloj interno (fOSC/4). 1: Reloj externo (↑ en RC0). bit 2 T1SYNC: Control de la sincronización con el reloj externo Sólo si TMR1CS=1 0: Sincronizar 1: No sincronizar bit 0 TMR1ON: Bit de encendido de TMR1 0: TMR1 apagado. 1: TMR1 encendido.
Compilador C para PIC Ejemplo: TIMER1 –
TMR1 en el compilador C de CCS •
Configuración del módulo TMR1. setup_timer_1 (modo); modo: T1_DISABLED (T1CON ← 00h)
T1_INTERNAL (T1CON ← 85h) T1_EXTERNAL (T1CON ← 87h) T1_EXTERNAL_SYNC (T1CON ← 83h) T1_CLK_OUT (T1CON ← 08h) T1_DIV_BY_1 (T1CON ← 00h) T1_DIV_BY_2 (T1CON ← 10h) T1_DIV_BY_4 (T1CON ← 20h) T1_DIV_BY_8 (T1CON ← 30h) Se pueden agrupar constantes de distintos grupos con |. •
Lectura / Escritura en el módulo TMR1. valor = get_timer1 (); set_timer1 (valor); valor: Entero de 16 bits.
Compilador C para PIC Ejemplo: TIMER1 #include <16f876.h> #fuses XT,NOWDT #use delay(clock=4000000) #use standard_io(b) temp1s() { int cont=0; output_toggle(PIN_B1); while (cont<2) { set_timer1 (3036); while (get_timer1()>=3036); cont++; } } main () { setup_timer_1 (T1_INTERNAL | T1_DIV_BY_8); while(1){ temp1s(); } }
Configurar el módulo TMR1 para generar una temporización de 1s. (dos de 0,5) 0.5=4/Fosc(65536-x)P X = 3036 Con Fosc=4MHz y preescaler 1:8
Compilador C para PIC Ejemplo: TIMER2 –
Registro T2CON (12h)
bits 6-3 TOUTPS3:TOUTPS0: Selección del postscaler 0000: Postscaler1:1 0001: Postscaler1:2 0010: Postscaler1:3 ..... 1111: Postscaler1:16 bit 2 TMR2ON: Bit de encendido de TMR2 0: Apagado 1: Habilitado bits 1:0 T2CKPS1:T2CKPS0: Selección del prescaler 00: Prescaler1 01: Prescaler4 1x: Prescaler16
Compilador C para PIC Ejemplo: TIMER2 –
TMR2 en el compilador C de CCS • Configuración del módulo TMR2. setup_timer_2 (modo,periodo,postscaler); modo: T2_DISABLED (T2CON ← 00h)
T2_DIV_BY_1 (T2CON ← 04h) T2_DIV_BY_4 (T2CON ← 05h) T2_DIV_BY_16 (T2CON ← 06h) periodo: Entero de 8 bits (0-255) que se pasa al registro PR2. postscaler: Valor del postscaler (1-16). •
Lectura / Escritura en el módulo TMR2. valor = get_timer2 (); set_timer2 (valor); valor: Entero de 8 bits.
Compilador C para PIC Ejemplo: TIMER2
Generar una señal cuadrada de 1KHz utilizando la interrupción del Timer2. Temp=[Prescaler(PR2+1)Postscaler]Tinstr
INCLUDE <16F876.h> #use delay(clock=4000000) #fuses XT,NOWDT #use standard_io(B)
500us=(4/4000000)·[4· (X+1) ·1]
x = 125 Con Fosc=4MHz preescaler 4 //variable de cambio postscaler 1
int1 var0=0; #int_TIMER2 void TIMER2_isr(void) { //Función Interrupción var0++; //se complementa la variable if (var0==1) output_bit(PIN_B0,1); //para semiperiodo alto else output_bit(PIN_B0,0); //para semiperiodo bajo set_timer0 (0x7C); } //se recarga el timer0
void main() { setup_timer_2 (T2_DIV_BY_4 ,124,1); //configuración timer2 enable_interrupts(INT_TIMER2); //habilita interrupcion timer0 enable_interrupts(global); //habilita interrupción general while (1); //bucle infinito }
Compilador C para PIC Ejemplo: TIMER2
Para ajustar el tiempo se carga el timer2 con 124 (0x7C). Esto es debido a la generación de código ensamblador por parte del compilador.
Compilador C para PIC Ejemplo: INTERRUPCIONES_TIMER
U1 9 10 1 2 3 4 5 6 7
OSC1/CLKIN OSC2/CLKOUT MCLR/Vpp/THV RA0/AN0 RA1/AN1
RB0/INT RB1 RB2 RB3/PGM RB4 RB5
RA2/AN2/VREF-
RB6/PGC
RA3/AN3/VREF+ RA4/T0CKI
RB7/PGD
RA5/AN4/SS
RC0/T1OSO/T1CKI RC1/T1OSI/CCP2 RC2/CCP1 RC3/SCK/SCL RC4/SDI/SDA RC5/SDO RC6/TX/CK RC7/RX/DT
21 22 23 24
D3
D1
D2
LED-GREEN LED-GREENLED-GREEN
25 26 27 28 11 12 13 14 15 16 17 18
PIC16F876
COMPILAR (F9) MONTARLO
R3
R1
R2
180
180
180
Compilador C para PIC Ejemplo: INTERRUPCIONES_TIMER –
Medir el ancho de un pulso mediante el TIMER1 y la Interrupción Externa por RB0. •
El TIMER1 es un contador de 16 bits que se incrementa cada 4 ciclos de Reloj (FOSC *4). A este tiempo le vamos a llamar PASO de TIMER1. Si el cristal de cuarzo es de 4 Mhz, entonces 1µs se produce un PASO de TIMER1.
•
Un ciclo completo del TIMER1, desde 0x0000 hasta 0xFFFF (65536 pasos), ocupa un tiempo total de 1µs * 65.536 = 65,536ms.
•
Podemos fijar un tipo de flanco a detectar y escribir un cierto código para ejecutarlo cuando ese tipo de flanco, subida o bajada, es detectado. este código escrito para tratar la interrupción externa por RB0 podemos mantener o cambiar el flanco a detectar, cambiándolo del de Subida al de Bajada o viceversa y leer o escribir el valor de TIMER1 que en ese momento tiene el contador.
Compilador C para PIC Ejemplo: INTERRUPCIONES_TIMER 1. Se configura la INTEXT por RB0 para detectar inicialmente el Flanco de Subida. 2.
Al llegarnos este Flanco de Subida se guarda el valor en ese momento de TIMER1.
3. Se cambia la configuración de la INTEXT por RB0 para detectar el siguiente Flanco de Bajada. 4. Cuando llegue el Flanco de Bajada se guarda de nuevo el valor de TIMER1. 5. Se vuelve a configurar la INTEXT por RB0 para detectar de nuevo un Flanco de Subida. 6. Con estos dos valores de TIMER1 se obtiene, expresados en PASOS de TIMER1, restando el segundo del primero, el tiempo que ha permanecido en alto el Pulso. Multiplicando dicho número de PASOS de TIMER1 por el tiempo que dura cada PASO (dependiente del cristal) se obtiene el Tiempo W. 7. El ancho de pulso máximo es de 65,536ms (un ciclo de TIMER1). El mínimo dependerá del tiempo que tarda en programa en gestionar la interrupción y los cálculos.
Compilador C para PIC Ejemplo: INTERRUPCIONES_TIMER Modificar el fichero LCD.C para trabajar con el LCD en el puerto C (guardarlo como LCD_MIO.C) LCD2 LM016L U1(RB0/INT)
S D E S D E V V V
U1 9 10 1 2 3 4 5 6 7
OSC1/CLKIN OSC2/CLKOUT
RB0/INT RB1
MCLR/Vpp/THV RA0/AN0 RA1/AN1
RB2 RB3/PGM RB4 RB5
RA2/AN2/VREF-
RB6/PGC
RA3/AN3/VREF+ RA4/T0CKI
RB7/PGD
RA5/AN4/SS
RC0/T1OSO/T1CKI RC1/T1OSI/CCP2 RC2/CCP1 RC3/SCK/SCL RC4/SDI/SDA RC5/SDO RC6/TX/CK RC7/RX/DT
PIC16F876
21 22 23 24 25 26 27 28 11 12 13 14 15 16 17 18
1 2 3
S W R R E 4 5 6
0 1 2 3 4 5 6 7 D D D D D D D D 7 8 9 0 1 2 3 4 1 1 1 1 1
Compilador C para PIC Ejemplo: INTERRUPCIONES_TIMER
Compilador C para PIC Ejemplo: INTERRUPCIONES_TIMER
COMPILAR (F9) MONTARLO