Uploaded by Jerimiah Miranda

EEE158 2021s1 ADC Exercise v2

advertisement
EEE 158: Electrical and Electronics
Engineering Laboratory V
Exercise #5: Analog-to-Digital Conversion
Introduction
Computers are ubiquitous in our everyday lives; microcontrollers, being a specific form, are no exception.
Nominally, they are devices that operate using a set of binary digits (bits) of which each are either ON or OFF. Thus, it
may be said that computers are digital; and operate in the discrete domain. Physical variables, on the other hand,
are not represented as a set of bits; rather, like real numbers, their numerical values can take on an arbitrary number
of digits both left and right of the decimal point (precision). Thus, these variables are said to be analog, and operate
in the continuous domain. Examples include voltage; power; current; temperature; wind speed; pressure; and so on.
Electronic computers are commonly used to automate calculations on our behalf; however, as digital devices
they cannot accept nor produce an arbitrary analog electrical signal on their own. In order to accept analog input,
an analog-to-digital converter (ADC) is needed. On the other hand, a digital-to-analog converter (DAC) would be
needed to produce analog outputs. Note that these 2 devices focus only on the electrical domain; conversion
to/from other domains (eg. mechanical) requires additional devices called transducers.1
Analog to Digital Conversion
The analog-to-digital converter, or ADC for short, is a device that is used to convert a voltage (or current)
input into a set of bits
suitable for digital processing. ADCs are divided into four types based on
their input format:
1.
Unipolar, voltage – only accepts non-negative voltages
2.
Bipolar, voltage – accepts both negative and positive voltages
3.
Unipolar, current – only accepts current sunk by a pin
4.
Bipolar, current input – accepts currents in both source and sink configurations2
Like any electronic component, the voltage ranges specified in the electrical ratings must be respected to
prevent damage to the component. Because common signals usually exceed the ADC supply voltage, external
processing circuits are often required. Furthermore, ADCs built into microcontrollers are usually of the unipolar,
voltage type; thus the discussion in this exercise pertains to that type.
1
2
An example of such a device is the LM35 temperature sensor, from EEE 151’s temperature-control experiments.
Motors and generators are transducers, too – between electrical and mechanical domains.
For any IC pin, the concept of source and sink must be understood. A pin where current flows out is said to be
sourcing; while the opposite direction is said to be sinking.
Page 1 of 8; Last revised 2021-12-07 12:40:33
EEE 158: Electrical and Electronics Engineering Laboratory V
Lab Exercise #5: Analog-to-Digital Conversion
The set of bits produced by a unipolar ADC is related to the input in the following manner:
where
•
is the input voltage. For
current-input ADCs, this will be
instead.
•
is the reference voltage of
the ADC. This is also the voltage
that will produce the highest
value from the ADC.3 Like its
input counterpart, for currentinput ADCs this will be
instead.
•
is the resolution of the ADC;
the higher, the better.
•
, or the greatest-integer
function, yields the largest
integer no larger than .
Figure 1: Four-bit ADC Response
Figure 1 shows the response of a
4-bit ADC, while Figure 2 shows that of a
10-bit ADC; for each, the ideal response is
also included. Even in theory, due to the
presence of
in the above equation
there will be a range of values for
that
will yield the same set of bits. Effectively,
this causes loss of fidelity, called
quantization error. This feature is both
irreversible, and inherent in the ADC
process; thus it can never be completely
eliminated.
Figure 2: Ten-bit ADC Response
3
The lower limit for a unipolar ADC is 0 volts (ie. VSS).
Page 2 of 8; Last revised 2021-12-07 12:40:33
EEE 158: Electrical and Electronics Engineering Laboratory V
Lab Exercise #5: Analog-to-Digital Conversion
The PIC32-family ADC
The PIC32 family of microcontrollers includes one (1) ADC whose input is multiplexed among different
possible input signals. Various registers control its operation, including enabling/disabling the peripheral; the
relevant ones are discussed in this document.
IMPORTANT: Use of microcontroller peripherals usually precludes use of certain pins as GPIOs, but it does
NOT preclude setting the appropriate bit/s for port direction/type on the precluded pins. It is the programmer’s
responsibility to set the appropriate port-control bits, the exact bit/s of which must be referred to in the devicespecific datasheet.
Provided with this exercise is a sample code for the ADC peripheral of the PIC32. Though there are comments
attempting to explain the rationale behind each register (ADC1CONx) setting, let us go into detail here:4
•
The ADC cannot be configured if it is disabled. Thus, the first task is to set the ON bit.
•
The ADC has an option of using either 10 bits (MODE12=0), or 12 bits (MODE12=1). Since higher resolution
is better, we use the 12-bit mode.
•
The digital result can be represented in one of a few ways. Note that certain modes yield representations
that are very different from what we are accustomed to in our programming classes. Coupled with the fact
that the ADC hardware is unipolar and 12-bit, we select the right-aligned 16-bit unsigned mode for
simplicity (MODE=0b000).
•
The ADC can automatically sample-and-convert the input signal. However, using this feature reliably
requires the use of interrupt handling, which for the ADC module could be spurious if triggered incorrectly
and/or external input noise is not accounted for. To minimize complexity, we resort to manual sampling via
control of the SAMP bit (ASAM=0).
•
Since we are doing manual sampling, the conversion trigger is by clearing the SAMP bit (SSRC=0b0000).
•
can be taken from different sources within the microcontroller. In this case, we use the supply voltage
itself as reference (VCFG=0b000), so that
can range from 0 to
.
•
We are not auto-scanning other channels/inputs, due to only one input being used; thus CSCNA=0.
•
We are selecting AN3 as our input; thus, CH0NA=0b000 and CH0SA=0b00011.
•
Looking at the physical pinout, AN3 is multiplexed on Channel 1 at Port B. Since the pin is to be used for
analog I/O rather than GP (digital) I/O, the corresponding ANSELB bit must be set; while the corresponding
TRISB is set because the pin is being used as an input.
•
The digital result is available at ADC1BUF0, stored in the representation determined by MODE.
◦
While the conversion is on-going, its contents will be indeterminate. The DONE bit is set by hardware to
indicate that A-D conversion is complete; in manual sampling mode it must be cleared by software
before commencing the next sample-convert cycle.
Let us see the ADC peripheral live (in the simulator). :D
4
The authoritative references are always the manufacturer’s family and device reference manuals.
Page 3 of 8; Last revised 2021-12-07 12:40:33
EEE 158: Electrical and Electronics Engineering Laboratory V
Lab Exercise #5: Analog-to-Digital Conversion
1.
Create a new project for the PIC32MM0064GPL036 chip, and name this project Exercise4a. The
instruction frequency must be set to 4 MHz.
2.
Add the provided sample code (Appendix A) to the project.
3.
Open the Stimulus window, and add a row for AN3. When fired, the stimulus should be 1.4 Volts.
4.
Create a watch for the variable adc_value. Debug the program, fire the stimulus, and pause after a short
while. adc_value should contain the value 0x06E4.
5.
[QUESTION; 5%, all-or-nothing] Change the stimulus to be equal to 3.1 Volts. What would the new
adc_value be? You might need to pause the simulation to see the values.
6.
[OBSERVATION; 10%] Do the digital values from Steps 4 & 5, as well as a few arbitrary values on the
interval [0, 3.3] correspond to the formula given in the ADC overview?
Exercise: Sweet Spot (30%)
Please use a new project for this part. You are to write code that causes RA0 and RC9 to turn ON and OFF
according to the following table when RB7 is pressed. When RB7 is not pressed, changing the analog input shall
have no effect on the states of RA0 and RC9. At system reset, both RA0 and RC9 shall initially be OFF.
Input Voltage
RA0
RC9
< 0.8
OFF
OFF
0.8 ≤ x < 1.6
OFF
ON
1.6 ≤ x < 2.4
ON
ON
≥ 2.4
ON
OFF
Exercise: Dimmer (15%)
Please use a new project for this part. You are to extend the previous part to have changes in RA0 and/or RC9
brightness done when RB13 is pressed. The brightness shall range from 0% at the minimum analog input (V SS), to
100% at the maximum analog input (V DD). Like RB7, when RB13 is not pressed the brightness shall remain
unchanged. At system reset, the initial brightness shall be 50%.
Note: Use of PWM for this part is required.
Page 4 of 8; Last revised 2021-12-07 12:40:33
EEE 158: Electrical and Electronics Engineering Laboratory V
Lab Exercise #5: Analog-to-Digital Conversion
Challenge: Color by Number v2 (40%)
This part requires the hardware dev board to be available. Please use a new project for this part.
You are to modify your solution for the challenge from the Combined Timers & CCP module to incorporate the
following changes. For the potentiometer, a value of 0% corresponds to full counterclockwise rotation; and 100% to
full clockwise rotation.
•
Pressing RB7 causes the brightness to change from 0% to 100%, in direct proportion to the potentiometer
setting at the time of RB7 being pressed. At system reset, the initial brightness shall be 50%.
•
Pressing RB13 causes the sequence to change according to the following criteria. At system reset, the
displayed color shall correspond to the first of the 5 digits, and remain frozen.
Potentiometer
Sequence Display
0% ≤ x ≤ 20%
Change every 0.4s, reverse order
20% < x < 40%
Change every 0.8s, reverse order
40% ≤ x ≤ 60%
Freeze at current position
60% < x < 80%
Change every 0.8s, normal order
80% ≤ x ≤ 100%
Change every 0.4s, normal order
Submission
You are to submit 3 ZIP files each containing the entire MPLAB X project for the corresponding requirement,
as well as a text file (.txt) containing answers to the walkthrough questions. The ZIP files must be named as
follows:
•
Sweet Spot: EEE158_<section>_<surname>_ADC_SweetSpot.zip
•
Dimmer: EEE158_<section>_<surname>_ADC_Dimmer.zip
•
Color Challenge v2: EEE158_<section>_<surname>_ADC_Challenge.zip
The 3 ZIP files, along with the answers to the walkthrough questions, must be submitted via UVLE. The
tentative deadline for this module is on 17 Dec 2021; the actual deadline is always kept up-to-date in the UVLE
submission bin.
Page 5 of 8; Last revised 2021-12-07 12:40:33
EEE 158: Electrical and Electronics Engineering Laboratory V
Lab Exercise #5: Analog-to-Digital Conversion
Appendix A: Sample ADC Source Code
/*
* main.c
* Sample code for using the ADC peripheral of PIC32MM0xx-series chips
*
* EEE 158: Electrical and Electronics Engineering Laboratory V
*
* Electrical and Electronics Engineering Institute, College of Engineering
* University of the Philippines - Diliman
*/
#include <xc.h>
#include <stdint.h>
/*
* Program-wide variables are declared here. With embedded systems,
* uninitialized variables are a big no-no!
*/
int16_t adc_value = 0;
// Raw value from the ADC
int16_t pwm_ref = 0;
// Reference for the PWM module
int main(void)
{
/*
* BEGIN ADC setup
*
* The 'FORM' and 'MODE12' members need special attention, as they
* directly influence how the read ADC value is represented in memory.
*
* The PIC32MMxxxx ADC can operate in either 10-bit mode, or 12-bit
* mode; higher resolution is better, but may be precluded by RAM
* issues (it should not be for this family, since the minimum
* supported representation of 16 bits is larger than the maximum
* resolution of 12 bits). Since our inputs will never be negative (due
* to electrical ratings being violated), we select the 16-bit
* *unsigned* integer form to save on space.
*/
AD1CON1bits.ON = 1;
// Enable ADC
AD1CON1bits.FORM = 0;
// See family reference datasheet
AD1CON1bits.MODE12 = 1; // See family reference datasheet
AD1CON1bits.ASAM = 0;
// Do NOT auto-sample
AD1CON1bits.SSRC = 0;
// Clearing SAMP will initiate conversion
AD1CON2bits.VCFG = 0;
AD1CON2bits.CSCNA = 0;
to be done
// Reference voltage is the power supply (~3.3V)
// Only one channel is used, or manual scanning is
/*
* Select AN3 as (+) input, and Vss (= 0V) as (-) input to ADC
*
Page 6 of 8; Last revised 2021-12-07 12:40:33
EEE 158: Electrical and Electronics Engineering Laboratory V
Lab Exercise #5: Analog-to-Digital Conversion
* This has the effect of the ADC input being
*
* IN = AN3 - 0 = AN3
*/
AD1CHSbits.CH0NA = 0b000;
// Selects AVSS (essentially, ground)
AD1CHSbits.CH0SA = 0b00011;
// Selects AN3
/// END ADC setup
/*
* BEGIN Port setup
*
* ADC is one of so-called "alternate functions". Its associated pin
* must be properly configured as well; this time, the device-specific
* datasheet will need to be consulted in addition to the family
* datasheet to figure out which PORT register set to use.
*/
// On the PIC32MM0064GPL036, AN3 is tied to PORT B, Channel 1.
TRISBbits.TRISB1 = 1;
// Input mode
ANSELBbits.ANSB1 = 1;
// Analog mode
/// END Port setup
////////////////////////////////////////////////////////////////////////
/*
* As always, microcontroller main()s are not supposed to return to the
* caller.
*/
AD1CON1bits.SAMP = 1;
// Initiate sampling
for (;;) {
/*
* ADC conversion is initiated using the following steps:
* - Set SAMP in AD1CON1
* - Wait for at least 3*t_{ad}
* - Clear SAMP
*
* When the conversion is complete, DONE in AD1CON1 is set.
* Since we selected manual sampling and conversion, the
* most-recent result is always in ADC1BUF0.
*/
if (AD1CON1bits.DONE) {
/*
* Conversion complete. Store the buffer's contents to
* our variable now because as soon as sampling is
* (re-)enabled, the buffer's contents will be
* overwritten.
*
* Note that DONE must be cleared in software; it is
* set by hardware. Since we selected manual sampling
Page 7 of 8; Last revised 2021-12-07 12:40:33
EEE 158: Electrical and Electronics Engineering Laboratory V
Lab Exercise #5: Analog-to-Digital Conversion
}
}
}
* and conversion, the most-recent result is always in
* ADC1BUF0.
*/
adc_value = ADC1BUF0;
AD1CON1bits.DONE = 0;
AD1CON1bits.SAMP = 1;
if (AD1CON1bits.SAMP) {
/*
* Wait 5 cycles before initiating conversion
*
* If other tasks need to be done in the interim, a
* solution using a counter to keep track of the number
* of iterations since last completion is required.
*/
asm volatile ("nop");
asm volatile ("nop");
asm volatile ("nop");
asm volatile ("nop");
asm volatile ("nop");
AD1CON1bits.SAMP = 0;
}
// This return must never be reached
return 1;
Page 8 of 8; Last revised 2021-12-07 12:40:33
Download