📄 an1708
字号:
***************************************************************************************
*
* Filename: SSADCON.ASM
* Revision: 1.00
* Date: June 10,1996
*
* Written By: Stephen Ledford
* Motorola CSIC Product Engineering
*
* Assembled Under: Micro Dialects, Inc. MicroASM-6805
*
* ********************************
* * Revision History *
* ********************************
*
* Revison 1.00 6/10/96 Original release
*
***************************************************************************************
*
* Program Description:
*
* This program performs conversions with the single slope A/D
* convertor system on the 68HC705JP7.
*
***************************************************************************************
*
* Registers
*
AMUX EQU $03 ;Ananlog MUX control register
TCR EQU $12 ;Timer control register
TSR EQU $13 ;Timer status register
ICRH EQU $14 :Input capture high byte buffer
ICRL EQU $15 ;Input capture low byte buffer
TMRH EQU $18 ;Timer count upper byte register (read)
TMRL EQU $19 ;Timer count low byte register (read)
OCRH EQU $18 ;Output compare register high byte (write)
OCRL EQU $19 ;Output compare register low byte (write)
ACR EQU $1D ;Analog System control resgister
ASR EQU $1E ;Analog System status register
*
* Start of main routine
*
ORG $50 ;RAM address space
*
REF RMB 2 ;refernce voltage conversion value
VAL RMB 2 ;converted value storage location
TEMP RMB 2 ;temporary storage space for processing
OCFVAL RMB 2 ;output compare value used for OCF/ICF method
*
ORG $700 ;start of ROM/EPROM address space
*
***************************************************************************************
*
* Main program routine
*
* This is an example main program that uses the OCF/ICF method to perform
* conversions and manage the analog subsystem.
*
***************************************************************************************
MAIN EQU *
*
* First set up to convert the reference voltage which in this case is the
* internal connection of VDD to the comparators.
*
LDA #$50 ;Set the DHOLD and VREF bits, clearing the MUX bits
STA AMUX ;Store to the AMUX register
REFWAIT LDA #$80 ;Load a loop counter to wait long enough for the sample
;cap to settle to the reference voltage
DECA ;Decrement the loop counter
BNE REFWAIT ;Loop back until the count is complete
BCLR 6,AMUX ;Clear the sample and hold bit to avoid changes in
;samples value
BCLR 4,AMUX ;Remove the VDD as the input source to the comparator
*
* Now perform the conversion
*
JSR OCFCON ;Jump to subroutine to perform an OCF/ICF conversion
LDA VAL ;Get the high byte of the converted result
STA REF ;Store it in the REFERENCE variable
LDA VAL+1 ;Get the low byte of the converted result
STA REF+1 ;Store it in the REFERENCE variable
*
* Now select a regular input channel and convert it
*
LDA #$41 ;Set the DHOLD bit and select channel 1 as input
STA AMUX ;Store to the AMUX register
SAMPLE LDA #$80 ;Load a loop counter to wait long enough for the sample
;cap to settle to the reference voltage
DECA ;Decrement the loop counter
BNE SAMPLE ;Loop back until the count is complete
BCLR 6,AMUX ;Clear the sample and hold bit to avoid changes in
;sampled value
BCLR 0,AMUX ;Deselect the input channel
*
JSR OCFCON ;Jump to subroutine to perform an OCF/ICF conversion
*
* Now there is a reference conversion and input channel conversion. Do the
* ratio calculation.
*
BRA MAIN ;Loop back to the top of the program
*
***************************************************************************************
*
* Subroutine to perform a fully manual conversion by cycle counting.
*
* This is a completely manual conversion method. The start of the
* conversion is manual and the completion of the conversion is
* manual. The conversion result is calculated by a software cycle
* count loop. Since this is a cycle counting loop, this does not have
* any other hardware dependencies such as the timer but gives the lowest
* resolution for conversion as well as prevents other processing from
* being performed.
*
***************************************************************************************
MANCON EQU *
*
* Initialization
*
CLR VAL ;Clear the conversion result upper byte
CLR VAL+1 ;Clear the conversion result lower byte
LDA #$05 ;Clear the CHG,ATD2, and ATD1 to configure for a manual
;mode conversion. Set CP2EN and ISEN to start up system
STA ACR ;Store the value in the ACR
*
* Start the conversion sequence by first discharging the external cap
*
LDA #$FF ;Load up a simple loop counter to wait time TDIS. This
;value should be tuned based on system bus speed.
MANINI DECA ;Decrement the loop counter
BNE MANINI ;Loop back until the amount of wait time is complete
BSET 5,ASR ;Set the CPFR2 bit to make sure the flags are clear
*
* Now begin the conversion by start of the charging on the ramp cap
*
SEI ;Disable all interrupts as this would mess up count
BSET 7,ACR ;Set the CHG bit engaging the current source
MANCNT INC VAL+1 ;Increment the conversion value low byte
BNE MANHIGH ;Branch around incrementing the high byte if not rolled
INC VAL ;Increment the conversion value high byte if low rolled
MANHIGH BRCLR 7,ASR,MANCNT ;Test the CPF2 flag and continue looping if not converted
CLR ACR ;Clear the CHG bit, discharging the external cap and turn
;the system off.
*
* Conversion is complete. Return to main program
*
CLI ;Enable interrupts again
RTS ;Return to calling routine
*
***************************************************************************************
*
* Subroutine to perform a partially manual conversion by cycle counting.
*
* This is a partially manual conversion method. The start of the
* conversion is manual and the completion of the conversion is
* automatic. The conversion result is calculated by a software cycle
* count loop. Since this is a cycle counting loop, this does not have
* any other hardware dependencies such as the timer but gives the lowest
* resolution for conversion as well as prevents other processing from
* being performed.
*
***************************************************************************************
CYCCON EQU *
*
* Initialization
*
CLR VAL ;Clear the conversion result upper byte
CLR VAL+1 ;Clear the conversion result lower byte
LDA #$25 ;Clear the CHG,ATD2 and set ATD1 to configure for a semi-manual
;mode conversion. Set CP2EN and ISEN to start up system
STA ACR ;Store the value in the ACR
*
* Start the conversion sequence by first discharging the external cap
*
LDA #$FF ;Load up a simple loop counter to wait time TDIS. This
;value should be tuned based on system bus speed.
WAITINI DECA ;Decrement the loop counter
BNE WAITINI ;Loop back until the amount of wait time is complete
BSET 5,ASR ;Set the CPFR2 bit to make sure the flags are clear
*
* Now begin the conversion by start of the charging on the ramp cap
*
SEI ;Disable all interrupts as this would mess up count
BSET 7,ACR ;Set the CHG bit engaging the current source
COUNT INC VAL+1 ;Increment the conversion value low byte
BNE NOHIGH ;Branch around incrementing the high byte if not rolled
INC VAL ;Increment the conversion value high byte if low rolled
NOHIGH BRCLR 7,ASR,COUNT ;Test the CPF2 flag and continue looping if not converted
;No need to do a manual discharge as this was handled by
;the convertor hardware.
CLR ACR ;Turn the convertor off
*
* Conversion is complete. Return to main program
*
CLI ;Enable interrupts again
RTS ;Return to calling routine
*
***************************************************************************************
*
* Subroutine to perform a conversion by use of the TOF to ICF method.
*
* This is just the setup routine for the TOF/ICF method. An ISR is also
* required to get the result when the conversion is completed. This routine
* requires the least amount of code intervention to perform and the best accuracy
* possiblebut the conversion can have the longest latency as the timer must reach
* its full count before a conversion begins.
*
***************************************************************************************
TOFCON EQU *
*
* Initialization
*
CLR VAL ;Clear the conversion result upper byte
CLR VAL+1 ;Clear the conversion result lower byte
LDA #$4D ;Clear the CHG,ATD1 and set ATD2 to configure for a
;TOF/ICF
;mode conversion. Set CP2EN and ISEN to start up system
;as well as enabling the Analog interrupts by setting CPIE
STA ACR ;Store the value in the ACR
*
* Start the conversion sequence by first discharging the external cap
*
LDA #$FF ;Load up a simple loop counter to wait time TDIS. This
;value should be tuned based on system bus speed.
TOFINI DECA ;Decrement the loop counter
BNE TOFINI ;Loop back until the amount of wait time is complete
BSET 5,ASR ;Set the CPFR2 bit to make sure the flags are clear
LDA TSR ;Read the timer status register to clear the TOF
LDA TMRL ;Read the low byte of the timer value to complete the
;clear
*
* The mode is configured to start at the TOF of the timer. Therefore wait
* until an interrupt occurs and the timer value should be captured.
*
WAIT ;Wait here until the analog interrupt occurs
;Other processing can occur if necessary until the
;interrupt occurs
CLR ACR ;Turn the convertor off so as not to cause another
;conversion and overrun of the result
*
* Conversion is complete. Return to main program
*
RTS ;Return to calling routine
*
***************************************************************************************
*
* Subroutine to perform a conversion by use of the OCF to ICF method.
*
* This is just the setup routine for the OCF/ICF method. An ISR is also
* required to get the result when the conversion is completed. This routine
* has a little more code required to support but has the lowest possible
* conversion time and the best accuracy possible.
*
***************************************************************************************
OCFCON EQU *
*
* Initialization
*
CLR VAL ;Clear the conversion result upper byte
CLR VAL+1 ;Clear the conversion result lower byte
LDA #$6D ;Clear the CHG and set ATD1,ATD2 to configure for a OCF/ICF
;mode conversion. Set CP2EN and ISEN to start up system
;as well as enabling the Analog interrupts by setting CPIE
STA ACR ;Store the value in the ACR
*
* Start the conversion sequence by first discharging the external cap
*
LDA #$FF ;Load up a simple loop counter to wait time TDIS. This
;value should be tuned based on system bus speed.
OCFINI DECA ;Decrement the loop counter
BNE OCFINI ;Loop back until the amount of wait time is complete
BSET 5,ASR ;Set the CPFR2 bit to make sure the flags are clear
*
* The mode is configured to start at the OCF of the timer. Therefore wait
* until an interrupt occurs and the timer value should be captured. Start
* by configuring the output compare value for an OCF to occur.
*
SEI ;Set the interrupt bit to prevent additional interrupts
CLRA ;Clear the accumulator to clear the carry bit
LDA TMRH ;Get the current value of the timer high byte
;This is necessary to freeze the timer value
LDA TMRL ;Load the current timer count low byte
ADD #$20 ;Add an offset to start the conversion sequence
STA OCFVAL+1 ;Store away for use later
LDA TMRH ;Get the current value of the timer high byte
ADD #0 ;Add the carry if there was one
STA OCFVAL ;Store the value for use later
STA OCRH :Store in the output compare to start the count
LDA TSR ;Read the TSR to allow clearing of the OCF
LDA OCFVAL+1 ;Get back the low byte value
STA OCRL ;Store in the lower byte of the output compare register
*
* Wait for the conversion to complete
*
CLI
WAIT ;Wait here until the analog interrupt occurs
;Other processing can occur if necessary until the
;interrupt occurs
CLR ACR ;Turn the convertor off so as not to cause another
;conversion and overrun of the result
*
* Conversion is complete. Return to main program
*
RTS ;Return to calling routine
*
***************************************************************************************
*
* ISR for control of the conversion methods both TOF/ICF anf OCF/ICF.
*
* Once the ISR is complete, the program control goes back to the calling
* subroutine to complete execution of the conversion. The conversion result
* placed in the variable CONV which is a 16 bit value.
*
***************************************************************************************
CONISR EQU *
SEI ;Set the interrupt bit to avoid other IRQs
*
* Get the result from the timer registers and place it in the variable CONV
*
LDA ICRH ;Get the high byte of the timer counter
STA VAL ;Store in the conversion result variable
LDA ICRL ;Get the low byte of the timer counter
SUB #1 ;Must subtract 1 from the result since the timer
;adds an extra tick to the counter
STA VAL+1 ;Store in the conversion result variable
LDA VAL ;Get back the high byte of the converstion result
SBC #0 ;Subtract just with the carry to finish the
;processing of the result
STA VAL ;Store back the processed result
*
* Check to see which kind of conversion is in process
*
BRCLR 5,ACR,TOFISR ;If the ATD1 bit is clear then this is a TOF/ICF
;else this is a OCF/ICF conversion method.
*
* Handle the OCF/ICF conversion result. Must subtract the OCF value to
* to find the delta time between the start and stop of the counter
*
ICFISR LDA OCFVAL+1 ;Load the value used to start the conversion
SUB VAL+1 ;Subtract from the captured timer value
STA VAL+1 ;Store back as the adjusted result
LDA OCFVAL :Load the high byte of the start value
SBC VAL ;Subtract with the carry from the captured value
STA VAL ;Store back in the result register high byte
*
* Handle the TOF/ICF conversion result. No post processing is required
* since the start is from a counter of $0000 to the captured count.
*
TOFISR CLR ACR ;Power down the Analog system so as not to get any
;errant conversions
*
* Return from interrupt
*
CLI ;Clear the interrupt bit to allow IRQs
RTI ;Return from interrupt
*
**************************************************************************************
*
* Vectors
*
***************************************************************************************
ORG $1FF2 ;Location of Analog system vector
ANALOG FCB CONISR ;Analog conversion ISR pointer
ORG $1FFE ;Location of Reset vector
RST FCB MAIN ;Reset vector pointer
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -