在HPM6200EVK的用户手册中,对定时器同步的描述如下
定时器支持同步信号,软件同步和通道间的同步较为简单,直接设置对应寄存器即可,硬件同步需要用到TRGM互联管理器进行信号的路由,本文记录了一个简单的例子,演示HPM6200EVK通过外部引脚控制定时器记数
首先是内部定时器配置部分
配置GPTMR2的通道0作为PWM输出,RLD寄存器设的比较大,方便后面现象的观察
需要注意的是,如果需要外部信号作为SYNCI,则需要在配置时设置synci_edge属性,这个属性决定了外部信号上升沿还是下降沿来的时候CNT进行重载
然后进行TRGM的配置,选择引脚PC06作为外部输入,需要查看引脚是否支持TRGM功能,只有支持该功能的引脚才能进行路由
同时一个芯片有多个TRGM管理器,比如说GPTMR2的SYNCI由TRGM2管理,所以你需要选择TRGM2下的外部输入信号作为触发
代码中将PC06的输入路由到GPTMR2的SYNCI
然后在主程序中,每1秒打印一次CNT的值
从打印可见,在没有外部信号的时候,正常自增,手动给PC06引脚一个方波,当有外部触发时,CNT的值重载,重新开始向上自增
从波形中可见,由于外部触发对CNT的重载,让最开始两个方波之间的周期为6.7S,随后则正常开始记数,方波周期变为5s
完整代码如下所示
/*
* Copyright (c) 2021 HPMicro
*
* SPDX-License-Identifier: BSD-3-Clause
*
*/
#include "board.h"
#include "hpm_sysctl_drv.h"
#include "hpm_gptmr_drv.h"
#include "hpm_debug_console.h"
#include "hpm_trgm_drv.h"
static void timer_config(void);
static void timer_sync_trgm(void);
volatile uint32_t times;
int main(void)
{
board_init();
timer_config();
timer_sync_trgm();
while(1) {
times = gptmr_channel_get_counter(HPM_GPTMR2,0,gptmr_counter_type_normal);
printf("times=%d\n",times);
board_delay_ms(1000);
}
return 0;
}
static void timer_config(void)
{
uint32_t gptmr_freq;
HPM_IOC->PAD[IOC_PAD_PC08].FUNC_CTL = IOC_PC08_FUNC_CTL_GPTMR2_COMP_0;
gptmr_channel_config_t config;
gptmr_channel_get_default_config(HPM_GPTMR2, &config);
gptmr_freq = clock_get_frequency(clock_gptmr2);
config.cmp_initial_polarity_high = true;
config.synci_edge = gptmr_synci_edge_both;
config.reload = gptmr_freq / 1000 * 5000;
config.cmp[0] = gptmr_freq / 1000 * 3500;
gptmr_channel_config(HPM_GPTMR2, 0, &config, false);
gptmr_start_counter(HPM_GPTMR2, 0);
}
static void timer_sync_trgm(void)
{
HPM_IOC->PAD[IOC_PAD_PC06].FUNC_CTL = IOC_PC06_FUNC_CTL_TRGM2_P_6;
trgm_output_t config = {0};
config.invert = false;
config.input = HPM_TRGM2_INPUT_SRC_TRGM2_P6;
config.type = trgm_output_same_as_input;
trgm_output_config(HPM_TRGM2, HPM_TRGM2_OUTPUT_SRC_GPTMR2_SYNCI, &config);
}