|
问题是这样的:我看到你的那本书里面讲到了使用测周法来对低频信号进行测量,我要测量的信号频率范围为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来反美的!
|