PROGRAMACIÓN DEL MICROCONTRLADOR PIC16F877A Lenguaje C - 1
Ing. Carlos E. Mendiola Mogollón
[email protected]
[ 01 ]
PROGRAMACIÓN DEL PIC16F877A
En el lenguaje C se pueden gestionar los puertos de dos formas: a) Se declaran los registros TRISX y PORTX definiendo su posición en la memoria RAM como variables de C. a) Utilizando las directivas específicas del compilador • #USE FAST_IO • #USE FIXED_IO • #USE STANDARD_IO
Ing. Carlos E. Mendiola Mogollón
[email protected]
Microcontrolador pic16F877A
GESTIÓN DE PUERTOS EN C
02/10/2013
Puertos de Entrada y Salida
[ 02 ]
PROGRAMACIÓN DEL PIC16F877A GESTION DE PUERTOS A TRAVÉS DE LA RAM
Microcontrolador pic16F877A
Se definen los registros PORTx y TRISx como bytes y se sitúan en la posición correspondiente de la memoria RAM. La directiva utilizada de C es #BYTE
02/10/2013
Puertos de Entrada y Salida
Ing. Carlos E. Mendiola Mogollón
[email protected]
[ 03 ]
PROGRAMACIÓN DEL PIC16F877A
• #BYTE TRISA = 0x85 • #BYTE PORTA = 0x05
// Variable TRISA en 85h // Variable PORTA en 05h
• #BYTE TRISB = 0x86 • #BYTE PORTB = 0x06
// Variable TRISB en 86h // Variable PORTB en 06h
• #BYTE TRISC = 0x87 • #BYTE PORTC = 0x07
// Variable TRISC en 87h // Variable PORTC en 07h
• #BYTE TRISD = 0x88 • #BYTE PORTD = 0x08
// Variable TRISD en 88h // Variable PORTD en 08h
• #BYTE TRISE = 0x89 • #BYTE PORTE = 0x09
// Variable TRISE en 89h // Variable PORTE en 09h
Ing. Carlos E. Mendiola Mogollón
[email protected]
Microcontrolador pic16F877A
#BYTE variable=constante;
02/10/2013
Puertos de Entrada y Salida
[ 04 ]
PROGRAMACIÓN DEL PIC16F877A
TRISB = 0xFF; TRISC = 0x00; TRISD = 0x0F;
// // // //
8 terminales de entrada 8 terminales de salida nible bajo es entrada, nible alto es salida
Escritura de puertos: PORTC = 0x12;
// salida de datos 00010010
Lectura de puertos: valor = PORTB; // entrada de datos
Ing. Carlos E. Mendiola Mogollón
[email protected]
Microcontrolador pic16F877A
Una vez definidas estas variables se pueden configurar y controlar los puertos a través de los comandos de asignación:
02/10/2013
Puertos de Entrada y Salida
[ 05 ]
PROGRAMACIÓN DEL PIC16F877A
bit_clear(var,bit); bit_set(var,bit); bit_test(var,bit); swap(var);
// // // //
Pone en 0 un bit(0 a 7) de la variable. Pone en 1 un bit(0 a 7) de la variable. Muestra el bit(0 a 7) de la variable. Intercambia nibles.
Se puede declarar un bit de un registro con una variable mediante la directiva #BIT nombre = posición.bit #BIT RB4 = 0x06.4 RB4 = 0;
Ing. Carlos E. Mendiola Mogollón
[email protected]
// PORTB = 0x86 // PIN RB4=0
Microcontrolador pic16F877A
Funciones de C que permiten trabajar bit a bit con los registros o variables definidas previamente:
02/10/2013
Puertos de Entrada y Salida
[ 06 ]
PROGRAMACIÓN DEL PIC16F877A Puertos de Entrada y Salida
//Ejemplo 01 #include <16F877a.h> #use delay(clock= 20000000) #byte portb=0x06 #byte trisb=0x86 void main(void) { bit_set(trisb,0); //Pin rb0 como entrada bit_clear(trisb,1);//Pin rb1 como salida
Ing. Carlos E. Mendiola Mogollón
[email protected]
while(1){ if(bit_test(portb,0)==1) { bit_set(portb,1); //Pin rb1=1 } else { bit_clear(portb,1); //Pin rb1=0 } } }
Microcontrolador pic16F877A
Configurar el pin rb0 como entrada (conectar un switch) y el pin rb1 como salida (conectar un led). La salida debe de tener el misto estado (alto/bajo) que la entrada.
02/10/2013
Ejemplo 01:
[ 07 ]
PROGRAMACIÓN DEL PIC16F877A
El compilador ofrece funciones predefinidas para trabajar con los puertos. Estas son: output_X(valor); // Por el puerto correspondiente saca el valor (0-255). input_X(); // Se obtiene el valor en el puerto correspondiente. set_tris_X(valor); // Carga el registro TRISx con el valor (0-255). port_b_pullups(valor); // valor = TRUE o valor = FALSE habilita get_trisX()
// o deshabilita las resistencias de pull-up en PORTB. // Devuelve el valor del registro TRISx
Donde la x es la inicial del puerto correspondiente (A,B,C,D,E).
Ing. Carlos E. Mendiola Mogollón
[email protected]
Microcontrolador pic16F877A
GESTION DE PUERTOS A TRAVÉS DE LAS DIRECTIVAS
02/10/2013
Puertos de Entrada y Salida
[ 08 ]
PROGRAMACIÓN DEL PIC16F877A
output_B(0xFF); Valor = input_C(); set_tris_D(0x0F);
// Saca por el puerto B el valor 11111111 // Lee el valor del puerto C // C0-C3 entradas, C4-C7 salida
Existen una serie de funciones asociadas a un termina o pin*. El parámetro pin* se define en un fichero include con un formato del tipo PIN_Xn, donde X es el puerto y n es el número de pin. #define PIN_B0 33 #define PIN_B1 34
Ing. Carlos E. Mendiola Mogollón
[email protected]
Microcontrolador pic16F877A
GESTION DE PUERTOS A TRAVÉS DE LAS DIRECTIVAS
02/10/2013
Puertos de Entrada y Salida
[ 09 ]
PROGRAMACIÓN DEL PIC16F877A
output_low(pin*); // Pin a 0 output_high(pin*); // Pin a 1 Output_bit(pin*,valor); // Pin al valor especificado. output_toggle(pin*); // Completa el valor de pin. output_float(pin*); // Pin de entrada, quedando a tensión flotante // (simula salida en drenador abierto). input_state(pin*); // Lee el valor del pin sin cambiar el sentido de // del terminal. input(pin*); // Lee el valor del pin.
Las funciones output_x() e input_x() dependen de la directiva tipo #USE*_IO que esté activa. Ing. Carlos E. Mendiola Mogollón
[email protected]
Microcontrolador pic16F877A
Las funciones son:
02/10/2013
Puertos de Entrada y Salida
[ 10 ]
PROGRAMACIÓN DEL PIC16F877A
#include <16F877a.h> #fuses HS, NOWDT #use delay(clock= 20000000) #use fast_io(B)
Ing. Carlos E. Mendiola Mogollón
[email protected]
void main(void) { port_b_pullups(TRUE); set_tris_B(0x01); // rb0:entrada rb1-7:salida output_low(PIN_B1); //Pin rb1=0 output_B(0x00); // borra PORTB while(1){ if(input(PIN_B0)==1) // rb0=1? output_low(PIN_B1); //si--> rb1=0 else output_high(PIN_B1);//no--> rb1=1 } }
Microcontrolador pic16F877A
Directiva #USE FAST_IO (PUERTO) [PUERTO:A…] Con la función output_x() se saca el valor al puerto y con la función input_x() se lee el puerto. Esta directiva no modifica previamente el registro TRIS correspondiente. Hay que asegurarse de que los TRIS están correctamente definidos. Entonces, el ejemplo 02 quedaría: //Ejemplo 02
02/10/2013
Puertos de Entrada y Salida
[ 11 ]
PROGRAMACIÓN DEL PIC16F877A
//Ejemplo 02 #include <16F877a.h> #fuses HS, NOWDT #use delay(clock= 20000000) #use standard_io(B)
Ing. Carlos E. Mendiola Mogollón
[email protected]
void main(void) { port_b_pullups(TRUE); output_B(0x00); // borra PORTB while(1) { if(input(PIN_B0)==1) //rb0=1? output_low(PIN_B1); //si--> rb1=0 else output_high(PIN_B1);//no--> rb1=1 } }
Microcontrolador pic16F877A
Directiva #USE STANDAR_IO (PUERTO) [PUERTO:A…] Con la función output_x() el compilador se asegura de que el terminal, o terminales correspondientes, sean de salida mediante la modificación del TRIS correspondiente. Con la función input_x() ocurre lo mismo pero asegurando el terminal o terminales como entrada. El ejemplo 02 quedaría:
02/10/2013
Puertos de Entrada y Salida
[ 12 ]
PROGRAMACIÓN DEL PIC16F877A
#include <16F877a.h> #fuses HS, NOWDT #use delay(clock= 20000000) #use fixed_io(b_outputs=pin_b1) void main(void) { port_b_pullups(TRUE); output_low(PIN_B1); //Pin rb1=salida while(1) { if(input(PIN_B0)==1) // rb0=1? output_low(PIN_B1); //si--> rb1=0 else output_high(PIN_B1);//no--> rb1=1 } }
Ing. Carlos E. Mendiola Mogollón
[email protected]
Microcontrolador pic16F877A
Directiva #USE FIXED_IO (PUERTO_OUTPUTS = pin*, …) [PUERTO:A…] El compilador se encarga de generar el código para definir los puertos de acuerdo con la información que indica la directiva (donde solo se indican los terminales de salida), sin tener en cuenta si la operación es de entrada o de salida. Entonces el ejemplo 02 quedaría: //Ejemplo 02
02/10/2013
Puertos de Entrada y Salida
[ 13 ]