253789174zjm 发表于 2014-6-23 15:01:01

定时器产生的问题

AVR MEGA8 单片机                定时器0产生135KHZ的中断
这时用定时器2产生5MS的中断,为何定时器2的中断进不去呢


但是如果把定时器0的频率放底一点,这时定时器2的中断就会正常功能了呢?


有没有人能知道如何解决这个问题

放上代码
/******************************************************************
* 功能:   ADC&PWM
* CPU型号: ATMEGA8A
* 晶振:    12MHz
* 说明:   
* 作    者:
* 电    话:
* Q   Q:
* 日    期:2
******************************************************************/

#include <iom8v.h>
#include <macros.h>
#include <eeprom.h>

#define uchar       unsigned char
#define uint         unsigned int

unsigned char CountNum;//用来记录中断,第一次中断是2MS
unsigned char Count;   //用来做10MS


unsigned char NUM=255;   //最初为135KHZ频率数值

unsigned int ad0=0;//全局变量 用来保存通道ADC0的数值
unsigned int ad1=0;//全局变量 用来保存通道ADC1的数值
unsigned int ad2=0;//全局变量 用来保存通道ADC2的数值
unsigned int ad3=0;//全局变量 用来保存通道ADC2的数值

//初始化看门狗
//开
void WDT_init(void)
{
WDR();
WDTCR=0x0f;//2s
}

//禁止看门狗
void WDT_OFF(void)
{
    WDTCR|=(1<<WDCE)|(1<<WDE);//2s
    WDTCR=0x00;//禁止
}

/*
//初始化TC0 1S
void init_timer0()
{
               TCCR0=0x00;//TCCR0工作于定时方式,先停止TC0
               TCNT0=0x06;//计数器初始值
               TCCR0=(1<<CS01)|(1<<CS00);//打开TC0用64分频
               TIMSK|=(1<<TOIE0);//开放TOIE0中断
}
*/

//初始化TC0
void init_timer0(uchar fp,uchar num)
{
               //TCCR0=0x00;//TCCR0工作于定时方式,先停止TC0
               //TCNT0=255; //135KHZ 255
               NUM=num;
               TCNT0=num;   //55KHZ203
               TCCR0=fp;//打开TC0不分频
               //TCCR0=(1<<CS01)|(1<<CS00);//打开TC0用64分频
               TIMSK|=(1<<TOIE0);//开放TOIE0中断
}


//TC0中断函数2MS定时
#pragma interrupt_handler timer0_fun:iv_TIMER0_OVF
void timer0_fun()
{
   //TCNT0=0x06;            //重装初值
   //TCNT0=255;            //重装初值
   /*
   if (++CountNum==5)
   {
         CountNum=0;
         Count++;
   }
   if (Count==100)       //Count=100就是一秒到时了
   {
         Count=0;
         //PORTB=~PINB;
   }
   */
    PORTD^=0x03;   // PB7输出135KHZ的 50%占空比
    //PORTD^=0x02;   // PB7输出135KHZ的 50%占空比   
    TCNT0=NUM;   //重装初值   
}

//ADC函数
//chanl:通道口设置 此处将用到AD0-AD3
uint mega8_ad(uchar chanl)
{
   uint addata;
               
               ACSR=0x80;            //关掉模拟比较器的电源(禁用模拟比较器)
               ADMUX=0;            //选用外部参考电压 左对齐
               ADMUX|=chanl;         //设置通道口 此处的chanl值为0-3 即ADC0-ADC3
               ADCSRA=0X80;          //选全能ADC,但此时还没有开始转换
               ADCSRA|=BIT(ADSC);    //启动第一次AD转换
               while(!(ADCSRA&(BIT(ADIF)))); //一直到转换完成
               
               addata=ADCL;   //读取低8位
               addata=addata+ADCH*256;    // 10位结果保存到addata
               return addata;
}   

//PWM 配置函数
void pwm_w_set(uint pwm_w)   //设定PWM脉冲宽度 占空比调整
{
   OCR1B=pwm_w;
}


//main函数

void main (void)
{
                DDRB =0XFF;//pwm
                PORTB=0XFF;
               
                DDRD =0XFF;//pwm
                PORTD=0X02;
               
                DDRC =0X00;// PC0-PC3 AD0-AD3
                PORTC=0X00;
               
          TCCR1A=0X63; //配置为快速PWM
          TCCR1B=0X19; //无预分频
       
          OCR1A=399;//(8000000/20K)-1=399
          pwm_w_set(199); //
               
                //init_timer0(5,191); // 60HZ
                init_timer0(1,167); // 135kHZ
               
                SEI();         //enable interrupts
               
                WDT_OFF();   //禁止看门狗
               
                while(1)
                {
                  ad0=mega8_ad(0);   //读数
                  ad1=mega8_ad(1);   //读数
                  ad2=mega8_ad(2);   //读数
                  ad3=mega8_ad(3);   //读数
                  
                  if((ad0>=409)&&(ad1>=613)&&(ad2>=818)&&(ad3>=920))//5V参考电压 613约为3V
                  {
                        PORTB&=0xfd;// PB1=0灯亮
                           }
                           else
                           {
                             PORTB|=0x02;// PB1=1灯灭
                           }
                }
}
页: [1]
查看完整版本: 定时器产生的问题