设置定时器为计数功能时,操作步骤如下:
(1)将计数用的GPIO口位引脚方向设置为输入
(2)在 R32_TMRx_CNT_END寄存器 中设定计数溢出终值,就是计数上限值
(3)配置模式设置寄存器(R8_TMRx_CTRL_MOD),置位 RB_TMR_MODE_IN 和 RB_TMR_CAP_COUNT,表示设置定时器为计数模式。
(4)清零模式设置寄存器(R8_TMRx_CTRL_MOD)的RB_TMR_ALL_CLEAR 位,通过 RB_TMR_CAP_EDGE 选择采样边沿方式,
(5)将模式设置寄存器(R8_TMRx_CTRL_MOD)的RB_TMR_COUNT_EN 置 1,使能计数功能;
(6)可选步骤,如果需要启用中断则设置相应的中断使能寄存器位;
(7)R32_TMRx_COUNT 存放当前计数值,每次计数达到计数终值(R32_TMRx_CNT_END寄存器),中断标志寄存器(R8_TMRx_INT_FLAG)的RB_TMR_IE_CYC_END 都会置 1 并且R32_TMRx_COUNT 清 0,如果开启中断则会触发硬件中断。
测试计划如下:
1、以TMR0产生周期(1ms)脉冲,输出到指定GPIO口(PB3)
2、短接1中的GPIO口(PB3)给另一个输入用的GPIO口(PB10,由系统的功能复用指定的GPIO口),作为TMR1的外部输入脉冲

3、配置TMR1为计数模式,输入脉冲为TMR0的输出脉冲
测试代码如下:
/*********************************************************************
* @fn TMR0_TimerInit
*
* @brief 定时功能初始化
*
* @param t - 定时时间,基于当前系统时钟Tsys, 最长定时周期 67108864
*
* @return none
*/
void TMR0_TimerInit(uint32_t t)
{
R32_TMR0_CNT_END = t;
R8_TMR0_CTRL_MOD = RB_TMR_ALL_CLEAR;
R8_TMR0_CTRL_MOD = RB_TMR_COUNT_EN;
}
// LED 接在 PB4
#define LED_PIN GPIO_Pin_4
int main()
{
uint8_t i;
SetSysClock(CLK_SOURCE_PLL_60MHz);
/* 配置串口调试 */
DebugInit();
PRINT("Start @ChipID=%02X\n", R8_CHIP_ID);
// 指定 PB3 和 PB4 为输出方式
GPIOB_SetBits(GPIO_Pin_4 | GPIO_Pin_3);
GPIOB_ModeCfg(GPIO_Pin_4 | GPIO_Pin_3, GPIO_ModeOut_PP_5mA);
TMR0_TimerInit(FREQ_SYS / 1000); // 设置定时时间 1ms ( (1/60MHz) * (60M / 1000))
TMR0_ITCfg(ENABLE, TMR0_3_IT_CYC_END); // 开启中断:周期结束
PFIC_EnableIRQ(TMR0_IRQn);
// 配置TMR1为计数模式,外部脉冲从 PB10 引入
// 测试时,需要短接 PB3 - PB10
// 配置 PB10 为输入模式
GPIOB_ModeCfg(GPIO_Pin_10, GPIO_ModeIN_PD);
// 重映射PB10为TMR1的功能复用引脚
GPIOPinRemap(ENABLE, RB_PIN_TMR1);
// 下降沿有效
TMR1_EXTSingleCounterInit(FallEdge_To_FallEdge);
TMR1_CountOverflowCfg(10); // 设置计数上限10
/* 开启计数溢出中断,计数10个周期进入中断 */
TMR1_ClearITFlag(TMR0_3_IT_CYC_END);
PFIC_EnableIRQ(TMR1_IRQn);
TMR1_ITCfg(ENABLE, TMR0_3_IT_CYC_END);
while(1);
}
/*********************************************************************
* @fn TMR0_IRQHandler
*
* @brief TMR0中断函数
*
* @return none
*/
__INTERRUPT
__HIGH_CODE
void TMR0_IRQHandler(void) // TMR0 定时中断
{
if(TMR0_GetITFlag(TMR0_3_IT_CYC_END)) {
// 清除中断标志
TMR0_ClearITFlag(TMR0_3_IT_CYC_END);
// GOPIO口翻转
GPIOB_InverseBits(GPIO_Pin_3);
}
}
/*********************************************************************
* @fn TMR1_IRQHandler
*
* @brief TMR1中断函数
*
* @return none
*/
__INTERRUPT
__HIGH_CODE
void TMR1_IRQHandler(void) // TMR1 定时中断
{
if(TMR1_GetITFlag(TMR0_3_IT_CYC_END))
{
TMR1_ClearITFlag(TMR0_3_IT_CYC_END);
/* 计数器计满,硬件自动清零,重新开始计数 */
// GOPIO口翻转
GPIOB_InverseBits(GPIO_Pin_4);
}
}由逻辑分析仪捕捉到的PB4口的输出信号:

说明:
1、根据程序,在定时器0中,PB3每1ms翻转一次,因而在PB3上产生周期为2ms的脉冲
2、PB3上的信号经PB10,成为定时器1的外部脉冲输入信号,收集到10个脉冲后,使PB4翻转。也就是说PB4上每20ms翻转一次。这个结果与逻辑分析仪得到的结果是一致的。
我要赚赏金
