Download ADC

Survey
yes no Was this document useful for you?
   Thank you for your participation!

* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project

Document related concepts

Flip-flop (electronics) wikipedia , lookup

Buck converter wikipedia , lookup

Switched-mode power supply wikipedia , lookup

Control system wikipedia , lookup

Rectiverter wikipedia , lookup

Electric vehicle conversion wikipedia , lookup

Time-to-digital converter wikipedia , lookup

Opto-isolator wikipedia , lookup

Immunity-aware programming wikipedia , lookup

Analog-to-digital converter wikipedia , lookup

Register renaming wikipedia , lookup

Transcript
ECE 4510/5530
Microcontroller Applications
Analog-to-Digital Converter
atd.c
Dr. Bradley J. Bazuin
Associate Professor
Department of Electrical and Computer Engineering
College of Engineering and Applied Sciences
Chapter 12: Parallel Ports
•
•
•
•
•
HCS12 ADC
ATD Module Block Diagram
ATD Module Pins
ATD Module Registers
ATD Coding
– Atd.c
ECE 4510
2
Successive Approximation Method
(1 of 3)
• Approximates the analog signal in n steps.
• The first step initializes the SAR register to 0.
• Perform a series of guessing steps that starts from the most
significant bit and proceeding toward the least significant
bit.
• For every bit in SAR register guess it to be 1.
• Converts the value of the SAR register to analog voltage.
• Compares the D/A output with the analog input and clears
the bit to 0 if the D/A output is larger.
Successive Approximation Method
(2 of 3)
analog
comparator
+
Vin (analog input)
-
Clock
Successive
Control
Logic approximation
register (SAR)
Digital-to-analog
converter
Output
Latch
VRH
VRL
Digital
code
Figure 12.4 Block diagram of a successive approximation A/D converter
Successive Approximation Method
(3 of 3)
Start
SAR[n-1, ..., 0]  0
in-1
SAR[i]  1
Convert the value in
SAR to a voltage
ii-1
Is the
Converted voltage
greater than
the input?
yes
SAR[i]  0
no
no
i = 0?
yes
Stop
Figure 12.5 Successive approximation A/D conversion method
ATD Block Diagram
Bus clock
Clock
prescaler
Conversion
complete interrupt
ATD clock
Mode and timing control
results
VRH
VRL
VDDA
VSSA
Successive
apparoximation
Register (SAR)
and DAC
ATD 0
ATD 1
ATD 2
ATD 3
ATD 4
ATD 5
ATD 6
ATD 7
AN7/PAD7
AN6/PAD6
AN5/PAD5
AN4/PAD4
AN3/PAD3
AN2/PAD2
AN1/PAD1
AN0/PAD0
sample and hold
1
Analog
MUX
1
+
comparator
ATD input enable register
Port AD data register
Figure 12.8 The HCS12 ATD block diagram
Signal Pins Related to A/D Converter
• The AD0 module has analog input pins AN0 ~ AN7.
– The AN7 pin can be optionally used as the trigger input pin for
AD0 module.
• The AD1 module has analog input pins AN8 ~ AN15.
– The AN15 pin can be optionally used as the trigger input pin for
AD1 module.
• VRH and VRL are the high and low reference voltage input.
• VDDA and VSSA are power supply and ground inputs for the
A/D converters.
Registers Related to A/D Converters
• Each A/D module has the following registers:
– Six control registers: ATDxCTL0 ~ ATDxCTL5.
(ATDxCTL0 and ATDxCTL1 are used for factory testing only).
– Two status registers: ATDxSTAT0 and ATDxSTAT1
– Two testing registers: ATDxTEST0 and ATDxTEST1
– One digital input enable register: ATDxDIEN
– One digital port data register: PTADx
– Eight 16-bit result registers ATDxDR0~ATDxDR7
– where, x = 0 or 1
Important Controls
• The ATD Clock must operate at a frequency between
500 kHz and 2 MHz. Always try for 2 MHz.
• Either single or multiple data samples will be taken when
commanded.
– Can be from the same analog input or from multiple inputs
• Figure out the Data Buffer, FIFO or Sequential Buffer
• Data format: unsigned right aligned preferred
– Signed left align is useful too.
• External or Internal conversion trigger
– Writing to ATDxCTRL5 starts internal conversion
ECE
4510/5530
9
Example Initialization
void adc0_init(void) //initialize ADC0
{
// General ADC Initialization
// Power Up, Fast Flag Clear, Power Down in Wait, trigger not by input (edge trigger), no ASCIE
ATD0CTL2
= ADPU | AFFC | AWAI;
delay(10);
// Delat to let the ATD power up
// Conversion sequence length (SxC = 0x1), no FIFOing, Freeze after completing the conversion
ATD0CTL3
= S1C | FRZ1 ;
ATD0CTL3
&= ~FIFO ;
// 10-bit res, 16 clock SMP, (PRS = 5 for 24 MHz or 1 for 8 MHz E-clock)
ATD0CTL4
= SMP1 | SMP2 | 0x05;
ATD0CTL4
&= ~(SRES8);
// right justify, unsigned, do not scan, not Multichannel
ATD0CTL5
= DJM | SMP2 | 0x05;
ATD0CTL5
&= ~(DSGN | SCAN | MULT);
}
ECE
4510/5530
10
ATD Control Register 2
(ATD0CTL2, ATD1CTL2)
reset:
7
6
5
ADPU
AFFC
AWAI
0
0
0
4
3
ETRIGLE ETRIGP
0
0
2
1
0
ETRIGE
ASCIE
ASCIF
0
0
0
ADPU: ATD power down bit
0 = power down ATD
1 = normal ATD operation
AFFC: ATD fast flag clear all bit
0 = ATD flag is cleared normally, i.e., read the status register before reading the result
register
1 = any access to a result register will cause the associated CCF flag to clear
automatically if it is set at the time
AWAI: ATD power down in wait mode bit
0 = ATD continues to run when the HCS12 is in wait mode
1 = halt conversion and power down ATD during wait mode
ETRIGLE: External trigger level/edge control
This bit controls the sensitivity of the external trigger signal. Details are shown in Table
12.1.
ETRIGP:External trigger polarity
This bit controls the polarity of the external trigger signal. See Table 12.1 for details.
ETRIGE: External trigger mode enable
0 = disable external trigger on ATD channel 7
1 = enable external trigger on ATD channel 7
ASCIE: ATD sequence complete interrupt enable bit
0 = disables ATD interrupt
1 = enables ATD interrupt on sequence complete (ASCIF = 1)
ASCIF: ATD sequence complete interrupt flag
0 = no ATD interrupt occurred
1 = ATD sequence complete interrupt pending
Figure 10.9 ATD control register 2 (ATDxCTL2, x = 0 or 1)
ATD Control Register 3
(ATD0CTL3 and ATD1CTL3)
reset:
7
6
5
4
3
2
1
0
0
S8C
S4C
S2C
S1C
FIFO
FRZ1
FRZ0
0
0
0
0
0
0
0
0
S8C,S4C,S2C,S1C: Conversion sequence limit
0000 = 8 conversions
0001 = 1 conversion
0010 = 2 conversions
0011 = 3 conversions
0100 = 4 conversions
0101 = 5 conversions
0110 = 6 conversions
0111 = 7 conversions
1xxx = 8 conversions
FIFO: Result register FIFO mode
0 = conversion results are placed in the corresponding result
register up to the selected sequence length
1 = conversion results are placed in consecutive result registers
(wrap around at end)
FRZ1 and FRZ0: background debug (freeze) enable bit
00: continue conversions in active background mode
01: reserved
10: finish current conversion, then freeze
11: freeze immediately when background mode is active
Figure 10.10 ATD control register 3 (ATDxCTL3, x = 0 or 1)
ATD Control Register 4
(ATD0CTL4 and ATD1CTL4)
•
•
•
This register sets the conversion
clock frequency, the length of
the second phase of the sample
time, and the resolution of the
A/D conversion.
Writes to this register will abort
the current conversion.
There are two stages in the
sample time. The first stage
sample time is fixed at two
conversion clock period. The
second stage is selected by
SMP1 and SMP2 bits of this
register.
7
6
SRES8 SMP1
reset:
0
0
5
4
3
2
1
0
SMP0
PRS4
PRS3
PRS2
PRS1
PRS0
0
0
0
1
0
1
SRES8: ATD resolution select bit
0 = 10-bit operation
1 = 8-bit operation
SMP1 and SMP0: select sample time bits
These bits are used to select the length of the second phase of the
sample time in units of ATD conversion clock cycles. See Table
12.2.
PRS4--PRS0: ATD clock prescaler bits
These five bits are the binary value prescaler value PRS. The ATD
conversion clock frequency is calculated as follows:
ATDclock =
[bus clock]
PRS + 1
 0.5
The ATD conversion frequency must be between 500KHz and 2
MHz. The clock prescaler values are shown in Table 12.3.
Figure 12.11 ATD control register 4 (ATDxCTL4, x = 0 or 1)
ATD Control Register 5
(ATD0CTL5 and ATD1CTL5)
•
•
•
•
•
Selects the type of conversion
sequence and the analog input
channels to be sampled.
Writes to this register will abort
the current conversion.
Table 12.4 selects the channel to
be converted.
Table 12.5 summarizes the result
data formats available and how
they are set up using the control
bits.
Table 12.6 illustrates the
difference between the signed and
unsigned, left justified and right
justified output codes for an input
signal range between 0 and
5.12V.
7
DJM
reset:
0
6
5
DSGN SCAN
0
0
4
3
2
1
0
MULT
0
CC
CB
CA
0
0
0
0
0
DJM: Result register data justification
0 = left justified data in the result registers
1 = right justified data in the result registers
DSGN: Result register data signed or unsigned representation
0 = unsigned data representation in the result registers
1 = signed data representation in the result registers (not available
in right justification)
SCAN: Enable continuous channel scan bit
0 = single conversion sequence
1 = continuous conversion sequences (scan mode)
MULT: Enable multichannel conversion bit
0 = sample only one channel
1 = sample across several channels
CC, CB, and CA: Channel select code
The channel selection is shown in Table 12.4.
Figure 12.12 ATD control register 5 (ATDxCTL5, x = 0 or 1)
Example Test/Cal Read
void adc0_cal(void) //initialize ADC1
{
extern int calbuf[3];
// Read reference low value
ATD0TEST1 = 0x01;
// Set the SC bit
ATD0CTL5 = (ATD0CTL5 & 0xF8) | CC | CA; // select the refernce low 0%101
while(!(ATD0STAT0 & SCF)); // wait until the conversion is complete
calbuf[2] = ATD0DR0;
// Read reference high value
ATD0CTL5 = (ATD0CTL5 & 0xF8) | CC; // select the refernce high 0%100
while(!(ATD0STAT0 & SCF)); // wait until the conversion is complete
calbuf[0] = ATD0DR0;
// Read reference middle value
ATD0CTL5 = (ATD0CTL5 & 0xF8) | CC | CB; // select the refernce high 0%110
while(!(ATD0STAT0 & SCF)); // wait until the conversion is complete
calbuf[1] = ATD0DR0;
ATD0TEST1 = 0x00;
// Reset the SC bit
}
ECE
4510/5530
15
ATD Test Register 1
(ATD0TEST1, ATD1TEST1)
• The SC bit is used to enable special channel conversion.
reset:
7
6
5
4
3
2
1
0
0
0
0
0
0
0
0
SC
0
0
0
0
0
0
0
0
SC: Special channel conversion bit
If this bit is set, the special channel conversion can be selected
using CC, CB, and CA of the ATDxCTL5 register. Table 12.7
shows the selection.
0 = special channel conversions disabled
1 = special channel conversions enabled
Figure 12.14 ATD test register 1 (ATDxTEST1, x = 0 or 1)
Table 12.7 Special channel select code
SC
CC
CB
CA
Analog input channel
1
1
1
1
1
0
1
1
1
1
x
0
0
1
1
x
0
1
0
1
Reserved
VRH
VRL
(VRH + VRL)/2
Reserved
ATD Status Register
(ATD0STAT0 and ATD1STAT0)
• Each status flag can be cleared by writing a 1 to it.
reset:
7
6
SCF
0
0
0
5
4
ETORF FIFOR
0
0
3
2
1
0
0
CC2
CC1
CC0
0
0
0
0
SCF: Sequence complete flag
0 = conversion sequence not completed
1 = conversion sequence has completed
ETORF: External trigger overrun flag
0 = no external trigger overrun has occurred
1 = external trigger overrun has occurred
FIFOR: FIFO overrun flag
0 = no overrun has occurred
1 = an overrun has occurred
CC2, CC1, CC0:conversion counter
The conversion counter points to the result register that will receive
the result of the current conversion.
In non-FIFO mode, this counter is reset to 0 at the begin and end of
the conversion.
In FIFO mode, this counter is not reset and will wrap around when
its maximum value is reached.
Figure 12.13 ATD status register 1 (ATDxSTAT0, x = 0 or 1)
Example Read One Sample
// read voltage from one channel once
unsigned int adc0_in1(char adc_channel)
{
unsigned int adata;
// Conversion sequence length (SxC = 0x1)
ATD0CTL3 = (ATD0CTL3 & 0x07) | S1C;
ATD0CTL5 = (ATD0CTL5 & 0xF8) | adc_channel; // select the channel
// Wait for the ADC to convert
while(!(ATD0STAT0 & SCF)); // wait until the conversion is complete
adata = ATD0DR0;
// read the result
return(adata);
}
ECE
4510/5530
18
Example Read Four Samples
// read voltage from one channel four times
unsigned int adc0_in4(char adc_channel)
{
unsigned int adata;
extern adcinbuf[4];
// Conversion sequence length (SxC = 0x4)
ATD0CTL3 = (ATD0CTL3 & 0x07) | S4C;
ATD0CTL5 = (ATD0CTL5 & 0xF8) | adc_channel; // select the channel
while(!(ATD0STAT0 & SCF));
adcinbuf[0] = ATD0DR0;
adcinbuf[1] = ATD0DR1;
adcinbuf[2] = ATD0DR2;
adcinbuf[3] = ATD0DR3;
return(adcinbuf[3]);
// wait until the conversion is complete
/* save results right justified */
}
ECE
4510/5530
19
ATD Conversion Result Registers
(ATDxDRy, x = 0~1, y= 0~7)
• Each result register is 16-bit ATDxDRy
and can be further divided into two 8-bit registers
ATDxDRHy and ATDxDRLy.
• The A/D conversion result can be stored right-justified or
left-justified.
ATD Status Register 1
(ATD0STAT1, ATD1STAT1)
• A flag can be cleared by one of the following:
– Write to ATDxCTL5 register.
– If AFFC = 0 and read of ATDxSTAT1 followed by read of result
register ATDxDRy.
– If AFFC = 1 and read of result register ATDxDRy
reset:
7
6
5
4
3
2
1
0
CCF7
CCF6
CCF5
CCF4
CCF3
CCF2
CCF1
CCF0
0
0
0
0
0
0
0
0
CCFx: conversion complete flag x (x = 7~0)
0 = conversion number x not completed
1 = conversion number x has completed, result in ATDyDRx
Figure 12.15 ATD status register 1 (ATDxSTAT1, x = 0 or 1)
The A/D Conversion Time
• The A/D conversion time is the sum of the converter time
and the sample time.
• The conversion timings for 500KHz and 2 MHz are shown
in Table 12.8.
Table 12.8 ATD conversion timings
ATD clock
frequency
resolution
converter
time
2+2 sample
clocks
2+4 sample
clocks
2+8 sample
clocks
2+16 sample
clocks
2 MHz
2 MHz
500 KHz
500 KHz
8-bit(1)
10-bit(2)
8-bit
10-bit
4 s
5 s
16 s
20 s
2 s
3 s
5 s
9 s
8 s
12 s
20 s
36 s
Note. 1. The fastest 8-bit resolution conversion time is 4 s + 2 s = 6 s.
2. The fastest 10-bit resolution conversion time is 5 s + 2 s = 7 s.
C Program to Collect 20
Samples from Channel AN7
#include “c:\egnu091\include\delay.c”
#include “c:\egnu091\include\hcs12.h”
void openAD0 (void)
void openAD0 (void);
{
ATD0CTL2
= 0xE0;
int buf[20];
delayby10us(2);
void main (void)
ATD0CTL3
= 0x22;
{
ATD0CTL4
= 0x05;
}
int i;
openAD0();
for (i = 0; i < 5; i++) {
ATD0CTL5 = 0x87;
/* start an A/D conversion */
while (!(ATD0STAT0 & SCF)); /* Has A/D conversion completed? */
buf[4*i + 0] = ATD0DR0;
/* save results right justified */
buf[4*i + 1] = ATD0DR1;
buf[4*i + 2] = ATD0DR2;
buf[4*i + 3] = ATD0DR3;
}
while(1);
}
Temperature Sensor LM35
• Precision Centigrade Temperature Sensor
– It has three pins with voltage output directly proportional to the
ambient temperature.
• It can measure temperature in the range of +2ºC to 150ºC
with a supply from 4~205V.
• Voltage output at 0 mV + 10 mV/ºC
C Program for Temperature
Measurement (1 of 3)
#include “c:\egnu091\include\hcs12.h”
#include “c:\egnu091\include\delay.c”
#include “c:\egnu091\include\convert.c”
#include “c:\egnu091\include\lcd_util_dragon12.c”
void openAD0(void);
char buf[8];
char *msg1 = "temperature = ";
char *blanks = "
";
void main (void)
{
int temp1,temp2;
char sign,fdigit,frem;
char *ptr;
delayby100ms(2);
/* wait for LCD kit to initialize */
openlcd();
/* configure LCD kit */
openAD0();
/* configure AD0 module */
cmd2lcd(0x80);
/* set cursor to upper left corner */
puts2lcd(msg1);
/* output the message "temperature = " */
C Program for Temperature
Measurement (2 of 3)
while(1) {
sign = 0;
/* initialize sign to be positive */
ATD0CTL5 = 0x87; /* start a conversion with result right justified */
while(!(ATD0STAT0 & SCF)); /* wait until conversion is done */
temp1 = (ATD0DR0 * 10) / 62;
/* integer part of temperature */
temp2 = (ATD0DR0 * 10) % 62; /* remainder part */
temp1 -= 40; /* subtract the offset from the actual temperature */
if (temp1 < 0){
/* temperature is negative */
sign = 1;
temp1 = ~temp1 + 1;
/* find the magnitude of temperature */
if (temp2) { /* remainder not zero */
temp1 --;
temp2 = 62 - temp2;
}
}
fdigit = (temp2 * 10) / 62;
/* compute the fractional digit */
frem = (temp2 * 10)%62;
if (frem > 31) {
fdigit ++;
if (fdigit == 10) {
/* round off the fraction digit */
fdigit = 0;
temp1++;
}
C Program for Temperature
Measurement (3 of 3)
}
if (sign) {
ptr = &buf[1];
/* point to the first space to hold ASCII string */
buf[0] = 0x2D;
/* store minus sign as the first character */
}
else
ptr = &buf[0];
int2alpha(temp1,ptr);
/* convert the integer part to ASCII string */
ptr = &buf[0];
while(*ptr)
/* find the end of the integer string */
ptr++;
*ptr++ = '.';
*ptr++ = fdigit + 0x30;
*ptr++ = 223;
/* add a degree character */
*ptr++ = 'C';
/* temperature in Celsius */
*ptr = 0;
/* terminate the temperature string */
cmd2lcd(0xC0);
/* move cursor to 2nd row */
puts2lcd(blanks);
/* clear the 2nd row */
cmd2lcd(0xC5);
/* set cursor to column 5 row 2 */
puts2lcd(&buf[0]); /* output the temperature */
delayby100ms(2); /* wait for 0.2 seconds */
}
}