分类:
2007-04-10 01:18:34
l 前言
本文介绍了PXA270 OS Timer模块的基本工作方式与编程模型,适合新手快速了解该模块的基本配置与使用。
【血的教训】
本教训来源于笔者编写和调试一个简单的定时器中断程序。程序运行以及调试症状是:可以进入相应的定时器中断服务程序,但是进入中断服务程序之后就无法跳出并返回,而是反复不停地执行中断服务程序中的指令。
根本原因在于无法跳出中断服务程序。原因很可能就在于中断标志没有清除导致一跳出中断随即又进入中断的状态。经细读Manual的相关部分,发现在匹配发生时OSSR置位并进入中断后,并不自动清零,需要软件来清除标志位。于是在中断服务程序中对OSSR寄存器写“0”来进行清除,结果发现还是无法跳出中断——百思不得其解,再次研读Manual时,发现清除OSSR是对相应位进行写“1”而非写“0”来完成的,而写“0”不会有任何效果。修正之后,一切正常。
教训:对Manual的一些细节不能忽略,对寄存器的操作也不可想当然马虎行事。在PXA270的外围控制器中,还有相当一部分寄存器也是通过写“1”来清除的;其他一些处理器芯片也有类似的寄存器控制方式。因此,是需要引起注意的。
另:如果你已对OS Timer相当了解,而且也没有该“血的教训”,则本文对你没有任何参考价值。
l PXA270 OS Timer简述
OS Timer一共提供12个定时器通道,允许软件产生定时中断。这12个通道定时器分为两组,前4个通道共用1个计数器,分别使用4个匹配寄存器,对3.25MHz时钟进行计数,该组定时器与PXA255的编程模式兼容,通道3可用作看门狗。另外一套则提供8个计数器和8个匹配寄存器,计数时钟由32.768KHz或13MHz或外部时钟产生;并且可以作为唤醒中断源。
l PXA255兼容定时器
该定时器的工作方式比较简单,只需要使用OIER、OSCR0、OSMRx和OSSR四个寄存器即可完成操作(用作看门狗时还需使用OWER)。
该定时器只能对3.25MHz时钟计数,四通道共用一个OSCR0。
首先要初始化定时器通道,即使用OIER寄存器使能相应的定时器通道,并在OSCR0设置计数初值,另外在相应通道的OSMRx中设置匹配数值(在初始化时也可以清除OSSR的相应位)。
每个时钟上升沿到来时,OSCR0就加1,并与OSMRx进行比较,如果发生匹配(两者相等),则停止计数,同时在OSSR中置位相应的位,并触发相应的中断(IRQ或FIQ中断,因此使用定时器时要首先在中断控制器中设置定时器中断类型并且使能相应中断),进入中断服务程序。
【中断服务程序】
OSSR用于在中断服务程序中判断是哪个定时器通道发生匹配所导致的中断,从而进行不同的中断服务。在退出中断服务程序前,必须清除OSSR的相应位(否则会一直触发中断不断进入中断服务程序,相当于在中断服务子程序的顶层加了一个while(1)循环)。
[注意]
(1)清除OSSR的某一位是通过对其写“1”来实现的,若对其写“0”则没有效果。
(2)该定时器是periodic型的,即发生匹配后,定时器继续对时钟计数。
l 定时器通道4-11
PXA270提供的定时器通道4-11的功能更为强大,操作也更为复杂。PXA270还专门为此给OS Timer模块提供了4个信号引脚,可支持外部同步,并且可产生时钟输出(通道10/11)。
该组定时器通道的基本工作方式和原理与通道0-3一致,只是提供更多的功能以及相应的寄存器控制。这些功能通过OMCRx设置,包括:
(1)可设置计数分辨率,选择多种计数时钟频率,最高计数精度为1us。
(2)可设置为periodic或non-periodic型定时器通道(匹配后继续计数或停止计数)。
(3)可用外部信号进行同步。
(4)可设置匹配时清零OSCRx。
(5)可为通道组定时器选择匹配的OSCRx(即OSMRm并非一定要与OSCRm进行匹配,也可设置为与通道组某一OSCRx进行匹配;例如OMCR5中可设置为通道5的OSMR5与自身的OSCR5匹配还是与通道组中的OSCR4进行匹配)。
(6)通道9/11可工作于Snapshot模式(快照模式)。
(7)通道10/11可通过CHOUT<0:1>进行时钟输出。
【说明】
(1)通道8-11有9个计数时钟可选,因此在OMCRx中需要4个bits来选择;
(2)易理解;
(3)外部同步信号通过EXT_SYNC<1:0>输入,可设置为是否进行外部同步以及选择那个外部同步信号。如果进行外部同步,则在外部同步信号的上升沿会复位相应通道计数寄存器OSCRx,重新开始计数。注意,外部同步信号传送到OS Timer模块需要两个计数时钟周期的延时(具体示例时序图参考Developer’s Manual)。
(4)易理解;
(5)、(6)主要方便多个定时器通道间的协同工作。设置为Snapshot模式时,读OSCR9/11的同时将OSCR8/11的值捕捉到寄存器OSNR中。
(7)详见Developer’s Manual。
l 附录(Counter Resolutions)
OS timer中每个计数器寄存器的计数精度/分辨率如下:
1.计数器0寄存器的时钟来源
OSCR0计数器寄存器总是在3.25-MHz时钟的上升沿加一。该时钟是在通道访问/控制模块中通过对13-MHz输入时钟(CLK_13M)进行四分频产生的。
2.通道4-11的时钟来源
OSCR7:4这四个计数器的计数时钟可分别设置为如下频率:
² 32.768kHz——直接使用32.768kHz时钟;
² 1kHz(1ms)——该时钟由32.768kHz时钟产生,因此周期并不精确等于1ms;
² 1Hz(1s)——该时钟也由32.768kHz时钟产生,同理不能精确;
² 1MHz(1us)——该时钟由13-MHz时钟产生;
² 外部时钟CLK_EXT输入。
对于通道8-11还有:
² 来自SSP1/2/3的帧检测信号;
² 1kHz(1ms)——UDC的帧起始信号。
【参考资料】《Intel PXA27x Processor Family Developer’s Manual》
【注】纰漏之处,恳请指正。转载请注明作者及出处。
chinaunix网友2008-01-24 16:58:59
最近我写了个pxa270定时器的中断驱动,使用定时器timer4时能中断返回,而类似的timer5~7却不能进中断:方法分别如下: TIMER4: OIER &= ~(1<<4); //Timer4 disable OSSR |= 1<<4; //clear Timer4 interrupt OSMR4 = timer.timer_interval; //value time OSCR4 = 0; //Timer4 count clear. OMCR4 = (3<<6) |(1<<3) | (1<<2); // us OIER |= 1<<4; //Timer4 enable TIMER5: OIER &= ~(1<<5); //Timer5 disable OSSR |= 1<<5; //clear Timer5 interrupt OSMR5 = timer.timer_interval; //value time OSCR5 = 0; //Timer4 count clear. OMCR5 = (3<<6) |(1<<3) | (1<<2); //