Analog to digital converters are electronic devices widely used in today’s digital world as most of the real-time signals are analog ones while the day-to-day devices of the contemporary world are mostly digital devices which can process only digital signals. This chapter describes the functioning of an analog to digital converter using PIC18F4550.
Analog signals are continuous time-varying signals. Most of the real world signals around us are analog in nature. Analog to digital conversion becomes inevitable when these real-world signals need to be processed in a digital environment.
ADC is the primary means by which an analog signal is converted into digital data that can be processed easily using a digital computer. There exist many types of ADCs for different purposes like counter type, flash type, successive approximation type, etc. Selection depends upon the requirement. The most inexpensive ADC available in the electronic market is the successive approximation type.
The successive approximation ADC generates a series of digital codes each corresponding to a fixed analog level with an internal counter to compare with the analog signal under conversion. The generation is stopped when the analog level becomes larger than the analog signal. The digital code corresponding to the analog level is the desired digital representation of the analog signal.
The performance of the ADC is measured using the resolution and speed as parameters. Resolution is nothing but the number of levels or intervals which can be divided from a certain analog input range which is expressed in bits. The resolution of an n-bit ADC is 1/(2^n). For example, an ADC with 10-bit resolution as one in PIC 18F4550 can have 2^10 (1024) intervals for the range of analog input signal.
The ADC in PIC18F4550 is a successive approximation ADC with a resolution of 10 bits. The resolution indicates how much the reference voltage can be divided. For a 10 bit resolution ADC, it is possible to divide up to 1024 (2^10) voltages. So for a 5V reference voltage, the minimum voltage will be 5/1024 = 4.8mV. This means 4.8mV in the analog pin will be detected as 1 and 9.6mV will be 2 (10 in binary). It can’t detect the difference between 1mV and 3mV since both will be detected as 0. This is where the resolution comes into the picture. The more the resolution is, ADC will be better at detecting the small voltage changes.
PIC18F4550 has 13 channels which mean 13 analog input signals can be converted simultaneously using the module. 8 choosable clock inputs are available for conversion and the module can be configured in auto triggering mode.
Other terminology usually appears while using ADC is the reference voltage. It specifies the minimum and maximum voltage range of analog input. PIC18F4550 has two reference voltage inputs, Vref- and Vref+. Vref- is the minimum input voltage of analog input and Vref+ is the maximum voltage. That means if Vref- is applied to the pin for conversion, the digital value after conversion will be 0 and for the Vref+, this will be the maximum value (1023 for 10-bit resolution). The PIC18F4550 pins for Vref+ are RA3 and Vref- is RA2. In normal cases, we set Vref- as 0 and Vref+ as 5V. The digital value is calculated based on the following equation.
Digital value = [Analog value/ (Vref+ - Vref-)] * (2^resolution) For Vref+ = Vdd, Vref- = Vss and 10 bit resolution Digital vaue = [Analog value/ 5*1024] Examples: for 0V -> Digital value = 0 for 2.49V -> Digital value = 511 (0b0111111111 in binary) for 4.99V -> Digital value = 1023 (0b1111111111 in binary)
Another term useful while using ADC is acquisition time. It is the time required to fully charge the charge holding capacitor to the input channel voltage level. In layman’s terms, it is the time required to wait before starting conversion and after applying input in the analog port pin. It depends on the holding capacitor value, an input impedance of the analog source, Vdd, conversion error, temperature etc. Based on the commonly used values, it is calculated as 2.45 us. What this means that we should start the conversion only after applying input analog and passing 2.45 us.
A/D conversion clock is the analog to digital conversion time per bit and denoted as Tad. A/D conversion requires 11 Tad per 10-bit conversion. There are seven possible options for Tad.
Tad must be greater than minimum Tad specified and must be as short as possible. From PIC18F4550 datasheet, it is 0.7 µs (page 400, table 28-29). So for a 20MHz PIC18F4550,
Fosc = 20 MHz Tosc = 1/20 MHz = 50ns If we select 16 Tosc 16 Tosc = 16x 50ns = 0.8 us which is more than 0.7 us(minimum requirement)
The module is configured by writing to certain special function registers. There are three control registers for the ADC module and two result registers.
This register uses to select input channels and control conversion process
ADCON2 uses to select voltage reference and selection of port pins for analog inputs.
ADCON2, on the other hand, uses to select ADC data format, clock options and acquisition time
The result of conversion which is a 10-bit digital value is stored in the ADRESH and ADRESL registers in the prescribed format specified by the configuration of DFM bit.
From the above calculations and descriptions, we are going to implement an analog to digital conversion in pin AN0 for a maximum voltage of 5V and minimum voltage 0V. Below are the steps required to do the conversion.
/* PCFG3:PCFG0 (ADCON1 bit 3-0) = 1110 -> AN0 only will analog and other 12 channels will digital VCFG0=0,VCFG1=0 -> Vref+ = VDD and Vref- = VSS */ADCON1 = 0b00001110;
/* 16Tosc conversion clock, 6Tad acquisition time, ADC Result Right Justified */ADCON2 = 0b10011101;
ADCON0 = ADCON0 | 1; // ADCON0.ADON = 1
ADCON0.GO = 1
while (Go == 1);// wait till GODONE bit is zero
ADC_Value = ADC_Value << 8; ADC_Value = ADC_Value + ADRESL;
A varying signal of 0-5V is applied in the AN0 pin of PIC18F4550 and the analog value is converted to the corresponding digital value.
Here the analog voltage is generated and varied using a potentiometer.
This code is based on the above-described settings. For delay, we have used default delay routine of XC8 compiler. For more details, refer How can I create a delay in my XC8 program
The result reads into a variable which should be 16-bit size.
#include<xc.h> #define _XTAL_FREQ = 20000000; #include "uart.h" int ADC_Value,k; char ADC_array[5]; int main() { UART_Init(); /* CHS3:CHS0 (ADCON0 bit 5-2) = 0000 -> Channel 0 */ ADCON0 = ADCON0 | 1; /* PCFG3:PCFG0 (ADCON1 bit 3-0) = 1110 -> AN0 only will analog and other 12 channels will digital VCFG0=0,VCFG1=0 -> Vref+ = VDD and Vref- = VSS */ ADCON1 = 0x0E; /* 16Tosc conversion clock, 6Tad acquisition time, ADC Result Right Justified */ ADCON2 = 0x9D; delay_ms(2); while(1) { GO = 1; // ADCON0.GODONE = 1 while(GO == 1); // wait till GODONE bit is zero ADC_Value = ADC_Value << 8; ADC_Value = ADC_Value + ADRESL; //Read converted result UART_string("ADC Value:"); for(k=0;k<=3;k++) { ADC_array[k] = ADC_Value % 10 + '0'; ADC_Value = ADC_Value / 10; } for(k=3;k>=0;k--) { UART_Char(ADC_array[k]); delay_ms(150); } UART_Char(0x0D); } }