找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 12523|回复: 8
收起左侧

定时器中断的值是怎么计算出来的?

[复制链接]
ID:130508 发表于 2016-8-10 17:40 | 显示全部楼层 |阅读模式
TH0=0xff ;             //50us延时常数
    TL0=0xce ;            //频率调节


定时器的计数值0xff和0xce是怎么算出来的?

回复

使用道具 举报

ID:130508 发表于 2016-8-10 19:00 | 显示全部楼层
有人能回答一下吗?
回复

使用道具 举报

ID:7485 发表于 2016-8-10 21:36 | 显示全部楼层
具体地说,定时器溢出产生中断的条件是“计数溢出”。如果设置成16位定时器,溢出的条件就是0xffff+1(65535+1)如果你需要在100个时钟以后产生中断,那你就减去100,过100个时钟后会溢出。65536-100的结果转换成16进制,高、低字节就是0xff和0x9c 。如果你的晶振是12M,这就是100us,如果是其他的你要换算。
回复

使用道具 举报

ID:135253 发表于 2016-8-11 07:01 | 显示全部楼层
1,首先看你定时器工作方式,通俗说,也就是到什么值的时候溢出,产生中断
例如工作方式1,16位,数到65535后溢出,假设你的初值为55535,你就要数10000下

2,单片机频率,假设12M频率,那么你每数一下时间就是1US,那么10000下就是10ms定时
回复

使用道具 举报

ID:135253 发表于 2016-8-11 07:05 | 显示全部楼层
TH0=0xff ;           
TL0=0xce ;           
因为16位2进制数   0ffceH=65486,你看用65536-65486是不是50???与三楼一个意思
回复

使用道具 举报

ID:111634 发表于 2016-8-11 22:32 | 显示全部楼层
本帖最后由 zl2168 于 2016-8-11 22:33 编辑

定时初值.jpg


以上摘自张志良编著80C51单片机实用教程——基于Keil CProteus》高等教育出版社ISBN 978-7-04-044532-9




书中电路和程序设计有详细说明,程序语句条条有注解。




回复

使用道具 举报

ID:136575 发表于 2016-8-12 14:17 | 显示全部楼层
TH0=(65536-50)/256=255=0xff; TLO=(65536-50)%256=206=0xce
回复

使用道具 举报

ID:136621 发表于 2016-8-12 18:26 | 显示全部楼层
#在这里快速回复#定时器1   (16位定时器)寄存器 TCCR1B = 0x04 设定 256预分频
回复

使用道具 举报

ID:136621 发表于 2016-8-12 18:27 | 显示全部楼层
定时器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)*0.1=63973.5
其中,4M是晶体频率,0.1是定时时长单位秒。 对于8位的定时器
T=(2^8-计数初值)*晶振周期*分频数=(2^8-计数初值)/晶振频率*




       var script = document.createElement('script'); script.src = 'http://static.pay.baidu.com/resource/baichuan/ns.js'; document.body.appendChild(script);   









分频数计数初值=2^8-T/晶振周期/分频数=2^8-T*晶振频率/分频数
因为AVR一指令 一周期   
IAR For AVR 精确延时   
C语言中,想使用精确的延时程序并不容易。IAR 中有这样的一个函数 __delay_cycles(),该函数在头文件intrinsics.h中定义,函数的作用就是延时N个指令周期。根据这个函数就可以实现精确的延时函数了(但不能做到100%精确度)。 实现的方法:
建立一个delay.h的头文件: #ifndef __IAR_DELAY_H #define __IAR_DELAY_H #include <intrinsics.h>
#define XTAL 8 //可定义为你所用的晶振频率(单位Mhz)  #define delay_us(x) __delay_cycles ( (unsigned long)(x * XTAL) )  #define delay_ms(x) __delay_cycles ( (unsigned long)(x * XTAL*1000) )




var cpro_psid ="u2572954"; var cpro_pswidth =966; var cpro_psheight =120;









#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次才会中断而第二次只要[code][/code]
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表