|
|||||||||||
| 技術(shù)交流 | 電路欣賞 | 工控天地 | 數(shù)字廣電 | 通信技術(shù) | 電源技術(shù) | 測(cè)控之家 | EMC技術(shù) | ARM技術(shù) | EDA技術(shù) | PCB技術(shù) | 嵌入式系統(tǒng) 驅(qū)動(dòng)編程 | 集成電路 | 器件替換 | 模擬技術(shù) | 新手園地 | 單 片 機(jī) | DSP技術(shù) | MCU技術(shù) | IC 設(shè)計(jì) | IC 產(chǎn)業(yè) | CAN-bus/DeviceNe |
我的晶振測(cè)頻小玩意兒 |
| 作者:BitFu 欄目:單片機(jī) |
本來想做個(gè)頻率計(jì),可是看這情況精度不高,想改進(jìn),有興趣的朋友一起探討。! 程序如下: main.c: /*************************** 文件名:main.c 功 能:晶體頻率計(jì)程序 器 件:ATMEGA48-20PI 編 譯:WINAVR20050214 C語(yǔ)言庫(kù):avr-libc-1.4.0 作者:芯藝 2005-12-6 ***************************/ #include <avr/io.h> #include <util/delay.h> #include <avr/interrupt.h> #include <stdlib.h> #include <math.h> #define uCHAR unsigned CHAR #define uint unsigned int #define uLONG unsigned LONG uint g_aTimerValue[2]; //記錄前后輸入捕獲時(shí)的時(shí)間印跡 uint g_bICP1Counter=0; //輸入捕獲中斷次數(shù)計(jì)數(shù)器 uCHAR g_bCaptureFlag=0; //一次測(cè)量完成標(biāo)記 uint g_bTimer1Counter=0; //定時(shí)器/計(jì)數(shù)器1溢出中斷次數(shù)計(jì)數(shù)器 CHAR g_strFreq[10]; //用于打印數(shù)據(jù)的字符緩沖區(qū) //誤差不會(huì)太大的延時(shí)1ms函數(shù) void DelayMs(uint t) { unsigned int i; for(i=0;i<t;i++) _delay_loop_2((F_CPU/1e6)*250); } //定時(shí)器/計(jì)數(shù)器1溢出中斷 SIGNAL(SIG_OVERFLOW1) { if(g_bICP1Counter) g_bTimer1Counter++; } //定時(shí)器計(jì)數(shù)器輸入捕獲中斷 SIGNAL(SIG_INPUT_CAPTURE1) { uint VALUE=ICR1; if(g_bICP1Counter==0) //第一次中斷 { g_aTimerValue[0]=VALUE; g_bICP1Counter=1; //輸入捕獲中斷計(jì)數(shù)1 } else if(g_bTimer1Counter>=100) { TIMSK1 =0; //禁止TIMER1相關(guān)中斷 TCCR1B = 0; g_aTimerValue[1]=VALUE; g_bCaptureFlag=1; //測(cè)量完成標(biāo)記置位 } else g_bICP1Counter++; //輸入捕獲中斷計(jì)數(shù) } //USART0異步寫一字符 int put_CHAR(CHAR c) { if(c=='\n') put_CHAR('\r'); while (!( UCSR0A & (1<<UDRE0))); UDR0 = c; return 0; } //向USART0口打印字符串 void myprint(CHAR *str) { uCHAR i; for(i=0;i<100;i++) { if(str[i]==0) break; else put_CHAR(str[i]); } } void Usart0Init(void) { UBRR0L=77; //設(shè)置波特率9600 bit/s 12MHZ:77 UCSR0B =_BV(TXEN0); //USART0發(fā)送允許 UCSR0C = _BV(UCSZ01)|_BV(UCSZ00); //設(shè)置幀格式: 8 個(gè)數(shù)據(jù)位, 1 個(gè)停止位 } //一次測(cè)量操作 uLONG GetFreq(void) { double ret,tmp; g_bICP1Counter=0; g_bTimer1Counter=0; TCNT1=0; TIMSK1 =_BV(ICIE1)|_BV(TOIE1); //兩個(gè)中斷使能 TCCR1B = _BV(CS10)|_BV(ICNC1); //不分頻,開始計(jì)數(shù),輸入捕獲濾波使能 while(g_bCaptureFlag==0) DelayMs(1); //前后輸入捕獲中斷時(shí)的定時(shí)器/計(jì)數(shù)器1值保存到了g_aTimerValue[2] //g_bTimer1Counter為第一次和最后一次輸入捕獲中斷期間定時(shí)器/計(jì)數(shù)器1發(fā)生的溢出中斷次數(shù) //g_bICP1Counter為測(cè)量期間輸入捕獲中斷產(chǎn)生的次數(shù) g_bCaptureFlag=0; tmp=0x10000 * (g_bTimer1Counter-1); tmp+= (0x10000 - g_aTimerValue[0]) + g_aTimerValue[1]; ret=12000000.0/tmp; return (uLONG)(ret*g_bICP1Counter*256); } //測(cè)試主程序 int main(void) { uLONG newfreq,oldfreq=0; Usart0Init(); sei(); while(1) { newfreq=GetFreq(); if(newfreq!=oldfreq) { oldfreq=newfreq; myprint(ltoa(oldfreq,g_strFreq,10)); myprint("\n"); } else DelayMs(100); }//main loop } |
| 2樓: | >>參與討論 |
| 作者: BitFu 于 2005/12/7 11:00:00 發(fā)布:
實(shí)物圖
|
|
| 3樓: | >>參與討論 |
| 作者: BitFu 于 2005/12/7 11:01:00 發(fā)布:
原理圖
|
|
| 4樓: | >>參與討論 |
| 作者: BitFu 于 2005/12/7 11:03:00 發(fā)布:
GAL16V8程序 MODULE COUNTER title '8bit counter www.chip-art.net 2005-11' COUNTER DEVICE 'P16V8R'; "使用GAL16V8 "CLK,OE的定義只能使用芯片約定的引腳 Clk,OC pin 1,11; Q0,Q1,Q2,Q3,Q4,Q5,Q6,Q7 pin 19,18,17,16,15,14,13,12; OUTPUT = [Q7,Q6,Q5,Q4,Q3,Q2,Q1,Q0]; equations OUTPUT.clk = Clk; "輸出與CLK有關(guān) OUTPUT.oe = !OC; "輸出受!OC才有效 WHEN !OC THEN "如果OC為低電平則 OUTPUT := OUTPUT + 1; "受時(shí)鐘觸發(fā)的鎖存 end COUNTER "本模塊程序結(jié)束 |
|
| 5樓: | >>參與討論 |
| 作者: BitFu 于 2005/12/7 11:05:00 發(fā)布:
測(cè)試后的輸出結(jié)果:
|
|
| 6樓: | >>參與討論 |
| 作者: BitFu 于 2005/12/7 11:08:00 發(fā)布:
這是個(gè)4M晶振的測(cè)試結(jié)果 |
|
| 7樓: | >>參與討論 |
| 作者: zsmbj 于 2005/12/7 11:16:00 發(fā)布:
不錯(cuò),不過首先要保證那個(gè)MCU的12M晶體的精度。 |
|
| 8樓: | >>參與討論 |
| 作者: xdsg 于 2005/12/10 9:00:00 發(fā)布:
不錯(cuò) |
|
| 9樓: | >>參與討論 |
| 作者: athlon64fx 于 2005/12/10 10:03:00 發(fā)布:
應(yīng)該用32K晶體 |
|
| 10樓: | >>參與討論 |
| 作者: BitFu 于 2005/12/10 12:05:00 發(fā)布:
現(xiàn)在就是精度上不去 大約50ppm 換成溫補(bǔ)晶振會(huì)怎么樣? |
|
| 11樓: | >>參與討論 |
| 作者: computer00 于 2005/12/10 12:46:00 發(fā)布:
一點(diǎn)建議: 這樣看容易眼花,超級(jí)終端可以使用0x08退格。你可以每次發(fā)送固定長(zhǎng)度,下次 發(fā)送前,先退格(即發(fā)一定數(shù)量的0x08),然后才發(fā)送數(shù)據(jù),這樣看起來數(shù)據(jù)顯示 的位置是固定的,容易看清楚。 另外開機(jī)時(shí),可發(fā)送清屏指令0x0c,為了可靠清屏,連續(xù)發(fā)兩次0x0c。 超級(jí)終端也支持漢字,總之界面可以再弄得漂亮點(diǎn)^_^ |
|
| 12樓: | >>參與討論 |
| 作者: default 于 2005/12/13 15:26:00 發(fā)布:
我來頂一下。還行 |
|
|
|
| 免費(fèi)注冊(cè)為維庫(kù)電子開發(fā)網(wǎng)會(huì)員,參與電子工程師社區(qū)討論,點(diǎn)此進(jìn)入 |
Copyright © 1998-2006 m.58mhw.cn 浙ICP證030469號(hào) |