manufacturer of I/O-rich SBCs, operator interfaces, handheld instruments, and development tools for embedded control low cost single board computers, embedded controllers, and operator interfaces for scientific instruments & industrial control development tools for embedded control order our low cost I/O-rich embedded control products embedded controller manufacturer profile single board computers & embedded controllers development tools & starter kits for your embedded design operator interfaces with touchscreens and graphical user interface plug-in expansion modules for digital & analog I/O C language & Forth language integrated development tools, IDE single board and embedded computer accessories embedded controller enclosures, bezels, environmental gaskets

The C Programmer’s Guide to the QVGA Controller

Table of Contents

PART 1 GETTING STARTED

Introduction. How to Use This Manual

Chapter 1: Getting to Know Your QVGA

PART 2 PROGRAMMING THE QVGA CONTROLLER

Chapter 2: Your First Program

Chapter 3: The IDE: Writing, Compiling, Downloading and Debugging Programs

Chapter 4: Making Effective Use of Memory

Chapter 5: Programming the Graphical User Interface

Chapter 6: Real Time Programming

Chapter 7: Failure and Run-Time Error Recovery

PART 3 COMMUNICATIONS, MEASUREMENT, AND CONTROL

Chapter 8: Digital and Timer-Controlled I/O

Chapter 9: Data Acquisition Using the QVGA Controller

Examining the Demonstration Program

Fundamentals of Analog to Digital Conversion

Determining the Resolution of an A/D Converter

Converting an A/D Count into Its Equivalent Voltage Reading

Using the 8-bit A/D

Using the 12-bit A/D

Running the Sample Program

Chapter 10: Outputting Voltages with Digital to Analog Conversion

Chapter 11: Serial Communications

Chapter 12: The Battery-Backed Real Time Clock

PART 4: PUTTING IT ALL TOGETHER

Chapter 13: A Turnkeyed Application

PART 5: REFERENCE DATA

Appendix A: QVGA Electrical Specifications

Appendix B: Connector Pinouts

Appendix C: Physical Dimensions

Appendix D: Schematics (pdf)

Chapter 9

<< Previous | Next>>

Chapter 9: Data Acquisition Using Analog to Digital Conversion

This chapter shows how to use the 24 channels of analog input/output on the QVGA Controller. The QVGA Controller  includes a high performance 8- channel 12-bit analog to digital (A/D) converter.  The 12-bit A/D can be configured to convert 8 channels of single-ended inputs or 4 channels of differential signal inputs, or combinations of single-ended and differential signals.  The input voltages can be unipolar, with a range from 0 to 5 volts, or bipolar, with a nominal range from -5 to +5 volts.  This voltage range can be adjusted using low and high reference voltages.  The demonstration code for this chapter in the ANALOGIO.C file also shows how to use C arrays and FORTH_ARRAYS as buffers, and describes how to store semi-permanent information in the QVGA Controller’s Electrically Erasable PROM (EEPROM).

This chapter describes the analog I/O devices available on the QED Board, explains how to connect the converters to external signals, and details the built-in driver routines that make analog I/O easy to use. Simple code is presented to calculate measured voltages based on A/D readings and to calculate the digital values required to instruct a DAC to output a specified voltage.  At the end of the chapter, sample circuitry and code is presented to convert a pair of 8 bit DACs into a high resolution DAC.

Data Acquisition Using the QVGA Controller

Many instrument applications require monitoring of analog signals and generation of analog control voltages.  Analog to digital (A/D) converters and digital to analog converters (DACs) can perform these functions.  An A/D converter samples analog signals and converts them to digital values that can be stored, processed, or displayed.  A DAC generates an analog voltage whose value is proportional to a specified digital number.

The resolution of an A/D or DAC is specified in bits.  For example, an 8-bit DAC can output any of 28 or 256 distinct analog levels; 256 is the maximum number of levels representable by an 8 bit binary number.  Similarly, a 12-bit A/D converts an analog signal into one of 4096 discrete digital numbers.

Table 9‑1      Analog I/O

I/O Lines

Type

Port Address

Comments / Alternate Uses

8

8-bit 0-5 V analog inputs

PE 0-7

Alternately may be used as digital inputs.

8

12-bit analog inputs

 

8 channels single-ended or 4 channels differential, unipolar (0-5 V) or bipolar (±5 V).

8

8-bit analog outputs

 

Multiplying, cascadable, 0-3V output DACs.

24

Analog I/O lines

 

 

The QVGA Controller hosts both analog to digital and digital to analog converters to address a wide variety of instrumentation and control applications.  It includes three 8-channel analog I/O devices:

  An 8-channel 8-bit analog to digital (A/D) converter that is built into the 68HC11 processor chip converts unipolar signals with a nominal 0 to +5 volt range;

  An 8-channel 12-bit A/D converter; and,

  An 8-channel 8-bit digital to analog converter (DAC), discussed in the next Chapter .

The 16 analog inputs and 8 analog outputs are brought out to a 40 pin analog connector (H2) on the QED-Flash Board (the smaller of the two boards of the QVGA Controller); the connector diagrams in an Appendix  specify the pin assignments.

The 8 bit A/D Converter

The 8 bit A/D converter in the processor converts unipolar signals with a nominal 0 to +5 volt range, and conversion results are returned in registers in the 68HC11.  The analog inputs are connected to the PORTE pins on the processor; these can be used as digital inputs if the 8 bit A/D is disabled. 

The 12 bit A/D Converter

The 12 bit A/D converter is interfaced to the processor via the fast serial peripheral interface (SPI).  Its chip select is a memory-mapped signal generated by the onboard logic.  The 12 bit A/D can be configured to convert 8 channels of single ended inputs or 4 channels of differential signal inputs, or combinations of single-ended and differential signals.  The input voltages can be unipolar, with a range from 0 to 5 volts, or bipolar, with a nominal range from -5 to +5 volts.  This voltage range can be adjusted via the low and high reference voltages named VRL and VRH.

Examining the Demonstration Program

The code discussed in this section is located in the file named ANALOGIO.C in the \MOSAIC\DEMOS_AND_DRIVERS\MISC\C EXAMPLES directory.  Most of the functions in this file are interactive versions of functions declared in the ANALOG.H file in the \MOSAIC\FABIUS\INCLUDE\MOSAIC directory; they are described in detail in the Control-C Glossary.

We recommend that you compile and download the ANALOGIO.C program now so that you can interactively work through the exercises in this chapter.  Simply use your TextPad editor to open ANALOGIO.C, and click on the Make Tool (the Make icon) to create the download file named ANALOGIO.DLF.  Then enter the Mosaic Terminal program, and type:

WARM

or:

COLD

to terminate any prior multitasking program that might be running, and select the “Send Text File” menu item to send ANALOGIO.DLF to the QVGA Controller.

Fundamentals of Analog to Digital Conversion

An analog to digital converter samples an analog signal and outputs a digital number that is proportional to the analog signal.  The A/D converters on the QVGA Controller sample input voltages and communicate the digital result to the 68HC11 processor.

The analog input signal must be within the input range of the A/D converter.  On the QVGA Controller, the lower bound of the range is equal to the voltage on VRL (voltage reference/low) and the upper bound of the allowable input range is equal to the voltage on VRH (voltage reference/high). The VRL and VRH references are brought out to the 40 pin Analog I/O connector and control the input voltage range of both the 8 bit and 12 bit A/D converters.  Their default values are 0 Volts (analog ground) and 5.0 Volts (analog +5V), respectively.  They can be driven to different voltages by external circuitry as described below.

The converter measures the input voltage with a certain specified resolution.  The resolution is the granularity with which the measurement is performed.  It can be specified as a number of bits or as a voltage increment.  For example, an A/D converter with only 1 bit of resolution and a 5 Volt input range would classify all voltages from 0 to just under 2.5 Volts as the digital value 0, and voltages from 2.5 Volts to 5 Volts as the digital value 1.  This converter has a resolution equal to 1 bit, which corresponds to 2.5 Volts per count.

The converter measures the input voltage with a specified accuracy.  The accuracy tells how close the measured value is to the actual voltage.  A typical 8 bit A/D converter is accurate to within plus or minus one least significant bit.

Determining the Resolution of an A/D Converter

The VRL and VRH analog input reference pins define the lower and upper voltages that can be converted by both the 8 bit A/D and the 12 bit A/D.  The resolution depends on the input voltage range.  The measurement resolution of a B-bit A/D, expressed in Volts per count, is

Eqn. 9‑1      Resolution = (VRH - VRL) / 2B                         [Volts per count]

where 2B is the number of counts that can be represented by a B-bit number.  From this equation we see that resolution becomes finer (better) as B grows larger or as the reference voltage range (VRH - VRL) gets smaller.  For the 8 bit A/D the resolution is

Eqn. 9‑2      8 bit Resolution = (VRH - VRL)/256                [Volts per count]

and for the 12 bit A/D the resolution is

Eqn. 9‑3      12 bit Resolution = (VRH - VRL)/4096            [Volts per count]

With the default VRL and VRH of 0 V and 5 V, respectively, the resolution of the 8 bit converter is 19.5 mV per count, and the resolution of the 12 bit converter is 1.22 mV per count.  The finer resolution of the 12 bit converter combined with its higher accuracy yields a more precise measurement of the analog input.

Converting an A/D Count into Its Equivalent Voltage Reading

To convert the 8-bit count returned by the A/D converter into an equivalent voltage, use the formula

Eqn. 9‑4      Input Voltage = VRL + ( Count * Resolution)          Eqn. 6.4

Combining this with Eqn. 6.1 yields

Eqn. 9‑5      Input Voltage = VRL + Count * (VRH - VRL) / 2B         Eqn. 6.5

Figure 9‑1    Conversion function for the 8-bit A/D.

Using the 8-bit A/D

Initializing the 8 Bit A/D

The 8 bit A/D is inside the 68HC11 processor chip, and is accessed via PORTE. This 8 bit port can be used as either an 8 channel A/D or as an octal digital input port.  When the QVGA Controller is first powered up, or after a reset or restart, the 8 bit A/D converter is disabled and PORTE is configured as a digital input port.  To turn on the A/D converter, a program must call the function:

 

AD8On()

 

A/D8.ON

Another function named AD8Off() A/D8.OFF is available to turn off the 8 bit A/D so that PORTE once again acts as a digital input port. 

The function named

 

InitAnalog()

defined in the ANALOGIO.C file calls AD8On().  If you interactively execute InitAnalog(), as,

InitAnalog( )

the 8 bit A/D converter will be turned on and ready for use. 

In an autostarting application you should include InitAnalog()A/D8.ON in your start-up code.

Hardware Connections

To sample an analog voltage, attach a voltage with a value between zero and +5 Volts to the 8 bit A/D channel 0 input named AN0. For example, try connecting the 1.5Vref signal (pin 37 on the Analog I/O connector) to the AN0 input (pin 10 on the Analog I/O connector).  See tbe Appendix  for connector diagrams. 

The 8 bit A/D inputs are the PortE signals named PE0/AN0 through PE7/AN0 available at pins 3 through 10 on the Analog I/O connector (see Appendix A).  Each analog signal is converted to a number between 0 and 255 indicating its value relative to VRL (the low voltage reference) and VRH (the high voltage reference).  The default values are VRL = 0 Volts (analog ground) and VRH = 5 Volts (the analog +5 Volt supply, designated +5VAN).  The exact voltage difference between VRH and VRL varies slightly from board to board; it is a good idea to measure the value on your board to obtain the most exact voltage equivalents of the measured A/D results.

8-bit A/D Reference Voltage

You may connect circuitry to the VRL and VRH pins to drive these references to desired levels between 0 and 5 Volts.  For example, in some applications it may be possible to increase the resolution of the conversion by reducing the input voltage range (VRH-VRL) as specified by Figure 9‑1.

Motorola’s data books specify some restrictions on the values of the reference signals VRL and VRH  (MC68HC11F1 Technical Data Manual,  p.13-10) for the 8 bit A/D.  First, VRL and VRH must be less than +5.1 Volts and greater than 0 Volts.  Second, the voltage on VRL must be less than the voltage on VRH.  Third, the difference between the voltages, (VRH - VRL), should be greater than 3 Volts if the converter is to meet all of its stated specifications.  Also note that VRH and VRL are connected to both the 8 bit A/D and the 12 bit A/D, so changing the references affects both converters.

We can calculate the range of resolutions possible from the 8 bit A/D based on Motorola’s suggested limits on VRL and VRH.  Referring to Eqn. 9‑2, we see that the finest resolution is

  3 Volts / 256 bits = 11.7 mV/bit

and the coarsest resolution is

  5.1 Volts / 256 bits = 19.9 mV/bit

This resolution is the voltage equivalent of one (least significant) bit in the A/D count.  The accuracy of the 68HC11’s A/D converter is plus or minus one least significant bit.

Once you have obtained a digital conversion result from the A/D, it is easy to calculate the measured voltage.  With B equal to 8 bits in Eqn. 9‑5, the input voltage corresponding to a given digital conversion “count” is given by

Input Voltage = VRL + Count * (VRH - VRL)  Eqn. 6.6

256

For example, with VRL = 0 Volts, VRH = 5.0 Volts, and a measured count of 128 (one half the full scale count), the measured input voltage is

 

Input Voltage = 128 * 5.0 / 256 = 2.5 Volts

which is at the midpoint of the input voltage range, as expected.

Performing Conversions

Before using the 8-bit A/D, execute

A/D8.ON

to initialize the converter.  Connect the desired analog signals to the PortE inputs available at the Analog I/O connector (see Appendix A).

Placing a channel number between 0 and 7 on the stack and executing the routine

A/D8.SAMPLE  ( channel# -- result )

reads the specified 8 bit A/D channel and returns the result on the data stack.  For example, we can connect an analog voltage to channel 7 (pin 3 on the analog connector, labeled PE7/AN7) and print the conversion result by executing

7  A/D8.SAMPLE  .

A/D8.SAMPLE GETs and RELEASEs the resource variable named A/D8.RESOURCE which mediates access to the 8-bit A/D converter in multitasking applications (the “Multitasking” chapter in the Software Manual covers these topics in detail).  Unfortunately, about 80% of the execution time of the A/D8.SAMPLE routine is devoted to the GET and RELEASE overhead.  In non-multitasked applications or in applications where only one task uses the 8 bit A/D, the faster routine

(A/D8.SAMPLE)  ( channel# -- result )

may be used.  It acquires the A/D sample without executing GET or RELEASE, and with an 8 MHz crystal it executes in only 35 microseconds compared to 180 microseconds for A/D8.SAMPLE.

The QED-Forth routine

A/D8.MULTIPLE  ( xaddr\#samples\channel# -- )

rapidly obtains a multiple number of samples from an A/D channel and stores the results as sequential bytes in memory starting at the specified extended address.  If the specified xaddr is in common RAM (consult the memory map appendix in the Software Manual), the sampling frequency is approximately 40 kHz (corresponding to 25 microseconds per sample).  If the specified xaddr is in paged memory, the sampling frequency is approximately 10 kHz (corresponding to 100 microseconds per sample).  These sampling frequencies double if the QED Board is clocked at 16 MHz.

A/D8.MULTIPLE GETs the resource variable A/D8.RESOURCE before performing the first conversion, and RELEASEs the resource variable after performing the last conversion.  The GET and RELEASE operations require about 150 microseconds to execute with an 8 MHz crystal.  In non-multitasked applications or in applications where only one task uses the 8 bit A/D, the programmer may use

(A/D8.MULTIPLE)  ( xaddr\#samples\channel# -- )

which does not call GET and RELEASE and thus executes more rapidly.  The sampling frequency is the same as specified for A/D8.MULTIPLE, but the setup and exit time is reduced by 150 microseconds.

For example, to acquire sixteen samples from channel 7 and store them starting at address B000H\0 in common memory, execute

HEX  B000 0  10 7  A/D8.MULTIPLE

To view the results as stored in memory, execute

B000 0 10 DUMP

If a stable noise-free signal is attached to the PE7/AN7 input, the acquired samples should all be equal to within 1 count.

 

 

Interactively Perform the Conversion

The Convert8() function is defined near the middle of the ANALOGIO.C file; you can see from its definition that it is simply an interactively callable version of the AD8Sample() function.  Now that you have connected an input voltage to channel AN0, you can type from your terminal:

Convert8( int 0)

The printed return value summary displays the conversion count; you’ll see a printout that looks something like this:

Rtn:  -30722    77 =0x87FE004D =fp: -3.822E-34

We know that this function returns an integer, so we identify “77” (hex 0x004D) as the return value; the other numbers in the summary are irrelevant.  If the input is 1.5 volts, the result should be approximately 77 counts (256 * 1.5 / 5.0).  If the input voltage equals VRL (the low reference voltage, typically at 0 Volts), the result will equal 0.  If the input is within 1 bit of VRH (the high reference voltage, typically at 5.0 Volts), the result will equal decimal 255.  If the input is exactly half of (VRH - VRL), the result will equal decimal 128.   

Multiple 8 Bit A/D Conversions with Results Stored in a C Array

The function AD8Multiple() which is defined in the ANALOG.H file expects as inputs a buffer xaddress (32 bit extended address), a sampling interval parameter, the number of samples, and a channel number.  When called, it performs the specified number of conversions and saves the results as single bytes in the specified buffer.  As explained in the Glossary, the sampling interval parameter specifies the timing of the samples, with 0 representing the fastest sampling, and 65,535 representing the slowest sampling.  You can sample at up to 100 kHz (100,000 samples per second) using the 8-bit A/D, and sample at up to 36 kHz using the 12-bit A/D, provided the processor is devoted to this single task.

The AD8ToCArray() function defined in ANALOGIO.C uses a standard C one-dimensional array named results_8 as the data buffer.  The function accepts a channel number as input, performs conversions at the fastest sampling speed (100 kHz), and places the results in the array.  The number of samples is specified by the  DEFAULT_NUMSAMPLES constant which equals 16.  Because we have connected the channel 0 input (AN0) to 1.5VREF, let’s perform the multiple conversion on this channel.  Type at your terminal:

AD8ToCArray( int 0)

remembering to type at least one space after the ( character.  This function does not return a value, so the printed return value summary is not relevant. To see the results of the conversion, you could write a simple C function that prints the contents of results_8; this is left as an exercise for you.  You can also use the debugging routine named DUMP to view a hexadecimal dump of the buffer.  To do this, type at your terminal:

results_8  0  16 DUMP

DUMP is a QED-Forth function that expects as inputs an address (in this case, results_8 puts the address on the data stack), a page (0, representing the common page), and the number of bytes to be dumped (16).  You should see a printout similar to this:

pg  addr 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F  0123456789ABCDEF

00  8E2D 4D 4D 4D 4D 4D 4D 4D 4D 4D 4D 4D 4D 4D 4D 4D 4D  MMMMMMMMMMMMMMMM   

This tells us that the contents of the 16 bytes starting at address 0x8E2D (which is the address of results_8) all equal 0x4D.  To the right of the hex dump the ascii equivalent of the memory contents is displayed; this is not relevant for the numerical data here.  We conclude that the A/D conversion result was 0x4D, equivalent to decimal 77; this is the same value returned by the Convert8() function above.  Your results may vary slightly depending on the exact value of supply voltage on the QVGA Controller – the +5V supply is used as the default reference voltage.

For Experts: How To Use Additional Features of the 8 Bit A/D

The built-in driver routines for the 8 bit A/D are easy to use and address the requirements of most applications.  If you wish to gain a detailed understanding of the operation of the 8 bit A/D, or need to use one of its special modes, the information in Appendix H may prove useful.  For example, one of the operating modes allows the 8 bit A/D converter to continuously sample four different analog inputs in rapid succession.  Appendix H describes the operation of the 68HC11’s A/D and presents sample code to control the 8 bit A/D.

Using the 12-bit A/D

Initializing the 12 Bit A/D and DAC

[[[

The serial peripheral interface (SPI) provides a data pathway for communications with serial devices including the onboard 12 bit A/D and 8 bit DAC.  As described in the previous chapter, the SPI is a fast synchronous 4-wire serial interface implemented on PortD pins 2-5 on the 68HC11. 

The SPI is disabled after a reset or restart.  To turn on and initialize the SPI so that it is compatible with the 12 bit A/D and 8 bit DAC, execute

INIT.SPI ( -- )

This configures the 68HC11 as the SPI master, with a 1 Megabit/second data transfer rate if the processor is clocked at 8 MHz, and a 2 Megabit/second rate if the processor is clocked at 16 MHz.  Data is valid on the rising leading edge of the SPI clock. You may interface other peripherals via the SPI as long as each peripheral has its own unique chip select signal.

To turn off the SPI, execute

SPI.OFF ( -- )

When the SPI is off, the 12 bit A/D and 8 bit DAC cannot be accessed, and PortD pins 2-5 are available as general purpose digital I/O pins.

The best general purpose initialization routine for the 12 bit A/D and 8 bit DAC is the QED-Forth word

INIT.A/D12&DAC ( -- )

which calls INIT.SPI and also ensures the PIA is configured with PPB as an output port so that a valid chip select signal is generated for the 12 bit A/D.  This routine should be executed before using the 12 bit A/D or 8 bit DAC.

Before using the 12 bit A/D, execute

INIT.A/D12&DAC

to initialize the SPI (serial peripheral interface) and PIA (peripheral interface adapter) which handle data transfer and chip selection, respectively.  The chip select signal for the 12 bit A/D is generated by the most significant bit of peripheral port B (PPB7). 

Connect the desired analog signals to the inputs which are labeled 12AN0-12AN7 on the 40 pin analog I/O connector on the QED Board (see the pin diagram in Appendix A).

The 12 bit A/D converts each analog signal to a number between 0 and 4095 indicating its value relative to VRL (the low voltage reference) and VRH (the high voltage reference).  The default values are VRL = 0 Volts (analog ground) and VRH = 5 Volts (the analog +5 Volt supply, designated +5VAN).  The exact voltage difference between VRH and VRL varies slightly from board to board; to assure maximum accuracy you can use a high quality digital voltmeter measure the input voltage range (VRH-VRL) on your board.

]]]

12-bit A/D Reference Voltage

[[[

VRL and VRH are connected through onboard resistors to analog ground and analog +5 Volts, respectively; this allows you to change the references to other values.  The 12 bit A/D converter requires low impedance reference voltages to achieve specified performance.  Thus it is strongly recommended that the VRH and VRL pins on the 40 pin analog connector be directly connected to the desired reference voltages.  To achieve a full 5 Volt conversion range, use a wire to connect VRL (pin 1 on the analog connector) to analog ground (pin 19), and use a wire to connect VRH (pin 2) to +5 VAN (pin 20). 

You may also connect low-output-impedance circuitry to the VRL and VRH pins to drive these references to desired levels between 0 and 5 Volts.  For example, an operational amplifier may be used to establish the desired reference voltages. According to Eqn. 6.2, reducing the input voltage range (VRH-VRL) increases the attainable resolution, and this may be useful in some applications.  Please note, however, that as (VRH-VRL) is decreased, the noise and nonlinearity of the 12 bit converter increase.  The data sheet for the LTC1290 A/D converter chip in Appendix F contains graphs that detail these effect.  Also note that VRH and VRL are connected to both the 8 bit A/D and the 12 bit A/D, so changing the references affects both converters.

]]]

12-bit A/D Resolution

[[[

Referring to Eqn. 6.3, we see that the default resolution of the 12 bit A/D when VRL = 0 V and VRH = 5.0 Volts is

Eqn. 9‑5 5.0 Volts / 4096 bits = 1.22 mV/bit

This resolution is the voltage equivalent of one (least significant) bit in the A/D count.  The accuracy of the 12 bit A/D converter is plus or minus one least significant bit.

Once you have obtained a digital conversion result from the A/D, it is easy to calculate the measured voltage.  With B equal to 12 bits in Eqn. 6.5, the input voltage corresponding to a given digital conversion “count” is given by

Eqn. 9‑5 Input Voltage = VRL + Count * (VRH - VRL)/ 4096

For example, with VRL = 0 Volts, VRH = 5.0 Volts, and a measured count of 2048 (one half the full scale count), the measured input voltage is

Eqn. 9‑5 Input Voltage = 2048 * 5.0 / 4096 = 2.5 Volts

which is at the midpoint of the input voltage range, as expected.

]]]

Initializing the 12-bit A/D

The 12-bit A/D is interfaced to the 68HC11F1 via the high speed serial peripheral interface (SPI).  The function:

 

InitAD12andDAC()

 

INIT.A/D12&DAC

initializes the SPI to be compatible with operation of the 12-bit A/D and the digital to analog converter (DAC). 

To initialize the hardware now so that you can interactively perform conversions, type the following command lines at your terminal:

DECIMAL  

InitEEChar( char 10, numsamples)

InitAnalog( )

Remember to include a space after each ( character.  The first command ensures that the number base is decimal, and the second command initializes a variable located in the EEPROM which specifies the number of 12 bit samples stored in the FORTH_ARRAY buffer; this will be discussed in more detail later in the chapter.  The InitAnalog( ) function calls InitAD12andDAC(), and also dimensions and zeros some buffers that will hold A/D conversion results.

Built-In Drivers

The 12 bit A/D can be configured for either single-ended or differential conversion.  Single-ended conversion simply means that the specified voltage is referenced to VRL (which is typically analog ground).  Differential conversion means that two signals are subtracted, and the difference in their voltages is converted to a digital number.  Differential conversion is useful when common-mode background signals such as 60 Hz noise or a slowly varying bias voltage must be canceled. 

The 8 channels of the A/D are numbered 0...7, and are arranged in “channel pairs” as [0,1], [2,3], [4,5], and [6,7].  The members of a channel pair may be differenced to obtain a differential conversion.  Moreover, either member of the pair may be specified as the “positive” side of the differential conversion. 

Placing a flag (true for single-ended, false for differential) and a channel number between 0 and 7 on the stack and executing the routine

A/D12.SAMPLE   ( single.ended?\channel# -- result )

performs a 12 bit A/D conversion and returns the result on the data stack.  For example, to perform a single-ended conversion (that is, referenced to VRL) of a voltage connected to channel 6 (pin 12, named 12AN6 on the analog I/O connector), execute

TRUE 6 A/D12.SAMPLE

and the result appears on the stack.  You can print the result with the . (dot) command.  If the input voltage equals VRL, the result will equal 0.  If the input is within 1 bit of VRH, the result will equal the full-scale value of 4095.  If the input is exactly half of (VRH - VRL), the result should equal 2048.

If differential conversion is specified, the channel number indicates the “positive” channel in the pair to be differenced.  For example, executing

FALSE 0 A/D12.SAMPLE

converts the difference of channel 0 minus channel 1.  On the other hand, executing

FALSE 1 A/D12.SAMPLE

converts the difference of channel 1 minus channel 0.  Voltage differences that are negative return a result of 0.

A/D12.SAMPLE GETs and RELEASEs the resource variable SPI.RESOURCE which mediates access to the 12 bit A/D converter and the 8 bit DAC in multitasking applications. Unfortunately, about 50% of the execution time of the A/D12.SAMPLE routine is devoted to the GET and RELEASE overhead.  In non-multitasked applications or in applications where only one task uses the SPI, the faster routine

(A/D12.SAMPLE)   ( single.ended?\channel# -- result )

may be used.  It acquires the A/D sample without executing GET or RELEASE, and it executes in only 73 microseconds compared to 143 microseconds for A/D12.SAMPLE.

The QED-Forth routine

A/D12.MULTIPLE   ( xaddr\#samples\single.ended?\channel# -- )

rapidly obtains a specified number of samples from an A/D channel and stores the results as sequential 2-byte values in memory starting at the specified extended address. If the xaddr is in common RAM (consult the memory map appendix in the Software Manual), the sampling frequency is approximately 12.5 kHz (corresponding to 80 microseconds per sample).  If the specified xaddr is in paged memory, the sampling frequency is approximately 6.6 kHz (corresponding to about 150 microseconds per sample).

A/D12.MULTIPLE GETs the resource variable SPI.RESOURCE before performing the first conversion, and RELEASEs the resource variable after performing the last conversion.  The GET and RELEASE operations require about 150 microseconds to execute with an 8 MHz crystal.  In non-multitasked applications or in applications where only one task uses the 12 bit A/D and the DAC, the programmer may use

(A/D12.MULTIPLE)   ( xaddr\#samples\single.ended?\channel# -- )

which does not call GET and RELEASE and thus executes more rapidly.  The sampling frequency is the same as specified for A/D12.MULTIPLE, but the setup and exit time is reduced by 150 microseconds.

For example, to acquire eight single-ended samples from channel 6 and store them starting at address B000H\0 in common memory, execute

HEX  B000 0  8 TRUE 6  A/D12.MULTIPLE

To view the results in memory, execute

B000 0 10 DUMP

Each sample occupies two bytes in memory.  If a stable noise-free signal is attached to the 12AN6 input, the acquired samples should be nearly equal.

 

Specifying the Type of Conversion

The function

 

AD12Sample( int flag, uint channel)

 

A/D12.SAMPLE   ( flag\channel# -- result )

expects a configuration flag and a channel number as inputs, performs a single conversion using the 12 bit A/D, and returns the conversion result.  The meaning of the flag is as follows:

 

Flag value

Type of conversion

-1

single ended, unipolar

0

differential, unipolar

1

single ended, bipolar

2

differential, bipolar

To perform a single-ended, unipolar conversion on channel 0 and print the result to your terminal, execute,

-1  0 A/D12.SAMPLE  .

Additional QED-Forth routines such as A/D12.MULTIPLE facilitate speedy multiple conversions; see their glossary entries for more details.  In sum, the 12 bit A/D converter is an easy to use peripheral that greatly enhances the analog input capabilities of the QVGA Controller.

Hardware Connections

To sample an analog voltage, attach a ground-referenced voltage in the range between zero and +5 Volts to the 12 bit A/D channel 0 input named 12AN0. For example, try connecting the 1.5Vref signal (pin 37 on the Analog I/O connector) to the 12AN0 input (pin 18 on the Analog I/O connector). See the Appendix for connector diagrams, and see Figure 1-3 in Chapter 1 to identify the Analog I/O connector on the QVGA Controller.

If the input voltage equals VRL (the low reference voltage, typically at 0 Volts), the result will equal 0.  If the input is within 1 bit of VRH (the high reference voltage, typically at 5.0 Volts), the result will equal decimal 4095.  If the input is exactly half of (VRH - VRL), the result will equal decimal 2048.  If the input is 1.5 volts, the result should be approximately 1230 counts.

To provide a default 0 to 5.0 Volt conversion range, the VRL and VRH references are tied to AGND and +5VAN through 1 kohm resistors; while this is fine for casual testing as we’re doing now, you’ll want to make the following connections for your actual design project:

To achieve full 12 bit accuracy, you must connect the low reference VRL signal and the high reference VRH signal to low-impedance supplies such as Analog Ground (AGND) and Analog +5V (+5VAN), respectively. This is accomplished by connecting VRL (pin 1) to AGND (pin 19), and connecting VRH  (pin 2) to +5VAN (pin 20) on the Analog I/O connector of the QED Board. 

Interactively Perform the Conversion

The Convert12() function is defined near the top of the ANALOGIO.C file.  It is defined using the _Q specifier so that it can be interactively called from your terminal.  Convert12() simply calls the conversion function AD12Sample() with the specified channel number and a flag = -1 (meaning that a single-ended unipolar conversion is performed).  Now that you have connected an input voltage (1.5Vref) to channel 12AN0, you can interactively type from your terminal:

Convert12( int 0)

As usual, remember to include a space after the ( character.  The printed return value summary displays the conversion count; you’ll see a printout that looks something like this:

Rtn:  -30722  1237 =0x87FE04D5 =fp: -3.822E-34

We know that this function returns an integer, so we identify “1237” as the return value.  (In hexadecimal notation, this is 0x04D5 which is the lower half of the hexadecimal summary value; the other numbers in the return value summary are irrelevant.)  If the input is 1.5 volts, the result should be approximately 1230 counts.  If the input voltage equals VRL (the low reference voltage, typically at 0 Volts), the result will equal 0.  If the input is within 1 bit of VRH (the high reference voltage, typically at 5.0 Volts), the result will equal 4095.  If the input is exactly half of (VRH - VRL), the result will equal 2048.

Multiple 12 Bit A/D Conversions with Results Stored in a FORTH ARRAY

The function AD12ToBuffer() which is defined in the ANALOG.H file expects as inputs a pointer to a FORTH_ARRAY, a sampling interval parameter, the number of samples, a conversion-type flag, and a channel number.  When called, it performs the specified number of conversions and saves the results as integers in the specified FORTH_ARRAY. As explained in the Control-C Glossary, the sampling interval parameter specifies the timing of the samples, with 0 representing the fastest sampling, and 65,535 representing the slowest sampling.  The conversion-type flag is the same as the flag for AD12Sample() as described above:

 

Flag value

Type of conversion

-1

single ended, unipolar

0

differential, unipolar

1

single ended, bipolar

2

differential, bipolar

The AD12ToForthArray() function defined in ANALOGIO.C is an interactive version of AD12ToBuffer().  It accepts a channel number as input, performs unipolar conversions at the fastest sampling speed, and places the results in the FORTH_ARRAY named results_12. The number of samples is specified by the variable named

numsamples

which is located in EEPROM. You’ll remember that when we initialized the 12-bit A/D we also initialized numsamples = 10, with the statement,

InitEEChar( char 10, numsamples)

so we expect that 10 samples will be stored in the results_12 array.  Because we have connected the channel 0 input (12AN0) to 1.5Vref, let’s perform the multiple conversion on this channel.  Type at your terminal,

AD12ToForthArray( int 0)

remembering to type at least one space after the (.  This function does not return a value, so the printed return value summary is not relevant.  To see the results of the conversion, we can print the contents of the results_12 array by typing from the terminal:

PrintForthArray( int 0, results_12)

where results_12 is the name of the FORTH_ARRAY to be printed, and the 0 parameter is a flag that tells the function that the results_12 array does not contain floating point data.  You should see the conversion results printed as a column of data on your terminal screen.

These Forth drivers control multiple conversions by the 8-bit and 12-bit A/D converters:

 

(A/D8.MULTIPLE)      ( xaddr\u1\#samples\channel# -- )

A/D8.MULTIPLE        ( xaddr\u1\#samples\channel# -- )

(A/D12.MULTIPLE)     ( xaddr\u1\#samples\flag\channel# -- )

A/D12.MULTIPLE       ( xaddr\u1\#samples\flag\channel# -- )

The stack pictures include an unsigned parameter “u1” that controls the interval between successive samples.  The revised routines and their stack pictures are as follows:

The xaddr specifies the starting address where the multiple samples are to be stored. The #samples and channel# parameters have obvious meanings (note that # is pronounced “number”).  The “u1” parameter sets the sampling interval; setting u=0 delivers the fastest sampling rate and u1 = 65,535 delivers the slowest sampling rate.  The sampling rate equals the base sampling rate as specified below plus 2.5 microseconds times “u1”.

Each routine has a latency (the time between calling the routine and taking the first sample) and a sampling period (the time between successive samples).  The times vary depending on whether the storage xaddr is in common memory (above 8000 hex) or in paged memory.  The following table summarizes the relevant times in microseconds:

 

Of course, the operation of interrupt routines including the timeslicer may increase the specified sampling times.  If the system can be structured so that no interrupts are active during sampling, these routines offer very precise control over the sampling frequency of the A/D converters.

In addition, the “flag” in the stack picture of the routines

 

A/D12.SAMPLE       ( flag\channel# -- result )

(A/D12.SAMPLE)     ( flag\channel# -- result )

A/D12.MULTIPLE     ( xaddr\u1\#samples\flag\channel# -- )

(A/D12.MULTIPLE)   ( xaddr\u1\#samples\flag\channel# -- )

has the following meaning:

 

The latter two flag values instruct the software to interpret the input voltage as a bipolar signal that can swing both above and below ground.

Bipolar Conversions

You can instruct the 12-bit A/D to interpret the input as a unipolar signal in the range 0-5 volts, or a bipolar signal in the range -5 to +5 volts.  Even without an external negative supply, voltages as low as -4.0 or -4.5 V can be converted. This is achieved by using a negative voltage generator on the Maxim RS-232 chip.  This negative voltage is connected to the V- supply input of the 12 bit A/D chip, and is also accessible at pin 39 on the Analog I/O connector, labeled “Analog Bus V-”.  Drawing current out of this “Analog Bus V-” pin to power external circuitry is not recommended, as the RS-232 chip cannot source much current, the output impedance is hundreds of ohms, and the voltage is poorly regulated.  Instead, to achieve clean rail-to-rail -5.0 V to +5.0 V conversions, connect an external -5 V supply to “Analog Bus V-” at pin 39 on the Analog I/O connector.

The drivers for the 12-bit A/D converter are:

 

(A/D12.SAMPLE) A/D12.SAMPLE  

(A/D12.MULTIPLE) A/D12.MULTIPLE

 

FastAD12Sample()     AD12Sample() 

FastAD12Multiple()   AD12 Multiple ()

The configuration flag passed to these routines lets you select unipolar or bipolar conversion as discussed above, in addition to single-ended (ground-referenced) or differential conversions.

Running the Sample Program

We have worked through much of the ANALOGIO.C file.  Its routines that use the digital to analog convertor (DAC) to output voltages are discussed in the next Chapter, and its use of EEPROM to store nonvolatile variables is discussed in the Chapter Making Effective Use of Memory.

Let’s run the program, which both acquires data an outputs a voltage.  If you have a valid voltage input such as 1.5Vref (pin 37 on the Analog I/O connector) attached to 12AN0 (pin 18), AN0 (pin 10), and Vin1 (pin 21), then the main function will work properly.  To initialize the analog converters, acquire multiple samples from channel 0 of each A/D, and to establish 2.5 volts at the output of DAC channel 1, simply type:

main

at your terminal.  The function prints the results of the multiple 12 bit conversions, and you can check the DAC channel 1 output with your voltmeter.  To change the number of samples acquired from the 12 bit A/D to 20, you can interactively type:

DECIMAL   InitEEChar( char 20, numsamples)

which modifies the contents of the numsamples variable in EEPROM.  When you again execute

main

you will notice that 20 values are now printed at your terminal.


Home|Site Map|Products|Manuals|Resources|Order|About Us
Copyright (c) 2006 Mosaic Industries, Inc.
Your source for single board computers, embedded controllers, and operator interfaces for instruments and automation