搜索
bottom↓
回复: 2

请教 关于测周法进行测频的问题。

[复制链接]

出0入0汤圆

发表于 2011-1-15 12:25:11 | 显示全部楼层 |阅读模式
问题是这样的:我看到你的那本书里面讲到了使用测周法来对低频信号进行测量,我要测量的信号频率范围为200-1000hz.您书上讲的测周法所使用的是两个定时/计数器资源,而两个都设置为CTC模式进行工作。在我的试验中,使用芯片为m128@12MHz,我将外部信号从T1口输入(CTC模式),而使用T3作为时基使用(普通模式@256分频),在T3的定时的中断周期为1.642ms,设置T1为测量1000个周期的时候进行一次中断。
现在出现的问题是:我通过PG4来进行观察,发现如果只有T3中断时,则该中断正常;但是当引入T1和T3中断时,则测试只有T1中断进行正常,T3中断并未进入。不知道是什么原因。这里我将自己的程序贴上。谢谢您了
//ICC-AVR application builder : 2010-10-10 10:28:33
// Target : M128
// Crystal: 12.0000Mhz

#include "config.h"

int locate=0;//用来表示数据栈中的数据数目
int trsfed=0;//用来表示要显示的数据
int result=0;//用来存放20个转换后的数据的总和
int data[12];//用来存放一个周期所转换来的数据
unsigned int freq=0;
unsigned char freq_ok=0;
int time3_hg;
int time3_lw;
unsigned long int freq_temp;
unsigned char j=0;
//int ADC_data;
void port_init(void)
{
PORTA = 0x00;
DDRA  = 0xff;
PORTB = 0x02;
DDRB  = 0x1F;
PORTC = 0x00; // m103 output only
DDRC  = 0xff; // output in PORC after transfer;
PORTD = 0x23;
DDRD  = 0x21;
PORTE = 0x00;
DDRE  = 0x00;
PORTF = 0x01;
DDRF  = 0xff;
PORTG = 0x13;
DDRG  = 0x03;
}

//TIMER3 initialize - prescale:256
// WGM: 0) Normal, TOP=0xFFFF
// desired value: 1.667mSec
// actual value:  1.664mSec (0.2%)
void timer3_init(void)
{
TCCR3B = 0x00; //stop
TCNT3H = 0xFF; //setup
TCNT3L = 0xB2;
OCR3AH = 0x00;
OCR3AL = 0x4E;
OCR3BH = 0x00;
OCR3BL = 0x4E;
OCR3CH = 0x00;
OCR3CL = 0x4E;
ICR3H  = 0x00;
ICR3L  = 0x4E;
TCCR3A = 0x00;
TCCR3B = 0x04; //start Timer
}
#pragma interrupt_handler timer3_ovf_isr:30
#pragma interrupt_handler timer1_compa_isr:13
void timer3_ovf_isr(void)

{
unsigned char sreg;
PORTG|=0x10;//该端口用来观察中断周期
  freq++;
   CLI();
//TIMER3 has overflowed
TCNT3H = 0xFF; //reload counter high value
TCNT3L = 0xB2; //reload counter low value
ADC_start();
delay_nus(10);
data_receive();
sreg=SREG;
SREG=sreg;
PORTG&=~0x10;
SEI();
}

//TIMER1 initialize - prescale:Rising edge
// WGM: 4) CTC, TOP=OCRnA
// desired value: 1mSec
// actual value: Out of range
void timer1_init(void)
{

TCCR1B = 0x00; //stop
TCNT1H = 0x00 /*INVALID SETTING*/;
TCNT1L = 0x00 /*INVALID SETTING*/;
OCR1AH = 0x03 /*INVALID SETTING*/;
OCR1AL = 0xE7 /*计数999个*/;
OCR1BH = 0x00 /*INVALID SETTING*/;
OCR1BL = 0x00 /*INVALID SETTING*/;
OCR1CH = 0x00 /*INVALID SETTING*/;
OCR1CL = 0x00 /*INVALID SETTING*/;
ICR1H  = 0x00 /*INVALID SETTING*/;
ICR1L  = 0x00 /*INVALID SETTING*/;
TCCR1A = 0xC0;
TCCR1B = 0x0F; //start Timer
}

void timer1_compa_isr(void)
{

time3_lw=TCNT3L;//compare occured TCNT1=OCR1A
time3_hg=TCNT3H;
time3_lw+=(time3_hg*256);
TCNT3H=0x00;
TCNT3L=0x00;
TIFR|=0x10;
freq_temp=freq;
freq=0;
freq_ok=1;

}

void init_devices(void)
{

//stop errant interrupts until set up
CLI(); //disable all interrupts
XDIV  = 0x00; //xtal divider
XMCRA = 0x00; //external memory
port_init();
timer3_init();
timer1_init();
MCUCR = 0x00;
EICRA = 0x00; //extended ext ints
EICRB = 0x00; //extended ext ints
EIMSK = 0x00;
TIMSK = 0x10; //timer interrupt sources
ETIMSK = 0x04; //extended timer interrupt sources
SEI(); //re-enable interrupts
//all peripherals are now initialized
}
void main(void)
{
  //port_init();
unsigned char i=0;
int jieguo;
  init_devices();
  delay_nus(100);
PORTB|=0x10;
DDRB|=0x10;
PORTE|=0x80;
DDRE=0xFF;
DDRG|=0x10;
initial_lcd();
  wr_lcd(0x01,0);                                 
Lcd_clrbmp();   
wr_lcd(0x01,0);
d_1();
ADC_init(0);
//ADC_start();
delay_nus(300);
PORTC=ADC_get();
  while(1)
  {
         if(freq_ok)
         {
           time3_lw-=65458;
           //freq_temp=freq_temp*77+time3_lw;
           //freq_temp=46875000/freq_temp;
           lcd_datadisp(3,5,freq_temp/1000,(freq_temp/100)%10);
       lcd_datadisp(3,6,(freq_temp/10)%10,freq_temp%10);
           freq_ok=0;
         }
  }
}

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

月入3000的是反美的。收入3万是亲美的。收入30万是移民美国的。收入300万是取得绿卡后回国,教唆那些3000来反美的!

出0入0汤圆

发表于 2011-1-17 10:50:52 | 显示全部楼层
1。改动你的题目,是希望大家都能参与讨论,找问题。
2。我书中的关键东西你基本是没有掌握。搬抄代码根本是没有用的。

先点评你的T/C3,采用普通模式工作,这个基时实际根本不准!基时不准,测出的东西还准吗?

void timer3_ovf_isr(void)

{                                                            ==》进入中断需要7个CLK
unsigned char sreg;
PORTG|=0x10;//该端口用来观察中断周期                        ==》延误  
  freq++;                                                    ==》这里又要延误     
   CLI();                                                    ==》根本是多余的!
//TIMER3 has overflowed
TCNT3H = 0xFF; //reload counter high value                  ==》延误
TCNT3L = 0xB2; //reload counter low value                   ==》到此为止,你的基时至少增加了16个CLK。整个基时增加了32个CLK!

ADC_start();                                                ==》以下3句要用多少时间?不应该放在中断中
delay_nus(10);
data_receive();
sreg=SREG;                                                  ==》这两句废物
SREG=sreg;
PORTG&=~0x10;
SEI();                                                      ==》此时开中断,为什么?是让T/C1中断进入及时记录T/C3的值?此时T/C3的值是T/C1正好为1000时的值吗?
}

建议你先仔细研究我书中的例子吧。

出0入0汤圆

 楼主| 发表于 2011-1-21 19:55:53 | 显示全部楼层
回复【1楼】machao
-----------------------------------------------------------------------

谢谢马老师,我觉得你指点的是,决定春节期间认认真真的学习您的书,多看看论坛,能多多的学习东西~谢谢啦
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

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

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

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