用AVR单片机制作的电容表.docx
《用AVR单片机制作的电容表.docx》由会员分享,可在线阅读,更多相关《用AVR单片机制作的电容表.docx(20页珍藏版)》请在冰豆网上搜索。
用AVR单片机制作的电容表
用AVR单片机制作的电容表
这种用AVR单片机制作的数显直读式电容表,具有能测量小至1pF的电容,量程广(1pF----470uF),能自动换挡,使用方便等优点。
(1)硬件电路
用分立元件电路测量电容的容量,至少要一个电压比较器,一个时间计数器以及一些逻辑电路,而用AVR单片机AT90S2313就可以实现这些功能。
1)工作原理用AVR单片机制作的数显直读模式电容表的电路图如图1
图1
该电路由AT90S2313单片机带输出锁存和三态控制的串入/并出转换器CD4094稳压块78L05,
以及4位共阳数码管等组成,所用元件不多,硬件电路非常简单。
该电路采用9V叠层电池供电,功耗较小,整机工作电流仅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置低,使Q1导通,
切换到高量程,R15R16并联向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:
有键按下
;--数据存储器定义--;
.dseg
.orgRAMTOP
DispPtr:
.byte1;显示缓冲区
DispBuf:
.byte4
KeyScan:
.byte2
Comp1:
.byte2;低量程校准
.Comp2:
.byte2;高量程校准
.Comp3:
.byte2;零校准值
StrBuf:
.byte10;十进制转换缓冲区
;--程序区--;
.cseg
rjmpreset;复位
rjmp0;外中断INT0
rjmp0;外中断INT1
rjmptc0_cap;TC1捕获
rjmp0;TC1捕获
rjmptc1_ovf;TC1溢出
rjmptc0_ovf;TC0溢出
;rjmp0;Rx接收寄存器准备好
;rjmp0;Tx发送寄存器准备好
;rjmp0;Txsfr空
;rjmp0;模拟比较器
;--初始化--;
reset:
outiSPL,low(RAMEND)
clr_0;清零寄存器
ldiwZ,RAMTOP清RAM;
ldiAL,128
stZ+,_0
decAL
brnePC–2
outiPORTD,0b0111100
outiDDRD,0b1111111
outiPORTB,0b01111000
outiDDRB,0b10001101
outiTCCR0,0b100;TC0时钟=39kHz
outiTIMSK,0b00000010;TC0溢出允许
sbiACSR,ACIC;接AC0至TC1输入捕获
clr_Flags
sei
ldiwY,DisoBuf;显示测试(500ms)
ldiAL,–1
stdY+0,AL
stdY+1,AL
stdY+2,AL
stdY+3,AL
ldiAL,125
rcalldly
rcallload_eep;读增量校准值
breqPC+6
ldiwZ,form3*2
rcallput_formed
ldiAL,250
rcalldly
;--主程序--;
main:
ldiAL,25
等待100ms,定时器2erapsed
mov_Stm1,AL
cbr_Flags,bit7
sbrc_Flags,7
rjmpbtn_pressed
tst_Stm1
brnePC–5
ldiAL,125;启动定时器2(500ms)
mov_Stm2,AL
rcallmeasure;低量程测量
brccPC+3;超时,试高量程
cbiPORTB,3
rcallmeasure
rcalladjust_zero;刷新显示
rcalladjust_gain
rcalldisp_val
sbiPORTB,3;置为低量程
rjmpmain
btn_pressed:
ldiAL,4;延时16ms
rcalldly
sbisPINB,6;ISP1-3短路?
rjmpcal_low;是,校准低量程
sbisPINB,5;ISP4-6短路?
rjmpcal_high;是,校准高量程
rjmpcan_offset;否则,校零
cal_high:
cbiPORTB,3;测大容量标准电容
rcallmeasure
sbiPORTB,3
ldiwC,0;X:
D:
C=1000*65536
;(100nF标准电容)
ldiwD,1000
ldiwX,0
ldiwZ,Comp2
cal_low:
rcallmeasure;测小容量标准电容
rcalladjust_zero
ldiwC,0;X:
D:
C=1000*65536
;(1nF标准电容)
ldiwD,10000
ldiwX,0
ldiwZ,Comp1
cal_copm:
clrwTO;X:
D:
C/=B:
A;
clrwT2
ldiEL,48
lslwC
rolwD
rolwX
rolwT0
rolwT2
cpwT0,A
cpcwT2,B
incCL
decEL
brnePC–21
orDL,DH;溢出检测
orDL,XL
orDL,XH
brnecal_err
stdwZ+0,C
rcallclr_disp
rcallsave_eep
rjmpmain
can_offset:
rcallmeasure;测量电容为零
orBL,BH;检测精度范围
brnecal_err
cpiBH,high(2000)
brcccal_err
stswComp3,A;设此值为零点
rcallclr_disp
rjmpmain
cal_err:
ldiwZ,form4*2
rcallput_formed
ldiAL,250
rcalldly
rjmpmain
dly:
mov_Stm1,AL
tst_Stm1
brnePC–1
ret
;--测电容--;
measure:
outTCNT1H,_0;清TC1并置时限
outTCNT1L,_0
clrT2L
ldiAL,20
sbisPORTB,3
ldiAL,152
movT2H,AL
outiTIFR,0b10001000;允许TC1溢出,TC1捕获
outiTIMSK,0b10001010
cbr_Flags,bit0+bit1+bit2
outiTCCR1B,0b01000001;开TC1
cbiDDRB,0;开始充电
sbrc_Flags,2;等待累计结束
rjmpmea_over
sbrs_Flags,1
rjmpPC-3
outiTCCR1B,0b01000000;关TC1
movewA,T4;取结果
movewB,T6
clc
ret
mea_over:
outiTCCR1B,0b01000000;关TC1
ldiAL,4;等待16ms
rcalldly
ldiBH,–1
sec
ret
adjust_zero:
sbisPORTB,3;高量程,跳一行
rjmpPC+19
ldswC,Comp3;B:
A-=Comp3
subwA,C
sbcBL,_0
sbcBH,_0
brccPC+10;CY=0,B:
A*=–1;置符号标志
sbr_Flags,bit0
comwA
comwB
adcAL,_0
adcAH,_0
adcBL,_0
adcBH,_0
ret
adjust_gain:
ldiwY,Comp1
sbisPORTB,3;增益调整
adiwYL,2;据量程取校准值送D
lddwD,Y+0
subwC,C;B:
A=B:
A*D/65536;
ldiEL,33
brccPC+3
addwC,D
rorwC
rorwB
rorwA
decEL
brnePC–10
movewA,B
movewB,C
ret
;--显示B:
A值,单位0.1pF--;
disp_val:
diwX,StrBuf;十进制转换缓冲区
clrDL;十进制数
incDL;---Digits++
clrCL;---/=10;
lslwA
rolwB
rolCL
cpiCL,10
brcsPC+3
subiCL,10
incAL
decCH
brnePC–10
stX+,CL
cpAL,_0
cpcAH,_0
cpcBL,_0
cpcBH,_0
brnePC–19
cpiDL,2;调整0.0pF数
brccPC+3
stX+,_0
incDL
sbisPORTB,3;高量程,数字调整
addiDL,3
ldiwZ,form2*2–4;模式选择
sbrs_Flags,0
adiwZL,16
adiwZL,4
decDL
cpiDL,2
brccPC–3
put_formed:
clrAH
ldiwY,DispBuf
lpm
adiwZL,1
movAL,TOL
clt
cpiAL,2
brccPC+3
bstAL,0
ldAL,–X
pushwZ
ldiwZ,seg7*2
addwZ,A
lpm
popwZ
bldT0L,0
stY+,T0L
cpiYL,DispBuf+4
brnePC–20
ret
clr_disp:
ldiwY,DispBuf
stY+,_0
cpiYL,DispBuf+4
brnePC–2
ret
form4:
.db14,5,15,15;E5
form3:
.db14,4,15,15;E4
form2:
.db10,1,0,13;-0.0p
.db10,0,0,13;-00p
.db14,3,15,15;E3
.db14,3,15,15;E3
form1:
.db15,1,0,13;0.0p
.db0,1,0,13;00.0p
.db0,0,0,13;000p
.db1,0,0,12;0.00n
.db0,1,0,12;00.0n
.db0,0,0,12;000n
.db1,0,0,11;0.00u
.db0,1,0,11;00.0u
.db0,0,0,11;000u
.db14,2,15,15;E2
.db14,2,15,15;E2
.db14,2,15,15;E2
seg7:
.db0xfc,0x60,0xda,0xf2,0x66,0xb6,0xbe,0xe0
0,1,2,3,4,5,6,7
.db0xfe,0xf6,0x02,0x4e,0xc4,0xce,0x9e,0x00
8,9,-,u,n,p,E,
;---EEPROM读写---;
load_eep:
ldiwY,Comp1;取校准数据
ldiwC,0x5501
rcallread_eep
stY+,AL
addCH,AL
cpiYL,Comp1+4
brnePC-4
rcallread_eep;和校验
cpAL,CH
breqPC+6
sti–Y,–1
st–Y,AL
st–Y,AL
st–Y,AL
ret
save_eep:
ldiwY,Comp1;存校准值
ldiwC,0x5501
ldAL,Y+
addCH,AL
rcallwrite_eep
cpiYL,Comp1+4
brnePC–4
movAL,CH;存校验和SUM
write_eep:
outEEAR,CL
incCL
outEEDR,AL
cli
sbiEECR,EEMWE
sbiEECR,EEWE
sei
sbicEECR,EEWE
rjmpPC–1
ret
read_eep:
outEEAR,CL
incCL
sbiEECR,EERE
inAL,EEDR
ret
;--TC1溢出中断处理--;
;T2L计数溢出formTCNT1
;置超时错标志.
Tc1_ovf:
pushAL
inAL,SREG
pushAL
incT2L
cpT2L,T2H
brcsPC+6
sbiDDRB,2
sbiDDRB,0
sbr_Flags,bit2
outiTIMSK,0b00000010
popAL
outSREG,AL
popAL
reti
;--TC1捕获中断--;
tc1_eep:
pushAL;结束测量
inAL,SREG
pushAL
sbisDDRB,2;转移by测量脉冲
rjmptc1c_ed
tc1c_st:
inT4L,ICR1L;Vc达到0.17Vcc
inT4H,ICR1H;取T1
movT6L,T2L
cbiDDRB,2;置Vth为0.5Vcc
ldiAL,20
decAL
brnePC–1
outiTIFR,0b00001000
rjmptc1c_e
tc1c_ed:
movT6H,T4L;Vc达到0.5Vcc
inT4L,ICR1L;取t2–t1
subT4L,T6H
movT6H,T4H
inT4H,ICR1H
sbcT4H,T6H
movT6H,T6L
movT6L,T2L
clrT6H
sbiDDRB,2;置Vth为0.17Vcc.
sbiDDRB,0;电容放电
outiTIMSK,0b00000010;中断屏蔽
sbr_Flags,bit1;测量结束
tc1c_e:
popAL
outSREG,AL
popAL
reti
;--TC0溢出中断处理(1kHz)--;
;刷新显示.键盘扫描.减_Stm1和_Stm2.(250Hz)
tc0_ovf:
pushAL
outiTCNT0,–39
sei
inAL,SREG
pushwA
pushwZ
ldiwZ,DispPtr;下一个显示数据
ldAH,Z
incAH
cpiAH,4
brcsPC+3
rcallscan_key
clrAH
stZ+,AH
outiPORTD,0b0111100;关显示
addZL,AH
ldiAL,bit6
lsrAL
subiAH,1
brccPC–2
comAL
andiAL,0b0111100
ldAH,Z;取段码
ldiZL,8;段码送sreg
sbrsAH,0
sbiPORTD,1
sbrcAH,0
cbiPORTD,1
sbiPORTD,0
cbiPORTD,0
lsrAH
decZL
brnePC–8
outPORTD,AL;显示
t0_exit:
popwZ
popwA
lddAH,Z+6
stdZ+6,AL
cpAL,AH
brnePC+7
lddAH,Z+5
stdZ+5,AL
eorAH,AL
andAH,AL
breqPC+2
outSREG,AL
popAL
reti
scan_key:
inAL,PINB;键扫描
comAL
andiAL,bit4
sbr_Flags,bit7
tst_Stm1;Stm减至零为止
breqPC+2
dec_Stm1
tst_Stm2
breqPC+2
dec_Stm2
ret
(4)校准及使用注意事项
首次使用电容表,必须先校准。
未经校准的电容表,在通电瞬间将显示“E4”,接着显示十几pF的杂散电容值。
校准前应准备1nF100nF的标准电容个一只。
校准步蹙如下:
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,所以每次开机都要清除杂散电容值。