USO DE LAS MÁSCARAS EN LA PROGRAMACIÓN DE MICROCONTROLADORES PIC

0
Autor: Mauro Montoya Arenas

Uso de máscaras en la programación de microcontroladores PIC

📝 Marcas de tiempo:

Esta teoría de la que te hablaré es válida para programar cualquier microcontrolador PIC. Bien, ¿Qué son las mascaras y para que se utilizan?. Las mascarás van a  ser líneas de código que se utilizan para alterar un bit que pertenece a un registro. 
Por ejemplo: Tengo un registro de 8 bits, y quiero trabajar solo con el bit b5. Los demás bits no me van a ser de utilidad. Para poder trabajar solo con ese bit, sin alterar los otros bits del registro, se utilizan las máscaras.
Ahora, tengo 2 opciones: yo puedo escribir 0 o 1 en un bit. O también puedo leer la información de un bit. 

¿Conoces la diferencia entre Hardware, Software y Firmware?. Quizás te puede interesar: https://educatronicosisc.blogspot.com/2022/03/hardware-software-y-firmware.html


Escritura de un bit

Mascara clear

Para nuestro caso, si yo quisiera escribir un 0 en un bit, tendría que usar una máscara clear. La n representa el número del bit al que le mandaré la información. Para nuestro ejemplo, n=b5. 
La programación sería la siguiente: colocamos el nombre del registro, seguido por el símbolo del ampersand (que en programación significa multiplicación). Después colocamos un "=". El símbolo de la virgulilla básicamente significa que le estamos mandando el negado de 1 al bit b5. ¿Y cual es el negado del 1?, el cero. Es decir que, estamos escribiendo un 0 al bit b5.

Internamente, ocurre lo siguiente:
Estamos multiplicando un 0 en el bit 5 del registro. De esa manera, escribimos en el bit5, y los demás bits del registro permanecen con su mismo valor.

Si ahora por ejemplo, quiero escribir un 0 en el bit 5 y en el bit 2. En la programación tengo que añadir el símbolo de la pleca y entre paréntesis colocar un 1<<b2.

Internamente, estamos multiplicando un 0 en el bit 5 y en el bit 2. De esa manera, escribimos un 0 en esos 2 bits sin modificar el resto del registro.

Mascara set

Ahora, si en lugar de escribir un 0 quiero escribir un 1, tenemos que usar una mascara set. Por ejemplo: escribiremos un 1 en el bit b5. Para ello, tengo que escribir lo siguiente: el nombre del registro, el símbolo de la pleca (que en programación significa suma), igual, entre paréntesis, 1 << b5. 

Internamente ocurre lo siguiente, le estamos sumando un 1 al registro en el bit b5. De esa manera, escribimos un 1 en el bit 5, sin modificar los otros bits del registro.

Si queremos ahora, escribir un 1 en el bit 5 y el bit 2, tenemos que colocar lo siguiente:

Internamente, estamos sumando un 1 al bit 5 y al bit 2 del registro. 

Mascara toggle

Ahora, si yo quiero conmutar el valor de un bit, debo seleccionar una mascara toggle. Para ello debo escribir lo siguiente: el nombre del registro, símbolo del acento circunflejo (que en programación significa conmutación), después coloco un igual, y entre paréntesis un 1<<bit5, que es el bit del cual voy a conmutar su valor.


Conmutar un valor significa lo siguiente, vamos a suponer que el bit 5 del registro tenía un valor de 0. Después de someter el registro a la mascara toggle de nuestro ejemplo. El valor del bit 5 cambia de 0 a 1. Y si ahora vuelvo a aplicar la misma mascara toggle, el valor del bit 5 cambia de 1 a 0. A eso nos referimos cuando decimos que conmutamos el valor del bit 5.

Si ahora quiero conmutar los valores del bit 5 y bit 2, escribimos lo siguiente:

Para reforzar esta teoría, veamos los siguientes ejemplos:
En el primer ejemplo quiero declarar el bit RA6 del puerto A, como salida. En los microcontroladores PIC18F4550, en total tengo 5 puertos. El registro que se usa para declarar un bit de un puerto como entrada o salida es el registro TRISx. Dependiendo de cual sea el puerto, debemos colocar TRISA, TRISB, TRISC, TRISD o TRISE.
Para configurar un bit como salida, el bit debe ser igual a 0. Y para configurar el bit como entrada, el bit debe ser igual a 1. 
Entonces, siguiendo con nuestro ejemplo, el bit RA6 debe ser igual a 0. Por lo que debemos aplicar un mascara clear. Entonces colocamos el registro TRISA, símbolo de ampersand, igual, símbolo de la virgulilla, entre paréntesis, 1 << (y el numero del bit), en nuestro caso, el 6.


Para nuestro siguiente ejemplo: Se requiere que mandemos un 1 lógico por el bit 4 del puerto D. Si queremos enviar datos por un bit, previamente, el bit tuvo que haber sido configurado como un bit de salida. 
Ahora, si queremos mandar información a un bit. Tenemos que usar el registro LATx, dependiendo del puerto, este registro se puede llamar LATA, LATB, LATC, LATD o LATE.  
En nuestro caso, al bit 4 del puerto D mandamos un 1 (por lo que debemos usar una mascara set). Entonces colocamos LATD, símbolo de la pleca, igual, entre paréntesis, 1<< (el numero del bit), en nuestro caso, 4.

Lectura de un bit

Bien, ya hemos hablado del caso en el que se usan las máscaras para la escritura de un bit. Ahora, vamos a hablar del caso en el que se usan las mascaras para leer un bit.
Si “n” es la posición de un bit (0,1,2…6,7) que vamos a leer. La mascara de lectura será la siguiente:
“MASCARA LEER”: (1 << n);

Si estamos evaluando si el bit "n" es 1. Tenemos que colocar la siguiente expresión: test, igual a la variable (es decir, el registro que usaremos para la lectura), símbolo de ampersand y la mascara del bit que leeré.
test = variable & mascara_leer

Si ahora estamos evaluando si el bit "n" es 0. Tenemos que colocar la siguiente expresión: test, igual, símbolo de exclamación (que en programación significa negado), entre paréntesis la variable, símbolo de ampersand, y la mascara.
test =! (variable & mascara_leer)

Vamos a hacer un ejemplo para que quede mas claro:
Supongamos que el bit2 del puerto E esta en 1. Nosotros realizaremos la lectura de ese puerto a través de una máscara. El registro que se usa para leer un puerto, es el registro PORTx. Dependiendo del puerto, ese registro se puede llamar PORTA, PORTB, PORTC, PORTD o PORTE.

Entonces, para el primer caso, voy a determinar si el bit 2 del puerto E es igual a 1. Entonces colocaré: test, igual, entre paréntesis el 1<< el numero del bit, en nuestro caso 2. Lo que hago con este comando, es multiplicar por 1 el bit 2. Si el resultado es 1, como este caso, la operación será verdadera.


Si en caso quisiéramos saber si el bit se encuentra en 0. Tendríamos que ejecutar la siguiente operación:

Si desarrollamos esto, nos daremos cuenta que nos sale 0 de resultado. 0 significa falso. Por lo tanto, concluimos que el bit no se encuentra en 0.

¿Sabes que son los sistemas embebidos?. Quizás te gustaría revisar: https://educatronicosisc.blogspot.com/2022/03/que-son-los-sistemas-embebidos.html

Programación del proyecto en MPLAB

Bien, ya que hemos aprendido sobre las máscaras, ahora si, vamos a explicar la programación el código del proyecto. 
En este proyecto, vamos a controlar la iluminación de un led a través de un interruptor. Cuando el interruptor este abierto, el led esta apagado. Cuando el interruptor esta cerrado, el led esta encendido.
El interruptor esta conectado en el bit RA0 del puerto A. Como podemos ver, el interruptor esta en una configuración de resistencia pull down. De tal forma, que el puerto RA0 lee un 0 lógico cuando el interruptor esta abierto, y lee un 1 lógico cuando el interruptor esta cerrado. 


Bien, en la programación, primero configuramos la librería config.h. Esta librería contiene las condiciones iniciales para hacer trabajar el PIC. La creación de esta librería ya lo he explicado en un anterior proyecto. Después de esto, definimos la frecuencia del CPU igual a 8MHz. Ahora, vamos a determinar si el bit 0 del puerto A esta en 1 lógico. Recordemos que en el pin 0 del puerto A esta conectado nuestro interruptor.
Si el interruptor esta abierto, la condición será falsa y la variable encendido será falso. Pero si el interruptor esta cerrado, la condición será verdadera y la variable encendido será verdadero. 

Ahora dentro del int main. Primero debemos colocar las condiciones de nuestro programa. Por eso, vamos a colocar ADCON1=0x0F, con eso nos aseguramos que todos los pines trabajen de forma digital.
El registro ADCON1 es el siguiente:

Los bits 6 y 7 no son usados, en el datasheet nos recomiendan que pongamos 0. El bit 5 y bit 4 también lo colocamos a 0. Los bits que van desde la posición 0 hasta la posición 3 van a servir para configurar cuantos pines serán analógicos y cuantos digitales. La mayoría de los pines del microcontrolador tienen un nombre ANx. El pin RA0 por ejemplo, también se llama AN0. El pin RB0 se llama AN12. Muchos pines tienen sus propios nombres ANx. 

Si escogemos, por ejemplo 0000, todos los pines AN serán analógicos. Si escogemos 1000, 6 pines (desde el AN7 hasta el AN12 serán digitales), y desde el AN0 hasta el AN6 serán analógicos. Ahora si escogemos 1111, todos los pines AN serán digitales. Como en nuestro caso no estamos usando pines analógicos, vamos a elegir esa opción. Es por eso que el registro ADCON1 es igual a 0x0F.

Bien continuando con el código, ahora configuramos el oscilador interno a 8 MHZ, el registro OSCCON ya lo explique en un video pasado. 
Como te había dicho, el interruptor estará conectado en el bit 0 puerto A. El interruptor es un periférico de entrada. Los periféricos de entrada se configuran en el registro TRISx como 1. Es por ello que usamos una mascará set para configurar como 1 el bit 0 del puerto A.

En el bit 7 del puerto C se encontrara el led, que es un periférico de salida. Los periféricos de salida se configuran como un 0. Por eso coloco una mascara clear para configurar como 0 el bit 7.
Inicialmente el led estará apagado, es decir, en 0 lógico.  Para mandarle un 0 al bit 7 del puerto C utilizo el registro LATC y una mascara clear.

Dentro de las llaves del bucle while. Utilizo un condicional if, para señalar que si la variable encendido es verdadero (es decir, si el interruptor esta cerrado), el led va a estar encendido. De lo contrario, si la variable es falsa (es decir, el interruptor esta abierto), entonces el led estará apagado.

/*Cabecera del programa*/
#include "config.h" //Cabecera de la configuracion de las cond. inic.
#define _XTAL_FREQ 8000000 //Definicion del oscilador del CPU
#define encendido (PORTA & (1<<0)) //Mascara para detectar RA0 en 1

/*Funcion principal*/
int main(void) {
    
    ADCON1=0x0f; //Tods los pines como digitales
    OSCCON =0x72; //Configura el oscilador interno a 8MHz
    TRISA |= (1<<0); //Configura el RA0 como entrada (interuptor)
    TRISC &=~(1<<7); //RC7 como salida (led)
    LATC &=~ (1<<0); //Iniciamos el LED apagado
     
    while(1){
        
        if(encendido){
            LATC |= (1<<7); //Led on
        }
        else{
            LATC &=~(1<<7); //LED off
        }
    }

    return 0;
}

Simulación del proyecto

Bien, para pasar a la simulación copiamos la ruta del archivo .hex del proyecto. Ahora nos dirigimos a proteus y copiamos. Le damos a correr y observamos, cuando yo cierro el interruptor, el led se prende. Y cuando lo abro el led se apaga.

Visita nuestro canal de YouTube para mas contenido: https://www.youtube.com/channel/UC93Nt6sA-7r_S7EtGO44GeA

 
🔥 En la descripción del video encontraras el código del proyecto:


Entradas que pueden interesarte

Sin comentarios

Artículos populares

Procesamiento digital de señales (ejemplos usando matlab)

Procesamiento digital de señales (ejemplos usando matlab)

Autor: Mauro Montoya Arenas   PROCESAMIENTO DIGITAL DE SEÑA…

¿Como configurar un microcontrolador PIC? - Primer Hola Mundo

¿Como configurar un microcontrolador PIC? - Primer Hola Mundo

Configuración de un PIC - Hola Mundo En esta oportunidad ap…

PROYECTO: SISTEMA DE TRÁFICO VEHICULAR UTILIZANDO EL PIC 18F4550

PROYECTO: SISTEMA DE TRÁFICO VEHICULAR UTILIZANDO EL PIC 18F4550

Autor: Alexis                                       Contac…

¿Qué son los Sistemas embebidos?

¿Qué son los Sistemas embebidos?

Sistemas embebidos  🔴 En este articulo encontrarás: - Func…