text: ME 4370/5370
  The MC9S12 contains two eight-channel, 10-bit A/D converter with +/- 1 LSB accuracy. Port AD bits PADx0-PADx7 are the analog input pins which are sampled and converted to 10-bit digital values. The results of the A/D conversion are placed in the data registers ADRxDnH, ADRxDnL. There are several A/D control registers, named ATDxCTL1 – ATDxCTL5, ATDxStat, which control the operation of the A/D. These registers must be initialized to perform the A/D process. These will be described in the following sections. In addition, a single reference voltage state must be physically set over the pins VRH and VRL (see the breakout board for these pins). VRH must not exceed 6V, and VRL must not go below 0V. The range VRH - VRL must be greater than or equal to 0 V. Using this reference range, all analog inputs are converted to a value using a linear conversion over this range. For example, if VRH = 5V and VRL = 0V, then an analog input of 2.5 V would be converted to a digital number of ½*28 or ½*256 or 127 (1 V input would be converted to 1/5*28 or 1/5*256). Note that the resolution is given as:
  “The Analog-to-Digital (A/D) Machine performs analog to digital conversions. The resolution of the A/D converter is program selectable at either 8 or 10 bits. This machine uses a successive approximation A/D architecture. It functions by comparing the stored analog sample potential with a series of digitally generated analog potentials. By following a binary search algorithm, the converter locates the approximating potential that is nearest to the sampled potential.”
  This register and the basic control bits are shown below. Of primary importance is the ADPU bit (A/D power up bit), which must be set to one to power up the A/D, and the interrupt enable bits if desired. For example, writing $80 to ATDxCTL2 will power up the A/D. After power-up, a 100 microsec. delay is required before using the A/D.
  0 = Disables A/D for reduced power consumption (default)
  1 = Allows the A/D to function normally
  A short time delay of 100 micro seconds should be executed after powering up the A/D to allow all analog circuits to be stabilized.
  After power-up (Step 1), a 100 microsec. delay is required before using the A/D.
  Set the conversion sequence mode using ATDxCTL3 (ATD ConTroL register 3, $0003 offset). This register controls the number of samples per conversion that are to be performed.
  These represent a binary value which is the length of the conversion sequence (as in Table 98, advanced S12 Information Manual)
  These bits also determine the result register assignments. The first result is placed in the first register, and so on. This is demonstrated in Table 99:
  Step 4: Set sampling and conversion time. The sampling and conversion time can be controlled, with ATDxCTL4 (offset $0004, address $0064). It is advised to use the default values. The general rule of thumb is that high-impedance sources require a longer sample time. Therefore, no action needs to be taken in step 3 for basic implementation
  Bit 7 6 5 4 3 2 1 bit 0
  Reset 0 0 0 0 0 1 0 1
  Step 5: Set ATDCTL5. The ATDxCTL5 register ($0065, $0005 offset) controls the sampling modes and starts the conversion process. This is done through the following bits:
  DJM – Data is justified left or right
  DSGN – Data is signed or unsigned
  SCAN – set for either a single scan sequence (0) or a continuous scan sequence (1)
  MULT – set to allow conversion of a single channel (0) or multiple channels (1)
  CC-CA – Selects the channel for conversion (when MULT=0)
  Note: If conversion is to be completed on 1 channel, then 4 or 8 conversions on that one channel are performed and stored. If conversion is to be completed on multiple channels, then 4 or 8 channels are read and stored. The following charts provide more information on ATDCTL5 selection.
  Reset 0 0 0 0 0 0 0 0
  0 = Data is left justified
  1 = Data is right justified
  For 10-bit resolution, left justified mode places the result into result register bits 6 through 15 (15 is MSB). In right justified mode, the results is placed into bits 0 through 9 (9 is MSB). For 8 bit resolution, left justified placed the result in the high byte, right justified into the low byte.
  DSGN: Sign of ATD
  0 = Convert as unsigned values
  1 = Convert as signed values
  SCAN: Enable continuous channel scan
  0 = Single conversion sequence each time ADTCTL5 is written (default)
  1 = Continuous conversion sequences
  MULT: Enable multichannel conversion
  0 = All conversions are done on a single input channel selected by CC-CA (default)
  1 = Each of the conversions are done on multiple channels
  When Mult is 0, the ATD samples only from the specified analog input channel for the entire conversion sequence (selected by CC-CA). When Mult is 1, the ATC samples across x channels (Number of channels determined by S8C-S1C), and CC-CA determines the starting input channel for conversion, with following channels sampled in the sequence determined by incrementing channel selection code.
  2. Wait for 100 microsec. Before using the A/D
  3. Select number of conversions by setting ATDCTL3
  4. Select the resolution and sample time, ATDCTL4
  5. Choose DJM, DSGN, SCAN, MULT and CC-CA bits in ATDCTL5
  6. Write to ATDCTL5 to start the conversion
  7. Wait for the conversion sequence to complete by polling the SCF bit in ATDSTAT
  8. Read the result in the ATDDR0H-ATDDR7H register
  #include /* derivative information */
  #include
  #include "lcd.h"
  #pragma LINK_INFO DERIVATIVE "mc9s12dp256b"
  void main( void )
  {
  unsigned int i; //loop counter
  char display[17] = "Voltage = x.x "; // initalize string
  LCD_init(); // Enable the LCD display
  ATD1CTL2 = 0x80; //normal A2D operation initialization
  for(i = 0; i < 1000; i++); //delay for initialization
  ATD1CTL3 = 0x08; // 1 conversion per scan
  ATD1CTL5 = 0x20; //continuous scan on AD1 channel 0 (PAD8)
  while(1)
  while(!(ATD1STAT0 & 0x80)); //wait for scan conversion to complete
  result = (float) ATD1DR0H / 0.051; %result in millivolts
  sprint(display, ‘The result is %d’,result);
  writeLine(display, 0); //write to screen
  }
  }