The following is contained in this document;
The 68HC11 contains an 8 channel A/D that converts an analog input signal to an 8-bit digit value. One of the 8 input lines (PORTE) are connected to the A/D using an internal multiplexer. The A/D is a successive approximation with a sample and hold circuit to minimize error caused by fast changing signals. Linearity error is +-1/2 least significant bit. Vrh and Vrl provides the input for the voltage reference and is usually connected to +5v for Vrh and ground for Vrl.
The A/D is enabled by setting the ADPU bit (7) of the OPTION register ($1039). The ADCTL register ($1030) controls the operation of the A/D. The channel is selected by writting the number to bits 0-3. The SCAN bit (5) selects 4 conversions and stop (0), or convert continuous (1). Also, a single conversion or 4 channels can be converted if the MULT bit (4) is cleared or set. The conversion is completed when the CCF bit (7) is set to 1. The results are written to registers AD1-ADR4 ($1031-$1034).
The A/D charge pump is clocked by either of 2 sources, E-clock or a 2.5Mhz RC internal oscillator. Selection is by clearing (E-clock) or setting (2.5Mhz RC) the CSEL bit (6) in the OPTION register ($1039). Under normal operating conditions with a 2Mhz E-clock (8Mhz oscillator), use the E-clock option. The internal RC is recommended for E-clocks less than 1Mhz.
The A/D will resume normal operations after a WAIT or STOP mode (STOP mode must exit with delay). It is recommended to turn off the A/D before STOP or WAIT mode is entered. The following shows 2 A/D routines, a normal 4 sample/64usec routine, and a fast 16usec routine.
*---------------------------------------------------------------------- * subroutine: AD_READ * description: This subroutine reads the A/D channel in A and returns * value in A. *---------------------------------------------------------------------- AD_READ STAA ADCTL ; Start the conversion ADL00 LDAA ADCTL ; Get the status BPL ADL00 ; Wait until complete, bit 7 is set LDAA ADR4 ; Return the result in A RTS ; Return from subroutine *---------------------------------------------------------------------- * subroutine: FAST_AD_READ * description: This subroutine reads the A/D channel in 16useconds. *---------------------------------------------------------------------- FAST_AD_READ STAA ADCTL ; Start the conversion LDAB #6 ; 1us - Load Loop counter ADF00 DECB ; 6 x 1us - Decrement the loop counter BNE ADF00 ; 6 x 1.5us - Loop back if not done LDAA ADR1 ; Get results to A RTS ; Return from subroutine
Let's design an application to show how to use the A/D converter. In this example, the micro does the following;
The general format of the 68hc11 program is to initialize the system,
initialize the serial channel, and then wait for a byte to be received
on the serial channel. Notice that the interrupts are disable and the micro
'polls' the serial data receive flag for a received character.
The following shows the Read A/D Software. This program can be
assembled and executed on the
*----------------------------------------------------------------------- * file: A2D.SRC * description: The file is the 68hc11 A/D example. * last update: 1/6/96 rpr * * Assembling Instruction: Using the MOTOROLA Freeware Assembly program * with the following command line input. * * as11 a2d.src register.src -l cre >a2d.lst *----------------------------------------------------------------------- ORG $8000 ; Set the program starting address. ; $8000 is for 32k DEV11 board. ; $E000 is for 8k parts (A8). ; $D000 for 12k parts (E9). *---------------------------------------------------------------------- * ISR: RESET *---------------------------------------------------------------------- RESET LDS #$1FF ; Set the Top of Stack BSR FIRST64 ; Setup the time-protected registers *---------------------------------------------------------------------- * MAINLOOP BACKGROUP PROCESSING * * The main loop is continuously executed. *---------------------------------------------------------------------- MAIN LDS #$1FF ; Maintain the top of stack SEI ; Keep interrupts disabled BSR MAINTAIN ; Make sure registers are set BSR RESET_WATCHDOG ; Reset the watchdog timer *------------------------------------------- * Check for a received A/D channel number *------------------------------------------- LDAA SCSR ; Get the SCI status register ANDA #RDRF ; Mask out the receiver full flag BEQ MAIN ; Loop back if no new received character LDAA SCDR ; Get A/D channel number ANDA #$07 ; Allow only channels 0 - 7 BSR AD_READ ; Read the requested A/D channel STAA SCDR : Send the results out the serial interface BRA MAIN ; Branch back and execute again *---------------------------------------------------------------------- * subroutine: FIRST64 * description: This subroutine initializes the time-protected registers * that can only be set within the first 64 E-cycles. * This is done for a hard reset, COP reset, or Clock * Monitor fail. *---------------------------------------------------------------------- FIRST64 LDAA #$01 ; Locate registers at $1000, RAM at $0000 STAA INIT ; INIT = #$01 LDAA #ADPU+IRQE+DLY+CR1 ; Turn on the A/D, set /IRQE for edge, STAA OPTION ; enable STOP startup delay, set COP timeout * ; period to 262.14 ms LDAA #PR0 ; Set TMSK2. Select 2us/cnt for timers STAA TMSK2 ; $00 --> prescaler = 1 (1us/cnt), 65ms overflow * ; $01 --> prescaler = 4 (2us/cnt), 131ms overflow * ; $02 --> prescaler = 8 (4us/cnt), 262ms overflow * ; $03 --> prescaler =16 (8us/cnt), 524ms overflow * RTS ; Return from subroutine *---------------------------------------------------------------------- * subroutine: RESET_WATCHDOG * description: This subroutine writes the reset pattern to the COP * reset register ($103A). *---------------------------------------------------------------------- RESET_WATCHDOG LDD #$55AA ; Set values to reset watchdog timer STAA COPRST ; Write the $55 STAB COPRST ; Write the $AA. This completes the reset RTS ; Return from subroutine *---------------------------------------------------------------------- * subroutine: AD_READ * description: This subroutine reads the A/D channel in A and returns * value in A. *---------------------------------------------------------------------- AD_READ STAA ADCTL ; Start the conversion ADL00 LDAA ADCTL ; Get the status BPL ADL00 ; Wait until complete, bit 7 is set LDAA ADR4 ; Return the result in A RTS ; Return from subroutine *---------------------------------------------------------------------- * subroutine: MAINTAIN * description: This subroutine maintains the base configuration by * continually rewritting the registers that are constant. * * returns: A = 0 *---------------------------------------------------------------------- MAINTAIN CLRA ; Clear the A register for use here. STAA TMSK2 ; Disable Timer Overflow Interrupt * ; Disable Real-Time Interrupt * ; Disable Pulse Accumulator interrupts. * ; Timer prescaler PR1,PR0 = 1 factor * ; Note: PR1 & PR0 time-protected but must be * ; maintained incase MAINTAIN is executed * ; within 64 E-cycles STAA TMSK1 ; Disable Output Compares and Input Captures * * Enable SCI receiver and transmitter, no interupts * LDAB #TE+RE ; Set SCCR2 STAB SCCR2 ; * * Keep baud rate at 9600 buad * LDAB #$30 ; Don't want to rewrite baud rate all the time CMPB BAUD ; BEQ M01 STAB BAUD M01 RTS ; Return from subroutine *---------------------------------------------------------------------- * INTERRUPT VECTORS *---------------------------------------------------------------------- * The following table defines the interrupt vectors. Whenever an interrupt * is acknowledged, the address contained in the vector table associated * with the interrupt needing attention is vectored (jumped) to. *---------------------------------------------------------------------- ORG $FFC0 FDB RESET ; Serial Communications FDB RESET ; Serial Peripherial Interface FDB RESET ; Pulse Accumulator Input Edge FDB RESET ; Pulse Accumulator Overflow FDB RESET ; Timer Overflow FDB RESET ; Timer Output Compare #5 FDB RESET ; Timer Output Compare #4 FDB RESET ; Timer Output Compare #3 FDB RESET ; Timer Output Compare #2 FDB RESET ; Timer Output Compare #1 FDB RESET ; Timer Input Capture #3 FDB RESET ; Timer Input Capture #2 FDB RESET ; Timer Input Capture #1 FDB RESET ; Real Time Interrupt FDB RESET ; /IRQ FDB RESET ; /XIRQ FDB RESET ; Software Interrupt FDB RESET ; Illegal Opcode FDB RESET ; Watchdog (COP) timer reset FDB RESET ; Clock monitor fail FDB RESET ; Power on, /RESET vector *---------------------------------------------------------------------- * End of file A2D.SRC *----------------------------------------------------------------------
The following is a QuickBasic program to send the channel to the micro and read the results.
'----------------------------------------------------------
' file: A2D.BAS
'
' description: This file is the basic interface file for
' the 68hc11 A/D tutorial.
'
' last update: January 6, 1996 rpr
'----------------------------------------------------------
CLS
PRINT "opening com1"
OPEN "COM1:9600,N,8,1,cd0,cs0,ds0,rb1000" FOR RANDOM AS #1
PRINT "com1 opened"
ak$ = ""
DO WHILE ak$ <> "E"
ak$ = UCASE$(INKEY$)
IF ak$ <> "" THEN
IF ak$ >= "0" AND ak$ <= "7" THEN
x = VAL(ak$) - VAL("0")
PRINT "Sending Channel "; x
PRINT #1, CHR$(x);
y = 0
WHILE LOC(1) < 1 AND y < 5000
y = y + 1
WEND
IF y >= 5000 THEN
PRINT "Value not received"
BEEP
ELSE
z = ASC(INPUT$(1, #1))
PRINT "A/D Channel #"; x; "="; z
END IF
ELSEIF ak$ = "E" THEN
PRINT "A2D example completed."
ELSE
PRINT "Invalid entry."
END IF
END IF
LOOP
END