单片机
返回首页

AT89C2051内部比较器应用例子

2023-04-03 来源:elecfans

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


进入单片机查看更多内容>>
相关视频
  • RISC-V嵌入式系统开发

  • SOC系统级芯片设计实验

  • 云龙51单片机实训视频教程(王云,字幕版)

  • 2022 Digi-Key KOL 系列: 你见过1GHz主频的单片机吗?Teensy 4.1开发板介绍

  • TI 新一代 C2000™ 微控制器:全方位助力伺服及马达驱动应用

  • MSP430电容触摸技术 - 防水Demo演示

精选电路图
  • PIC单片机控制的遥控防盗报警器电路

  • 红外线探测报警器

  • 使用ESP8266从NTP服务器获取时间并在OLED显示器上显示

  • 用NE555制作定时器

  • RS-485基础知识:处理空闲总线条件的两种常见方法

  • 基于ICL296的大电流开关稳压器电源电路

    相关电子头条文章