最近在学习TI LM3S8962的通用定时器模块, 通过查找资料知道在 Stellaris 系列 ARM 内部通常集成有 2~4 个通用定时器模块(General-Purpose Timer Module,GPTM) ,分别称为 Timer0、Timer1、Timer2 和 Timer3。它们的用法是相同的:每个 Timer 模块都可以配置为一个 32 位定时器或一个 32 位 RTC 定时器;也可以拆分为两个16 位的定时/计数器 TimerA 和 TimerB,它们可以被配置为独立运行的定时器、事件计数器或 PWM。
Timer 模块具有非常丰富的功能:
1. 32 位定时器模式:
可编程单次触发(one-shot)定时器
可编程周期(periodic)定时器
实时时钟 RTC(Real Time Clock)
软件可控的事件暂停(用于单步调试时暂停计数,RTC 模式除外)
2. 16 位定时器模式:
带 8 位预分频器的通用定时器功能
可编程单次触发(one-shot)定时器
可编程周期(periodic)定时器
软件可控的事件暂停
3. 16 位输入捕获模式:
输入边沿计数捕获
输入边沿定时捕获
4. 16 位 PWM 模式:
用法简单的 PWM(Pulse-Width Modulation,脉宽调制)模式
可通过软件实现 PWM 信号周期、占空比、输出反相等的控制
我在想是否可以通过16位输入捕获模式:输入边沿计数捕获功能来检测编码器脉冲来实现测速,通过测试还真的可行,只是精度不是很高。下面贴上程序
#include "systemInit.h"
#define PART_LM3S8962
#include
void timerInitCapCOUnt(void)
{
SysCtlPeripheralEnable(CCP0_PERIPH);
SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER0);
GPIOPinTypeTimer(CCP1_PORT,CCP1_PIN);
TimerConfigure(TIMER0_BASE,TIMER_CFG_16_BIT_PAIR|TIMER_CFG_B_CAP_COUNT);
TimerControlEvent(TIMER0_BASE,TIMER_B,TIMER_EVENT_NEG_EDGE);
TimerLoadSet(TIMER0_BASE,TIMER_B,0xFFFF);
TimerMatchSet(TIMER0_BASE,TIMER_B,0);
// TimerControlStall(TIMER0_BASE,TIMER_B,true);
TimerIntEnable(TIMER0_BASE,TIMER_CAPB_EVENT);
IntEnable(INT_TIMER0B);
IntMasterEnable();
TimerEnable(TIMER0_BASE,TIMER_B);
}
void TIMER0B_ISR(void)
{
unsigned long ulStatus;
ulStatus = TimerIntStatus(TIMER0_BASE,true);
TimerIntClear(TIMER0_BASE,ulStatus);
/* if (ulStatus & TIMER_CAPB_EVENT) // 若是 TimerA 事件捕获中断
{
CAP_Flag = true; // 置位捕获标志
}
*/
if (ulStatus == TIMER_CAPB_MATCH)
{
Led_Toggle(2);
}
}
volatile unsigned long ulVal;
// SysTick计数器的中断服务函数
void SysTick_ISR(void)
{
Led_Toggle(3);
TimerDisable(TIMER0_BASE, TIMER_B); // 禁止 Timer 计数
ulVal =100 * (0xFFFF - TimerValueGet(TIMER0_BASE, TIMER_B));
TimerLoadSet(TIMER0_BASE,TIMER_B,0xFFFF);
TimerEnable(TIMER0_BASE,TIMER_B);
}
// 主函数(程序入口)
int main(void)
{
jtagWait(); // 防止JTAG失效,重要!
clockInit(); // 时钟初始化:晶振,6MHz
timerInitCapCOUnt();
SysTickPeriodSet(60000UL); // 设置SysTick计数器的周期值
SysTickIntEnable(); // 使能SysTick中断
IntMasterEnable(); // 使能处理器中断
SysTickEnable();
while(1)
{
}
}