今日得以继续我的电赛MSP432学习之路:所用开发板MSP432P401R
定时器是任何单片机开发板十分重要的模块,在几日的学习使用过程中,本人也对其使用原理等产生过许多疑问,他究竟是怎么存储计数值、捕获值的?一个定时器四个通道是怎么回事?0~3这四个通道究竟会不会互相影响?当我清零捕获值时,对定时器计数值是否有影响呢?
此文主要讲解这些在MSP432定时器编程方面可能遇到的小疑问,大多是本人在研究过程中产生的,也许会帮助到大家!
一、MSP432一个定时器四个通道互不影响:
先笼统的说:我们可以认为MSP432有四个定时器、16个定时器模块,并且每个定时器都有对应引脚资源可以配置为或是捕获模式,或是PWM输出模式,都互不干扰!
四个定时器通道(TimerA0、TimerA1、TimerA2、TimerA3)可以产生四种不同的定时器溢出中断,即不同的定时频率、定时周期
然后每个定时器都有四个模块,都可以分别配置为捕获或者PWM模式,就是有16个捕获或者PWM模块。
其中,每个定时器的通道0存的基准CCR0是频率基准,决定了每个定时器(TimerA0、TimerA1、TimerA2、TimerA3)的定时周期与频率,不建议更改!
Msp432P401r是一款具有四个定时器通道(TimerA0、TimerA1、TimerA2、TimerA3)的微控制器。这些定时器通道是相互独立的,可以单独配置和使用为不同中断溢出MSP432P401R是Texas Instruments的一款微控制器,它有16个定时器模块。互相之间不会产生影响。
在MSP432微控制器中,定时器0有4个独立的通道(0、1、2、3),它们可以互相独立地配置为捕获或计时模式。
这意味着我们可以单独配置每个通道的功能,它们之间没有直接的相互影响。
每个通道都有自己的寄存器和控制位,我们可以独立设置和访问这些寄存器。
在捕获模式下,每个通道可以用于捕获外部事件的时间戳或脉冲宽度测量。
在计时模式下,每个通道可以用于测量时间间隔或生成定时器中断。
当然今后可能需要注意中断优先级的分配,使得定时器运转程序如我们所愿!
二、每个定时器的通道0与其余通道(1、2、3)具有较大差异:
对于MSP432P401R的定时器通道0与其余通道之间的差别,主要体现在以下几个方面:
1. 功能:
通道0在每个定时器中通常具有更多的功能选项。它经常用作基本定时器,用于产生单个定时脉冲或精确的定时延迟。而通道1、2、3通常用于更复杂的定时事件生成或波形生成,它们支持更多的功能比如捕获、比较等。
2. 寄存器:
每个定时器通道都有自己的一组寄存器,用于配置和控制通道的功能。通道0与其他通道的寄存器可能会有一些差别,例如命名和功能。
3. 输出引脚:
通道0通常具有一个输出引脚,可用于生成定时信号。而通道1、2、3通常没有单独的输出引脚,它们可能需要通过其他引脚或模块来输出定时信号。
三、每个定时器计数值、捕获值分开存储:
MSP432P401R是Texas Instruments的一款微控制器,它有4个定时器、16个定时器模块。
每个定时器都有分别存储的一组捕获值寄存器和一个计数值寄存器。计数计时寄存器数量(4个)取决于定时器数量,捕获值寄存器个数(16个)取决于定时器模块数量。
在MSP432微控制器上配置定时器计数功能时,可以同时选择定时器某个通道配置为捕获模式。
计数计时的时间取决于定时器的时钟源和预分频器设置。
需要选择定时器的时钟源,可以是外部时钟源或内部时钟源(如MCLK或SMCLK)。然后,可以使用预分频器将时钟源的频率分频。根据所选时钟源和预分频器的设置,可以计算出计时周期的时间。
定时器捕获值存储在定时器的捕获寄存器中。
这些寄存器是特定于每个定时器模块的,并且用于存储捕获的计数值。
定时器捕获值通常表示定时器计数器在特定事件(如电平变化或脉冲边沿)发生时的计数值。可以使用这些捕获值来进行时间测量或频率计算等应用。
要计算定时器捕获值,首先需要将捕获的计数值读取到相应的寄存器中。然后,可以使用这个捕获值与其他计数值进行计算,例如计算时间间隔或频率。
四、MSP432的一些基地址宏定义:
1.TIMER_Ax_BASE
#define TIMER_A0_BASE (PERIPH_BASE +0x00000000) /*!< Base address of module TIMER_A0 registers */
#define TIMER_A1_BASE (PERIPH_BASE +0x00000400) /*!< Base address of module TIMER_A1 registers */
#define TIMER_A2_BASE (PERIPH_BASE +0x00000800) /*!< Base address of module TIMER_A2 registers */
#define TIMER_A3_BASE (PERIPH_BASE +0x00000C00) /*!< Base address of module TIMER_A3 registers */
TIMER_Ax_BASE用于访问Timer A模块的寄存器。
以下是使用TIMER_Ax_BASE的一些基本用途
配置Timer A模块:
使用TIMER_Ax_BASE,可以配置Timer A的计时模式、计时器周期、计时器分频器等参数。
启动计时器:
启动Timer A模块以开始计时,您可以使用CCTLn寄存器中的特定位来使能和禁用定时器中断,并使用CTL寄存器的相应位来启动定时器。
处理定时中断:
如果启用了定时器中断,可以编写相应的中断处理函数来处理定时器中断。根据需求而有所不同。
2.TIMER_A_CAPTURECOMPARE_REGISTER_x
//*****************************************************************************
//
// The following are values that can be passed to the compareRegister parameter
//
//*****************************************************************************
#define TIMER_A_CAPTURECOMPARE_REGISTER_0 0x02
#define TIMER_A_CAPTURECOMPARE_REGISTER_1 0x04
#define TIMER_A_CAPTURECOMPARE_REGISTER_2 0x06
#define TIMER_A_CAPTURECOMPARE_REGISTER_3 0x08
#define TIMER_A_CAPTURECOMPARE_REGISTER_4 0x0A
#define TIMER_A_CAPTURECOMPARE_REGISTER_5 0x0C
#define TIMER_A_CAPTURECOMPARE_REGISTER_6 0x0E
//*****************************************************************************
指定定时器模块中的比较寄存器。
这些寄存器可以用于捕获计时器的当前值或与计时器的值进行比较。
在使用TIMER_A_CAPTURECOMPARE_REGISTER_x之前,需要首先初始化定时器模块。
以下是一个使用TIMER_A_CAPTURECOMPARE_REGISTER_x的示例:
1. 设置定时器模块的计数模式、频率和其他参数。
2. 选择一个可用的捕获比较寄存器,如TIMER_A_CAPTURECOMPARE_REGISTER_0。
3. 根据需要,配置比较寄存器的模式,例如捕获模式或比较模式。
4. 配置比较寄存器的相关参数,如计数值或比较模式。
5. 启动定时器模块。
一旦定时器模块启动,就可以使用TIMER_A_CAPTURECOMPARE_REGISTER_x来获取计时器的当前值或与计时器的值进行比较。
具体如何使用TIMER_A_CAPTURECOMPARE_REGISTER_x取决于应用需求,例如可以使用捕获模式来测量外部信号的脉冲宽度,或者使用比较模式来生成定时器中断或输出信号。
需要注意的是,对于每个比较寄存器,需要根据实际使用情况配置适当的中断和计时器操作。
3.TIMER_A_xxx_MODE
//*****************************************************************************
//
// The following are values that can be passed to the timerMode parameter
//
//*****************************************************************************
#define TIMER_A_STOP_MODE TIMER_A_CTL_MC_0
#define TIMER_A_UP_MODE TIMER_A_CTL_MC_1
#define TIMER_A_CONTINUOUS_MODE TIMER_A_CTL_MC_2
#define TIMER_A_UPDOWN_MODE TIMER_A_CTL_MC_3
//*****************************************************************************
代表了Timer A的不同工作模式,用于控制定时器的行为。
1. TIMER_A_STOP_MODE:
这个宏定义用于设置Timer A为停止模式。在停止模式下,定时器不工作,计数器停止计数。该模式通常在不需要定时器计数的时候使用。
2. TIMER_A_UP_MODE:
这个宏定义用于设置Timer A为向上计数模式。在向上计数模式下,计数器从0开始递增直到达到设定的上限值。当计数器到达上限值时,会触发中断或者产生输出信号,然后重新从0开始计数。
3. TIMER_A_CONTINUOUS_MODE:
这个宏定义用于设置Timer A为连续模式。在连续模式下,计数器从0开始递增,无论是否达到上限值,都会一直计数下去。这种模式适用于需要无限计数的应用场景。
4. TIMER_A_UPDOWN_MODE:
这个宏定义用于设置Timer A为向上/向下计数模式。在这个模式下,计数器从0开始递增直到达到设定的上限值,然后又从上限值开始递减直到0,然后再次递增,如此循环。这种模式适用于需要周期性计数的应用场景。
4.INT_TAx_y
#define INT_TA0_0 (24) /* TA0_0 IRQ */
#define INT_TA0_N (25) /* TA0_N IRQ */
#define INT_TA1_0 (26) /* TA1_0 IRQ */
#define INT_TA1_N (27) /* TA1_N IRQ */
#define INT_TA2_0 (28) /* TA2_0 IRQ */
#define INT_TA2_N (29) /* TA2_N IRQ */
#define INT_TA3_0 (30) /* TA3_0 IRQ */
#define INT_TA3_N (31) /* TA3_N IRQ */
定时器/计数器(Timer/Counter)模块的中断标识符。
每个INT_TAx_y对应于不同的定时器/计数器模块。
这些中断标识符可以在编程中用于启用和处理特定定时器/计数器的中断。
使用MSP432的软件包或编程环境,可以通过以下步骤来使用这些定时器模块和相应的中断标识符:
1. 配置定时器/计数器模块:
选择一个定时器/计数器模块(例如TA0、TA1等),并设置其工作模式、时钟源、分频比等参数。
2. 启用中断功能:
使用INT_TAx_y中断标识符,启用或禁用所选定时器/计数器模块的中断功能。
3. 编写中断处理程序:
在中断向量表或特定的中断服务函数中编写处理程序,用于处理所选定时器/计数器模块的中断事件。
4. 启动定时器/计数器:
启动所选定时器/计数器模块,开始计时或计数。
5.TIMER_A_CCTLN_COV_OFS和TIMER_A_CCTLN_COV
/* TIMER_A_CCTLN[COV] Bits */
#define TIMER_A_CCTLN_COV_OFS ( 1) /*!< COV Bit Offset */
#define TIMER_A_CCTLN_COV ((uint16_t)0x0002) /*!< Capture overflow */
用于控制计时器A模块的比较/捕获控制寄存器CCTL的偏移量和溢出比较模式。
TIMER_A_CCTLN_COV_OFS和TIMER_A_CCTLN_COV是两个宏定义,
TIMER_A_CCTLN_COV_OFS是一个偏移宏,表示CCTL寄存器在控制寄存器组中的偏移量。它用于访问CCTL寄存器,该寄存器用于配置计时器A模块的比较/捕获通道。
TIMER_A_CCTLN_COV宏定义表示CCTL寄存器的溢出比较模式。它用于配置CCTL寄存器,以确定比较/捕获通道是用于捕获定时器溢出事件还是与其他事件进行比较。
6.TIMER_A_READ_SYNCHRONIZED_CAPTURECOMPAREINPUT和TIMER_A_READ_CAPTURE_COMPARE_INPUT
//*****************************************************************************
//
// The following are values that can be passed to the synchronized parameter
//
//*****************************************************************************
#define TIMER_A_READ_SYNCHRONIZED_CAPTURECOMPAREINPUT TIMER_A_CCTLN_SCCI
#define TIMER_A_READ_CAPTURE_COMPARE_INPUT TIMER_A_CCTLN_CCI
都是定时器A模块控制寄存器中使用的常量。
1. TIMER_A_CCTLN_SCCI(TIMER_A_READ_SYNCHRONIZED_CAPTURECOMPAREINPUT)是用于配置定时器A的比较输出触发模式的常量。它指示定时器A在捕获比较输入时使用同步触发机制。这意味着定时器A的捕获比较输入会与外部信号进行同步,以确保准确的时间测量。
2. TIMER_A_CCTLN_CCI(TIMER_A_READ_CAPTURE_COMPARE_INPUT)是用于配置定时器A的比较输入信号的常量。它指示定时器A将比较输入设置为捕获模式,以便在定时器A计数器到达指定值时,输入信号的状态将被捕获。
这些常量在MSP432的Timer A控制寄存器(CCTLx)中使用,其中x表示定时器A的各个通道(0-5)。
使用这些常量的步骤如下:
1. 配置定时器A的相关寄存器:通过编程设置相关的控制寄存器,例如CCTLx和CTL。
2. 选择相应的模式:根据需求选择TIMER_A_CCTLN_SCCI或TIMER_A_CCTLN_CCI常量,以配置捕获比较功能的触发模式或输入信号。
3. 启动定时器A:设置CTL寄存器中的计数器模式和时钟源,然后启动定时器A。
4. 处理捕获或比较事件:当定时器A的计数器达到指定值时,相关的捕获或比较事件将会发生。根据需要,进行相应的事件处理。
7.TIMER_A_CAPTURECOMPARE_INPUT_HIGH和TIMER_A_CAPTURECOMPARE_INPUT_LOW
#define TIMER_A_CAPTURECOMPARE_INPUT_HIGH 0x01
#define TIMER_A_CAPTURECOMPARE_INPUT_LOW 0x00
用于配置定时器模块的捕获比较输入模式。
这些宏定义定义了输入模式的不同状态。
`TIMER_A_CAPTURECOMPARE_INPUT_HIGH`表示“高电平”输入模式,而`TIMER_A_CAPTURECOMPARE_INPUT_LOW`表示“低电平”输入模式。
这些宏定义一般在使用MSP432的定时器模块进行输入捕获操作时使用。通过设置定时器的捕获比较寄存器(Capture/Compare Register)的输入模式,可以根据输入信号的电平状态来触发相应的捕获事件。
五、定时器相关函数:
1.MAP_Timer_A_clearInterruptFlag(TIMER_Ax_BASE);
用于清除定时器A的捕获/比较通道的溢出中断标志位。
当定时器A的捕获/比较通道A产生中断时,中断标志会被设置。通过调用该函数,可以清除这个中断标志,以便处理器可以继续进行其他任务。
2.MAP_Timer_A_clearCaptureCompareInterrupt(TIMER_Ax_BASE,TIMER_A_CAPTURECOMPARE_REGISTER_x);
是用于清除特定定时器(Timer A)的特定比较捕获中断。
TIMER_Ax_BASE`表示要操作的定时器A的基地址
TIMER_A_CAPTURECOMPARE_REGISTER_x`表示要操作的比较捕获寄存器的编号。
3. MAP_Interrupt_enableInterrupt(INT_TAx_y);
开启定时器端口中断函数。
4.MAP_Timer_A_startCounter(TIMER_Ax_BASE,TIMER_A_xxx_MODE);
选择计数工作模式并启动定时器开始计数。
5.MAP_Timer_A_getEnabledInterruptStatus(TIMER_Ax_BASE );
查询定时器A的使能中断状态。
函数的作用是查询指定定时器A模块的使能中断状态,并返回当前的状态值。
函数的使用方法如下:
1. 包含头文件 #include <ti/devices/msp432p4xx/driverlib/driverlib.h>
2. 初始化定时器A模块。
3. 使用函数 TIMER_A_getEnabledInterruptStatus(TIMER_Ax_BASE),其中TIMER_Ax_BASE是特定定时器A模块的基地址,用于查询该模块的使能中断状态。
4. 函数返回值是一个32位的掩码,表示各个中断标志位的状态。根据具体需要,可以使用位运算(如与操作)来查询特定的中断标志位。
6. BITBAND_PERI(TIMER_A_CMSIS(TIMER_Ax_BASE)->CCTL[X], TIMER_A_CCTLN_COV_OFS) = 0;
将 Timer A 比较控制寄存器 (CCTL[X]) 中的 "COV" 位清零。
这个语句使用了字节操作宏 BITBAND_PERI,它是一种优化技术,用于在单个位级别上访问外设寄存器。通过使用 BITBAND_PERI,可以直接对特定位进行操作,而不必读取整个寄存器。这样可以提高代码效率和执行速度。
具体到这个语句中,TIMER_Ax_BASE 是 Timer A 的基地址,X 是比较器的编号(0 到 6),TIMER_A_CMSIS 和 TIMER_A_CCTLN_COV_OFS 是定义在设备头文件中的宏,用于计算对应的 CCTL[X] 的偏移量和 COV 位在该寄存器中的位偏移量。
通常,在编写 MSP432 的定时器中断代码时,会遇到需要清除溢出标志的情况。此时,可以使用类似于上述代码的语句,将相关的比较控制寄存器中的溢出位清零,以允许下次溢出中断正确触发。
7.MAP_Timer_A_getCaptureCompareEnabledInterruptStatus(TIMER_Ax_BASE,TIMER_A_CAPTURECOMPARE_REGISTER_x);
获取捕捉比较器中的使能状态。
在MSP432中,定时器用于测量时间、执行中断、计时等操作。捕捉比较器是一种与定时器关联的特殊寄存器,可以用来捕捉或比较定时器的值。捕捉比较器的使能状态用于确定是否允许对应的中断。
在需要判断捕捉比较器中断使能状态的时候,可以使用该函数来获取相应的状态值。函数会返回一个bool类型的返回值,true表示中断使能,false表示中断禁用。
8.MAP_Timer_A_getSynchronizedCaptureCompareInput(TIMER_Ax_BASE,TIMER_A_CAPTURECOMPARE_REGISTER_x,TIMER_A_READ_CAPTURE_COMPARE_INPUT)==TIMER_A_CAPTURECOMPARE_INPUT_LOW);
通过TIMER_A模块获取指定计时器和比较器的输入信号,并判断该输入信号是低电平。
MAP_Timer_A_getSynchronizedCaptureCompareInput()是一个用于获取比较器输入信号的函数。其中,TIMER_Ax_BASE表示定时器A模块的基地址,TIMER_A_CAPTURECOMPARE_REGISTER_x表示指定的比较器寄存器,TIMER_A_READ_CAPTURE_COMPARE_INPUT表示读取比较器输入信号的操作。
这段代码的功能是判断指定的比较器输入信号是否为低电平。
9.MAP_Timer_A_clearTimer(TIMER_Ax_BASE);
清除指定的定时器。
这个函数可以在需要停止或重置定时器的时候使用。当调用这个函数后,定时器的计数器会被清零,定时器停止计数。
下面是使用`MAP_Timer_A_clearTimer()`的一般步骤:
1. 配置定时器的参数。可以使用“Timer_A_initUpMode()”函数或者其他相应的配置函数配置定时器。
2. 在需要处理的时候调用“MAP_Timer_A_clearTimer(TIMER_Ax_BASE)”来清除定时器。
需要注意的是,TIMER_Ax_BASE中的x代表具体的定时器编号(例如TIMER_A0_BASE、TIMER_A1_BASE等),您需要根据自己的应用选择正确的定时器。
这个函数通常在需要停止或者重置定时器的时候用到,例如在定时器到达指定时间后,或者在程序中需要重新开始计时等情况下使用。
10.ROM_Timer_A_getCaptureCompareCount (TIMER_Ax_BASE,
TIMER_A_CAPTURECOMPARE_REGISTER_x)
获取定时器A中的捕获比较寄存器的计数值。
该函数指针指向MSP432 ROM中的函数,并且可以通过调用此函数来获得捕获比较寄存器的计数值。
在使用ROM_Timer_A_getCaptureCompareCount函数之前,需要先初始化定时器A的相关设置,然后可以通过调用该函数来获取捕获比较寄存器的计数值。
通常情况下,需要提供两个参数:要访问的定时器号,要访问的捕获比较寄存器号。
定时器捕获比较寄存器的计数值取决于定时器的时钟源和预分频器的设置。
定时器的计数值随着时钟脉冲的到达而增加,当计数值达到定时器的最大计数值时,定时器会发出中断或触发一些其他的操作,例如输出比较或捕获。
因此,定时器捕获比较寄存器的计数值受到定时器的时钟源和预分频器的设置的影响。正确设置这些参数可以实现所需的计数速度和精度。
11.ROM_Timer_A_getCaptureCompareInterruptStatus(TIMER_Ax_BASE,TIMER_A_CAPTURECOMPARE_REGISTER_x,uint_fast16_t mask))
获取Timer A模块的捕获比较中断的状态。
参数:
要操作的Timer A模块编号。
要操作的捕获比较寄存器编号。
要检查的中断状态的掩码。
该函数的主要作用是查询指定Timer A模块捕获比较寄存器的中断状态。
该函数通常在需要获取Timer A模块捕获比较中断状态时使用,可以用于判断是否发生了特定的中断事件,以便做出相应的处理。
12.ROM_Timer_A_getCounterValue(TIMER_Ax_BASE);
返回一个 uint16_t 类型的计数器值。
这是一个函数指针,它指向 Timer_A 模块的计数器值的获取函数。该函数的参数是一个 Timer 实例的地址,返回一个 uint16_t 类型的计数器值