矿石收音机论坛

 找回密码
 加入会员

QQ登录

只需一步,快速开始

搜索
查看: 2632|回复: 11

有谁做过对数字频率计的闸门时间100s改装?

[复制链接]
     
发表于 2018-4-16 12:30:48 | 显示全部楼层 |阅读模式
目前现成300元以下的数字频率计怎么都没有闸门时间在100s的?可有人改装过?不知兆信F1000L与 胜利VC2000和VC3165能否改装?
     
发表于 2018-4-16 13:03:20 | 显示全部楼层
100s您忍得住么?
回复 支持 反对

使用道具 举报

     
发表于 2018-4-16 13:22:05 | 显示全部楼层

不只是你忍不忍得住的问题,还要看信号忍不忍得住。如果真的有精确测定频率的需求,100s 让机器自己去忍,等有空再回来也没问题,关键是,

1、信号的频率抖动
2、基准的频率抖动
3、频率计自身的抖动

三者导致你设置 100s 的 Gate 是否是有意义的,设置 100s 得出的多一位数据是否是稳定、有效的?我觉得楼主举例的经济频率计不提供 100s Gate,可能是三者都不满足的缘故。

中档频率计可以设置 1000s Gate

微信图片_20180416131901.jpg
回复 支持 反对

使用道具 举报

     
 楼主| 发表于 2018-4-16 21:27:52 | 显示全部楼层
本帖最后由 lmwyl 于 2018-4-16 21:29 编辑

哈哈,我是想测试时钟32768Hz晶振,如果能调试岀0.01Hz分辨率那么日误差就是0.026秒,在此当然要不考虑石英本身误差的ppm等上100s是完全没问题
回复 支持 反对

使用道具 举报

     
发表于 2018-4-17 00:10:13 | 显示全部楼层
lmwyl 发表于 2018-4-16 21:27
哈哈,我是想测试时钟32768Hz晶振,如果能调试岀0.01Hz分辨率那么日误差就是0.026秒,在此当然要不考虑石英 ...

这个,对于基准为 10MHZ 的频率计来说,等精度分辨 32768 HZ 中的 0.01HZ 只需要大概 0.3 秒 Gate

实际上的频率计,10MHZ 的基准,0.1s 至少可以分辨 32768HZ 中的 0.001HZ,好一些的比如前面说的中档频率计,0.1s Gate 可以分辨到 0.00001HZ 的。

微信图片_20180417000604.jpg
回复 支持 反对

使用道具 举报

     
 楼主| 发表于 2018-4-18 06:28:20 | 显示全部楼层
washu 发表于 2018-4-17 00:10
这个,对于基准为 10MHZ 的频率计来说,等精度分辨 32768 HZ 中的 0.01HZ 只需要大概 0.3 秒 Gate

实 ...

学习了,只可惜对于业余买这玩玩似不… ,昨天100大洋淘个二手VC2000看看能改否。
回复 支持 反对

使用道具 举报

     
发表于 2018-4-18 10:33:01 | 显示全部楼层
lmwyl 发表于 2018-4-18 06:28
学习了,只可惜对于业余买这玩玩似不… ,昨天100大洋淘个二手VC2000看看能改否。

当然不是叫你买安捷伦而是告诉你解决这个问题的正确思路,是用等精度频率计 你还真没给我听进去

不过既然你有能力改造这个,说明你玩单片机的水平足够高,自己做一个等精度频率计或者把那玩意改造成等精度频率计也是很轻松的,本坛就有 DIY 的等精度频率计,好像是一秒 7 位,正好 32768.00 HZ,你稍微参考以下就行:
http://www.crystalradio.cn/thread-865517-1-1.html

回复 支持 反对

使用道具 举报

     
发表于 2018-4-20 19:39:37 | 显示全部楼层
lmwyl 发表于 2018-4-16 21:27
哈哈,我是想测试时钟32768Hz晶振,如果能调试岀0.01Hz分辨率那么日误差就是0.026秒,在此当然要不考虑石英 ...

要精准直接用电波钟机芯。32768晶振准确度本来就不高,尤其受温度影响,夏天调准了冬天又变了。能调到每天能有几秒误差就已经很好了。
回复 支持 反对

使用道具 举报

     
 楼主| 发表于 2018-4-21 15:12:07 | 显示全部楼层
washu 发表于 2018-4-18 10:33
当然不是叫你买安捷伦而是告诉你解决这个问题的正确思路,是用等精度频率计  你还真没给我听进去
...

多谢指导!只因我是完全自学的业余电子爱好者,现在视力不行了都老花300多度了,我是想看看能否简单地将胜利VC2000频率计闸门10s电路再串个类似74HC390芯片做个开关,利用每100s闸计数器32768Hz那么不就是3276800Hz轻易分辨率岀0.001Hz,现苦于没有胜利VC2000频率计电路图,看来只能要拆开画相关电路图了。
回复 支持 反对

使用道具 举报

     
发表于 2018-4-23 23:47:57 | 显示全部楼层
lmwyl 发表于 2018-4-21 15:12
多谢指导!只因我是完全自学的业余电子爱好者,现在视力不行了都老花300多度了,我是想看看能否简单地将 ...

改电路可能更麻烦了。而且100s时间也太长了,即使成了,也不好用啊。
建议按wash说的,改用等精度频率测量方法就可以了。如果不想买再买的这种频率计,可以自己做一个,按如下方案制作即可:

用STC12C5A60S2单片机搭一个最小系统,也就几个元件。晶振用18.432MHz
然后将P3.3与P3.5连接起来做为频率计的输入端。信号整形后,送入这个端子即可。

显示器用LCD1602,连接线按程序中定义的连线即可
sbit lcd_RS = P0^0; //数据命令控制位,0命令1数据
sbit lcd_RW = P0^1; //读写位,0写1读
sbit lcd_EN = P0^2; //使能位,下降沿触发
sbit lcd_D4 = P0^3; //数据端口D4
sbit lcd_D5 = P0^4; //数据端口D5
sbit lcd_D6 = P0^5; //数据端口D6
sbit lcd_D7 = P0^6; //数据端口D7

lcd1602的vo端子对地接2.2k电阻,供电用5V


程序如下(我以前写的一个程序的基础上修改的,没有优化,闸门0.7s,32768Hz可分辨到+-0.01Hz左右),设计这个程序还是有一点小难度,弄了1天,时间关系,不想优化了,如果兴趣自行优化一下。程序中有一半代码是无用的,可以删除,不会删的话,就留着也没事。

//==========================================================================
//  ESR表驱动程序 V2.0
//  许剑伟 于莆田 2012.4
//  2013.7月最后修改
//==========================================================================
//==========================================================================
#define uchar unsigned char
#define uint  unsigned int
#define ulong  unsigned long
#include <reg52.h>

//==========================================================================
// 项目:LCD1602 四线驱动程序
// 设计要点:
//     LCD1602 的运行速度慢,而单片机运行的速度快,因此容易因为速度不
//     匹配造成调试失败。因此,调试之前应准确测试lcd_delay() 延时函数
//     准确的延时量,如果不能满足注释中的要求,则应调整循次数。每步操
//     作所需的延时量,按照数据手册指标指行,同时留下足够的时间余量。
// 硬件连接:
//     至少需要9条线,电源线2条,7条信号线。信号线详见程序中的接口定义。
//     清注意对LCD1602比对的调节,否则无显示。
// 设计:许剑伟,于莆田,2010.12
//==========================================================================
sbit lcd_RS = P0^0; //数据命令控制位,0命令1数据
sbit lcd_RW = P0^1; //读写位,0写1读
sbit lcd_EN = P0^2; //使能位,下降沿触发
sbit lcd_D4 = P0^3; //数据端口D4
sbit lcd_D5 = P0^4; //数据端口D5
sbit lcd_D6 = P0^5; //数据端口D6
sbit lcd_D7 = P0^6; //数据端口D7
//==========================================================================
void lcd_delay(int n){ //LCD专用延时函数
  //32MHz钟频下,约循环3000次延迟1毫秒
  int i,j;
  if(n<0)    { for(i=0;i< 10;i++); return; } //10us
  if(n== 0)  { for(i=0;i<50;i++); return; } //50us
  for(;n;n--){ for(j=0;j<1000;j++);        } //n毫秒
}
//==========================================================================
void lcd_B(char f, uchar c, char t){ //控制四线式接口LCD的7个脚
  //f=0写命令字, f=1写RAM数据, f=2读地址(或读忙), f=3读RAM数据
  lcd_EN = 1;
  lcd_RS = f%2;
  lcd_RW = f/2%2;
  //移入高四位
  lcd_D4 = c & 16;
  lcd_D5 = c & 32;
  lcd_D6 = c & 64;
  lcd_D7 = c & 128;
  lcd_delay(-1);  lcd_EN = 0; //使能脉冲
  if(f==4) { lcd_delay(t); return; }
  lcd_EN = 1;
  //移入低四位
  lcd_D4 = c & 1;
  lcd_D5 = c & 2;
  lcd_D6 = c & 4;
  lcd_D7 = c & 8;
  lcd_delay(-1);  lcd_EN = 0; //使能脉冲
  lcd_delay(t);  //不同的命令,响应时间不同,清零命令需要2ms
  lcd_EN = 1;
  lcd_RS = 1;
  lcd_RW = 1;
  lcd_D4 = 1;
  lcd_D5 = 1;
  lcd_D6 = 1;
  lcd_D7 = 1;
}
//==========================================================================
void lcd_init(){ //LCD1602 初始化
  //启动四线模式须势行9个步骤,初始化所须耗时较长,约65ms,时限不可减
  lcd_delay(20); //启动lcd之前须延时大于15ms,直到VDD大于4.5V
  lcd_B(4, 0x30, 9); //置8线模式,须延时大于4.1ms
  lcd_B(4, 0x30, 5); //置8线模式,须延时大于100us
  lcd_B(4, 0x30, 5); //置8线模式,手册中未指定延时
  lcd_B(4, 0x20, 5); //进入四线模式
  lcd_B(0, 0x28, 5); //四线模式双行显示
  lcd_B(0, 0x0C, 5); //打开显示器
  lcd_B(0, 0x80, 5); //RAM指针定位
  lcd_B(0, 0x01, 5); //启动清屏命初始化LCD
}
//==========================================================================
//=========================几个功能常用函数=================================
void lcd_cls()         { lcd_B(0, 0x01+0, 2);  } //清屏
void lcd_cur0()        { lcd_B(0, 0x0C+0, 0);  } //隐藏光标
void lcd_goto1(uchar x){ lcd_B(0, 0x80+x, 0);  } //设置DDRAM地址,第1行x位
void lcd_goto2(uchar x){ lcd_B(0, 0xC0+x, 0);  } //设置DDRAM地址,第2行x位
void lcd_putc(uchar d) { lcd_B(1, 0x00+d, 0);  } //字符输出
void lcd_puts(uchar *s){ for(; *s; s++) lcd_B(1,*s,0); } //字串输出
//==============字符显示函数====================
#define digW 4 //数字显示位数宏
void lcd_puti(long a,char w){ //定宽显示正整数
  char i=0, s[11] = "          ";
  if(a<0) { a=-a; lcd_puts("-"); }
  else    lcd_puts(" ");
  do{
   s[i++] = a%10+48;
   a /= 10;
  }while(a);
  for(;w;w--) lcd_putc(s[w-1]);
}
void lcd_putf(float a,char n,char w){ //浮点输出,n是保留小数的位数,w是数字宽度
char i,g,fi=0;
long b,c=1;
if(a<0) { lcd_putc('-'); a = -a; }
else    { lcd_putc(' '); }
for(i=0;i<n;i++) a *= 10;
for(i=1;i<w;i++) c *= 10;
b = a;
for(i=0;i<w;i++){
  g = b/c;
  b -= g*c;
  c /= 10;
  if(g>9||g<0) g='*'-48;
  if(i == w-n ) lcd_putc('.');
  if(!g && !fi && i<w-n-1) { lcd_putc(' '); continue; }
  lcd_putc(g+48);
  fi = 1;
}
if(!n) lcd_putc(' '); //无小数点的补足显示宽度
}
void lcd_putPic(char n,char *s){ //写入自字义字符
char i;
n = n<<3;
for(i=0;i<8;i++){
  lcd_B(0,0x40+n+i,0);
  lcd_B(1,s,0);
}
}

//==========================================================================
//===============================延时函数===================================
void delay(uint loop) { uint i; for(i=0;i<loop;i++); } //延时函数
void delay2(uint k)   { for(;k>0;k--) delay(10000);  } //长延时,k=100大约对应1秒

//==========================================================================
//=================================AD转换===================================
sfr P1ASF = 0x9D;     //将P1置为模拟口寄存器(使能),各位中为1的有效
sfr ADC_CONTR = 0xBC; //A/D转换控制寄存器
sfr ADC_res   = 0xBD; //A/D转换结果寄存器
sfr ADC_resl  = 0xBE; //A/D转换结果寄存器

void set_channel(char channel){
P1ASF = 1<<channel;
ADC_CONTR = channel+128; //最高位是电源开关,低3位通道选择
delay(1); //首次打开电源应延迟,使输入稳定
}
uint getAD2(){
ADC_CONTR |= 0x08;             //00001000,置ADC_START=1启动A/D 转换
while ( !(ADC_CONTR & 0x10) ); //等待A/D转换结束(ADC_FLAG==0)
ADC_CONTR &= 0xE7;             //11100111,置ADC_FLAG=0清除结束标记, 置ADC_START=0关闭A/D 转换
return ADC_res*4 + ADC_resl;
}
/*
uchar get_AD(){
ADC_CONTR |= 0x08;             //00001000,置ADC_START=1启动A/D 转换
while( !(ADC_CONTR & 0x10) );  //等待A/D转换结束(ADC_FLAG==0)
ADC_CONTR &= 0xE7;             //11100111,置ADC_FLAG=0清除结束标记, 置ADC_START=0关闭A/D 转换
return ADC_res;
}
*/


//==========================================================================
//==================================EEPROW偏程==============================
sfr IAP_data  = 0xC2;
sfr IAP_addrH = 0xC3;
sfr IAP_addrL = 0xC4;
sfr IAP_cmd   = 0xC5;
sfr IAP_trig  = 0xC6;
sfr IAP_contr = 0xC7;
/********************
写字节时,可以将原有数据中的1改为0,无法将0改为1,只能使用擦除命令将0改为1
应注意,擦除命令会将整个扇区擦除
*********************/
int eepEn = 0;
void saEEP(){ //触发并EEP保护
if(eepEn==12345) IAP_trig = 0x5A;  //先送5A
if(eepEn==12345) IAP_trig = 0xA5;  //先送5A再送A5立即触发
IAP_cmd = 0;      //关闭令,保护
IAP_contr = 0;    //关EEPROM,保护
IAP_trig = 0;
IAP_addrL = 255; //设置读取地址的低字节,地址改变才需要设置
IAP_addrH = 255; //设置读取地址的高字节,地址改变才需要设置
}
uchar readEEP(uint k){ //读取
IAP_addrL = k;    //设置读取地址的低字节,地址改变才需要设置
IAP_addrH = k>>8; //设置读取地址的高字节,地址改变才需要设置
IAP_contr = 0x81; //设置等待时间,1MHz以下取7,2M以下取6,3M取5,6M取4,12M取3,20M取2,24M取1,30M取0,前导1表示许档IAP
IAP_cmd = 1;      //读取值1,写取2,擦除取3,擦除时按所在字节整个扇区撺除
saEEP(); //触发并保护
return IAP_data;
}
void writeEEP(uint k, uchar da){ //写入
IAP_data = da;    //传入数据
IAP_addrL = k;    //设置读取地址的低字节,地址改变才需要设置
IAP_addrH = k>>8; //设置读取地址的高字节,地址改变才需要设置
IAP_contr = 0x81; //设置等待时间,1MHz以下取7,2M以下取6,3M取5,6M取4,12M取3,20M取2,24M取1,30M取0,前导1表示许档IAP
IAP_cmd = 2;      //读取值1,写取2,擦除取3,擦除时按所在字节整个扇区撺除
saEEP(); //触发并保护
}
void eraseEEP(uint k){ //擦除
IAP_addrL = k;    //设置读取地址的低字节,地址改变才需要设置
IAP_addrH = k>>8; //设置读取地址的高字节,地址改变才需要设置
IAP_contr = 0x81; //设置等待时间,1MHz以下取7,2M以下取6,3M取5,6M取4,12M取3,20M取2,24M取1,30M取0,前导1表示许档IAP
IAP_cmd = 3;      //读取值1,写取2,擦除取3,擦除时按所在字节整个扇区撺除
saEEP(); //触发并保护
}


xdata struct Ida{
int c[3];  //起点校准,中点校准,末点校准
} cs;

void cs_RW(char rw){
uchar i,*p = &cs;
const int offs=512;
if(rw){
  eraseEEP(offs);
  for(i=0;i<sizeof(cs);i++) writeEEP(i+offs,p);
}else{
  for(i=0;i<sizeof(cs);i++) p=readEEP(i+offs);
}
}


//==========================================================================
//==================================ESR主程序===============================
//==========================================================================
sfr P1M1=0x91; //P1端口设置寄存器
sfr P1M0=0x92; //P1端口设置寄存器
sfr P0M1=0x93; //P0端口设置寄存器
sfr P0M0=0x94; //P0端口设置寄存器
sfr P2M1=0x95; //P2端口设置寄存器
sfr P2M0=0x96; //P2端口设置寄存器
sfr P3M1=0xB1; //P3端口设置寄存器
sfr P3M0=0xB2; //P3端口设置寄存器
sfr WAKE_CLKO = 0x8F;
sfr AUXR = 0x8E;
sfr BRT = 0x9C;


xdata uchar menu=0,menu2=0; //菜单变量
ulong nn = 0; //时序计数器


long feq=0;
unsigned char Tk0=0,Tk1=0;
unsigned long f0=0,f1=0,Tm=200;
void timerInter0(void) interrupt 1 {//T0中断
  static unsigned char Tu=0;
  Tk0++;
  Tu = (Tu+1)%Tm;
  if(!Tu) { IE1 = 0; EX1 = 1; } //开外部中断
}
void timerInter1(void) interrupt 3 { Tk1++; } //T1中断

void int0(void) interrupt 0{ } //INT0中断
void int1(void) interrupt 2{ //INT1中断
static unsigned long m0=0,m1=0;
unsigned long n0,n1;
unsigned char v,a,b,c;
unsigned char V,A,B,C;
EX1 = 0; //关外部中断INT1
//如果c值小,跳变发生在取c与取v之间,b可信
//如果c值大,跳变发生在取c与取b之间,b不可信
v = TH0; c = TL0; b = TH0; a = Tk0;
V = TH1; C = TL1; B = TH1; A = Tk1;
if(v!=b) { //取值时定时器高位跳变
  if(c<128){ if(b==0) a++; } //INT1优先级高定时计数中断此时无法触法,a无法跳变,所以这里修正a
  else b--; //b不可信,需修正
}
if(V!=B) { //取值时计数器高位跳变
  if(C<128){ if(B==0) A++; } //INT1优先级高定时计数中断此时无法触法,a无法跳变,所以这里修正a
  else B--; //b不可信,需修正
}
n0 = a*256L*256L + b*256L + c;
n1 = A*256L*256L + B*256L + C;
if(n0<m0) f0 = (1L<<24)+n0-m0; else f0 = n0-m0;
if(n1<m1) f1 = (1L<<24)+n1-m1; else f1 = n1-m1;
m0 = n0;
m1 = n1;
}



main(){
uchar kn=0,key=0,keya=0,keyb=0; //键盘响应变量
//端口初始化,M1M0,00常规口,01推挽口,10高阻口,11开漏口
P1M0 = 0x01;    //P1.0推挽口
P1M1 = 0x00;    //
P3M0 = 0x00;    //00110000 P3.3,P3.4置为高阻口
P3M1 = 0x28;    //00100000


delay2(3);    //等待升压电源电压上升
lcd_init();   //初始化LCD
lcd_cur0();   lcd_puts("Vref V1.0");   //隐藏光标并显示片本
lcd_goto2(0); lcd_puts("XJW Putian,2013"); //显示作者
lcd_putPic(1,"\x00\x00\xE\x11\x11\x0a\x1b\x00");
delay2(100);  lcd_cls(); //启动延时
eepEn= 12345;
cs_RW(0);   //读EEPROM
if( ((uint)cs.c[0]>>8)==0xff )  cs.c[0] = cs.c[1] = cs.c[2] = 0;


AUXR |= 0x80;  //T0工作在1T
AUXR |= 0x40;  //T1工作在1T
AUXR |= 0x04;  //BRT工作在1T


WAKE_CLKO |= 0x04; //允许BRT输出时钟
AUXR |= 0x10; //启动BRT
BRT = 1;

TMOD =  0x51;  //T1置为16位计数器,T0置为16位定时器
TR0 = TR1 = 1; //起动计数
ET0 = ET1 = 1; //开定时器中断
IT1 = 1; //INT1中断下降沿触发,置1后,只要有下降沿就会IE1就会置位,不受EX1控制
EX1 = 0; //INT1中断许可设置
PX1 = 1; //INT1中断优先级置1,即IP |= 0x04;
EA = 1;        //开总中断


set_channel(1); //设置AD转换通道
while(1){
  nn++;
  //扫描键盘
  key=0;  keya=keyb;  keyb=(~P3)&(128+64+32);
  if(keya){
   if(!keyb){ //键弹起
     if(kn>2)  key = keya;   //短按
     if(kn>40) key = keya+1; //长按,约1至2秒
     kn = 0;
   }
   else kn += kn<255?1:0;
  }
  //菜单系统
  if(key==65){ //菜单键
        lcd_cls();
        if(++menu>1) menu=0,menu2=0;
  }
  if(key==64){ //保存参数
   //cs_RW(1);
   //lcd_cls();
   //lcd_puts("saved OK");
   //delay2(50);
  }
  if(menu==0){ //显示输出电压
    if(nn%20==0){
          lcd_goto1(0);  lcd_putf(18432000.0*f1/f0,2,10);
          //lcd_goto1(0);  lcd_puti(f0,7);
          //lcd_goto2(0);  lcd_puti(f1,7);
        }
  }
  if(menu==1){ //校准
  }
  delay(10000);
}//while end
}
//==========================================================================
回复 支持 反对

使用道具 举报

     
 楼主| 发表于 2018-4-24 07:39:04 | 显示全部楼层
本帖最后由 lmwyl 于 2018-4-24 07:40 编辑
xjw01 发表于 2018-4-23 23:47
改电路可能更麻烦了。而且100s时间也太长了,即使成了,也不好用啊。
建议按wash说的,改用等精度频率测 ...


十分感谢!是太麻烦了,不过收到的VC2000频率计后一试,发现问题很简单只要用频率计第4档在计数器状况下阐门10s测试100s后看是否为3276800不就行了,不过我在经过几次约3000s测试过程中每隔几佰秒记录下来再经过推算发现几种32768的石英本身就有约最大0.05Hz的漂移,不过业余下应该够了,那天也装个你的"自制32768Hz时钟信号感应器":试试
回复 支持 反对

使用道具 举报

     
发表于 2018-4-24 10:13:33 | 显示全部楼层
washu 发表于 2018-4-16 13:22
不只是你忍不忍得住的问题,还要看信号忍不忍得住。如果真的有精确测定频率的需求,100s 让机器自己去忍 ...

图中组合,频率基准不确定度大约相当于多少ppm?
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 加入会员

本版积分规则

小黑屋|手机版|矿石收音机 ( 蒙ICP备05000029号-1 )

蒙公网安备 15040402000005号

GMT+8, 2024-4-25 08:55

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表