SCREA 发表于 2014-2-20 16:33:46

求原因?AVR16捕获调试的原因。TIMER1输入捕获频率计例程

本帖最后由 SCREA 于 2014-2-20 16:35 编辑

求怎么回事,第1、3、4个频率正常,唯独频率从1K到5K左右不正常
//-----------------------------------------------------------------
//名称: 用TIMER1输入捕获功能设计的频率计
//-----------------------------------------------------------------
//说明: 本例运行时,切换不同的频率输入,然后按下K1按键,数码管上将
//      显示当前频率值.两次捕获的时间差值即为当前输入频率的周期,
//      周期倒数即可得到当前频率.
//
//-----------------------------------------------------------------
#defineF_CPU1000000UL //1M晶振
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#define INT8U   unsigned char
#define INT16Uunsigned int

//共阴数码管0-9的数字编码,最后一位为黑屏
const INT8U SEG_CODE[] =
{0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x00};

//分解后的待显示数位
INT8U Display_Buffer[] = {0,0,0,0};

//连续两次捕获计数变量
INT16U CAPi=0,CAPj=0;

volatile        INT16U Buffer = {0};
volatileunsigned long SS = 0;
volatile INT8U j=0;
//-----------------------------------------------------------------
// 数码管显示频率
//-----------------------------------------------------------------
void Show_FRQ_ON_DSY()
{
        INT8U i=0;
        for( i =0;i<4;i++)
        {
                PORTB = ~_BV(i);
                PORTA = SEG_CODE[ Display_Buffer ];
                if(i==0)PORTA |= 0x80;       
                _delay_ms(2);               
        }
}

//------------------------------------------------------------------
// 主程序
//------------------------------------------------------------------
int main()
{
        INT8U LastKey = 0xff;
        DDRA = 0xff;       
        DDRB = 0xff;       
        DDRC = 0x00;        PORTC = 0xff;
        DDRD = 0x00;        PORTD = 0xff;

        TCCR1B = _BV(ICNC1) | _BV(ICES1);//输入捕获噪声音消除,ICP上升沿触发捕获,分频系数1(1MHz,1us触发一次)
        sei();
        while(1)
        {
                if( LastKey != PINC)
                {
                        TIMSK = _BV(TICIE1);
                        TCCR1B |= 0x01;
                        LastKey = PINC;
                }
                Show_FRQ_ON_DSY();
        }

}

//------------------------------------------------------------------
// T1输入捕获中断子程序
//------------------------------------------------------------------
ISR (TIMER1_CAPT_vect)
{
        INT8U i,k;
        INT16U temp=0;
        if(CAPi == 0 )CAPi = ICR1;
        else
        {
                CAPj = ICR1 - CAPi;
                Buffer =1000000UL/ CAPj;
                j++;
                if(j==6)
                {
                        j=0;
                        TIMSK = 0x00;
                        TCCR1B &= 0xf8;
                        for(k=0;k<6;k++)                                                //采样6次,取中间4个值求平均
                        {
                                for(i=0;i<5-k;i++)
                                {
                                        if(Buffer>Buffer)
                                        {
                                                temp = Buffer;
                                                Buffer = Buffer;
                                                Buffer = temp;       
                                        }
                                }       
                        }
                        SS = (Buffer + Buffer + Buffer+ Buffer )/4;
                        for(i=3;i!= 0xff;i--)
                        {
                                Display_Buffer = SS%10;
                                SS /= 10;
                        }
                }
                TCNT1 = CAPi = CAPj = 0;
        }


}
页: [1]
查看完整版本: 求原因?AVR16捕获调试的原因。TIMER1输入捕获频率计例程