Chapter 9 Micro
Chapter 9 Micro
9.1 Introduction
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.
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.
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:
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.
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
. . .
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)
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
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.
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 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
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.
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)
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).
⁄ (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.
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).
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:
This relationship, along with the A/D equation (9.5), leads to the following equation:
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:
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)
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 }
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:
204
PROBLEMS
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).
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.
205
4. In this problem it is assumed the following:
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.
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.
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.
207