Está en la página 1de 6

Julio 2016 Programación de PICs Version 1.

00

Practicas Clase Avanzada de programación de PICs

Clase 1

Introducción:
Las prácticas de esta clase se realizaran sobre la plataforma MPLAB Xpress, por lo que es necesario
contar con los siguientes requisitos.

- Un explorador de internet
- Tener el ultimo Java Runtime instalado en la PC
- Descargar el archivo MCC_Xpress.jnlp (Se realiza desde la interfaz del MPLAB Xpress)

Práctica 1: Debounce de un pulsador


En el primer código que realizaremos en la clase veremos cómo realizar el Debounce o el anti-
rebote al accionar un pulsador. La practica consiste en detectar la pulsación del switch S2 ubicado
en la placa y que este controle el encendido y apagado del LED, es decir, si el pulsador se oprime
una vez, se enciende el led y si vuelve a oprimir, se apaga, evitando que los cambios de estados
espurios que puedan existir modifiquen el estado del LED.

Descripción:
El pulsador o switch es un elemento muy utilizado en la generación de interfaces con el usuario, de
esta manera se puede acceder datos al sistema utilizando este elemento. Pero un botón mecánico
tiene la desventaja de que el cambio de estado no se produce de manera suave, sino que se
producen cambios erráticos hasta que se toma el estado deseado. Este comportamiento puede
generar que se detecten más de un cambio de estado cuando en realidad solo se oprimió una vez
el pulsador. Para evitar esto, normalmente lo que se hace es detectar el primer cambio de estado
y generar un retardo que enmascare por un tiempo los siguientes valores hasta que se alcance la
estabilidad del accionamiento mecánico y evitar detectar otras posibles activaciones “espurias”
del pulsador. Otro modo de atacar este problema es el de tomar muestras equi-espaciadas del
estado del pulsador y determinar si se produce la activación o no del mismo. Este segundo método
es el que se realizara en la práctica, se tomaran muestras del pulsador cada 50 milisegundos para
detectar o no, los cambios de estados.

Periféricos utilizados:
Para esta práctica se utilizaran los pines GPIO para activar el encendido de los LEDs de la placa y
leer el estado del pulsador.

1
Julio 2016 Programación de PICs Version 1.00

Configuración del MCC

Código:
#include "mcc_generated_files/mcc.h"

/*
Defines
*/
#define BUTTON_PRESSED 0
#define BUTTON_NOT_PRESSED 1

2
Julio 2016 Programación de PICs Version 1.00

/*
Prototypes
*/
bool BUTTON_IsPressed(void);
bool BUTTON_Activate(void);
/*
Main application
*/
void main(void)
{
// initialize the device
SYSTEM_Initialize();

while (1)
{
// Add your application code
if(BUTTON_Activate())
{
D2_Toggle();
}
__delay_ms(50);
}
}

En la función principal se inicia con el llamado a la función que inicializa los periféricos del PIC,
SYSTEM_Initialize(); Luego se encuentra el bucle principal del programa el cual se testea
una función que indica si se oprimió el botón o no. Esta función es la encargada de detectar la
pulsación, pero se necesita que se ejecute cada 50 milisegundos, ya que compara el estado
anterior con el actual para determinar si se oprimió el pulsador. Una vez que la función devuelve la
activación del pulsador, se realiza un toggle del LED D2.

Funciones Auxiliares
//Funciones Auxiliares
bool BUTTON_IsPressed(void)
{
return ( (BUTTON_PORT == BUTTON_PRESSED) ? true : false);
}

bool BUTTON_Activate(void)
{
static bool lastState = false;
bool actualState;
bool activateButton;

actualState = BUTTON_IsPressed();
if( actualState && !lastState)
activateButton = true;
else
activateButton = false;

lastState = actualState;
return activateButton;
}

3
Julio 2016 Programación de PICs Version 1.00

Para detectar si se oprime el pulsador y evitar el efecto rebote que se puede originar por el
manejo de partes mecánicas, se utilizan estas funciones auxiliares. Como están dedicadas al
pulsador de la placa, los nombres de estas funciones comienzan con BUTTON. Una de las
funciones, BUTTON_IsPressed, es la encargada de tomar el valor actual del pulsador, si esta
pulsado devuelve True, sino, False. La otra función, BUTTON_Activate, debe ejecutarse cada
cierto tiempo, ya que esta toma una muestra del estado anterior y la compara con el actual, si
hubo un cambio, en este caso pasa de no oprimido a oprimido, la función devuelve True. Por ello
es importante que el tiempo de muestreo sea lo suficientemente grande como para evitar el
efecto rebote.

Práctica 2: Cambio de sentido en la rotación


Utilizando lo aprendido en la práctica anterior, generar un programa que cree un encendido
secuencial de los LEDs simulando una rotación y cada vez que se oprima el pulsador, generar un
cambio en la dirección de la rotación.

Descripción:
Se utilizara el mismo concepto aprendido en la práctica anterior para ir tomando muestras del
estado del pulsador y evitar el efecto rebote. Al detectar que se oprimió el pulsador, se debe
generar un evento que indique el cambio en el sentido de la rotación.

Periféricos Utilizados:
En esta práctica se utilizaran los pines GPIO para crear la secuencia de encendido en los LEDs y
poder tomar el estado del pulsador.

Configuración MCC:

4
Julio 2016 Programación de PICs Version 1.00

Código:
#include "mcc_generated_files/mcc.h"

/*
Defines
*/
#define BUTTON_PRESSED 0
#define BUTTON_NOT_PRESSED 1

/*
Prototypes
*/
bool BUTTON_IsPressed(void);
bool BUTTON_Activated(void);
void LED_LoadRegister(unsigned char led_register);
/*
Main application
*/
void main(void)
{
// initialize the device
SYSTEM_Initialize();

bool rotateLeft = true;


int contador = 0;
unsigned char rotateReg = 1;

while (1)
{
// Add your application code
if(BUTTON_Activated())
rotateLeft = !rotateLeft;

__delay_ms(50);
contador++;

if(contador == 10)
{

5
Julio 2016 Programación de PICs Version 1.00

//reseteo contador
contador = 0;
if(rotateLeft)
{
rotateReg <<= 1;
if(rotateReg == 16)
rotateReg = 1;
}
else
{
rotateReg >>= 1;
if(rotateReg == 0)
rotateReg = 8;
}
LED_LoadRegister(rotateReg);
}

}
}

En la función principal de este código se realiza la misma idea que en la práctica anterior, se
muestrea cada 50 milisegundos el estado del pulsador para saber si se oprimió. Entre cada
muestreo del pulsador se incrementa un contador que termina su cuenta en 10, la idea de este
contador es la de contar diez retardos de 50 milisegundos para alcanzar los 500 milisegundos, y así
actualizar el estado de los encendidos del LED. Por defecto, la rotación comienza a izquierda, con
el operador <<, esto se especifica con la variable booleana rotateReg que comienza en True.
Cuando se detecta que se oprimió el pulsador, con la función BUTTON_Activated(), se cambia el
valor de esta variable booleana, para que la rotación sea a derecha.

Funciones Auxiliares:
//Funciones Auxiliares
void LED_LoadRegister(unsigned char led_register)
{
D2_LAT = led_register & 1;
D3_LAT = (led_register & 2) >> 1;
D4_LAT = (led_register & 4) >> 2;
D5_LAT = (led_register & 8) >> 3;
}

Como función auxiliar en esta práctica se agrega LED_LoadRegister() el cual recibe como
parámetro una variable char sin signo a la cual se mapean los cuatro bits menos significativos a los
LEDs de la placa Xpress.

También podría gustarte