AVR使用范例定时器应用范例.docx
《AVR使用范例定时器应用范例.docx》由会员分享,可在线阅读,更多相关《AVR使用范例定时器应用范例.docx(9页珍藏版)》请在冰豆网上搜索。
![AVR使用范例定时器应用范例.docx](https://file1.bdocx.com/fileroot1/2023-3/30/00c69c7a-c228-4c30-9d7d-a4f824d22f13/00c69c7a-c228-4c30-9d7d-a4f824d22f131.gif)
AVR使用范例定时器应用范例
AVR使用范例--定时器应用范例
本页关键词:
avr定时器计算avr定时器应用avr定时器中断范例avr定时器avr定时器0编程avr定时器的应用程序avr定时器使用例程avr定时器输出脉冲avr定时器程序avr定时器初值
本文详细介绍avr定时器timer的使用方法,PWM的设定与注意事项,通过ICC快速完成参数设定,并通过一个实际例子定时LED的显示解说详细过程。
定时器在工程中应用非常广泛,avr有八位和十六位两种定时器,AVR定时器能够非常精确的定时,下面介绍使用ICCapplicationbuilder快速使用定时器的方法。
使用ICCapplicationbuilder快速配置定时器
第一步:
新建工程保存到特定目录下。
第二步:
ICC>>Tools>>applicationbuilder
第三步:
设置单片机型号和晶振频率,如下图,非常重要,因为这会关系到定时的准确性甚至正确性。
第四步:
设定定时器Timer0,操作如下图,请仔细核对每一项。
这里我们跳过了端口IO的设定,因为对我们不是很重要。
点击OK,检查生成的程序,下图展示了生成的程序的详细含义。
你将得到的程序如下,灰色部分为添加的注释。
只介绍定时器部分,其他请参考新手入门相关内容,如果你并不急于理解这些内容,请跳过。
/*定时器的工作原理是:
定时器在预分频这么多个时钟周期后使ICNIn的值加一,当TCNTn到达最大值时发生溢出中断。
用户在溢出中断中填写定时器重载语句,开始下一次定时工作,通过设定TCNTn的值和OCRn的值可以设置定时器的定时长短。
*/
//TIMER0initialize-prescale:
1024/*定时器预分频,预分频由TCCRn的CS02,CS01,CS00确定,详情查看数据手册*/
//WGM:
Normal/*定时器*/
//desiredvalue:
20mSec/*定时器期望设定时间*/
//actualvalue:
19.861mSec(0.7%)/*定时器实际定时时间,误差比例*/
voidtimer0_init(void)
{
TCCR0=0x00;//stop/*定时器停止,TCCR0寄存器完全控制timer0的运行情况,详细可参考数据手册。
*/
TCNT0=0x71;//setcount/*定时器寄存器开始值*/
OCR0=0x8F;//setcompare/*定时器比较值*/
TCCR0=0x05;//starttimer/*定时器开始*/
}
#pragmainterrupt_handlertimer0_comp_isr:
20
voidtimer0_comp_isr(void)
{
//compareoccuredTCNT0=OCR0/*定时器比较匹配中断,这里没有添加任何语句,实际操作中可以用此实现自制PWM*/
}
#pragmainterrupt_handlertimer0_ovf_isr:
10
voidtimer0_ovf_isr(void)
{
TCNT0=0x71;//reloadcountervalue/*定时器溢出后需要重载TCNTn,然后在之后添加用户程序,
记住不要在定时器中断里添加特别耗时的程序。
*/
}
//callthisroutinetoinitializeallperipherals
voidinit_devices(void)
{
//stoperrantinterruptsuntilsetup
CLI();//disableallinterrupts
port_init();
timer0_init();
MCUCR=0x00;
GICR=0x00;
TIMSK=0x03;//timerinterruptsources/*这里设定允许Timer0比较中断和溢出中断。
*/
SEI();//re-enableinterrupts
//allperipheralsarenowinitialized
}
下面通过用同样的方法操作做一个“小秒表”,LED每秒更新一次,效果如下图:
本程序我们用了定时器二,因为timer0是八位定时器,无法完成一秒的定时任务。
下载相关文件
程序如下:
//ICC-AVRapplicationbuilder:
2006-11-2411:
46:
03
//Target:
M16
//Crystal:
7.3728Mhz
#include
#include
constled_table[16]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x88,0x86,0xc7,0xc4,0x83,0x8b};//0~~f
//定义LED的数据表,注意,只有0到9是正确的,A-F我没有认真写。
typedefunsignedcharuint8;
uint8i;
voidport_init(void)
{
PORTA=0x00;
DDRA=0xFF;
PORTB=0x00;
DDRB=0x00;
PORTC=0x00;//m103outputonly
DDRC=0x00;
PORTD=0x00;
DDRD=0x00;
}
//TIMER1initialize-prescale:
1024
//WGM:
0)Normal,TOP=0xFFFF
//desiredvalue:
1Sec
//actualvalue:
1.000Sec(0.0%)
voidtimer1_init(void)
{
TCCR1B=0x00;//stop
TCNT1H=0xE3;//setup
TCNT1L=0xE1;
OCR1AH=0x1C;
OCR1AL=0x1F;
OCR1BH=0x1C;
OCR1BL=0x1F;
ICR1H=0x1C;
ICR1L=0x1F;
TCCR1A=0x00;
TCCR1B=0x05;//startTimer
}
#pragmainterrupt_handlertimer1_compa_isr:
7
voidtimer1_compa_isr(void)
{
//compareoccuredTCNT1=OCR1A
}
#pragmainterrupt_handlertimer1_compb_isr:
8
voidtimer1_compb_isr(void)
{
//compareoccuredTCNT1=OCR1B
}
#pragmainterrupt_handlertimer1_ovf_isr:
9
voidtimer1_ovf_isr(void)//将每秒执行一次
{
//TIMER1hasoverflowed
TCNT1H=0xE3;//reloadcounterhighvalue
TCNT1L=0xE1;//reloadcounterlowvalue
i++;
if(i==10)i=0;//等于十时,恢复零
PORTA=led_table[i];//这里使LED变化
}
//callthisroutinetoinitializeallperipherals
voidinit_devices(void)
{
//stoperrantinterruptsuntilsetup
CLI();//disableallinterrupts
port_init();
timer1_init();
MCUCR=0x00;
GICR=0x00;
TIMSK=0x1C;//timerinterruptsources/*定时器使用中断规则设定*/
SEI();//re-enableinterrupts
//allperipheralsarenowinitialized
}
voidmain(void)
{
init_devices();
while
(1)
;
}