搜索
bottom↓
回复: 40

求助:可以给单片机外接晶体振荡器求出该晶振频率吗?

[复制链接]

出0入0汤圆

发表于 2012-7-24 11:31:11 | 显示全部楼层 |阅读模式
已知一个石英晶体的谐振频率为5MHz左右(大概偏差几十Hz),想要较为准确测试出其谐振频率,可以把它作为一个晶振,接到单片机的两个晶振输入端,然后算出这个石英晶体的谐振频率么?如果可以的话,具体怎么接怎么求算?精度如何?对应的程序怎么写?如果不行的话,有高手能够提供有用建议么?

阿莫论坛20周年了!感谢大家的支持与爱护!!

知道什么是神吗?其实神本来也是人,只不过神做了人做不到的事情 所以才成了神。 (头文字D, 杜汶泽)

出20入12汤圆

发表于 2012-7-24 11:49:06 | 显示全部楼层
估计不行,因为使用单片机内部的振荡器作为参考标准,内部振荡器的精度相对于你的要求来说太低了

出0入663汤圆

发表于 2012-7-24 12:27:12 | 显示全部楼层
测普通晶体的谐振频率至少需要用恒温晶振做参考时钟。

出0入0汤圆

发表于 2012-7-24 13:39:27 来自手机 | 显示全部楼层
不用算啊 STC单片机下载的时候在STC-ISP软件里有晶振频率显示 精度貌似很高

出0入0汤圆

 楼主| 发表于 2012-7-24 14:23:09 | 显示全部楼层
gaoyichuan000 发表于 2012-7-24 13:39
不用算啊 STC单片机下载的时候在STC-ISP软件里有晶振频率显示 精度貌似很高

不是这个意思。我们重点是要测量一个石英晶体(和晶振不完全一样)的谐振频率,想出一个方案是把它作为单片机的晶振驱动单片机工作。如果可以测出该方案下的频率是不是就可以理解为是该晶振的谐振频率??

出0入0汤圆

 楼主| 发表于 2012-7-24 14:23:35 | 显示全部楼层
gzhuli 发表于 2012-7-24 12:27
测普通晶体的谐振频率至少需要用恒温晶振做参考时钟。

不是这个意思。我们重点是要测量一个石英晶体(和晶振不完全一样)的谐振频率,想出一个方案是把它作为单片机的晶振驱动单片机工作。如果可以测出该方案下的频率是不是就可以理解为是该晶振的谐振频率??

出0入0汤圆

 楼主| 发表于 2012-7-24 14:23:51 | 显示全部楼层
gaoyichuan000 发表于 2012-7-24 13:39
不用算啊 STC单片机下载的时候在STC-ISP软件里有晶振频率显示 精度貌似很高

不是这个意思。我们重点是要测量一个石英晶体(和晶振不完全一样)的谐振频率,想出一个方案是把它作为单片机的晶振驱动单片机工作。如果可以测出该方案下的频率是不是就可以理解为是该晶振的谐振频率??

出0入0汤圆

 楼主| 发表于 2012-7-24 14:24:14 | 显示全部楼层
gaolf_2012 发表于 2012-7-24 11:49
估计不行,因为使用单片机内部的振荡器作为参考标准,内部振荡器的精度相对于你的要求来说太低了 ...

不是这个意思。我们重点是要测量一个石英晶体(和晶振不完全一样)的谐振频率,想出一个方案是把它作为单片机的晶振驱动单片机工作。如果可以测出该方案下的频率是不是就可以理解为是该晶振的谐振频率??

出0入663汤圆

发表于 2012-7-24 14:59:23 | 显示全部楼层
zzfu2010 发表于 2012-7-24 14:23
不是这个意思。我们重点是要测量一个石英晶体(和晶振不完全一样)的谐振频率,想出一个方案是把它作为单 ...

晶体并联谐振频率和串联谐振频率之分,单片机是皮尔斯振荡电路,谐振频率介于串联谐振和并联谐振之间,具体频率跟负载电容和杂散电容有关,不知你想干嘛。

出0入0汤圆

 楼主| 发表于 2012-7-25 00:39:14 | 显示全部楼层
gzhuli 发表于 2012-7-24 14:59
晶体并联谐振频率和串联谐振频率之分,单片机是皮尔斯振荡电路,谐振频率介于串联谐振和并联谐振之间,具 ...

我们是在研究一个用石英晶体做成的传感器,需要测出晶体的谐振频率,虽然有一些经典的电路比如皮尔斯振荡电路可以用于检测,不过由于自己动手搭建出一个模电振荡电路太难了就打算用一下单片机方案。不知道能不能行的通。

出0入663汤圆

发表于 2012-7-25 01:48:42 | 显示全部楼层
zzfu2010 发表于 2012-7-25 00:39
我们是在研究一个用石英晶体做成的传感器,需要测出晶体的谐振频率,虽然有一些经典的电路比如皮尔斯振荡 ...

用74HCU04就能搭出皮尔斯振荡器,跟单片机内部的振荡器是一样的。
附件是很好的参考资料。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

发表于 2012-7-25 05:09:45 | 显示全部楼层
that's fairly simple:

1) use your crystal to form an oscillator and use a known crystal to run the mcu to measure its frequency;
2) use a known crystal to form an oscillator and use your crystal to run the mcu to measure the frequency.

出0入0汤圆

发表于 2012-7-25 08:44:37 | 显示全部楼层
本帖最后由 surf_131 于 2012-7-25 08:46 编辑

如果lz你用的是pic芯片,由于pic单片机的Fosc与Fcy(机器周期)之间有确定的对应关系,即4个振荡器周期等于一个机器周期,所以,从原理上你可以测量一个精确的时钟源来判断本机时钟的偏差。
最高工作频率数十兆,作为pic机器一般不允许超过25M。5M时误差数十赫,也就是说,精度至少要达到6位。这个分辨率恐怕就不是一般单片机能够达到的了。
例如,你用CCP捕捉来判断频率误差,但是CCP只有16比特,不到5位精度。
如果测量精度低,是有可能实现的。精度高就没有办法了。毕竟单片机是非常廉价的装置,用途也不同。

出0入0汤圆

 楼主| 发表于 2012-7-28 11:41:32 | 显示全部楼层
gzhuli 发表于 2012-7-25 01:48
用74HCU04就能搭出皮尔斯振荡器,跟单片机内部的振荡器是一样的。
附件是很好的参考资料。 ...

嗯 多谢啦!我再思考下,不懂得地方再请教,嘿嘿!

出0入0汤圆

 楼主| 发表于 2012-7-28 11:41:58 | 显示全部楼层
millwood0 发表于 2012-7-25 05:09
that's fairly simple:

1) use your crystal to form an oscillator and use a known crystal to run the  ...

嗯 多谢指点!我再思考下,不懂得地方再请教,嘿嘿!

出0入0汤圆

 楼主| 发表于 2012-7-28 11:42:34 | 显示全部楼层
surf_131 发表于 2012-7-25 08:44
如果lz你用的是pic芯片,由于pic单片机的Fosc与Fcy(机器周期)之间有确定的对应关系,即4个振荡器周期等于 ...

嗯。我再想想,多谢指点!!

出0入0汤圆

发表于 2012-7-28 21:25:00 | 显示全部楼层
你写一个程序,比如定时器中断控制一个IO翻转,
然后用频率计测那个IO,
最后反算出那个晶振的频率,
我就是这样测的!

出0入0汤圆

发表于 2012-7-31 15:42:40 | 显示全部楼层
学习了。         

出0入0汤圆

 楼主| 发表于 2012-7-31 19:42:10 | 显示全部楼层
chengzepeng 发表于 2012-7-28 21:25
你写一个程序,比如定时器中断控制一个IO翻转,
然后用频率计测那个IO,
最后反算出那个晶振的频率,

嗯  回校尝试下 现在在家 不方便 多谢指教啦!

出0入0汤圆

发表于 2012-8-1 00:43:05 | 显示全部楼层
chengzepeng 发表于 2012-7-28 21:25
你写一个程序,比如定时器中断控制一个IO翻转,
然后用频率计测那个IO,
最后反算出那个晶振的频率,

还不如直接弄个晶体振荡器电路,振起来后频率计读出.........上单片机再倒回去算,属于脱裤子放屁。

出0入0汤圆

 楼主| 发表于 2012-8-1 11:26:03 | 显示全部楼层
zhufeng88 发表于 2012-8-1 10:40
我也正在学习中,顶...

嗯 共同努力!!

出0入0汤圆

发表于 2012-8-1 14:46:26 | 显示全部楼层
surf_131 发表于 2012-8-1 00:43
还不如直接弄个晶体振荡器电路,振起来后频率计读出.........上单片机再倒回去算,属于脱裤子放屁。 ...

你的晶体振荡电路如果不在单片机上实测就会有差别,
如果直接用示波器或者频率计接单片机那个振荡输出脚就会影响振荡,
还有假设你的5M晶振接在测试电路上是5M(调试好的电路),
这样你接到单片机上就不一定是5M,
也许是4.9998M(配置的负载电容可以细调),
因为你没有去实测。

出0入0汤圆

发表于 2012-8-1 15:10:03 | 显示全部楼层
chengzepeng 发表于 2012-8-1 14:46
你的晶体振荡电路如果不在单片机上实测就会有差别,
如果直接用示波器或者频率计接单片机那个振荡输出脚 ...

任何晶体都不是“单一”谐振的,都是双峰,较低的是串谐频率,较高的是并谐频率,在二者之间晶体等效于一个高q值电感。任何驱动晶体实现震荡的外部电路都带有电容性,这外来电容就决定了实际发生的振荡的频率。
一般说,如果是运行实际任务,单片机基本不依赖自己内部时钟进行精确定时。需要长期准确频率,可以用RTCC,更精确时可以配GPS模块校准时间。需要可控的精确频率源,有些型号自带VCO+PLL。
获取精确时钟的办法很多,为什么要死守一个晶体?

再说,测试一个振荡器就一定要在振荡器内部来测?不会做一个驱动级?随便一个射极跟随器就隔离掉了对振荡器的影响。

出0入0汤圆

发表于 2012-8-3 15:13:56 | 显示全部楼层
搂主要测的是该晶体在某个单片机上的振荡频率,
我觉得最容易和最准确的就是通过单片机自身运行然后输出到一个IO反映出该晶体当前的频率,
我测单片机的内部振荡频率就这样测的,
如果说要更高精度那么单片机接晶体(不是晶振)明显不是好选择,
如果测晶体的话随意一个振荡电路都可以判断好坏.

目的和出发点选择确定选用哪种测试方案.

注: 晶体就是普通那个不带振荡电路的无源晶振,晶振就是那种有源晶振,
一般叫晶振的都是无源晶振,
所以楼主说的晶振应该是无源晶振.

出0入0汤圆

发表于 2012-8-3 17:38:36 | 显示全部楼层
我感觉你可以用频率已知稳定度较好的的晶振测,要用汇编写,用斯密特触发器测频率,LZ你自己看是测周还是测频精度比较高

出0入0汤圆

 楼主| 发表于 2012-8-11 13:58:46 | 显示全部楼层
surf_131 发表于 2012-8-1 00:43
还不如直接弄个晶体振荡器电路,振起来后频率计读出.........上单片机再倒回去算,属于脱裤子放屁。 ...

用模电做晶体振荡电路做了很久一直没有出来。于是就想能不能用单片机来测量。至于这个方法能不能行得通我也是不太清楚,因此发帖求助,现在在尝试各位大神回复的帖子。

出0入0汤圆

 楼主| 发表于 2012-8-11 14:16:57 | 显示全部楼层
chengzepeng 发表于 2012-8-3 15:13
搂主要测的是该晶体在某个单片机上的振荡频率,
我觉得最容易和最准确的就是通过单片机自身运行然后输出到一 ...

我们目的要测试的就是一个孤立的石英晶体(有电极)的振荡频率,也就是一个无源晶振吧。之前一直是用振荡电路做,由于自己模电不是很强电路的参数一直没弄好,导致不能正确测出,于是才想到转用单片机来测量。。由于自己是新手,请问大侠您提出的建议可以行得通么?另外,方便贴出来您写的程序吗?多谢!

出0入0汤圆

发表于 2012-8-11 15:44:13 | 显示全部楼层
zzfu2010 发表于 2012-8-11 14:16
我们目的要测试的就是一个孤立的石英晶体(有电极)的振荡频率,也就是一个无源晶振吧。之前一直是用振荡 ...

我已经说过,即便知道待测晶体的频率范围,你用它自身怎么测量自己的准确频率?
这就如同你有一把尺子,要知道这尺子偏差多少,仅凭它自己怎么得知?

振荡器测量,只要从那电路上外接个射极跟随器,降低测量系统引进的误差,普通频率计就完全没有问题。就是说能够达到10E-6的精度。
非要用单片机当振荡器也不是绝对不行,但是测量精度难说了。
最简单的,只要主循环里面一个语句:

LED^=LED;
事先定义一个IO口为输出,命名为LED。然后在这个口上测量频率,得到的频率乘以16(假定循环语句等于一个机器周期),就是晶体的频率了。其它振荡器配的两个电容,还有选择频率源等,要自己查手册解决了。

出0入0汤圆

发表于 2012-8-11 16:04:35 | 显示全部楼层
  1. #include <pic.h>

  2. // 内部振荡GP4/GP5为IO,关看门狗,上电复位延时,开外部复位脚,关数据保护,关代码保护,开掉电复位
  3. __CONFIG(FOSC_INTRCIO & WDTE_OFF & PWRTE_ON & MCLRE_ON & CP_OFF & CPD_OFF & BOREN_OFF);   // 12F675&12F629
  4. //                更换这个振荡类型

  5. void mcu_init()
  6. {
  7.         CMCON  = 0b00000111;                 // 关闭内部比较器
  8.         ANSEL  = 0;                                // 全部为数字IO,用629时可以不用这一句
  9.         TRISIO = 0b00111000;                 //
  10.         GPIO   = 0;                                //       

  11. }

  12. void main(void)
  13. {
  14.         mcu_init();
  15.         while(1)                        // 循环一次5个指令时间,4M时钟时输出100KHz,5M时钟时GP0输出125KHz
  16.         {
  17.                 GP0 = !GP0;        // 下面如果用空指令会运行多一个指令
  18.                 GP1 = 0;                // 当空指令用
  19.         }
  20. }
复制代码
将频率计接到GP0看频率就知道准不准了,
用10秒钟的阀门时可以达到最高测量精度。

出0入0汤圆

 楼主| 发表于 2012-8-11 16:05:09 | 显示全部楼层
surf_131 发表于 2012-8-11 15:44
我已经说过,即便知道待测晶体的频率范围,你用它自身怎么测量自己的准确频率?
这就如同你有一把尺子, ...

谢谢指点~
有一点比较讨厌的是,用模拟振荡电路一直没有做成功,请问大侠您有好的5M晶体振荡电路推荐么?我是说具体的电路(最好有各个元件的具体值)。非常感谢!

出0入0汤圆

 楼主| 发表于 2012-8-11 16:07:31 | 显示全部楼层
chengzepeng 发表于 2012-8-11 16:04
将频率计接到GP0看频率就知道准不准了,
用10秒钟的阀门时可以达到最高测量精度。 ...

额,不好意思啊,我对pic单片机不太了解,我们用的是AT89C52(或S52),请问能够兼容吗?应该怎样修改?多谢。。。。。

出0入0汤圆

发表于 2012-8-11 16:12:53 | 显示全部楼层
  1. #include <pic.h>

  2. // 内部振荡GP4/GP5为IO,关看门狗,上电复位延时,开外部复位脚,关数据保护,关代码保护,开掉电复位
  3. __CONFIG(FOSC_INTRCIO & WDTE_OFF & PWRTE_ON & MCLRE_ON & CP_OFF & CPD_OFF & BOREN_OFF);   // 12F675&12F629
  4. //                更换这个振荡类型

  5. void mcu_init()
  6. {
  7.         CMCON  = 0b00000111;                 // 关闭内部比较器
  8.         ANSEL  = 0;                                        // 全部为数字IO,用629时可以不用这一句
  9.         TRISIO = 0b00111000;                 //
  10.         GPIO   = 0;                                        //       

  11. }

  12. void main(void)
  13. {
  14.         mcu_init();
  15.     while(1)                        // 循环一次5个指令时间,4M时钟时输出200KHz,5M时钟时GP0输出250KHz
  16.         {
  17.                 GP0 = 1;
  18.                 GP0 = 1;
  19.                 GP0 = 0;       
  20.     }
  21. }
复制代码

出0入0汤圆

 楼主| 发表于 2012-8-11 16:30:09 | 显示全部楼层
chengzepeng 发表于 2012-8-11 16:12

请问这个程序能够用于AT89C52(或S52)么?由于我对pic不怎么理解,感觉还是用于pic的程序啊……

出0入0汤圆

发表于 2012-8-11 17:01:35 | 显示全部楼层
本帖最后由 chengzepeng 于 2012-8-11 17:03 编辑
  1. #include<AT89X51.H>

  2. void main()
  3. {
  4.         while(1)
  5.         {
  6.                 P1_0 = 1;
  7.                 P1_0 = 0;
  8.         }
  9. }
复制代码
由于51是12分频的,所以5M的晶体分频后得到 5/12 M 的指令速度,指令时间为1/(5/12)= 2.4uS,
一个循环4指令,2.4*4=9.6uS,
输出频率为1000/9.6=104.166666666666666666666............................循环 (KHz)

还有拜托别做伸手当,
以及你想搞51的跑错到了PIC的区?

出0入0汤圆

 楼主| 发表于 2012-8-11 17:34:03 | 显示全部楼层
chengzepeng 发表于 2012-8-11 17:01
由于51是12分频的,所以5M的晶体分频后得到 5/12 M 的指令速度,指令时间为1/(5/12)= 2.4uS,
一个循环4 ...

啊,不好意思啊,因为发帖时候是第一次来阿莫,所以可能不小心点错了,不好意思啊
多谢指点了!

出0入0汤圆

 楼主| 发表于 2012-8-11 17:38:43 | 显示全部楼层
chengzepeng 发表于 2012-8-11 17:01
由于51是12分频的,所以5M的晶体分频后得到 5/12 M 的指令速度,指令时间为1/(5/12)= 2.4uS,
一个循环4 ...

其实对51也是接触没有多久。。。我们项目本来以为模电能够解决,后来发现太恶心了,讨论下寻思换个方案,刚刚接触没有多久,所以很不好意思了。。。

出0入0汤圆

发表于 2012-8-11 18:04:21 | 显示全部楼层
如果要求不高的话用个单片机做个简单的频率计就可以了,
并且计算频率误差什么的!
前提是你的单片机速度够快,
简单的看下频率的话买个频率计也就是一百来块!

出0入0汤圆

发表于 2012-8-11 23:32:04 | 显示全部楼层
不过由于自己动手搭建出一个模电振荡电路太难了


if so, maybe you want to consider a different career than EE.

出0入0汤圆

发表于 2012-8-11 23:32:53 | 显示全部楼层
  1. void mcu_init()...
复制代码
that's almost word-for-word what I do.

:)

出0入0汤圆

发表于 2012-8-11 23:43:28 | 显示全部楼层
millwood0 发表于 2012-8-11 23:32
that's almost word-for-word what I do.

:)

LS拜托使用中文,

拿你的话扔进谷歌看了也不知道说啥,

如果是问那个子函数用途的话,

这个单片机的初始化你不会不明白吧?

为了方便移植程序把初始化独立出来的!

出0入0汤圆

发表于 2012-8-19 22:34:55 | 显示全部楼层
支持同学
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-7-24 02:25

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

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