* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
Download ADC
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
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 in-1 SAR[i] 1 Convert the value in SAR to a voltage ii-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 */ } }