Interview

10 PIC Microcontroller Interview Questions and Answers

Prepare for your next technical interview with this guide on PIC microcontrollers, featuring common questions and detailed answers.

PIC microcontrollers are a popular choice in embedded systems due to their versatility, low cost, and ease of programming. These microcontrollers are used in a wide range of applications, from consumer electronics to industrial automation, making them a valuable skill set for engineers and developers. With a robust architecture and extensive support from development tools, PIC microcontrollers offer a reliable platform for creating efficient and innovative solutions.

This article provides a curated selection of interview questions designed to test your knowledge and problem-solving abilities with PIC microcontrollers. By working through these questions, you will gain a deeper understanding of key concepts and be better prepared to demonstrate your expertise in technical interviews.

PIC Microcontroller Interview Questions and Answers

1. Describe the basic architecture of a PIC microcontroller.

The basic architecture of a PIC microcontroller includes several components:

  • Central Processing Unit (CPU): Executes instructions and controls other components.
  • Memory: Includes Program Memory (Flash) for code storage and Data Memory (RAM) for temporary data. Some models have EEPROM for non-volatile storage.
  • I/O Ports: Allow interaction with external devices, configurable as input or output.
  • Timers/Counters: Used for time-based operations like generating delays or counting events.
  • Analog-to-Digital Converter (ADC): Converts analog signals to digital values for processing.
  • Serial Communication Modules: Enable communication with other devices via UART, SPI, and I2C.
  • Interrupts: Allow immediate response to events, interrupting current execution flow.

2. Provide a code snippet to configure a GPIO pin as an output and toggle its state every second.

To configure a GPIO pin as an output and toggle its state every second on a PIC microcontroller, use the following code snippet with MPLAB X IDE and XC8 compiler:

#include <xc.h>

// Configuration bits
#pragma config FOSC = INTRC_NOCLKOUT
#pragma config WDTE = OFF
#pragma config PWRTE = OFF
#pragma config MCLRE = ON
#pragma config CP = OFF
#pragma config CPD = OFF
#pragma config BOREN = ON
#pragma config IESO = OFF
#pragma config FCMEN = OFF
#pragma config LVP = OFF

#define _XTAL_FREQ 4000000

void main(void) {
    TRISBbits.TRISB0 = 0; // Set RB0 as output

    while (1) {
        LATBbits.LATB0 = ~LATBbits.LATB0; // Toggle RB0
        __delay_ms(1000); // Delay for 1 second
    }
}

3. Write a code example to initialize a timer to generate an interrupt every 1 millisecond.

#include <xc.h>

// Configuration bits
#pragma config FOSC = INTOSCIO
#pragma config WDTE = OFF
#pragma config PWRTE = OFF
#pragma config MCLRE = ON
#pragma config CP = OFF
#pragma config CPD = OFF
#pragma config BOREN = ON
#pragma config IESO = OFF
#pragma config FCMEN = OFF
#pragma config LVP = OFF

void __interrupt() ISR() {
    if (TMR1IF) {
        TMR1IF = 0;  // Clear the interrupt flag
        TMR1 = 65536 - 1000;  // Reload the timer for 1ms
    }
}

void main() {
    T1CON = 0x31;  // Timer1 on, prescaler 1:8
    TMR1 = 65536 - 1000;  // Load the timer for 1ms
    TMR1IE = 1;  // Enable Timer1 interrupt
    PEIE = 1;  // Enable peripheral interrupts
    GIE = 1;  // Enable global interrupts

    while (1) {
        // Main loop
    }
}

4. Write a code example to generate a PWM signal with a 50% duty cycle on a specific pin.

#include <xc.h>

// Configuration bits
#pragma config FOSC = INTRC_NOCLKOUT
#pragma config WDTE = OFF
#pragma config PWRTE = OFF
#pragma config MCLRE = ON
#pragma config CP = OFF
#pragma config CPD = OFF
#pragma config BOREN = ON
#pragma config IESO = OFF
#pragma config FCMEN = OFF
#pragma config LVP = OFF

void main(void) {
    PR2 = 0xFF; // Set the PWM period

    CCPR1L = 0x80; // 50% duty cycle
    CCP1CONbits.DC1B = 0;

    CCP1CONbits.CCP1M = 0b1100; // Configure CCP1 for PWM mode

    T2CONbits.T2CKPS = 0b01; // Prescaler is 4
    T2CONbits.TMR2ON = 1;    // Enable Timer2

    TRISCbits.TRISC2 = 0; // Set PWM pin as output

    while (1) {
        // Main loop
    }
}

5. Provide a code snippet to send and receive data using UART.

To send and receive data using UART on a PIC microcontroller, initialize the UART module, configure the baud rate, and implement functions to send and receive data.

Example:

#include <xc.h>

// Configuration bits
#pragma config FOSC = INTRC_NOCLKOUT
#pragma config WDTE = OFF
#pragma config PWRTE = ON
#pragma config MCLRE = ON
#pragma config CP = OFF
#pragma config CPD = OFF
#pragma config BOREN = ON
#pragma config IESO = OFF
#pragma config FCMEN = OFF
#pragma config LVP = OFF

#define _XTAL_FREQ 4000000

void UART_Init(long baud_rate) {
    unsigned int x;
    x = (_XTAL_FREQ - baud_rate * 64) / (baud_rate * 64);
    if (x > 255) {
        x = (_XTAL_FREQ - baud_rate * 16) / (baud_rate * 16);
        BRGH = 1;
    }
    if (x < 256) {
        SPBRG = x;
    }
    SYNC = 0;
    SPEN = 1;
    TRISC7 = 1;
    TRISC6 = 0;
    CREN = 1;
    TXEN = 1;
}

void UART_Write(char data) {
    while (!TRMT);
    TXREG = data;
}

char UART_Read() {
    while (!RCIF);
    return RCREG;
}

void main() {
    UART_Init(9600);
    while (1) {
        char received = UART_Read();
        UART_Write(received);
    }
}

6. Write a code example to communicate with an I2C temperature sensor and read its value.

#include <xc.h>
#include <stdint.h>

#define _XTAL_FREQ 4000000
#define I2C_WRITE 0
#define I2C_READ 1

void I2C_Init(void) {
    SSPCON = 0b00101000;
    SSPCON2 = 0;
    SSPADD = (_XTAL_FREQ / (4 * 100000)) - 1;
    SSPSTAT = 0;
}

void I2C_Start(void) {
    SEN = 1;
    while (SEN);
}

void I2C_Stop(void) {
    PEN = 1;
    while (PEN);
}

void I2C_Write(uint8_t data) {
    SSPBUF = data;
    while (!SSPIF);
    SSPIF = 0;
}

uint8_t I2C_Read(uint8_t ack) {
    RCEN = 1;
    while (!SSPIF);
    SSPIF = 0;
    uint8_t data = SSPBUF;
    ACKDT = ack;
    ACKEN = 1;
    while (ACKEN);
    return data;
}

uint16_t Read_Temperature(void) {
    uint16_t temperature;
    I2C_Start();
    I2C_Write(0x90 | I2C_WRITE);
    I2C_Write(0x00);
    I2C_Start();
    I2C_Write(0x90 | I2C_READ);
    temperature = I2C_Read(0) << 8;
    temperature |= I2C_Read(1);
    I2C_Stop();
    return temperature;
}

void main(void) {
    I2C_Init();
    uint16_t temperature = Read_Temperature();
    while (1) {
        // Use the temperature value as needed
    }
}

7. Provide a code snippet to communicate with an SPI-based EEPROM and read/write data.

#include <xc.h>

// Configuration bits
#pragma config FOSC = HS
#pragma config WDTE = OFF
#pragma config PWRTE = OFF
#pragma config BOREN = ON
#pragma config LVP = OFF
#pragma config CPD = OFF
#pragma config WRT = OFF
#pragma config CP = OFF

#define CS LATBbits.LATB0

void SPI_Init() {
    TRISC5 = 0;
    TRISC4 = 1;
    TRISC3 = 0;
    SSPSTAT = 0x40;
    SSPCON = 0x20;
}

void SPI_Write(unsigned char data) {
    SSPBUF = data;
    while(!SSPSTATbits.BF);
}

unsigned char SPI_Read() {
    SSPBUF = 0xFF;
    while(!SSPSTATbits.BF);
    return SSPBUF;
}

void EEPROM_Write(unsigned char address, unsigned char data) {
    CS = 0;
    SPI_Write(0x06);
    CS = 1;
    __delay_ms(1);
    CS = 0;
    SPI_Write(0x02);
    SPI_Write(address);
    SPI_Write(data);
    CS = 1;
    __delay_ms(5);
}

unsigned char EEPROM_Read(unsigned char address) {
    unsigned char data;
    CS = 0;
    SPI_Write(0x03);
    SPI_Write(address);
    data = SPI_Read();
    CS = 1;
    return data;
}

void main() {
    SPI_Init();
    EEPROM_Write(0x10, 0x55);
    unsigned char data = EEPROM_Read(0x10);
    while(1);
}

8. Explain how to configure and use different power management modes.

PIC microcontrollers offer several power management modes to optimize power consumption:

  • Run Mode: Full-speed operation, highest power consumption.
  • Idle Mode: CPU halted, peripherals active, reduced power usage.
  • Sleep Mode: CPU and peripherals halted, minimal power usage, wake via watchdog timer or interrupts.
  • Doze Mode: Reduced CPU clock, peripherals at full speed, balances power savings and performance.

To configure these modes, set specific control registers. For Sleep Mode, use the SLEEP instruction; for Idle Mode, adjust the OSCCON register.

9. Provide a code example to integrate FreeRTOS into a project and create a simple task.

To integrate FreeRTOS into a PIC microcontroller project and create a simple task:

  • Include FreeRTOS header files.
  • Define the task function.
  • Create the task in the main function.
  • Start the scheduler.

Example:

#include <FreeRTOS.h>
#include <task.h>

void vTaskFunction(void *pvParameters) {
    for (;;) {
        // Task code
    }
}

int main(void) {
    // System initialization

    xTaskCreate(vTaskFunction, "Task 1", 100, NULL, 1, NULL);

    vTaskStartScheduler();

    for (;;);
    return 0;
}

10. Provide a code snippet to initialize and use a Real-Time Clock (RTC).

#include <xc.h>

// Configuration bits
#pragma config FOSC = INTRC_NOCLKOUT
#pragma config WDTE = OFF
#pragma config PWRTE = OFF
#pragma config MCLRE = ON
#pragma config CP = OFF
#pragma config CPD = OFF
#pragma config BOREN = ON
#pragma config IESO = OFF
#pragma config FCMEN = OFF
#pragma config LVP = OFF

void RTC_Init() {
    T1CON = 0x31; // Timer1 with external 32.768 kHz crystal
    TMR1H = 0x80; // Preload Timer1 for 1 second overflow
    TMR1L = 0x00;
    TMR1IF = 0;
    TMR1IE = 1;
    PEIE = 1;
    GIE = 1;
}

void __interrupt() ISR() {
    if (TMR1IF) {
        TMR1IF = 0;
        TMR1H = 0x80;
        TMR1L = 0x00;
        // Increment RTC seconds, minutes, hours, etc.
    }
}

void main() {
    RTC_Init();
    while (1) {
        // Main loop
    }
}
Previous

10 DNS server Interview Questions and Answers

Back to Interview
Next

10 ZigBee Interview Questions and Answers