[原创] LM3S811定时器输入捕捉功能分析与应用

blackwc2006   2011-5-19 22:57 楼主
LM3S系列单片机的定时器模块一共有三种工作模式:
(1)定时器模式
(2)输入捕捉模式
(3)PWM模式

这里主要研究一下输入捕捉功能。

定时器的输入捕捉模式是用来捕捉外部事件发生的时间或者对外部事件进行计数。
当定时器工作于输入捕捉模式时,定时器被配置为16Bit减计数工作方式,预分频寄存器在这里将不起作用。

所谓“输入捕捉”包括两部分,“输入”和“捕捉”
“输入”指要有外部信号输入,有输入信号就需要引脚,可以作为外部信号输入的引脚如下图:
1.JPG
2.JPG

“捕捉”就是捕捉外部事件,这些外部事件可以是
(1)输入信号的上升沿
(2)输入信号的下降沿
(3)输入信号的双边沿

在16bit输入捕捉模式下,定时器又有两种工作方式:
3.JPG

1、边沿计数方式:
    在边沿计数方式下,定时器会对外部事件进行计数。工作过程如下
    (1)、定时器装载
    (2)、使能定时器
    (3)、每输入一个要捕捉的事件定时器计数值减一
    (4)、若计数值与匹配寄存器的值相等,则停止计数(禁能定时器),并产生中断。

配置实例:
将Timer1A设为输入捕捉模式对外部信号的上升沿进行计数
//Timer1A对应CCP2,对应的外部引脚是PD5,将PD5配置为CCP引脚
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD);
GPIOPinTypeTimer(GPIO_PORTD_BASE,GPIO_PIN_5);
//配置Timer1A
SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER1);
TimerConfigure(TIMER1_BASE,TIMER_CFG_16_BIT_PAIR|TIMER_CFG_A_CAP_COUNT);  //将Timer1A设为输入计数工作方式
TimerLoadSet(TIMER1_BASE,TIMER_A,10000);           //设置装载寄存器的值
TimerMatchSet(TIMER1_BASE,TIMER_A,2000);           //设置匹配寄存器的值
TimerControlEvent(TIMER1_BASE,TIMER_A,TIMER_EVENT_POS_EDGE);    //配置Timer1A捕捉上升沿
//使能中断
TimerIntEnable(TIMER1_BASE,TIMER_TIMA_TIMEOUT|TIMER_CAPA_MATCH);   //使能匹配中断
IntEnable(INT_TIMER1A);
IntMasterEnable();
TimerEnable(TIMER1_BASE,TIMER_A);         //使能Timer1A

在这个配置例子中,Timer1A将从10000开始减计数,每当PD5输入一个上升沿,Timer1A计数值减一。
当Timer1A的计数值等于2000时,Timer1A将被禁能,同时产生中断。只有再次调用TimerEnable()使能Timer1A才能让定时器继续工作。

边沿计数方式还有另一种使用方法:
这种使用方法在数据手册中没有提及
我们可以向匹配寄存器中写入一个比装载寄存器大的值,这样就会导致计数值永远不会等于匹配寄存器的值,匹配中断永远不会发生。
于是定时器就会一直对外部事件计数,当计数器溢出时会将溢出标志位置位,重新装载,然后继续计数。除非调用TimerDisable()函数禁能定时器计数才会停止。

配置实例
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD);
GPIOPinTypeTimer(GPIO_PORTD_BASE,GPIO_PIN_5);
//配置Timer1A
SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER1);
TimerConfigure(TIMER1_BASE,TIMER_CFG_16_BIT_PAIR|TIMER_CFG_A_CAP_COUNT);  //将Timer1A设为输入计数工作方式
TimerLoadSet(TIMER1_BASE,TIMER_A,10000);           //设置装载寄存器的值
TimerMatchSet(TIMER1_BASE,TIMER_A,10001);           //设置匹配寄存器的值
TimerControlEvent(TIMER1_BASE,TIMER_A,TIMER_EVENT_POS_EDGE);    //配置Timer1A捕捉上升沿
//使能中断
TimerIntEnable(TIMER1_BASE,TIMER_TIMA_TIMEOUT|TIMER_TIMA_TIMEOUT);   //使能溢出中断
IntEnable(INT_TIMER1A);
IntMasterEnable();
TimerEnable(TIMER1_BASE,TIMER_A);         //使能Timer1A

这里Timer1A会对外部事件循环计数,每当定时器溢出产生溢出中断。

2、边沿定时方式:
在边沿定时工作方式下,定时器以系统时钟频率进行减计数,定时器溢出后会重新装载定时器并继续减计数。
当输入一个外部事件后,定时器会将外部事件发生时刻定时器的值复制到GPTMTnR中并产生中断信号,此时可以通过TimerValueGet函数读取该值。

配置实例:
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD);
GPIOPinTypeTimer(GPIO_PORTD_BASE,GPIO_PIN_5);
//配置Timer1A
SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER1);
TimerConfigure(TIMER1_BASE,TIMER_CFG_16_BIT_PAIR|TIMER_CFG_A_CAP_TIME);  //将Timer1A设为输入计数工作方式
TimerLoadSet(TIMER1_BASE,TIMER_A,60000);           //设置装载寄存器的值
TimerControlEvent(TIMER1_BASE,TIMER_A,TIMER_EVENT_POS_EDGE);    //配置Timer1A捕捉上升沿
//使能中断
TimerIntEnable(TIMER1_BASE,TIMER_TIMA_TIMEOUT|TIMER_CAPA_EVENT);   //使能输入事件中断
IntEnable(INT_TIMER1A);
IntMasterEnable();
TimerEnable(TIMER1_BASE,TIMER_A);         //使能Timer1A


下面是输入捕捉模式的注意事项,摘自英文版的数据手册,在中文版数据手册里没有提及
4.JPG
大意是:
1、对于上升沿检测,输入信号在上升沿后必须保持高电平至少两个系统时钟周期。类似的,对于下降沿检测,输入信号在下降沿后必须保持低电平至少两个系统时钟周期。基于以上原则,边沿检测的最大输入信号频率是1/4系统时钟。
2、预分频器在输入捕捉模式下不可用。


——————————分割线——————————


是芯片就难免有Bug,LM3S811的定时器在输入捕捉模式下就有两个Bug。
5.JPG
上图为811的勘误表节选。
第一个Bug:在边沿计数(Edge Count mode)工作方式下,如果禁能了Timer,计数值会被错误的减一。
也就是说,如果我们在程序中主动调用TimerDisable函数禁能定时器,用TimerValueGet得到的值是准确值-1。
解决方案:软件禁能定时器后,在再次启动定时器前应将定时器装载为当前计数值+1。

第二个Bug:在边沿计数(Edge Count mode)工作方式下,按照数据手册的说法,当定时器的计数值与匹配寄存器的值相等后,定时器会被禁能并且重新装载。但实际情况是定时器不会自动装载。
解决方案:在下次启用该定时器是应重新装载定时器(用TimerLoadSet函数)


定时器输入捕捉功能的一个应用就是测频,下面这个程序将811配置成一个频率计
测频.rar (141.9 KB)
(下载次数: 225, 2011-5-19 22:57 上传)

输入信号:1Hz~24MHz,0V-3.3V方波
信号输入引脚:PD5
测频原理:

对于高频信号,测量一定时间内输入信号上升沿个数。
对于低频信号,测量两个上升沿事件的时间。
测量结果通过串口打印

程序大致流程:
(1)初始化外设:UART0,Timer0,Timer1(Timer0用来定时,Timer1用来输入捕捉)
(2)用Timer0定时200ms,同时Timer1对输入信号上升沿进行计数
(3)若(2)中计数值小于2000,转(5)
(4)若(2)中计数值大于2000,转(6)
(5)测量两个信号上升沿的间隔时间,将计算出的频率值通过串口打印,转(7)
(6)计数值乘5即为频率值,打印
(7)延时0.5s,转(2)

[ 本帖最后由 blackwc2006 于 2011-5-19 22:58 编辑 ]

回复评论 (7)

哈哈 不错不错 支持
点赞  2011-5-20 07:58
顶顶嘿嘿
点赞  2011-5-20 09:29

1Hz~24MHz能到达到?

边沿检测的最大输入信号频率是1/4系统时钟,系统为50M,那么测周期时为沿检查,最大输入信号频率是1/4系统时钟,达不到24M,最大为50M/4?

 

点赞  2011-6-13 07:32
问题同上
点赞  2012-2-20 17:22
mark
点赞  2012-3-4 10:01
楼主太棒了
点赞  2014-3-27 16:55
顶!
点赞  2014-8-5 13:21
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复