1、用AVR单片机制作的电容表 用AVR单片机制作的电容表 这种用AVR单片机制作的数显直读式电容表,具有能测量小至1pF的电容,量程广(1pF-470uF),能自动换挡,使用方便等优点。(1) 硬件电路 用分立元件电路测量电容的容量,至少要一个电压比较器,一个时间计数器以及一些逻辑电路,而用AVR单片机AT90S2313就可以实现这些功能。1) 工作原理 用AVR单片机制作的数显直读模式电容表的电路图如图1图1该电路由AT90S2313单片机 带输出锁存和三态控制的串入/并出转换器CD4094 稳压块78L05,以及4位共阳数码管等组成,所用元件不多,硬件电路非常简单。该电路采用9V叠层电池供电
2、,功耗较小,整机工作电流仅32mA左右。 (2)工作过程将待测电容Cx插入JP2,在500ms内将会触发以下测量过程。测量从低量程开始,单片机先将PB3置为高电平,使Q1截止,断开3.3k电阻R15,仅通过3.3M电阻R16对Cx充电,单片机开始计时,Cx上的电压经R14送单片机内比较器的AIN0端,并与AIN1端的电压0.5Vcc比较,如果在130ms内AIN0端的电压Vc达不到0.5Vcc,说明Cx大于57Nf,应切换到高量程,反之,单片机将充电时间换算成Cx的容量,连同容量的单位通过数码管显示出来;如果需要切换到高量程,则单片机会将PB0口置低,Cx通过PB0放电,放电完成后再将PB3置
3、低,使Q1导通,切换到高量程,R15 R16并联向Cx充电(加快充电时间),并重新计时,如果1秒内Cx上的电压Vc达不到0.5Vcc,说明Cx大于440uF,超量程,数码管显示“E2”,表示测量失败,反之,单片机将充电时间换算成Cx的容量,连同容量的单位通过数码管显示出来。(3)源程序.include “2313def.inc”.include “avr.inc.def _0=r15 ;零寄存器.def _Stm1=r14 ;系统定时器.def _Stm2=r13 ;系统定时器.def _Flags=r25 ;标志寄存器 ;b0:结果为minus ;b1:捕获完毕 ;b2:累计时间溢出 ;b7
4、:有键按下 ;-数据存储器定义-;.dseg.org RAMTOPDispPtr:.byte 1 ;显示缓冲区DispBuf:.byte 4 KeyScan:.byte 2Comp1:.byte2 ;低量程校准.Comp2:.byte2 ;高量程校准.Comp3:.byte2 ;零校准值StrBuf:.byte 10 ;十进制转换缓冲区;- 程序区 -;.csegrjmp reset ;复位rjmp 0 ;外中断INT0rjmp 0 ;外中断INT1rjmp tc0_cap ;TC1捕获rjmp 0 ;TC1捕获rjmp tc1_ovf ;TC1溢出rjmp tc0_ovf ;TC0溢出;rj
5、mp 0 ;Rx接收寄存器准备好;rjmp 0 ;Tx发送寄存器准备好;rjmp 0 ;Tx sfr 空;rjmp 0 ;模拟比较器;-初始化-;reset:outi SPL,low(RAMEND) clr _0 ;清零寄存器 ldiw Z, RAMTOP 清RAM;ldi AL, 128st Z+,_0dec AL brne PC2outi PORTD,0b0111100outi DDRD,0b1111111outi PORTB,0b01111000outi DDRB,0b10001101outi TCCR0,0b100 ;TC0时钟=39kHzouti TIMSK,0b00000010 ;
6、TC0溢出允许sbi ACSR, ACIC ;接AC0至TC1输入捕获clr _Flagsseildiw Y, DisoBuf ;显示测试(500ms)ldi AL, 1std Y+0, ALstd Y+1, ALstd Y+2, ALstd Y+3, ALldi AL, 125rcall dlyrcall load_eep ;读增量校准值breq PC+6ldiw Z, form3*2rcall put_formedldi AL, 250rcall dly ;-主程序-;main:ldi AL, 25 等待100ms,定时器2erapsedmov _Stm1,ALcbr _Flags,bit
7、7sbrc _Flags,7rjmp btn_pressedtst _Stm1brne PC5ldi AL,125 ; 启动定时器2(500ms)mov _Stm2,ALrcall measure ;低量程测量brcc PC+3 ;超时,试高量程cbi PORTB,3 rcall measure rcall adjust_zero ;刷新显示 rcall adjust_gain rcall disp_val sbi PORTB,3 ;置为低量程 rjmp main btn_pressed:ldi AL,4 ;延时16ms rcall dly sbis PINB,6 ;ISP1-3短路? rjm
8、p cal_low ;是,校准低量程 sbis PINB,5 ;ISP4-6短路? rjmp cal_high ;是,校准高量程 rjmp can_offset ;否则,校零cal_high:cbi PORTB,3 ;测大容量标准电容 rcall measure sbi PORTB,3 ldiw C,0 ;X:D:C=1000*65536 ;(100nF标准电容) ldiw D,1000 ldiw X,0 ldiw Z,Comp2cal_low:rcall measure ;测小容量标准电容 rcall adjust_zero ldiw C,0 ;X:D:C=1000*65536 ;(1nF标
9、准电容) ldiw D,10000 ldiw X,0 ldiw Z,Comp1cal_copm:clrw TO ;X:D:C/=B:A; clrw T2 ldi EL,48 lslw C rolw D rolw X rolw T0 rolw T2 cpw T0,A cpcw T2,B inc CL dec EL brne PC21 or DL,DH ;溢出检测 or DL,XL or DL,XH brne cal_err stdw Z+0,C rcall clr_disp rcall save_eep rjmp maincan_offset:rcall measure ;测量电容为零 or B
10、L, BH ;检测精度范围 brne cal_err cpi BH, high(2000) brcc cal_err stsw Comp3,A ;设此值为零点 rcall clr_disp rjmp maincal_err:ldiw Z,form4*2 rcall put_formed ldi AL,250 rcall dly rjmp maindly: mov _Stm1,AL tst _Stm1 brne PC1 ret ;-测电容-;measure:out TCNT1H,_0 ;清TC1并置时限 out TCNT1L,_0 clr T2L ldi AL, 20 sbis PORTB, 3
11、 ldi AL, 152 mov T2H, AL outi TIFR,0b10001000 ;允许TC1溢出,TC1捕获 outi TIMSK,0b10001010 cbr _Flags,bit0+bit1+bit2 outi TCCR1B,0b01000001 ;开TC1 cbi DDRB,0 ;开始充电 sbrc _Flags, 2 ;等待累计结束 rjmp mea_over sbrs _Flags,1 rjmp PC-3 outi TCCR1B, 0b01000000 ;关TC1 movew A,T4 ;取结果 movew B, T6 clc retmea_over:outi TCCR1
12、B,0b01000000 ;关TC1 ldi AL,4 ;等待16ms rcall dly ldi BH, 1 sec retadjust_zero:sbis PORTB,3 ;高量程,跳一行 rjmp PC+19 ldsw C,Comp3 ;B:A -=Comp3 subw A,C sbc BL,_0 sbc BH,_0 brcc PC+10;CY=0,B:A *=1 ;置符号标志 sbr _Flags,bit0 comw A comw B adc AL,_0 adc AH,_0 adc BL,_0 adc BH,_0 retadjust_gain:ldiw Y,Comp1 sbis POR
13、TB,3 ;增益调整 adiw YL,2 ;据量程取校准值送D lddw D,Y+0 subw C, C ;B:A = B:A * D / 65536; ldi EL,33 brcc PC+3 addw C,D rorw C rorw B rorw A dec EL brne PC10 movew A,B movew B,C ret ;-显示B:A值,单位0.1pF-;disp_val:diw X,StrBuf ;十进制转换缓冲区 clr DL ;十进制数 inc DL ;-Digits+ clr CL ;-/=10; lslw A rolw B rol CL cpi CL,10 brcs P
14、C+3 subi CL,10 inc AL dec CH brne PC10 st X+,CL cp AL,_0 cpc AH,_0 cpc BL,_0 cpc BH,_0 brne PC19 cpi DL,2 ;调整0.0pF数 brcc PC+3 st X+,_0 inc DL sbis PORTB, 3 ;高量程,数字调整 addi DL,3 ldiw Z, form2*24 ;模式选择 sbrs _Flags, 0 adiw ZL,16 adiw ZL,4 dec DL cpi DL,2 brcc PC3put_formed:clr AH ldiw Y,DispBuf lpm adiw
15、 ZL,1 mov AL,TOL clt cpi AL,2 brcc PC+3 bst AL,0 ld AL, X pushw Z ldiw Z,seg7*2 addw Z,A lpm popw Z bld T0L,0 st Y+,T0L cpi YL,DispBuf+4 brne PC20 retclr_disp:ldiw Y,DispBuf st Y+,_0 cpi YL,DispBuf+4 brne PC2 retform4:.db 14,5,15,15 ;E5form3:.db 14,4,15,15 ;E4form2:.db 10,1,0,13 ;-0.0p .db 10,0,0,13
16、 ;-00p .db 14,3,15,15 ;E3 .db 14,3,15,15 ;E3form1:.db 15,1,0,13 ;0.0p .db 0,1,0,13 ;00.0p .db 0,0,0,13 ;000p .db 1,0,0,12 ;0.00n .db 0,1,0,12 ;00.0n .db 0,0,0,12 ;000n .db 1,0,0,11 ;0.00u .db 0,1,0,11 ;00.0u .db 0,0,0,11 ;000u .db 14,2,15,15 ;E2 .db 14,2,15,15 ;E2 .db 14,2,15,15 ;E2seg7:.db 0xfc,0x6
17、0,0xda,0xf2,0x66,0xb6,0xbe,0xe0 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 .db 0xfe,0xf6,0x02,0x4e,0xc4,0xce,0x9e,0x00 8 , 9 , - , u , n , p , E , ;-EEPROM 读写-;load_eep:ldiw Y,Comp1 ;取校准数据 ldiw C,0x5501 rcall read_eep st Y+,AL add CH, AL cpi YL,Comp1+4 brne PC-4 rcall read_eep ;和校验 cp AL,CH breq PC+6 sti Y, 1 st
18、 Y,ALst Y,ALst Y,ALretsave_eep:ldiw Y,Comp1 ;存校准值 ldiw C,0x5501 ld AL, Y+ add CH,AL rcall write_eep cpi YL,Comp1+4 brne PC4 mov AL,CH ;存校验和SUMwrite_eep:out EEAR,CL inc CL out EEDR,AL cli sbi EECR,EEMWE sbi EECR,EEWE sei sbic EECR,EEWE rjmp PC1 retread_eep:out EEAR,CL inc CL sbi EECR,EERE in AL,EEDR
19、ret ;-TC1溢出中断处理-; ;T2L计数溢出form TCNT1 ;置超时错标志.Tc1_ovf:push AL in AL,SREG push AL inc T2L cp T2L,T2H brcs PC+6 sbi DDRB,2 sbi DDRB,0 sbr _Flags,bit2 outi TIMSK,0b00000010 pop AL out SREG,AL pop AL reti ;-TC1捕获中断-;tc1_eep:pushAL ;结束测量 in AL,SREG push AL sbis DDRB,2 ;转移by测量脉冲 rjmp tc1c_edtc1c_st:in T4L,
20、ICR1L ;Vc达到0.17Vcc in T4H,ICR1H ;取T1 mov T6L,T2L cbi DDRB,2 ;置Vth为0.5Vcc ldi AL,20 dec AL brne PC1 outi TIFR,0b00001000 rjmp tc1c_etc1c_ed:mov T6H,T4L ;Vc达到0.5Vcc in T4L,ICR1L ;取t2t1 sub T4L,T6H mov T6H,T4H in T4H,ICR1H sbc T4H,T6H mov T6H,T6L mov T6L,T2L clr T6H sbi DDRB,2 ;置Vth为0.17Vcc. sbi DDRB,0
21、 ;电容放电 outi TIMSK,0b00000010 ;中断屏蔽 sbr _Flags,bit1 ;测量结束tc1c_e:pop AL out SREG,AL pop AL reti ;-TC0溢出中断处理(1kHz)-; ;刷新显示.键盘扫描.减_Stm1和_Stm2.(250Hz)tc0_ovf:push AL outi TCNT0, 39 sei in AL,SREG pushw A pushw Z ldiw Z,DispPtr ;下一个显示数据 ld AH,Z inc AH cpi AH,4 brcs PC+3 rcall scan_key clr AH st Z+,AH outi
22、 PORTD,0b0111100 ;关显示 add ZL,AH ldi AL,bit6 lsr AL subi AH,1 brcc PC2 com AL andi AL,0b0111100 ld AH,Z ;取段码 ldi ZL,8 ;段码送sreg sbrs AH,0 sbi PORTD,1 sbrc AH,0 cbi PORTD,1 sbi PORTD,0 cbi PORTD,0 lsr AH dec ZL brne PC8 out PORTD,AL ;显示t0_exit:popw Z popw A ldd AH,Z+6 std Z+6,AL cp AL,AH brne PC+7 ldd
23、AH,Z+5 std Z+5,AL eor AH,AL and AH,AL breq PC+2 out SREG,AL pop AL retiscan_key:in AL,PINB ;键扫描 com AL andi AL,bit4 sbr _Flags,bit7 tst _Stm1 ;Stm减至零为止 breq PC+2 dec _Stm1 tst _Stm2 breq PC+2 dec _Stm2 ret(4)校准及使用注意事项首次使用电容表,必须先校准。未经校准的电容表,在通电瞬间将显示“E4”,接着显示十几pF的杂散电容值。校准前应准备1nF 100nF的标准电容个一只。校准步蹙如下:a.将开关S2闭合,按校正键S1清除杂散电容值,使电容表显示0.00pF;b.短接JP1的 脚,再将1nF标准电容插入测试口JP2,按S1,使电容表显示1.00nF; c.断开 JP1的 脚,短接JP1的 脚将100nF标准电容插入JP2,按S1,使电容表显示100nF。 校准之后,开机瞬间不再显示“E4”,而是显示 “8。8。8。8”,表示已经校准,可使用。校准值自动存入单片机繁荣EEPROM,以后不需要再校准。杂散电容值不存入EEPROM,所以每次开机都要清除杂散电容值。