定时/计数器 脉冲计数

定时/计数器(Timer/counter)是单片机芯片中最基本的外围接口,它的用途非常广泛,常用于测量时间、速度、频率、脉宽、提供定时脉冲信号 等。相对于一般8位单片机而言,AVR不仅配备了更多的定时/计数器接口,而且还是增强型的,功能非常强大。ATmega128一共配置了2个8位和2个 16位,共4个定时/计数器,本小节重点对它的一些增强功能的应用做基本的介绍。 5.9.1 预分频器
  定时/计数器最基本的功能就是对脉冲信号计数,当计数器计满后(8位为255,16位为65535),再来一个脉冲它就翻转到0,并产生中断信号。同
其他单片机类似,AVR的定时/计数器的计数脉冲可以来自外部的引脚,也可以由从内部系统时钟获得;但AVR的定时/计数器在内部系统时钟和计数单元之间
增加了一个预分频器,利用预分频器,定时/计数器可以从内部系统时钟获得不同频率的信号。表5-1为系统时钟为4MHz使用定时/计数器0的最高计时精度
和时宽范围。
表5-1 T/C0计时精度和时宽(系统时钟4MHz)
分频系数  计时频率  最高计时精度(TCNT0=255)  最宽时宽(TCNT0=0)
1          4MHz      0.25us                    64us
8          500KHz    2us                       512us
32         125KHz    8us                       2.048ms
64         62.5KHz   16us                      4.096ms
128        31.25KHz  32us                      8.192ms
256        15.625KHz 64us                      16.384ms
1024       3906.25Hz 256us                     65.536ms
  从表中看出,在系统时钟为4MHz时,8位的T/C0最高计时精度为0.25us,最长的时宽可达到65.536ms。而使用16位的定时/计数器
时,不需要辅助的软件计数器,就可以非常方便的设计一个时间长达16.777216秒(精度为256us)的定时器,这对于其它的8位单片机是做不到的。

AVR单片机的每一个定时/计数器都配备独立的、多达10位的预分频器,由软件设定分频系数,与8/16位定时/计数器配合,可以提供多种档次的定时
时间。使用时可选取最接近的定时档次,即选8/16位定时/计数器与分频系数的最优组合,减少了定时误差。所以,AVR定时/计数器的显著特点之一是:高
精度和宽时范围,使得用户应用起来更加灵活和方便。此外,AVR的USART、SPI、I2C、WDT等都不占用这些定时/计数器。
5.9.2 输入捕捉功能
  ATmega128的两个16位定时/计数器(T/C1、T/C3)具有输入捕捉功能,它是AVR定时/计数器的又一个显著的特点。其基本作用是当一
个事件发生时,立即将定时/计数器的值锁定在输入捕捉寄存器中(定时/计数器保持继续运行)。利用输入捕捉功能,可以对一个事件从发生到结束的时间进行更
加精确,如下面的示例中精确测量一个脉冲的宽度。
  测量一个脉冲的宽度,就是测量脉冲上升沿到下降之间的时间。不使用输入捕捉功能,一般情况往往需要使用两个外围部件才能完成和实现。如使用1个定时/
计数器加1个外部中断(或模拟比较器):定时/计数器用于计时;而外部中断方式设置成电平变化触发方式,用于检测脉冲的上升和下降沿。当外部中断输入电平
由低变高,触发中断,读取时间1;等到输入电平由高变低时,再次触发中断,读取时间2;两次时间差既为脉冲宽度。这种实现方式不仅多占用了一个单片机的内
部资源,而且精度也受到中断响应时间的限制。因为一旦中断发生,MCU响应中断需要时间,在中断中可能要进行适当的中断现场保护,才能读取时间值。而此时
的时间值比中断发生的时间已经滞后了。
  而使用ATmega128的1个定时/计数器,再配合其输入捕捉功能来测量脉冲的宽度就非常方便,下面是实现的程序示例。
#include <mega128.h>
#define ICP1 PIND.4 //脉冲输入由ICP1(Pind.4)输入
unsigned char ov_counter;
unsigned int rising_edge,falling_edge;
unsigned long pulse_clocks;
interrupt [TIM1_OVF] void timer1_ovf_isr(void) // T/C1溢出中断
{
ov_counter++; //记录溢出次数
}
interrupt [TIM1_CAPT] void timer1_capt_isr(void) // T/C1捕捉中断
{
if (ICP1)
{ //上升沿中断
rising_edge = ICR1; //记录上升沿开始时间
TCCR1B = TCCR1B & 0xBF; //设置T/C1为下降沿触发捕捉
ov_counter = 0; //清零溢出计数器
}
else
{ //下降沿中断
falling_edge = ICR1; //记录下降沿时间
TCCR1B = TCCR1B | 0x40; //设置T/C1为上升沿触发捕捉
pulse_clocks = (unsigned long)falling_edge - (unsigned long)rising_edge
+ (unsigned long)ov_counter * 0x10000 / 500; //计算脉冲宽度
}
}
void main(void)
{
TCCR1B=0x42; //初始化T/C1,1/8分频,上升沿触发捕捉
TIMSK=0x24; //允许T/C1溢出和捕捉中断
#asm("sei")
while (1)
     {………
     };
}
  这段程序是在CVAVR中实现的。在T/C1的捕捉中断中,先检查ICP1的实际状态,以确定是出现了上升沿还是下降沿信号。如果中断是由上升沿触发
的(ICP1为高电平),程序便开始一次脉冲宽度的测量:记录下上升沿出现的时间,把T/C1的捕捉触发方式改为下降沿触发,并清空溢出计数器。如果中断
由下降沿触发(ICP1为低电平),表示到达脉冲的未端,程序记录下降沿出现时间,计算出脉冲的宽度,再将T/C1的捕捉触发方式改为上升沿触发,以开始
下一次的测量。
  脉冲的实际宽度(毫秒格式)是根据T/C1的计数时钟个数来计算的。本例中T/C1的计数时钟是系统时钟(4MHz)的8分频,即500KHz,相应
的计数脉冲宽度为2us。因此计算出从上升沿和下降沿之间总的计数脉冲个数,除以500个脉冲(为1ms)即得到以毫秒为单位的被测脉冲宽度了。
  可以看到,使用定时/计数器以及配合它的捕捉功能测量脉冲宽度,不仅节省系统的硬件资源,编写程序简单,而且精度也高,因为读到的上升沿和下降沿的时间就是其实际发生的时间。

时间: 2024-10-14 09:00:58

定时/计数器 脉冲计数的相关文章

STM32 定时器用于外部脉冲计数(转)

源:STM32 定时器用于外部脉冲计数 STM32 定时器(一)——定时器时间的计算 STM32的定时器是灰常NB的,也是灰常让人头晕的(当然是对于白菜来说的). STM32中的定时器有很多用法: (一)系统时钟(SysTick) 设置非常简单,以下是产生1ms中断的设置,和产生10ms延时的函数: void RCC_Configuration(void) { RCC_ClocksTypeDef RCC_ClockFreq; SystemInit();//源自system_stm32f10x.c

关于STM32F103 脉冲计数的问题

//TIM2_CH2 PWM部分初始化 //PWM输出初始化//arr:自动重装值//psc:时钟预分频数 计数器功能void TIM2_ETR_Init(u16 arr,u16 psc){ //此部分需手动修改IO口设置RCC->APB1ENR|=1<<0; //TIM2时钟使能 RCC->APB2ENR|=1<<2; //使能PORTA时钟 GPIOA->CRL &= 0XFFFFFF0F; //GPIOA->CRL |= 0X00000080;

K60的DMA多路脉冲计数

最近在做飞思卡尔的智能车,由于要用到两路脉冲计数,但是由于K60只有3个FTM, 一个分给电机,一个分给舵机,另一个用于正交解码. 所以FTM用不到了,只能另行办法.LPT虽然也可以计数,但是却只能计数一路而已,后来上网查了一下,发现可以用DMA来实现多路脉冲计数. 但是由于不知道DMA的触发的方式是以PORT的,所以我选择用了PTA25和PTA27来触发DMA,结果发现,能测出来一路脉冲数是正确的,另一路却是刚才那路的两倍.经过百度查了好多资料,折腾了1天半,还是没找出来错误.于是不小心点开了

[芯片] 2、接口技术&#183;实验二&#183;定时/计数器8253

目录 一.实验目的和要求 二.实验原理与背景 三.实验具体的内容 3-1.计数器方式0实验 3-2.计数器方式3实验 3-3.计数器级联实验 四.实验的代码说明 4-1.计数器方式0实验代码及说明 4-2.计数器方式3实验代码及说明 4-3.计数器级联实验代码及说明 五.实验结果的分析 5-1.计数方式0实验分析 5-2.计数方式3实验分析 5-3.级联方式实验分析 附录资料 一.实验目的和要求 学会8253芯片和微机接口原理和方法. 掌握8253定时\计数芯片的基本工作原理.工作方式和编程原理

stm32寄存器版学习笔记06 输入捕获(ETR脉冲计数)

STM32外部脉冲ETR引脚:TIM1-->PA12;TIMER2-->PA0:TIMER3-->PD2;TIMER4-->PE0… 1.TIM2 PA0计数 配置步骤 ①开启TIM2时钟,配置PA0输入 APB1外设复位寄存器 (RCC_APB1RSTR) APB2外设时钟使能寄存器(RCC_APB2ENR) 置1开启.清0关闭. Eg:RCC->APB1ENR|=1<<0; //使能TIM2时钟  RCC->APB2ENR|=1<<2;  

单片机应用编程技巧问答

1. C语言和汇编语言在开发单片机时各有哪些优缺点? 答:汇编语言是一种用文字助记符来表示机器指令的符号语言,是最接近机器码的一种语言.其主要优点是占用资源少.程序执行效率高.但是不同的CPU,其汇编语言可能有所差异,所以不易移植. C语言是一种结构化的高级语言.其优点是可读性好,移植容易,是普遍使用的一种计算机语言.缺点是占用资源较多,执行效率没有汇编高. 对于目前普遍使用的RISC架构的8bit MCU来说,其内部ROM.RAM.STACK等资源都有限,如果使用C语言编写,一条C语言指令编译

[学习笔记]15个QA让你快速入门51单片机开发

一.C语言相关... 1 Q1:sbit与sfr代表是什么?有什么作用?... 1 Q2:#define OSC_FREQ  22118400L这句宏命令里的“L”是什么意思?... 1 Q3:我粘贴了别人的代码,怎么发现没有unit这个类型?... 1 Q4:为什么好多变量都是char类型?它不是字符类型吗?怎么可以用来计数?    1 Q4.1:51单片机中的char,int,long,float,double各占多少个字节,取值范围多大?    1 Q5:unsigned char dat

单片机定时/计数工作方式

单片机中的定时/计数器都能有多种用途,要通过定时/计数器的方式控制字来设置,需要的用途. 在单片机中有两个特殊功能寄存器与定时/计数有关,这就是TMOD和TCON.,TMOD和TCON是名称,我们在写程序时就能直接用这个名称来指定它们,当然也能直接用它们的地址89H和88H来指定它们(其实用名称也就是直接用地址,汇编软件帮你翻译一下而已).     TMOD被分成两部份,每部份4位.分别用于控制T1和T0.TCON也被分成两部份,高4位用于定时/计数器,低4位则用于中断(TF1.0在这).TR0

单片机计数脉冲

#include <pic.h> __CONFIG(0x3004);//(0X30C4); #define T0_40MS 100    // 定义 TMR0 延时10MS 的时间常数 #define T1_100MS 40536 #define        DN                        RA5        //Motor rise                 2        DN #define        UP