Los microcontroladores son los cerebros invisibles detrás de innumerables dispositivos electrónicos que utilizamos diariamente, desde hornos de microondas y controles remotos a sistemas automotrices y dispositivos médicos. Entre las muchas familias microcontroladores disponibles, los microcontroladores PIC (Controlador de Interfaz Periférico) desarrollados por Microchip Technology, destacan por su simplicidad, bajo costo y amplia gama de modelos adecuados para los códigos de inicio y los profesionales.

¿Qué es un microcontrolador de PIC?

Un microcontrolador PIC es un equipo de un solo chip que integra una unidad central de procesamiento (CPU), memoria (RAM, ROM/Flash), y periféricos de entrada/salida programables en un solo circuito integrado. Los PIC son dispositivos de arquitectura de Harvard que significan que el programa y los recuerdos de datos son separados, lo que permite el acceso simultáneo y mejora la velocidad de ejecución.

Comienzo con la programación de PIC en C

La programación de microcontroladores de PIC en C requiere un entorno de desarrollo, un compilador, un programador/debugger y algún hardware básico. El lenguaje C es preferido porque abstrae la complejidad del nivel de montaje y permite la manipulación directa del registro y la generación de código eficiente.

1. Instalar MPLAB X IDE

MPLAB X IDE es el entorno de desarrollo integrado oficial de Microchip. Se basa en la plataforma NetBeans y proporciona la gestión de proyectos, la edición de códigos, la depuración y las herramientas de simulación. Descargar MPLAB X IDE del sitio web de Microchip. El IDE es gratuito y disponible para Windows, macOS y Linux.

2. Instalar el Compilador XC8

El compilador XC8 traduce código C en código de máquina para microcontroladores PIC. Reemplaza al compilador HI-TECH C más antiguo. Descargar XC8 e instalarlo. Microchip ofrece una versión gratuita con optimización moderada (para el aprendizaje y la mayoría de los proyectos). Para la optimización completa, se requiere una licencia de pago.

3. Obtener un programador

Para transferir el código de su computadora al microcontrolador PIC, necesita un programador de hardware. Las opciones más comunes son el PICkit 4, PICkit 5, o MPLAB Snap. Estos dispositivos se conectan a través de USB y tienen un pequeño encabezado que se conecta a los pines de programación del PIC (a menudo ICSP – Programación de serie en el circuito).

4. Configurar un circuito de panel de pan

Para el primer proyecto clásico, parpadeando un LED, necesita un microcontrolador PIC, una placa de pan, un LED, un resistor de límite actual (normalmente 220Ω a 470Ω), una fuente de alimentación de 5V (o una fuente de alimentación regulada mediante un regulador de tensión), y un cristal de 20 MHz o oscilador interno (la mayoría de los PIC modernos tienen osciladores internos).

Escribir su primer programa de PIC en C

El programa clásico " blink marginal " es el equivalente integrado del "Hello World. limitada " Muestra el control, el tiempo y los bucles infinitos de I/O. A continuación se presenta un ejemplo completo para un PIC16F88 utilizando el oscilador interno a 8 MHz.

Ejemplo completo del código de enlace

// PIC16F88 Blink LED Example using Internal Oscillator
#define _XTAL_FREQ 8000000 // Define oscillator frequency for delay macros

#include <xc.h> // XC8 header file

// Configuration bits: internal oscillator, no watchdog, power-up timer enabled
#pragma config FOSC = INTOSCIO // Internal oscillator with I/O on RA6
#pragma config WDTE = OFF // Watchdog Timer disabled
#pragma config PWRTE = ON // Power-up Timer enabled
#pragma config MCLRE = OFF // RA5/MCLR as digital I/O
#pragma config BOREN = OFF // Brown-out reset disabled
#pragma config LVP = OFF // Low-voltage programming disabled
#pragma config CPD = OFF // Data EEPROM code protection off
#pragma config CP = OFF // Flash program memory code protection off

void main(void) {
 TRISB = 0x00; // Set all Port B pins as outputs
 PORTB = 0x00; // Clear Port B outputs
 while(1) {
 RB0 = 1; // Turn LED on (connect LED to RB0)
 __delay_ms(500); // Delay 500 ms
 RB0 = 0; // Turn LED off
 __delay_ms(500); // Delay 500 ms
 }
}

El macro es proporcionado por XC8 y requiere definir a la frecuencia osciladora real. Las líneas fijan bits de configuración de hardware — esenciales para una correcta operación. En este ejemplo, el oscilador interno se utiliza, por lo que no se necesita cristal externo. Después de compilar y programación, el LED se abrirá a intervalos de 0,5 segundos.

Comprender conceptos clave en la programación de PIC

Para ir más allá de parpadear un LED, debe comprender varios conceptos fundamentales que definen la programación integrada de C para los PIC. Estos conceptos son los bloques de construcción para proyectos más complejos.

Registros y Manipulación de Bit

[LT] [FLT] [El operador de la PIC se controla mediante la fijación o la limpieza de bits en registros especiales de funciones (SFRs). Por ejemplo, el registro configura la dirección de los pines de Port B. La configuración de un bits a 1 hace que el pin sea una entrada; la limpieza lo hace una salida.

TRISBbits.TRISB0 = 0; // Alternative using bitfield structure
PORTBbits.RB0 = 1; // Set pin RB0 high

Siempre consulte la hoja de datos del microcontrolador para encontrar los nombres de registro correctos y posiciones de bits.

Puertos de entrada/salida

Los microcontroladores PIC tienen varios puertos I/O (PORTA, PORTB, PORTC, etc.) Cada puerto tiene registros asociados: para dirección, para lectura de niveles de entrada, y para escribir niveles de salida (el registro evita problemas de lectura-modificación-escritura].

Interrupciones

Las interrupciones permiten al microcontrolador responder a eventos (como una pulsación de botones, el flujo de tiempo o la recepción de datos en serie) sin encuestas continuas. Cuando se produce una interrupción, la CPU detiene el programa principal, ejecuta una rutina de servicio interrumpida (ISR), y luego se reanudará. En XC8, la ISR se define utilizando el calificador de función .

Ejemplo: Interrupción externa en RB0

void __interrupt() ISR(void) {
 if(INTF) { // Check if external interrupt flag is set
 LATB ^= 0x01; // Toggle RB0 (LED)
 INTF = 0; // Clear interrupt flag
 }
}

void main(void) {
 TRISB = 0x00; // All outputs
 PORTB = 0x00;
 OPTION_REG &= 0xBF; // Clear INTEDG to interrupt on falling edge
 INTCON |= 0x90; // Enable GIE and INTE
 while(1); // Infinite loop, wait for interrupt
}

Las interrupciones son cruciales para sistemas eficientes en tiempo real, pero requieren un manejo cuidadoso de variables compartidas (utilizar interrumpe volátil y posiblemente deshabilitado durante secciones críticas).

Timers

Las máquinas son contadores de hardware que pueden generar retrasos, medir la frecuencia de señal de entrada, o producir ondas PWM. La mayoría de los PIC tienen varios módulos de temporizador (Timer0, Timer1, Timer2, etc.) con diferentes capacidades. Timer0 es un temporizador de 8 bits con un prescaler; Timer1 es de 16 bits y puede operar de forma asincrónica; Timer2 es de 8 bits y a menudo se puede interrumpir un intervalo preciso para PW

// Example: Configure Timer0 to interrupt every 10 ms at 8 MHz internal clock
// Prescaler = 256; TMR0 load value = 0xF0 (240 decimal)
// Timer0 tick = 4 / 8MHz = 0.5 µs * 256 = 128 µs per increment
// 240 * 128 µs = 30.72 ms (adjust for desired period)
TMR0 = 0xF0;
OPTION_REG = 0x07; // Prescaler 1:256 assigned to Timer0, internal clock
INTCONbits.TMR0IE = 1; // Enable Timer0 interrupt
INTCONbits.GIE = 1;

Comprender los temporizadores es esencial para generar bases de tiempo exactas, señales PWM para el control de motores o capturar anchos de pulso de entrada.

Conversor analógico a digital (ADC)

Muchos PIC incluyen un módulo ADC que convierte una tensión analógica (0 a VDD) en un valor digital. El ADC utiliza un circuito de muestra y posición sucesiva (SAR) arquitectura. Para leer un sensor analógico, configurar el canal, establecer el tiempo de adquisición, iniciar la conversión, esperar la terminación y leer los registros de resultados (ADRESH, ADRESL).

ADCON0 = 0x01; // Select channel AN0, turn ADC on
__delay_us(10); // Wait for acquisition time
GO_nDONE = 1; // Start conversion
while(GO_nDONE); // Wait for conversion to finish
int analogValue = ((ADRESH << 8) + ADRESL); // 10-bit result

Las lecturas de ADC se pueden utilizar para la detección de temperatura, intensidad de luz, potenciómetros y muchas otras entradas analógicas.

Protocolos de comunicación periférica

Los PICs soportan protocolos de serie comunes: UART (series asincrónico), SPI (sincrónico), e I2C (interfase de dos hilos).Estos permiten la comunicación con sensores, pantallas, otros microcontroladores y módulos.

  • UART: Utilizado para RS-232, consolas seriales, módulos GPS, módulos Bluetooth. Configurar la tasa de baud, permitir el envío/recibir, y utilizar los registros TXREG/RCREG.
  • SPI: Full-duplex, master/slave. Ideal para transferencia de datos de alta velocidad con tarjetas SD, pantallas y módulos RF. Utiliza los pines SDI, SDO, SCK y SS.
  • I2C: Autobús de dos hilos con dirección. Adecuado para conectar múltiples dispositivos lentos como sensores y EEPROMs. Usa pins SDA y SCL.

Cada protocolo requiere una inicialización cuidadosa de la velocidad del reloj, el formato de datos y la interrumpencia de la manipulación si se utiliza en modo no bloqueador.

Organización de la memoria y consideraciones de programación

Los microcontroladores de PIC tienen memoria de programa separada (Flash), memoria de datos (RAM), y a veces EEPROM. La memoria del programa almacena el firmware; memoria de datos contiene variables y registros; EEPROM persiste pequeñas cantidades de datos a través de ciclos de energía. Cuando se programa en C, puede utilizar clasificadores de const para colocar datos en la memoria del programa (utilizando ] atributo o ]

Usando datos EEPROM

Muchos PIC incluyen el EEPROM interno con rutinas proporcionadas por el compilador. Ejemplo:

#include <xc.h>
void write_eeprom(unsigned char addr, unsigned char data) {
 while(WR); // Wait for previous write to finish
 EEADR = addr;
 EEDATA = data;
 EECON1bits.EEPGD = 0; // Point to EEPROM
 EECON1bits.WREN = 1; // Enable write
 INTCONbits.GIE = 0; // Disable interrupts
 EECON2 = 0x55; // Required sequence
 EECON2 = 0xAA;
 EECON1bits.WR = 1; // Start write
 INTCONbits.GIE = 1; // Re-enable interrupts
 EECON1bits.WREN = 0; // Disable write after completion
}

Consejos de depuración y optimización

Debugging embedded code can be challenging because you cannot use a traditional debugger over a UART? limitmdash;?that es donde un depurador de circuito como PICkit 4 brilla. MPLAB X IDE admite puntos de ruptura, relojes variables y un solo apalancamiento. Sin embargo, para simple depuración, puede cambiar un código LED o enviar caracteres sobre UART.

Consejos de optimización: Use variables locales cuando sea posible (si residen en GPRs). Optimización compiladora en XC8 (libre de ofertas de versión -O0; versión pagada -O1, -O2, -Os). Funciones pequeñas en línea. Use registros en lugar de RAM global. Para los bucles críticos de tiempo, considere usar un tiempo de interrupción en lugar de esperar demoras.

Recursos para el aprendizaje continuo

El mejor recurso de aprendizaje es la hoja de datos PIC16F88 y la hoja de datos de su dispositivo específico. Microchip también ofrece notas de aplicación, ejemplos de código y un foro activo Microchip. Libros como "Programación de los microcontroladores PIC con los proyectos XC8cro

Conclusión

Programación de microcontroladores PIC en C abre un mundo de creación de sistema integrado, desde simples parpadeadores LED a sofisticados redes de sensores y controladores de motor. Al configurar el compilador MPLAB X IDE y XC8, entender los fundamentos de registros, I/O, interrumpe, temporizadores y periféricos, y utilizar la gran cantidad de documentación y recursos comunitarios, puede progresar rápidamente desde los proyectos de experimentación inicial hasta el desarrollo integrado.