Analog to digital converter (ADC)
In this
chapter we will discuss about microcontroller important peripheral Analog to digital converter. We will
cover the entire basic configuration of ADC peripheral.
You have
seen on my past posts, we used pic18f2520 microcontroller. This controller has 10bit
ADC modules inbuilt. A 10bit ADC means, it has a resolution of 10bits = 0 to
1023. Therefore, our best resolution is 1 part out of 1024. If we compare
voltage vs resolution with ref(+) 5v
and ref(-) 0v.
1024
= 0.0048828125v
For example:-
ref(+) = 5v
ref(-) = 0v
ADC input volt = 2.3v
Digital value = (1024 / (5-0)) *2.3 = 471
Basically
microcontroller converts voltage to digital numerical value. That numerical
value uses as the representation of the original input voltage while
programming and you can use this value for various purposes in your program.
Second
important point is ADC module can only be give conversion result when voltage
is in defined reference range. Otherwise it will give a garbage value or can be
damage. In many cases, the high and low voltage references are selected as the
microcontroller supply voltage and ground, at other times an external reference
or references are used.
ADC Block diagram
Pic18f2520 has ADC module registers:
PIC18f2520 ADC module has five registers. The ADCON0 register, shown in Register 19-1, controls the operation of
the A/D module. The ADCON1 register, shown in Register 19-2, configures the
functions of the port pins. The ADCON2 register, shown in Register 19-3,
configures the A/D clock source, programmed acquisition time and justification.
• A/D Result High Register (ADRESH)
• A/D Result Low Register (ADRESL)
• A/D Control Register 0 (ADCON0)
• A/D Control Register 1 (ADCON1)
• A/D Control Register 2 (ADCON2)
ADCON0: A/D CONTROL REGISTER 0
Bit6-7 :- Unimplemented: Read as ‘0’
Bit5-2 :- Analog Channel Selection bits
·
We
can select any one channel at a time ADC. These bits are important while you
using multi-channel otherwise it will only configure one time.
Now we are using single
ADC channel “AD0”.
ADCON0bits.CHS0 = 0; //AD0 channel selection.
ADCON0bits.CHS1 = 0;
ADCON0bits.CHS2 = 0;
ADCON0bits.CHS3 = 0;
Bit1 :- AD conversion status
·
This
bits will tell that our ADC module is in working or free. Basically this bit
use for monitor ADC module conversion. This bit should be clear (0) or can be
use waiting for interrupt then check result registers.
ADCON0bits.Go
Bit0 :- ADC on/off bit.
·
This
bit uses for on-off the ADC module processing.
ADCON0bits.ADON = 1; // AD conversion start
ADCON0bits.ADON = 0; // AD conversion stop
ADCON1: A/D CONTROL REGISTER 1
Bit7-6
:- Not in use
Bit5 :-
Voltage reference selection bit
·
We
have discussed already that we can use reference voltage with in a valid range.
There are two types of selection. First is the selection of according to
microcontroller power supply and other is use external voltage reference.
ADCON1bits.VCFG1 = 1; // Select external reference voltage range.
ADCON1bits.VCFG1 = 0; // Select controller Vss reference voltage
range.
Bit4 :-
Voltage reference selection bit
ADCON1bits.VCFG0 = 1; // Select external reference voltage range.
ADCON1bits.VCFG0 = 0; // Select controller Vdd reference voltage
range.
Bit3-0 :- Port pin selection as digital or analog
input type.
·
The value in the bit
3 to 0 determines if pins are configured as analog or digital. Consult the data
sheet of the device for a table that shows the allowable configuration options
for port pins.
We are using AD0 as analog input .
ADCON1bits.PCFG3 = 1;
ADCON1bits.PCFG2 = 1;
ADCON1bits.PCFG1 = 1;
ADCON1bits.PCFG0 = 0;
ADCON2: A/D CONTROL REGISTER 2
Bit7 :- AD conversion valve
format
·
This bit is
important to get right result. Often we make mistake in define this bit
correctly. The conversion value represent in two registers. The high and low
result registers are ADRESH and ADRESL.
·
The result can be
either left or right justified. When the result is left justified, the eight
most significant bits will be placed in the ADRESH register with the least
significant bits placed in the ADRESL register. When right justified, the eight
least significant bits will be placed in the ADRESL register with the most
significant bits placed in the ADRESH register. The selection of right or left
justification will depend on the requirements of the user’s software.
ADCON2bits.ADMF = 1; //
Right justified.
ADCON2bits.ADMF = 0; //
Left justified.
Bit6 :- Not in use
Bit5-3 :- A/D
Acquisition Time Select bits
·
Acquisition time
is the ADC capacitor charging and discharging. If time is not sufficient then
result will be garbage. The holding capacitor must be given sufficient time to
settle to the analog input voltage level before the actual conversion is
initiated.
·
See the equation
19-1,2,3 for more detail in controller datasheet.
·
Basically I
always uses 12TAD.
ADCON2bits.ADQT = 1;
ADCON2bits.ADQT = 0;
ADCON2bits.ADQT = 1;
Bit2-0 :- AD conversion
clock selection
·
This time will be
the analog to digital clock period multiplied by the number of bits of
resolution in the analog to digital converter plus the two to three additional
clock periods for the settling time.
·
There are two
types of clock sources can be select. Main controller oscillator or AD RC
oscillator. We will use fosc/64.
ADCONbits.ADCS2 = 1;
ADCONbits.ADCS1 = 1;
ADCONbits.ADCS0 = 0;
A/D Conversions
Now the time
is to make software to read the RA0/AN0
pin analogical input voltage. We will connect a LED on PORTC0 and operate led if ADC conversion value reached on our set
value. ADC uses many of the purposes in embedded field. Some of these are
temperature display, liquid leveler and many more.
Circuit diagram:-
Software procedure flow diagram
Codes:-
#include
<p18f2520.h>
#define
LED PORTCbits.RC0 // Define LED
PORT pin.
void
ADC_result(void);
float
ADC_data = 0;
float
Set_Value = 2.35;
void
main()
{
TRISC = 0x00; // PORTC as output port.
TRISA = 0xFF; // Configure PORTA pins as input.
PORTC = 0x00; // PORTC output 0 at starting time.
ADCON0 = 0x01; // ADC on, Channel-0 select.
ADCON1 = 0x0E; // Voltage reference VDD to Vss, AN-0 as analog
input.
ADCON2 = 0xAE; // Right justified, 12 TAD, FOSC/64.
while(1)
{
ADC_result(); // Call to ADC checking function.
if(ADC_data >
Set_Value)
{
LED
= 1; // On LED if voltage cross
limit value.
}
else
{
LED = 0;
}
}
}
void
ADC_result()
{
ADCON0bits.GO = 1; // Set ADC conversion in progress.
while( ADCON0bits.GO == 1 ); // Wait until conversion is not complete.
// Convert AD value to voltage.
ADC_data = (ADRESL + (ADRESH * 256))
/ 204.8;
}
Download Project File :- https://drive.google.com/file/d/0B886Kbl42IVua1JvQkktMUFlVFU/view?usp=sharing
No comments:
Post a Comment