10.04.26 AVR单片机的定时器/ 中断_奋斗的2010_百度空间

//AVR单片机的中断,这部份很难理解!

//这是从网上截来的代码,写的很不错。值得参考和研究下。

#include<iom16v.h>
#include<macros.h>

unsigned char shi,fen,miao;
unsigned char t=0;
#define DATA_T0_INIT 156
#define DATA_T1_INIT 31249
#define DATA_T2_INIT 156
unsigned int T0_CAPT=0;
//T0/C0溢出中断向量端口
#pragma interrupt_handler Timer0_over:iv_TIMER0_OVF  
//T0/C0比较匹配中断向量端口
#pragma interrupt_handler Timer0_COMP:iv_TIMER0_COMP
//T1/C1溢出中断向量端口
#pragma interrupt_handler Timer1_Ov:iv_TIMER1_OVF
//T1/C1比较匹配B中断向量端口
#pragma interrupt_handler Timer1_COMPB:iv_TIMER1_COMPB
//T1/C1比较匹配A中断向量端口
#pragma interrupt_handler Timer1_COMPA:iv_TIMER1_COMPA
//T1/C1事件捕捉中断向量端口
#pragma interrupt_handler Timer1_CAPT:iv_TIMER1_CAPT
//T2/C2溢出中断向量端口
#pragma interrupt_handler Timer2_OVF:iv_TIMER2_OVF
//T2/C2比较匹配中断向量端口
#pragma interrupt_handler Timer2_COMP:iv_TIMER2_COMP

         
/*********************************************T0定时器**************************************************************************/
void T0_init(unsigned char a,unsigned char b)//a是0采用定时器的溢出中断使能,是1采用比较匹配中断使能,b为0,1,2,3,4,分别代表分频的方式,0,8,64,256,1024
{
if(a==0)
{TCNT0=255-DATA_T0_INIT;TIMSK|=0X01;//TIMSK|=0X01;溢出中断使能,
}
else
{ OCR0=DATA_T0_INIT;TCNT0=0;
TIMSK|=0X02;// TIMSK|=0X02;比较匹配中断使能
}
switch(b)
{
case 0:TCCR0=0X01;break;//TCCR0=0X01;无预分频
case 1:TCCR0=0X02;break;//TCCR0=0X02;8分频.
case 2:TCCR0=0X03;break;//TCCR0=0X03;256分频.
case 3:TCCR0=0X04;break;//TCCR0=0X04;64分频.
case 4:TCCR0=0X05;break;//TCCR0=0X05;1024分频.

------------------

// 不全 我补统下:

case 5:TCCR0=0x06;break;//时钟由T0引脚注入,下降沿触发

case 6:TCCR0=0x07:break;//时钟由T0引脚注入,上升沿触发

-----------------


}
SREG|=BIT(7); //全局中断使能
shi=0;fen=0;miao=0;

}

void Timer0_over(void)
{TCNT0=255-DATA_T0_INIT;
t++;
if(t>=50){t=0;miao++;if(miao>=60){fen++;miao=0;if(fen>=60){shi++,fen=0;if(shi>=24)shi=0;fen=0;}}}
}
void Timer0_COMP(void)
{TCNT0=0;
t++;
if(t>=50){t=0;miao++;if(miao>=60){fen++;miao=0;if(fen>=60){shi++,fen=0;if(shi>=24)shi=0;fen=0;}}}
}

/*********************************************T1定时器**************************************************************************/

void Timer1_init(unsigned char a,unsigned char b)
{ //31249 是top值,8mhz 256分频.
TCCR1A=0x00;   //普通端口操作
SREG|=0x80; //开放全局中断
if(a==1)
    {TCNT1=DATA_T1_INIT;}
else{TCNT1=0;}
switch(a)
{
case 0:TCCR1B|=0X01;break;//TCCR1B=0X01;无预分频
case 1:TCCR1B|=0X02;break;//TCCR1B=0X02;8分频.
case 2:TCCR1B|=0X03;break;//TCCR1B=0X04;64分频.
case 3:TCCR1B|=0X04;break;//TCCR1B=0X03;256分频.
case 4:TCCR1B|=0X05;break;//TCCR1B=0X05;1024分频.
}
switch(b)
{
case 1:TIMSK|=0x04;break;//T1溢出中断使能
case 2:OCR1B=DATA_T1_INIT;TIMSK|=0x08;break;//T1比较匹配B中断使能
case 3:OCR1A=DATA_T1_INIT;TIMSK|=0x10;break;//T1比较匹配A中断使能
case 4:TCCR1B|=0x80;//ICNC1:1使能噪声捕捉功能
       TCCR1B|=0x40;//噪声捕捉事件的触发方式 ICES1:0下降沿。1上升沿,
       TIMSK|=0x20;break;//T1事件捕捉中断使能
}

}
void Timer1_Ov(void)
{   t++;  
    TCNT1=DATA_T1_INIT; //计数值装入寄存器 T= 0.125uS*N*(1+TOP)   TOP=t/(0.125*256)-1
miao++;if(miao>=60){fen++;miao=0;if(fen>=60){shi++,fen=0;if(shi>=24)shi=0;fen=0;}}
}
void Timer1_COMPB()
{TCNT1=0;
{miao++;if(miao>=60){fen++;miao=0;if(fen>=60){shi++,fen=0;if(shi>=24)shi=0;fen=0;}}}
}
void Timer1_COMPA()
{ TCNT1=0;
{miao++;if(miao>=60){fen++;miao=0;if(fen>=60){shi++,fen=0;if(shi>=24)shi=0;fen=0;}}}
}
void Timer1_CAPT()
{
T0_CAPT=ICR1;
}
/*********************************************T2定时器**************************************************************************/

void Timer2_init(unsigned char a,unsigned char b)
{
/*TCCR2控制寄存器
BIT7    BIT 6   BIT5   BIT4    BIT3   BIT2   BIT1   BIT0
FOC2    WGM20 COM21 COM20   WGM21    CS22   CS21   CS20*/
//WGM21:WGM20   0:0普通模式top=0xff
//COM21:COM20   0:0 正常端口操作,不跟OC2相连

ASSR=0x00;//ASSR=0x00;有IO时钟驱动。ASSR|=0x08;异步模式。由Pc6-Pc7之间的外接石英晶体驱动
/*
ASSR控制寄存器
bit3   bit2      bit 1      bit 0
AS2 TCUN2UB    OCR2UB    TCR2UB
TCUN2UB:异步模式:写TCNT2时会引起 TCUN2UB置位,写完成时,TCUN2UB自动清零,TCUN2UB=0代表TCNT2可以写入新的数值了
OCR2UB:异步模式:写OCR2时会引起 OCR2UB置位,写OCR2完成时,OCR2UB自动清零,OCR2UB=0代表OCR2可以写入新的数值了
TCR2UB:异步模式:写TCCR2时会引起 TCR2UB置位,写TCCR2完成时,TCR2UB自动清零,TCR2UB=0代表TCCR2可以写入新的数值了


*/
switch(a)
{
case 0:TCCR2|=0X01;break;//TCCR2=0X01;无预分频
case 1:TCCR2|=0X02;break;//TCCR2=0X02;8分频.
case 2:TCCR2|=0X03;break;//TCCR2=0X04;64分频.
case 3:TCCR2|=0X04;break;//TCCR2=0X03;256分频.
case 4:TCCR2|=0X05;break;//TCCR2=0X05;1024分频.
}
if(b==0)
{TCNT2=255-DATA_T2_INIT; TIMSK|=0x40;}//T2溢出中断使能
else {TCNT2=0;OCR2=DATA_T2_INIT;TIMSK|=0x80;}//T2比较匹配中断使能
}

void Timer2_OVF()
{TCNT2=255-DATA_T2_INIT;
t++;
if(t>=50){t=0;miao++;if(miao>=60){fen++;miao=0;if(fen>=60){shi++,fen=0;if(shi>=24)shi=0;fen=0;}}}

}

void Timer2_COMP()
{TCNT2=0;
t++;
if(t>=50){t=0;miao++;if(miao>=60){fen++;miao=0;if(fen>=60){shi++,fen=0;if(shi>=24)shi=0;fen=0;}}}
}



郑重声明:资讯 【10.04.26 AVR单片机的定时器/ 中断_奋斗的2010_百度空间】由 发布,版权归原作者及其所在单位,其原创性以及文中陈述文字和内容未经(企业库qiyeku.com)证实,请读者仅作参考,并请自行核实相关内容。若本文有侵犯到您的版权, 请你提供相关证明及申请并与我们联系(qiyeku # qq.com)或【在线投诉】,我们审核后将会尽快处理。
—— 相关资讯 ——