SCTimer/PWM定时器

在LPC824中,除了常用的多速率定时器MRT之外,还有一个非常有特色的定时器SCTimer/PWM。它不仅是一个定时器,还是一个状态机和事件发生器。SCTimer/PWM是NXP特有的定时器,下面就来详细讨论一下。

SCTimer/PWM定时器所涉及到的寄存器有点多,一共有75个,具体如下表所示。

未标题-1

在MDK环境中,针对以上SCT寄存器,定义了如下的结构体。

typedef struct {
__IO uint32_t CONFIG;
__IO uint32_t CTRL;
__IO uint32_t LIMIT;
__IO uint32_t HALT;
__IO uint32_t STOP;
__IO uint32_t START;
__I uint32_t RESERVED0[10];
__IO uint32_t COUNT;
__IO uint32_t STATE;
__I uint32_t INPUT;
__IO uint32_t REGMODE;
__IO uint32_t OUTPUT;
__IO uint32_t OUTPUTDIRCTRL;
__IO uint32_t RES;
__IO uint32_t DMAREQ0;
__IO uint32_t DMAREQ1;
__I uint32_t RESERVED1[35];
__IO uint32_t EVEN;
__IO uint32_t EVFLAG;
__IO uint32_t CONEN;
__IO uint32_t CONFLAG;
union {
__IO uint32_t CAP0;
__IO uint32_t MATCH0;
};
union {
__IO uint32_t CAP1;
__IO uint32_t MATCH1;
};
union {
__IO uint32_t CAP2;
__IO uint32_t MATCH2;
};
union {
__IO uint32_t MATCH3;
__IO uint32_t CAP3;
};
union {
__IO uint32_t CAP4;
__IO uint32_t MATCH4;
};
union {
__IO uint32_t MATCH5;
__IO uint32_t CAP5;
};
union {
__IO uint32_t CAP6;
__IO uint32_t MATCH6;
};
union {
__IO uint32_t CAP7;
__IO uint32_t MATCH7;
};
__I uint32_t RESERVED2[56];
union {
__IO uint32_t CAPCTRL0;
__IO uint32_t MATCHREL0;
};
union {
__IO uint32_t CAPCTRL1;
__IO uint32_t MATCHREL1;
};
union {
__IO uint32_t CAPCTRL2;
__IO uint32_t MATCHREL2;
};
union {
__IO uint32_t MATCHREL3;
__IO uint32_t CAPCTRL3;
};
union {
__IO uint32_t CAPCTRL4;
__IO uint32_t MATCHREL4;
};
union {
__IO uint32_t CAPCTRL5;
__IO uint32_t MATCHREL5;
};
union {
__IO uint32_t CAPCTRL6;
__IO uint32_t MATCHREL6;
};
union {
__IO uint32_t CAPCTRL7;
__IO uint32_t MATCHREL7;
};
__I uint32_t RESERVED3[56];
__IO uint32_t EV0_STATE;
__IO uint32_t EV0_CTRL;
__IO uint32_t EV1_STATE;
__IO uint32_t EV1_CTRL;
__IO uint32_t EV2_STATE;
__IO uint32_t EV2_CTRL;
__IO uint32_t EV3_STATE;
__IO uint32_t EV3_CTRL;
__IO uint32_t EV4_STATE;
__IO uint32_t EV4_CTRL;
__IO uint32_t EV5_STATE;
__IO uint32_t EV5_CTRL;
__IO uint32_t EV6_STATE;
__IO uint32_t EV6_CTRL;
__IO uint32_t EV7_STATE;
__IO uint32_t EV7_CTRL;
__I uint32_t RESERVED4[112];
__IO uint32_t OUT0_SET;
__IO uint32_t OUT0_CLR;
__IO uint32_t OUT1_SET;
__IO uint32_t OUT1_CLR;
__IO uint32_t OUT2_SET;
__IO uint32_t OUT2_CLR;
__IO uint32_t OUT3_SET;
__IO uint32_t OUT3_CLR;
__IO uint32_t OUT4_SET;
__IO uint32_t OUT4_CLR;
__IO uint32_t OUT5_SET;
__IO uint32_t OUT5_CLR;
} LPC_SCT_Type;

SCT定时器组的基址为0x50004000,所以要将基址指针强制转换为上述结构体,还要加上下面的定义。
#define LPC_SCT_BASE 0x50004000UL
#define LPC_SCT ((LPC_SCT_Type *) LPC_SCT_BASE)

在上述结构体中,并没有把上表中的全部75个寄存器都进行定义。这是因为在SCTimer/PWM定时器中,可以把它设置成一个32位或两个16位的两种工作模式。而在MDK开发环境所提供的的结构体定义中,只定义了32位模式的寄存器。观察上表中的寄存器名称及其地址偏移可以发现,其实在16位模式下,只不过是把原来32位的寄存器分成高低两个16位的寄存器来用而已,其本质并没有改变。所以在表中分别对拆分后的两个寄存器都进行了命名,并且其名称其实就是在原寄存器名称的基础上,分别加H和L的后缀来表示高、低位的两个寄存器而已。进一步观察可看到,其实后缀为L的寄存器与原寄存器的地址是完全一样的,而后缀为H的寄存器地址只与原寄存器的地址偏移了两个字节(16位)而已。所以在MDK中,若要操作16位方式的寄存器,完全可以通过对原寄存器进行高低16位分开的写入方式来进行,并不困难。

下面就一一对上述寄存器进行讨论(只讨论32位的原寄存器)。先来看SCT配置寄存器CONFIG,其字节地址为0x50004000,下表给出了它的全部位结构。

未标题-2

该寄存器用于配置SCT的整体操作,要在配置其他寄存器之前配置该寄存器(即最先配置)。该寄存器只允许以字的形式写入,任何尝试写入半字数值将会导致总线错误。

下面是SCT控制寄存器CTRL,其字节地址为0x50004004,下表给出了它的全部位结构。

未标题-3

从上表中可见,该寄存器分为高低16位两部分进行配置,如果CONFIG寄存器中的UNIFY位为1,则仅使用_L位来配置整个统一的SCT,如果CONFIG寄存器中的UNIFY位为0,则该寄存器会被作为两个寄存器CTRL_L和CTRL_H来配置。L和H寄存器都可单独执行读或写操作,也可在单一的32位读或写操作中进行读写(注:在LPC824中所有具备高低16位配置的寄存器都具有此属性,为避免重复,后面就不再对每一个寄存器阐述此属性了)。

上述CTRL寄存器在计数器处于停止(STOP)或终止(HALT)状态时,才可以配置该寄存器的所有位。当计数器处于运行状态时,唯一能够被写入的只有STOP或HALT位。如果SCTimer/PWM做为两个16位计数器运行,则只有在两个计数器都不处于终止状态时才能更改输出状态。

下面是SCT限值事件选择寄存器LIMIT,其字节地址为0x50004008,下表给出了它的全部位结构。

未标题-4

正在运行的计数器会受事件的限制,当该寄存器中选定的事件发生时,计数器会清零或者改变计数方向(双向模式)。寄存器的每个位都关联一个事件(如位0为事件0……等等),设置一个位会导致其关联的事件被当做限制事件(LIMIT事件)。当出现任何限制事件时,计数器会复位到0(单向模式)或改变其计数方向(双向模式)。注意,当计数器向上计数到全1或向下递减至0时,始终相当于发生了一个限制事件。有关限定实际的限制事件(匹配,I/O引脚切换等),需要参考EVn_CTRL寄存器。另外,若在配置寄存器CONFIG中置位了AUTOLIMIT_L或AUTOLIMIT_H位(使能AUTOLIMIT功能),则只要出现匹配寄存器0匹配的情况(仅限匹配寄存器0),也能够自动引发限制条件(不需要再配置该寄存器来指定限制事件)。

下面是SCT终止事件选择寄存器HALT,其字节地址为0x5000400C,下表给出了它的全部位结构。

未标题-5

正在运行的计数器可能会被事件终止(禁用),当该寄存器中选定的事件发生时,计数器停止运行且禁用所有待发生的事件。寄存器的每个位都关联一个事件(如位0为事件0……等等),设置一个位会导致其关联事件被当做终止事件(HALT事件)。为了限制造成计数器终止的实际事件(匹配,I/O引脚切换等),需要参考EVn_CTRL寄存器。注意,只有当软件清除CTRL寄存器中的HALT位时,才可以移除HALT条件。

下面是SCT停止事件选择寄存器STOP,其字节地址为0x50004010,下表给出了它的全部位结构。

未标题-6

正在运行的计数器可能被事件停止,当该寄存器中选定的事件发生时会停止计数,即计数器停止运行并保持当前值。事件生成保持使能,在START寄存器中选定的任何事件(例如I/O事件)或其他计数器生成的事件都可以重启计数器。该计数器指明了由哪个事件停止计数器,寄存器的每个位都关联一个事件(如位0为事件0……等等),设置一个位会导致其关联事件被当做停止事件(STOP事件)。为了限制造成计数器停止的实际事件(匹配,I/O引脚切换等),需要参考EVn_CTRL寄存器。注意,软件可通过向CTRL寄存器写入来停止和重启计数器。

下面是SCT开始事件选择寄存器START,其字节地址为0x50004014,下表给出了它的全部位结构。

未标题-7

已停止的计数器可能被事件重启,当该寄存器中选定的事件发生时,会从当前计数器数值开始进行计数。寄存器的每个位都关联一个事件(如位0为事件0……等等),设置一个位会导致其关联事件被当做开始事件(START事件)。发生任意开始事件时,硬件会清除控制寄存器CTRL中的STOP位。注意,开始事件不会对HALT位造成影响,只有软件能够移除HALT条件。如要限制启动计数器的实际事件(I/O引脚切换或其他运行计数器在双计数器模式下生成的事件),需要参考EVn_CTRL计数器。

下面是SCT计数器寄存器COUNT,其字节地址为0x50004040,下表给出了它的全部位结构。

未标题-8

如果CONFIG寄存器中的UNIFY位为1,则计数器被作为一个统一的32位寄存器来使用(同时使用_L和_H位)。如果CONFIG寄存器中的UNIFY位为0,则会将该寄存器作为两个寄存器COUNT_L和COUNT_H来使用。另外,只有在计数器终止(CTRL寄存器中的HALT位置位为1)时,才能向 COUNT_L、 COUNT_H或统一寄存器进行写入操作。如果在计数器未终止时尝试对其执行写入操作,会引发总线错误。此外,软件可以随时读取计数器寄存器的值。

下面是SCT状态寄存器STATE,其字节地址为0x50004044,下表给出了它的全部位结构。

未标题-9

状态变量是区分SCTimer/PWM与其他计数器/定时器/PWM模块的主要方式,它仅在特定状态下才产生事件,事件可以执行下列操作:
•置位和清除输出
•限制、停止和启动计数器
•发出中断和DMA请求
•修改状态变量
状态变量值完全在应用程序的控制之下,如果应用程序不使用状态,则状态变量值将保留为零,这也是系统的默认值。

每个使能和禁用的事件组会被分配一个名为状态变量的编号。例如,一个数值为0的状态变量可能使能了事件0、2和3,且禁用了所有其他事件。一个数值为1的状态变量可能使能了事件1、4和5,且禁用了所有其他事件。通过配置EVm_STATE寄存器(在后面),可以具体来限定每组中哪些事件被使能和禁用。

使用状态变量可以跟踪和控制任何所需操作序列中的相关计数器的多个周期,状态变量在逻辑上与代表SCT配置的状态机图相关。状态变量的所有可能值均由包含所有定义事件的EVm_CTRL寄存器(在后面)中的STATELD/STATEV字段设置。在多个计数器周期期间,状态变量的更改反映了相关状态机是如何从一种状态变为另一种状态的。

下面是SCT输入寄存器INPUT,其字节地址为0x50004048,下表给出了它的全部位结构。

未标题-10

AIN位显示了在SCT时钟的每个上升沿上捕获的输入的状态。这相当于近乎直接读取输入,但会引发异步输入信号出现假波动。

SIN位显示了用于检测事件的输入的形式。根据CONFIG寄存器的INSYNC字段所指定的输入内容,可能包括额外的同步阶段:
•如果INSYNC位被设置用于输入,输入会经过三重SCT时钟同步,导致稳定信号延迟3个SCT时钟周期。
•如果INSYNC位未置位,则SIN位值与AIN位值相同。 

下面是SCT匹配/捕获模式寄存器REGMODE,其字节地址为0x5000404C,下表给出了它的全部位结构。

未标题-11

SCT包含有多个匹配/捕获寄存器,他们都是共用地址的,该寄存器就用于选择每个匹配/捕获寄存器具体是用作匹配寄存器(MATCHm)还是捕获寄存器(CAPm)。每个匹配/捕获寄存器都有一个随附寄存器,在将主寄存器用作匹配寄存器时被用作重新载入寄存器(MATCHRELm), 或者在将寄存器用作捕获寄存器时被用作捕获控制寄存器(CAPCTRLm)。只有在UNIFY位等于0时,才会使用REGMODE_H。

下面是SCT输出寄存器OUTPUT,其字节地址为0x50004050,下表给出了它的全部位结构。

未标题-12

在该寄存器中,每个SCT输出都有一个对应的位,使得软件可以直接控制输出状态或读取其当前状态。在计数器运行期间,只能由事件置位、清除或切换输出。然而,通过使用此寄存器,当终止两个计数器来直接控制输出时,软件可以对任何一个输出寄存器执行写入操作。只有当所有计数器(L计数器、H计数器或统一计数器)被终止(CTRL寄存器中的HALT位置位为1)时,才能向OUT寄存器写入。此外,软件可以随时对该寄存器执行读取操作来了解输出状态。 

下面是SCT双向输出控制寄存器OUTPUTDIRCTRL,其字节地址为0x50004054,下表给出了它的全部位结构。

未标题-13

在双向模式下时,该寄存器用于指定(每个输出)计数方向对输出的设置和清除操作含义的影响。使用该寄存器的目的在于简化创建中心对齐输出波形的流程,并消除限制额外事件的需要。

下面是SCT冲突解决寄存器RES,其字节地址为0x50004058,下表给出了它的全部位结构。

未标题-14

如果多个事件(或甚至是相同事件)同时出现,要同时置位和清除给定输出,则该寄存器会指明需要执行哪些操作。如果要使能事件,使之在每次发生时间时切换输出,则应置位OUTn_SET和OUTn_CLR寄存器中与该事件对应的位,并将此寄存器的On_RES值设置为0x3。

下面是SCT的DMA请求寄存器DMAREQ0和DMAREQ1,其字节地址为0x5000405C和0x50004060,下表给出了DMAREQ0的全部位结构(DMAREQ1的可参考)。

未标题-15

SCT包含了两个DMA请求输出,这些寄存器会在发生特定事件、或计数器的匹配寄存器从重新载入寄存器中加载时触发DMA请求。这些寄存器只允许以字的形式写入,任何尝试写入半字数值将会导致总线错误。在SCT控制下启动与其他外设的DMA通信活动时,DMA请求尤其有用。

--待续--

posted @ 2025-11-11 16:03  fxzq  阅读(11)  评论(0)    收藏  举报