AVR定时器中断初值计算方法

AVR 定时器中断初值计算方法
使用芯片AT Mega16 外部晶振
定时器1 (16位定时器)寄存器TCCR1B = 0x04 设定256预分频
要利用定时器定时1秒
1,4000000 / 256 = 15625 说明定时器每
当1/15625 秒就会触发一次中断
2,65535 - 15625 = 49910 计算出要累加多少次才能在1秒后出发定时器1的溢出中断
3,49910 <==> C2 F6 将计算后的值换算成16进制
4,TCNT1H = 0xC2 ; 对寄存器赋值
TCNT1L = 0xF6 ;
=================================================
例如用16位定时器TIMER1,4MHZ晶振,256分频,100ms定时,如何求得初值赋给TCNT1
65536-(4M/256)*=
其中,4M是晶体频率,是定时时长单位秒。

对于8位的定时器
T=(2^8-计数初值)*晶振周期*分频数=(2^8-计数初值)/晶振频率*分频数计数初值=2^8-T/晶振周期/分频数=2^8-T*晶振频率/分频数
因为AVR一指令一周期
IAR For AVR 精确延时
C语言中,想使用精确的延时程序并不容易。

IAR 中有这样的一个函数__delay_cycles(),该函数在头文件中定义,函数的作用就是延时N个指令周期。

根据这个函数就可以实现精确的延时函数了(但不能做到100%精确度)。

实现的方法:
建立一个的头文件:
#ifndef __IAR_DELAY_H
#define __IAR_DELAY_H
#include <>
#define XTAL 8 //可定义为你所用的晶振频率(单位Mhz)#define delay_us(x) __delay_cycles ( (unsigned lon g)(x * XTAL) )
#define delay_ms(x) __delay_cycles ( (unsigned lon g)(x * XTAL*1000) )
#define delay_s(x) __delay_cycles ( (unsigned long )(x * XTAL*1000000) )
#endif
注意:__delay_cycles(x),x必须是常量或则是常量表达式,如果是变量则编译报错!
关于溢出中断不管是哪个单片机都是不断累加,使其寄存器溢出触发中断,然后跳转到中断函数处执行中断服务程序。

对于定时器初值的设定可以加深对定时器的工作原理的理解。

ATMega16 里面有8位和16位两种定时器,他们何时会溢出这个是固定的,也就是到达他们的计数范围的最大值就会产生中断,8位的定时器的最大计数范围是0~256(2的8次方),就是累加到256后他就会产生中断,16位的定时器最大计数范围是0~65536(2的16次方),累加到65536时他就会产生中断。

而我们所谓的计数初值是就是要设定定时器在什么地方开始计数,以8位定时器为例比如:初值为100,所以定时器从100开始累加,累加了156次,加到256后产生中断,这就是中间消耗的时间和指令周期就是我们要去设定的时间;再比
如:初值是200,所以定时器从200开始累加,累加了56次,加到256后产生中断,可以看到第一定时要累加156次才会中断而第二次只要累加56次就会产生中断,显然第一次设定的时间要比第二次的长。

定时器不仅可以定时,而且我们用到定时器的时候往往是需要精确定时的时候。

我们可以计算出我们设定的初值会在多长时间后进入中断。

实验平台:ATMega16
晶振:MHz
对初值的计算:
1,/ 1024 = 10800 设定为1024倍分频,得到每1秒需要进行多少次累加
2,
10800 / 100 = 108
得到10ms 的定时需要进行多少次累加。

3,
256 - 108 = 148
计算范围最大值减去要累加的时间,得到初值,即从哪里开始累加才能在溢出时为10ms的时
间。

4,148 <==> 0x94
得到十六进制值,赋值给TCNT0代码:定时10ms
#include <>
unsigned char flag = 0;
void timer_init(void)
{
TCCR0 = 0x05;
//进行1024分频
TCNT0 = 0x94;
//赋计数初值
TIMSK_TOIE0 = 1;
//开使能
SREG_I = 1;
//开总中断
}
#pragma vector = TIMER0_OVF_vect
__interrupt void time0_normal(void)
{
TCNT0 = 0x94;
//重新赋初值
flag++;
}
void main(void)
{
timer_init();
DDRB_Bit0 = 1;
while(1)
{
if(flag == 100)
//10ms 重复100次,即为1秒
{
PORTB_Bit0 = ~PORTB_Bit0;
//让LED闪烁
flag = 0;
}
}
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++ ++++++++++++++++//
实验平台:ATMega16
晶振:
16位定时器初值设定:
1,/ 256 = 43200 设定256倍分频,得到每1秒需要进行多少次累加
2,
65536 - 43200 = 22336 计算范围最大值减去要累加的时间,得到初值,即从哪里开始累加才能在溢出时为1s 的时间。

3,
22336 <==> 0x57 0x40 得到十六进制值,赋值给TCNT1H , TCNT1L
:定时1s
#include <>
unsigned char flag = 0;
void timer_init(void)
{
TCCR1B = 0x04;
TCNT1H = 0x57;
TCNT1L = 0x40;
TIMSK_TOIE1 = 1;
SREG_I = 1;
}
#pragma vector = TIMER1_OVF_vect
__interrupt void time1_normal(void) {
TCNT1H = 0x57;
TCNT1L = 0x40;
flag++;
}
void main(void)
{
timer_init();
DDRB_Bit0 = 1;
while(1)
{
if(flag == 1)
}
}。

合集下载

单片机定时器初值计算公式(51单片机和AVR单片机的初值计算三种方法)

单片机定时器初值计算公式(51单片机和AVR单片机的初值计算三种方法)

单片机定时器初值计算公式(51单片机和A VR单片机的初值计算三种方法)单片机定时器初值计算公式
一、51单片机定时器初值计算1、方法一
void main(void)
{
s1=1;
TMOD=0x01; //使用定时器T0的模式1
TH0=(65536-46083)/256; //定时器T0的高8位设置初值
TL0=(65536-46083)%256; //定时器T0的低8位设置初值
函数功能:定时器T0的中断服务函数
********************************************************/
void TIme0(void )interrupt 1 using 0 //定时器T0的中断编号为1,使用第1组工作寄存器
{
count++; //每产生1次中断,中断累计次数加1
if(count==20)//如果中断次数计满20次
count=0; //中断累计次数清0
s++; //秒加1
网络上阅读一段程序,定时器初值46083 是怎么计算出来的?一般我们如用AT892051的话定时50MS 就是TH0=(65536-50000)/256;
猜想应该是使用的12M晶体,20次为1S.
2、方法二
10MS定时器初值的计算:
1)晶振12M
12MHz除12为1MHz,也就是说一秒=1000000次机器周期。

10ms=10000次机器周期。

65536-10000=55536(d8f0)。

AVR的常用中断编程

AVR的常用中断编程

实在没有财富了,才拿自己写的东西出来献丑。

平时自己并不常用A VR,所以没有写得很完全,这个是做参考用,如果您接纳了我这种写法,可以自己写完所有的东西自己建立一个固件库。

包含了三个文件,分别是interrupt.c、interruptt.h和MacroAndConst.h,如果有疑问或者见解可以发邮件给我,我的邮箱:349705262@。

现在粘贴如下:/*interrupt.h里面的内容*/#ifndef _INTERRUPT_H_#define _INTERRUPT_H_#include<iom16v.h>#include<macros.h>#include"MacroAndConst.h"#include"interrupt.h"extern void INT(uchar int_num,uchar sense_ctrl);/*函数名:exteral_int()(外部中断控制函数)参数:int_num(外部中断数),sense_ctrl(触发方式)外部中断的数int_num的取值为0和1,为0时是外部中断0,为1时是外部中断1sense_ctrl的取值如下:0:为低电平产生中断1:任意逻辑电平变化都产生中断2:下降沿产生中断3:上升沿产生中断功能:设置外部中断并使能外部中断函数编写流程:1、写MCU控制寄存器MCUCR,选择是外部中断0还是1,并且选择触发方式;2、写MCU控制与状态寄存器MCUCSR,选择使能外部中断。

调用例子:main(){INT(0,2);//设置外部中断0,下降沿触发中断SREG=0x80;//打开总中断while(1){}}#pragma interrupt_handler int0:2void int0()//外部中断0响应函数{//写执行语句}-----------------------------------------------------------------------------------*/extern void TCNT0_8bit(uchar timer_counter,uchar clock_select);/*函数名:TCNT0_8bit()(设置8位定时计数器为定时器)参数:timer_counter(定时计数器寄存器初始值),clock_select(时钟分频选择) clock_select可取一下值:0:无时钟,T/C 不工作1:1 分频( 没有预分频)2:8 分频( 来自预分频器)3:64 分频( 来自预分频器)4:256 分频( 来自预分频器)5:1024分频( 来自预分频器)6:时钟由T0 引脚输入,下降沿触发7:时钟由T0 引脚输入,上升沿触发功能:设置8位定时计数器并使能定时计数器函数编写流程:1、重置T/C控制寄存器,WGM0和WGM1为0,普通模式2、选择时钟源3、赋8位定时计数器初值4、溢出中断使能调用例子:void main(){TCNT0(142,5);//选择1024分频,初值为142SREG|=0x80;//打开总中断while(1){}}#pragma interrupt_handler int0:10void tcnt0(){TCNT0=142;//重新赋值//写需要执行的语句}-----------------------------------------------------------------------------------*/extern void TCNT1_16bit(uint tcnt1_val,uchar clock_select);/*函数名:TCNT1_16bit()(设置16为定时计数器为定时器)参数:tcnt1_val(TCNT1初始值),clock_select(时钟分频选择)clock_select可取一下值:0:无时钟,T/C 不工作1:1 分频( 没有预分频)2:8 分频( 来自预分频器)3:64 分频( 来自预分频器)4:256 分频( 来自预分频器)5:1024分频( 来自预分频器)6:时钟由T0 引脚输入,下降沿触发7:时钟由T0 引脚输入,上升沿触发功能:设置16位定时计数器并使能相应溢出中断函数编写流程:1、设置TCCR1A、TCCR1B寄存器2、选择时钟分频3、赋初始16位定时计数器值4、溢出中断使能调用例子:#pragma interrupt_handler tcnt0:9void main(){TCNT1_16bit(57722,5);SREG|=0x80;while(1){}}void tcnt0(){TCNT1=57722;//写相应语句}-----------------------------------------------------------------------------------*/extern void Input_Capture(void);/*------------------------------------------------------------------------------------------------*/extern void FAST_PWM_16bit(uchar clock_select,uint ICR1_val,uint OCR1A_val,uint OCR1B_val);/*函数名:FAST_PWM_16bit()(设置16位定时计数器的快速PWM功能)参数:clock_select(时钟分频选择),ICR1_val(ICR1寄存器的值),OCR1A_val(OCR1A寄存器的值),0CR1B_val(OCR1B寄存器的值)clock_select可取一下值:0:无时钟,T/C 不工作1:1 分频( 没有预分频)2:8 分频( 来自预分频器)3:64 分频( 来自预分频器)4:256 分频( 来自预分频器)5:1024分频( 来自预分频器)6:时钟由T0 引脚输入,下降沿触发7:时钟由T0 引脚输入,上升沿触发功能:设置16位定时计数器的快速PWM功能,快速PWM模式恒为14模式,此模式下TOP值恒设为ICR1寄存器中的值函数编写流程:1、设置PD4、PD5为输出2、设置TCCR1A、TCCR1B寄存器3、选择时钟分频4、赋值ICR1,OCR1A,OCR1B备注:PWM的频率可以计算如下:PWM频率=时钟频率/(分频数*(1+ICR1_val))PWM的占空比可计算如下:PWM占空比=OCR1A_val/ICR1 (PD5引脚输出)PWM占空比=OCR1B_val/ICR1 (PD4引脚输出)调用例子:void main(){FAST_PWM_16bit(3,1249,625,625);while(1){}}-----------------------------------------------------------------------------------*/#endif/*interrupt.c里面的内容*/#include"interrupt.h"void INT(uchar int_num,uchar sense_ctrl)//外部中断设置函数{switch(int_num){case 0: MCUCR|=sense_ctrl;//控制产生中断方式GICR|=0x40;//使能外部中断0break;case 1: MCUCR=MCUCR|(sense_ctrl*0x04);GICR|=0x80;break;case 2: MCUCSR=MCUCR||(sense_ctrl<<7);GICR=0x20;break;default:break;}}void TCNT0_8bit(uchar time_counter,uchar clock_select){TCCR0=0;//重置T/C控制寄存器,WGM0和WGM1为0,普通模式TCCR0|=clock_select;//选择时钟源TCNT0=time_counter;//初始化T/C寄存器TIMSK|=(1<<TOIE0);//溢出中断使能}void TCNT1_16bit(uint tcnt1_val,uchar clock_select){TCCR1A=0;//重置TCCR1ATCCR1B=0;//重置TCCR1B//普通模式TCCR1B|=clock_select;//选择时钟源TCNT1=tcnt1_val;//定时计数器初始化TIMSK|=(1<<TOIE1);//使能溢出中断}void Input_Capture(){TCCR1A=0;TCCR1B=0xc4;//使用输入噪声抑制器,输入捕捉为上升沿触发,时钟256分频TIMSK|=(1<<TICIE1);//输入捕捉中断使能TIMSK|=(1<<TOIE1);//T/C1溢出中断使能}void FAST_PWM_16bit(uchar clock_select,uint ICR1_val,uint OCR1A_val,uint OCR1B_val) {DDRD|=0x30;TCCR1A|=0XA2;//设置为快速PWM15模式,PD4、PD5口在匹配时输出电平翻转clock_select|=0x18;TCCR1B|=clock_select;ICR1=ICR1_val;OCR1A=OCR1A_val;OCR1B=OCR1B_val;}/*MacroAndConst.h里面的内容*/ #ifndef _MACRO_AND_CONST_H_ #define _MACRO_AND_CONST_H_typedef unsigned int uint;typedef unsigned char uchar; #endif。

单片机C语言编程中定时器初值计算的两种方法

单片机C语言编程中定时器初值计算的两种方法

单片机C语言编程中定时器初值计算的两种方法在单片机C语言编程中,定时器的初值计算是一个重要的环节。

定时器的初值是一个整数值,用于设置定时器的计数范围和计数周期。

根据不同的需求和硬件平台,可以采取不同的方法来计算定时器的初值。

1.基于精确的时间计算方法:基于精确的时间计算方法主要是根据需要定时的时间长度来计算定时器的初值。

首先,需要确定定时器的频率,即每秒钟产生的中断次数。

然后,需要计算出所需的计数周期,即需要定时的时间长度乘以定时器的频率。

最后,通过计算周期与定时器的初始值之间的关系,可以得到定时器的初值。

基于精确的时间计算方法能够保证定时器的精度,在需要精确控制时间的应用中比较常见。

2.基于试验和估算的方法:基于试验和估算的方法适用于一些不需要非常精确的定时器应用。

这种方法一般通过实验来确定合适的定时器初值。

首先,设置一个初值,然后通过实际运行代码并观察计时结果,不断调整初值,直到达到所需的定时效果。

例如,在一个LED闪烁的应用中,假设希望每个LED的亮灭时间为1秒。

可以通过设置一个初值,然后不断调整初值,直到每个LED的亮灭时间接近1秒。

在调整初值时,可以通过观察LED亮灭的频率来判断初值是否合适。

基于试验和估算的方法相对简单,适用于一些对定时器精度要求不高的应用。

需要注意的是,在定时器初值的计算过程中,需要考虑定时器的工作模式、预分频系数等因素,以确保定时器的计时周期和频率能够满足要求。

在单片机C语言编程中,定时器的初值计算是一个重要而复杂的任务。

根据不同的应用需求和硬件平台,可以选择不同的计算方法。

基于精确的时间计算方法适用于那些对定时器精度有较高要求的应用,而基于试验和估算的方法适用于一些对定时器精度要求不高的应用。

无论选用哪种方法,在计算定时器初值时,需要充分考虑定时器的工作模式、频率和计时周期等因素,以确保定时器的计时与实际需求相符。

同时,在实际应用中,定时器初值也可能需要通过实验和调试进行调整,以保证定时器的工作效果。

单片机定时器初值计算公式

单片机定时器初值计算公式

单片机定时器初值计算公式
为了计算定时器的初值,我们首先需要了解定时器的时钟源和分频因子。

时钟源是指提供给定时器的时钟信号,它可以是内部时钟源或外部时钟源。

内部时钟源通常由单片机的时钟系统产生,而外部时钟源可以来自于其他外部设备。

分频因子是指将时钟源频率分频后得到的频率值。

分频因子的设置决定了定时器的计数速度。

通常情况下,定时器的计数速度是时钟源频率除以分频因子。

根据定时器的时钟源和分频因子,可以使用以下公式来计算定时器的初值:
初值=(2^N-1)-(频率/分频因子/所需的时间间隔)
其中,N是定时器寄存器的位数,频率是时钟源的频率,分频因子是时钟源的分频因子,所需的时间间隔是我们希望定时器计数到的时间。

以下是一个简单的例子,用于演示如何使用公式计算定时器的初值:假设我们的单片机采用内部时钟源,频率为8MHz,定时器的分频因子为64,我们希望定时器在10ms的时间间隔内计数完毕。

首先,我们需要计算出时钟源的频率经过分频后的实际频率:
实际频率=8MHz/64=125kHz
然后,将实际频率代入公式,我们可以计算出初值:
初值 = (2^8 - 1) - (125kHz/10ms) = 31 - 12.5 = 18.5
由于初值必须是整数,我们可以将初值进行取整操作,最终的初值为18
需要注意的是,计算出来的初值是用来装载到定时器寄存器的值,所以在使用时需要将其转换为二进制形式,并根据单片机的具体定时器配置进行相应的设置。

总结起来,单片机定时器初值的计算公式为:
初值=(2^N-1)-(频率/分频因子/所需的时间间隔)
通过计算出的初值,我们可以对定时器进行设置,实现所需的时间控制功能。

AVR单片机定时计数器TC0图解教程

AVR单片机定时计数器TC0图解教程

数 值 比 较 器
=
更新
输出比较寄存器 0 Output Compare Register OCR0
Output Compare Flag 输出比较匹配中断标志,转向中断向量执行中断服 务时硬件自动清零
TIFR(Timer Interrupt Flag Register) 定时计数器中断标志寄存器 初值 R/W Bit 000 T/C0 不工作(无时钟源) 001 CLKIO (不分频) 010 CLKIO / 8 011 CLKIO / 64 100 CLKIO / 256 101 CLKIO / 1024 110 外 T0 引脚,下降沿触发 111 外 T0 引脚,上升沿触发 0 RW OCF2 0 RW TOV2 0 RW ICF1 0 RW OCF1A 0 RW OCF1B 0 RW TOV1 0 RW OCF0 0 RW TOV0
Timer0 OverFlow Flag 转向 中断向量执行中断服务时 硬件自动清零
定时/计数器 Timer0/Counter0 Register TCNT0
清0 TCNT0=0xFF
数 值 比 较 器
=
00 普通定时器模式 01 PWM 相位修正 00 CTC 模式 00 快速 PWM 模式
Output Compare Flag 输出比较匹配中断标志,转向中断向量执行中断服 务时硬件自动清零
ห้องสมุดไป่ตู้
Timer0 OverFlow Flag 转向 中断向量执行中断服务时 硬件自动清零
定时/计数器 Timer0/Counter0 Register TCNT0 TCNT0=0xFF 数 值 比 较 器
清0
=
更新
00 普通定时器模式 01 PWM 相位修正 00 CTC 模式 00 快速 PWM 模式

AVR定时器的用法要点介绍

AVR定时器的用法要点介绍

AVR定时器的用法要点介绍符号定义:BOTTOM 计数器计到0x0000 时即达到BOTTOMMAX 计数器计到0xFFFF ( 十进制的65535) 时即达到MAXTOP 计数器计到计数序列的最大值时即达到TOP。

TOP 值可以为固定值0x00FF、0x01FF或 0x03FF,或是存储于寄存器 OCR1A或ICR1里的数值,具体有赖于工作模式------注意MAX和TOP是不同的,在表格[波形产生模式的位描述]可以看到它们的作用分5种工作类型1 普通模式 WGM1=0跟51的普通模式差不多,有TOV1溢出中断标志,发生于MAX(0xFFFF)时1 采用内部计数时钟用于 ICP捕捉输入场合---测量脉宽/红外解码(捕捉输入功能可以工作在多种模式下,而不单单只是普通模式)2 采用外部计数脉冲输入用于计数,测频其他的应用,采用其他模式更为方便,不需要像51般费神2 CTC模式 [比较匹配时清零定时器模式] WGM1=4,12跟51的自动重载模式差不多1 用于输出50%占空比的方波信号2 用于产生准确的连续定时信号WGM1=4时,最大值由OCR1A设定,TOP时产生OCF1A比较匹配中断标志WGM1=12时,最大值由ICF1设定, TOP时产生ICF1输入捕捉中断标志------如果TOP=MAX,TOP时也会产生TOV1溢出中断标志注:WGM=15时,也能实现从OC1A输出方波,而且具备双缓冲功能计算公式: fOCn=fclk_IO/(2*N*(1+TOP))变量N 代表预分频因子(1、8、64、256、1024),T2多了(32、128)两级。

3 快速PWM模式 WGM1=5,6,7,14,15单斜波计数,用于输出高频率的PWM信号(比双斜波的高一倍频率)都有TOV1溢出中断,发生于TOP时[不是MAX,跟普通模式,CTC模式不一样]比较匹配后可以产生OCF1x比较匹配中断.WGM1=5时, 最大值为0x00FF, 8位分辨率WGM1=6时, 最大值为0x01FF, 9位分辨率WGM1=7时, 最大值为0x03FF,10位分辨率WGM1=14时,最大值由ICF1设定, TOP时产生ICF1输入捕捉中断 (单缓冲)WGM1=15时,最大值由OCR1A设定,TOP时产生OCF1A比较匹配中断(双缓冲,但OC1A将没有PWM能力,最多只能输出方波) 改变TOP值时必须保证新的TOP值不小于所有比较寄存器的数值注意,即使OCR1A/B设为0x0000,也会输出一个定时器时钟周期的窄脉冲,而不是一直为低电平计算公式:fPWM=fclk_IO/(N*(1+TOP))4 相位修正PWM模式 WGM1=1,2,3,10,11双斜波计数,用于输出高精度的,相位准确的,对称的PWM信号都有TOV1溢出中断,但发生在BOOTOM时比较匹配后可以产生OCF1x比较匹配中断.WGM1=1时, 最大值为0x00FF, 8位分辨率WGM1=2时, 最大值为0x01FF, 9位分辨率WGM1=3时, 最大值为0x03FF,10位分辨率WGM1=10时,最大值由ICF1设定, TOP时产生ICF1输入捕捉中断 (单缓冲)WGM1=11时,最大值由OCR1A设定,TOP时产生OCF1A比较匹配中断(双缓冲,但OC1A将没有PWM能力,最多只能输出方波)改变TOP值时必须保证新的TOP值不小于所有比较寄存器的数值可以输出0%~100%占空比的PWM信号若要在T/C 运行时改变TOP 值,最好用相位与频率修正模式代替相位修正模式。

定时器初值计算公式

定时器初值计算公式
定时器是一种常见的计时设备,它在嵌入式系统中有着广泛的应用。

通常情况下,我们需要设置定时器的初值,以确定计时的周期和触发时间。

那么,如何通过初值计算公式来计算定时器的周期呢?
我们需要了解定时器的工作原理。

在定时器开始计时时,它会从一个初始值开始递减,直到减到0时触发定时器中断。

这个初始值就是我们所说的初值。

因此,我们可以根据定时器的时钟频率和初值来计算定时器的周期和触发时间。

假设定时器的时钟频率为F,初值为N,定时器的周期为T,那么根据初值计算公式有:
T = (N + 1) / F
这个公式可以帮助我们快速计算定时器的周期。

需要注意的是,初值是一个整数,因此在计算周期时需要将初值加1。

例如,假设我们要设置一个定时器的周期为10ms,时钟频率为10MHz,那么我们可以通过初值计算公式来计算出初值为:
N = T × F - 1 = 10 × 10^(-3) × 10^7 - 1 = 99999
因此,我们可以将定时器的初值设置为99999,这样就能够实现10ms的定时器周期。

需要注意的是,定时器的实际周期可能会受到时钟频率精度和误差的影响,因此在实际应用中,我们需要根据实际情况进行调整和校准。

初值计算公式是计算定时器周期和触发时间的重要工具,它可以帮助我们快速地设置定时器的初值,实现精确的计时功能。

在实际应用中,我们需要根据具体的需求和系统环境进行调整和优化,以达到最佳的性能和稳定性。

AVR教程(十八):AVR 定时器中断程序

LED 控制电路原理图 //应用软件: ICC AVRAVR /*01010101010101010101010101010101010101010101010101010101010101010101 ---------------------------------------------------------------------实验内容: 使用 AVR 的定时器 T1做1S 定时,并使用 PD 口的 LED 指示灯做简单指示。 ---------------------------------------------------------------------硬件连接: 将 PD 口的 LED 指示灯使能开关切换到"ON"状态。 ----------------------------------------------------------------------
输 入: 返 回: --------------------------------------------------------------------*/ #pragma interrupt_handler timer1_ovf_isr:9 void timer1_ovf_isr(void) { TCNT1H = 0xE3; //reload counter high value TCNT1L = 0xE1; //reload counter low value DISP_PORT++; //每加1S,显示加1 } /*-------------------------------------------------------------------程序名称: 程序功能: 注意事项:没什么好注意的,不要直接对单片机控制板加220V 电压就行了! 提示说明: 输 入: 返 回: --------------------------------------------------------------------*/ void main(void) { DISP_DDR = 0XFF; //设置显示口为输出 timer1_init(); SEI(); while(1); } 系统调试

AVR ATmega16定时器溢出中断使用小结

关于溢出中断不管是哪个单片机都是不断累加,使其寄存器溢出触发中断,然后跳转到中断函数处执行中断服务程序。

对于定时器初值的设定可以加深对定时器的工作原理的理解。

ATMega16 里面有8位和16位两种定时器,他们何时会溢出这个是固定的,也就是到达他们的计数范围的最大值就会产生中断,8位的定时器的最大计数范围是0~256(2的8次方),就是累加到256后他就会产生中断,16位的定时器最大计数范围是0~65536(2的16次方),累加到65536时他就会产生中断。

而我们所谓的计数初值是就是要设定定时器在什么地方开始计数,以8位定时器为例比如:初值为100,所以定时器从100开始累加,累加了156次,加到256后产生中断,这就是中间消耗的时间和指令周期就是我们要去设定的时间;再比如:初值是200,所以定时器从200开始累加,累加了56次,加到256后产生中断,可以看到第一定时要累加156次才会中断而第二次只要累加56次就会产生中断,显然第一次设定的时间要比第二次的长。

定时器不仅可以定时,而且我们用到定时器的时候往往是需要精确定时的时候。

我们可以计算出我们设定的初值会在多长时间后进入中断。

下面的是8位定时器设定的时候需要用的寄存器:实验平台:ATMega16晶振: 11.0592 MHz对初值的计算:1,11059200 / 1024 = 10800 设定为1024倍分频,得到每1秒需要进行多少次累加2,10800 / 100 = 108 得到10ms 的定时需要进行多少次累加(第一步计算出每一秒进行的累加次数,由于一秒是100个10ms,故除数为100)3,256 - 108 = 148 计算范围最大值(8位寄存器)减去要累加的时间,得到初值,即从哪里开始累加才能在溢出时为10ms的时间。

4,148 <==> 0x94 得到十六进制值,赋值给TCNT0#实验代码:定时10ms_ICCAVR#include <iom16.h>unsigned char flag = 0;void timer_init(void){TCCR0 = 0x05; //进行1024分频TCNT0 = 0x94; //赋计数初值TIMSK_TOIE0 = 1; //开使能SREG_I = 1; //开总中断}#pragma vector = TIMER0_OVF_vect__interrupt void time0_normal(void){TCNT0 = 0x94; //重新赋初值flag++;}void main(void){timer_init();DDRB_Bit0 = 1;while(1){if(flag == 100) //10ms 重复100次,即为1秒 {PORTB_Bit0 = ~PORTB_Bit0; //让LED闪烁flag = 0;}}}//+++++++++++++++++++++++++++++++++++++++ ++++++++++++++++++++++++++++++//实验平台:ATMega16晶振:11.059216位定时器初值设定:1,11059200 / 256 = 43200 设定256倍分频,得到每1秒需要进行多少次累加2,65536 - 43200 = 22336 计算范围最大值减去要累加的时间,得到初值,即从哪里开始累加才能在溢出时为1s的时间。

定时器初值计算方法

定时器初值计算方法
定时器初值是指定时器被设置时的初始值,通常用于控制定时器的工作时间或计数器。

以下是一些常见的定时器初值计算方法:
1. 使用默认初值:大多数定时器都有一个默认的初值,可以在定时器配置中设置。

如果忘记了初值,可以使用默认值。

2. 计算定时器的时钟频率:可以使用定时器的时钟频率来计算
初值。

时钟频率是指定时器每秒钟所执行的计数次数。

可以通过以下公式来计算定时器初值:初值 = 2 / 时钟频率。

例如,如果定时器的频率为100MHz,则可以使用以下公式计算初值:初值 = 2 / 10000000 = 0.00002。

3. 计算定时器的工作周期:可以使用定时器的中断周期来计算
初值。

中断周期是指定时器在发生中断时执行的计数器次数。

可以通过以下公式来计算定时器初值:初值 = 中断周期 / 工作周期。

例如,如果定时器的中断周期是10秒钟,工作周期是1秒,则可以使用以下公式计算初值:初值 = 10 / 1 = 10。

4. 根据定时器的地址计算初值:如果想根据定时器的地址计算
初值,需要知道定时器的段寄存器地址和功能寄存器地址。

可以使用以下公式计算初值:初值 =段寄存器地址 / 功能寄存器地址。

例如,
如果定时器的段寄存器的地址是0x4000,功能寄存器的地址是
0x3000,则可以使用以下公式计算初值:初值 = 0x4000 / 0x3000 = 0.2。

需要注意的是,使用这些方法计算初值时,应该考虑到定时器的精度和实际时钟频率等因素。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
相关文档
最新文档