目的:通过PA1输出0.993KHz方波,用PD6采集该输出方波频率。
问题:当注释掉T1计频中断timer1_capt_isr后,PA1口可以产生0.993KHz的信号;当启用timer1_capt_isr中断后,PA1口只有0.224KHz,这咋回事呢:dizzy:
/*
LCD12864液晶屏显示实验。
PA1输出0.993KHz方波,通过PD6采集,并显示
*/
#include <iom16v.h>
#include "font.h"
#include "lcd12864.h"
#include <macros.h>
int contN;
unsigned char flow_flag=0; //用于标记定时器溢出,如果溢出了,只记录到TCNT的值就不对了哦,需要进行处理,应该是TOP*flow_flag+TCNT
unsigned int icpnum=0; //记录每次采集的TCNT差值,注意整个过程中不要操作TCNT,以免引入误差
unsigned char timerover_error=0;
unsigned int last_icrvalue=0; //记录上次的ICR值
unsigned int value;
void timer1_init(void)
{
TCCR1B = 0x00; //stop
TCNT1H = 0x00;
TCNT1L = 0x00;
ICR1H = 0x00;
ICR1L = 0x00;
TCCR1A = 0x00;
TCCR1B|=(1<<ICNC1)|(1<<ICES1)|(1<<CS11)|(1<<CS10);
}
#pragma interrupt_handler timer1_capt_isr:12
void timer1_capt_isr(void)
{
PORTA|=(1<<7);
//CLI();
value=ICR1L;
value|=(int)ICR1H << 8;
if(flow_flag==0)
{
icpnum=value-last_icrvalue;
}
else
{
if(flow_flag==1)
{
flow_flag=0;
icpnum=0xFFFF-last_icrvalue+value;
}
else
{
timerover_error=1;
flow_flag=0;
}
}
last_icrvalue=value;
SEI();
}
void timer0_init(void)
{
TCCR0 = 0x00;
TCNT0 = 0xc6;
OCR0 = 0xc6;
TIMSK |= 0x03;
TCCR0 |=0B00011;
}
void init_devices(void)
{
CLI();
MCUCR = 0x00;
MCUCSR = 0x80;//禁止JTAG
GICR = 0x00;
DDRA |= (1<<PA1);
DDRD &=~ (1<<PD6);
PORTD |= (1<<PD6);
timer0_init();
timer1_init(); //定时器1初始化
SEI();//开全局中断
}
//T0比较中断服务程序
#pragma interrupt_handler timer0_comp_isr:20
void timer0_comp_isr(void)
{
TCNT0 = 0xc6;
PORTA^=BIT(1);//
PORTD^=BIT(0);//
contN++;
}
//led show
void LCD_init(void)
{
DDRB = 0xFF;
DDRC |= (1<<PC7)|(1<<PC6);//0xC0;
DDRD |= (1<<PD7)|(1<<PD6);//0xD0;
PORTC |=(1<< PC6);// 0x40;
PORTD |= (1<< PD6);//0x40;
PORTD &= ~(1<<PD7);//~0x80;
}
void displaynum(unsigned char row,int aa)
{ int at;
unsigned char asi1,n;
at=aa;n=1;
while(at>0)
{
asi1=at%10+48;
at/=10;
disp_charNum((16-n)*8+1,row,asi1);
n=n+1;
}
}
void main(void)
{
unsigned int showN;
float Freque_value=0.00,T=0.00;//带小数位,精确度高
unsigned int Freque=0,t=0; //只显示整数,精确度低
unsigned int temp=0;
init_devices();
disp_init();
DDRA |=(1<<7) ;
PORTA &=~(1<< PA7);
DDRD |=(1<<0) ;
//PORTD &=~(1<< PA0);
disp_clear(0, 128, 0);
disp_clear(0, 128, 2);
disp_clear(0, 128, 4);
disp_clear(0, 128, 6);
while (1)
{
if(timerover_error==1)
{
//错误处理程序
}
temp = icpnum;
Freque_value=(float)((float)1000000/(float)temp);
//Freque=1000000/temp;
T = (float)((float)temp/(float)1000);
//t=temp/1000;
displaynum(5,Freque_value);//LCD 显示数值
}
}
|