
RT1052的PIT定时器
最后得到的效果是这样的,没做啥,就验证是否进入了中断。
发布日期:2021-05-07 22:29:20
浏览次数:19
分类:精选文章
本文共 2579 字,大约阅读时间需要 8 分钟。
开发平台
- Board:野火RT1052-MINI
- IDE:Keil 5.28
关于PIT
PIT定时器(Periodic Interrupt Timer),也叫做周期性中断定时器(反正我是这么翻译的),是一个32位递减计数器,每个时钟周期减1。与普通的定时器相比,它只能递减计数,而不能向上计数,普通的定时器,相对高级一点的能向上或者向下计数,甚至再高级一点的可以产生pwm等等。而它就只能周期计数。但是不要小看它,它最大的作用就是为其它外设提供周期信号。这听起来像废话,普通定时器不行吗?当然行,但是普通定时器需要重启计数器才能改变计数周期,而PIT定时器可以不需要重新启动(其实就是重新初始化)就可以改变计数周期。典型的应用就是PIT+ADC,ADC周期性采集255(或者更大)的信号数据,通过FFT(快速傅里叶变换)处理,得到一段新的信号,这是很常见的,特别是做混合信号处理的时候。
描述一下特性吧:- 支持生成中断并且可以独立设置启用或屏蔽。
- 共享一个中断号(IRQ,别的Kinetis系列貌似没有,在1052上共用)。
- 具有相同的计数时钟。
- 可以独立设置计数器的计数值、启动和停止。
- 32 位递减计数,除定时器 0(四个定时器是 0 到 3),其他定时器可以设置为定 时器连接模式,组成一个 64 位定时器。
- 无需重新启动计时器即可更改计数器周期
PIT的SDK配置
步入正题,用SDK配置PIT:
首先初始化pit,记得添加对应的.c和.h文件,代码如下:
void Pit_init(uint8_t PIT_CHn,uint32_t reload){ pit_config_t config; pit_chnl_t channel; if(PIT_CHn==0) channel = kPIT_Chnl_0; else if(PIT_CHn==1) channel = kPIT_Chnl_1; else if(PIT_CHn==2) channel = kPIT_Chnl_2; else if(PIT_CHn==3) channel = kPIT_Chnl_3; /* PIT时钟配置 */ CLOCK_SetMux(kCLOCK_PerclkMux,1U); CLOCK_SetDiv(kCLOCK_PerclkDiv,0U); PIT_GetDefaultConfig(&config); config.enableRunInDebug = true; PIT_Init(PIT, &config); /* 设置PIT定时器通道0自动重装载值 */ PIT_SetTimerPeriod(PIT,channel,USEC_TO_COUNT(reload, PIT_SOURCE_CLOCK)); /* 清除通道0的中断标志位 */ PIT_ClearStatusFlags(PIT,channel,kPIT_TimerFlag); /* 使能通道0的计时完成中断 */ PIT_EnableInterrupts(PIT, channel, kPIT_TimerInterruptEnable); //Set_NVIC_PriorityGroup(Group_4); //Set_IRQn_Priority(PIT_IRQn,Group4_PreemptPriority_6, Group4_SubPriority_0); PIT_NVIC_Config(); /* 使能中断 */ EnableIRQ(PIT_IRQn); if(PIT_CHn==0) PIT_StartTimer(PIT,kPIT_Chnl_0); else if(PIT_CHn==1) PIT_StartTimer(PIT,kPIT_Chnl_1); else if(PIT_CHn==2) PIT_StartTimer(PIT,kPIT_Chnl_2); else if(PIT_CHn==3) PIT_StartTimer(PIT,kPIT_Chnl_3);}
为了方便,写成通用型的了。
初始化之前,需要写好中断配置:
static void PIT_NVIC_Config(void){ uint32_t Priority_Encode = 0; NVIC_SetPriorityGrouping(0x04); Priority_Encode = NVIC_EncodePriority (0x04, 0x06, 0x00);//得到中断优先级编码 NVIC_SetPriority(PIT_IRQn,Priority_Encode);}
然后编写对应的中断服务函数:
void PIT_IRQHandler(void){ if(PIT_GetStatusFlags(PIT, kPIT_Chnl_0)) { /* 清除中断标志位 */ PIT_ClearStatusFlags(PIT, kPIT_Chnl_0, kPIT_TimerFlag); PRINTF("进入PIT_CH0\n"); } else if(PIT_GetStatusFlags(PIT, kPIT_Chnl_1)) { /* 清除中断标志位 */ PIT_ClearStatusFlags(PIT, kPIT_Chnl_1, kPIT_TimerFlag); PRINTF("进入PIT_CH1\n"); }}
我这里只用了两个通道的PIT定时器,所以在中断中只做了两次判断。

发表评论
最新留言
第一次来,支持一个
[***.219.124.196]2025年04月12日 09时47分04秒
关于作者

喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
图解哈希表及其原理
2019-03-06
Head First设计模式——迭代器模式
2019-03-06
MongoDB版本及存储引擎区别
2019-03-06
shell echo单行和多行文字定向写入到文件中
2019-03-06
AtCoder Beginner Contest 100 题解
2019-03-06
【数据结构】可持久化线段树初步
2019-03-06
后缀树
2019-03-06
Java高性能编程之CAS与ABA及解决方法
2019-03-06
从BIO到Netty的演变
2019-03-06
《算法导论》第二章笔记
2019-03-06
HTML节点操作
2019-03-06
浏览器页面呈现过程
2019-03-06
HTML5新特性
2019-03-06
async/await剖析
2019-03-06
cmp命令
2019-03-06
一次编辑
2019-03-06
代理模式
2019-03-06
长按键入
2019-03-06
JavaScript中的链式调用
2019-03-06
day-04-列表
2019-03-06