| AT89C2051内部比较器应用例子
; This program implements a simple two-digit voltmeter, utilizing an ; AT89Cx051 microcontroller, two resistors, a capacitor and two HP5082-7300 ; decimal LED displays. The code is compatible with both the AT89C1051 and ; AT89C2051 when operating with a 12 MHz clock. Code modifications may be ; required for operation at a different clock rate. ; ; The voltmeter application demonstrates the RC analog-to-digital conversion ; method. The microcontroller uses an output pin, which swings from ground to ; Vcc, to alternately charge and discharge the capacitor through a resistor. ; Utilizing the internal comparator, the microcontroller measures the time ; required for the voltage on the capacitor to match the unknown voltage and ; uses the result as an index into a table. The table contains display values ; corresponding to the capacitor voltage. Each display value is encoded in ; one byte as two BCD digits, which are displayed as volts and tenths of a ; volt on the two decimal displays. There is no software hysteresis, so the ; display may oscillate at a transition voltage. ; ; The conversion routine, ADC, is general purpose, returning the entry in ; the table which corresponds to the measured time. The table contents may ; be modified to any data format required by an application. ; ; The NOP instructions in the conversion routine are used to delay the first ; sample in the charge and discharge portions of the measurement cycle. ; The amount of delay has an effect on measurement accuracy, and the number ; of NOPs may be adjusted (slightly) for best results. ; ; SCOUNT is defined as the minimum number of samples which must be taken to ; guarantee that the voltage on the capacitor has reached Vcc/2. TCHARGE and ; TDISCHARGE are defined as the minimum time required for the voltage on the ; capacitor to approach within 1/2 delta V of Vcc and ground, respectively. ; The minimum conversion time is approximately TCHARGE + TDISCHARGE, or ; six milliseconds. The maximum conversion time is approximately TCHARGE + ; TDISCHARGE + 2 * (5 microseconds * SCOUNT), or seven milliseconds. ; ; For additional information refer to the application note.
SCOUNT EQU 79 ; minimum samples to reach Vcc/2 TCHARGE EQU 3 ; cap charge time, in milliseconds TDISCHARGE EQU 3 ; cap discharge time, in milliseconds
DSEG AT 0020H
ORG 0020H ; stack origin stack: DS 0020H ; stack depth
CSEG
ORG 0000H ; power on/reset vector jmp on_reset
ORG 0003H ; external interrupt 0 vector reti ; undefined
ORG 000BH ; timer 0 overflow vector reti ; undefined
ORG 0013H ; external interrupt 1 vector reti ; undefined
ORG 001BH ; timer 1 overflow vector reti ; undefined
ORG 0023H ; serial I/O interrupt vector reti ; undefined
ORG 0040H ; begin constant data space
$INCLUDE(vtable.asm) ; get lookup table
ORG 00E0H ; begin code space USING 0 ; register bank zero on_reset: mov sp, #(stack-1) ; initialize stack pointer
mov IE, #0 ; deactivate all interrupts
mov p1, #0 ; write zeros to displays mov a, #0ffh ; deactivate output ports mov p1, a ; mov p3, a ;
clr p3.7 ; discharge capacitor mov a, #TDISCHARGE ; wait call delay_ms ; loop: call adc ; convert call vshow ; display voltage sjmp loop ; again
ADC: ; Convert analog-to-digital. ; Triggers capacitor charge/discharge and samples the comparator ; output at regular intervals until the comparator changes state. ; The sample interval is five microseconds with a 12 MHz clock. ; A maximum of SCOUNT samples are taken during the charge portion ; of the cycle and SCOUNT samples during the discharge portion of ; the cycle. The number of samples is used as an index into a table ; containing voltage equivalents. The number of table entries is ; twice SCOUNT. If the comparator does not switch, the last table ; entry is returned. Assumes that the capacitor is fully discharged ; on entry, and discharges the capacitor before return. ; The table entry is returned in A. Nothing is saved.
; Charge capacitor.
mov a, #0 ; initialize loop count setb p3.7 ; begin charging 1 uS nop ; padding 1 uS nop ; 1 uS ad1: jb p3.6, ad4 ; jump if comp output high 2 uS
inc a ; increment count 1 uS cjne a, #SCOUNT, ad1 ; loop until timeout 2 uS
; Timeout. ; Be sure capacitor is fully charged.
mov a, #TCHARGE ; wait call delay_ms ;
; Discharge capacitor.
mov a, #0 ; initialize loop count clr p3.7 ; begin discharging 1 uS nop ; padding 1 uS nop ; 1 uS ad2: jnb p3.6, ad3 ; jump if comp output low 2 uS
inc a ; increment count 1 uS cjne a, #SCOUNT, ad2 ; loop until timeout 2 uS
; Timeout.
dec a ; last count ad3: add a, #SCOUNT ; use top half of table
; Fetch table entry. ad4: mov dptr, #VoltTable ; pointer to base of table movc a, @a+dptr ; get voltage data push acc ; save data temporarily
; Be sure capacitor is fully discharged.
clr p3.7 ; begin discharging mov a, #TDISCHARGE ; wait call delay_ms ;
pop acc ret
vshow: ; Display two BCD digits on a pair of HP5082-7300 displays. ; The four data lines to each display share P1.7:1.4. The units ; display is selected by a low on P1.3 and the tenths display by a ; low on P1.2. The units display is wired to light the decimal point. ; On entry, expects two packed BCD digits in A. Returns nothing. ; All registers preserved, including flags.
push psw push acc
push acc ; save digits orl a, #00001111b ; set unused bits mov p1, a ; write units digit clr p1.3 ; strobe data into display setb p1.3 ;
pop acc ; restore digits swap a ; move low digit into high nybble orl a, #00001111b ; set unused bits mov p1, a ; write tenths digit clr p1.2 ; strobe data into display setb p1.2 ;
pop acc pop psw ret
delay_ms:
; Delay for approximately one millisecond times the value in A. ; All registers preserved, including flags.
push psw push acc push b
mov b, #0 ddm: djnz b, $ ; 512 uS @ 12 MHz djnz b, $ ; 512 uS @ 12 MHz djnz acc, ddm
pop b pop acc pop psw ret
END
 (综合电子论坛) |
*注:部份文章为网上收录供大家共同学习参考之用,并不代表本站意见。如存在版权问题请马上通知我们,我们将马上删除。 |