4、定时器驱动开发:GPT12模块配置、定时中断产生、用于轮速脉冲捕获的输入捕获模式
好,咱们今天聊点硬核的——定时器驱动。嗯,准确地说,是英飞凌TC2xx系列里那个叫GPT12的模块。
说实话,我最早接触这个模块时,第一反应是“这玩意儿跟通用定时器有啥区别?”后来在项目里被轮速传感器折腾得够呛,才真正体会到它的价值。你想想看,ABS控制器要实时捕捉四个轮子的脉冲信号,每个轮子转速从几赫兹到几千赫兹不等,普通定时器还真不一定扛得住。
4.1 GPT12模块的核心特性
GPT12全称是General Purpose Timer 12,它其实是个“双核”定时器单元——内部包含两个独立的定时器模块:GPT12E和GPT12F。每个模块又各有三个子单元:T2、T3、T4(或者T5、T6、T7)。
我个人习惯把T3/T6当作核心定时器,T2/T4用作捕获/比较通道。为什么这么分?因为T3/T6支持递增/递减计数模式,还能跟其他定时器级联,灵活性最高。
| 子单元 | 位数 | 主要功能 | 典型用途 |
|---|---|---|---|
| T2/T5 | 16位 | 捕获/比较 | 轮速脉冲捕获 |
| T3/T6 | 16位 | 定时器/计数器 | 基础定时中断 |
| T4/T7 | 16位 | 捕获/比较 | PWM生成或附加捕获 |
这里有个关键点:GPT12的时钟源可以独立选择。你可以让T3跑在系统时钟的某个分频上,而T2用外部引脚输入的时钟。这在处理不同速率的轮速信号时特别有用。
4.2 定时中断的产生机制
产生定时中断,说白了就是让计数器从0跑到某个设定值,然后触发中断。但GPT12的玩法比这丰富。
我建议你这样配置T3作为基础定时器:
// 伪代码示例:GPT12 T3定时中断配置
void GPT12_Timer_Init(void)
{
// 1. 使能GPT12模块时钟
GPT12E->CLC.B.DISR = 0; // 使能运行
// 2. 配置T3控制寄存器
GPT12E->T3CON.B.T3R = 0; // 停止定时器
GPT12E->T3CON.B.T3M = 0x0; // 定时器模式(递增计数)
GPT12E->T3CON.B.T3I = 0x5; // 输入分频:fGPT / 32
// 3. 设置重载值(假设系统时钟100MHz,目标中断频率1kHz)
// 分频后时钟 = 100MHz / 32 = 3.125MHz
// 重载值 = 3.125MHz / 1kHz = 3125
GPT12E->T3REL.B.REL = 3125 - 1; // 注意:从0计数到3124
// 4. 加载重载值到计数器
GPT12E->T3CON.B.T3UD = 0; // 递增计数
GPT12E->T3CON.B.T3OE = 0; // 禁止输出
GPT12E->T3CON.B.T3OTL = 0; // 输出电平初始为0
// 5. 使能中断
GPT12E->T3IC.B.T3IE = 1; // 使能T3中断
// 设置中断优先级(根据系统需求)
// 6. 启动定时器
GPT12E->T3CON.B.T3R = 1;
}
嗯,这里要注意:重载值减1这个细节,很多人第一次写会踩坑。因为计数器是从0开始计数的,所以实际计数值是 REL + 1。
4.3 输入捕获模式:轮速脉冲的精准测量
轮速传感器输出的信号,说白了就是一串脉冲。每个脉冲对应齿圈上的一个齿。要算出轮速,你需要知道两个信息:脉冲周期,或者单位时间内的脉冲数。
输入捕获模式就是干这个的。它能在脉冲的上升沿或下降沿,自动把当前定时器的计数值“抓”到捕获寄存器里。整个过程不需要CPU干预,你只需要在中断里读寄存器就行。
我个人习惯用T2的捕获功能来配合T3。T3作为自由运行的定时器,T2负责捕获:
// 伪代码示例:T2输入捕获配置
void GPT12_Capture_Init(void)
{
// 1. 配置T2为捕获模式
GPT12E->T2CON.B.T2M = 0x2; // 捕获模式(上升沿触发)
GPT12E->T2CON.B.T2I = 0x0; // 不分频
// 2. 选择捕获源(连接到轮速传感器引脚)
// 具体引脚映射需要参考芯片数据手册
// 3. 使能捕获中断
GPT12E->T2IC.B.T2IE = 1;
// 4. 启动T2
GPT12E->T2CON.B.T2R = 1;
}
// 捕获中断服务函数
void GPT12_T2_IRQHandler(void)
{
uint16_t captured_value;
// 读取捕获值
captured_value = GPT12E->T2CAPREL.B.CAPREL;
// 计算脉冲周期(需要结合T3的计数值)
// 这里省略具体计算逻辑
// 清除中断标志
GPT12E->T2IC.B.T2IR = 0;
}
4.4 实际项目中的避坑指南
我在项目里遇到过几个典型问题,分享给你:
- 捕获丢失问题:当轮速很高时,脉冲间隔很短。如果中断响应不及时,可能会漏掉捕获事件。我的解决办法是:启用GPT12的“捕获溢出中断”,并配合DMA来搬运数据。
- 时钟同步问题:GPT12的时钟域可能和CPU时钟不同步。在读取捕获值时,建议连续读两次,如果一致再使用。这是经典的“双读校验”技巧。
- 噪声干扰:轮速传感器的信号在低速时特别容易受干扰。我习惯在捕获引脚上加一个简单的硬件滤波(RC低通),同时在软件里做“边沿去抖”——连续两次捕获值相差太小时,直接丢弃。
- GPT12的T3/T6适合做基础定时器,T2/T4/T5/T7适合做捕获
- 定时中断配置时,重载值要减1
- 输入捕获模式下,建议用双读校验确保数据一致性
- 轮速脉冲捕获要处理好高速和低速两种极端情况
好了,关于GPT12的定时器驱动,咱们就聊到这儿。下一章我会讲PWM输出和电机控制,到时候会用到今天说的定时中断和捕获知识。你先把这部分消化一下,有问题随时翻翻数据手册——嗯,那玩意儿虽然厚,但关键章节其实就那么几页。