数字化VF变换器设计.docx
《数字化VF变换器设计.docx》由会员分享,可在线阅读,更多相关《数字化VF变换器设计.docx(6页珍藏版)》请在冰豆网上搜索。
数字化VF变换器设计
数字化VF变换器设计
Vf变换器是把电压成比例的转换成频率的一种电子装置,由于它的结构简单(对于IO来讲只有一根电压输入和频率输出线)广泛的应用于工程项目和电加工机床中。
以往工程师们往往采用比较成熟的LM331来做VF变换器,由于它的VF变换的线性比较好(在比较大电压输入的范围内),所以经常被工程人员采用。
但是它毕竟是个模拟器件,无法把VF的转换精度提高到HZ级别,且在温度变化的环境中温漂相对大。
另在实际工程实践中干扰是无处不在的。
虽然可以采用滤波器来滤除干扰,但是对于那种瞬间强脉冲式干扰会对331产生干扰,造成频率瞬间抖动
这对以有些设备是不允许的。
故不能被用在环境温度变化大,有强干扰且要求精度比较高的场合。
以下是我设计的基于MCU的VF变换器,由于采用了AD变换器,将模拟电压转换为数字量来处理,故可以很好的解决温漂问题。
(采用PIC16F877AAD变换的精度为10bit只要参考电压控制在一定的范围内----取决与你的应用),而频率变换采用的是16bit的定时器作为时基故理论精度可控制在2的16次方-1的精度。
另在AD变换之后加入了一级抗瞬间强干扰法和平均值滤波算法可以有效对抗干扰和温漂等问题。
关于VF变换器的算法采用了比较经典的PI算法,代码如下;
#include
__CONFIG(0x3B32);
#defineucharunsignedchar
#defineuintunsignedint
uintad_val();
voidinit();
voidint_init();
voiddelay(uintx);
voidsc();
voidvf();
uintlednum;
intadval,val;
uintadtemp,advaltemp;
ucharadcunt,adflg;
ucharbai,shi,ge,dlv;
uinttime_cunt;//VF变换时间
ucharflg_ad_en;//ad标记
ucharflg_pid_en;//pid标记
ucharflg_vf_en;//vf变换标记
ucharflg_dl_en;//数字滤波标志
ucharflg_ch;
ucharpid_cunt;
floatfval;//ad值
intpid_val_g;//给定
intpid_val_b;//反馈
intd_fadval;
intfa,fb,fc,fd;
uinta1,a2,a3,a4;
voidmain()
{
init();//IO初始化
int_init();//中断初始化
adtemp=0;//清寄存器
dlv=20;//数字滤波器赋值
time_cunt=10;
while
(1)
{
if(flg_ad_en==1)
{
RC1=0;
flg_ad_en=0;//表示AD采样结束
val=ADRESH;
adval=val<<8|ADRESL;
fval=adval/1023.0*50.0;
//******如果flg_ad_en标记为1,那么求AD转换的值***//
if(5<=fval<20)//此处20为分压所得的数据
{
d_fadval=d_fadval+fval;//浮点数累加
dlv--;
if(dlv==0)
{
dlv=20;
d_fadval=d_fadval/20;//求平均数
pid_val_b=d_fadval*2;//补偿分压值
d_fadval=0;//累加数归零
flg_pid_en=1;//pid允许位
}
}
}
//******以上为数字滤波程序**************//
if(flg_pid_en==1)
{
pid_cunt=1;
flg_pid_en=0;//允许位归零
pid_val_g=16;
fa=pid_val_g-pid_val_b;
fb=fa*4;
}
}
}
voidinterrupttime2()//中断处理
{
if(TMR2IF==1)
{
TMR2IF=0;
time_cunt--;
if(time_cunt==0)
{
time_cunt=100-fb;//16*16*0.4us*5,这里需要设置变量
if(RC0==1)
{
RC0=0;
}
else
{
RC0=1;
}
}
}
if(ADIF==1)
{
ADIF=0;
flg_ad_en=1;
ADGO=1;
RC1=1;
}
}
voidinit()
{
TRISA=0x01;
TRISB=0;
TRISE=0;
TRISD=0;
TRISC=0;
PORTE=0;
PORTD=0;
PORTB=0;
PORTA=0;
PORTE=0x06;
delay
(2);
PORTE=0;
CMCON=0x07;//关比较器
ADCON0=0x81;//1/64,CH0,poweron
ADCON1=0xce;//数据右对齐AN0为模拟输入。
ADGO=1;
//-----AD初始化----------
}
voidint_init()
{
GIE=1;//开总中断
ADIE-1;//开AD中断
PEIE=1;//开外围中段
TMR2IE=1;//开定时器2中断
T2CON=0x2a;//前后分频5/1(5*4),定时器2电源关闭。
TMR2IF=0;//清中断标志位
TMR2ON=1;//开定时器2
PR2=0x01;//十进制数20(5*4*50=1000us)
}
voiddelay(uintx)//延时程序
{
uinta,b;
for(a=x;a>0;a--)
for(b=110;b>0;b--);
}
特别申明
由于以前上传此文档时的疏忽,把调试阶段的版本代码上传到baidu文库,在使用时会造成vf输出频率不随电压变化而变换。
特此更正。
错误点原来为fval=adval/1023*50;
更正为fval=adval/1023.0*50.0;
对由此造成的不便,深表歉意。