0% found this document useful (0 votes)
21 views

Chapter 9 Micro

Uploaded by

yorgodaoud360
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
21 views

Chapter 9 Micro

Uploaded by

yorgodaoud360
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 18

Chapter 9: Analog-to-Digital Conversion

9.1 Introduction

The purpose of the Analog-to-Digital converter (ADC) is to transform a voltage sample to a


proportional digital code thereby allowing the measurement of physical quantities such as
voltage, current, temperature, atmospheric pressure, etc. Most sensors transform physical
quantities into voltage. For instance the LM35 temperature sensor converts the temperature
range (0 – 100 ºC) into a linear voltage range between 0 and 1 Volt as described by the
characteristic curve of figure 9.1. Due to the digital nature of a microcontroller, the ADC
serves as a mediator between the analog world in which we live and the digital world created
by Man.
Voltage
1V

10 mV / °C

Temperature
0 100 ºC
Figure 9.1: Characteristic curve of LM35 temperature sensor.

This chapter discusses the functionality of the ADC and its use in a variety of applications.
The Sample-and-Hold (SAH) circuit and the Successive-Approximation (SAR) ADC will be
explained and pertinent timing constraints will be covered as well.

9.2 Sample-and-Hold Circuitry

In order to convert a voltage sample to digital code, the sample is not allowed to change value
during conversion. This is because analog-to-digital conversion is not an instantaneous
process. The successive-approximation A/D converter, employed by the PIC18 family, is a
state machine requiring a number of clock cycles to complete the conversion process.

Since signals in general (e.g. audio signals) vary rapidly as a function of time, the need to
track the input signal is performed via a Sample-and-Hold (SAH) circuit depicted in figure
9.2. The 5 pF capacitor (Cin) in the figure models the input capacitance of the SAH whereas
Chold is used to store or hold the input sample for conversion. In order to track an input signal,
the sampling switch S is closed and the RC circuit formed by (Ric + RSS) and Chold allows the
holding capacitor to track the input signal within five time constants. This “tracking time” Tc
has been computed to be 1.2 μs under the worst considerations. If other factors such as the
amplifier settling time (TAMP = 5 μs) and the temperature coefficient (TCOFF = 1.25 μs for an
operating temperature of 50 °C) are taken into account, then the acquisition time (TACQ =
TAMP + TC + TCOFF) adds up to 7.45 μs. Therefore, the sampling switch S must be closed for
at least 7.45 μs for reliable data acquisition. When the ADC is commanded to start conversion
(GO = 1), S is opened and the input signal is disconnected from the hold capacitor.
Simultaneously swich ̅ is closed and the conversion process of the sample stored across Chold
is initiated. Due to the high input impedance of the ADC, the voltage sample remains constant

190
during conversion. Upon termination, an end-of-conversion flag (̅̅̅̅̅̅̅̅ ) is asserted to 0 and
consequently ̅ is opened and S is closed. This means that the SAH will go back to sampling
mode. The charge holding capacitor Chold is discharged after each sample via the discharge
switch. This feature helps to optimize the sampling process, as the circuit always needs to
charge the capacitor, rather than charge/discharge based upon previously measured values.

Figure 9.2: Analog input model.

9.3 Successive Approximation ADC

In reference to figure 9.3, the successive approximation analog-to-digital (SAR ADC)


converter circuit typically consists of five chief sub-circuits:

1. A sample and hold circuit to acquire the input voltage (Vin).


2. A voltage comparator that compares Vin to the DAC’s output. It outputs the comparison
result to the successive approximation register (SAR).
3. A successive approximation register sub-circuit designed to supply an approximate
digital code of Vin to the internal DAC.
4. An internal reference DAC that supplies the comparator with an analog voltage
equivalent of the digital code output of the SAR for comparison with Vin.
5. A register ADRES to store the ADC result upon end-of-conversion (EOC).

Figure 9.3: 8-bit Successive approximation ADC block diagram

191
The successive approximation register is initialized so that the most significant bit D7 is
equal to a digital 1 and all other bits are equal to 0. This code is fed into the DAC which
supplies the analog equivalent of this digital code (VREF+ - VREF-) / 2 into the comparator
circuit for comparison against the input sample. If this analog voltage exceeds Vin, the
comparator causes the SAR to reset this bit and set the next bit to a digital 1. If it is lwer, then
the bit is left a 1 and the next bit is set to 1. This binary search, exemplified in figure 9.4,
continues until every bit in the SAR has been tested. The ADC result is the digital
approximation of the sampled input and is output by the ADC at the end of the conversion
(̅̅̅̅̅̅̅̅ = 0). As shown in this algorithm, a successive-approximation ADC requires:

1. An input voltage sample Vin to be converted to digital.


2. A reference voltage source VREF to specify the output range (0 - VREF).
3. A DAC to convert the ith approximation xi to a voltage.
4. A comparator to compare the DAC's voltage with the input voltage.
5. A register to store the output of the comparator and apply a new value to the DAC.

SAR ADC Operation for Vin = 4 V. ADRES = 0xCD Thresholds Used in Search
Cycle Bit D7D6…D1D0 V+ V- Vo DAC Input DAC Output
1 D7 1000 0000 4 V 2.50000000 V 1 1000 0000 2.50000000 V
2 D6 1100 0000 4 V 3.75000000 V 1 0100 0000 1.25000000 V
3 D5 1110 0000 4 V 4.37500000 V 0 0010 0000 0.62500000 V
4 D4 1101 0000 4 V 4.06250000 V 0 0001 0000 0.31250000 V
5 D3 1100 1000 4 V 3.90625000 V 1 0000 1000 0.15625000 V
6 D2 1100 1100 4 V 3.98437500 V 1 0000 0100 0.07812500 V
7 D1 1100 1110 4 V 4.02343750 V 0 0000 0010 0.03906250 V
8 D0 1100 1101 4 V 4.00390625 V 1 0000 0001 0.01953125 V

Figure 9.4: Iterations of 8-bit SAR ADC for V+ = 4 V, VREF+ = 5 V and VREF- = 0 V.

The ADC of the PIC18F microcontroller generates a 10-bit approximation upon end-of-
conversion. Figure 9.5 shows the timing diagram of the A/D converter after the GO bit has
been asserted. The A/D conversion requires 11 TAD per 10-bit conversion where TAD is the
A/D conversion per bit. Upon termination, the 10-bit A/D result is saved in
ADRESH:ADRESL (A/D result high and low). Simultaneously, the ̅̅̅̅̅̅̅̅̅ bit is cleared by
the hardware (end-of-conversion indicator) and the sampling switch is closed again to allow
the capacitor to track the input signal in anticipation for conversion. When the next sample is
to be converted, the GO bit is set once again. This disconnects the sampling switch from the
input signal and initiates the conversion process. The charges held across the capacitor’s
plates will not discharge during conversion due to the high input impedance of the converter.

Figure 9.5: A/D conversion TAD cycles. Acquisition time TACQ = 0 (ACQT<2:0> = 000).

192
9.4 A/D Functionality and Associated registers

In reference to figure 9.6, The A/D converter module of PIC18F45K22 devices has 28
external analog channels (channel AN28 is reserved at this point) and 3 internal channels
(FVR BUF, DAC and CTMU). The external channels occupy all the ports either partially or
completely. The analog multiplexer allows conversion of one channel at a time in accordance
with the Channel Select Bits CHS<3:0> in control register ADCON0 (figure 9.7). The user
should first set ADON in ADCON0 in order to turn on the A/D. The selected channel is fed
to the A/D converter via the sample and hold circuit. The GO bit in ADCON0 initiates the
conversion process. Upon end-of-conversion, the same bit (also called ̅̅̅̅̅̅̅̅ ) is cleared by
the hardware and the 10-bit digital result is stored in ADRESH:ADRESL.

Figure 9.6: A/D block diagram.

193
ADCON0: A/D CONTROL REGISTER 0
U-0 R/W-0 R/W-0 R/W-0 R/W-0 R/W-0 R/W-0 R/W-0
- CHS<4:0> ̅̅̅̅̅̅̅̅ ADON
bit 7 bit 0
R = Readable bit W = Writable bit U = Unimplemented bit, read as ‘0’
-n = Value at POR ‘1’ = Bit is set ‘0’ = Bit is cleared x = Bit is unknown

bit 7 Unimplemented: Read as ‘0’

Bit 6-2 CHS<4:0>: Analog Channel Select bits


00000 = AN0
00001 = AN1
00010 = AN2
00011 = AN3
00100 = AN4
00101 = AN5(1)
00110 = AN6(1)
00111 = AN7(1)
01000 = AN8

. . .

10011 = AN19
10100 = AN20(1)
10101 = AN21(1)
10110 = AN22(1)
10111 = AN23(1)
11000 = AN24(1)
11001 = AN25(1)
11010 = AN26(1)
11011 = AN27(1)
11100 = Reserved
11101 = CTMU
11110 = DAC
11111 = FVR BUF2 (1.024V/2.048V/2.096V Volt Fixed Voltage Reference)(2)

bit 1 ̅̅̅̅̅̅̅̅: A/D Conversion Status bit


1 = A/D conversion cycle in progress. Setting this bit starts an A/D conversion cycle.
This bit is automatically cleared by hardware when the A/D conversion has completed.
0 = A/D conversion completed / not in progress)

bit 0 ADON: ADC Enable bit


1 = ADC is enabled
0 = ADC is disabled and consumes no operating current

Note 1: Available on PIC18(L)F4XK22 devices only.


Note 2: Allow greater than 15 μs acquisition time when measuring the Fixed Voltage Reference.

Figure 9.7: ADCON0 - A/D configuration register 0.

The voltage configuration bits PVCFG<1:0> and NVCFG<1:0> in ADCON1 (see figure
9.8) select the reference voltages VREF+ and VREF- of the A/D converter. These references
essentially specify the minimum and maximum voltages that can be applied to the analog
inputs. In most cases, the references used are VREF+ = VDD = 5V and VREF- = VSS = 0V
(internal references). This way a voltage range of 0 to 5V provides a digital code between
0x000 and 0x3FF for the 10-bit A/D.

194
ADCON1: A/D CONTROL REGISTER 1
R/W-0 U-0 U-0 U-0 R/W-0 R/W-0 R/W-0 R/W-0
TRIGSEL PVCFG<1:0> NVCFG<1:0>
bit 7 bit 0

R = Readable bit W = Writable bit U = Unimplemented bit, read as ‘0’


-n = Value at POR ‘1’ = Bit is set ‘0’ = Bit is cleared x = Bit is unknown

bit 7 TRIGSEL: Special Trigger Select bit


1 = Selects the special trigger from CTMU
0 = Selects the special trigger from CCP5

bit 6-4 Unimplemented: Read as ‘0’

bit 3-2 PVCFG<1:0>: Positive Voltage Reference Configuration bits


00 = A/D VREF+ connected to internal signal, AVDD
01 = A/D VREF+ connected to external pin, VREF+
10 = A/D VREF+ connected to internal signal, FVR BUF2
11 = Reserved (by default, A/D VREF+ connected to internal signal, AVDD)

bit 1-0 NVCFG<1:0>: Negative Voltage Reference Configuration bits


00 = A/D VREF- connected to internal signal, AVSS
01 = A/D VREF- connected to external pin, VREF-
10 = Reserved (by default, A/D VREF- connected to internal signal, AVSS)
11 = Reserved (by default, A/D VREF- connected to internal signal, AVSS)

Figure 9.8: ADCON1 - A/D configuration register 1.

Figure 9.9 illustrates the role of ADFM (A/D Format Select) in selecting whether the ADC
result is right justified (ADFM = 1) or left justified (ADFM = 0). This control bit belongs to
ADCON2 (figure 9.10) For 8-bit resolution, the 2 LSBs are dropped and hence left
justification is recommended. This way the result to be processed is read from ADRESH.
When 10-bit resolution is required, right justification of the result turns out to be easier in
processing the information unless fractional arithmetic or fixed-point notation is used.

Figure 9.9: A/D result justification.

Bits ADCS2:ADCS0 specify the conversion time per bit TAD. The conversion time Tconv is
11 TAD. When the internal RC oscillator is used to trigger the A/D converter (ADCS<2:0> =
x11), TAD is guaranteed a typical value of 1.7 μs. The MCU manufacturer notes that for
correct A/D conversion, TAD must be at least 1 μs. Figure 9.11 tabulates the conversion time
per bit TAD for all values of ADCS<2:0> and for different operating frequencies Fosc.

195
ADCON2: A/D CONTROL REGISTER 2
R/W-0 U-0 R/W-0 R/W-0 R/W-0 R/W-0 R/W-0 R/W-0
ADFM ACQT<2:0> ADCS<2:0>
bit 7 bit 0

bit 7 ADFM: A/D Result Format Select bit


1 = Right justified
0 = Left justified

bit 6 Unimplemented: Read as ‘0’

bit 5-3 ACQT<2:0>: A/D Acquisition time select bits. Acquisition time is the duration that the A/D
charge holding capacitor remains connected to A/D channel from the instant the GO/ DONE
bit is set until conversions begins.
000 = 0(1)
001 = 2 TAD
010 = 4 TAD
011 = 6 TAD
100 = 8 TAD
101 = 12 TAD
110 = 16 TAD
111 = 20 TAD

bit 2-0 ADCS<2:0>: A/D Conversion Clock Select bits


000 = FOSC/2
001 = FOSC /8
010 = FOSC /32
011 = FRC(1) (clock derived from a dedicated internal oscillator = 600 kHz nominal)
100 = FOSC /4
101 = FOSC /16
110 = FOSC /64
111 = FRC(1) (clock derived from a dedicated internal oscillator = 600 kHz nominal)

Note 1: When the A/D clock source is selected as FRC then the start of conversion is delayed by one
instruction cycle after the GO/ DONE bit is set to allow the SLEEP instruction to be executed.

Figure 9.10: ADCON2 - A/D configuration register 2.

ADC Clock Period (TAD) Device Frequency (FOSC)


ADC Clock ADCS<2:0> 64 MHz 16 MHz 4 MHz 1 MHz
Fosc / 2 000 31.25 ns(2) 125 ns(2) 500 ns(2) 2 μs
Fosc / 4 100 62.5 ns(2) 250 ns(2) 1 μs 4 μs(3)
Fosc / 8 001 400 ns(2) 500 ns(2) 2 μs(3) 8 μs(3)
Fosc / 16 101 250 ns(2) 1 μs 4 μs(3) 16 μs(3)
Fosc / 32 010 500 ns(2) 2 μs 8 μs(3) 32 μs(3)
(3)
Fosc / 64 110 1 μs 4 μs 16 μs(3) 64 μs(3)
FRC x11 1 - 4 μs(1, 4) 1 - 4 μs(1, 4)
1 - 4 μs(1, 4) 1 - 4 μs(1, 4)

Legend: Yellow shaded cells are outside of recommended range.


Note 1: The FRC source has a typical time of TAD 1.7 μs.
Note 2: These violate the minimum required TAD time.
Note 3: For faster conversion times, the selection of another clock source is recommended.
Note 4: When the device frequency is greater than 1 MHz, the FRC clock source is only
recommended if the conversion will be performed during the sleep mode.

Figure 9.11: ADC clock period versus device operating frequencies.

196
The acquisition time is programmable via ACQT<2:0> in ADCON2. It is the time the
sampling switch tracks the input signal before conversion. The minimum acquisition time has
been computed to be 7.45 µs. Figure 9.12 shows a pertaining time diagram.

Figure 9.12: A/D conversion cycles. Acquisition time TACQ = 4 TAD (ACQT<2:0> = 010)

9.5 A/D Operation Summary

The procedure to follow in using the A/D converter is outlined subsequently:

1. Configure the A/D module:


 Configure analog pins (ANSEL) and voltage references (ADCON1). The analog
input channels must have their corresponding TRIS bits selected as input.
 Select A/D input channel (ADCON0).
 Select A/D conversion clock, acquisition time and data format (ADCON2).
 Turn on A/D module (ADON in ADCON0).
2. Configure A/D interrupt if desired. Set ADIE (PIE1), GIE and PEIE (INTCON).
3. Wait the required acquisition time.
4. Start conversion: set ̅̅̅̅̅̅̅̅̅ bit (ADCON0).
5. Wait for A/D conversion to complete, by either:
 Waiting for the ̅̅̅̅̅̅̅̅̅ bit to be cleared (interrupts disabled); or
 Waiting for the A/D interrupt.
6. Read A/D result registers (ADRESH/ADRESL). Clear bit ADIF if in interrupt mode.
7. Process A/D result then go back to step 3 if more samples are to be converted.

9.6 A/D Transfer Function

The A/D converter maps an analog voltage into an N-bit digital value. This mapping is
described by a transfer function. An ideal transfer function is one in which there are no errors
or non-linearity. Figure 9.13 describes the ideal behavior of PIC18F A/D converters.

The transfer function shows the voltage axis subdivided into 256 subdivisions or steps. The
width of a step is 1 LSB defined as

197
(9.1)

where n is the A/D resolution in bits (n = 8 or 10). Throughout this chapter, we will assume
that VREF- = 0V and VREF+ = 5V = VREF. Hence equation 9.1 becomes

{ } (9.2)

The curve of figure 9.13 shows the A/D transfer function for 10-bit resolution. One can easily
see that if a voltage falls between -1/2 LSB and +1/2 LSB, the assigned digital code is 0x000.
For a voltage between 1/2 LSB and 3/2 LSB, the assigned digital code is 0x001. In general,

( )( ) ( )( ) ( ) (9.3)

where Vin is the input voltage applied and ADRES is the A/D result stored in
ADRESH:ADRESL. The red straight line crossing the staircase of figure 9.13 is the line that
best fits the points on the curve. It can be used to relate ADRES to Vin. This characteristic
equation is given by:

⁄ (9.4)

ADRES
Full-Scale Range
0x3FF
0x3FE
0x3FD
0x3FC
0x3FB
. . . . . . ½ LSB ideal
0x004
Full-Scale Transition
0x003
0x002
0x001
Analog Input Voltage
0x000
½ LSB ideal
Zero-Scale
VDD/VREF+
VSS/VREF- Transition

Figure 9.13: Ideal A/D transfer function for PIC18F microcontrollers (10-bit resolution).

Solving for Vin as a function of ADRES, we get

⁄ (9.5)

The upcoming examples illustrate how these equations can be used to design a digital
voltmeter as well as a thermometer.

198
9.7 Instrumentation Examples

This section introduces the reader to the concept of instrumentation through a couple of
examples. With the ADC, any physical quantity may be measured provided of course that
there is an appropriate sensor for it.

Example 9.1 - Digital Voltmeter: Write a program to implement a 2-digit voltmeter to


measure an applied voltage between 0.0 V and 5.0 V. Use the circuit of figure 9.14 to test it.

Solution: In order to measure the voltage with one digit after the decimal point, we can
multiply Vin of equation (9.5) by 10 then place the decimal point on the LCD at the
appropriate position. This removes the hassle of having to work with fractions. Therefore, the
voltage to be displayed, for n = 8 and VREF = 5 V, is given by:

⁄ ⁄ (9.6)

which happens to be a nice equation from a coding point of view. The program is listed in
figure 9.15. The precision can be easily updated for 2 digits after the decimal point.

Figure 9.14: Digital voltmeter with one digit after the decimal point.

Program that implements a digital voltmeter with 1 digit of precision after the decimal point.
1 #include <p18cxxx.h>
2 #include <LCD4lib.h>
3
4 void Setup(void);
5 void MeasureV(void);
6
7 void main(void) {
8 Setup();
9 while (1)
10 MeasureV();
11 }
12
13 void Setup(void) {
14 InitLCD(); // init LCD display
15 DispRomStr(Ln1Ch0, (ROM *) "- DC Voltmeter -"); // display line 1
16 DispRomStr(Ln2Ch0, (ROM *) " Vin = _._ Volts"); // display line 2

199
17
18 ADCON0bits.ADON = 1; // turn on A/D, AN0: default channel
19 ADCON2 = 0b00001001; // left justify, Tconv = 22 us, Tacq = 4 us
20 }
21
22 void MeasureV(void) {
23 unsigned char Result;
24 char Digits[3];
25
26 ADCON0bits.GO = 1; // start A/D conversion
27 while (ADCON0bits.NOT_DONE); // wait until EOC
28 Result = ((unsigned) 50 * ADRESH + 128) / 256; // 128/256 (rounding)
29 Bin2Asc(Result, Digits); // convert to ASCII
30 DispVarStr(&Digits[1], Ln2Ch7, 1); // digit before DP
31 DispVarStr(&Digits[2], Ln2Ch9, 1); // digit after DP
32 }

Figure 9.15: Digital voltmeter program (precision: 1-digit after the decimal point).

The concept of measuring DC voltage can be easily employed to measure AC voltages. In


fact, the high voltage can be dropped down to a low level (say around 12 Vrms) via a step
down transformer (isolated case) or a voltage divider (non-isolated case). From this point on,
the voltage can be converted to DC via a bridge rectifier followed by a capacitor filter. The
overall interface circuit can be designed to provide a DC voltage level between 0 and 5V for
an AC input between 0 and 255 Vrms. Since the A/D reading provides a digital code
proportional to the applied voltage, a value of ADRESH = 255 (8-bit mode) is equivalent to
an applied AC voltage of 255 Vrms, and so forth. For further precision of the voltage
measurement, one would resort to the 10-bit A/D resolution.

Example 9.2 – Digital Thermostat: In reference to figures 9.16 and 9.17, it is desired to
implement a digital thermostat using the LM35 temperature sensor which provides an
output voltage of 10 mV/°C. In this example, the sensor is intended to measure a
temperature range between 0 and 100 °C. This means that its output voltage will vary
between 0V to 1 V. Since the ADC converter generally uses the internal references VDD
and VSS, an amplifier with a gain of 5 is placed between the sensor and the ADC input in
order to take advantage of the full-scale range of the ADC.

a. Write a program to implement the digital thermometer on the LCD. Hint: The
relationship between the temperature and the ADC input Vin is given by:

TC  100 Vin 5  20 Vin (9.7)

This relationship, along with the A/D equation (9.5), leads to the following equation:

TC  (100 ADRES ) 256 (9.8)

b. Add the option of displaying the temperature in Celsius or Fahrenheit. Initially, the
system displays degree Celsius. When the user presses the PB, the temperature unit is
toggled (Celsius → Fahrenheit and vice versa). Recall that F = 1.8C + 32. To avoid
floating point computations, you need to compute 10F = 18C + 320.

c. Add a the function Control() that turns on the LEDs: Hi, Lo and Med in accordance

200
with the following algorithm:

0 C  TC  20C, Turn on Lo LED


20 C  TC  30C, Turn on Med LED
30 C  TC  100C, Turn on Hi LED

Figure 9.16: Digital thermostat displaying T = 25 ºC or 77.0 ºF (20 ºC ≤ T ≤ 30 ºC).

Figure 9.17: Digital thermostat displaying T = 96.8 ºF or 36 ºC (T > 30 ºC).

Solution: The complete program is listed in figure 9.18. It is self-explanatory and modular.
The temperature thresholds used (20 ºC and 30 ºC) are converted to their equivalent A/D
reading (LoTemp = 61 and HiTemp = 76) by solving for ADRES in equation (9.8). This
gives
ADRES  256 TC / 100 (9.9)

Program that implements a digital thermometer (Celsius/Fahrenheit) on a Liquid Crystal Display.


1 #include <p18cxxx.h>
2 #include <LCD4lib.h>
3
4 #define Hi PORTBbits.RB7 // High temperature indicator
5 #define Med PORTBbits.RB6 // Medium temp. indicator
6 #define Lo PORTBbits.RB5 // Low temperature indicator
7
8 #define DegC FLAGS.B0 // DegC = 1, C else F

201
9 #define HiTemp 76 // A/D reading for T = 30 C
10 #define LoTemp 51 // A/D reading for T = 20 C
11
12 void Setup(void);
13 void Control(void);
14 void C_or_F(void);
15 void TestPB(void);
16
17 char Digits[5];
18
19 void main(void) {
20 Setup();
21 while (1) {
22 Control(); // indicate hi, lo or medium temperature
23 C_or_F(); // use current A/D result
24 TestPB(); // start A/D & test PB
25 // Sleep(); // awakened by WDT reset (if enabled)
26 }
27 }
28
29 void Setup(void) {
30 InitLCD(); // init LCD display
31 DispRomStr(Ln1Ch0, (ROM *) "---Thermostat---"); // display top line
32 DispRomStr(Ln2Ch0, (ROM *) "T = Celsius"); // initially in C
33 DegC = 1; // display Celsius initially
34
35 ADCON0bits.ADON = 1; // turn on A/D, AN0: default channel
36 ADCON2 = 0b00001001; // left justify, Tconv = 24 us, Tacq = 4 us
37
38 ANSELB = 0x00; TRISB = 0x07; // RB7..RB5 are output pins
39 INTCON2bits.INTEDG0 = 0; // RB0 reacts to a falling edge
40 INTCON2bits.RBPU = 0; // use internal pull-up resistor
41 }
42
43 void Control(void) {
44 PORTB = PORTB & 0b11111000; // turn off Hi, Med & Lo
45 if (ADRESH > HiTemp)
46 Hi = 1; // T > HiTemp, turn on high LED
47 else if (ADRESH >= LoTemp)
48 Med = 1; // LoTemp <= T <= HiTemp, turn on med. LED
49 else
50 Lo = 1; // else T < LoTemp, turn on low LED
51 }
52
53 void C_or_F(void) {
54 unsigned char Celsius;
55 unsigned int Fahrenheit;
56 char Degree = 0xDF; // ASCII character of degree symbol
57
58 Celsius = ((unsigned) 100 * ADRESH + 128) / 256; // ( plus rounding)
59 if (DegC) {
60 Bin2Asc(Celsius, Digits); // convert voltage to BCD
61 if (Digits[0] == '0') // compare against ASCII of 0
62 Digits[0] = '+'; // display '+' instead of '0'
63 DispVarStr(Digits, Ln2Ch4, 3);
64 DispVarStr(&Degree, Ln2Ch8, 1); // display degree symbol
65 } else {
66 Fahrenheit = ((unsigned) 18 * Celsius + 320); // F = (1.8 C+32) * 10
67 Bin2AscE(Fahrenheit, Digits); // Digits+0 is ignored

202
68 if (Digits[1] == '0') // compare against ASCII of 0
69 Digits[1] = '+'; // display '+' instead of '0'
70 DispVarStr(&Digits[1], Ln2Ch4, 3); // digits before DP
71 DispVarStr(&Digits[4], Ln2Ch8, 1); // digits after DP
72 DispVarStr(&Degree, Ln2Ch10, 1); // display degree symbol
73 }
74 }
75
76 void TestPB(void) {
77 ADCON0bits.GO = 1; // conversion for next iteration
78 if (INTCONbits.INT0IF == 1) {
79 INTCONbits.INT0IF = 0;
80 DegC = ~DegC; // toggle indicator
81 if (DegC)
82 DispRomStr(Ln2Ch0, (ROM *) "T = Celsius");
83 else
84 DispRomStr(Ln2Ch0, (ROM *) "T = . Fahr.");
85 }
86 }

Figure 9.18: Program listing of the digital thermostat.

This program may be operated in the sleep mode and periodically interrupted via the
watchdog timer every 64 ms or so. This insures the device consumes minimum power.
Figure 9.19 shows the actual ampifier circuit with a gain of 5. The MCP601 by Microchip is
an operational amplifier that can be powered up with a single supply of +5V. The
potentiometer is used to calibrate the temperature. It can be shown that the error on the
measurement is ± 0.2 ºC for n = 8 and ± 0.06 ºC for n = 10.

Figure 9.19: LM35 (10 mV/ºC) used to measure a temperature range between 0 and 100 °C.

203
9.8 Conclusion

Applications of the A/D converter are numerous. Here is a list of some of them:

 Digital signal processing.


 Digital communication.
 Instrumentation.
 Digital control.

204
PROBLEMS

1. In this problem it is assumed that Fosc = 10 MHz.


a. What is the ADC conversion time per sample for ADCS<2:0> = 101?
b. What is the ADC acquisition time for ACQT<2:0> = 100?
c. What must be the maximum sampling rate in this case?
d. Using the ADC in 10-bit mode with VREF+ = 4V and VREF- = 0V, find the ADC
reading (in base 10) for Vin = 2.7 V and Vin = 3.6 V.
e. Using the setup of figure 9.19, explain how the precision on the measured temperature
may be obtained for the 8-bit mode as well as the 10-bit mode.

2. Redo the voltmeter example of section 9.7 with 2 digits of precision after the decimal
point. Justify using the ADC with a resolution of 10 bits. Derive the new expression to be
computed. Note: use a high granularity pot to see the 2-digit precision (figure 9.20).

Figure 9.20: Voltmeter with 2-digit precision.

3. Write a program to flash the LED of figure 9.21 every T ms. T varies between 10 ms (for
ADRES = 0 or 1) and 2550 ms ≈ 2.5 sec for ADRES = 255. The flashing period is
controlled by the variable resistor and the flashing steps are 10 ms.

Figure 9.21: Variable speed flasher.

205
4. In this problem it is assumed the following:

 Crystal frequency Fosc = 4 MHz.


 ADC resolution n is 8 bits. Result is stored in ADRESH (left justification).
 VREF- = 0V and VREF+ = 5V.
 The voltage Vin applied to ADC ranges between 0V and 5V.

a. Write the expression of ADRESH as a function of Vin. Fill-in the entries of column 2
in figure 9.22 accordingly.
b. Write a program to test the ADC by displaying the converted sample on PORTB.
Fill-in the displayed code in the third and fourth columns of figure 9.22. Compare the
theoretical code (column 2) against the experimental code (column 3)? Explain
discrepancies.

Vin ADRESH ADRESH ADRESH


Analog in Hex in Hex in Decimal
Input (part (a)) (part (b)) (part (b))
0.00 V
0.50 V
1.00 V
1.50 V
2.00 V
2.50 V
3.00 V
3.50 V
4.00 V
4.50 V
4.99 V

Figure 9.22: Vin versus ADC reading.

c. Write a program to show the decimal result of the ADC on the 3-digit multiplexed of
figure 9.23. Verify that your results match the above table. Indicate how this device
can be used to measure AC voltage between 0V and 255V.

Figure 9.23: Multiplexed display to show ADC reading in decimal.

206
5. Redo the voltmeter example of section 9.7 with 2 digits of precision after the decimal
point. Use a multiplexed 7-segment display (figure 9.24).

Figure 9.24: Multiplexed display for voltmeter with 2 digits after the decimal point.

6. Redo the programmable timer controlled by the Analog-to-Digital converter (example


9.4) using a multiplexed display. Figure 9.25 shows the hardware setup.

Figure 9.25: Timer with ADC control and Multiplexed display.

207

You might also like