ADC Example Code for PIC16F877A (using MPLAB X and XC8)

Here’s an example of how to use the Analog-to-Digital Converter (ADC) module of the PIC16F877A microcontroller to read an analog signal and display the result via serial communication.

ADC Example Code for PIC16F877A (using MPLAB X and XC8):

// ADC Example for PIC16F877A

#define _XTAL_FREQ 16000000 // Define clock frequency (16 MHz)
#include <stdio.h> // For sprintf()
#include <xc.h>

// CONFIG
#pragma config FOSC = HS // Oscillator Selection bits (HS oscillator)
#pragma config WDTE = OFF // Watchdog Timer Enable bit (WDT disabled)
#pragma config PWRTE = OFF // Power-up Timer Enable bit (PWRT disabled)
#pragma config BOREN = ON // Brown-out Reset Enable bit (BOR enabled)
#pragma config LVP = OFF // Low-Voltage Programming Disable bit
#pragma config CPD = OFF // Data EEPROM Memory Code Protection bit (Code protection off)
#pragma config WRT = OFF // Flash Program Memory Write Enable bits (Write protection off)
#pragma config CP = OFF // Flash Program Memory Code Protection bit (Code protection off)

void ADC_Init() {
ADCON0 = 0x41; // Turn ON ADC and select Fosc/8 and Channel 0 (AN0)
ADCON1 = 0x80; // Set result format to right justified, and use VDD as reference voltage
}

unsigned int ADC_Read(unsigned char channel) {
if (channel > 7) return 0; // Invalid channel check

ADCON0 &= 0xC5; // Clear the current channel bits
ADCON0 |= channel << 3; // Set the required channel

__delay_ms(2); // Acquisition time delay
GO_nDONE = 1; // Start conversion
while (GO_nDONE); // Wait for conversion to complete

return ((ADRESH << 8) + ADRESL); // Return the 10-bit result
}

void UART_Init() {
// Set baud rate to 9600
SPBRG = 24; // 9600 Baud rate for 16 MHz clock

TXSTAbits.BRGH = 0; // Low baud rate
TXSTAbits.SYNC = 0; // Asynchronous mode
TXSTAbits.TXEN = 1; // Enable transmission

RCSTAbits.SPEN = 1; // Enable serial port
RCSTAbits.CREN = 1; // Enable reception
}

void UART_SendChar(char data) {
while (!TXIF); // Wait for the transmit buffer to be empty
TXREG = data; // Send the data
}

void UART_SendString(char* str) {
while (*str != '\0') {
UART_SendChar(*str);
str++;
}
}

void main() {
ADC_Init(); // Initialize ADC
UART_Init(); // Initialize UART for serial communication

unsigned int adc_value;
char buffer[20];

while (1) {
adc_value = ADC_Read(0); // Read ADC value from channel 0 (AN0)

// Convert ADC value to a string
sprintf(buffer, "ADC Value: %u\r\n", adc_value);

// Send ADC value to serial monitor
UART_SendString(buffer);

__delay_ms(500); // Delay for 500ms
}
}


Explanation:

1. ADC Initialization (ADC_Init)

  • ADCON0 = 0x41: Enables the ADC and selects Fosc/8 as the clock source and AN0 (analog channel 0) as the input.
  • ADCON1 = 0x80: Sets the result format to right-justified, meaning the 10-bit ADC result will be stored in two 8-bit registers (ADRESH and ADRESL), and the voltage reference is set to VDD (5V or whatever is supplied).

2. Reading from ADC (ADC_Read)

  • The ADC_Read function allows reading from any of the 8 analog input channels (AN0 to AN7). It starts a conversion and waits until the conversion is complete before returning the 10-bit ADC result.

3. UART Initialization (UART_Init)

  • Initializes the UART for serial communication at 9600 baud. This will allow the PIC to send data to a serial monitor (like in MPLAB X or any serial terminal program).

4. Sending Data over UART (UART_SendChar, UART_SendString)

  • These functions send individual characters and strings, respectively, over the serial port to the computer.

5. Main Loop

  • The main loop continuously reads the analog value from AN0 (Channel 0) and sends the result over UART every 500ms.

The sprintf function is used to format the ADC result into a string, which is then sent to the serial monitor using UART_SendString.

Circuit Setup:

ADC Example Code for PIC16F877A

  1. Analog Input (Potentiometer or Sensor):

    • Connect a potentiometer or analog sensor to AN0 (pin 2) of the PIC16F877A.
    • The other ends of the potentiometer should connect to VDD and Ground, respectively.
  2. UART Communication:

    • Connect the TX pin (pin 25, RC6) of the PIC to the RX pin of your serial-to-USB converter (for communication with a PC).
    • Ensure the ground of the PIC is connected to the ground of the serial interface.
  3. Power:

    • Use a 5V regulated power supply for the PIC16F877A and ensure the analog input range (from 0V to 5V) matches this power level.

Output

Once the circuit is set up, you can open a serial terminal on your PC (with a baud rate of 9600) to observe the real-time ADC values being printed. When you vary the analog input (e.g., by turning the potentiometer), the ADC value will change accordingly and will be sent to the serial terminal.

This is a basic example, but you can modify it to read multiple channels, process sensor data, or take action based on the ADC values (e.g., controlling motors, LEDs, or other devices).

Related Topics

PIC16f877A LED Blink Code

How to Control an LED Using a Switch with PIC16F877A

Push Button controlling LED - Programming Arduino using Matlab

Analog Read and Processing - Programming Arduino using Matlab


Post a Comment

Previous Post Next Post