定时器计数器时占用CPU吗

2013年12月 VB大版内专家分月排行榜第二2013年3月 VB大版内专家分月排行榜第二2013年1月 VB大版内专家分月排行榜第二2012年9月 VB大版内专家分月排行榜第二2012年8月 VB大版内专家分月排行榜第二2012年7月 VB大版内专家分月排行榜第二2006年7月 VB大版内专家分月排行榜第二2006年5月 VB大版内专家分月排行榜第二
2014年9月 VB大版内专家分月排行榜第三2013年7月 VB大版内专家分月排行榜第三2013年6月 VB大版内专家分月排行榜第三2013年4月 VB大版内专家分月排行榜第三2012年11月 VB大版内专家分月排行榜第三2006年6月 VB大版内专家分月排行榜第三2006年4月 VB大版内专家分月排行榜第三2002年12月 VB大版内专家分月排行榜第三2002年11月 VB大版内专家分月排行榜第三
匿名用户不能发表回复!|
每天回帖即可获得10分可用分!小技巧:
你还可以输入10000个字符
(Ctrl+Enter)
请遵守CSDN,不得违反国家法律法规。
转载文章请注明出自“CSDN(www.csdn.net)”。如是商业用途请联系原作者。为什么说用定时器延时就不会浪费CPU?_单片机吧_百度贴吧
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&签到排名:今日本吧第个签到,本吧因你更精彩,明天继续来努力!
本吧签到人数:0成为超级会员,使用一键签到本月漏签0次!成为超级会员,赠送8张补签卡连续签到:天&&累计签到:天超级会员单次开通12个月以上,赠送连续签到卡3张
关注:131,243贴子:
为什么说用定时器延时就不会浪费CPU?收藏
用定时器产生一个1ms的中断,然后在中断函数将全局变量i++,main函数:led=0;delay(500);led=1;。我的分析是这样的,开始CPU点亮led然后调用delay延时函数启动定时器,CPU不断判断i是否达到500,当达到500次中断即i=500时led关闭。这么看来CPU还是在执行着,定时器好像没帮CPU减负呀?这样和软件延时不一样吗,软件延时CPU不断的对变量自减?
上海虚谷科技承接各种上海单片机开发和上海单片机开发项目联系电话: 郭先生
我想说如果定时器不够用了怎么办。。。
当你遇到复杂的程序。你需要用定时器来优化你的算法。优化算法的结果就是CPU减负。----------------------------------------------------------我是菜鸟。天真的理解不代表真正含义。。看楼下怎么说?
Cpu延时的时候不能干别的事,如果你不需要做别的事当然无所谓,等你需要的时候,用定时器就可以让定时器去定时,Cpu继续处理程序
定时器是一个硬件装置,是一个单元
他们是并行工作的。
像楼上说的那样。定时器是和cpu并行工作的。你可以在延时的时候做其他事情。如果是cpu延时,那就不能做其他事了。
67l说得对。建议楼主查一下相关资料看定时器是如何工作的,这是基本概念。
单线程都一样,多线程延时时cpu可以去处理别的任务,定时器产生中断再跳回来
像这样写,依旧是死等,依旧浪费CPU时间。
单片机专业技术团队为您提供硬件设计,单片机编程及技术培训;提供完整的物联网开发,智能家居项目,汽车电子仪表等项目解决方案
定时器就像一个闹钟一样,过一段时间来看一下,你延迟就是在那死等了。。。就像多线程一样,没事干别的去,别老占着CPU
如果,程序编写的不好,那么,即使你用定时器,也可能浪费 CPU。
登录百度帐号推荐应用
为兴趣而生,贴吧更懂你。或博客访问: 594592
博文数量: 229
博客积分: 2788
博客等级: 少校
技术积分: 2095
注册时间:
知之者不如好之,好之者不如乐之
IT168企业级官微
微信号:IT168qiye
系统架构师大会
微信号:SACC2013
分类: 嵌入式
定时器是单片机的重要功能模块之一,在检测、控制领域有广泛应用。定时器常用作定时时钟,以实现定时检测、定时响应、定时控制,并且可用于产生ms宽的脉
冲信号,驱动步进电机。定时和计数功能最终都是通过计数实现的,若计数的事件源是周期固定的脉冲,则可以实现定时功能,否则只能实现计数功能。因此可以将
定时和计数功能由一个部件实现。
一、定时器/计数器原理
& && & 实现定时和计数的方法一般有:软件定时、专用硬件电路和可编程定时器/计数器三种方法。
软件定时:执行一个循环程序进行时间延迟。定时准确,不需要外加硬件电路,但增加CPU开销。
专用硬件电路定时:可实现精确的定时和计数,但参数调节不便。
可编程定时器/计数器:不占用CPU时间,能与CPU并行工作,实现精确的定时和计数,又可以通过编程设置其工作方式和其它参数,因此使用方便。
& & 定时器的基本工作原理是:利用计数器对固定周期的脉冲计数,通过寄存器的溢出来触发中断。
二、定时器的具体应用步骤:
1、使用定时器时主要有两种方法:
& & 1)使用定时中断技术,计时溢出时触发中断,预先设计的中断子程序将被自动调用;
& & 2)使用查询法检查是否出现计时溢出,溢出时执行指定代码。
& & 上述方法中使用的较多的是第一种。
2、具体应用步骤如下:
& & 1) 打开中断允许位:
对 IE 寄存器进行控制,IE寄存器各位的信息如下图所示:
& && && && && && && && &图2.2-1 中断使能寄存器组成
EA:&&为0 时关所有中断;为1时开所有中断
ET2:为0时关T2中断;为 1时开T2 中断,只有、8752才有此中断
ES:&&为0时关串口中断;为 1时开串口中断
ET1:为0时关T1中断;为 1时开T1 中断
EX1:为0时关INT1中断;为1时开INT1中断
ET0:为0时关T0中断;为 1时开T0 中断
EX0:为0时关INT0中断;为1时开INT0中断
& &2)选择定时器/计时器的工作方式:
定时器TMOD格式,如下图所示 :
& && && && && && && && && && && &&&图2.2-2定时器TMOD格式
& & CPU 在每个机器周期内对 T0/T1 检测一次,但只有在前一次检测为 1 和后一次检测为 0时才会使计数器加
1。因此,计数器不是由外部时钟负边沿触发,而是在两次检测到负跳变存在时才进行计数的。由于两次检测需要 24 个时钟脉冲,故 T0/T1
线上输入的 0或 1 的持续时间不能少于一个机器周期。通常,T0 或 T1 输入线上的计数脉冲频率总小于 100kHz。
& & 方式 0:定时器/计时器按 13 位加 1 计数,这 13 位由 TH 中的高 8 位和 TL 中的低 5 位组成,其中TL中的高3 位弃之不用(与MCS-48兼容)。
& && && && && && && && && && && &&&图2.2-3 定时器0的计数位数& &
& & 13 位计数器按加 1 计数器计数,计满为 0 时能自动向 CPU 发出溢出中断请求,但要它再次计数,CPU必须在其中断服务程序中为它重装初值。
& & 方式 1:16 位加1计数器,由TH 和TL 组成,在方式 1的工作情况和方式0的相同,只
是计数器值是方式0 的8倍。
& && && && && && && && && && && && && && && && && && && && &&&图2.2-4&&定时器1的计数位数
& && & 方式 2:计数器被拆成一个 8 位寄存器 TH 和一个 8 位计数器 TL,CPU 对它们初始化时必须送相同的定时初值。当计数器启动后,TL按8位加1 计数,当它计满回零时,一方面向CPU发送溢出中断请求,另一方面从 TH 中重新获得初值并启动计数。
& && && && && && && && && && && && && && && && && && && && && & 图2.2-5&&定时器2的计数位数
& && & 方式 3:T0 和T1 工作方式不同,TH0 和 TL0 按两个独立的 8 位计数器工作,T1 只能按不需要中断的方式2 工作。
& && & 在方式 3 下的 TH0 和 TL0 是有区别的:TL0 可以设定为定时器/计时器或计数器模式工作,仍由TR0 控制,并采用TF0
作为溢出中断标志;TH0 只能按定时器/计时器模式工作,它借用TR1和 TF1 来控制并存放溢出中断标志。因此, T1就没有控制位可以用了,故
TL1 在计满回零时不会产生溢出中断请求的。
& && & 显然,T0 和T1设定为方式3,实际上就相当于设定了 3个8 位计数器同时工作,其中 TH0和TL0 为两个由软件重装的8
位计数器,TH1 和TL1为自动重装的8位计数器,但无溢出中断请求产生。由于
TL1工作于无中断请求状态,故用它来作为串口可变波特率发生器是最好不过的。
& && && && && && && && && && && && && && && && && && && && && && && && && &&&图2.2-6&&
& && && &&&3)为计数器赋值
计数器初值计算:
& && && && && && && && && && && && && && && && && && && && && & TC = M ? C
& && && && & TC:计数器初值,M:计数器模值(2k),C:把计数器计满的计数值
定时器初值计算:
& && && && && && && && && && &T = (M ? TC)T计数& && && && & 或& && && && & TC = M ? T/T计数
& && && && & M:模值,T 计数:单片机时钟周期 TCLK(ΦCLK的倒数)的12 倍;TC 为定时器的定时初值,T为欲定时的时间。
& && && && && && && && && && && && && && && && && && && &TC = M ? T × /12
& && && && & M:模值,ΦCLK:单片机时钟周期ΦCLK;TC 为定时器的定时初值,T 为欲定时的时间。
& && && && & 例如:单片机主脉冲频率ΦCLK为12MHz,最大定时时间为:
& && && && && && & 方式0 时& & TMAX = 213×1us = 8.192ms
& && && && && && & 方式1 时& & TMAX = 216×1us = 65.536ms
& && && && && && & 方式2 和方式3&&TMAX = 28×1us = 0.256ms
& && & & &4) 启动计时器
& && && && && && && && && && && && && && && && && && && && & 图2.2-7 计时器控制寄存器&&
TR0:为0时,停T0计数;为1 时,启T0 计数
TF0:为0 时,无T0中断(硬件复位);为1 时,有 T0 溢出中断
TR1:为0时,停 T1计数;为1 时,启T1 计数
TF1:为0 时,无T1中断(硬件复位);为1 时,有 T1 溢出中断
IE1:为0 时,硬件复位;为 1时INT1上有中断
IT1:为0 时,INT1电平触发(软件复位);为1时,INT1负边沿触发
IE0:为0 时,硬件复位;为 1时INT0上有中断
IT0:为0 时,INT0电平触发(软件复位);INT0负边沿触发
& && & 当然,最重要的工作室编写定时器中断服务程序,当定时器的时间到达(计时溢出)时即触发中断,所编写的相应的程序会被自动执行。
对于方式0、1、3,如果希望定时器能按设定的某固定时间间隔不断触发,还需要在定时中断服务程序中再次设置定时寄存器初值(TH0/TL0或TH1
/TL1),对于方式2则不需要,因为该方式下定时寄存器低字节(TH0或TL1)独立完成计数工作,在定时中断发生时,定时寄存器高字节(TH0
或TH1)的值会自动重新赋给低字节,高字节的值在整个过程中保持不变。
& && && &需要注意的是,如果仅在主程序中设置了定时寄存器的初值,中断程序中未重新给定时寄存器赋值,中断程序将以该方式下的最大定时值工作。例如,方式0为13位,最大值为8192;方式1为16位,最大值为65535.
阅读(601) | 评论(0) | 转发(1) |
相关热门文章
给主人留下些什么吧!~~
请登录后评论。以下试题来自:
问答题简答题定时/计数器用作定时器时,对外界计数频率有何限制?
由于确认1次负跳变要花2个机器周期,即24个振荡周期,因此外部输入的计数脉冲的最高频率为系统振荡器频率的1/24。
为您推荐的考试题库
您可能感兴趣的试卷
你可能感兴趣的试题
定时/计数器作定时时,其计数脉冲由系统振荡器产生的内部时钟信号12分频后提供。定时时间与时钟频率和定时初值有关。
同样可以求得方式1下的最大定时时间为262.144ms;方式2下的最大定时时间为1024ms。
RETI指令在返回的同时清除相应的优先级触发器,以允许下次中断
A、同一级别的中断请求按时间的先后顺序响应。
B、同一时间同一级别的多中断请求,将形成阻塞,系统无法响应。
C、低优先级中断请求不能中断高优先级中断请求,但是高优先级中断请求能中断低优先级中断请求。
D、同级中断不能嵌套。
A、定时中断
B、脉冲方式的外部中断
C、外部串行中断
D、电平方式的外部中断AVR——使用定时器必须弄清的几个概念!
在MCU中(M16),定时器是独立的一个模块,M16有三个独立的定时器模块,即T/C0、T/C1和T/C2;其中T/C0和T/C2都是8位的定时器,而T/C1是一个16位的定时器。定时器的工作是独立于CPU之外自行运行的硬件模块。
1、定时器何时开始工作(或说计数)的?
当TCCR0!=0x00任何模式下,只要MCU一上电,T/C就开始计时工作。其实TCCR0主要是定时器的预分频和波形模式、比较匹配模式的设置,说到预分频,不得不提一下这个模块,这个模块是T/C0、T/C1共用的一个模块,但可以有不同的分频设置。
2、定时器是如何进行工作的:说到定时器的工作,不得不说三个个重要参数:TCNT0、OCR0,TIMSK,TCNT0是设置定时器的计时初始值,定时器开始工作后立即从TCNT0一直累加到0XFF,累加过程所消耗的时间就是我们需要的定时时间;OCR0是一个比较设定值,当TCNT0的值累计到OCR0时(TNCT0==OCR0),如果有开启比较匹配中断功能,那么此时就会产生比较中断,所以,OCR0的值一般都是设置在TCNT0初始值和0XFF之间,之外的任何值都不会产生比较中断。TIMSK是一个中断使能位设置,就是我们需要计时器溢出中断或是比较匹配中断功能或两者都要时就对TIMSK的相应寄存器位进行设置。
3、定时器的中断使用,一个定时器可以有两个中断资源可利用,一个只溢出中断,另一个是比较匹配中断,如上面2所说的。想说明的溢出中断子程序内一般要有重载TCNT0的初始值,否则,TCNT0就会从0X00开始累加计数到0XFF,所耗费的时间就不我们想要的时间。比较中断就是当TCNT0==OCR0时,发生比较匹配中断;所以,中断子程序中一般只插入少量的处理代码,否则,会发生所谓的中断套嵌的现象,由于M16不支持中断套嵌,这样会使得中断子程序中的部分代码无法执行,严重时会造成系统崩溃。
4、TCNT0和OCR0的值换算:对于8bit的计时器,TCNT0一般可以由下面的公式换算:
& TCNT0=256-(TV*F)/N;
& TV: 所想要设定的定时时间,单位,us
晶振频率(MHz)
& & N: 分频因子
定时器是独立运行的,它不占用CPU的时间,不需要指令,只有调用对应的寄存器的时候才需要参与。
mega16为例,它有三个寄存器,timer0,timer1和timer2,T0和T2是8位定时器,T1是16位寄存器,T2为异步定时器,三个定时器都可以用于产生PWM。
以定时器T0来简单介绍定时器的操作方法,T0有三个寄存器可以被CPU访问,TCCR0,TCNT0,OCR0,下面看一段ICC生成的定时器初始化程序。
//TIMER0 initialize - prescale:8
// WGM: Normal
// desired value: 1KHz
// actual value: 1.000KHz (0.0%)
void timer0_init(void)
TCCR0 = 0x00; //stop
TCNT0 = 0x83; //set count
OCR0 = 0x7D; //set compare
TCCR0 = 0x02; //start timer
TCCR0为控制寄存器,用于控制定时器的工作模式细节;
TCNT0为T/C 寄存器,它的值在定时器的每个工作周期里加一或减一,实现定时操作,CPU可以随时读写TCNT0;
OCR0:输出比较寄存器,它包含一个8 位的数据,不间断地与计数器数值TCNT0
进行比较。匹配事件可以用来产生输出比较中断,或者用来在OC0 引脚上产生波形。
这里说最简单的模式,TCNT一直加一,到达最大值0xFF然后清零,进入下一次计数,在上面的程序中。
TCCR0=0x00;关闭T0的时钟源,定时器停止工作。
TCNT0=0x83;设置T/C寄存器的初始值,及让定时器从TCNT0从0x83开始定时或计数。
OCR0 = 0x7D;设定比较匹配寄存器的值,这个程序里没有使用。
TCCR0 = 0x02;选择时钟源,来自时钟8分频,设置后定时器就开始工作。
初始化后定时器开始工作,TCNT0在每一个定时器时钟加一,当TCNT0等于OCR0的值时,T/C 中断标志寄存器-
TIFR中的OCF0
置位,如果这时候TIMSK中OCIE0为1(即允许T0比较匹配中断),并且全局中断允许,比较匹配中断即运行。中断程序中可以对TCNT0和0CR0进行操作,对定时器进行调整。
TCNT0继续加一,当达到0xFF时,T/C 中断标志寄存器-
TIFR中的TOV0置位,如果这时候TIMSK中TOIE0为1(即允许T0溢出中断),并且全局中断允许,溢出中断即运行。中断程序中可以对TCNT0和0CR0进行操作,对定时器进行调整。
和定时器相关的寄存器还有SREG和TIMSK,前者位1控制全局中段允许,后者位1(OCIE0)和位0(TOIE0)分别控制比较匹配中断和溢出比较匹配中断允许。
实际的过程中,定时器相关寄存器的操作非常灵活,可以在溢出中断中修改TCNT0的值,也可以在中断中修改OCR0的值,后面的实验中会讲到用定时器1修改OCR1A的方法实现1S精确定时。
师傅领进门,修行靠个人,定时器的基本原理说到这里,要更深入的了解定时器,请看数据手册。
定时公式:Time=PRE*(MAX-TCNT0+1) /F_cpu单位S
,其中,PRE为与分频数,本例中为8,MAX即为最大值255,TCNT0为初始化时的值,本例中为0x83(十进制的131),T_cpu,系统时钟频率,本例中为1000000。
本例程序中定时时间为:Time=8*(255-131+1)/.001 S
,即为1ms,1Khz。可以看出,如果晶振选为8M,则定时时间变为0.000125S,也就是说晶振越大,定时时间越短,预分频越大,定时越长。
在设置时如果你选择1ms,会得到如下结果,和上面的1Khz相同。
//TIMER0 initialize - prescale:8
// WGM: Normal
// desired value: 1mSec
// actual value: 1.000mSec (0.0%)
void timer0_init(void)
TCCR0 = 0x00; //stop
TCNT0 = 0x83; //set count
OCR0 = 0x7D; //set compare
TCCR0 = 0x02; //start timer
//ICC-AVR application builder :
// Target : M16
// Crystal: 1.0000Mhz
// 用途:演示定时器的工作原理
// 作者:古欣
// AVR与虚拟仪器 [url][/url]
#include &iom16v.h&
#include &macros.h&
void port_init(void)
PORTA = 0x00;
DDRA = 0x03; //PA0 PA1 输出
PORTB = 0x00;
DDRB = 0xFF; //PB 输出
PORTC = 0x00; //m103 output only
DDRC = 0x00;
PORTD = 0x00;
DDRD = 0x00;
//TIMER0 initialize - prescale:8
// WGM: Normal
// desired value: 1KHz
// actual value: 1.000KHz (0.0%)
void timer0_init(void)
TCCR0 = 0x00; //stop
TCNT0 = 0x83; //set count
OCR0 = 0x7D; //set compare
TCCR0 = 0x02; //start timer
//比较匹配中断
#pragma interrupt_handler timer0_comp_isr:20
void timer0_comp_isr(void)
//compare occured TCNT0=OCR0
if(OCR0==0x7D) //调整0x7D
OCR0=0x7F;
OCR0=0x7D;
PORTA ^= 0x01; //PA0取反
//溢出中断中断
#pragma interrupt_handler timer0_ovf_isr:10
void timer0_ovf_isr(void)
TCNT0 = 0x83; //reload counter value
PORTA ^= 0x01; //PA0取反
//call this routine to initialize all peripherals
void init_devices(void)
//stop errant interrupts until set up
CLI(); //disable all interrupts
port_init();
timer0_init();
MCUCR = 0x00;
GICR = 0x00;
TIMSK = 0x03; //timer interrupt sources 允许定时器零匹配和溢出中断
SEI(); //re-enable interrupts
//all peripherals are now initialized
void main(void)
init_devices();
PORTA=0x00;
PORTB = TCNT0; //任何时候都可以读TCNT0
已投稿到:
以上网友发言只代表其个人观点,不代表新浪网的观点或立场。

我要回帖

更多关于 stm32定时器外部计数 的文章

 

随机推荐